* feat(settings): add editor font size setting for chat input and code editor Adds an 'Editor font size' control in Settings > Appearance that sets an absolute px font size for the chat input textarea and the in-app CodeMirror editor. Mirrors the existing terminalFontSize lifecycle. - New store field editorFontSize (default 13, clamp 9-32, step 1) in useUIStore with narrow selectors at each consumer. - Persistence wired through appearanceAutoSave, desktop + runtime API types, and persistence.ts read/normalize. - Settings UI row (NumberInput) with reset to 13, VisibleSetting union entry, OpenChamberPage registration, and search index entry appearance.editor-font-size. - Applied as a post-zoom absolute override on the chat input textarea and on the CodeMirror theme's content rule, leaving gutter/line-number chrome at its existing hardcoded sizes (matches terminal scope). - All 10 locales translated (en, es, fr, ja, ko, pl, pt-BR, uk, zh-CN, zh-TW); no English placeholders in non-English dictionaries. Refs #1325 * fix(codemirror): use unitless lineHeight so it scales with editor font size The & rule in the CodeMirror theme set lineHeight to 1.5rem (~24px), which does not scale when editorFontSize is increased (e.g., 28-32px). This causes overlapping lines at larger font sizes. Change to unitless 1.5, which scales proportionally with whatever fontSize resolves to (dynamic prop or --text-code fallback). Matches browser best practice for proportional leading. Review comment: https://github.com/openchamber/openchamber/pull/2065 --------- Co-authored-by: bashrusakh <bashrusakh@users.noreply.github.com> Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
This commit is contained in:
committed by
GitHub
co-authored by
bashrusakh
Bohdan Triapitsyn
parent
bfaf62e222
commit
e0229917f8
@@ -1121,6 +1121,7 @@ const ChatInputComponent: React.FC<ChatInputProps> = ({ onOpenSettings, scrollTo
|
|||||||
const inputBarOffset = useUIStore((state) => state.inputBarOffset);
|
const inputBarOffset = useUIStore((state) => state.inputBarOffset);
|
||||||
const persistChatDraft = useUIStore((state) => state.persistChatDraft);
|
const persistChatDraft = useUIStore((state) => state.persistChatDraft);
|
||||||
const inputSpellcheckEnabled = useUIStore((state) => state.inputSpellcheckEnabled);
|
const inputSpellcheckEnabled = useUIStore((state) => state.inputSpellcheckEnabled);
|
||||||
|
const editorFontSize = useUIStore((state) => state.editorFontSize);
|
||||||
const isExpandedInput = useUIStore((state) => state.isExpandedInput);
|
const isExpandedInput = useUIStore((state) => state.isExpandedInput);
|
||||||
const setExpandedInput = useUIStore((state) => state.setExpandedInput);
|
const setExpandedInput = useUIStore((state) => state.setExpandedInput);
|
||||||
const setTimelineDialogOpen = useUIStore((state) => state.setTimelineDialogOpen);
|
const setTimelineDialogOpen = useUIStore((state) => state.setTimelineDialogOpen);
|
||||||
@@ -5256,6 +5257,7 @@ const ChatInputComponent: React.FC<ChatInputProps> = ({ onOpenSettings, scrollTo
|
|||||||
maxHeight: !isComposerExpanded && textareaSize ? `${textareaSize.maxHeight}px` : undefined,
|
maxHeight: !isComposerExpanded && textareaSize ? `${textareaSize.maxHeight}px` : undefined,
|
||||||
borderTopLeftRadius: chatInputRadius,
|
borderTopLeftRadius: chatInputRadius,
|
||||||
borderTopRightRadius: chatInputRadius,
|
borderTopRightRadius: chatInputRadius,
|
||||||
|
fontSize: `${editorFontSize}px`,
|
||||||
}}
|
}}
|
||||||
rows={1}
|
rows={1}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ const VisualSectionContent: React.FC = () => {
|
|||||||
...(!isVSCode ? ['weekStart' as const] : []),
|
...(!isVSCode ? ['weekStart' as const] : []),
|
||||||
'fontSize',
|
'fontSize',
|
||||||
'terminalFontSize',
|
'terminalFontSize',
|
||||||
|
'editorFontSize',
|
||||||
'fileEditorKeymap',
|
'fileEditorKeymap',
|
||||||
'spacing',
|
'spacing',
|
||||||
'inputBarOffset',
|
'inputBarOffset',
|
||||||
|
|||||||
@@ -245,7 +245,7 @@ const normalizeUserMessageRenderingMode = (mode: unknown): 'markdown' | 'plain'
|
|||||||
return mode === 'markdown' ? 'markdown' : 'plain';
|
return mode === 'markdown' ? 'markdown' : 'plain';
|
||||||
};
|
};
|
||||||
|
|
||||||
type VisibleSetting = 'sessionAssist' | 'theme' | 'pwaInstallName' | 'pwaOrientation' | 'mobileKeyboardMode' | 'timeFormat' | 'weekStart' | 'fontSize' | 'terminalFontSize' | 'spacing' | 'inputBarOffset' | 'mermaidRendering' | 'userMessageRendering' | 'chatRenderMode' | 'messageTransport' | 'activityRenderMode' | 'collapsibleUserMessages' | 'stickyUserHeader' | 'wideChatLayout' | 'codeBlockLineWrap' | 'splitAssistantMessageActions' | 'diffLayout' | 'mobileStatusBar' | 'dotfiles' | 'fileViewerPreview' | 'reasoning' | 'showToolFileIcons' | 'showTurnChangedFiles' | 'expandedTools' | 'followUpBehavior' | 'terminalQuickKeys' | 'fileEditorKeymap' | 'persistDraft' | 'inputSpellcheck' | 'reportUsage' | 'expandedEditorToolbar';
|
type VisibleSetting = 'sessionAssist' | 'theme' | 'pwaInstallName' | 'pwaOrientation' | 'mobileKeyboardMode' | 'timeFormat' | 'weekStart' | 'fontSize' | 'terminalFontSize' | 'editorFontSize' | 'spacing' | 'inputBarOffset' | 'mermaidRendering' | 'userMessageRendering' | 'chatRenderMode' | 'messageTransport' | 'activityRenderMode' | 'collapsibleUserMessages' | 'stickyUserHeader' | 'wideChatLayout' | 'codeBlockLineWrap' | 'splitAssistantMessageActions' | 'diffLayout' | 'mobileStatusBar' | 'dotfiles' | 'fileViewerPreview' | 'reasoning' | 'showToolFileIcons' | 'showTurnChangedFiles' | 'expandedTools' | 'followUpBehavior' | 'terminalQuickKeys' | 'fileEditorKeymap' | 'persistDraft' | 'inputSpellcheck' | 'reportUsage' | 'expandedEditorToolbar';
|
||||||
|
|
||||||
interface OpenChamberVisualSettingsProps {
|
interface OpenChamberVisualSettingsProps {
|
||||||
/** Which settings to show. If undefined, shows all. */
|
/** Which settings to show. If undefined, shows all. */
|
||||||
@@ -289,6 +289,8 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
|
|||||||
const setFontSize = useUIStore(state => state.setFontSize);
|
const setFontSize = useUIStore(state => state.setFontSize);
|
||||||
const terminalFontSize = useUIStore(state => state.terminalFontSize);
|
const terminalFontSize = useUIStore(state => state.terminalFontSize);
|
||||||
const setTerminalFontSize = useUIStore(state => state.setTerminalFontSize);
|
const setTerminalFontSize = useUIStore(state => state.setTerminalFontSize);
|
||||||
|
const editorFontSize = useUIStore(state => state.editorFontSize);
|
||||||
|
const setEditorFontSize = useUIStore(state => state.setEditorFontSize);
|
||||||
const uiFont = useUIStore(state => state.uiFont);
|
const uiFont = useUIStore(state => state.uiFont);
|
||||||
const setUiFont = useUIStore(state => state.setUiFont);
|
const setUiFont = useUIStore(state => state.setUiFont);
|
||||||
const monoFont = useUIStore(state => state.monoFont);
|
const monoFont = useUIStore(state => state.monoFont);
|
||||||
@@ -553,7 +555,7 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
|
|||||||
const hasAppearanceSettings = isVSCode
|
const hasAppearanceSettings = isVSCode
|
||||||
? hasLocalizationSettings
|
? hasLocalizationSettings
|
||||||
: (shouldShow('theme') || showMobileLayoutSetting || shouldShow('pwaInstallName') || shouldShow('pwaOrientation') || shouldShow('timeFormat') || shouldShow('weekStart'));
|
: (shouldShow('theme') || showMobileLayoutSetting || shouldShow('pwaInstallName') || shouldShow('pwaOrientation') || shouldShow('timeFormat') || shouldShow('weekStart'));
|
||||||
const hasLayoutSettings = shouldShow('fontSize') || shouldShow('terminalFontSize') || shouldShow('spacing') || shouldShow('inputBarOffset');
|
const hasLayoutSettings = shouldShow('fontSize') || shouldShow('terminalFontSize') || shouldShow('editorFontSize') || shouldShow('spacing') || shouldShow('inputBarOffset');
|
||||||
const hasNavigationSettings = (shouldShow('terminalQuickKeys') && !isMobile) || shouldShow('fileEditorKeymap') || shouldShow('expandedEditorToolbar');
|
const hasNavigationSettings = (shouldShow('terminalQuickKeys') && !isMobile) || shouldShow('fileEditorKeymap') || shouldShow('expandedEditorToolbar');
|
||||||
const hasBehaviorSettings = shouldShow('mermaidRendering')
|
const hasBehaviorSettings = shouldShow('mermaidRendering')
|
||||||
|| shouldShow('userMessageRendering')
|
|| shouldShow('userMessageRendering')
|
||||||
@@ -1253,6 +1255,35 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{shouldShow('editorFontSize') && (
|
||||||
|
<div data-settings-item="appearance.editor-font-size" className={cn("py-1", isMobile ? "flex flex-col gap-3" : "flex items-center gap-8")}>
|
||||||
|
<div className={cn("flex min-w-0 flex-col", isMobile ? "w-full" : "w-56 shrink-0")}>
|
||||||
|
<span className="typography-ui-label text-foreground">{t('settings.openchamber.visual.field.editorFontSize')}</span>
|
||||||
|
</div>
|
||||||
|
<div className={cn("flex items-center gap-2", isMobile ? "w-full" : "w-fit")}>
|
||||||
|
<NumberInput
|
||||||
|
value={editorFontSize}
|
||||||
|
onValueChange={setEditorFontSize}
|
||||||
|
min={9}
|
||||||
|
max={32}
|
||||||
|
step={1}
|
||||||
|
className="w-16"
|
||||||
|
/>
|
||||||
|
<Button size="sm"
|
||||||
|
type="button"
|
||||||
|
variant="ghost"
|
||||||
|
onClick={() => setEditorFontSize(13)}
|
||||||
|
disabled={editorFontSize === 13}
|
||||||
|
className="h-7 w-7 px-0 text-muted-foreground hover:text-foreground"
|
||||||
|
aria-label={t('settings.openchamber.visual.actions.resetEditorFontSizeAria')}
|
||||||
|
title={t('settings.common.actions.reset')}
|
||||||
|
>
|
||||||
|
<Icon name="restart" className="h-3.5 w-3.5" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
{shouldShow('spacing') && (
|
{shouldShow('spacing') && (
|
||||||
<div data-settings-item="appearance.spacing-density" className={cn("py-1", isMobile ? "flex flex-col gap-3" : "flex items-center gap-8")}>
|
<div data-settings-item="appearance.spacing-density" className={cn("py-1", isMobile ? "flex flex-col gap-3" : "flex items-center gap-8")}>
|
||||||
<div className={cn("flex min-w-0 flex-col", isMobile ? "w-full" : "w-56 shrink-0")}>
|
<div className={cn("flex min-w-0 flex-col", isMobile ? "w-full" : "w-56 shrink-0")}>
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import { shikiHighlightExtension } from '@/lib/codemirror/shikiHighlight';
|
|||||||
import { getResolvedShikiTheme } from '@/lib/shiki/appThemeRegistry';
|
import { getResolvedShikiTheme } from '@/lib/shiki/appThemeRegistry';
|
||||||
import { getLanguageFromExtension } from '@/lib/toolHelpers';
|
import { getLanguageFromExtension } from '@/lib/toolHelpers';
|
||||||
import { useThemeSystem } from '@/contexts/useThemeSystem';
|
import { useThemeSystem } from '@/contexts/useThemeSystem';
|
||||||
|
import { useUIStore } from '@/stores/useUIStore';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import { EditorView } from '@codemirror/view';
|
import { EditorView } from '@codemirror/view';
|
||||||
import type { Extension } from '@codemirror/state';
|
import type { Extension } from '@codemirror/state';
|
||||||
@@ -244,22 +245,24 @@ const SkillsInstalledPage: React.FC = () => {
|
|||||||
loadSkillDetails();
|
loadSkillDetails();
|
||||||
}, [selectedSkill, isNewSkill, selectedSkillName, skills, skillDraft, getSkillDetail]);
|
}, [selectedSkill, isNewSkill, selectedSkillName, skills, skillDraft, getSkillDetail]);
|
||||||
|
|
||||||
|
const editorFontSize = useUIStore((state) => state.editorFontSize);
|
||||||
|
|
||||||
const skillEditorExtensions = React.useMemo<Extension[]>(() => {
|
const skillEditorExtensions = React.useMemo<Extension[]>(() => {
|
||||||
const extensions: Extension[] = [createFlexokiCodeMirrorTheme(currentTheme)];
|
const extensions: Extension[] = [createFlexokiCodeMirrorTheme(currentTheme, { fontSize: editorFontSize })];
|
||||||
const markdownExtension = languageByExtension(SKILL_DOCUMENT_PATH);
|
const markdownExtension = languageByExtension(SKILL_DOCUMENT_PATH);
|
||||||
if (markdownExtension) {
|
if (markdownExtension) {
|
||||||
extensions.push(markdownExtension);
|
extensions.push(markdownExtension);
|
||||||
}
|
}
|
||||||
extensions.push(EditorView.lineWrapping);
|
extensions.push(EditorView.lineWrapping);
|
||||||
return extensions;
|
return extensions;
|
||||||
}, [currentTheme]);
|
}, [currentTheme, editorFontSize]);
|
||||||
|
|
||||||
const supportingFileEditorExtensions = React.useMemo<Extension[]>(() => {
|
const supportingFileEditorExtensions = React.useMemo<Extension[]>(() => {
|
||||||
const filePath = newFileName.trim() || 'supporting-file.md';
|
const filePath = newFileName.trim() || 'supporting-file.md';
|
||||||
// Shiki token colors for code supporting files; markdown stays on lezer.
|
// Shiki token colors for code supporting files; markdown stays on lezer.
|
||||||
const shikiLanguage = getLanguageFromExtension(filePath);
|
const shikiLanguage = getLanguageFromExtension(filePath);
|
||||||
const useShiki = Boolean(shikiLanguage) && shikiLanguage !== 'markdown';
|
const useShiki = Boolean(shikiLanguage) && shikiLanguage !== 'markdown';
|
||||||
const extensions: Extension[] = [createFlexokiCodeMirrorTheme(currentTheme, useShiki ? { syntaxColors: false } : undefined)];
|
const extensions: Extension[] = [createFlexokiCodeMirrorTheme(currentTheme, useShiki ? { syntaxColors: false, fontSize: editorFontSize } : { fontSize: editorFontSize })];
|
||||||
const languageExtension = languageByExtension(filePath);
|
const languageExtension = languageByExtension(filePath);
|
||||||
if (languageExtension) {
|
if (languageExtension) {
|
||||||
extensions.push(languageExtension);
|
extensions.push(languageExtension);
|
||||||
@@ -273,7 +276,7 @@ const SkillsInstalledPage: React.FC = () => {
|
|||||||
}
|
}
|
||||||
extensions.push(EditorView.lineWrapping);
|
extensions.push(EditorView.lineWrapping);
|
||||||
return extensions;
|
return extensions;
|
||||||
}, [currentTheme, newFileName]);
|
}, [currentTheme, newFileName, editorFontSize]);
|
||||||
|
|
||||||
const handleDescriptionChange = React.useCallback((nextDescription: string) => {
|
const handleDescriptionChange = React.useCallback((nextDescription: string) => {
|
||||||
setDescription(nextDescription);
|
setDescription(nextDescription);
|
||||||
|
|||||||
@@ -2885,17 +2885,19 @@ export const FilesView: React.FC<FilesViewProps> = ({ mode = 'full' }) => {
|
|||||||
return () => window.removeEventListener('keydown', handleKeyDown);
|
return () => window.removeEventListener('keydown', handleKeyDown);
|
||||||
}, [canEdit, isMobile, shortcutOverrides, textViewMode]);
|
}, [canEdit, isMobile, shortcutOverrides, textViewMode]);
|
||||||
|
|
||||||
|
const editorFontSize = useUIStore((state) => state.editorFontSize);
|
||||||
|
|
||||||
const editorExtensions = React.useMemo(() => {
|
const editorExtensions = React.useMemo(() => {
|
||||||
if (!selectedFile?.path) {
|
if (!selectedFile?.path) {
|
||||||
return [createFlexokiCodeMirrorTheme(currentTheme)];
|
return [createFlexokiCodeMirrorTheme(currentTheme, { fontSize: editorFontSize })];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shiki token colors (worker-backed) match the Shiki file view exactly.
|
// Shiki token colors (worker-backed) match the Shiki file view exactly.
|
||||||
// Same language resolver as the view, so both agree on the language. When
|
// Same language resolver as the view, so both agree on the language. When
|
||||||
// Shiki is the color source, drop the lezer token colors to avoid a
|
// Shiki is the color source, drop the lezer token colors to avoid a
|
||||||
// competing highlighter (keep the lezer language for indentation/folding).
|
// competing highlighter (Keep the lezer language for indentation/folding).
|
||||||
const shikiLanguage = getLanguageFromExtension(selectedFile.path);
|
const shikiLanguage = getLanguageFromExtension(selectedFile.path);
|
||||||
const extensions = [createFlexokiCodeMirrorTheme(currentTheme, shikiLanguage ? { syntaxColors: false } : undefined)];
|
const extensions = [createFlexokiCodeMirrorTheme(currentTheme, shikiLanguage ? { syntaxColors: false, fontSize: editorFontSize } : { fontSize: editorFontSize })];
|
||||||
const language = staticLanguageExtension ?? dynamicLanguageExtension;
|
const language = staticLanguageExtension ?? dynamicLanguageExtension;
|
||||||
if (language) {
|
if (language) {
|
||||||
extensions.push(language);
|
extensions.push(language);
|
||||||
@@ -2925,7 +2927,7 @@ export const FilesView: React.FC<FilesViewProps> = ({ mode = 'full' }) => {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
return extensions;
|
return extensions;
|
||||||
}, [currentTheme, selectedFile?.path, staticLanguageExtension, dynamicLanguageExtension, wrapLines, isMobile, nudgeEditorSelectionAboveKeyboard]);
|
}, [currentTheme, selectedFile?.path, staticLanguageExtension, dynamicLanguageExtension, wrapLines, isMobile, nudgeEditorSelectionAboveKeyboard, editorFontSize]);
|
||||||
|
|
||||||
const pierreTheme = React.useMemo(
|
const pierreTheme = React.useMemo(
|
||||||
() => ({ light: lightTheme.metadata.id, dark: darkTheme.metadata.id }),
|
() => ({ light: lightTheme.metadata.id, dark: darkTheme.metadata.id }),
|
||||||
|
|||||||
@@ -345,12 +345,14 @@ export const PlanView: React.FC<PlanViewProps> = ({ targetPath = null }) => {
|
|||||||
};
|
};
|
||||||
}, [cancel, commentText, editingDraftId, isMobile, lineSelection]);
|
}, [cancel, commentText, editingDraftId, isMobile, lineSelection]);
|
||||||
|
|
||||||
|
const editorFontSize = useUIStore((state) => state.editorFontSize);
|
||||||
|
|
||||||
const editorExtensions = React.useMemo(() => {
|
const editorExtensions = React.useMemo(() => {
|
||||||
// Shiki token colors only for code files; markdown keeps the lezer
|
// Shiki token colors only for code files; markdown keeps the lezer
|
||||||
// highlighter (markdown-aware bold headings etc., and no Shiki view to match).
|
// highlighter (markdown-aware bold headings etc., and no Shiki view to match).
|
||||||
const shikiLanguage = resolvedPath ? getLanguageFromExtension(resolvedPath) : null;
|
const shikiLanguage = resolvedPath ? getLanguageFromExtension(resolvedPath) : null;
|
||||||
const useShiki = Boolean(shikiLanguage) && shikiLanguage !== 'markdown';
|
const useShiki = Boolean(shikiLanguage) && shikiLanguage !== 'markdown';
|
||||||
const extensions = [createFlexokiCodeMirrorTheme(currentTheme, useShiki ? { syntaxColors: false } : undefined)];
|
const extensions = [createFlexokiCodeMirrorTheme(currentTheme, useShiki ? { syntaxColors: false, fontSize: editorFontSize } : { fontSize: editorFontSize })];
|
||||||
const language = languageByExtension(resolvedPath || 'plan.md');
|
const language = languageByExtension(resolvedPath || 'plan.md');
|
||||||
if (language) {
|
if (language) {
|
||||||
extensions.push(language);
|
extensions.push(language);
|
||||||
@@ -364,7 +366,7 @@ export const PlanView: React.FC<PlanViewProps> = ({ targetPath = null }) => {
|
|||||||
}
|
}
|
||||||
extensions.push(EditorView.lineWrapping);
|
extensions.push(EditorView.lineWrapping);
|
||||||
return extensions;
|
return extensions;
|
||||||
}, [currentTheme, resolvedPath]);
|
}, [currentTheme, resolvedPath, editorFontSize]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
// Saved project plans opened via context panel should work even when session plan mode is off.
|
// Saved project plans opened via context panel should work even when session plan mode is off.
|
||||||
|
|||||||
@@ -657,6 +657,7 @@ export interface SettingsPayload {
|
|||||||
showSplitAssistantMessageActions?: boolean;
|
showSplitAssistantMessageActions?: boolean;
|
||||||
fontSize?: number;
|
fontSize?: number;
|
||||||
terminalFontSize?: number;
|
terminalFontSize?: number;
|
||||||
|
editorFontSize?: number;
|
||||||
uiFont?: string;
|
uiFont?: string;
|
||||||
monoFont?: string;
|
monoFont?: string;
|
||||||
padding?: number;
|
padding?: number;
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ type AppearanceSlice = {
|
|||||||
sessionRetentionAction: 'archive' | 'delete';
|
sessionRetentionAction: 'archive' | 'delete';
|
||||||
fontSize: number;
|
fontSize: number;
|
||||||
terminalFontSize: number;
|
terminalFontSize: number;
|
||||||
|
editorFontSize: number;
|
||||||
uiFont: UiFontOption;
|
uiFont: UiFontOption;
|
||||||
monoFont: MonoFontOption;
|
monoFont: MonoFontOption;
|
||||||
padding: number;
|
padding: number;
|
||||||
@@ -72,6 +73,7 @@ export const startAppearanceAutoSave = (): void => {
|
|||||||
sessionRetentionAction: useUIStore.getState().sessionRetentionAction,
|
sessionRetentionAction: useUIStore.getState().sessionRetentionAction,
|
||||||
fontSize: useUIStore.getState().fontSize,
|
fontSize: useUIStore.getState().fontSize,
|
||||||
terminalFontSize: useUIStore.getState().terminalFontSize,
|
terminalFontSize: useUIStore.getState().terminalFontSize,
|
||||||
|
editorFontSize: useUIStore.getState().editorFontSize,
|
||||||
uiFont: useUIStore.getState().uiFont,
|
uiFont: useUIStore.getState().uiFont,
|
||||||
monoFont: useUIStore.getState().monoFont,
|
monoFont: useUIStore.getState().monoFont,
|
||||||
padding: useUIStore.getState().padding,
|
padding: useUIStore.getState().padding,
|
||||||
@@ -125,6 +127,7 @@ export const startAppearanceAutoSave = (): void => {
|
|||||||
sessionRetentionAction: state.sessionRetentionAction,
|
sessionRetentionAction: state.sessionRetentionAction,
|
||||||
fontSize: state.fontSize,
|
fontSize: state.fontSize,
|
||||||
terminalFontSize: state.terminalFontSize,
|
terminalFontSize: state.terminalFontSize,
|
||||||
|
editorFontSize: state.editorFontSize,
|
||||||
uiFont: state.uiFont,
|
uiFont: state.uiFont,
|
||||||
monoFont: state.monoFont,
|
monoFont: state.monoFont,
|
||||||
padding: state.padding,
|
padding: state.padding,
|
||||||
@@ -200,6 +203,9 @@ export const startAppearanceAutoSave = (): void => {
|
|||||||
if (current.terminalFontSize !== previous.terminalFontSize) {
|
if (current.terminalFontSize !== previous.terminalFontSize) {
|
||||||
diff.terminalFontSize = current.terminalFontSize;
|
diff.terminalFontSize = current.terminalFontSize;
|
||||||
}
|
}
|
||||||
|
if (current.editorFontSize !== previous.editorFontSize) {
|
||||||
|
diff.editorFontSize = current.editorFontSize;
|
||||||
|
}
|
||||||
if (current.uiFont !== previous.uiFont) {
|
if (current.uiFont !== previous.uiFont) {
|
||||||
diff.uiFont = current.uiFont;
|
diff.uiFont = current.uiFont;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export function createFlexokiCodeMirrorTheme(
|
|||||||
// When syntax colors are provided elsewhere (e.g. the Shiki decoration
|
// When syntax colors are provided elsewhere (e.g. the Shiki decoration
|
||||||
// extension), pass `{ syntaxColors: false }` to keep only the editor UI theme
|
// extension), pass `{ syntaxColors: false }` to keep only the editor UI theme
|
||||||
// (gutters, selection, cursor) and avoid a competing token color source.
|
// (gutters, selection, cursor) and avoid a competing token color source.
|
||||||
options?: { syntaxColors?: boolean },
|
options?: { syntaxColors?: boolean; fontSize?: number },
|
||||||
): Extension {
|
): Extension {
|
||||||
const isDark = theme.metadata.variant === 'dark';
|
const isDark = theme.metadata.variant === 'dark';
|
||||||
|
|
||||||
@@ -19,12 +19,14 @@ export function createFlexokiCodeMirrorTheme(
|
|||||||
const highlights = theme.colors.syntax.highlights || {};
|
const highlights = theme.colors.syntax.highlights || {};
|
||||||
const tokens = theme.colors.syntax.tokens || {};
|
const tokens = theme.colors.syntax.tokens || {};
|
||||||
|
|
||||||
|
const contentFontSize = options?.fontSize ? `${options.fontSize}px` : 'var(--text-code)';
|
||||||
|
|
||||||
const ui = EditorView.theme({
|
const ui = EditorView.theme({
|
||||||
'&': {
|
'&': {
|
||||||
backgroundColor: 'var(--background)',
|
backgroundColor: 'var(--background)',
|
||||||
color: theme.colors.syntax.base.foreground,
|
color: theme.colors.syntax.base.foreground,
|
||||||
fontSize: 'var(--text-code)',
|
fontSize: contentFontSize,
|
||||||
lineHeight: '1.5rem',
|
lineHeight: '1.5',
|
||||||
position: 'relative' as const,
|
position: 'relative' as const,
|
||||||
},
|
},
|
||||||
'.cm-scroller': {
|
'.cm-scroller': {
|
||||||
|
|||||||
@@ -155,6 +155,7 @@ export type DesktopSettings = {
|
|||||||
showSplitAssistantMessageActions?: boolean;
|
showSplitAssistantMessageActions?: boolean;
|
||||||
fontSize?: number;
|
fontSize?: number;
|
||||||
terminalFontSize?: number;
|
terminalFontSize?: number;
|
||||||
|
editorFontSize?: number;
|
||||||
uiFont?: string;
|
uiFont?: string;
|
||||||
monoFont?: string;
|
monoFont?: string;
|
||||||
padding?: number;
|
padding?: number;
|
||||||
|
|||||||
@@ -1731,10 +1731,12 @@ export const settingsDict = {
|
|||||||
'settings.openchamber.visual.field.fontSizePercentageAria': 'Font size percentage',
|
'settings.openchamber.visual.field.fontSizePercentageAria': 'Font size percentage',
|
||||||
'settings.openchamber.visual.actions.resetFontSizeAria': 'Reset font size',
|
'settings.openchamber.visual.actions.resetFontSizeAria': 'Reset font size',
|
||||||
'settings.openchamber.visual.field.terminalFontSize': 'Terminal Font Size',
|
'settings.openchamber.visual.field.terminalFontSize': 'Terminal Font Size',
|
||||||
|
'settings.openchamber.visual.field.editorFontSize': 'Editor Font Size',
|
||||||
'settings.openchamber.visual.field.codeFont': 'Code Font',
|
'settings.openchamber.visual.field.codeFont': 'Code Font',
|
||||||
'settings.openchamber.visual.field.selectCodeFontAria': 'Select code font',
|
'settings.openchamber.visual.field.selectCodeFontAria': 'Select code font',
|
||||||
'settings.openchamber.visual.actions.resetCodeFontAria': 'Reset code font',
|
'settings.openchamber.visual.actions.resetCodeFontAria': 'Reset code font',
|
||||||
'settings.openchamber.visual.actions.resetTerminalFontSizeAria': 'Reset terminal font size',
|
'settings.openchamber.visual.actions.resetTerminalFontSizeAria': 'Reset terminal font size',
|
||||||
|
'settings.openchamber.visual.actions.resetEditorFontSizeAria': 'Reset editor font size',
|
||||||
'settings.openchamber.visual.field.spacingDensity': 'Spacing Density',
|
'settings.openchamber.visual.field.spacingDensity': 'Spacing Density',
|
||||||
'settings.openchamber.visual.actions.resetSpacingAria': 'Reset spacing',
|
'settings.openchamber.visual.actions.resetSpacingAria': 'Reset spacing',
|
||||||
'settings.openchamber.visual.field.inputBarOffset': 'Input Bar Offset',
|
'settings.openchamber.visual.field.inputBarOffset': 'Input Bar Offset',
|
||||||
|
|||||||
@@ -1698,10 +1698,12 @@ export const settingsDict = {
|
|||||||
"settings.openchamber.visual.field.fontSizePercentageAria": "Porcentaje de tamaño de fuente",
|
"settings.openchamber.visual.field.fontSizePercentageAria": "Porcentaje de tamaño de fuente",
|
||||||
"settings.openchamber.visual.actions.resetFontSizeAria": "Restablecer tamaño de fuente",
|
"settings.openchamber.visual.actions.resetFontSizeAria": "Restablecer tamaño de fuente",
|
||||||
"settings.openchamber.visual.field.terminalFontSize": "Tamaño de fuente del terminal",
|
"settings.openchamber.visual.field.terminalFontSize": "Tamaño de fuente del terminal",
|
||||||
|
"settings.openchamber.visual.field.editorFontSize": "Tamaño de fuente del editor",
|
||||||
"settings.openchamber.visual.field.codeFont": "Fuente de código",
|
"settings.openchamber.visual.field.codeFont": "Fuente de código",
|
||||||
"settings.openchamber.visual.field.selectCodeFontAria": "Seleccionar fuente de código",
|
"settings.openchamber.visual.field.selectCodeFontAria": "Seleccionar fuente de código",
|
||||||
"settings.openchamber.visual.actions.resetCodeFontAria": "Restablecer fuente de código",
|
"settings.openchamber.visual.actions.resetCodeFontAria": "Restablecer fuente de código",
|
||||||
"settings.openchamber.visual.actions.resetTerminalFontSizeAria": "Restablecer tamaño de fuente del terminal",
|
"settings.openchamber.visual.actions.resetTerminalFontSizeAria": "Restablecer tamaño de fuente del terminal",
|
||||||
|
"settings.openchamber.visual.actions.resetEditorFontSizeAria": "Restablecer tamaño de fuente del editor",
|
||||||
"settings.openchamber.visual.field.spacingDensity": "Densidad de espaciado",
|
"settings.openchamber.visual.field.spacingDensity": "Densidad de espaciado",
|
||||||
"settings.openchamber.visual.actions.resetSpacingAria": "Restablecer espaciado",
|
"settings.openchamber.visual.actions.resetSpacingAria": "Restablecer espaciado",
|
||||||
"settings.openchamber.visual.field.inputBarOffset": "Desplazamiento de la barra de entrada",
|
"settings.openchamber.visual.field.inputBarOffset": "Desplazamiento de la barra de entrada",
|
||||||
|
|||||||
@@ -1613,10 +1613,12 @@ export const settingsDict = {
|
|||||||
'settings.openchamber.visual.field.fontSizePercentageAria': 'Pourcentage de taille de police',
|
'settings.openchamber.visual.field.fontSizePercentageAria': 'Pourcentage de taille de police',
|
||||||
'settings.openchamber.visual.actions.resetFontSizeAria': 'Réinitialiser la taille de la police',
|
'settings.openchamber.visual.actions.resetFontSizeAria': 'Réinitialiser la taille de la police',
|
||||||
'settings.openchamber.visual.field.terminalFontSize': 'Taille de la police du terminal',
|
'settings.openchamber.visual.field.terminalFontSize': 'Taille de la police du terminal',
|
||||||
|
'settings.openchamber.visual.field.editorFontSize': 'Taille de la police de l\'éditeur',
|
||||||
'settings.openchamber.visual.field.codeFont': 'Police de code',
|
'settings.openchamber.visual.field.codeFont': 'Police de code',
|
||||||
'settings.openchamber.visual.field.selectCodeFontAria': 'Sélectionnez la police du code',
|
'settings.openchamber.visual.field.selectCodeFontAria': 'Sélectionnez la police du code',
|
||||||
'settings.openchamber.visual.actions.resetCodeFontAria': 'Réinitialiser la police du code',
|
'settings.openchamber.visual.actions.resetCodeFontAria': 'Réinitialiser la police du code',
|
||||||
'settings.openchamber.visual.actions.resetTerminalFontSizeAria': 'Réinitialiser la taille de la police du terminal',
|
'settings.openchamber.visual.actions.resetTerminalFontSizeAria': 'Réinitialiser la taille de la police du terminal',
|
||||||
|
'settings.openchamber.visual.actions.resetEditorFontSizeAria': 'Réinitialiser la taille de la police de l\'éditeur',
|
||||||
'settings.openchamber.visual.field.spacingDensity': 'Densité d\'espacement',
|
'settings.openchamber.visual.field.spacingDensity': 'Densité d\'espacement',
|
||||||
'settings.openchamber.visual.actions.resetSpacingAria': 'Réinitialiser l\'espacement',
|
'settings.openchamber.visual.actions.resetSpacingAria': 'Réinitialiser l\'espacement',
|
||||||
'settings.openchamber.visual.field.inputBarOffset': 'Décalage de la barre d\'entrée',
|
'settings.openchamber.visual.field.inputBarOffset': 'Décalage de la barre d\'entrée',
|
||||||
|
|||||||
@@ -1731,10 +1731,12 @@ export const settingsDict = {
|
|||||||
'settings.openchamber.visual.field.fontSizePercentageAria': 'フォントサイズの割合',
|
'settings.openchamber.visual.field.fontSizePercentageAria': 'フォントサイズの割合',
|
||||||
'settings.openchamber.visual.actions.resetFontSizeAria': 'フォントサイズをリセット',
|
'settings.openchamber.visual.actions.resetFontSizeAria': 'フォントサイズをリセット',
|
||||||
'settings.openchamber.visual.field.terminalFontSize': 'ターミナルフォントサイズ',
|
'settings.openchamber.visual.field.terminalFontSize': 'ターミナルフォントサイズ',
|
||||||
|
'settings.openchamber.visual.field.editorFontSize': 'エディターフォントサイズ',
|
||||||
'settings.openchamber.visual.field.codeFont': 'コードフォント',
|
'settings.openchamber.visual.field.codeFont': 'コードフォント',
|
||||||
'settings.openchamber.visual.field.selectCodeFontAria': 'コードフォントを選択',
|
'settings.openchamber.visual.field.selectCodeFontAria': 'コードフォントを選択',
|
||||||
'settings.openchamber.visual.actions.resetCodeFontAria': 'コードフォントをリセット',
|
'settings.openchamber.visual.actions.resetCodeFontAria': 'コードフォントをリセット',
|
||||||
'settings.openchamber.visual.actions.resetTerminalFontSizeAria': 'ターミナルフォントサイズをリセット',
|
'settings.openchamber.visual.actions.resetTerminalFontSizeAria': 'ターミナルフォントサイズをリセット',
|
||||||
|
'settings.openchamber.visual.actions.resetEditorFontSizeAria': 'エディターフォントサイズをリセット',
|
||||||
'settings.openchamber.visual.field.spacingDensity': '間隔の密度',
|
'settings.openchamber.visual.field.spacingDensity': '間隔の密度',
|
||||||
'settings.openchamber.visual.actions.resetSpacingAria': '間隔をリセット',
|
'settings.openchamber.visual.actions.resetSpacingAria': '間隔をリセット',
|
||||||
'settings.openchamber.visual.field.inputBarOffset': '入力バーオフセット',
|
'settings.openchamber.visual.field.inputBarOffset': '入力バーオフセット',
|
||||||
|
|||||||
@@ -1698,10 +1698,12 @@ export const settingsDict = {
|
|||||||
'settings.openchamber.visual.field.fontSizePercentageAria': '폰트 크기 비율',
|
'settings.openchamber.visual.field.fontSizePercentageAria': '폰트 크기 비율',
|
||||||
'settings.openchamber.visual.actions.resetFontSizeAria': '폰트 크기 초기화',
|
'settings.openchamber.visual.actions.resetFontSizeAria': '폰트 크기 초기화',
|
||||||
'settings.openchamber.visual.field.terminalFontSize': '터미널 폰트 크기',
|
'settings.openchamber.visual.field.terminalFontSize': '터미널 폰트 크기',
|
||||||
|
'settings.openchamber.visual.field.editorFontSize': '에디터 폰트 크기',
|
||||||
'settings.openchamber.visual.field.codeFont': '코드 폰트',
|
'settings.openchamber.visual.field.codeFont': '코드 폰트',
|
||||||
'settings.openchamber.visual.field.selectCodeFontAria': '코드 폰트 선택',
|
'settings.openchamber.visual.field.selectCodeFontAria': '코드 폰트 선택',
|
||||||
'settings.openchamber.visual.actions.resetCodeFontAria': '코드 폰트 초기화',
|
'settings.openchamber.visual.actions.resetCodeFontAria': '코드 폰트 초기화',
|
||||||
'settings.openchamber.visual.actions.resetTerminalFontSizeAria': '터미널 폰트 크기 초기화',
|
'settings.openchamber.visual.actions.resetTerminalFontSizeAria': '터미널 폰트 크기 초기화',
|
||||||
|
'settings.openchamber.visual.actions.resetEditorFontSizeAria': '에디터 폰트 크기 초기화',
|
||||||
'settings.openchamber.visual.field.spacingDensity': '간격 밀도',
|
'settings.openchamber.visual.field.spacingDensity': '간격 밀도',
|
||||||
'settings.openchamber.visual.actions.resetSpacingAria': '간격 초기화',
|
'settings.openchamber.visual.actions.resetSpacingAria': '간격 초기화',
|
||||||
'settings.openchamber.visual.field.inputBarOffset': '입력 바 오프셋',
|
'settings.openchamber.visual.field.inputBarOffset': '입력 바 오프셋',
|
||||||
|
|||||||
@@ -935,6 +935,7 @@ export const settingsDict = {
|
|||||||
'settings.openchamber.visual.actions.resetInterfaceFontAria': 'Zresetuj czcionkę interfejsu',
|
'settings.openchamber.visual.actions.resetInterfaceFontAria': 'Zresetuj czcionkę interfejsu',
|
||||||
'settings.openchamber.visual.actions.resetSpacingAria': 'Zresetuj odstępy',
|
'settings.openchamber.visual.actions.resetSpacingAria': 'Zresetuj odstępy',
|
||||||
'settings.openchamber.visual.actions.resetTerminalFontSizeAria': 'Zresetuj rozmiar czcionki terminala',
|
'settings.openchamber.visual.actions.resetTerminalFontSizeAria': 'Zresetuj rozmiar czcionki terminala',
|
||||||
|
'settings.openchamber.visual.actions.resetEditorFontSizeAria': 'Zresetuj rozmiar czcionki edytora',
|
||||||
'settings.openchamber.visual.field.activityDefaultModeAria': 'Domyślny tryb aktywności: {option}',
|
'settings.openchamber.visual.field.activityDefaultModeAria': 'Domyślny tryb aktywności: {option}',
|
||||||
'settings.openchamber.visual.field.bash': 'Bash',
|
'settings.openchamber.visual.field.bash': 'Bash',
|
||||||
'settings.openchamber.visual.field.codeFont': 'Czcionka kodu',
|
'settings.openchamber.visual.field.codeFont': 'Czcionka kodu',
|
||||||
@@ -1004,6 +1005,7 @@ export const settingsDict = {
|
|||||||
'settings.openchamber.visual.field.expandedEditorToolbarAria': 'Always show editor toolbar',
|
'settings.openchamber.visual.field.expandedEditorToolbarAria': 'Always show editor toolbar',
|
||||||
'settings.openchamber.visual.field.expandedEditorToolbar': 'Always show editor toolbar (docked under the file tabs)',
|
'settings.openchamber.visual.field.expandedEditorToolbar': 'Always show editor toolbar (docked under the file tabs)',
|
||||||
'settings.openchamber.visual.field.terminalFontSize': 'Rozmiar czcionki terminala',
|
'settings.openchamber.visual.field.terminalFontSize': 'Rozmiar czcionki terminala',
|
||||||
|
'settings.openchamber.visual.field.editorFontSize': 'Rozmiar czcionki edytora',
|
||||||
'settings.openchamber.visual.field.terminalQuickKeys': 'Szybkie klawisze terminala',
|
'settings.openchamber.visual.field.terminalQuickKeys': 'Szybkie klawisze terminala',
|
||||||
'settings.openchamber.visual.field.terminalQuickKeysAria': 'Szybkie klawisze terminala',
|
'settings.openchamber.visual.field.terminalQuickKeysAria': 'Szybkie klawisze terminala',
|
||||||
'settings.openchamber.visual.field.terminalQuickKeysTooltip': 'Pokaż Esc, Ctrl i strzałki w widoku terminala',
|
'settings.openchamber.visual.field.terminalQuickKeysTooltip': 'Pokaż Esc, Ctrl i strzałki w widoku terminala',
|
||||||
|
|||||||
@@ -1698,10 +1698,12 @@ export const settingsDict = {
|
|||||||
"settings.openchamber.visual.field.fontSizePercentageAria": "Porcentagem do tamanho base",
|
"settings.openchamber.visual.field.fontSizePercentageAria": "Porcentagem do tamanho base",
|
||||||
"settings.openchamber.visual.actions.resetFontSizeAria": "Redefinir tamanho base",
|
"settings.openchamber.visual.actions.resetFontSizeAria": "Redefinir tamanho base",
|
||||||
"settings.openchamber.visual.field.terminalFontSize": "Tamanho base do terminal",
|
"settings.openchamber.visual.field.terminalFontSize": "Tamanho base do terminal",
|
||||||
|
"settings.openchamber.visual.field.editorFontSize": "Tamanho base do editor",
|
||||||
"settings.openchamber.visual.field.codeFont": "Fonte do código",
|
"settings.openchamber.visual.field.codeFont": "Fonte do código",
|
||||||
"settings.openchamber.visual.field.selectCodeFontAria": "Selecionar fonte do código",
|
"settings.openchamber.visual.field.selectCodeFontAria": "Selecionar fonte do código",
|
||||||
"settings.openchamber.visual.actions.resetCodeFontAria": "Redefinir fonte do código",
|
"settings.openchamber.visual.actions.resetCodeFontAria": "Redefinir fonte do código",
|
||||||
"settings.openchamber.visual.actions.resetTerminalFontSizeAria": "Redefinir tamanho base do terminal",
|
"settings.openchamber.visual.actions.resetTerminalFontSizeAria": "Redefinir tamanho base do terminal",
|
||||||
|
"settings.openchamber.visual.actions.resetEditorFontSizeAria": "Redefinir tamanho base do editor",
|
||||||
"settings.openchamber.visual.field.spacingDensity": "Densidade de espaçamento",
|
"settings.openchamber.visual.field.spacingDensity": "Densidade de espaçamento",
|
||||||
"settings.openchamber.visual.actions.resetSpacingAria": "Redefinir espaçamento",
|
"settings.openchamber.visual.actions.resetSpacingAria": "Redefinir espaçamento",
|
||||||
"settings.openchamber.visual.field.inputBarOffset": "Deslocamento da barra de entrada",
|
"settings.openchamber.visual.field.inputBarOffset": "Deslocamento da barra de entrada",
|
||||||
|
|||||||
@@ -1698,10 +1698,12 @@ export const settingsDict = {
|
|||||||
"settings.openchamber.visual.field.fontSizePercentageAria": "Розмір шрифту у відсотках",
|
"settings.openchamber.visual.field.fontSizePercentageAria": "Розмір шрифту у відсотках",
|
||||||
"settings.openchamber.visual.actions.resetFontSizeAria": "Скинути розмір шрифту",
|
"settings.openchamber.visual.actions.resetFontSizeAria": "Скинути розмір шрифту",
|
||||||
"settings.openchamber.visual.field.terminalFontSize": "Розмір шрифту терміналу",
|
"settings.openchamber.visual.field.terminalFontSize": "Розмір шрифту терміналу",
|
||||||
|
"settings.openchamber.visual.field.editorFontSize": "Розмір шрифту редактора",
|
||||||
"settings.openchamber.visual.field.codeFont": "Шрифт коду",
|
"settings.openchamber.visual.field.codeFont": "Шрифт коду",
|
||||||
"settings.openchamber.visual.field.selectCodeFontAria": "Вибрати шрифт коду",
|
"settings.openchamber.visual.field.selectCodeFontAria": "Вибрати шрифт коду",
|
||||||
"settings.openchamber.visual.actions.resetCodeFontAria": "Скинути шрифт коду",
|
"settings.openchamber.visual.actions.resetCodeFontAria": "Скинути шрифт коду",
|
||||||
"settings.openchamber.visual.actions.resetTerminalFontSizeAria": "Скинути розмір шрифту терміналу",
|
"settings.openchamber.visual.actions.resetTerminalFontSizeAria": "Скинути розмір шрифту терміналу",
|
||||||
|
"settings.openchamber.visual.actions.resetEditorFontSizeAria": "Скинути розмір шрифту редактора",
|
||||||
"settings.openchamber.visual.field.spacingDensity": "Щільність інтервалу",
|
"settings.openchamber.visual.field.spacingDensity": "Щільність інтервалу",
|
||||||
"settings.openchamber.visual.actions.resetSpacingAria": "Скинути інтервал",
|
"settings.openchamber.visual.actions.resetSpacingAria": "Скинути інтервал",
|
||||||
"settings.openchamber.visual.field.inputBarOffset": "Зміщення панелі вводу",
|
"settings.openchamber.visual.field.inputBarOffset": "Зміщення панелі вводу",
|
||||||
|
|||||||
@@ -1698,10 +1698,12 @@ export const settingsDict = {
|
|||||||
'settings.openchamber.visual.field.fontSizePercentageAria': '字体大小百分比',
|
'settings.openchamber.visual.field.fontSizePercentageAria': '字体大小百分比',
|
||||||
'settings.openchamber.visual.actions.resetFontSizeAria': '重置字体大小',
|
'settings.openchamber.visual.actions.resetFontSizeAria': '重置字体大小',
|
||||||
'settings.openchamber.visual.field.terminalFontSize': '终端字体大小',
|
'settings.openchamber.visual.field.terminalFontSize': '终端字体大小',
|
||||||
|
'settings.openchamber.visual.field.editorFontSize': '编辑器字体大小',
|
||||||
'settings.openchamber.visual.field.codeFont': '代码字体',
|
'settings.openchamber.visual.field.codeFont': '代码字体',
|
||||||
'settings.openchamber.visual.field.selectCodeFontAria': '选择代码字体',
|
'settings.openchamber.visual.field.selectCodeFontAria': '选择代码字体',
|
||||||
'settings.openchamber.visual.actions.resetCodeFontAria': '重置代码字体',
|
'settings.openchamber.visual.actions.resetCodeFontAria': '重置代码字体',
|
||||||
'settings.openchamber.visual.actions.resetTerminalFontSizeAria': '重置终端字体大小',
|
'settings.openchamber.visual.actions.resetTerminalFontSizeAria': '重置终端字体大小',
|
||||||
|
'settings.openchamber.visual.actions.resetEditorFontSizeAria': '重置编辑器字体大小',
|
||||||
'settings.openchamber.visual.field.spacingDensity': '间距密度',
|
'settings.openchamber.visual.field.spacingDensity': '间距密度',
|
||||||
'settings.openchamber.visual.actions.resetSpacingAria': '重置间距',
|
'settings.openchamber.visual.actions.resetSpacingAria': '重置间距',
|
||||||
'settings.openchamber.visual.field.inputBarOffset': '输入栏偏移',
|
'settings.openchamber.visual.field.inputBarOffset': '输入栏偏移',
|
||||||
|
|||||||
@@ -1609,10 +1609,12 @@
|
|||||||
'settings.openchamber.visual.field.fontSizePercentageAria': '字體大小百分比',
|
'settings.openchamber.visual.field.fontSizePercentageAria': '字體大小百分比',
|
||||||
'settings.openchamber.visual.actions.resetFontSizeAria': '重設字體大小',
|
'settings.openchamber.visual.actions.resetFontSizeAria': '重設字體大小',
|
||||||
'settings.openchamber.visual.field.terminalFontSize': '終端機字體大小',
|
'settings.openchamber.visual.field.terminalFontSize': '終端機字體大小',
|
||||||
|
'settings.openchamber.visual.field.editorFontSize': '編輯器字體大小',
|
||||||
'settings.openchamber.visual.field.codeFont': '程式碼字體',
|
'settings.openchamber.visual.field.codeFont': '程式碼字體',
|
||||||
'settings.openchamber.visual.field.selectCodeFontAria': '選擇程式碼字體',
|
'settings.openchamber.visual.field.selectCodeFontAria': '選擇程式碼字體',
|
||||||
'settings.openchamber.visual.actions.resetCodeFontAria': '重設程式碼字體',
|
'settings.openchamber.visual.actions.resetCodeFontAria': '重設程式碼字體',
|
||||||
'settings.openchamber.visual.actions.resetTerminalFontSizeAria': '重設終端機字體大小',
|
'settings.openchamber.visual.actions.resetTerminalFontSizeAria': '重設終端機字體大小',
|
||||||
|
'settings.openchamber.visual.actions.resetEditorFontSizeAria': '重設編輯器字體大小',
|
||||||
'settings.openchamber.visual.field.spacingDensity': '間距密度',
|
'settings.openchamber.visual.field.spacingDensity': '間距密度',
|
||||||
'settings.openchamber.visual.actions.resetSpacingAria': '重設間距',
|
'settings.openchamber.visual.actions.resetSpacingAria': '重設間距',
|
||||||
'settings.openchamber.visual.field.inputBarOffset': '輸入列偏移',
|
'settings.openchamber.visual.field.inputBarOffset': '輸入列偏移',
|
||||||
|
|||||||
@@ -594,6 +594,9 @@ const applyDesktopUiPreferences = (settings: DesktopSettings) => {
|
|||||||
if (typeof settings.terminalFontSize === 'number' && Number.isFinite(settings.terminalFontSize) && settings.terminalFontSize !== store.terminalFontSize) {
|
if (typeof settings.terminalFontSize === 'number' && Number.isFinite(settings.terminalFontSize) && settings.terminalFontSize !== store.terminalFontSize) {
|
||||||
store.setTerminalFontSize(settings.terminalFontSize);
|
store.setTerminalFontSize(settings.terminalFontSize);
|
||||||
}
|
}
|
||||||
|
if (typeof settings.editorFontSize === 'number' && Number.isFinite(settings.editorFontSize) && settings.editorFontSize !== store.editorFontSize) {
|
||||||
|
store.setEditorFontSize(settings.editorFontSize);
|
||||||
|
}
|
||||||
if (isUiFontOption(settings.uiFont) && settings.uiFont !== store.uiFont) {
|
if (isUiFontOption(settings.uiFont) && settings.uiFont !== store.uiFont) {
|
||||||
store.setUiFont(settings.uiFont);
|
store.setUiFont(settings.uiFont);
|
||||||
}
|
}
|
||||||
@@ -1111,6 +1114,9 @@ const sanitizeWebSettings = (payload: unknown): DesktopSettings | null => {
|
|||||||
if (typeof candidate.terminalFontSize === 'number' && Number.isFinite(candidate.terminalFontSize)) {
|
if (typeof candidate.terminalFontSize === 'number' && Number.isFinite(candidate.terminalFontSize)) {
|
||||||
result.terminalFontSize = candidate.terminalFontSize;
|
result.terminalFontSize = candidate.terminalFontSize;
|
||||||
}
|
}
|
||||||
|
if (typeof candidate.editorFontSize === 'number' && Number.isFinite(candidate.editorFontSize)) {
|
||||||
|
result.editorFontSize = candidate.editorFontSize;
|
||||||
|
}
|
||||||
if (isUiFontOption(candidate.uiFont)) {
|
if (isUiFontOption(candidate.uiFont)) {
|
||||||
result.uiFont = candidate.uiFont;
|
result.uiFont = candidate.uiFont;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,6 +116,12 @@ const SETTINGS_SEARCH_ITEMS: readonly SettingsSearchItem[] = [
|
|||||||
titleKey: 'settings.openchamber.visual.field.terminalFontSize',
|
titleKey: 'settings.openchamber.visual.field.terminalFontSize',
|
||||||
keywords: ['terminal', 'font', 'text size'],
|
keywords: ['terminal', 'font', 'text size'],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'appearance.editor-font-size',
|
||||||
|
page: 'appearance',
|
||||||
|
titleKey: 'settings.openchamber.visual.field.editorFontSize',
|
||||||
|
keywords: ['editor', 'font', 'text size', 'code'],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'appearance.spacing-density',
|
id: 'appearance.spacing-density',
|
||||||
page: 'appearance',
|
page: 'appearance',
|
||||||
|
|||||||
@@ -587,6 +587,7 @@ interface UIStore {
|
|||||||
// Global draft welcome starters; null = unset (use the default built-in set).
|
// Global draft welcome starters; null = unset (use the default built-in set).
|
||||||
globalDraftStarters: DraftStarterRef[] | null;
|
globalDraftStarters: DraftStarterRef[] | null;
|
||||||
terminalFontSize: number;
|
terminalFontSize: number;
|
||||||
|
editorFontSize: number;
|
||||||
uiFont: UiFontOption;
|
uiFont: UiFontOption;
|
||||||
monoFont: MonoFontOption;
|
monoFont: MonoFontOption;
|
||||||
padding: number;
|
padding: number;
|
||||||
@@ -736,6 +737,7 @@ interface UIStore {
|
|||||||
setFontSize: (size: number) => void;
|
setFontSize: (size: number) => void;
|
||||||
setGlobalDraftStarters: (refs: DraftStarterRef[]) => void;
|
setGlobalDraftStarters: (refs: DraftStarterRef[]) => void;
|
||||||
setTerminalFontSize: (size: number) => void;
|
setTerminalFontSize: (size: number) => void;
|
||||||
|
setEditorFontSize: (size: number) => void;
|
||||||
setUiFont: (font: UiFontOption) => void;
|
setUiFont: (font: UiFontOption) => void;
|
||||||
setMonoFont: (font: MonoFontOption) => void;
|
setMonoFont: (font: MonoFontOption) => void;
|
||||||
setPadding: (size: number) => void;
|
setPadding: (size: number) => void;
|
||||||
@@ -883,6 +885,7 @@ export const useUIStore = create<UIStore>()(
|
|||||||
fontSize: 100,
|
fontSize: 100,
|
||||||
globalDraftStarters: null,
|
globalDraftStarters: null,
|
||||||
terminalFontSize: 13,
|
terminalFontSize: 13,
|
||||||
|
editorFontSize: 13,
|
||||||
uiFont: DEFAULT_UI_FONT,
|
uiFont: DEFAULT_UI_FONT,
|
||||||
monoFont: DEFAULT_MONO_FONT,
|
monoFont: DEFAULT_MONO_FONT,
|
||||||
padding: 100,
|
padding: 100,
|
||||||
@@ -1633,6 +1636,12 @@ export const useUIStore = create<UIStore>()(
|
|||||||
set({ terminalFontSize: clamped });
|
set({ terminalFontSize: clamped });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setEditorFontSize: (size) => {
|
||||||
|
const rounded = Math.round(size);
|
||||||
|
const clamped = Math.max(9, Math.min(32, rounded));
|
||||||
|
set({ editorFontSize: clamped });
|
||||||
|
},
|
||||||
|
|
||||||
setUiFont: (font) => {
|
setUiFont: (font) => {
|
||||||
set({ uiFont: font });
|
set({ uiFont: font });
|
||||||
},
|
},
|
||||||
@@ -2279,6 +2288,7 @@ export const useUIStore = create<UIStore>()(
|
|||||||
fontSize: state.fontSize,
|
fontSize: state.fontSize,
|
||||||
globalDraftStarters: state.globalDraftStarters,
|
globalDraftStarters: state.globalDraftStarters,
|
||||||
terminalFontSize: state.terminalFontSize,
|
terminalFontSize: state.terminalFontSize,
|
||||||
|
editorFontSize: state.editorFontSize,
|
||||||
uiFont: state.uiFont,
|
uiFont: state.uiFont,
|
||||||
monoFont: state.monoFont,
|
monoFont: state.monoFont,
|
||||||
padding: state.padding,
|
padding: state.padding,
|
||||||
|
|||||||
Reference in New Issue
Block a user