[mobile] Add actions for more items in context menu

This commit is contained in:
JuliaSvinareva 2021-03-16 00:59:14 +03:00
parent 299db5fcb6
commit 3921dfa9ee
5 changed files with 139 additions and 97 deletions

View file

@ -1,8 +1,8 @@
import React, { Component } 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 { Device } from '../../../../common/mobile/utils/device'
import ContextMenuView, { idContextMenuElement } from '../view/ContextMenu'; import ContextMenuView, { idContextMenuElement, ActionsWithExtraItems } from '../view/ContextMenu';
const idCntextMenuTargetElement = '#idx-context-menu-target'; const idCntextMenuTargetElement = '#idx-context-menu-target';
@ -11,12 +11,15 @@ class ContextMenuController extends Component {
super(props); super(props);
this.state = { this.state = {
opened: false opened: false,
, items: [] items: [],
openedMore: false,
extraItems: []
}; };
this.onMenuItemClick = this.onMenuItemClick.bind(this); this.onMenuItemClick = this.onMenuItemClick.bind(this);
this.onMenuClosed = this.onMenuClosed.bind(this); this.onMenuClosed = this.onMenuClosed.bind(this);
this.onActionClosed = this.onActionClosed.bind(this);
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);
@ -96,7 +99,10 @@ class ContextMenuController extends Component {
onApiOpenContextMenu(x, y) { onApiOpenContextMenu(x, y) {
if ( !this.state.opened ) { if ( !this.state.opened ) {
this.setState({items: this.initMenuItems()}); this.setState({
items: this.initMenuItems(),
extraItems: this.initExtraItems()
});
this.$targetEl.css({left: `${x}px`, top: `${y}px`}); this.$targetEl.css({left: `${x}px`, top: `${y}px`});
const popover = f7.popover.open(idContextMenuElement, idCntextMenuTargetElement); const popover = f7.popover.open(idContextMenuElement, idCntextMenuTargetElement);
@ -132,8 +138,16 @@ class ContextMenuController extends Component {
// })(); // })();
} }
onActionClosed() {
this.setState({openedMore: false});
}
onMenuItemClick(action) { onMenuItemClick(action) {
this.onApiHideContextMenu(); this.onApiHideContextMenu();
if (action === 'showActionSheet') {
this.setState({openedMore: true});
}
} }
componentWillUnmount() { componentWillUnmount() {
@ -158,9 +172,16 @@ class ContextMenuController extends Component {
return []; return [];
} }
initExtraItems () {
return [];
}
render() { render() {
return ( return (
<ContextMenuView items={this.state.items} onMenuClosed={this.onMenuClosed} onMenuItemClick={this.onMenuItemClick} /> <Fragment>
<ContextMenuView items={this.state.items} onMenuClosed={this.onMenuClosed} onMenuItemClick={this.onMenuItemClick} />
<ActionsWithExtraItems items={this.state.extraItems} onMenuItemClick={this.onMenuItemClick} opened={this.state.openedMore} onActionClosed={this.onActionClosed}/>
</Fragment>
) )
} }
} }

View file

@ -1,6 +1,7 @@
import React, { Component } from 'react'; import React, { Component } from 'react';
import { Popover, List, ListItem, ListButton, Link, Icon } from 'framework7-react'; import { Popover, List, ListItem, ListButton, Link, Icon, Actions, ActionsGroup, ActionsButton } from 'framework7-react';
import { f7 } from 'framework7-react'; import { f7 } from 'framework7-react';
import { useTranslation } from 'react-i18next';
const idContextMenuElement = "idx-context-menu-popover"; const idContextMenuElement = "idx-context-menu-popover";
@ -38,5 +39,24 @@ class ContextMenuView extends Component {
} }
} }
const ActionsWithExtraItems = ({items, onMenuItemClick, opened, onActionClosed}) => {
const { t } = useTranslation();
const _t = t('ContextMenu', {returnObjects: true});
return (
<Actions opened={opened} onActionsClosed={() => onActionClosed()}>
<ActionsGroup>
{items.length > 0 && items.map((item, index)=>{
return(
<ActionsButton key={`act-${item.caption}`} onClick={() => {onMenuItemClick(item.event)}}>{item.caption}</ActionsButton>
)
})}
</ActionsGroup>
<ActionsGroup>
<ActionsButton>{_t.menuCancel}</ActionsButton>
</ActionsGroup>
</Actions>
)
};
const exportedIdMenuElemen = `#${idContextMenuElement}`; const exportedIdMenuElemen = `#${idContextMenuElement}`;
export {ContextMenuView as default, exportedIdMenuElemen as idContextMenuElement}; export {ContextMenuView as default, exportedIdMenuElemen as idContextMenuElement, ActionsWithExtraItems};

View file

@ -4,4 +4,8 @@
.document-menu { .document-menu {
width: auto; width: auto;
}
html.phone .document-menu .list-block .list-button {
padding: 0 10px;
} }

View file

