Merge branch 'feature/mobile-apps-on-reactjs' of https://github.com/ONLYOFFICE/web-apps into feature/mobile-apps-on-reactjs
This commit is contained in:
commit
38ebce8e5a
|
@ -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 (
|
||||
<ContextMenuView items={this.initMenuItems()} onMenuClosed={this.onMenuClosed} onMenuItemClick={this.onMenuItemClick} />
|
||||
<ContextMenuView items={this.state.items} onMenuClosed={this.onMenuClosed} onMenuItemClick={this.onMenuItemClick} />
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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, EditReply, ViewComments, ViewCurrentComments} from '../../view/collaboration/Comments';
|
||||
|
||||
// utils
|
||||
const timeZoneOffsetInMs = (new Date()).getTimezoneOffset() * 60000;
|
||||
|
@ -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();
|
||||
|
@ -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,34 +267,30 @@ class AddCommentController extends Component {
|
|||
return false;
|
||||
}
|
||||
render() {
|
||||
const isOpen = this.props.storeComments.isOpenAddComment;
|
||||
let userInfo;
|
||||
if (isOpen) {
|
||||
userInfo = this.getUserInfo();
|
||||
}
|
||||
return(
|
||||
isOpen ? <AddComment userInfo={userInfo} onAddNewComment={this.onAddNewComment} /> : null
|
||||
this.state.isOpen ? <AddComment userInfo={this.getUserInfo()} onAddNewComment={this.onAddNewComment} closeAddComment={this.closeAddComment}/> : null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
this.onEditReply = this.onEditReply.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 +324,104 @@ 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
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;
|
||||
return (
|
||||
<Fragment>
|
||||
{storeComments.isOpenEditComment && <EditComment comment={comment} onEditComment={this.onEditComment}/>}
|
||||
{storeComments.isOpenAddReply && <AddReply userInfo={this.getUserInfo()} comment={comment} onAddReply={this.onAddReply}/>}
|
||||
{storeComments.isOpenEditReply && <EditReply comment={comment} reply={storeComments.currentReply} onEditReply={this.onEditReply}/>}
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class ViewCommentsController extends Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
this.onCommentMenuClick = this.onCommentMenuClick.bind(this);
|
||||
this.onResolveComment = this.onResolveComment.bind(this);
|
||||
this.closeViewCurComments = this.closeViewCurComments.bind(this);
|
||||
|
||||
this.state = {
|
||||
isOpenViewCurComments: false
|
||||
};
|
||||
|
||||
Common.Notifications.on('viewcomment', () => {
|
||||
this.setState({isOpenViewCurComments: true});
|
||||
});
|
||||
}
|
||||
closeViewCurComments () {
|
||||
this.setState({isOpenViewCurComments: false});
|
||||
}
|
||||
onResolveComment (comment) {
|
||||
let reply = null,
|
||||
addReply = null,
|
||||
|
@ -358,17 +464,13 @@ 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) {
|
||||
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);
|
||||
|
@ -404,19 +506,12 @@ 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) {
|
||||
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);
|
||||
|
@ -431,35 +526,27 @@ 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;
|
||||
case 'addReply':
|
||||
console.log('addReply');
|
||||
this.props.storeComments.openAddReply(true, comment);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
closeEditComment () {
|
||||
this.setState({showEditComment: false});
|
||||
}
|
||||
render() {
|
||||
return(
|
||||
<Fragment>
|
||||
<ViewComments showEditComment={this.showEditComment}
|
||||
onCommentMenuClick={this.onCommentMenuClick}
|
||||
onResolveComment={this.onResolveComment}
|
||||
/>
|
||||
{this.state.showEditComment && <EditComment editProps={this.state.editProps} opened={this.state.showEditComment} close={this.closeEditComment}/>}
|
||||
{this.props.allComments && <ViewComments onCommentMenuClick={this.onCommentMenuClick} onResolveComment={this.onResolveComment} />}
|
||||
{this.state.isOpenViewCurComments && <ViewCurrentComments opened={this.state.isOpenViewCurComments} closeCurComments={this.closeViewCurComments} />}
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
@ -467,10 +554,12 @@ class ViewCommentsController extends Component {
|
|||
|
||||
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
|
||||
};
|
|
@ -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);
|
||||
|
@ -102,12 +123,31 @@ export class storeComments {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Add comment modal window
|
||||
@observable isOpenAddComment = false;
|
||||
// Edit comment
|
||||
currentComment = null;
|
||||
isOpenEditComment = false;
|
||||
openEditComment (open, comment) {
|
||||
if (open !== this.isOpenEditComment) {
|
||||
this.currentComment = open ? comment : null;
|
||||
this.isOpenEditComment = open;
|
||||
}
|
||||
}
|
||||
|
||||
@action openAddComment (open) {
|
||||
if (open !== this.isOpenAddComment) {
|
||||
this.isOpenAddComment = open;
|
||||
currentReply = null;
|
||||
isOpenAddReply = false;
|
||||
openAddReply (open, comment) {
|
||||
if (open !== this.isOpenAddReply) {
|
||||
this.currentComment = open ? comment : null;
|
||||
this.isOpenAddReply = open;
|
||||
}
|
||||
}
|
||||
|
||||
isOpenEditReply = false;
|
||||
openEditReply (open, comment, reply) {
|
||||
if (open !== this.isOpenEditReply) {
|
||||
this.currentComment = open ? comment : null;
|
||||
this.currentReply = open ? reply : null;
|
||||
this.isOpenEditReply = open;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
@ -45,10 +54,12 @@ export class storeUsers {
|
|||
}
|
||||
|
||||
searchUserById (id) {
|
||||
let user = null;
|
||||
this.users.forEach((item) => {
|
||||
if (item.asc_getIdOriginal() === id) {
|
||||
return item;
|
||||
user = item;
|
||||
}
|
||||
});
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,9 +26,9 @@ class ContextMenuView extends Component {
|
|||
>
|
||||
<List className="list-block">
|
||||
{buttons.map((b, index) =>
|
||||
!!b.text ?
|
||||
<ListButton className="asd" title={b.text} key={index} onClick={e => this.props.onMenuItemClick(b.action)} /> :
|
||||
<ListButton className="asd" title={b.text} key={index}>
|
||||
!b.icon ?
|
||||
<ListButton title={b.caption} key={index} onClick={e => this.props.onMenuItemClick(b.event)} /> :
|
||||
<ListButton key={index}>
|
||||
<Icon slot="media" icon={`icon_mask ${b.icon}`} />
|
||||
</ListButton>
|
||||
)}
|
||||
|
|
|
@ -49,7 +49,12 @@ const routes = [
|
|||
},
|
||||
{
|
||||
path: '/comments/',
|
||||
component: ViewCommentsController
|
||||
component: ViewCommentsController,
|
||||
options: {
|
||||
props: {
|
||||
allComments: true
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
@ -19,7 +19,7 @@ const AddCommentPopup = inject("storeComments")(observer(props => {
|
|||
<Navbar>
|
||||
<NavLeft>
|
||||
<Link onClick={() => {
|
||||
props.storeComments.openAddComment(false);
|
||||
props.closeAddComment();
|
||||
f7.popup.close('.add-comment-popup');
|
||||
}}>{_t.textCancel}</Link>
|
||||
</NavLeft>
|
||||
|
@ -28,7 +28,7 @@ const AddCommentPopup = inject("storeComments")(observer(props => {
|
|||
<Link className={stateText.length === 0 && 'disabled'}
|
||||
onClick={() => {
|
||||
if (props.onAddNewComment(stateText, false)) {
|
||||
props.storeComments.openAddComment(false);
|
||||
props.closeAddComment();
|
||||
f7.popup.close('.add-comment-popup');
|
||||
}
|
||||
}}>
|
||||
|
@ -37,7 +37,7 @@ const AddCommentPopup = inject("storeComments")(observer(props => {
|
|||
</NavRight>
|
||||
</Navbar>
|
||||
<div className='wrap-comment'>
|
||||
<div className="header-comment">
|
||||
<div className="comment-header">
|
||||
{Device.android &&
|
||||
<div className='initials' style={{backgroundColor: `${userInfo.color}`}}>{userInfo.initials}</div>
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ const AddCommentDialog = inject("storeComments")(observer(props => {
|
|||
</div>
|
||||
</div>
|
||||
<div class='wrap-comment'>
|
||||
<div class="header-comment">
|
||||
<div class="comment-header">
|
||||
${Device.android ? templateInitials : ''}
|
||||
<div class='name'>${userInfo.name}</div>
|
||||
</div>
|
||||
|
@ -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 ?
|
||||
<AddCommentPopup userInfo={props.userInfo} onAddNewComment={props.onAddNewComment} /> :
|
||||
<AddCommentDialog userInfo={props.userInfo} onAddNewComment={props.onAddNewComment} />
|
||||
<AddCommentPopup {...props} /> :
|
||||
<AddCommentDialog {...props} />
|
||||
)
|
||||
};
|
||||
|
||||
|
@ -148,19 +148,40 @@ const CommentActions = ({comment, onCommentMenuClick, opened, openActionComment}
|
|||
)
|
||||
};
|
||||
|
||||
// Edit comment
|
||||
const EditCommentPopup = ({comment, onEditComment, opened, close}) => {
|
||||
const ReplyActions = ({comment, reply, onCommentMenuClick, opened, openActionReply}) => {
|
||||
const { t } = useTranslation();
|
||||
const _t = t('Common.Collaboration', {returnObjects: true});
|
||||
const [stateText, setText] = useState(comment.comment);
|
||||
console.log(comment);
|
||||
return (
|
||||
<Popup className="edit-comment-popup" opened={opened} animate={true}>
|
||||
<Actions id='reply-menu' opened={opened} onActionsClosed={() => openActionReply(false)}>
|
||||
<ActionsGroup>
|
||||
{reply && <Fragment>
|
||||
{reply.editable && <ActionsButton onClick={() => {onCommentMenuClick('editReply', comment, reply);}}>{_t.textEdit}</ActionsButton>}
|
||||
{reply.removable && <ActionsButton color='red' onClick={() => {onCommentMenuClick('deleteReply', comment, reply);}}>{_t.textDeleteReply}</ActionsButton>}
|
||||
</Fragment>
|
||||
}
|
||||
</ActionsGroup>
|
||||
<ActionsGroup>
|
||||
<ActionsButton>{_t.textCancel}</ActionsButton>
|
||||
</ActionsGroup>
|
||||
</Actions>
|
||||
)
|
||||
};
|
||||
|
||||
// Edit comment
|
||||
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);
|
||||
return (
|
||||
<Popup className="edit-comment-popup">
|
||||
<Navbar>
|
||||
<NavLeft>
|
||||
<Link onClick={() => {
|
||||
close();
|
||||
//f7.popup.close('.edit-comment-popup');
|
||||
f7.popup.close('.edit-comment-popup');
|
||||
storeComments.openEditComment(false);
|
||||
}}>{_t.textCancel}</Link>
|
||||
</NavLeft>
|
||||
<NavTitle>{_t.textEditComment}</NavTitle>
|
||||
|
@ -168,8 +189,8 @@ const EditCommentPopup = ({comment, onEditComment, opened, close}) => {
|
|||
<Link className={stateText.length === 0 && 'disabled'}
|
||||
onClick={() => {
|
||||
onEditComment(comment, stateText);
|
||||
close();
|
||||
//f7.popup.close('.edit-comment-popup');
|
||||
f7.popup.close('.edit-comment-popup');
|
||||
storeComments.openEditComment(false);
|
||||
}}
|
||||
>
|
||||
{Device.android ? <Icon icon='icon-done-comment-white'/> : _t.textDone}
|
||||
|
@ -192,13 +213,315 @@ const EditCommentPopup = ({comment, onEditComment, opened, close}) => {
|
|||
</div>
|
||||
</Popup>
|
||||
)
|
||||
};
|
||||
}));
|
||||
|
||||
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 = `<div class="initials" style="background-color: ${comment.userColor};">${comment.userInitials}</div>`;
|
||||
useEffect(() => {
|
||||
f7.dialog.create({
|
||||
destroyOnClose: true,
|
||||
containerEl: document.getElementById('edit-comment-dialog'),
|
||||
content:
|
||||
`<div class="navbar">
|
||||
<div class="navbar-bg"></div>
|
||||
<div class="navbar-inner sliding">
|
||||
<div class="left">
|
||||
<a href="#" id="comment-cancel">${_t.textCancel}</a>
|
||||
</div>
|
||||
<div class="title">${_t.textEditComment}</div>
|
||||
<div class="right">
|
||||
<a href="#" class="done" id="comment-done">${ Device.android ? '<i class="icon icon-done-comment-white"></i>' : _t.textDone}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='wrap-comment'>
|
||||
<div class="comment-header">
|
||||
${Device.android ? templateInitials : ''}
|
||||
<div>
|
||||
<div class='name'>${comment.userName}</div>
|
||||
<div class='comment-date'>${comment.date}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='wrap-textarea'>
|
||||
<textarea id='comment-text' placeholder='${_t.textEditComment}' autofocus>${comment.comment}</textarea>
|
||||
</div>
|
||||
</div>`,
|
||||
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');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}).open();
|
||||
});
|
||||
return (
|
||||
<div id='edit-comment-dialog'></div>
|
||||
);
|
||||
}));
|
||||
|
||||
const EditComment = ({comment, onEditComment}) => {
|
||||
return (
|
||||
Device.phone ?
|
||||
<EditCommentPopup {...editProps} opened={opened} close={close}/> :
|
||||
<EditCommentDialog />
|
||||
<EditCommentPopup comment={comment} onEditComment={onEditComment}/> :
|
||||
<EditCommentDialog comment={comment} onEditComment={onEditComment}/>
|
||||
)
|
||||
};
|
||||
|
||||
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 (
|
||||
<Popup className="add-reply-popup">
|
||||
<Navbar>
|
||||
<NavLeft>
|
||||
<Link onClick={() => {
|
||||
storeComments.openAddReply(false);
|
||||
f7.popup.close('.add-reply-popup');
|
||||
}}>{_t.textCancel}</Link>
|
||||
</NavLeft>
|
||||
<NavTitle>{_t.textAddReply}</NavTitle>
|
||||
<NavRight>
|
||||
<Link className={stateText.length === 0 && 'disabled'}
|
||||
onClick={() => {
|
||||
onAddReply(comment, stateText);
|
||||
storeComments.openAddReply(false);
|
||||
f7.popup.close('.add-reply-popup');
|
||||
}}>
|
||||
{Device.android ? <Icon icon='icon-done-comment-white'/> : _t.textDone}
|
||||
</Link>
|
||||
</NavRight>
|
||||
</Navbar>
|
||||
<div className='wrap-comment'>
|
||||
<div className="comment-header">
|
||||
{Device.android &&
|
||||
<div className='initials' style={{backgroundColor: `${userInfo.color}`}}>{userInfo.initials}</div>
|
||||
}
|
||||
<div className='name'>{userInfo.name}</div>
|
||||
</div>
|
||||
<div className='wrap-textarea'>
|
||||
<Input type='textarea' placeholder={_t.textAddReply} autofocus value={stateText} onChange={(event) => {setText(event.target.value);}}></Input>
|
||||
</div>
|
||||
</div>
|
||||
</Popup>
|
||||
)
|
||||
}));
|
||||
|
||||
const AddReplyDialog = inject("storeComments")(observer(({storeComments, userInfo, comment, onAddReply}) => {
|
||||
const { t } = useTranslation();
|
||||
const _t = t('Common.Collaboration', {returnObjects: true});
|
||||
const templateInitials = `<div class="initials" style="background-color: ${userInfo.color};">${userInfo.initials}</div>`;
|
||||
useEffect(() => {
|
||||
f7.dialog.create({
|
||||
destroyOnClose: true,
|
||||
containerEl: document.getElementById('add-reply-dialog'),
|
||||
content:
|
||||
`<div class="navbar">
|
||||
<div class="navbar-bg"></div>
|
||||
<div class="navbar-inner sliding">
|
||||
<div class="left">
|
||||
<a href="#" id="reply-cancel">${_t.textCancel}</a>
|
||||
</div>
|
||||
<div class="title">${_t.textAddReply}</div>
|
||||
<div class="right">
|
||||
<a href="#" class="done" id="reply-done">${ Device.android ? '<i class="icon icon-done-comment-white"></i>' : _t.textDone}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='wrap-comment'>
|
||||
<div class="comment-header">
|
||||
${Device.android ? templateInitials : ''}
|
||||
<div class='name'>${userInfo.name}</div>
|
||||
</div>
|
||||
<div class='wrap-textarea'>
|
||||
<textarea id='reply-text' placeholder='${_t.textAddReply}' autofocus></textarea>
|
||||
</div>
|
||||
</div>`,
|
||||
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 (
|
||||
<div id='add-reply-dialog'></div>
|
||||
);
|
||||
}));
|
||||
|
||||
const AddReply = ({userInfo, comment, onAddReply}) => {
|
||||
return (
|
||||
Device.phone ?
|
||||
<AddReplyPopup userInfo={userInfo} comment={comment} onAddReply={onAddReply}/> :
|
||||
<AddReplyDialog userInfo={userInfo} comment={comment} onAddReply={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 (
|
||||
<Popup className="edit-reply-popup">
|
||||
<Navbar>
|
||||
<NavLeft>
|
||||
<Link onClick={() => {
|
||||
f7.popup.close('.edit-reply-popup');
|
||||
storeComments.openEditReply(false);
|
||||
}}>{_t.textCancel}</Link>
|
||||
</NavLeft>
|
||||
<NavTitle>{_t.textEditReply}</NavTitle>
|
||||
<NavRight>
|
||||
<Link className={stateText.length === 0 && 'disabled'}
|
||||
onClick={() => {
|
||||
onEditReply(comment, reply, stateText);
|
||||
f7.popup.close('.edit-reply-popup');
|
||||
storeComments.openEditReply(false);
|
||||
}}
|
||||
>
|
||||
{Device.android ? <Icon icon='icon-done-comment-white'/> : _t.textDone}
|
||||
</Link>
|
||||
</NavRight>
|
||||
</Navbar>
|
||||
<div className='wrap-comment'>
|
||||
<div className="comment-header">
|
||||
{Device.android &&
|
||||
<div className='initials' style={{backgroundColor: `${reply.userColor}`}}>{reply.userInitials}</div>
|
||||
}
|
||||
<div>
|
||||
<div className='name'>{reply.userName}</div>
|
||||
<div className='reply-date'>{reply.date}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='wrap-textarea'>
|
||||
<Input type='textarea' placeholder={_t.textEditReply} autofocus value={stateText} onChange={(event) => {setText(event.target.value);}}></Input>
|
||||
</div>
|
||||
</div>
|
||||
</Popup>
|
||||
)
|
||||
}));
|
||||
|
||||
const EditReplyDialog = inject("storeComments")(observer(({storeComments, comment, reply, onEditReply}) => {
|
||||
const { t } = useTranslation();
|
||||
const _t = t('Common.Collaboration', {returnObjects: true});
|
||||
const templateInitials = `<div class="initials" style="background-color: ${reply.userColor};">${reply.userInitials}</div>`;
|
||||
useEffect(() => {
|
||||
f7.dialog.create({
|
||||
destroyOnClose: true,
|
||||
containerEl: document.getElementById('edit-reply-dialog'),
|
||||
content:
|
||||
`<div class="navbar">
|
||||
<div class="navbar-bg"></div>
|
||||
<div class="navbar-inner sliding">
|
||||
<div class="left">
|
||||
<a href="#" id="reply-cancel">${_t.textCancel}</a>
|
||||
</div>
|
||||
<div class="title">${_t.textEditReply}</div>
|
||||
<div class="right">
|
||||
<a href="#" class="done" id="reply-done">${ Device.android ? '<i class="icon icon-done-comment-white"></i>' : _t.textDone}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='wrap-comment'>
|
||||
<div class="comment-header">
|
||||
${Device.android ? templateInitials : ''}
|
||||
<div>
|
||||
<div class='name'>${reply.userName}</div>
|
||||
<div class='reply-date'>${reply.date}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='wrap-textarea'>
|
||||
<textarea id='reply-text' placeholder='${_t.textEditComment}' autofocus>${reply.reply}</textarea>
|
||||
</div>
|
||||
</div>`,
|
||||
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 (
|
||||
<div id='edit-reply-dialog'></div>
|
||||
);
|
||||
}));
|
||||
|
||||
const EditReply = ({comment, reply, onEditReply}) => {
|
||||
return (
|
||||
Device.phone ?
|
||||
<EditReplyPopup comment={comment} reply={reply} onEditReply={onEditReply}/> :
|
||||
<EditReplyDialog comment={comment} reply={reply} onEditReply={onEditReply}/>
|
||||
)
|
||||
};
|
||||
|
||||
|
@ -221,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 (
|
||||
<Page>
|
||||
<Navbar title={_t.textComments} backLink={_t.textBack}/>
|
||||
|
@ -245,7 +571,7 @@ const ViewComments = ({storeComments, storeAppOptions, onCommentMenuClick, onRes
|
|||
<div className='right'>
|
||||
<div className='comment-resolve' onClick={() => {onResolveComment(comment);}}><Icon icon={comment.resolved ? 'icon-resolve-comment check' : 'icon-resolve-comment'} /></div>
|
||||
<div className='comment-menu'
|
||||
onClick={() => {setClickComment(comment); openActionComment(true);}}
|
||||
onClick={() => {setComment(comment); openActionComment(true);}}
|
||||
><Icon icon='icon-menu-comment'/></div>
|
||||
</div>
|
||||
}
|
||||
|
@ -254,7 +580,7 @@ const ViewComments = ({storeComments, storeAppOptions, onCommentMenuClick, onRes
|
|||
{comment.quote && <div className='comment-quote'>{sliceQuote(comment.quote)}</div>}
|
||||
<div className='comment-text'><pre>{comment.comment}</pre></div>
|
||||
{comment.replies.length > 0 &&
|
||||
<ul className='list-reply'>
|
||||
<ul className='reply-list'>
|
||||
{comment.replies.map((reply, indexReply) => {
|
||||
return (
|
||||
<li key={`reply-${indexComment}-${indexReply}`}
|
||||
|
@ -273,7 +599,11 @@ const ViewComments = ({storeComments, storeAppOptions, onCommentMenuClick, onRes
|
|||
</div>
|
||||
{!viewMode &&
|
||||
<div className='right'>
|
||||
<div className='reply-menu'><Icon icon='icon-menu-comment'/></div>
|
||||
<div className='reply-menu'
|
||||
onClick={() => {setComment(comment); setReply(reply); openActionReply(true);}}
|
||||
>
|
||||
<Icon icon='icon-menu-comment'/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
@ -296,14 +626,108 @@ const ViewComments = ({storeComments, storeAppOptions, onCommentMenuClick, onRes
|
|||
}
|
||||
|
||||
<CommentActions comment={clickComment} onCommentMenuClick={onCommentMenuClick} opened={commentActionsOpened} openActionComment={openActionComment}/>
|
||||
<ReplyActions comment={clickComment} reply={reply} onCommentMenuClick={onCommentMenuClick} opened={replyActionsOpened} openActionReply={openActionReply}/>
|
||||
</Page>
|
||||
)
|
||||
};
|
||||
|
||||
const _ViewComments = inject('storeComments', 'storeAppOptions')(observer(ViewComments));
|
||||
|
||||
const CommentList = () => {
|
||||
return (
|
||||
<List>
|
||||
|
||||
</List>
|
||||
)
|
||||
};
|
||||
|
||||
const ViewCommentSheet = ({closeCurComments}) => {
|
||||
const { t } = useTranslation();
|
||||
const _t = t('Common.Collaboration', {returnObjects: true});
|
||||
|
||||
useEffect(() => {
|
||||
f7.sheet.open('#view-comment-sheet');
|
||||
});
|
||||
|
||||
const [stateHeight, setHeight] = useState('45%');
|
||||
const [stateOpacity, setOpacity] = useState(1);
|
||||
|
||||
const [stateStartY, setStartY] = useState();
|
||||
const [isNeedClose, setNeedClose] = useState(false);
|
||||
|
||||
const handleTouchStart = (event) => {
|
||||
const touchObj = event.changedTouches[0];
|
||||
setStartY(parseInt(touchObj.clientY));
|
||||
};
|
||||
const handleTouchMove = (event) => {
|
||||
const touchObj = event.changedTouches[0];
|
||||
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 {
|
||||
setNeedClose(true);
|
||||
setOpacity(0.6);
|
||||
}
|
||||
};
|
||||
const handleTouchEnd = (event) => {
|
||||
console.log('end');
|
||||
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%');
|
||||
}
|
||||
};
|
||||
return (
|
||||
<Sheet id='view-comment-sheet' style={{height: `${stateHeight}`, opacity: `${stateOpacity}`}}>
|
||||
<Toolbar position='bottom'>
|
||||
<Link className='btn-add-reply' href='#'>{_t.textAddReply}</Link>
|
||||
<div className='comment-navigation row'>
|
||||
<Link href='#'><Icon slot='media' icon='icon-prev'/></Link>
|
||||
<Link href='#'><Icon slot='media' icon='icon-next'/></Link>
|
||||
</div>
|
||||
</Toolbar>
|
||||
<div id='swipe-handler' className='swipe-container' onTouchStart={handleTouchStart} onTouchMove={handleTouchMove} onTouchEnd={handleTouchEnd}>
|
||||
<Icon icon='icon-swipe'/>
|
||||
</div>
|
||||
<CommentList />
|
||||
</Sheet>
|
||||
)
|
||||
};
|
||||
|
||||
const ViewCommentPopover = () => {
|
||||
useEffect(() => {
|
||||
f7.popover.open('#view-comment-popover', '#btn-coauth');
|
||||
});
|
||||
return (
|
||||
<Popover id='view-comment-popover'>
|
||||
<CommentList />
|
||||
</Popover>
|
||||
)
|
||||
};
|
||||
|
||||
const ViewCurrentComments = props => {
|
||||
return (
|
||||
Device.phone ?
|
||||
<ViewCommentSheet {...props}/> :
|
||||
<ViewCommentPopover {...props}/>
|
||||
)
|
||||
};
|
||||
|
||||
export {
|
||||
AddComment,
|
||||
EditComment,
|
||||
_ViewComments as ViewComments
|
||||
}
|
||||
AddReply,
|
||||
EditReply,
|
||||
_ViewComments as ViewComments,
|
||||
ViewCurrentComments
|
||||
};
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
@comment-date: #6d6d72;
|
||||
@swipe-icon: rgba(0, 0, 0, 0.12);
|
||||
|
||||
@import './ios/comments';
|
||||
@import './material/comments';
|
||||
|
||||
|
@ -17,14 +20,14 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
#add-comment-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 {
|
||||
.name, .comment-date, .reply-date {
|
||||
text-align: left;
|
||||
}
|
||||
.wrap-textarea {
|
||||
|
@ -74,7 +77,6 @@
|
|||
line-height: 18px;
|
||||
color: @comment-date;
|
||||
margin: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
.comment-quote {
|
||||
color: @themeColor;
|
||||
|
@ -96,11 +98,60 @@
|
|||
overflow-wrap: break-word;
|
||||
}
|
||||
}
|
||||
.list-reply {
|
||||
.reply-list {
|
||||
padding-left: 26px;
|
||||
}
|
||||
}
|
||||
|
||||
.edit-comment-popup {
|
||||
.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 200ms;
|
||||
transition: height 200ms;
|
||||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,8 +8,6 @@
|
|||
@background-normal: @white;
|
||||
@autoColor: @black;
|
||||
|
||||
@comment-date: #6d6d72;
|
||||
|
||||
.popup, .popover, .sheet-modal {
|
||||
.list {
|
||||
&:first-child {
|
||||
|
|
|
@ -4,5 +4,16 @@
|
|||
&.icon_mask {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
&.icon-prev {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
.encoded-svg-background('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 22 22" fill="@{themeColor}"><g><path d="M16,20.5L15,21.5L4.5,11l0,0l0,0L15,0.5L16,1.5L6.6,11L16,20.5z"/></g></svg>');
|
||||
}
|
||||
&.icon-next {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
.encoded-svg-background('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 22 22" fill="@{themeColor}"><g><path d="M15.5,11L6,1.5l1.1-1.1L17.5,11l0,0l0,0L7.1,21.5L6,20.5L15.5,11z"/></g></svg>');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
.device-android {
|
||||
.wrap-comment {
|
||||
.header-comment {
|
||||
.wrap-comment, .comment-list, .reply-list {
|
||||
.comment-header, .reply-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.initials {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
border-radius: 50px;
|
||||
color: @white;
|
||||
display: flex;
|
||||
|
@ -15,13 +12,24 @@
|
|||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.wrap-comment {
|
||||
.comment-header {
|
||||
align-items: center;
|
||||
.initials {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
}
|
||||
}
|
||||
.wrap-textarea {
|
||||
.input:not(.input-outline):after {
|
||||
content: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
#add-comment-dialog {
|
||||
|
||||
#add-comment-dialog, #edit-comment-dialog, #add-reply-dialog, #edit-reply-dialog {
|
||||
.dialog {
|
||||
--f7-dialog-text-color: @black;
|
||||
.done {
|
||||
|
@ -29,4 +37,46 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.comment-list {
|
||||
.item-inner:after {
|
||||
content: none;
|
||||
}
|
||||
.comment-header {
|
||||
.left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.initials {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.reply-list {
|
||||
.reply-header {
|
||||
.left {
|
||||
display: flex;
|
||||
.initials {
|
||||
margin-top: 5px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.edit-comment-popup, .edit-reply-popup, #edit-comment-dialog, #edit-reply-dialog {
|
||||
.wrap-comment {
|
||||
.comment-header, .reply-header {
|
||||
.initials {
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -4,5 +4,16 @@
|
|||
&.icon_mask {
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
&.icon-prev {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
.encoded-svg-background('<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M15.4219 7.40625L10.8281 12L15.4219 16.5938L14.0156 18L8.01562 12L14.0156 6L15.4219 7.40625Z" fill="@{themeColor}"/></svg>');
|
||||
}
|
||||
&.icon-next {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
.encoded-svg-background('<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9.98438 6L15.9844 12L9.98438 18L8.57812 16.5938L13.1719 12L8.57812 7.40625L9.98438 6Z" fill="@{themeColor}"/></svg>');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -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,244 @@ class ContextMenu extends ContextMenuController {
|
|||
onMenuItemClick(action) {
|
||||
super.onMenuItemClick(action);
|
||||
|
||||
console.log("on click item");
|
||||
switch (action) {
|
||||
case 'addcomment':
|
||||
Common.Notifications.trigger('addcomment');
|
||||
break;
|
||||
case 'viewcomment':
|
||||
Common.Notifications.trigger('viewcomment');
|
||||
break;
|
||||
}
|
||||
|
||||
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'
|
||||
});
|
||||
}
|
||||
|
||||
// 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',
|
||||
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: '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 };
|
||||
export { ContextMenu as default };
|
|
@ -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} from "../../../../common/mobile/lib/controller/collaboration/Comments";
|
||||
import {
|
||||
CommentsController,
|
||||
AddCommentController,
|
||||
EditCommentController,
|
||||
ViewCommentsController
|
||||
} from "../../../../common/mobile/lib/controller/collaboration/Comments";
|
||||
|
||||
@inject(
|
||||
"storeAppOptions",
|
||||
|
@ -335,6 +340,8 @@ class MainController extends Component {
|
|||
<ReviewController />
|
||||
<CommentsController />
|
||||
<AddCommentController />
|
||||
<EditCommentController />
|
||||
<ViewCommentsController />
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -440,16 +440,6 @@
|
|||
height: 24px;
|
||||
.encoded-svg-background('<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9 16.1719L19.5938 5.57812L21 6.98438L9 18.9844L3.42188 13.4062L4.82812 12L9 16.1719Z" fill="#40865C" fill-opacity="0.6"/></svg>');
|
||||
}
|
||||
&.icon-prev-comment {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
.encoded-svg-background('<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M15.4219 7.40625L10.8281 12L15.4219 16.5938L14.0156 18L8.01562 12L14.0156 6L15.4219 7.40625Z" fill="@{themeColor}"/></svg>');
|
||||
}
|
||||
&.icon-next-comment {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
.encoded-svg-background('<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9.98438 6L15.9844 12L9.98438 18L8.57812 16.5938L13.1719 12L8.57812 7.40625L9.98438 6Z" fill="@{themeColor}"/></svg>');
|
||||
}
|
||||
&.icon-done-comment {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
|
|
|
@ -8,10 +8,9 @@ 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, idContextMenuElement } from '../controller/ContextMenu';
|
||||
import ContextMenu from '../controller/ContextMenu';
|
||||
|
||||
export default class MainPage extends Component {
|
||||
constructor(props) {
|
||||
|
@ -25,7 +24,7 @@ export default class MainPage extends Component {
|
|||
}
|
||||
|
||||
handleClickToOpenOptions = opts => {
|
||||
f7.popover.close(idContextMenuElement, false);
|
||||
ContextMenu.closeContextMenu();
|
||||
|
||||
this.setState(state => {
|
||||
if ( opts == 'edit' )
|
||||
|
|
|
@ -1,8 +1,23 @@
|
|||
import {action, observable} from 'mobx';
|
||||
import {makeObservable, action, observable} from 'mobx';
|
||||
|
||||
export class storeAppOptions {
|
||||
constructor() {
|
||||
makeObservable(this, {
|
||||
isEdit: observable,
|
||||
canViewComments: observable,
|
||||
canReview: observable,
|
||||
setConfigOptions: action,
|
||||
setPermissionOptions: action,
|
||||
setCanViewReview: action
|
||||
});
|
||||
}
|
||||
|
||||
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';
|
||||
|
@ -24,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);
|
||||
|
@ -71,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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
@ -67,7 +71,6 @@ export class storeTableSettings {
|
|||
// Border style
|
||||
@observable cellBorders;
|
||||
@observable cellBorderWidth = 0.5;
|
||||
@observable cellBorderWidth = 0.5;
|
||||
@observable cellBorderColor = '000000';
|
||||
|
||||
borderSizeTransform () {
|
||||
|
|
|
@ -202,7 +202,7 @@ const AddOther = props => {
|
|||
<List>
|
||||
<ListItem title={_t.textComment} onClick={() => {
|
||||
props.closeModal();
|
||||
props.storeComments.openAddComment(true);
|
||||
Common.Notifications.trigger('addcomment');
|
||||
}}>
|
||||
<Icon slot="media" icon="icon-insert-comment"></Icon>
|
||||
</ListItem>
|
||||
|
|
|
@ -187,18 +187,6 @@
|
|||
.encoded-svg-mask('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 22 22" fill="@{themeColor}"><g><path d="M1,20v-1h21v1H1z M12,16H1v-1h11V16z M12,12H1v-1h11V12z M12,8H1V7h11V8z M21,11.2l0.2,0.3L21,11.8L16.7,16L16,15.3l3.8-3.8L16,7.7L16.7,7L21,11.2z M22,4H1V3h21V4z"/></g></svg>');
|
||||
}
|
||||
|
||||
&.icon-prev, &.icon-prev-comment {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
.encoded-svg-background('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 22 22" fill="@{themeColor}"><g><path d="M16,20.5L15,21.5L4.5,11l0,0l0,0L15,0.5L16,1.5L6.6,11L16,20.5z"/></g></svg>');
|
||||
}
|
||||
|
||||
&.icon-next, &.icon-next-comment {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
.encoded-svg-background('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 22 22" fill="@{themeColor}"><g><path d="M15.5,11L6,1.5l1.1-1.1L17.5,11l0,0l0,0L7.1,21.5L6,20.5L15.5,11z"/></g></svg>');
|
||||
}
|
||||
|
||||
&.icon-table-add-column-left {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
|
|
|
@ -471,18 +471,6 @@
|
|||
.encoded-svg-background('<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9 16.1719L19.5938 5.57812L21 6.98438L9 18.9844L3.42188 13.4062L4.82812 12L9 16.1719Z" fill="#40865C" fill-opacity="0.6"/></svg>');
|
||||
}
|
||||
|
||||
&.icon-prev-comment {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
.encoded-svg-background('<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M15.4219 7.40625L10.8281 12L15.4219 16.5938L14.0156 18L8.01562 12L14.0156 6L15.4219 7.40625Z" fill="@{themeColor}"/></svg>');
|
||||
}
|
||||
|
||||
&.icon-next-comment {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
.encoded-svg-background('<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9.98438 6L15.9844 12L9.98438 18L8.57812 16.5938L13.1719 12L8.57812 7.40625L9.98438 6Z" fill="@{themeColor}"/></svg>');
|
||||
}
|
||||
|
||||
&.icon-done-comment {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -123,16 +123,6 @@
|
|||
height: 22px;
|
||||
.encoded-svg-mask('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 22 22" fill="@{themeColor}"><g><rect class="cls-1" x="2" y="18" width="19" height="1"/><rect class="cls-1" x="2" y="20" width="19" height="1"/><polygon class="cls-1" points="11 4 12 4 12 15.17 14.35 13.2 15 14.06 11.5 17 8 14 8.65 13.2 11 15.17 11 4"/></g></svg>');
|
||||
}
|
||||
&.icon-prev, &.icon-prev-comment {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
.encoded-svg-background('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 22 22" fill="@{themeColor}"><g><path d="M16,20.5L15,21.5L4.5,11l0,0l0,0L15,0.5L16,1.5L6.6,11L16,20.5z"/></g></svg>');
|
||||
}
|
||||
&.icon-next, &.icon-next-comment {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
.encoded-svg-background('<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 22 22" fill="@{themeColor}"><g><path d="M15.5,11L6,1.5l1.1-1.1L17.5,11l0,0l0,0L7.1,21.5L6,20.5L15.5,11z"/></g></svg>');
|
||||
}
|
||||
&.icon-expand-down {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
|
|
|
@ -365,16 +365,6 @@
|
|||
height: 24px;
|
||||
.encoded-svg-background('<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9 16.1719L19.5938 5.57812L21 6.98438L9 18.9844L3.42188 13.4062L4.82812 12L9 16.1719Z" fill="#40865C" fill-opacity="0.6"/></svg>');
|
||||
}
|
||||
&.icon-prev-comment {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
.encoded-svg-background('<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M15.4219 7.40625L10.8281 12L15.4219 16.5938L14.0156 18L8.01562 12L14.0156 6L15.4219 7.40625Z" fill="@{themeColor}"/></svg>');
|
||||
}
|
||||
&.icon-next-comment {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
.encoded-svg-background('<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9.98438 6L15.9844 12L9.98438 18L8.57812 16.5938L13.1719 12L8.57812 7.40625L9.98438 6Z" fill="@{themeColor}"/></svg>');
|
||||
}
|
||||
&.icon-done-comment {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
|
|
2
vendor/framework7-react/babel.config.js
vendored
2
vendor/framework7-react/babel.config.js
vendored
|
@ -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}],
|
||||
],
|
||||
};
|
||||
|
|
4
vendor/framework7-react/package.json
vendored
4
vendor/framework7-react/package.json
vendored
|
@ -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",
|
||||
|
|
Loading…
Reference in a new issue