From 5c53f958f80ae4058d8eabe37e6c37a4a4d2db02 Mon Sep 17 00:00:00 2001 From: Maxim Kadushkin Date: Wed, 3 Mar 2021 14:47:49 +0300 Subject: [PATCH 01/13] [DE mobile] context menu depends on selected objects --- .../mobile/lib/controller/ContextMenu.jsx | 13 +- apps/common/mobile/lib/view/ContextMenu.jsx | 6 +- .../mobile/src/controller/ContextMenu.jsx | 252 +++++++++++++++++- apps/documenteditor/mobile/src/page/main.jsx | 4 +- .../mobile/src/store/appOptions.js | 8 + 5 files changed, 262 insertions(+), 21 deletions(-) diff --git a/apps/common/mobile/lib/controller/ContextMenu.jsx b/apps/common/mobile/lib/controller/ContextMenu.jsx index ef0f50118..f25deba51 100644 --- a/apps/common/mobile/lib/controller/ContextMenu.jsx +++ b/apps/common/mobile/lib/controller/ContextMenu.jsx @@ -12,8 +12,10 @@ class ContextMenuController extends Component { this.state = { opened: false + , items: [] }; + this.onMenuItemClick = this.onMenuItemClick.bind(this); this.onMenuClosed = this.onMenuClosed.bind(this); this.onDocumentReady = this.onDocumentReady.bind(this); this.onApiOpenContextMenu = this.onApiOpenContextMenu.bind(this); @@ -94,6 +96,8 @@ class ContextMenuController extends Component { onApiOpenContextMenu(x, y) { if ( !this.state.opened ) { + this.setState({items: this.initMenuItems()}); + this.$targetEl.css({left: `${x}px`, top: `${y}px`}); const popover = f7.popover.open(idContextMenuElement, idCntextMenuTargetElement); @@ -108,7 +112,8 @@ class ContextMenuController extends Component { onApiHideContextMenu() { if ( this.state.opened ) { - f7.popover.close(idContextMenuElement); + $$(idContextMenuElement).hide(); + f7.popover.close(idContextMenuElement, false); this.$targetEl.css({left: '-10000px', top: '-10000px'}); this.setState({opened: false}); @@ -116,6 +121,9 @@ class ContextMenuController extends Component { } onMenuClosed() { + this.$targetEl.css({left: '-10000px', top: '-10000px'}); + this.setState({opened: false}); + // (async () => { // await 1 && this.setState(state => { // this.$targetEl.css({left: '-10000px', top: '-10000px'}); @@ -125,6 +133,7 @@ class ContextMenuController extends Component { } onMenuItemClick(action) { + this.onApiHideContextMenu(); } componentWillUnmount() { @@ -151,7 +160,7 @@ class ContextMenuController extends Component { render() { return ( - + ) } } diff --git a/apps/common/mobile/lib/view/ContextMenu.jsx b/apps/common/mobile/lib/view/ContextMenu.jsx index 954b15e5b..4bf1c2c61 100644 --- a/apps/common/mobile/lib/view/ContextMenu.jsx +++ b/apps/common/mobile/lib/view/ContextMenu.jsx @@ -26,9 +26,9 @@ class ContextMenuView extends Component { > {buttons.map((b, index) => - !!b.text ? - this.props.onMenuItemClick(b.action)} /> : - + !b.icon ? + this.props.onMenuItemClick(b.event)} /> : + )} diff --git a/apps/documenteditor/mobile/src/controller/ContextMenu.jsx b/apps/documenteditor/mobile/src/controller/ContextMenu.jsx index 23d5d362d..5a09e6f84 100644 --- a/apps/documenteditor/mobile/src/controller/ContextMenu.jsx +++ b/apps/documenteditor/mobile/src/controller/ContextMenu.jsx @@ -1,13 +1,43 @@ -import React from 'react'; +import React, { useContext } from 'react'; import { f7 } from 'framework7-react'; +import { inject, observer } from "mobx-react"; import ContextMenuController from '../../../../common/mobile/lib/controller/ContextMenu'; import { idContextMenuElement } from '../../../../common/mobile/lib/view/ContextMenu'; +import { Device } from '../../../../common/mobile/utils/device'; +@inject ( stores => ({ + isEdit: stores.storeAppOptions.isEdit, + canViewComments: stores.storeAppOptions.canViewComments, + canReview: stores.storeAppOptions.canReview +})) class ContextMenu extends ContextMenuController { constructor(props) { super(props); // console.log('context menu controller created'); + this.onApiShowComment = this.onApiShowComment.bind(this); + this.onApiHideComment = this.onApiHideComment.bind(this); + } + + static closeContextMenu() { + f7.popover.close(idContextMenuElement, false); + } + + componentWillUnmount() { + super.componentWillUnmount(); + + const api = Common.EditorApi.get(); + api.asc_unregisterCallback('asc_onShowComment', this.onApiShowComment); + api.asc_unregisterCallback('asc_onHideComment', this.onApiHideComment); + } + + + onApiShowComment(comments) { + this.isComments = comments && comments.length > 0; + } + + onApiHideComment() { + this.isComments = false; } // onMenuClosed() { @@ -17,23 +47,217 @@ class ContextMenu extends ContextMenuController { onMenuItemClick(action) { super.onMenuItemClick(action); - console.log("on click item"); + console.log("click context menu item: " + action); + } + + onDocumentReady() { + super.onDocumentReady(); + + const api = Common.EditorApi.get(); + api.asc_registerCallback('asc_onShowComment', this.onApiShowComment); + api.asc_registerCallback('asc_onHideComment', this.onApiHideComment); } initMenuItems() { - return [ - { - text: 'Edit', - action: 'edit' - }, { - text: 'View', - action: 'view' - }, { - icon: 'icon-paste', - action: 'review' + if ( !Common.EditorApi ) return []; + + const { isEdit, canViewComments, canReview } = this.props; + + const api = Common.EditorApi.get(); + const stack = api.getSelectedElements(); + const canCopy = api.can_CopyCut(); + + let itemsIcon = [], + itemsText = []; + + if ( canCopy ) { + itemsIcon.push({ + caption: /*me.menuCopy*/ 'Copy', + event: 'copy', + icon: 'icon-copy' + }); + } + + if ( canViewComments && this.isComments && isEdit ) { + itemsText.push({ + caption: /*me.menuViewComment*/'View Comment', + event: 'viewcomment' + }); + } + + let isText = false, + isTable = false, + isImage = false, + isChart = false, + isShape = false, + isLink = false, + lockedText = false, + lockedTable = false, + lockedImage = false, + lockedHeader = false; + + stack.forEach(item => { + const objectType = item.get_ObjectType(), + objectValue = item.get_ObjectValue(); + + if ( objectType == Asc.c_oAscTypeSelectElement.Header ) { + lockedHeader = objectValue.get_Locked(); + } else + if ( objectType == Asc.c_oAscTypeSelectElement.Paragraph ) { + lockedText = objectValue.get_Locked(); + isText = true; + } else + if ( objectType == Asc.c_oAscTypeSelectElement.Image ) { + lockedImage = objectValue.get_Locked(); + if ( objectValue && objectValue.get_ChartProperties() ) { + isChart = true; + } else + if ( objectValue && objectValue.get_ShapeProperties() ) { + isShape = true; + } else { + isImage = true; + } + } else + if ( objectType == Asc.c_oAscTypeSelectElement.Table ) { + lockedTable = objectValue.get_Locked(); + isTable = true; + } else + if ( objectType == Asc.c_oAscTypeSelectElement.Hyperlink ) { + isLink = true; } - ]; + }); + + if ( stack.length > 0 ) { + const swapItems = function(items, indexBefore, indexAfter) { + items[indexAfter] = items.splice(indexBefore, 1, items[indexAfter])[0]; + }; + + if ( isEdit && !this.isDisconnected ) { + if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader && canCopy ) { + itemsIcon.push({ + // caption: me.menuCut, + event: 'cut', + icon: 'icon-cut' + }); + + // Swap 'Copy' and 'Cut' + swapItems(itemsIcon, 0, 1); + } + + if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader ) { + itemsIcon.push({ + // caption: me.menuPaste, + event: 'paste', + icon: 'icon-paste' + }); + } + + if ( isTable && api.CheckBeforeMergeCells() && !lockedTable && !lockedHeader) { + itemsText.push({ + caption: /*me.menuMerge*/'Merge', + event: 'merge' + }); + } + + if ( isTable && api.CheckBeforeSplitCells() && !lockedTable && !lockedHeader ) { + itemsText.push({ + caption: /*me.menuSplit*/'Split', + event: 'split' + }); + } + + if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader ) { + itemsText.push({ + caption: /*me.menuDelete*/'Delete', + event: 'delete' + }); + } + + if ( isTable && !lockedTable && !lockedText && !lockedHeader ) { + itemsText.push({ + caption: /*me.menuDeleteTable*/'Delete Table', + event: 'deletetable' + }); + } + + if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader ){ + itemsText.push({ + caption: /*me.menuEdit*/'Edit', + event: 'edit' + }); + } + + // if ( !_.isEmpty(api.can_AddHyperlink()) && !lockedHeader) { + // arrItems.push({ + // caption: me.menuAddLink, + // event: 'addlink' + // }); + // } + + if ( canReview ) { + if (false /*_inRevisionChange*/) { + itemsText.push({ + caption: /*me.menuReviewChange*/'Review Change', + event: 'reviewchange' + }); + } else { + itemsText.push({ + caption: /*me.menuReview*/'Review', + event: 'review' + }); + } + } + + if ( this.isComments && canViewComments ) { + itemsText.push({ + caption: /*me.menuViewComment*/'View Comment', + event: 'viewcomment' + }); + } + + const isObject = isShape || isChart || isImage || isTable; + const hideAddComment = !canViewComments || api.can_AddQuotedComment() === false || lockedText || lockedTable || lockedImage || lockedHeader || (!isText && isObject); + if ( !hideAddComment ) { + itemsText.push({ + caption: /*me.menuAddComment*/'Add Comment', + event: 'addcomment' + }); + } + } + } + + if ( isLink ) { + itemsText.push({ + caption: /*me.menuOpenLink*/'Open Link', + event: 'openlink' + }); + } + + if ( Device.phone && itemsText.length > 2 ) { + // _actionSheets = arrItems.slice(2); + // arrItems = arrItems.slice(0, 2); + // arrItems.push({ + // caption: me.menuMore, + // event: 'showActionSheet' + // }); + this.extraItems = itemsText.splice(2,itemsText.length, { + caption: /*me.menuMore*/'More', + event: 'showActionSheet' + }); + } + + return itemsIcon.concat(itemsText); + // return [{ + // caption: 'Edit', + // event: 'edit' + // }, { + // caption: 'View', + // event: 'view' + // }, { + // icon: 'icon-paste', + // event: 'review' + // }]; } } -export { ContextMenu, idContextMenuElement }; \ No newline at end of file +export { ContextMenu as default }; \ No newline at end of file diff --git a/apps/documenteditor/mobile/src/page/main.jsx b/apps/documenteditor/mobile/src/page/main.jsx index 8775dcdd7..be5a0685e 100644 --- a/apps/documenteditor/mobile/src/page/main.jsx +++ b/apps/documenteditor/mobile/src/page/main.jsx @@ -11,7 +11,7 @@ import Collaboration from '../../../../common/mobile/lib/view/collaboration/Coll import { AddCommentController } from '../../../../common/mobile/lib/controller/collaboration/Comments.jsx'; import { Device } from '../../../../common/mobile/utils/device' import { Search, SearchSettings } from '../controller/Search'; -import { ContextMenu, idContextMenuElement } from '../controller/ContextMenu'; +import ContextMenu from '../controller/ContextMenu'; export default class MainPage extends Component { constructor(props) { @@ -25,7 +25,7 @@ export default class MainPage extends Component { } handleClickToOpenOptions = opts => { - f7.popover.close(idContextMenuElement, false); + ContextMenu.closeContextMenu(); this.setState(state => { if ( opts == 'edit' ) diff --git a/apps/documenteditor/mobile/src/store/appOptions.js b/apps/documenteditor/mobile/src/store/appOptions.js index 5020a25a8..998753556 100644 --- a/apps/documenteditor/mobile/src/store/appOptions.js +++ b/apps/documenteditor/mobile/src/store/appOptions.js @@ -1,6 +1,14 @@ import {action, observable} from 'mobx'; export class storeAppOptions { + constructor() { + // makeObservable(this); + } + + @observable isEdit = false; + @observable canViewComments = false; + @observable canReview = false; + config = {}; @action setConfigOptions (config) { this.config = config; From 8410b269c4416f71519b05195e8eb637fe19c091 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Wed, 3 Mar 2021 19:49:36 +0300 Subject: [PATCH 02/13] [mobile] Comments (edit comment, add reply) --- .../lib/controller/collaboration/Comments.jsx | 131 ++++++++--- apps/common/mobile/lib/store/comments.js | 18 ++ .../lib/view/collaboration/Comments.jsx | 207 +++++++++++++++++- .../mobile/resources/less/comments.less | 6 +- .../mobile/src/controller/Main.jsx | 3 +- 5 files changed, 317 insertions(+), 48 deletions(-) diff --git a/apps/common/mobile/lib/controller/collaboration/Comments.jsx b/apps/common/mobile/lib/controller/collaboration/Comments.jsx index a55dff87d..9db80cab2 100644 --- a/apps/common/mobile/lib/controller/collaboration/Comments.jsx +++ b/apps/common/mobile/lib/controller/collaboration/Comments.jsx @@ -5,7 +5,7 @@ import {Device} from '../../../../../common/mobile/utils/device'; import { withTranslation} from 'react-i18next'; import { LocalStorage } from '../../../utils/LocalStorage'; -import {AddComment, EditComment, ViewComments} from '../../view/collaboration/Comments'; +import {AddComment, EditComment, AddReply, ViewComments} from '../../view/collaboration/Comments'; // utils const timeZoneOffsetInMs = (new Date()).getTimezoneOffset() * 60000; @@ -266,23 +266,23 @@ class AddCommentController extends Component { } } -class ViewCommentsController extends Component { +class EditCommentController extends Component { constructor (props) { super(props); - this.onCommentMenuClick = this.onCommentMenuClick.bind(this); - this.onResolveComment = this.onResolveComment.bind(this); this.onEditComment = this.onEditComment.bind(this); - this.closeEditComment = this.closeEditComment.bind(this); - + this.onAddReply = this.onAddReply.bind(this); + } + getUserInfo () { this.currentUser = this.props.users.currentUser; - - this.state = { - showEditComment: false, - showEditReply: false + const name = this.currentUser.asc_getUserName(); + return { + name: name, + initials: this.props.users.getInitials(name), + color: this.currentUser.asc_getColor() }; } onChangeComment (comment) { - const ascComment = !!Asc.asc_CCommentDataWord ? new Asc.asc_CCommentDataWord(null) : new Asc.asc_CCommentData(null); + const ascComment = typeof Asc.asc_CCommentDataWord !== 'undefined' ? new Asc.asc_CCommentDataWord(null) : new Asc.asc_CCommentData(null); if (ascComment && comment) { ascComment.asc_putText(comment.comment); ascComment.asc_putQuoteText(comment.quote); @@ -316,6 +316,86 @@ class ViewCommentsController extends Component { api.asc_changeComment(comment.uid, ascComment); } } + onEditComment (comment, text) { + comment.comment = text.trim(); + const user = this.props.users.currentUser; + comment.userid = user.asc_getIdOriginal(); + comment.username = user.asc_getUserName(); + this.onChangeComment(comment); + } + onAddReply (comment, replyVal) { + let reply = null; + let addReply = null; + const ascComment = (typeof Asc.asc_CCommentDataWord !== 'undefined' ? new Asc.asc_CCommentDataWord(null) : new Asc.asc_CCommentData(null)); + + if (ascComment) { + ascComment.asc_putText(comment.comment); + ascComment.asc_putQuoteText(comment.quote); + ascComment.asc_putTime(utcDateToString(new Date(comment.time))); + ascComment.asc_putOnlyOfficeTime(ooDateToString(new Date(comment.time))); + ascComment.asc_putUserId(comment.userId); + ascComment.asc_putUserName(comment.userName); + ascComment.asc_putSolved(comment.resolved); + ascComment.asc_putGuid(comment.guid); + + if (!!ascComment.asc_putDocumentFlag) { + ascComment.asc_putDocumentFlag(comment.unattached); + } + + reply = comment.replies; + if (reply && reply.length) { + reply.forEach(function (reply) { + + addReply = (typeof Asc.asc_CCommentDataWord !== 'undefined' ? new Asc.asc_CCommentDataWord(null) : new Asc.asc_CCommentData(null)); + if (addReply) { + addReply.asc_putText(reply.reply); + addReply.asc_putTime(utcDateToString(new Date(reply.time))); + addReply.asc_putOnlyOfficeTime(ooDateToString(new Date(reply.time))); + addReply.asc_putUserId(reply.userId); + addReply.asc_putUserName(reply.userName); + + ascComment.asc_addReply(addReply); + } + }); + } + + addReply = (typeof Asc.asc_CCommentDataWord !== 'undefined' ? new Asc.asc_CCommentDataWord(null) : new Asc.asc_CCommentData(null)); + if (addReply) { + addReply.asc_putText(replyVal); + addReply.asc_putTime(utcDateToString(new Date())); + addReply.asc_putOnlyOfficeTime(ooDateToString(new Date())); + const currentUser = this.props.users.currentUser; + addReply.asc_putUserId(currentUser.asc_getIdOriginal()); + addReply.asc_putUserName(currentUser.asc_getUserName()); + + ascComment.asc_addReply(addReply); + + const api = Common.EditorApi.get(); + api.asc_changeComment(comment.uid, ascComment); + } + } + } + render() { + const storeComments = this.props.storeComments; + const comment = storeComments.currentComment; + return ( + + {storeComments.isOpenEditComment && } + {storeComments.isOpenAddReply && } + + ) + } +} + +class ViewCommentsController extends Component { + constructor (props) { + super(props); + this.onCommentMenuClick = this.onCommentMenuClick.bind(this); + this.onResolveComment = this.onResolveComment.bind(this); + this.closeEditComment = this.closeEditComment.bind(this); + + this.currentUser = this.props.users.currentUser; + } onResolveComment (comment) { let reply = null, addReply = null, @@ -358,12 +438,6 @@ class ViewCommentsController extends Component { const api = Common.EditorApi.get(); comment && api.asc_removeComment(comment.uid); } - onEditComment (comment, text) { - comment.comment = text.trim(); - comment.userid = this.currentUser.asc_getIdOriginal(); - comment.username = this.currentUser.asc_getUserName(); - this.onChangeComment(comment); - } deleteReply (comment, indReply) { let replies = null, addReply = null, @@ -409,14 +483,7 @@ class ViewCommentsController extends Component { const _t = t("Common.Collaboration", { returnObjects: true }); switch (action) { case 'editComment': - this.setState({ - showEditComment: true, - editProps: { - comment: comment, - onEditComment: this.onEditComment - } - }); - console.log('editComment'); + this.props.storeComments.openEditComment(true, comment); break; case 'resolve': this.onResolveComment(comment); @@ -444,7 +511,7 @@ class ViewCommentsController extends Component { ); break; case 'addReply': - console.log('addReply'); + this.props.storeComments.openAddReply(true, comment); break; } } @@ -454,23 +521,21 @@ class ViewCommentsController extends Component { } render() { return( - - - {this.state.showEditComment && } - + ) } } const _CommentsController = inject('storeAppOptions', 'storeComments', 'users')(observer(CommentsController)); const _AddCommentController = inject('storeAppOptions', 'storeComments', 'users')(observer(AddCommentController)); +const _EditCommentController = inject('storeComments', 'users')(observer(EditCommentController)); const _ViewCommentsController = inject('storeComments', 'users')(observer(withTranslation()(ViewCommentsController))); export { _CommentsController as CommentsController, _AddCommentController as AddCommentController, + _EditCommentController as EditCommentController, _ViewCommentsController as ViewCommentsController }; \ No newline at end of file diff --git a/apps/common/mobile/lib/store/comments.js b/apps/common/mobile/lib/store/comments.js index 345636f10..fff628012 100644 --- a/apps/common/mobile/lib/store/comments.js +++ b/apps/common/mobile/lib/store/comments.js @@ -110,4 +110,22 @@ export class storeComments { this.isOpenAddComment = open; } } + + // Edit comment + currentComment = null; + @observable isOpenEditComment = false; + @action openEditComment (open, comment) { + if (open !== this.isOpenEditComment) { + this.currentComment = open ? comment : null; + this.isOpenEditComment = open; + } + } + + @observable isOpenAddReply = false; + @action openAddReply (open, comment) { + if (open !== this.isOpenAddReply) { + this.currentComment = open ? comment : null; + this.isOpenAddReply = open; + } + } } \ No newline at end of file diff --git a/apps/common/mobile/lib/view/collaboration/Comments.jsx b/apps/common/mobile/lib/view/collaboration/Comments.jsx index 10bb4a25f..50899d6da 100644 --- a/apps/common/mobile/lib/view/collaboration/Comments.jsx +++ b/apps/common/mobile/lib/view/collaboration/Comments.jsx @@ -149,18 +149,20 @@ const CommentActions = ({comment, onCommentMenuClick, opened, openActionComment} }; // Edit comment -const EditCommentPopup = ({comment, onEditComment, opened, close}) => { +const EditCommentPopup = inject("storeComments")(observer(({storeComments, comment, onEditComment}) => { const { t } = useTranslation(); const _t = t('Common.Collaboration', {returnObjects: true}); + useEffect(() => { + f7.popup.open('.edit-comment-popup'); + }); const [stateText, setText] = useState(comment.comment); - console.log(comment); return ( - + { - close(); - //f7.popup.close('.edit-comment-popup'); + f7.popup.close('.edit-comment-popup'); + storeComments.openEditComment(false); }}>{_t.textCancel} {_t.textEditComment} @@ -168,8 +170,8 @@ const EditCommentPopup = ({comment, onEditComment, opened, close}) => { { onEditComment(comment, stateText); - close(); - //f7.popup.close('.edit-comment-popup'); + f7.popup.close('.edit-comment-popup'); + storeComments.openEditComment(false); }} > {Device.android ? : _t.textDone} @@ -192,13 +194,195 @@ const EditCommentPopup = ({comment, onEditComment, opened, close}) => { ) -}; +})); -const EditComment = ({editProps, opened, close}) => { +const EditCommentDialog = inject("storeComments")(observer(({storeComments, comment, onEditComment}) => { + const { t } = useTranslation(); + const _t = t('Common.Collaboration', {returnObjects: true}); + const templateInitials = `
${comment.userInitials}
`; + useEffect(() => { + f7.dialog.create({ + destroyOnClose: true, + containerEl: document.getElementById('edit-comment-dialog'), + content: + ` +
+
+ ${Device.android ? templateInitials : ''} +
+
${comment.userName}
+
${comment.date}
+
+
+
+ +
+
`, + on: { + opened: () => { + const cancel = document.getElementById('comment-cancel'); + cancel.addEventListener('click', () => { + f7.dialog.close(); + storeComments.openEditComment(false); + }); + const done = document.getElementById('comment-done'); + done.addEventListener('click', () => { + const value = document.getElementById('comment-text').value; + if (value.length > 0) { + onEditComment(comment, value); + f7.dialog.close(); + storeComments.openEditComment(false); + } + }); + const area = document.getElementById('comment-text'); + area.addEventListener('input', (event) => { + if (event.target.value.length === 0 && !done.classList.contains('disabled')) { + done.classList.add('disabled'); + } else if (event.target.value.length > 0 && done.classList.contains('disabled')) { + done.classList.remove('disabled'); + } + }); + done.classList.add('disabled'); + } + } + }).open(); + }); + return ( +
+ ); +})); + +const EditComment = ({comment, onEditComment}) => { return ( Device.phone ? - : - + : + + ) +}; + +const AddReplyPopup = inject("storeComments")(observer(({storeComments, userInfo, comment, onAddReply}) => { + const { t } = useTranslation(); + const _t = t('Common.Collaboration', {returnObjects: true}); + useEffect(() => { + f7.popup.open('.add-reply-popup'); + }); + const [stateText, setText] = useState(''); + return ( + + + + { + storeComments.openAddReply(false); + f7.popup.close('.add-reply-popup'); + }}>{_t.textCancel} + + {_t.textAddReply} + + { + onAddReply(comment, stateText); + storeComments.openAddReply(false); + f7.popup.close('.add-reply-popup'); + }}> + {Device.android ? : _t.textDone} + + + +
+
+ {Device.android && +
{userInfo.initials}
+ } +
{userInfo.name}
+
+
+ {setText(event.target.value);}}> +
+
+
+ ) +})); + +const AddReplyDialog = inject("storeComments")(observer(({storeComments, userInfo, comment, onAddReply}) => { + const { t } = useTranslation(); + const _t = t('Common.Collaboration', {returnObjects: true}); + const templateInitials = `
${userInfo.initials}
`; + useEffect(() => { + f7.dialog.create({ + destroyOnClose: true, + containerEl: document.getElementById('add-reply-dialog'), + content: + ` +
+
+ ${Device.android ? templateInitials : ''} +
${userInfo.name}
+
+
+ +
+
`, + on: { + opened: () => { + const cancel = document.getElementById('reply-cancel'); + cancel.addEventListener('click', () => { + f7.dialog.close(); + storeComments.openAddReply(false); + }); + const done = document.getElementById('reply-done'); + done.addEventListener('click', () => { + const value = document.getElementById('reply-text').value; + if (value.length > 0) { + onAddReply(comment, value); + f7.dialog.close(); + storeComments.openAddReply(false); + } + }); + const area = document.getElementById('reply-text'); + area.addEventListener('input', (event) => { + if (event.target.value.length === 0 && !done.classList.contains('disabled')) { + done.classList.add('disabled'); + } else if (event.target.value.length > 0 && done.classList.contains('disabled')) { + done.classList.remove('disabled'); + } + }); + done.classList.add('disabled'); + } + } + }).open(); + }); + return ( +
+ ); +})); + +const AddReply = ({userInfo, comment, onAddReply}) => { + return ( + Device.phone ? + : + ) }; @@ -305,5 +489,6 @@ const _ViewComments = inject('storeComments', 'storeAppOptions')(observer(ViewCo export { AddComment, EditComment, + AddReply, _ViewComments as ViewComments } diff --git a/apps/common/mobile/resources/less/comments.less b/apps/common/mobile/resources/less/comments.less index abc2140ad..115164539 100644 --- a/apps/common/mobile/resources/less/comments.less +++ b/apps/common/mobile/resources/less/comments.less @@ -17,14 +17,14 @@ } } } -#add-comment-dialog { +#add-comment-dialog, #edit-comment-dialog, #add-reply-dialog { .dialog { --f7-dialog-width: 400px; .dialog-inner { padding: 0; height: 400px; .wrap-comment { - .name { + .name, .comment-date { text-align: left; } .wrap-textarea { @@ -101,6 +101,6 @@ } } -.edit-comment-popup { +.edit-comment-popup, .add-reply-popup { z-index: 20000; } \ No newline at end of file diff --git a/apps/documenteditor/mobile/src/controller/Main.jsx b/apps/documenteditor/mobile/src/controller/Main.jsx index 3bd8fa965..f4f9989e1 100644 --- a/apps/documenteditor/mobile/src/controller/Main.jsx +++ b/apps/documenteditor/mobile/src/controller/Main.jsx @@ -6,7 +6,7 @@ import { withTranslation } from 'react-i18next'; import CollaborationController from '../../../../common/mobile/lib/controller/collaboration/Collaboration.jsx'; import {InitReviewController as ReviewController} from '../../../../common/mobile/lib/controller/collaboration/Review.jsx'; import { onAdvancedOptions } from './settings/Download.jsx'; -import {CommentsController, AddCommentController} from "../../../../common/mobile/lib/controller/collaboration/Comments"; +import {CommentsController, AddCommentController, EditCommentController} from "../../../../common/mobile/lib/controller/collaboration/Comments"; @inject( "storeAppOptions", @@ -335,6 +335,7 @@ class MainController extends Component { + ) } From e8749b09d62ce4fd5c5312bebf9773c491f5aaa2 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Wed, 3 Mar 2021 21:21:03 +0300 Subject: [PATCH 03/13] [mobile] Comments (edit reply) --- .../lib/controller/collaboration/Comments.jsx | 23 ++- apps/common/mobile/lib/store/comments.js | 10 ++ .../lib/view/collaboration/Comments.jsx | 156 +++++++++++++++++- .../mobile/resources/less/comments.less | 6 +- apps/documenteditor/mobile/locale/en.json | 3 +- 5 files changed, 184 insertions(+), 14 deletions(-) diff --git a/apps/common/mobile/lib/controller/collaboration/Comments.jsx b/apps/common/mobile/lib/controller/collaboration/Comments.jsx index 9db80cab2..97237c753 100644 --- a/apps/common/mobile/lib/controller/collaboration/Comments.jsx +++ b/apps/common/mobile/lib/controller/collaboration/Comments.jsx @@ -5,7 +5,7 @@ import {Device} from '../../../../../common/mobile/utils/device'; import { withTranslation} from 'react-i18next'; import { LocalStorage } from '../../../utils/LocalStorage'; -import {AddComment, EditComment, AddReply, ViewComments} from '../../view/collaboration/Comments'; +import {AddComment, EditComment, AddReply, EditReply, ViewComments} from '../../view/collaboration/Comments'; // utils const timeZoneOffsetInMs = (new Date()).getTimezoneOffset() * 60000; @@ -271,6 +271,7 @@ class EditCommentController extends Component { super(props); this.onEditComment = this.onEditComment.bind(this); this.onAddReply = this.onAddReply.bind(this); + this.onEditReply = this.onEditReply.bind(this); } getUserInfo () { this.currentUser = this.props.users.currentUser; @@ -375,6 +376,14 @@ class EditCommentController extends Component { } } } + onEditReply (comment, reply, textReply) { + const currentUser = this.props.users.currentUser; + const indReply = reply.ind; + comment.replies[indReply].reply = textReply; + comment.replies[indReply].userid = currentUser.asc_getIdOriginal(); + comment.replies[indReply].username = currentUser.asc_getUserName(); + this.onChangeComment(comment); + } render() { const storeComments = this.props.storeComments; const comment = storeComments.currentComment; @@ -382,6 +391,7 @@ class EditCommentController extends Component { {storeComments.isOpenEditComment && } {storeComments.isOpenAddReply && } + {storeComments.isOpenEditReply && } ) } @@ -438,11 +448,13 @@ class ViewCommentsController extends Component { const api = Common.EditorApi.get(); comment && api.asc_removeComment(comment.uid); } - deleteReply (comment, indReply) { + deleteReply (comment, reply) { let replies = null, addReply = null, ascComment = (!!Asc.asc_CCommentDataWord ? new Asc.asc_CCommentDataWord(null) : new Asc.asc_CCommentData(null)); + const indReply = reply.ind; + if (ascComment && comment) { ascComment.asc_putText(comment.comment); ascComment.asc_putQuoteText(comment.quote); @@ -478,7 +490,7 @@ class ViewCommentsController extends Component { api.asc_changeComment(comment.uid, ascComment); } } - onCommentMenuClick (action, comment) { + onCommentMenuClick (action, comment, reply) { const { t } = this.props; const _t = t("Common.Collaboration", { returnObjects: true }); switch (action) { @@ -498,15 +510,14 @@ class ViewCommentsController extends Component { ); break; case 'editReply': - this.setState({showEditReply: true}); - console.log('editReply'); + this.props.storeComments.openEditReply(true, comment, reply); break; case 'deleteReply': f7.dialog.confirm( _t.textMessageDeleteReply, _t.textDeleteReply, () => { - this.deleteReply(comment, indReply); + this.deleteReply(comment, reply); } ); break; diff --git a/apps/common/mobile/lib/store/comments.js b/apps/common/mobile/lib/store/comments.js index fff628012..145434609 100644 --- a/apps/common/mobile/lib/store/comments.js +++ b/apps/common/mobile/lib/store/comments.js @@ -121,6 +121,7 @@ export class storeComments { } } + currentReply = null; @observable isOpenAddReply = false; @action openAddReply (open, comment) { if (open !== this.isOpenAddReply) { @@ -128,4 +129,13 @@ export class storeComments { this.isOpenAddReply = open; } } + + @observable isOpenEditReply = false; + @action openEditReply (open, comment, reply) { + if (open !== this.isOpenEditReply) { + this.currentComment = open ? comment : null; + this.currentReply = open ? reply : null; + this.isOpenEditReply = open; + } + } } \ No newline at end of file diff --git a/apps/common/mobile/lib/view/collaboration/Comments.jsx b/apps/common/mobile/lib/view/collaboration/Comments.jsx index 50899d6da..0a3432c24 100644 --- a/apps/common/mobile/lib/view/collaboration/Comments.jsx +++ b/apps/common/mobile/lib/view/collaboration/Comments.jsx @@ -148,6 +148,25 @@ const CommentActions = ({comment, onCommentMenuClick, opened, openActionComment} ) }; +const ReplyActions = ({comment, reply, onCommentMenuClick, opened, openActionReply}) => { + const { t } = useTranslation(); + const _t = t('Common.Collaboration', {returnObjects: true}); + return ( + openActionReply(false)}> + + {reply && + {reply.editable && {onCommentMenuClick('editReply', comment, reply);}}>{_t.textEdit}} + {reply.removable && {onCommentMenuClick('deleteReply', comment, reply);}}>{_t.textDeleteReply}} + + } + + + {_t.textCancel} + + + ) +}; + // Edit comment const EditCommentPopup = inject("storeComments")(observer(({storeComments, comment, onEditComment}) => { const { t } = useTranslation(); @@ -253,7 +272,6 @@ const EditCommentDialog = inject("storeComments")(observer(({storeComments, comm done.classList.remove('disabled'); } }); - done.classList.add('disabled'); } } }).open(); @@ -386,6 +404,127 @@ const AddReply = ({userInfo, comment, onAddReply}) => { ) }; +const EditReplyPopup = inject("storeComments")(observer(({storeComments, comment, reply, onEditReply}) => { + const { t } = useTranslation(); + const _t = t('Common.Collaboration', {returnObjects: true}); + useEffect(() => { + f7.popup.open('.edit-reply-popup'); + }); + const [stateText, setText] = useState(reply.reply); + return ( + + + + { + f7.popup.close('.edit-reply-popup'); + storeComments.openEditReply(false); + }}>{_t.textCancel} + + {_t.textEditReply} + + { + onEditReply(comment, reply, stateText); + f7.popup.close('.edit-reply-popup'); + storeComments.openEditReply(false); + }} + > + {Device.android ? : _t.textDone} + + + +
+
+ {Device.android && +
{reply.userInitials}
+ } +
+
{reply.userName}
+
{reply.date}
+
+
+
+ {setText(event.target.value);}}> +
+
+
+ ) +})); + +const EditReplyDialog = inject("storeComments")(observer(({storeComments, comment, reply, onEditReply}) => { + const { t } = useTranslation(); + const _t = t('Common.Collaboration', {returnObjects: true}); + const templateInitials = `
${reply.userInitials}
`; + useEffect(() => { + f7.dialog.create({ + destroyOnClose: true, + containerEl: document.getElementById('edit-reply-dialog'), + content: + ` +
+
+ ${Device.android ? templateInitials : ''} +
+
${reply.userName}
+
${reply.date}
+
+
+
+ +
+
`, + on: { + opened: () => { + const cancel = document.getElementById('reply-cancel'); + cancel.addEventListener('click', () => { + f7.dialog.close(); + storeComments.openEditReply(false); + }); + const done = document.getElementById('reply-done'); + done.addEventListener('click', () => { + const value = document.getElementById('reply-text').value; + if (value.length > 0) { + onEditReply(comment, reply, value); + f7.dialog.close(); + storeComments.openEditReply(false); + } + }); + const area = document.getElementById('reply-text'); + area.addEventListener('input', (event) => { + if (event.target.value.length === 0 && !done.classList.contains('disabled')) { + done.classList.add('disabled'); + } else if (event.target.value.length > 0 && done.classList.contains('disabled')) { + done.classList.remove('disabled'); + } + }); + } + } + }).open(); + }); + return ( +
+ ); +})); + +const EditReply = ({comment, reply, onEditReply}) => { + return ( + Device.phone ? + : + + ) +}; + // View comments const ViewComments = ({storeComments, storeAppOptions, onCommentMenuClick, onResolveComment}) => { const { t } = useTranslation(); @@ -405,9 +544,12 @@ const ViewComments = ({storeComments, storeAppOptions, onCommentMenuClick, onRes } }; - const [clickComment, setClickComment] = useState(); + const [clickComment, setComment] = useState(); const [commentActionsOpened, openActionComment] = useState(false); + const [reply, setReply] = useState(); + const [replyActionsOpened, openActionReply] = useState(false); + return ( @@ -429,7 +571,7 @@ const ViewComments = ({storeComments, storeAppOptions, onCommentMenuClick, onRes
{onResolveComment(comment);}}>
{setClickComment(comment); openActionComment(true);}} + onClick={() => {setComment(comment); openActionComment(true);}} >
} @@ -457,7 +599,11 @@ const ViewComments = ({storeComments, storeAppOptions, onCommentMenuClick, onRes {!viewMode &&
-
+
{setComment(comment); setReply(reply); openActionReply(true);}} + > + +
} @@ -480,6 +626,7 @@ const ViewComments = ({storeComments, storeAppOptions, onCommentMenuClick, onRes } +
) }; @@ -490,5 +637,6 @@ export { AddComment, EditComment, AddReply, + EditReply, _ViewComments as ViewComments } diff --git a/apps/common/mobile/resources/less/comments.less b/apps/common/mobile/resources/less/comments.less index 115164539..c1cf3af2c 100644 --- a/apps/common/mobile/resources/less/comments.less +++ b/apps/common/mobile/resources/less/comments.less @@ -17,14 +17,14 @@ } } } -#add-comment-dialog, #edit-comment-dialog, #add-reply-dialog { +#add-comment-dialog, #edit-comment-dialog, #add-reply-dialog, #edit-reply-dialog { .dialog { --f7-dialog-width: 400px; .dialog-inner { padding: 0; height: 400px; .wrap-comment { - .name, .comment-date { + .name, .comment-date, .reply-date { text-align: left; } .wrap-textarea { @@ -101,6 +101,6 @@ } } -.edit-comment-popup, .add-reply-popup { +.edit-comment-popup, .add-reply-popup, .edit-reply-popup { z-index: 20000; } \ No newline at end of file diff --git a/apps/documenteditor/mobile/locale/en.json b/apps/documenteditor/mobile/locale/en.json index 00f9f0ea6..23eca76da 100644 --- a/apps/documenteditor/mobile/locale/en.json +++ b/apps/documenteditor/mobile/locale/en.json @@ -125,7 +125,8 @@ "textMessageDeleteComment": "Do you really want to delete this comment?", "textMessageDeleteReply": "Do you really want to delete this reply?", "textDeleteReply": "Delete Reply", - "textEditComment": "Edit Comment" + "textEditComment": "Edit Comment", + "textEditReply": "Edit Reply" } }, "Settings": { From 0f2a4d8138cbf8709a8aadb370a82b5839817a80 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Thu, 4 Mar 2021 20:24:35 +0300 Subject: [PATCH 04/13] [mobile] Fix comments --- apps/common/mobile/lib/controller/collaboration/Comments.jsx | 4 ++-- apps/common/mobile/lib/store/users.js | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/common/mobile/lib/controller/collaboration/Comments.jsx b/apps/common/mobile/lib/controller/collaboration/Comments.jsx index 97237c753..b363eb458 100644 --- a/apps/common/mobile/lib/controller/collaboration/Comments.jsx +++ b/apps/common/mobile/lib/controller/collaboration/Comments.jsx @@ -113,9 +113,9 @@ class CommentsController extends Component { let user = this.usersStore.searchUserById(data.asc_getUserId()); comment.comment = data.asc_getText(); - comment.userid = data.asc_getUserId(); + comment.userId = data.asc_getUserId(); comment.userName = data.asc_getUserName(); - comment.usercolor = (user) ? user.asc_getColor() : null; + comment.userColor = (user) ? user.asc_getColor() : null; comment.resolved = data.asc_getSolved(); comment.quote = data.asc_getQuoteText(); comment.time = date.getTime(); diff --git a/apps/common/mobile/lib/store/users.js b/apps/common/mobile/lib/store/users.js index 3597f63a2..596955304 100644 --- a/apps/common/mobile/lib/store/users.js +++ b/apps/common/mobile/lib/store/users.js @@ -45,10 +45,12 @@ export class storeUsers { } searchUserById (id) { + let user = null; this.users.forEach((item) => { if (item.asc_getIdOriginal() === id) { - return item; + user = item; } }); + return user; } } From 7cf42452aee6bc13555f8099d46eba01d74489c4 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Thu, 4 Mar 2021 20:25:50 +0300 Subject: [PATCH 05/13] [mobile] Add styles of comments for android --- .../lib/view/collaboration/Comments.jsx | 14 ++--- .../mobile/resources/less/comments.less | 2 +- .../resources/less/material/comments.less | 62 +++++++++++++++++-- 3 files changed, 64 insertions(+), 14 deletions(-) diff --git a/apps/common/mobile/lib/view/collaboration/Comments.jsx b/apps/common/mobile/lib/view/collaboration/Comments.jsx index 0a3432c24..d90cc3886 100644 --- a/apps/common/mobile/lib/view/collaboration/Comments.jsx +++ b/apps/common/mobile/lib/view/collaboration/Comments.jsx @@ -37,7 +37,7 @@ const AddCommentPopup = inject("storeComments")(observer(props => {
-
+
{Device.android &&
{userInfo.initials}
} @@ -74,7 +74,7 @@ const AddCommentDialog = inject("storeComments")(observer(props => {
-
+
${Device.android ? templateInitials : ''}
${userInfo.name}
@@ -237,7 +237,7 @@ const EditCommentDialog = inject("storeComments")(observer(({storeComments, comm
-
+
${Device.android ? templateInitials : ''}
${comment.userName}
@@ -318,7 +318,7 @@ const AddReplyPopup = inject("storeComments")(observer(({storeComments, userInfo
-
+
{Device.android &&
{userInfo.initials}
} @@ -354,7 +354,7 @@ const AddReplyDialog = inject("storeComments")(observer(({storeComments, userInf
-
+
${Device.android ? templateInitials : ''}
${userInfo.name}
@@ -473,7 +473,7 @@ const EditReplyDialog = inject("storeComments")(observer(({storeComments, commen
-
+
${Device.android ? templateInitials : ''}
${reply.userName}
@@ -580,7 +580,7 @@ const ViewComments = ({storeComments, storeAppOptions, onCommentMenuClick, onRes {comment.quote &&
{sliceQuote(comment.quote)}
}
{comment.comment}
{comment.replies.length > 0 && -
    +
      {comment.replies.map((reply, indexReply) => { return (
    • Date: Fri, 5 Mar 2021 18:23:35 +0300 Subject: [PATCH 06/13] [mobile] Open add comment from context menu --- .../lib/controller/collaboration/Comments.jsx | 19 +++++++---- apps/common/mobile/lib/store/comments.js | 9 ------ .../lib/view/collaboration/Comments.jsx | 12 +++---- .../mobile/src/controller/ContextMenu.jsx | 32 ++++++++++++++++--- apps/documenteditor/mobile/src/page/main.jsx | 1 - .../mobile/src/view/add/AddOther.jsx | 2 +- 6 files changed, 48 insertions(+), 27 deletions(-) diff --git a/apps/common/mobile/lib/controller/collaboration/Comments.jsx b/apps/common/mobile/lib/controller/collaboration/Comments.jsx index b363eb458..331adc103 100644 --- a/apps/common/mobile/lib/controller/collaboration/Comments.jsx +++ b/apps/common/mobile/lib/controller/collaboration/Comments.jsx @@ -218,8 +218,20 @@ class CommentsController extends Component { class AddCommentController extends Component { constructor(props) { super(props); + this.closeAddComment = this.closeAddComment.bind(this); this.getUserInfo = this.getUserInfo.bind(this); this.onAddNewComment = this.onAddNewComment.bind(this); + + this.state = { + isOpen: false + }; + + Common.Notifications.on('addcomment', () => { + this.setState({isOpen: true}); + }); + } + closeAddComment () { + this.setState({isOpen: false}); } getUserInfo () { this.currentUser = this.props.users.currentUser; @@ -255,13 +267,8 @@ class AddCommentController extends Component { return false; } render() { - const isOpen = this.props.storeComments.isOpenAddComment; - let userInfo; - if (isOpen) { - userInfo = this.getUserInfo(); - } return( - isOpen ? : null + this.state.isOpen ? : null ) } } diff --git a/apps/common/mobile/lib/store/comments.js b/apps/common/mobile/lib/store/comments.js index 145434609..ee08defaf 100644 --- a/apps/common/mobile/lib/store/comments.js +++ b/apps/common/mobile/lib/store/comments.js @@ -102,15 +102,6 @@ export class storeComments { return false; } - // Add comment modal window - @observable isOpenAddComment = false; - - @action openAddComment (open) { - if (open !== this.isOpenAddComment) { - this.isOpenAddComment = open; - } - } - // Edit comment currentComment = null; @observable isOpenEditComment = false; diff --git a/apps/common/mobile/lib/view/collaboration/Comments.jsx b/apps/common/mobile/lib/view/collaboration/Comments.jsx index d90cc3886..16f1ba3ce 100644 --- a/apps/common/mobile/lib/view/collaboration/Comments.jsx +++ b/apps/common/mobile/lib/view/collaboration/Comments.jsx @@ -19,7 +19,7 @@ const AddCommentPopup = inject("storeComments")(observer(props => { { - props.storeComments.openAddComment(false); + props.closeAddComment(); f7.popup.close('.add-comment-popup'); }}>{_t.textCancel} @@ -28,7 +28,7 @@ const AddCommentPopup = inject("storeComments")(observer(props => { { if (props.onAddNewComment(stateText, false)) { - props.storeComments.openAddComment(false); + props.closeAddComment(); f7.popup.close('.add-comment-popup'); } }}> @@ -87,14 +87,14 @@ const AddCommentDialog = inject("storeComments")(observer(props => { const cancel = document.getElementById('comment-cancel'); cancel.addEventListener('click', () => { f7.dialog.close(); - props.storeComments.openAddComment(false); + props.closeAddComment(); }); const done = document.getElementById('comment-done'); done.addEventListener('click', () => { const value = document.getElementById('comment-text').value; if (value.length > 0 && props.onAddNewComment(value, false)) { f7.dialog.close(); - props.storeComments.openAddComment(false); + props.closeAddComment(); } }); const area = document.getElementById('comment-text'); @@ -118,8 +118,8 @@ const AddCommentDialog = inject("storeComments")(observer(props => { const AddComment = props => { return ( Device.phone ? - : - + : + ) }; diff --git a/apps/documenteditor/mobile/src/controller/ContextMenu.jsx b/apps/documenteditor/mobile/src/controller/ContextMenu.jsx index 5a09e6f84..3e11cd706 100644 --- a/apps/documenteditor/mobile/src/controller/ContextMenu.jsx +++ b/apps/documenteditor/mobile/src/controller/ContextMenu.jsx @@ -47,6 +47,12 @@ class ContextMenu extends ContextMenuController { onMenuItemClick(action) { super.onMenuItemClick(action); + switch (action) { + case 'addcomment': + Common.Notifications.trigger('addcomment'); + break; + } + console.log("click context menu item: " + action); } @@ -78,7 +84,7 @@ class ContextMenu extends ContextMenuController { }); } - if ( canViewComments && this.isComments && isEdit ) { + if ( canViewComments && this.isComments && !isEdit ) { itemsText.push({ caption: /*me.menuViewComment*/'View Comment', event: 'viewcomment' @@ -152,6 +158,24 @@ class ContextMenu extends ContextMenuController { }); } + // For test + if ( this.isComments && canViewComments ) { + itemsText.push({ + caption: /*me.menuViewComment*/'View Comment', + event: 'viewcomment' + }); + } + + const isObject = isShape || isChart || isImage || isTable; + const hideAddComment = !canViewComments || api.can_AddQuotedComment() === false || lockedText || lockedTable || lockedImage || lockedHeader || (!isText && isObject); + if ( !hideAddComment ) { + itemsText.push({ + caption: /*me.menuAddComment*/'Add Comment', + event: 'addcomment' + }); + } + // end test + if ( isTable && api.CheckBeforeMergeCells() && !lockedTable && !lockedHeader) { itemsText.push({ caption: /*me.menuMerge*/'Merge', @@ -215,14 +239,14 @@ class ContextMenu extends ContextMenuController { }); } - const isObject = isShape || isChart || isImage || isTable; + /*const isObject = isShape || isChart || isImage || isTable; const hideAddComment = !canViewComments || api.can_AddQuotedComment() === false || lockedText || lockedTable || lockedImage || lockedHeader || (!isText && isObject); if ( !hideAddComment ) { itemsText.push({ - caption: /*me.menuAddComment*/'Add Comment', + caption: 'Add Comment', event: 'addcomment' }); - } + }*/ } } diff --git a/apps/documenteditor/mobile/src/page/main.jsx b/apps/documenteditor/mobile/src/page/main.jsx index be5a0685e..fbed1a5e1 100644 --- a/apps/documenteditor/mobile/src/page/main.jsx +++ b/apps/documenteditor/mobile/src/page/main.jsx @@ -8,7 +8,6 @@ import EditOptions from '../view/edit/Edit'; import AddOptions from '../view/add/Add'; import Settings from '../view/settings/Settings'; import Collaboration from '../../../../common/mobile/lib/view/collaboration/Collaboration.jsx' -import { AddCommentController } from '../../../../common/mobile/lib/controller/collaboration/Comments.jsx'; import { Device } from '../../../../common/mobile/utils/device' import { Search, SearchSettings } from '../controller/Search'; import ContextMenu from '../controller/ContextMenu'; diff --git a/apps/documenteditor/mobile/src/view/add/AddOther.jsx b/apps/documenteditor/mobile/src/view/add/AddOther.jsx index 15dc2e139..25040fc49 100644 --- a/apps/documenteditor/mobile/src/view/add/AddOther.jsx +++ b/apps/documenteditor/mobile/src/view/add/AddOther.jsx @@ -202,7 +202,7 @@ const AddOther = props => { { props.closeModal(); - props.storeComments.openAddComment(true); + Common.Notifications.trigger('addcomment'); }}> From 1232c64fc7d26a60dd43cce3a6fba63443cc68d0 Mon Sep 17 00:00:00 2001 From: Maxim Kadushkin Date: Sun, 7 Mar 2021 23:40:54 +0300 Subject: [PATCH 07/13] [common] mobx version is up to 6 --- vendor/framework7-react/babel.config.js | 2 +- vendor/framework7-react/package.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/vendor/framework7-react/babel.config.js b/vendor/framework7-react/babel.config.js index a899c701d..b6def8dbb 100644 --- a/vendor/framework7-react/babel.config.js +++ b/vendor/framework7-react/babel.config.js @@ -9,6 +9,6 @@ module.exports = { '@babel/plugin-transform-runtime', '@babel/plugin-syntax-dynamic-import', ['@babel/plugin-proposal-decorators', {'legacy': true }], - ['@babel/plugin-proposal-class-properties',{'loose':true}], + ['@babel/plugin-proposal-class-properties',{'loose':false}], ], }; diff --git a/vendor/framework7-react/package.json b/vendor/framework7-react/package.json index 2cfa15418..a7e241a4d 100644 --- a/vendor/framework7-react/package.json +++ b/vendor/framework7-react/package.json @@ -58,8 +58,8 @@ "less": "^3.13.1", "less-loader": "^6.2.0", "mini-css-extract-plugin": "^0.9.0", - "mobx": "^5.15.7", - "mobx-react": "^6.3.1", + "mobx": "^6.1.8", + "mobx-react": "^7.1.0", "optimize-css-assets-webpack-plugin": "^5.0.4", "ora": "^4.1.1", "postcss-loader": "^3.0.0", From 46747c223ad5a72c2324607e07f94b65df6db726 Mon Sep 17 00:00:00 2001 From: Maxim Kadushkin Date: Sun, 7 Mar 2021 23:43:22 +0300 Subject: [PATCH 08/13] [DE mobile] fix some stores according to mobx v. 6 --- .../mobile/src/store/applicationSettings.js | 52 ++++++++++++------- .../mobile/src/store/tableSettings.js | 6 ++- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/apps/documenteditor/mobile/src/store/applicationSettings.js b/apps/documenteditor/mobile/src/store/applicationSettings.js index 968c84b78..a1e17a40c 100644 --- a/apps/documenteditor/mobile/src/store/applicationSettings.js +++ b/apps/documenteditor/mobile/src/store/applicationSettings.js @@ -1,45 +1,59 @@ -import {action, observable} from 'mobx'; +import {makeObservable, action, observable} from 'mobx'; export class storeApplicationSettings { - - @observable unitMeasurement = 1; + constructor() { + makeObservable(this, { + unitMeasurement: observable + , isSpellChecking: observable + , isNonprintingCharacters: observable + , isHiddenTableBorders: observable + , isComments: observable + , isResolvedComments: observable + , macrosMode: observable + , changeSpellCheck: action + , changeUnitMeasurement: action + , changeNoCharacters: action + , changeShowTableEmptyLine: action + , changeDisplayComments: action + , changeDisplayResolved: action + , changeMacrosSettings: action + }) + } - @observable isSpellChecking = true; + unitMeasurement = 1; + isSpellChecking = true; + isNonprintingCharacters = false; + isHiddenTableBorders = false; + isComments = true; + isResolvedComments = true; + macrosMode = 0; - @observable isNonprintingCharacters = false; - @observable isHiddenTableBorders = false; - - @observable isComments = true; - @observable isResolvedComments = true; - - @observable macrosMode = 0; - - @action changeUnitMeasurement(value) { + changeUnitMeasurement(value) { this.unitMeasurement = +value; } - @action changeSpellCheck(value) { + changeSpellCheck(value) { this.isSpellChecking = value; } - @action changeNoCharacters(value) { + changeNoCharacters(value) { this.isNonprintingCharacters = value; } - @action changeShowTableEmptyLine(value) { + changeShowTableEmptyLine(value) { this.isHiddenTableBorders = value; } - @action changeDisplayComments(value) { + changeDisplayComments(value) { this.isComments = value; if (!value) this.changeDisplayResolved(value); } - @action changeDisplayResolved(value) { + changeDisplayResolved(value) { this.isResolvedComments = value; } - @action changeMacrosSettings(value) { + changeMacrosSettings(value) { this.macrosMode = +value; } } \ No newline at end of file diff --git a/apps/documenteditor/mobile/src/store/tableSettings.js b/apps/documenteditor/mobile/src/store/tableSettings.js index 440c1f658..7adc88958 100644 --- a/apps/documenteditor/mobile/src/store/tableSettings.js +++ b/apps/documenteditor/mobile/src/store/tableSettings.js @@ -1,7 +1,11 @@ -import {action, observable, computed} from 'mobx'; +import {makeObservable, action, observable, computed} from 'mobx'; import {f7} from 'framework7-react'; export class storeTableSettings { + constructor() { + makeObservable(this) + } + @observable _templates = []; @action initTableTemplates (templates) { this._templates = templates; From f63f4d3a7b01f33a41160d2dd86d904ad414ce06 Mon Sep 17 00:00:00 2001 From: Maxim Kadushkin Date: Sun, 7 Mar 2021 23:43:41 +0300 Subject: [PATCH 09/13] [DE mobile] refactoring --- .../src/controller/settings/ApplicationSettings.jsx | 13 +++++-------- .../mobile/src/store/tableSettings.js | 1 - 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/apps/documenteditor/mobile/src/controller/settings/ApplicationSettings.jsx b/apps/documenteditor/mobile/src/controller/settings/ApplicationSettings.jsx index 39b4fd77e..4f8275494 100644 --- a/apps/documenteditor/mobile/src/controller/settings/ApplicationSettings.jsx +++ b/apps/documenteditor/mobile/src/controller/settings/ApplicationSettings.jsx @@ -25,16 +25,14 @@ class ApplicationSettingsController extends Component { } switchNoCharacters(value) { - Common.localStorage.setItem("de-mobile-no-characters", value); + LocalStorage.setItem("de-mobile-no-characters", value); - const api = Common.EditorApi.get(); - api.put_ShowParaMarks(value); + Common.EditorApi.get().put_ShowParaMarks(value); } switchShowTableEmptyLine(value) { - Common.localStorage.setItem("de-mobile-hidden-borders", value); - const api = Common.EditorApi.get(); - api.put_ShowTableEmptyLine(value); + LocalStorage.setItem("de-mobile-hidden-borders", value); + Common.EditorApi.get().put_ShowTableEmptyLine(value); } switchDisplayComments(value) { @@ -51,10 +49,9 @@ class ApplicationSettingsController extends Component { } switchDisplayResolved(value) { - const api = Common.EditorApi.get(); const displayComments = LocalStorage.getBool("de-mobile-settings-livecomment"); if (displayComments) { - api.asc_showComments(value); + Common.EditorApi.get().asc_showComments(value); LocalStorage.setBool("de-settings-resolvedcomment", value); } } diff --git a/apps/documenteditor/mobile/src/store/tableSettings.js b/apps/documenteditor/mobile/src/store/tableSettings.js index 7adc88958..b40d71bc0 100644 --- a/apps/documenteditor/mobile/src/store/tableSettings.js +++ b/apps/documenteditor/mobile/src/store/tableSettings.js @@ -71,7 +71,6 @@ export class storeTableSettings { // Border style @observable cellBorders; @observable cellBorderWidth = 0.5; - @observable cellBorderWidth = 0.5; @observable cellBorderColor = '000000'; borderSizeTransform () { From 48c50b145bfdcc805121c1a9ed9936491b53ecaf Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Mon, 8 Mar 2021 21:30:42 +0300 Subject: [PATCH 10/13] [mobile] Make comment view from context menu --- .../lib/controller/collaboration/Comments.jsx | 26 ++-- .../lib/view/collaboration/Collaboration.jsx | 7 +- .../lib/view/collaboration/Comments.jsx | 133 +++++++++++++++++- .../mobile/resources/less/comments.less | 53 ++++++- apps/common/mobile/resources/less/common.less | 2 - .../mobile/resources/less/ios/icons.less | 11 ++ .../mobile/resources/less/material/icons.less | 11 ++ .../mobile/src/controller/ContextMenu.jsx | 3 + .../mobile/src/controller/Main.jsx | 8 +- .../mobile/src/less/icons-material.less | 10 -- .../mobile/src/less/icons-ios.less | 12 -- .../mobile/src/less/icons-material.less | 12 -- .../mobile/src/less/icons-ios.less | 10 -- .../mobile/src/less/icons-material.less | 10 -- 14 files changed, 236 insertions(+), 72 deletions(-) diff --git a/apps/common/mobile/lib/controller/collaboration/Comments.jsx b/apps/common/mobile/lib/controller/collaboration/Comments.jsx index 331adc103..8b44d1322 100644 --- a/apps/common/mobile/lib/controller/collaboration/Comments.jsx +++ b/apps/common/mobile/lib/controller/collaboration/Comments.jsx @@ -5,7 +5,7 @@ import {Device} from '../../../../../common/mobile/utils/device'; import { withTranslation} from 'react-i18next'; import { LocalStorage } from '../../../utils/LocalStorage'; -import {AddComment, EditComment, AddReply, EditReply, ViewComments} from '../../view/collaboration/Comments'; +import {AddComment, EditComment, AddReply, EditReply, ViewComments, ViewCurrentComments} from '../../view/collaboration/Comments'; // utils const timeZoneOffsetInMs = (new Date()).getTimezoneOffset() * 60000; @@ -409,9 +409,18 @@ class ViewCommentsController extends Component { super(props); this.onCommentMenuClick = this.onCommentMenuClick.bind(this); this.onResolveComment = this.onResolveComment.bind(this); - this.closeEditComment = this.closeEditComment.bind(this); + this.closeViewCurComments = this.closeViewCurComments.bind(this); - this.currentUser = this.props.users.currentUser; + this.state = { + isOpenViewCurComments: false + }; + + Common.Notifications.on('viewcomment', () => { + this.setState({isOpenViewCurComments: true}); + }); + } + closeViewCurComments () { + this.setState({isOpenViewCurComments: false}); } onResolveComment (comment) { let reply = null, @@ -533,15 +542,12 @@ class ViewCommentsController extends Component { break; } } - - closeEditComment () { - this.setState({showEditComment: false}); - } render() { return( - + + {this.props.allComments && } + {this.state.isOpenViewCurComments && } + ) } } diff --git a/apps/common/mobile/lib/view/collaboration/Collaboration.jsx b/apps/common/mobile/lib/view/collaboration/Collaboration.jsx index 76f48102c..03e2a3051 100644 --- a/apps/common/mobile/lib/view/collaboration/Collaboration.jsx +++ b/apps/common/mobile/lib/view/collaboration/Collaboration.jsx @@ -49,7 +49,12 @@ const routes = [ }, { path: '/comments/', - component: ViewCommentsController + component: ViewCommentsController, + options: { + props: { + allComments: true + } + } } ]; diff --git a/apps/common/mobile/lib/view/collaboration/Comments.jsx b/apps/common/mobile/lib/view/collaboration/Comments.jsx index 16f1ba3ce..4a6fb606a 100644 --- a/apps/common/mobile/lib/view/collaboration/Comments.jsx +++ b/apps/common/mobile/lib/view/collaboration/Comments.jsx @@ -1,6 +1,6 @@ import React, {useState, useEffect, Fragment} from 'react'; import {observer, inject} from "mobx-react"; -import { f7, Popup, Page, Navbar, NavLeft, NavRight, NavTitle, Link, Input, Icon, List, ListItem, Actions, ActionsGroup, ActionsButton } from 'framework7-react'; +import { f7, Popup, Sheet, Popover, Page, Toolbar, Navbar, NavLeft, NavRight, NavTitle, Link, Input, Icon, List, ListItem, Actions, ActionsGroup, ActionsButton } from 'framework7-react'; import { useTranslation } from 'react-i18next'; import {Device} from '../../../utils/device'; @@ -633,10 +633,137 @@ const ViewComments = ({storeComments, storeAppOptions, onCommentMenuClick, onRes const _ViewComments = inject('storeComments', 'storeAppOptions')(observer(ViewComments)); +const CommentList = () => { + return ( + + + + ) +}; + +const ViewCommentSheet = ({closeCurComments}) => { + const { t } = useTranslation(); + const _t = t('Common.Collaboration', {returnObjects: true}); + + const appHeight = f7.height; + //const [sheetHeight, setSheetHeight] = useState('45%'); + + let swipeStart, + swipeChange; + + useEffect(() => { + f7.sheet.open('#view-comment-sheet'); + const swipeHandler = document.getElementById('swipe-handler'); + swipeHandler.addEventListener('touchstart', handleTouchStart); + swipeHandler.addEventListener('touchmove', handleTouchMove); + swipeHandler.addEventListener('touchend', handleTouchEnd); + }); + const handleTouchStart = (event) => { + console.log('start'); + const touchObj = event.changedTouches[0]; + swipeStart = parseInt(touchObj.clientY); + swipeChange = parseInt(touchObj.clientY); + }; + const handleTouchMove = (event) => { + console.log('move'); + const touchObj = event.changedTouches[0]; + const dist = parseInt(touchObj.clientY) - swipeStart; + const height = (appHeight - parseInt(touchObj.clientY)).toString(); + document.getElementById('view-comment-sheet').style.setProperty('height', `${height}px`); + /*if (dist < 0) { + newHeight = '100%'; + me.swipeFull = true; + me.closeCommentPicker = false; + if (window.SSE) { + if ($('.container-view-comment').hasClass('onHide')) { + $('.container-view-comment').removeClass('onHide'); + } + } else { + $('.container-view-comment').css('opacity', '1'); + } + } else if (dist < 100) { + newHeight = '50%'; + me.swipeFull = false; + me.closeCommentPicker = false; + if (window.SSE) { + if ($('.container-view-comment').hasClass('onHide')) { + $('.container-view-comment').removeClass('onHide'); + } + } else { + $('.container-view-comment').css('opacity', '1'); + } + } else { + me.closeCommentPicker = true; + if (window.SSE) { + if (!$('.container-view-comment').hasClass('onHide')) { + $('.container-view-comment').addClass('onHide'); + } + } else { + $('.container-view-comment').css('opacity', '0.6'); + } + } + $('.container-view-comment').css('height', newHeight); + me.swipeHeight = newHeight; + e.preventDefault();*/ + }; + const handleTouchEnd = () => { + console.log('end'); + /*var touchobj = e.changedTouches[0]; + var swipeEnd = parseInt(touchobj.clientY); + var dist = swipeEnd - me.swipeStart; + if (me.closeCommentPicker) { + uiApp.closeModal(); + me.modalViewComment.remove(); + } else if (me.swipeFull) { + if (dist > 20) { + $('.container-view-comment').css('height', '50%'); + } + } + me.swipeHeight = undefined; + me.swipeChange = undefined; + me.closeCommentPicker = undefined;*/ + }; + return ( + + + {_t.textAddReply} +
      + + +
      +
      +
      + +
      + +
      + ) +}; + +const ViewCommentPopover = () => { + useEffect(() => { + f7.popover.open('#view-comment-popover', '#btn-coauth'); + }); + return ( + + + + ) +}; + +const ViewCurrentComments = props => { + return ( + Device.phone ? + : + + ) +}; + export { AddComment, EditComment, AddReply, EditReply, - _ViewComments as ViewComments -} + _ViewComments as ViewComments, + ViewCurrentComments +}; diff --git a/apps/common/mobile/resources/less/comments.less b/apps/common/mobile/resources/less/comments.less index 0b4be0bec..84ac95711 100644 --- a/apps/common/mobile/resources/less/comments.less +++ b/apps/common/mobile/resources/less/comments.less @@ -1,3 +1,6 @@ +@comment-date: #6d6d72; +@swipe-icon: rgba(0, 0, 0, 0.12); + @import './ios/comments'; @import './material/comments'; @@ -74,7 +77,6 @@ line-height: 18px; color: @comment-date; margin: 0; - margin-top: 0; } .comment-quote { color: @themeColor; @@ -103,4 +105,53 @@ .edit-comment-popup, .add-reply-popup, .edit-reply-popup { z-index: 20000; +} + +#view-comment-sheet { + background-color: @white; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + height: 45%; + box-shadow: 0 1px 10px rgba(0, 0, 0, 0.2), 0 4px 5px rgba(0, 0, 0, 0.12); + //-webkit-transition: height 100ms; + //transition: height 120ms; + .top { + height: 90%; + } + .swipe-container { + display: flex; + justify-content: center; + height: 40px; + .icon-swipe { + margin-top: 8px; + width: 40px; + height: 4px; + background: @swipe-icon; + border-radius: 2px; + } + } + .toolbar { + position: fixed; + background-color: @white; + box-shadow: 0px 1px 10px rgba(0, 0, 0, 0.2), 0px 4px 5px rgba(0, 0, 0, 0.12), 0px 2px 4px rgba(0, 0, 0, 0.14); + .link { + --f7-toolbar-link-color: @themeColor; + } + .toolbar-inner { + padding: 0 16px; + } + .btn-add-reply { + padding: 0; + min-width: 80px; + font-size: 16px; + } + .comment-navigation { + min-width: 62px; + display: flex; + justify-content: space-between; + .link { + padding: 0 12px; + } + } + } } \ No newline at end of file diff --git a/apps/common/mobile/resources/less/common.less b/apps/common/mobile/resources/less/common.less index 690e48226..ea20b6639 100644 --- a/apps/common/mobile/resources/less/common.less +++ b/apps/common/mobile/resources/less/common.less @@ -8,8 +8,6 @@ @background-normal: @white; @autoColor: @black; -@comment-date: #6d6d72; - .popup, .popover, .sheet-modal { .list { &:first-child { diff --git a/apps/common/mobile/resources/less/ios/icons.less b/apps/common/mobile/resources/less/ios/icons.less index 5fa78c04f..820a9527a 100644 --- a/apps/common/mobile/resources/less/ios/icons.less +++ b/apps/common/mobile/resources/less/ios/icons.less @@ -4,5 +4,16 @@ &.icon_mask { background-color: white; } + + &.icon-prev { + width: 22px; + height: 22px; + .encoded-svg-background(''); + } + &.icon-next { + width: 22px; + height: 22px; + .encoded-svg-background(''); + } } } diff --git a/apps/common/mobile/resources/less/material/icons.less b/apps/common/mobile/resources/less/material/icons.less index 6891a5b97..6e8f3626b 100644 --- a/apps/common/mobile/resources/less/material/icons.less +++ b/apps/common/mobile/resources/less/material/icons.less @@ -4,5 +4,16 @@ &.icon_mask { background-color: black; } + + &.icon-prev { + width: 24px; + height: 24px; + .encoded-svg-background(''); + } + &.icon-next { + width: 24px; + height: 24px; + .encoded-svg-background(''); + } } } diff --git a/apps/documenteditor/mobile/src/controller/ContextMenu.jsx b/apps/documenteditor/mobile/src/controller/ContextMenu.jsx index 3e11cd706..c82ae0f3a 100644 --- a/apps/documenteditor/mobile/src/controller/ContextMenu.jsx +++ b/apps/documenteditor/mobile/src/controller/ContextMenu.jsx @@ -51,6 +51,9 @@ class ContextMenu extends ContextMenuController { case 'addcomment': Common.Notifications.trigger('addcomment'); break; + case 'viewcomment': + Common.Notifications.trigger('viewcomment'); + break; } console.log("click context menu item: " + action); diff --git a/apps/documenteditor/mobile/src/controller/Main.jsx b/apps/documenteditor/mobile/src/controller/Main.jsx index f4f9989e1..564edf439 100644 --- a/apps/documenteditor/mobile/src/controller/Main.jsx +++ b/apps/documenteditor/mobile/src/controller/Main.jsx @@ -6,7 +6,12 @@ import { withTranslation } from 'react-i18next'; import CollaborationController from '../../../../common/mobile/lib/controller/collaboration/Collaboration.jsx'; import {InitReviewController as ReviewController} from '../../../../common/mobile/lib/controller/collaboration/Review.jsx'; import { onAdvancedOptions } from './settings/Download.jsx'; -import {CommentsController, AddCommentController, EditCommentController} from "../../../../common/mobile/lib/controller/collaboration/Comments"; +import { + CommentsController, + AddCommentController, + EditCommentController, + ViewCommentsController +} from "../../../../common/mobile/lib/controller/collaboration/Comments"; @inject( "storeAppOptions", @@ -336,6 +341,7 @@ class MainController extends Component { + ) } diff --git a/apps/documenteditor/mobile/src/less/icons-material.less b/apps/documenteditor/mobile/src/less/icons-material.less index 8b6dc0e2c..8590b8555 100644 --- a/apps/documenteditor/mobile/src/less/icons-material.less +++ b/apps/documenteditor/mobile/src/less/icons-material.less @@ -440,16 +440,6 @@ height: 24px; .encoded-svg-background(''); } - &.icon-prev-comment { - width: 24px; - height: 24px; - .encoded-svg-background(''); - } - &.icon-next-comment { - width: 24px; - height: 24px; - .encoded-svg-background(''); - } &.icon-done-comment { width: 24px; height: 24px; diff --git a/apps/presentationeditor/mobile/src/less/icons-ios.less b/apps/presentationeditor/mobile/src/less/icons-ios.less index 6b77662cd..d43e2a6b4 100644 --- a/apps/presentationeditor/mobile/src/less/icons-ios.less +++ b/apps/presentationeditor/mobile/src/less/icons-ios.less @@ -187,18 +187,6 @@ .encoded-svg-mask(''); } - &.icon-prev, &.icon-prev-comment { - width: 22px; - height: 22px; - .encoded-svg-background(''); - } - - &.icon-next, &.icon-next-comment { - width: 22px; - height: 22px; - .encoded-svg-background(''); - } - &.icon-table-add-column-left { width: 22px; height: 22px; diff --git a/apps/presentationeditor/mobile/src/less/icons-material.less b/apps/presentationeditor/mobile/src/less/icons-material.less index b1de085b6..3c7098570 100644 --- a/apps/presentationeditor/mobile/src/less/icons-material.less +++ b/apps/presentationeditor/mobile/src/less/icons-material.less @@ -471,18 +471,6 @@ .encoded-svg-background(''); } - &.icon-prev-comment { - width: 24px; - height: 24px; - .encoded-svg-background(''); - } - - &.icon-next-comment { - width: 24px; - height: 24px; - .encoded-svg-background(''); - } - &.icon-done-comment { width: 24px; height: 24px; diff --git a/apps/spreadsheeteditor/mobile/src/less/icons-ios.less b/apps/spreadsheeteditor/mobile/src/less/icons-ios.less index ec61398a8..ded1d72c2 100644 --- a/apps/spreadsheeteditor/mobile/src/less/icons-ios.less +++ b/apps/spreadsheeteditor/mobile/src/less/icons-ios.less @@ -123,16 +123,6 @@ height: 22px; .encoded-svg-mask(''); } - &.icon-prev, &.icon-prev-comment { - width: 22px; - height: 22px; - .encoded-svg-background(''); - } - &.icon-next, &.icon-next-comment { - width: 22px; - height: 22px; - .encoded-svg-background(''); - } &.icon-expand-down { width: 22px; height: 22px; diff --git a/apps/spreadsheeteditor/mobile/src/less/icons-material.less b/apps/spreadsheeteditor/mobile/src/less/icons-material.less index 2f1fcf0c7..bfaba3ec2 100644 --- a/apps/spreadsheeteditor/mobile/src/less/icons-material.less +++ b/apps/spreadsheeteditor/mobile/src/less/icons-material.less @@ -365,16 +365,6 @@ height: 24px; .encoded-svg-background(''); } - &.icon-prev-comment { - width: 24px; - height: 24px; - .encoded-svg-background(''); - } - &.icon-next-comment { - width: 24px; - height: 24px; - .encoded-svg-background(''); - } &.icon-done-comment { width: 24px; height: 24px; From 1cf1bb5df35235808ac677ab22c3ec8f239b11e2 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Tue, 9 Mar 2021 15:27:26 +0300 Subject: [PATCH 11/13] [mobile] Fix users and comments stores according to mobx v. 6 --- apps/common/mobile/lib/store/comments.js | 53 +++++++++++++++++------- apps/common/mobile/lib/store/users.js | 23 ++++++---- 2 files changed, 53 insertions(+), 23 deletions(-) diff --git a/apps/common/mobile/lib/store/comments.js b/apps/common/mobile/lib/store/comments.js index ee08defaf..ffc55c4c2 100644 --- a/apps/common/mobile/lib/store/comments.js +++ b/apps/common/mobile/lib/store/comments.js @@ -1,11 +1,35 @@ -import {observable, action, computed} from 'mobx'; +import {makeObservable, observable, action, computed} from 'mobx'; export class storeComments { - @observable collectionComments = []; - @observable groupCollectionComments = []; + constructor() { + makeObservable(this, { + collectionComments: observable, + groupCollectionComments: observable, + filter: observable, + groupCollectionFilter: observable, - @action addComment (comment) { + addComment: action, + removeComment: action, + changeFilter: action, + + sortComments: computed, + + isOpenEditComment: observable, + openEditComment: action, + isOpenAddReply: observable, + openAddReply: action, + isOpenEditReply: observable, + openEditReply: action + }) + } + collectionComments = []; + groupCollectionComments = []; + + filter = undefined; + groupCollectionFilter = []; // for sse + + addComment (comment) { comment.groupName ? this.addCommentToGroupCollection(comment) : this.addCommentToCollection(comment); } @@ -24,7 +48,7 @@ export class storeComments { } } - @action removeComment (id) { + removeComment (id) { if (this.collectionComments.length > 0) { this.removeCommentFromCollection(id); } else { @@ -57,10 +81,7 @@ export class storeComments { } } - @observable filter; // for sse - @observable groupCollectionFilter = []; // for sse - - @action changeFilter (filter) { + changeFilter (filter) { let comments = []; this.filter = filter; filter.forEach((item) => { @@ -94,7 +115,7 @@ export class storeComments { return model; } - @computed get sortComments () { + get sortComments () { const comments = (this.groupCollectionFilter.length !== 0) ? this.groupCollectionFilter : (this.collectionComments.length !== 0 ? this.collectionComments : false); if (comments.length > 0) { return [...comments].sort((a, b) => a.time > b.time ? 1 : -1); @@ -104,8 +125,8 @@ export class storeComments { // Edit comment currentComment = null; - @observable isOpenEditComment = false; - @action openEditComment (open, comment) { + isOpenEditComment = false; + openEditComment (open, comment) { if (open !== this.isOpenEditComment) { this.currentComment = open ? comment : null; this.isOpenEditComment = open; @@ -113,16 +134,16 @@ export class storeComments { } currentReply = null; - @observable isOpenAddReply = false; - @action openAddReply (open, comment) { + isOpenAddReply = false; + openAddReply (open, comment) { if (open !== this.isOpenAddReply) { this.currentComment = open ? comment : null; this.isOpenAddReply = open; } } - @observable isOpenEditReply = false; - @action openEditReply (open, comment, reply) { + isOpenEditReply = false; + openEditReply (open, comment, reply) { if (open !== this.isOpenEditReply) { this.currentComment = open ? comment : null; this.currentReply = open ? reply : null; diff --git a/apps/common/mobile/lib/store/users.js b/apps/common/mobile/lib/store/users.js index 596955304..4b4dc4eb3 100644 --- a/apps/common/mobile/lib/store/users.js +++ b/apps/common/mobile/lib/store/users.js @@ -1,16 +1,25 @@ -import {observable, action, computed} from 'mobx'; +import {makeObservable, observable, action} from 'mobx'; export class storeUsers { - @observable users = []; + constructor() { + makeObservable(this, { + users: observable, + reset: action, + currentUser: observable, + setCurrentUser: action, + connection: action + }) + } - @action reset(users) { + users = []; + currentUser; + + reset (users) { this.users = Object.values(users) } - @observable currentUser; - - @action setCurrentUser(id) { + setCurrentUser (id) { this.users.forEach((item) => { if (item.asc_getIdOriginal() === id) { this.currentUser = item; @@ -18,7 +27,7 @@ export class storeUsers { }); } - @action connection (change) { + connection (change) { let changed = false; for (let uid in this.users) { if (undefined !== uid) { From 1c899fb7ed976a642528583fd5a97086c7c874f4 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Tue, 9 Mar 2021 18:05:16 +0300 Subject: [PATCH 12/13] [DE PE mobile] Fix app options stores according to mobx v. 6 --- .../mobile/src/store/appOptions.js | 23 ++++++++++++------- .../mobile/src/store/appOptions.js | 15 +++++++++--- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/apps/documenteditor/mobile/src/store/appOptions.js b/apps/documenteditor/mobile/src/store/appOptions.js index 998753556..a26bc4255 100644 --- a/apps/documenteditor/mobile/src/store/appOptions.js +++ b/apps/documenteditor/mobile/src/store/appOptions.js @@ -1,16 +1,23 @@ -import {action, observable} from 'mobx'; +import {makeObservable, action, observable} from 'mobx'; export class storeAppOptions { constructor() { - // makeObservable(this); + makeObservable(this, { + isEdit: observable, + canViewComments: observable, + canReview: observable, + setConfigOptions: action, + setPermissionOptions: action, + setCanViewReview: action + }); } - @observable isEdit = false; - @observable canViewComments = false; - @observable canReview = false; + isEdit = false; + canViewComments = false; + canReview = false; config = {}; - @action setConfigOptions (config) { + setConfigOptions (config) { this.config = config; this.user = Common.Utils.fillUserInfo(config.user, config.lang, "Local.User"/*me.textAnonymous*/); this.isDesktopApp = config.targetApp == 'desktop'; @@ -32,7 +39,7 @@ export class storeAppOptions { this.canBack = this.canBackToFolder === true; this.canPlugins = false; } - @action setPermissionOptions (document, licType, params, permissions) { + setPermissionOptions (document, licType, params, permissions) { this.review = (permissions.review === undefined) ? (permissions.edit !== false) : permissions.review; this.canAnalytics = params.asc_getIsAnalyticsEnable(); this.canLicense = (licType === Asc.c_oLicenseResult.Success || licType === Asc.c_oLicenseResult.SuccessLimit); @@ -79,7 +86,7 @@ export class storeAppOptions { this.canUseReviewPermissions = this.canLicense && this.customization && this.customization.reviewPermissions && (typeof (this.customization.reviewPermissions) == 'object'); } - @action setCanViewReview (value) { + setCanViewReview (value) { this.canViewReview = value; } } \ No newline at end of file diff --git a/apps/presentationeditor/mobile/src/store/appOptions.js b/apps/presentationeditor/mobile/src/store/appOptions.js index 7bec65bc4..c07f81eaa 100644 --- a/apps/presentationeditor/mobile/src/store/appOptions.js +++ b/apps/presentationeditor/mobile/src/store/appOptions.js @@ -1,8 +1,17 @@ -import {action, observable} from 'mobx'; +import {makeObservable, action, observable} from 'mobx'; export class storeAppOptions { + constructor() { + makeObservable(this, { + isEdit: observable, + setConfigOptions: action, + setPermissionOptions: action + }); + } + + isEdit = false; config = {}; - @action setConfigOptions (config) { + setConfigOptions (config) { this.config = config; this.user = Common.Utils.fillUserInfo(config.user, config.lang, "Local.User"/*me.textAnonymous*/); this.isDesktopApp = config.targetApp == 'desktop'; @@ -24,7 +33,7 @@ export class storeAppOptions { this.canBack = this.canBackToFolder === true; this.canPlugins = false; } - @action setPermissionOptions (document, licType, params, permissions) { + setPermissionOptions (document, licType, params, permissions) { this.review = (permissions.review === undefined) ? (permissions.edit !== false) : permissions.review; this.canAnalytics = params.asc_getIsAnalyticsEnable(); this.canLicense = (licType === Asc.c_oLicenseResult.Success || licType === Asc.c_oLicenseResult.SuccessLimit); From c9e5a419541caedc8b063856e57cc1e99ace2bc6 Mon Sep 17 00:00:00 2001 From: JuliaSvinareva Date: Tue, 9 Mar 2021 19:29:06 +0300 Subject: [PATCH 13/13] [mobile] Fixed swipe animation of view current comment --- .../lib/view/collaboration/Comments.jsx | 96 ++++++------------- .../mobile/resources/less/comments.less | 4 +- 2 files changed, 32 insertions(+), 68 deletions(-) diff --git a/apps/common/mobile/lib/view/collaboration/Comments.jsx b/apps/common/mobile/lib/view/collaboration/Comments.jsx index 4a6fb606a..96d87328f 100644 --- a/apps/common/mobile/lib/view/collaboration/Comments.jsx +++ b/apps/common/mobile/lib/view/collaboration/Comments.jsx @@ -645,86 +645,50 @@ const ViewCommentSheet = ({closeCurComments}) => { const { t } = useTranslation(); const _t = t('Common.Collaboration', {returnObjects: true}); - const appHeight = f7.height; - //const [sheetHeight, setSheetHeight] = useState('45%'); - - let swipeStart, - swipeChange; - useEffect(() => { f7.sheet.open('#view-comment-sheet'); - const swipeHandler = document.getElementById('swipe-handler'); - swipeHandler.addEventListener('touchstart', handleTouchStart); - swipeHandler.addEventListener('touchmove', handleTouchMove); - swipeHandler.addEventListener('touchend', handleTouchEnd); }); + + const [stateHeight, setHeight] = useState('45%'); + const [stateOpacity, setOpacity] = useState(1); + + const [stateStartY, setStartY] = useState(); + const [isNeedClose, setNeedClose] = useState(false); + const handleTouchStart = (event) => { - console.log('start'); const touchObj = event.changedTouches[0]; - swipeStart = parseInt(touchObj.clientY); - swipeChange = parseInt(touchObj.clientY); + setStartY(parseInt(touchObj.clientY)); }; const handleTouchMove = (event) => { - console.log('move'); const touchObj = event.changedTouches[0]; - const dist = parseInt(touchObj.clientY) - swipeStart; - const height = (appHeight - parseInt(touchObj.clientY)).toString(); - document.getElementById('view-comment-sheet').style.setProperty('height', `${height}px`); - /*if (dist < 0) { - newHeight = '100%'; - me.swipeFull = true; - me.closeCommentPicker = false; - if (window.SSE) { - if ($('.container-view-comment').hasClass('onHide')) { - $('.container-view-comment').removeClass('onHide'); - } - } else { - $('.container-view-comment').css('opacity', '1'); - } - } else if (dist < 100) { - newHeight = '50%'; - me.swipeFull = false; - me.closeCommentPicker = false; - if (window.SSE) { - if ($('.container-view-comment').hasClass('onHide')) { - $('.container-view-comment').removeClass('onHide'); - } - } else { - $('.container-view-comment').css('opacity', '1'); - } + const dist = parseInt(touchObj.clientY) - stateStartY; + if (dist < 0) { // to top + setHeight('90%'); + setOpacity(1); + setNeedClose(false); + } else if (dist < 80) { + setHeight('45%'); + setOpacity(1); + setNeedClose(false); } else { - me.closeCommentPicker = true; - if (window.SSE) { - if (!$('.container-view-comment').hasClass('onHide')) { - $('.container-view-comment').addClass('onHide'); - } - } else { - $('.container-view-comment').css('opacity', '0.6'); - } + setNeedClose(true); + setOpacity(0.6); } - $('.container-view-comment').css('height', newHeight); - me.swipeHeight = newHeight; - e.preventDefault();*/ }; - const handleTouchEnd = () => { + const handleTouchEnd = (event) => { console.log('end'); - /*var touchobj = e.changedTouches[0]; - var swipeEnd = parseInt(touchobj.clientY); - var dist = swipeEnd - me.swipeStart; - if (me.closeCommentPicker) { - uiApp.closeModal(); - me.modalViewComment.remove(); - } else if (me.swipeFull) { - if (dist > 20) { - $('.container-view-comment').css('height', '50%'); - } + const touchObj = event.changedTouches[0]; + const swipeEnd = parseInt(touchObj.clientY); + const dist = swipeEnd - stateStartY; + if (isNeedClose) { + f7.sheet.close('#view-comment-sheet'); + closeCurComments(); + } else if (stateHeight === '90%' && dist > 20) { + setHeight('45%'); } - me.swipeHeight = undefined; - me.swipeChange = undefined; - me.closeCommentPicker = undefined;*/ }; return ( - + {_t.textAddReply}
      @@ -732,7 +696,7 @@ const ViewCommentSheet = ({closeCurComments}) => {
      -
      +
      diff --git a/apps/common/mobile/resources/less/comments.less b/apps/common/mobile/resources/less/comments.less index 84ac95711..9bd88e835 100644 --- a/apps/common/mobile/resources/less/comments.less +++ b/apps/common/mobile/resources/less/comments.less @@ -113,8 +113,8 @@ border-top-right-radius: 4px; height: 45%; box-shadow: 0 1px 10px rgba(0, 0, 0, 0.2), 0 4px 5px rgba(0, 0, 0, 0.12); - //-webkit-transition: height 100ms; - //transition: height 120ms; + webkit-transition: height 200ms; + transition: height 200ms; .top { height: 90%; }