feat: switch to page and hide wiki browserView

This commit is contained in:
lin onetwo 2023-07-08 17:39:26 +08:00
parent 5ef24b10c8
commit aefd9dcd88
9 changed files with 79 additions and 44 deletions

View file

@ -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]);

View file

@ -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 <div>{t('Loading')}</div>;
const { sidebar, themeSource } = preferences;
return (
<>
<InnerContentRoot>

View file

@ -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,

View file

@ -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<IPage[]>;
@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<void> {
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<void> {

View file

@ -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<void> {
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
}
}
}

View file

@ -40,6 +40,7 @@ export interface IViewService {
getView: (workspaceID: string, windowName: WindowNames) => BrowserView | undefined;
getViewCount(): Promise<number>;
getViewCurrentUrl(workspaceID?: string): Promise<string | undefined>;
hideView(browserWindow: BrowserWindow): Promise<void>;
/**
* 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,

View file

@ -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<IContextService, 'isOnline'>;
git: Pick<IGitService, 'commitAndSync'>;
native: Pick<INativeService, 'open' | 'openInEditor' | 'openInGitGuiApp' | 'getLocalHostUrlWithActualInfo'>;
pages: Pick<IPagesService, 'setActivePage' | 'getActivePage'>;
view: Pick<IViewService, 'reloadViewsWebContents' | 'getViewCurrentUrl'>;
wiki: Pick<IWikiService, 'wikiOperation' | 'requestWikiSendActionMessage'>;
wikiGitWorkspace: Pick<IWikiGitWorkspaceService, 'removeWorkspace'>;
@ -38,6 +40,9 @@ interface IWorkspaceMenuRequiredServices {
export async function openWorkspaceTagTiddler(workspace: IWorkspace, service: IWorkspaceMenuRequiredServices): Promise<void> {
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) {

View file

@ -393,6 +393,28 @@ export class WorkspaceView implements IWorkspaceViewService {
}
}
public async clearActiveWorkspaceView(idToDeactivate?: string): Promise<void> {
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<void> {
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<void> {
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 */
}

View file

@ -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<void>;
clearBrowsingData(): Promise<void>;
clearBrowsingDataWithConfirm(): Promise<void>;
hibernateWorkspaceView(id: string): Promise<void>;