mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 21:05:19 +00:00
feat(core): add setting commands (#4568)
Co-authored-by: Peng Xiao <pengxiao@outlook.com>
This commit is contained in:
@@ -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 (
|
||||
<MenuItem
|
||||
key={option.name}
|
||||
selected={currentLanguage === option.originalName}
|
||||
selected={currentLanguage?.originalName === option.originalName}
|
||||
title={option.name}
|
||||
onSelect={() => 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 (
|
||||
<Menu
|
||||
items={
|
||||
(
|
||||
<LanguageMenuContent
|
||||
currentLanguage={currentLanguage?.originalName}
|
||||
onSelect={onSelect}
|
||||
/>
|
||||
) as ReactElement
|
||||
}
|
||||
items={(<LanguageMenuContent />) as ReactElement}
|
||||
contentOptions={{
|
||||
style: {
|
||||
background: 'var(--affine-white)',
|
||||
|
||||
@@ -24,7 +24,7 @@ export const ThemeSettings = () => {
|
||||
<RadioButtonGroup
|
||||
width={250}
|
||||
className={settingWrapper}
|
||||
defaultValue={theme}
|
||||
value={theme}
|
||||
onValueChange={useCallback(
|
||||
(value: string) => {
|
||||
setTheme(value);
|
||||
@@ -52,7 +52,7 @@ const FontFamilySettings = () => {
|
||||
<RadioButtonGroup
|
||||
width={250}
|
||||
className={settingWrapper}
|
||||
defaultValue={appSettings.fontStyle}
|
||||
value={appSettings.fontStyle}
|
||||
onValueChange={useCallback(
|
||||
(key: AppSetting['fontStyle']) => {
|
||||
setAppSettings({ fontStyle: key });
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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 (
|
||||
<Command
|
||||
{...rest}
|
||||
@@ -153,20 +157,32 @@ export const CMDKContainer = ({
|
||||
}}
|
||||
>
|
||||
{/* todo: add page context here */}
|
||||
{isInEditor ? (
|
||||
<div className={styles.pageTitleWrapper}>
|
||||
<span className={styles.pageTitle}>
|
||||
{pageMeta.title ? pageMeta.title : t['Untitled']()}
|
||||
</span>
|
||||
</div>
|
||||
) : null}
|
||||
<Command.Input
|
||||
placeholder={t['com.affine.cmdk.placeholder']()}
|
||||
autoFocus
|
||||
{...rest}
|
||||
value={query}
|
||||
onValueChange={onQueryChange}
|
||||
className={clsx(className, styles.searchInput)}
|
||||
className={clsx(className, styles.searchInput, {
|
||||
inEditor: isInEditor,
|
||||
})}
|
||||
/>
|
||||
<Command.List>{children}</Command.List>
|
||||
</Command>
|
||||
);
|
||||
};
|
||||
|
||||
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}
|
||||
>
|
||||
<Suspense fallback={<Command.Loading />}>
|
||||
<QuickSearchCommands onOpenChange={props.onOpenChange} />
|
||||
|
||||
Reference in New Issue
Block a user