feat(core): journal extension loader (#5557)

This commit is contained in:
Cats Juice
2024-01-18 09:27:56 +00:00
parent 8b1b5b2e93
commit 496dc588be
7 changed files with 51 additions and 17 deletions

View File

@@ -35,7 +35,7 @@ export const mainHeader = style([
export const sidebarHeader = style([ export const sidebarHeader = style([
header, header,
{ {
padding: '0 14px', padding: '0 16px',
gap: '12px', gap: '12px',
}, },
]); ]);

View File

@@ -11,6 +11,7 @@ import { JournalTodayButton } from '@affine/core/components/blocksuite/block-sui
import { PageHeaderMenuButton } from '@affine/core/components/blocksuite/block-suite-header/menu'; import { PageHeaderMenuButton } from '@affine/core/components/blocksuite/block-suite-header/menu';
import { EditorModeSwitch } from '@affine/core/components/blocksuite/block-suite-mode-switch'; import { EditorModeSwitch } from '@affine/core/components/blocksuite/block-suite-mode-switch';
import { useJournalInfoHelper } from '@affine/core/hooks/use-journal'; import { useJournalInfoHelper } from '@affine/core/hooks/use-journal';
import type { BlockSuiteWorkspace } from '@affine/core/shared';
import type { Workspace } from '@affine/workspace'; import type { Workspace } from '@affine/workspace';
import { RightSidebarIcon } from '@blocksuite/icons'; import { RightSidebarIcon } from '@blocksuite/icons';
import type { Page } from '@blocksuite/store'; import type { Page } from '@blocksuite/store';
@@ -187,7 +188,11 @@ export function DetailPageHeader(props: PageHeaderProps) {
); );
} }
function WindowsSidebarHeader() { interface SidebarHeaderProps {
workspace: BlockSuiteWorkspace;
page: Page;
}
function WindowsSidebarHeader(props: SidebarHeaderProps) {
return ( return (
<> <>
<Header className={styles.sidebarHeader} style={{ paddingRight: 0 }}> <Header className={styles.sidebarHeader} style={{ paddingRight: 0 }}>
@@ -196,26 +201,22 @@ function WindowsSidebarHeader() {
<WindowsAppControls /> <WindowsAppControls />
</Header> </Header>
<div className={styles.standaloneExtensionSwitcherWrapper}> <div className={styles.standaloneExtensionSwitcherWrapper}>
<ExtensionTabs /> <ExtensionTabs {...props} />
</div> </div>
</> </>
); );
} }
function NonWindowsSidebarHeader() { function NonWindowsSidebarHeader(props: SidebarHeaderProps) {
return ( return (
<Header className={styles.sidebarHeader}> <Header className={styles.sidebarHeader}>
<ExtensionTabs /> <ExtensionTabs {...props} />
<div className={styles.spacer} /> <div className={styles.spacer} />
<ToggleSidebarButton /> <ToggleSidebarButton />
</Header> </Header>
); );
} }
export function RightSidebarHeader() { export const RightSidebarHeader = isWindowsDesktop
return isWindowsDesktop ? ( ? WindowsSidebarHeader
<WindowsSidebarHeader /> : NonWindowsSidebarHeader;
) : (
<NonWindowsSidebarHeader />
);
}

View File

@@ -193,7 +193,7 @@ const DetailPageImpl = memo(function DetailPageImpl({ page }: { page: Page }) {
sidebar={ sidebar={
!isInTrash ? ( !isInTrash ? (
<div className={styles.sidebarContainerInner}> <div className={styles.sidebarContainerInner}>
<RightSidebarHeader /> <RightSidebarHeader workspace={blockSuiteWorkspace} page={page} />
<EditorSidebar /> <EditorSidebar />
</div> </div>
) : null ) : null

View File

@@ -1,16 +1,18 @@
// main editor sidebar states // main editor sidebar states
import { assertExists } from '@blocksuite/global/utils'; import { assertExists, isEqual } from '@blocksuite/global/utils';
import { atom } from 'jotai'; import { atom } from 'jotai';
import { selectAtom } from 'jotai/utils'; import { selectAtom } from 'jotai/utils';
import { copilotExtension } from './extensions/copilot'; import { copilotExtension } from './extensions/copilot';
import { framePanelExtension } from './extensions/frame'; import { framePanelExtension } from './extensions/frame';
import { journalExtension } from './extensions/journal';
import { outlineExtension } from './extensions/outline'; import { outlineExtension } from './extensions/outline';
import type { EditorExtension, EditorExtensionName } from './types'; import type { EditorExtension, EditorExtensionName } from './types';
// the list of all possible extensions in affine. // the list of all possible extensions in affine.
// order matters (determines the order of the tabs) // order matters (determines the order of the tabs)
export const extensions: EditorExtension[] = [ export const extensions: EditorExtension[] = [
journalExtension,
outlineExtension, outlineExtension,
framePanelExtension, framePanelExtension,
copilotExtension, copilotExtension,
@@ -42,7 +44,8 @@ const widthAtom = selectAtom(baseStateAtom, state => state.width);
export const editorExtensionsAtom = selectAtom( export const editorExtensionsAtom = selectAtom(
baseStateAtom, baseStateAtom,
state => state.extensions state => state.extensions,
isEqual
); );
// get/set sidebar open state // get/set sidebar open state

View File

@@ -1,6 +1,9 @@
import { IconButton } from '@affine/component'; import { IconButton } from '@affine/component';
import { useJournalInfoHelper } from '@affine/core/hooks/use-journal';
import { useWorkspaceEnabledFeatures } from '@affine/core/hooks/use-workspace-features'; import { useWorkspaceEnabledFeatures } from '@affine/core/hooks/use-workspace-features';
import type { BlockSuiteWorkspace } from '@affine/core/shared';
import { FeatureType } from '@affine/graphql'; import { FeatureType } from '@affine/graphql';
import type { Page } from '@blocksuite/store';
import { assignInlineVars } from '@vanilla-extract/dynamic'; import { assignInlineVars } from '@vanilla-extract/dynamic';
import { useAtom, useAtomValue } from 'jotai'; import { useAtom, useAtomValue } from 'jotai';
import { useEffect } from 'react'; import { useEffect } from 'react';
@@ -11,18 +14,32 @@ import {
} from '../atoms'; } from '../atoms';
import * as styles from './extensions.css'; import * as styles from './extensions.css';
export interface ExtensionTabsProps {
workspace: BlockSuiteWorkspace;
page: Page;
}
// provide a switcher for active extensions // provide a switcher for active extensions
// will be used in global top header (MacOS) or sidebar (Windows) // will be used in global top header (MacOS) or sidebar (Windows)
export const ExtensionTabs = () => { export const ExtensionTabs = ({ page }: ExtensionTabsProps) => {
// todo: filter in editorExtensionsAtom instead? // todo: filter in editorExtensionsAtom instead?
const copilotEnabled = useWorkspaceEnabledFeatures().includes( const copilotEnabled = useWorkspaceEnabledFeatures().includes(
FeatureType.Copilot FeatureType.Copilot
); );
const { isJournal } = useJournalInfoHelper(page.meta);
const exts = useAtomValue(editorExtensionsAtom).filter(ext => { const exts = useAtomValue(editorExtensionsAtom).filter(ext => {
if (ext.name === 'copilot' && !copilotEnabled) return false; if (ext.name === 'copilot' && !copilotEnabled) return false;
return true; return true;
}); });
const [selected, setSelected] = useAtom(editorSidebarActiveExtensionAtom); const [selected, setSelected] = useAtom(editorSidebarActiveExtensionAtom);
// if journal is active, set selected to journal
useEffect(() => {
isJournal && setSelected('journal');
}, [isJournal, setSelected]);
const vars = assignInlineVars({ const vars = assignInlineVars({
[styles.activeIdx]: String( [styles.activeIdx]: String(
exts.findIndex(ext => ext.name === selected?.name) ?? 0 exts.findIndex(ext => ext.name === selected?.name) ?? 0

View File

@@ -0,0 +1,13 @@
import { TodayIcon } from '@blocksuite/icons';
import type { EditorExtension } from '..';
const EditorJournalPanel = () => {
return <div>journal extension</div>;
};
export const journalExtension: EditorExtension = {
name: 'journal',
icon: <TodayIcon />,
Component: EditorJournalPanel,
};

View File

@@ -1,4 +1,4 @@
export type EditorExtensionName = 'outline' | 'frame' | 'copilot'; export type EditorExtensionName = 'outline' | 'frame' | 'copilot' | 'journal';
export interface EditorExtension { export interface EditorExtension {
name: EditorExtensionName; name: EditorExtensionName;