fix(files): close preview on navigation/delete/rename + backfill i18n (#150)
* i18n: backfill files/download translations for de, es, fr, ja, ko, pt Add nav.files, files.* (39 keys), and download.* (9 keys) so the file browser UI is fully localized in these six locales instead of falling back to English. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(files): close preview when navigating or affected file changes Opening a preview and then navigating directories, deleting the previewed file, or renaming it left the preview pane stuck on stale content because previewFile was never cleared. - stores/hermes/files.ts: - fetchEntries clears previewFile on path change (in-place refresh keeps the preview). - deleteEntry / renameEntry clear preview/editor state when the affected entry matches the previewed/edited file or its parent. - Add isAffected(target, changed, isDir) helper. - components/hermes/files/FilePreview.vue: replace the misleading common.cancel close button with a dedicated files.closePreview key plus an X icon and quaternary style. - i18n: add files.closePreview to all 8 locales. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -63,6 +63,15 @@ export function isTextFile(name: string): boolean {
|
||||
return !binaryExts.has(getFileExt(name))
|
||||
}
|
||||
|
||||
// Returns true if `targetPath` is the same as `changedPath` or lives inside it
|
||||
// when `changedIsDir` is true. Used to invalidate preview/editor state when
|
||||
// the underlying file is deleted or renamed.
|
||||
function isAffected(targetPath: string, changedPath: string, changedIsDir: boolean): boolean {
|
||||
if (targetPath === changedPath) return true
|
||||
if (changedIsDir && targetPath.startsWith(changedPath + '/')) return true
|
||||
return false
|
||||
}
|
||||
|
||||
export const useFilesStore = defineStore('files', () => {
|
||||
const currentPath = ref('')
|
||||
const entries = ref<FileEntry[]>([])
|
||||
@@ -104,6 +113,12 @@ export const useFilesStore = defineStore('files', () => {
|
||||
})
|
||||
|
||||
async function fetchEntries(path?: string) {
|
||||
if (path !== undefined && path !== currentPath.value) {
|
||||
// Switching directory invalidates the current preview; close it so the
|
||||
// file list becomes visible again. The editor has its own dirty-check
|
||||
// (see hasUnsavedChanges), so we leave editingFile alone here.
|
||||
previewFile.value = null
|
||||
}
|
||||
if (path !== undefined) currentPath.value = path
|
||||
loading.value = true
|
||||
try {
|
||||
@@ -167,6 +182,12 @@ export const useFilesStore = defineStore('files', () => {
|
||||
|
||||
async function deleteEntry(entry: FileEntry) {
|
||||
await filesApi.deleteFile(entry.path, entry.isDir)
|
||||
if (previewFile.value && isAffected(previewFile.value.path, entry.path, entry.isDir)) {
|
||||
previewFile.value = null
|
||||
}
|
||||
if (editingFile.value && isAffected(editingFile.value.path, entry.path, entry.isDir)) {
|
||||
editingFile.value = null
|
||||
}
|
||||
await fetchEntries()
|
||||
}
|
||||
|
||||
@@ -174,6 +195,12 @@ export const useFilesStore = defineStore('files', () => {
|
||||
const parentPath = entry.path.includes('/') ? entry.path.slice(0, entry.path.lastIndexOf('/')) : ''
|
||||
const newPath = parentPath ? `${parentPath}/${newName}` : newName
|
||||
await filesApi.renameFile(entry.path, newPath)
|
||||
if (previewFile.value && isAffected(previewFile.value.path, entry.path, entry.isDir)) {
|
||||
previewFile.value = null
|
||||
}
|
||||
if (editingFile.value && isAffected(editingFile.value.path, entry.path, entry.isDir)) {
|
||||
editingFile.value = null
|
||||
}
|
||||
await fetchEntries()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user