diff --git a/app/common/state/contextMenuState.js b/app/common/state/contextMenuState.js index 31840aa9830..7880efe2108 100644 --- a/app/common/state/contextMenuState.js +++ b/app/common/state/contextMenuState.js @@ -5,6 +5,7 @@ const Immutable = require('immutable') const assert = require('assert') const { makeImmutable, isMap } = require('./immutableUtil') +const uuid = require('uuid') const validateState = function (state) { state = makeImmutable(state) @@ -12,31 +13,34 @@ const validateState = function (state) { return state } +let contextMenuDetail = Immutable.Map() +let hamburgerMenuWasOpen = false + const api = { setContextMenu: (windowState, detail) => { detail = makeImmutable(detail) windowState = validateState(windowState) if (!detail) { - if (windowState.getIn(['contextMenuDetail', 'type']) === 'hamburgerMenu') { - windowState = windowState.set('hamburgerMenuWasOpen', true) + if (contextMenuDetail.get('type') === 'hamburgerMenu') { + hamburgerMenuWasOpen = true } else { - windowState = windowState.set('hamburgerMenuWasOpen', false) + hamburgerMenuWasOpen = false } + contextMenuDetail = Immutable.Map() windowState = windowState.delete('contextMenuDetail') } else { - if (!(detail.get('type') === 'hamburgerMenu' && windowState.get('hamburgerMenuWasOpen'))) { - windowState = windowState.set('contextMenuDetail', detail) + if (!(detail.get('type') === 'hamburgerMenu' && hamburgerMenuWasOpen)) { + contextMenuDetail = detail + windowState = windowState.set('contextMenuDetail', uuid()) } - windowState = windowState.set('hamburgerMenuWasOpen', false) + hamburgerMenuWasOpen = false } - return windowState }, - getContextMenu: (windowState) => { - windowState = validateState(windowState) - return windowState.get('contextMenuDetail', Immutable.Map()) + getContextMenu: () => { + return contextMenuDetail }, selectedIndex: (windowState) => { diff --git a/app/renderer/components/common/contextMenu/contextMenu.js b/app/renderer/components/common/contextMenu/contextMenu.js index 845c4660838..83ab7d97759 100644 --- a/app/renderer/components/common/contextMenu/contextMenu.js +++ b/app/renderer/components/common/contextMenu/contextMenu.js @@ -15,6 +15,9 @@ const windowActions = require('../../../../../js/actions/windowActions') // Constants const keyCodes = require('../../../../common/constants/keyCodes') +// State +const contextMenuState = require('../../../../common/state/contextMenuState') + // Utils const cx = require('../../../../../js/lib/classSet') const frameStateUtil = require('../../../../../js/state/frameStateUtil') @@ -215,7 +218,7 @@ class ContextMenu extends React.Component { const currentWindow = state.get('currentWindow') const activeFrame = frameStateUtil.getActiveFrame(currentWindow) || Immutable.Map() const selectedIndex = currentWindow.getIn(['ui', 'contextMenu', 'selectedIndex'], null) - const contextMenuDetail = currentWindow.get('contextMenuDetail', Immutable.Map()) + const contextMenuDetail = contextMenuState.getContextMenu() const props = {} props.lastZoomPercentage = activeFrame.get('lastZoomPercentage') diff --git a/app/renderer/components/frame/frame.js b/app/renderer/components/frame/frame.js index ec167d5ba9d..2cdd9b5832d 100644 --- a/app/renderer/components/frame/frame.js +++ b/app/renderer/components/frame/frame.js @@ -24,6 +24,7 @@ const windowStore = require('../../../../js/stores/windowStore') const appStoreRenderer = require('../../../../js/stores/appStoreRenderer') // State +const contextMenuState = require('../../../common/state/contextMenuState') const siteSettings = require('../../../../js/state/siteSettings') const siteSettingsState = require('../../../common/state/siteSettingsState') const tabState = require('../../../common/state/tabState') @@ -856,7 +857,7 @@ class Frame extends React.Component { const allSiteSettings = siteSettingsState.getAllSiteSettings(state, isPrivate) const frameSiteSettings = siteSettings.getSiteSettingsForURL(allSiteSettings, location) || Immutable.Map() - const contextMenu = currentWindow.get('contextMenuDetail') + const contextMenu = contextMenuState.getContextMenu() const tab = tabId && tabId > -1 && tabState.getByTabId(state, tabId) const props = {} diff --git a/app/renderer/reducers/contextMenuReducer.js b/app/renderer/reducers/contextMenuReducer.js index 4f6c02b3f46..aa33081fd90 100644 --- a/app/renderer/reducers/contextMenuReducer.js +++ b/app/renderer/reducers/contextMenuReducer.js @@ -510,7 +510,7 @@ const onShowBookmarkFolderMenu = (state, action) => { const menuTemplate = showBookmarkFolderInit(state, action.get('bookmarkKey')) if (action.get('submenuIndex') != null) { - let contextMenu = contextMenuState.getContextMenu(state) + let contextMenu = contextMenuState.getContextMenu() let openedSubmenuDetails = contextMenu.get('openedSubmenuDetails', Immutable.List()) openedSubmenuDetails = openedSubmenuDetails diff --git a/docs/state.md b/docs/state.md index 2c0b8ae5e5d..a3e8269c9e8 100644 --- a/docs/state.md +++ b/docs/state.md @@ -674,23 +674,7 @@ WindowStore }, cleanedOnShutdown: boolean, // whether app data was successfully cleared on shutdown closedFrames: [], // holds the same type of frame objects as frames - contextMenuDetail: { - bottom: number, // the bottom position of the context menu - left: number, // the left position of the context menu - maxHeight: number, // the maximum height of the context menu - openedSubmenuDetails: [{ - template: [], // same as template in contextMenuDetail - y: number // the relative y position - }], - right: number, // the right position of the context menu - template: [{ - click: function, // callback for the context menu to call when clicked - dragOver: function, // callback for when something is dragged over this item - drop: function, // callback for when something is dropped on this item - label: string // label of context menu item - }], - top: number // the top position of the context menu - }, + contextMenuDetail: string, // uuid for triggering state update createdFaviconDirectory: boolean, // whether the ledger-favicons directory has been created already in the appData directory frames: [{ aboutDetails: object, // details for about pages diff --git a/js/actions/windowActions.js b/js/actions/windowActions.js index 63b1e673a9f..0ffc2724a40 100644 --- a/js/actions/windowActions.js +++ b/js/actions/windowActions.js @@ -531,14 +531,19 @@ const windowActions = { }, /** - * Dispatches a message to set context menu detail. - * If set, also indicates that the context menu is shown. - * @param {Object} detail - The context menu detail + * Dispatches a message to set context menu uuid and also set detail + * in contextMenuState. + * If uuid set, also indicates that the context menu is shown. + * @param {Object} detail - uuid */ setContextMenuDetail: function (detail) { + const Immutable = require('immutable') + const contextMenuState = require('../../app/common/state/contextMenuState') + let state = contextMenuState.setContextMenu(Immutable.Map(), detail) + const contextMenuDetail = state.get('contextMenuDetail') dispatch({ actionType: windowConstants.WINDOW_SET_CONTEXT_MENU_DETAIL, - detail + contextMenuDetail }) }, diff --git a/js/stores/windowStore.js b/js/stores/windowStore.js index cd2d05a54c5..710da144406 100644 --- a/js/stores/windowStore.js +++ b/js/stores/windowStore.js @@ -465,21 +465,28 @@ const doAction = (action) => { windowState = windowState.delete('bookmarkFolderDetail') break case windowConstants.WINDOW_AUTOFILL_SELECTION_CLICKED: + windowState = contextMenuState.setContextMenu(windowState) ipc.send('autofill-selection-clicked', action.tabId, action.value, action.frontEndId, action.index) - windowState = windowState.delete('contextMenuDetail') break case windowConstants.WINDOW_AUTOFILL_POPUP_HIDDEN: - if (!action.detail && - windowState.getIn(['contextMenuDetail', 'type']) === 'autofill' && - windowState.getIn(['contextMenuDetail', 'tabId']) === action.tabId) { - windowState = windowState.delete('contextMenuDetail') - if (action.notify) { - ipc.send('autofill-popup-hidden', action.tabId) + { + const contextMenuDetail = contextMenuState.getContextMenu() + if (!action.detail && + contextMenuDetail.get('type') === 'autofill' && + contextMenuDetail.get('tabId') === action.tabId) { + windowState = contextMenuState.setContextMenu(windowState) + if (action.notify) { + ipc.send('autofill-popup-hidden', action.tabId) + } } + break } - break case windowConstants.WINDOW_SET_CONTEXT_MENU_DETAIL: - windowState = contextMenuState.setContextMenu(windowState, action.detail) + if (action.contextMenuDetail) { + windowState = windowState.set('contextMenuDetail', action.contextMenuDetail) + } else { + windowState = windowState.delete('contextMenuDetail') + } break case windowConstants.WINDOW_SET_POPUP_WINDOW_DETAIL: if (!action.detail) { @@ -641,7 +648,7 @@ const doAction = (action) => { break case windowConstants.WINDOW_TOGGLE_MENUBAR_VISIBLE: if (getSetting(settings.AUTO_HIDE_MENU)) { - doAction({actionType: windowConstants.WINDOW_SET_CONTEXT_MENU_DETAIL}) + windowState = contextMenuState.setContextMenu(windowState) // Use value if provided; if not, toggle to opposite. const newVisibleStatus = typeof action.isVisible === 'boolean' ? action.isVisible @@ -665,7 +672,7 @@ const doAction = (action) => { if (getSetting(settings.AUTO_HIDE_MENU)) { doAction({actionType: windowConstants.WINDOW_TOGGLE_MENUBAR_VISIBLE, isVisible: false}) } else { - doAction({actionType: windowConstants.WINDOW_SET_CONTEXT_MENU_DETAIL}) + windowState = contextMenuState.setContextMenu(windowState) } doAction({actionType: windowConstants.WINDOW_SET_MENUBAR_SELECTED_INDEX}) doAction({actionType: windowConstants.WINDOW_SET_CONTEXT_MENU_SELECTED_INDEX})