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('
- App Version -
- - -{text.appVersion}
- - -- Oh-My-Desk v.{newVersion} {text.downloadNotice} -
-- {currentProgress}MB / {totalProgress}MB -
- -- Oh-My-Desk v. - - is Downloading. -
-- 0 - MB / - 0 - MB -
- -- Oh-My-Desk v. - - is Downloading. -
-- 0 - MB / - 0 - MB -
- -{text.updateNotice}({currentVersion} {'=>'} {newVersion})
-- {text.updateContent} -
- - -- A new version of Oh My Desk is available! - ( - - => - - ) -
-- Update Content -
- - -