mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 21:27:20 +00:00
feat(editor): add more open doc options to editor toolbar (#9588)
fix AF-2036, AF-2092
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { TagService } from '@affine/core/modules/tag';
|
||||
import { WorkspaceService } from '@affine/core/modules/workspace';
|
||||
import { isNewTabTrigger } from '@affine/core/utils';
|
||||
import { inferOpenMode } from '@affine/core/utils';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { AllDocsIcon } from '@blocksuite/icons/rc';
|
||||
import { useLiveData, useService } from '@toeverything/infra';
|
||||
@@ -36,10 +36,9 @@ export const EmptyDocs = ({
|
||||
|
||||
const onCreate = useCallback(
|
||||
(e: MouseEvent) => {
|
||||
const doc = pageHelper.createPage(
|
||||
undefined,
|
||||
isNewTabTrigger(e) ? 'new-tab' : true
|
||||
);
|
||||
const doc = pageHelper.createPage(undefined, {
|
||||
at: inferOpenMode(e),
|
||||
});
|
||||
|
||||
if (tag) tag.tag(doc.id);
|
||||
},
|
||||
|
||||
@@ -53,13 +53,13 @@ import { extendEdgelessPreviewSpec } from './specs/custom/root-block';
|
||||
import {
|
||||
patchDocModeService,
|
||||
patchEdgelessClipboard,
|
||||
patchEmbedLinkedDocBlockConfig,
|
||||
patchForAttachmentEmbedViews,
|
||||
patchForClipboardInElectron,
|
||||
patchForMobile,
|
||||
patchForSharedPage,
|
||||
patchGenerateDocUrlExtension,
|
||||
patchNotificationService,
|
||||
patchOpenDocExtension,
|
||||
patchParseDocUrlExtension,
|
||||
patchPeekViewService,
|
||||
patchQuickSearchService,
|
||||
@@ -160,11 +160,11 @@ const usePatchSpecs = (shared: boolean, mode: DocMode) => {
|
||||
|
||||
patched = patched.concat(patchNotificationService(confirmModal));
|
||||
patched = patched.concat(patchPeekViewService(peekViewService));
|
||||
patched = patched.concat(patchOpenDocExtension());
|
||||
patched = patched.concat(patchEdgelessClipboard());
|
||||
patched = patched.concat(patchParseDocUrlExtension(framework));
|
||||
patched = patched.concat(patchGenerateDocUrlExtension(framework));
|
||||
patched = patched.concat(patchQuickSearchService(framework));
|
||||
patched = patched.concat(patchEmbedLinkedDocBlockConfig(framework));
|
||||
if (shared) {
|
||||
patched = patched.concat(patchForSharedPage());
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
CodeBlockSpec,
|
||||
DatabaseBlockSpec,
|
||||
DataViewBlockSpec,
|
||||
DefaultOpenDocExtension,
|
||||
DividerBlockSpec,
|
||||
EditPropsStore,
|
||||
EmbedExtensions,
|
||||
@@ -38,6 +39,7 @@ const CommonBlockSpecs: ExtensionType[] = [
|
||||
AttachmentBlockSpec,
|
||||
AdapterFactoryExtensions,
|
||||
FontLoaderService,
|
||||
DefaultOpenDocExtension,
|
||||
].flat();
|
||||
|
||||
export const DefaultBlockSpecs: ExtensionType[] = [
|
||||
|
||||
@@ -24,10 +24,9 @@ import {
|
||||
} from '@affine/core/modules/quicksearch';
|
||||
import { ExternalLinksQuickSearchSession } from '@affine/core/modules/quicksearch/impls/external-links';
|
||||
import { JournalsQuickSearchSession } from '@affine/core/modules/quicksearch/impls/journals';
|
||||
import { WorkbenchService } from '@affine/core/modules/workbench';
|
||||
import { WorkspaceService } from '@affine/core/modules/workspace';
|
||||
import { isNewTabTrigger } from '@affine/core/utils';
|
||||
import { DebugLogger } from '@affine/debug';
|
||||
import { I18n } from '@affine/i18n';
|
||||
import { track } from '@affine/track';
|
||||
import {
|
||||
BlockServiceWatcher,
|
||||
@@ -39,6 +38,8 @@ import type {
|
||||
AffineReference,
|
||||
DocMode,
|
||||
DocModeProvider,
|
||||
OpenDocConfig,
|
||||
OpenDocConfigItem,
|
||||
PeekOptions,
|
||||
PeekViewService as BSPeekViewService,
|
||||
QuickSearchResult,
|
||||
@@ -50,11 +51,11 @@ import {
|
||||
DocModeExtension,
|
||||
EdgelessRootBlockComponent,
|
||||
EmbedLinkedDocBlockComponent,
|
||||
EmbedLinkedDocBlockConfigExtension,
|
||||
GenerateDocUrlExtension,
|
||||
MobileSpecsPatches,
|
||||
NativeClipboardExtension,
|
||||
NotificationExtension,
|
||||
OpenDocExtension,
|
||||
ParseDocUrlExtension,
|
||||
PeekViewExtension,
|
||||
QuickSearchExtension,
|
||||
@@ -67,6 +68,12 @@ import {
|
||||
Text,
|
||||
} from '@blocksuite/affine/store';
|
||||
import type { ReferenceParams } from '@blocksuite/affine-model';
|
||||
import {
|
||||
CenterPeekIcon,
|
||||
ExpandFullIcon,
|
||||
OpenInNewIcon,
|
||||
SplitViewIcon,
|
||||
} from '@blocksuite/icons/lit';
|
||||
import { type FrameworkProvider } from '@toeverything/infra';
|
||||
import { type TemplateResult } from 'lit';
|
||||
import { customElement } from 'lit/decorators.js';
|
||||
@@ -236,18 +243,35 @@ export function patchNotificationService({
|
||||
});
|
||||
}
|
||||
|
||||
export function patchEmbedLinkedDocBlockConfig(framework: FrameworkProvider) {
|
||||
const getWorkbench = () => framework.get(WorkbenchService).workbench;
|
||||
|
||||
return EmbedLinkedDocBlockConfigExtension({
|
||||
handleClick(e, _, refInfo) {
|
||||
if (isNewTabTrigger(e)) {
|
||||
const workbench = getWorkbench();
|
||||
workbench.openDoc(refInfo.pageId, { at: 'new-tab' });
|
||||
e.preventDefault();
|
||||
}
|
||||
},
|
||||
});
|
||||
export function patchOpenDocExtension() {
|
||||
const openDocConfig: OpenDocConfig = {
|
||||
items: [
|
||||
{
|
||||
type: 'open-in-active-view',
|
||||
label: I18n['com.affine.peek-view-controls.open-doc'](),
|
||||
icon: ExpandFullIcon(),
|
||||
},
|
||||
BUILD_CONFIG.isElectron
|
||||
? {
|
||||
type: 'open-in-new-view',
|
||||
label:
|
||||
I18n['com.affine.peek-view-controls.open-doc-in-split-view'](),
|
||||
icon: SplitViewIcon(),
|
||||
}
|
||||
: null,
|
||||
{
|
||||
type: 'open-in-new-tab',
|
||||
label: I18n['com.affine.peek-view-controls.open-doc-in-new-tab'](),
|
||||
icon: OpenInNewIcon(),
|
||||
},
|
||||
{
|
||||
type: 'open-in-center-peek',
|
||||
label: I18n['com.affine.peek-view-controls.open-doc-in-center-peek'](),
|
||||
icon: CenterPeekIcon(),
|
||||
},
|
||||
].filter((item): item is OpenDocConfigItem => item !== null),
|
||||
};
|
||||
return OpenDocExtension(openDocConfig);
|
||||
}
|
||||
|
||||
export function patchPeekViewService(service: PeekViewService) {
|
||||
|
||||
@@ -26,7 +26,16 @@ export const usePageHelper = (docCollection: Workspace) => {
|
||||
const appSidebar = appSidebarService.sidebar;
|
||||
|
||||
const createPageAndOpen = useCallback(
|
||||
(mode?: DocMode, open?: boolean | 'new-tab') => {
|
||||
(
|
||||
mode?: DocMode,
|
||||
options: {
|
||||
at?: 'new-tab' | 'tail' | 'active';
|
||||
show?: boolean;
|
||||
} = {
|
||||
at: 'active',
|
||||
show: true,
|
||||
}
|
||||
) => {
|
||||
appSidebar.setHovering(false);
|
||||
const docProps: DocProps = {
|
||||
note: editorSettingService.editorSetting.get('affine:note'),
|
||||
@@ -37,10 +46,12 @@ export const usePageHelper = (docCollection: Workspace) => {
|
||||
docRecordList.doc$(page.id).value?.setPrimaryMode(mode);
|
||||
}
|
||||
|
||||
if (open !== false)
|
||||
if (options.show !== false) {
|
||||
workbench.openDoc(page.id, {
|
||||
at: open === 'new-tab' ? 'new-tab' : 'active',
|
||||
at: options.at,
|
||||
show: options.show,
|
||||
});
|
||||
}
|
||||
return page;
|
||||
},
|
||||
[
|
||||
@@ -53,8 +64,16 @@ export const usePageHelper = (docCollection: Workspace) => {
|
||||
);
|
||||
|
||||
const createEdgelessAndOpen = useCallback(
|
||||
(open?: boolean | 'new-tab') => {
|
||||
return createPageAndOpen('edgeless', open);
|
||||
(
|
||||
options: {
|
||||
at?: 'new-tab' | 'tail' | 'active';
|
||||
show?: boolean;
|
||||
} = {
|
||||
at: 'active',
|
||||
show: true,
|
||||
}
|
||||
) => {
|
||||
return createPageAndOpen('edgeless', options);
|
||||
},
|
||||
[createPageAndOpen]
|
||||
);
|
||||
@@ -103,8 +122,13 @@ export const usePageHelper = (docCollection: Workspace) => {
|
||||
|
||||
return useMemo(() => {
|
||||
return {
|
||||
createPage: (mode?: DocMode, open?: boolean | 'new-tab') =>
|
||||
createPageAndOpen(mode, open),
|
||||
createPage: (
|
||||
mode?: DocMode,
|
||||
options?: {
|
||||
at?: 'new-tab' | 'tail' | 'active';
|
||||
show?: boolean;
|
||||
}
|
||||
) => createPageAndOpen(mode, options),
|
||||
createEdgeless: createEdgelessAndOpen,
|
||||
importFile: importFileAndOpen,
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@ import type { Tag } from '@affine/core/modules/tag';
|
||||
import { TagService } from '@affine/core/modules/tag';
|
||||
import { WorkbenchService } from '@affine/core/modules/workbench';
|
||||
import { WorkspaceService } from '@affine/core/modules/workspace';
|
||||
import { isNewTabTrigger } from '@affine/core/utils';
|
||||
import { inferOpenMode } from '@affine/core/utils';
|
||||
import type { Collection } from '@affine/env/filter';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { track } from '@affine/track';
|
||||
@@ -92,15 +92,11 @@ export const PageListHeader = () => {
|
||||
<PageListNewPageButton
|
||||
size="small"
|
||||
testId="new-page-button-trigger"
|
||||
onCreateEdgeless={e =>
|
||||
createEdgeless(isNewTabTrigger(e) ? 'new-tab' : true)
|
||||
}
|
||||
onCreateEdgeless={e => createEdgeless({ at: inferOpenMode(e) })}
|
||||
onCreatePage={e =>
|
||||
createPage('page' as DocMode, isNewTabTrigger(e) ? 'new-tab' : true)
|
||||
}
|
||||
onCreateDoc={e =>
|
||||
createPage(undefined, isNewTabTrigger(e) ? 'new-tab' : true)
|
||||
createPage('page' as DocMode, { at: inferOpenMode(e) })
|
||||
}
|
||||
onCreateDoc={e => createPage(undefined, { at: inferOpenMode(e) })}
|
||||
onImportFile={onImportFile}
|
||||
>
|
||||
<div className={styles.buttonText}>{t['New Page']()}</div>
|
||||
|
||||
@@ -9,7 +9,7 @@ import { WorkspaceModeFilterTab } from '@affine/core/components/pure/workspace-m
|
||||
import { WorkspaceDialogService } from '@affine/core/modules/dialogs';
|
||||
import { WorkbenchService } from '@affine/core/modules/workbench';
|
||||
import { WorkspaceService } from '@affine/core/modules/workspace';
|
||||
import { isNewTabTrigger } from '@affine/core/utils';
|
||||
import { inferOpenMode } from '@affine/core/utils';
|
||||
import type { Filter } from '@affine/env/filter';
|
||||
import { track } from '@affine/track';
|
||||
import { PlusIcon } from '@blocksuite/icons/rc';
|
||||
@@ -89,15 +89,9 @@ export const AllPageHeader = ({
|
||||
styles.headerCreateNewButton,
|
||||
!showCreateNew && styles.headerCreateNewButtonHidden
|
||||
)}
|
||||
onCreateEdgeless={e =>
|
||||
createEdgeless(isNewTabTrigger(e) ? 'new-tab' : true)
|
||||
}
|
||||
onCreatePage={e =>
|
||||
createPage('page', isNewTabTrigger(e) ? 'new-tab' : true)
|
||||
}
|
||||
onCreateDoc={e =>
|
||||
createPage(undefined, isNewTabTrigger(e) ? 'new-tab' : true)
|
||||
}
|
||||
onCreateEdgeless={e => createEdgeless({ at: inferOpenMode(e) })}
|
||||
onCreatePage={e => createPage('page', { at: inferOpenMode(e) })}
|
||||
onCreateDoc={e => createPage(undefined, { at: inferOpenMode(e) })}
|
||||
onImportFile={onImportFile}
|
||||
>
|
||||
<PlusIcon />
|
||||
|
||||
@@ -11,9 +11,11 @@ import { DocService } from '@affine/core/modules/doc';
|
||||
import { EditorService } from '@affine/core/modules/editor';
|
||||
import { FeatureFlagService } from '@affine/core/modules/feature-flag';
|
||||
import { GlobalContextService } from '@affine/core/modules/global-context';
|
||||
import { PeekViewService } from '@affine/core/modules/peek-view';
|
||||
import { RecentDocsService } from '@affine/core/modules/quicksearch';
|
||||
import { ViewService } from '@affine/core/modules/workbench';
|
||||
import { WorkspaceService } from '@affine/core/modules/workspace';
|
||||
import { isNewTabTrigger } from '@affine/core/utils';
|
||||
import { RefNodeSlotsProvider } from '@blocksuite/affine/blocks';
|
||||
import { DisposableGroup } from '@blocksuite/affine/global/utils';
|
||||
import { type AffineEditorContainer } from '@blocksuite/affine/presets';
|
||||
@@ -39,7 +41,6 @@ import { GlobalPageHistoryModal } from '../../../../components/affine/page-histo
|
||||
import { useRegisterBlocksuiteEditorCommands } from '../../../../components/hooks/affine/use-register-blocksuite-editor-commands';
|
||||
import { useActiveBlocksuiteEditor } from '../../../../components/hooks/use-block-suite-editor';
|
||||
import { usePageDocumentTitle } from '../../../../components/hooks/use-global-state';
|
||||
import { useNavigateHelper } from '../../../../components/hooks/use-navigate-helper';
|
||||
import { PageDetailEditor } from '../../../../components/page-detail-editor';
|
||||
import { TrashPageFooter } from '../../../../components/pure/trash-page-footer';
|
||||
import { TopTip } from '../../../../components/top-tip';
|
||||
@@ -81,7 +82,6 @@ const DetailPageImpl = memo(function DetailPageImpl() {
|
||||
const editor = editorService.editor;
|
||||
const view = viewService.view;
|
||||
const workspace = workspaceService.workspace;
|
||||
const docCollection = workspace.docCollection;
|
||||
const globalContext = globalContextService.globalContext;
|
||||
const doc = docService.doc;
|
||||
|
||||
@@ -89,7 +89,6 @@ const DetailPageImpl = memo(function DetailPageImpl() {
|
||||
const activeSidebarTab = useLiveData(view.activeSidebarTab$);
|
||||
|
||||
const isInTrash = useLiveData(doc.meta$.map(meta => meta.trash));
|
||||
const { openPage, jumpToPageBlock } = useNavigateHelper();
|
||||
const editorContainer = useLiveData(editor.editorContainer$);
|
||||
|
||||
const isSideBarOpen = useLiveData(workbench.sidebarOpen$);
|
||||
@@ -97,6 +96,8 @@ const DetailPageImpl = memo(function DetailPageImpl() {
|
||||
const chatPanelRef = useRef<ChatPanel | null>(null);
|
||||
const { setDocReadonly } = useDocMetaHelper();
|
||||
|
||||
const peekView = useService(PeekViewService).peekView;
|
||||
|
||||
const isActiveView = useIsActiveView();
|
||||
// TODO(@eyhn): remove jotai here
|
||||
const [_, setActiveBlockSuiteEditor] = useActiveBlocksuiteEditor();
|
||||
@@ -178,25 +179,50 @@ const DetailPageImpl = memo(function DetailPageImpl() {
|
||||
const refNodeSlots = std.getOptional(RefNodeSlotsProvider);
|
||||
if (refNodeSlots) {
|
||||
disposable.add(
|
||||
refNodeSlots.docLinkClicked.on(({ pageId, params }) => {
|
||||
if (params) {
|
||||
const { mode, blockIds, elementIds } = params;
|
||||
jumpToPageBlock(
|
||||
docCollection.id,
|
||||
pageId,
|
||||
mode,
|
||||
blockIds,
|
||||
elementIds
|
||||
);
|
||||
return;
|
||||
// the event should not be emitted by AffineReference
|
||||
refNodeSlots.docLinkClicked.on(
|
||||
({ pageId, params, openMode, event }) => {
|
||||
openMode ??=
|
||||
event && isNewTabTrigger(event)
|
||||
? 'open-in-new-tab'
|
||||
: 'open-in-active-view';
|
||||
if (openMode !== 'open-in-center-peek') {
|
||||
const at = (() => {
|
||||
if (openMode === 'open-in-active-view') {
|
||||
return 'active';
|
||||
}
|
||||
// split view is only supported on electron
|
||||
if (openMode === 'open-in-new-view') {
|
||||
return BUILD_CONFIG.isElectron ? 'tail' : 'new-tab';
|
||||
}
|
||||
if (openMode === 'open-in-new-tab') {
|
||||
return 'new-tab';
|
||||
}
|
||||
return 'active';
|
||||
})();
|
||||
workbench.openDoc(
|
||||
{
|
||||
docId: pageId,
|
||||
blockIds: params?.blockIds,
|
||||
elementIds: params?.elementIds,
|
||||
},
|
||||
{
|
||||
at: at,
|
||||
show: true,
|
||||
}
|
||||
);
|
||||
} else {
|
||||
peekView
|
||||
.open({
|
||||
docRef: {
|
||||
docId: pageId,
|
||||
},
|
||||
...params,
|
||||
})
|
||||
.catch(console.error);
|
||||
}
|
||||
}
|
||||
|
||||
if (editor.doc.id === pageId) {
|
||||
return;
|
||||
}
|
||||
|
||||
openPage(docCollection.id, pageId);
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -212,7 +238,7 @@ const DetailPageImpl = memo(function DetailPageImpl() {
|
||||
disposable.dispose();
|
||||
};
|
||||
},
|
||||
[editor, openPage, docCollection.id, jumpToPageBlock]
|
||||
[editor, workbench, peekView]
|
||||
);
|
||||
|
||||
const [hasScrollTop, setHasScrollTop] = useState(false);
|
||||
|
||||
@@ -18,7 +18,7 @@ export const AppTabCreate = ({ tab }: AppTabCustomFCProps) => {
|
||||
const createPage = useCallback(
|
||||
(isActive: boolean) => {
|
||||
if (isActive) return;
|
||||
const doc = pageHelper.createPage(undefined, false);
|
||||
const doc = pageHelper.createPage(undefined, { show: false });
|
||||
workbench.openDoc({ docId: doc.id, fromTab: 'true' });
|
||||
track.$.navigationPanel.$.createDoc();
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { IconButton } from '@affine/component';
|
||||
import { usePageHelper } from '@affine/core/components/blocksuite/block-suite-page-list/utils';
|
||||
import { WorkspaceService } from '@affine/core/modules/workspace';
|
||||
import { isNewTabTrigger } from '@affine/core/utils';
|
||||
import { inferOpenMode } from '@affine/core/utils';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import track from '@affine/track';
|
||||
import { PlusIcon } from '@blocksuite/icons/rc';
|
||||
@@ -25,7 +25,7 @@ export function AddPageButton({ className, style }: AddPageButtonProps) {
|
||||
|
||||
const onClickNewPage = useCallback(
|
||||
(e?: MouseEvent) => {
|
||||
pageHelper.createPage(undefined, isNewTabTrigger(e) ? 'new-tab' : true);
|
||||
pageHelper.createPage(undefined, { at: inferOpenMode(e) });
|
||||
track.$.navigationPanel.$.createDoc();
|
||||
},
|
||||
[pageHelper]
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
} from '@affine/core/modules/favorite';
|
||||
import { WorkspaceService } from '@affine/core/modules/workspace';
|
||||
import type { AffineDNDData } from '@affine/core/types/dnd';
|
||||
import { isNewTabTrigger } from '@affine/core/utils';
|
||||
import { inferOpenMode } from '@affine/core/utils';
|
||||
import { useI18n } from '@affine/i18n';
|
||||
import { track } from '@affine/track';
|
||||
import { PlusIcon } from '@blocksuite/icons/rc';
|
||||
@@ -81,10 +81,7 @@ export const ExplorerFavorites = () => {
|
||||
|
||||
const handleCreateNewFavoriteDoc: MouseEventHandler = useCallback(
|
||||
e => {
|
||||
const newDoc = createPage(
|
||||
undefined,
|
||||
isNewTabTrigger(e) ? 'new-tab' : true
|
||||
);
|
||||
const newDoc = createPage(undefined, { at: inferOpenMode(e) });
|
||||
favoriteService.favoriteList.add(
|
||||
'doc',
|
||||
newDoc.id,
|
||||
|
||||
@@ -27,13 +27,13 @@ export class DesktopWorkbenchNewTabHandler
|
||||
constructor(private readonly electronApi: DesktopApiService) {
|
||||
super();
|
||||
}
|
||||
handle({ basename, to }: { basename: string; to: To }) {
|
||||
handle({ basename, to, show }: { basename: string; to: To; show: boolean }) {
|
||||
const path = typeof to === 'string' ? parsePath(to) : to;
|
||||
this.electronApi.api.handler.ui
|
||||
.addTab({
|
||||
basename,
|
||||
view: { path },
|
||||
show: false,
|
||||
show: show,
|
||||
})
|
||||
.catch(console.error);
|
||||
}
|
||||
|
||||
@@ -240,6 +240,7 @@ export const SplitViewPanel = memo(function SplitViewPanel({
|
||||
dropTargetRef.current = node;
|
||||
dragRef.current = node;
|
||||
}}
|
||||
data-is-active={isActive && views.length > 1 && !draggingEntity}
|
||||
className={styles.splitViewPanelDrag}
|
||||
>
|
||||
<div draggable={false} className={styles.splitViewPanelContent}>
|
||||
|
||||
@@ -74,7 +74,7 @@ export const splitViewPanelDrag = style({
|
||||
transition: 'box-shadow 0.5s cubic-bezier(0.16, 1, 0.3, 1)',
|
||||
},
|
||||
|
||||
'[data-is-active="true"] &::after': {
|
||||
'[data-is-active="true"]&::after': {
|
||||
boxShadow: `inset 0 0 0 1px ${cssVarV2('button/primary')}`,
|
||||
},
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useDraggable } from '@affine/component';
|
||||
import { useAsyncCallback } from '@affine/core/components/hooks/affine-async-hooks';
|
||||
import type { AffineDNDData, AffineDNDEntity } from '@affine/core/types/dnd';
|
||||
import { isNewTabTrigger } from '@affine/core/utils';
|
||||
import { inferOpenMode as inferOpenAt } from '@affine/core/utils';
|
||||
import { useLiveData, useServices } from '@toeverything/infra';
|
||||
import { type To } from 'history';
|
||||
import { forwardRef, type MouseEvent } from 'react';
|
||||
@@ -62,13 +62,8 @@ export const WorkbenchLink = forwardRef<HTMLAnchorElement, WorkbenchLinkProps>(
|
||||
if (event.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
const at = (() => {
|
||||
if (isNewTabTrigger(event)) {
|
||||
return BUILD_CONFIG.isElectron && event.altKey ? 'tail' : 'new-tab';
|
||||
}
|
||||
return 'active';
|
||||
})();
|
||||
workbench.open(to, { at, replaceHistory });
|
||||
const at = inferOpenAt(event);
|
||||
workbench.open(to, { at, replaceHistory, show: false });
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
},
|
||||
|
||||
@@ -8,11 +8,21 @@ export function preventDefault(event: BaseSyntheticEvent) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
export function stopEvent(event: BaseSyntheticEvent) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
export function isNewTabTrigger(event?: React.MouseEvent | MouseEvent) {
|
||||
return event
|
||||
? (event.ctrlKey || event.metaKey || event.button === 1) && !event.altKey
|
||||
: false;
|
||||
}
|
||||
|
||||
export function isNewTabTrigger(event?: React.MouseEvent | MouseEvent) {
|
||||
return event ? event.ctrlKey || event.metaKey || event.button === 1 : false;
|
||||
export function isNewViewTrigger(event?: React.MouseEvent | MouseEvent) {
|
||||
return event ? (event.ctrlKey || event.metaKey) && event.altKey : false;
|
||||
}
|
||||
|
||||
export function inferOpenMode(event?: React.MouseEvent | MouseEvent) {
|
||||
if (isNewTabTrigger(event)) {
|
||||
return 'new-tab';
|
||||
} else if (isNewViewTrigger(event)) {
|
||||
return BUILD_CONFIG.isElectron ? 'tail' : 'new-tab';
|
||||
}
|
||||
return 'active';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user