diff --git a/frontend/src/components/dir-view-mode/constants.js b/frontend/src/components/dir-view-mode/constants.js
index 0f0485ca85..6e27ee40ae 100644
--- a/frontend/src/components/dir-view-mode/constants.js
+++ b/frontend/src/components/dir-view-mode/constants.js
@@ -1,3 +1,4 @@
+export * from '../../metadata/constants';
export const LIST_MODE = 'list';
export const GRID_MODE = 'grid';
export const METADATA_MODE = 'metadata';
diff --git a/frontend/src/components/dirent-detail/detail-container.js b/frontend/src/components/dirent-detail/detail-container.js
index 5eb994c7c8..d442a8093f 100644
--- a/frontend/src/components/dirent-detail/detail-container.js
+++ b/frontend/src/components/dirent-detail/detail-container.js
@@ -1,38 +1,51 @@
-import React from 'react';
+import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import LibDetail from './lib-details';
import DirentDetail from './dirent-details';
import GalleryDetail from '../../metadata/components/gallery-details';
import ObjectUtils from '../../metadata/utils/object-utils';
+import { MetadataContext } from '../../metadata';
import { METADATA_MODE } from '../dir-view-mode/constants';
const DetailContainer = React.memo(({ repoID, path, dirent, currentRepoInfo, repoTags, fileTags, onClose, onFileTagChanged, mode }) => {
- const renderContent = () => {
- if (mode === METADATA_MODE) {
- const viewID = path.split('/').pop();
- return ;
+ useEffect(() => {
+ // init context
+ if (!window.sfMetadataContext) {
+ const context = new MetadataContext();
+ window.sfMetadataContext = context;
+ window.sfMetadataContext.init({ repoID, repoInfo: currentRepoInfo });
}
- if (path === '/' && !dirent) {
- return ;
- }
+ return () => {
+ if (window.sfMetadataContext && mode !== METADATA_MODE) {
+ window.sfMetadataContext.destroy();
+ delete window['sfMetadataContext'];
+ }
+ };
+ }, [repoID, currentRepoInfo, mode]);
+
+ if (mode === METADATA_MODE) {
+ const viewID = path.split('/').pop();
+ return ;
+ }
+
+ if (path === '/' && !dirent) {
+ return ;
+ }
- return (
-
- );
- };
-
- return renderContent();
+ return (
+
+ );
}, (props, nextProps) => {
const isChanged =
props.repoID !== nextProps.repoID ||
diff --git a/frontend/src/metadata/components/gallery-details/index.js b/frontend/src/metadata/components/gallery-details/index.js
index c3281834bf..323155b797 100644
--- a/frontend/src/metadata/components/gallery-details/index.js
+++ b/frontend/src/metadata/components/gallery-details/index.js
@@ -9,7 +9,7 @@ import { Utils } from '../../../utils/utils';
import { gettext, siteRoot, thumbnailSizeForGrid } from '../../../utils/constants';
import { Detail, Header, Body } from '../../../components/dirent-detail/detail';
import { CellType, PRIVATE_COLUMN_KEY } from '../../constants';
-import { useMetadata } from '../../../metadata';
+import { useMetadata, useGallery } from '../../../metadata';
import { seafileAPI } from '../../../utils/seafile-api';
import FileDetails from '../../../components/dirent-detail/dirent-details/file-details';
import { Dirent } from '../../../models';
@@ -18,39 +18,14 @@ const GalleryDetail = ({ currentRepoInfo, viewID, onClose }) => {
const [isLoading, setLoading] = useState(true);
const [repo, setRepo] = useState({});
const [direntDetail, setDirentDetail] = useState(null);
- const { viewsMap, currentImage } = useMetadata();
+ const { viewsMap } = useMetadata();
+ const { currentImage } = useGallery();
const view = useMemo(() => viewsMap[viewID], [viewID, viewsMap]);
const icon = useMemo(() => Utils.getFolderIconUrl(), []);
- const filesField = useMemo(() => ({ type: CellType.NUMBER, name: gettext('Files') }), []);
- const sizeField = useMemo(() => ({ type: CellType.TEXT, name: gettext('Size') }), []);
const creatorField = useMemo(() => ({ type: CellType.CREATOR, name: gettext('Creator') }), []);
const mtimeField = useMemo(() => ({ type: CellType.MTIME, name: gettext('Last modified time') }), []);
- const filesCount = useMemo(() => {
- if (!window.sfMetadataContext || !window.sfMetadataStore) return 0;
-
- const store = window.sfMetadataStore;
- return store.data.rows.reduce((count, row) => Utils.imageCheck(row[PRIVATE_COLUMN_KEY.FILE_NAME]) ? count + 1 : count, 0);
- }, []);
-
- const sizeCount = useMemo(() => {
- // count all images size
- if (!window.sfMetadataContext || !window.sfMetadataStore) return 0;
-
- const store = window.sfMetadataStore;
- const total = store.data.rows.reduce((size, row) => {
- if (Utils.imageCheck(row[PRIVATE_COLUMN_KEY.FILE_NAME])) {
- const sizeStr = row[PRIVATE_COLUMN_KEY.SIZE];
- const sizeNum = parseInt(sizeStr);
- return size + sizeNum;
- }
- return size;
- }, 0);
-
- return Utils.bytesToSize(total);
- }, []);
-
useEffect(() => {
setLoading(true);
seafileAPI.getRepoInfo(currentRepoInfo.repo_id).then(res => {
@@ -101,18 +76,9 @@ const GalleryDetail = ({ currentRepoInfo, viewID, onClose }) => {
) : (
-
-
-
-
-
-
-
-
-
{
+ const [currentImage, setCurrentImage] = useState(null);
+
+ const updateCurrentImage = useCallback((image) => {
+ setCurrentImage(image);
+ }, []);
+
+ return (
+
+ {children}
+
+ );
+};
+
+export const useGallery = () => {
+ const context = useContext(GalleryContext);
+
+ if (!context) {
+ throw new Error('\'GalleryContext\' is null');
+ }
+
+ return context;
+};
diff --git a/frontend/src/metadata/hooks/index.js b/frontend/src/metadata/hooks/index.js
index 74b4c9ab56..73beeb7a5a 100644
--- a/frontend/src/metadata/hooks/index.js
+++ b/frontend/src/metadata/hooks/index.js
@@ -1,3 +1,4 @@
export { MetadataProvider, useMetadata } from './metadata';
export { EnableMetadataProvider, useEnableMetadata } from './enable-metadata';
export { CollaboratorsProvider, useCollaborators } from './collaborators';
+export { GalleryProvider, useGallery } from './gallery';
diff --git a/frontend/src/metadata/hooks/metadata.js b/frontend/src/metadata/hooks/metadata.js
index 0476fb6f62..ce634afc75 100644
--- a/frontend/src/metadata/hooks/metadata.js
+++ b/frontend/src/metadata/hooks/metadata.js
@@ -20,7 +20,6 @@ export const MetadataProvider = ({ repoID, hideMetadataView, selectMetadataView,
const [navigation, setNavigation] = useState([]);
const [staticView, setStaticView] = useState([]);
const [, setCount] = useState(0);
- const [currentImage, setCurrentImage] = useState(null);
const viewsMap = useRef({});
@@ -139,6 +138,7 @@ export const MetadataProvider = ({ repoID, hideMetadataView, selectMetadataView,
name: isFaceRecognitionView ? gettext('Photos - classfied by people') : gettext('File extended properties'),
type: isFaceRecognitionView ? PRIVATE_FILE_TYPE.FACE_RECOGNITION : PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES,
isDir: () => false,
+ viewType: view.type,
},
parentNode: {},
key: repoID,
@@ -214,10 +214,6 @@ export const MetadataProvider = ({ repoID, hideMetadataView, selectMetadataView,
});
}, [repoID]);
- const updateCurrentImage = useCallback((image) => {
- setCurrentImage(image);
- }, []);
-
return (
{children}
diff --git a/frontend/src/metadata/views/gallery/gallery-main.js b/frontend/src/metadata/views/gallery/gallery-main.js
index 74b57c45b8..82a77b5907 100644
--- a/frontend/src/metadata/views/gallery/gallery-main.js
+++ b/frontend/src/metadata/views/gallery/gallery-main.js
@@ -81,7 +81,16 @@ const GalleryMain = ({
}, []);
const handleClickOutside = useCallback((e) => {
- if (imageRef.current && !imageRef.current.contains(e.target) && containerRef.current && containerRef.current.contains(e.target)) {
+ const images = containerRef.current.querySelectorAll('.metadata-gallery-image-item');
+ let isClickInsideImage = false;
+
+ images.forEach(img => {
+ if (img.contains(e.target)) {
+ isClickInsideImage = true;
+ }
+ });
+
+ if (!isClickInsideImage && containerRef.current.contains(e.target)) {
onImageSelect([]);
}
}, [onImageSelect]);
@@ -129,7 +138,6 @@ const GalleryMain = ({
{name || gettext('Empty')}
)}
{
const containerRef = useRef(null);
const renderMoreTimer = useRef(null);
- const { updateCurrentImage } = useMetadata();
+ const { updateCurrentImage } = useGallery();
const { metadata, store } = useMetadataView();
const repoID = store.repoId;
- useEffect(() => {
- updateCurrentImage(selectedImages[0]);
- }, [selectedImages, updateCurrentImage]);
+ useEffect(() => updateCurrentImage(selectedImages[0]), [selectedImages, updateCurrentImage]);
const selectedImageIDs = useMemo(() => {
return selectedImages.map(image => image.id);
diff --git a/frontend/src/pages/lib-content-view/lib-content-view.js b/frontend/src/pages/lib-content-view/lib-content-view.js
index 2516ddf7b7..1a871643ce 100644
--- a/frontend/src/pages/lib-content-view/lib-content-view.js
+++ b/frontend/src/pages/lib-content-view/lib-content-view.js
@@ -21,8 +21,8 @@ import CopyMoveDirentProgressDialog from '../../components/dialog/copy-move-dire
import DeleteFolderDialog from '../../components/dialog/delete-folder-dialog';
import { EVENT_BUS_TYPE } from '../../components/common/event-bus-type';
import { PRIVATE_FILE_TYPE } from '../../constants';
-import { MetadataProvider, CollaboratorsProvider } from '../../metadata/hooks';
-import { LIST_MODE, METADATA_MODE, FACE_RECOGNITION_MODE } from '../../components/dir-view-mode/constants';
+import { MetadataProvider, CollaboratorsProvider, GalleryProvider } from '../../metadata/hooks';
+import { LIST_MODE, METADATA_MODE, FACE_RECOGNITION_MODE, VIEW_TYPE } from '../../components/dir-view-mode/constants';
import CurDirPath from '../../components/cur-dir-path';
import DirTool from '../../components/cur-dir-path/dir-tool';
import DetailContainer from '../../components/dirent-detail/detail-container';
@@ -538,14 +538,14 @@ class LibContentView extends React.Component {
window.history.pushState({ url: url, path: filePath }, filePath, url);
};
- showFileMetadata = (filePath, viewId) => {
+ showFileMetadata = (filePath, viewId, viewType) => {
const repoID = this.props.repoID;
const repoInfo = this.state.currentRepoInfo;
this.setState({
currentMode: METADATA_MODE,
path: filePath,
viewId: viewId,
- isDirentDetailShow: false
+ isDirentDetailShow: viewType === VIEW_TYPE.GALLERY ? this.state.isDirentDetailShow : false,
}, () => {
setTimeout(() => {
this.unsubscribeEventBus = window.sfMetadataContext.eventBus.subscribe(EVENT_BUS_TYPE.OPEN_MARKDOWN_DIALOG, this.openMarkDownDialog);
@@ -1897,7 +1897,7 @@ class LibContentView extends React.Component {
}
} else if (Utils.isFileMetadata(node?.object?.type)) {
if (node.path !== this.state.path) {
- this.showFileMetadata(node.path, node.view_id || '0000');
+ this.showFileMetadata(node.path, node.view_id || '0000', node.object.viewType);
}
} else if (Utils.isFaceRecognition(node?.object?.type)) {
if (node.path !== this.state.path) {
@@ -2360,92 +2360,94 @@ class LibContentView extends React.Component {
}
-
- {this.state.pathExist ?
-
- :
-
{gettext('Folder does not exist.')}
- }
- {this.state.isDirentDetailShow && (
-
- )}
-
+
+
+ {this.state.pathExist ?
+
+ :
+
{gettext('Folder does not exist.')}
+ }
+ {this.state.isDirentDetailShow && (
+
+ )}
+
+
{canUpload && this.state.pathExist && !this.state.isViewFile && this.state.currentMode !== METADATA_MODE && (