From 6ee693b9366ac52d2b1a36bb906c76158dcb2ed8 Mon Sep 17 00:00:00 2001 From: Michael An <2331806369@qq.com> Date: Fri, 14 Feb 2025 11:01:21 +0800 Subject: [PATCH] clean image preview cache after rotate --- frontend/src/components/dir-view-mode/dir-files.js | 11 ++++++----- .../components/dirent-grid-view/dirent-grid-view.js | 11 ++++++----- .../components/dirent-list-view/dirent-list-view.js | 11 ++++++----- .../components/cell-formatter/image-previewer.js | 13 +++++++------ 4 files changed, 25 insertions(+), 21 deletions(-) diff --git a/frontend/src/components/dir-view-mode/dir-files.js b/frontend/src/components/dir-view-mode/dir-files.js index 8b576ad094c..0f939a157dd 100644 --- a/frontend/src/components/dir-view-mode/dir-files.js +++ b/frontend/src/components/dir-view-mode/dir-files.js @@ -61,6 +61,7 @@ class DirFiles extends React.Component { this.isNodeMenuShow = true; this.imageItemsSnapshot = []; this.imageIndexSnapshot = 0; + this.rotateImageCacheBuster = new Date().getTime(); } componentDidUpdate(prevProps) { @@ -252,9 +253,9 @@ class DirFiles extends React.Component { const src = `${siteRoot}repo/${repoID}/raw${path}`; let thumbnail = ''; if (repoEncrypted || isGIF) { - thumbnail = src; + thumbnail = `${src}?t=${this.rotateImageCacheBuster}`; } else { - thumbnail = `${siteRoot}thumbnail/${repoID}/${thumbnailSizeForOriginal}${path}`; + thumbnail = `${siteRoot}thumbnail/${repoID}/${thumbnailSizeForOriginal}${path}?t=${this.rotateImageCacheBuster}`; } return { name, @@ -325,11 +326,11 @@ class DirFiles extends React.Component { imageAPI.rotateImage(repoID, path, 360 - angle).then((res) => { seafileAPI.createThumbnail(repoID, path, thumbnailDefaultSize).then((res) => { // Generate a unique query parameter to bust the cache - const cacheBuster = new Date().getTime(); - const newThumbnailSrc = `${res.data.encoded_thumbnail_src}?t=${cacheBuster}`; + this.rotateImageCacheBuster = new Date().getTime(); + const newThumbnailSrc = `${res.data.encoded_thumbnail_src}?t=${this.rotateImageCacheBuster}`; this.setState((prevState) => { const updatedImageItems = [...prevState.imageNodeItems]; - updatedImageItems[imageIndex].src = newThumbnailSrc; + updatedImageItems[imageIndex].thumbnail = newThumbnailSrc; return { imageNodeItems: updatedImageItems }; }); // Update the thumbnail URL with the cache-busting query parameter diff --git a/frontend/src/components/dirent-grid-view/dirent-grid-view.js b/frontend/src/components/dirent-grid-view/dirent-grid-view.js index 64663f7bcfa..89cdf79cc7c 100644 --- a/frontend/src/components/dirent-grid-view/dirent-grid-view.js +++ b/frontend/src/components/dirent-grid-view/dirent-grid-view.js @@ -102,6 +102,7 @@ class DirentGridView extends React.Component { }; this.containerRef = React.createRef(); this.isRepoOwner = props.currentRepoInfo.owner_email === username; + this.rotateImageCacheBuster = new Date().getTime(); } componentDidMount() { @@ -604,9 +605,9 @@ class DirentGridView extends React.Component { let thumbnail = ''; const isGIF = fileExt === 'gif'; if (repoEncrypted || isGIF) { - thumbnail = `${siteRoot}repo/${repoID}/raw${path}?t=${cacheBuster}`; + thumbnail = `${siteRoot}repo/${repoID}/raw${path}?t=${cacheBuster}?t=${this.rotateImageCacheBuster}`; } else { - thumbnail = `${siteRoot}thumbnail/${repoID}/${thumbnailSizeForOriginal}${path}`; + thumbnail = `${siteRoot}thumbnail/${repoID}/${thumbnailSizeForOriginal}${path}?t=${this.rotateImageCacheBuster}`; } let src = ''; @@ -684,11 +685,11 @@ class DirentGridView extends React.Component { imageAPI.rotateImage(repoID, path, 360 - angle).then((res) => { seafileAPI.createThumbnail(repoID, path, thumbnailDefaultSize).then((res) => { // Generate a unique query parameter to bust the cache - const cacheBuster = new Date().getTime(); - const newThumbnailSrc = `${res.data.encoded_thumbnail_src}?t=${cacheBuster}`; + this.rotateImageCacheBuster = new Date().getTime(); + const newThumbnailSrc = `${res.data.encoded_thumbnail_src}?t=${this.rotateImageCacheBuster}`; this.setState((prevState) => { const updatedImageItems = [...prevState.imageItems]; - updatedImageItems[imageIndex].src = newThumbnailSrc; + updatedImageItems[imageIndex].thumbnail = newThumbnailSrc; return { imageItems: updatedImageItems }; }); // Update the thumbnail URL with the cache-busting query parameter diff --git a/frontend/src/components/dirent-list-view/dirent-list-view.js b/frontend/src/components/dirent-list-view/dirent-list-view.js index a09107156d9..72c3ec0b5d2 100644 --- a/frontend/src/components/dirent-list-view/dirent-list-view.js +++ b/frontend/src/components/dirent-list-view/dirent-list-view.js @@ -102,6 +102,7 @@ class DirentListView extends React.Component { const { modify } = customPermission.permission; this.canDrop = modify; } + this.rotateImageCacheBuster = new Date().getTime(); } componentDidMount() { @@ -191,9 +192,9 @@ class DirentListView extends React.Component { let thumbnail = ''; const isGIF = fileExt === 'gif'; if (repoEncrypted || isGIF) { - thumbnail = `${siteRoot}repo/${repoID}/raw${path}`; + thumbnail = `${siteRoot}repo/${repoID}/raw${path}?t=${this.rotateImageCacheBuster}`; } else { - thumbnail = `${siteRoot}thumbnail/${repoID}/${thumbnailSizeForOriginal}${path}`; + thumbnail = `${siteRoot}thumbnail/${repoID}/${thumbnailSizeForOriginal}${path}?t=${this.rotateImageCacheBuster}`; } let src = ''; @@ -271,11 +272,11 @@ class DirentListView extends React.Component { imageAPI.rotateImage(repoID, path, 360 - angle).then((res) => { seafileAPI.createThumbnail(repoID, path, thumbnailDefaultSize).then((res) => { // Generate a unique query parameter to bust the cache - const cacheBuster = new Date().getTime(); - const newThumbnailSrc = `${res.data.encoded_thumbnail_src}?t=${cacheBuster}`; + this.rotateImageCacheBuster = new Date().getTime(); + const newThumbnailSrc = `${res.data.encoded_thumbnail_src}?t=${this.rotateImageCacheBuster}`; this.setState((prevState) => { const updatedImageItems = [...prevState.imageItems]; - updatedImageItems[imageIndex].src = newThumbnailSrc; + updatedImageItems[imageIndex].thumbnail = newThumbnailSrc; return { imageItems: updatedImageItems }; }); // Update the thumbnail URL with the cache-busting query parameter diff --git a/frontend/src/metadata/components/cell-formatter/image-previewer.js b/frontend/src/metadata/components/cell-formatter/image-previewer.js index fc0d24cc8e6..2f1d7f5c9ba 100644 --- a/frontend/src/metadata/components/cell-formatter/image-previewer.js +++ b/frontend/src/metadata/components/cell-formatter/image-previewer.js @@ -1,6 +1,6 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useState, useRef } from 'react'; import PropTypes from 'prop-types'; -import { ModalPortal } from '@seafile/sf-metadata-ui-component'; +import ModalPortal from '../../../components/modal-portal'; import toaster from '../../../components/toast'; import ImageDialog from '../../../components/dialog/image-dialog'; import imageAPI from '../../../utils/image-api'; @@ -12,6 +12,7 @@ import { getFileNameFromRecord, getParentDirFromRecord, getRecordIdFromRecord } const ImagePreviewer = ({ record, table, repoID, repoInfo, closeImagePopup }) => { const [imageIndex, setImageIndex] = useState(0); const [imageItems, setImageItems] = useState([]); + let rotateImageCacheBuster = useRef(new Date().getTime()); useEffect(() => { const newImageItems = table.rows @@ -30,7 +31,7 @@ const ImagePreviewer = ({ record, table, repoID, repoInfo, closeImagePopup }) => id, name: fileName, url: `${siteRoot}lib/${repoID}/file${path}`, - thumbnail: `${siteRoot}thumbnail/${repoID}/${thumbnailSizeForOriginal}${path}`, + thumbnail: `${siteRoot}thumbnail/${repoID}/${thumbnailSizeForOriginal}${path}?t=${rotateImageCacheBuster.current}`, src: src, parentDir, downloadURL: `${fileServerRoot}repos/${repoID}/files${path}/?op=download`, @@ -66,9 +67,9 @@ const ImagePreviewer = ({ record, table, repoID, repoInfo, closeImagePopup }) => if (res.data?.success) { seafileAPI.createThumbnail(repoID, path, thumbnailDefaultSize).then((res) => { if (res.data?.encoded_thumbnail_src) { - const cacheBuster = new Date().getTime(); - const newThumbnailSrc = `${res.data.encoded_thumbnail_src}?t=${cacheBuster}`; - imageItems[imageIndex].src = newThumbnailSrc; + rotateImageCacheBuster.current = new Date().getTime(); + const newThumbnailSrc = `${res.data.encoded_thumbnail_src}?t=${rotateImageCacheBuster.current}`; + imageItems[imageIndex].thumbnail = newThumbnailSrc; setImageItems(imageItems); } }).catch(error => {