From 96c2ebc98629aef555adafa91b06b85870ea37ee Mon Sep 17 00:00:00 2001 From: tiddlygit-test Date: Fri, 5 Feb 2021 00:07:53 +0800 Subject: [PATCH] refactor: workspace senders --- .../existed-wiki-path-form.tsx | 5 +-- src/components/dialog-add-workspace/index.tsx | 5 ++- .../new-wiki-path-form.tsx | 6 ++-- src/components/dialog-preferences/index.tsx | 2 +- src/constants/channels.ts | 1 - src/main.ts | 2 +- src/preload/view.ts | 1 - src/preload/wiki-git-api.ts | 28 --------------- src/senders/index.ts | 20 ----------- src/services/git/index.ts | 5 +++ src/services/git/inspect.ts | 9 +++-- src/services/git/interface.ts | 3 ++ src/services/libs/bindServiceAndProxy.ts | 4 +-- src/services/preferences/index.ts | 34 ++----------------- src/services/workspacesView/index.ts | 26 +++++++++++--- src/services/workspacesView/interface.ts | 2 ++ src/state/dialog-add-workspace/actions.ts | 23 +++++++------ src/state/dialog-edit-workspace/reducers.ts | 6 ++-- src/state/workspace-metas/reducers.ts | 8 ++--- src/state/workspaces/reducers.ts | 9 +++-- 20 files changed, 74 insertions(+), 125 deletions(-) delete mode 100644 src/preload/wiki-git-api.ts diff --git a/src/components/dialog-add-workspace/existed-wiki-path-form.tsx b/src/components/dialog-add-workspace/existed-wiki-path-form.tsx index ab5375f2..a618c0a4 100644 --- a/src/components/dialog-add-workspace/existed-wiki-path-form.tsx +++ b/src/components/dialog-add-workspace/existed-wiki-path-form.tsx @@ -15,7 +15,6 @@ import MenuItem from '@material-ui/core/MenuItem'; import FolderIcon from '@material-ui/icons/Folder'; import Autocomplete from '@material-ui/lab/Autocomplete'; import * as actions from '../../state/dialog-add-workspace/actions'; -import { getWorkspaces } from '../../senders'; const CreateContainer: ComponentType<{}> = styled(Paper)` margin-top: 5px; `; @@ -83,7 +82,9 @@ function WikiPathForm({ }: Props) { const [workspaces, workspacesSetter] = useState({}); useEffect(() => { - workspacesSetter(getWorkspaces()); + void (async () => { + workspacesSetter(await window.service.workspace.getWorkspaces()); + })(); }, []); const hasError = wikiCreationMessage.startsWith('Error'); const { t } = useTranslation(); diff --git a/src/components/dialog-add-workspace/index.tsx b/src/components/dialog-add-workspace/index.tsx index 4d26c311..79a5b38d 100644 --- a/src/components/dialog-add-workspace/index.tsx +++ b/src/components/dialog-add-workspace/index.tsx @@ -88,14 +88,13 @@ export default function AddWorkspace() { }, [mainWikiToLink]); const [githubWikiUrl, githubWikiUrlSetter] = useState(''); useEffect(() => { - async function getWorkspaceRemoteInEffect(): Promise { + void (async function getWorkspaceRemoteInEffect(): Promise { const url = await window.service.git.getWorkspacesRemote(existedFolderLocation); // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions if (url) { githubWikiUrlSetter(url); } - } - void getWorkspaceRemoteInEffect(); + })(); }, [githubWikiUrl, existedFolderLocation]); const [wikiFolderName, wikiFolderNameSetter] = useState('tiddlywiki'); diff --git a/src/components/dialog-add-workspace/new-wiki-path-form.tsx b/src/components/dialog-add-workspace/new-wiki-path-form.tsx index fcfab0d5..a70507b0 100644 --- a/src/components/dialog-add-workspace/new-wiki-path-form.tsx +++ b/src/components/dialog-add-workspace/new-wiki-path-form.tsx @@ -15,7 +15,7 @@ import MenuItem from '@material-ui/core/MenuItem'; import FolderIcon from '@material-ui/icons/Folder'; import Autocomplete from '@material-ui/lab/Autocomplete'; import * as actions from '../../state/dialog-add-workspace/actions'; -import { getWorkspaces } from '../../senders'; + const CreateContainer: ComponentType<{}> = styled(Paper)` margin-top: 5px; `; @@ -82,7 +82,9 @@ function NewWikiPathForm({ }: Props) { const [workspaces, workspacesSetter] = useState({}); useEffect(() => { - workspacesSetter(getWorkspaces()); + void (async () => { + workspacesSetter(await window.service.workspace.getWorkspaces()); + })(); }, []); const hasError = wikiCreationMessage.startsWith('Error'); const { t } = useTranslation(); diff --git a/src/components/dialog-preferences/index.tsx b/src/components/dialog-preferences/index.tsx index 422e2dd3..e257e919 100644 --- a/src/components/dialog-preferences/index.tsx +++ b/src/components/dialog-preferences/index.tsx @@ -1142,7 +1142,7 @@ const Preferences = ({ - + diff --git a/src/constants/channels.ts b/src/constants/channels.ts index 3e7bec4b..c2fc6167 100644 --- a/src/constants/channels.ts +++ b/src/constants/channels.ts @@ -51,7 +51,6 @@ export enum PreferenceChannel { update = 'update', getPreference = 'get-preference', getPreferences = 'get-preferences', - requestClearBrowsingData = 'request-clear-browsing-data', } export enum WindowChannel { diff --git a/src/main.ts b/src/main.ts index 25b62e5c..bd7222dd 100755 --- a/src/main.ts +++ b/src/main.ts @@ -52,7 +52,7 @@ const gotTheLock = app.requestSingleInstanceLock(); container.bind(serviceIdentifier.Authentication).to(Authentication).inSingletonScope(); container.bind(serviceIdentifier.Git).to(Git).inSingletonScope(); container.bind(serviceIdentifier.MenuService).to(MenuService).inSingletonScope(); -container.bind(serviceIdentifier.Notification).to(NotificationService).inSingletonScope(); +container.bind(serviceIdentifier.NotificationService).to(NotificationService).inSingletonScope(); container.bind(serviceIdentifier.NativeService).to(NativeService).inSingletonScope(); container.bind(serviceIdentifier.Preference).to(Preference).inSingletonScope(); container.bind(serviceIdentifier.SystemPreference).to(SystemPreference).inSingletonScope(); diff --git a/src/preload/view.ts b/src/preload/view.ts index 2ec2c0e5..bd6ff889 100644 --- a/src/preload/view.ts +++ b/src/preload/view.ts @@ -3,7 +3,6 @@ import { enable as enableDarkMode, disable as disableDarkMode } from 'darkreader import ContextMenuBuilder from '@services/libs/context-menu-builder'; import i18next from '@services/libs/i18n'; import './wiki-operation'; -import './wiki-git-api'; import { preference } from './common/services'; const { MenuItem, shell } = remote; diff --git a/src/preload/wiki-git-api.ts b/src/preload/wiki-git-api.ts deleted file mode 100644 index 0d379a7d..00000000 --- a/src/preload/wiki-git-api.ts +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Provide API from electron to tiddlywiki - * This file should be required by view.ts preload script to work - */ -import { contextBridge } from 'electron'; - -import { container } from '@services/container'; -import { getModifiedFileList } from '@services/git/inspect'; -import type { IGitService } from '@services/git/interface'; -import type { IWorkspaceService } from '@services/workspaces/interface'; -import type { IAuthenticationService } from '@services/auth/interface'; -import serviceIdentifier from '@services/serviceIdentifier'; - -contextBridge.exposeInMainWorld('git', { - getModifiedFileList, - commitAndSync: (wikiPath: string, githubRepoUrl: string) => { - const gitService = container.get(serviceIdentifier.Git); - const authService = container.get(serviceIdentifier.Authentication); - const userInfo = authService.get('authing'); - if (userInfo !== undefined) { - return gitService.commitAndSync(wikiPath, githubRepoUrl, userInfo); - } - }, - getWorkspacesAsList: () => { - const workspaceService = container.get(serviceIdentifier.Workspace); - return workspaceService.getWorkspacesAsList(); - }, -}); diff --git a/src/senders/index.ts b/src/senders/index.ts index cce0c912..508b7a85 100644 --- a/src/senders/index.ts +++ b/src/senders/index.ts @@ -12,22 +12,6 @@ export const getShouldUseDarkColors = async (): Promise => { await ipcRenderer.invoke('get-should-use-dark-colors'); }; -// Workspace -export const getWorkspace = (id: string) => ipcRenderer.invokeSync('get-workspace', id); -export const getWorkspaces = () => ipcRenderer.invokeSync('get-workspaces'); -export const requestClearBrowsingData = async () => await ipcRenderer.invoke('request-clear-browsing-data'); -export const requestCreateWorkspace = async ( - name: string, - isSubWiki: boolean, - mainWikiToLink: string, - port: number, - homeUrl: string, - gitUrl: string, - picture: string, - transparentBackground: boolean, - tagName: string, -) => await ipcRenderer.invoke('request-create-workspace', name, isSubWiki, mainWikiToLink, port, homeUrl, gitUrl, picture, transparentBackground, tagName); - export const requestHibernateWorkspace = async (id: string) => await ipcRenderer.invoke('request-hibernate-workspace', id); export const requestOpenUrlInWorkspace = async (url: string, id: string) => await ipcRenderer.invoke('request-open-url-in-workspace', url, id); export const requestRealignActiveWorkspace = async () => await ipcRenderer.invoke('request-realign-active-workspace'); @@ -51,10 +35,6 @@ export const getIsDevelopment = () => ipcRenderer.invokeSync('get-constant', 'is export const getBaseName = (pathString: string): string => ipcRenderer.invokeSync('get-basename', pathString); export const getDirectoryName = (pathString: string): string => ipcRenderer.invokeSync('get-dirname', pathString); -// Workspace Meta -export const getWorkspaceMeta = (id: string) => ipcRenderer.invokeSync('get-workspace-meta', id); -export const getWorkspaceMetas = () => ipcRenderer.invokeSync('get-workspace-metas'); - // Find In Page export const requestFindInPage = async (text: string, forward: boolean) => await ipcRenderer.invoke('request-find-in-page', text, !!forward); export const requestStopFindInPage = async (close: boolean) => await ipcRenderer.invoke('request-stop-find-in-page', !!close); diff --git a/src/services/git/index.ts b/src/services/git/index.ts index 0501a03f..410e49b6 100644 --- a/src/services/git/index.ts +++ b/src/services/git/index.ts @@ -12,6 +12,7 @@ import type { IPreferenceService } from '@services/preferences/interface'; import { logger } from '@services/libs/log'; import i18n from '@services/libs/i18n'; import { IUserInfo } from '@services/types'; +import { getModifiedFileList, ModifiedFileList } from './inspect'; import { IGitService } from './interface'; @injectable() @@ -32,6 +33,10 @@ export class Git implements IGitService { return await github.getRemoteUrl(wikiFolderPath); } + public async getModifiedFileList(wikiFolderPath: string): Promise { + return await getModifiedFileList(wikiFolderPath); + } + /** * * @param {string} githubRepoName similar to "linonetwo/wiki", string after "https://github.com/" diff --git a/src/services/git/inspect.ts b/src/services/git/inspect.ts index 79c94fb9..58d750be 100644 --- a/src/services/git/inspect.ts +++ b/src/services/git/inspect.ts @@ -2,11 +2,16 @@ import path from 'path'; import { compact } from 'lodash'; import { GitProcess } from 'dugite'; +export interface ModifiedFileList { + type: string; + fileRelativePath: string; + filePath: string; +} /** * Get modified files and modify type in a folder * @param {string} wikiFolderPath location to scan git modify state */ -async function getModifiedFileList(wikiFolderPath: string): Promise> { +export async function getModifiedFileList(wikiFolderPath: string): Promise { const { stdout } = await GitProcess.exec(['status', '--porcelain'], wikiFolderPath); const stdoutLines = stdout.split('\n'); return compact(compact(stdoutLines).map((line) => /^\s?(\?\?|[ACMR]|[ACMR][DM])\s?(\S+)$/.exec(line))).map(([_, type, fileRelativePath]) => ({ @@ -15,5 +20,3 @@ async function getModifiedFileList(wikiFolderPath: string): Promise Promise | undefined; updateGitInfoTiddler(githubRepoName: string): Promise; + getModifiedFileList(wikiFolderPath: string): Promise; initWikiGit(wikiFolderPath: string, githubRepoUrl: string, userInfo: IUserInfo, isMainWiki: boolean): Promise; commitAndSync(wikiFolderPath: string, githubRepoUrl: string, userInfo: IUserInfo): Promise; getWorkspacesRemote(wikiFolderPath: string): Promise; @@ -19,6 +21,7 @@ export const GitServiceIPCDescriptor = { properties: { debounceCommitAndSync: ProxyPropertyType.Function, updateGitInfoTiddler: ProxyPropertyType.Function, + getModifiedFileList: ProxyPropertyType.Function, initWikiGit: ProxyPropertyType.Function, commitAndSync: ProxyPropertyType.Function, getWorkspacesRemote: ProxyPropertyType.Function, diff --git a/src/services/libs/bindServiceAndProxy.ts b/src/services/libs/bindServiceAndProxy.ts index 0ea46759..e329e757 100644 --- a/src/services/libs/bindServiceAndProxy.ts +++ b/src/services/libs/bindServiceAndProxy.ts @@ -43,7 +43,7 @@ container.bind(serviceIdentifier.Context).to(ContextService).in container.bind(serviceIdentifier.Git).to(Git).inSingletonScope(); container.bind(serviceIdentifier.MenuService).to(MenuService).inSingletonScope(); container.bind(serviceIdentifier.NativeService).to(NativeService).inSingletonScope(); -container.bind(serviceIdentifier.Notification).to(NotificationService).inSingletonScope(); +container.bind(serviceIdentifier.NotificationService).to(NotificationService).inSingletonScope(); container.bind(serviceIdentifier.Preference).to(Preference).inSingletonScope(); container.bind(serviceIdentifier.SystemPreference).to(SystemPreference).inSingletonScope(); container.bind(serviceIdentifier.Updater).to(Updater).inSingletonScope(); @@ -60,7 +60,7 @@ const contextService = container.get(serviceIdentifier.Context) const gitService = container.get(serviceIdentifier.Git); const menuService = container.get(serviceIdentifier.MenuService); const nativeService = container.get(serviceIdentifier.NativeService); -const notificationService = container.get(serviceIdentifier.Notification); +const notificationService = container.get(serviceIdentifier.NotificationService); const preferenceService = container.get(serviceIdentifier.Preference); const systemPreferenceService = container.get(serviceIdentifier.SystemPreference); const viewService = container.get(serviceIdentifier.View); diff --git a/src/services/preferences/index.ts b/src/services/preferences/index.ts index e09ab232..eb831df6 100755 --- a/src/services/preferences/index.ts +++ b/src/services/preferences/index.ts @@ -1,6 +1,6 @@ import { injectable } from 'inversify'; import getDecorators from 'inversify-inject-decorators'; -import { app, App, remote, ipcMain, dialog } from 'electron'; +import { app, App, remote, dialog } from 'electron'; import path from 'path'; import semver from 'semver'; import settings from 'electron-settings'; @@ -85,43 +85,13 @@ const defaultPreferences: IPreferences = { @injectable() export class Preference implements IPreferenceService { @lazyInject(serviceIdentifier.Window) private readonly windowService!: IWindowService; - @lazyInject(serviceIdentifier.Notification) private readonly notificationService!: INotificationService; - @lazyInject(serviceIdentifier.WorkspaceView) private readonly workspaceViewService!: IWorkspaceViewService; + @lazyInject(serviceIdentifier.NotificationService) private readonly notificationService!: INotificationService; cachedPreferences: IPreferences; readonly version = '2018.2'; constructor() { this.cachedPreferences = this.getInitPreferencesForCache(); - this.init(); - } - - init(): void { - ipcMain.handle(PreferenceChannel.requestClearBrowsingData, () => { - const availableWindowToShowDialog = this.windowService.get(WindowNames.preferences) ?? this.windowService.get(WindowNames.main); - if (availableWindowToShowDialog !== undefined) { - dialog - .showMessageBox(availableWindowToShowDialog, { - type: 'question', - buttons: [i18n.t('Preference.ResetNow'), i18n.t('Cancel')], - message: i18n.t('Preference.ClearBrowsingDataMessage'), - cancelId: 1, - }) - .then(({ response }) => { - if (response === 0) { - return this.workspaceViewService.clearBrowsingData(); - } - }) - .catch(console.error); - } - }); - - ipcMain.handle(PreferenceChannel.getPreference, (_event, name: keyof IPreferences) => { - return this.get(name); - }); - ipcMain.handle(PreferenceChannel.getPreferences, (_event) => { - return this.cachedPreferences; - }); } public async resetWithConfirm(): Promise { diff --git a/src/services/workspacesView/index.ts b/src/services/workspacesView/index.ts index ef23bbb2..c02ac28c 100644 --- a/src/services/workspacesView/index.ts +++ b/src/services/workspacesView/index.ts @@ -1,7 +1,8 @@ -import { app, ipcMain, session } from 'electron'; +import { app, ipcMain, session, dialog } from 'electron'; import { injectable, inject } from 'inversify'; import serviceIdentifier from '@services/serviceIdentifier'; +import i18n from '@services/libs/i18n'; import type { IViewService } from '@services/view/interface'; import type { IWorkspaceService, IWorkspace } from '@services/workspaces/interface'; import type { IWindowService } from '@services/windows/interface'; @@ -22,10 +23,6 @@ export class WorkspaceView implements IWorkspaceViewService { } private initIPCHandlers(): void { - ipcMain.handle('request-create-workspace', async (_event, workspaceOptions: IWorkspace) => { - await this.createWorkspaceView(workspaceOptions); - this.menuService.buildMenu(); - }); ipcMain.handle('request-set-active-workspace', async (_event, id) => { if (this.workspaceService.get(id) !== undefined) { await this.setActiveWorkspaceView(id); @@ -169,6 +166,25 @@ export class WorkspaceView implements IWorkspaceViewService { this.viewService.removeView(id); } + public async clearBrowsingDataWithConfirm(): Promise { + const availableWindowToShowDialog = this.windowService.get(WindowNames.preferences) ?? this.windowService.get(WindowNames.main); + if (availableWindowToShowDialog !== undefined) { + await dialog + .showMessageBox(availableWindowToShowDialog, { + type: 'question', + buttons: [i18n.t('Preference.ResetNow'), i18n.t('Cancel')], + message: i18n.t('Preference.ClearBrowsingDataMessage'), + cancelId: 1, + }) + .then(({ response }) => { + if (response === 0) { + return this.clearBrowsingData(); + } + }) + .catch(console.error); + } + } + public async clearBrowsingData(): Promise { await session.defaultSession.clearStorageData(); const workspaces = this.workspaceService.getWorkspaces(); diff --git a/src/services/workspacesView/interface.ts b/src/services/workspacesView/interface.ts index c94bf57c..4dbf7d86 100644 --- a/src/services/workspacesView/interface.ts +++ b/src/services/workspacesView/interface.ts @@ -15,6 +15,7 @@ export interface IWorkspaceViewService { setActiveWorkspaceView(id: string): Promise; removeWorkspaceView(id: string): Promise; clearBrowsingData(): Promise; + clearBrowsingDataWithConfirm(): Promise; /** * Try load url, if no id or no active workspace, then nothing will happened * @param url url to load @@ -34,6 +35,7 @@ export const WorkspaceViewServiceIPCDescriptor = { setActiveWorkspaceView: ProxyPropertyType.Function, removeWorkspaceView: ProxyPropertyType.Function, clearBrowsingData: ProxyPropertyType.Function, + clearBrowsingDataWithConfirm: ProxyPropertyType.Function, loadURL: ProxyPropertyType.Function, realignActiveWorkspace: ProxyPropertyType.Function, }, diff --git a/src/state/dialog-add-workspace/actions.ts b/src/state/dialog-add-workspace/actions.ts index 34e0e170..8e0c318f 100755 --- a/src/state/dialog-add-workspace/actions.ts +++ b/src/state/dialog-add-workspace/actions.ts @@ -8,7 +8,6 @@ import validate from '../../helpers/validate'; import isUrl from '../../helpers/is-url'; import hasErrors from '../../helpers/has-errors'; -import { requestCreateWorkspace } from '../../senders'; import i18n from 'i18next'; export const setWikiCreationMessage = (message: string) => ({ @@ -52,17 +51,19 @@ export const save = () => async (dispatch: any, getState: any) => { const url = form.homeUrl.trim(); const homeUrl = isUrl(url) ? url : `http://${url}`; - await requestCreateWorkspace( - form.name, - form.isSubWiki, - form.mainWikiToLink, - form.port, + // FIXME: maybe use createWorkspace instead? + await window.service.workspaceView.createWorkspaceView({ + name: form.name, + isSubWiki: form.isSubWiki, + mainWikiToLink: form.mainWikiToLink, + port: form.port, homeUrl, - form.gitUrl, - form.internetIcon || form.picturePath, - Boolean(form.transparentBackground), - form.tagName, - ); + gitUrl: form.gitUrl, + picturePath: form.internetIcon || form.picturePath, + transparentBackground: Boolean(form.transparentBackground), + tagName: form.tagName, + }); + await window.service.menu.buildMenu(); if (!form.isSubWiki) { dispatch(setWikiCreationMessage(i18n.t('AddWorkspace.WorkspaceUpdated'))); // and wiki will be closed after wiki server started, close logic is inside wiki-worker-manager.js diff --git a/src/state/dialog-edit-workspace/reducers.ts b/src/state/dialog-edit-workspace/reducers.ts index 482a7948..ac1d3c74 100644 --- a/src/state/dialog-edit-workspace/reducers.ts +++ b/src/state/dialog-edit-workspace/reducers.ts @@ -2,13 +2,11 @@ import { combineReducers } from 'redux'; import { DIALOG_EDIT_WORKSPACE_INIT, UPDATE_EDIT_WORKSPACE_DOWNLOADING_ICON, UPDATE_EDIT_WORKSPACE_FORM } from '../../constants/actions'; -import { getWorkspaces } from '../../senders'; - -const form = (state = {}, action: any) => { +const form = async (state = {}, action: any) => { switch (action.type) { case DIALOG_EDIT_WORKSPACE_INIT: { const editWorkspaceId = window.remote.getGlobal('editWorkspaceId'); - const workspaces = getWorkspaces(); + const workspaces = await window.service.workspace.getWorkspaces(); const workspaceList = Object.values(workspaces); const workspace = workspaces[editWorkspaceId]; workspaceList.some((item, index) => { diff --git a/src/state/workspace-metas/reducers.ts b/src/state/workspace-metas/reducers.ts index 9cccd5dd..ef3d4b4e 100644 --- a/src/state/workspace-metas/reducers.ts +++ b/src/state/workspace-metas/reducers.ts @@ -1,10 +1,10 @@ import { SET_WORKSPACE_META, SET_WORKSPACE_METAS } from '../../constants/actions'; -import { getWorkspaceMetas } from '../../senders'; -const initialState = getWorkspaceMetas(); - -const workspaceMetas = (state = initialState, action: any) => { +const workspaceMetas = async (state, action: any) => { + if (state === undefined) { + state = await window.service.workspace.getAllMetaData() + } switch (action.type) { case SET_WORKSPACE_METAS: { return action.workspaceMetas; diff --git a/src/state/workspaces/reducers.ts b/src/state/workspaces/reducers.ts index 053679a7..a1e8baef 100644 --- a/src/state/workspaces/reducers.ts +++ b/src/state/workspaces/reducers.ts @@ -1,10 +1,9 @@ import { SET_WORKSPACE, SET_WORKSPACES } from '../../constants/actions'; -import { getWorkspaces } from '../../senders'; - -const initialState = getWorkspaces(); - -const workspaces = (state = initialState, action: any) => { +const workspaces = async (state = initialState, action: any) => { + if (state === undefined) { + state = await window.service.workspace.getWorkspaces(); + } switch (action.type) { case SET_WORKSPACES: { return action.workspaces;