mirror of
https://github.com/tiddly-gittly/TidGi-Desktop.git
synced 2025-12-05 18:20:39 -08:00
feat: deeplink
This commit is contained in:
parent
bf8a2995b6
commit
bd2b8a4449
12 changed files with 153 additions and 43 deletions
|
|
@ -89,6 +89,7 @@ const config = {
|
|||
executableName: 'tidgi',
|
||||
config: {
|
||||
maintainer: 'Lin Onetwo <linonetwo012@gmail.com>',
|
||||
mimeType: ['x-scheme-handler/tidgi'],
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -97,6 +98,7 @@ const config = {
|
|||
executableName: 'tidgi',
|
||||
config: {
|
||||
maintainer: 'Lin Onetwo <linonetwo012@gmail.com>',
|
||||
mimeType: ['x-scheme-handler/tidgi'],
|
||||
},
|
||||
},
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import serviceIdentifier from '@services/serviceIdentifier';
|
|||
import { WindowNames } from '@services/windows/WindowProperties';
|
||||
|
||||
import { IDatabaseService } from '@services/database/interface';
|
||||
import { IDeepLinkService } from '@services/deepLink/interface';
|
||||
import { initializeObservables } from '@services/libs/initializeObservables';
|
||||
import { reportErrorToGithubWithTemplates } from '@services/native/reportError';
|
||||
import type { IUpdaterService } from '@services/updater/interface';
|
||||
|
|
@ -51,8 +52,6 @@ protocol.registerSchemesAsPrivileged([
|
|||
{ scheme: 'file', privileges: { bypassCSP: true, allowServiceWorkers: true, supportFetchAPI: true, corsEnabled: true, stream: true } },
|
||||
{ scheme: 'mailto', privileges: { standard: true } },
|
||||
]);
|
||||
// TODO: handle workspace name + tiddler name in uri https://www.electronjs.org/docs/latest/tutorial/launch-app-from-url-in-another-app
|
||||
app.setAsDefaultProtocolClient('tidgi');
|
||||
bindServiceAndProxy();
|
||||
const preferenceService = container.get<IPreferenceService>(serviceIdentifier.Preference);
|
||||
const updaterService = container.get<IUpdaterService>(serviceIdentifier.Updater);
|
||||
|
|
@ -61,6 +60,7 @@ const wikiService = container.get<IWikiService>(serviceIdentifier.Wiki);
|
|||
const windowService = container.get<IWindowService>(serviceIdentifier.Window);
|
||||
const workspaceViewService = container.get<IWorkspaceViewService>(serviceIdentifier.WorkspaceView);
|
||||
const databaseService = container.get<IDatabaseService>(serviceIdentifier.Database);
|
||||
const deepLinkService = container.get<IDeepLinkService>(serviceIdentifier.DeepLink);
|
||||
app.on('second-instance', async () => {
|
||||
// see also src/helpers/singleInstance.ts
|
||||
// Someone tried to run a second instance, for example, when `runOnBackground` is true, we should focus our window.
|
||||
|
|
@ -83,6 +83,8 @@ void preferenceService.get('ignoreCertificateErrors').then((ignoreCertificateErr
|
|||
const commonInit = async (): Promise<void> => {
|
||||
await app.whenReady();
|
||||
// if user want a menubar, we create a new window for that
|
||||
// handle workspace name + tiddler name in uri https://www.electronjs.org/docs/latest/tutorial/launch-app-from-url-in-another-app
|
||||
deepLinkService.initializeDeepLink('tidgi');
|
||||
await Promise.all([
|
||||
windowService.open(WindowNames.main),
|
||||
preferenceService.get('attachToMenubar').then(async (attachToMenubar) => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useSortable } from '@dnd-kit/sortable';
|
||||
import { CSS } from '@dnd-kit/utilities';
|
||||
import { getWorkspaceMenuTemplate, openWorkspaceTagTiddler } from '@services/workspaces/getWorkspaceMenuTemplate';
|
||||
import { getWorkspaceMenuTemplate } from '@services/workspaces/getWorkspaceMenuTemplate';
|
||||
import { IWorkspaceWithMetadata } from '@services/workspaces/interface';
|
||||
import { MouseEvent, useCallback, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
|
@ -31,7 +31,7 @@ export function SortableWorkspaceSelectorButton({ index, workspace, showSidebarT
|
|||
workspaceClickedLoadingSetter(true);
|
||||
try {
|
||||
setLocation(`/${WindowNames.main}/${PageType.wiki}/${id}/`);
|
||||
await openWorkspaceTagTiddler(workspace, window.service);
|
||||
await window.service.workspace.openWorkspaceTiddler(workspace);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
await window.service.native.log('error', error.message);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { AsyncifyProxy } from 'electron-ipc-cat/common';
|
|||
|
||||
import { AuthenticationServiceIPCDescriptor, IAuthenticationService } from '@services/auth/interface';
|
||||
import { ContextServiceIPCDescriptor, IContextService } from '@services/context/interface';
|
||||
import { DeepLinkServiceIPCDescriptor, IDeepLinkService } from '@services/deepLink/interface';
|
||||
import { GitServiceIPCDescriptor, IGitService } from '@services/git/interface';
|
||||
import { IMenuService, MenuServiceIPCDescriptor } from '@services/menu/interface';
|
||||
import { INativeService, NativeServiceIPCDescriptor } from '@services/native/interface';
|
||||
|
|
@ -44,6 +45,7 @@ export const wikiGitWorkspace = createProxy<IWikiGitWorkspaceService>(WikiGitWor
|
|||
export const window = createProxy<IWindowService>(WindowServiceIPCDescriptor);
|
||||
export const workspace = createProxy<AsyncifyProxy<IWorkspaceService>>(WorkspaceServiceIPCDescriptor);
|
||||
export const workspaceView = createProxy<IWorkspaceViewService>(WorkspaceViewServiceIPCDescriptor);
|
||||
export const deepLink = createProxy<IDeepLinkService>(DeepLinkServiceIPCDescriptor);
|
||||
|
||||
export const descriptors = {
|
||||
auth: AuthenticationServiceIPCDescriptor,
|
||||
|
|
@ -64,4 +66,5 @@ export const descriptors = {
|
|||
window: WindowServiceIPCDescriptor,
|
||||
workspace: WorkspaceServiceIPCDescriptor,
|
||||
workspaceView: WorkspaceViewServiceIPCDescriptor,
|
||||
deepLink: DeepLinkServiceIPCDescriptor,
|
||||
};
|
||||
|
|
|
|||
73
src/services/deepLink/index.ts
Normal file
73
src/services/deepLink/index.ts
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
import { lazyInject } from '@services/container';
|
||||
import { logger } from '@services/libs/log';
|
||||
import serviceIdentifier from '@services/serviceIdentifier';
|
||||
import { IWorkspaceService } from '@services/workspaces/interface';
|
||||
import { app } from 'electron';
|
||||
import { injectable } from 'inversify';
|
||||
import path from 'node:path';
|
||||
import { IDeepLinkService } from './interface';
|
||||
|
||||
@injectable()
|
||||
export class DeepLinkService implements IDeepLinkService {
|
||||
@lazyInject(serviceIdentifier.Workspace)
|
||||
private readonly workspaceService!: IWorkspaceService;
|
||||
|
||||
/**
|
||||
* Handle link and open the workspace.
|
||||
* @param requestUrl like `tidgi://lxqsftvfppu_z4zbaadc0/#:Index` or `tidgi://lxqsftvfppu_z4zbaadc0/#%E6%96%B0%E6%9D%A1%E7%9B%AE`
|
||||
*/
|
||||
private readonly deepLinkHandler: (requestUrl: string) => Promise<void> = async (requestUrl) => {
|
||||
logger.info(`Receiving deep link`, { requestUrl, function: 'deepLinkHandler' });
|
||||
const url = new URL(requestUrl);
|
||||
const workspaceId = url.hostname;
|
||||
const workspace = await this.workspaceService.get(workspaceId);
|
||||
if (workspace === undefined) {
|
||||
logger.error(`Workspace not found`, { workspaceId, function: 'deepLinkHandler' });
|
||||
return;
|
||||
}
|
||||
let tiddlerName = url.hash.substring(1); // remove '#:'
|
||||
if (tiddlerName.includes(':')) {
|
||||
tiddlerName = tiddlerName.split(':')[1];
|
||||
}
|
||||
logger.info(`Open deep link`, { workspaceId, tiddlerName, function: 'deepLinkHandler' });
|
||||
await this.workspaceService.openWorkspaceTiddler(workspace, tiddlerName);
|
||||
};
|
||||
|
||||
public initializeDeepLink(protocol: string) {
|
||||
if (process.defaultApp) {
|
||||
if (process.argv.length >= 2) {
|
||||
app.setAsDefaultProtocolClient(protocol, process.execPath, [path.resolve(process.argv[1])]);
|
||||
}
|
||||
} else {
|
||||
app.setAsDefaultProtocolClient(protocol);
|
||||
}
|
||||
|
||||
if (process.platform === 'darwin') {
|
||||
this.setupMacOSHandler();
|
||||
} else {
|
||||
this.setupWindowsLinuxHandler();
|
||||
}
|
||||
}
|
||||
|
||||
private setupMacOSHandler(): void {
|
||||
app.on('open-url', (event, url) => {
|
||||
event.preventDefault();
|
||||
this.deepLinkHandler(url);
|
||||
});
|
||||
}
|
||||
|
||||
private setupWindowsLinuxHandler(): void {
|
||||
const gotTheLock = app.requestSingleInstanceLock();
|
||||
|
||||
if (gotTheLock) {
|
||||
app.on('second-instance', (event, commandLine) => {
|
||||
const url = commandLine.pop();
|
||||
if (url !== undefined && url !== '') {
|
||||
this.deepLinkHandler(url);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
app.quit();
|
||||
}
|
||||
}
|
||||
}
|
||||
16
src/services/deepLink/interface.ts
Normal file
16
src/services/deepLink/interface.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { ProxyPropertyType } from 'electron-ipc-cat/common';
|
||||
|
||||
export interface IDeepLinkService {
|
||||
/**
|
||||
* Initialize deep link service.
|
||||
* @param protocol The protocol to be used for deep linking.
|
||||
*/
|
||||
initializeDeepLink(protocol: string): void;
|
||||
}
|
||||
|
||||
export const DeepLinkServiceIPCDescriptor = {
|
||||
channel: 'DeepLinkChannel',
|
||||
properties: {
|
||||
initializeDeepLink: ProxyPropertyType.Function,
|
||||
},
|
||||
};
|
||||
|
|
@ -9,6 +9,7 @@ import serviceIdentifier from '@services/serviceIdentifier';
|
|||
import { Authentication } from '@services/auth';
|
||||
import { ContextService } from '@services/context';
|
||||
import { DatabaseService } from '@services/database';
|
||||
import { DeepLinkService } from '@services/deepLink';
|
||||
import { Git } from '@services/git';
|
||||
import { MenuService } from '@services/menu';
|
||||
import { NativeService } from '@services/native';
|
||||
|
|
@ -32,6 +33,8 @@ import type { IContextService } from '@services/context/interface';
|
|||
import { ContextServiceIPCDescriptor } from '@services/context/interface';
|
||||
import type { IDatabaseService } from '@services/database/interface';
|
||||
import { DatabaseServiceIPCDescriptor } from '@services/database/interface';
|
||||
import type { IDeepLinkService } from '@services/deepLink/interface';
|
||||
import { DeepLinkServiceIPCDescriptor } from '@services/deepLink/interface';
|
||||
import type { IGitService } from '@services/git/interface';
|
||||
import { GitServiceIPCDescriptor } from '@services/git/interface';
|
||||
import type { IMenuService } from '@services/menu/interface';
|
||||
|
|
@ -85,6 +88,7 @@ export function bindServiceAndProxy(): void {
|
|||
container.bind<IWindowService>(serviceIdentifier.Window).to(Window).inSingletonScope();
|
||||
container.bind<IWorkspaceService>(serviceIdentifier.Workspace).to(Workspace).inSingletonScope();
|
||||
container.bind<IWorkspaceViewService>(serviceIdentifier.WorkspaceView).to(WorkspaceView).inSingletonScope();
|
||||
container.bind<IDeepLinkService>(serviceIdentifier.DeepLink).to(DeepLinkService).inSingletonScope();
|
||||
|
||||
const authService = container.get<IAuthenticationService>(serviceIdentifier.Authentication);
|
||||
const contextService = container.get<IContextService>(serviceIdentifier.Context);
|
||||
|
|
@ -105,6 +109,7 @@ export function bindServiceAndProxy(): void {
|
|||
const windowService = container.get<IWindowService>(serviceIdentifier.Window);
|
||||
const workspaceService = container.get<IWorkspaceService>(serviceIdentifier.Workspace);
|
||||
const workspaceViewService = container.get<IWorkspaceViewService>(serviceIdentifier.WorkspaceView);
|
||||
const deepLinkService = container.get<IDeepLinkService>(serviceIdentifier.DeepLink);
|
||||
|
||||
registerProxy(authService, AuthenticationServiceIPCDescriptor);
|
||||
registerProxy(contextService, ContextServiceIPCDescriptor);
|
||||
|
|
@ -125,4 +130,5 @@ export function bindServiceAndProxy(): void {
|
|||
registerProxy(windowService, WindowServiceIPCDescriptor);
|
||||
registerProxy(workspaceService, WorkspaceServiceIPCDescriptor);
|
||||
registerProxy(workspaceViewService, WorkspaceViewServiceIPCDescriptor);
|
||||
registerProxy(deepLinkService, DeepLinkServiceIPCDescriptor);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,13 +12,12 @@ import type { IPagesService } from '@services/pages/interface';
|
|||
import type { IPreferenceService } from '@services/preferences/interface';
|
||||
import serviceIdentifier from '@services/serviceIdentifier';
|
||||
import { ISyncService } from '@services/sync/interface';
|
||||
import type { IUpdaterService } from '@services/updater/interface';
|
||||
import type { IViewService } from '@services/view/interface';
|
||||
import type { IWikiService } from '@services/wiki/interface';
|
||||
import type { IWikiGitWorkspaceService } from '@services/wikiGitWorkspace/interface';
|
||||
import type { IWindowService } from '@services/windows/interface';
|
||||
import { WindowNames } from '@services/windows/WindowProperties';
|
||||
import { getWorkspaceMenuTemplate, openWorkspaceTagTiddler } from '@services/workspaces/getWorkspaceMenuTemplate';
|
||||
import { getWorkspaceMenuTemplate } from '@services/workspaces/getWorkspaceMenuTemplate';
|
||||
import type { IWorkspaceService } from '@services/workspaces/interface';
|
||||
import type { IWorkspaceViewService } from '@services/workspacesView/interface';
|
||||
import { app, ContextMenuParams, Menu, MenuItem, MenuItemConstructorOptions, shell, WebContents } from 'electron';
|
||||
|
|
@ -51,9 +50,6 @@ export class MenuService implements IMenuService {
|
|||
@lazyInject(serviceIdentifier.Preference)
|
||||
private readonly preferenceService!: IPreferenceService;
|
||||
|
||||
@lazyInject(serviceIdentifier.Updater)
|
||||
private readonly updaterService!: IUpdaterService;
|
||||
|
||||
@lazyInject(serviceIdentifier.View)
|
||||
private readonly viewService!: IViewService;
|
||||
|
||||
|
|
@ -384,7 +380,7 @@ export class MenuService implements IMenuService {
|
|||
tagName: workspace.tagName ?? (workspace.isSubWiki ? workspace.name : `${workspace.name} ${i18n.t('WorkspaceSelector.DefaultTiddlers')}`),
|
||||
}),
|
||||
click: async () => {
|
||||
await openWorkspaceTagTiddler(workspace, services);
|
||||
await this.workspaceService.openWorkspaceTiddler(workspace);
|
||||
},
|
||||
})),
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -18,4 +18,5 @@ export default {
|
|||
Window: Symbol.for('Window'),
|
||||
Workspace: Symbol.for('Workspace'),
|
||||
WorkspaceView: Symbol.for('WorkspaceView'),
|
||||
DeepLink: Symbol.for('DeepLinkService'),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
/* eslint-disable @typescript-eslint/strict-boolean-expressions */
|
||||
import { WikiChannel } from '@/constants/channels';
|
||||
import { getDefaultHTTPServerIP } from '@/constants/urls';
|
||||
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 { IPagesService } from '@services/pages/interface';
|
||||
import { ISyncService } from '@services/sync/interface';
|
||||
import { SupportedStorageServices } from '@services/types';
|
||||
import type { IViewService } from '@services/view/interface';
|
||||
|
|
@ -30,7 +29,7 @@ interface IWorkspaceMenuRequiredServices {
|
|||
wiki: Pick<IWikiService, 'wikiOperationInBrowser' | 'wikiOperationInServer'>;
|
||||
wikiGitWorkspace: Pick<IWikiGitWorkspaceService, 'removeWorkspace'>;
|
||||
window: Pick<IWindowService, 'open'>;
|
||||
workspace: Pick<IWorkspaceService, 'getActiveWorkspace' | 'getSubWorkspacesAsList'>;
|
||||
workspace: Pick<IWorkspaceService, 'getActiveWorkspace' | 'getSubWorkspacesAsList' | 'openWorkspaceTiddler'>;
|
||||
workspaceView: Pick<
|
||||
IWorkspaceViewService,
|
||||
| 'wakeUpWorkspaceView'
|
||||
|
|
@ -43,33 +42,6 @@ interface IWorkspaceMenuRequiredServices {
|
|||
>;
|
||||
}
|
||||
|
||||
export async function openWorkspaceTagTiddler(workspace: IWorkspace, service: IWorkspaceMenuRequiredServices): Promise<void> {
|
||||
const { id: idToActive, isSubWiki, tagName, mainWikiID } = workspace;
|
||||
// switch to workspace page
|
||||
const [oldActiveWorkspace] = await Promise.all([
|
||||
service.workspace.getActiveWorkspace(),
|
||||
service.pages.setActivePage(PageType.wiki),
|
||||
service.native.log('debug', 'openWorkspaceTagTiddler', { workspace }),
|
||||
]);
|
||||
// if is a new main workspace, active its browser view first
|
||||
if (!isSubWiki && idToActive) {
|
||||
if (oldActiveWorkspace?.id !== idToActive) {
|
||||
await service.workspaceView.setActiveWorkspaceView(idToActive);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// is not a new main workspace
|
||||
// open tiddler in the active view
|
||||
if (isSubWiki && mainWikiID) {
|
||||
if (oldActiveWorkspace?.id !== mainWikiID) {
|
||||
await service.workspaceView.setActiveWorkspaceView(mainWikiID);
|
||||
}
|
||||
if (tagName) {
|
||||
await service.wiki.wikiOperationInBrowser(WikiChannel.openTiddler, mainWikiID, [tagName]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function getWorkspaceMenuTemplate(
|
||||
workspace: IWorkspace,
|
||||
t: TFunction<[_DefaultNamespace, ...Array<Exclude<FlatNamespace, _DefaultNamespace>>]>,
|
||||
|
|
@ -83,7 +55,7 @@ export async function getWorkspaceMenuTemplate(
|
|||
tagName: tagName ?? (isSubWiki ? name : `${name} ${t('WorkspaceSelector.DefaultTiddlers')}`),
|
||||
}),
|
||||
click: async () => {
|
||||
await openWorkspaceTagTiddler(workspace, service);
|
||||
await service.workspace.openWorkspaceTiddler(workspace);
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import path from 'path';
|
|||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { WikiChannel } from '@/constants/channels';
|
||||
import { DELAY_MENU_REGISTER } from '@/constants/parameters';
|
||||
import { getDefaultTidGiUrl } from '@/constants/urls';
|
||||
import { IAuthenticationService } from '@services/auth/interface';
|
||||
|
|
@ -20,7 +21,7 @@ import { IDatabaseService } from '@services/database/interface';
|
|||
import { i18n } from '@services/libs/i18n';
|
||||
import { logger } from '@services/libs/log';
|
||||
import type { IMenuService } from '@services/menu/interface';
|
||||
import { IPagesService } from '@services/pages/interface';
|
||||
import { IPagesService, PageType } from '@services/pages/interface';
|
||||
import serviceIdentifier from '@services/serviceIdentifier';
|
||||
import { SupportedStorageServices } from '@services/types';
|
||||
import type { IViewService } from '@services/view/interface';
|
||||
|
|
@ -167,7 +168,13 @@ export class Workspace implements IWorkspaceService {
|
|||
}
|
||||
|
||||
private getSync(id: string): IWorkspace | undefined {
|
||||
return this.getWorkspacesSync()[id];
|
||||
const workspaces = this.getWorkspacesSync();
|
||||
if (id in workspaces) {
|
||||
return workspaces[id];
|
||||
}
|
||||
// Try find with lowercased key. sometimes user will use id that is all lowercased. Because tidgi:// url is somehow lowercased.
|
||||
const foundKey = Object.keys(workspaces).find((key) => key.toLowerCase() === id.toLowerCase());
|
||||
return foundKey ? workspaces[foundKey] : undefined;
|
||||
}
|
||||
|
||||
public get$(id: string): Observable<IWorkspace | undefined> {
|
||||
|
|
@ -470,4 +477,31 @@ export class Workspace implements IWorkspaceService {
|
|||
const workspaceMetaData = this.getMetaDataSync(id);
|
||||
return typeof workspaceMetaData?.didFailLoadErrorMessage === 'string' && workspaceMetaData.didFailLoadErrorMessage.length > 0;
|
||||
}
|
||||
|
||||
public async openWorkspaceTiddler(workspace: IWorkspace, title?: string): Promise<void> {
|
||||
const { id: idToActive, isSubWiki, mainWikiID } = workspace;
|
||||
const oldActiveWorkspace = await this.getActiveWorkspace();
|
||||
await this.pagesService.setActivePage(PageType.wiki);
|
||||
logger.log('debug', 'openWorkspaceTiddler', { workspace });
|
||||
// If is main wiki, open the wiki, and open provided title, or simply switch to it if no title provided
|
||||
if (!isSubWiki && idToActive) {
|
||||
if (oldActiveWorkspace?.id !== idToActive) {
|
||||
await this.workspaceViewService.setActiveWorkspaceView(idToActive);
|
||||
}
|
||||
if (title) {
|
||||
await this.wikiService.wikiOperationInBrowser(WikiChannel.openTiddler, idToActive, [title]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// If is sub wiki, open the main wiki first and open the tag or provided title
|
||||
if (isSubWiki && mainWikiID) {
|
||||
if (oldActiveWorkspace?.id !== mainWikiID) {
|
||||
await this.workspaceViewService.setActiveWorkspaceView(mainWikiID);
|
||||
}
|
||||
const subWikiTag = title ?? workspace.tagName;
|
||||
if (subWikiTag) {
|
||||
await this.wikiService.wikiOperationInBrowser(WikiChannel.openTiddler, mainWikiID, [subWikiTag]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -203,6 +203,10 @@ export interface IWorkspaceService {
|
|||
getWorkspaces(): Promise<Record<string, IWorkspace>>;
|
||||
getWorkspacesAsList(): Promise<IWorkspace[]>;
|
||||
getWorkspacesWithMetadata(): IWorkspacesWithMetadata;
|
||||
/**
|
||||
* Open a tiddler in the workspace, open workspace's tag by default.
|
||||
*/
|
||||
openWorkspaceTiddler(workspace: IWorkspace, title?: string): Promise<void>;
|
||||
remove(id: string): Promise<void>;
|
||||
removeWorkspacePicture(id: string): Promise<void>;
|
||||
set(id: string, workspace: IWorkspace, immediate?: boolean): Promise<void>;
|
||||
|
|
@ -241,6 +245,7 @@ export const WorkspaceServiceIPCDescriptor = {
|
|||
getWorkspaces: ProxyPropertyType.Function,
|
||||
getWorkspacesAsList: ProxyPropertyType.Function,
|
||||
getWorkspacesWithMetadata: ProxyPropertyType.Function,
|
||||
openWorkspaceTiddler: ProxyPropertyType.Function,
|
||||
remove: ProxyPropertyType.Function,
|
||||
removeWorkspacePicture: ProxyPropertyType.Function,
|
||||
set: ProxyPropertyType.Function,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue