feat(editor): add more open doc options to editor toolbar (#9588)

fix AF-2036, AF-2092
This commit is contained in:
pengx17
2025-01-09 08:04:21 +00:00
parent 890a962196
commit f78857bb11
41 changed files with 558 additions and 271 deletions

View File

@@ -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);
},

View File

@@ -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());
}

View File

@@ -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[] = [

View File

@@ -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) {

View File

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

View File

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