[mobile] Add actions for more items in context menu
This commit is contained in:
		
							parent
							
								
									299db5fcb6
								
							
						
					
					
						commit
						b4bd17d0bc
					
				| 
						 | 
				
			
			@ -1,8 +1,8 @@
 | 
			
		|||
import React, { Component } from 'react';
 | 
			
		||||
import React, { Component, Fragment } from 'react';
 | 
			
		||||
import { f7 } from 'framework7-react';
 | 
			
		||||
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';
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -11,12 +11,15 @@ class ContextMenuController extends Component {
 | 
			
		|||
        super(props);
 | 
			
		||||
 | 
			
		||||
        this.state = {
 | 
			
		||||
            opened: false
 | 
			
		||||
            , items: []
 | 
			
		||||
            opened: false,
 | 
			
		||||
            items: [],
 | 
			
		||||
            openedMore: false,
 | 
			
		||||
            extraItems: []
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        this.onMenuItemClick = this.onMenuItemClick.bind(this);
 | 
			
		||||
        this.onMenuClosed = this.onMenuClosed.bind(this);
 | 
			
		||||
        this.onActionClosed = this.onActionClosed.bind(this);
 | 
			
		||||
        this.onDocumentReady = this.onDocumentReady.bind(this);
 | 
			
		||||
        this.onApiOpenContextMenu = this.onApiOpenContextMenu.bind(this);
 | 
			
		||||
        this.onApiHideContextMenu = this.onApiHideContextMenu.bind(this);
 | 
			
		||||
| 
						 | 
				
			
			@ -96,7 +99,10 @@ class ContextMenuController extends Component {
 | 
			
		|||
 | 
			
		||||
    onApiOpenContextMenu(x, y) {
 | 
			
		||||
        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`});
 | 
			
		||||
            const popover = f7.popover.open(idContextMenuElement, idCntextMenuTargetElement);
 | 
			
		||||
| 
						 | 
				
			
			@ -132,8 +138,16 @@ class ContextMenuController extends Component {
 | 
			
		|||
        // })();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    onActionClosed() {
 | 
			
		||||
        this.setState({openedMore: false});
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    onMenuItemClick(action) {
 | 
			
		||||
        this.onApiHideContextMenu();
 | 
			
		||||
 | 
			
		||||
        if (action === 'showActionSheet') {
 | 
			
		||||
            this.setState({openedMore: true});
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    componentWillUnmount() {
 | 
			
		||||
| 
						 | 
				
			
			@ -158,9 +172,16 @@ class ContextMenuController extends Component {
 | 
			
		|||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    initExtraItems () {
 | 
			
		||||
        return [];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    render() {
 | 
			
		||||
        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>
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
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 { useTranslation } from 'react-i18next';
 | 
			
		||||
 | 
			
		||||
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}`;
 | 
			
		||||
export {ContextMenuView as default, exportedIdMenuElemen as idContextMenuElement};
 | 
			
		||||
export {ContextMenuView as default, exportedIdMenuElemen as idContextMenuElement, ActionsWithExtraItems};
 | 
			
		||||
| 
						 | 
				
			
			@ -4,4 +4,8 @@
 | 
			
		|||
 | 
			
		||||
.document-menu {
 | 
			
		||||
    width: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
html.phone .document-menu .list-block .list-button {
 | 
			
		||||
    padding: 0 10px;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -129,6 +129,21 @@
 | 
			
		|||
      "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": {
 | 
			
		||||
    "textCancel": "Cancel",
 | 
			
		||||
    "textSettings": "Settings",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,7 @@ 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';
 | 
			
		||||
import { withTranslation} from 'react-i18next';
 | 
			
		||||
 | 
			
		||||
@inject ( stores => ({
 | 
			
		||||
    isEdit: stores.storeAppOptions.isEdit,
 | 
			
		||||
| 
						 | 
				
			
			@ -70,6 +71,9 @@ class ContextMenu extends ContextMenuController {
 | 
			
		|||
    initMenuItems() {
 | 
			
		||||
        if ( !Common.EditorApi ) return [];
 | 
			
		||||
 | 
			
		||||
        const { t } = this.props;
 | 
			
		||||
        const _t = t("ContextMenu", { returnObjects: true });
 | 
			
		||||
 | 
			
		||||
        const { isEdit, canViewComments, canReview } = this.props;
 | 
			
		||||
 | 
			
		||||
        const api = Common.EditorApi.get();
 | 
			
		||||
| 
						 | 
				
			
			@ -81,7 +85,6 @@ class ContextMenu extends ContextMenuController {
 | 
			
		|||
 | 
			
		||||
        if ( canCopy ) {
 | 
			
		||||
            itemsIcon.push({
 | 
			
		||||
                caption: /*me.menuCopy*/ 'Copy',
 | 
			
		||||
                event: 'copy',
 | 
			
		||||
                icon: 'icon-copy'
 | 
			
		||||
            });
 | 
			
		||||
| 
						 | 
				
			
			@ -89,7 +92,7 @@ class ContextMenu extends ContextMenuController {
 | 
			
		|||
 | 
			
		||||
        if ( canViewComments && this.isComments && !isEdit ) {
 | 
			
		||||
            itemsText.push({
 | 
			
		||||
                caption: /*me.menuViewComment*/'View Comment',
 | 
			
		||||
                caption: _t.menuViewComment,
 | 
			
		||||
                event: 'viewcomment'
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -144,7 +147,6 @@ class ContextMenu extends ContextMenuController {
 | 
			
		|||
            if ( isEdit && !this.isDisconnected ) {
 | 
			
		||||
                if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader && canCopy ) {
 | 
			
		||||
                    itemsIcon.push({
 | 
			
		||||
                        // caption: me.menuCut,
 | 
			
		||||
                        event: 'cut',
 | 
			
		||||
                        icon: 'icon-cut'
 | 
			
		||||
                    });
 | 
			
		||||
| 
						 | 
				
			
			@ -155,16 +157,70 @@ class ContextMenu extends ContextMenuController {
 | 
			
		|||
 | 
			
		||||
                if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader ) {
 | 
			
		||||
                    itemsIcon.push({
 | 
			
		||||
                        // caption: me.menuPaste,
 | 
			
		||||
                        event: '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 ) {
 | 
			
		||||
                    itemsText.push({
 | 
			
		||||
                        caption: /*me.menuViewComment*/'View Comment',
 | 
			
		||||
                        caption: _t.menuViewComment,
 | 
			
		||||
                        event: 'viewcomment'
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
| 
						 | 
				
			
			@ -173,102 +229,23 @@ class ContextMenu extends ContextMenuController {
 | 
			
		|||
                const hideAddComment = !canViewComments || api.can_AddQuotedComment() === false || lockedText || lockedTable || lockedImage || lockedHeader || (!isText && isObject);
 | 
			
		||||
                if ( !hideAddComment ) {
 | 
			
		||||
                    itemsText.push({
 | 
			
		||||
                        caption: /*me.menuAddComment*/'Add Comment',
 | 
			
		||||
                        caption: _t.menuAddComment,
 | 
			
		||||
                        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',
 | 
			
		||||
                caption: _t.menuOpenLink,
 | 
			
		||||
                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',
 | 
			
		||||
                caption: _t.menuMore,
 | 
			
		||||
                event: 'showActionSheet'
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -285,6 +262,11 @@ class ContextMenu extends ContextMenuController {
 | 
			
		|||
        //         event: 'review'
 | 
			
		||||
        //     }];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    initExtraItems () {
 | 
			
		||||
        return (this.extraItems && this.extraItems.length > 0 ? this.extraItems : []);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export { ContextMenu as default };
 | 
			
		||||
const _ContextMenu = withTranslation()(ContextMenu);
 | 
			
		||||
export { _ContextMenu as default };
 | 
			
		||||
		Loading…
	
		Reference in a new issue