-
Notifications
You must be signed in to change notification settings - Fork 264
feat: update reset thumbnail feature #306
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
f7088df
77ebb6d
9c89e1a
c04c04a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
import { Box, Divider, ListItemIcon, ListItemText, Menu, MenuItem, styled, Typography, useTheme } from "@mui/material"; | ||
import { useCallback, useMemo } from "react"; | ||
import { useCallback, useEffect, useMemo } from "react"; | ||
import { useTranslation } from "react-i18next"; | ||
import { closeContextMenu } from "../../../redux/fileManagerSlice.ts"; | ||
import { CreateNewDialogType } from "../../../redux/globalStateSlice.ts"; | ||
|
@@ -22,6 +22,7 @@ import { | |
} from "../../../redux/thunks/file.ts"; | ||
import { refreshFileList, uploadClicked, uploadFromClipboard } from "../../../redux/thunks/filemanager.ts"; | ||
import { openViewers } from "../../../redux/thunks/viewer.ts"; | ||
import { primeThumbExtsCache } from "../../../redux/thunks/thumb.ts"; | ||
import AppFolder from "../../Icons/AppFolder.tsx"; | ||
import ArchiveArrow from "../../Icons/ArchiveArrow.tsx"; | ||
import ArrowSync from "../../Icons/ArrowSync.tsx"; | ||
|
@@ -107,6 +108,13 @@ const ContextMenu = ({ fmIndex = 0 }: ContextMenuProps) => { | |
dispatch(closeContextMenu({ index: fmIndex, value: undefined })); | ||
}, [dispatch]); | ||
|
||
// Ensure supported thumbnail extensions are primed when menu opens | ||
useEffect(() => { | ||
if (contextMenuOpen) { | ||
dispatch(primeThumbExtsCache()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wait... does this mean adding an extra request for whenever a new context menu is open for the first time?
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the second option is better, i will modify it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not resolved. The extra request is still sent every time a user opens the explorer page. |
||
} | ||
}, [contextMenuOpen, dispatch]); | ||
|
||
const showOpenWithCascading = displayOpt.showOpenWithCascading && displayOpt.showOpenWithCascading(); | ||
const showOpenWith = displayOpt.showOpenWith && displayOpt.showOpenWith(); | ||
let part1 = | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
import { useMemo } from "react"; | ||
import { FileResponse, FileType, Metadata, NavigatorCapability } from "../../../api/explorer.ts"; | ||
import { getCachedThumbExts } from "../../../redux/thunks/thumb.ts"; | ||
import { GroupPermission } from "../../../api/user.ts"; | ||
import { defaultPath } from "../../../hooks/useNavigation.tsx"; | ||
import { ContextMenuTypes } from "../../../redux/fileManagerSlice.ts"; | ||
|
@@ -77,6 +78,7 @@ export interface DisplayOption { | |
showDirectLinkManagement?: boolean; | ||
showManageShares?: boolean; | ||
showCreateArchive?: boolean; | ||
showResetThumb?: boolean; | ||
|
||
andCapability?: Boolset; | ||
orCapability?: Boolset; | ||
|
@@ -291,11 +293,23 @@ export const getActionOpt = ( | |
display.orCapability && | ||
display.orCapability.enabled(NavigatorCapability.download_file); | ||
|
||
// Reset thumbnail is available when at least one file is selected and | ||
// current capability allows generating thumbnails | ||
// Show only when at least one selected file has a supported extension, | ||
// based on cached supported thumbnail extensions. | ||
const cache = getCachedThumbExts(); | ||
const anySupported = | ||
cache instanceof Set | ||
? targets.some((f) => f.type == FileType.file && cache.has((fileExtension(f.name) || "").toLowerCase())) | ||
: false; | ||
display.showResetThumb = display.hasFile && anySupported; | ||
MasonDye marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Load thumb exts only after user clicked the context menu option.
|
||
|
||
display.showMore = | ||
display.showVersionControl || | ||
display.showManageShares || | ||
display.showCreateArchive || | ||
display.showDirectLinkManagement; | ||
display.showDirectLinkManagement || | ||
display.showResetThumb; | ||
return display; | ||
}; | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -93,8 +93,11 @@ const GalleryImage = memo((props: FileBlockProps) => { | |
return; | ||
} | ||
|
||
// Reset to loading state before reloading thumb (e.g., after reset) | ||
setImageLoading(true); | ||
setThumbSrc(undefined); | ||
tryLoadThumbSrc(); | ||
}, [inView]); | ||
}, [inView, file, file.metadata?.[Metadata.thumbDisabled]]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will trigger a reload of the thumbnail after reset. But you already loaded once in https://github.com/cloudreve/frontend/pull/306/files#diff-acc4829d8b9ac4ca5b1f91063828fb9acd9704b8d210258944946090996786e1R1201 So two identical requests will be made? |
||
|
||
const onIconClick = useCallback( | ||
(e: React.MouseEvent<HTMLElement>) => { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ import { | |
sendUnlockFiles, | ||
setCurrentVersion, | ||
} from "../../api/api.ts"; | ||
import { getCachedThumbExts } from "./thumb.ts"; | ||
import { | ||
ConflictDetail, | ||
DirectLink, | ||
|
@@ -39,7 +40,7 @@ import { loadingDebounceMs } from "../../constants"; | |
import { defaultPath } from "../../hooks/useNavigation.tsx"; | ||
import SessionManager, { UserSettings } from "../../session"; | ||
import { addRecentUsedColor, addUsedTags } from "../../session/utils.ts"; | ||
import { getFileLinkedUri } from "../../util"; | ||
import { fileExtension, getFileLinkedUri } from "../../util"; | ||
import Boolset from "../../util/boolset.ts"; | ||
import { canCopyMoveTo } from "../../util/permission.ts"; | ||
import CrUri, { Filesystem } from "../../util/uri.ts"; | ||
|
@@ -1154,6 +1155,64 @@ export function batchGetDirectLinks(index: number, files: FileResponse[]): AppTh | |
}; | ||
} | ||
|
||
export function resetThumbnails(files: FileResponse[]): AppThunk { | ||
return async (dispatch, getState) => { | ||
const cache = getCachedThumbExts(); | ||
const uris = files | ||
.filter((f) => f.type == FileType.file) | ||
.filter((f) => | ||
cache === undefined || cache === null ? true : cache.has((fileExtension(f.name) || "").toLowerCase()), | ||
) | ||
.map((f) => getFileLinkedUri(f)); | ||
|
||
if (uris.length === 0) { | ||
enqueueSnackbar({ | ||
message: i18next.t("application:fileManager.noFileCanResetThumbnail"), | ||
preventDuplicate: true, | ||
variant: "warning", | ||
action: DefaultCloseAction, | ||
}); | ||
return; | ||
} | ||
|
||
try { | ||
// Re-enable thumbnails by removing the disable mark, and update local metadata/cache. | ||
const targetFiles = files | ||
.filter((f) => f.type == FileType.file) | ||
.filter((f) => | ||
cache === undefined || cache === null ? true : cache.has((fileExtension(f.name) || "").toLowerCase()), | ||
); | ||
|
||
await dispatch( | ||
patchFileMetadata(FileManagerIndex.main, targetFiles, [ | ||
{ | ||
key: Metadata.thumbDisabled, | ||
remove: true, | ||
}, | ||
]), | ||
); | ||
|
||
// 预取:立即为所选文件请求缩略图(不依赖列表刷新或滚动触发) | ||
const fm = getState().fileManager[FileManagerIndex.main]; | ||
const toPrefetch = targetFiles | ||
.map((f) => fm.list?.files.find((ff) => ff.path === f.path) || f) | ||
.filter((f): f is FileResponse => !!f); | ||
// 并发触发 GET /file/thumb | ||
await Promise.allSettled(toPrefetch.map((f) => dispatch(loadFileThumb(FileManagerIndex.main, f)))); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
// 成功信息 | ||
enqueueSnackbar({ | ||
message: i18next.t("application:fileManager.resetThumbnailRequested"), | ||
variant: "success", | ||
action: DefaultCloseAction, | ||
}); | ||
// 不再刷新文件列表;组件会基于metadata变化自动重新请求所选文件的缩略图 | ||
} catch (_e) { | ||
// Error snackbar is handled in send() | ||
} | ||
}; | ||
} | ||
|
||
// Single file symbolic links might be invalid if original file is renamed by its owner, | ||
// we need to refresh the symbolic links by getting the latest file list | ||
export function refreshSingleFileSymbolicLinks(file: FileResponse): AppThunk<Promise<FileResponse>> { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please reuse
frontend/src/redux/thunks/site.ts
Line 6 in 3596160