@ -129,6 +129,21 @@
"textEditReply": "Edit Reply" "textEditReply": "Edit Reply"
} }
}, },
"ContextMenu": {
"menuViewComment": "View Comment",
"menuAddComment": "Add Comment",
"menuMerge": "Merge",
"menuSplit": "Split",
"menuDelete": "Delete",
"menuDeleteTable": "Delete Table",
"menuEdit": "Edit",
"menuAddLink": "Add Link",
"menuReviewChange": "Review Change",
"menuReview": "Review",
"menuOpenLink": "Open Link",
"menuMore": "More",
"menuCancel": "Cancel"
},
"Settings": { "Settings": {
"textCancel": "Cancel", "textCancel": "Cancel",
"textSettings": "Settings", "textSettings": "Settings",

View file

@ -4,6 +4,7 @@ import { inject, observer } from "mobx-react";
import ContextMenuController from '../../../../common/mobile/lib/controller/ContextMenu'; import ContextMenuController from '../../../../common/mobile/lib/controller/ContextMenu';
import { idContextMenuElement } from '../../../../common/mobile/lib/view/ContextMenu'; import { idContextMenuElement } from '../../../../common/mobile/lib/view/ContextMenu';
import { Device } from '../../../../common/mobile/utils/device'; import { Device } from '../../../../common/mobile/utils/device';
import { withTranslation} from 'react-i18next';
@inject ( stores => ({ @inject ( stores => ({
isEdit: stores.storeAppOptions.isEdit, isEdit: stores.storeAppOptions.isEdit,
@ -70,6 +71,9 @@ class ContextMenu extends ContextMenuController {
initMenuItems() { initMenuItems() {
if ( !Common.EditorApi ) return []; if ( !Common.EditorApi ) return [];
const { t } = this.props;
const _t = t("ContextMenu", { returnObjects: true });
const { isEdit, canViewComments, canReview } = this.props; const { isEdit, canViewComments, canReview } = this.props;
const api = Common.EditorApi.get(); const api = Common.EditorApi.get();
@ -81,7 +85,6 @@ class ContextMenu extends ContextMenuController {
if ( canCopy ) { if ( canCopy ) {
itemsIcon.push({ itemsIcon.push({
caption: /*me.menuCopy*/ 'Copy',
event: 'copy', event: 'copy',
icon: 'icon-copy' icon: 'icon-copy'
}); });
@ -89,7 +92,7 @@ class ContextMenu extends ContextMenuController {
if ( canViewComments && this.isComments && !isEdit ) { if ( canViewComments && this.isComments && !isEdit ) {
itemsText.push({ itemsText.push({
caption: /*me.menuViewComment*/'View Comment', caption: _t.menuViewComment,
event: 'viewcomment' event: 'viewcomment'
}); });
} }
@ -144,7 +147,6 @@ class ContextMenu extends ContextMenuController {
if ( isEdit && !this.isDisconnected ) { if ( isEdit && !this.isDisconnected ) {
if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader && canCopy ) { if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader && canCopy ) {
itemsIcon.push({ itemsIcon.push({
// caption: me.menuCut,
event: 'cut', event: 'cut',
icon: 'icon-cut' icon: 'icon-cut'
}); });
@ -155,16 +157,70 @@ class ContextMenu extends ContextMenuController {
if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader ) { if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader ) {
itemsIcon.push({ itemsIcon.push({
// caption: me.menuPaste,
event: 'paste', event: 'paste',
icon: 'icon-paste' icon: 'icon-paste'
}); });
} }
// For test if ( isTable && api.CheckBeforeMergeCells() && !lockedTable && !lockedHeader) {
itemsText.push({
caption: _t.menuMerge,
event: 'merge'
});
}
if ( isTable && api.CheckBeforeSplitCells() && !lockedTable && !lockedHeader ) {
itemsText.push({
caption: _t.menuSplit,
event: 'split'
});
}
if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader ) {
itemsText.push({
caption: _t.menuDelete,
event: 'delete'
});
}
if ( isTable && !lockedTable && !lockedText && !lockedHeader ) {
itemsText.push({
caption: _t.menuDeleteTable,
event: 'deletetable'
});
}
if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader ){
itemsText.push({
caption: _t.menuEdit,
event: 'edit'
});
}
// if ( !_.isEmpty(api.can_AddHyperlink()) && !lockedHeader) {
// arrItems.push({
// caption: _t.menuAddLink,
// event: 'addlink'
// });
// }
if ( canReview ) {
if (false /*_inRevisionChange*/) {
itemsText.push({
caption: _t.menuReviewChange,
event: 'reviewchange'
});
} else {
itemsText.push({
caption: _t.menuReview,
event: 'review'
});
}
}
if ( this.isComments && canViewComments ) { if ( this.isComments && canViewComments ) {
itemsText.push({ itemsText.push({
caption: /*me.menuViewComment*/'View Comment', caption: _t.menuViewComment,
event: 'viewcomment' event: 'viewcomment'
}); });
} }
@ -173,102 +229,23 @@ class ContextMenu extends ContextMenuController {
const hideAddComment = !canViewComments || api.can_AddQuotedComment() === false || lockedText || lockedTable || lockedImage || lockedHeader || (!isText && isObject); const hideAddComment = !canViewComments || api.can_AddQuotedComment() === false || lockedText || lockedTable || lockedImage || lockedHeader || (!isText && isObject);
if ( !hideAddComment ) { if ( !hideAddComment ) {
itemsText.push({ itemsText.push({
caption: /*me.menuAddComment*/'Add Comment', caption: _t.menuAddComment,
event: 'addcomment' 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 ) { if ( isLink ) {
itemsText.push({ itemsText.push({
caption: /*me.menuOpenLink*/'Open Link', caption: _t.menuOpenLink,
event: 'openlink' event: 'openlink'
}); });
} }
if ( Device.phone && itemsText.length > 2 ) { 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, { this.extraItems = itemsText.splice(2,itemsText.length, {
caption: /*me.menuMore*/'More', caption: _t.menuMore,
event: 'showActionSheet' event: 'showActionSheet'
}); });
} }
@ -285,6 +262,11 @@ class ContextMenu extends ContextMenuController {
// event: 'review' // event: 'review'
// }]; // }];
} }
initExtraItems () {
return (this.extraItems && this.extraItems.length > 0 ? this.extraItems : []);
}
} }
export { ContextMenu as default }; const _ContextMenu = withTranslation()(ContextMenu);
export { _ContextMenu as default };