From 3e6e71966e66a919e5a754e152ced21e2fb51491 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Mon, 25 Jan 2021 20:12:50 +0300 Subject: [PATCH 01/14] [PE mobile] Added the ability to insert slides --- .../mobile/resources/less/common-ios.less | 2 +- .../mobile/src/controller/add/AddSlide.jsx | 20 ++++++++++++++++-- .../mobile/src/store/slideSettings.js | 18 ++++++++++++++++ .../mobile/src/view/add/AddSlide.jsx | 21 +++++++++++++++---- 4 files changed, 54 insertions(+), 7 deletions(-) diff --git a/apps/common/mobile/resources/less/common-ios.less b/apps/common/mobile/resources/less/common-ios.less index ee582bc7be..c4e29da777 100644 --- a/apps/common/mobile/resources/less/common-ios.less +++ b/apps/common/mobile/resources/less/common-ios.less @@ -366,7 +366,7 @@ } } - .dataview, #add-table, #add-shape { + .dataview, #add-table, #add-shape, #add-slide { &.page-content { background-color: @white; } diff --git a/apps/presentationeditor/mobile/src/controller/add/AddSlide.jsx b/apps/presentationeditor/mobile/src/controller/add/AddSlide.jsx index 5723596ce6..6c2cb706b4 100644 --- a/apps/presentationeditor/mobile/src/controller/add/AddSlide.jsx +++ b/apps/presentationeditor/mobile/src/controller/add/AddSlide.jsx @@ -3,15 +3,31 @@ import { f7 } from 'framework7-react'; import {Device} from '../../../../../common/mobile/utils/device'; import {observer, inject} from "mobx-react"; -import { AddSlide } from '../../view/add/AddSlide'; +import AddSlide from '../../view/add/AddSlide'; class AddSlideController extends Component { constructor (props) { super(props); + this.onSlideLayout = this.onSlideLayout.bind(this); } + + closeModal () { + if ( Device.phone ) { + f7.sheet.close('.add-popup', true); + } else { + f7.popover.close('#add-popover'); + } + } + + onSlideLayout (type) { + const api = Common.EditorApi.get(); + api.AddSlide(type); + this.closeModal(); + } + render () { return ( - ) } diff --git a/apps/presentationeditor/mobile/src/store/slideSettings.js b/apps/presentationeditor/mobile/src/store/slideSettings.js index 0899b7bbcc..37ee3ec4c3 100644 --- a/apps/presentationeditor/mobile/src/store/slideSettings.js +++ b/apps/presentationeditor/mobile/src/store/slideSettings.js @@ -41,6 +41,24 @@ export class storeSlideSettings { @action addArrayLayouts(array) { this.arrayLayouts = array; } + @computed get slideLayouts () { + const layouts = []; + const columns = 2; + let row = -1; + this.arrayLayouts.forEach((item, index)=>{ + if (0 == index % columns) { + layouts.push([]); + row++ + } + layouts[row].push({ + type: item.getIndex(), + image: item.get_Image(), + width: item.get_Width(), + height: item.get_Height() + }); + }); + return layouts; + } @action changeSlideLayoutIndex(index) { this.slideLayoutIndex = index; diff --git a/apps/presentationeditor/mobile/src/view/add/AddSlide.jsx b/apps/presentationeditor/mobile/src/view/add/AddSlide.jsx index 3a4daa85c3..96b50c2678 100644 --- a/apps/presentationeditor/mobile/src/view/add/AddSlide.jsx +++ b/apps/presentationeditor/mobile/src/view/add/AddSlide.jsx @@ -5,11 +5,24 @@ import { useTranslation } from 'react-i18next'; import {Device} from '../../../../../common/mobile/utils/device'; const AddSlide = props => { + const layouts = props.storeSlideSettings.slideLayouts; return ( - - - +
+ {layouts.map((row, rowIndex) => { + return ( +
    + {row.map((layout, index) => { + return ( +
  • {props.onSlideLayout(layout.type)}}> + +
  • + ) + })} +
+ ) + })} +
) }; -export {AddSlide}; \ No newline at end of file +export default inject("storeSlideSettings")(observer(AddSlide)); \ No newline at end of file From 74835308dea3c78cad8ce65f7d5ee1eb0c6b4319 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Tue, 26 Jan 2021 14:49:24 +0300 Subject: [PATCH 02/14] [PE mobile] Added the ability to inser shapes --- .../mobile/src/controller/add/AddShape.jsx | 20 ++++++++++++++-- .../mobile/src/view/add/AddShape.jsx | 23 +++++++++++++++---- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/apps/presentationeditor/mobile/src/controller/add/AddShape.jsx b/apps/presentationeditor/mobile/src/controller/add/AddShape.jsx index bf649dc1d4..74d3cdd5df 100644 --- a/apps/presentationeditor/mobile/src/controller/add/AddShape.jsx +++ b/apps/presentationeditor/mobile/src/controller/add/AddShape.jsx @@ -3,15 +3,31 @@ import { f7 } from 'framework7-react'; import {Device} from '../../../../../common/mobile/utils/device'; import {observer, inject} from "mobx-react"; -import { AddShape } from '../../view/add/AddShape'; +import AddShape from '../../view/add/AddShape'; class AddShapeController extends Component { constructor (props) { super(props); + this.onShapeClick = this.onShapeClick.bind(this); } + + closeModal () { + if ( Device.phone ) { + f7.sheet.close('.add-popup', true); + } else { + f7.popover.close('#add-popover'); + } + } + + onShapeClick (type) { + const api = Common.EditorApi.get(); + api.AddShapeOnCurrentPage(type); + this.closeModal(); + } + render () { return ( - ) } diff --git a/apps/presentationeditor/mobile/src/view/add/AddShape.jsx b/apps/presentationeditor/mobile/src/view/add/AddShape.jsx index bf408d896b..e5910762b5 100644 --- a/apps/presentationeditor/mobile/src/view/add/AddShape.jsx +++ b/apps/presentationeditor/mobile/src/view/add/AddShape.jsx @@ -5,11 +5,26 @@ import { useTranslation } from 'react-i18next'; import {Device} from '../../../../../common/mobile/utils/device'; const AddShape = props => { + const shapes = props.storeShapeSettings.getStyleGroups(); return ( - - - +
+ {shapes.map((row, indexRow) => { + return ( +
    + {row.map((shape, index) => { + return ( +
  • {props.onShapeClick(shape.type)}}> +
    +
    +
  • + ) + })} +
+ ) + })} +
) }; -export {AddShape}; \ No newline at end of file +export default inject("storeShapeSettings")(observer(AddShape)); \ No newline at end of file From 63062620188b7285872fd7b6096a642f0108acd1 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Tue, 26 Jan 2021 15:50:09 +0300 Subject: [PATCH 03/14] [PE mobile] Added the ability to insert images --- apps/presentationeditor/mobile/locale/en.json | 12 +++- .../mobile/src/controller/add/AddImage.jsx | 59 +++++++++++++++++++ .../mobile/src/view/add/Add.jsx | 13 ++-- .../mobile/src/view/add/AddImage.jsx | 49 +++++++++++++++ 4 files changed, 128 insertions(+), 5 deletions(-) create mode 100644 apps/presentationeditor/mobile/src/controller/add/AddImage.jsx create mode 100644 apps/presentationeditor/mobile/src/view/add/AddImage.jsx diff --git a/apps/presentationeditor/mobile/locale/en.json b/apps/presentationeditor/mobile/locale/en.json index 50f54901ff..f73e3be1ce 100644 --- a/apps/presentationeditor/mobile/locale/en.json +++ b/apps/presentationeditor/mobile/locale/en.json @@ -77,7 +77,17 @@ "textSlide": "Slide", "textShape": "Shape", "textImage": "Image", - "textOther": "Other" + "textOther": "Other", + "textPictureFromLibrary": "Picture from Library", + "textPictureFromURL": "Picture from URL", + "textLinkSettings": "LinkSettings", + "textBack": "Back", + "textEmptyImgUrl": "You need to specify image URL.", + "txtNotUrl": "This field should be a URL in the format \"http://www.example.com\"", + "notcriticalErrorTitle": "Warning", + "textAddress": "Address", + "textImageURL": "Image URL", + "textInsertImage": "Insert Image" }, "Edit": { "textText": "Text", diff --git a/apps/presentationeditor/mobile/src/controller/add/AddImage.jsx b/apps/presentationeditor/mobile/src/controller/add/AddImage.jsx new file mode 100644 index 0000000000..4aafae09b1 --- /dev/null +++ b/apps/presentationeditor/mobile/src/controller/add/AddImage.jsx @@ -0,0 +1,59 @@ +import React, {Component} from 'react'; +import { f7 } from 'framework7-react'; +import {Device} from '../../../../../common/mobile/utils/device'; +import { withTranslation} from 'react-i18next'; + +import {AddImage} from '../../view/add/AddImage'; + +class AddImageController extends Component { + constructor (props) { + super(props); + this.onInsertByFile = this.onInsertByFile.bind(this); + this.onInsertByUrl = this.onInsertByUrl.bind(this); + } + + closeModal () { + if ( Device.phone ) { + f7.sheet.close('.add-popup', true); + } else { + f7.popover.close('#add-popover'); + } + } + + onInsertByFile () { + const api = Common.EditorApi.get(); + api.asc_addImage(); + this.closeModal(); + } + + onInsertByUrl (value) { + const { t } = this.props; + const _t = t("View.Add", { returnObjects: true }); + + const _value = value.replace(/ /g, ''); + + if (_value) { + if ((/((^https?)|(^ftp)):\/\/.+/i.test(_value))) { + this.closeModal(); + const api = Common.EditorApi.get(); + api.AddImageUrl(_value); + } else { + f7.dialog.alert(_t.txtNotUrl, _t.notcriticalErrorTitle); + } + } else { + f7.dialog.alert(_t.textEmptyImgUrl, _t.notcriticalErrorTitle); + } + } + + render () { + return ( + + ) + } +} + +const AddImageWithTranslation = withTranslation()(AddImageController); + +export {AddImageWithTranslation as AddImageController}; \ No newline at end of file diff --git a/apps/presentationeditor/mobile/src/view/add/Add.jsx b/apps/presentationeditor/mobile/src/view/add/Add.jsx index 07d98fa646..7e91fbc50b 100644 --- a/apps/presentationeditor/mobile/src/view/add/Add.jsx +++ b/apps/presentationeditor/mobile/src/view/add/Add.jsx @@ -7,11 +7,16 @@ import {Device} from '../../../../../common/mobile/utils/device'; import AddSlideController from "../../controller/add/AddSlide"; import AddShapeController from "../../controller/add/AddShape"; -//import AddImageController from "../../controller/add/AddImage"; +import {AddImageController} from "../../controller/add/AddImage"; +import {PageImageLinkSettings} from "./AddImage"; //import AddOtherController from "../../controller/add/AddOther"; const routes = [ - + // Image + { + path: '/add-image-from-url/', + component: PageImageLinkSettings + } ]; const AddLayoutNavbar = ({ tabs, inPopover }) => { @@ -58,13 +63,13 @@ const AddTabs = props => { icon: 'icon-add-shape', component: }); - /*tabs.push({ + tabs.push({ caption: _t.textImage, id: 'add-image', icon: 'icon-add-image', component: }); - tabs.push({ + /*tabs.push({ caption: _t.textOther, id: 'add-other', icon: 'icon-add-other', diff --git a/apps/presentationeditor/mobile/src/view/add/AddImage.jsx b/apps/presentationeditor/mobile/src/view/add/AddImage.jsx new file mode 100644 index 0000000000..f25c979df9 --- /dev/null +++ b/apps/presentationeditor/mobile/src/view/add/AddImage.jsx @@ -0,0 +1,49 @@ +import React, {useState} from 'react'; +import {observer, inject} from "mobx-react"; +import {List, ListItem, Page, Navbar, Icon, ListButton, ListInput, BlockTitle} from 'framework7-react'; +import { useTranslation } from 'react-i18next'; + +const PageLinkSettings = props => { + const { t } = useTranslation(); + const _t = t('View.Add', {returnObjects: true}); + const [stateValue, setValue] = useState(''); + return ( + + + {_t.textAddress} + + {setValue(event.target.value)}} + > + + + + {props.onInsertByUrl(stateValue)}}> + + + ) +}; + +const AddImage = props => { + const { t } = useTranslation(); + const _t = t('View.Add', {returnObjects: true}); + return ( + + {props.onInsertByFile()}}> + + + + + + + ) +}; + +export {AddImage, PageLinkSettings as PageImageLinkSettings}; \ No newline at end of file From 89eff1f6b81e22aeed2b467b0f3b8fb9c00bb314 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Tue, 26 Jan 2021 20:09:40 +0300 Subject: [PATCH 04/14] [PE mobile] Added the ability to insert tables --- .../mobile/resources/less/common-ios.less | 2 +- apps/presentationeditor/mobile/locale/en.json | 8 +- .../mobile/src/controller/Main.jsx | 8 +- .../mobile/src/controller/add/AddOther.jsx | 102 ++++++++++++++++++ .../mobile/src/store/mainStore.js | 6 +- .../mobile/src/store/tableSettings.js | 21 ++++ .../mobile/src/view/add/Add.jsx | 12 ++- .../mobile/src/view/add/AddOther.jsx | 54 ++++++++++ 8 files changed, 204 insertions(+), 9 deletions(-) create mode 100644 apps/presentationeditor/mobile/src/controller/add/AddOther.jsx create mode 100644 apps/presentationeditor/mobile/src/store/tableSettings.js create mode 100644 apps/presentationeditor/mobile/src/view/add/AddOther.jsx diff --git a/apps/common/mobile/resources/less/common-ios.less b/apps/common/mobile/resources/less/common-ios.less index c4e29da777..ed0a5d46e6 100644 --- a/apps/common/mobile/resources/less/common-ios.less +++ b/apps/common/mobile/resources/less/common-ios.less @@ -367,7 +367,7 @@ } .dataview, #add-table, #add-shape, #add-slide { - &.page-content { + &.page-content, .page-content { background-color: @white; } } diff --git a/apps/presentationeditor/mobile/locale/en.json b/apps/presentationeditor/mobile/locale/en.json index f73e3be1ce..bae19375cb 100644 --- a/apps/presentationeditor/mobile/locale/en.json +++ b/apps/presentationeditor/mobile/locale/en.json @@ -87,7 +87,13 @@ "notcriticalErrorTitle": "Warning", "textAddress": "Address", "textImageURL": "Image URL", - "textInsertImage": "Insert Image" + "textInsertImage": "Insert Image", + "textTable": "Table", + "textComment": "Comment", + "textTableSize": "Table Size", + "textColumns": "Columns", + "textRows": "Rows", + "textCancel": "Cancel" }, "Edit": { "textText": "Text", diff --git a/apps/presentationeditor/mobile/src/controller/Main.jsx b/apps/presentationeditor/mobile/src/controller/Main.jsx index 40c892ac14..5633a9f893 100644 --- a/apps/presentationeditor/mobile/src/controller/Main.jsx +++ b/apps/presentationeditor/mobile/src/controller/Main.jsx @@ -5,7 +5,7 @@ import { f7 } from "framework7-react"; import { withTranslation } from 'react-i18next'; import CollaborationController from '../../../../common/mobile/lib/controller/Collaboration.jsx' -@inject("storeFocusObjects", "storeAppOptions", "storePresentationInfo", "storePresentationSettings", "storeSlideSettings", "storeTextSettings") +@inject("storeFocusObjects", "storeAppOptions", "storePresentationInfo", "storePresentationSettings", "storeSlideSettings", "storeTextSettings", "storeTableSettings") class MainController extends Component { constructor(props) { super(props) @@ -298,6 +298,12 @@ class MainController extends Component { this.api.asc_registerCallback('asc_onParaSpacingLine', (vc) => { storeTextSettings.resetLineSpacing(vc); }); + + //table settings + const storeTableSettings = this.props.storeTableSettings; + this.api.asc_registerCallback('asc_onInitTableTemplates', (templates) => { + storeTableSettings.initTableTemplates(templates); + }); } _onDocumentContentReady() { diff --git a/apps/presentationeditor/mobile/src/controller/add/AddOther.jsx b/apps/presentationeditor/mobile/src/controller/add/AddOther.jsx new file mode 100644 index 0000000000..e2838493e9 --- /dev/null +++ b/apps/presentationeditor/mobile/src/controller/add/AddOther.jsx @@ -0,0 +1,102 @@ +import React, {Component} from 'react'; +import { f7 } from 'framework7-react'; +import {Device} from '../../../../../common/mobile/utils/device'; +import { withTranslation} from 'react-i18next'; + +import {AddOther} from '../../view/add/AddOther'; + +class AddOtherController extends Component { + constructor (props) { + super(props); + this.onStyleClick = this.onStyleClick.bind(this); + this.initStyleTable = this.initStyleTable.bind(this); + + this.initTable = false; + } + + closeModal () { + if ( Device.phone ) { + f7.sheet.close('.add-popup', true); + } else { + f7.popover.close('#add-popover'); + } + } + + initStyleTable () { + if (!this.initTable) { + const api = Common.EditorApi.get(); + api.asc_GetDefaultTableStyles(); + this.initTable = true; + } + } + + onStyleClick (type) { + const api = Common.EditorApi.get(); + + this.closeModal(); + + const { t } = this.props; + const _t = t("View.Add", { returnObjects: true }); + + let picker; + + const dialog = f7.dialog.create({ + title: _t.textTableSize, + text: '', + content: + '
' + + '
' + + '
' + _t.textColumns + '
' + + '
' + _t.textRows + '
' + + '
' + + '
' + + '
', + buttons: [ + { + text: _t.textCancel + }, + { + text: 'OK', + bold: true, + onClick: function () { + const size = picker.value; + + api.put_Table(parseInt(size[0]), parseInt(size[1]), undefined, type.toString()); + } + } + ] + }).open(); + dialog.on('opened', () => { + picker = f7.picker.create({ + containerEl: document.getElementById('picker-table-size'), + cols: [ + { + textAlign: 'center', + width: '100%', + values: [1,2,3,4,5,6,7,8,9,10] + }, + { + textAlign: 'center', + width: '100%', + values: [1,2,3,4,5,6,7,8,9,10] + } + ], + toolbar: false, + rotateEffect: true, + value: [3, 3] + }); + }); + } + + render () { + return ( + + ) + } +} + +const AddOtherWithTranslation = withTranslation()(AddOtherController); + +export {AddOtherWithTranslation as AddOtherController}; \ No newline at end of file diff --git a/apps/presentationeditor/mobile/src/store/mainStore.js b/apps/presentationeditor/mobile/src/store/mainStore.js index e379be9395..078711d47f 100644 --- a/apps/presentationeditor/mobile/src/store/mainStore.js +++ b/apps/presentationeditor/mobile/src/store/mainStore.js @@ -14,7 +14,7 @@ import { storeShapeSettings } from './shapeSettings'; // import {storeParagraphSettings} from "./paragraphSettings"; // import {storeShapeSettings} from "./shapeSettings"; // import {storeImageSettings} from "./imageSettings"; -// import {storeTableSettings} from "./tableSettings"; +import {storeTableSettings} from "./tableSettings"; // import {storeChartSettings} from "./chartSettings"; export const stores = { @@ -28,11 +28,11 @@ export const stores = { storeSlideSettings: new storeSlideSettings(), storePalette: new storePalette(), storeTextSettings: new storeTextSettings(), - storeShapeSettings: new storeShapeSettings() + storeShapeSettings: new storeShapeSettings(), // storeTextSettings: new storeTextSettings(), // storeParagraphSettings: new storeParagraphSettings(), // storeShapeSettings: new storeShapeSettings(), // storeChartSettings: new storeChartSettings(), - // storeTableSettings: new storeTableSettings() + storeTableSettings: new storeTableSettings() }; diff --git a/apps/presentationeditor/mobile/src/store/tableSettings.js b/apps/presentationeditor/mobile/src/store/tableSettings.js new file mode 100644 index 0000000000..3e8f23f30f --- /dev/null +++ b/apps/presentationeditor/mobile/src/store/tableSettings.js @@ -0,0 +1,21 @@ +import {action, observable, computed} from 'mobx'; +import {f7} from 'framework7-react'; + +export class storeTableSettings { + @observable _templates = []; + + @action initTableTemplates(templates) { + this._templates = templates; + } + + @computed get styles() { + let styles = []; + for (let template of this._templates) { + styles.push({ + imageUrl: template.asc_getImage(), + templateId: template.asc_getId() + }); + } + return styles; + } +} \ No newline at end of file diff --git a/apps/presentationeditor/mobile/src/view/add/Add.jsx b/apps/presentationeditor/mobile/src/view/add/Add.jsx index 7e91fbc50b..4adc94947f 100644 --- a/apps/presentationeditor/mobile/src/view/add/Add.jsx +++ b/apps/presentationeditor/mobile/src/view/add/Add.jsx @@ -9,13 +9,19 @@ import AddSlideController from "../../controller/add/AddSlide"; import AddShapeController from "../../controller/add/AddShape"; import {AddImageController} from "../../controller/add/AddImage"; import {PageImageLinkSettings} from "./AddImage"; -//import AddOtherController from "../../controller/add/AddOther"; +import {AddOtherController} from "../../controller/add/AddOther"; +import {PageAddTable} from "./AddOther"; const routes = [ // Image { path: '/add-image-from-url/', component: PageImageLinkSettings + }, + // Other + { + path: '/add-table/', + component: PageAddTable } ]; @@ -69,12 +75,12 @@ const AddTabs = props => { icon: 'icon-add-image', component: }); - /*tabs.push({ + tabs.push({ caption: _t.textOther, id: 'add-other', icon: 'icon-add-other', component: - });*/ + }); return ( diff --git a/apps/presentationeditor/mobile/src/view/add/AddOther.jsx b/apps/presentationeditor/mobile/src/view/add/AddOther.jsx new file mode 100644 index 0000000000..f0a016b1e2 --- /dev/null +++ b/apps/presentationeditor/mobile/src/view/add/AddOther.jsx @@ -0,0 +1,54 @@ +import React, {useState} from 'react'; +import {observer, inject} from "mobx-react"; +import {List, ListItem, Page, Navbar, Icon, ListButton, ListInput, BlockTitle, Segmented, Button} from 'framework7-react'; +import { useTranslation } from 'react-i18next'; +import {Device} from "../../../../../common/mobile/utils/device"; + +const PageTable = props => { + props.initStyleTable(); + const { t } = useTranslation(); + const _t = t('View.Add', {returnObjects: true}); + const storeTableSettings = props.storeTableSettings; + const styles = storeTableSettings.styles; + return ( + + +
+
    + {styles.map((style, index) => { + return ( +
  • {props.onStyleClick(style.templateId)}}> + +
  • + ) + })} +
