From 1f6a105e5c284a233f947e5fa3fc03b1373413ba Mon Sep 17 00:00:00 2001 From: JimmFly Date: Wed, 11 Oct 2023 11:31:04 +0800 Subject: [PATCH] feat(core): add setting commands (#4568) Co-authored-by: Peng Xiao --- apps/core/src/atoms/settings.ts | 2 +- apps/core/src/commands/affine-help.tsx | 58 +++++ apps/core/src/commands/affine-settings.tsx | 245 +++++++++++++++++- apps/core/src/commands/affine-updates.tsx | 35 +++ apps/core/src/commands/index.ts | 3 + .../components/affine/language-menu/index.tsx | 43 +-- .../general-setting/appearance/index.tsx | 4 +- .../core/src/components/pure/cmdk/main.css.ts | 29 +++ apps/core/src/components/pure/cmdk/main.tsx | 21 +- .../src/hooks/affine/use-language-helper.ts | 34 +++ apps/core/src/hooks/use-navigate-helper.ts | 9 +- .../hooks/use-register-workspace-commands.ts | 28 +- apps/core/src/layouts/workspace-layout.tsx | 8 +- .../quick-search-main.stories.tsx | 12 + .../app-sidebar/app-updater-button/index.tsx | 2 + packages/component/src/ui/switch/switch.tsx | 39 ++- packages/i18n/src/resources/en.json | 12 +- 17 files changed, 524 insertions(+), 60 deletions(-) create mode 100644 apps/core/src/commands/affine-help.tsx create mode 100644 apps/core/src/commands/affine-updates.tsx create mode 100644 apps/core/src/hooks/affine/use-language-helper.ts diff --git a/apps/core/src/atoms/settings.ts b/apps/core/src/atoms/settings.ts index 6ea4af9177..eac2abafcd 100644 --- a/apps/core/src/atoms/settings.ts +++ b/apps/core/src/atoms/settings.ts @@ -63,7 +63,7 @@ const appSettingBaseAtom = atomWithStorage('affine-settings', { type SetStateAction = Value | ((prev: Value) => Value); -const appSettingAtom = atom< +export const appSettingAtom = atom< AppSetting, [SetStateAction>], void diff --git a/apps/core/src/commands/affine-help.tsx b/apps/core/src/commands/affine-help.tsx new file mode 100644 index 0000000000..4897be3bca --- /dev/null +++ b/apps/core/src/commands/affine-help.tsx @@ -0,0 +1,58 @@ +import type { useAFFiNEI18N } from '@affine/i18n/hooks'; +import { ContactWithUsIcon, NewIcon, UserGuideIcon } from '@blocksuite/icons'; +import { registerAffineCommand } from '@toeverything/infra/command'; +import type { createStore } from 'jotai'; + +import { openOnboardingModalAtom, openSettingModalAtom } from '../atoms'; + +export function registerAffineHelpCommands({ + t, + store, +}: { + t: ReturnType; + store: ReturnType; +}) { + const unsubs: Array<() => void> = []; + unsubs.push( + registerAffineCommand({ + id: 'affine:help-whats-new', + category: 'affine:help', + icon: , + label: () => t['com.affine.cmdk.affine.whats-new'](), + run() { + window.open(runtimeConfig.changelogUrl, '_blank'); + }, + }) + ); + unsubs.push( + registerAffineCommand({ + id: 'affine:help-contact-us', + category: 'affine:help', + icon: , + label: () => t['com.affine.cmdk.affine.contact-us'](), + run() { + store.set(openSettingModalAtom, { + open: true, + activeTab: 'about', + workspaceId: null, + }); + }, + }) + ); + unsubs.push( + registerAffineCommand({ + id: 'affine:help-getting-started', + category: 'affine:help', + icon: , + label: () => t['com.affine.cmdk.affine.getting-started'](), + preconditionStrategy: () => environment.isDesktop, + run() { + store.set(openOnboardingModalAtom, true); + }, + }) + ); + + return () => { + unsubs.forEach(unsub => unsub()); + }; +} diff --git a/apps/core/src/commands/affine-settings.tsx b/apps/core/src/commands/affine-settings.tsx index cbce95be81..a077684277 100644 --- a/apps/core/src/commands/affine-settings.tsx +++ b/apps/core/src/commands/affine-settings.tsx @@ -5,20 +5,85 @@ import { PreconditionStrategy, registerAffineCommand, } from '@toeverything/infra/command'; -import type { createStore } from 'jotai'; +import { type createStore, useAtomValue } from 'jotai'; import type { useTheme } from 'next-themes'; import { openQuickSearchModalAtom } from '../atoms'; +import { appSettingAtom } from '../atoms/settings'; +import type { useLanguageHelper } from '../hooks/affine/use-language-helper'; + +// todo - find a better way to abstract the following translations components +const ClientBorderStyleLabel = () => { + const { clientBorder } = useAtomValue(appSettingAtom); + return ( + + Change Client Border Style to + state + + ); +}; + +const FullWidthLayoutLabel = () => { + const { fullWidthLayout } = useAtomValue(appSettingAtom); + return ( + + Change Full Width Layout to + state + + ); +}; + +const NoisyBackgroundLabel = () => { + const { enableNoisyBackground } = useAtomValue(appSettingAtom); + return ( + + Change Noise Background On The Sidebar to state + + ); +}; + +const BlurBackgroundLabel = () => { + const { enableBlurBackground } = useAtomValue(appSettingAtom); + return ( + + Change Translucent UI On The Sidebar to state + + ); +}; export function registerAffineSettingsCommands({ + t, store, theme, + languageHelper, }: { t: ReturnType; store: ReturnType; theme: ReturnType; + languageHelper: ReturnType; }) { const unsubs: Array<() => void> = []; + const { onSelect, languagesList, currentLanguage } = languageHelper; unsubs.push( registerAffineCommand({ id: 'affine:show-quick-search', @@ -29,7 +94,8 @@ export function registerAffineSettingsCommands({ }, icon: , run() { - store.set(openQuickSearchModalAtom, true); + const quickSearchModalState = store.get(openQuickSearchModalAtom); + store.set(openQuickSearchModalAtom, !quickSearchModalState); }, }) ); @@ -94,6 +160,181 @@ export function registerAffineSettingsCommands({ }) ); + //Font styles + unsubs.push( + registerAffineCommand({ + id: 'affine:change-font-style-to-sans', + label: ( + + Change Font Style to fontFamily + + ), + category: 'affine:settings', + icon: , + preconditionStrategy: () => + store.get(appSettingAtom).fontStyle !== 'Sans', + run() { + store.set(appSettingAtom, prev => ({ + ...prev, + fontStyle: 'Sans', + })); + }, + }) + ); + + unsubs.push( + registerAffineCommand({ + id: 'affine:change-font-style-to-serif', + label: ( + + Change Font Style to + + fontFamily + + + ), + category: 'affine:settings', + icon: , + preconditionStrategy: () => + store.get(appSettingAtom).fontStyle !== 'Serif', + run() { + store.set(appSettingAtom, prev => ({ + ...prev, + fontStyle: 'Serif', + })); + }, + }) + ); + + unsubs.push( + registerAffineCommand({ + id: 'affine:change-font-style-to-mono', + label: ( + + Change Font Style to + + fontFamily + + + ), + category: 'affine:settings', + icon: , + preconditionStrategy: () => + store.get(appSettingAtom).fontStyle !== 'Mono', + run() { + store.set(appSettingAtom, prev => ({ + ...prev, + fontStyle: 'Mono', + })); + }, + }) + ); + + //Display Language + languagesList.forEach(language => { + unsubs.push( + registerAffineCommand({ + id: `affine:change-display-language-to-${language.name}`, + label: ( + + Change Display Language to + language + + ), + category: 'affine:settings', + icon: , + preconditionStrategy: () => currentLanguage?.tag !== language.tag, + run() { + onSelect(language.tag); + }, + }) + ); + }); + + //Layout Style + unsubs.push( + registerAffineCommand({ + id: `affine:change-client-border-style`, + label: , + category: 'affine:settings', + icon: , + preconditionStrategy: () => environment.isDesktop, + run() { + store.set(appSettingAtom, prev => ({ + ...prev, + clientBorder: !prev.clientBorder, + })); + }, + }) + ); + + unsubs.push( + registerAffineCommand({ + id: `affine:change-full-width-layout`, + label: , + category: 'affine:settings', + icon: , + run() { + store.set(appSettingAtom, prev => ({ + ...prev, + fullWidthLayout: !prev.fullWidthLayout, + })); + }, + }) + ); + + unsubs.push( + registerAffineCommand({ + id: `affine:change-noise-background-on-the-sidebar`, + label: , + category: 'affine:settings', + icon: , + preconditionStrategy: () => environment.isDesktop, + run() { + store.set(appSettingAtom, prev => ({ + ...prev, + enableNoisyBackground: !prev.enableNoisyBackground, + })); + }, + }) + ); + + unsubs.push( + registerAffineCommand({ + id: `affine:change-translucent-ui-on-the-sidebar`, + label: , + category: 'affine:settings', + icon: , + preconditionStrategy: () => environment.isDesktop, + run() { + store.set(appSettingAtom, prev => ({ + ...prev, + enableBlurBackground: !prev.enableBlurBackground, + })); + }, + }) + ); + return () => { unsubs.forEach(unsub => unsub()); }; diff --git a/apps/core/src/commands/affine-updates.tsx b/apps/core/src/commands/affine-updates.tsx new file mode 100644 index 0000000000..0574db8676 --- /dev/null +++ b/apps/core/src/commands/affine-updates.tsx @@ -0,0 +1,35 @@ +import { updateReadyAtom } from '@affine/component/app-sidebar/app-updater-button'; +import type { useAFFiNEI18N } from '@affine/i18n/hooks'; +import { ResetIcon } from '@blocksuite/icons'; +import { registerAffineCommand } from '@toeverything/infra/command'; +import type { createStore } from 'jotai'; + +export function registerAffineUpdatesCommands({ + t, + store, +}: { + t: ReturnType; + store: ReturnType; +}) { + const unsubs: Array<() => void> = []; + + unsubs.push( + registerAffineCommand({ + id: 'affine:restart-to-upgrade', + category: 'affine:updates', + icon: , + label: () => t['com.affine.cmdk.affine.restart-to-upgrade'](), + preconditionStrategy: () => !!store.get(updateReadyAtom), + run() { + window.apis?.updater.quitAndInstall().catch(err => { + // TODO: add error toast here + console.error(err); + }); + }, + }) + ); + + return () => { + unsubs.forEach(unsub => unsub()); + }; +} diff --git a/apps/core/src/commands/index.ts b/apps/core/src/commands/index.ts index cb3a1ece40..b2b5ddafab 100644 --- a/apps/core/src/commands/index.ts +++ b/apps/core/src/commands/index.ts @@ -1,3 +1,6 @@ export * from './affine-creation'; +export * from './affine-help'; export * from './affine-layout'; +export * from './affine-navigation'; export * from './affine-settings'; +export * from './affine-updates'; diff --git a/apps/core/src/components/affine/language-menu/index.tsx b/apps/core/src/components/affine/language-menu/index.tsx index 83c2ee6e56..66d94b39c5 100644 --- a/apps/core/src/components/affine/language-menu/index.tsx +++ b/apps/core/src/components/affine/language-menu/index.tsx @@ -1,24 +1,18 @@ -import { LOCALES } from '@affine/i18n'; -import { useI18N } from '@affine/i18n'; import { Menu, MenuItem, MenuTrigger } from '@toeverything/components/menu'; -import type { ReactElement } from 'react'; -import { useCallback, useMemo } from 'react'; +import { memo, type ReactElement } from 'react'; + +import { useLanguageHelper } from '../../../hooks/affine/use-language-helper'; // Fixme: keyboard focus should be supported by Menu component -const LanguageMenuContent = ({ - currentLanguage, - onSelect, -}: { - currentLanguage?: string; - onSelect: (value: string) => void; -}) => { +const LanguageMenuContent = memo(function LanguageMenuContent() { + const { currentLanguage, languagesList, onSelect } = useLanguageHelper(); return ( <> - {LOCALES.map(option => { + {languagesList.map(option => { return ( onSelect(option.tag)} > @@ -28,30 +22,13 @@ const LanguageMenuContent = ({ })} ); -}; +}); export const LanguageMenu = () => { - const i18n = useI18N(); - const currentLanguage = useMemo( - () => LOCALES.find(item => item.tag === i18n.language), - [i18n.language] - ); - const onSelect = useCallback( - (event: string) => { - return i18n.changeLanguage(event); - }, - [i18n] - ); + const { currentLanguage } = useLanguageHelper(); return ( - ) as ReactElement - } + items={() as ReactElement} contentOptions={{ style: { background: 'var(--affine-white)', diff --git a/apps/core/src/components/affine/setting-modal/general-setting/appearance/index.tsx b/apps/core/src/components/affine/setting-modal/general-setting/appearance/index.tsx index 7fd3937f17..931696d501 100644 --- a/apps/core/src/components/affine/setting-modal/general-setting/appearance/index.tsx +++ b/apps/core/src/components/affine/setting-modal/general-setting/appearance/index.tsx @@ -24,7 +24,7 @@ export const ThemeSettings = () => { { setTheme(value); @@ -52,7 +52,7 @@ const FontFamilySettings = () => { { setAppSettings({ fontStyle: key }); diff --git a/apps/core/src/components/pure/cmdk/main.css.ts b/apps/core/src/components/pure/cmdk/main.css.ts index 025fce2ac2..cd672d946a 100644 --- a/apps/core/src/components/pure/cmdk/main.css.ts +++ b/apps/core/src/components/pure/cmdk/main.css.ts @@ -19,6 +19,32 @@ export const searchInput = style({ '::placeholder': { color: 'var(--affine-text-secondary-color)', }, + selectors: { + '&.inEditor': { + paddingTop: '12px', + paddingBottom: '18px', + }, + }, +}); + +export const pageTitleWrapper = style({ + display: 'flex', + alignItems: 'center', + padding: '18px 24px 0 24px', + width: '100%', +}); + +export const pageTitle = style({ + padding: '2px 6px', + borderRadius: 4, + fontSize: 'var(--affine-font-xs)', + lineHeight: '20px', + color: 'var(--affine-text-secondary-color)', + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + maxWidth: '100%', + backgroundColor: 'var(--affine-background-secondary-color)', }); export const panelContainer = style({ @@ -41,6 +67,9 @@ export const itemLabel = style({ lineHeight: '1.5', color: 'var(--affine-text-primary-color)', flex: 1, + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', }); export const timestamp = style({ diff --git a/apps/core/src/components/pure/cmdk/main.tsx b/apps/core/src/components/pure/cmdk/main.tsx index 2bd1ec3bc4..66f68c9b4d 100644 --- a/apps/core/src/components/pure/cmdk/main.tsx +++ b/apps/core/src/components/pure/cmdk/main.tsx @@ -1,6 +1,7 @@ import { Command } from '@affine/cmdk'; import { formatDate } from '@affine/component/page-list'; import { useAFFiNEI18N } from '@affine/i18n/hooks'; +import type { PageMeta } from '@blocksuite/store'; import type { CommandCategory } from '@toeverything/infra/command'; import clsx from 'clsx'; import { useAtom, useSetAtom } from 'jotai'; @@ -124,14 +125,17 @@ export const CMDKContainer = ({ onQueryChange, query, children, + pageMeta, ...rest }: React.PropsWithChildren<{ className?: string; query: string; + pageMeta?: PageMeta; onQueryChange: (query: string) => void; }>) => { const t = useAFFiNEI18N(); const [value, setValue] = useAtom(cmdkValueAtom); + const isInEditor = pageMeta !== undefined; return ( {/* todo: add page context here */} + {isInEditor ? ( +
+ + {pageMeta.title ? pageMeta.title : t['Untitled']()} + +
+ ) : null} {children}
); }; -export const CMDKQuickSearchModal = (props: CMDKModalProps) => { +export const CMDKQuickSearchModal = ({ + pageMeta, + ...props +}: CMDKModalProps & { pageMeta?: PageMeta }) => { const [query, setQuery] = useAtom(cmdkQueryAtom); useLayoutEffect(() => { if (props.open) { @@ -179,6 +195,7 @@ export const CMDKQuickSearchModal = (props: CMDKModalProps) => { className={styles.root} query={query} onQueryChange={setQuery} + pageMeta={pageMeta} > }> diff --git a/apps/core/src/hooks/affine/use-language-helper.ts b/apps/core/src/hooks/affine/use-language-helper.ts new file mode 100644 index 0000000000..fc11aaf3c4 --- /dev/null +++ b/apps/core/src/hooks/affine/use-language-helper.ts @@ -0,0 +1,34 @@ +import { LOCALES, useI18N } from '@affine/i18n'; +import { useCallback, useMemo } from 'react'; + +export function useLanguageHelper() { + const i18n = useI18N(); + const currentLanguage = useMemo( + () => LOCALES.find(item => item.tag === i18n.language), + [i18n.language] + ); + const languagesList = useMemo( + () => + LOCALES.map(item => ({ + tag: item.tag, + originalName: item.originalName, + name: item.name, + })), + [] + ); + const onSelect = useCallback( + (event: string) => { + i18n.changeLanguage(event); + }, + [i18n] + ); + + return useMemo( + () => ({ + currentLanguage, + languagesList, + onSelect, + }), + [currentLanguage, languagesList, onSelect] + ); +} diff --git a/apps/core/src/hooks/use-navigate-helper.ts b/apps/core/src/hooks/use-navigate-helper.ts index 5b677afea0..d56e4d554b 100644 --- a/apps/core/src/hooks/use-navigate-helper.ts +++ b/apps/core/src/hooks/use-navigate-helper.ts @@ -52,17 +52,20 @@ export function useNavigateHelper() { }, [navigate] ); + + const isPublicWorkspace = useMemo(() => { + return location.pathname.indexOf('/public-workspace') === 0; + }, [location.pathname]); + const openPage = useCallback( (workspaceId: string, pageId: string) => { - const isPublicWorkspace = - location.pathname.indexOf('/public-workspace') === 0; if (isPublicWorkspace) { return jumpToPublicWorkspacePage(workspaceId, pageId); } else { return jumpToPage(workspaceId, pageId); } }, - [jumpToPage, jumpToPublicWorkspacePage, location.pathname] + [jumpToPage, jumpToPublicWorkspacePage, isPublicWorkspace] ); const jumpToIndex = useCallback( diff --git a/apps/core/src/hooks/use-register-workspace-commands.ts b/apps/core/src/hooks/use-register-workspace-commands.ts index ac78467ea0..94f0746df8 100644 --- a/apps/core/src/hooks/use-register-workspace-commands.ts +++ b/apps/core/src/hooks/use-register-workspace-commands.ts @@ -6,11 +6,14 @@ import { useEffect } from 'react'; import { allPageModeSelectAtom } from '../atoms'; import { registerAffineCreationCommands, + registerAffineHelpCommands, registerAffineLayoutCommands, + registerAffineNavigationCommands, registerAffineSettingsCommands, + registerAffineUpdatesCommands, } from '../commands'; -import { registerAffineNavigationCommands } from '../commands/affine-navigation'; import { usePageHelper } from '../components/blocksuite/block-suite-page-list/utils'; +import { useLanguageHelper } from './affine/use-language-helper'; import { useCurrentWorkspace } from './current/use-current-workspace'; import { useNavigateHelper } from './use-navigate-helper'; @@ -19,11 +22,18 @@ export function useRegisterWorkspaceCommands() { const t = useAFFiNEI18N(); const theme = useTheme(); const [currentWorkspace] = useCurrentWorkspace(); + const languageHelper = useLanguageHelper(); const pageHelper = usePageHelper(currentWorkspace.blockSuiteWorkspace); const navigationHelper = useNavigateHelper(); const [pageListMode, setPageListMode] = useAtom(allPageModeSelectAtom); useEffect(() => { const unsubs: Array<() => void> = []; + unsubs.push( + registerAffineUpdatesCommands({ + store, + t, + }) + ); unsubs.push( registerAffineNavigationCommands({ store, @@ -34,7 +44,14 @@ export function useRegisterWorkspaceCommands() { setPageListMode, }) ); - unsubs.push(registerAffineSettingsCommands({ store, t, theme })); + unsubs.push( + registerAffineSettingsCommands({ + store, + t, + theme, + languageHelper, + }) + ); unsubs.push(registerAffineLayoutCommands({ store, t })); unsubs.push( registerAffineCreationCommands({ @@ -43,6 +60,12 @@ export function useRegisterWorkspaceCommands() { t, }) ); + unsubs.push( + registerAffineHelpCommands({ + store, + t, + }) + ); return () => { unsubs.forEach(unsub => unsub()); @@ -56,5 +79,6 @@ export function useRegisterWorkspaceCommands() { navigationHelper, pageListMode, setPageListMode, + languageHelper, ]); } diff --git a/apps/core/src/layouts/workspace-layout.tsx b/apps/core/src/layouts/workspace-layout.tsx index 6336559e5f..00b1d2f72a 100644 --- a/apps/core/src/layouts/workspace-layout.tsx +++ b/apps/core/src/layouts/workspace-layout.tsx @@ -69,11 +69,16 @@ const CMDKQuickSearchModal = lazy(() => ); export const QuickSearch = () => { - const [currentWorkspace] = useCurrentWorkspace(); const [openQuickSearchModal, setOpenQuickSearchModalAtom] = useAtom( openQuickSearchModalAtom ); + + const [currentWorkspace] = useCurrentWorkspace(); + const { pageId } = useParams(); const blockSuiteWorkspace = currentWorkspace?.blockSuiteWorkspace; + const pageMeta = useBlockSuitePageMeta( + currentWorkspace?.blockSuiteWorkspace + ).find(meta => meta.id === pageId); if (!blockSuiteWorkspace) { return null; @@ -83,6 +88,7 @@ export const QuickSearch = () => { ); }; diff --git a/apps/storybook/src/stories/quick-search/quick-search-main.stories.tsx b/apps/storybook/src/stories/quick-search/quick-search-main.stories.tsx index 06427b35c1..c443fe54ce 100644 --- a/apps/storybook/src/stories/quick-search/quick-search-main.stories.tsx +++ b/apps/storybook/src/stories/quick-search/quick-search-main.stories.tsx @@ -42,6 +42,18 @@ function useRegisterCommands() { theme: 'auto', themes: ['auto', 'dark', 'light'], }, + languageHelper: { + onSelect: () => {}, + languagesList: [ + { tag: 'en', name: 'English', originalName: 'English' }, + { + tag: 'zh-Hans', + name: 'Simplified Chinese', + originalName: '简体中文', + }, + ], + currentLanguage: undefined, + }, }), registerAffineCreationCommands({ t, diff --git a/packages/component/src/components/app-sidebar/app-updater-button/index.tsx b/packages/component/src/components/app-sidebar/app-updater-button/index.tsx index 1d927594c5..a3afe7a00d 100644 --- a/packages/component/src/components/app-sidebar/app-updater-button/index.tsx +++ b/packages/component/src/components/app-sidebar/app-updater-button/index.tsx @@ -259,3 +259,5 @@ export function AppUpdaterButton({ /> ); } + +export * from './index.jotai'; diff --git a/packages/component/src/ui/switch/switch.tsx b/packages/component/src/ui/switch/switch.tsx index 344de98b78..fb65a98869 100644 --- a/packages/component/src/ui/switch/switch.tsx +++ b/packages/component/src/ui/switch/switch.tsx @@ -1,6 +1,11 @@ // components/switch.tsx import clsx from 'clsx'; -import { type HTMLAttributes, type ReactNode, useState } from 'react'; +import { + type HTMLAttributes, + type ReactNode, + useCallback, + useState, +} from 'react'; import * as styles from './index.css'; @@ -10,15 +15,23 @@ type SwitchProps = Omit, 'onChange'> & { children?: ReactNode; }; -export const Switch = (props: SwitchProps) => { - const { checked, onChange, children, ...otherProps } = props; - const [isChecked, setIsChecked] = useState(checked); +export const Switch = ({ + checked: checkedProp = false, + onChange: onChangeProp, + children, + ...otherProps +}: SwitchProps) => { + const [checkedState, setCheckedState] = useState(checkedProp); - const handleChange = (event: React.ChangeEvent) => { - const newChecked = event.target.checked; - setIsChecked(newChecked); - onChange?.(newChecked); - }; + const checked = onChangeProp ? checkedProp : checkedState; + const onChange = useCallback( + (event: React.ChangeEvent) => { + const newChecked = event.target.checked; + if (onChangeProp) onChangeProp(newChecked); + else setCheckedState(newChecked); + }, + [onChangeProp] + ); return ( diff --git a/packages/i18n/src/resources/en.json b/packages/i18n/src/resources/en.json index 1c0649ad44..e79a3c2369 100644 --- a/packages/i18n/src/resources/en.json +++ b/packages/i18n/src/resources/en.json @@ -618,5 +618,15 @@ "com.affine.cmdk.affine.import-workspace": "Import Workspace", "com.affine.cmdk.affine.editor.add-to-favourites": "Add to Favourites", "com.affine.cmdk.affine.editor.remove-from-favourites": "Remove from Favourites", - "com.affine.cmdk.affine.editor.restore-from-trash": "Restore from Trash" + "com.affine.cmdk.affine.editor.restore-from-trash": "Restore from Trash", + "com.affine.cmdk.affine.font-style.to": "Change Font Style to <1>{{fontFamily}}", + "com.affine.cmdk.affine.display-language.to": "Change Display Language to <1>{{language}}", + "com.affine.cmdk.affine.client-border-style.to": "Change Client Border Style to <1>{{state}}", + "com.affine.cmdk.affine.full-width-layout.to": "Change Full Width Layout to <1>{{state}}", + "com.affine.cmdk.affine.noise-background-on-the-sidebar.to": "Change Noise Background On The Sidebar to <1>{{state}}", + "com.affine.cmdk.affine.translucent-ui-on-the-sidebar.to": "Change Translucent UI On The Sidebar to <1>{{state}}", + "com.affine.cmdk.affine.whats-new": "What's New", + "com.affine.cmdk.affine.getting-started": "Getting Started", + "com.affine.cmdk.affine.contact-us": "Contact Us", + "com.affine.cmdk.affine.restart-to-upgrade": "Restart to Upgrade" }