feat: pe, se

This commit is contained in:
Konstantin Kireyev
2025-01-14 23:30:01 +05:00
parent 458cedd973
commit db29cbd3f2
22 changed files with 151 additions and 46 deletions

View File

@ -68,28 +68,44 @@ export const DrawView = ({ currentTool, setTool, settings, setSettings, colors,
</div>
</Sheet>
<div className="draw-toolbar">
<Button type='button' fill={currentTool === 'pen'} onClick={() => setTool('pen')}>
<SvgIcon symbolId={IconDrawPen.id} className='icon icon-svg'/>
</Button>
<Button type='button' fill={currentTool === 'highlighter'} onClick={() => setTool('highlighter')}>
<SvgIcon symbolId={IconDrawHighlighter.id} className='icon icon-svg'/>
</Button>
<Button type='button' sheetOpen=".draw-sheet--settings">
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<circle cx="50%" cy="50%" r="8" fill={settings.color}/>
</svg>
</Button>
<div className='draw-toolbar-divider'/>
<Button type='button' disabled={false} fill={currentTool === 'eraser'} onClick={() => setTool('eraser')}>
<SvgIcon symbolId={IconClearObject.id} className='icon icon-svg'/>
</Button>
<Button type='button' disabled={false} onClick={() => setTool('eraseEntireScreen')}>
<SvgIcon symbolId={IconClearAll.id} className='icon icon-svg'/>
</Button>
<div className='draw-toolbar-divider'/>
<Button type='button' fill={currentTool === 'scroll'} onClick={() => setTool('scroll')} tabIndex='-1'>
<SvgIcon symbolId={IconScroll.id} className='icon icon-svg'/>
</Button>
<div className="draw-toolbar-item">
<Button type='button' fill={currentTool === 'pen'} onClick={() => setTool('pen')}>
<SvgIcon symbolId={IconDrawPen.id} className='icon icon-svg'/>
</Button>
</div>
<div className="draw-toolbar-item">
<Button type='button' fill={currentTool === 'highlighter'} onClick={() => setTool('highlighter')}>
<SvgIcon symbolId={IconDrawHighlighter.id} className='icon icon-svg'/>
</Button>
</div>
<div className="draw-toolbar-item">
<Button type='button' sheetOpen=".draw-sheet--settings">
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<circle cx="50%" cy="50%" r="8" fill={settings.color}/>
</svg>
</Button>
</div>
<div className="draw-toolbar-item">
<div className='draw-toolbar-divider'/>
</div>
<div className="draw-toolbar-item">
<Button type='button' disabled={false} fill={currentTool === 'eraser'} onClick={() => setTool('eraser')}>
<SvgIcon symbolId={IconClearObject.id} className='icon icon-svg'/>
</Button>
</div>
<div className="draw-toolbar-item">
<Button type='button' disabled={false} onClick={() => setTool('eraseEntireScreen')}>
<SvgIcon symbolId={IconClearAll.id} className='icon icon-svg'/>
</Button>
</div>
<div className="draw-toolbar-item">
<div className='draw-toolbar-divider'/>
</div>
<div className="draw-toolbar-item">
<Button type='button' fill={currentTool === 'scroll'} onClick={() => setTool('scroll')} tabIndex='-1'>
<SvgIcon symbolId={IconScroll.id} className='icon icon-svg'/>
</Button>
</div>
</div>
</React.Fragment>
)

View File

@ -107,24 +107,37 @@
}
.draw-toolbar {
padding-inline: 10px;
display: flex;
justify-content: space-between;
align-items: center;
padding-inline: 10px;
width: 100%;
button {
display: flex;
padding: 0;
width: 36px;
height: 36px;
min-width: 36px;
border-radius: 7px;
border: none;
@media (min-width: 550px) {
display: grid;
grid-template-columns: repeat(8, 1fr);
}
&.button-fill {
color: @brandColor;
background-color: @button-active-opacity;
&-item {
@media (min-width: 550px) {
display: flex;
align-items: center;
justify-content: center;
}
button {
display: flex;
padding: 0;
width: 36px;
height: 36px;
min-width: 36px;
border-radius: 7px;
border: none;
&.button-fill {
color: @brandColor;
background-color: @button-active-opacity;
}
}
}

View File

@ -65,7 +65,7 @@
&.icon-close {
width: 24px;
height: 24px;
.encoded-svg-mask('<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M18.9844 6.42188L13.4062 12L18.9844 17.5781L17.5781 18.9844L12 13.4062L6.42188 18.9844L5.01562 17.5781L10.5938 12L5.01562 6.42188L6.42188 5.01562L12 10.5938L17.5781 5.01562L18.9844 6.42188Z"/></svg>', @text-normal);
.encoded-svg-mask('<svg xmlns="http://www.w3.org/2000/svg" fill="@{toolbar-icons}" width="24" height="24" viewBox="0 0 24 24"><path d="M18.9844 6.42188L13.4062 12L18.9844 17.5781L17.5781 18.9844L12 13.4062L6.42188 18.9844L5.01562 17.5781L10.5938 12L5.01562 6.42188L6.42188 5.01562L12 10.5938L17.5781 5.01562L18.9844 6.42188Z"/></svg>', @toolbar-icons);
}
&.icon-done-disabled {
width: 24px;

View File

@ -270,6 +270,7 @@
"waitText": "Please, wait..."
},
"Toolbar": {
"textOk": "OK",
"dlgLeaveMsgText": "You have unsaved changes in this document. Click 'Stay on this Page' to wait for autosave. Click 'Leave this Page' to discard all the unsaved changes.",
"dlgLeaveTitleText": "You leave the application",
"leaveButtonText": "Leave this page",
@ -281,6 +282,7 @@
"View": {
"Add": {
"notcriticalErrorTitle": "Warning",
"textDrawing": "Drawing",
"textAddLink": "Add Link",
"textAddress": "Address",
"textBack": "Back",
@ -554,5 +556,11 @@
"textVersion": "Version",
"textVersionHistory": "Version History"
}
},
"Draw": {
"textOpacity": "Opacity",
"textLineSize": "Line size",
"textColor": "Color",
"textCustomColor": "Custom color"
}
}

View File

@ -259,6 +259,7 @@ const ToolbarController = inject('storeAppOptions', 'users', 'storeFocusObjects'
<ToolbarView
openOptions={props.openOptions}
isEdit={appOptions.isEdit}
isDrawMode={appOptions.isDrawMode}
docTitle={docTitle}
isShowBack={isShowBack}
isCanUndo={isCanUndo}

View File

@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy" content="default-src * 'self' 'unsafe-inline' 'unsafe-eval' data: blob:">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui, viewport-fit=cover">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui, viewport-fit=cover, interactive-widget=resizes-content">
<meta name="theme-color" content="#007aff">
<meta name="format-detection" content="telephone=no">

View File

@ -2,6 +2,7 @@
@import '../../../../common/mobile/resources/less/_mixins.less';
@import '../../../../common/mobile/resources/less/colors-table.less';
@import '../../../../common/mobile/resources/less/colors-table-dark.less';
@import '../../../../common/mobile/resources/less/draw.less';
@import './app-rtl.less';
@brandColor: var(--brand-slide);

View File

@ -1,3 +1,8 @@
.icon-svg {
fill: @brand-slide;
color: @brand-slide;
}
i.icon {
&.icon-format-pptx {
width: 22px;

View File

@ -14,6 +14,7 @@ import SettingsController from '../controller/settings/Settings';
import AddView from '../view/add/Add';
import EditView from '../view/edit/Edit';
import VersionHistoryController from '../../../../common/mobile/lib/controller/VersionHistory';
import { DrawController } from "../../../../common/mobile/lib/controller/Draw";
export const MainContext = createContext();
@ -212,6 +213,9 @@ class MainPage extends Component {
</Navbar>
{/* Page content */}
<View id="editor_sdk" />
<Navbar id='drawbar' style={{ display: !appOptions.isDrawMode && 'none' }}>
<DrawController />
</Navbar>
{isShowPlaceholder ?
<div className="doc-placeholder">

View File

@ -9,6 +9,9 @@ export class storeAppOptions {
setConfigOptions: action,
setPermissionOptions: action,
isDrawMode: observable,
changeDrawMode: action,
lostEditingRights: observable,
changeEditingRights: action,
canBrandingExt: observable,
@ -28,6 +31,11 @@ export class storeAppOptions {
config = {};
customization;
isDrawMode = false;
changeDrawMode(value) {
this.isDrawMode = value;
}
lostEditingRights = false;
changeEditingRights (value) {
this.lostEditingRights = value;

View File

@ -23,7 +23,8 @@ const ToolbarView = props => {
return (
<Fragment>
<NavLeft>
{(props.isShowBack && !isVersionHistoryMode) && <Link className={`btn-doc-back${(props.disabledControls || isOpenModal) && ' disabled'}`} icon='icon-return' onClick={() => Common.Notifications.trigger('goback')}></Link>}
{props.isDrawMode && <Link text={Device.ios ? t("Toolbar.textOk") : ''} icon={Device.android ? 'icon-close' : null} className='back-reader-mode' onClick={() => Common.Notifications.trigger('draw:stop')}/>}
{(props.isShowBack && !props.isDrawMode && !isVersionHistoryMode) && <Link className={`btn-doc-back${(props.disabledControls || isOpenModal) && ' disabled'}`} icon='icon-return' onClick={() => Common.Notifications.trigger('goback')}></Link>}
{isVersionHistoryMode ? <a href="#" className='btn-close-history' onClick={(e) => {
e.preventDefault();
props.closeHistory();
@ -47,21 +48,21 @@ const ToolbarView = props => {
onUndoClick: props.onUndo,
onRedoClick: props.onRedo
})}
{!isVersionHistoryMode &&
{(!isVersionHistoryMode && !props.isDrawMode) &&
<Link className={(props.disabledControls || props.disabledPreview || isOpenModal) && 'disabled'} icon='icon-play' href={false} onClick={() => {props.openOptions('preview')}}></Link>
}
{(props.showEditDocument && !isVersionHistoryMode) &&
<Link className={(props.disabledControls || isOpenModal) ? 'disabled' : ''} icon='icon-edit' href={false} onClick={props.onEditDocument}></Link>
}
{(props.isEdit && EditorUIController.getToolbarOptions && !isVersionHistoryMode) && EditorUIController.getToolbarOptions({
{(props.isEdit && EditorUIController.getToolbarOptions && !props.isDrawMode && !isVersionHistoryMode) && EditorUIController.getToolbarOptions({
disabledEdit: props.disabledEdit || props.disabledControls || isDisconnected || props.disabledPreview || isOpenModal,
disabledAdd: props.disabledControls || isDisconnected || isOpenModal,
onEditClick: () => props.openOptions('edit'),
onAddClick: () => props.openOptions('add')
})}
{Device.phone ? null : <Link className={(props.disabledControls || props.disabledPreview || isOpenModal) && 'disabled'} icon='icon-search' searchbarEnable='.searchbar' href={false}></Link>}
{props.displayCollaboration && window.matchMedia("(min-width: 375px)").matches && !isVersionHistoryMode ? <Link className={(props.disabledControls || isOpenModal) && 'disabled'} id='btn-coauth' href={false} icon='icon-collaboration' onClick={() => props.openOptions('coauth')}></Link> : null}
{isVersionHistoryMode ? <Link id='btn-open-history' icon='icon-version-history' href={false} className={isOpenModal && 'disabled'} onClick={() => props.openOptions('history')}></Link> : null}
{props.displayCollaboration && window.matchMedia("(min-width: 375px)").matches && !props.isDrawMode && !isVersionHistoryMode ? <Link className={(props.disabledControls || isOpenModal) && 'disabled'} id='btn-coauth' href={false} icon='icon-collaboration' onClick={() => props.openOptions('coauth')}></Link> : null}
{(isVersionHistoryMode && !props.isDrawMode) ? <Link id='btn-open-history' icon='icon-version-history' href={false} className={isOpenModal && 'disabled'} onClick={() => props.openOptions('history')}></Link> : null}
<Link className={(props.disabledSettings || props.disabledControls || isDisconnected || isOpenModal) && 'disabled'} id='btn-settings' icon='icon-settings' href={false} onClick={() => props.openOptions('settings')}></Link>
</NavRight>
</Fragment>

View File

@ -3,6 +3,8 @@ import {observer, inject} from "mobx-react";
import {List, ListItem, Page, Navbar, Icon, ListButton, ListInput, BlockTitle, SkeletonBlock, Segmented, Button} from 'framework7-react';
import { useTranslation } from 'react-i18next';
import {Device} from "../../../../../common/mobile/utils/device";
import SvgIcon from "../../../../../common/mobile/lib/component/SvgIcon";
import IconDraw from "../../../../../common/mobile/resources/icons/draw.svg";
const PageTable = props => {
const { t } = useTranslation();
@ -71,6 +73,14 @@ const AddOther = props => {
<Icon slot="media" icon="icon-link"></Icon>
</ListItem>
}
{!Device.ios && (
<ListItem key='drawing' title={_t.textDrawing} onClick={() => {
props.closeModal();
Common.Notifications.trigger('draw:start');
}}>
<SvgIcon slot='media' symbolId={IconDraw.id} className='icon icon-svg'/>
</ListItem>
)}
</List>
)
};

View File

@ -443,6 +443,7 @@
"textWarnDeleteSheet": "The sheet maybe has data. Proceed operation?"
},
"Toolbar": {
"textOk": "OK",
"dlgLeaveMsgText": "You have unsaved changes in this document. Click 'Stay on this Page' to wait for autosave. Click 'Leave this Page' to discard all the unsaved changes.",
"dlgLeaveTitleText": "You leave the application",
"leaveButtonText": "Leave this Page",
@ -453,6 +454,7 @@
},
"View": {
"Add": {
"textDrawing": "Drawing",
"errorMaxRows": "ERROR! The maximum number of data series per chart is 255.",
"errorStockChart": "Incorrect row order. To build a stock chart, place the data on the sheet in the following order:<br> opening price, max price, min price, closing price.",
"notcriticalErrorTitle": "Warning",
@ -862,5 +864,11 @@
"txtZh": "Chinese",
"warnDownloadAs": "If you continue saving in this format all features except the text will be lost.<br>Are you sure you want to continue?"
}
},
"Draw": {
"textOpacity": "Opacity",
"textLineSize": "Line size",
"textColor": "Color",
"textCustomColor": "Custom color"
}
}

View File

@ -277,6 +277,7 @@ const ToolbarController = inject('storeAppOptions', 'users', 'storeSpreadsheetIn
<ToolbarView
openOptions={props.openOptions}
isEdit={appOptions.isEdit}
isDrawMode={appOptions.isDrawMode}
docTitle={docTitle}
isShowBack={isShowBack}
isCanUndo={isCanUndo}

View File

@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy" content="default-src * 'self' 'unsafe-inline' 'unsafe-eval' data: blob:">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui, viewport-fit=cover">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui, viewport-fit=cover, interactive-widget=resizes-content">
<meta name="theme-color" content="#007aff">
<meta name="format-detection" content="telephone=no">

View File

@ -3,6 +3,7 @@
@import '../../../../common/mobile/resources/less/_mixins.less';
@import '../../../../common/mobile/resources/less/colors-table.less';
@import '../../../../common/mobile/resources/less/colors-table-dark.less';
@import '../../../../common/mobile/resources/less/draw.less';
@import './app-rtl.less';
// @themeColor: #40865c;

View File

@ -1,3 +1,7 @@
.icon-svg {
fill: @brand-cell;
color: @brand-cell;
}
.chart-types .thumb {
//@relativepath: '../../resources/img';

View File

@ -17,6 +17,7 @@ import SettingsController from '../controller/settings/Settings';
import AddingController from '../controller/add/Add';
import EditView from '../view/edit/Edit';
import VersionHistoryController from '../../../../common/mobile/lib/controller/VersionHistory';
import { DrawController } from "../../../../common/mobile/lib/controller/Draw";
export const MainContext = createContext();
@ -208,6 +209,9 @@ class MainPage extends Component {
<CellEditor onClickToOpenAddOptions={(panels, button) => this.handleClickToOpenOptions('add', {panels: panels, button: button})} />
{/* Page content */}
<View id="editor_sdk" />
<Navbar id='drawbar' style={{ display: !appOptions.isDrawMode && 'none' }}>
<DrawController />
</Navbar>
{isShowPlaceholder ?
<div className="doc-placeholder">
<div className="columns"></div>

View File

@ -9,6 +9,9 @@ export class storeAppOptions {
setConfigOptions: action,
setPermissionOptions: action,
isDrawMode: observable,
changeDrawMode: action,
lostEditingRights: observable,
changeEditingRights: action,
@ -25,6 +28,11 @@ export class storeAppOptions {
isEdit = false;
config = {};
customization;
isDrawMode = false;
changeDrawMode(value) {
this.isDrawMode = value;
}
canViewComments = false;
changeCanViewComments(value) {

View File

@ -218,7 +218,7 @@ const StatusbarView = inject('storeAppOptions', 'storeWorksheets', 'users')(obse
return (
<Fragment>
<View id="idx-statusbar" className="statusbar" style={viewStyle}>
<View id="idx-statusbar" className="statusbar" style={{ 'margin-bottom': storeAppOptions.isDrawMode ? 'calc(44px + env(safe-area-inset-bottom) + env(keyboard-inset-top))' : undefined, ...viewStyle }}>
{isEdit &&
<div id="idx-box-add-tab" className={`${isDisconnected || isWorkbookLocked ? 'disabled box-tab' : 'box-tab'}`}>
<Link href={false} id="idx-btn-addtab" className={`tab${isDisabledEditSheet || isDisconnected || isWorkbookLocked || isProtectedWorkbook ? ' disabled' : ''}`} onClick={props.onAddTabClicked}>

View File

@ -32,7 +32,8 @@ const ToolbarView = props => {
return (
<Fragment>
<NavLeft>
{(props.isShowBack && !isVersionHistoryMode) && <Link className={`btn-doc-back${(props.disabledControls || isOpenModal) && ' disabled'}`} icon='icon-return' onClick={() => Common.Notifications.trigger('goback')}></Link>}
{props.isDrawMode && <Link icon='icon-close' onClick={() => Common.Notifications.trigger('draw:stop')}/>}
{(!props.isDrawMode && props.isShowBack && !isVersionHistoryMode) && <Link className={`btn-doc-back${(props.disabledControls || isOpenModal) && ' disabled'}`} icon='icon-return' onClick={() => Common.Notifications.trigger('goback')}></Link>}
{isVersionHistoryMode ? <a href="#" className='btn-close-history' onClick={(e) => {
e.preventDefault();
props.closeHistory();
@ -49,7 +50,7 @@ const ToolbarView = props => {
{(props.showEditDocument && !isVersionHistoryMode) &&
<Link className={(props.disabledControls || isOpenModal) ? 'disabled' : ''} icon='icon-edit' href={false} onClick={props.onEditDocument}></Link>
}
{(props.isEdit && EditorUIController.toolbarOptions && !isVersionHistoryMode) && EditorUIController.toolbarOptions.getEditOptions({
{(!props.isDrawMode && props.isEdit && EditorUIController.toolbarOptions && !isVersionHistoryMode) && EditorUIController.toolbarOptions.getEditOptions({
disabled: props.disabledEditControls || props.disabledControls || isDisconnected || isOpenModal,
wsProps,
focusOn,
@ -58,7 +59,7 @@ const ToolbarView = props => {
onAddClick: () => props.openOptions('add')
})}
{Device.phone ? null : <Link className={(props.disabledControls || props.disabledSearch || isOpenModal) && 'disabled'} icon='icon-search' searchbarEnable='.searchbar' href={false}></Link>}
{props.displayCollaboration && window.matchMedia("(min-width: 360px)").matches && !isVersionHistoryMode ? <Link className={(props.disabledControls || props.disabledCollaboration || isOpenModal) && 'disabled'} id='btn-coauth' href={false} icon='icon-collaboration' onClick={() => props.openOptions('coauth')}></Link> : null}
{!props.isDrawMode && props.displayCollaboration && window.matchMedia("(min-width: 360px)").matches && !isVersionHistoryMode ? <Link className={(props.disabledControls || props.disabledCollaboration || isOpenModal) && 'disabled'} id='btn-coauth' href={false} icon='icon-collaboration' onClick={() => props.openOptions('coauth')}></Link> : null}
{isVersionHistoryMode ? <Link id='btn-open-history' icon='icon-version-history' href={false} className={isOpenModal && 'disabled'} onClick={() => props.openOptions('history')}></Link> : null}
<Link className={(props.disabledSettings || props.disabledControls || isDisconnected || isOpenModal) && 'disabled'} id='btn-settings' icon='icon-settings' href={false} onClick={() => props.openOptions('settings')}></Link>
</NavRight>

View File

@ -3,6 +3,9 @@ import { inject, observer } from 'mobx-react';
import {List, ListItem, Icon} from 'framework7-react';
import { useTranslation } from 'react-i18next';
import { MainContext } from '../../page/main';
import { Device } from "../../../../../common/mobile/utils/device";
import SvgIcon from "../../../../../common/mobile/lib/component/SvgIcon";
import IconDraw from "../../../../../common/mobile/resources/icons/draw.svg";
const AddOther = inject("storeFocusObjects", "storeAppOptions")(observer(props => {
const { t } = useTranslation();
@ -34,6 +37,14 @@ const AddOther = inject("storeFocusObjects", "storeAppOptions")(observer(props =
}}>
<Icon slot="media" icon="icon-link"></Icon>
</ListItem>
{!Device.ios && (
<ListItem key='drawing' title={_t.textDrawing} onClick={() => {
props.closeModal();
Common.Notifications.trigger('draw:start');
}}>
<SvgIcon slot='media' symbolId={IconDraw.id} className='icon icon-svg'/>
</ListItem>
)}
</List>
)
}));