+
+
+ ) +}; + + +const AddOther = props => { + const { t } = useTranslation(); + const _t = t('View.Add', {returnObjects: true}); + return ( + + + + + + + + + ) +}; + +const PageAddTable = inject("storeTableSettings")(observer(PageTable)); + +export {AddOther, + PageAddTable}; \ No newline at end of file From cae686188fca26e400dfe9773ea2aa124538be74 Mon Sep 17 00:00:00 2001 From: Maxim Kadushkin Date: Wed, 27 Jan 2021 16:36:16 +0300 Subject: [PATCH 05/14] [DE mobile] renamed Search view --- .../documenteditor/mobile/src/view/Search.jsx | 13 +- .../documenteditor/mobile/src/view/search.jsx | 116 ------------------ 2 files changed, 11 insertions(+), 118 deletions(-) delete mode 100644 apps/documenteditor/mobile/src/view/search.jsx diff --git a/apps/documenteditor/mobile/src/view/Search.jsx b/apps/documenteditor/mobile/src/view/Search.jsx index c5c01ac652..f7ddd46093 100644 --- a/apps/documenteditor/mobile/src/view/Search.jsx +++ b/apps/documenteditor/mobile/src/view/Search.jsx @@ -1,5 +1,6 @@ import React, { Component } from 'react'; import { Searchbar, Popover, Popup, View, Page, List, ListItem, Navbar, NavRight, Link } from 'framework7-react'; +import { Toggle } from 'framework7-react'; import { f7ready, f7 } from 'framework7-react'; import { Device } from '../../../../common/mobile/utils/device'; @@ -38,8 +39,16 @@ class SearchSettingsView extends Component { {navbar} - this.onFindReplaceClick('find')}> - this.onFindReplaceClick('replace')}> + this.onFindReplaceClick('find')} /> + this.onFindReplaceClick('replace')} /> + + + + + + + +
; diff --git a/apps/documenteditor/mobile/src/view/search.jsx b/apps/documenteditor/mobile/src/view/search.jsx deleted file mode 100644 index c5c01ac652..0000000000 --- a/apps/documenteditor/mobile/src/view/search.jsx +++ /dev/null @@ -1,116 +0,0 @@ -import React, { Component } from 'react'; -import { Searchbar, Popover, Popup, View, Page, List, ListItem, Navbar, NavRight, Link } from 'framework7-react'; -import { f7ready, f7 } from 'framework7-react'; -import { Device } from '../../../../common/mobile/utils/device'; - -const popoverStyle = { - height: '300px' -}; - -class SearchSettingsView extends Component { - constructor(props) { - super(props); - - this.state = { - useReplace: false, - caseSensitive: false, - markResults: false - }; - } - - onFindReplaceClick(action) { - this.setState({ - useReplace: action == 'replace' - }); - } - - render() { - const show_popover = true; - const navbar = - - {!show_popover && - - Done - } - ; - const content = - - - {navbar} - - this.onFindReplaceClick('find')}> - this.onFindReplaceClick('replace')}> - - - ; - return ( - show_popover ? - {content} : - {content} - ) - } -} - -class SearchView extends Component { - constructor(props) { - super(props); - - $$(document).on('page:init', (e, page) => { - if ( page.name == 'home' ) { - f7.searchbar.create({ - el: '.searchbar', - customSearch: true, - expandable: true, - backdrop: false, - on: { - search: (bar, curval, prevval) => { - console.log('on search results ' + curval); - } - } - }); - } - }); - - this.onSettingsClick = this.onSettingsClick.bind(this); - } - - componentDidMount(){ - } - - onSettingsClick(e) { - if ( Device.phone ) { - // f7.popup.open('.settings-popup'); - } else f7.popover.open('#idx-search-settings', '#idx-btn-search-settings'); - } - - render() { - return ( -
-
-
-
- - - -
-
- - - -
- - Cancel -
- - ) - } -} - -export {SearchView as default, SearchSettingsView}; From defbbe6e9473dfdc94f4caecb0304621349e61c9 Mon Sep 17 00:00:00 2001 From: Maxim Kadushkin Date: Wed, 27 Jan 2021 16:37:00 +0300 Subject: [PATCH 06/14] [common] changed popover stylesheet --- .../mobile/resources/less/common-ios.less | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/apps/common/mobile/resources/less/common-ios.less b/apps/common/mobile/resources/less/common-ios.less index ed0a5d46e6..b153c61c51 100644 --- a/apps/common/mobile/resources/less/common-ios.less +++ b/apps/common/mobile/resources/less/common-ios.less @@ -153,14 +153,24 @@ } } - .popover li:last-child { - .segmented a { - &:first-child { - border-radius: var(--f7-button-border-radius) 0 0 var(--f7-button-border-radius); - } + .popover { + li:last-child { + .segmented a { + &:first-child { + border-radius: var(--f7-button-border-radius) 0 0 var(--f7-button-border-radius); + } - &:last-child { - border-radius: 0 var(--f7-button-border-radius) var(--f7-button-border-radius) 0; + &:last-child { + border-radius: 0 var(--f7-button-border-radius) var(--f7-button-border-radius) 0; + } + } + } + + .page-content { + > .list { + &:last-child { + margin-bottom: 30px; + } } } } From 962468fb83a3b67e0bb5fab1f5f7abf4dcb5051e Mon Sep 17 00:00:00 2001 From: Maxim Kadushkin Date: Wed, 27 Jan 2021 16:38:13 +0300 Subject: [PATCH 07/14] [SSE mobile] added common stylesheets file --- apps/common/mobile/resources/less/variables.less | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 apps/common/mobile/resources/less/variables.less diff --git a/apps/common/mobile/resources/less/variables.less b/apps/common/mobile/resources/less/variables.less new file mode 100644 index 0000000000..2ba2c9402e --- /dev/null +++ b/apps/common/mobile/resources/less/variables.less @@ -0,0 +1,3 @@ + +@border-regular-control: #cbcbcb; +@text-normal: #000; From f51607830a2b0dba52a644776295c8901f979332 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Wed, 27 Jan 2021 19:24:29 +0300 Subject: [PATCH 08/14] [SSE mobile] Added insert popover/popup --- apps/spreadsheeteditor/mobile/locale/en.json | 8 ++ .../mobile/src/controller/add/AddChart.jsx | 28 ++++ .../mobile/src/controller/add/AddFormula.jsx | 28 ++++ .../mobile/src/less/icons-ios.less | 2 +- .../mobile/src/page/main.jsx | 27 ++-- .../mobile/src/view/add/Add.jsx | 122 ++++++++++++++++++ .../mobile/src/view/add/AddChart.jsx | 12 ++ .../mobile/src/view/add/AddFormula.jsx | 12 ++ 8 files changed, 228 insertions(+), 11 deletions(-) create mode 100644 apps/spreadsheeteditor/mobile/src/controller/add/AddChart.jsx create mode 100644 apps/spreadsheeteditor/mobile/src/controller/add/AddFormula.jsx create mode 100644 apps/spreadsheeteditor/mobile/src/view/add/Add.jsx create mode 100644 apps/spreadsheeteditor/mobile/src/view/add/AddChart.jsx create mode 100644 apps/spreadsheeteditor/mobile/src/view/add/AddFormula.jsx diff --git a/apps/spreadsheeteditor/mobile/locale/en.json b/apps/spreadsheeteditor/mobile/locale/en.json index 4a18434f1c..dd3001b6b6 100644 --- a/apps/spreadsheeteditor/mobile/locale/en.json +++ b/apps/spreadsheeteditor/mobile/locale/en.json @@ -5,5 +5,13 @@ }, "textAnonymous": "Anonymous" } + }, + "View" : { + "Add" : { + "textChart": "Chart", + "textFormula": "Formula", + "textShape": "Shape", + "textOther": "Other" + } } } diff --git a/apps/spreadsheeteditor/mobile/src/controller/add/AddChart.jsx b/apps/spreadsheeteditor/mobile/src/controller/add/AddChart.jsx new file mode 100644 index 0000000000..5e69d6d853 --- /dev/null +++ b/apps/spreadsheeteditor/mobile/src/controller/add/AddChart.jsx @@ -0,0 +1,28 @@ +import React, {Component} from 'react'; +import { f7 } from 'framework7-react'; +import {Device} from '../../../../../common/mobile/utils/device'; + +import AddChart from '../../view/add/AddChart'; + +class AddChartController extends Component { + constructor (props) { + super(props); + } + + closeModal () { + if ( Device.phone ) { + f7.sheet.close('.add-popup', true); + } else { + f7.popover.close('#add-popover'); + } + } + + render () { + return ( + + ) + } +} + +export default AddChartController; \ No newline at end of file diff --git a/apps/spreadsheeteditor/mobile/src/controller/add/AddFormula.jsx b/apps/spreadsheeteditor/mobile/src/controller/add/AddFormula.jsx new file mode 100644 index 0000000000..46959e5c29 --- /dev/null +++ b/apps/spreadsheeteditor/mobile/src/controller/add/AddFormula.jsx @@ -0,0 +1,28 @@ +import React, {Component} from 'react'; +import { f7 } from 'framework7-react'; +import {Device} from '../../../../../common/mobile/utils/device'; + +import AddFormula from '../../view/add/AddFormula'; + +class AddFormulaController extends Component { + constructor (props) { + super(props); + } + + closeModal () { + if ( Device.phone ) { + f7.sheet.close('.add-popup', true); + } else { + f7.popover.close('#add-popover'); + } + } + + render () { + return ( + + ) + } +} + +export default AddFormulaController; \ No newline at end of file diff --git a/apps/spreadsheeteditor/mobile/src/less/icons-ios.less b/apps/spreadsheeteditor/mobile/src/less/icons-ios.less index 36cb30894f..ec61398a84 100644 --- a/apps/spreadsheeteditor/mobile/src/less/icons-ios.less +++ b/apps/spreadsheeteditor/mobile/src/less/icons-ios.less @@ -475,7 +475,7 @@ } } - .active { + .tab-link-active { i.icon { &.icon-add-chart { width: 24px; diff --git a/apps/spreadsheeteditor/mobile/src/page/main.jsx b/apps/spreadsheeteditor/mobile/src/page/main.jsx index 0d648d5223..d5db591300 100644 --- a/apps/spreadsheeteditor/mobile/src/page/main.jsx +++ b/apps/spreadsheeteditor/mobile/src/page/main.jsx @@ -6,12 +6,14 @@ import Settings from '../view/settings/Settings'; import CollaborationView from '../../../../common/mobile/lib/view/Collaboration.jsx' import CellEditor from '../controller/CellEditor'; import Statusbar from '../controller/StatusBar' +import AddOptions from "../view/add/Add"; export default class MainPage extends Component { constructor(props) { super(props); this.state = { editOptionsVisible: false, + addOptionsVisible: false, settingsVisible: false, collaborationVisible: false, }; @@ -21,12 +23,12 @@ export default class MainPage extends Component { this.setState(state => { if ( opts == 'edit' ) return {editOptionsVisible: true}; - else - if ( opts == 'settings' ) + else if ( opts == 'add' ) + return {addOptionsVisible: true}; + else if ( opts == 'settings' ) return {settingsVisible: true}; - else - if ( opts == 'coauth' ) - return {collaborationVisible: true} + else if ( opts == 'coauth' ) + return {collaborationVisible: true}; }); }; @@ -35,12 +37,12 @@ export default class MainPage extends Component { await 1 && this.setState(state => { if ( opts == 'edit' ) return {editOptionsVisible: false}; - else - if ( opts == 'settings' ) + else if ( opts == 'add' ) + return {addOptionsVisible: false}; + else if ( opts == 'settings' ) return {settingsVisible: false}; - else - if ( opts == 'coauth' ) - return {collaborationVisible: false} + else if ( opts == 'coauth' ) + return {collaborationVisible: false}; }) })(); }; @@ -57,6 +59,7 @@ export default class MainPage extends Component { this.handleClickToOpenOptions('edit')}> + this.handleClickToOpenOptions('add')}> this.handleClickToOpenOptions('coauth')}> this.handleClickToOpenOptions('settings')}> @@ -68,6 +71,10 @@ export default class MainPage extends Component { {/*!this.state.editOptionsVisible ? null :*/} {/**/} {/*}*/} + { + !this.state.addOptionsVisible ? null : + + } { !this.state.settingsVisible ? null : diff --git a/apps/spreadsheeteditor/mobile/src/view/add/Add.jsx b/apps/spreadsheeteditor/mobile/src/view/add/Add.jsx new file mode 100644 index 0000000000..619b8983ad --- /dev/null +++ b/apps/spreadsheeteditor/mobile/src/view/add/Add.jsx @@ -0,0 +1,122 @@ +import React, {Component, useEffect} from 'react'; +import {View,Page,Navbar,NavRight,Link,Popup,Popover,Icon,Tabs,Tab} from 'framework7-react'; +import { useTranslation } from 'react-i18next'; +import {f7} from 'framework7-react'; +import { observer, inject } from "mobx-react"; +import {Device} from '../../../../../common/mobile/utils/device'; + +import AddChartController from "../../controller/add/AddChart"; +import AddFormulaController from "../../controller/add/AddFormula"; +//import AddShapeController from "../../controller/add/AddShape"; +//import {AddOtherController} from "../../controller/add/AddOther"; + +const routes = [ +]; + +const AddLayoutNavbar = ({ tabs, inPopover }) => { + const isAndroid = Device.android; + return ( + +
+ {tabs.map((item, index) => + + + )} + {isAndroid && } +
+ { !inPopover && } +
+ ) +}; + +const AddLayoutContent = ({ tabs }) => { + return ( + + {tabs.map((item, index) => + + {item.component} + + )} + + ) +}; + +const AddTabs = props => { + const { t } = useTranslation(); + const _t = t('Add', {returnObjects: true}); + const tabs = []; + tabs.push({ + caption: _t.textChart, + id: 'add-chart', + icon: 'icon-add-chart', + component: + }); + tabs.push({ + caption: _t.textFormula, + id: 'add-formula', + icon: 'icon-add-formula', + component: + }); + /*tabs.push({ + caption: _t.textShape, + id: 'add-shape', + icon: 'icon-add-shape', + component: + }); + tabs.push({ + caption: _t.textOther, + id: 'add-other', + icon: 'icon-add-other', + component: + });*/ + return ( + + + + + + + ) +}; + +class AddView extends Component { + constructor(props) { + super(props); + + this.onoptionclick = this.onoptionclick.bind(this); + } + onoptionclick(page){ + f7.views.current.router.navigate(page); + } + render() { + const show_popover = this.props.usePopover; + return ( + show_popover ? + this.props.onclosed()}> + + : + this.props.onclosed()}> + + + ) + } +} + +const Add = props => { + useEffect(() => { + if ( Device.phone ) + f7.popup.open('.add-popup'); + else f7.popover.open('#add-popover', '#btn-add'); + + return () => { + // component will unmount + } + }); + const onviewclosed = () => { + if ( props.onclosed ) + props.onclosed(); + }; + return +}; + +export default Add; \ No newline at end of file diff --git a/apps/spreadsheeteditor/mobile/src/view/add/AddChart.jsx b/apps/spreadsheeteditor/mobile/src/view/add/AddChart.jsx new file mode 100644 index 0000000000..8eec1a782e --- /dev/null +++ b/apps/spreadsheeteditor/mobile/src/view/add/AddChart.jsx @@ -0,0 +1,12 @@ +import React, {Fragment, useState} from 'react'; +import {observer, inject} from "mobx-react"; + +const AddChart = props => { + return ( + + + + ) +}; + +export default AddChart; \ No newline at end of file diff --git a/apps/spreadsheeteditor/mobile/src/view/add/AddFormula.jsx b/apps/spreadsheeteditor/mobile/src/view/add/AddFormula.jsx new file mode 100644 index 0000000000..b8272b828e --- /dev/null +++ b/apps/spreadsheeteditor/mobile/src/view/add/AddFormula.jsx @@ -0,0 +1,12 @@ +import React, {Fragment, useState} from 'react'; +import {observer, inject} from "mobx-react"; + +const AddFormula = props => { + return ( + + + + ) +}; + +export default AddFormula; \ No newline at end of file From 711cea9e3eb52913edaea30696feb607f8fe8d3c Mon Sep 17 00:00:00 2001 From: Maxim Kadushkin Date: Thu, 28 Jan 2021 13:27:18 +0300 Subject: [PATCH 09/14] [common] Searchbar moved to common --- .../mobile/lib}/controller/Search.jsx | 7 ++- .../src => common/mobile/lib}/view/Search.jsx | 56 +++++++++++++++++-- apps/common/mobile/resources/less/search.less | 4 ++ apps/documenteditor/mobile/src/page/main.jsx | 2 +- 4 files changed, 61 insertions(+), 8 deletions(-) rename apps/{documenteditor/mobile/src => common/mobile/lib}/controller/Search.jsx (57%) rename apps/{documenteditor/mobile/src => common/mobile/lib}/view/Search.jsx (71%) diff --git a/apps/documenteditor/mobile/src/controller/Search.jsx b/apps/common/mobile/lib/controller/Search.jsx similarity index 57% rename from apps/documenteditor/mobile/src/controller/Search.jsx rename to apps/common/mobile/lib/controller/Search.jsx index 6c662c5f3c..610ce2facd 100644 --- a/apps/documenteditor/mobile/src/controller/Search.jsx +++ b/apps/common/mobile/lib/controller/Search.jsx @@ -1,8 +1,13 @@ import React from 'react'; import SearchView, {SearchSettingsView} from '../view/Search' + const SearchController = props => { - return + const _onSearchQuery = params => { + console.log('on search: ' + params); + }; + + return }; export {SearchController as Search, SearchSettingsView as SearchSettings}; diff --git a/apps/documenteditor/mobile/src/view/Search.jsx b/apps/common/mobile/lib/view/Search.jsx similarity index 71% rename from apps/documenteditor/mobile/src/view/Search.jsx rename to apps/common/mobile/lib/view/Search.jsx index f7ddd46093..e896f80e16 100644 --- a/apps/documenteditor/mobile/src/view/Search.jsx +++ b/apps/common/mobile/lib/view/Search.jsx @@ -1,8 +1,15 @@ import React, { Component } from 'react'; import { Searchbar, Popover, Popup, View, Page, List, ListItem, Navbar, NavRight, Link } from 'framework7-react'; import { Toggle } from 'framework7-react'; -import { f7ready, f7 } from 'framework7-react'; +import { f7 } from 'framework7-react'; +import { Dom7 } from 'framework7'; import { Device } from '../../../../common/mobile/utils/device'; +import { observable } from "mobx"; +import { observer } from "mobx-react"; + +const searchOptions = observable({ + usereplace: false +}); const popoverStyle = { height: '300px' @@ -20,9 +27,13 @@ class SearchSettingsView extends Component { } onFindReplaceClick(action) { + searchOptions.usereplace = action == 'replace'; this.setState({ - useReplace: action == 'replace' + useReplace: searchOptions.usereplace }); + + + if (this.onReplaceChecked) {} } render() { @@ -60,20 +71,20 @@ class SearchSettingsView extends Component { } } +@observer class SearchView extends Component { constructor(props) { super(props); $$(document).on('page:init', (e, page) => { if ( page.name == 'home' ) { - f7.searchbar.create({ + this.searchbar = f7.searchbar.create({ el: '.searchbar', customSearch: true, expandable: true, backdrop: false, on: { search: (bar, curval, prevval) => { - console.log('on search results ' + curval); } } }); @@ -81,9 +92,12 @@ class SearchView extends Component { }); this.onSettingsClick = this.onSettingsClick.bind(this); + this.onSearchClick = this.onSearchClick.bind(this); } componentDidMount(){ + const $$ = Dom7; + this.$repalce = $$('#idx-replace-val'); } onSettingsClick(e) { @@ -92,7 +106,32 @@ class SearchView extends Component { } else f7.popover.open('#idx-search-settings', '#idx-btn-search-settings'); } + searchParams() { + let params = { + text: this.searchbar.query, + direction: action + }; + } + + onSearchClick(action) { + if ( this.searchbar && this.searchbar.query) { + if ( this.props.onSearchQuery ) { + let params = { + text: this.searchbar.query, + direction: action + }; + + if ( searchOptions.usereplace ) + params.replace = this.$replace.val(); + + this.props.onSearchQuery(params); + } + } + } + render() { + const usereplace = searchOptions.usereplace; + const hidden = {display: "none"}; return (
@@ -107,11 +146,16 @@ class SearchView extends Component { +
+ + + +
diff --git a/apps/common/mobile/resources/less/search.less b/apps/common/mobile/resources/less/search.less index ab694cea8d..21249b9414 100644 --- a/apps/common/mobile/resources/less/search.less +++ b/apps/common/mobile/resources/less/search.less @@ -13,4 +13,8 @@ .hairline(bottom, @statusBarBorderColor); } } + + .searchbar-input-wrap { + margin-right: 10px; + } } diff --git a/apps/documenteditor/mobile/src/page/main.jsx b/apps/documenteditor/mobile/src/page/main.jsx index 86b1996de3..fc9d05cc2e 100644 --- a/apps/documenteditor/mobile/src/page/main.jsx +++ b/apps/documenteditor/mobile/src/page/main.jsx @@ -6,7 +6,7 @@ import AddOptions from '../view/add/Add'; import Settings from '../view/settings/Settings'; import CollaborationView from '../../../../common/mobile/lib/view/Collaboration.jsx' import { Device } from '../../../../common/mobile/utils/device' -import { Search, SearchSettings } from '../controller/Search'; +import { Search, SearchSettings } from '../../../../common/mobile/lib/controller/Search'; export default class MainPage extends Component { constructor(props) { From 273ef21d44c92f4751971bbab72090641a355fac Mon Sep 17 00:00:00 2001 From: Maxim Kadushkin Date: Thu, 28 Jan 2021 13:27:56 +0300 Subject: [PATCH 10/14] [DE mobile] refactoring --- .../src/view/settings/ApplicationSettings.jsx | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/apps/documenteditor/mobile/src/view/settings/ApplicationSettings.jsx b/apps/documenteditor/mobile/src/view/settings/ApplicationSettings.jsx index 9a3a800600..9561950344 100644 --- a/apps/documenteditor/mobile/src/view/settings/ApplicationSettings.jsx +++ b/apps/documenteditor/mobile/src/view/settings/ApplicationSettings.jsx @@ -39,8 +39,7 @@ const PageApplicationSettings = props => { onChange={() => changeMeasureSettings(2)}> - - {_t.textSpellcheck} + { store.changeSpellCheck(!isSpellChecking); @@ -50,8 +49,7 @@ const PageApplicationSettings = props => { - {/*ToDo: if (DisplayMode == "final" || DisplayMode == "original") {disabled} */} - {_t.textNoCharacters} + {/*ToDo: if (DisplayMode == "final" || DisplayMode == "original") {disabled} */} { store.changeNoCharacters(!isNonprintingCharacters); @@ -59,8 +57,7 @@ const PageApplicationSettings = props => { }} /> - {/*ToDo: if (DisplayMode == "final" || DisplayMode == "original") {disabled} */} - {_t.textHiddenTableBorders} + {/*ToDo: if (DisplayMode == "final" || DisplayMode == "original") {disabled} */} { store.changeShowTableEmptyLine(!isHiddenTableBorders); @@ -73,17 +70,15 @@ const PageApplicationSettings = props => { } {_t.textCommentsDisplay} - - {_t.textComments} - + { store.changeDisplayComments(!isComments); props.switchDisplayComments(!isComments); }} /> - - {_t.textResolvedComments} + { store.changeDisplayResolved(!isResolvedComments); From 6c95a26e76f0d1cf12daee75e659b18fc4a95c36 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Thu, 28 Jan 2021 14:45:38 +0300 Subject: [PATCH 11/14] [SSE mobile] Added edit popover/sheet --- apps/spreadsheeteditor/mobile/locale/en.json | 5 + .../mobile/src/controller/Main.jsx | 9 ++ .../mobile/src/controller/edit/EditCell.jsx | 20 +++ .../mobile/src/page/main.jsx | 9 +- .../mobile/src/store/focusObjects.js | 138 ++++++++++++++++++ .../mobile/src/store/mainStore.js | 4 +- .../mobile/src/view/edit/Edit.jsx | 138 ++++++++++++++++++ .../mobile/src/view/edit/EditCell.jsx | 12 ++ 8 files changed, 329 insertions(+), 6 deletions(-) create mode 100644 apps/spreadsheeteditor/mobile/src/controller/edit/EditCell.jsx create mode 100644 apps/spreadsheeteditor/mobile/src/store/focusObjects.js create mode 100644 apps/spreadsheeteditor/mobile/src/view/edit/Edit.jsx create mode 100644 apps/spreadsheeteditor/mobile/src/view/edit/EditCell.jsx diff --git a/apps/spreadsheeteditor/mobile/locale/en.json b/apps/spreadsheeteditor/mobile/locale/en.json index dd3001b6b6..f7c5fa5cd7 100644 --- a/apps/spreadsheeteditor/mobile/locale/en.json +++ b/apps/spreadsheeteditor/mobile/locale/en.json @@ -12,6 +12,11 @@ "textFormula": "Formula", "textShape": "Shape", "textOther": "Other" + }, + "Edit" : { + "textSelectObjectToEdit": "Select object to edit", + "textSettings": "Settings", + "textCell": "Cell" } } } diff --git a/apps/spreadsheeteditor/mobile/src/controller/Main.jsx b/apps/spreadsheeteditor/mobile/src/controller/Main.jsx index 3aa5693cd9..0a28824c78 100644 --- a/apps/spreadsheeteditor/mobile/src/controller/Main.jsx +++ b/apps/spreadsheeteditor/mobile/src/controller/Main.jsx @@ -5,6 +5,7 @@ import { f7 } from 'framework7-react'; import { withTranslation } from 'react-i18next'; import CollaborationController from '../../../../common/mobile/lib/controller/Collaboration.jsx' +@inject("storeFocusObjects") class MainController extends Component { constructor(props) { super(props) @@ -202,6 +203,14 @@ class MainController extends Component { // me.api.asc_registerCallback('asc_onPrintUrl', _.bind(me.onPrintUrl, me)); // me.api.asc_registerCallback('asc_onDocumentName', _.bind(me.onDocumentName, me)); me.api.asc_registerCallback('asc_onEndAction', me._onLongActionEnd.bind(me)); + + const storeFocusObjects = this.props.storeFocusObjects; + this.api.asc_registerCallback('asc_onFocusObject', objects => { + storeFocusObjects.resetFocusObjects(objects); + }); + this.api.asc_registerCallback('asc_onSelectionChanged', cellInfo => { + storeFocusObjects.resetCellInfo(cellInfo); + }); } _onLongActionEnd(type, id) { diff --git a/apps/spreadsheeteditor/mobile/src/controller/edit/EditCell.jsx b/apps/spreadsheeteditor/mobile/src/controller/edit/EditCell.jsx new file mode 100644 index 0000000000..d74d69b64c --- /dev/null +++ b/apps/spreadsheeteditor/mobile/src/controller/edit/EditCell.jsx @@ -0,0 +1,20 @@ +import React, {Component} from 'react'; +import { f7 } from 'framework7-react'; +import {Device} from '../../../../../common/mobile/utils/device'; + +import EditCell from '../../view/edit/EditCell'; + +class EditCellController extends Component { + constructor (props) { + super(props); + } + + render () { + return ( + + ) + } +} + +export default EditCellController; \ No newline at end of file diff --git a/apps/spreadsheeteditor/mobile/src/page/main.jsx b/apps/spreadsheeteditor/mobile/src/page/main.jsx index d5db591300..5d51c19929 100644 --- a/apps/spreadsheeteditor/mobile/src/page/main.jsx +++ b/apps/spreadsheeteditor/mobile/src/page/main.jsx @@ -7,6 +7,7 @@ import CollaborationView from '../../../../common/mobile/lib/view/Collaboration. import CellEditor from '../controller/CellEditor'; import Statusbar from '../controller/StatusBar' import AddOptions from "../view/add/Add"; +import EditOptions from "../view/edit/Edit"; export default class MainPage extends Component { constructor(props) { @@ -67,10 +68,10 @@ export default class MainPage extends Component { {/* Page content */} - {/*{*/} - {/*!this.state.editOptionsVisible ? null :*/} - {/**/} - {/*}*/} + { + !this.state.editOptionsVisible ? null : + + } { !this.state.addOptionsVisible ? null : diff --git a/apps/spreadsheeteditor/mobile/src/store/focusObjects.js b/apps/spreadsheeteditor/mobile/src/store/focusObjects.js new file mode 100644 index 0000000000..5d87693d9c --- /dev/null +++ b/apps/spreadsheeteditor/mobile/src/store/focusObjects.js @@ -0,0 +1,138 @@ +import {action, observable, computed} from 'mobx'; + +export class storeFocusObjects { + @observable focusOn = undefined; + + @observable _focusObjects = []; + + @action resetFocusObjects(objects) { + this.focusOn = 'obj'; + this._focusObjects = objects; + } + + @computed get objects() { + const _objects = []; + for (let object of this._focusObjects) { + const type = object.get_ObjectType(); + + if (Asc.c_oAscTypeSelectElement.Paragraph == type) { + _objects.push('text', 'paragraph'); + } else if (Asc.c_oAscTypeSelectElement.Table == type) { + _objects.push('table'); + } else if (Asc.c_oAscTypeSelectElement.Image == type) { + if (object.get_ObjectValue().get_ChartProperties()) { + _objects.push('chart'); + } else if (object.get_ObjectValue().get_ShapeProperties()) { + _objects.push('shape'); + } else { + _objects.push('image'); + } + } else if (Asc.c_oAscTypeSelectElement.Hyperlink == type) { + _objects.push('hyperlink'); + } + } + const resultArr = _objects.filter((value, index, self) => self.indexOf(value) === index); //get uniq array + // Exclude shapes if chart exist + if (resultArr.indexOf('chart') > -1) { + resultArr.splice(resultArr.indexOf('shape'), 1); + } + return resultArr; + } + + @observable _cellInfo; + + @action resetCellInfo (cellInfo) { + this.focusOn = 'cell'; + this._cellInfo = cellInfo; + } + + @computed get selections () { + const _selections = []; + + let isCell, isRow, isCol, isAll, isChart, isImage, isTextShape, isShape, isTextChart, + selType = this._cellInfo.asc_getSelectionType(), + isObjLocked = false; + + switch (selType) { + case Asc.c_oAscSelectionType.RangeCells: isCell = true; break; + case Asc.c_oAscSelectionType.RangeRow: isRow = true; break; + case Asc.c_oAscSelectionType.RangeCol: isCol = true; break; + case Asc.c_oAscSelectionType.RangeMax: isAll = true; break; + case Asc.c_oAscSelectionType.RangeImage: isImage = true; break; + case Asc.c_oAscSelectionType.RangeShape: isShape = true; break; + case Asc.c_oAscSelectionType.RangeChart: isChart = true; break; + case Asc.c_oAscSelectionType.RangeChartText:isTextChart = true; break; + case Asc.c_oAscSelectionType.RangeShapeText: isTextShape = true; break; + } + + if (isImage || isShape || isChart) { + isImage = isShape = isChart = false; + let has_chartprops = false; + let selectedObjects = Common.EditorApi.get().asc_getGraphicObjectProps(); + + for (let i = 0; i < selectedObjects.length; i++) { + if (selectedObjects[i].asc_getObjectType() == Asc.c_oAscTypeSelectElement.Image) { + const elValue = selectedObjects[i].asc_getObjectValue(); + isObjLocked = isObjLocked || elValue.asc_getLocked(); + const shapeProps = elValue.asc_getShapeProperties(); + + if (shapeProps) { + if (shapeProps.asc_getFromChart()) { + isChart = true; + } else { + isShape = true; + } + } else if (elValue.asc_getChartProperties()) { + isChart = true; + has_chartprops = true; + } else { + isImage = true; + } + } + } + } else if (isTextShape || isTextChart) { + const selectedObjects = this.api.asc_getGraphicObjectProps(); + let isEquation = false; + + for (var i = 0; i < selectedObjects.length; i++) { + const elType = selectedObjects[i].asc_getObjectType(); + if (elType == Asc.c_oAscTypeSelectElement.Image) { + const value = selectedObjects[i].asc_getObjectValue(); + isObjLocked = isObjLocked || value.asc_getLocked(); + } else if (elType == Asc.c_oAscTypeSelectElement.Paragraph) { + } else if (elType == Asc.c_oAscTypeSelectElement.Math) { + isEquation = true; + } + } + } + if (isChart || isTextChart) { + _selections.push('chart'); + + if (isTextChart) { + _selections.push('text'); + } + } else if ((isShape || isTextShape) && !isImage) { + _selections.push('shape'); + + if (isTextShape) { + _selections.push('text'); + } + } else if (isImage) { + _selections.push('image'); + + if (isShape) { + _selections.push('shape'); + } + } else { + _selections.push('cell'); + + if (this._cellInfo.asc_getHyperlink()) { + _selections.push('hyperlink'); + } + } + return _selections; + } + + + +} \ No newline at end of file diff --git a/apps/spreadsheeteditor/mobile/src/store/mainStore.js b/apps/spreadsheeteditor/mobile/src/store/mainStore.js index a54c22e561..850aea6f8e 100644 --- a/apps/spreadsheeteditor/mobile/src/store/mainStore.js +++ b/apps/spreadsheeteditor/mobile/src/store/mainStore.js @@ -1,6 +1,6 @@ // import {storeDocumentSettings} from './documentSettings'; -// import {storeFocusObjects} from "./focusObjects"; +import {storeFocusObjects} from "./focusObjects"; import {storeUsers} from '../../../../common/mobile/lib/store/users'; import {storeWorksheets} from './sheets'; // import {storeTextSettings} from "./textSettings"; @@ -11,7 +11,7 @@ import {storeWorksheets} from './sheets'; // import {storeChartSettings} from "./chartSettings"; export const stores = { - // storeFocusObjects: new storeFocusObjects(), + storeFocusObjects: new storeFocusObjects(), // storeDocumentSettings: new storeDocumentSettings(), users: new storeUsers(), sheets: new storeWorksheets() diff --git a/apps/spreadsheeteditor/mobile/src/view/edit/Edit.jsx b/apps/spreadsheeteditor/mobile/src/view/edit/Edit.jsx new file mode 100644 index 0000000000..3ed9651ef2 --- /dev/null +++ b/apps/spreadsheeteditor/mobile/src/view/edit/Edit.jsx @@ -0,0 +1,138 @@ +import React, {useState, useEffect} from 'react'; +import {observer, inject} from "mobx-react"; +import { Popover, Sheet, View, Page, Navbar, NavRight, NavLeft, NavTitle, Tabs, Tab, Link } from 'framework7-react'; +import { f7 } from 'framework7-react'; +import { useTranslation } from 'react-i18next'; +import {Device} from '../../../../../common/mobile/utils/device'; + +import EditCellController from "../../controller/edit/EditCell"; + +const routes = [ +]; + +const EmptyEditLayout = () => { + const { t } = useTranslation(); + const _t = t('View.Edit', {returnObjects: true}); + return ( + +
+
+

{_t.textSelectObjectToEdit}

+
+
+
+ ) +}; + +const EditLayoutNavbar = ({ editors, inPopover }) => { + const isAndroid = Device.android; + const { t } = useTranslation(); + const _t = t('View.Edit', {returnObjects: true}); + return ( + + { + editors.length > 1 ? +
+ {editors.map((item, index) => {item.caption})} + {isAndroid && } +
: + { editors[0].caption } + } + { !inPopover && } +
+ ) +}; + +const EditLayoutContent = ({ editors }) => { + if (editors.length > 1) { + return ( + + {editors.map((item, index) => + + {item.component} + + )} + + ) + } else { + return ( + + {editors[0].component} + + ) + } +}; + +const EditTabs = props => { + const { t } = useTranslation(); + const _t = t('View.Edit', {returnObjects: true}); + + const store = props.storeFocusObjects; + const settings = !store.focusOn ? [] : (store.focusOn === 'obj' ? store.settings : store.selections); + let editors = []; + if (settings.length < 1) { + editors.push({ + caption: _t.textSettings, + component: + }); + } else { + if (settings.indexOf('cell') > -1) { + editors.push({ + caption: _t.textCell, + id: 'edit-text', + component: + }) + } + } + + return ( + + + + + + + + ) +}; + +const EditTabsContainer = inject("storeFocusObjects")(observer(EditTabs)); + +const EditView = props => { + const onOptionClick = (page) => { + $f7.views.current.router.navigate(page); + }; + const show_popover = props.usePopover; + return ( + show_popover ? + props.onClosed()}> + + : + props.onClosed()}> + + + ) +}; + +const EditOptions = props => { + useEffect(() => { + if ( Device.phone ) + f7.sheet.open('#edit-sheet'); + else f7.popover.open('#edit-popover', '#btn-edit'); + + return () => { + // component will unmount + } + }); + + const onviewclosed = () => { + if ( props.onclosed ) + props.onclosed(); + }; + + return ( + + ) +}; + +export default EditOptions; \ No newline at end of file diff --git a/apps/spreadsheeteditor/mobile/src/view/edit/EditCell.jsx b/apps/spreadsheeteditor/mobile/src/view/edit/EditCell.jsx new file mode 100644 index 0000000000..6299857112 --- /dev/null +++ b/apps/spreadsheeteditor/mobile/src/view/edit/EditCell.jsx @@ -0,0 +1,12 @@ +import React, {Fragment, useState} from 'react'; +import {observer, inject} from "mobx-react"; + +const EditCell = props => { + return ( + + + + ) +}; + +export default EditCell; \ No newline at end of file From 3e6f6bc9647bea846e6ba8890907e098410b3b2a Mon Sep 17 00:00:00 2001 From: Maxim Kadushkin Date: Thu, 28 Jan 2021 19:23:28 +0300 Subject: [PATCH 12/14] [DE mobile] custom Search for DE --- apps/common/mobile/lib/controller/Search.jsx | 6 +-- apps/common/mobile/lib/view/Search.jsx | 32 +++++------- .../mobile/src/controller/Search.jsx | 51 +++++++++++++++++++ apps/documenteditor/mobile/src/page/main.jsx | 2 +- 4 files changed, 69 insertions(+), 22 deletions(-) create mode 100644 apps/documenteditor/mobile/src/controller/Search.jsx diff --git a/apps/common/mobile/lib/controller/Search.jsx b/apps/common/mobile/lib/controller/Search.jsx index 610ce2facd..fa60859ecc 100644 --- a/apps/common/mobile/lib/controller/Search.jsx +++ b/apps/common/mobile/lib/controller/Search.jsx @@ -3,11 +3,11 @@ import SearchView, {SearchSettingsView} from '../view/Search' const SearchController = props => { - const _onSearchQuery = params => { + const onSearchQuery = params => { console.log('on search: ' + params); }; - return + return }; -export {SearchController as Search, SearchSettingsView as SearchSettings}; +export {SearchController, SearchView, SearchSettingsView}; diff --git a/apps/common/mobile/lib/view/Search.jsx b/apps/common/mobile/lib/view/Search.jsx index e896f80e16..54d21fa0b6 100644 --- a/apps/common/mobile/lib/view/Search.jsx +++ b/apps/common/mobile/lib/view/Search.jsx @@ -36,6 +36,9 @@ class SearchSettingsView extends Component { if (this.onReplaceChecked) {} } + extraSearchOptions() { + } + render() { const show_popover = true; const navbar = @@ -45,6 +48,7 @@ class SearchSettingsView extends Component { Done } ; + const extra = this.extraSearchOptions(); const content = @@ -53,14 +57,7 @@ class SearchSettingsView extends Component { this.onFindReplaceClick('find')} /> this.onFindReplaceClick('replace')} />
- - - - - - - - + { extra } ; return ( @@ -108,21 +105,20 @@ class SearchView extends Component { searchParams() { let params = { - text: this.searchbar.query, - direction: action + find: this.searchbar.query }; + + if ( searchOptions.usereplace ) + params.replace = this.$replace.val(); + + return params; } onSearchClick(action) { if ( this.searchbar && this.searchbar.query) { if ( this.props.onSearchQuery ) { - let params = { - text: this.searchbar.query, - direction: action - }; - - if ( searchOptions.usereplace ) - params.replace = this.$replace.val(); + let params = this.searchParams(); + params.to = action; this.props.onSearchQuery(params); } @@ -166,4 +162,4 @@ class SearchView extends Component { } } -export {SearchView as default, SearchSettingsView}; +export {SearchView as default, SearchView, SearchSettingsView}; diff --git a/apps/documenteditor/mobile/src/controller/Search.jsx b/apps/documenteditor/mobile/src/controller/Search.jsx new file mode 100644 index 0000000000..7bd7116a26 --- /dev/null +++ b/apps/documenteditor/mobile/src/controller/Search.jsx @@ -0,0 +1,51 @@ +import React from 'react'; +import { List, ListItem, Toggle } from 'framework7-react'; +import { SearchController, SearchView, SearchSettingsView } from '../../../../common/mobile/lib/controller/Search'; +import { f7 } from 'framework7-react'; + + +class SearchSettings extends SearchSettingsView { + constructor(props) { + super(props); + } + + extraSearchOptions() { + const anc_markup = super.extraSearchOptions(); + + const markup = + + + + + + + ; + + return {...anc_markup, ...markup}; + } +} + +class DESearchView extends SearchView { + searchParams() { + let params = super.searchParams(); + + const checkboxCaseSensitive = f7.toggle.get('.toggle-case-sensitive'), + checkboxMarkResults = f7.toggle.get('.toggle-mark-results'); + const searchOptions = { + caseSensitive: checkboxCaseSensitive.checked, + highlight: checkboxMarkResults.checked + }; + + return {...params, ...searchOptions}; + } +} + +const Search = props => { + const onSearchQuery = params => { + console.log('on search: ' + params.find); + }; + + return +}; + +export {Search, SearchSettings} diff --git a/apps/documenteditor/mobile/src/page/main.jsx b/apps/documenteditor/mobile/src/page/main.jsx index fc9d05cc2e..86b1996de3 100644 --- a/apps/documenteditor/mobile/src/page/main.jsx +++ b/apps/documenteditor/mobile/src/page/main.jsx @@ -6,7 +6,7 @@ import AddOptions from '../view/add/Add'; import Settings from '../view/settings/Settings'; import CollaborationView from '../../../../common/mobile/lib/view/Collaboration.jsx' import { Device } from '../../../../common/mobile/utils/device' -import { Search, SearchSettings } from '../../../../common/mobile/lib/controller/Search'; +import { Search, SearchSettings } from '../controller/Search'; export default class MainPage extends Component { constructor(props) { From 6998771d0c609f3aa9cf60d25d612fc6a3cb125f Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Fri, 29 Jan 2021 00:30:33 +0300 Subject: [PATCH 13/14] [PE mobile] Added the ability insert links --- .../resources/less/common-material.less | 4 +- apps/presentationeditor/mobile/locale/en.json | 16 +- .../mobile/src/controller/Main.jsx | 8 +- .../mobile/src/controller/add/AddLink.jsx | 112 +++++++++++++ .../mobile/src/store/focusObjects.js | 10 ++ .../mobile/src/store/linkSettings.js | 8 + .../mobile/src/store/mainStore.js | 4 +- .../mobile/src/view/add/Add.jsx | 14 ++ .../mobile/src/view/add/AddLink.jsx | 154 ++++++++++++++++++ .../mobile/src/view/add/AddOther.jsx | 10 +- 10 files changed, 333 insertions(+), 7 deletions(-) create mode 100644 apps/presentationeditor/mobile/src/controller/add/AddLink.jsx create mode 100644 apps/presentationeditor/mobile/src/store/linkSettings.js create mode 100644 apps/presentationeditor/mobile/src/view/add/AddLink.jsx diff --git a/apps/common/mobile/resources/less/common-material.less b/apps/common/mobile/resources/less/common-material.less index dab99d7c26..18af81ee12 100644 --- a/apps/common/mobile/resources/less/common-material.less +++ b/apps/common/mobile/resources/less/common-material.less @@ -165,10 +165,10 @@ } } &.inputs-list { - .item-input { + .item-input, .item-link { .item-inner { display: block; - .item-label { + .item-title, .item-label { width: 100%; font-size: 12px; } diff --git a/apps/presentationeditor/mobile/locale/en.json b/apps/presentationeditor/mobile/locale/en.json index bae19375cb..80ea8dd647 100644 --- a/apps/presentationeditor/mobile/locale/en.json +++ b/apps/presentationeditor/mobile/locale/en.json @@ -93,7 +93,21 @@ "textTableSize": "Table Size", "textColumns": "Columns", "textRows": "Rows", - "textCancel": "Cancel" + "textCancel": "Cancel", + "textLink": "Link", + "textLinkType": "Link Type", + "textExternalLink": "External Link", + "textSlideInThisPresentation": "Slide in this Presentation", + "textLinkTo": "Link to", + "textNextSlide": "Next Slide", + "textPreviousSlide": "Previous Slide", + "textFirstSlide": "First Slide", + "textLastSlide": "Last Slide", + "textSlideNumber": "Slide Number", + "textDisplay": "Display", + "textDefault": "Selected text", + "textScreenTip": "Screen Tip", + "textInsert": "Insert" }, "Edit": { "textText": "Text", diff --git a/apps/presentationeditor/mobile/src/controller/Main.jsx b/apps/presentationeditor/mobile/src/controller/Main.jsx index 5633a9f893..0ee0ca0289 100644 --- a/apps/presentationeditor/mobile/src/controller/Main.jsx +++ b/apps/presentationeditor/mobile/src/controller/Main.jsx @@ -5,7 +5,7 @@ import { f7 } from "framework7-react"; import { withTranslation } from 'react-i18next'; import CollaborationController from '../../../../common/mobile/lib/controller/Collaboration.jsx' -@inject("storeFocusObjects", "storeAppOptions", "storePresentationInfo", "storePresentationSettings", "storeSlideSettings", "storeTextSettings", "storeTableSettings") +@inject("storeFocusObjects", "storeAppOptions", "storePresentationInfo", "storePresentationSettings", "storeSlideSettings", "storeTextSettings", "storeTableSettings", "storeLinkSettings") class MainController extends Component { constructor(props) { super(props) @@ -304,6 +304,12 @@ class MainController extends Component { this.api.asc_registerCallback('asc_onInitTableTemplates', (templates) => { storeTableSettings.initTableTemplates(templates); }); + + //link settings + const storeLinkSettings = this.props.storeLinkSettings; + this.api.asc_registerCallback('asc_onCanAddHyperlink', (value) => { + storeLinkSettings.canAddHyperlink(value); + }); } _onDocumentContentReady() { diff --git a/apps/presentationeditor/mobile/src/controller/add/AddLink.jsx b/apps/presentationeditor/mobile/src/controller/add/AddLink.jsx new file mode 100644 index 0000000000..e9e9ba81a6 --- /dev/null +++ b/apps/presentationeditor/mobile/src/controller/add/AddLink.jsx @@ -0,0 +1,112 @@ +import React, {Component} from 'react'; +import { f7 } from 'framework7-react'; +import {Device} from '../../../../../common/mobile/utils/device'; +import { withTranslation} from 'react-i18next'; + +import {PageLink} from '../../view/add/AddLink'; + +class AddLinkController extends Component { + constructor (props) { + super(props); + this.onInsertLink = this.onInsertLink.bind(this); + this.getTextDisplay = this.getTextDisplay.bind(this); + + const api = Common.EditorApi.get(); + this.textDisplay = api.can_AddHyperlink(); + } + + closeModal () { + if ( Device.phone ) { + f7.sheet.close('.add-popup', true); + } else { + f7.popover.close('#add-popover'); + } + } + + onInsertLink (type, linkInfo) { + const api = Common.EditorApi.get(); + const { t } = this.props; + const _t = t("View.Add", { returnObjects: true }); + + const c_oHyperlinkType = { + InternalLink: 0, + WebLink: 1 + }; + const display = linkInfo.display; + const tip = linkInfo.tip; + const props = new Asc.CHyperlinkProperty(); + let def_display = ''; + + if (type == c_oHyperlinkType.WebLink) { + let url = linkInfo.url; + const urltype = api.asc_getUrlType(url.trim()); + const isEmail = (urltype == 2); + if (urltype < 1) { + f7.dialog.alert(_t.txtNotUrl, _t.notcriticalErrorTitle); + return; + } + + url = url.replace(/^\s+|\s+$/g, ''); + if (!/(((^https?)|(^ftp)):\/\/)|(^mailto:)/i.test(url)) + url = (isEmail ? 'mailto:' : 'http://' ) + url; + url = url.replace(new RegExp("%20", 'g'), " "); + + props.put_Value(url); + props.put_ToolTip(tip); + def_display = url; + } else { + let url = "ppaction://hlink"; + let slidetip = ''; + switch (linkInfo.linkTo) { + case 0: + url = url + "showjump?jump=nextslide"; + slidetip = _t.textNextSlide; + break; + case 1: + url = url + "showjump?jump=previousslide"; + slidetip = _t.textPrevSlide; + break; + case 2: + url = url + "showjump?jump=firstslide"; + slidetip = _t.textFirstSlide; + break; + case 3: + url = url + "showjump?jump=lastslide"; + slidetip = _t.textLastSlide; + break; + case 4: + url = url + "sldjumpslide" + linkInfo.numberTo; + slidetip = _t.textSlide + ' ' + (linkInfo.numberTo + 1); + break; + } + props.put_Value(url); + props.put_ToolTip(!tip ? slidetip : tip); + def_display = slidetip; + } + + if (!linkInfo.displayDisabled) { + props.put_Text(!display ? def_display : display); + } else + props.put_Text(null); + + api.add_Hyperlink(props); + + this.closeModal(); + } + + getTextDisplay () { + return this.textDisplay; + } + + render () { + return ( + + ) + } +} + +const AddLinkWithTranslation = withTranslation()(AddLinkController); + +export {AddLinkWithTranslation as AddLinkController}; \ No newline at end of file diff --git a/apps/presentationeditor/mobile/src/store/focusObjects.js b/apps/presentationeditor/mobile/src/store/focusObjects.js index 4fda23195a..f1a5fbc494 100644 --- a/apps/presentationeditor/mobile/src/store/focusObjects.js +++ b/apps/presentationeditor/mobile/src/store/focusObjects.js @@ -83,6 +83,16 @@ export class storeFocusObjects { } } + @computed get paragraphLocked() { + let _paragraphLocked = false; + for (let object of this._focusObjects) { + if (Asc.c_oAscTypeSelectElement.Paragraph == object.get_ObjectType()) { + _paragraphLocked = object.get_ObjectValue().get_Locked(); + } + } + return _paragraphLocked; + } + @computed get shapeObject() { const shapes = []; for (let object of this._focusObjects) { diff --git a/apps/presentationeditor/mobile/src/store/linkSettings.js b/apps/presentationeditor/mobile/src/store/linkSettings.js new file mode 100644 index 0000000000..9670a64667 --- /dev/null +++ b/apps/presentationeditor/mobile/src/store/linkSettings.js @@ -0,0 +1,8 @@ +import {action, observable, computed} from 'mobx'; + +export class storeLinkSettings { + @observable canAddLink; + @action canAddHyperlink (value) { + this.canAddLink = value; + } +} \ No newline at end of file diff --git a/apps/presentationeditor/mobile/src/store/mainStore.js b/apps/presentationeditor/mobile/src/store/mainStore.js index 078711d47f..7afc1eb9b3 100644 --- a/apps/presentationeditor/mobile/src/store/mainStore.js +++ b/apps/presentationeditor/mobile/src/store/mainStore.js @@ -16,6 +16,7 @@ import { storeShapeSettings } from './shapeSettings'; // import {storeImageSettings} from "./imageSettings"; import {storeTableSettings} from "./tableSettings"; // import {storeChartSettings} from "./chartSettings"; +import {storeLinkSettings} from "./linkSettings"; export const stores = { storeAppOptions: new storeAppOptions(), @@ -33,6 +34,7 @@ export const stores = { // storeParagraphSettings: new storeParagraphSettings(), // storeShapeSettings: new storeShapeSettings(), // storeChartSettings: new storeChartSettings(), - storeTableSettings: new storeTableSettings() + storeTableSettings: new storeTableSettings(), + storeLinkSettings: new storeLinkSettings() }; diff --git a/apps/presentationeditor/mobile/src/view/add/Add.jsx b/apps/presentationeditor/mobile/src/view/add/Add.jsx index 4adc94947f..00f312662b 100644 --- a/apps/presentationeditor/mobile/src/view/add/Add.jsx +++ b/apps/presentationeditor/mobile/src/view/add/Add.jsx @@ -11,6 +11,8 @@ import {AddImageController} from "../../controller/add/AddImage"; import {PageImageLinkSettings} from "./AddImage"; import {AddOtherController} from "../../controller/add/AddOther"; import {PageAddTable} from "./AddOther"; +import {AddLinkController} from "../../controller/add/AddLink"; +import {PageTypeLink, PageLinkTo} from "./AddLink"; const routes = [ // Image @@ -22,6 +24,18 @@ const routes = [ { path: '/add-table/', component: PageAddTable + }, + { + path: '/add-link/', + component: AddLinkController + }, + { + path: '/add-link-type/', + component: PageTypeLink + }, + { + path: '/add-link-to/', + component: PageLinkTo } ]; diff --git a/apps/presentationeditor/mobile/src/view/add/AddLink.jsx b/apps/presentationeditor/mobile/src/view/add/AddLink.jsx new file mode 100644 index 0000000000..567a23e843 --- /dev/null +++ b/apps/presentationeditor/mobile/src/view/add/AddLink.jsx @@ -0,0 +1,154 @@ +import React, {useState} from 'react'; +import {observer, inject} from "mobx-react"; +import {List, ListItem, Page, Navbar, Icon, ListButton, ListInput, Segmented, Button} from 'framework7-react'; +import { useTranslation } from 'react-i18next'; +import {Device} from "../../../../../common/mobile/utils/device"; + +const PageTypeLink = props => { + const { t } = useTranslation(); + const _t = t('View.Add', {returnObjects: true}); + const [typeLink, setTypeLink] = useState(props.curType); + return ( + + + + {setTypeLink(1); props.changeType(1);}}> + {setTypeLink(0); props.changeType(0);}}> + + + ) +}; + +const PageLinkTo = props => { + const isAndroid = Device.android; + const { t } = useTranslation(); + const _t = t('View.Add', {returnObjects: true}); + + const [stateTypeTo, setTypeTo] = useState(props.curTo); + const changeTypeTo = (type) => { + setTypeTo(type); + props.changeTo(type); + }; + + const [stateNumberTo, setNumberTo] = useState(0); + const changeNumber = (curNumber, isDecrement) => { + setTypeTo(4); + let value; + if (isDecrement) { + value = curNumber - 1; + } else { + value = curNumber + 1; + } + setNumberTo(value); + props.changeTo(4, value); + }; + return ( + + + + {changeTypeTo(0)}}> + {changeTypeTo(1)}}> + {changeTypeTo(2)}}> + {changeTypeTo(3)}}> + + {!isAndroid &&
{stateNumberTo + 1}
} +
+ + + {isAndroid && } + + +
+
+
+
+ ) +}; + +const PageLink = props => { + const { t } = useTranslation(); + const _t = t('View.Add', {returnObjects: true}); + + const [typeLink, setTypeLink] = useState(1); + const textType = typeLink === 1 ? _t.textExternalLink : _t.textSlideInThisPresentation; + const changeType = (newType) => { + setTypeLink(newType); + }; + + const [link, setLink] = useState(''); + + const [linkTo, setLinkTo] = useState(0); + const [displayTo, setDisplayTo] = useState(_t.textNextSlide); + const [numberTo, setNumberTo] = useState(0); + const changeTo = (type, number) => { + setLinkTo(type); + switch (type) { + case 0 : setDisplayTo(_t.textNextSlide); break; + case 1 : setDisplayTo(_t.textPreviousSlide); break; + case 2 : setDisplayTo(_t.textFirstSlide); break; + case 3 : setDisplayTo(_t.textLastSlide); break; + case 4 : setDisplayTo(`${_t.textSlide} ${number + 1}`); setNumberTo(number); break; + } + }; + + const display = props.getTextDisplay(); + const displayDisabled = display !== false && display === null; + const [stateDisplay, setDisplay] = useState(display !== false ? ((display !== null) ? display : _t.textDefault) : ""); + + const [screenTip, setScreenTip] = useState(''); + + return ( + + + + + {typeLink === 1 ? + {setLink(event.target.value)}} + /> : + + } + {setDisplay(event.target.value)}} + /> + {setScreenTip(event.target.value)}} + /> + + + { + props.onInsertLink(typeLink, (typeLink === 1 ? + {url: link, display: stateDisplay, tip: screenTip, displayDisabled: displayDisabled } : + {linkTo: linkTo, numberTo: numberTo, display: stateDisplay, tip: screenTip, displayDisabled: displayDisabled})); + }} + /> + + + ) +}; + +export {PageLink, + PageLinkTo, + PageTypeLink} \ No newline at end of file diff --git a/apps/presentationeditor/mobile/src/view/add/AddOther.jsx b/apps/presentationeditor/mobile/src/view/add/AddOther.jsx index f0a016b1e2..e80478b4a2 100644 --- a/apps/presentationeditor/mobile/src/view/add/AddOther.jsx +++ b/apps/presentationeditor/mobile/src/view/add/AddOther.jsx @@ -29,10 +29,10 @@ const PageTable = props => { ) }; - const AddOther = props => { const { t } = useTranslation(); const _t = t('View.Add', {returnObjects: true}); + const showInsertLink = props.storeLinkSettings.canAddLink && !props.storeFocusObjects.paragraphLocked; return ( { + {showInsertLink && + + + + } ) }; const PageAddTable = inject("storeTableSettings")(observer(PageTable)); +const AddOtherContainer = inject("storeFocusObjects", "storeLinkSettings")(observer(AddOther)); -export {AddOther, +export {AddOtherContainer as AddOther, PageAddTable}; \ No newline at end of file From c124342f126824dd228d7a0f2fceea2cd8447fe8 Mon Sep 17 00:00:00 2001 From: Maxim Kadushkin Date: Fri, 29 Jan 2021 10:01:02 +0300 Subject: [PATCH 14/14] [DE mobile] extended Searchbar --- apps/common/mobile/lib/view/Search.jsx | 71 +++++++++++++++++-- .../mobile/src/controller/Search.jsx | 28 +++++++- 2 files changed, 92 insertions(+), 7 deletions(-) diff --git a/apps/common/mobile/lib/view/Search.jsx b/apps/common/mobile/lib/view/Search.jsx index 54d21fa0b6..51bca9ca58 100644 --- a/apps/common/mobile/lib/view/Search.jsx +++ b/apps/common/mobile/lib/view/Search.jsx @@ -15,6 +15,9 @@ const popoverStyle = { height: '300px' }; +const SEARCH_BACKWARD = 'back'; +const SEARCH_FORWARD = 'next'; + class SearchSettingsView extends Component { constructor(props) { super(props); @@ -82,9 +85,30 @@ class SearchView extends Component { backdrop: false, on: { search: (bar, curval, prevval) => { - } + }, + enable: this.onSearchbarShow.bind(this, true), + disable: this.onSearchbarShow.bind(this, false) } }); + + // function iOSVersion() { + // var ua = navigator.userAgent; + // var m; + // return (m = /(iPad|iPhone|iphone).*?(OS |os |OS\_)(\d+((_|\.)\d)?((_|\.)\d)?)/.exec(ua)) ? parseFloat(m[3]) : 0; + // } + + const $$ = Dom7; + const $editor = $$('#editor_sdk'); + if (false /*iOSVersion() < 13*/) { + // $editor.single('mousedown touchstart', _.bind(me.onEditorTouchStart, me)); + // $editor.single('mouseup touchend', _.bind(me.onEditorTouchEnd, me)); + } else { + // $editor.single('pointerdown', this.onEditorTouchStart, me)); + // $editor.single('pointerup', _.bind(me.onEditorTouchEnd, me)); + } + + $editor.on('pointerdown', this.onEditorTouchStart.bind(this)); + $editor.on('pointerup', this.onEditorTouchEnd.bind(this)); } }); @@ -118,13 +142,51 @@ class SearchView extends Component { if ( this.searchbar && this.searchbar.query) { if ( this.props.onSearchQuery ) { let params = this.searchParams(); - params.to = action; + params.forward = action != SEARCH_BACKWARD; this.props.onSearchQuery(params); } } } + onSearchbarShow(isshowed, bar) { + if ( !isshowed ) { + this.$repalce.val(''); + } + } + + onEditorTouchStart(e) { + this.startPoint = this.pointerPosition(e); + } + + onEditorTouchEnd(e) { + const endPoint = this.pointerPosition(e); + + if ( this.searchbar.enabled ) { + const distance = (this.startPoint.x === undefined || this.startPoint.y === undefined) ? 0 : + Math.sqrt((endPoint.x -= this.startPoint.x) * endPoint.x + (endPoint.y -= this.startPoint.y) * endPoint.y); + + if ( distance < 1 ) { + this.searchbar.disable(); + } + } + } + + pointerPosition(e) { + let out = {x:0, y:0}; + if ( e.type == 'touchstart' || e.type == 'touchend' ) { + const touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0]; + out.x = touch.pageX; + out.y = touch.pageY; + } else + if ( e.type == 'mousedown' || e.type == 'mouseup' ) { + out.x = e.pageX; + out.y = e.pageY; + } + + return out; + } + render() { const usereplace = searchOptions.usereplace; const hidden = {display: "none"}; @@ -148,14 +210,13 @@ class SearchView extends Component { - Cancel ) diff --git a/apps/documenteditor/mobile/src/controller/Search.jsx b/apps/documenteditor/mobile/src/controller/Search.jsx index 7bd7116a26..99ac30ccc7 100644 --- a/apps/documenteditor/mobile/src/controller/Search.jsx +++ b/apps/documenteditor/mobile/src/controller/Search.jsx @@ -7,6 +7,13 @@ import { f7 } from 'framework7-react'; class SearchSettings extends SearchSettingsView { constructor(props) { super(props); + + this.onToggleMarkResults = this.onToggleMarkResults.bind(this); + } + + onToggleMarkResults(checked) { + const api = Common.EditorApi.get(); + api.asc_selectSearchingResults(checked); } extraSearchOptions() { @@ -17,7 +24,7 @@ class SearchSettings extends SearchSettingsView {
- +
; @@ -38,11 +45,28 @@ class DESearchView extends SearchView { return {...params, ...searchOptions}; } + + onSearchbarShow(isshowed, bar) { + super.onSearchbarShow(isshowed, bar); + + const api = Common.EditorApi.get(); + if ( isshowed ) { + const checkboxMarkResults = f7.toggle.get('.toggle-mark-results'); + api.asc_selectSearchingResults(checkboxMarkResults.checked); + } else api.asc_selectSearchingResults(false); + } } const Search = props => { const onSearchQuery = params => { - console.log('on search: ' + params.find); + const api = Common.EditorApi.get(); + + if ( !params.replace ) { + if ( !api.asc_findText(params.find, params.forward, params.caseSensitive, params.highlight) ) { + f7.dialog.alert('there are no more results', e => { + }); + } + } }; return