TidGi-Desktop/src/services/workspaces/getWorkspaceMenuTemplate.ts

188 lines
7.2 KiB
TypeScript

/* 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 { ISyncService } from '@services/sync/interface';
import { SupportedStorageServices } from '@services/types';
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 type { IWorkspaceViewService } from '@services/workspacesView/interface';
import type { MenuItemConstructorOptions } from 'electron';
import type { FlatNamespace, TFunction } from 'i18next';
import type { _DefaultNamespace } from 'react-i18next/TransWithoutContext';
import type { IWorkspace, IWorkspaceService } from './interface';
interface IWorkspaceMenuRequiredServices {
auth: Pick<IAuthenticationService, 'getStorageServiceUserInfo'>;
context: Pick<IContextService, 'isOnline'>;
git: Pick<IGitService, 'commitAndSync'>;
native: Pick<INativeService, 'log' | 'openURI' | 'openPath' | 'openInEditor' | 'openInGitGuiApp' | 'getLocalHostUrlWithActualInfo'>;
pages: Pick<IPagesService, 'setActivePage' | 'getActivePage'>;
sync: Pick<ISyncService, 'syncWikiIfNeeded'>;
view: Pick<IViewService, 'reloadViewsWebContents' | 'getViewCurrentUrl'>;
wiki: Pick<IWikiService, 'wikiOperationInBrowser' | 'wikiOperationInServer'>;
wikiGitWorkspace: Pick<IWikiGitWorkspaceService, 'removeWorkspace'>;
window: Pick<IWindowService, 'open'>;
workspace: Pick<IWorkspaceService, 'getActiveWorkspace' | 'getSubWorkspacesAsList'>;
workspaceView: Pick<
IWorkspaceViewService,
| 'wakeUpWorkspaceView'
| 'hibernateWorkspaceView'
| 'setActiveWorkspaceView'
| 'restartWorkspaceViewService'
| 'realignActiveWorkspace'
| 'openUrlInWorkspace'
| 'openWorkspaceWindowWithView'
>;
}
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>>]>,
service: IWorkspaceMenuRequiredServices,
): Promise<MenuItemConstructorOptions[]> {
const { active, id, hibernated, tagName, isSubWiki, wikiFolderLocation, gitUrl, storageService, port, name, enableHTTPAPI, lastUrl, homeUrl } = workspace;
/* eslint-disable @typescript-eslint/no-misused-promises */
const template: MenuItemConstructorOptions[] = [
{
label: t('WorkspaceSelector.OpenWorkspaceTagTiddler', {
tagName: tagName ?? (isSubWiki ? name : `${name} ${t('WorkspaceSelector.DefaultTiddlers')}`),
}),
click: async () => {
await openWorkspaceTagTiddler(workspace, service);
},
},
{
label: t('ContextMenu.OpenWorkspaceInNewWindow'),
enabled: !hibernated,
click: async () => {
await service.workspaceView.openWorkspaceWindowWithView(workspace, { uri: lastUrl ?? homeUrl });
},
},
{
label: t('WorkspaceSelector.EditWorkspace'),
click: async () => {
await service.window.open(WindowNames.editWorkspace, { workspaceID: id });
},
},
{
label: t('WorkspaceSelector.RemoveWorkspace'),
click: async () => {
await service.wikiGitWorkspace.removeWorkspace(id);
},
},
{
label: t('WorkspaceSelector.OpenWorkspaceFolder'),
click: async () => {
await service.native.openPath(wikiFolderLocation);
},
},
{
label: t('WorkspaceSelector.OpenWorkspaceFolderInEditor'),
click: async () => await service.native.openInEditor(wikiFolderLocation),
},
{
label: t('WorkspaceSelector.OpenWorkspaceFolderInGitGUI'),
click: async () => await service.native.openInGitGuiApp(wikiFolderLocation),
},
{
label: `${t('WorkspaceSelector.OpenInBrowser')}${enableHTTPAPI ? '' : t('WorkspaceSelector.OpenInBrowserDisabledHint')}`,
enabled: enableHTTPAPI,
click: async () => {
const actualIP = await service.native.getLocalHostUrlWithActualInfo(getDefaultHTTPServerIP(port), id);
await service.native.openURI(actualIP);
},
},
];
if (gitUrl !== null && gitUrl.length > 0 && storageService !== SupportedStorageServices.local) {
const userInfo = await service.auth.getStorageServiceUserInfo(storageService);
if (userInfo !== undefined) {
const isOnline = await service.context.isOnline();
template.push({
label: t('ContextMenu.SyncNow') + (isOnline ? '' : `(${t('ContextMenu.NoNetworkConnection')})`),
enabled: isOnline,
click: async () => {
await service.sync.syncWikiIfNeeded(workspace);
},
});
}
}
if (storageService === SupportedStorageServices.local) {
template.push({
label: t('ContextMenu.BackupNow'),
click: async () => {
await service.sync.syncWikiIfNeeded(workspace);
},
});
}
if (!isSubWiki) {
template.push(
{
label: t('ContextMenu.RestartService'),
click: async () => {
await service.workspaceView.restartWorkspaceViewService(id);
await service.workspaceView.realignActiveWorkspace(id);
},
},
{
label: t('ContextMenu.Reload'),
click: async () => {
await service.view.reloadViewsWebContents(id);
},
},
);
}
if (!active && !isSubWiki) {
// This is rarely used, put in the middle.
template.splice(3, 0, {
label: hibernated ? t('WorkspaceSelector.WakeUpWorkspace') : t('WorkspaceSelector.HibernateWorkspace'),
click: async () => {
if (hibernated) {
await service.workspaceView.wakeUpWorkspaceView(id);
return;
}
await service.workspaceView.hibernateWorkspaceView(id);
},
});
}
/* eslint-enable @typescript-eslint/no-misused-promises */
return template;
}