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
No known key found for this signature in database
GPG Key ID: 1C1E76924FAFDDE4
7 changed files with 51 additions and 17 deletions

View File

@ -35,7 +35,7 @@ export const mainHeader = style([
export const sidebarHeader = style([
header,
{
padding: '0 14px',
padding: '0 16px',
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 { EditorModeSwitch } from '@affine/core/components/blocksuite/block-suite-mode-switch';
import { useJournalInfoHelper } from '@affine/core/hooks/use-journal';
import type { BlockSuiteWorkspace } from '@affine/core/shared';
import type { Workspace } from '@affine/workspace';
import { RightSidebarIcon } from '@blocksuite/icons';
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 (
<>
<Header className={styles.sidebarHeader} style={{ paddingRight: 0 }}>
@ -196,26 +201,22 @@ function WindowsSidebarHeader() {
<WindowsAppControls />
</Header>
<div className={styles.standaloneExtensionSwitcherWrapper}>
<ExtensionTabs />
<ExtensionTabs {...props} />
</div>
</>
);
}
function NonWindowsSidebarHeader() {
function NonWindowsSidebarHeader(props: SidebarHeaderProps) {
return (
<Header className={styles.sidebarHeader}>
<ExtensionTabs />
<ExtensionTabs {...props} />
<div className={styles.spacer} />
<ToggleSidebarButton />
</Header>
);
}
export function RightSidebarHeader() {
return isWindowsDesktop ? (
<WindowsSidebarHeader />
) : (
<NonWindowsSidebarHeader />
);
}
export const RightSidebarHeader = isWindowsDesktop
? WindowsSidebarHeader
: NonWindowsSidebarHeader;

View File

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

View File

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

View File

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