mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-05 06:24:37 +00:00
fix(web): compact terminal tool cards by default (#601)
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
import { beforeEach, describe, expect, it } from 'vitest'
|
||||
import {
|
||||
DEFAULT_TERMINAL_TOOL_DISPLAY_MODE,
|
||||
getInitialTerminalToolDisplayMode,
|
||||
getTerminalToolDisplayModeOptions,
|
||||
} from './useTerminalToolDisplayMode'
|
||||
|
||||
describe('useTerminalToolDisplayMode helpers', () => {
|
||||
beforeEach(() => {
|
||||
window.localStorage.clear()
|
||||
})
|
||||
|
||||
it('returns the allowed terminal tool display options', () => {
|
||||
expect(getTerminalToolDisplayModeOptions()).toEqual([
|
||||
{ value: 'compact', labelKey: 'settings.chat.terminalToolDisplay.compact' },
|
||||
{ value: 'detailed', labelKey: 'settings.chat.terminalToolDisplay.detailed' },
|
||||
])
|
||||
})
|
||||
|
||||
it('falls back to the default display mode for missing or invalid storage values', () => {
|
||||
expect(getInitialTerminalToolDisplayMode()).toBe(DEFAULT_TERMINAL_TOOL_DISPLAY_MODE)
|
||||
|
||||
window.localStorage.setItem('hapi-terminal-tool-display-mode', 'invalid')
|
||||
expect(getInitialTerminalToolDisplayMode()).toBe(DEFAULT_TERMINAL_TOOL_DISPLAY_MODE)
|
||||
})
|
||||
|
||||
it('reads a valid stored terminal tool display mode', () => {
|
||||
window.localStorage.setItem('hapi-terminal-tool-display-mode', 'detailed')
|
||||
|
||||
expect(getInitialTerminalToolDisplayMode()).toBe('detailed')
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,99 @@
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
|
||||
export type TerminalToolDisplayMode = 'compact' | 'detailed'
|
||||
|
||||
export const DEFAULT_TERMINAL_TOOL_DISPLAY_MODE: TerminalToolDisplayMode = 'compact'
|
||||
|
||||
export function getTerminalToolDisplayModeOptions(): ReadonlyArray<{ value: TerminalToolDisplayMode; labelKey: string }> {
|
||||
return [
|
||||
{ value: 'compact', labelKey: 'settings.chat.terminalToolDisplay.compact' },
|
||||
{ value: 'detailed', labelKey: 'settings.chat.terminalToolDisplay.detailed' },
|
||||
]
|
||||
}
|
||||
|
||||
function getTerminalToolDisplayModeStorageKey(): string {
|
||||
return 'hapi-terminal-tool-display-mode'
|
||||
}
|
||||
|
||||
function isBrowser(): boolean {
|
||||
return typeof window !== 'undefined' && typeof document !== 'undefined'
|
||||
}
|
||||
|
||||
function safeGetItem(key: string): string | null {
|
||||
if (!isBrowser()) {
|
||||
return null
|
||||
}
|
||||
try {
|
||||
return localStorage.getItem(key)
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
function safeSetItem(key: string, value: string): void {
|
||||
if (!isBrowser()) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
localStorage.setItem(key, value)
|
||||
} catch {
|
||||
// Ignore storage errors
|
||||
}
|
||||
}
|
||||
|
||||
function safeRemoveItem(key: string): void {
|
||||
if (!isBrowser()) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
localStorage.removeItem(key)
|
||||
} catch {
|
||||
// Ignore storage errors
|
||||
}
|
||||
}
|
||||
|
||||
function parseTerminalToolDisplayMode(raw: string | null): TerminalToolDisplayMode {
|
||||
if (raw === 'compact' || raw === 'detailed') {
|
||||
return raw
|
||||
}
|
||||
return DEFAULT_TERMINAL_TOOL_DISPLAY_MODE
|
||||
}
|
||||
|
||||
export function getInitialTerminalToolDisplayMode(): TerminalToolDisplayMode {
|
||||
return parseTerminalToolDisplayMode(safeGetItem(getTerminalToolDisplayModeStorageKey()))
|
||||
}
|
||||
|
||||
export function useTerminalToolDisplayMode(): {
|
||||
terminalToolDisplayMode: TerminalToolDisplayMode
|
||||
setTerminalToolDisplayMode: (mode: TerminalToolDisplayMode) => void
|
||||
} {
|
||||
const [terminalToolDisplayMode, setTerminalToolDisplayModeState] = useState<TerminalToolDisplayMode>(getInitialTerminalToolDisplayMode)
|
||||
|
||||
useEffect(() => {
|
||||
if (!isBrowser()) {
|
||||
return
|
||||
}
|
||||
|
||||
const onStorage = (event: StorageEvent) => {
|
||||
if (event.key !== getTerminalToolDisplayModeStorageKey()) {
|
||||
return
|
||||
}
|
||||
setTerminalToolDisplayModeState(parseTerminalToolDisplayMode(event.newValue))
|
||||
}
|
||||
|
||||
window.addEventListener('storage', onStorage)
|
||||
return () => window.removeEventListener('storage', onStorage)
|
||||
}, [])
|
||||
|
||||
const setTerminalToolDisplayMode = useCallback((mode: TerminalToolDisplayMode) => {
|
||||
setTerminalToolDisplayModeState(mode)
|
||||
|
||||
if (mode === DEFAULT_TERMINAL_TOOL_DISPLAY_MODE) {
|
||||
safeRemoveItem(getTerminalToolDisplayModeStorageKey())
|
||||
} else {
|
||||
safeSetItem(getTerminalToolDisplayModeStorageKey(), mode)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return { terminalToolDisplayMode, setTerminalToolDisplayMode }
|
||||
}
|
||||
Reference in New Issue
Block a user