diff --git a/src/components/PageIconAndSelector/SortablePageSelectorButton.tsx b/src/components/PageIconAndSelector/SortablePageSelectorButton.tsx index 0c4ecfe8..9a8911d1 100644 --- a/src/components/PageIconAndSelector/SortablePageSelectorButton.tsx +++ b/src/components/PageIconAndSelector/SortablePageSelectorButton.tsx @@ -40,7 +40,7 @@ export function SortablePageSelectorButton({ index, page, showSidebarTexts, page } } pageClickedLoadingSetter(false); - }, [type]); + }, [id, setLocation, type]); const name = useMemo(() => { return getBuildInPageName(type, t); }, [type, t]); diff --git a/src/pages/Workflow/index.tsx b/src/pages/Workflow/index.tsx index cb30ded0..e03a6090 100644 --- a/src/pages/Workflow/index.tsx +++ b/src/pages/Workflow/index.tsx @@ -1,16 +1,8 @@ /* eslint-disable @typescript-eslint/strict-boolean-expressions */ /* eslint-disable @typescript-eslint/promise-function-async */ -import { Typography } from '@material-ui/core'; import { useTranslation } from 'react-i18next'; import styled from 'styled-components'; -import { usePreferenceObservable } from '@services/preferences/hooks'; -import { useWorkspacesListObservable } from '@services/workspaces/hooks'; -import { useState } from 'react'; -import { useAutoCreateFirstWorkspace } from '../Main/useAutoCreateFirstWorkspace'; -import { Languages } from '../Preferences/sections/Languages'; -import { TiddlyWiki } from '../Preferences/sections/TiddlyWiki'; - const InnerContentRoot = styled.div` flex: 1; display: flex; @@ -24,21 +16,6 @@ const InnerContentRoot = styled.div` export default function Workflow(): JSX.Element { const { t } = useTranslation(); - const workspacesList = useWorkspacesListObservable(); - - const activeWorkspaceMetadata = workspacesList - ?.map((workspace) => ({ active: workspace.active, ...workspace.metadata })) - ?.find((workspace) => workspace.active); - const activeWorkspace = workspacesList?.find((workspace) => workspace.active); - const hasError = typeof activeWorkspaceMetadata?.didFailLoadErrorMessage === 'string' && - activeWorkspaceMetadata?.didFailLoadErrorMessage.length > 0 && - activeWorkspaceMetadata?.isLoading === false; - const [wikiCreationMessage, wikiCreationMessageSetter] = useState(''); - useAutoCreateFirstWorkspace(workspacesList, wikiCreationMessageSetter); - const preferences = usePreferenceObservable(); - if (preferences === undefined) return
{t('Loading')}
; - - const { sidebar, themeSource } = preferences; return ( <> diff --git a/src/services/menu/index.ts b/src/services/menu/index.ts index 39a22b8c..40ed898d 100644 --- a/src/services/menu/index.ts +++ b/src/services/menu/index.ts @@ -7,6 +7,7 @@ import type { IGitService } from '@services/git/interface'; import { i18n } from '@services/libs/i18n'; import { logger } from '@services/libs/log'; import type { INativeService } from '@services/native/interface'; +import type { IPagesService } from '@services/pages/interface'; import type { IPreferenceService } from '@services/preferences/interface'; import serviceIdentifier from '@services/serviceIdentifier'; import type { IUpdaterService } from '@services/updater/interface'; @@ -38,6 +39,9 @@ export class MenuService implements IMenuService { @lazyInject(serviceIdentifier.Git) private readonly gitService!: IGitService; + @lazyInject(serviceIdentifier.Pages) + private readonly pagesService!: IPagesService; + @lazyInject(serviceIdentifier.NativeService) private readonly nativeService!: INativeService; @@ -403,6 +407,7 @@ export class MenuService implements IMenuService { context: this.contextService, git: this.gitService, native: this.nativeService, + pages: this.pagesService, view: this.viewService, wiki: this.wikiService, wikiGitWorkspace: this.wikiGitWorkspaceService, diff --git a/src/services/pages/index.ts b/src/services/pages/index.ts index 441a1384..bbbf663d 100644 --- a/src/services/pages/index.ts +++ b/src/services/pages/index.ts @@ -5,10 +5,8 @@ import { debounce, pickBy } from 'lodash'; import { lazyInject } from '@services/container'; import { logger } from '@services/libs/log'; -import { IPreferenceService } from '@services/preferences/interface'; import serviceIdentifier from '@services/serviceIdentifier'; -import { IWindowService } from '@services/windows/interface'; -import { IWorkspaceService } from '@services/workspaces/interface'; +import { IWorkspaceViewService } from '@services/workspacesView/interface'; import { BehaviorSubject } from 'rxjs'; import { debouncedSetSettingFile } from './debouncedSetSettingFile'; import { defaultBuildInPages } from './defaultBuildInPages'; @@ -23,14 +21,8 @@ export class Pages implements IPagesService { public pages$: BehaviorSubject; - @lazyInject(serviceIdentifier.Workspace) - private readonly workspaceService!: IWorkspaceService; - - @lazyInject(serviceIdentifier.Window) - private readonly windowService!: IWindowService; - - @lazyInject(serviceIdentifier.Preference) - private readonly preferenceService!: IPreferenceService; + @lazyInject(serviceIdentifier.WorkspaceView) + private readonly workspaceViewService!: IWorkspaceViewService; constructor() { this.pages = this.getInitPagesForCache(); @@ -55,13 +47,12 @@ export class Pages implements IPagesService { public async setActivePage(id: string | PageType, oldActivePageID: string | PageType | undefined): Promise { logger.info(`openPage: ${id}`); - await this.update(id, { active: true }); - if (oldActivePageID !== id) { - await this.clearActivePage(oldActivePageID); - } - // switch from workspace to page , clear active workspace to close its browser view - const activeWorkspace = this.workspaceService.getActiveWorkspaceSync(); - await this.workspaceService.clearActiveWorkspace(activeWorkspace?.id); + await Promise.all([ + this.update(id, { active: true }), + oldActivePageID !== id && this.clearActivePage(oldActivePageID), + // if not switch to wiki page, e.g. switch from workspace to workflow page, clear active workspace and close its browser view + id !== PageType.wiki && this.workspaceViewService.clearActiveWorkspaceView(), + ]); } public async clearActivePage(id: string | PageType | undefined): Promise { diff --git a/src/services/view/index.ts b/src/services/view/index.ts index ec893916..471b37c1 100644 --- a/src/services/view/index.ts +++ b/src/services/view/index.ts @@ -565,7 +565,7 @@ export class View implements IViewService { const contentSize = browserWindow.getContentSize(); if (await this.workspaceService.workspaceDidFailLoad(activeId)) { logger.warn(`realignActiveView() hide because didFailLoad`); - view?.setBounds(await getViewBounds(contentSize as [number, number], false, 0, 0)); // hide browserView to show error message + await this.hideView(browserWindow); } else { logger.debug(`realignActiveView() contentSize set to ${JSON.stringify(contentSize)}`); view?.setBounds(await getViewBounds(contentSize as [number, number])); @@ -582,4 +582,12 @@ export class View implements IViewService { setTimeout(() => void this.realignActiveView(browserWindow, activeId, true), 1000); } }; + + public async hideView(browserWindow: BrowserWindow): Promise { + const view = browserWindow.getBrowserView(); + if (view !== null) { + const contentSize = browserWindow.getContentSize(); + view?.setBounds(await getViewBounds(contentSize as [number, number], false, 0, 0)); // hide browserView to show error message or other pages + } + } } diff --git a/src/services/view/interface.ts b/src/services/view/interface.ts index 003133d9..2a2b0be5 100644 --- a/src/services/view/interface.ts +++ b/src/services/view/interface.ts @@ -40,6 +40,7 @@ export interface IViewService { getView: (workspaceID: string, windowName: WindowNames) => BrowserView | undefined; getViewCount(): Promise; getViewCurrentUrl(workspaceID?: string): Promise; + hideView(browserWindow: BrowserWindow): Promise; /** * Try catch loadUrl, other wise it will throw unhandled promise rejection Error: ERR_CONNECTION_REFUSED (-102) loading 'http://localhost:5212/ * We will set `didFailLoadErrorMessage`, it will set didFailLoadErrorMessage, and we throw actuarial error after that @@ -74,6 +75,7 @@ export const ViewServiceIPCDescriptor = { getView: ProxyPropertyType.Function, getViewCount: ProxyPropertyType.Function, getViewCurrentUrl: ProxyPropertyType.Function, + hideView: ProxyPropertyType.Function, realignActiveView: ProxyPropertyType.Function, reloadActiveBrowserView: ProxyPropertyType.Function, reloadViewsWebContents: ProxyPropertyType.Function, diff --git a/src/services/workspaces/getWorkspaceMenuTemplate.ts b/src/services/workspaces/getWorkspaceMenuTemplate.ts index dce03823..fad3d83d 100644 --- a/src/services/workspaces/getWorkspaceMenuTemplate.ts +++ b/src/services/workspaces/getWorkspaceMenuTemplate.ts @@ -4,6 +4,7 @@ import type { IAuthenticationService } from '@services/auth/interface'; import { IContextService } from '@services/context/interface'; import { IGitService } from '@services/git/interface'; import type { INativeService } from '@services/native/interface'; +import { IPagesService, PageType } from '@services/pages/interface'; import { SupportedStorageServices } from '@services/types'; import type { IViewService } from '@services/view/interface'; import type { IWikiService } from '@services/wiki/interface'; @@ -20,6 +21,7 @@ interface IWorkspaceMenuRequiredServices { context: Pick; git: Pick; native: Pick; + pages: Pick; view: Pick; wiki: Pick; wikiGitWorkspace: Pick; @@ -38,6 +40,9 @@ interface IWorkspaceMenuRequiredServices { export async function openWorkspaceTagTiddler(workspace: IWorkspace, service: IWorkspaceMenuRequiredServices): Promise { const { id: idToActive, isSubWiki, tagName, mainWikiID } = workspace; + // switch to workspace page + const oldActivePage = await service.pages.getActivePage(); + await service.pages.setActivePage(PageType.wiki, oldActivePage?.id); const oldActiveWorkspace = await service.workspace.getActiveWorkspace(); // if is a new main workspace, active its browser view first if (!isSubWiki && idToActive !== null && idToActive !== undefined && oldActiveWorkspace?.id !== idToActive) { diff --git a/src/services/workspacesView/index.ts b/src/services/workspacesView/index.ts index 363d2218..f1b8e167 100644 --- a/src/services/workspacesView/index.ts +++ b/src/services/workspacesView/index.ts @@ -393,6 +393,28 @@ export class WorkspaceView implements IWorkspaceViewService { } } + public async clearActiveWorkspaceView(idToDeactivate?: string): Promise { + const activeWorkspace = idToDeactivate === undefined ? await this.workspaceService.getActiveWorkspace() : await this.workspaceService.get(idToDeactivate); + await this.workspaceService.clearActiveWorkspace(activeWorkspace?.id); + if (activeWorkspace === undefined) { + return; + } + if (activeWorkspace.isSubWiki && typeof activeWorkspace.mainWikiID === 'string') { + logger.debug(`${activeWorkspace.id} is a subwiki, set its main wiki ${activeWorkspace.mainWikiID} to deactivated instead.`, { function: 'clearActiveWorkspaceView' }); + await this.clearActiveWorkspaceView(activeWorkspace.mainWikiID); + return; + } + try { + await this.hideWorkspaceView(); + } catch (error) { + logger.error(`Error while setActiveWorkspaceView(): ${(error as Error).message}`, error); + throw error; + } + if (activeWorkspace.hibernateWhenUnused) { + await this.hibernateWorkspaceView(activeWorkspace.id); + } + } + public async removeWorkspaceView(workspaceID: string): Promise { const mainWindow = this.windowService.get(WindowNames.main); // if there's only one workspace left, clear all @@ -549,6 +571,27 @@ export class WorkspaceView implements IWorkspaceViewService { } await Promise.all(tasks); } - /* eslint-enable @typescript-eslint/strict-boolean-expressions */ } + + private async hideWorkspaceView(): Promise { + const mainWindow = this.windowService.get(WindowNames.main); + const menuBarWindow = this.windowService.get(WindowNames.menuBar); + const mainBrowserViewWebContent = mainWindow?.getBrowserView()?.webContents; + const menuBarBrowserViewWebContent = menuBarWindow?.getBrowserView()?.webContents; + const tasks = []; + if (mainBrowserViewWebContent) { + tasks.push(this.viewService.hideView(mainWindow)); + logger.debug(`hideActiveWorkspaceView: hide main window browserView.`); + } else { + logger.warn(`hideActiveWorkspaceView: no mainBrowserViewWebContent, skip main window browserView.`); + } + if (menuBarBrowserViewWebContent) { + logger.debug(`hideActiveWorkspaceView: hide menu bar window browserView.`); + tasks.push(this.viewService.hideView(menuBarWindow)); + } else { + logger.info(`hideActiveWorkspaceView: no menuBarBrowserViewWebContent, skip menu bar window browserView.`); + } + await Promise.all(tasks); + } + /* eslint-enable @typescript-eslint/strict-boolean-expressions */ } diff --git a/src/services/workspacesView/interface.ts b/src/services/workspacesView/interface.ts index 9849900c..03b9df93 100644 --- a/src/services/workspacesView/interface.ts +++ b/src/services/workspacesView/interface.ts @@ -22,6 +22,10 @@ export interface IInitializeWorkspaceOptions { * Deal with operations that needs to create a workspace and a browserView at once */ export interface IWorkspaceViewService { + /** + * Hide BrowserView, so page below it will show up. + */ + clearActiveWorkspaceView(): Promise; clearBrowsingData(): Promise; clearBrowsingDataWithConfirm(): Promise; hibernateWorkspaceView(id: string): Promise;