Fix/sub wiki tag tree (#667)

* fix: different out path on macos

* fix: let go hibernation promise, so it's faster on macos

* log marker [test-id-TIDGI_MINI_WINDOW_CREATED]

* Skip registerShortcutByKey  in test

* fix: mini window on mac

* Remove useless log marker

* Update handleAttachToTidgiMiniWindow.ts

* fix: log marker check all log files

* lint

* fix: open in new window now showing wiki title

* Update package.json

* feat: basic load and save to sub wiki using in-tag-tree-of

* fix: load sub-wiki content and prevent echo

* fix: test and ui logic

* test: refactor subwiki test logic to a file

* refactor: shorten steps by using dedicated step, and test underlying micro steps

* fix: review

* refactor: remove outdated method signature

* test: unit cover adaptor subwiki routing

* Update FileSystemAdaptor.routing.test.ts

* fix: merge issue
This commit is contained in:
lin onetwo 2025-12-07 03:31:34 +08:00 committed by GitHub
parent 8a84d9b468
commit c2be8e4186
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
57 changed files with 2176 additions and 414 deletions

View file

@ -22,6 +22,7 @@ import { isWikiWorkspace } from '@services/workspaces/interface';
import { DELAY_MENU_REGISTER } from '@/constants/parameters';
import type { ISyncService } from '@services/sync/interface';
import { workspaceSorter } from '@services/workspaces/utilities';
import type { IInitializeWorkspaceOptions, IWorkspaceViewService } from './interface';
import { registerMenu } from './registerMenu';
import { getTidgiMiniWindowTargetWorkspace } from './utilities';
@ -49,9 +50,8 @@ export class WorkspaceView implements IWorkspaceViewService {
workspacesList.filter((workspace) => isWikiWorkspace(workspace) && !workspace.isSubWiki && !workspace.pageType).forEach((workspace) => {
wikiService.setWikiStartLockOn(workspace.id);
});
// sorting (-1 will make a in the front, b in the back)
const sortedList = workspacesList
.sort((a, b) => a.order - b.order) // sort by order, 1-2<0, so first will be the first
.sort(workspaceSorter)
.sort((a, b) => (a.active && !b.active ? -1 : 0)) // put active wiki first
.sort((a, b) => (isWikiWorkspace(a) && a.isSubWiki && (!isWikiWorkspace(b) || !b.isSubWiki) ? -1 : 0)); // put subwiki on top, they can't restart wiki, so need to sync them first, then let main wiki restart the wiki // revert this after tw can reload tid from fs
await mapSeries(sortedList, async (workspace) => {
@ -361,13 +361,21 @@ export class WorkspaceView implements IWorkspaceViewService {
if (isWikiWorkspace(newWorkspace) && newWorkspace.isSubWiki && typeof newWorkspace.mainWikiID === 'string') {
logger.debug(`${nextWorkspaceID} is a subwiki, set its main wiki ${newWorkspace.mainWikiID} to active instead.`);
await this.setActiveWorkspaceView(newWorkspace.mainWikiID);
if (typeof newWorkspace.tagName === 'string') {
await container.get<IWikiService>(serviceIdentifier.Wiki).wikiOperationInBrowser(WikiChannel.openTiddler, newWorkspace.mainWikiID, [newWorkspace.tagName]);
// Open the first tag if available
if (newWorkspace.tagNames.length > 0) {
await container.get<IWikiService>(serviceIdentifier.Wiki).wikiOperationInBrowser(WikiChannel.openTiddler, newWorkspace.mainWikiID, [newWorkspace.tagNames[0]]);
}
return;
}
// later process will use the current active workspace
await container.get<IWorkspaceService>(serviceIdentifier.Workspace).setActiveWorkspace(nextWorkspaceID, oldActiveWorkspace?.id);
// Schedule hibernation of old workspace before waking up new workspace
// This prevents blocking when wakeUp calls loadURL
if (oldActiveWorkspace !== undefined && oldActiveWorkspace.id !== nextWorkspaceID) {
void this.hibernateWorkspace(oldActiveWorkspace.id);
}
if (isWikiWorkspace(newWorkspace) && newWorkspace.hibernated) {
await this.wakeUpWorkspaceView(nextWorkspaceID);
}
@ -383,6 +391,12 @@ export class WorkspaceView implements IWorkspaceViewService {
}
try {
// Schedule hibernation of old workspace before loading new workspace
// This prevents blocking on loadURL and allows faster UI updates
if (oldActiveWorkspace !== undefined && oldActiveWorkspace.id !== nextWorkspaceID) {
void this.hibernateWorkspace(oldActiveWorkspace.id);
}
await container.get<IViewService>(serviceIdentifier.View).setActiveViewForAllBrowserViews(nextWorkspaceID);
await this.realignActiveWorkspace(nextWorkspaceID);
} catch (error) {
@ -392,13 +406,18 @@ export class WorkspaceView implements IWorkspaceViewService {
});
throw error;
}
// if we are switching to a new workspace, we hide and/or hibernate old view, and activate new view
// This must happen after view setup succeeds to avoid issues with workspace that hasn't started yet
if (oldActiveWorkspace !== undefined && oldActiveWorkspace.id !== nextWorkspaceID) {
await this.hideWorkspaceView(oldActiveWorkspace.id);
if (isWikiWorkspace(oldActiveWorkspace) && oldActiveWorkspace.hibernateWhenUnused) {
await this.hibernateWorkspaceView(oldActiveWorkspace.id);
}
}
/**
* This promise could be `void` to let go, not blocking other logic like switch to new workspace, and hibernate workspace on background.
*/
private async hibernateWorkspace(workspaceID: string): Promise<void> {
const workspace = await container.get<IWorkspaceService>(serviceIdentifier.Workspace).get(workspaceID);
if (workspace === undefined) return;
await this.hideWorkspaceView(workspaceID);
if (isWikiWorkspace(workspace) && workspace.hibernateWhenUnused) {
await this.hibernateWorkspaceView(workspaceID);
}
}