[SSE mobile] Resolved conflict
This commit is contained in:
commit
4a0af99640
|
@ -1,6 +1,7 @@
|
||||||
import React, { Component, Fragment } from 'react';
|
import React, { Component, Fragment } from 'react';
|
||||||
import { f7 } from 'framework7-react';
|
import { f7 } from 'framework7-react';
|
||||||
import { Device } from '../../../../common/mobile/utils/device'
|
import {observer, inject} from "mobx-react";
|
||||||
|
import { Device } from '../../../../common/mobile/utils/device';
|
||||||
|
|
||||||
import ContextMenuView, { idContextMenuElement, ActionsWithExtraItems } from '../view/ContextMenu';
|
import ContextMenuView, { idContextMenuElement, ActionsWithExtraItems } from '../view/ContextMenu';
|
||||||
|
|
||||||
|
@ -23,6 +24,8 @@ class ContextMenuController extends Component {
|
||||||
this.onDocumentReady = this.onDocumentReady.bind(this);
|
this.onDocumentReady = this.onDocumentReady.bind(this);
|
||||||
this.onApiOpenContextMenu = this.onApiOpenContextMenu.bind(this);
|
this.onApiOpenContextMenu = this.onApiOpenContextMenu.bind(this);
|
||||||
this.onApiHideContextMenu = this.onApiHideContextMenu.bind(this);
|
this.onApiHideContextMenu = this.onApiHideContextMenu.bind(this);
|
||||||
|
this.onApiShowForeignCursorLabel = this.onApiShowForeignCursorLabel.bind(this);
|
||||||
|
this.onApiHideForeignCursorLabel = this.onApiHideForeignCursorLabel.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onDocumentReady() {
|
onDocumentReady() {
|
||||||
|
@ -38,6 +41,8 @@ class ContextMenuController extends Component {
|
||||||
const api = Common.EditorApi.get();
|
const api = Common.EditorApi.get();
|
||||||
api.asc_registerCallback('asc_onShowPopMenu', this.onApiOpenContextMenu);
|
api.asc_registerCallback('asc_onShowPopMenu', this.onApiOpenContextMenu);
|
||||||
api.asc_registerCallback('asc_onHidePopMenu', this.onApiHideContextMenu);
|
api.asc_registerCallback('asc_onHidePopMenu', this.onApiHideContextMenu);
|
||||||
|
api.asc_registerCallback('asc_onShowForeignCursorLabel', this.onApiShowForeignCursorLabel);
|
||||||
|
api.asc_registerCallback('asc_onHideForeignCursorLabel', this.onApiHideForeignCursorLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
offsetPopoverTop(popover) {
|
offsetPopoverTop(popover) {
|
||||||
|
@ -150,12 +155,61 @@ class ContextMenuController extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onApiShowForeignCursorLabel(UserId, X, Y, color) {
|
||||||
|
/** coauthoring begin **/
|
||||||
|
const tipHeight = 20;
|
||||||
|
|
||||||
|
if (!this.fastCoAuthTips) {
|
||||||
|
this.fastCoAuthTips = [];
|
||||||
|
}
|
||||||
|
let src;
|
||||||
|
for (let i=0; i<this.fastCoAuthTips.length; i++) {
|
||||||
|
if (this.fastCoAuthTips[i].attr('userid') === UserId) {
|
||||||
|
src = this.fastCoAuthTips[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!src) {
|
||||||
|
src = $$(`<div class="username-tip"></div>`);
|
||||||
|
src.attr('userid', UserId);
|
||||||
|
src.css({'background-color': '#'+Common.Utils.ThemeColor.getHexColor(color.get_r(), color.get_g(), color.get_b())});
|
||||||
|
src.text(this.getUserName(UserId));
|
||||||
|
$$('#id_main_parent').append(src);
|
||||||
|
this.fastCoAuthTips.push(src);
|
||||||
|
//src.fadeIn(150);
|
||||||
|
src[0].classList.add('active');
|
||||||
|
|
||||||
|
$$('#id_main_view').append(src);
|
||||||
|
}
|
||||||
|
src.css({
|
||||||
|
top: (Y - tipHeight) + 'px',
|
||||||
|
left: X + 'px'});
|
||||||
|
/** coauthoring end **/
|
||||||
|
}
|
||||||
|
|
||||||
|
onApiHideForeignCursorLabel(userId) {
|
||||||
|
/** coauthoring begin **/
|
||||||
|
for (let i=0; i<this.fastCoAuthTips.length; i++) {
|
||||||
|
if (this.fastCoAuthTips[i].attr('userid') == userId) {
|
||||||
|
const src = this.fastCoAuthTips[i];
|
||||||
|
//this.fastCoAuthTips[i].fadeOut(150, () => {src.remove()});
|
||||||
|
src[0].classList.remove('active');
|
||||||
|
src.remove();
|
||||||
|
this.fastCoAuthTips.splice(i, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** coauthoring end **/
|
||||||
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
Common.Notifications.off('document:ready', this.onDocumentReady);
|
Common.Notifications.off('document:ready', this.onDocumentReady);
|
||||||
|
|
||||||
const api = Common.EditorApi.get();
|
const api = Common.EditorApi.get();
|
||||||
api.asc_unregisterCallback('asc_onShowPopMenu', this.onApiOpenContextMenu);
|
api.asc_unregisterCallback('asc_onShowPopMenu', this.onApiOpenContextMenu);
|
||||||
api.asc_unregisterCallback('asc_onHidePopMenu', this.onApiHideContextMenu);
|
api.asc_unregisterCallback('asc_onHidePopMenu', this.onApiHideContextMenu);
|
||||||
|
api.asc_unregisterCallback('asc_onShowForeignCursorLabel', this.onApiShowForeignCursorLabel);
|
||||||
|
api.asc_unregisterCallback('asc_onHideForeignCursorLabel', this.onApiHideForeignCursorLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
|
|
@ -1,17 +1,63 @@
|
||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import {observer, inject} from "mobx-react"
|
import {observer, inject} from "mobx-react"
|
||||||
|
import { LocalStorage } from '../../../utils/LocalStorage';
|
||||||
|
|
||||||
class CollaborationController extends Component {
|
class CollaborationController extends Component {
|
||||||
constructor(props){
|
constructor(props){
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
Common.Notifications.on('configOptionsFill', () => {
|
Common.Notifications.on('engineCreated', (api) => {
|
||||||
const api = Common.EditorApi.get();
|
|
||||||
// this.api = api;
|
|
||||||
api.asc_registerCallback('asc_onAuthParticipantsChanged', this.onChangeEditUsers.bind(this));
|
api.asc_registerCallback('asc_onAuthParticipantsChanged', this.onChangeEditUsers.bind(this));
|
||||||
api.asc_registerCallback('asc_onParticipantsChanged', this.onChangeEditUsers.bind(this));
|
api.asc_registerCallback('asc_onParticipantsChanged', this.onChangeEditUsers.bind(this));
|
||||||
api.asc_registerCallback('asc_onConnectionStateChanged', this.onUserConnection.bind(this));
|
api.asc_registerCallback('asc_onConnectionStateChanged', this.onUserConnection.bind(this));
|
||||||
|
api.asc_registerCallback('asc_onCoAuthoringDisconnect', this.onCoAuthoringDisconnect.bind(this));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Common.Notifications.on('document:ready', this.onDocumentReady.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
onDocumentReady() {
|
||||||
|
const api = Common.EditorApi.get();
|
||||||
|
const appOptions = this.props.storeAppOptions;
|
||||||
|
/** coauthoring begin **/
|
||||||
|
let isFastCoauth;
|
||||||
|
if (appOptions.isEdit && appOptions.canLicense && !appOptions.isOffline && appOptions.canCoAuthoring) {
|
||||||
|
// Force ON fast co-authoring mode
|
||||||
|
isFastCoauth = true;
|
||||||
|
api.asc_SetFastCollaborative(isFastCoauth);
|
||||||
|
|
||||||
|
if (window.editorType === 'de') {
|
||||||
|
const value = LocalStorage.getItem((isFastCoauth) ? "de-settings-showchanges-fast" : "de-settings-showchanges-strict");
|
||||||
|
if (value !== null) {
|
||||||
|
api.SetCollaborativeMarksShowType(
|
||||||
|
value === 'all' ? Asc.c_oAscCollaborativeMarksShowType.All :
|
||||||
|
value === 'none' ? Asc.c_oAscCollaborativeMarksShowType.None : Asc.c_oAscCollaborativeMarksShowType.LastChanges);
|
||||||
|
} else {
|
||||||
|
api.SetCollaborativeMarksShowType(isFastCoauth ? Asc.c_oAscCollaborativeMarksShowType.None : Asc.c_oAscCollaborativeMarksShowType.LastChanges);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!appOptions.isEdit && appOptions.isRestrictedEdit) {
|
||||||
|
isFastCoauth = true;
|
||||||
|
api.asc_SetFastCollaborative(isFastCoauth);
|
||||||
|
window.editorType === 'de' && api.SetCollaborativeMarksShowType(Asc.c_oAscCollaborativeMarksShowType.None);
|
||||||
|
api.asc_setAutoSaveGap(1);
|
||||||
|
} else {
|
||||||
|
isFastCoauth = false;
|
||||||
|
api.asc_SetFastCollaborative(isFastCoauth);
|
||||||
|
window.editorType === 'de' && api.SetCollaborativeMarksShowType(Asc.c_oAscCollaborativeMarksShowType.None);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (appOptions.isEdit) {
|
||||||
|
let value;
|
||||||
|
if (window.editorType === 'sse') {
|
||||||
|
value = appOptions.canAutosave ? 1 : 0; // FORCE AUTOSAVE
|
||||||
|
} else {
|
||||||
|
value = isFastCoauth; // Common.localStorage.getItem("de-settings-autosave");
|
||||||
|
value = (!isFastCoauth && value !== null) ? parseInt(value) : (appOptions.canCoAuthoring ? 1 : 0);
|
||||||
|
}
|
||||||
|
api.asc_setAutoSaveGap(value);
|
||||||
|
}
|
||||||
|
/** coauthoring end **/
|
||||||
}
|
}
|
||||||
|
|
||||||
onChangeEditUsers(users) {
|
onChangeEditUsers(users) {
|
||||||
|
@ -24,6 +70,10 @@ class CollaborationController extends Component {
|
||||||
this.props.users.connection(change);
|
this.props.users.connection(change);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onCoAuthoringDisconnect() {
|
||||||
|
this.props.users.resetDisconnected(true);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,6 +238,9 @@ class AddCommentController extends Component {
|
||||||
}
|
}
|
||||||
getUserInfo () {
|
getUserInfo () {
|
||||||
this.currentUser = this.props.users.currentUser;
|
this.currentUser = this.props.users.currentUser;
|
||||||
|
if (!this.currentUser) {
|
||||||
|
this.currentUser = this.props.users.setCurrentUser(this.props.storeAppOptions.user.id);
|
||||||
|
}
|
||||||
const name = this.currentUser.asc_getUserName();
|
const name = this.currentUser.asc_getUserName();
|
||||||
return {
|
return {
|
||||||
name: name,
|
name: name,
|
||||||
|
|
|
@ -8,12 +8,15 @@ export class storeUsers {
|
||||||
reset: action,
|
reset: action,
|
||||||
currentUser: observable,
|
currentUser: observable,
|
||||||
setCurrentUser: action,
|
setCurrentUser: action,
|
||||||
connection: action
|
connection: action,
|
||||||
|
isDisconnected: observable,
|
||||||
|
resetDisconnected: action
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
users = [];
|
users = [];
|
||||||
currentUser;
|
currentUser;
|
||||||
|
isDisconnected = false;
|
||||||
|
|
||||||
reset (users) {
|
reset (users) {
|
||||||
this.users = Object.values(users)
|
this.users = Object.values(users)
|
||||||
|
@ -25,6 +28,7 @@ export class storeUsers {
|
||||||
this.currentUser = item;
|
this.currentUser = item;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return this.currentUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
connection (change) {
|
connection (change) {
|
||||||
|
@ -41,6 +45,10 @@ export class storeUsers {
|
||||||
!changed && change && (this.users[change.asc_getId()] = change);
|
!changed && change && (this.users[change.asc_getId()] = change);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetDisconnected (isDisconnected) {
|
||||||
|
this.isDisconnected = isDisconnected;
|
||||||
|
}
|
||||||
|
|
||||||
getInitials (name) {
|
getInitials (name) {
|
||||||
const fio = Common.Utils.UserInfoParser.getParsedName(name).split(' ');
|
const fio = Common.Utils.UserInfoParser.getParsedName(name).split(' ');
|
||||||
let initials = fio[0].substring(0, 1).toUpperCase();
|
let initials = fio[0].substring(0, 1).toUpperCase();
|
||||||
|
@ -62,4 +70,14 @@ export class storeUsers {
|
||||||
});
|
});
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
searchUserByCurrentId (id) {
|
||||||
|
let user = null;
|
||||||
|
this.users.forEach((item) => {
|
||||||
|
if (item.asc_getId() === id) {
|
||||||
|
user = item;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return user;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ const ActionsWithExtraItems = ({items, onMenuItemClick, opened, onActionClosed})
|
||||||
<ActionsGroup>
|
<ActionsGroup>
|
||||||
{items.length > 0 && items.map((item, index)=>{
|
{items.length > 0 && items.map((item, index)=>{
|
||||||
return(
|
return(
|
||||||
<ActionsButton key={`act-${item.caption}`} onClick={() => {onMenuItemClick(item.event)}}>{item.caption}</ActionsButton>
|
<ActionsButton key={`act-${index}`} onClick={() => {onMenuItemClick(item.event)}}>{item.caption}</ActionsButton>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</ActionsGroup>
|
</ActionsGroup>
|
||||||
|
|
|
@ -669,6 +669,22 @@ input[type="number"]::-webkit-inner-spin-button {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.username-tip {
|
||||||
|
height: 20px;
|
||||||
|
color: @white;
|
||||||
|
padding: 0 10px;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 900;
|
||||||
|
display: none;
|
||||||
|
pointer-events: none;
|
||||||
|
transition: opacity 0.1ms ease-out;
|
||||||
|
opacity: 0;
|
||||||
|
&.active {
|
||||||
|
display: block;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.comment-list {
|
.comment-list {
|
||||||
.item-inner:after, li:last-child li .item-inner:after {
|
ul:after, .item-inner:after, li:last-child li .item-inner:after {
|
||||||
content: none;
|
content: none;
|
||||||
}
|
}
|
||||||
.comment-header {
|
.comment-header {
|
||||||
|
|
|
@ -11,7 +11,9 @@ import { Device } from '../../../../common/mobile/utils/device';
|
||||||
@inject ( stores => ({
|
@inject ( stores => ({
|
||||||
isEdit: stores.storeAppOptions.isEdit,
|
isEdit: stores.storeAppOptions.isEdit,
|
||||||
canViewComments: stores.storeAppOptions.canViewComments,
|
canViewComments: stores.storeAppOptions.canViewComments,
|
||||||
canReview: stores.storeAppOptions.canReview
|
canReview: stores.storeAppOptions.canReview,
|
||||||
|
users: stores.users,
|
||||||
|
isDisconnected: stores.users.isDisconnected
|
||||||
}))
|
}))
|
||||||
class ContextMenu extends ContextMenuController {
|
class ContextMenu extends ContextMenuController {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -21,12 +23,18 @@ class ContextMenu extends ContextMenuController {
|
||||||
this.onApiShowComment = this.onApiShowComment.bind(this);
|
this.onApiShowComment = this.onApiShowComment.bind(this);
|
||||||
this.onApiHideComment = this.onApiHideComment.bind(this);
|
this.onApiHideComment = this.onApiHideComment.bind(this);
|
||||||
this.onApiShowChange = this.onApiShowChange.bind(this);
|
this.onApiShowChange = this.onApiShowChange.bind(this);
|
||||||
|
this.getUserName = this.getUserName.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
static closeContextMenu() {
|
static closeContextMenu() {
|
||||||
f7.popover.close(idContextMenuElement, false);
|
f7.popover.close(idContextMenuElement, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getUserName(id) {
|
||||||
|
const user = this.props.users.searchUserByCurrentId(id);
|
||||||
|
return Common.Utils.UserInfoParser.getParsedName(user.asc_getUserName());
|
||||||
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
super.componentWillUnmount();
|
super.componentWillUnmount();
|
||||||
|
|
||||||
|
@ -224,7 +232,7 @@ class ContextMenu extends ContextMenuController {
|
||||||
const { t } = this.props;
|
const { t } = this.props;
|
||||||
const _t = t("ContextMenu", { returnObjects: true });
|
const _t = t("ContextMenu", { returnObjects: true });
|
||||||
|
|
||||||
const { isEdit, canViewComments, canReview } = this.props;
|
const { isEdit, canViewComments, canReview, isDisconnected } = this.props;
|
||||||
|
|
||||||
const api = Common.EditorApi.get();
|
const api = Common.EditorApi.get();
|
||||||
const stack = api.getSelectedElements();
|
const stack = api.getSelectedElements();
|
||||||
|
@ -294,7 +302,7 @@ class ContextMenu extends ContextMenuController {
|
||||||
items[indexAfter] = items.splice(indexBefore, 1, items[indexAfter])[0];
|
items[indexAfter] = items.splice(indexBefore, 1, items[indexAfter])[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
if ( isEdit && !this.isDisconnected ) {
|
if ( isEdit && !isDisconnected ) {
|
||||||
if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader && canCopy ) {
|
if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader && canCopy ) {
|
||||||
itemsIcon.push({
|
itemsIcon.push({
|
||||||
event: 'cut',
|
event: 'cut',
|
||||||
|
|
|
@ -24,6 +24,19 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"ContextMenu": {
|
||||||
|
"menuViewComment": "View Comment",
|
||||||
|
"menuAddComment": "Add Comment",
|
||||||
|
"menuDelete": "Delete",
|
||||||
|
"menuEdit": "Edit",
|
||||||
|
"menuAddLink": "Add Link",
|
||||||
|
"menuOpenLink": "Open Link",
|
||||||
|
"menuMore": "More",
|
||||||
|
"menuCancel": "Cancel",
|
||||||
|
"textCopyCutPasteActions": "Copy, Cut and Paste Actions",
|
||||||
|
"errorCopyCutPaste": "Copy, cut and paste actions using the context menu will be performed within the current file only.",
|
||||||
|
"textDoNotShowAgain": "Don't show again"
|
||||||
|
},
|
||||||
"View": {
|
"View": {
|
||||||
"Settings": {
|
"Settings": {
|
||||||
"textDone": "Done",
|
"textDone": "Done",
|
||||||
|
@ -101,6 +114,7 @@
|
||||||
"textColumns": "Columns",
|
"textColumns": "Columns",
|
||||||
"textRows": "Rows",
|
"textRows": "Rows",
|
||||||
"textCancel": "Cancel",
|
"textCancel": "Cancel",
|
||||||
|
"textAddLink": "Add Link",
|
||||||
"textLink": "Link",
|
"textLink": "Link",
|
||||||
"textLinkType": "Link Type",
|
"textLinkType": "Link Type",
|
||||||
"textExternalLink": "External Link",
|
"textExternalLink": "External Link",
|
||||||
|
@ -267,6 +281,27 @@
|
||||||
"textThemeColors": "Theme Colors",
|
"textThemeColors": "Theme Colors",
|
||||||
"textStandartColors": "Standard Colors",
|
"textStandartColors": "Standard Colors",
|
||||||
"textCustomColors": "Custom Colors"
|
"textCustomColors": "Custom Colors"
|
||||||
|
},
|
||||||
|
"Collaboration": {
|
||||||
|
"textCollaboration": "Collaboration",
|
||||||
|
"textBack": "Back",
|
||||||
|
"textUsers": "Users",
|
||||||
|
"textEditUser": "Users who are editing the file:",
|
||||||
|
"textComments": "Comments",
|
||||||
|
"textAddComment": "Add Comment",
|
||||||
|
"textCancel": "Cancel",
|
||||||
|
"textDone": "Done",
|
||||||
|
"textNoComments": "This document doesn't contain comments",
|
||||||
|
"textEdit": "Edit",
|
||||||
|
"textResolve": "Resolve",
|
||||||
|
"textReopen": "Reopen",
|
||||||
|
"textAddReply": "Add Reply",
|
||||||
|
"textDeleteComment": "Delete Comment",
|
||||||
|
"textMessageDeleteComment": "Do you really want to delete this comment?",
|
||||||
|
"textMessageDeleteReply": "Do you really want to delete this reply?",
|
||||||
|
"textDeleteReply": "Delete Reply",
|
||||||
|
"textEditComment": "Edit Comment",
|
||||||
|
"textEditReply": "Edit Reply"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,6 +4,8 @@ import ReactDOM from 'react-dom';
|
||||||
|
|
||||||
// Import Framework7
|
// Import Framework7
|
||||||
import Framework7 from 'framework7/lite-bundle';
|
import Framework7 from 'framework7/lite-bundle';
|
||||||
|
import { Dom7 } from 'framework7';
|
||||||
|
window.$$ = Dom7;
|
||||||
|
|
||||||
// Import Framework7-React Plugin
|
// Import Framework7-React Plugin
|
||||||
import Framework7React from 'framework7-react';
|
import Framework7React from 'framework7-react';
|
||||||
|
|
312
apps/presentationeditor/mobile/src/controller/ContextMenu.jsx
Normal file
312
apps/presentationeditor/mobile/src/controller/ContextMenu.jsx
Normal file
|
@ -0,0 +1,312 @@
|
||||||
|
import React, { useContext } from 'react';
|
||||||
|
import { f7 } from 'framework7-react';
|
||||||
|
import { inject, observer } from "mobx-react";
|
||||||
|
import { withTranslation} from 'react-i18next';
|
||||||
|
import { LocalStorage } from '../../../../common/mobile/utils/LocalStorage';
|
||||||
|
|
||||||
|
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,
|
||||||
|
users: stores.users,
|
||||||
|
isDisconnected: stores.users.isDisconnected
|
||||||
|
}))
|
||||||
|
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);
|
||||||
|
this.getUserName = this.getUserName.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
static closeContextMenu() {
|
||||||
|
f7.popover.close(idContextMenuElement, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
getUserName(id) {
|
||||||
|
const user = this.props.users.searchUserByCurrentId(id);
|
||||||
|
return Common.Utils.UserInfoParser.getParsedName(user.asc_getUserName());
|
||||||
|
}
|
||||||
|
|
||||||
|
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() {
|
||||||
|
// super.onMenuClosed();
|
||||||
|
// }
|
||||||
|
|
||||||
|
onMenuItemClick(action) {
|
||||||
|
super.onMenuItemClick(action);
|
||||||
|
|
||||||
|
const api = Common.EditorApi.get();
|
||||||
|
switch (action) {
|
||||||
|
case 'cut':
|
||||||
|
if (!api.Cut() && !LocalStorage.getBool("pe-hide-copy-cut-paste-warning")) {
|
||||||
|
this.showCopyCutPasteModal();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'copy':
|
||||||
|
if (!api.Copy() && !LocalStorage.getBool("pe-hide-copy-cut-paste-warning")) {
|
||||||
|
this.showCopyCutPasteModal();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'paste':
|
||||||
|
if (!api.Paste() && !LocalStorage.getBool("pe-hide-copy-cut-paste-warning")) {
|
||||||
|
this.showCopyCutPasteModal();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'addcomment':
|
||||||
|
Common.Notifications.trigger('addcomment');
|
||||||
|
break;
|
||||||
|
case 'viewcomment':
|
||||||
|
Common.Notifications.trigger('viewcomment');
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
api.asc_Remove();
|
||||||
|
break;
|
||||||
|
case 'edit':
|
||||||
|
setTimeout(() => {
|
||||||
|
this.props.openOptions('edit');
|
||||||
|
}, 0);
|
||||||
|
break;
|
||||||
|
case 'addlink':
|
||||||
|
setTimeout(() => {
|
||||||
|
this.props.openOptions('add', 'link');
|
||||||
|
}, 400)
|
||||||
|
break;
|
||||||
|
case 'openlink':
|
||||||
|
const stack = Common.EditorApi.get().getSelectedElements();
|
||||||
|
let value;
|
||||||
|
stack.forEach((item) => {
|
||||||
|
if (item.get_ObjectType() == Asc.c_oAscTypeSelectElement.Hyperlink) {
|
||||||
|
value = item.get_ObjectValue().get_Value();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
value && this.openLink(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("click context menu item: " + action);
|
||||||
|
}
|
||||||
|
|
||||||
|
showCopyCutPasteModal() {
|
||||||
|
const { t } = this.props;
|
||||||
|
const _t = t("ContextMenu", { returnObjects: true });
|
||||||
|
f7.dialog.create({
|
||||||
|
title: _t.textCopyCutPasteActions,
|
||||||
|
text: _t.errorCopyCutPaste,
|
||||||
|
content: `<div class="checkbox-in-modal">
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" name="checkbox-show" />
|
||||||
|
<i class="icon-checkbox"></i>
|
||||||
|
</label>
|
||||||
|
<span class="right-text">${_t.textDoNotShowAgain}</span>
|
||||||
|
</div>`,
|
||||||
|
buttons: [{
|
||||||
|
text: 'OK',
|
||||||
|
onClick: () => {
|
||||||
|
const dontShow = $$('input[name="checkbox-show"]').prop('checked');
|
||||||
|
if (dontShow) LocalStorage.setItem("de-hide-copy-cut-paste-warning", 1);
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}).open();
|
||||||
|
}
|
||||||
|
|
||||||
|
openLink(url) {
|
||||||
|
const api = Common.EditorApi.get();
|
||||||
|
if (api.asc_getUrlType(url) > 0) {
|
||||||
|
const newDocumentPage = window.open(url, '_blank');
|
||||||
|
if (newDocumentPage) {
|
||||||
|
newDocumentPage.focus();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
api.asc_GoToInternalHyperlink(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onDocumentReady() {
|
||||||
|
super.onDocumentReady();
|
||||||
|
|
||||||
|
const api = Common.EditorApi.get();
|
||||||
|
api.asc_registerCallback('asc_onShowComment', this.onApiShowComment);
|
||||||
|
api.asc_registerCallback('asc_onHideComment', this.onApiHideComment);
|
||||||
|
}
|
||||||
|
|
||||||
|
initMenuItems() {
|
||||||
|
if ( !Common.EditorApi ) return [];
|
||||||
|
|
||||||
|
const { t } = this.props;
|
||||||
|
const _t = t("ContextMenu", { returnObjects: true });
|
||||||
|
|
||||||
|
const { isEdit, canViewComments, canReview, isDisconnected } = this.props;
|
||||||
|
|
||||||
|
const api = Common.EditorApi.get();
|
||||||
|
const stack = api.getSelectedElements();
|
||||||
|
const canCopy = api.can_CopyCut();
|
||||||
|
|
||||||
|
let itemsIcon = [],
|
||||||
|
itemsText = [];
|
||||||
|
|
||||||
|
let isText = false,
|
||||||
|
isTable = false,
|
||||||
|
isImage = false,
|
||||||
|
isChart = false,
|
||||||
|
isShape = false,
|
||||||
|
isLink = false,
|
||||||
|
isSlide = false,
|
||||||
|
isObject = false;
|
||||||
|
|
||||||
|
stack.forEach(item => {
|
||||||
|
const objectType = item.get_ObjectType(),
|
||||||
|
objectValue = item.get_ObjectValue();
|
||||||
|
|
||||||
|
if (objectType == Asc.c_oAscTypeSelectElement.Paragraph) {
|
||||||
|
isText = true;
|
||||||
|
} else if (objectType == Asc.c_oAscTypeSelectElement.Image) {
|
||||||
|
isImage = true;
|
||||||
|
} else if (objectType == Asc.c_oAscTypeSelectElement.Chart) {
|
||||||
|
isChart = true;
|
||||||
|
} else if (objectType == Asc.c_oAscTypeSelectElement.Shape) {
|
||||||
|
isShape = true;
|
||||||
|
} else if (objectType == Asc.c_oAscTypeSelectElement.Table) {
|
||||||
|
isTable = true;
|
||||||
|
} else if (objectType == Asc.c_oAscTypeSelectElement.Hyperlink) {
|
||||||
|
isLink = true;
|
||||||
|
} else if (objectType == Asc.c_oAscTypeSelectElement.Slide) {
|
||||||
|
isSlide = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
isObject = isText || isImage || isChart || isShape || isTable;
|
||||||
|
|
||||||
|
if (canCopy && isObject) {
|
||||||
|
itemsIcon.push({
|
||||||
|
event: 'copy',
|
||||||
|
icon: 'icon-copy'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (canViewComments && this.isComments && !isEdit) {
|
||||||
|
itemsText.push({
|
||||||
|
caption: _t.menuViewComment,
|
||||||
|
event: 'viewcomment'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( stack.length > 0 ) {
|
||||||
|
let topObject = stack[stack.length - 1],
|
||||||
|
topObjectType = topObject.get_ObjectType(),
|
||||||
|
topObjectValue = topObject.get_ObjectValue(),
|
||||||
|
objectLocked = typeof topObjectValue.get_Locked === 'function' ? topObjectValue.get_Locked() : false;
|
||||||
|
|
||||||
|
!objectLocked && (objectLocked = typeof topObjectValue.get_LockDelete === 'function' ? topObjectValue.get_LockDelete() : false);
|
||||||
|
|
||||||
|
const swapItems = function(items, indexBefore, indexAfter) {
|
||||||
|
items[indexAfter] = items.splice(indexBefore, 1, items[indexAfter])[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!objectLocked && isEdit && !isDisconnected) {
|
||||||
|
if (canCopy && isObject) {
|
||||||
|
itemsIcon.push({
|
||||||
|
event: 'cut',
|
||||||
|
icon: 'icon-cut'
|
||||||
|
});
|
||||||
|
|
||||||
|
// Swap 'Copy' and 'Cut'
|
||||||
|
swapItems(itemsIcon, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
itemsIcon.push({
|
||||||
|
event: 'paste',
|
||||||
|
icon: 'icon-paste'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isObject)
|
||||||
|
itemsText.push({
|
||||||
|
caption: _t.menuDelete,
|
||||||
|
event: 'delete'
|
||||||
|
});
|
||||||
|
|
||||||
|
itemsText.push({
|
||||||
|
caption: _t.menuEdit,
|
||||||
|
event: 'edit'
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!isLink && api.can_AddHyperlink() !== false) {
|
||||||
|
itemsText.push({
|
||||||
|
caption: _t.menuAddLink,
|
||||||
|
event: 'addlink'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isComments && canViewComments) {
|
||||||
|
itemsText.push({
|
||||||
|
caption: _t.menuViewComment,
|
||||||
|
event: 'viewcomment'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var hideAddComment = (isText && isChart) || api.can_AddQuotedComment() === false || !canViewComments;
|
||||||
|
if (!hideAddComment) {
|
||||||
|
itemsText.push({
|
||||||
|
caption: _t.menuAddComment,
|
||||||
|
event: 'addcomment'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isLink) {
|
||||||
|
itemsText.push({
|
||||||
|
caption: _t.menuOpenLink,
|
||||||
|
event: 'openlink'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ( Device.phone && itemsText.length > 2 ) {
|
||||||
|
this.extraItems = itemsText.splice(2,itemsText.length, {
|
||||||
|
caption: _t.menuMore,
|
||||||
|
event: 'showActionSheet'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return itemsIcon.concat(itemsText);
|
||||||
|
// return [{
|
||||||
|
// caption: 'Edit',
|
||||||
|
// event: 'edit'
|
||||||
|
// }, {
|
||||||
|
// caption: 'View',
|
||||||
|
// event: 'view'
|
||||||
|
// }, {
|
||||||
|
// icon: 'icon-paste',
|
||||||
|
// event: 'review'
|
||||||
|
// }];
|
||||||
|
}
|
||||||
|
|
||||||
|
initExtraItems () {
|
||||||
|
return (this.extraItems && this.extraItems.length > 0 ? this.extraItems : []);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const _ContextMenu = withTranslation()(ContextMenu);
|
||||||
|
_ContextMenu.closeContextMenu = ContextMenu.closeContextMenu;
|
||||||
|
export { _ContextMenu as default };
|
|
@ -1,9 +1,15 @@
|
||||||
|
|
||||||
import React, { Component } from 'react'
|
import React, { Component, Fragment } from 'react'
|
||||||
import { inject } from "mobx-react";
|
import { inject } from "mobx-react";
|
||||||
import { f7 } from "framework7-react";
|
import { f7 } from "framework7-react";
|
||||||
import { withTranslation } from 'react-i18next';
|
import { withTranslation } from 'react-i18next';
|
||||||
import CollaborationController from '../../../../common/mobile/lib/controller/collaboration/Collaboration.jsx'
|
import CollaborationController from '../../../../common/mobile/lib/controller/collaboration/Collaboration.jsx';
|
||||||
|
import {
|
||||||
|
CommentsController,
|
||||||
|
AddCommentController,
|
||||||
|
EditCommentController,
|
||||||
|
ViewCommentsController
|
||||||
|
} from "../../../../common/mobile/lib/controller/collaboration/Comments";
|
||||||
|
|
||||||
@inject("storeFocusObjects", "storeAppOptions", "storePresentationInfo", "storePresentationSettings", "storeSlideSettings", "storeTextSettings", "storeTableSettings", "storeChartSettings", "storeLinkSettings")
|
@inject("storeFocusObjects", "storeAppOptions", "storePresentationInfo", "storePresentationSettings", "storeSlideSettings", "storeTextSettings", "storeTableSettings", "storeChartSettings", "storeLinkSettings")
|
||||||
class MainController extends Component {
|
class MainController extends Component {
|
||||||
|
@ -334,6 +340,8 @@ class MainController extends Component {
|
||||||
|
|
||||||
Common.Gateway.documentReady();
|
Common.Gateway.documentReady();
|
||||||
f7.emit('resize');
|
f7.emit('resize');
|
||||||
|
|
||||||
|
Common.Notifications.trigger('document:ready');
|
||||||
}
|
}
|
||||||
|
|
||||||
_onOpenDocumentProgress(progress) {
|
_onOpenDocumentProgress(progress) {
|
||||||
|
@ -346,7 +354,15 @@ class MainController extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <CollaborationController />
|
return (
|
||||||
|
<Fragment>
|
||||||
|
<CollaborationController />
|
||||||
|
<CommentsController />
|
||||||
|
<AddCommentController />
|
||||||
|
<EditCommentController />
|
||||||
|
<ViewCommentsController />
|
||||||
|
</Fragment>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
|
|
@ -102,6 +102,7 @@ class AddLinkController extends Component {
|
||||||
return (
|
return (
|
||||||
<PageLink onInsertLink={this.onInsertLink}
|
<PageLink onInsertLink={this.onInsertLink}
|
||||||
getTextDisplay={this.getTextDisplay}
|
getTextDisplay={this.getTextDisplay}
|
||||||
|
noNavbar={this.props.noNavbar}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,10 +88,38 @@ class AddOtherController extends Component {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hideAddComment () {
|
||||||
|
const api = Common.EditorApi.get();
|
||||||
|
const stack = api.getSelectedElements();
|
||||||
|
let isText = false,
|
||||||
|
isChart = false;
|
||||||
|
|
||||||
|
stack.forEach((item) => {
|
||||||
|
const objectType = item.get_ObjectType();
|
||||||
|
if (objectType === Asc.c_oAscTypeSelectElement.Paragraph) {
|
||||||
|
isText = true;
|
||||||
|
} else if (objectType === Asc.c_oAscTypeSelectElement.Chart) {
|
||||||
|
isChart = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (stack.length > 0) {
|
||||||
|
const topObject = stack[stack.length - 1];
|
||||||
|
const topObjectValue = topObject.get_ObjectValue();
|
||||||
|
let objectLocked = typeof topObjectValue.get_Locked === 'function' ? topObjectValue.get_Locked() : false;
|
||||||
|
!objectLocked && (objectLocked = typeof topObjectValue.get_LockDelete === 'function' ? topObjectValue.get_LockDelete() : false);
|
||||||
|
if (!objectLocked) {
|
||||||
|
return ((isText && isChart) || api.can_AddQuotedComment() === false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<AddOther onStyleClick={this.onStyleClick}
|
<AddOther closeModal={this.closeModal}
|
||||||
|
onStyleClick={this.onStyleClick}
|
||||||
initStyleTable={this.initStyleTable}
|
initStyleTable={this.initStyleTable}
|
||||||
|
hideAddComment={this.hideAddComment}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
@import '../../../../common/mobile/resources/less/dataview.less';
|
@import '../../../../common/mobile/resources/less/dataview.less';
|
||||||
@import '../../../../common/mobile/resources/less/about.less';
|
@import '../../../../common/mobile/resources/less/about.less';
|
||||||
@import '../../../../common/mobile/resources/less/search.less';
|
@import '../../../../common/mobile/resources/less/search.less';
|
||||||
|
@import '../../../../common/mobile/resources/less/contextmenu.less';
|
||||||
|
@import '../../../../common/mobile/resources/less/comments.less';
|
||||||
@import './app-material.less';
|
@import './app-material.less';
|
||||||
@import './app-ios.less';
|
@import './app-ios.less';
|
||||||
@import './icons-ios.less';
|
@import './icons-ios.less';
|
||||||
|
|
|
@ -7,6 +7,7 @@ import Settings from '../view/settings/Settings';
|
||||||
import CollaborationView from '../../../../common/mobile/lib/view/collaboration/Collaboration.jsx';
|
import CollaborationView from '../../../../common/mobile/lib/view/collaboration/Collaboration.jsx';
|
||||||
import { Device } from '../../../../common/mobile/utils/device';
|
import { Device } from '../../../../common/mobile/utils/device';
|
||||||
import { Search, SearchSettings } from '../controller/Search';
|
import { Search, SearchSettings } from '../controller/Search';
|
||||||
|
import ContextMenu from '../controller/ContextMenu';
|
||||||
|
|
||||||
export default class MainPage extends Component {
|
export default class MainPage extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -19,12 +20,17 @@ export default class MainPage extends Component {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
handleClickToOpenOptions = opts => {
|
handleClickToOpenOptions = (opts, showOpts) => {
|
||||||
|
ContextMenu.closeContextMenu();
|
||||||
|
|
||||||
this.setState(state => {
|
this.setState(state => {
|
||||||
if ( opts == 'edit' )
|
if ( opts == 'edit' )
|
||||||
return {editOptionsVisible: true};
|
return {editOptionsVisible: true};
|
||||||
else if ( opts == 'add' )
|
else if ( opts == 'add' )
|
||||||
return {addOptionsVisible: true};
|
return {
|
||||||
|
addOptionsVisible: true,
|
||||||
|
addShowOptions: showOpts
|
||||||
|
};
|
||||||
else if ( opts == 'settings' )
|
else if ( opts == 'settings' )
|
||||||
return {settingsVisible: true};
|
return {settingsVisible: true};
|
||||||
else if ( opts == 'coauth' )
|
else if ( opts == 'coauth' )
|
||||||
|
@ -77,7 +83,7 @@ export default class MainPage extends Component {
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
!this.state.addOptionsVisible ? null :
|
!this.state.addOptionsVisible ? null :
|
||||||
<AddOptions onclosed={this.handleOptionsViewClosed.bind(this, 'add')} />
|
<AddOptions onclosed={this.handleOptionsViewClosed.bind(this, 'add')} showOptions={this.state.addShowOptions} />
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
!this.state.settingsVisible ? null :
|
!this.state.settingsVisible ? null :
|
||||||
|
@ -87,6 +93,7 @@ export default class MainPage extends Component {
|
||||||
!this.state.collaborationVisible ? null :
|
!this.state.collaborationVisible ? null :
|
||||||
<CollaborationView onclosed={this.handleOptionsViewClosed.bind(this, 'coauth')} />
|
<CollaborationView onclosed={this.handleOptionsViewClosed.bind(this, 'coauth')} />
|
||||||
}
|
}
|
||||||
|
<ContextMenu openOptions={this.handleClickToOpenOptions.bind(this)} />
|
||||||
</Page>
|
</Page>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import { storeLinkSettings } from "./linkSettings";
|
||||||
// import {storeParagraphSettings} from "./paragraphSettings";
|
// import {storeParagraphSettings} from "./paragraphSettings";
|
||||||
// import {storeShapeSettings} from "./shapeSettings";
|
// import {storeShapeSettings} from "./shapeSettings";
|
||||||
// import {storeImageSettings} from "./imageSettings";
|
// import {storeImageSettings} from "./imageSettings";
|
||||||
|
import {storeComments} from "../../../../common/mobile/lib/store/comments";
|
||||||
|
|
||||||
export const stores = {
|
export const stores = {
|
||||||
storeAppOptions: new storeAppOptions(),
|
storeAppOptions: new storeAppOptions(),
|
||||||
|
@ -31,10 +32,11 @@ export const stores = {
|
||||||
storeShapeSettings: new storeShapeSettings(),
|
storeShapeSettings: new storeShapeSettings(),
|
||||||
storeTableSettings: new storeTableSettings(),
|
storeTableSettings: new storeTableSettings(),
|
||||||
storeChartSettings: new storeChartSettings(),
|
storeChartSettings: new storeChartSettings(),
|
||||||
storeLinkSettings: new storeLinkSettings()
|
storeLinkSettings: new storeLinkSettings(),
|
||||||
// storeTextSettings: new storeTextSettings(),
|
// storeTextSettings: new storeTextSettings(),
|
||||||
// storeParagraphSettings: new storeParagraphSettings(),
|
// storeParagraphSettings: new storeParagraphSettings(),
|
||||||
// storeShapeSettings: new storeShapeSettings(),
|
// storeShapeSettings: new storeShapeSettings(),
|
||||||
// storeChartSettings: new storeChartSettings(),
|
// storeChartSettings: new storeChartSettings(),
|
||||||
|
storeComments: new storeComments()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import React, {Component, useEffect} from 'react';
|
import React, {Component, useEffect} from 'react';
|
||||||
import {View,Page,Navbar,NavRight,Link,Popup,Popover,Icon,Tabs,Tab} from 'framework7-react';
|
import {View,Page,Navbar,NavRight, NavTitle, Link,Popup,Popover,Icon,Tabs,Tab} from 'framework7-react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import {f7} from 'framework7-react';
|
import {f7} from 'framework7-react';
|
||||||
import { observer, inject } from "mobx-react";
|
import { observer, inject } from "mobx-react";
|
||||||
|
@ -43,13 +43,16 @@ const AddLayoutNavbar = ({ tabs, inPopover }) => {
|
||||||
const isAndroid = Device.android;
|
const isAndroid = Device.android;
|
||||||
return (
|
return (
|
||||||
<Navbar>
|
<Navbar>
|
||||||
<div className='tab-buttons tabbar'>
|
{tabs.length > 1 ?
|
||||||
{tabs.map((item, index) =>
|
<div className='tab-buttons tabbar'>
|
||||||
<Link key={"pe-link-" + item.id} tabLink={"#" + item.id} tabLinkActive={index === 0}>
|
{tabs.map((item, index) =>
|
||||||
<Icon slot="media" icon={item.icon}></Icon>
|
<Link key={"pe-link-" + item.id} tabLink={"#" + item.id} tabLinkActive={index === 0}>
|
||||||
</Link>)}
|
<Icon slot="media" icon={item.icon}></Icon>
|
||||||
{isAndroid && <span className='tab-link-highlight' style={{width: 100 / tabs.lenght + '%'}}></span>}
|
</Link>)}
|
||||||
</div>
|
{isAndroid && <span className='tab-link-highlight' style={{width: 100 / tabs.lenght + '%'}}></span>}
|
||||||
|
</div> :
|
||||||
|
<NavTitle>{tabs[0].caption}</NavTitle>
|
||||||
|
}
|
||||||
{ !inPopover && <NavRight><Link icon='icon-expand-down' popupClose=".add-popup"></Link></NavRight> }
|
{ !inPopover && <NavRight><Link icon='icon-expand-down' popupClose=".add-popup"></Link></NavRight> }
|
||||||
</Navbar>
|
</Navbar>
|
||||||
)
|
)
|
||||||
|
@ -69,32 +72,42 @@ const AddLayoutContent = ({ tabs }) => {
|
||||||
|
|
||||||
const AddTabs = props => {
|
const AddTabs = props => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const _t = t('Add', {returnObjects: true});
|
const _t = t('View.Add', {returnObjects: true});
|
||||||
|
const showPanels = props.showPanels;
|
||||||
const tabs = [];
|
const tabs = [];
|
||||||
tabs.push({
|
if (!showPanels) {
|
||||||
caption: _t.textSlide,
|
tabs.push({
|
||||||
id: 'add-slide',
|
caption: _t.textSlide,
|
||||||
icon: 'icon-add-slide',
|
id: 'add-slide',
|
||||||
component: <AddSlideController />
|
icon: 'icon-add-slide',
|
||||||
});
|
component: <AddSlideController />
|
||||||
tabs.push({
|
});
|
||||||
caption: _t.textShape,
|
tabs.push({
|
||||||
id: 'add-shape',
|
caption: _t.textShape,
|
||||||
icon: 'icon-add-shape',
|
id: 'add-shape',
|
||||||
component: <AddShapeController />
|
icon: 'icon-add-shape',
|
||||||
});
|
component: <AddShapeController/>
|
||||||
tabs.push({
|
});
|
||||||
caption: _t.textImage,
|
tabs.push({
|
||||||
id: 'add-image',
|
caption: _t.textImage,
|
||||||
icon: 'icon-add-image',
|
id: 'add-image',
|
||||||
component: <AddImageController />
|
icon: 'icon-add-image',
|
||||||
});
|
component: <AddImageController/>
|
||||||
tabs.push({
|
});
|
||||||
caption: _t.textOther,
|
tabs.push({
|
||||||
id: 'add-other',
|
caption: _t.textOther,
|
||||||
icon: 'icon-add-other',
|
id: 'add-other',
|
||||||
component: <AddOtherController />
|
icon: 'icon-add-other',
|
||||||
});
|
component: <AddOtherController/>
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (showPanels && showPanels === 'link') {
|
||||||
|
tabs.push({
|
||||||
|
caption: _t.textAddLink,
|
||||||
|
id: 'add-link',
|
||||||
|
component: <AddLinkController noNavbar={true}/>
|
||||||
|
});
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<View style={props.style} stackPages={true} routes={routes}>
|
<View style={props.style} stackPages={true} routes={routes}>
|
||||||
<Page pageContent={false}>
|
<Page pageContent={false}>
|
||||||
|
@ -119,10 +132,10 @@ class AddView extends Component {
|
||||||
return (
|
return (
|
||||||
show_popover ?
|
show_popover ?
|
||||||
<Popover id="add-popover" className="popover__titled" onPopoverClosed={() => this.props.onclosed()}>
|
<Popover id="add-popover" className="popover__titled" onPopoverClosed={() => this.props.onclosed()}>
|
||||||
<AddTabs inPopover={true} onOptionClick={this.onoptionclick} style={{height: '410px'}} />
|
<AddTabs inPopover={true} onOptionClick={this.onoptionclick} style={{height: '410px'}} showPanels={this.props.showPanels} />
|
||||||
</Popover> :
|
</Popover> :
|
||||||
<Popup className="add-popup" onPopupClosed={() => this.props.onclosed()}>
|
<Popup className="add-popup" onPopupClosed={() => this.props.onclosed()}>
|
||||||
<AddTabs onOptionClick={this.onoptionclick} />
|
<AddTabs onOptionClick={this.onoptionclick} showPanels={this.props.showPanels} />
|
||||||
</Popup>
|
</Popup>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -142,7 +155,7 @@ const Add = props => {
|
||||||
if ( props.onclosed )
|
if ( props.onclosed )
|
||||||
props.onclosed();
|
props.onclosed();
|
||||||
};
|
};
|
||||||
return <AddView usePopover={!Device.phone} onclosed={onviewclosed} />
|
return <AddView usePopover={!Device.phone} onclosed={onviewclosed} showPanels={props.showOptions} />
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Add;
|
export default Add;
|
|
@ -103,7 +103,7 @@ const PageLink = props => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page>
|
<Page>
|
||||||
<Navbar title={_t.textLink} backLink={_t.textBack}/>
|
{!props.noNavbar && <Navbar title={_t.textLink} backLink={_t.textBack}/>}
|
||||||
<List inlineLabels className='inputs-list'>
|
<List inlineLabels className='inputs-list'>
|
||||||
<ListItem link={'/add-link-type/'} title={_t.textLinkType} after={textType} routeProps={{
|
<ListItem link={'/add-link-type/'} title={_t.textLinkType} after={textType} routeProps={{
|
||||||
changeType: changeType,
|
changeType: changeType,
|
||||||
|
|
|
@ -33,6 +33,7 @@ const AddOther = props => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const _t = t('View.Add', {returnObjects: true});
|
const _t = t('View.Add', {returnObjects: true});
|
||||||
const showInsertLink = props.storeLinkSettings.canAddLink && !props.storeFocusObjects.paragraphLocked;
|
const showInsertLink = props.storeLinkSettings.canAddLink && !props.storeFocusObjects.paragraphLocked;
|
||||||
|
const hideAddComment = props.hideAddComment();
|
||||||
return (
|
return (
|
||||||
<List>
|
<List>
|
||||||
<ListItem title={_t.textTable} link={'/add-table/'} routeProps={{
|
<ListItem title={_t.textTable} link={'/add-table/'} routeProps={{
|
||||||
|
@ -41,9 +42,12 @@ const AddOther = props => {
|
||||||
}}>
|
}}>
|
||||||
<Icon slot="media" icon="icon-add-table"></Icon>
|
<Icon slot="media" icon="icon-add-table"></Icon>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
<ListItem title={_t.textComment}>
|
{!hideAddComment && <ListItem title={_t.textComment} onClick={() => {
|
||||||
|
props.closeModal();
|
||||||
|
Common.Notifications.trigger('addcomment');
|
||||||
|
}}>
|
||||||
<Icon slot="media" icon="icon-insert-comment"></Icon>
|
<Icon slot="media" icon="icon-insert-comment"></Icon>
|
||||||
</ListItem>
|
</ListItem>}
|
||||||
{showInsertLink &&
|
{showInsertLink &&
|
||||||
<ListItem title={_t.textLink} link={'/add-link/'}>
|
<ListItem title={_t.textLink} link={'/add-link/'}>
|
||||||
<Icon slot="media" icon="icon-link"></Icon>
|
<Icon slot="media" icon="icon-link"></Icon>
|
||||||
|
|
|
@ -4,6 +4,8 @@ import ReactDOM from 'react-dom';
|
||||||
|
|
||||||
// Import Framework7
|
// Import Framework7
|
||||||
import Framework7 from 'framework7/lite-bundle';
|
import Framework7 from 'framework7/lite-bundle';
|
||||||
|
import { Dom7 } from 'framework7';
|
||||||
|
window.$$ = Dom7;
|
||||||
|
|
||||||
// Import Framework7-React Plugin
|
// Import Framework7-React Plugin
|
||||||
import Framework7React from 'framework7-react';
|
import Framework7React from 'framework7-react';
|
||||||
|
|
|
@ -18,17 +18,26 @@ const Statusbar = inject('sheets', 'storeAppOptions')(props => {
|
||||||
let isDisconnected = false;
|
let isDisconnected = false;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log("status bar did mount");
|
const on_api_created = api => {
|
||||||
|
api.asc_registerCallback('asc_onSheetsChanged', onApiSheetsChanged.bind(api));
|
||||||
|
};
|
||||||
|
|
||||||
|
const on_main_view_click = e => {
|
||||||
|
// f7.popover.close('.document-menu.modal-in');
|
||||||
|
};
|
||||||
|
|
||||||
Common.Notifications.on('api:disconnect', onApiDisconnect);
|
Common.Notifications.on('api:disconnect', onApiDisconnect);
|
||||||
Common.Notifications.on('document:ready', onApiSheetsChanged);
|
Common.Notifications.on('document:ready', onApiSheetsChanged);
|
||||||
Common.Notifications.on('engineCreated', api => {
|
Common.Notifications.on('engineCreated', on_api_created);
|
||||||
api.asc_registerCallback('asc_onUpdateTabColor', onApiUpdateTabColor);
|
|
||||||
// api.asc_registerCallback('asc_onWorkbookLocked', onWorkbookLocked);
|
$$('.view-main').on('click', on_main_view_click);
|
||||||
// api.asc_registerCallback('asc_onWorksheetLocked', onWorksheetLocked);
|
|
||||||
api.asc_registerCallback('asc_onSheetsChanged', onApiSheetsChanged);
|
return () => {
|
||||||
api.asc_registerCallback('asc_onCoAuthoringDisconnect', onApiDisconnect);
|
Common.Notifications.off('document:ready', onApiSheetsChanged);
|
||||||
});
|
Common.Notifications.off('engineCreated', on_api_created);
|
||||||
|
|
||||||
|
$$('.view-main').off('click', on_main_view_click);
|
||||||
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// const onWorkbookLocked = locked => {
|
// const onWorkbookLocked = locked => {
|
||||||
|
|
|
@ -4,7 +4,7 @@ const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
||||||
|
|
||||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||||
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin');
|
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
|
||||||
const TerserPlugin = require('terser-webpack-plugin');
|
const TerserPlugin = require('terser-webpack-plugin');
|
||||||
const WorkboxPlugin = require('workbox-webpack-plugin');
|
const WorkboxPlugin = require('workbox-webpack-plugin');
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@ module.exports = {
|
||||||
minimizer: [new TerserPlugin({
|
minimizer: [new TerserPlugin({
|
||||||
sourceMap: true,
|
sourceMap: true,
|
||||||
})],
|
})],
|
||||||
|
moduleIds: 'named',
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
|
@ -162,8 +163,8 @@ module.exports = {
|
||||||
}),
|
}),
|
||||||
|
|
||||||
...(env === 'production' ? [
|
...(env === 'production' ? [
|
||||||
new OptimizeCSSPlugin({
|
new CssMinimizerPlugin({
|
||||||
cssProcessorOptions: {
|
processorOptions: {
|
||||||
safe: true,
|
safe: true,
|
||||||
map: { inline: false },
|
map: { inline: false },
|
||||||
},
|
},
|
||||||
|
@ -172,7 +173,7 @@ module.exports = {
|
||||||
] : [
|
] : [
|
||||||
// Development only plugins
|
// Development only plugins
|
||||||
new webpack.HotModuleReplacementPlugin(),
|
new webpack.HotModuleReplacementPlugin(),
|
||||||
new webpack.NamedModulesPlugin(),
|
// new webpack.NamedModulesPlugin(),
|
||||||
]),
|
]),
|
||||||
// new CleanWebpackPlugin(),
|
// new CleanWebpackPlugin(),
|
||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
|
|
25
vendor/framework7-react/package.json
vendored
25
vendor/framework7-react/package.json
vendored
|
@ -25,14 +25,14 @@
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dom7": "^3.0.0",
|
"dom7": "^3.0.0",
|
||||||
"framework7": "^6.0.4",
|
"framework7": "^6.0.14",
|
||||||
"framework7-icons": "^3.0.1",
|
"framework7-icons": "^3.0.1",
|
||||||
"framework7-react": "^6.0.4",
|
"framework7-react": "^6.0.14",
|
||||||
"i18next": "^19.8.4",
|
"i18next": "^19.8.4",
|
||||||
"i18next-fetch-backend": "^3.0.0",
|
"i18next-fetch-backend": "^3.0.0",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"react": "^17.0.1",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.1",
|
"react-dom": "^17.0.2",
|
||||||
"react-i18next": "^11.8.5",
|
"react-i18next": "^11.8.5",
|
||||||
"swiper": "^6.4.8",
|
"swiper": "^6.4.8",
|
||||||
"template7": "^1.4.2"
|
"template7": "^1.4.2"
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
"@babel/plugin-proposal-decorators": "^7.12.12",
|
"@babel/plugin-proposal-decorators": "^7.12.12",
|
||||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
||||||
"@babel/plugin-transform-runtime": "^7.12.10",
|
"@babel/plugin-transform-runtime": "^7.12.10",
|
||||||
"@babel/preset-env": "^7.12.11",
|
"@babel/preset-env": "^7.13.12",
|
||||||
"@babel/preset-react": "^7.12.10",
|
"@babel/preset-react": "^7.12.10",
|
||||||
"@babel/runtime": "^7.12.5",
|
"@babel/runtime": "^7.12.5",
|
||||||
"babel-loader": "^8.2.2",
|
"babel-loader": "^8.2.2",
|
||||||
|
@ -53,27 +53,24 @@
|
||||||
"cpy-cli": "^3.1.1",
|
"cpy-cli": "^3.1.1",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"css-loader": "^4.3.0",
|
"css-loader": "^4.3.0",
|
||||||
|
"css-minimizer-webpack-plugin": "^1.3.0",
|
||||||
"file-loader": "^6.2.0",
|
"file-loader": "^6.2.0",
|
||||||
"html-webpack-plugin": "^4.5.1",
|
"html-webpack-plugin": "^5.3.1",
|
||||||
"less": "^3.13.1",
|
"less": "^3.13.1",
|
||||||
"less-loader": "^6.2.0",
|
"less-loader": "^6.2.0",
|
||||||
"mini-css-extract-plugin": "^0.9.0",
|
"mini-css-extract-plugin": "^1.3.9",
|
||||||
"mobx": "^6.1.8",
|
"mobx": "^6.1.8",
|
||||||
"mobx-react": "^7.1.0",
|
"mobx-react": "^7.1.0",
|
||||||
"optimize-css-assets-webpack-plugin": "^5.0.4",
|
|
||||||
"ora": "^4.1.1",
|
"ora": "^4.1.1",
|
||||||
"postcss-loader": "^3.0.0",
|
"postcss-loader": "^3.0.0",
|
||||||
"postcss-preset-env": "^6.7.0",
|
"postcss-preset-env": "^6.7.0",
|
||||||
"react-redux": "^7.2.2",
|
|
||||||
"redux": "^4.0.5",
|
|
||||||
"redux-thunk": "^2.3.0",
|
|
||||||
"rimraf": "^3.0.2",
|
"rimraf": "^3.0.2",
|
||||||
"style-loader": "^1.3.0",
|
"style-loader": "^1.3.0",
|
||||||
"terser-webpack-plugin": "^3.1.0",
|
"terser-webpack-plugin": "^3.1.0",
|
||||||
"url-loader": "^4.1.1",
|
"url-loader": "^4.1.1",
|
||||||
"webpack": "^4.46.0",
|
"webpack": "^5.26.3",
|
||||||
"webpack-cli": "^3.3.12",
|
"webpack-cli": "^4.5.0",
|
||||||
"webpack-dev-server": "^3.11.2",
|
"webpack-dev-server": "^3.11.2",
|
||||||
"workbox-webpack-plugin": "^5.1.4"
|
"workbox-webpack-plugin": "^6.1.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue