From f0c01772e95c4dad7a499064528f2359e8298901 Mon Sep 17 00:00:00 2001 From: canwdev <9585126+canwdev@users.noreply.github.com> Date: Mon, 26 Oct 2026 22:16:56 +0800 Subject: [PATCH 1/6] fix: keep folder scroll position in memory only --- CHANGELOG.md | 6 +++++ backend-go/config/config.go | 2 +- frontend/src/enum/version.ts | 2 +- .../views/FileManager/ExplorerUI/FileList.vue | 24 +++++++------------ .../FileManager/ExplorerUI/explorer-state.ts | 6 +++++ .../FileManager/ExplorerUI/path-state.ts | 3 +-- 6 files changed, 23 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68703987..58a821c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ The version number is defined in `frontend/src/enum/version.ts` and must stay in sync with `const Version` in `backend-go/config/config.go`. +## 1.5.2 + +### Fixes + +- **Folder state**: The scroll position is kept only in the current page and resets after a refresh, while the sort mode remains saved per folder (frontend). + ## 1.5.1 ### UI diff --git a/backend-go/config/config.go b/backend-go/config/config.go index d1ae129e..78e66e25 100644 --- a/backend-go/config/config.go +++ b/backend-go/config/config.go @@ -141,7 +141,7 @@ type Cfg struct { } const PkgName = "file-lite-go" -const Version = "1.5.1" +const Version = "1.5.2" var cfg Cfg var dataBaseDir string diff --git a/frontend/src/enum/version.ts b/frontend/src/enum/version.ts index e2611b47..29780cc3 100644 --- a/frontend/src/enum/version.ts +++ b/frontend/src/enum/version.ts @@ -1,4 +1,4 @@ export const PKG_NAME = 'file-lite' // also update config.go: const Version = " // and CHANGELOG.md -export const VERSION = '1.5.1' +export const VERSION = '1.5.2' diff --git a/frontend/src/views/FileManager/ExplorerUI/FileList.vue b/frontend/src/views/FileManager/ExplorerUI/FileList.vue index 2732ffa9..b8c8ad45 100644 --- a/frontend/src/views/FileManager/ExplorerUI/FileList.vue +++ b/frontend/src/views/FileManager/ExplorerUI/FileList.vue @@ -25,7 +25,7 @@ import { ExplorerEvents, useExplorerBusOn } from '../utils/bus' import { GROUP_HEADER_HEIGHT, groupEntries } from '../utils/group' import { composeSortMode, parseSortMode } from '../utils/sort' import { acceptDirDrag, beginEntryDrag, dragSession, dropIntoDir, endEntryDrag, isExternalFileDrag, isInternalDrag, useDragEnabled } from './entry-drag' -import { explorerStateMap, groupDescRef, groupFieldRef, sortModeRef } from './explorer-state' +import { explorerStateMap, groupDescRef, groupFieldRef, scrollPositionMap, sortModeRef } from './explorer-state' import { createDefaultFileFilter, isFileFilterActive } from './file-filter' import { getEntryTypeLabel } from './file-type' import FileGridItem from './FileGridItem.vue' @@ -1588,7 +1588,7 @@ useShortcut({ }) // 缓存滚动位置 -function getSetScrollPosition(action: 'get' | 'set', value = 0) { +function getSetScrollPosition(action: 'get' | 'set', value = 0): number { const el = explorerContentRef.value if (!el) { return 0 @@ -1596,9 +1596,8 @@ function getSetScrollPosition(action: 'get' | 'set', value = 0) { if (action === 'get') { return el.scrollTop } - else if (action === 'set') { - el.scrollTop = value - } + el.scrollTop = value + return value } function scrollToFile(name: string) { @@ -1668,10 +1667,10 @@ function selectAndReveal(name: string) { * 恢复本目录上次的滚动位置。 * * 保活的标签被重新显示时调用:`display:none` 期间容器尺寸为 0,虚拟列表的可视区是空的, - * 需要重新量一次并滚回去(位置按 path 存在 explorerStateMap 里)。 + * 需要重新量一次并滚回去(位置按 path 存在内存里的 scrollPositionMap 中,刷新即失效)。 */ function restoreViewport() { - const position = explorerStateMap.value[basePath.value]?.position || 0 + const position = scrollPositionMap[basePath.value] ?? 0 nextTick(() => { virtualList.refresh() virtualGrid.refresh() @@ -1686,20 +1685,13 @@ function restoreViewport() { } watchDebounced(files, () => { - if (explorerStateMap.value[basePath.value]) { + if (scrollPositionMap[basePath.value] !== undefined) { restoreViewport() } }, { debounce: 100, maxWait: 1000 }) const debounceHandleScroll = useDebounceFn(() => { const position = getSetScrollPosition('get') - if (!explorerStateMap.value[basePath.value]) { - explorerStateMap.value[basePath.value] = { position } - } - else { - explorerStateMap.value[basePath.value].position = position - } - - // console.log('save', basePath.value, position) + scrollPositionMap[basePath.value] = position }, 500) useEventListener(() => explorerContentRef.value, 'scroll', debounceHandleScroll) diff --git a/frontend/src/views/FileManager/ExplorerUI/explorer-state.ts b/frontend/src/views/FileManager/ExplorerUI/explorer-state.ts index 5f741e46..a7d30cb4 100644 --- a/frontend/src/views/FileManager/ExplorerUI/explorer-state.ts +++ b/frontend/src/views/FileManager/ExplorerUI/explorer-state.ts @@ -1,6 +1,7 @@ import type { SortField } from '../utils/sort' import type { PathState } from './path-state' import { useStorage } from '@vueuse/core' +import { reactive } from 'vue' import { LsKeys } from '@/enum' import { SortType } from '@/types/server' import { normalizeListingPath } from '../utils' @@ -20,6 +21,11 @@ export const explorerStateMap = useStorage>( { listenToStorageChanges: false }, ) +/** + * 滚动位置只在当前页面内存里保留(键为 listing 路径),刷新页面即失效,不持久化。 + */ +export const scrollPositionMap = reactive>({}) + /** 只写某个目录**自己**的状态,不碰继承链 */ function writeOwnPathState(path: string, key: K, val: NonNullable) { const entry = normalizeListingPath(path) diff --git a/frontend/src/views/FileManager/ExplorerUI/path-state.ts b/frontend/src/views/FileManager/ExplorerUI/path-state.ts index 2f96d23e..53fd7048 100644 --- a/frontend/src/views/FileManager/ExplorerUI/path-state.ts +++ b/frontend/src/views/FileManager/ExplorerUI/path-state.ts @@ -3,9 +3,8 @@ import type { SortType } from '@/types/server' import { normalizeListingPath, normalizePath } from '../../../utils/path/form' import { boundaryFor, listingParent } from '../utils/volume-mounts' -/** 每个目录自己的界面状态;排序 / 分组支持向祖先继承,位置与折叠组只属于自己。 */ +/** 每个目录自己的界面状态;排序 / 分组支持向祖先继承,折叠组只属于自己。 */ export interface PathState { - position?: number sortMode?: SortType groupField?: SortField | 'none' groupDesc?: boolean From 7ac8b9d27a7918482112731c480ebf0a9c9b0df6 Mon Sep 17 00:00:00 2001 From: canwdev <9585126+canwdev@users.noreply.github.com> Date: Mon, 26 Oct 2026 22:27:13 +0800 Subject: [PATCH 2/6] feat: save folder list/grid view per path with inheritance --- CHANGELOG.md | 4 +++ frontend/src/store/index.ts | 1 - .../src/views/FileManager/ExplorerPane.vue | 3 +- .../views/FileManager/ExplorerUI/FileList.vue | 15 +++++----- .../FileManager/ExplorerUI/explorer-state.ts | 13 +++++++++ .../ExplorerUI/explorer-tabs-store.ts | 29 +++++++++---------- .../FileManager/ExplorerUI/path-state.test.ts | 8 ++++- .../FileManager/ExplorerUI/path-state.ts | 3 +- 8 files changed, 48 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 58a821c6..18278866 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ The version number is defined in `frontend/src/enum/version.ts` and must stay in ## 1.5.2 +### UI + +- **Folder view**: The list or grid view is saved per folder and inherited by its subfolders, instead of one global view for every folder (frontend). + ### Fixes - **Folder state**: The scroll position is kept only in the current page and resets after a refresh, while the sort mode remains saved per folder (frontend). diff --git a/frontend/src/store/index.ts b/frontend/src/store/index.ts index e3658d4a..b7c5b588 100644 --- a/frontend/src/store/index.ts +++ b/frontend/src/store/index.ts @@ -71,7 +71,6 @@ function createDefaultLocalSettingsStore() { showHidden: true, /** 排序后是否把文件夹排在文件前面 */ sortFoldersFirst: true, - isGridView: false, iconSizeList: 16, iconSizeGrid: 48, /** diff --git a/frontend/src/views/FileManager/ExplorerPane.vue b/frontend/src/views/FileManager/ExplorerPane.vue index c3f8923c..7b6db79e 100644 --- a/frontend/src/views/FileManager/ExplorerPane.vue +++ b/frontend/src/views/FileManager/ExplorerPane.vue @@ -41,7 +41,7 @@ const props = withDefaults( active?: boolean // 本面板是不是当前聚焦的面板:拆分项里两个面板只有一个是 focused?: boolean - // 面板自己的视图偏好(list/grid、图标大小);不传则用全局设置 + // 面板自己的图标大小偏好;不传则用全局设置 view?: ExplorerPaneView }>(), { @@ -95,7 +95,6 @@ function syncBranchViewProp(enabled: boolean) { if (Boolean(props.view?.branch) === enabled) return const base = props.view ?? { - grid: localSettingsStore.value.isGridView, iconSizeList: localSettingsStore.value.iconSizeList, iconSizeGrid: localSettingsStore.value.iconSizeGrid, } diff --git a/frontend/src/views/FileManager/ExplorerUI/FileList.vue b/frontend/src/views/FileManager/ExplorerUI/FileList.vue index b8c8ad45..9e16be01 100644 --- a/frontend/src/views/FileManager/ExplorerUI/FileList.vue +++ b/frontend/src/views/FileManager/ExplorerUI/FileList.vue @@ -25,7 +25,7 @@ import { ExplorerEvents, useExplorerBusOn } from '../utils/bus' import { GROUP_HEADER_HEIGHT, groupEntries } from '../utils/group' import { composeSortMode, parseSortMode } from '../utils/sort' import { acceptDirDrag, beginEntryDrag, dragSession, dropIntoDir, endEntryDrag, isExternalFileDrag, isInternalDrag, useDragEnabled } from './entry-drag' -import { explorerStateMap, groupDescRef, groupFieldRef, scrollPositionMap, sortModeRef } from './explorer-state' +import { explorerStateMap, gridRef, groupDescRef, groupFieldRef, scrollPositionMap, sortModeRef } from './explorer-state' import { createDefaultFileFilter, isFileFilterActive } from './file-filter' import { getEntryTypeLabel } from './file-type' import FileGridItem from './FileGridItem.vue' @@ -58,7 +58,7 @@ const props = withDefaults( * 否则后台面板一加载完就会把活动面板抢走。 */ focused?: boolean - /** 面板自己的视图偏好(list/grid、图标大小);不传则用全局设置 */ + /** 面板自己的图标大小偏好;不传则用全局设置 */ view?: ExplorerPaneView /** * 上一次列目录失败的原因;非空时列表区显示错误空状态而不是「This folder is empty」。 @@ -101,14 +101,15 @@ function clearCollapsedGroups() { } /** - * 视图偏好(list/grid、图标大小)属于**面板**:拆分视图里两个面板各看各的, + * 图标大小偏好属于**面板**:拆分视图里两个面板各看各的, * 改一个不会带着另一个一起变。面板还没设置过时回落到全局设置。 * * 状态由外壳持有(挂在标签 store 的面板上,跟着标签一起持久化),这里只按值收发: * 外壳没有接线(选择器窗口)时也不会丢,它会把这一份写回全局设置。 + * + * 列表/图标视图(grid)不在面板上:它按目录持久化并沿祖先继承(见 `gridRef`)。 */ const paneView = computed(() => props.view ?? { - grid: localSettingsStore.value.isGridView, iconSizeList: localSettingsStore.value.iconSizeList, iconSizeGrid: localSettingsStore.value.iconSizeGrid, }) @@ -117,10 +118,8 @@ function updatePaneView(patch: Partial) { emit('update:view', { ...paneView.value, ...patch }) } -const isGridView = computed({ - get: () => paneView.value.grid, - set: (val: boolean) => updatePaneView({ grid: val }), -}) +/** 列表/图标视图:目录自己的设置 > 祖先继承 > 默认列表。 */ +const isGridView = gridRef(basePath) const isBranchView = computed({ get: () => Boolean(paneView.value.branch) && !selectFileMode.value, set: (val: boolean) => { diff --git a/frontend/src/views/FileManager/ExplorerUI/explorer-state.ts b/frontend/src/views/FileManager/ExplorerUI/explorer-state.ts index a7d30cb4..8d59a5bd 100644 --- a/frontend/src/views/FileManager/ExplorerUI/explorer-state.ts +++ b/frontend/src/views/FileManager/ExplorerUI/explorer-state.ts @@ -54,6 +54,11 @@ export function getPathGroupDesc(path: string): boolean { return resolveInheritedPathState(explorerStateMap.value, path, 'groupDesc', mountPaths()) ?? false } +/** 有效列表/图标视图:目录自己的手动设置 > 最近一个手动设置过的祖先 > 默认列表。 */ +export function getPathGrid(path: string): boolean { + return resolveInheritedPathState(explorerStateMap.value, path, 'grid', mountPaths()) ?? false +} + /** 排序 ref:读走继承解析,写落在当前目录自己的记录上 */ export function sortModeRef(path: Ref) { return computed({ @@ -77,3 +82,11 @@ export function groupDescRef(path: Ref) { set: (val: boolean) => writeOwnPathState(path.value, 'groupDesc', val), }) } + +/** 列表/图标视图 ref,读写语义同 `sortModeRef` */ +export function gridRef(path: Ref) { + return computed({ + get: () => getPathGrid(path.value), + set: (val: boolean) => writeOwnPathState(path.value, 'grid', val), + }) +} diff --git a/frontend/src/views/FileManager/ExplorerUI/explorer-tabs-store.ts b/frontend/src/views/FileManager/ExplorerUI/explorer-tabs-store.ts index 45413587..86fdb9cb 100644 --- a/frontend/src/views/FileManager/ExplorerUI/explorer-tabs-store.ts +++ b/frontend/src/views/FileManager/ExplorerUI/explorer-tabs-store.ts @@ -16,12 +16,13 @@ import { normalizeListingPath } from '../utils' * 「还没导航过」,外壳要靠它决定是否打开第一个磁盘,归一成 `/` 会把这个语义弄丢。 */ /** - * 面板自己的视图偏好。跟标签内容一起挂在面板上持久化:拆分视图里两个面板各看各的, + * 面板自己的图标大小偏好。跟标签内容一起挂在面板上持久化:拆分视图里两个面板各看各的, * 改动一个不会带着另一个一起变。没设置过的面板(刚开、没动过)继续用全局设置, * 选择器窗口没有面板级状态,也一直走全局设置。 + * + * 列表/图标视图(grid)不在这里:它按目录持久化并沿祖先继承,见 explorer-state.ts。 */ export interface ExplorerPaneView { - grid: boolean iconSizeList: number iconSizeGrid: number /** 平铺子目录中的全部文件(Total Commander Ctrl+B) */ @@ -31,7 +32,7 @@ export interface ExplorerPaneView { export interface ExplorerTab { id: string path: string - /** 面板级视图偏好;未设置时由外壳回落到全局设置 */ + /** 面板级图标大小偏好;未设置时由外壳回落到全局设置 */ view?: ExplorerPaneView } @@ -64,13 +65,13 @@ function createItem(path: string, view?: ExplorerPaneView): ExplorerTabItem { } /** - * 新面板继承的视图偏好。 + * 新面板继承的图标大小偏好。 * - * 只带 list/grid 与图标大小:`branch`(平铺子目录)是**当前目录**的临时模式, + * 只带图标大小:`branch`(平铺子目录)是**当前目录**的临时模式, * 跟着新标签走会让它一打开就平铺整个继承来的目录,所以不继承。 */ function inheritedPaneView(view: ExplorerPaneView): ExplorerPaneView { - return { grid: view.grid, iconSizeList: view.iconSizeList, iconSizeGrid: view.iconSizeGrid } + return { iconSizeList: view.iconSizeList, iconSizeGrid: view.iconSizeGrid } } export function isSplitItem(item: ExplorerTabItem): boolean { @@ -115,17 +116,16 @@ function normalizePanes(raw: unknown): ExplorerTab[] { return panes } -/** 面板级视图偏好三项必须齐全才认,否则整份丢掉,回落到全局设置 */ +/** 面板级图标大小两项必须齐全才认,否则整份丢掉,回落到全局设置 */ function normalizePaneView(raw: unknown): ExplorerPaneView | undefined { if (!raw || typeof raw !== 'object') { return undefined } - const { grid, iconSizeList, iconSizeGrid } = raw as Partial - if (typeof grid !== 'boolean' || !Number.isFinite(iconSizeList) || !Number.isFinite(iconSizeGrid)) { + const { iconSizeList, iconSizeGrid } = raw as Partial + if (!Number.isFinite(iconSizeList) || !Number.isFinite(iconSizeGrid)) { return undefined } return { - grid, iconSizeList: iconSizeList as number, iconSizeGrid: iconSizeGrid as number, } @@ -218,8 +218,8 @@ export function useExplorerTabs() { /** * 新建标签并激活,永远追加在最后。默认沿用当前标签的路径(和资源管理器一致)。 * - * 视图偏好继承**当前聚焦面板**:手动切过 list/grid 或调过图标大小之后再开新标签, - * 不会又退回全局默认。聚焦面板还没设过面板级视图(`view` 为空)时不写入, + * 图标大小偏好继承**当前聚焦面板**:调过图标大小之后再开新标签, + * 不会又退回全局默认。聚焦面板还没设过面板级图标大小(`view` 为空)时不写入, * 新面板继续走全局设置——与它的来源面板表现一致。 */ function addTab(path = activePath.value): string { @@ -350,7 +350,7 @@ export function useExplorerTabs() { setTabPath(activeTabId.value, path) } - /** 写某个面板自己的视图偏好(list/grid、图标大小),只影响这一个面板 */ + /** 写某个面板自己的图标大小偏好,只影响这一个面板 */ function setPaneView(paneId: string, view: ExplorerPaneView) { const item = findPaneOwner(paneId) if (!item) { @@ -369,8 +369,7 @@ export function useExplorerTabs() { * 拆分视图:优先吸收右邻单标签项,其次左邻,都没有就新建一个同路径标签当第二个面板。 * 合并后的项落在两者中靠前的位置,面板顺序保持标签条原来的左右顺序。 * - * 新建的那个面板继承被拆分面板的视图偏好——否则在 grid 下拆分最后一个标签会得到 - * 「一 grid 一 list」,看起来像是拆分把视图弄丢了。 + * 新建的那个面板继承被拆分面板的图标大小偏好,两个面板看起来一致。 */ function splitTab(itemId: string) { const index = findItemIndex(itemId) diff --git a/frontend/src/views/FileManager/ExplorerUI/path-state.test.ts b/frontend/src/views/FileManager/ExplorerUI/path-state.test.ts index 2e8ca524..d24e9528 100644 --- a/frontend/src/views/FileManager/ExplorerUI/path-state.test.ts +++ b/frontend/src/views/FileManager/ExplorerUI/path-state.test.ts @@ -6,7 +6,7 @@ import { resolveInheritedPathState } from './path-state' const MOUNTS = ['/', '/data', '//server/share'] -type ResolvableKey = 'sortMode' | 'groupField' | 'groupDesc' +type ResolvableKey = 'sortMode' | 'groupField' | 'groupDesc' | 'grid' function resolve(state: Record, path: string, key: ResolvableKey) { return resolveInheritedPathState(state, path, key, MOUNTS) @@ -51,6 +51,12 @@ describe('resolveInheritedPathState', () => { expect(resolve(state, '/data/a/', 'groupDesc')).toBe(false) }) + test('列表/图标视图同样沿祖先继承', () => { + expect(resolve({ '/data/': { grid: true } }, '/data/a/', 'grid')).toBe(true) + expect(resolve({ '/data/': { grid: true }, '/data/a/': { grid: false } }, '/data/a/', 'grid')).toBe(false) + expect(resolve({}, '/data/a/', 'grid')).toBeUndefined() + }) + test('没有任何设置时返回 undefined', () => { expect(resolve({}, '/data/a/', 'sortMode')).toBeUndefined() expect(resolve({}, '', 'sortMode')).toBeUndefined() diff --git a/frontend/src/views/FileManager/ExplorerUI/path-state.ts b/frontend/src/views/FileManager/ExplorerUI/path-state.ts index 53fd7048..db990296 100644 --- a/frontend/src/views/FileManager/ExplorerUI/path-state.ts +++ b/frontend/src/views/FileManager/ExplorerUI/path-state.ts @@ -3,8 +3,9 @@ import type { SortType } from '@/types/server' import { normalizeListingPath, normalizePath } from '../../../utils/path/form' import { boundaryFor, listingParent } from '../utils/volume-mounts' -/** 每个目录自己的界面状态;排序 / 分组支持向祖先继承,折叠组只属于自己。 */ +/** 每个目录自己的界面状态;列表/图标视图、排序 / 分组支持向祖先继承,折叠组只属于自己。 */ export interface PathState { + grid?: boolean sortMode?: SortType groupField?: SortField | 'none' groupDesc?: boolean From 2633921515858d941c9bc9261d51699886be04b4 Mon Sep 17 00:00:00 2001 From: canwdev <9585126+canwdev@users.noreply.github.com> Date: Mon, 26 Oct 2026 22:29:43 +0800 Subject: [PATCH 3/6] docs: drop scroll position from folder state changelog entry --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18278866..b4ca6d33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ The version number is defined in `frontend/src/enum/version.ts` and must stay in ### Fixes -- **Folder state**: The scroll position is kept only in the current page and resets after a refresh, while the sort mode remains saved per folder (frontend). +- **Folder state**: The sort mode is saved per folder and inherited by subfolders (frontend). ## 1.5.1 From bfa2779492a514288f3f5fd6d8043a50ff695aee Mon Sep 17 00:00:00 2001 From: canwdev <9585126+canwdev@users.noreply.github.com> Date: Mon, 26 Oct 2026 22:35:56 +0800 Subject: [PATCH 4/6] i18n: simplify folder state label --- frontend/src/i18n/locales/en-US/index.json | 2 +- frontend/src/i18n/locales/ja-JP/index.json | 2 +- frontend/src/i18n/locales/zh-CN/index.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/i18n/locales/en-US/index.json b/frontend/src/i18n/locales/en-US/index.json index 93ef09b2..cbef8cd9 100644 --- a/frontend/src/i18n/locales/en-US/index.json +++ b/frontend/src/i18n/locales/en-US/index.json @@ -123,7 +123,7 @@ "filter_by_key_scope_or_descripti": "Filter by key, scope or description", "filter_name": "Filter name", "folder": "Folder", - "folder_state": "Folder state (scroll position & sort mode)", + "folder_state": "Folder state", "forward": "Forward", "fullscreen": "Fullscreen", "gigantic_4_gb": "Gigantic", diff --git a/frontend/src/i18n/locales/ja-JP/index.json b/frontend/src/i18n/locales/ja-JP/index.json index 36af16fb..7cb6734d 100644 --- a/frontend/src/i18n/locales/ja-JP/index.json +++ b/frontend/src/i18n/locales/ja-JP/index.json @@ -121,7 +121,7 @@ "filter_by_key_scope_or_descripti": "キー、スコープ、または説明でフィルター", "filter_name": "フィルター名", "folder": "フォルダ", - "folder_state": "フォルダの状態(スクロール位置と並べ替えモード)", + "folder_state": "フォルダの状態", "forward": "進む", "fullscreen": "全画面表示", "gigantic_4_gb": "巨大", diff --git a/frontend/src/i18n/locales/zh-CN/index.json b/frontend/src/i18n/locales/zh-CN/index.json index 4facc8a6..34f163bb 100644 --- a/frontend/src/i18n/locales/zh-CN/index.json +++ b/frontend/src/i18n/locales/zh-CN/index.json @@ -123,7 +123,7 @@ "filter_by_key_scope_or_descripti": "按键、作用域或描述筛选", "filter_name": "筛选名称", "folder": "文件夹", - "folder_state": "文件夹状态(滚动位置和排序方式)", + "folder_state": "文件夹状态", "forward": "前进", "fullscreen": "全屏", "gigantic_4_gb": "超大", From fb4e1bbf96dcc306a84b5954f6066ec6b81bb774 Mon Sep 17 00:00:00 2001 From: canwdev <9585126+canwdev@users.noreply.github.com> Date: Mon, 26 Oct 2026 22:41:40 +0800 Subject: [PATCH 5/6] fix: wallpaper upload button shows Upload... when idle --- .../src/themes/translucent/TranslucentBackgroundSettings.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/themes/translucent/TranslucentBackgroundSettings.vue b/frontend/src/themes/translucent/TranslucentBackgroundSettings.vue index 4d48b8a8..dc7a2523 100644 --- a/frontend/src/themes/translucent/TranslucentBackgroundSettings.vue +++ b/frontend/src/themes/translucent/TranslucentBackgroundSettings.vue @@ -131,7 +131,7 @@ async function onFileChange(event: Event) { :disabled="busy" @click="pickFile" > - {{ busy ? 'Uploading…' : 'Upload' }} + {{ busy ? 'Uploading' : 'Upload...' }} From d010f2e8d9de650319032891f0f753a0b1c8e204 Mon Sep 17 00:00:00 2001 From: canwdev <9585126+canwdev@users.noreply.github.com> Date: Mon, 26 Oct 2026 22:54:20 +0800 Subject: [PATCH 6/6] docs: lay the README screenshots out as full-width tiles Drop the screenshot/feature table: each shot now spans the text column with its description above it, in both READMEs. Recapture the properties shot with the windows cascaded below the file list so the UI behind stays visible, and rename its caption to Multiple windows. --- README.md | 42 ++++++++++++++++++++------- docs/screenshots/08-properties.webp | Bin 31740 -> 45142 bytes docs/zh-CN/README.md | 43 +++++++++++++++++++++------- e2e/README.md | 4 +-- e2e/scripts/capture-docs.mjs | 16 +++++++---- 5 files changed, 78 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 8ae6f7be..87093f8b 100644 --- a/README.md +++ b/README.md @@ -12,17 +12,39 @@ ![File Lite](docs/screenshots/00-main.webp) +## Screenshots -| Screenshot | Feature | -| --------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| ![Tabs and split view](docs/screenshots/01-tabs-split.webp) | **Tabs & split view**: Chrome-like tabs with a Total Commander-style multi-pane view, horizontal and vertical, where files can be dragged straight from one pane into the other. | -| ![Transfers and background tasks](docs/screenshots/02-transfers-tasks.webp) | **Transfers & background tasks**: Uploads and downloads, while copy, move and delete run on the server — with progress and cancel, gathered in the top-right panel. | -| ![Endless Gallery](docs/screenshots/03-gallery.webp) | **Endless Gallery**: A short-video-style vertical feed of the images, videos and audio in the current folder, with touch, wheel and keyboard navigation, and a collect list. | -| ![Music player](docs/screenshots/04-music-player.webp) | **Music player**: Playlist, embedded cover art and synced lyrics. | -| ![Video player](docs/screenshots/05-video-player.webp) | **Video player**: ArtPlayer or the native `