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 { + ) }