feat: add collapsible user message setting
This commit is contained in:
@@ -8,6 +8,7 @@ import { useSkillsStore } from '@/stores/useSkillsStore';
|
||||
import { Icon } from "@/components/icon/Icon";
|
||||
import { useEffectiveDirectory } from '@/hooks/useEffectiveDirectory';
|
||||
import { getDirectoryForFilePath } from '@/lib/path-utils';
|
||||
import { useI18n } from '@/lib/i18n';
|
||||
import {
|
||||
buildAgentHref,
|
||||
buildAgentMentionUrl,
|
||||
@@ -57,9 +58,11 @@ const UserTextPart: React.FC<UserTextPartProps> = ({ part, messageId, agentMenti
|
||||
const [isExpanded, setIsExpanded] = React.useState(false);
|
||||
const [isTruncated, setIsTruncated] = React.useState(false);
|
||||
const userMessageRenderingMode = useUIStore((state) => state.userMessageRenderingMode);
|
||||
const collapsibleUserMessages = useUIStore((state) => state.collapsibleUserMessages);
|
||||
const skills = useSkillsStore((state) => state.skills);
|
||||
const openContextFile = useUIStore((state) => state.openContextFile);
|
||||
const effectiveDirectory = useEffectiveDirectory();
|
||||
const { t } = useI18n();
|
||||
const normalizedRenderingMode = normalizeUserMessageRenderingMode(userMessageRenderingMode);
|
||||
const textRef = React.useRef<HTMLDivElement>(null);
|
||||
const skillByName = React.useMemo(() => new Map(skills.map((skill) => [skill.name, skill])), [skills]);
|
||||
@@ -89,7 +92,7 @@ const UserTextPart: React.FC<UserTextPartProps> = ({ part, messageId, agentMenti
|
||||
if (!el) return;
|
||||
|
||||
const checkTruncation = () => {
|
||||
if (!isExpanded) {
|
||||
if (collapsibleUserMessages && !isExpanded) {
|
||||
setIsTruncated(el.scrollHeight > el.clientHeight);
|
||||
}
|
||||
};
|
||||
@@ -100,7 +103,14 @@ const UserTextPart: React.FC<UserTextPartProps> = ({ part, messageId, agentMenti
|
||||
resizeObserver.observe(el);
|
||||
|
||||
return () => resizeObserver.disconnect();
|
||||
}, [textContent, isExpanded]);
|
||||
}, [collapsibleUserMessages, textContent, isExpanded]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!collapsibleUserMessages) {
|
||||
setIsExpanded(false);
|
||||
setIsTruncated(false);
|
||||
}
|
||||
}, [collapsibleUserMessages]);
|
||||
|
||||
const handleClick = React.useCallback((event: React.MouseEvent<HTMLDivElement>) => {
|
||||
const target = event.target as HTMLElement | null;
|
||||
@@ -123,10 +133,10 @@ const UserTextPart: React.FC<UserTextPartProps> = ({ part, messageId, agentMenti
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isExpanded && isTruncated) {
|
||||
if (collapsibleUserMessages && !isExpanded && isTruncated) {
|
||||
setIsExpanded(true);
|
||||
}
|
||||
}, [hasActiveSelectionInElement, isExpanded, isTruncated, openSkill]);
|
||||
}, [collapsibleUserMessages, hasActiveSelectionInElement, isExpanded, isTruncated, openSkill]);
|
||||
|
||||
const handleCollapse = React.useCallback((event: React.MouseEvent) => {
|
||||
event.stopPropagation();
|
||||
@@ -222,12 +232,12 @@ const UserTextPart: React.FC<UserTextPartProps> = ({ part, messageId, agentMenti
|
||||
|
||||
return (
|
||||
<div className="relative" key={part.id || `${messageId}-user-text`}>
|
||||
{isExpanded && (
|
||||
{collapsibleUserMessages && isExpanded && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleCollapse}
|
||||
className="absolute top-0 right-0 z-10 flex items-center justify-center rounded-sm bg-[var(--surface-elevated)] p-0.5 text-[var(--surface-mutedForeground)] hover:text-[var(--surface-foreground)] hover:bg-[var(--interactive-hover)] transition-colors"
|
||||
aria-label="Collapse"
|
||||
aria-label={t('chat.message.userText.collapseAria')}
|
||||
>
|
||||
<Icon name="arrow-up-s" className="h-3.5 w-3.5" />
|
||||
</button>
|
||||
@@ -237,8 +247,8 @@ const UserTextPart: React.FC<UserTextPartProps> = ({ part, messageId, agentMenti
|
||||
"break-words font-sans typography-markdown-body",
|
||||
isExpanded && "pb-3",
|
||||
normalizedRenderingMode === 'plain' && 'whitespace-pre-wrap',
|
||||
!isExpanded && "line-clamp-2",
|
||||
isTruncated && !isExpanded && "cursor-pointer"
|
||||
collapsibleUserMessages && !isExpanded && "line-clamp-2",
|
||||
collapsibleUserMessages && isTruncated && !isExpanded && "cursor-pointer"
|
||||
)}
|
||||
ref={textRef}
|
||||
onClick={handleClick}
|
||||
|
||||
@@ -143,7 +143,7 @@ const VisualSectionContent: React.FC = () => {
|
||||
|
||||
// Chat section: User message rendering, Diff layout, Mobile status bar, Show reasoning traces, Queue mode, Persist draft
|
||||
const ChatSectionContent: React.FC = () => {
|
||||
return <OpenChamberVisualSettings visibleSettings={['chatRenderMode', 'messageTransport', 'activityRenderMode', 'userMessageRendering', 'mermaidRendering', 'reasoning', 'showToolFileIcons', 'showTurnChangedFiles', 'expandedTools', 'stickyUserHeader', 'wideChatLayout', 'splitAssistantMessageActions', 'diffLayout', 'dotfiles', 'fileViewerPreview', 'queueMode', 'persistDraft', 'inputSpellcheck']} />;
|
||||
return <OpenChamberVisualSettings visibleSettings={['chatRenderMode', 'messageTransport', 'activityRenderMode', 'userMessageRendering', 'mermaidRendering', 'reasoning', 'showToolFileIcons', 'showTurnChangedFiles', 'expandedTools', 'collapsibleUserMessages', 'stickyUserHeader', 'wideChatLayout', 'splitAssistantMessageActions', 'diffLayout', 'dotfiles', 'fileViewerPreview', 'queueMode', 'persistDraft', 'inputSpellcheck']} />;
|
||||
};
|
||||
|
||||
// Sessions section: Default model & agent, Session retention
|
||||
|
||||
@@ -247,7 +247,7 @@ const normalizeUserMessageRenderingMode = (mode: unknown): 'markdown' | 'plain'
|
||||
return mode === 'markdown' ? 'markdown' : 'plain';
|
||||
};
|
||||
|
||||
export type VisibleSetting = 'theme' | 'pwaInstallName' | 'pwaOrientation' | 'mobileKeyboardMode' | 'timeFormat' | 'weekStart' | 'fontSize' | 'terminalFontSize' | 'spacing' | 'inputBarOffset' | 'mermaidRendering' | 'userMessageRendering' | 'chatRenderMode' | 'messageTransport' | 'activityRenderMode' | 'stickyUserHeader' | 'wideChatLayout' | 'splitAssistantMessageActions' | 'diffLayout' | 'mobileStatusBar' | 'dotfiles' | 'fileViewerPreview' | 'reasoning' | 'showToolFileIcons' | 'showTurnChangedFiles' | 'expandedTools' | 'queueMode' | 'terminalQuickKeys' | 'fileEditorKeymap' | 'persistDraft' | 'inputSpellcheck' | 'reportUsage';
|
||||
export type VisibleSetting = 'theme' | 'pwaInstallName' | 'pwaOrientation' | 'mobileKeyboardMode' | 'timeFormat' | 'weekStart' | 'fontSize' | 'terminalFontSize' | 'spacing' | 'inputBarOffset' | 'mermaidRendering' | 'userMessageRendering' | 'chatRenderMode' | 'messageTransport' | 'activityRenderMode' | 'collapsibleUserMessages' | 'stickyUserHeader' | 'wideChatLayout' | 'splitAssistantMessageActions' | 'diffLayout' | 'mobileStatusBar' | 'dotfiles' | 'fileViewerPreview' | 'reasoning' | 'showToolFileIcons' | 'showTurnChangedFiles' | 'expandedTools' | 'queueMode' | 'terminalQuickKeys' | 'fileEditorKeymap' | 'persistDraft' | 'inputSpellcheck' | 'reportUsage';
|
||||
|
||||
interface OpenChamberVisualSettingsProps {
|
||||
/** Which settings to show. If undefined, shows all. */
|
||||
@@ -269,6 +269,8 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
|
||||
const setMermaidRenderingMode = useUIStore(state => state.setMermaidRenderingMode);
|
||||
const userMessageRenderingMode = useUIStore(state => state.userMessageRenderingMode);
|
||||
const setUserMessageRenderingMode = useUIStore(state => state.setUserMessageRenderingMode);
|
||||
const collapsibleUserMessages = useUIStore(state => state.collapsibleUserMessages);
|
||||
const setCollapsibleUserMessages = useUIStore(state => state.setCollapsibleUserMessages);
|
||||
const stickyUserHeader = useUIStore(state => state.stickyUserHeader);
|
||||
const setStickyUserHeader = useUIStore(state => state.setStickyUserHeader);
|
||||
const wideChatLayoutEnabled = useUIStore(state => state.wideChatLayoutEnabled);
|
||||
@@ -413,6 +415,11 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
|
||||
void updateDesktopSettings({ stickyUserHeader: enabled });
|
||||
}, [setStickyUserHeader]);
|
||||
|
||||
const handleCollapsibleUserMessagesChange = React.useCallback((enabled: boolean) => {
|
||||
setCollapsibleUserMessages(enabled);
|
||||
void updateDesktopSettings({ collapsibleUserMessages: enabled });
|
||||
}, [setCollapsibleUserMessages]);
|
||||
|
||||
const handleWideChatLayoutChange = React.useCallback((enabled: boolean) => {
|
||||
setWideChatLayoutEnabled(enabled);
|
||||
void updateDesktopSettings({ wideChatLayoutEnabled: enabled });
|
||||
@@ -532,6 +539,7 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
|
||||
|| shouldShow('chatRenderMode')
|
||||
|| shouldShow('messageTransport')
|
||||
|| (shouldShow('activityRenderMode') && chatRenderMode === 'sorted')
|
||||
|| shouldShow('collapsibleUserMessages')
|
||||
|| shouldShow('stickyUserHeader')
|
||||
|| shouldShow('wideChatLayout')
|
||||
|| shouldShow('splitAssistantMessageActions')
|
||||
@@ -1696,7 +1704,7 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{(shouldShow('stickyUserHeader') || shouldShow('wideChatLayout') || shouldShow('splitAssistantMessageActions') || shouldShow('dotfiles') || shouldShow('fileViewerPreview') || shouldShow('queueMode') || shouldShow('persistDraft') || shouldShow('showToolFileIcons') || shouldShow('showTurnChangedFiles') || (!isMobile && shouldShow('inputSpellcheck')) || shouldShow('reasoning')) && (
|
||||
{(shouldShow('collapsibleUserMessages') || shouldShow('stickyUserHeader') || shouldShow('wideChatLayout') || shouldShow('splitAssistantMessageActions') || shouldShow('dotfiles') || shouldShow('fileViewerPreview') || shouldShow('queueMode') || shouldShow('persistDraft') || shouldShow('showToolFileIcons') || shouldShow('showTurnChangedFiles') || (!isMobile && shouldShow('inputSpellcheck')) || shouldShow('reasoning')) && (
|
||||
<section className="p-2 space-y-0.5">
|
||||
{shouldShow('reasoning') && (
|
||||
<div
|
||||
@@ -1745,6 +1753,30 @@ export const OpenChamberVisualSettings: React.FC<OpenChamberVisualSettingsProps>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{shouldShow('collapsibleUserMessages') && (
|
||||
<div
|
||||
data-settings-item="chat.collapsible-user-messages"
|
||||
className="group flex cursor-pointer items-center gap-2 py-0.5"
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
aria-pressed={collapsibleUserMessages}
|
||||
onClick={() => handleCollapsibleUserMessagesChange(!collapsibleUserMessages)}
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === ' ' || event.key === 'Enter') {
|
||||
event.preventDefault();
|
||||
handleCollapsibleUserMessagesChange(!collapsibleUserMessages);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Checkbox
|
||||
checked={collapsibleUserMessages}
|
||||
onChange={handleCollapsibleUserMessagesChange}
|
||||
ariaLabel={t('settings.openchamber.visual.field.collapsibleUserMessagesAria')}
|
||||
/>
|
||||
<span className="typography-ui-label text-foreground">{t('settings.openchamber.visual.field.collapsibleUserMessages')}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{shouldShow('stickyUserHeader') && (
|
||||
<div
|
||||
data-settings-item="chat.sticky-user-header"
|
||||
|
||||
@@ -144,6 +144,7 @@ export type DesktopSettings = {
|
||||
activityRenderMode?: 'collapsed' | 'summary';
|
||||
mermaidRenderingMode?: 'svg' | 'ascii';
|
||||
userMessageRenderingMode?: 'markdown' | 'plain';
|
||||
collapsibleUserMessages?: boolean;
|
||||
stickyUserHeader?: boolean;
|
||||
wideChatLayoutEnabled?: boolean;
|
||||
showSplitAssistantMessageActions?: boolean;
|
||||
|
||||
@@ -1633,6 +1633,8 @@ export const settingsDict = {
|
||||
'settings.openchamber.visual.field.showReasoningTraces': 'Show Reasoning Traces',
|
||||
'settings.openchamber.visual.field.collapsibleThinkingBlocksAria': 'Enable collapsible reasoning blocks',
|
||||
'settings.openchamber.visual.field.collapsibleThinkingBlocks': 'Enable Collapsible Reasoning Blocks',
|
||||
'settings.openchamber.visual.field.collapsibleUserMessagesAria': 'Collapse long user messages',
|
||||
'settings.openchamber.visual.field.collapsibleUserMessages': 'Collapse Long User Messages',
|
||||
'settings.openchamber.visual.field.stickyUserHeaderAria': 'Sticky user header',
|
||||
'settings.openchamber.visual.field.stickyUserHeader': 'Sticky User Header',
|
||||
'settings.openchamber.visual.field.wideChatLayoutAria': 'Wide chat layout',
|
||||
@@ -1687,6 +1689,7 @@ export const settingsDict = {
|
||||
'settings.openchamber.visual.option.userMessageRendering.markdown.description': 'Render user text with markdown formatting.',
|
||||
'settings.openchamber.visual.option.userMessageRendering.plain.label': 'Plain text',
|
||||
'settings.openchamber.visual.option.userMessageRendering.plain.description': 'Render user text with preserved whitespace and links.',
|
||||
'chat.message.userText.collapseAria': 'Collapse user message',
|
||||
'settings.openchamber.visual.option.chatRenderMode.sorted.label': 'Sorted',
|
||||
'settings.openchamber.visual.option.chatRenderMode.sorted.description': 'Render completed assistant messages without live streaming.',
|
||||
'settings.openchamber.visual.option.chatRenderMode.live.label': 'Live',
|
||||
|
||||
@@ -1600,6 +1600,8 @@ export const settingsDict = {
|
||||
"settings.openchamber.visual.field.showReasoningTraces": "Mostrar trazas de razonamiento",
|
||||
"settings.openchamber.visual.field.collapsibleThinkingBlocksAria": "Habilitar bloques de razonamiento colapsables",
|
||||
"settings.openchamber.visual.field.collapsibleThinkingBlocks": "Habilitar Bloques de Razonamiento Colapsables",
|
||||
"settings.openchamber.visual.field.collapsibleUserMessagesAria": "Contraer mensajes largos del usuario",
|
||||
"settings.openchamber.visual.field.collapsibleUserMessages": "Contraer mensajes largos del usuario",
|
||||
"settings.openchamber.visual.field.stickyUserHeaderAria": "Encabezado del usuario fijo",
|
||||
"settings.openchamber.visual.field.stickyUserHeader": "Encabezado de usuario fijo",
|
||||
"settings.openchamber.visual.field.wideChatLayoutAria": "Diseño de chat ancho",
|
||||
@@ -1654,6 +1656,7 @@ export const settingsDict = {
|
||||
"settings.openchamber.visual.option.userMessageRendering.markdown.description": "Renderiza el texto del usuario con formato markdown.",
|
||||
"settings.openchamber.visual.option.userMessageRendering.plain.label": "Texto plano",
|
||||
"settings.openchamber.visual.option.userMessageRendering.plain.description": "Renderiza el texto del usuario con espacios en blanco y enlaces preservados.",
|
||||
"chat.message.userText.collapseAria": "Contraer mensaje del usuario",
|
||||
"settings.openchamber.visual.option.chatRenderMode.sorted.label": "Ordenado",
|
||||
"settings.openchamber.visual.option.chatRenderMode.sorted.description": "Renderiza mensajes completados del asistente sin transmisión en vivo.",
|
||||
"settings.openchamber.visual.option.chatRenderMode.live.label": "En vivo",
|
||||
|
||||
@@ -1576,6 +1576,8 @@ export const settingsDict = {
|
||||
'settings.openchamber.visual.field.showReasoningTraces': 'Afficher les traces de raisonnement',
|
||||
'settings.openchamber.visual.field.collapsibleThinkingBlocksAria': 'Activer les blocs de raisonnement pliables',
|
||||
'settings.openchamber.visual.field.collapsibleThinkingBlocks': 'Activer les blocs de raisonnement pliables',
|
||||
'settings.openchamber.visual.field.collapsibleUserMessagesAria': 'Réduire les longs messages utilisateur',
|
||||
'settings.openchamber.visual.field.collapsibleUserMessages': 'Réduire les longs messages utilisateur',
|
||||
'settings.openchamber.visual.field.stickyUserHeaderAria': 'En-tête utilisateur collant',
|
||||
'settings.openchamber.visual.field.stickyUserHeader': 'En-tête utilisateur collant',
|
||||
'settings.openchamber.visual.field.wideChatLayoutAria': 'Large disposition de discussion',
|
||||
@@ -1628,6 +1630,7 @@ export const settingsDict = {
|
||||
'settings.openchamber.visual.option.userMessageRendering.markdown.description': 'Rendre le texte utilisateur avec un formatage markdown.',
|
||||
'settings.openchamber.visual.option.userMessageRendering.plain.label': 'Texte brut',
|
||||
'settings.openchamber.visual.option.userMessageRendering.plain.description': 'Rendre le texte utilisateur avec des espaces et des liens préservés.',
|
||||
'chat.message.userText.collapseAria': 'Réduire le message utilisateur',
|
||||
'settings.openchamber.visual.option.chatRenderMode.sorted.label': 'Trié',
|
||||
'settings.openchamber.visual.option.chatRenderMode.sorted.description': 'Restituez les messages de l\'assistant terminés sans diffusion en direct.',
|
||||
'settings.openchamber.visual.option.chatRenderMode.live.label': 'En direct',
|
||||
|
||||
@@ -1600,6 +1600,8 @@ export const settingsDict = {
|
||||
'settings.openchamber.visual.field.showReasoningTraces': 'Reasoning Trace 표시',
|
||||
'settings.openchamber.visual.field.collapsibleThinkingBlocksAria': '접을 수 있는 추론 블록 활성화',
|
||||
'settings.openchamber.visual.field.collapsibleThinkingBlocks': '접을 수 있는 추론 블록 활성화',
|
||||
'settings.openchamber.visual.field.collapsibleUserMessagesAria': '긴 사용자 메시지 접기',
|
||||
'settings.openchamber.visual.field.collapsibleUserMessages': '긴 사용자 메시지 접기',
|
||||
'settings.openchamber.visual.field.stickyUserHeaderAria': '고정 사용자 헤더',
|
||||
'settings.openchamber.visual.field.stickyUserHeader': '고정 사용자 헤더',
|
||||
'settings.openchamber.visual.field.wideChatLayoutAria': '넓은 채팅 레이아웃',
|
||||
@@ -1654,6 +1656,7 @@ export const settingsDict = {
|
||||
'settings.openchamber.visual.option.userMessageRendering.markdown.description': '사용자 텍스트를 Markdown 서식으로 렌더링합니다.',
|
||||
'settings.openchamber.visual.option.userMessageRendering.plain.label': 'Plain text',
|
||||
'settings.openchamber.visual.option.userMessageRendering.plain.description': '공백과 링크를 보존해 사용자 텍스트를 렌더링합니다.',
|
||||
'chat.message.userText.collapseAria': '사용자 메시지 접기',
|
||||
'settings.openchamber.visual.option.chatRenderMode.sorted.label': '정렬됨',
|
||||
'settings.openchamber.visual.option.chatRenderMode.sorted.description': '완료된 assistant 메시지를 live streaming 없이 렌더링합니다.',
|
||||
'settings.openchamber.visual.option.chatRenderMode.live.label': 'Live',
|
||||
|
||||
@@ -940,6 +940,8 @@ export const settingsDict = {
|
||||
'settings.openchamber.visual.field.showReasoningTracesAria': 'Pokaż ślady rozumowania',
|
||||
'settings.openchamber.visual.field.collapsibleThinkingBlocks': 'Włącz zwijalne bloki rozumowania',
|
||||
'settings.openchamber.visual.field.collapsibleThinkingBlocksAria': 'Włącz zwijalne bloki rozumowania',
|
||||
'settings.openchamber.visual.field.collapsibleUserMessages': 'Zwijaj długie wiadomości użytkownika',
|
||||
'settings.openchamber.visual.field.collapsibleUserMessagesAria': 'Zwijaj długie wiadomości użytkownika',
|
||||
'settings.openchamber.visual.field.showSplitAssistantMessageActions': 'Akcje asystenta w treści',
|
||||
'settings.openchamber.visual.field.showSplitAssistantMessageActionsAria': 'Akcje asystenta w treści',
|
||||
'settings.openchamber.visual.field.showSplitAssistantMessageActionsTooltip': 'Pokaż Kopiuj odpowiedź, Zapisz jako obraz i Odczytaj na głos w blokach tekstu asystenta, które pojawiają się przed późniejszymi wywołaniami narzędzi w tej samej odpowiedzi.',
|
||||
@@ -1011,6 +1013,7 @@ export const settingsDict = {
|
||||
'settings.openchamber.visual.option.userMessageRendering.markdown.label': 'Markdown',
|
||||
'settings.openchamber.visual.option.userMessageRendering.plain.description': 'Renderuj tekst użytkownika z zachowaniem białych znaków i linków.',
|
||||
'settings.openchamber.visual.option.userMessageRendering.plain.label': 'Zwykły tekst',
|
||||
'chat.message.userText.collapseAria': 'Zwiń wiadomość użytkownika',
|
||||
'settings.openchamber.visual.option.weekStart.auto.description': 'Używaj lokalnego początku tygodnia.',
|
||||
'settings.openchamber.visual.option.weekStart.auto.label': 'Auto',
|
||||
'settings.openchamber.visual.option.weekStart.monday.label': 'Poniedziałek',
|
||||
|
||||
@@ -1600,6 +1600,8 @@ export const settingsDict = {
|
||||
"settings.openchamber.visual.field.showReasoningTraces": "Mostrar rastros de raciocínio",
|
||||
"settings.openchamber.visual.field.collapsibleThinkingBlocksAria": "Habilitar blocos de raciocínio recolhíveis",
|
||||
"settings.openchamber.visual.field.collapsibleThinkingBlocks": "Habilitar Blocos de Raciocínio Recolhíveis",
|
||||
"settings.openchamber.visual.field.collapsibleUserMessagesAria": "Recolher mensagens longas do usuário",
|
||||
"settings.openchamber.visual.field.collapsibleUserMessages": "Recolher mensagens longas do usuário",
|
||||
"settings.openchamber.visual.field.stickyUserHeaderAria": "Cabeçalho do usuário fixo",
|
||||
"settings.openchamber.visual.field.stickyUserHeader": "Cabeçalho do usuário fixo",
|
||||
"settings.openchamber.visual.field.wideChatLayoutAria": "Layout de chat amplo",
|
||||
@@ -1654,6 +1656,7 @@ export const settingsDict = {
|
||||
"settings.openchamber.visual.option.userMessageRendering.markdown.description": "Renderiza o texto do usuário com formato markdown.",
|
||||
"settings.openchamber.visual.option.userMessageRendering.plain.label": "Texto simples",
|
||||
"settings.openchamber.visual.option.userMessageRendering.plain.description": "Renderiza o texto do usuário com espaços em branco e links preservados.",
|
||||
"chat.message.userText.collapseAria": "Recolher mensagem do usuário",
|
||||
"settings.openchamber.visual.option.chatRenderMode.sorted.label": "Ordenado",
|
||||
"settings.openchamber.visual.option.chatRenderMode.sorted.description": "Renderiza mensagens concluídas do assistente sem transmissão ao vivo.",
|
||||
"settings.openchamber.visual.option.chatRenderMode.live.label": "Ao vivo",
|
||||
|
||||
@@ -1600,6 +1600,8 @@ export const settingsDict = {
|
||||
"settings.openchamber.visual.field.showReasoningTraces": "Показати сліди міркувань",
|
||||
"settings.openchamber.visual.field.collapsibleThinkingBlocksAria": "Увімкнути згортальні блоки міркувань",
|
||||
"settings.openchamber.visual.field.collapsibleThinkingBlocks": "Увімкнути згортальні блоки міркувань",
|
||||
"settings.openchamber.visual.field.collapsibleUserMessagesAria": "Згортати довгі повідомлення користувача",
|
||||
"settings.openchamber.visual.field.collapsibleUserMessages": "Згортати довгі повідомлення користувача",
|
||||
"settings.openchamber.visual.field.stickyUserHeaderAria": "Закріплений заголовок користувача",
|
||||
"settings.openchamber.visual.field.stickyUserHeader": "Закріплений заголовок користувача",
|
||||
"settings.openchamber.visual.field.wideChatLayoutAria": "Широкий макет чату",
|
||||
@@ -1654,6 +1656,7 @@ export const settingsDict = {
|
||||
"settings.openchamber.visual.option.userMessageRendering.markdown.description": "Виводити текст користувача з форматуванням розмітки.",
|
||||
"settings.openchamber.visual.option.userMessageRendering.plain.label": "Звичайний текст",
|
||||
"settings.openchamber.visual.option.userMessageRendering.plain.description": "Показувати текст користувача зі збереженням пробілів і посилань.",
|
||||
"chat.message.userText.collapseAria": "Згорнути повідомлення користувача",
|
||||
"settings.openchamber.visual.option.chatRenderMode.sorted.label": "Відсортовано",
|
||||
"settings.openchamber.visual.option.chatRenderMode.sorted.description": "Показувати готові повідомлення помічника без live-трансляції.",
|
||||
"settings.openchamber.visual.option.chatRenderMode.live.label": "Live",
|
||||
|
||||
@@ -1600,6 +1600,8 @@ export const settingsDict = {
|
||||
'settings.openchamber.visual.field.showReasoningTraces': '显示推理轨迹',
|
||||
'settings.openchamber.visual.field.collapsibleThinkingBlocksAria': '启用可折叠推理块',
|
||||
'settings.openchamber.visual.field.collapsibleThinkingBlocks': '启用可折叠推理块',
|
||||
'settings.openchamber.visual.field.collapsibleUserMessagesAria': '折叠较长的用户消息',
|
||||
'settings.openchamber.visual.field.collapsibleUserMessages': '折叠较长的用户消息',
|
||||
'settings.openchamber.visual.field.stickyUserHeaderAria': '固定用户消息头',
|
||||
'settings.openchamber.visual.field.stickyUserHeader': '固定用户消息头',
|
||||
'settings.openchamber.visual.field.wideChatLayoutAria': '宽聊天布局',
|
||||
@@ -1654,6 +1656,7 @@ export const settingsDict = {
|
||||
'settings.openchamber.visual.option.userMessageRendering.markdown.description': '用 Markdown 格式渲染用户文本。',
|
||||
'settings.openchamber.visual.option.userMessageRendering.plain.label': '纯文本',
|
||||
'settings.openchamber.visual.option.userMessageRendering.plain.description': '保留空白和链接,以纯文本渲染用户文本。',
|
||||
'chat.message.userText.collapseAria': '折叠用户消息',
|
||||
'settings.openchamber.visual.option.chatRenderMode.sorted.label': '排序后显示',
|
||||
'settings.openchamber.visual.option.chatRenderMode.sorted.description': '不进行实时流式显示,待助手消息完成后再渲染。',
|
||||
'settings.openchamber.visual.option.chatRenderMode.live.label': '实时显示',
|
||||
|
||||
@@ -1521,6 +1521,8 @@
|
||||
'settings.openchamber.visual.field.showReasoningTraces': '顯示推理軌跡',
|
||||
'settings.openchamber.visual.field.collapsibleThinkingBlocksAria': '啟用可摺疊推理區塊',
|
||||
'settings.openchamber.visual.field.collapsibleThinkingBlocks': '啟用可摺疊推理區塊',
|
||||
'settings.openchamber.visual.field.collapsibleUserMessagesAria': '收合較長的使用者訊息',
|
||||
'settings.openchamber.visual.field.collapsibleUserMessages': '收合較長的使用者訊息',
|
||||
'settings.openchamber.visual.field.stickyUserHeaderAria': '固定使用者訊息標頭',
|
||||
'settings.openchamber.visual.field.stickyUserHeader': '固定使用者訊息標頭',
|
||||
'settings.openchamber.visual.field.wideChatLayoutAria': '寬聊天佈局',
|
||||
@@ -1575,6 +1577,7 @@
|
||||
'settings.openchamber.visual.option.userMessageRendering.markdown.description': '用 Markdown 格式渲染使用者文字。',
|
||||
'settings.openchamber.visual.option.userMessageRendering.plain.label': '純文字',
|
||||
'settings.openchamber.visual.option.userMessageRendering.plain.description': '保留空白和連結,以純文字渲染使用者文字。',
|
||||
'chat.message.userText.collapseAria': '收合使用者訊息',
|
||||
'settings.openchamber.visual.option.chatRenderMode.sorted.label': '排序後顯示',
|
||||
'settings.openchamber.visual.option.chatRenderMode.sorted.description': '不進行即時串流顯示,待助理訊息完成後再渲染。',
|
||||
'settings.openchamber.visual.option.chatRenderMode.live.label': '即時顯示',
|
||||
|
||||
@@ -500,6 +500,9 @@ const applyDesktopUiPreferences = (settings: DesktopSettings) => {
|
||||
store.setUserMessageRenderingMode(settings.userMessageRenderingMode);
|
||||
}
|
||||
}
|
||||
if (typeof settings.collapsibleUserMessages === 'boolean' && settings.collapsibleUserMessages !== store.collapsibleUserMessages) {
|
||||
store.setCollapsibleUserMessages(settings.collapsibleUserMessages);
|
||||
}
|
||||
if (typeof settings.messageStreamTransport === 'string'
|
||||
&& (settings.messageStreamTransport === 'auto' || settings.messageStreamTransport === 'ws' || settings.messageStreamTransport === 'sse')) {
|
||||
if (configStore && settings.messageStreamTransport !== configStore.settingsMessageStreamTransport) {
|
||||
@@ -997,6 +1000,9 @@ const sanitizeWebSettings = (payload: unknown): DesktopSettings | null => {
|
||||
&& (candidate.userMessageRenderingMode === 'markdown' || candidate.userMessageRenderingMode === 'plain')) {
|
||||
result.userMessageRenderingMode = candidate.userMessageRenderingMode;
|
||||
}
|
||||
if (typeof candidate.collapsibleUserMessages === 'boolean') {
|
||||
result.collapsibleUserMessages = candidate.collapsibleUserMessages;
|
||||
}
|
||||
if (typeof candidate.stickyUserHeader === 'boolean') {
|
||||
result.stickyUserHeader = candidate.stickyUserHeader;
|
||||
}
|
||||
|
||||
@@ -160,6 +160,12 @@ export const SETTINGS_SEARCH_ITEMS: readonly SettingsSearchItem[] = [
|
||||
titleKey: 'settings.openchamber.visual.field.stickyUserHeader',
|
||||
keywords: ['messages', 'header'],
|
||||
},
|
||||
{
|
||||
id: 'chat.collapsible-user-messages',
|
||||
page: 'chat',
|
||||
titleKey: 'settings.openchamber.visual.field.collapsibleUserMessages',
|
||||
keywords: ['collapse', 'expand', 'clamp', 'long messages', 'user messages'],
|
||||
},
|
||||
{
|
||||
id: 'chat.wide-layout',
|
||||
page: 'chat',
|
||||
|
||||
@@ -618,6 +618,7 @@ interface UIStore {
|
||||
weekStartPreference: WeekStartPreference;
|
||||
mermaidRenderingMode: MermaidRenderingMode;
|
||||
userMessageRenderingMode: UserMessageRenderingMode;
|
||||
collapsibleUserMessages: boolean;
|
||||
stickyUserHeader: boolean;
|
||||
showSplitAssistantMessageActions: boolean;
|
||||
isMobileSessionStatusBarCollapsed: boolean;
|
||||
@@ -760,6 +761,7 @@ interface UIStore {
|
||||
setWeekStartPreference: (value: WeekStartPreference) => void;
|
||||
setMermaidRenderingMode: (value: MermaidRenderingMode) => void;
|
||||
setUserMessageRenderingMode: (value: UserMessageRenderingMode) => void;
|
||||
setCollapsibleUserMessages: (value: boolean) => void;
|
||||
setStickyUserHeader: (value: boolean) => void;
|
||||
setShowSplitAssistantMessageActions: (value: boolean) => void;
|
||||
setIsMobileSessionStatusBarCollapsed: (value: boolean) => void;
|
||||
@@ -895,6 +897,7 @@ export const useUIStore = create<UIStore>()(
|
||||
weekStartPreference: 'auto',
|
||||
mermaidRenderingMode: 'svg',
|
||||
userMessageRenderingMode: 'markdown',
|
||||
collapsibleUserMessages: true,
|
||||
stickyUserHeader: false,
|
||||
showSplitAssistantMessageActions: false,
|
||||
isMobileSessionStatusBarCollapsed: false,
|
||||
@@ -2001,6 +2004,9 @@ export const useUIStore = create<UIStore>()(
|
||||
setUserMessageRenderingMode: (value) => {
|
||||
set({ userMessageRenderingMode: value });
|
||||
},
|
||||
setCollapsibleUserMessages: (value) => {
|
||||
set({ collapsibleUserMessages: value });
|
||||
},
|
||||
setStickyUserHeader: (value) => {
|
||||
set({ stickyUserHeader: value });
|
||||
},
|
||||
@@ -2232,6 +2238,7 @@ export const useUIStore = create<UIStore>()(
|
||||
weekStartPreference: state.weekStartPreference,
|
||||
mermaidRenderingMode: state.mermaidRenderingMode,
|
||||
userMessageRenderingMode: state.userMessageRenderingMode,
|
||||
collapsibleUserMessages: state.collapsibleUserMessages,
|
||||
stickyUserHeader: state.stickyUserHeader,
|
||||
showSplitAssistantMessageActions: state.showSplitAssistantMessageActions,
|
||||
isMobileSessionStatusBarCollapsed: state.isMobileSessionStatusBarCollapsed,
|
||||
|
||||
Reference in New Issue
Block a user