Skip to content

Commit 950a213

Browse files
committed
Let users hide the bottom function key bar
A beta user found the F-key command-button row at the bottom of the window wasted space and asked to hide it. Add an `appearance.showFunctionKeyBar` boolean setting (Appearance > Listing, default `true` so current behavior is preserved) that toggles the bar live, no restart. - New registry entry + `SettingsValues` type, modeled on `appearance.useAppIconsForDocuments`. - `reactive-settings.svelte.ts` gains the reactive slot, init read, change-apply case, and a `getShowFunctionKeyBar()` getter (pure-FE setting, so no Tauri command or applier case is needed). - `+page.svelte` feeds `FunctionKeyBar`'s `visible` prop from the reactive getter via `$derived` instead of a hardcoded `true`. - New `SettingSwitch` row in `ListingSection.svelte` ("Show function key bar"). - Tests: registry default/section/keywords/validation, plus the a11y mock for the new row.
1 parent a476c4b commit 950a213

7 files changed

Lines changed: 62 additions & 1 deletion

File tree

apps/desktop/src/lib/settings/reactive-settings.svelte.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ let dateTimeFormat = $state<DateTimeFormat>('iso')
3030
let customDateTimeFormat = $state<string>('YYYY-MM-DD HH:mm')
3131
let fileSizeFormat = $state<FileSizeFormat>('binary')
3232
let useAppIconsForDocuments = $state<boolean>(true)
33+
let showFunctionKeyBar = $state<boolean>(true)
3334
let directorySortMode = $state<DirectorySortMode>('likeFiles')
3435
let appColor = $state<AppColor>('cmdr-gold')
3536
let sizeDisplay = $state<SizeDisplayMode>('smart')
@@ -61,6 +62,7 @@ export async function initReactiveSettings(): Promise<void> {
6162
customDateTimeFormat = getSetting('appearance.customDateTimeFormat')
6263
fileSizeFormat = getSetting('appearance.fileSizeFormat')
6364
useAppIconsForDocuments = getSetting('appearance.useAppIconsForDocuments')
65+
showFunctionKeyBar = getSetting('appearance.showFunctionKeyBar')
6466
directorySortMode = getSetting('listing.directorySortMode')
6567
appColor = getSetting('appearance.appColor')
6668
sizeDisplay = getSetting('listing.sizeDisplay')
@@ -113,6 +115,9 @@ function applySettingChange(id: string, value: unknown): void {
113115
// Clear the icon cache so icons are re-fetched with the new setting
114116
void clearExtensionIconCache()
115117
break
118+
case 'appearance.showFunctionKeyBar':
119+
showFunctionKeyBar = value as boolean
120+
break
116121
case 'listing.directorySortMode':
117122
directorySortMode = value as DirectorySortMode
118123
break
@@ -195,6 +200,11 @@ export function getUseAppIconsForDocuments(): boolean {
195200
return useAppIconsForDocuments
196201
}
197202

203+
/** Get whether the bottom function key bar (F-key command buttons) is shown. */
204+
export function getShowFunctionKeyBar(): boolean {
205+
return showFunctionKeyBar
206+
}
207+
198208
/** Get current directory sort mode */
199209
export function getDirectorySortMode(): DirectorySortMode {
200210
return directorySortMode

apps/desktop/src/lib/settings/sections/ListingSection.a11y.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { expectNoA11yViolations } from '$lib/test-a11y'
1010
vi.mock('$lib/settings/settings-store', () => ({
1111
getSetting: vi.fn((key: string) => {
1212
if (key === 'appearance.useAppIconsForDocuments') return true
13+
if (key === 'appearance.showFunctionKeyBar') return true
1314
if (key === 'listing.directorySortMode') return 'likeFiles'
1415
if (key === 'listing.briefColumnWidthMode') return 'paneWidth'
1516
if (key === 'listing.briefColumnWidthMaxPx') return 400

apps/desktop/src/lib/settings/sections/ListingSection.svelte

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
const shouldShow = $derived(createShouldShow(searchQuery))
1919
2020
const appIconsDef = getSettingDefinition('appearance.useAppIconsForDocuments') ?? { label: '', description: '' }
21+
const fnKeyBarDef = getSettingDefinition('appearance.showFunctionKeyBar') ?? { label: '', description: '' }
2122
const dirSortDef = getSettingDefinition('listing.directorySortMode') ?? { label: '', description: '' }
2223
const briefWidthModeDef = getSettingDefinition('listing.briefColumnWidthMode') ?? { label: '', description: '' }
2324
@@ -44,6 +45,16 @@
4445
<SettingSwitch id="appearance.useAppIconsForDocuments" />
4546
</SettingRow>
4647
{/if}
48+
{#if shouldShow('appearance.showFunctionKeyBar')}
49+
<SettingRow
50+
id="appearance.showFunctionKeyBar"
51+
label={fnKeyBarDef.label}
52+
description={fnKeyBarDef.description}
53+
{searchQuery}
54+
>
55+
<SettingSwitch id="appearance.showFunctionKeyBar" />
56+
</SettingRow>
57+
{/if}
4758
{#if shouldShow('listing.directorySortMode')}
4859
<SettingRow
4960
id="listing.directorySortMode"

apps/desktop/src/lib/settings/settings-registry.test.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,33 @@ describe('search.recentSearches.maxCount', () => {
224224
})
225225
})
226226

227+
describe('appearance.showFunctionKeyBar', () => {
228+
it('registers a boolean switch in Appearance > Listing, defaulting to on (current behavior)', () => {
229+
const def = getSettingDefinition('appearance.showFunctionKeyBar')
230+
expect(def).toBeDefined()
231+
expect(def?.type).toBe('boolean')
232+
expect(def?.component).toBe('switch')
233+
expect(getDefaultValue('appearance.showFunctionKeyBar')).toBe(true)
234+
expect(def?.section).toEqual(['Appearance', 'Listing'])
235+
})
236+
237+
it('is reachable via natural lookup keywords', () => {
238+
const keywords = getSettingDefinition('appearance.showFunctionKeyBar')?.keywords ?? []
239+
for (const term of ['function', 'key', 'bar', 'f-key', 'shortcut']) {
240+
expect(keywords).toContain(term)
241+
}
242+
})
243+
244+
it('validates booleans only', () => {
245+
expect(() => {
246+
validateSettingValue('appearance.showFunctionKeyBar', false)
247+
}).not.toThrow()
248+
expect(() => {
249+
validateSettingValue('appearance.showFunctionKeyBar', 'yes')
250+
}).toThrow()
251+
})
252+
})
253+
227254
describe('buildSectionTree', () => {
228255
it('should build a tree from settings', () => {
229256
const tree = buildSectionTree()

apps/desktop/src/lib/settings/settings-registry.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,16 @@ export const settingsRegistry: SettingDefinition[] = [
291291
default: true,
292292
component: 'switch',
293293
},
294+
{
295+
id: 'appearance.showFunctionKeyBar',
296+
section: ['Appearance', 'Listing'],
297+
label: 'Show function key bar',
298+
description: 'Show the row of F-key command buttons (Rename, View, Copy, and so on) at the bottom of the window.',
299+
keywords: ['function', 'key', 'bar', 'f-key', 'fkey', 'shortcut', 'buttons', 'bottom', 'toolbar'],
300+
type: 'boolean',
301+
default: true,
302+
component: 'switch',
303+
},
294304
{
295305
id: 'listing.directorySortMode',
296306
section: ['Appearance', 'Listing'],

apps/desktop/src/lib/settings/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ export interface SettingsValues {
131131
'appearance.textSize': number
132132
'appearance.uiDensity': UiDensity
133133
'appearance.useAppIconsForDocuments': boolean
134+
'appearance.showFunctionKeyBar': boolean
134135
'appearance.fileSizeFormat': FileSizeFormat
135136
'appearance.sizeColors': SizeColorsPalette
136137
'appearance.dateColors': DateColorsPalette

apps/desktop/src/routes/(main)/+page.svelte

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import { initSystemStrings } from '$lib/system-strings.svelte'
5151
import { openSettingsWindow } from '$lib/settings/settings-window'
5252
import { getSetting, setSetting } from '$lib/settings'
53+
import { getShowFunctionKeyBar } from '$lib/settings/reactive-settings.svelte'
5354
import { addToast } from '$lib/ui/toast'
5455
import { openFileViewer } from '$lib/file-viewer/open-viewer'
5556
import { startDownloadsEventBridge } from '$lib/downloads/event-bridge.svelte'
@@ -107,7 +108,7 @@
107108
let explorerRef: ExplorerAPI | undefined = $state()
108109
let windowTitle = $state('Cmdr')
109110
let appMode = $state<AppMode>(getAppMode())
110-
const showFunctionKeyBar = $state(true)
111+
const showFunctionKeyBar = $derived(getShowFunctionKeyBar())
111112
112113
// Event handlers stored for cleanup
113114
let handleKeyDown: ((e: KeyboardEvent) => void) | undefined

0 commit comments

Comments
 (0)