prevent stale data in caches, add toolbar actions (#18 )
This commit is contained in:
+22
-3
@@ -98,6 +98,15 @@ export default function Toolbar() {
|
||||
refetchInterval: 5_000,
|
||||
})
|
||||
|
||||
const { data: vfsList } = useQuery({
|
||||
queryKey: ['vfs', 'list'],
|
||||
queryFn: async () => {
|
||||
const response = await rclone('/vfs/list')
|
||||
return response?.vfses ?? []
|
||||
},
|
||||
refetchInterval: 5_000,
|
||||
})
|
||||
|
||||
const remotes = useMemo(() => remotesQuery.data ?? [], [remotesQuery.data])
|
||||
const remoteTypes = useMemo(() => remoteTypesQuery.data ?? {}, [remoteTypesQuery.data])
|
||||
|
||||
@@ -115,12 +124,13 @@ export default function Toolbar() {
|
||||
useEffect(() => {
|
||||
console.log(`${mountList?.length} mounts`)
|
||||
console.log(`${serveList?.length} serves`)
|
||||
console.log(`${vfsList?.length} vfses`)
|
||||
|
||||
const { results } = runToolbarEngine(searchStringDebounced, remotes, remoteTypes)
|
||||
startTransition(() => {
|
||||
setEngineResults(results)
|
||||
})
|
||||
}, [mountList, serveList, searchStringDebounced, remotes, remoteTypes])
|
||||
}, [mountList, serveList, vfsList, searchStringDebounced, remotes, remoteTypes])
|
||||
|
||||
useEffect(() => {
|
||||
let unlisten: (() => void) | undefined
|
||||
@@ -190,16 +200,25 @@ export default function Toolbar() {
|
||||
}, [])
|
||||
|
||||
const handleExecute = useCallback(async (result: ResolvedToolbarResult) => {
|
||||
await closeToolbar()
|
||||
setSearchString('')
|
||||
let keepOpen = false
|
||||
|
||||
try {
|
||||
const action = result.resolve()
|
||||
await action.onPress(result.args, {
|
||||
openWindow,
|
||||
updateText: (text: string) => {
|
||||
setSearchString(text)
|
||||
keepOpen = true
|
||||
},
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('[Toolbar] Failed to execute action', error)
|
||||
}
|
||||
|
||||
if (!keepOpen) {
|
||||
await closeToolbar()
|
||||
setSearchString('')
|
||||
}
|
||||
}, [])
|
||||
|
||||
const executeShortcutAtIndex = useCallback(
|
||||
|
||||
+117
-5
@@ -755,6 +755,7 @@ const actions: ToolbarActionDefinition[] = [
|
||||
)
|
||||
)
|
||||
}
|
||||
results.push(createBaseResult('Back', 'Return to menu', { _action: 'back' }, 50))
|
||||
return results
|
||||
}
|
||||
|
||||
@@ -780,15 +781,17 @@ const actions: ToolbarActionDefinition[] = [
|
||||
|
||||
return results
|
||||
},
|
||||
onPress: async (args) => {
|
||||
onPress: async (args, context) => {
|
||||
if (args._action === 'back') {
|
||||
context.updateText('')
|
||||
return
|
||||
}
|
||||
|
||||
const remote =
|
||||
typeof args.remote === 'string' && args.remote.length > 0 ? args.remote : undefined
|
||||
|
||||
if (!remote) {
|
||||
await notify({
|
||||
title: 'Error',
|
||||
body: 'Please specify a remote to browse',
|
||||
})
|
||||
context.updateText('Browse ')
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1146,6 +1149,115 @@ const actions: ToolbarActionDefinition[] = [
|
||||
await getCurrentWindow().emit('close-app')
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'vfs',
|
||||
label: 'VFS',
|
||||
description: COMMAND_DESCRIPTIONS.vfs,
|
||||
keywords: COMMAND_KEYWORDS.vfs,
|
||||
getDefaultResult: () => createBaseResult('VFS', 'Specify a cache to forget', {}, 35),
|
||||
getResults: ({ query }) => {
|
||||
if (query && !matchesKeyword(query, COMMAND_KEYWORDS.vfs)) {
|
||||
return []
|
||||
}
|
||||
|
||||
const results: ToolbarActionResult[] = []
|
||||
|
||||
const activeVfses = queryClient.getQueryData(['vfs', 'list']) as string[] | undefined
|
||||
|
||||
if (activeVfses && activeVfses.length > 0) {
|
||||
for (const vfs of activeVfses) {
|
||||
results.push(
|
||||
createBaseResult(
|
||||
`Forget ${vfs}`,
|
||||
'Clear the VFS directory cache',
|
||||
{ _action: 'forget', _fs: vfs },
|
||||
180
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
if (activeVfses.length >= 2) {
|
||||
results.push(
|
||||
createBaseResult(
|
||||
`Forget All VFS Caches (${activeVfses.length} active)`,
|
||||
'Clear all VFS directory caches',
|
||||
{ _action: 'forget_all' },
|
||||
170
|
||||
)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
results.push(
|
||||
createBaseResult('Back', 'No active VFS caches', { _action: 'back' }, 35)
|
||||
)
|
||||
}
|
||||
|
||||
return results
|
||||
},
|
||||
onPress: async (args, context) => {
|
||||
if (!args._action) {
|
||||
context.updateText('VFS ')
|
||||
return
|
||||
}
|
||||
|
||||
if (args._action === 'back') {
|
||||
context.updateText('')
|
||||
return
|
||||
}
|
||||
|
||||
if (args._action === 'forget') {
|
||||
const fs = args._fs as string
|
||||
try {
|
||||
await rclone('/vfs/forget', {
|
||||
params: {
|
||||
query: {
|
||||
fs,
|
||||
},
|
||||
},
|
||||
})
|
||||
await notify({
|
||||
title: 'VFS Cache Cleared',
|
||||
body: `Directory cache for ${fs} has been cleared`,
|
||||
})
|
||||
queryClient.setQueryData(
|
||||
['vfs', 'list'],
|
||||
(old: string[] | undefined) => old?.filter((v) => v !== fs) ?? []
|
||||
)
|
||||
} catch (error) {
|
||||
console.error('[toolbar] failed to forget VFS cache', error)
|
||||
await message(
|
||||
error instanceof Error ? error.message : 'Failed to clear VFS cache',
|
||||
{
|
||||
title: 'VFS Forget',
|
||||
kind: 'error',
|
||||
}
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (args._action === 'forget_all') {
|
||||
try {
|
||||
await rclone('/vfs/forget')
|
||||
await notify({
|
||||
title: 'All VFS Caches Cleared',
|
||||
body: 'All VFS directory caches have been cleared',
|
||||
})
|
||||
queryClient.setQueryData(['vfs', 'list'], [])
|
||||
} catch (error) {
|
||||
console.error('[toolbar] failed to forget all VFS caches', error)
|
||||
await message(
|
||||
error instanceof Error ? error.message : 'Failed to clear all VFS caches',
|
||||
{
|
||||
title: 'VFS Forget All',
|
||||
kind: 'error',
|
||||
}
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
export function getToolbarActions(): ToolbarActionDefinition[] {
|
||||
|
||||
@@ -24,6 +24,7 @@ const REMOTE_EDIT_DESCRIPTION = 'Edit a remote.'
|
||||
const REMOTE_AUTO_MOUNT_DESCRIPTION = 'Configure auto mount options for a remote.'
|
||||
const REMOTE_LIST_DESCRIPTION = 'Show all configured remotes.'
|
||||
const QUIT_DESCRIPTION = 'Quit the application.'
|
||||
const VFS_DESCRIPTION = 'Forget the local cache for one or all remotes.'
|
||||
|
||||
export const COMMAND_CONFIG = {
|
||||
copy: { route: '/copy', windowLabel: 'Copy' },
|
||||
@@ -47,6 +48,7 @@ export const COMMAND_CONFIG = {
|
||||
remoteAutoMount: {},
|
||||
remoteList: {},
|
||||
quit: {},
|
||||
vfs: {},
|
||||
} as const
|
||||
|
||||
export const COMMAND_DESCRIPTIONS: Record<ToolbarCommandId, string> = {
|
||||
@@ -71,6 +73,7 @@ export const COMMAND_DESCRIPTIONS: Record<ToolbarCommandId, string> = {
|
||||
remoteAutoMount: REMOTE_AUTO_MOUNT_DESCRIPTION,
|
||||
remoteList: REMOTE_LIST_DESCRIPTION,
|
||||
quit: QUIT_DESCRIPTION,
|
||||
vfs: VFS_DESCRIPTION,
|
||||
}
|
||||
|
||||
export const COMMAND_KEYWORDS: Record<ToolbarCommandId, string[]> = {
|
||||
@@ -95,4 +98,5 @@ export const COMMAND_KEYWORDS: Record<ToolbarCommandId, string[]> = {
|
||||
remoteAutoMount: ['mount', 'remote', 'update', 'change'],
|
||||
remoteList: ['remote', 'list', 'show'],
|
||||
quit: ['quit', 'exit', 'close'],
|
||||
vfs: ['vfs', 'cache', 'forget'],
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ export type ToolbarCommandId =
|
||||
| 'remoteAutoMount'
|
||||
| 'quit'
|
||||
| 'remoteList'
|
||||
| 'vfs'
|
||||
|
||||
export type ToolbarActionArgs = Record<string, any>
|
||||
|
||||
@@ -32,6 +33,7 @@ export interface ToolbarActionResult {
|
||||
|
||||
export interface ToolbarActionOnPressContext {
|
||||
openWindow: (options: { name: string; url: string }) => Promise<unknown>
|
||||
updateText: (text: string) => void
|
||||
}
|
||||
|
||||
export interface ToolbarActionPath {
|
||||
|
||||
Reference in New Issue
Block a user