diff --git a/.eslintrc b/.eslintrc index 577df5b5..2306c3ce 100644 --- a/.eslintrc +++ b/.eslintrc @@ -22,7 +22,8 @@ "react/jsx-one-expression-per-line": 0, "lines-between-class-members": 0, "no-continue": 0, - "no-bitwise": 0 + "no-bitwise": 0, + "react/destructuring-assignment": 0 }, "parser": "babel-eslint", "globals": { diff --git a/app/actions/__tests__/preference.spec.js b/app/actions/__tests__/preference.spec.js deleted file mode 100644 index ce42ef50..00000000 --- a/app/actions/__tests__/preference.spec.js +++ /dev/null @@ -1,50 +0,0 @@ -import * as CATEGORY from 'actions/constant/actionCategory'; -import * as TYPES from 'actions/constant/actionTypes'; -import * as actions from 'actions/preference'; - -describe('test preference action', () => { - const mockId = 'mock-id'; - const mockMeta = { - category: CATEGORY.SELF, - }; - - it('should handle preferenceAllocateId', () => { - const mockAction = { - type: TYPES.PREFERENCE_ALLOCATE_ID, - payload: { - id: mockId, - }, - meta: { - category: CATEGORY.BROADCAST, - }, - }; - - expect(actions.preferenceAllocateId(mockId)) - .toEqual(mockAction); - }); - - it('should handle preferenceOpen', () => { - const mockAction = { - type: TYPES.PREFERENCE_OPEN, - meta: { - category: CATEGORY.TARGET, - containMain: true, - }, - }; - - expect(actions.preferenceOpen(mockId)) - .toEqual(mockAction); - }); - - it('should handle preferenceClose', () => { - const mockAction = { - type: TYPES.PREFERENCE_CLOSE, - payload: { - id: 'mock-id', - }, - meta: mockMeta, - }; - - expect(actions.preferenceClose('mock-id')).toEqual(mockAction); - }); -}); diff --git a/app/actions/__tests__/search.spec.js b/app/actions/__tests__/search.spec.js index 8c44e6cb..6ce1eb73 100644 --- a/app/actions/__tests__/search.spec.js +++ b/app/actions/__tests__/search.spec.js @@ -65,40 +65,4 @@ describe('test search actions', () => { expect(actions.searchWidgetSelectIncrease()).toEqual(mockAction); }); - - it('should handle searchWindowHide', () => { - const mockAction = { - type: TYPES.SEARCH_WINDOW_HIDE, - payload: {}, - meta: { - category: CATEGORY.TARGET, - containMain: true, - self: false, - }, - }; - - expect(actions.searchWindowHide()).toEqual(mockAction); - }); - - it('should handle searchTrayOpen', () => { - const mockAction = { - type: TYPES.SEARCH_TRAY_OPEN, - meta: { - category: CATEGORY.BROADCAST, - }, - }; - - expect(actions.searchTrayOpen()).toEqual(mockAction); - }); - - it('should handle searchTrayClose', () => { - const mockAction = { - type: TYPES.SEARCH_TRAY_CLOSE, - meta: { - category: CATEGORY.BROADCAST, - }, - }; - - expect(actions.searchTrayClose()).toEqual(mockAction); - }); }); diff --git a/app/actions/__tests__/update.spec.js b/app/actions/__tests__/update.spec.js deleted file mode 100644 index abbd0c42..00000000 --- a/app/actions/__tests__/update.spec.js +++ /dev/null @@ -1,226 +0,0 @@ -import { BrowserWindow } from 'electron'; -import * as actions from 'actions/update'; -import * as CATEGORY from 'actions/constant/actionCategory'; -import * as TYPES from 'actions/constant/actionTypes'; - -describe('test update action', () => { - it('should handle updateCheckRequest', () => { - const mockAction = { - type: TYPES.UPDATE_CHECK_REQUEST, - meta: { - category: CATEGORY.BROADCAST, - }, - }; - - expect(actions.updateCheckRequest()) - .toEqual(mockAction); - }); - - it('should handle updateCheckRequestOnManual', () => { - const mockAction = { - type: TYPES.UPDATE_CHECK_REQUEST_ON_MANUAL, - meta: { - category: CATEGORY.BROADCAST, - }, - }; - - expect(actions.updateCheckRequestOnManual()) - .toEqual(mockAction); - }); - - it('should handle updateCheckSuccess', () => { - const mockAction = { - type: TYPES.UPDATE_CHECK_SUCCESS, - payload: { - version: 'mock-version', - releaseNotes: 'mock-release-note', - }, - meta: { - category: CATEGORY.BROADCAST, - }, - }; - - expect(actions.updateCheckSuccess('mock-version', 'mock-release-note')) - .toEqual(mockAction); - }); - - it('should handle updateCheckFailure', () => { - const mockAction = { - type: TYPES.UPDATE_CHECK_FAILURE, - meta: { - category: CATEGORY.BROADCAST, - }, - }; - - expect(actions.updateCheckFailure()) - .toEqual(mockAction); - }); - - it('should handle updateDownloadRequest', () => { - const mockAction = { - type: TYPES.UPDATE_DOWNLOAD_REQUEST, - meta: { - category: CATEGORY.BROADCAST, - }, - }; - - expect(actions.updateDownloadRequest()) - .toEqual(mockAction); - }); - - it('should handle updateDownloadSuccess', () => { - const mockAction = { - type: TYPES.UPDATE_DOWNLOAD_SUCCESS, - meta: { - category: CATEGORY.BROADCAST, - }, - }; - - expect(actions.updateDownloadSuccess()) - .toEqual(mockAction); - }); - - it('should handle updateDownloadFailure', () => { - const mockAction = { - type: TYPES.UPDATE_DOWNLOAD_FAILURE, - meta: { - category: CATEGORY.BROADCAST, - }, - }; - - expect(actions.updateDownloadFailure()) - .toEqual(mockAction); - }); - - it('should handle updateDownloadProgress', () => { - const mockAction = { - type: TYPES.UPDATE_DOWNLOAD_PROGRESS, - payload: { - downloadObj: { - aa: 'aa', - bb: 'bb', - }, - }, - meta: { - category: CATEGORY.TARGET, - target: ['mock-id'], - containMain: true, - }, - }; - - expect(actions.updateDownloadProgress({ - aa: 'aa', - bb: 'bb', - }, 'mock-id')) - .toEqual(mockAction); - }); - - it('should handle updateSkipThisVersion', () => { - const mockAction = { - type: TYPES.UPDATE_SKIP_THIS_VERSION, - payload: { - version: 'mock-version', - }, - meta: { - category: CATEGORY.TARGET, - containMain: true, - self: false, - }, - }; - - expect(actions.updateSkipThisVersion('mock-version')) - .toEqual(mockAction); - }); - - it('should handle updateProgressCancel', () => { - const mockAction = { - type: TYPES.UPDATE_PROGRESS_CANCEL, - meta: { - category: CATEGORY.TARGET, - containMain: true, - self: false, - }, - }; - - expect(actions.updateProgressCancel()) - .toEqual(mockAction); - }); - - it('should handle updateSetAutoCheckUpdate', () => { - const mockAction = { - type: TYPES.UPDATE_SET_AUTO_CHECK_UPDATE, - payload: { - isCheckUpdateWhenStart: true, - }, - meta: { - category: CATEGORY.BROADCAST, - }, - }; - - expect(actions.updateSetAutoCheckUpdate(true)) - .toEqual(mockAction); - }); - - it('should handle updateSetAutoUpdate', () => { - const mockAction = { - type: TYPES.UPDATE_SET_AUTO_UPDATE, - payload: { - isDownloadUpdateWhenStart: true, - }, - meta: { - category: CATEGORY.BROADCAST, - }, - }; - - expect(actions.updateSetAutoUpdate(true)) - .toEqual(mockAction); - }); - - it('should handle updateInstallingDownloaded', () => { - const mockAction = { - type: TYPES.UPDATE_INSTALLING_DOWNLOADED, - meta: { - category: CATEGORY.BROADCAST, - }, - }; - - expect(actions.updateInstallingDownloaded()) - .toEqual(mockAction); - }); - - it('should handle updateProgressWindowOpen', () => { - const mockBrowserWindow = new BrowserWindow(); - const mockAction = { - type: TYPES.UPDATE_PROGRESS_WINDOW_OPEN, - payload: { - id: 'mock-id', - win: mockBrowserWindow, - }, - meta: { - category: CATEGORY.TARGET, - self: false, - containMain: true, - }, - }; - - expect(actions.updateProgressWindowOpen('mock-id', mockBrowserWindow)) - .toEqual(mockAction); - }); - - it('should handle updateProgressWindowClose', () => { - const mockAction = { - type: TYPES.UPDATE_PROGRESS_WINDOW_CLOSE, - payload: { - id: 'mock-id', - }, - meta: { - category: CATEGORY.TARGET, - self: false, - containMain: true, - }, - }; - - expect(actions.updateProgressWindowClose('mock-id')) - .toEqual(mockAction); - }); -}); diff --git a/app/actions/__tests__/window.spec.js b/app/actions/__tests__/window.spec.js deleted file mode 100644 index 2c277885..00000000 --- a/app/actions/__tests__/window.spec.js +++ /dev/null @@ -1,26 +0,0 @@ -import { BrowserWindow } from 'electron'; -import { openBrowserWindow } from 'actions/window'; -import * as CATEGORY from 'actions/constant/actionCategory'; -import * as TYPES from 'actions/constant/actionTypes'; - -describe('test window action', () => { - const mockId = 'mock-id'; - const mockMeta = { - category: CATEGORY.SELF, - }; - - it('should handle openBrowserWindow', () => { - const mockWindow = JSON.stringify(new BrowserWindow()); - const mockAction = { - type: TYPES.OPEN_BROWSER_WINDOW, - payload: { - id: mockId, - browserWindow: mockWindow, - }, - meta: mockMeta, - }; - - expect(openBrowserWindow(mockId, mockWindow)) - .toEqual(mockAction); - }); -}); diff --git a/app/actions/constant/actionTypes.js b/app/actions/constant/actionTypes.js index bcdd0be6..efd17469 100644 --- a/app/actions/constant/actionTypes.js +++ b/app/actions/constant/actionTypes.js @@ -1,9 +1,5 @@ export const MODAL_OPEN = 'MODAL_OPEN'; export const MODAL_CLOSE = 'MODAL_CLOSE'; -export const OPEN_BROWSER_WINDOW = 'OPEN_BROWSER_WINDOW'; -export const PREFERENCE_ALLOCATE_ID = 'PREFERENCE_ALLOCATE_ID'; -export const PREFERENCE_OPEN = 'PREFERENCE_OPEN'; -export const PREFERENCE_CLOSE = 'PREFERENCE_CLOSE'; export const SET_HOT_KEY_SEARCH_WINDOW = 'SET_HOT_KEY_SEARCH_WINDOW'; export const SET_INITIAL_STORE = 'SET_INITIAL_STORE'; export const SET_LANGUAGE_ENGLISH = 'SET_LANGUAGE_ENGLISH'; @@ -15,11 +11,8 @@ export const TOGGLE_WIDGET_DEFAULT_USER_AGENT = 'TOGGLE_WIDGET_DEFAULT_USER_AGEN export const SEARCH_APP_QUIT = 'SEARCH_APP_QUIT'; export const SEARCH_CHANGE_KEYWORD = 'SEARCH_CHANGE_KEYWORD'; export const SEARCH_SET_FILTER = 'SEARCH_SET_FILTER'; -export const SEARCH_TRAY_OPEN = 'SEARCH_TRAY_OPEN'; -export const SEARCH_TRAY_CLOSE = 'SEARCH_TRAY_CLOSE'; export const SEARCH_WIDGET_SELECT_INCREASE = 'SEARCH_WIDGET_SELECT_INCREASE'; export const SEARCH_WIDGET_SELECT_DECREASE = 'SEARCH_WIDGET_SELECT_DECREASE'; -export const SEARCH_WINDOW_HIDE = 'SEARCH_WINDOW_HIDE'; export const UPDATE_CHECK_REQUEST = 'UPDATE_CHECK_REQUEST'; export const UPDATE_CHECK_REQUEST_ON_MANUAL = 'UPDATE_CHECK_REQUEST_ON_MANUAL'; export const UPDATE_CHECK_SUCCESS = 'UPDATE_CHECK_SUCCESS'; diff --git a/app/actions/preference.js b/app/actions/preference.js deleted file mode 100644 index ddb07826..00000000 --- a/app/actions/preference.js +++ /dev/null @@ -1,28 +0,0 @@ -import { createActions } from 'redux-actions'; -import * as TYPES from 'actions/constant/actionTypes'; -import * as CATEGORY from 'actions/constant/actionCategory'; - -/** - * Action Set about Preference window. - */ -export const { - preferenceOpen, - preferenceClose, - preferenceAllocateId, -} = createActions({ - [TYPES.PREFERENCE_OPEN]: [ - () => {}, - () => ({ - category: CATEGORY.TARGET, - containMain: true, - }), - ], - [TYPES.PREFERENCE_CLOSE]: [ - id => ({ id }), - () => ({ category: CATEGORY.SELF }), - ], - [TYPES.PREFERENCE_ALLOCATE_ID]: [ - id => ({ id }), - () => ({ category: CATEGORY.BROADCAST }), - ], -}); diff --git a/app/actions/search.js b/app/actions/search.js index 4e4b815f..73a5ae79 100644 --- a/app/actions/search.js +++ b/app/actions/search.js @@ -6,9 +6,6 @@ export const { searchAppQuit, searchChangeKeyword, searchSetFilter, - searchTrayOpen, - searchTrayClose, - searchWindowHide, searchWidgetSelectIncrease, searchWidgetSelectDecrease, } = createActions({ @@ -37,31 +34,6 @@ export const { filter => ({ filter }), () => ({ category: CATEGORY.SELF }), ], - [TYPES.SEARCH_TRAY_OPEN]: [ - /** - * Open tray menu about searching. - */ - () => {}, - () => ({ category: CATEGORY.BROADCAST }), - ], - [TYPES.SEARCH_TRAY_CLOSE]: [ - /** - * Close tray menu about searching. - */ - () => {}, - () => ({ category: CATEGORY.BROADCAST }), - ], - [TYPES.SEARCH_WINDOW_HIDE]: [ - /** - * Hide tray menu about searching. - */ - () => ({}), - () => ({ - category: CATEGORY.TARGET, - containMain: true, - self: false, - }), - ], [TYPES.SEARCH_WIDGET_SELECT_INCREASE]: [ /** * Increase select index in list about searching window. diff --git a/app/actions/update.js b/app/actions/update.js deleted file mode 100644 index b50386e4..00000000 --- a/app/actions/update.js +++ /dev/null @@ -1,163 +0,0 @@ -import { createActions } from 'redux-actions'; -import * as TYPES from 'actions/constant/actionTypes'; -import * as CATEGORY from 'actions/constant/actionCategory'; - -export const { - updateCheckRequest, - updateCheckRequestOnManual, - updateCheckSuccess, - updateCheckFailure, - updateDownloadRequest, - updateDownloadSuccess, - updateDownloadFailure, - updateDownloadProgress, - updateInstallingDownloaded, - updateProgressCancel, - updateProgressWindowOpen, - updateProgressWindowClose, - updateSetAutoCheckUpdate, - updateSetAutoUpdate, - updateSkipThisVersion, -} = createActions({ - [TYPES.UPDATE_CHECK_REQUEST]: [ - /** - * Request API fetch if exist new version of update automatically when start app. - */ - () => {}, - () => ({ category: CATEGORY.BROADCAST }), - ], - [TYPES.UPDATE_CHECK_REQUEST_ON_MANUAL]: [ - /** - * Request API fetch if exist new version of update manually when click check button. - */ - () => {}, - () => ({ category: CATEGORY.BROADCAST }), - ], - [TYPES.UPDATE_CHECK_SUCCESS]: [ - /** - * Complete update check. - */ - (version, releaseNotes) => ({ version, releaseNotes }), - () => ({ category: CATEGORY.BROADCAST }), - ], - [TYPES.UPDATE_CHECK_FAILURE]: [ - /** - * Failure update check. - */ - () => {}, - () => ({ category: CATEGORY.BROADCAST }), - ], - [TYPES.UPDATE_DOWNLOAD_REQUEST]: [ - /** - * Request API fetch new download update file. - */ - () => {}, - () => ({ category: CATEGORY.BROADCAST }), - ], - [TYPES.UPDATE_DOWNLOAD_SUCCESS]: [ - /** - * Success API fetch new download update file. - */ - () => {}, - () => ({ category: CATEGORY.BROADCAST }), - ], - [TYPES.UPDATE_DOWNLOAD_FAILURE]: [ - /** - * Failure API fetch new download update file. - */ - () => {}, - () => ({ category: CATEGORY.BROADCAST }), - ], - [TYPES.UPDATE_DOWNLOAD_PROGRESS]: [ - /** - * Get update download information at real time. - * @param:Object obj: information about download like remain file size and download speed. - * @returns {{downloadObj : *}} - */ - obj => ({ downloadObj: obj }), - (obj, id) => ({ - category: CATEGORY.TARGET, - target: [id], - containMain: true, - }), - ], - [TYPES.UPDATE_INSTALLING_DOWNLOADED]: [ - /** - * Update is Installed but it doesn't install yet. - * TODO: - * Update file doesn't install immediately in macOS. - * So check this boolean because don't do update check of duplicate. - */ - () => {}, - () => ({ category: CATEGORY.BROADCAST }), - ], - [TYPES.UPDATE_PROGRESS_CANCEL]: [ - /** - * Cancel download process. - */ - () => {}, - () => ({ - category: CATEGORY.TARGET, - self: false, - containMain: true, - }), - ], - [TYPES.UPDATE_PROGRESS_WINDOW_OPEN]: [ - /** - * Open window about download process window. - * @param:String id: identification of window download process window. - * @param:BrowserWindow win: Electron BrowserWindow Object of download process window - * @returns {{id : *, win : *}} - */ - (id, win) => ({ id, win }), - () => ({ - category: CATEGORY.TARGET, - self: false, - containMain: true, - }), - ], - [TYPES.UPDATE_PROGRESS_WINDOW_CLOSE]: [ - /** - * Close window about download process window. - * @param:String id: identification of window download process window. - * @returns {{id : *}} - */ - id => ({ id }), - () => ({ - category: CATEGORY.TARGET, - self: false, - containMain: true, - }), - ], - [TYPES.UPDATE_SET_AUTO_CHECK_UPDATE]: [ - /** - * Set about update auto check. - * @param:Boolean isCheckUpdateWhenStart: next value about check update. - * @returns {{isCheckUpdateWhenStart : *}} - */ - isCheckUpdateWhenStart => ({ isCheckUpdateWhenStart }), - () => ({ category: CATEGORY.BROADCAST }), - ], - [TYPES.UPDATE_SET_AUTO_UPDATE]: [ - /** - * Set about update auto download. - * @param:Boolean isDownloadUpdateWhenStart: next value about download update. - * @returns {{isDownloadUpdateWhenStart : *}} - */ - isDownloadUpdateWhenStart => ({ isDownloadUpdateWhenStart }), - () => ({ category: CATEGORY.BROADCAST }), - ], - [TYPES.UPDATE_SKIP_THIS_VERSION]: [ - /** - * Set skip version about update. - * @param:String version: skip version about update. - * @returns {{version : *}} - */ - version => ({ version }), - () => ({ - category: CATEGORY.TARGET, - self: false, - containMain: true, - }), - ], -}); diff --git a/app/actions/window.js b/app/actions/window.js deleted file mode 100644 index e308ae05..00000000 --- a/app/actions/window.js +++ /dev/null @@ -1,21 +0,0 @@ -import { createActions } from 'redux-actions'; -import * as TYPES from 'actions/constant/actionTypes'; -import * as CATEGORY from 'actions/constant/actionCategory'; - -/** - * To use that open window. - */ -export const { // eslint-disable-line import/prefer-default-export - openBrowserWindow, -} = createActions({ - [TYPES.OPEN_BROWSER_WINDOW]: [ - /** - * When open new window, Dispatch this action. - * @param:String id: identification of window - * @param:BrowserWindow? browserWindow: Electron BrowserWindow of target - * @returns {{id: *, browserWindow: *}} - */ - (id, browserWindow) => ({ id, browserWindow }), - () => ({ category: CATEGORY.SELF }), - ], -}); diff --git a/app/config.js b/app/config.js index 1da4a421..00a16a3b 100644 --- a/app/config.js +++ b/app/config.js @@ -6,6 +6,7 @@ const TEMP_DIR = process.platform === 'win32' ? 'C:\\Windows\\Temp' : '/tmp'; const IS_TEST = process.env.NODE_ENV === 'test'; const SETTING_FILE = 'store.json'; +export const APP_VERSION = (app || remote.app).getVersion(); export const SETTING_FILE_PATH = !IS_TEST ? path.join(BASIC_PATH, 'oh-my-desk', SETTING_FILE) : path.join(TEMP_DIR, SETTING_FILE); diff --git a/app/constants/setting/index.js b/app/constants/setting/index.js deleted file mode 100644 index 78f710bc..00000000 --- a/app/constants/setting/index.js +++ /dev/null @@ -1 +0,0 @@ -export const defaultWidgets = `{"config":{"defaultUserAgent":"DESKTOP","language":"English","newVersion":null,"releaseNotes":null,"skipVersion":null,"hotKeySearchWindow":"Ctrl+Space"},"status":{"isRestartAfterUpdate":false,"isCheckUpdateWhenStart":false,"isUpdateCheckFetch":false,"isDownloadFetch":false,"isTrayOpen":true,"isLaunchAppWhenLogin":true,"isDownloadUpdateWhenStart":false,"isOpenWidgetWhenStart":true,"isUrlCheckFetch":false,"isUpdateCheckOnManual":false},"identification":{"downloadProgress":null,"preference":null,"widgetInfoById":{"fb07e56a-2ef3-4c3f-b7d4-3680a7173dd2":{"size":{"height":787,"width":750},"isEditProgress":false,"isMakeProgress":false,"position":{"x":360,"y":83},"createTime":"2018-11-13T04:10:58.640Z","name":"google","isOnTop":false,"url":"https://www.google.com/","isOpen":false,"favorites":true,"userAgent":"DESKTOP","resentFocusTime":"2018-11-13T11:32:48.186Z","id":"fb07e56a-2ef3-4c3f-b7d4-3680a7173dd2","reloadInterval":5},"e8581480-cd58-458a-a268-f9869fa5fcfc":{"size":{"height":777,"width":821},"isEditProgress":false,"isMakeProgress":false,"position":{"x":575,"y":115},"createTime":"2018-11-13T11:32:08.049Z","name":"trello","isOnTop":false,"url":"https://trello.com/","isOpen":false,"favorites":false,"userAgent":"DESKTOP","resentFocusTime":"2018-11-25T16:33:47.625Z","id":"e8581480-cd58-458a-a268-f9869fa5fcfc"},"d5db9663-4879-47ca-ab63-10cf74de2967":{"size":{"height":600,"width":500},"isEditProgress":false,"isMakeProgress":false,"position":{"x":600,"y":99},"createTime":"2018-11-25T16:34:16.673Z","name":"translator","isOnTop":false,"url":"https://translate.google.com/","isOpen":false,"favorites":false,"resentFocusTime":"2018-11-25T16:34:17.266Z","id":"d5db9663-4879-47ca-ab63-10cf74de2967"}}}}`;//eslint-disable-line diff --git a/app/e2e-ipc-handler.js b/app/e2e-ipc-handler.js index 651ae222..76bb2d91 100644 --- a/app/e2e-ipc-handler.js +++ b/app/e2e-ipc-handler.js @@ -1,13 +1,13 @@ import { ipcMain } from 'electron'; -import TrayMenuBar from 'main/utils/menu/trayMenuBar'; +import { showSearch, hideSearch } from 'main/utils/window/search'; function e2eIpcHandler() { ipcMain.on('search.window.open', () => { - TrayMenuBar.showWindow(); + showSearch(); }); ipcMain.on('search.window.close', () => { - TrayMenuBar.hideWindow(); + hideSearch(); }); } diff --git a/app/main.js b/app/main.js index e280210a..0b77042a 100644 --- a/app/main.js +++ b/app/main.js @@ -1,21 +1,73 @@ import { app } from 'electron'; import store from 'store/storeMain'; import saveData from 'main/utils/disk/saveData'; -import init from 'main/utils/init'; -import { preferenceClose } from 'actions/preference'; import { widgetCloseWhole } from 'actions/widget'; -import { setWhenQuitApp } from 'actions/setting'; +import { setInitialStore, setWhenQuitApp } from 'actions/setting'; import { isOpenWidgetWhenStartSelector } from 'store/reducers/share/status/selectors'; +import { showSearch, hideSearch } from 'main/utils/window/search'; +import autoLaunchConfig from 'main/utils/window/autoLaunch'; +import subscribeActionMain from 'store/utils/subscribeActionMain'; +import createMenu from 'main/utils/menu/createMenu'; +import handlingSearchHotKey from 'main/utils/menu/handlingSearchHotKey'; +import { hotKeySearchWindowSelector } from 'store/reducers/share/config/selectors'; +import openAllWidgetStatusOpen from 'main/utils/window/openAllWidgetStatusOpen'; +import openReduxDevTools from 'main/utils/window/openReduxDevTools'; +import handleIPC from 'main/utils/handleIPC'; +import { autoUpdater } from 'electron-updater'; -app.on('ready', init); +const SAVE_SETTING_INTERVAL = 300000; +/** + * When start app. + */ +app.on('ready', () => { + const state = store.getState(); + const hotkeyToOpenSearch = hotKeySearchWindowSelector(state); + + createMenu(); + handlingSearchHotKey(hotkeyToOpenSearch); + openAllWidgetStatusOpen(); + + // Config action to communication with renderer + subscribeActionMain(store); + + // auto launch & update + autoLaunchConfig(); + autoUpdater.checkForUpdatesAndNotify(); + + handleIPC(); + // config data + setInterval(saveData, SAVE_SETTING_INTERVAL); + store.dispatch(setInitialStore()); + + openReduxDevTools(); +}); + + +/** + * Only Mac OS + * When start app, relaunch app, dock icon click. + */ +app.on('activate', (e, isOpenWindow) => { + if (!isOpenWindow) { + showSearch(); + } else { + hideSearch(); + } +}); + +/** + * When quit app. + * This event doesn't occur when logout user(terminate OS) on WindowOS. + */ app.on('before-quit', () => { - const isOpenWidgetWhenStart = isOpenWidgetWhenStartSelector(store.getState()); + const { getState, dispatch } = store; + const state = getState(); + const isOpenWidgetWhenStart = isOpenWidgetWhenStartSelector(state); if (!isOpenWidgetWhenStart) { - store.dispatch(widgetCloseWhole()); + dispatch(widgetCloseWhole()); } - store.dispatch(preferenceClose()); - store.dispatch(setWhenQuitApp()); + dispatch(setWhenQuitApp()); saveData(); }); diff --git a/app/main/controllers/__tests__/preference.spec.js b/app/main/controllers/__tests__/preference.spec.js index 7385a485..4bf2388b 100644 --- a/app/main/controllers/__tests__/preference.spec.js +++ b/app/main/controllers/__tests__/preference.spec.js @@ -1,19 +1,10 @@ -import { autoUpdater } from 'electron-updater'; -import { CancellationToken } from 'electron-builder-http'; import * as TYPES from 'actions/constant/actionTypes'; -import * as openPreference from 'main/utils/window/openPreference'; import * as autoLaunch from 'main/utils/window/autoLaunch'; -import store from 'store/storeMain'; import createMenu from 'main/utils/menu/createMenu'; -import openUpdateProgress from 'main/utils/update/openUpdateProgress'; -import { - updateDownloadSuccess, -} from 'actions/update'; import preferenceController from '../preference'; jest.mock('electron-builder-http'); jest.mock('main/utils/menu/createMenu'); -jest.mock('main/utils/update/openUpdateProgress'); jest.mock('electron-updater'); describe('test preference controller', () => { @@ -21,19 +12,6 @@ describe('test preference controller', () => { jest.clearAllMocks(); }); - it('should handle OPEN_PREFERENCE', () => { - const mockOpenPreference = jest.spyOn(openPreference, 'default'); - mockOpenPreference.mockImplementation(jest.fn()); - const mockAction = { - type: TYPES.PREFERENCE_OPEN, - }; - - preferenceController(mockAction); - - expect(mockOpenPreference).toHaveBeenCalledTimes(1); - expect(mockOpenPreference).toHaveBeenCalledWith(); - }); - it('should handle TOGGLE_OPEN_APP_WHEN_LOGIN', () => { const mockAutoLaunch = jest.spyOn(autoLaunch, 'default'); mockAutoLaunch.mockImplementation(jest.fn()); @@ -68,46 +46,4 @@ describe('test preference controller', () => { expect(createMenu).toHaveBeenCalledTimes(1); expect(createMenu).toHaveBeenCalledWith(); }); - - describe('should handle UPDATE_DOWNLOAD_REQUEST', () => { - const mockAction = { - type: TYPES.UPDATE_DOWNLOAD_REQUEST, - }; - - it('should call basic logic', () => { - preferenceController(mockAction); - - expect(openUpdateProgress).toHaveBeenCalledTimes(1); - expect(openUpdateProgress).toHaveBeenCalledWith(); - }); - - it('should call download success to promise then', () => { - const dispatch = jest.spyOn(store, 'dispatch'); - const downloadUpdate = jest - .spyOn(autoUpdater, 'downloadUpdate') - .mockImplementation(() => Promise.resolve()); - - preferenceController(mockAction); - - expect(downloadUpdate).toHaveBeenCalledTimes(1); - expect(downloadUpdate).toHaveBeenCalledWith(CancellationToken.mock.instances[0]); - - return downloadUpdate().then(() => { - expect(dispatch).toHaveBeenCalledTimes(1); - expect(dispatch).toHaveBeenCalledWith(updateDownloadSuccess()); - }); - }); - - it('should call progress cancel', () => { - preferenceController(mockAction); - - const cancellationToken = CancellationToken.mock.instances[0]; - cancellationToken.cancel = jest.fn(); - const cancelAction = { type: TYPES.UPDATE_PROGRESS_CANCEL }; - - preferenceController(cancelAction); - - expect(cancellationToken.cancel).toHaveBeenCalledTimes(1); - }); - }); }); diff --git a/app/main/controllers/__tests__/search.spec.js b/app/main/controllers/__tests__/search.spec.js deleted file mode 100644 index 65993293..00000000 --- a/app/main/controllers/__tests__/search.spec.js +++ /dev/null @@ -1,16 +0,0 @@ -import * as TYPES from 'actions/constant/actionTypes'; -import trayBar from 'main/utils/menu/trayMenuBar'; -import searchController from '../search'; - -describe('test search controller', () => { - it('should handle SEARCH_WINDOW_HIDE', () => { - trayBar.hideWindow = jest.fn(); - const mockAction = { - type: TYPES.SEARCH_WINDOW_HIDE, - }; - searchController(mockAction); - - expect(trayBar.hideWindow).toHaveBeenCalledTimes(1); - expect(trayBar.hideWindow).toHaveBeenCalledWith(); - }); -}); diff --git a/app/main/controllers/__tests__/widget.spec.js b/app/main/controllers/__tests__/widget.spec.js index d6413d94..aba7b589 100644 --- a/app/main/controllers/__tests__/widget.spec.js +++ b/app/main/controllers/__tests__/widget.spec.js @@ -1,354 +1,359 @@ -import Immutable from 'immutable'; -import { BrowserWindow } from 'electron'; -import * as TYPES from 'actions/constant/actionTypes'; -import storeMock from 'store/storeMain'; -import { openBrowserWindow } from 'actions/window'; -import * as utils from 'main/utils/widget/makeWidget'; -import saveData from 'main/utils/disk/saveData'; -import widgetController from '../widget'; - -jest.mock('main/utils/disk/saveData'); - -describe('test widgetController', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - const mockBrowserWindow = new BrowserWindow(); - storeMock.dispatch = jest.fn(); - - it('should handle TYPES.WIDGET_MAKE_REQUEST', () => { - const mockAction = { - type: TYPES.WIDGET_MAKE_REQUEST, - payload: { - id: 'mock-id', - info: { - name: 'mock-name', - url: 'mock-url', - isOpen: false, - }, - }, - }; - - const makeWidgetWindow = jest.spyOn(utils, 'default'); - makeWidgetWindow.mockImplementationOnce(() => mockBrowserWindow); - - widgetController(mockAction); - - expect(makeWidgetWindow).toHaveBeenCalledTimes(1); - expect(makeWidgetWindow).toHaveBeenCalledWith('mock-id', undefined, true); - - expect(storeMock.dispatch).toHaveBeenCalledTimes(1); - expect(storeMock.dispatch).toHaveBeenCalledWith( - openBrowserWindow( - 'mock-id', - mockBrowserWindow, - ), - ); - expect(saveData).toHaveBeenCalledTimes(1); - }); - - describe('should handle TYPES.WIDGET_OPEN', () => { - const mockAction = { - type: TYPES.WIDGET_OPEN, - payload: { - id: 'mock-id', - isFocus: true, - }, - }; - const makeWidgetWindow = jest.spyOn(utils, 'default'); - - it('when widget is exist', () => { - const browserWindow = new BrowserWindow(); - - const mockStore = Immutable.Map({ - personal: Immutable.Map({ - identification: Immutable.Map({ - browserWindowById: Immutable.Map({ - 'mock-id': browserWindow, - }), - }), - }), - share: Immutable.Map({ - identification: Immutable.fromJS({ - widgetInfoById: { - 'mock-id': { - name: 'mock-name', - url: 'mock-url', - isOpen: false, - }, - }, - }), - }), - }); - - widgetController(mockAction, mockStore, mockStore); - - expect(browserWindow.show).toHaveBeenCalledTimes(1); - expect(browserWindow.show).toHaveBeenCalledWith(); - expect(makeWidgetWindow).toHaveBeenCalledTimes(0); - }); - - it('when widget is not exist', () => { - const mockStore = Immutable.Map({ - personal: Immutable.Map({ - identification: Immutable.Map({ - browserWindowById: Immutable.Map({}), - }), - }), - share: Immutable.Map({ - identification: Immutable.fromJS({ - widgetInfoById: { - 'mock-id': { - name: 'mock-name', - url: 'mock-url', - isOpen: false, - }, - }, - }), - }), - }); - makeWidgetWindow.mockImplementationOnce(() => mockBrowserWindow); - widgetController(mockAction, mockStore, mockStore); - - expect(makeWidgetWindow).toHaveBeenCalledTimes(1); - expect(makeWidgetWindow).toHaveBeenCalledWith('mock-id', { - name: 'mock-name', - url: 'mock-url', - isOpen: false, - }, true); - expect(storeMock.dispatch).toHaveBeenCalledTimes(1); - expect(storeMock.dispatch).toHaveBeenCalledWith( - openBrowserWindow( - 'mock-id', - mockBrowserWindow, - ), - ); - }); - }); - - describe('should handle TYPES.WIDGET_CLOSE', () => { - const browserWindow = new BrowserWindow(); - const mockAction = { - type: TYPES.WIDGET_CLOSE, - payload: { - id: 'mock-id', - info: { - name: 'mock-name', - url: 'mock-url', - isOpen: false, - }, - }, - }; - - it('when widget exist', () => { - const mockStore = Immutable.Map({ - personal: Immutable.Map({ - identification: Immutable.Map({ - browserWindowById: Immutable.Map({ - 'mock-id': browserWindow, - }), - }), - }), - share: Immutable.Map({ - identification: Immutable.fromJS({ - widgetInfoById: { - 'mock-id': { - name: 'mock-name', - url: 'mock-url', - isOpen: false, - }, - }, - }), - }), - }); - widgetController(mockAction, mockStore, mockStore); - - expect(browserWindow.close).toHaveBeenCalledTimes(1); - expect(browserWindow.close).toHaveBeenCalledWith(); - }); - - it('when widget don\'t exist', () => { - const mockStore = Immutable.Map({ - personal: Immutable.Map({ - identification: Immutable.Map({ - browserWindowById: Immutable.Map({}), - }), - }), - share: Immutable.Map({ - identification: Immutable.fromJS({ - widgetInfoById: { - 'mock-id': { - name: 'mock-name', - url: 'mock-url', - isOpen: false, - }, - }, - }), - }), - }); - widgetController(mockAction, mockStore, mockStore); - - expect(browserWindow.close).toHaveBeenCalledTimes(0); - }); - }); - - describe('should handle TYPES.WIDGET_DELETE', () => { - const browserWindow = new BrowserWindow(); - const mockAction = { - type: TYPES.WIDGET_DELETE, - payload: { - id: 'mock-id', - info: { - name: 'mock-name', - url: 'mock-url', - isOpen: false, - }, - }, - }; - - it('when widget exist', () => { - const mockStore = Immutable.Map({ - personal: Immutable.Map({ - identification: Immutable.Map({ - browserWindowById: Immutable.Map({ - 'mock-id': browserWindow, - }), - }), - }), - share: Immutable.Map({ - identification: Immutable.fromJS({ - widgetInfoById: { - 'mock-id': { - name: 'mock-name', - url: 'mock-url', - isOpen: false, - }, - }, - }), - }), - }); - widgetController(mockAction, mockStore, mockStore); - - expect(browserWindow.close).toHaveBeenCalledTimes(1); - expect(browserWindow.close).toHaveBeenCalledWith(); - }); - - it('when widget don\'t exist', () => { - const mockStore = Immutable.Map({ - personal: Immutable.Map({ - identification: Immutable.Map({ - browserWindowById: Immutable.Map({}), - }), - }), - share: Immutable.Map({ - identification: Immutable.fromJS({ - widgetInfoById: { - 'mock-id': { - name: 'mock-name', - url: 'mock-url', - isOpen: false, - }, - }, - }), - }), - }); - widgetController(mockAction, mockStore, mockStore); - - expect(browserWindow.close).toHaveBeenCalledTimes(0); - }); - }); - - describe('should handle WIDGET_UPDATE_INFO', () => { - const browserWindow = new BrowserWindow(); - const mockStore = Immutable.Map({ - personal: Immutable.Map({ - identification: Immutable.Map({ - browserWindowById: Immutable.Map({ - 'mock-id': browserWindow, - }), - }), - }), - share: Immutable.Map({ - identification: Immutable.fromJS({ - widgetInfoById: { - 'mock-id': { - name: 'mock-name', - url: 'mock-url', - isOpen: false, - }, - }, - }), - }), - }); - - describe('test isOnTop', () => { - it('when widget don\'t exist', () => { - const mockAction = { - type: TYPES.WIDGET_UPDATE_INFO, - payload: { - id: 'mock-id', - info: { - isOnTop: false, - }, - }, - }; - const mockWithoutWindow = Immutable.Map({ - personal: Immutable.Map({ - identification: Immutable.Map({ - browserWindowById: Immutable.Map({}), - }), - }), - share: Immutable.Map({ - identification: Immutable.fromJS({ - widgetInfoById: { - 'mock-id': { - name: 'mock-name', - url: 'mock-url', - isOpen: false, - }, - }, - }), - }), - }); - - widgetController(mockAction, mockWithoutWindow, mockWithoutWindow); - - expect(browserWindow.setAlwaysOnTop).toHaveBeenCalledTimes(0); - }); - - it('when isOnTop is false', () => { - const mockAction = { - type: TYPES.WIDGET_UPDATE_INFO, - payload: { - id: 'mock-id', - info: { - isOnTop: false, - }, - }, - }; - - widgetController(mockAction, mockStore, mockStore); - - expect(browserWindow.setAlwaysOnTop).toHaveBeenCalledTimes(1); - expect(browserWindow.setAlwaysOnTop).toHaveBeenCalledWith(false); - }); - - it('when isOnTop is true', () => { - const mockAction = { - type: TYPES.WIDGET_UPDATE_INFO, - payload: { - id: 'mock-id', - info: { - isOnTop: true, - }, - }, - }; - - widgetController(mockAction, mockStore, mockStore); - - expect(browserWindow.setAlwaysOnTop).toHaveBeenCalledTimes(1); - expect(browserWindow.setAlwaysOnTop).toHaveBeenCalledWith(true); - }); - }); +describe('', () => { + it('should ', () => { }); }); + +// import Immutable from 'immutable'; +// import { BrowserWindow } from 'electron'; +// import * as TYPES from 'actions/constant/actionTypes'; +// import storeMock from 'store/storeMain'; +// import { openBrowserWindow } from 'actions/window'; +// import widget from 'main/utils/window/widget'; +// import saveData from 'main/utils/disk/saveData'; +// import widgetController from '../widget'; +// +// jest.mock('main/utils/disk/saveData'); +// +// describe('test widgetController', () => { +// beforeEach(() => { +// jest.clearAllMocks(); +// }); +// const mockBrowserWindow = new BrowserWindow(); +// storeMock.dispatch = jest.fn(); +// +// it('should handle TYPES.WIDGET_MAKE_REQUEST', () => { +// const mockAction = { +// type: TYPES.WIDGET_MAKE_REQUEST, +// payload: { +// id: 'mock-id', +// info: { +// name: 'mock-name', +// url: 'mock-url', +// isOpen: false, +// }, +// }, +// }; +// +// const makeWidgetWindow = jest.spyOn(widget, 'openWidget'); +// makeWidgetWindow.mockImplementationOnce(() => mockBrowserWindow); +// +// widgetController(mockAction); +// +// expect(makeWidgetWindow).toHaveBeenCalledTimes(1); +// expect(makeWidgetWindow).toHaveBeenCalledWith('mock-id', undefined, true); +// +// expect(storeMock.dispatch).toHaveBeenCalledTimes(1); +// expect(storeMock.dispatch).toHaveBeenCalledWith( +// openBrowserWindow( +// 'mock-id', +// mockBrowserWindow, +// ), +// ); +// expect(saveData).toHaveBeenCalledTimes(1); +// }); +// +// describe('should handle TYPES.WIDGET_OPEN', () => { +// const mockAction = { +// type: TYPES.WIDGET_OPEN, +// payload: { +// id: 'mock-id', +// isFocus: true, +// }, +// }; +// const makeWidgetWindow = jest.spyOn(widget, 'openWidget'); +// +// it('when widget is exist', () => { +// const browserWindow = new BrowserWindow(); +// +// const mockStore = Immutable.Map({ +// personal: Immutable.Map({ +// identification: Immutable.Map({ +// browserWindowById: Immutable.Map({ +// 'mock-id': browserWindow, +// }), +// }), +// }), +// share: Immutable.Map({ +// identification: Immutable.fromJS({ +// widgetInfoById: { +// 'mock-id': { +// name: 'mock-name', +// url: 'mock-url', +// isOpen: false, +// }, +// }, +// }), +// }), +// }); +// +// widgetController(mockAction, mockStore, mockStore); +// +// expect(browserWindow.show).toHaveBeenCalledTimes(1); +// expect(browserWindow.show).toHaveBeenCalledWith(); +// expect(makeWidgetWindow).toHaveBeenCalledTimes(0); +// }); +// +// it('when widget is not exist', () => { +// const mockStore = Immutable.Map({ +// personal: Immutable.Map({ +// identification: Immutable.Map({ +// browserWindowById: Immutable.Map({}), +// }), +// }), +// share: Immutable.Map({ +// identification: Immutable.fromJS({ +// widgetInfoById: { +// 'mock-id': { +// name: 'mock-name', +// url: 'mock-url', +// isOpen: false, +// }, +// }, +// }), +// }), +// }); +// makeWidgetWindow.mockImplementationOnce(() => mockBrowserWindow); +// widgetController(mockAction, mockStore, mockStore); +// +// expect(makeWidgetWindow).toHaveBeenCalledTimes(1); +// expect(makeWidgetWindow).toHaveBeenCalledWith('mock-id', { +// name: 'mock-name', +// url: 'mock-url', +// isOpen: false, +// }, true); +// expect(storeMock.dispatch).toHaveBeenCalledTimes(1); +// expect(storeMock.dispatch).toHaveBeenCalledWith( +// openBrowserWindow( +// 'mock-id', +// mockBrowserWindow, +// ), +// ); +// }); +// }); +// +// describe('should handle TYPES.WIDGET_CLOSE', () => { +// const browserWindow = new BrowserWindow(); +// const mockAction = { +// type: TYPES.WIDGET_CLOSE, +// payload: { +// id: 'mock-id', +// info: { +// name: 'mock-name', +// url: 'mock-url', +// isOpen: false, +// }, +// }, +// }; +// +// it('when widget exist', () => { +// const mockStore = Immutable.Map({ +// personal: Immutable.Map({ +// identification: Immutable.Map({ +// browserWindowById: Immutable.Map({ +// 'mock-id': browserWindow, +// }), +// }), +// }), +// share: Immutable.Map({ +// identification: Immutable.fromJS({ +// widgetInfoById: { +// 'mock-id': { +// name: 'mock-name', +// url: 'mock-url', +// isOpen: false, +// }, +// }, +// }), +// }), +// }); +// widgetController(mockAction, mockStore, mockStore); +// +// expect(browserWindow.close).toHaveBeenCalledTimes(1); +// expect(browserWindow.close).toHaveBeenCalledWith(); +// }); +// +// it('when widget don\'t exist', () => { +// const mockStore = Immutable.Map({ +// personal: Immutable.Map({ +// identification: Immutable.Map({ +// browserWindowById: Immutable.Map({}), +// }), +// }), +// share: Immutable.Map({ +// identification: Immutable.fromJS({ +// widgetInfoById: { +// 'mock-id': { +// name: 'mock-name', +// url: 'mock-url', +// isOpen: false, +// }, +// }, +// }), +// }), +// }); +// widgetController(mockAction, mockStore, mockStore); +// +// expect(browserWindow.close).toHaveBeenCalledTimes(0); +// }); +// }); +// +// describe('should handle TYPES.WIDGET_DELETE', () => { +// const browserWindow = new BrowserWindow(); +// const mockAction = { +// type: TYPES.WIDGET_DELETE, +// payload: { +// id: 'mock-id', +// info: { +// name: 'mock-name', +// url: 'mock-url', +// isOpen: false, +// }, +// }, +// }; +// +// it('when widget exist', () => { +// const mockStore = Immutable.Map({ +// personal: Immutable.Map({ +// identification: Immutable.Map({ +// browserWindowById: Immutable.Map({ +// 'mock-id': browserWindow, +// }), +// }), +// }), +// share: Immutable.Map({ +// identification: Immutable.fromJS({ +// widgetInfoById: { +// 'mock-id': { +// name: 'mock-name', +// url: 'mock-url', +// isOpen: false, +// }, +// }, +// }), +// }), +// }); +// widgetController(mockAction, mockStore, mockStore); +// +// expect(browserWindow.close).toHaveBeenCalledTimes(1); +// expect(browserWindow.close).toHaveBeenCalledWith(); +// }); +// +// it('when widget don\'t exist', () => { +// const mockStore = Immutable.Map({ +// personal: Immutable.Map({ +// identification: Immutable.Map({ +// browserWindowById: Immutable.Map({}), +// }), +// }), +// share: Immutable.Map({ +// identification: Immutable.fromJS({ +// widgetInfoById: { +// 'mock-id': { +// name: 'mock-name', +// url: 'mock-url', +// isOpen: false, +// }, +// }, +// }), +// }), +// }); +// widgetController(mockAction, mockStore, mockStore); +// +// expect(browserWindow.close).toHaveBeenCalledTimes(0); +// }); +// }); +// +// describe('should handle WIDGET_UPDATE_INFO', () => { +// const browserWindow = new BrowserWindow(); +// const mockStore = Immutable.Map({ +// personal: Immutable.Map({ +// identification: Immutable.Map({ +// browserWindowById: Immutable.Map({ +// 'mock-id': browserWindow, +// }), +// }), +// }), +// share: Immutable.Map({ +// identification: Immutable.fromJS({ +// widgetInfoById: { +// 'mock-id': { +// name: 'mock-name', +// url: 'mock-url', +// isOpen: false, +// }, +// }, +// }), +// }), +// }); +// +// describe('test isOnTop', () => { +// it('when widget don\'t exist', () => { +// const mockAction = { +// type: TYPES.WIDGET_UPDATE_INFO, +// payload: { +// id: 'mock-id', +// info: { +// isOnTop: false, +// }, +// }, +// }; +// const mockWithoutWindow = Immutable.Map({ +// personal: Immutable.Map({ +// identification: Immutable.Map({ +// browserWindowById: Immutable.Map({}), +// }), +// }), +// share: Immutable.Map({ +// identification: Immutable.fromJS({ +// widgetInfoById: { +// 'mock-id': { +// name: 'mock-name', +// url: 'mock-url', +// isOpen: false, +// }, +// }, +// }), +// }), +// }); +// +// widgetController(mockAction, mockWithoutWindow, mockWithoutWindow); +// +// expect(browserWindow.setAlwaysOnTop).toHaveBeenCalledTimes(0); +// }); +// +// it('when isOnTop is false', () => { +// const mockAction = { +// type: TYPES.WIDGET_UPDATE_INFO, +// payload: { +// id: 'mock-id', +// info: { +// isOnTop: false, +// }, +// }, +// }; +// +// widgetController(mockAction, mockStore, mockStore); +// +// expect(browserWindow.setAlwaysOnTop).toHaveBeenCalledTimes(1); +// expect(browserWindow.setAlwaysOnTop).toHaveBeenCalledWith(false); +// }); +// +// it('when isOnTop is true', () => { +// const mockAction = { +// type: TYPES.WIDGET_UPDATE_INFO, +// payload: { +// id: 'mock-id', +// info: { +// isOnTop: true, +// }, +// }, +// }; +// +// widgetController(mockAction, mockStore, mockStore); +// +// expect(browserWindow.setAlwaysOnTop).toHaveBeenCalledTimes(1); +// expect(browserWindow.setAlwaysOnTop).toHaveBeenCalledWith(true); +// }); +// }); +// }); +// }); diff --git a/app/main/controllers/preference.js b/app/main/controllers/preference.js index 6272d4c4..a74676db 100644 --- a/app/main/controllers/preference.js +++ b/app/main/controllers/preference.js @@ -1,27 +1,10 @@ -import { autoUpdater } from 'electron-updater'; -import { CancellationToken } from 'electron-builder-http'; -import store from 'store/storeMain'; -import openPreference from 'main/utils/window/openPreference'; import * as TYPES from 'actions/constant/actionTypes'; import autoLaunch from 'main/utils/window/autoLaunch'; import createMenu from 'main/utils/menu/createMenu'; -import { - updateCheckSuccess, - updateCheckFailure, - updateDownloadSuccess, - updateDownloadFailure, -} from 'actions/update'; -import openUpdateProgress from 'main/utils/update/openUpdateProgress'; - -let cancellationToken; const preferenceController = (action) => { const { type } = action; switch (type) { // eslint-disable-line default-case - case TYPES.PREFERENCE_OPEN: { - openPreference(); - break; - } case TYPES.TOGGLE_OPEN_APP_WHEN_LOGIN: { autoLaunch(); break; @@ -31,34 +14,6 @@ const preferenceController = (action) => { createMenu(); break; } - case TYPES.UPDATE_CHECK_REQUEST: - case TYPES.UPDATE_CHECK_REQUEST_ON_MANUAL: { - autoUpdater.checkForUpdates() - .then((data) => { - const { version: nextVersion, releaseNotes } = data.updateInfo; - store.dispatch(updateCheckSuccess(nextVersion, releaseNotes)); - }) - .catch((err) => { - store.dispatch(updateCheckFailure(err)); - }); - break; - } - case TYPES.UPDATE_DOWNLOAD_REQUEST: { - openUpdateProgress(); - cancellationToken = new CancellationToken(); - autoUpdater.downloadUpdate(cancellationToken) - .then(() => { - store.dispatch(updateDownloadSuccess()); - }) - .catch((err) => { - store.dispatch(updateDownloadFailure(err)); - }); - break; - } - case TYPES.UPDATE_PROGRESS_CANCEL: { - cancellationToken.cancel(); - break; - } } }; diff --git a/app/main/controllers/search.js b/app/main/controllers/search.js index a584e9b6..872ab013 100644 --- a/app/main/controllers/search.js +++ b/app/main/controllers/search.js @@ -1,16 +1,11 @@ import { app, dialog } from 'electron'; import * as TYPES from 'actions/constant/actionTypes'; -import TrayBar from 'main/utils/menu/trayMenuBar'; import { LOGO_ICON_PATH } from 'config'; import i18n from 'constants/i18n'; const searchController = (action) => { const { type } = action; switch (type) { // eslint-disable-line default-case - case TYPES.SEARCH_WINDOW_HIDE: { - TrayBar.hideWindow(); - break; - } case TYPES.SEARCH_APP_QUIT: { const text = i18n().search; const options = { diff --git a/app/main/controllers/widget.js b/app/main/controllers/widget.js index 013648c0..7aa00664 100644 --- a/app/main/controllers/widget.js +++ b/app/main/controllers/widget.js @@ -1,9 +1,11 @@ -import React from 'react'; // eslint-disable-line import axios from 'axios'; -import makeWidget from 'main/utils/widget/makeWidget'; +import { + closeWidget, + openWidget, + setAlwaysOnTop, +} from 'main/utils/window/widget'; import store from 'store/storeMain'; import * as TYPES from 'actions/constant/actionTypes'; -import { openBrowserWindow } from 'actions/window'; import { widgetUpdateInfo, widgetUrlCheckRequest, @@ -12,7 +14,6 @@ import { import { isUrlCheckFetchSelector } from 'store/reducers/share/status/selectors'; import { modalOpen } from 'actions/modal'; import * as sharedId from 'store/reducers/share/identification/selectors'; -import * as identificationSelector from 'store/reducers/personal/identification/selectors'; import saveData from 'main/utils/disk/saveData'; const widgetController = (action, prev) => { @@ -20,54 +21,37 @@ const widgetController = (action, prev) => { switch (type) { // eslint-disable-line default-case case TYPES.WIDGET_MAKE_REQUEST: { const { id } = action.payload; - const widgetWin = makeWidget(id, undefined, true); - store.dispatch(openBrowserWindow(id, widgetWin)); + openWidget(id); saveData(); break; } case TYPES.WIDGET_OPEN: { const { id, isFocus } = action.payload; const byId = sharedId.widgetInfoByIdSelector(prev); - const item = byId.get(id); - - const winWidgets = identificationSelector.browserWindowByIdSelector(prev); - const widget = winWidgets.get(id); + const info = byId.get(id).toJS(); - if (widget) { - widget.show(); - } else { - const widgetWin = makeWidget(id, item.toJS(), isFocus); - - store.dispatch(openBrowserWindow(id, widgetWin)); - } + openWidget(id, info, isFocus); + saveData(); break; } case TYPES.WIDGET_CLOSE: case TYPES.WIDGET_DELETE: { const { id } = action.payload; - const winWidgets = identificationSelector.browserWindowByIdSelector(prev); - const widget = winWidgets.get(id); - if (widget) { - widget.close(); - } + closeWidget(id); break; } case TYPES.WIDGET_UPDATE_INFO: { const { id, info } = action.payload; - const winWidgets = identificationSelector.browserWindowByIdSelector(prev); - const widget = winWidgets.get(id); - if (widget) { - Object.keys(info).forEach((target) => { - switch (target) { // eslint-disable-line default-case - case 'isOnTop': { - widget.setAlwaysOnTop(info.isOnTop); - } + Object.keys(info).forEach((target) => { + switch (target) { // eslint-disable-line default-case + case 'isOnTop': { + setAlwaysOnTop(id, info.isOnTop); } - }); - } + } + }); break; } case TYPES.WIDGET_URL_VALID_CHECK: { diff --git a/app/main/utils/__tests__/handleIPC.spec.js b/app/main/utils/__tests__/handleIPC.spec.js new file mode 100644 index 00000000..cde27ffe --- /dev/null +++ b/app/main/utils/__tests__/handleIPC.spec.js @@ -0,0 +1,22 @@ +import { ipcMain } from 'electron'; +import * as pref from 'main/utils/window/preference'; +import handleIPC from '../handleIPC'; + +describe('test handleIPC', () => { + handleIPC(); + + it('should match number of whole handler', () => { + expect(ipcMain.on).toHaveBeenCalledTimes(1); + }); + + it('should call preference open', () => { + expect(ipcMain.on) + .toHaveBeenCalledWith('preference.open', expect.any(Function)); + + const openPreference = jest.spyOn(pref, 'openPreference'); + const cb = ipcMain.on.mock.calls.filter(i => i[0] === 'preference.open')[0][1]; + + cb(); + expect(openPreference).toHaveBeenCalledTimes(1); + }); +}); diff --git a/app/main/utils/__tests__/init.spec.js b/app/main/utils/__tests__/init.spec.js deleted file mode 100644 index 8e86ee00..00000000 --- a/app/main/utils/__tests__/init.spec.js +++ /dev/null @@ -1,100 +0,0 @@ -import { app, globalShortcut } from 'electron'; -import { autoUpdater } from 'electron-updater'; -import autoLaunch from 'main/utils/window/autoLaunch'; -import createMenu from 'main/utils/menu/createMenu'; -import openAllWidgetStatusOpen from 'main/utils/window/openAllWidgetStatusOpen'; -import store from 'store/storeMain'; -import subscribeActionMain from 'store/utils/subscribeActionMain'; -import TrayMenuBar from 'main/utils/menu/trayMenuBar'; - -import init from 'main/utils/init'; - -jest.mock('electron-updater'); -jest.mock('main/utils/window/autoLaunch'); -jest.mock('main/utils/update/autoUpdateConfig'); -jest.mock('main/utils/menu/createMenu'); -jest.mock('main/utils/window/openAllWidgetStatusOpen'); -jest.mock('store/utils/subscribeActionMain'); -jest.mock('main/utils/menu/trayMenuBar'); - -describe('test init function', () => { - init(); - - it('should call local module function', () => { - expect(subscribeActionMain).toHaveBeenCalledTimes(1); - expect(subscribeActionMain).toHaveBeenCalledWith(store); - expect(autoLaunch).toHaveBeenCalledTimes(1); - expect(autoLaunch).toHaveBeenCalledWith(); - expect(autoUpdater.checkForUpdatesAndNotify).toHaveBeenCalledTimes(1); - expect(createMenu).toHaveBeenCalledTimes(1); - expect(openAllWidgetStatusOpen).toHaveBeenCalledTimes(1); - expect(app.on).toHaveBeenCalledTimes(1); - }); - - describe.skip('should test globalShortcut register', () => { - TrayMenuBar.hideWindow = jest.fn(); - TrayMenuBar.showWindow = jest.fn(); - - beforeEach(() => { - TrayMenuBar.hideWindow.mockClear(); - TrayMenuBar.showWindow.mockClear(); - }); - - expect(globalShortcut.register) - .toHaveBeenCalledWith('Ctrl+Space', expect.any(Function)); - const cb = globalShortcut.register.mock.calls[0][1]; - - it('when TrayMenuBar.window === true and window.isFocused === true', () => { - const blur = jest.fn(); - TrayMenuBar.window = { - isFocused: () => true, - blur, - }; - - cb(); - - expect(TrayMenuBar.hideWindow).toHaveBeenCalledTimes(1); - expect(blur).toHaveBeenCalledTimes(1); - expect(TrayMenuBar.showWindow).toHaveBeenCalledTimes(0); - }); - - it('when TrayMenuBar.window === false or window.isFocused === false', () => { - TrayMenuBar.window = { - isFocused: () => false, - }; - - cb(); - - expect(TrayMenuBar.showWindow).toHaveBeenCalledTimes(1); - expect(TrayMenuBar.hideWindow).toHaveBeenCalledTimes(0); - }); - }); - - describe('should test globalShortcut register', () => { - TrayMenuBar.hideWindow = jest.fn(); - TrayMenuBar.showWindow = jest.fn(); - - beforeEach(() => { - TrayMenuBar.hideWindow.mockClear(); - TrayMenuBar.showWindow.mockClear(); - }); - - expect(app.on) - .toHaveBeenCalledWith('activate', expect.any(Function)); - const cb = app.on.mock.calls[0][1]; - - it('when isOpenWindow === true', () => { - cb(undefined, true); - - expect(TrayMenuBar.hideWindow).toHaveBeenCalledTimes(1); - expect(TrayMenuBar.showWindow).toHaveBeenCalledTimes(0); - }); - - it('when isOpenWindow === false', () => { - cb(undefined, false); - - expect(TrayMenuBar.showWindow).toHaveBeenCalledTimes(1); - expect(TrayMenuBar.hideWindow).toHaveBeenCalledTimes(0); - }); - }); -}); diff --git a/app/main/utils/__tests__/update/autoUpdateConfig.spec.js b/app/main/utils/__tests__/update/autoUpdateConfig.spec.js deleted file mode 100644 index 7fc428a5..00000000 --- a/app/main/utils/__tests__/update/autoUpdateConfig.spec.js +++ /dev/null @@ -1,160 +0,0 @@ -import { autoUpdater } from 'electron-updater'; -import store from 'store/storeMain'; -import autoUpdateConfig from 'main/utils/update/autoUpdateConfig'; -import openUpdateWindow from 'main/utils/update/openUpdateWindow'; -import * as configSelector from 'store/reducers/share/config/selectors'; -import * as statusSelector from 'store/reducers/share/status/selectors'; -import * as identificationSelector from 'store/reducers/share/identification/selectors'; -import * as actions from 'actions/update'; - -jest.mock('main/utils/update/openUpdateWindow'); - -describe('test autoUpdateConfig', () => { - const dispatch = jest - .spyOn(store, 'dispatch') - .mockImplementation(() => jest.fn()); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should check default', () => { - autoUpdateConfig(); - - expect(autoUpdater.autoDownload).toBe(false); - expect(autoUpdater.autoInstallOnAppQuit).toBe(true); - }); - - describe('should test autoUpdater on', () => { - it('should call autoUpdater on', () => { - autoUpdateConfig(); - - expect(autoUpdater.on).toHaveBeenCalledTimes(2); - expect(autoUpdater.on).toHaveBeenCalledWith( - 'download-progress', - expect.any(Function), - ); - expect(autoUpdater.on).toHaveBeenCalledWith( - 'update-available', - expect.any(Function), - ); - }); - - it('should check download-progress callback', () => { - jest.spyOn(identificationSelector, 'downloadProgressSelector') - .mockImplementation(() => 'mock-id'); - - autoUpdateConfig(); - - dispatch.mockClear(); - const cb = autoUpdater.on.mock.calls[0][1]; - cb({ a: 'aa' }); - - expect(dispatch).toHaveBeenCalledTimes(1); - expect(dispatch).toHaveBeenCalledWith( - actions.updateDownloadProgress({ a: 'aa' }, 'mock-id'), - ); - }); - - describe('should check update-available callback', () => { - it('when isDownloadUpdateWhenStart is true', () => { - jest.spyOn(statusSelector, 'isDownloadUpdateWhenStartSelector') - .mockImplementation(() => true); - - autoUpdateConfig(); - - dispatch.mockClear(); - const cb = autoUpdater.on.mock.calls[1][1]; - cb({ version: 'mock-version' }); - expect(dispatch).toHaveBeenCalledTimes(1); - expect(dispatch).toHaveBeenCalledWith( - actions.updateDownloadRequest(), - ); - }); - - it('when isUpdateCheckOnManual is true', () => { - jest.spyOn(statusSelector, 'isUpdateCheckOnManualSelector') - .mockImplementation(() => true); - - autoUpdateConfig(); - - const cb = autoUpdater.on.mock.calls[1][1]; - cb({ version: 'mock-version' }); - - expect(openUpdateWindow).toHaveBeenCalledTimes(1); - expect(openUpdateWindow).toHaveBeenCalledWith(); - }); - - it('when skipVersion !== nextVersion is true', () => { - jest.spyOn(statusSelector, 'isUpdateCheckOnManualSelector') - .mockImplementation(() => false); - jest.spyOn(statusSelector, 'isDownloadUpdateWhenStartSelector') - .mockImplementation(() => false); - jest.spyOn(configSelector, 'skipVersionSelector') - .mockImplementation(() => 'mock-version-2'); - - autoUpdateConfig(); - - const cb = autoUpdater.on.mock.calls[1][1]; - cb({ version: 'mock-version' }); - - expect(openUpdateWindow).toHaveBeenCalledTimes(1); - expect(openUpdateWindow).toHaveBeenCalledWith(); - }); - - it('when skipVersion === nextVersion is true', () => { - jest.spyOn(statusSelector, 'isUpdateCheckOnManualSelector') - .mockImplementation(() => false); - jest.spyOn(statusSelector, 'isDownloadUpdateWhenStartSelector') - .mockImplementation(() => false); - jest.spyOn(configSelector, 'skipVersionSelector') - .mockImplementation(() => 'mock-version'); - - autoUpdateConfig(); - - const cb = autoUpdater.on.mock.calls[1][1]; - cb({ version: 'mock-version' }); - - expect(openUpdateWindow).toHaveBeenCalledTimes(0); - }); - }); - }); - - describe('should test about auto checking', () => { - it('when isRestartAfterUpdate is true', () => { - jest.spyOn(statusSelector, 'isRestartAfterUpdateSelector') - .mockImplementation(() => true); - - autoUpdateConfig(); - - expect(dispatch).toHaveBeenCalledTimes(1); - expect(dispatch).toHaveBeenCalledWith(actions.updateInstallingDownloaded()); - }); - - it('when isInstalling is false and isDownloadUpdateWhenStart === true', () => { - jest.spyOn(statusSelector, 'isRestartAfterUpdateSelector') - .mockImplementation(() => false); - jest.spyOn(statusSelector, 'isDownloadUpdateWhenStartSelector') - .mockImplementation(() => true); - - autoUpdateConfig(); - - expect(dispatch).toHaveBeenCalledTimes(1); - expect(dispatch).toHaveBeenCalledWith(actions.updateCheckRequest()); - }); - - it('when isInstalling is false and isCheckUpdateWhenStart === true', () => { - jest.spyOn(statusSelector, 'isRestartAfterUpdateSelector') - .mockImplementation(() => false); - jest.spyOn(statusSelector, 'isDownloadUpdateWhenStartSelector') - .mockImplementation(() => false); - jest.spyOn(statusSelector, 'isCheckUpdateWhenStartSelector') - .mockImplementation(() => true); - - autoUpdateConfig(); - - expect(dispatch).toHaveBeenCalledTimes(1); - expect(dispatch).toHaveBeenCalledWith(actions.updateCheckRequest()); - }); - }); -}); diff --git a/app/main/utils/__tests__/update/openUpdateProgress.spec.js b/app/main/utils/__tests__/update/openUpdateProgress.spec.js deleted file mode 100644 index 293d479b..00000000 --- a/app/main/utils/__tests__/update/openUpdateProgress.spec.js +++ /dev/null @@ -1,49 +0,0 @@ -import { BrowserWindow } from 'electron'; -import uuid from 'uuid'; -import { UPDATE_PROGRESS_PATH } from 'config'; -import store from 'store/storeMain'; -import openUpdateProgress from 'main/utils/update/openUpdateProgress'; -import { updateProgressWindowOpen, updateProgressWindowClose } from 'actions/update'; - -jest.mock('uuid'); - -describe('test openUpdateProgress', () => { - const mockWindow = new BrowserWindow(); - jest.spyOn(uuid, 'v4').mockImplementation(() => 'mock-id'); - BrowserWindow.mockImplementation(() => mockWindow); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should handle store.dispatch', () => { - const dispatch = jest.spyOn(store, 'dispatch'); - openUpdateProgress(); - - expect(dispatch).toHaveBeenCalledTimes(1); - expect(dispatch).toHaveBeenCalledWith( - updateProgressWindowOpen('mock-id', mockWindow), - ); - }); - - it('should handle updateWindow.on', () => { - const dispatch = jest.spyOn(store, 'dispatch'); - openUpdateProgress(); - - expect(mockWindow.on).toHaveBeenCalledTimes(1); - expect(mockWindow.on).toHaveBeenCalledWith('closed', expect.any(Function)); - - dispatch.mockClear(); - mockWindow.on.mock.calls[0][1](); - - expect(dispatch).toHaveBeenCalledTimes(1); - expect(dispatch).toHaveBeenCalledWith(updateProgressWindowClose('mock-id')); - }); - - it('should call BrowserWindow.loadURL', () => { - openUpdateProgress(); - - expect(mockWindow.loadURL).toHaveBeenCalledTimes(1); - expect(mockWindow.loadURL).toHaveBeenCalledWith(UPDATE_PROGRESS_PATH); - }); -}); diff --git a/app/main/utils/__tests__/update/openUpdateWindow.spec.js b/app/main/utils/__tests__/update/openUpdateWindow.spec.js deleted file mode 100644 index 82243c6c..00000000 --- a/app/main/utils/__tests__/update/openUpdateWindow.spec.js +++ /dev/null @@ -1,19 +0,0 @@ -import { BrowserWindow } from 'electron'; -import { UPDATE_WINDOW_PATH } from 'config'; -import openUpdateWindow from 'main/utils/update/openUpdateWindow'; - -describe('test openUpdateWindow', () => { - const mockWindow = new BrowserWindow(); - BrowserWindow.mockImplementation(() => mockWindow); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should call BrowserWindow.loadURL', () => { - openUpdateWindow(); - - expect(mockWindow.loadURL).toHaveBeenCalledTimes(1); - expect(mockWindow.loadURL).toHaveBeenCalledWith(UPDATE_WINDOW_PATH); - }); -}); diff --git a/app/main/utils/__tests__/widget/makeWidget.spec.js b/app/main/utils/__tests__/widget/makeWidget.spec.js deleted file mode 100644 index 87839dec..00000000 --- a/app/main/utils/__tests__/widget/makeWidget.spec.js +++ /dev/null @@ -1,251 +0,0 @@ -import { BrowserWindow, dialog } from 'electron'; -import Immutable from 'immutable'; -import * as actions from 'actions/widget'; -import { BrowserWindow as MockBrowserWindow } from 'app/__mocks__/electron'; -import storeMock from 'store/storeMain'; -import { WIDGET_PATH, LOGO_ICON_PATH } from 'config'; -import * as updateWidgetContentBounds from 'main/utils/widget/updateWidgetContentBounds'; -import makeWidget from 'main/utils/widget/makeWidget'; - -jest.mock('fs'); -jest.mock('electron'); - -describe('test makeWidgetWindow', () => { - storeMock.dispatch = jest.fn(); - const mockInfo = { - name: 'mock-name', - url: 'mock-url', - isOpen: false, - }; - - const mock = new MockBrowserWindow({ - x: 10, - y: 20, - height: 100, - width: 200, - }); - BrowserWindow.mockImplementation(() => mock); - - makeWidget('mock-id', mockInfo); - - describe('test BrowserWindow.on', () => { - it('should call about widget.on', () => { - expect(mock.on).toHaveBeenCalledTimes(5); - expect(mock.on).toHaveBeenCalledWith('move', expect.any(Function)); - expect(mock.on).toHaveBeenCalledWith('resize', expect.any(Function)); - expect(mock.on).toHaveBeenCalledWith('close', expect.any(Function)); - expect(mock.on).toHaveBeenCalledWith('closed', expect.any(Function)); - expect(mock.on).toHaveBeenCalledWith('focus', expect.any(Function)); - }); - - it('should call callback of move event', () => { - storeMock.dispatch.mockClear(); - const mockUpdateWidgetContentBounds = jest.spyOn(updateWidgetContentBounds, 'default'); - const cb = mock.on.mock.calls[0][1]; - cb(); - - expect(mockUpdateWidgetContentBounds).toHaveBeenCalledTimes(1); - expect(mockUpdateWidgetContentBounds) - .toHaveBeenCalledWith('mock-id', expect.any(Object)); - }); - - it('should call callback of resize event', () => { - const mockUpdateWidgetContentBounds = jest.spyOn(updateWidgetContentBounds, 'default'); - const cb = mock.on.mock.calls[1][1]; - cb(); - - expect(mockUpdateWidgetContentBounds).toHaveBeenCalledTimes(2); - expect(mockUpdateWidgetContentBounds) - .toHaveBeenCalledWith('mock-id', expect.any(Object)); - }); - - describe('test callback of close event', () => { - const cb = mock.on.mock.calls[2][1]; - const preventDefault = jest.fn(); - const event = { - preventDefault, - }; - beforeEach(() => { - preventDefault.mockClear(); - dialog.showMessageBox.mockClear(); - mock.destroy.mockClear(); - }); - - it('when targetInfo doesn\'t exist ', () => { - storeMock.getState = () => Immutable.fromJS({ - share: { - identification: { - widgetInfoById: {}, - }, - }, - }); - cb(event); - - expect(preventDefault).toHaveBeenCalledTimes(0); - expect(dialog.showMessageBox).toHaveBeenCalledTimes(0); - }); - - it('when targetInfo exist and isMakeProgress === true', () => { - storeMock.getState = () => Immutable.fromJS({ - share: { - identification: { - widgetInfoById: { - 'mock-id': { - isMakeProgress: true, - }, - }, - }, - }, - }); - cb(event); - - expect(preventDefault).toHaveBeenCalledTimes(1); - expect(dialog.showMessageBox).toHaveBeenCalledTimes(1); - expect(dialog.showMessageBox).toHaveBeenCalledWith({ - type: 'info', - title: 'Close Widget', - message: 'Content of progress will be disappear. \nDo close making window?', - buttons: ['Ok', 'Cancel'], - icon: LOGO_ICON_PATH, - }, expect.any(Function)); - }); - - it('when targetInfo exist and isEditProgress === true', () => { - storeMock.getState = () => Immutable.fromJS({ - share: { - identification: { - widgetInfoById: { - 'mock-id': { - isEditProgress: true, - }, - }, - }, - }, - }); - cb(event); - - expect(preventDefault).toHaveBeenCalledTimes(1); - expect(dialog.showMessageBox).toHaveBeenCalledTimes(1); - expect(dialog.showMessageBox).toHaveBeenCalledWith({ - type: 'info', - title: 'Close Widget', - message: 'Content of progress will be disappear. \nDo close making window?', - buttons: ['Ok', 'Cancel'], - icon: LOGO_ICON_PATH, - }, expect.any(Function)); - }); - - describe('test dialog.showMessageBox callback', () => { - storeMock.getState = () => Immutable.fromJS({ - share: { - identification: { - widgetInfoById: { - 'mock-id': { - isEditProgress: true, - }, - }, - }, - }, - }); - cb(event); - - const dialogCb = dialog.showMessageBox.mock.calls[0][1]; - - it('when index === 0', () => { - dialogCb(0); - - expect(mock.destroy).toHaveBeenCalledTimes(1); - }); - - it('when index !== 0', () => { - dialogCb(1); - - expect(mock.destroy).toHaveBeenCalledTimes(0); - }); - }); - }); - - it('should call callback of closed event', () => { - storeMock.dispatch.mockClear(); - const cb = mock.on.mock.calls[3][1]; - cb(); - - expect(storeMock.dispatch).toHaveBeenCalledTimes(1); - expect(storeMock.dispatch).toHaveBeenCalledWith( - actions.widgetClosed('mock-id'), - ); - }); - - it('should call callback of focus event', () => { - storeMock.dispatch.mockClear(); - const cb = mock.on.mock.calls[4][1]; - cb(); - - expect(storeMock.dispatch).toHaveBeenCalledTimes(1); - expect(storeMock.dispatch) - .toHaveBeenCalledWith(actions.widgetFocus('mock-id')); - }); - }); - - describe('test BrowserWindow.webContents.on', () => { - it('should call webContents.on correctly', () => { - expect(mock.webContents.on).toHaveBeenCalledTimes(1); - expect(mock.webContents.on).toHaveBeenCalledWith( - 'did-finish-load', - expect.any(Function), - ); - }); - - it('should call webContents.on callback function', () => { - storeMock.dispatch.mockClear(); - const cb = mock.webContents.on.mock.calls[0][1]; - cb(); - - expect(storeMock.dispatch).toHaveBeenCalledTimes(1); - expect(storeMock.dispatch).toHaveBeenCalledWith( - actions.widgetAllocateIdTarget('mock-id'), - ); - }); - }); - - describe('test BrowserWindow.loadURL', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('when process.env.NODE_ENV === development', () => { - makeWidget('mock-id', mockInfo); - expect(mock.loadURL).toHaveBeenCalledTimes(1); - expect(mock.loadURL).toHaveBeenCalledWith(WIDGET_PATH); - }); - - // TODO test about process.env.NODE_ENV === 'production' - }); - - - describe('test BrowserWindow.once', () => { - it('should call BrowserWindow.once', () => { - expect(mock.once).toHaveBeenCalledTimes(1); - expect(mock.once).toHaveBeenCalledWith('ready-to-show', expect.any(Function)); - }); - - it('should call callback of BrowserWindow.once', () => { - const cb = mock.once.mock.calls[0][1]; - cb(); - - expect(mock.showInactive).toHaveBeenCalledTimes(1); - expect(mock.showInactive).toHaveBeenCalledWith(); - }); - - it('should call callback of BrowserWindow.once', () => { - mock.once.mockClear(); - makeWidget('mock-id', mockInfo, true); - - const cb = mock.once.mock.calls[0][1]; - cb(); - - expect(mock.show).toHaveBeenCalledTimes(1); - expect(mock.show).toHaveBeenCalledWith(); - }); - }); -}); diff --git a/app/main/utils/__tests__/window/openAllWidgetStatusOpen.spec.js b/app/main/utils/__tests__/window/openAllWidgetStatusOpen.spec.js index c394c55b..72c008ea 100644 --- a/app/main/utils/__tests__/window/openAllWidgetStatusOpen.spec.js +++ b/app/main/utils/__tests__/window/openAllWidgetStatusOpen.spec.js @@ -1,13 +1,12 @@ import { BrowserWindow } from 'electron'; import Immutable from 'immutable'; import store from 'store/storeMain'; -import { openBrowserWindow } from 'actions/window'; -import * as makeWidget from 'main/utils/widget/makeWidget'; +import * as widget from 'main/utils/window/widget'; import openAllWidgetStatusOpen from 'main/utils/window/openAllWidgetStatusOpen'; describe('test openAllWidgetStatusOpen', () => { it('should call openAllWidgetStatusOpen', () => { - const makeWidgetWindow = jest.spyOn(makeWidget, 'default'); + const makeWidgetWindow = jest.spyOn(widget, 'openWidget'); const mockWindow = new BrowserWindow(); store.getState = jest.fn(); store.dispatch = jest.fn(); @@ -18,16 +17,25 @@ describe('test openAllWidgetStatusOpen', () => { mock1: { a: 'aa', isOpen: true, + position: {}, + size: {}, }, mock2: { isOpen: false, + position: {}, + size: {}, }, mock3: { b: 'bb', isOpen: true, + position: {}, + size: {}, }, mock4: { isOpen: false, + + position: {}, + size: {}, }, }, }, @@ -40,18 +48,21 @@ describe('test openAllWidgetStatusOpen', () => { expect(makeWidgetWindow).toHaveBeenCalledTimes(2); expect(makeWidgetWindow.mock.calls[0]).toEqual([ 'mock1', - { isOpen: true, a: 'aa' }, + { + isOpen: true, + a: 'aa', + position: {}, + size: {}, + }, ]); expect(makeWidgetWindow.mock.calls[1]).toEqual([ 'mock3', - { isOpen: true, b: 'bb' }, + { + isOpen: true, + b: 'bb', + position: {}, + size: {}, + }, ]); - expect(store.dispatch).toHaveBeenCalledTimes(1); - expect(store.dispatch).toHaveBeenCalledWith( - openBrowserWindow( - ['mock1', 'mock3'], - [mockWindow, mockWindow], - ), - ); }); }); diff --git a/app/main/utils/__tests__/window/openPreference.spec.js b/app/main/utils/__tests__/window/openPreference.spec.js deleted file mode 100644 index 77c4003f..00000000 --- a/app/main/utils/__tests__/window/openPreference.spec.js +++ /dev/null @@ -1,112 +0,0 @@ -import { BrowserWindow } from 'electron'; -import Immutable from 'immutable'; -import uuid from 'uuid'; -import store from 'store/storeMain'; -import { PREFERENCE_PATH } from 'config'; -import openPreference from 'main/utils/window/openPreference'; -import { openBrowserWindow } from 'actions/window'; -import * as preferenceActions from 'actions/preference'; - -jest.mock('store/storeMain'); - -describe('test openPreference', () => { - const mockWindow = new BrowserWindow(); - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('when winId exist', () => { - const mockStore = Immutable.Map({ - share: Immutable.Map({ - identification: Immutable.Map({ - preference: 'mock-id', - }), - }), - personal: Immutable.Map({ - identification: Immutable.Map({ - browserWindowById: Immutable.Map({ - 'mock-id': mockWindow, - }), - }), - }), - }); - store.getState.mockImplementation(() => mockStore); - - openPreference(); - - expect(mockWindow.show).toHaveBeenCalledTimes(1); - expect(mockWindow.show).toHaveBeenCalledWith(); - }); - - describe('when winId doesn\'t exist', () => { - BrowserWindow.mockImplementation(() => mockWindow); - - const mockStore = Immutable.Map({ - share: Immutable.Map({ - identification: Immutable.Map({ - preference: null, - }), - }), - personal: Immutable.Map({ - identification: Immutable.Map({ - browserWindowById: Immutable.Map({ - 'mock-id': mockWindow, - }), - }), - }), - }); - uuid.v4 = jest.fn(() => 'mockId'); - - - it('should call BrowserWindow.loadURL', () => { - store.getState.mockImplementation(() => mockStore); - openPreference(); - - expect(mockWindow.loadURL).toHaveBeenCalledTimes(1); - expect(mockWindow.loadURL).toHaveBeenCalledWith(PREFERENCE_PATH); - }); - - it('should call BrowserWindow.on', () => { - openPreference(); - expect(mockWindow.on).toHaveBeenCalledTimes(1); - expect(mockWindow.on).toHaveBeenCalledWith( - 'close', - expect.any(Function), - ); - - const cb = mockWindow.on.mock.calls[0][1]; - cb(); - - expect(store.dispatch).toHaveBeenCalledTimes(3); - expect(store.dispatch).toHaveBeenCalledWith(preferenceActions.preferenceClose('mockId')); - }); - - describe('should call openDevTools if NODE_ENV', () => { - it('when NODE_ENV is not development', () => { - process.env.NODE_ENV = 'test'; - openPreference(); - - expect(mockWindow.webContents.openDevTools).toHaveBeenCalledTimes(0); - }); - - it('when NODE_ENV is development', () => { - process.env.NODE_ENV = 'development'; - openPreference(); - - expect(mockWindow.webContents.openDevTools).toHaveBeenCalledTimes(1); - }); - }); - - it('should call dispatch action when default', () => { - openPreference(); - - expect(store.dispatch).toHaveBeenCalledTimes(2); - expect(store.dispatch).toHaveBeenCalledWith( - preferenceActions.preferenceAllocateId('mockId'), - ); - expect(store.dispatch).toHaveBeenCalledWith( - openBrowserWindow('mockId', mockWindow), - ); - }); - }); -}); diff --git a/app/main/utils/__tests__/window/preference.spec.js b/app/main/utils/__tests__/window/preference.spec.js new file mode 100644 index 00000000..01601d1d --- /dev/null +++ b/app/main/utils/__tests__/window/preference.spec.js @@ -0,0 +1,46 @@ +import { BrowserWindow } from 'electron'; +import { PREFERENCE_PATH } from 'config'; +import { preference, openPreference } from 'main/utils/window/preference'; + + +describe('test window/preference', () => { + describe('when preference is null', () => { + afterAll(() => { + jest.clearAllMocks(); + }); + const mockWindow = new BrowserWindow(); + BrowserWindow.mockImplementationOnce(() => mockWindow); + + openPreference(); + + it('match preference', () => { + expect(preference).toEqual(mockWindow); + }); + + it('match loadURL', () => { + expect(preference.loadURL).toHaveBeenCalledTimes(1); + expect(preference.loadURL).toHaveBeenCalledWith(PREFERENCE_PATH); + }); + + it('match on.close', () => { + expect(mockWindow.on).toHaveBeenCalledTimes(1); + expect(mockWindow.on).toHaveBeenCalledWith('close', expect.any(Function)); + + expect(preference).toEqual(mockWindow); + const cb = mockWindow.on.mock.calls[0][1]; + + cb(); + expect(preference).toEqual(null); + }); + }); + + it('when preference is not null', () => { + const mockWindow = new BrowserWindow(); + BrowserWindow.mockImplementationOnce(() => mockWindow); + + openPreference(); + openPreference(); + + expect(preference.show).toHaveBeenCalledTimes(1); + }); +}); diff --git a/app/main/utils/handleIPC.js b/app/main/utils/handleIPC.js new file mode 100644 index 00000000..281915b2 --- /dev/null +++ b/app/main/utils/handleIPC.js @@ -0,0 +1,10 @@ +import { ipcMain } from 'electron'; +import { openPreference } from 'main/utils/window/preference'; + +function handleIPC() { + ipcMain.on('preference.open', () => { + openPreference(); + }); +} + +export default handleIPC; diff --git a/app/main/utils/init.js b/app/main/utils/init.js deleted file mode 100644 index 31b5d3a7..00000000 --- a/app/main/utils/init.js +++ /dev/null @@ -1,60 +0,0 @@ -import { - app, - BrowserView, - BrowserWindow, -} from 'electron'; -import { autoUpdater } from 'electron-updater'; -import autoLaunch from 'main/utils/window/autoLaunch'; -import createMenu from 'main/utils/menu/createMenu'; -import handlingSearchHotKey from 'main/utils/menu/handlingSearchHotKey'; -import openAllWidgetStatusOpen from 'main/utils/window/openAllWidgetStatusOpen'; -import store from 'store/storeMain'; -import subscribeActionMain from 'store/utils/subscribeActionMain'; -import { hotKeySearchWindowSelector } from 'store/reducers/share/config/selectors'; -import saveData from 'main/utils/disk/saveData'; -import TrayMenuBar from 'main/utils/menu/trayMenuBar'; -import { setInitialStore } from 'actions/setting'; -import e2eIpcHandler from '../../e2e-ipc-handler'; - -// save data about setting every 5 minutes. -const SAVE_SETTING_INTERVAL = 300000; - -function init() { - autoLaunch(); - subscribeActionMain(store); - createMenu(); - handlingSearchHotKey(hotKeySearchWindowSelector(store.getState())); - openAllWidgetStatusOpen(); - autoUpdater.checkForUpdatesAndNotify(); - setInterval(saveData, SAVE_SETTING_INTERVAL); - - app.on('activate', (e, isOpenWindow) => { - if (!isOpenWindow) { - TrayMenuBar.showWindow(); - } else { - TrayMenuBar.hideWindow(); - } - }); - - if (process.env.IS_DEVTOOLS) { - const devToolsWin = new BrowserWindow({ title: 'main process redux-devtools', width: 500, height: 500 }); - const devToolsView = new BrowserView(); - devToolsWin.setBrowserView(devToolsView); - devToolsView.setBounds({ - x: 0, - y: 0, - width: 500, - height: 480, - }); - devToolsView.setAutoResize({ width: true, height: true }); - devToolsView.webContents.loadURL('http://remotedev.io/local/'); - } - - store.dispatch(setInitialStore()); - - if (process.env.NODE_ENV === 'test') { - e2eIpcHandler(); - } -} - -export default init; diff --git a/app/main/utils/menu/createMenu.js b/app/main/utils/menu/createMenu.js index 2421f4aa..8b395579 100644 --- a/app/main/utils/menu/createMenu.js +++ b/app/main/utils/menu/createMenu.js @@ -2,7 +2,7 @@ import { app, Menu } from 'electron'; import os from 'os'; import store from 'store/storeMain'; import { widgetMakeRequest } from 'actions/widget'; -import openPreference from 'main/utils/window/openPreference'; +import { openPreference } from 'main/utils/window/preference'; import i18n from 'constants/i18n'; // reference by https://electronjs.org/docs/api/menu#examples diff --git a/app/main/utils/menu/handlingSearchHotKey.js b/app/main/utils/menu/handlingSearchHotKey.js index cb5c6e1c..447e3535 100644 --- a/app/main/utils/menu/handlingSearchHotKey.js +++ b/app/main/utils/menu/handlingSearchHotKey.js @@ -1,18 +1,11 @@ -import { remote, globalShortcut } from 'electron'; +import { globalShortcut } from 'electron'; +import { toggleSearch } from 'main/utils/window/search'; function handlingSearchHotKey(key) { - if (!remote) { - const TrayMenuBar = require('main/utils/menu/trayMenuBar').default; // eslint-disable-line global-require - globalShortcut.unregisterAll(); - globalShortcut.register(key, () => { - if (TrayMenuBar.window && TrayMenuBar.window.isFocused()) { - TrayMenuBar.window.blur(); // Need to reopen in windowOS - TrayMenuBar.hideWindow(); // Need to reopen in macOS - } else { - TrayMenuBar.showWindow(); - } - }); - } + globalShortcut.unregisterAll(); + globalShortcut.register(key, () => { + toggleSearch(); + }); } export default handlingSearchHotKey; diff --git a/app/main/utils/menu/trayMenuBar.js b/app/main/utils/menu/trayMenuBar.js deleted file mode 100644 index dec57f39..00000000 --- a/app/main/utils/menu/trayMenuBar.js +++ /dev/null @@ -1,61 +0,0 @@ -import { app, globalShortcut, Menu } from 'electron'; -import menuBar from 'menubar'; -import store from 'store/storeMain'; -import { - searchTrayClose, - searchTrayOpen, -} from 'actions/search'; -import { - SEARCH_PATH, - TRAY_ICON_PATH, -} from 'config'; -import i18n from 'constants/i18n'; -import openPreference from 'main/utils/window/openPreference'; - -const trayMenuBar = menuBar({ - icon: TRAY_ICON_PATH, - index: SEARCH_PATH, - showDockIcon: true, - tooltip: `oh-my-desk ${app.getVersion()}`, - fullscreenable: false, - resizable: false, - height: 445, -}); - -trayMenuBar.on('show', () => { - globalShortcut.register('Escape', () => { - if (trayMenuBar.window && trayMenuBar.window.isFocused()) { - trayMenuBar.window.blur(); // Need to reopen in windowOS - trayMenuBar.hideWindow(); // Need to reopen in macOS - } - }); - store.dispatch(searchTrayOpen()); -}); - -trayMenuBar.on('hide', () => { - store.dispatch(searchTrayClose()); - globalShortcut.unregister('Escape'); -}); - -trayMenuBar.on('after-close', () => { - store.dispatch(searchTrayClose()); - globalShortcut.unregister('Escape'); -}); - -trayMenuBar.on('ready', () => { - const { tray } = trayMenuBar; - const popUpContextMenuInTray = () => { - const text = i18n().menu; - - tray.popUpContextMenu(Menu.buildFromTemplate([ - { label: text.preference, click: openPreference }, - { type: 'separator' }, - { label: text.open, click: () => trayMenuBar.showWindow() }, - { label: text.quit, role: 'quit' }, - ])); - }; - - tray.on('right-click', popUpContextMenuInTray); -}); - -export default trayMenuBar; diff --git a/app/main/utils/update/autoUpdateConfig.js b/app/main/utils/update/autoUpdateConfig.js deleted file mode 100644 index 785a0cef..00000000 --- a/app/main/utils/update/autoUpdateConfig.js +++ /dev/null @@ -1,56 +0,0 @@ -import { autoUpdater } from 'electron-updater'; -import store from 'store/storeMain'; -import { - updateCheckRequest, - updateDownloadProgress, - updateDownloadRequest, - updateInstallingDownloaded, -} from 'actions/update'; -import { - isCheckUpdateWhenStartSelector, - isDownloadUpdateWhenStartSelector, - isRestartAfterUpdateSelector, - isUpdateCheckOnManualSelector, -} from 'store/reducers/share/status/selectors'; -import { skipVersionSelector } from 'store/reducers/share/config/selectors'; -import { downloadProgressSelector } from 'store/reducers/share/identification/selectors'; -import openUpdateWindow from 'main/utils/update/openUpdateWindow'; - - -function autoUpdateConfig() { - const isDownloadUpdateWhenStart = isDownloadUpdateWhenStartSelector(store.getState()); - const isCheckUpdateWhenStart = isCheckUpdateWhenStartSelector(store.getState()); - - autoUpdater.autoDownload = false; - autoUpdater.autoInstallOnAppQuit = true; - autoUpdater.on('download-progress', (downloadObj) => { - const id = downloadProgressSelector(store.getState()); - - store.dispatch(updateDownloadProgress(downloadObj, id)); - }); - - autoUpdater.on('update-available', (updateInfo) => { - const skipVersion = skipVersionSelector(store.getState()); - const nextVersion = updateInfo.version; - const isUpdateCheckOnManual = isUpdateCheckOnManualSelector(store.getState()); - - if (isUpdateCheckOnManual) { - openUpdateWindow(); - } else if (isDownloadUpdateWhenStart) { - store.dispatch(updateDownloadRequest()); - } else if (skipVersion !== nextVersion) { - openUpdateWindow(); - } - }); - - const isInstalling = isRestartAfterUpdateSelector(store.getState()); - if (!isInstalling) { - if (isDownloadUpdateWhenStart || isCheckUpdateWhenStart) { - store.dispatch(updateCheckRequest()); - } - } else { - store.dispatch(updateInstallingDownloaded()); - } -} - -export default autoUpdateConfig; diff --git a/app/main/utils/update/openUpdateProgress.js b/app/main/utils/update/openUpdateProgress.js deleted file mode 100644 index c56edd78..00000000 --- a/app/main/utils/update/openUpdateProgress.js +++ /dev/null @@ -1,31 +0,0 @@ -import { BrowserWindow } from 'electron'; -import { v4 } from 'uuid'; -import store from 'store/storeMain'; -import { UPDATE_PROGRESS_PATH } from 'config'; -import { - updateProgressWindowOpen, - updateProgressWindowClose, -} from 'actions/update'; - -const openUpdateWindow = () => { - const updateWindow = new BrowserWindow({ - width: 500, - height: 150, - frame: false, - show: true, - webPreferences: { - devTools: process.env.NODE_ENV === 'development', - }, - }); - const id = v4(); - - updateWindow.on('closed', () => { - store.dispatch(updateProgressWindowClose(id)); - }); - - store.dispatch(updateProgressWindowOpen(id, updateWindow)); - - updateWindow.loadURL(UPDATE_PROGRESS_PATH); -}; - -export default openUpdateWindow; diff --git a/app/main/utils/update/openUpdateWindow.js b/app/main/utils/update/openUpdateWindow.js deleted file mode 100644 index aaeb11a2..00000000 --- a/app/main/utils/update/openUpdateWindow.js +++ /dev/null @@ -1,18 +0,0 @@ -import { BrowserWindow } from 'electron'; -import { UPDATE_WINDOW_PATH } from 'config'; - -const openUpdateWindow = () => { - const updateWindow = new BrowserWindow({ - width: 700, - height: 400, - resizable: false, - show: true, - webPreferences: { - devTools: process.env.NODE_ENV === 'development', - }, - }); - - updateWindow.loadURL(UPDATE_WINDOW_PATH); -}; - -export default openUpdateWindow; diff --git a/app/main/utils/widget/makeWidget.js b/app/main/utils/widget/makeWidget.js deleted file mode 100644 index a5d0f5f2..00000000 --- a/app/main/utils/widget/makeWidget.js +++ /dev/null @@ -1,90 +0,0 @@ -import { BrowserWindow, dialog } from 'electron'; -import * as actions from 'actions/widget'; -import { widgetInfoByIdSelector } from 'store/reducers/share/identification/selectors'; -import store from 'store/storeMain'; -import createWidget from 'main/utils/widget/createWidget'; -import updateWidgetContentBounds from 'main/utils/widget/updateWidgetContentBounds'; -import { WIDGET_PATH, LOGO_ICON_PATH } from 'config'; -import i18n from 'constants/i18n'; - -const makeWidget = (id, info, isFocus) => { - const widgetInfo = createWidget(id, info); - const widget = new BrowserWindow({ - acceptFirstMouse: true, - title: widgetInfo.name, - x: widgetInfo.position.x, - y: widgetInfo.position.y, - width: widgetInfo.size.width, - height: widgetInfo.size.height, - alwaysOnTop: widgetInfo.isOnTop, - autoHideMenuBar: true, - titleBarStyle: 'default', - show: false, - frame: false, - minWidth: 200, - minHeight: 300, - }); - - widget.loadURL(WIDGET_PATH); - - widget.once('ready-to-show', () => { - if (isFocus) { - widget.show(); - } else { - widget.showInactive(); - } - }); - - widget.on('move', () => { - updateWidgetContentBounds(id, widget); - }); - - widget.on('resize', () => { - updateWidgetContentBounds(id, widget); - }); - - widget.on('close', (e) => { - const text = i18n().widget; - const targetInfo = widgetInfoByIdSelector(store.getState()).get(id); - if (!targetInfo) { - return; - } - const isMakeProgress = targetInfo.get('isMakeProgress'); - const isEditProgress = targetInfo.get('isEditProgress'); - - /** - * Confirm when widget is making or is Editing. - */ - if (isMakeProgress || isEditProgress) { - e.preventDefault(); - const options = { - type: 'info', - title: text.closeWidget, - message: text.closeMessage(targetInfo.get('name')), - buttons: [text.ok, text.cancel], - icon: LOGO_ICON_PATH, - }; - dialog.showMessageBox(options, (index) => { - if (index === 0) { // when click Yes button - widget.destroy(); - } - }); - } - }); - - widget.on('closed', () => { - store.dispatch(actions.widgetClosed(id)); - }); - - widget.on('focus', () => { - store.dispatch(actions.widgetFocus(id)); - }); - - widget.webContents.on('did-finish-load', () => { - store.dispatch(actions.widgetAllocateIdTarget(id)); - }); - - return widget; -}; - -export default makeWidget; diff --git a/app/main/utils/window/openAllWidgetStatusOpen.js b/app/main/utils/window/openAllWidgetStatusOpen.js index 52104294..821891f5 100644 --- a/app/main/utils/window/openAllWidgetStatusOpen.js +++ b/app/main/utils/window/openAllWidgetStatusOpen.js @@ -1,18 +1,14 @@ -import makeWidget from 'main/utils/widget/makeWidget'; +import { openWidget } from 'main/utils/window/widget'; import * as sharedId from 'store/reducers/share/identification/selectors'; -import { openBrowserWindow } from 'actions/window'; import store from 'store/storeMain'; const openAllWidgetStatusOpen = () => { const byIdIsOpenIsTrue = sharedId.getByIdsIsOpenIsTrue(store.getState()); const keyArray = byIdIsOpenIsTrue.keySeq().toArray(); - const arr = []; keyArray.forEach((item) => { - arr.push(makeWidget(item, byIdIsOpenIsTrue.get(item).toJS())); + openWidget(item, byIdIsOpenIsTrue.get(item).toJS()); }); - - store.dispatch(openBrowserWindow(keyArray, arr)); }; export default openAllWidgetStatusOpen; diff --git a/app/main/utils/window/openPreference.js b/app/main/utils/window/openPreference.js deleted file mode 100644 index e7e44f16..00000000 --- a/app/main/utils/window/openPreference.js +++ /dev/null @@ -1,48 +0,0 @@ -import { BrowserWindow } from 'electron'; -import { v4 } from 'uuid'; -import store from 'store/storeMain'; -import * as identificationSelector from 'store/reducers/share/identification/selectors'; -import * as identification from 'store/reducers/personal/identification/selectors'; -import { openBrowserWindow } from 'actions/window'; -import * as preferenceAction from 'actions/preference'; -import { PREFERENCE_PATH } from 'config'; - -const openPreference = () => { - const winId = identificationSelector.preferenceSelector(store.getState()); - let winPreference; - - if (winId) { - const browserWindowById = identification.browserWindowByIdSelector(store.getState()); - winPreference = browserWindowById.get(winId); - winPreference.show(); - return; - } - - winPreference = new BrowserWindow({ - acceptFirstMouse: true, - width: 500, - height: 450, - resizable: false, - webPreferences: { - devTools: process.env.NODE_ENV === 'development', - }, - }); - - winPreference.loadURL(PREFERENCE_PATH); - - if (process.env.NODE_ENV === 'development') { - winPreference.webContents.openDevTools(); - } - - const id = v4(); - - winPreference.on('close', () => { - store.dispatch(preferenceAction.preferenceClose(id)); - }); - - - store.dispatch(preferenceAction.preferenceAllocateId(id)); - store.dispatch(openBrowserWindow(id, winPreference)); -}; - -export default openPreference; diff --git a/app/main/utils/window/openReduxDevTools.js b/app/main/utils/window/openReduxDevTools.js new file mode 100644 index 00000000..f504f435 --- /dev/null +++ b/app/main/utils/window/openReduxDevTools.js @@ -0,0 +1,24 @@ +import { BrowserView, BrowserWindow } from 'electron'; + +/** + * For main process redux-store, pop up redux-devtools window. + */ +function openReduxDevTools() { + if (!process.env.IS_DEVTOOLS) { + return; + } + + const devToolsWin = new BrowserWindow({ title: 'main process redux-devtools', width: 500, height: 500 }); + const devToolsView = new BrowserView(); + devToolsWin.setBrowserView(devToolsView); + devToolsView.setBounds({ + x: 0, + y: 0, + width: 500, + height: 480, + }); + devToolsView.setAutoResize({ width: true, height: true }); + devToolsView.webContents.loadURL('http://remotedev.io/local/'); +} + +export default openReduxDevTools; diff --git a/app/main/utils/window/preference.js b/app/main/utils/window/preference.js new file mode 100644 index 00000000..92864b55 --- /dev/null +++ b/app/main/utils/window/preference.js @@ -0,0 +1,25 @@ +import { BrowserWindow } from 'electron'; +import { PREFERENCE_PATH } from 'config'; + +export let preference = null; // eslint-disable-line import/no-mutable-exports + +export function openPreference() { + if (preference) { + preference.show(); + } else { + preference = new BrowserWindow({ + acceptFirstMouse: true, + width: 500, + height: 450, + resizable: false, + webPreferences: { + devTools: process.env.NODE_ENV === 'development', + }, + }); + + preference.loadURL(PREFERENCE_PATH); + preference.on('close', () => { + preference = null; + }); + } +} diff --git a/app/main/utils/window/search.js b/app/main/utils/window/search.js new file mode 100644 index 00000000..b65c1b15 --- /dev/null +++ b/app/main/utils/window/search.js @@ -0,0 +1,64 @@ +import menuBar from 'menubar'; +import { APP_VERSION, SEARCH_PATH, TRAY_ICON_PATH } from 'config'; +import { globalShortcut, Menu } from 'electron'; +import i18n from 'constants/i18n'; +import { openPreference } from 'main/utils/window/preference'; + +export const search = menuBar({ + icon: TRAY_ICON_PATH, + index: SEARCH_PATH, + showDockIcon: true, + tooltip: `oh-my-desk ${APP_VERSION}`, + fullscreenable: false, + resizable: false, + height: 460, +}); + +export function showSearch() { + search.showWindow(); +} + +export function hideSearch() { + /** + * To hide tray window of menubar(Tray window), + * Need to below both logic. + * + * windowOS need to `search.window.blur()` to hide menubar. + * macOS need to `search.hideWindow()`. + */ + search.window.blur(); // Need to reopen in windowOS + search.hideWindow(); // Need to reopen in macOS +} + +export function toggleSearch() { + if (search.window && search.window.isFocused()) { + hideSearch(); + } else { + showSearch(); + } +} + +export function contextMenuOnTray() { + const { tray } = search; + const text = i18n().menu; + + tray.popUpContextMenu(Menu.buildFromTemplate([ + { label: text.preference, click: openPreference }, + { type: 'separator' }, + { label: text.open, click: () => tray.showWindow() }, + { label: text.quit, role: 'quit' }, + ])); +} + +search.on('show', () => { + globalShortcut.register('Escape', hideSearch); + search.window.webContents.send('tray.show'); +}); +search.on('hide', () => { + globalShortcut.unregister('Escape'); + search.window.webContents.send('tray.hide'); +}); +search.on('after-close', () => globalShortcut.unregister('Escape')); +search.on('ready', () => { + search.tray.on('right-click', contextMenuOnTray); +}); diff --git a/app/main/utils/window/widget.js b/app/main/utils/window/widget.js new file mode 100644 index 00000000..c4be6aa6 --- /dev/null +++ b/app/main/utils/window/widget.js @@ -0,0 +1,140 @@ +import { BrowserWindow, dialog } from 'electron'; +import debounce from 'debounce'; +import { LOGO_ICON_PATH, WIDGET_PATH } from 'config'; +import store from 'store/storeMain'; +import createWidget from 'main/utils/widget/createWidget'; +import updateWidgetContentBounds from 'main/utils/widget/updateWidgetContentBounds'; +import i18n from 'constants/i18n'; +import { widgetInfoByIdSelector } from 'store/reducers/share/identification/selectors'; +import * as actions from 'actions/widget'; + +class WidgetManager { + constructor() { + this.window = {}; + } + + addWindow = (id, win) => { + this.window[id] = win; + }; + + deleteWindow = (id) => { + delete this.window[id]; + }; + + getWindow = (id) => { + const info = widgetInfoByIdSelector(store.getState()).get(id).toJS(); + + return { + win: this.window[id], + ...info, + }; + }; + + isExist = id => !!this.window[id]; +} + +export const manager = new WidgetManager(); + +function confirmToClose(info) { + const text = i18n().widget; + + const options = { + type: 'info', + title: text.closeWidget, + message: text.closeMessage(info.name), + buttons: [text.ok, text.cancel], + icon: LOGO_ICON_PATH, + }; + dialog.showMessageBox(options, (index) => { + if (index === 0) { // when click Yes button + info.win.destroy(); + } + }); +} + +export function openWidget(id, info = createWidget(), isFocus = true) { + if (manager.isExist(id)) { + const { win } = manager.getWindow(id); + + win.show(); + return; + } + + const { + name, + position, + size, + isOnTop, + } = info; + const { x, y } = position; + const { height, width } = size; + + const widget = new BrowserWindow({ + acceptFirstMouse: true, + title: name, + x, + y, + width, + height, + alwaysOnTop: isOnTop, + autoHideMenuBar: true, + show: false, + frame: false, + minWidth: 200, + minHeight: 300, + }); + manager.addWindow(id, widget); + + widget.loadURL(WIDGET_PATH); + widget.once('ready-to-show', () => { + if (isFocus) { + widget.show(); + } else { + widget.showInactive(); + } + }); + widget.on('move', + debounce(() => updateWidgetContentBounds(id, widget), 1000, true)); + widget.on('resize', + debounce(() => updateWidgetContentBounds(id, widget), 1000, true)); + widget.on('close', (e) => { + const targetInfo = manager.getWindow(id); + const { + isMakeProgress, + isEditProgress, + } = targetInfo; + + /** + * Confirm when widget is making or is Editing. + */ + if (isMakeProgress || isEditProgress) { + e.preventDefault(); + confirmToClose(targetInfo); + } + }); + widget.on('closed', () => { + store.dispatch(actions.widgetClosed(id)); + manager.deleteWindow(id); + }); + widget.on('focus', () => store.dispatch(actions.widgetFocus(id))); + widget.webContents.on('did-finish-load', + () => { + store.dispatch(actions.widgetAllocateIdTarget(id)); + }); +} + +export function closeWidget(id) { + if (manager.isExist(id)) { + const { win } = manager.getWindow(id); + + win.close(); + } +} + +export function setAlwaysOnTop(id, bool) { + if (manager.isExist(id)) { + const { win } = manager.getWindow(id); + + win.setAlwaysOnTop(bool); + } +} diff --git a/app/renderer/pages/preference/components/Update/Update.scss b/app/renderer/pages/preference/components/Update/Update.scss deleted file mode 100644 index a53c699b..00000000 --- a/app/renderer/pages/preference/components/Update/Update.scss +++ /dev/null @@ -1,22 +0,0 @@ -.Update { - margin: 15px; -} - -.Update__title { - font-weight: 600; - font-size: 14px; -} - -.Update__app-name { - display: block; - color: #507deb; - text-decoration: underline; - margin: 10px; -} - -.Update__list { - display: flex; - padding: 10px; - background: white; - font-size: 14px; -} diff --git a/app/renderer/pages/preference/components/Update/Update.spec.jsx b/app/renderer/pages/preference/components/Update/Update.spec.jsx deleted file mode 100644 index 1d718813..00000000 --- a/app/renderer/pages/preference/components/Update/Update.spec.jsx +++ /dev/null @@ -1,46 +0,0 @@ -import React from 'react'; -import { shallow } from 'enzyme'; -import { shell } from 'electron'; - -import Update from '.'; - -describe('', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should match to snapshot when render default', () => { - const wrapper = shallow(); - - expect(wrapper).toMatchSnapshot(); - }); - - it('should test static handleOpenLink', () => { - shell.openExternal = jest.fn(); - - Update.handleOpenLink(); - - expect(shell.openExternal).toHaveBeenCalledTimes(1); - expect(shell.openExternal).toHaveBeenCalledWith('https://github.com/AhKi/oh-my-desk'); - }); - - describe('should call handleUpdateCheck', () => { - const onUpdateCheckOnManual = jest.fn(); - const wrapper = shallow(); - - it('when props isUpdateCheckFetch === true', () => { - wrapper.setProps({ isUpdateCheckFetch: true }); - - wrapper.instance().handleUpdateCheck(); - expect(onUpdateCheckOnManual).toHaveBeenCalledTimes(0); - }); - - it('when props isUpdateCheckFetch === false', () => { - wrapper.setProps({ isUpdateCheckFetch: false }); - - wrapper.instance().handleUpdateCheck(); - expect(onUpdateCheckOnManual).toHaveBeenCalledTimes(1); - expect(onUpdateCheckOnManual).toHaveBeenCalledWith(); - }); - }); -}); diff --git a/app/renderer/pages/preference/components/Update/__snapshots__/Update.spec.jsx.snap b/app/renderer/pages/preference/components/Update/__snapshots__/Update.spec.jsx.snap deleted file mode 100644 index e553d90c..00000000 --- a/app/renderer/pages/preference/components/Update/__snapshots__/Update.spec.jsx.snap +++ /dev/null @@ -1,28 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[` should match to snapshot when render default 1`] = ` -
-

- App Version -

- - -
-`; diff --git a/app/renderer/pages/preference/components/Update/index.jsx b/app/renderer/pages/preference/components/Update/index.jsx deleted file mode 100644 index b23dd184..00000000 --- a/app/renderer/pages/preference/components/Update/index.jsx +++ /dev/null @@ -1,67 +0,0 @@ -import React from 'react'; -import { remote, shell } from 'electron'; -import PropTypes from 'prop-types'; -import i18n from 'constants/i18n'; -import './Update.scss'; - -const propTypes = { - isUpdateCheckFetch: PropTypes.bool, - onUpdateCheckOnManual: PropTypes.func, -}; -const defaultProps = { - isUpdateCheckFetch: false, - onUpdateCheckOnManual() {}, -}; - -class Update extends React.Component { - static handleOpenLink() { - shell.openExternal('https://github.com/AhKi/oh-my-desk'); - } - - constructor(props) { - super(props); - this.handleUpdateCheck = this.handleUpdateCheck.bind(this); - } - - handleUpdateCheck() { - const { isUpdateCheckFetch, onUpdateCheckOnManual } = this.props; - - if (!isUpdateCheckFetch) { - onUpdateCheckOnManual(); - } - } - - - render() { - const text = i18n().preference; - const appName = remote.app.getName(); - const appVersion = remote.app.getVersion(); - const { isUpdateCheckFetch } = this.props; - - return ( -
-

{text.appVersion}

- - -
- ); - } -} - -Update.propTypes = propTypes; -Update.defaultProps = defaultProps; - -export default Update; diff --git a/app/renderer/pages/preference/containers/UpdateContainer.jsx b/app/renderer/pages/preference/containers/UpdateContainer.jsx deleted file mode 100644 index cace9315..00000000 --- a/app/renderer/pages/preference/containers/UpdateContainer.jsx +++ /dev/null @@ -1,14 +0,0 @@ -import { connect } from 'react-redux'; -import { updateCheckRequestOnManual } from 'actions/update'; -import { isUpdateCheckFetchSelector } from 'store/reducers/share/status/selectors'; -import Update from '../components/Update'; - -const mapStateToProps = state => ({ - isUpdateCheckFetch: isUpdateCheckFetchSelector(state), -}); - -const mapDispatchToProps = { - onUpdateCheckOnManual: updateCheckRequestOnManual, -}; - -export default connect(mapStateToProps, mapDispatchToProps)(Update); diff --git a/app/renderer/pages/search/components/SearchInput/SearchInput.spec.jsx b/app/renderer/pages/search/components/SearchInput/SearchInput.spec.jsx index 0ebe681f..3071ee15 100644 --- a/app/renderer/pages/search/components/SearchInput/SearchInput.spec.jsx +++ b/app/renderer/pages/search/components/SearchInput/SearchInput.spec.jsx @@ -1,5 +1,6 @@ import React from 'react'; import { mount } from 'enzyme'; +import { ipcRenderer } from 'electron'; import SearchInput from '.'; describe('Test SearchInput Component', () => { @@ -19,49 +20,43 @@ describe('Test SearchInput Component', () => { expect(wrapper).toMatchSnapshot(); }); - it('should test componentDidMount', () => { + describe('should test componentDidMount', () => { const componentDidMount = jest.spyOn(SearchInput.prototype, 'componentDidMount'); - const wrapper = mount(); - const inputRef = wrapper.instance().inputRef.current; - expect(componentDidMount).toHaveBeenCalledTimes(1); - expect(document.activeElement).toEqual(inputRef); - }); + it('should focus input element', () => { + const wrapper = mount(); + const inputRef = wrapper.instance().inputRef.current; - describe('should test componentDidUpdate', () => { - const componentDidUpdate = jest.spyOn(SearchInput.prototype, 'componentDidUpdate'); - const wrapper = mount(); - const inputRef = wrapper.instance().inputRef.current; - inputRef.focus = jest.fn(); + expect(componentDidMount).toHaveBeenCalledTimes(1); + expect(document.activeElement).toEqual(inputRef); + }); - it('when isTrayOpen change from false to true', () => { - expect(wrapper.instance().props.isTrayOpen).toBe(false); - wrapper.setProps({ - isTrayOpen: true, - }); + it('should match number of event that handled IPC', () => { + mount(); - expect(componentDidUpdate).toHaveBeenCalledTimes(1); - expect(inputRef.focus).toHaveBeenCalledTimes(1); + expect(ipcRenderer.on).toHaveBeenCalledTimes(2); }); - it('when isTrayOpen change from false to true', () => { - expect(wrapper.instance().props.isTrayOpen).toBe(true); - wrapper.setProps({ - isTrayOpen: false, + describe('should test IPC callback function', () => { + it('when tray.show', () => { + const wrapper = mount(); + const inputRef = wrapper.instance().inputRef.current; + const showCb = ipcRenderer.on.mock.calls.filter(i => i[0] === 'tray.show')[0][1]; + + inputRef.blur(); + expect(document.activeElement).not.toEqual(inputRef); + showCb(); + expect(document.activeElement).toEqual(inputRef); }); - expect(componentDidUpdate).toHaveBeenCalledTimes(1); - expect(inputRef.focus).toHaveBeenCalledTimes(1); - }); + it('when tray.hide', () => { + const onChangeKeyword = jest.fn(); + mount(); + const hideCb = ipcRenderer.on.mock.calls.filter(i => i[0] === 'tray.hide')[0][1]; + hideCb(); - it('when isTrayOpen doesn\'t change', () => { - expect(wrapper.instance().props.isTrayOpen).toBe(false); - wrapper.setProps({ - isTrayOpen: false, + expect(onChangeKeyword).toHaveBeenNthCalledWith(1, ''); }); - - expect(componentDidUpdate).toHaveBeenCalledTimes(1); - expect(inputRef.focus).toHaveBeenCalledTimes(0); }); }); diff --git a/app/renderer/pages/search/components/SearchInput/__snapshots__/SearchInput.spec.jsx.snap b/app/renderer/pages/search/components/SearchInput/__snapshots__/SearchInput.spec.jsx.snap index 6041e3f8..d3ab2fd1 100644 --- a/app/renderer/pages/search/components/SearchInput/__snapshots__/SearchInput.spec.jsx.snap +++ b/app/renderer/pages/search/components/SearchInput/__snapshots__/SearchInput.spec.jsx.snap @@ -3,7 +3,6 @@ exports[`Test SearchInput Component should match to snapshot 1`] = ` @@ -29,7 +28,6 @@ exports[`Test SearchInput Component should match to snapshot 1`] = ` exports[`Test SearchInput Component should match to snapshot when filter !== ALL 1`] = ` diff --git a/app/renderer/pages/search/components/SearchInput/index.jsx b/app/renderer/pages/search/components/SearchInput/index.jsx index f3a43205..4619c533 100644 --- a/app/renderer/pages/search/components/SearchInput/index.jsx +++ b/app/renderer/pages/search/components/SearchInput/index.jsx @@ -1,4 +1,5 @@ import React from 'react'; +import { ipcRenderer } from 'electron'; import i18n from 'constants/i18n'; import PropTypes from 'prop-types'; import searchIcon from 'assets/icon/icon-magnifying.svg'; @@ -7,13 +8,11 @@ import './SearchInput.scss'; const propTypes = { filter: PropTypes.string, keyword: PropTypes.string, - isTrayOpen: PropTypes.bool, onChangeKeyword: PropTypes.func, }; const defaultProps = { filter: 'ALL', keyword: '', - isTrayOpen: false, onChangeKeyword() {}, }; @@ -26,14 +25,12 @@ class SearchInput extends React.Component { componentDidMount() { this.inputRef.current.focus(); - } - - componentDidUpdate(prevProps) { - const { isTrayOpen } = this.props; - - if (prevProps.isTrayOpen !== isTrayOpen) { + ipcRenderer.on('tray.show', () => { this.inputRef.current.focus(); - } + }); + ipcRenderer.on('tray.hide', () => { + this.props.onChangeKeyword(''); + }); } handleChangeKeyword(e) { diff --git a/app/renderer/pages/search/components/SearchItem/SearchItem.spec.jsx b/app/renderer/pages/search/components/SearchItem/SearchItem.spec.jsx index 9cc8610e..469c96c5 100644 --- a/app/renderer/pages/search/components/SearchItem/SearchItem.spec.jsx +++ b/app/renderer/pages/search/components/SearchItem/SearchItem.spec.jsx @@ -148,4 +148,49 @@ describe('Test SearchItem Component', () => { favorites: true, }); }); + + describe('should call handleFocusWidget', () => { + const onShowWidget = jest.fn(); + const event = { + preventDefault: jest.fn(), + }; + + it('when item.isOpen === true', () => { + const wrapper = shallow( + , + ); + const btn = wrapper.find('.SearchItem__Btn'); + + expect(wrapper.instance().props.item.isOpen).toBe(true); + btn.simulate('click', event); + + expect(onShowWidget).toHaveBeenNthCalledWith(1, 'mock-id'); + expect(event.preventDefault).toHaveBeenCalledTimes(1); + }); + + it('when item.isOpen === false', () => { + const wrapper = shallow( + , + ); + const btn = wrapper.find('.SearchItem__Btn'); + + expect(wrapper.instance().props.item.isOpen).toBe(false); + btn.simulate('click', event); + + expect(onShowWidget).toHaveBeenCalledTimes(0); + expect(event.preventDefault).toHaveBeenCalledTimes(0); + }); + }); }); diff --git a/app/renderer/pages/search/components/SearchList/SearchList.spec.jsx b/app/renderer/pages/search/components/SearchList/SearchList.spec.jsx index 85461b0f..c08c165a 100644 --- a/app/renderer/pages/search/components/SearchList/SearchList.spec.jsx +++ b/app/renderer/pages/search/components/SearchList/SearchList.spec.jsx @@ -51,14 +51,12 @@ describe('Test SearchList Component', () => { }; const onSelectDecrease = jest.fn(); const onSelectIncrease = jest.fn(); - const onHideWindow = jest.fn(); const onShowWidget = jest.fn(); const wrapper = shallow( , ); @@ -86,8 +84,6 @@ describe('Test SearchList Component', () => { expect(onShowWidget).toHaveBeenCalledTimes(1); expect(onShowWidget).toHaveBeenCalledWith('mock1', true); - expect(onHideWindow).toHaveBeenCalledTimes(1); - expect(onHideWindow).toHaveBeenCalledWith(); }); }); }); diff --git a/app/renderer/pages/search/components/SearchList/index.jsx b/app/renderer/pages/search/components/SearchList/index.jsx index 5d56ca99..800aa11a 100644 --- a/app/renderer/pages/search/components/SearchList/index.jsx +++ b/app/renderer/pages/search/components/SearchList/index.jsx @@ -8,7 +8,6 @@ const propTypes = { list: PropTypes.arrayOf(PropTypes.object), // eslint-disable-line no-unused-prop-types selectedIndex: PropTypes.number, onCloseWidget: PropTypes.func, - onHideWindow: PropTypes.func, onSelectIncrease: PropTypes.func, onSelectDecrease: PropTypes.func, onShowWidget: PropTypes.func, @@ -20,7 +19,6 @@ const defaultProps = { list: [], keyword: '', onCloseWidget() {}, - onHideWindow() {}, onSelectIncrease() {}, onSelectDecrease() {}, onShowWidget() {}, @@ -74,7 +72,6 @@ class SearchList extends React.Component { const { list, selectedIndex, - onHideWindow, onShowWidget, onSelectIncrease, onSelectDecrease, @@ -92,7 +89,6 @@ class SearchList extends React.Component { if (e.key === 'Enter') { e.preventDefault(); - onHideWindow(); onShowWidget(list[selectedIndex].id, true); } } diff --git a/app/renderer/pages/search/components/SearchMenu/SearchMenu.spec.jsx b/app/renderer/pages/search/components/SearchMenu/SearchMenu.spec.jsx index 77db3d7a..6e5131b9 100644 --- a/app/renderer/pages/search/components/SearchMenu/SearchMenu.spec.jsx +++ b/app/renderer/pages/search/components/SearchMenu/SearchMenu.spec.jsx @@ -1,4 +1,5 @@ import React from 'react'; +import { ipcRenderer } from 'electron'; import { shallow } from 'enzyme'; import SearchMenu from '.'; @@ -80,4 +81,24 @@ describe('Test SearchMenu Component', () => { expect(onSetFilter).toHaveBeenCalledWith('FAVORITES'); }); }); + + it('should call ipcRenderer.send when click data-test-id="menu-setting"', () => { + const wrapper = shallow(); + const btn = wrapper.find('[data-test-id="menu-setting"]'); + + btn.simulate('click'); + + expect(ipcRenderer.send).toHaveBeenCalledTimes(1); + expect(ipcRenderer.send).toHaveBeenCalledWith('preference.open'); + }); + + it('should call props.onMakeWidgetRequest when click data-test-id="menu-new-widget"', () => { + const onMakeWidgetRequest = jest.fn(); + const wrapper = shallow(); + const btn = wrapper.find('[data-test-id="menu-new-widget"]'); + + btn.simulate('click'); + + expect(onMakeWidgetRequest).toHaveBeenCalledTimes(1); + }); }); diff --git a/app/renderer/pages/search/components/SearchMenu/index.jsx b/app/renderer/pages/search/components/SearchMenu/index.jsx index 85b84964..be7b7c19 100644 --- a/app/renderer/pages/search/components/SearchMenu/index.jsx +++ b/app/renderer/pages/search/components/SearchMenu/index.jsx @@ -1,5 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { ipcRenderer } from 'electron'; import cx from 'classnames'; import icon from 'assets/oh-my-desk-icon.png'; import addIcon from 'assets/icon/icon-plus-white.svg'; @@ -13,14 +14,12 @@ import './SearchMenu.scss'; const propTypes = { filter: PropTypes.string, onMakeWidgetRequest: PropTypes.func, - onOpenPreference: PropTypes.func, onQuitApp: PropTypes.func, onSetFilter: PropTypes.func, }; const defaultProps = { filter: 'ALL', onMakeWidgetRequest() {}, - onOpenPreference() {}, onQuitApp() {}, onSetFilter() {}, }; @@ -57,7 +56,7 @@ class SearchMenu extends React.Component { render() { const text = i18n().search; - const { filter, onOpenPreference, onQuitApp } = this.props; + const { filter, onQuitApp } = this.props; const allMenuClassName = cx('SearchMenu__Btn', { 'SearchMenu__Btn--active': filter === 'ALL', }); @@ -123,7 +122,7 @@ class SearchMenu extends React.Component { className="SearchMenu__Btn" data-test-id="menu-setting" type="button" - onClick={onOpenPreference} + onClick={() => ipcRenderer.send('preference.open')} > ({ filter: filterSelector(state), - isTrayOpen: isTrayOpenSelector(state), keyword: keywordSelector(state), }); const mapDispatchToProps = { diff --git a/app/renderer/pages/search/containers/SearchListContainer.jsx b/app/renderer/pages/search/containers/SearchListContainer.jsx index 02277cea..493b85ff 100644 --- a/app/renderer/pages/search/containers/SearchListContainer.jsx +++ b/app/renderer/pages/search/containers/SearchListContainer.jsx @@ -13,7 +13,6 @@ import { import { searchWidgetSelectIncrease, searchWidgetSelectDecrease, - searchWindowHide, } from 'actions/search'; import SearchList from '../components/SearchList'; @@ -25,7 +24,6 @@ const mapStateToProps = state => ({ const mapDispatchToProps = { onCloseWidget: widgetClose, - onHideWindow: searchWindowHide, onSelectIncrease: searchWidgetSelectIncrease, onSelectDecrease: searchWidgetSelectDecrease, onShowWidget: widgetOpen, diff --git a/app/renderer/pages/search/containers/SearchMenuContainer.jsx b/app/renderer/pages/search/containers/SearchMenuContainer.jsx index f6687553..245283b1 100644 --- a/app/renderer/pages/search/containers/SearchMenuContainer.jsx +++ b/app/renderer/pages/search/containers/SearchMenuContainer.jsx @@ -1,7 +1,6 @@ import { connect } from 'react-redux'; import toJS from 'renderer/components/toJS'; import { filterSelector } from 'store/reducers/personal/search/selectors'; -import { preferenceOpen } from 'actions/preference'; import { searchAppQuit, searchSetFilter, @@ -16,7 +15,6 @@ const mapStateToProps = state => ({ const mapDispatchToProps = { onQuitApp: searchAppQuit, onMakeWidgetRequest: widgetMakeRequest, - onOpenPreference: preferenceOpen, onSetFilter: searchSetFilter, }; diff --git a/app/renderer/pages/update/UpdateProgress/UpdateProgress.html b/app/renderer/pages/update/UpdateProgress/UpdateProgress.html deleted file mode 100644 index 05177657..00000000 --- a/app/renderer/pages/update/UpdateProgress/UpdateProgress.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - Oh-My-Desk Update Downloading - - -
- - - diff --git a/app/renderer/pages/update/UpdateProgress/UpdateProgress.jsx b/app/renderer/pages/update/UpdateProgress/UpdateProgress.jsx deleted file mode 100644 index ade55d9c..00000000 --- a/app/renderer/pages/update/UpdateProgress/UpdateProgress.jsx +++ /dev/null @@ -1,92 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { remote } from 'electron'; -import cx from 'classnames'; -import i18n from 'constants/i18n'; -import logo from 'assets/oh-my-desk-icon.png'; -import './UpdateProgress.scss'; - -const propTypes = { - currentProgress: PropTypes.number, - isDownload: PropTypes.bool, - totalProgress: PropTypes.number, - newVersion: PropTypes.string, - onCancelDownload: PropTypes.func, -}; -const defaultProps = { - currentProgress: 0, - isDownload: false, - totalProgress: 0, - newVersion: '', - onCancelDownload() {}, -}; - -class UpdateProgress extends React.Component { - constructor(props) { - super(props); - this.handleClickButton = this.handleClickButton.bind(this); - } - - handleClickButton() { - const { isDownload, onCancelDownload } = this.props; - - if (isDownload) { - onCancelDownload(); - } else { - remote.app.relaunch(); - remote.app.quit(); - } - remote.getCurrentWindow().close(); - } - - render() { - const text = i18n().update; - const { - currentProgress, - isDownload, - totalProgress, - newVersion, - } = this.props; - const btnClassName = cx('Btn', 'UpdateProgress__btn', { - 'Btn--gray': isDownload, - 'Btn--primary': !isDownload, - }); - - return ( -
-
- Oh-My-Desk {text.downloading} -
-
- -

- Oh-My-Desk v.{newVersion} {text.downloadNotice} -

-
-
-
-

- {currentProgress}MB / {totalProgress}MB -

- -
-
- ); - } -} - -UpdateProgress.propTypes = propTypes; -UpdateProgress.defaultProps = defaultProps; - -export default UpdateProgress; diff --git a/app/renderer/pages/update/UpdateProgress/UpdateProgress.scss b/app/renderer/pages/update/UpdateProgress/UpdateProgress.scss deleted file mode 100644 index 817088d3..00000000 --- a/app/renderer/pages/update/UpdateProgress/UpdateProgress.scss +++ /dev/null @@ -1,55 +0,0 @@ -.UpdateProgress { - height: 100%; -} - -.UpdateProgress__title { - background-color: rgb(227,227,227); - height: 21px; - text-align: center; - line-height: 190%; - font-size: 11px; - -webkit-app-region: drag; -} - -.UpdateProgress__content { - padding: 20px 30px 20px 30px; - background-color: rgb(235, 237, 241); - height: 100%; -} -.UpdateProgress__logo { - float: left; - height: 60px; - margin-right: 10px; - width: 60px; - margin-top: 10px; -} - -.UpdateProgress__notice { - font-size: 13px; - margin: 5px; -} - -.UpdateProgress__progress-bar { - float: left; - width: 350px; - height: 8px; - margin: 5px; - background-color: rgb(210, 210, 210); - border-radius: 25px; -} - -.UpdateProgress__progress-bar-gauge { - height: 100%; - width: 0; - background-color: dodgerblue; -} - -.UpdateProgress__progress-rate { - font-size: 12px; -} - -.UpdateProgress__btn { - float: right; - font-size: 12px; - padding: 3px; -} diff --git a/app/renderer/pages/update/UpdateProgress/UpdateProgress.spec.jsx b/app/renderer/pages/update/UpdateProgress/UpdateProgress.spec.jsx deleted file mode 100644 index 05c83b53..00000000 --- a/app/renderer/pages/update/UpdateProgress/UpdateProgress.spec.jsx +++ /dev/null @@ -1,60 +0,0 @@ -import React from 'react'; -import { shallow } from 'enzyme'; -import { remote } from 'electron'; -import UpdateProgress from './UpdateProgress'; - -describe('', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should match to snapshot when render default', () => { - const wrapper = shallow(); - - expect(wrapper).toMatchSnapshot(); - }); - - it('should match to snapshot when props.isDownload === true', () => { - const wrapper = shallow(); - - expect(wrapper).toMatchSnapshot(); - }); - - describe('should test handleClickButton', () => { - // const handleClickButton = jest.spyOn(UpdateProgress.prototype, 'handleClickButton'); - const relaunch = jest.fn(); - const quit = jest.fn(); - const close = jest.fn(); - - remote.app = { - relaunch, - quit, - }; - remote.getCurrentWindow = () => ({ - close, - }); - - const onCancelDownload = jest.fn(); - const wrapper = shallow(); - - it('when isDownload === true', () => { - wrapper.setProps({ isDownload: true }); - wrapper.instance().handleClickButton(); - - expect(onCancelDownload).toHaveBeenCalledTimes(1); - expect(close).toHaveBeenCalledTimes(1); - expect(relaunch).toHaveBeenCalledTimes(0); - expect(quit).toHaveBeenCalledTimes(0); - }); - - it('when isDownload === false', () => { - wrapper.setProps({ isDownload: false }); - wrapper.instance().handleClickButton(); - - expect(onCancelDownload).toHaveBeenCalledTimes(0); - expect(close).toHaveBeenCalledTimes(1); - expect(relaunch).toHaveBeenCalledTimes(1); - expect(quit).toHaveBeenCalledTimes(1); - }); - }); -}); diff --git a/app/renderer/pages/update/UpdateProgress/UpdateProgressContainer.jsx b/app/renderer/pages/update/UpdateProgress/UpdateProgressContainer.jsx deleted file mode 100644 index 66331ab3..00000000 --- a/app/renderer/pages/update/UpdateProgress/UpdateProgressContainer.jsx +++ /dev/null @@ -1,22 +0,0 @@ -import { connect } from 'react-redux'; -import { - currentProgressSelector, - totalProgressSelector, -} from 'store/reducers/personal/update/selectors'; -import { newVersionSelector } from 'store/reducers/share/config/selectors'; -import { isDownloadFetchSelector } from 'store/reducers/share/status/selectors'; -import { updateProgressCancel } from 'actions/update'; -import UpdateProgress from './UpdateProgress'; - -const mapStateToProps = state => ({ - currentProgress: currentProgressSelector(state), - totalProgress: totalProgressSelector(state), - newVersion: newVersionSelector(state), - isDownload: isDownloadFetchSelector(state), -}); - -const mapDispatchToProps = { - onCancelDownload: updateProgressCancel, -}; - -export default connect(mapStateToProps, mapDispatchToProps)(UpdateProgress); diff --git a/app/renderer/pages/update/UpdateProgress/__snapshots__/UpdateProgress.spec.jsx.snap b/app/renderer/pages/update/UpdateProgress/__snapshots__/UpdateProgress.spec.jsx.snap deleted file mode 100644 index d07e74c1..00000000 --- a/app/renderer/pages/update/UpdateProgress/__snapshots__/UpdateProgress.spec.jsx.snap +++ /dev/null @@ -1,113 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[` should match to snapshot when props.isDownload === true 1`] = ` -
-
- Oh-My-Desk - is Downloading -
-
- -

- Oh-My-Desk v. - - is Downloading. -

-
-
-
-

- 0 - MB / - 0 - MB -

- -
-
-`; - -exports[` should match to snapshot when render default 1`] = ` -
-
- Oh-My-Desk - is Downloading -
-
- -

- Oh-My-Desk v. - - is Downloading. -

-
-
-
-

- 0 - MB / - 0 - MB -

- -
-
-`; diff --git a/app/renderer/pages/update/UpdateProgress/index.jsx b/app/renderer/pages/update/UpdateProgress/index.jsx deleted file mode 100644 index 7d54a323..00000000 --- a/app/renderer/pages/update/UpdateProgress/index.jsx +++ /dev/null @@ -1,17 +0,0 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import { Provider } from 'react-redux'; -import configureStore from 'store/configureStore'; -import subscribeActionRenderer from 'store/utils/subscribeActionRenderer'; -import 'scss/index.scss'; -import UpdateProgressContainer from './UpdateProgressContainer'; - -const store = configureStore(); -subscribeActionRenderer(store); - -ReactDOM.render( - - - , - document.getElementById('root'), -); diff --git a/app/renderer/pages/update/UpdateWindow/UpdateWindow.html b/app/renderer/pages/update/UpdateWindow/UpdateWindow.html deleted file mode 100644 index aed87bae..00000000 --- a/app/renderer/pages/update/UpdateWindow/UpdateWindow.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - Oh-My-Desk Update - - -
- - - diff --git a/app/renderer/pages/update/UpdateWindow/UpdateWindow.jsx b/app/renderer/pages/update/UpdateWindow/UpdateWindow.jsx deleted file mode 100644 index b53942d2..00000000 --- a/app/renderer/pages/update/UpdateWindow/UpdateWindow.jsx +++ /dev/null @@ -1,139 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { remote } from 'electron'; -import i18n from 'constants/i18n'; -import logo from 'assets/oh-my-desk-icon.png'; -import './UpdateWindow.scss'; - -const propTypes = { - isDownloadUpdateWhenStart: PropTypes.bool, - isDownloadFetch: PropTypes.bool, - newVersion: PropTypes.string, - releaseNotes: PropTypes.string, - onSetAutoUpdate: PropTypes.func, - onSkipThisVersion: PropTypes.func, - onInstallRequest: PropTypes.func, -}; - -const defaultProps = { - isDownloadUpdateWhenStart: false, - isDownloadFetch: false, - newVersion: null, - releaseNotes: '', - onSetAutoUpdate() {}, - onSkipThisVersion() {}, - onInstallRequest() {}, -}; - -class UpdateWindow extends React.Component { - constructor(props) { - super(props); - this.state = { - isDownloadUpdateWhenStart: props.isDownloadUpdateWhenStart, - }; - this.widget = remote.getCurrentWindow(); - this.handleChangeAutoUpdate = this.handleChangeAutoUpdate.bind(this); - this.handleSkipVersion = this.handleSkipVersion.bind(this); - this.handleInstallUpdate = this.handleInstallUpdate.bind(this); - this.handleWindowClose = this.handleWindowClose.bind(this); - } - - componentDidMount() { - window.document.title = `Oh-My-Desk ${i18n().update.update}`; - } - - handleChangeAutoUpdate() { - this.setState(prevState => ({ - isDownloadUpdateWhenStart: !prevState.isDownloadUpdateWhenStart, - })); - } - - handleSkipVersion() { - const { newVersion, onSkipThisVersion } = this.props; - - onSkipThisVersion(newVersion); - this.handleWindowClose(); - } - - handleInstallUpdate() { - const { isDownloadFetch, onInstallRequest } = this.props; - - if (!isDownloadFetch) { - onInstallRequest(); - } - this.handleWindowClose(); - } - - handleWindowClose() { - const { onSetAutoUpdate } = this.props; - const { isDownloadUpdateWhenStart } = this.state; - - onSetAutoUpdate(isDownloadUpdateWhenStart); - this.widget.close(); - } - - render() { - const { newVersion, releaseNotes } = this.props; - const { isDownloadUpdateWhenStart } = this.state; - const currentVersion = remote.app.getVersion(); - const text = i18n().update; - - return ( -
-
- -

{text.updateNotice}({currentVersion} {'=>'} {newVersion})

-
-
-

- {text.updateContent} -

-
- -
-
- - - -
-
- ); - } -} - -UpdateWindow.propTypes = propTypes; -UpdateWindow.defaultProps = defaultProps; - -export default UpdateWindow; diff --git a/app/renderer/pages/update/UpdateWindow/UpdateWindow.scss b/app/renderer/pages/update/UpdateWindow/UpdateWindow.scss deleted file mode 100644 index 3182b239..00000000 --- a/app/renderer/pages/update/UpdateWindow/UpdateWindow.scss +++ /dev/null @@ -1,73 +0,0 @@ -.UpdateWindow { - padding: 20px 40px 20px 40px; - background-color: rgb(235, 237, 241); - height: 100%; -} - -.UpdateWindow__title { - text-align: center; - margin-top: 10px; - width: 100%; -} - -.UpdateWindow__logo { - display: block; - width: 60px; - margin: auto; - float: left; - height: 60px; -} - -.UpdateWindow__notice { - font-weight: 700; - font-size: 14px; - margin-top: 5px; -} - -.UpdateWindow__content { - text-align: left; -} - -.UpdateWindow__content-title { - margin-bottom: 5px; - font-weight: 600; - font-size: 13px; -} - -.UpdateWindow__content-note { - background-color: white; - overflow: scroll; - height: 150px; - width: 100%; - border: 1px solid rgb(200, 200, 200); - margin: auto; -} - -.UpdateWindow__checkbox-label { - display: block; - font-size: 12px; - margin-top: 5px; -} - -.UpdateWindow__checkbox { - margin-right: 5px; -} - -.UpdateWindow__btn-set { - margin-top: 15px; -} - -.UpdateWindow__btn-skip { - float: left; - padding: 3px; - width: 100px; - margin: 5px; -} - -.UpdateWindow__btn-install, -.UpdateWindow__btn-remind { - float: right; - padding: 3px; - width: 100px; - margin: 5px; -} diff --git a/app/renderer/pages/update/UpdateWindow/UpdateWindow.spec.jsx b/app/renderer/pages/update/UpdateWindow/UpdateWindow.spec.jsx deleted file mode 100644 index d260739e..00000000 --- a/app/renderer/pages/update/UpdateWindow/UpdateWindow.spec.jsx +++ /dev/null @@ -1,107 +0,0 @@ -import React from 'react'; -import { shallow, mount } from 'enzyme'; -import UpdateWindow from './UpdateWindow'; - -describe('', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should match to snapshot when render default', () => { - const wrapper = shallow(); - - expect(wrapper).toMatchSnapshot(); - }); - - describe('should call handleChangeAutoUpdate', () => { - const wrapper = shallow(); - - it('when state.autoUpdate is false', () => { - wrapper.setState({ isDownloadUpdateWhenStart: false }); - expect(wrapper.instance().state.isDownloadUpdateWhenStart).toBe(false); - wrapper.instance().handleChangeAutoUpdate(); - expect(wrapper.instance().state.isDownloadUpdateWhenStart).toBe(true); - }); - - it('when state.autoUpdate is true', () => { - wrapper.setState({ isDownloadUpdateWhenStart: true }); - expect(wrapper.instance().state.isDownloadUpdateWhenStart).toBe(true); - wrapper.instance().handleChangeAutoUpdate(); - expect(wrapper.instance().state.isDownloadUpdateWhenStart).toBe(false); - }); - }); - - it('should call handleSkipVersion', () => { - const onSkipThisVersion = jest.fn(); - const handleWindowClose = jest.spyOn(UpdateWindow.prototype, 'handleWindowClose'); - const wrapper = mount( - , - ); - wrapper.instance().widget = { - close: jest.fn(), - }; - - wrapper.instance().handleSkipVersion(); - - expect(handleWindowClose).toHaveBeenCalledTimes(1); - expect(handleWindowClose).toHaveBeenCalledWith(); - expect(onSkipThisVersion).toHaveBeenCalledTimes(1); - expect(onSkipThisVersion).toHaveBeenCalledWith('new-version'); - }); - - describe('should call handleInstallUpdate', () => { - const onInstallRequest = jest.fn(); - const handleWindowClose = jest.spyOn(UpdateWindow.prototype, 'handleWindowClose'); - const wrapper = mount( - , - ); - - wrapper.instance().widget = { - close: jest.fn(), - }; - - it('when isDownloadFetch === true', () => { - wrapper.setProps({ isDownloadFetch: true }); - - wrapper.instance().handleInstallUpdate(); - - expect(onInstallRequest).toHaveBeenCalledTimes(0); - expect(handleWindowClose).toHaveBeenCalledTimes(1); - expect(handleWindowClose).toHaveBeenCalledWith(); - }); - - it('when isDownloadFetch === false', () => { - wrapper.setProps({ isDownloadFetch: false }); - - wrapper.instance().handleInstallUpdate(); - - expect(onInstallRequest).toHaveBeenCalledTimes(1); - expect(onInstallRequest).toHaveBeenCalledWith(); - expect(handleWindowClose).toHaveBeenCalledTimes(1); - expect(handleWindowClose).toHaveBeenCalledWith(); - }); - }); - - it('should call handleWindowClose', () => { - const onSetAutoUpdate = jest.fn(); - const close = jest.fn(); - const wrapper = shallow(); - wrapper.instance().widget = { - close, - }; - - wrapper.instance().handleWindowClose(); - - expect(onSetAutoUpdate).toHaveBeenCalledTimes(1); - expect(onSetAutoUpdate) - .toHaveBeenCalledWith(wrapper.instance().state.isDownloadUpdateWhenStart); - expect(close).toHaveBeenCalledTimes(1); - expect(close).toHaveBeenCalledWith(); - }); -}); diff --git a/app/renderer/pages/update/UpdateWindow/UpdateWindowContainer.jsx b/app/renderer/pages/update/UpdateWindow/UpdateWindowContainer.jsx deleted file mode 100644 index 9f1bf1ec..00000000 --- a/app/renderer/pages/update/UpdateWindow/UpdateWindowContainer.jsx +++ /dev/null @@ -1,30 +0,0 @@ -import { connect } from 'react-redux'; -import { - updateSkipThisVersion, - updateDownloadRequest, - updateSetAutoUpdate, -} from 'actions/update'; -import { - isDownloadFetchSelector, - isDownloadUpdateWhenStartSelector, -} from 'store/reducers/share/status/selectors'; -import { - newVersionSelector, - releaseNotesSelector, -} from 'store/reducers/share/config/selectors'; -import UpdateWindow from './UpdateWindow'; - -const mapStateToProps = state => ({ - isDownloadFetch: isDownloadFetchSelector(state), - isDownloadUpdateWhenStart: isDownloadUpdateWhenStartSelector(state), - newVersion: newVersionSelector(state), - releaseNotes: releaseNotesSelector(state), -}); - -const mapDispatchToProps = { - onSetAutoUpdate: updateSetAutoUpdate, - onSkipThisVersion: updateSkipThisVersion, - onInstallRequest: updateDownloadRequest, -}; - -export default connect(mapStateToProps, mapDispatchToProps)(UpdateWindow); diff --git a/app/renderer/pages/update/UpdateWindow/__snapshots__/UpdateWindow.spec.jsx.snap b/app/renderer/pages/update/UpdateWindow/__snapshots__/UpdateWindow.spec.jsx.snap deleted file mode 100644 index add9bc55..00000000 --- a/app/renderer/pages/update/UpdateWindow/__snapshots__/UpdateWindow.spec.jsx.snap +++ /dev/null @@ -1,82 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[` should match to snapshot when render default 1`] = ` -
-
- -

- A new version of Oh My Desk is available! - ( - - => - - ) -

-
-
-

- Update Content -

-
- -
-
- - - -
-
-`; diff --git a/app/renderer/pages/update/UpdateWindow/index.jsx b/app/renderer/pages/update/UpdateWindow/index.jsx deleted file mode 100644 index f85e3006..00000000 --- a/app/renderer/pages/update/UpdateWindow/index.jsx +++ /dev/null @@ -1,17 +0,0 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import { Provider } from 'react-redux'; -import configureStore from 'store/configureStore'; -import subscribeActionRenderer from 'store/utils/subscribeActionRenderer'; -import 'scss/index.scss'; -import UpdateWindowContainer from './UpdateWindowContainer'; - -const store = configureStore(); -subscribeActionRenderer(store); - -ReactDOM.render( - - - , - document.getElementById('root'), -); diff --git a/app/renderer/pages/widget/components/ReloadTimer/ReloadTimer.spec.jsx b/app/renderer/pages/widget/components/ReloadTimer/ReloadTimer.spec.jsx deleted file mode 100644 index 8486f174..00000000 --- a/app/renderer/pages/widget/components/ReloadTimer/ReloadTimer.spec.jsx +++ /dev/null @@ -1,119 +0,0 @@ -import React from 'react'; -import { shallow } from 'enzyme'; - -import ReloadTimer from '.'; - -describe('', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should match to snapshot when render default', () => { - const wrapper = shallow(); - - expect(wrapper).toMatchSnapshot(); - }); - - it('should match to snapshot when render default', () => { - const wrapper = shallow(); - wrapper.setState({ timer: 6015 }); - - expect(wrapper).toMatchSnapshot(); - }); - - it('should call handleCancelTimer', () => { - const onUpdateInfo = jest.fn(); - const wrapper = shallow(); - - wrapper.instance().handleCancelTimer(); - - expect(onUpdateInfo).toHaveBeenCalledTimes(1); - expect(onUpdateInfo).toHaveBeenCalledWith('mock-id', { - reloadInterval: 0, - }); - }); - - describe('should call handleTick', () => { - const webView = { - reload: jest.fn(), - }; - const wrapper = shallow(); - - it('when timer <= 0', () => { - wrapper.setState({ timer: 0 }); - - wrapper.instance().handleTick(); - - expect(webView.reload).toHaveBeenCalledTimes(1); - expect(webView.reload).toHaveBeenCalledWith(); - expect(wrapper.instance().state.timer).toBe(50); - }); - - it('when timer <= 0', () => { - wrapper.setState({ timer: 10 }); - - wrapper.instance().handleTick(); - - expect(webView.reload).toHaveBeenCalledTimes(0); - expect(wrapper.instance().state.timer).toBe(9); - }); - }); - - it.skip('should call componentDidUpdate', () => { - const componentDidUpdate = jest.spyOn(ReloadTimer.prototype, 'componentDidUpdate'); - const wrapper = shallow(); - - expect(wrapper.instance().state.timer).toBe(0); - expect(componentDidUpdate).toHaveBeenCalledTimes(0); - - wrapper.setProps({ reloadTimer: 50 }); - - expect(componentDidUpdate).toHaveBeenCalledTimes(2); - expect(wrapper.instance().state.timer).toBe(50); - }); - - it.skip('should test componentDidMount and componentWillUnmount', () => { - jest.useFakeTimers(); - const componentDidMount = jest.spyOn(ReloadTimer.prototype, 'componentDidMount'); - const componentWillUnmount = jest.spyOn(ReloadTimer.prototype, 'componentWillUnmount'); - const wrapper = shallow(); - const { handleTick, tick } = wrapper.instance(); - - expect(componentDidMount).toHaveBeenCalledTimes(1); - expect(setInterval).toHaveBeenCalledTimes(1); - expect(setInterval).toHaveBeenCalledWith( - handleTick, - 1000, - ); - - wrapper.unmount(); - expect(componentWillUnmount).toHaveBeenCalledTimes(1); - expect(clearInterval).toHaveBeenCalledTimes(1); - expect(clearInterval).toHaveBeenCalledWith(tick); - }); - - describe.skip('should test handleToggleTimer', () => { - jest.useFakeTimers(); - - const wrapper = shallow(); - - it('when this.tick === null', () => { - wrapper.instance().tick = null; - wrapper.instance().handleToggleTimer(); - - expect(setInterval).toHaveBeenCalledTimes(1); - expect(setInterval).toHaveBeenCalledWith( - wrapper.instance().handleTick, - 1000, - ); - }); - - it('when this.tick !== null', () => { - wrapper.instance().tick = 50; - wrapper.instance().handleToggleTimer(); - - expect(clearInterval).toHaveBeenCalledTimes(1); - expect(clearInterval).toHaveBeenCalledWith(50); - }); - }); -}); diff --git a/app/renderer/pages/widget/components/ReloadTimer/__snapshots__/ReloadTimer.spec.jsx.snap b/app/renderer/pages/widget/components/ReloadTimer/__snapshots__/ReloadTimer.spec.jsx.snap deleted file mode 100644 index 17dc536a..00000000 --- a/app/renderer/pages/widget/components/ReloadTimer/__snapshots__/ReloadTimer.spec.jsx.snap +++ /dev/null @@ -1,53 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[` should match to snapshot when render default 1`] = ` -
- - -
-`; - -exports[` should match to snapshot when render default 2`] = ` -
- - -
-`; diff --git a/app/renderer/pages/widget/containers/WebWidgetContainer.jsx b/app/renderer/pages/widget/containers/WebWidgetContainer.jsx index 478b6703..eb206b69 100644 --- a/app/renderer/pages/widget/containers/WebWidgetContainer.jsx +++ b/app/renderer/pages/widget/containers/WebWidgetContainer.jsx @@ -8,7 +8,6 @@ import { widgetUpdateInfo, widgetUrlValidCheck, } from 'actions/widget'; -import { preferenceOpen } from 'actions/preference'; import WebWidget from '../components/WebWidget'; const mapStateToProps = state => ({ @@ -21,7 +20,6 @@ const mapDispatchToProps = { onCheckUrlValidation: widgetUrlValidCheck, onMakeWidget: widgetMakeRequest, onUpdateInfo: widgetUpdateInfo, - onOpenPreference: preferenceOpen, }; export default connect(mapStateToProps, mapDispatchToProps)(toJS(WebWidget)); diff --git a/app/store/middleware/__tests__/categorizeActionInMain.spec.js b/app/store/middleware/__tests__/categorizeActionInMain.spec.js deleted file mode 100644 index b6d6d3ee..00000000 --- a/app/store/middleware/__tests__/categorizeActionInMain.spec.js +++ /dev/null @@ -1,244 +0,0 @@ -import { BrowserWindow, webContents } from 'electron'; -import Immutable from 'immutable'; -import configureStore from 'redux-mock-store'; -import * as CATEGORY from 'actions/constant/actionCategory'; -import controllers from 'main/controllers'; -import categorizeActionInMain from '../categorizeActionInMain'; - -jest.mock('main/controllers'); - -describe('test categorizeActionInMain', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - const next = jest.fn(); - const mockState = Immutable.Map({ - a: 'aa', - b: 'bb', - }); - const store = { - getState: jest.fn(() => mockState), - }; - - it('when action is not FSA', () => { - const mockAction = () => {}; - - categorizeActionInMain(store)(next)(mockAction); - - expect(controllers).toHaveBeenCalledTimes(1); - expect(controllers).toHaveBeenCalledWith(mockAction, mockState); - expect(store.getState).toHaveBeenCalledTimes(1); - expect(store.getState).toHaveBeenCalledWith(); - expect(next).toHaveBeenCalledTimes(1); - expect(next).toHaveBeenCalledWith(mockAction); - }); - - it('when action don\'t have meta.category', () => { - const mockAction = { - type: 'SOME_TYPE', - }; - - categorizeActionInMain(store)(next)(mockAction); - - expect(controllers).toHaveBeenCalledTimes(1); - expect(controllers).toHaveBeenCalledWith(mockAction, mockState); - expect(store.getState).toHaveBeenCalledTimes(1); - expect(store.getState).toHaveBeenCalledWith(); - expect(next).toHaveBeenCalledTimes(1); - expect(next).toHaveBeenCalledWith(mockAction); - }); - - describe('when action is FSA', () => { - it('when action.category is SELF', () => { - const mockAction = { - type: 'SOME_TYPE', - meta: { - category: CATEGORY.SELF, - }, - }; - - categorizeActionInMain(store)(next)(mockAction); - - expect(controllers).toHaveBeenCalledTimes(1); - expect(controllers).toHaveBeenCalledWith(mockAction, mockState); - expect(store.getState).toHaveBeenCalledTimes(1); - expect(store.getState).toHaveBeenCalledWith(); - expect(next).toHaveBeenCalledTimes(1); - expect(next).toHaveBeenCalledWith(mockAction); - }); - - describe('when action.category is BROADCAST', () => { - const send = jest.fn(); - webContents.getAllWebContents.mockImplementation(() => [{ send }, { send }]); - - it('should action.meta.transmitted === true ', () => { - const mockAction = { - type: 'SOME_TYPE', - meta: { - category: CATEGORY.BROADCAST, - transmitted: true, - }, - }; - categorizeActionInMain(store)(next)(mockAction); - - expect(controllers).toHaveBeenCalledTimes(1); - expect(controllers).toHaveBeenCalledWith(mockAction, mockState); - expect(store.getState).toHaveBeenCalledTimes(1); - expect(store.getState).toHaveBeenCalledWith(); - expect(next).toHaveBeenCalledTimes(1); - expect(next).toHaveBeenCalledWith(mockAction); - expect(send).toHaveBeenCalledTimes(0); - }); - - it('should action.meta.transmitted is undefined or false', () => { - const mockAction = { - type: 'SOME_TYPE', - meta: { - category: CATEGORY.BROADCAST, - }, - }; - const mockBroadcastAction = { - type: 'SOME_TYPE', - meta: { - category: CATEGORY.BROADCAST, - transmitted: true, - }, - }; - - categorizeActionInMain(store)(next)(mockAction); - - expect(controllers).toHaveBeenCalledTimes(1); - expect(controllers).toHaveBeenCalledWith(mockAction, mockState); - expect(store.getState).toHaveBeenCalledTimes(1); - expect(store.getState).toHaveBeenCalledWith(); - expect(next).toHaveBeenCalledTimes(1); - expect(next).toHaveBeenCalledWith(mockAction); - expect(send).toHaveBeenCalledTimes(2); - expect(send).toHaveBeenCalledWith( - 'redux-action', - mockBroadcastAction, - ); - }); - }); - - describe('when action.category is TARGET ', () => { - it('when meta.transmitted === true', () => { - const mockAction = { - type: 'SOME_TYPE', - meta: { - category: CATEGORY.TARGET, - transmitted: true, - }, - }; - categorizeActionInMain(store)(next)(mockAction); - - expect(controllers).toHaveBeenCalledTimes(1); - expect(controllers).toHaveBeenCalledWith(mockAction, mockState); - expect(store.getState).toHaveBeenCalledTimes(1); - expect(store.getState).toHaveBeenCalledWith(); - expect(next).toHaveBeenCalledTimes(1); - expect(next).toHaveBeenCalledWith(mockAction); - }); - - describe('should meta.transmitted is undefined or false', () => { - const mockWindow = new BrowserWindow(); - const initialState = Immutable.Map({ - personal: Immutable.Map({ - identification: Immutable.Map({ - browserWindowById: Immutable.Map({ - mock1: mockWindow, - mock2: mockWindow, - mock3: mockWindow, - }), - }), - }), - }); - const mockStore = configureStore(); - const storeMock = mockStore(initialState); - - it('basic test', () => { - const mockAction = { - type: 'SOME_TYPE', - meta: { - category: CATEGORY.TARGET, - target: ['mock1', 'mock3'], - }, - }; - const targetAction = { - type: 'SOME_TYPE', - meta: { - category: CATEGORY.TARGET, - target: ['mock1', 'mock3'], - transmitted: true, - }, - }; - - categorizeActionInMain(storeMock)(next)(mockAction); - - expect(mockWindow.webContents.send).toHaveBeenCalledTimes(2); - expect(mockWindow.webContents.send).toHaveBeenCalledWith( - 'redux-action', - targetAction, - ); - }); - - it('basic test', () => { - const mockAction = { - type: 'SOME_TYPE', - meta: { - category: CATEGORY.TARGET, - }, - }; - - categorizeActionInMain(storeMock)(next)(mockAction); - - expect(mockWindow.webContents.send).toHaveBeenCalledTimes(0); - }); - - it('when meta.self is true', () => { - const mockAction = { - type: 'SOME_TYPE', - meta: { - category: CATEGORY.TARGET, - target: ['mock1', 'mock3'], - self: true, - }, - }; - - categorizeActionInMain(storeMock)(next)(mockAction); - expect(next).toHaveBeenCalledTimes(1); - expect(next).toHaveBeenCalledWith(mockAction); - }); - - it('when meta.containMain is true', () => { - const mockAction = { - type: 'SOME_TYPE', - meta: { - category: CATEGORY.TARGET, - target: ['mock1', 'mock3'], - containMain: true, - }, - }; - - categorizeActionInMain(storeMock)(next)(mockAction); - expect(next).toHaveBeenCalledTimes(1); - expect(next).toHaveBeenCalledWith(mockAction); - }); - - it('when meta.self is false', () => { - const mockAction = { - type: 'SOME_TYPE', - meta: { - category: CATEGORY.TARGET, - target: ['mock1', 'mock3'], - self: false, - }, - }; - - categorizeActionInMain(storeMock)(next)(mockAction); - expect(next).toHaveBeenCalledTimes(0); - }); - }); - }); - }); -}); diff --git a/app/store/middleware/categorizeActionInMain.js b/app/store/middleware/categorizeActionInMain.js index ea9bb0de..d856532f 100644 --- a/app/store/middleware/categorizeActionInMain.js +++ b/app/store/middleware/categorizeActionInMain.js @@ -1,7 +1,7 @@ import { webContents } from 'electron'; import { isFSA } from 'flux-standard-action'; import * as CATEGORY from 'actions/constant/actionCategory'; -import { browserWindowByIdSelector } from 'store/reducers/personal/identification/selectors'; +import { manager } from 'main/utils/window/widget'; import controller from 'main/controllers'; // TODO Add link about action categorizing docs @@ -67,7 +67,6 @@ const categorizeActionInMain = store => next => (action) => { } const { target } = meta; - const winById = browserWindowByIdSelector(store.getState()); const targetArr = []; const targetAction = { type: action.type, @@ -80,7 +79,7 @@ const categorizeActionInMain = store => next => (action) => { if (target) { target.forEach((id) => { // TODO exception that id is not validity - targetArr.push(winById.get(id)); + targetArr.push(manager.getWindow(id).win); }); } diff --git a/app/store/reducers/personal/identification/__tests__/browserWindowById.js b/app/store/reducers/personal/identification/__tests__/browserWindowById.js deleted file mode 100644 index 2ac02ac2..00000000 --- a/app/store/reducers/personal/identification/__tests__/browserWindowById.js +++ /dev/null @@ -1,72 +0,0 @@ -import Immutable from 'immutable'; -import { BrowserWindow } from 'electron'; -import { openBrowserWindow } from 'actions/window'; -import * as updateActions from 'actions/update'; -import * as widgetActions from 'actions/widget'; -import browserWindowById from '../browserWindowById'; - -describe('test browserWindowById reducer', () => { - it('should match initialState', () => { - expect(browserWindowById(undefined, {})).toEqual(Immutable.Map()); - }); - - describe('should handle openBrowserWindow', () => { - it('when number of id is one', () => { - const mockId = 'mock-id'; - const mockWin = new BrowserWindow(); - const mockResult = Immutable.Map({ - [mockId]: mockWin, - }); - - expect(browserWindowById(undefined, openBrowserWindow(mockId, mockWin))) - .toEqual(mockResult); - }); - - it('when id are array', () => { - const mockWin = new BrowserWindow(); - const mockId = ['mock1', 'mock2']; - const mockWinArray = [mockWin, mockWin]; - const mockResult = Immutable.Map({ - mock1: mockWin, - mock2: mockWin, - }); - - expect(browserWindowById(undefined, openBrowserWindow(mockId, mockWinArray))) - .toEqual(mockResult); - }); - }); - - it('should handle updateProgressWindowOpen', () => { - const mockId = 'mock-id'; - const mockWin = new BrowserWindow(); - const mockResult = Immutable.Map({ - [mockId]: mockWin, - }); - - expect(browserWindowById(undefined, updateActions.updateProgressWindowOpen(mockId, mockWin))) - .toEqual(mockResult); - }); - - describe('test when close window in browserWindowById', () => { - const mockId = 'mock-id'; - const mockWin = new BrowserWindow(); - const mockInitial = Immutable.Map({ - [mockId]: mockWin, - }); - - it('should handle widgetClose', () => { - expect(browserWindowById(mockInitial, widgetActions.widgetClose(mockId))) - .toEqual(Immutable.Map({})); - }); - - it('should handle widgetClosed', () => { - expect(browserWindowById(mockInitial, widgetActions.widgetClosed(mockId))) - .toEqual(Immutable.Map({})); - }); - - it('should handle updateProgressWindowClose', () => { - expect(browserWindowById(mockInitial, updateActions.updateProgressWindowClose(mockId))) - .toEqual(Immutable.Map({})); - }); - }); -}); diff --git a/app/store/reducers/personal/identification/__tests__/selectors.spec.js b/app/store/reducers/personal/identification/__tests__/selectors.spec.js index 242d942e..47e9c36d 100644 --- a/app/store/reducers/personal/identification/__tests__/selectors.spec.js +++ b/app/store/reducers/personal/identification/__tests__/selectors.spec.js @@ -1,4 +1,3 @@ -import { BrowserWindow } from 'electron'; import Immutable from 'immutable'; import * as selectors from '../selectors'; @@ -14,20 +13,4 @@ describe('test identification selectors', () => { expect(selectors.myselfSelector(mockStore)).toEqual('mock-id'); }); - - it('should handle browserWindowById', () => { - const mockSelected = Immutable.Map({ - mock1: new BrowserWindow(), - mock2: new BrowserWindow(), - }); - const mockState = Immutable.Map({ - personal: Immutable.Map({ - identification: Immutable.Map({ - browserWindowById: mockSelected, - }), - }), - }); - - expect(selectors.browserWindowByIdSelector(mockState)).toEqual(mockSelected); - }); }); diff --git a/app/store/reducers/personal/identification/browserWindowById.js b/app/store/reducers/personal/identification/browserWindowById.js deleted file mode 100644 index 2e5bc575..00000000 --- a/app/store/reducers/personal/identification/browserWindowById.js +++ /dev/null @@ -1,38 +0,0 @@ -import Immutable from 'immutable'; -import { combineActions, handleActions } from 'redux-actions'; -import * as TYPES from 'actions/constant/actionTypes'; - -const initialState = Immutable.Map(); - -const browserWindowByIdReducer = handleActions({ - [TYPES.OPEN_BROWSER_WINDOW]: (state, action) => { - const { id, browserWindow } = action.payload; - - if (Array.isArray(id)) { - let nextState = state; - id.forEach((item, index) => { - nextState = nextState.set(item, browserWindow[index]); - }); - return nextState; - } - - return state.set(id, browserWindow); - }, - [TYPES.UPDATE_PROGRESS_WINDOW_OPEN]: (state, action) => { - const { id, win } = action.payload; - - return state.set(id, win); - }, - [combineActions( - TYPES.WIDGET_CLOSE, - TYPES.WIDGET_CLOSED, - TYPES.PREFERENCE_CLOSE, - TYPES.UPDATE_PROGRESS_WINDOW_CLOSE, - )]: (state, action) => { - const { id } = action.payload; - - return id ? state.delete(id) : state; - }, -}, initialState); - -export default browserWindowByIdReducer; diff --git a/app/store/reducers/personal/identification/index.js b/app/store/reducers/personal/identification/index.js index 882be3cd..0cc8c15b 100644 --- a/app/store/reducers/personal/identification/index.js +++ b/app/store/reducers/personal/identification/index.js @@ -1,9 +1,7 @@ import { combineReducers } from 'redux-immutable'; -import browserWindowById from './browserWindowById'; import myself from './myself'; const identificationReducers = combineReducers({ - browserWindowById, myself, }); diff --git a/app/store/reducers/personal/identification/selectors/index.js b/app/store/reducers/personal/identification/selectors/index.js index 2f7d3651..8fe2c2fe 100644 --- a/app/store/reducers/personal/identification/selectors/index.js +++ b/app/store/reducers/personal/identification/selectors/index.js @@ -10,8 +10,3 @@ export const myselfSelector = createSelector( identificationSelector, identification => identification.get('myself'), ); - -export const browserWindowByIdSelector = createSelector( - identificationSelector, - identification => identification.get('browserWindowById'), -); diff --git a/app/store/reducers/personal/index.js b/app/store/reducers/personal/index.js index f207fc99..6224f718 100644 --- a/app/store/reducers/personal/index.js +++ b/app/store/reducers/personal/index.js @@ -2,13 +2,11 @@ import { combineReducers } from 'redux-immutable'; import modal from './modal'; import identification from './identification'; import search from './search'; -import update from './update'; const personalReducer = combineReducers({ modal, identification, search, - update, }); export default personalReducer; diff --git a/app/store/reducers/personal/search/keyword.js b/app/store/reducers/personal/search/keyword.js index 58b7a6e5..ab4bedd8 100644 --- a/app/store/reducers/personal/search/keyword.js +++ b/app/store/reducers/personal/search/keyword.js @@ -7,7 +7,6 @@ const keywordReducer = handleActions({ [TYPES.SEARCH_CHANGE_KEYWORD]: (state, action) => action.payload.value, [combineActions( TYPES.SEARCH_SET_FILTER, - TYPES.SEARCH_TRAY_CLOSE, )]: () => initialState, }, initialState); diff --git a/app/store/reducers/personal/update/__tests__/currentProgress.spec.js b/app/store/reducers/personal/update/__tests__/currentProgress.spec.js deleted file mode 100644 index 371bb3b1..00000000 --- a/app/store/reducers/personal/update/__tests__/currentProgress.spec.js +++ /dev/null @@ -1,25 +0,0 @@ -import * as actions from 'actions/update'; -import { setInitialStore } from 'actions/setting'; -import currentProgress from '../currentProgress'; - -describe('test currentProgress reducer', () => { - const initialState = 0; - - it('should test initialState', () => { - expect(currentProgress(undefined, {})).toBe(initialState); - }); - - it('should handle setInitialStore', () => { - expect(currentProgress(150, setInitialStore())).toBe(initialState); - }); - - it('should handle updateProgressCancel', () => { - expect(currentProgress(150, actions.updateProgressCancel())).toBe(initialState); - }); - - it('should handle updateDownloadProgress', () => { - expect(currentProgress(undefined, actions.updateDownloadProgress({ - transferred: 12345678, - }))).toBe(12.3); - }); -}); diff --git a/app/store/reducers/personal/update/__tests__/selectors.spec.js b/app/store/reducers/personal/update/__tests__/selectors.spec.js deleted file mode 100644 index 8a4c0a90..00000000 --- a/app/store/reducers/personal/update/__tests__/selectors.spec.js +++ /dev/null @@ -1,30 +0,0 @@ -import Immutable from 'immutable'; -import * as selectors from '../selectors'; - -describe('test select about update', () => { - it('should select currentProgress', () => { - const initialState = Immutable.fromJS({ - personal: { - update: { - currentProgress: 123.4, - }, - }, - }); - - expect(selectors.currentProgressSelector(initialState)) - .toEqual(123.4); - }); - - it('should select totalProgress', () => { - const initialState = Immutable.fromJS({ - personal: { - update: { - totalProgress: 123.4, - }, - }, - }); - - expect(selectors.totalProgressSelector(initialState)) - .toEqual(123.4); - }); -}); diff --git a/app/store/reducers/personal/update/__tests__/totalProgress.spec.js b/app/store/reducers/personal/update/__tests__/totalProgress.spec.js deleted file mode 100644 index 3fee4491..00000000 --- a/app/store/reducers/personal/update/__tests__/totalProgress.spec.js +++ /dev/null @@ -1,25 +0,0 @@ -import * as actions from 'actions/update'; -import { setInitialStore } from 'actions/setting'; -import totalProgress from '../totalProgress'; - -describe('test totalProgress reducer', () => { - const initialState = 0; - - it('should test initialState', () => { - expect(totalProgress(undefined, {})).toBe(initialState); - }); - - it('should handle setInitialStore', () => { - expect(totalProgress(150, setInitialStore())).toBe(initialState); - }); - - it('should handle updateProgressCancel', () => { - expect(totalProgress(150, actions.updateProgressCancel())).toBe(initialState); - }); - - it('should handle updateDownloadProgress', () => { - expect(totalProgress(undefined, actions.updateDownloadProgress({ - total: 12345678, - }))).toBe(12.3); - }); -}); diff --git a/app/store/reducers/personal/update/currentProgress.js b/app/store/reducers/personal/update/currentProgress.js deleted file mode 100644 index 1776ea66..00000000 --- a/app/store/reducers/personal/update/currentProgress.js +++ /dev/null @@ -1,18 +0,0 @@ -import { combineActions, handleActions } from 'redux-actions'; -import * as TYPES from 'actions/constant/actionTypes'; - -const initialState = 0; - -const currentProgressReducer = handleActions({ - [TYPES.UPDATE_DOWNLOAD_PROGRESS]: (state, action) => { - const { downloadObj } = action.payload; - - return Number((downloadObj.transferred / 1000000).toFixed(1)); - }, - [combineActions( - TYPES.SET_INITIAL_STORE, - TYPES.UPDATE_PROGRESS_CANCEL, - )]: () => initialState, -}, initialState); - -export default currentProgressReducer; diff --git a/app/store/reducers/personal/update/index.js b/app/store/reducers/personal/update/index.js deleted file mode 100644 index 417778bc..00000000 --- a/app/store/reducers/personal/update/index.js +++ /dev/null @@ -1,10 +0,0 @@ -import { combineReducers } from 'redux-immutable'; -import currentProgress from './currentProgress'; -import totalProgress from './totalProgress'; - -const updateReducer = combineReducers({ - currentProgress, - totalProgress, -}); - -export default updateReducer; diff --git a/app/store/reducers/personal/update/selectors/index.js b/app/store/reducers/personal/update/selectors/index.js deleted file mode 100644 index c8d4cc98..00000000 --- a/app/store/reducers/personal/update/selectors/index.js +++ /dev/null @@ -1,17 +0,0 @@ -import { createSelector } from 'reselect'; -import personalSelector from '../../selectors'; - -export const updateSelector = createSelector( - personalSelector, - personal => personal.get('update'), -); - -export const currentProgressSelector = createSelector( - updateSelector, - update => update.get('currentProgress'), -); - -export const totalProgressSelector = createSelector( - updateSelector, - search => search.get('totalProgress'), -); diff --git a/app/store/reducers/personal/update/totalProgress.js b/app/store/reducers/personal/update/totalProgress.js deleted file mode 100644 index 54d84ed2..00000000 --- a/app/store/reducers/personal/update/totalProgress.js +++ /dev/null @@ -1,18 +0,0 @@ -import { combineActions, handleActions } from 'redux-actions'; -import * as TYPES from 'actions/constant/actionTypes'; - -const initialState = 0; - -const totalProgressReducer = handleActions({ - [TYPES.UPDATE_DOWNLOAD_PROGRESS]: (state, action) => { - const { downloadObj } = action.payload; - - return Number((downloadObj.total / 1000000).toFixed(1)); - }, - [combineActions( - TYPES.UPDATE_PROGRESS_CANCEL, - TYPES.SET_INITIAL_STORE, - )]: () => initialState, -}, initialState); - -export default totalProgressReducer; diff --git a/app/store/reducers/share/config/__tests__/newVersion.spec.js b/app/store/reducers/share/config/__tests__/newVersion.spec.js deleted file mode 100644 index 03b1d0eb..00000000 --- a/app/store/reducers/share/config/__tests__/newVersion.spec.js +++ /dev/null @@ -1,15 +0,0 @@ -import * as actions from 'actions/update'; -import newVersion from '../newVersion'; - -describe('test newVersion reducer', () => { - const initialState = null; - - it('should test initialState', () => { - expect(newVersion(undefined, {})).toBe(initialState); - }); - - it('should handle updateCheckSuccess', () => { - expect(newVersion(false, actions.updateCheckSuccess('new-version'))) - .toBe('new-version'); - }); -}); diff --git a/app/store/reducers/share/config/__tests__/releaseNotes.spec.js b/app/store/reducers/share/config/__tests__/releaseNotes.spec.js deleted file mode 100644 index e7ff9961..00000000 --- a/app/store/reducers/share/config/__tests__/releaseNotes.spec.js +++ /dev/null @@ -1,15 +0,0 @@ -import * as actions from 'actions/update'; -import releaseNotes from '../releaseNotes'; - -describe('test releaseNotes reducer', () => { - const initialState = null; - - it('should test initialState', () => { - expect(releaseNotes(undefined, {})).toBe(initialState); - }); - - it('should handle updateCheckSuccess', () => { - expect(releaseNotes(undefined, actions.updateCheckSuccess('mock-id', 'mock-release'))) - .toBe('mock-release'); - }); -}); diff --git a/app/store/reducers/share/config/__tests__/selectors.spec.js b/app/store/reducers/share/config/__tests__/selectors.spec.js index 6834a858..e15dd0a0 100644 --- a/app/store/reducers/share/config/__tests__/selectors.spec.js +++ b/app/store/reducers/share/config/__tests__/selectors.spec.js @@ -27,43 +27,4 @@ describe('test config selectors', () => { expect(selectors.defaultUserAgentSelector(initialState)) .toEqual('MOBILE'); }); - - it('should select newVersion', () => { - const initialState = Immutable.fromJS({ - share: { - config: { - newVersion: 'new-version', - }, - }, - }); - - expect(selectors.newVersionSelector(initialState)) - .toEqual('new-version'); - }); - - it('should select releaseNotes', () => { - const initialState = Immutable.fromJS({ - share: { - config: { - releaseNotes: 'new-release', - }, - }, - }); - - expect(selectors.releaseNotesSelector(initialState)) - .toEqual('new-release'); - }); - - it('should select skipVersion', () => { - const initialState = Immutable.fromJS({ - share: { - config: { - skipVersion: 'skip-version', - }, - }, - }); - - expect(selectors.skipVersionSelector(initialState)) - .toEqual('skip-version'); - }); }); diff --git a/app/store/reducers/share/config/__tests__/skipVersion.spec.js b/app/store/reducers/share/config/__tests__/skipVersion.spec.js deleted file mode 100644 index a4ecccc1..00000000 --- a/app/store/reducers/share/config/__tests__/skipVersion.spec.js +++ /dev/null @@ -1,15 +0,0 @@ -import * as actions from 'actions/update'; -import skipVersion from '../skipVersion'; - -describe('test skipVersion reducer', () => { - const initialState = null; - - it('should test initialState', () => { - expect(skipVersion(undefined, {})).toBe(initialState); - }); - - it('should handle updateCheckSuccess', () => { - expect(skipVersion(undefined, actions.updateSkipThisVersion('mock-version'))) - .toBe('mock-version'); - }); -}); diff --git a/app/store/reducers/share/config/hotKeySearchWindow.js b/app/store/reducers/share/config/hotKeySearchWindow.js index 5263bae9..8b27c9da 100644 --- a/app/store/reducers/share/config/hotKeySearchWindow.js +++ b/app/store/reducers/share/config/hotKeySearchWindow.js @@ -1,6 +1,6 @@ +import { remote } from 'electron'; import { handleActions } from 'redux-actions'; import * as TYPES from 'actions/constant/actionTypes'; -import handlingSearchHotKey from 'main/utils/menu/handlingSearchHotKey'; // eslint-disable-line const initialState = 'Ctrl+Space'; @@ -8,7 +8,10 @@ const HotKeySearchWindowReducer = handleActions({ [TYPES.SET_HOT_KEY_SEARCH_WINDOW]: (state, action) => { const { key } = action.payload; - handlingSearchHotKey(key); + if (!remote) { // if main process of electron + const handlingSearchHotKey = require('main/utils/menu/handlingSearchHotKey'); // eslint-disable-line + handlingSearchHotKey(key); + } return key; }, diff --git a/app/store/reducers/share/config/index.js b/app/store/reducers/share/config/index.js index b6b109c4..ab6ba662 100644 --- a/app/store/reducers/share/config/index.js +++ b/app/store/reducers/share/config/index.js @@ -2,17 +2,11 @@ import { combineReducers } from 'redux-immutable'; import defaultUserAgent from './defaultUserAgent'; import hotKeySearchWindow from './hotKeySearchWindow'; import language from './language'; -import newVersion from './newVersion'; -import releaseNotes from './releaseNotes'; -import skipVersion from './skipVersion'; const configReducer = combineReducers({ defaultUserAgent, hotKeySearchWindow, language, - newVersion, - releaseNotes, - skipVersion, }); export default configReducer; diff --git a/app/store/reducers/share/config/newVersion.js b/app/store/reducers/share/config/newVersion.js deleted file mode 100644 index 7b61b30d..00000000 --- a/app/store/reducers/share/config/newVersion.js +++ /dev/null @@ -1,10 +0,0 @@ -import { handleActions } from 'redux-actions'; -import * as TYPES from 'actions/constant/actionTypes'; - -const initialState = null; - -const newVersionReducer = handleActions({ - [TYPES.UPDATE_CHECK_SUCCESS]: (state, action) => action.payload.version, -}, initialState); - -export default newVersionReducer; diff --git a/app/store/reducers/share/config/releaseNotes.js b/app/store/reducers/share/config/releaseNotes.js deleted file mode 100644 index cf44bc90..00000000 --- a/app/store/reducers/share/config/releaseNotes.js +++ /dev/null @@ -1,10 +0,0 @@ -import { handleActions } from 'redux-actions'; -import * as TYPES from 'actions/constant/actionTypes'; - -const initialState = null; - -const releaseNotesReducer = handleActions({ - [TYPES.UPDATE_CHECK_SUCCESS]: (state, action) => action.payload.releaseNotes, -}, initialState); - -export default releaseNotesReducer; diff --git a/app/store/reducers/share/config/selectors/index.js b/app/store/reducers/share/config/selectors/index.js index 463b1618..3ad5e200 100644 --- a/app/store/reducers/share/config/selectors/index.js +++ b/app/store/reducers/share/config/selectors/index.js @@ -20,18 +20,3 @@ export const languageSelector = createSelector( configSelector, config => config.get('language'), ); - -export const newVersionSelector = createSelector( - configSelector, - config => config.get('newVersion'), -); - -export const releaseNotesSelector = createSelector( - configSelector, - config => config.get('releaseNotes'), -); - -export const skipVersionSelector = createSelector( - configSelector, - config => config.get('skipVersion'), -); diff --git a/app/store/reducers/share/config/skipVersion.js b/app/store/reducers/share/config/skipVersion.js deleted file mode 100644 index f5f3a14b..00000000 --- a/app/store/reducers/share/config/skipVersion.js +++ /dev/null @@ -1,10 +0,0 @@ -import { handleActions } from 'redux-actions'; -import * as TYPES from 'actions/constant/actionTypes'; - -const initialState = null; - -const skipVersionReducer = handleActions({ - [TYPES.UPDATE_SKIP_THIS_VERSION]: (state, action) => action.payload.version, -}, initialState); - -export default skipVersionReducer; diff --git a/app/store/reducers/share/identification/__tests__/downloadProgress.js b/app/store/reducers/share/identification/__tests__/downloadProgress.js deleted file mode 100644 index 2e107d59..00000000 --- a/app/store/reducers/share/identification/__tests__/downloadProgress.js +++ /dev/null @@ -1,20 +0,0 @@ -import * as actions from 'actions/update'; -import downloadProgress from '../downloadProgress'; - -describe('test downloadProgress reducer', () => { - const initialState = null; - - it('should test initialState', () => { - expect(downloadProgress(undefined, {})).toBe(initialState); - }); - - it('should handle updateProgressWindowOpen', () => { - expect(downloadProgress(undefined, actions.updateProgressWindowOpen('mock-id'))) - .toBe('mock-id'); - }); - - it('should handle updateProgressWindowClose', () => { - expect(downloadProgress('mock-id', actions.updateProgressWindowClose())) - .toBe(initialState); - }); -}); diff --git a/app/store/reducers/share/identification/__tests__/preference.spec.js b/app/store/reducers/share/identification/__tests__/preference.spec.js deleted file mode 100644 index d55b20dc..00000000 --- a/app/store/reducers/share/identification/__tests__/preference.spec.js +++ /dev/null @@ -1,20 +0,0 @@ -import * as actions from 'actions/preference'; -import preference from '../preference'; - -describe('test preference reducer', () => { - const mockId = 'mockId'; - - it('should test initialState', () => { - expect(preference(undefined, {})).toBe(null); - }); - - it('should handle preferenceAllocateId', () => { - expect(preference(undefined, actions.preferenceAllocateId(mockId))) - .toEqual(mockId); - }); - - it('should handle preferenceClose', () => { - expect(preference(mockId, actions.preferenceClose())) - .toEqual(null); - }); -}); diff --git a/app/store/reducers/share/identification/__tests__/selectors.spec.js b/app/store/reducers/share/identification/__tests__/selectors.spec.js index fd331c75..00690fe6 100644 --- a/app/store/reducers/share/identification/__tests__/selectors.spec.js +++ b/app/store/reducers/share/identification/__tests__/selectors.spec.js @@ -5,19 +5,6 @@ import * as selectors from '../selectors'; jest.unmock('moment'); describe('test identification selectors', () => { - it('should select downloadProgress', () => { - const initialState = Immutable.fromJS({ - share: { - identification: { - downloadProgress: 'mock-id', - }, - }, - }); - - expect(selectors.downloadProgressSelector(initialState)) - .toEqual('mock-id'); - }); - it('should select preference', () => { const initialState = Immutable.fromJS({ share: { diff --git a/app/store/reducers/share/identification/__tests__/widgetInfoById.spec.js b/app/store/reducers/share/identification/__tests__/widgetInfoById.spec.js index 69c0e957..20924e72 100644 --- a/app/store/reducers/share/identification/__tests__/widgetInfoById.spec.js +++ b/app/store/reducers/share/identification/__tests__/widgetInfoById.spec.js @@ -125,73 +125,6 @@ describe('test widgets widgetInfoById reducer', () => { .toEqual(Immutable.fromJS(resultState)); }); - it('should handle WIDGET_CLOSE', () => { - const mockId = 'mock-id'; - const initialState = { - [mockId]: { - name: 'mock-name', - url: 'mock-url', - isOpen: true, - position: { - x: 10, - y: 20, - }, - size: { - height: 100, - width: 200, - }, - }, - }; - const nextState = { - [mockId]: { - name: 'mock-name', - url: 'mock-url', - isOpen: false, - position: { - x: 10, - y: 20, - }, - size: { - height: 100, - width: 200, - }, - }, - }; - - expect(widgetInfoById(Immutable.fromJS(initialState), widgetActions.widgetClose(mockId))) - .toEqual(Immutable.fromJS(nextState)); - - expect(widgetInfoById(Immutable.fromJS(initialState), widgetActions.widgetClose('mock-temp-id'))) - .toEqual(Immutable.fromJS(initialState)); - }); - - it('should handle WIDGET_CLOSE when widget is making progress', () => { - const mockId = 'mock-id'; - const initialState = { - [mockId]: { - name: 'mock-name', - url: 'mock-url', - isOpen: true, - position: { - x: 10, - y: 20, - }, - size: { - height: 100, - width: 200, - }, - isMakeProgress: true, - }, - }; - const nextState = {}; - - expect(widgetInfoById(Immutable.fromJS(initialState), widgetActions.widgetClose(mockId))) - .toEqual(Immutable.fromJS(nextState)); - - expect(widgetInfoById(Immutable.fromJS(initialState), widgetActions.widgetClose('mock-temp-id'))) - .toEqual(Immutable.fromJS(initialState)); - }); - it('should handle WIDGET_CLOSED', () => { const mockId = 'mock-id'; const initialState = { diff --git a/app/store/reducers/share/identification/downloadProgress.js b/app/store/reducers/share/identification/downloadProgress.js deleted file mode 100644 index f41b8faa..00000000 --- a/app/store/reducers/share/identification/downloadProgress.js +++ /dev/null @@ -1,11 +0,0 @@ -import { handleActions } from 'redux-actions'; -import * as TYPES from 'actions/constant/actionTypes'; - -const initialState = null; - -const downloadProgressReducer = handleActions({ - [TYPES.UPDATE_PROGRESS_WINDOW_OPEN]: (state, action) => action.payload.id, - [TYPES.UPDATE_PROGRESS_WINDOW_CLOSE]: () => initialState, -}, initialState); - -export default downloadProgressReducer; diff --git a/app/store/reducers/share/identification/index.js b/app/store/reducers/share/identification/index.js index 60d9bdec..feacf995 100644 --- a/app/store/reducers/share/identification/index.js +++ b/app/store/reducers/share/identification/index.js @@ -1,11 +1,7 @@ import { combineReducers } from 'redux-immutable'; -import downloadProgress from './downloadProgress'; -import preference from './preference'; import widgetInfoById from './widgetInfoById'; const identificationReducer = combineReducers({ - downloadProgress, - preference, widgetInfoById, }); diff --git a/app/store/reducers/share/identification/preference.js b/app/store/reducers/share/identification/preference.js deleted file mode 100644 index 0eb4fcd6..00000000 --- a/app/store/reducers/share/identification/preference.js +++ /dev/null @@ -1,11 +0,0 @@ -import { handleActions } from 'redux-actions'; -import * as TYPES from 'actions/constant/actionTypes'; - -const initialState = null; - -const preferenceReducer = handleActions({ - [TYPES.PREFERENCE_ALLOCATE_ID]: (state, action) => action.payload.id, - [TYPES.PREFERENCE_CLOSE]: () => initialState, -}, initialState); - -export default preferenceReducer; diff --git a/app/store/reducers/share/identification/selectors/index.js b/app/store/reducers/share/identification/selectors/index.js index 9744b898..ee9a4077 100644 --- a/app/store/reducers/share/identification/selectors/index.js +++ b/app/store/reducers/share/identification/selectors/index.js @@ -10,11 +10,6 @@ export const identificationSelector = createSelector( share => share.get('identification'), ); -export const downloadProgressSelector = createSelector( - identificationSelector, - identification => identification.get('downloadProgress'), -); - export const preferenceSelector = createSelector( identificationSelector, identification => identification.get('preference'), diff --git a/app/store/reducers/share/identification/widgetInfoById.js b/app/store/reducers/share/identification/widgetInfoById.js index def5c722..30525737 100644 --- a/app/store/reducers/share/identification/widgetInfoById.js +++ b/app/store/reducers/share/identification/widgetInfoById.js @@ -1,4 +1,4 @@ -import { combineActions, handleActions } from 'redux-actions'; +import { handleActions } from 'redux-actions'; import Immutable from 'immutable'; import createWidget from 'main/utils/widget/createWidget'; import * as TYPES from 'actions/constant/actionTypes'; @@ -33,10 +33,7 @@ const widgetInfoByIdReducer = handleActions({ return state.set(id, widget.set('isOpen', true)); }, - [combineActions( - TYPES.WIDGET_CLOSE, - TYPES.WIDGET_CLOSED, - )]: (state, action) => { + [TYPES.WIDGET_CLOSED]: (state, action) => { const { id } = action.payload; const widget = state.get(id); @@ -48,6 +45,10 @@ const widgetInfoByIdReducer = handleActions({ return state.delete(id); } + if (widget.get('isEditProgress')) { + return state.set(id, widget.set('isOpen', false).set('isEditProgress', false)); + } + return state.set(id, widget.set('isOpen', false)); }, [TYPES.WIDGET_DELETE]: (state, action) => { @@ -77,7 +78,7 @@ const widgetInfoByIdReducer = handleActions({ [TYPES.WIDGET_CLOSE_WHOLE]: state => state.map(item => item.set('isOpen', false)), [TYPES.SET_WHEN_QUIT_APP]: (state) => { let result = state; - state.map((item) => { // eslint-disable-line array-callback-return + state.forEach((item) => { const isMakeProgress = item.get('isMakeProgress'); const isEditProgress = item.get('isEditProgress'); diff --git a/app/store/reducers/share/status/__tests__/isCheckUpdateWhenStart.spec.js b/app/store/reducers/share/status/__tests__/isCheckUpdateWhenStart.spec.js deleted file mode 100644 index 5a990108..00000000 --- a/app/store/reducers/share/status/__tests__/isCheckUpdateWhenStart.spec.js +++ /dev/null @@ -1,22 +0,0 @@ -import * as actions from 'actions/update'; -import isCheckUpdateWhenStart from '../isCheckUpdateWhenStart'; - -describe('test isCheckUpdateWhenStart reducer', () => { - const initialState = false; - - it('should test initialState', () => { - expect(isCheckUpdateWhenStart(undefined, {})).toBe(initialState); - }); - - describe('should handle updateSetAutoUpdate', () => { - it('when isCheckUpdateWhenStart is true', () => { - expect(isCheckUpdateWhenStart(false, actions.updateSetAutoCheckUpdate(true))) - .toBe(true); - }); - - it('when isCheckUpdateWhenStart is false', () => { - expect(isCheckUpdateWhenStart(true, actions.updateSetAutoCheckUpdate(false))) - .toBe(false); - }); - }); -}); diff --git a/app/store/reducers/share/status/__tests__/isDownloadFetch.spec.js b/app/store/reducers/share/status/__tests__/isDownloadFetch.spec.js deleted file mode 100644 index a368f07e..00000000 --- a/app/store/reducers/share/status/__tests__/isDownloadFetch.spec.js +++ /dev/null @@ -1,31 +0,0 @@ -import * as actions from 'actions/update'; -import { setInitialStore } from 'actions/setting'; -import isDownloadFetch from '../isDownloadFetch'; - -describe('test isDownloadFetch reducer', () => { - const initialState = false; - - it('should test initialState', () => { - expect(isDownloadFetch(undefined, {})).toBe(initialState); - }); - - it('should handle updateDownloadRequest', () => { - expect(isDownloadFetch(false, actions.updateDownloadRequest())) - .toBe(true); - }); - - it('should handle updateDownloadSuccess', () => { - expect(isDownloadFetch(true, actions.updateDownloadSuccess())) - .toBe(false); - }); - - it('should handle updateDownloadFailure', () => { - expect(isDownloadFetch(true, actions.updateDownloadFailure())) - .toBe(false); - }); - - it('should handle setInitialStore', () => { - expect(isDownloadFetch(true, setInitialStore())) - .toBe(false); - }); -}); diff --git a/app/store/reducers/share/status/__tests__/isDownloadUpdateWhenStart.js b/app/store/reducers/share/status/__tests__/isDownloadUpdateWhenStart.js deleted file mode 100644 index e18578be..00000000 --- a/app/store/reducers/share/status/__tests__/isDownloadUpdateWhenStart.js +++ /dev/null @@ -1,22 +0,0 @@ -import * as actions from 'actions/update'; -import isDownloadUpdateWhenStart from '../isDownloadUpdateWhenStart'; - -describe('test isDownloadUpdateWhenStart reducer', () => { - const initialState = false; - - it('should test initialState', () => { - expect(isDownloadUpdateWhenStart(undefined, {})).toBe(initialState); - }); - - describe('should handle updateSetAutoUpdate', () => { - it('when isDownloadUpdateWhenStart is true', () => { - expect(isDownloadUpdateWhenStart(false, actions.updateSetAutoUpdate(true))) - .toBe(true); - }); - - it('when isDownloadUpdateWhenStart is false', () => { - expect(isDownloadUpdateWhenStart(true, actions.updateSetAutoUpdate(false))) - .toBe(false); - }); - }); -}); diff --git a/app/store/reducers/share/status/__tests__/isRestartAfterUpdate.spec.js b/app/store/reducers/share/status/__tests__/isRestartAfterUpdate.spec.js deleted file mode 100644 index 2a5bfb6b..00000000 --- a/app/store/reducers/share/status/__tests__/isRestartAfterUpdate.spec.js +++ /dev/null @@ -1,20 +0,0 @@ -import * as actions from 'actions/update'; -import isRestartAfterUpdate from '../isRestartAfterUpdate'; - -describe('test isRestartAfterUpdate reducer', () => { - const initialState = false; - - it('should test initialState', () => { - expect(isRestartAfterUpdate(undefined, {})).toBe(initialState); - }); - - it('should handle updateDownloadSuccess', () => { - expect(isRestartAfterUpdate(false, actions.updateDownloadSuccess())) - .toBe(true); - }); - - it('should handle updateInstallingDownloaded', () => { - expect(isRestartAfterUpdate(true, actions.updateInstallingDownloaded())) - .toBe(false); - }); -}); diff --git a/app/store/reducers/share/status/__tests__/isTrayOpen.spec.js b/app/store/reducers/share/status/__tests__/isTrayOpen.spec.js deleted file mode 100644 index 961547c3..00000000 --- a/app/store/reducers/share/status/__tests__/isTrayOpen.spec.js +++ /dev/null @@ -1,18 +0,0 @@ -import * as actions from 'actions/search'; -import isTrayOpen from '../isTrayOpen'; - -describe('test isTrayOpen reducer', () => { - const initialState = false; - - it('should test initialState', () => { - expect(isTrayOpen(undefined, {})).toBe(initialState); - }); - - it('should handle searchTrayClose', () => { - expect(isTrayOpen(undefined, actions.searchTrayClose())).toBe(false); - }); - - it('should handle searchTrayOpen', () => { - expect(isTrayOpen(undefined, actions.searchTrayOpen())).toBe(true); - }); -}); diff --git a/app/store/reducers/share/status/__tests__/isUpdateCheckFetch.spec.js b/app/store/reducers/share/status/__tests__/isUpdateCheckFetch.spec.js deleted file mode 100644 index da245407..00000000 --- a/app/store/reducers/share/status/__tests__/isUpdateCheckFetch.spec.js +++ /dev/null @@ -1,36 +0,0 @@ -import * as actions from 'actions/update'; -import { setInitialStore } from 'actions/setting'; -import isUpdateCheckFetch from '../isUpdateCheckFetch'; - -describe('test isUpdateCheckFetch reducer', () => { - const initialState = false; - - it('should test initialState', () => { - expect(isUpdateCheckFetch(undefined, {})).toBe(initialState); - }); - - it('should handle updateCheckRequest', () => { - expect(isUpdateCheckFetch(false, actions.updateCheckRequest())) - .toBe(true); - }); - - it('should handle updateCheckRequestOnManual', () => { - expect(isUpdateCheckFetch(false, actions.updateCheckRequestOnManual())) - .toBe(true); - }); - - it('should handle updateCheckSuccess', () => { - expect(isUpdateCheckFetch(true, actions.updateCheckSuccess())) - .toBe(false); - }); - - it('should handle updateCheckFailure', () => { - expect(isUpdateCheckFetch(true, actions.updateCheckFailure())) - .toBe(false); - }); - - it('should handle setInitialStore', () => { - expect(isUpdateCheckFetch(true, setInitialStore())) - .toBe(false); - }); -}); diff --git a/app/store/reducers/share/status/__tests__/isUpdateCheckOnManual.spec.js b/app/store/reducers/share/status/__tests__/isUpdateCheckOnManual.spec.js deleted file mode 100644 index bf20e60b..00000000 --- a/app/store/reducers/share/status/__tests__/isUpdateCheckOnManual.spec.js +++ /dev/null @@ -1,31 +0,0 @@ -import * as actions from 'actions/update'; -import { setInitialStore } from 'actions/setting'; -import isUpdateCheckOnManual from '../isUpdateCheckOnManual'; - -describe('test isUpdateCheckOnManual reducer', () => { - const initialState = false; - - it('should test initialState', () => { - expect(isUpdateCheckOnManual(undefined, {})).toBe(initialState); - }); - - it('should handle updateCheckRequestOnManual', () => { - expect(isUpdateCheckOnManual(false, actions.updateCheckRequestOnManual())) - .toBe(true); - }); - - it('should handle updateCheckSuccess', () => { - expect(isUpdateCheckOnManual(true, actions.updateCheckSuccess())) - .toBe(false); - }); - - it('should handle updateCheckFailure', () => { - expect(isUpdateCheckOnManual(true, actions.updateCheckFailure())) - .toBe(false); - }); - - it('should handle setInitialStore', () => { - expect(isUpdateCheckOnManual(true, setInitialStore())) - .toBe(false); - }); -}); diff --git a/app/store/reducers/share/status/__tests__/selectors.spec.js b/app/store/reducers/share/status/__tests__/selectors.spec.js index eb8d1d8e..10f9777e 100644 --- a/app/store/reducers/share/status/__tests__/selectors.spec.js +++ b/app/store/reducers/share/status/__tests__/selectors.spec.js @@ -15,45 +15,6 @@ describe('test status selectors', () => { .toEqual(false); }); - it('should select isCheckUpdateWhenStart', () => { - const initialState = Immutable.fromJS({ - share: { - status: { - isCheckUpdateWhenStart: false, - }, - }, - }); - - expect(selectors.isCheckUpdateWhenStartSelector(initialState)) - .toEqual(false); - }); - - it('should select isDownloadFetch', () => { - const initialState = Immutable.fromJS({ - share: { - status: { - isDownloadFetch: false, - }, - }, - }); - - expect(selectors.isDownloadFetchSelector(initialState)) - .toEqual(false); - }); - - it('should select isDownloadUpdateWhenStart', () => { - const initialState = Immutable.fromJS({ - share: { - status: { - isDownloadUpdateWhenStart: false, - }, - }, - }); - - expect(selectors.isDownloadUpdateWhenStartSelector(initialState)) - .toEqual(false); - }); - it('should select isOpenWidgetWhenStart', () => { const initialState = Immutable.fromJS({ share: { @@ -67,59 +28,6 @@ describe('test status selectors', () => { .toEqual(false); }); - - it('should select isRestartAfterUpdate', () => { - const initialState = Immutable.fromJS({ - share: { - status: { - isRestartAfterUpdate: false, - }, - }, - }); - - expect(selectors.isRestartAfterUpdateSelector(initialState)) - .toEqual(false); - }); - - it('should select isTrayOpen', () => { - const initialState = Immutable.fromJS({ - share: { - status: { - isTrayOpen: false, - }, - }, - }); - - expect(selectors.isTrayOpenSelector(initialState)) - .toEqual(false); - }); - - it('should select isUpdateCheckFetch', () => { - const initialState = Immutable.fromJS({ - share: { - status: { - isUpdateCheckFetch: false, - }, - }, - }); - - expect(selectors.isUpdateCheckFetchSelector(initialState)) - .toEqual(false); - }); - - it('should select isUpdateCheckOnManual', () => { - const initialState = Immutable.fromJS({ - share: { - status: { - isUpdateCheckOnManual: false, - }, - }, - }); - - expect(selectors.isUpdateCheckOnManualSelector(initialState)) - .toEqual(false); - }); - it('should select isUrlCheckFetch', () => { const initialState = Immutable.fromJS({ share: { diff --git a/app/store/reducers/share/status/index.js b/app/store/reducers/share/status/index.js index 8f076d71..b30d7f24 100644 --- a/app/store/reducers/share/status/index.js +++ b/app/store/reducers/share/status/index.js @@ -1,25 +1,11 @@ import { combineReducers } from 'redux-immutable'; -import isCheckUpdateWhenStart from './isCheckUpdateWhenStart'; -import isDownloadFetch from './isDownloadFetch'; -import isDownloadUpdateWhenStart from './isDownloadUpdateWhenStart'; import isLaunchAppWhenLogin from './isLaunchAppWhenLogin'; import isOpenWidgetWhenStart from './isOpenWidgetWhenStart'; -import isRestartAfterUpdate from './isRestartAfterUpdate'; -import isTrayOpen from './isTrayOpen'; -import isUpdateCheckFetch from './isUpdateCheckFetch'; -import isUpdateCheckOnManual from './isUpdateCheckOnManual'; import isUrlCheckFetch from './isUrlCheckFetch'; const statusReducer = combineReducers({ - isCheckUpdateWhenStart, - isDownloadFetch, - isDownloadUpdateWhenStart, isLaunchAppWhenLogin, isOpenWidgetWhenStart, - isRestartAfterUpdate, - isTrayOpen, - isUpdateCheckFetch, - isUpdateCheckOnManual, isUrlCheckFetch, }); diff --git a/app/store/reducers/share/status/isCheckUpdateWhenStart.js b/app/store/reducers/share/status/isCheckUpdateWhenStart.js deleted file mode 100644 index fe6dc4f2..00000000 --- a/app/store/reducers/share/status/isCheckUpdateWhenStart.js +++ /dev/null @@ -1,10 +0,0 @@ -import { handleActions } from 'redux-actions'; -import * as TYPES from 'actions/constant/actionTypes'; - -const initialState = false; - -const isCheckUpdateWhenStartReducer = handleActions({ - [TYPES.UPDATE_SET_AUTO_CHECK_UPDATE]: (state, action) => action.payload.isCheckUpdateWhenStart, -}, initialState); - -export default isCheckUpdateWhenStartReducer; diff --git a/app/store/reducers/share/status/isDownloadFetch.js b/app/store/reducers/share/status/isDownloadFetch.js deleted file mode 100644 index 842c29d5..00000000 --- a/app/store/reducers/share/status/isDownloadFetch.js +++ /dev/null @@ -1,15 +0,0 @@ -import { combineActions, handleActions } from 'redux-actions'; -import * as TYPES from 'actions/constant/actionTypes'; - -const initialState = false; - -const isDownloadFetchReducer = handleActions({ - [TYPES.UPDATE_DOWNLOAD_REQUEST]: () => true, - [combineActions( - TYPES.UPDATE_DOWNLOAD_SUCCESS, - TYPES.UPDATE_DOWNLOAD_FAILURE, - TYPES.SET_INITIAL_STORE, - )]: () => false, -}, initialState); - -export default isDownloadFetchReducer; diff --git a/app/store/reducers/share/status/isDownloadUpdateWhenStart.js b/app/store/reducers/share/status/isDownloadUpdateWhenStart.js deleted file mode 100644 index f9fc65c9..00000000 --- a/app/store/reducers/share/status/isDownloadUpdateWhenStart.js +++ /dev/null @@ -1,10 +0,0 @@ -import { handleActions } from 'redux-actions'; -import * as TYPES from 'actions/constant/actionTypes'; - -const initialState = false; - -const isDownloadUpdateWhenStartReducer = handleActions({ - [TYPES.UPDATE_SET_AUTO_UPDATE]: (state, action) => action.payload.isDownloadUpdateWhenStart, -}, initialState); - -export default isDownloadUpdateWhenStartReducer; diff --git a/app/store/reducers/share/status/isRestartAfterUpdate.js b/app/store/reducers/share/status/isRestartAfterUpdate.js deleted file mode 100644 index 5507e5e2..00000000 --- a/app/store/reducers/share/status/isRestartAfterUpdate.js +++ /dev/null @@ -1,11 +0,0 @@ -import { handleActions } from 'redux-actions'; -import * as TYPES from 'actions/constant/actionTypes'; - -const initialState = false; - -const isRestartAfterUpdateReducer = handleActions({ - [TYPES.UPDATE_DOWNLOAD_SUCCESS]: () => true, - [TYPES.UPDATE_INSTALLING_DOWNLOADED]: () => false, -}, initialState); - -export default isRestartAfterUpdateReducer; diff --git a/app/store/reducers/share/status/isTrayOpen.js b/app/store/reducers/share/status/isTrayOpen.js deleted file mode 100644 index 81eb26b4..00000000 --- a/app/store/reducers/share/status/isTrayOpen.js +++ /dev/null @@ -1,11 +0,0 @@ -import { handleActions } from 'redux-actions'; -import * as TYPES from 'actions/constant/actionTypes'; - -const initialState = false; - -const isTrayOpenReducer = handleActions({ - [TYPES.SEARCH_TRAY_OPEN]: () => true, - [TYPES.SEARCH_TRAY_CLOSE]: () => false, -}, initialState); - -export default isTrayOpenReducer; diff --git a/app/store/reducers/share/status/isUpdateCheckFetch.js b/app/store/reducers/share/status/isUpdateCheckFetch.js deleted file mode 100644 index a12f4b2f..00000000 --- a/app/store/reducers/share/status/isUpdateCheckFetch.js +++ /dev/null @@ -1,18 +0,0 @@ -import { combineActions, handleActions } from 'redux-actions'; -import * as TYPES from 'actions/constant/actionTypes'; - -const initialState = false; - -const isUpdateCheckFetchReducer = handleActions({ - [combineActions( - TYPES.UPDATE_CHECK_REQUEST, - TYPES.UPDATE_CHECK_REQUEST_ON_MANUAL, - )]: () => true, - [combineActions( - TYPES.UPDATE_CHECK_FAILURE, - TYPES.UPDATE_CHECK_SUCCESS, - TYPES.SET_INITIAL_STORE, - )]: () => false, -}, initialState); - -export default isUpdateCheckFetchReducer; diff --git a/app/store/reducers/share/status/isUpdateCheckOnManual.js b/app/store/reducers/share/status/isUpdateCheckOnManual.js deleted file mode 100644 index 35755988..00000000 --- a/app/store/reducers/share/status/isUpdateCheckOnManual.js +++ /dev/null @@ -1,15 +0,0 @@ -import { combineActions, handleActions } from 'redux-actions'; -import * as TYPES from 'actions/constant/actionTypes'; - -const initialState = false; - -const isUpdateCheckOnManualReducer = handleActions({ - [TYPES.UPDATE_CHECK_REQUEST_ON_MANUAL]: () => true, - [combineActions( - TYPES.UPDATE_CHECK_FAILURE, - TYPES.UPDATE_CHECK_SUCCESS, - TYPES.SET_INITIAL_STORE, - )]: () => false, -}, initialState); - -export default isUpdateCheckOnManualReducer; diff --git a/app/store/reducers/share/status/selectors/index.js b/app/store/reducers/share/status/selectors/index.js index c253b381..883f470d 100644 --- a/app/store/reducers/share/status/selectors/index.js +++ b/app/store/reducers/share/status/selectors/index.js @@ -31,26 +31,6 @@ export const isOpenWidgetWhenStartSelector = createSelector( status => status.get('isOpenWidgetWhenStart'), ); -export const isRestartAfterUpdateSelector = createSelector( - statusSelector, - status => status.get('isRestartAfterUpdate'), -); - -export const isTrayOpenSelector = createSelector( - statusSelector, - status => status.get('isTrayOpen'), -); - -export const isUpdateCheckFetchSelector = createSelector( - statusSelector, - status => status.get('isUpdateCheckFetch'), -); - -export const isUpdateCheckOnManualSelector = createSelector( - statusSelector, - status => status.get('isUpdateCheckOnManual'), -); - export const isUrlCheckFetchSelector = createSelector( statusSelector, status => status.get('isUrlCheckFetch'), diff --git a/package.json b/package.json index 86d6dee6..321049fd 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "axios": "^0.18.0", "classnames": "^2.2.6", "css-loader": "^0.28.11", + "debounce": "^1.2.0", "electron-builder-http": "^19.27.5", "electron-updater": "^3.0.3", "flux-standard-action": "^2.0.3", diff --git a/webpack.basic.config.js b/webpack.basic.config.js index 30b75fe5..7674cc32 100644 --- a/webpack.basic.config.js +++ b/webpack.basic.config.js @@ -8,8 +8,6 @@ module.exports = { preloadScript: './app/renderer/pages/widget/preloadScript.js', preference: './app/renderer/pages/preference/index.jsx', search: './app/renderer/pages/search/index.jsx', - updateWindow: './app/renderer/pages/update/UpdateWindow/index.jsx', - updateProgress: './app/renderer/pages/update/UpdateProgress/index.jsx' }, target: 'electron-renderer', module: { @@ -76,18 +74,6 @@ module.exports = { template: path.join(__dirname, './app/renderer/pages/search/search.html'), inject: 'body', }), - new HtmlWebpackPlugin({ - chunks: ['updateWindow'], - filename: 'UpdateWindow.html', - template: path.join(__dirname, './app/renderer/pages/update/UpdateWindow/UpdateWindow.html'), - inject: 'body', - }), - new HtmlWebpackPlugin({ - chunks: ['updateProgress'], - filename: 'UpdateProgress.html', - template: path.join(__dirname, './app/renderer/pages/update/UpdateProgress/UpdateProgress.html'), - inject: 'body', - }), new webpack.DefinePlugin({ 'process.env': { NODE_ENV: JSON.stringify(process.env.NODE_ENV), diff --git a/yarn.lock b/yarn.lock index 92cd41a4..632d9c82 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2577,6 +2577,11 @@ date-now@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" +debounce@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.0.tgz#44a540abc0ea9943018dc0eaa95cce87f65cd131" + integrity sha512-mYtLl1xfZLi1m4RtQYlZgJUNQjl4ZxVnHzIR8nLLgi4q1YT8o/WM+MK/f8yfcc9s5Ir5zRaPZyZU6xs1Syoocg== + debug@2.6.9, debug@^2.1.2, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3, debug@^2.6.6, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"