refactor(core): set edgeless theme on doc created (#8670)

This commit is contained in:
EYHN
2024-11-04 04:38:03 +00:00
parent a4f27ef391
commit 12e3cf1d07
27 changed files with 107 additions and 126 deletions

View File

@@ -10,7 +10,6 @@ export * from './modules/feature-flag';
export * from './modules/global-context'; export * from './modules/global-context';
export * from './modules/lifecycle'; export * from './modules/lifecycle';
export * from './modules/storage'; export * from './modules/storage';
export * from './modules/theme';
export * from './modules/workspace'; export * from './modules/workspace';
export * from './orm'; export * from './orm';
export * from './storage'; export * from './storage';
@@ -27,7 +26,6 @@ import {
configureGlobalStorageModule, configureGlobalStorageModule,
configureTestingGlobalStorage, configureTestingGlobalStorage,
} from './modules/storage'; } from './modules/storage';
import { configureAppThemeModule } from './modules/theme';
import { import {
configureTestingWorkspaceProvider, configureTestingWorkspaceProvider,
configureWorkspaceModule, configureWorkspaceModule,
@@ -41,7 +39,6 @@ export function configureInfraModules(framework: Framework) {
configureGlobalContextModule(framework); configureGlobalContextModule(framework);
configureLifecycleModule(framework); configureLifecycleModule(framework);
configureFeatureFlagModule(framework); configureFeatureFlagModule(framework);
configureAppThemeModule(framework);
} }
export function configureTestingInfraModules(framework: Framework) { export function configureTestingInfraModules(framework: Framework) {

View File

@@ -0,0 +1,4 @@
import { createEvent } from '../../../framework';
import type { DocRecord } from '../entities/record';
export const DocCreated = createEvent<DocRecord>('DocCreated');

View File

@@ -1,6 +1,7 @@
export { Doc } from './entities/doc'; export { Doc } from './entities/doc';
export { DocRecord } from './entities/record'; export { DocRecord } from './entities/record';
export { DocRecordList } from './entities/record-list'; export { DocRecordList } from './entities/record-list';
export { DocCreated } from './events';
export { DocScope } from './scopes/doc'; export { DocScope } from './scopes/doc';
export { DocService } from './services/doc'; export { DocService } from './services/doc';
export { DocsService } from './services/docs'; export { DocsService } from './services/docs';

View File

@@ -11,6 +11,7 @@ import { ObjectPool } from '../../../utils';
import type { Doc } from '../entities/doc'; import type { Doc } from '../entities/doc';
import { DocPropertyList } from '../entities/property-list'; import { DocPropertyList } from '../entities/property-list';
import { DocRecordList } from '../entities/record-list'; import { DocRecordList } from '../entities/record-list';
import { DocCreated } from '../events';
import { DocScope } from '../scopes/doc'; import { DocScope } from '../scopes/doc';
import type { DocsStore } from '../stores/docs'; import type { DocsStore } from '../stores/docs';
import { DocService } from './doc'; import { DocService } from './doc';
@@ -74,6 +75,7 @@ export class DocsService extends Service {
if (options.primaryMode) { if (options.primaryMode) {
docRecord.setPrimaryMode(options.primaryMode); docRecord.setPrimaryMode(options.primaryMode);
} }
this.eventBus.emit(DocCreated, docRecord);
return docRecord; return docRecord;
} }

View File

@@ -1,9 +0,0 @@
export { AppThemeService } from './services/theme';
import type { Framework } from '../../framework';
import { AppTheme } from './entities/theme';
import { AppThemeService } from './services/theme';
export function configureAppThemeModule(framework: Framework) {
framework.service(AppThemeService).entity(AppTheme);
}

View File

@@ -1,5 +1,5 @@
import { AffineContext } from '@affine/component/context';
import { AppFallback } from '@affine/core/components/affine/app-container'; import { AppFallback } from '@affine/core/components/affine/app-container';
import { AffineContext } from '@affine/core/components/context';
import { Telemetry } from '@affine/core/components/telemetry'; import { Telemetry } from '@affine/core/components/telemetry';
import { configureMobileModules } from '@affine/core/mobile/modules'; import { configureMobileModules } from '@affine/core/mobile/modules';
import { router } from '@affine/core/mobile/router'; import { router } from '@affine/core/mobile/router';

View File

@@ -1,6 +1,6 @@
import { AffineContext } from '@affine/component/context';
import { GlobalLoading } from '@affine/component/global-loading'; import { GlobalLoading } from '@affine/component/global-loading';
import { AppFallback } from '@affine/core/components/affine/app-container'; import { AppFallback } from '@affine/core/components/affine/app-container';
import { AffineContext } from '@affine/core/components/context';
import { WindowsAppControls } from '@affine/core/components/pure/header/windows-app-controls'; import { WindowsAppControls } from '@affine/core/components/pure/header/windows-app-controls';
import { Telemetry } from '@affine/core/components/telemetry'; import { Telemetry } from '@affine/core/components/telemetry';
import { router } from '@affine/core/desktop/router'; import { router } from '@affine/core/desktop/router';

View File

@@ -1,6 +1,6 @@
import { ThemeProvider } from '@affine/component/theme-provider';
import { ShellAppFallback } from '@affine/core/components/affine/app-container'; import { ShellAppFallback } from '@affine/core/components/affine/app-container';
import { useAppSettingHelper } from '@affine/core/components/hooks/affine/use-app-setting-helper'; import { useAppSettingHelper } from '@affine/core/components/hooks/affine/use-app-setting-helper';
import { ThemeProvider } from '@affine/core/components/theme-provider';
import { configureAppSidebarModule } from '@affine/core/modules/app-sidebar'; import { configureAppSidebarModule } from '@affine/core/modules/app-sidebar';
import { import {
AppTabsHeader, AppTabsHeader,
@@ -9,9 +9,9 @@ import {
import { configureDesktopApiModule } from '@affine/core/modules/desktop-api'; import { configureDesktopApiModule } from '@affine/core/modules/desktop-api';
import { configureI18nModule, I18nProvider } from '@affine/core/modules/i18n'; import { configureI18nModule, I18nProvider } from '@affine/core/modules/i18n';
import { configureElectronStateStorageImpls } from '@affine/core/modules/storage'; import { configureElectronStateStorageImpls } from '@affine/core/modules/storage';
import { configureAppThemeModule } from '@affine/core/modules/theme';
import { SplitViewFallback } from '@affine/core/modules/workbench/view/split-view/split-view'; import { SplitViewFallback } from '@affine/core/modules/workbench/view/split-view/split-view';
import { import {
configureAppThemeModule,
configureGlobalStorageModule, configureGlobalStorageModule,
Framework, Framework,
FrameworkRoot, FrameworkRoot,

View File

@@ -1,5 +1,5 @@
import { AffineContext } from '@affine/component/context';
import { AppFallback } from '@affine/core/components/affine/app-container'; import { AppFallback } from '@affine/core/components/affine/app-container';
import { AffineContext } from '@affine/core/components/context';
import { Telemetry } from '@affine/core/components/telemetry'; import { Telemetry } from '@affine/core/components/telemetry';
import { configureMobileModules } from '@affine/core/mobile/modules'; import { configureMobileModules } from '@affine/core/mobile/modules';
import { router } from '@affine/core/mobile/router'; import { router } from '@affine/core/mobile/router';

View File

@@ -1,5 +1,5 @@
import { AffineContext } from '@affine/component/context';
import { AppFallback } from '@affine/core/components/affine/app-container'; import { AppFallback } from '@affine/core/components/affine/app-container';
import { AffineContext } from '@affine/core/components/context';
import { Telemetry } from '@affine/core/components/telemetry'; import { Telemetry } from '@affine/core/components/telemetry';
import { configureMobileModules } from '@affine/core/mobile/modules'; import { configureMobileModules } from '@affine/core/mobile/modules';
import { router } from '@affine/core/mobile/router'; import { router } from '@affine/core/mobile/router';

View File

@@ -1,6 +1,6 @@
import { AffineContext } from '@affine/component/context';
import { GlobalLoading } from '@affine/component/global-loading'; import { GlobalLoading } from '@affine/component/global-loading';
import { AppFallback } from '@affine/core/components/affine/app-container'; import { AppFallback } from '@affine/core/components/affine/app-container';
import { AffineContext } from '@affine/core/components/context';
import { Telemetry } from '@affine/core/components/telemetry'; import { Telemetry } from '@affine/core/components/telemetry';
import { router } from '@affine/core/desktop/router'; import { router } from '@affine/core/desktop/router';
import { configureCommonModules } from '@affine/core/modules'; import { configureCommonModules } from '@affine/core/modules';

View File

@@ -3,6 +3,7 @@ import {
AIPageRootBlockSpec, AIPageRootBlockSpec,
} from '@affine/core/blocksuite/presets/ai'; } from '@affine/core/blocksuite/presets/ai';
import { EditorSettingService } from '@affine/core/modules/editor-setting'; import { EditorSettingService } from '@affine/core/modules/editor-setting';
import { AppThemeService } from '@affine/core/modules/theme';
import { mixpanel } from '@affine/track'; import { mixpanel } from '@affine/track';
import { import {
ConfigExtension, ConfigExtension,
@@ -32,7 +33,6 @@ import {
} from '@blocksuite/affine-shared/utils'; } from '@blocksuite/affine-shared/utils';
import type { Container } from '@blocksuite/global/di'; import type { Container } from '@blocksuite/global/di';
import { import {
AppThemeService,
DocService, DocService,
DocsService, DocsService,
type FrameworkProvider, type FrameworkProvider,

View File

@@ -2,26 +2,22 @@ import type { WeekDatePickerHandle } from '@affine/component';
import { WeekDatePicker } from '@affine/component'; import { WeekDatePicker } from '@affine/component';
import { useJournalRouteHelper } from '@affine/core/components/hooks/use-journal'; import { useJournalRouteHelper } from '@affine/core/components/hooks/use-journal';
import { JournalService } from '@affine/core/modules/journal'; import { JournalService } from '@affine/core/modules/journal';
import type { Doc, DocCollection } from '@blocksuite/affine/store'; import type { Doc } from '@blocksuite/affine/store';
import { useLiveData, useService } from '@toeverything/infra'; import { useLiveData, useService } from '@toeverything/infra';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { useEffect, useRef, useState } from 'react'; import { useEffect, useRef, useState } from 'react';
export interface JournalWeekDatePickerProps { export interface JournalWeekDatePickerProps {
docCollection: DocCollection;
page: Doc; page: Doc;
} }
const weekStyle = { maxWidth: 800, width: '100%' }; const weekStyle = { maxWidth: 800, width: '100%' };
export const JournalWeekDatePicker = ({ export const JournalWeekDatePicker = ({ page }: JournalWeekDatePickerProps) => {
docCollection,
page,
}: JournalWeekDatePickerProps) => {
const handleRef = useRef<WeekDatePickerHandle>(null); const handleRef = useRef<WeekDatePickerHandle>(null);
const journalService = useService(JournalService); const journalService = useService(JournalService);
const journalDateStr = useLiveData(journalService.journalDate$(page.id)); const journalDateStr = useLiveData(journalService.journalDate$(page.id));
const journalDate = journalDateStr ? dayjs(journalDateStr) : null; const journalDate = journalDateStr ? dayjs(journalDateStr) : null;
const { openJournal } = useJournalRouteHelper(docCollection); const { openJournal } = useJournalRouteHelper();
const [date, setDate] = useState( const [date, setDate] = useState(
(journalDate ?? dayjs()).format('YYYY-MM-DD') (journalDate ?? dayjs()).format('YYYY-MM-DD')
); );

View File

@@ -1,18 +1,11 @@
import { Button } from '@affine/component'; import { Button } from '@affine/component';
import { useJournalRouteHelper } from '@affine/core/components/hooks/use-journal'; import { useJournalRouteHelper } from '@affine/core/components/hooks/use-journal';
import { useI18n } from '@affine/i18n'; import { useI18n } from '@affine/i18n';
import type { DocCollection } from '@blocksuite/affine/store';
import { useCallback } from 'react'; import { useCallback } from 'react';
export interface JournalTodayButtonProps { export const JournalTodayButton = () => {
docCollection: DocCollection;
}
export const JournalTodayButton = ({
docCollection,
}: JournalTodayButtonProps) => {
const t = useI18n(); const t = useI18n();
const journalHelper = useJournalRouteHelper(docCollection); const journalHelper = useJournalRouteHelper();
const onToday = useCallback(() => { const onToday = useCallback(() => {
journalHelper.openToday(); journalHelper.openToday();

View File

@@ -5,11 +5,8 @@ import { WorkbenchService } from '@affine/core/modules/workbench';
import { type DocMode } from '@blocksuite/affine/blocks'; import { type DocMode } from '@blocksuite/affine/blocks';
import type { DocCollection } from '@blocksuite/affine/store'; import type { DocCollection } from '@blocksuite/affine/store';
import { type DocProps, DocsService, useServices } from '@toeverything/infra'; import { type DocProps, DocsService, useServices } from '@toeverything/infra';
import { useTheme } from 'next-themes';
import { useCallback, useMemo } from 'react'; import { useCallback, useMemo } from 'react';
import { getValueByDefaultTheme } from '../../hooks/use-journal';
export const usePageHelper = (docCollection: DocCollection) => { export const usePageHelper = (docCollection: DocCollection) => {
const { const {
docsService, docsService,
@@ -25,7 +22,6 @@ export const usePageHelper = (docCollection: DocCollection) => {
const workbench = workbenchService.workbench; const workbench = workbenchService.workbench;
const docRecordList = docsService.list; const docRecordList = docsService.list;
const appSidebar = appSidebarService.sidebar; const appSidebar = appSidebarService.sidebar;
const { resolvedTheme } = useTheme();
const createPageAndOpen = useCallback( const createPageAndOpen = useCallback(
(mode?: DocMode, open?: boolean | 'new-tab') => { (mode?: DocMode, open?: boolean | 'new-tab') => {
@@ -35,14 +31,6 @@ export const usePageHelper = (docCollection: DocCollection) => {
}; };
const page = docsService.createDoc({ docProps }); const page = docsService.createDoc({ docProps });
const value = getValueByDefaultTheme(
editorSettingService.editorSetting.settings$.value.edgelessDefaultTheme,
resolvedTheme || 'light'
);
docRecordList
.doc$(page.id)
.value?.setProperty('edgelessColorTheme', value);
if (mode) { if (mode) {
docRecordList.doc$(page.id).value?.setPrimaryMode(mode); docRecordList.doc$(page.id).value?.setPrimaryMode(mode);
} }
@@ -58,7 +46,6 @@ export const usePageHelper = (docCollection: DocCollection) => {
docRecordList, docRecordList,
docsService, docsService,
editorSettingService.editorSetting, editorSettingService.editorSetting,
resolvedTheme,
workbench, workbench,
] ]
); );

View File

@@ -1,12 +1,11 @@
import { ConfirmModalProvider } from '@affine/component';
import { ProviderComposer } from '@affine/component/provider-composer'; import { ProviderComposer } from '@affine/component/provider-composer';
import { ThemeProvider } from '@affine/component/theme-provider'; import { ThemeProvider } from '@affine/core/components/theme-provider';
import type { createStore } from 'jotai'; import type { createStore } from 'jotai';
import { Provider } from 'jotai'; import { Provider } from 'jotai';
import type { PropsWithChildren } from 'react'; import type { PropsWithChildren } from 'react';
import { useMemo } from 'react'; import { useMemo } from 'react';
import { ConfirmModalProvider } from '../../ui/modal';
export type AffineContextProps = PropsWithChildren<{ export type AffineContextProps = PropsWithChildren<{
store?: ReturnType<typeof createStore>; store?: ReturnType<typeof createStore>;
}>; }>;

View File

@@ -1,9 +1,8 @@
import { EditorSettingService } from '@affine/core/modules/editor-setting'; import { EditorSettingService } from '@affine/core/modules/editor-setting';
import type { EdgelessDefaultTheme } from '@affine/core/modules/editor-setting/schema';
import { JournalService } from '@affine/core/modules/journal'; import { JournalService } from '@affine/core/modules/journal';
import { i18nTime } from '@affine/i18n'; import { i18nTime } from '@affine/i18n';
import { track } from '@affine/track'; import { track } from '@affine/track';
import { type DocCollection, Text } from '@blocksuite/affine/store'; import { Text } from '@blocksuite/affine/store';
import { import {
type DocProps, type DocProps,
DocsService, DocsService,
@@ -12,29 +11,9 @@ import {
useServices, useServices,
} from '@toeverything/infra'; } from '@toeverything/infra';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import { useTheme } from 'next-themes';
import { useCallback, useMemo } from 'react'; import { useCallback, useMemo } from 'react';
import { WorkbenchService } from '../../modules/workbench'; import { WorkbenchService } from '../../modules/workbench';
import { useDocCollectionHelper } from './use-block-suite-workspace-helper';
export const getValueByDefaultTheme = (
defaultTheme: EdgelessDefaultTheme,
currentAppTheme: string
) => {
switch (defaultTheme) {
case 'dark':
return 'dark';
case 'light':
return 'light';
case 'specified':
return currentAppTheme === 'dark' ? 'dark' : 'light';
case 'auto':
return 'system';
default:
return 'system';
}
};
type MaybeDate = Date | string | number; type MaybeDate = Date | string | number;
export const JOURNAL_DATE_FORMAT = 'YYYY-MM-DD'; export const JOURNAL_DATE_FORMAT = 'YYYY-MM-DD';
@@ -53,9 +32,7 @@ function toDayjs(j?: string | false) {
/** /**
* @deprecated use `JournalService` directly * @deprecated use `JournalService` directly
*/ */
export const useJournalHelper = (docCollection: DocCollection) => { export const useJournalHelper = () => {
const bsWorkspaceHelper = useDocCollectionHelper(docCollection);
const { resolvedTheme } = useTheme();
const { docsService, editorSettingService, journalService } = useServices({ const { docsService, editorSettingService, journalService } = useServices({
DocsService, DocsService,
EditorSettingService, EditorSettingService,
@@ -69,17 +46,11 @@ export const useJournalHelper = (docCollection: DocCollection) => {
(maybeDate: MaybeDate) => { (maybeDate: MaybeDate) => {
const day = dayjs(maybeDate); const day = dayjs(maybeDate);
const title = day.format(JOURNAL_DATE_FORMAT); const title = day.format(JOURNAL_DATE_FORMAT);
const page = bsWorkspaceHelper.createDoc(); const docRecord = docsService.createDoc();
const value = getValueByDefaultTheme( const { doc, release } = docsService.open(docRecord.id);
editorSettingService.editorSetting.settings$.value.edgelessDefaultTheme, docsService.list.setPrimaryMode(docRecord.id, 'page');
resolvedTheme || 'light'
);
docsService.list
.doc$(page.id)
.value?.setProperty('edgelessColorTheme', value);
docsService.list.setPrimaryMode(page.id, 'page');
// set created date to match the journal date // set created date to match the journal date
page.collection.setDocMeta(page.id, { docRecord.setMeta({
createDate: dayjs() createDate: dayjs()
.set('year', day.year()) .set('year', day.year())
.set('month', day.month()) .set('month', day.month())
@@ -91,17 +62,12 @@ export const useJournalHelper = (docCollection: DocCollection) => {
page: { title: new Text(title) }, page: { title: new Text(title) },
note: editorSettingService.editorSetting.get('affine:note'), note: editorSettingService.editorSetting.get('affine:note'),
}; };
initDocFromProps(page, docProps); initDocFromProps(doc.blockSuiteDoc, docProps);
journalService.setJournalDate(page.id, title); release();
return page; journalService.setJournalDate(docRecord.id, title);
return docRecord;
}, },
[ [docsService, editorSettingService.editorSetting, journalService]
bsWorkspaceHelper,
editorSettingService.editorSetting,
resolvedTheme,
docsService.list,
journalService,
]
); );
/** /**
@@ -138,8 +104,8 @@ export const useJournalHelper = (docCollection: DocCollection) => {
}; };
// split useJournalRouteHelper since it requires a <Route /> context, which may not work in lit // split useJournalRouteHelper since it requires a <Route /> context, which may not work in lit
export const useJournalRouteHelper = (docCollection: DocCollection) => { export const useJournalRouteHelper = () => {
const { getJournalByDate } = useJournalHelper(docCollection); const { getJournalByDate } = useJournalHelper();
const workbench = useService(WorkbenchService).workbench; const workbench = useService(WorkbenchService).workbench;
/** /**
* open journal by date, create one if not exist * open journal by date, create one if not exist

View File

@@ -149,9 +149,7 @@ export const RootAppSidebar = (): ReactElement => {
{t['com.affine.workspaceSubPath.all']()} {t['com.affine.workspaceSubPath.all']()}
</span> </span>
</MenuLinkItem> </MenuLinkItem>
<AppSidebarJournalButton <AppSidebarJournalButton />
docCollection={currentWorkspace.docCollection}
/>
<MenuItem <MenuItem
data-testid="slider-bar-workspace-setting-button" data-testid="slider-bar-workspace-setting-button"
icon={<SettingsIcon />} icon={<SettingsIcon />}

View File

@@ -8,23 +8,16 @@ import { DocDisplayMetaService } from '@affine/core/modules/doc-display-meta';
import { WorkbenchService } from '@affine/core/modules/workbench'; import { WorkbenchService } from '@affine/core/modules/workbench';
import { isNewTabTrigger } from '@affine/core/utils'; import { isNewTabTrigger } from '@affine/core/utils';
import { useI18n } from '@affine/i18n'; import { useI18n } from '@affine/i18n';
import type { DocCollection } from '@blocksuite/affine/store';
import { TodayIcon } from '@blocksuite/icons/rc'; import { TodayIcon } from '@blocksuite/icons/rc';
import { useLiveData, useService } from '@toeverything/infra'; import { useLiveData, useService } from '@toeverything/infra';
import { type MouseEvent } from 'react'; import { type MouseEvent } from 'react';
interface AppSidebarJournalButtonProps { export const AppSidebarJournalButton = () => {
docCollection: DocCollection;
}
export const AppSidebarJournalButton = ({
docCollection,
}: AppSidebarJournalButtonProps) => {
const t = useI18n(); const t = useI18n();
const docDisplayMetaService = useService(DocDisplayMetaService); const docDisplayMetaService = useService(DocDisplayMetaService);
const workbench = useService(WorkbenchService).workbench; const workbench = useService(WorkbenchService).workbench;
const location = useLiveData(workbench.location$); const location = useLiveData(workbench.location$);
const { openToday } = useJournalRouteHelper(docCollection); const { openToday } = useJournalRouteHelper();
const maybeDocId = location.pathname.split('/')[1]; const maybeDocId = location.pathname.split('/')[1];
const { isJournal } = useJournalInfoHelper(maybeDocId); const { isJournal } = useJournalInfoHelper(maybeDocId);

View File

@@ -1,11 +1,12 @@
import { AppThemeService, useService } from '@toeverything/infra'; import { AppThemeService } from '@affine/core/modules/theme';
import { useService } from '@toeverything/infra';
import { ThemeProvider as NextThemeProvider, useTheme } from 'next-themes'; import { ThemeProvider as NextThemeProvider, useTheme } from 'next-themes';
import type { PropsWithChildren } from 'react'; import type { PropsWithChildren } from 'react';
import { useEffect } from 'react'; import { useEffect } from 'react';
const themes = ['dark', 'light']; const themes = ['dark', 'light'];
export function ThemeObserver() { function ThemeObserver() {
const { resolvedTheme } = useTheme(); const { resolvedTheme } = useTheme();
const service = useService(AppThemeService); const service = useService(AppThemeService);

View File

@@ -67,14 +67,9 @@ export function JournalPageHeader({ page, workspace }: PageHeaderProps) {
<ViewIcon icon="journal" /> <ViewIcon icon="journal" />
<EditorModeSwitch /> <EditorModeSwitch />
<div className={styles.journalWeekPicker}> <div className={styles.journalWeekPicker}>
<JournalWeekDatePicker <JournalWeekDatePicker page={page} />
docCollection={workspace.docCollection}
page={page}
/>
</div> </div>
{hideToday ? null : ( {hideToday ? null : <JournalTodayButton />}
<JournalTodayButton docCollection={workspace.docCollection} />
)}
<HeaderDivider /> <HeaderDivider />
<PageHeaderMenuButton <PageHeaderMenuButton
isJournal isJournal

View File

@@ -21,7 +21,6 @@ import {
DocsService, DocsService,
useLiveData, useLiveData,
useService, useService,
WorkspaceService,
} from '@toeverything/infra'; } from '@toeverything/infra';
import { assignInlineVars } from '@vanilla-extract/dynamic'; import { assignInlineVars } from '@vanilla-extract/dynamic';
import clsx from 'clsx'; import clsx from 'clsx';
@@ -100,12 +99,11 @@ const mobile = environment.isMobile;
export const EditorJournalPanel = () => { export const EditorJournalPanel = () => {
const t = useI18n(); const t = useI18n();
const doc = useService(DocService).doc; const doc = useService(DocService).doc;
const workspace = useService(WorkspaceService).workspace;
const journalService = useService(JournalService); const journalService = useService(JournalService);
const journalDateStr = useLiveData(journalService.journalDate$(doc.id)); const journalDateStr = useLiveData(journalService.journalDate$(doc.id));
const journalDate = journalDateStr ? dayjs(journalDateStr) : null; const journalDate = journalDateStr ? dayjs(journalDateStr) : null;
const isJournal = !!journalDate; const isJournal = !!journalDate;
const { openJournal } = useJournalRouteHelper(workspace.docCollection); const { openJournal } = useJournalRouteHelper();
const onDateSelect = useCallback( const onDateSelect = useCallback(
(date: string) => { (date: string) => {

View File

@@ -26,6 +26,7 @@ import { configureShareSettingModule } from './share-setting';
import { configureSystemFontFamilyModule } from './system-font-family'; import { configureSystemFontFamilyModule } from './system-font-family';
import { configureTagModule } from './tag'; import { configureTagModule } from './tag';
import { configureTelemetryModule } from './telemetry'; import { configureTelemetryModule } from './telemetry';
import { configureAppThemeModule } from './theme';
import { configureThemeEditorModule } from './theme-editor'; import { configureThemeEditorModule } from './theme-editor';
import { configureUrlModule } from './url'; import { configureUrlModule } from './url';
import { configureUserspaceModule } from './userspace'; import { configureUserspaceModule } from './userspace';
@@ -61,4 +62,5 @@ export function configureCommonModules(framework: Framework) {
configureAppSidebarModule(framework); configureAppSidebarModule(framework);
configureJournalModule(framework); configureJournalModule(framework);
configureUrlModule(framework); configureUrlModule(framework);
configureAppThemeModule(framework);
} }

View File

@@ -1,5 +1,4 @@
import { Entity } from '../../../framework'; import { Entity, LiveData } from '@toeverything/infra';
import { LiveData } from '../../../livedata';
export class AppTheme extends Entity { export class AppTheme extends Entity {
theme$ = new LiveData<string | undefined>(undefined); theme$ = new LiveData<string | undefined>(undefined);

View File

@@ -0,0 +1,16 @@
export { AppThemeService } from './services/theme';
import { type Framework, WorkspaceScope } from '@toeverything/infra';
import { EditorSettingService } from '../editor-setting';
import { AppTheme } from './entities/theme';
import { EdgelessThemeService } from './services/edgeless-theme';
import { AppThemeService } from './services/theme';
export function configureAppThemeModule(framework: Framework) {
framework
.service(AppThemeService)
.entity(AppTheme)
.scope(WorkspaceScope)
.service(EdgelessThemeService, [AppThemeService, EditorSettingService]);
}

View File

@@ -0,0 +1,42 @@
import type { DocRecord } from '@toeverything/infra';
import { DocCreated, OnEvent, Service } from '@toeverything/infra';
import type { EditorSettingService } from '../../editor-setting';
import type { EdgelessDefaultTheme } from '../../editor-setting/schema';
import type { AppThemeService } from './theme';
const getValueByDefaultTheme = (
defaultTheme: EdgelessDefaultTheme,
currentAppTheme: string
) => {
switch (defaultTheme) {
case 'dark':
return 'dark';
case 'light':
return 'light';
case 'specified':
return currentAppTheme === 'dark' ? 'dark' : 'light';
case 'auto':
return 'system';
default:
return 'system';
}
};
@OnEvent(DocCreated, i => i.onDocCreated)
export class EdgelessThemeService extends Service {
constructor(
private readonly appThemeService: AppThemeService,
private readonly editorSettingService: EditorSettingService
) {
super();
}
onDocCreated(docRecord: DocRecord) {
const value = getValueByDefaultTheme(
this.editorSettingService.editorSetting.get('edgelessDefaultTheme'),
this.appThemeService.appTheme.theme$.value ?? 'light'
);
docRecord.setProperty('edgelessColorTheme', value);
}
}

View File

@@ -1,4 +1,5 @@
import { Service } from '../../../framework'; import { Service } from '@toeverything/infra';
import { AppTheme } from '../entities/theme'; import { AppTheme } from '../entities/theme';
export class AppThemeService extends Service { export class AppThemeService extends Service {