diff --git a/frontend/src/components/dir-view-mode/dir-views.js b/frontend/src/components/dir-view-mode/dir-views.js index 725299adc42..c09ac8ea5f9 100644 --- a/frontend/src/components/dir-view-mode/dir-views.js +++ b/frontend/src/components/dir-view-mode/dir-views.js @@ -1,11 +1,8 @@ -import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; import PropTypes from 'prop-types'; import { gettext } from '../../utils/constants'; -import { Utils } from '../../utils/utils'; import TreeSection from '../tree-section'; -import { MetadataStatusManagementDialog, MetadataTreeView } from '../../metadata'; -import metadataAPI from '../../metadata/api'; -import toaster from '../toast'; +import { MetadataStatusManagementDialog, MetadataTreeView, useMetadataStatus } from '../../metadata'; const DirViews = ({ userPerm, repoID, currentPath, onNodeClick }) => { const enableMetadataManagement = useMemo(() => { @@ -13,9 +10,8 @@ const DirViews = ({ userPerm, repoID, currentPath, onNodeClick }) => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [window.app.pageOptions.enableMetadataManagement]); - const [loading, setLoading] = useState(true); const [showMetadataStatusManagementDialog, setShowMetadataStatusManagementDialog] = useState(false); - const [metadataStatus, setMetadataStatus] = useState(false); + const { enableExtendedProperties, updateEnableExtendedProperties } = useMetadataStatus(); const moreOperations = useMemo(() => { if (!enableMetadataManagement) return []; if (userPerm !== 'rw' && userPerm !== 'admin') return []; @@ -24,25 +20,6 @@ const DirViews = ({ userPerm, repoID, currentPath, onNodeClick }) => { ]; }, [enableMetadataManagement, userPerm]); - useEffect(() => { - if (!enableMetadataManagement) { - setLoading(false); - return; - } - - const repoMetadataManagementEnabledStatusRes = metadataAPI.getMetadataStatus(repoID); - Promise.all([repoMetadataManagementEnabledStatusRes]).then(results => { - const [repoMetadataManagementEnabledStatusRes] = results; - setMetadataStatus(repoMetadataManagementEnabledStatusRes.data.enabled); - setLoading(false); - }).catch(error => { - const errorMsg = Utils.getErrorMsg(error, true); - toaster.danger(errorMsg); - setLoading(false); - }); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - const moreOperationClick = useCallback((operationKey) => { if (operationKey === 'extended-properties') { setShowMetadataStatusManagementDialog(true); @@ -55,9 +32,8 @@ const DirViews = ({ userPerm, repoID, currentPath, onNodeClick }) => { }, []); const toggleMetadataStatus = useCallback((value) => { - if (metadataStatus === value) return; - setMetadataStatus(value); - }, [metadataStatus]); + updateEnableExtendedProperties(value); + }, [updateEnableExtendedProperties]); return ( <> @@ -67,11 +43,11 @@ const DirViews = ({ userPerm, repoID, currentPath, onNodeClick }) => { moreOperations={moreOperations} moreOperationClick={moreOperationClick} > - {!loading && metadataStatus && ()} + {enableExtendedProperties && ()} {showMetadataStatusManagementDialog && ( { }, [setDragHandlerTop]); useEffect(() => { - const width = localStorage.getItem('sf_cur_view_detail_width', 300); + const lastSettingsValue = localStorage.getItem('sf_cur_view_detail_width'); + const width = lastSettingsValue ? parseInt(lastSettingsValue) : 300; setWidth(width); }, []); diff --git a/frontend/src/components/dirent-detail/dirent-details/dir-details.js b/frontend/src/components/dirent-detail/dirent-details/dir-details.js index 7e504de982a..e0ee3099785 100644 --- a/frontend/src/components/dirent-detail/dirent-details/dir-details.js +++ b/frontend/src/components/dirent-detail/dirent-details/dir-details.js @@ -1,27 +1,19 @@ import React, { useMemo } from 'react'; import PropTypes from 'prop-types'; -import { getDirentPath, getFileParent } from './utils'; +import { getDirentPath } from './utils'; import DetailItem from '../detail-item'; import { CellType } from '../../../metadata/metadata-view/_basic'; import { gettext } from '../../../utils/constants'; -import { MetadataDetails } from '../../../metadata'; +import { MetadataDetails, useMetadataStatus } from '../../../metadata'; const DirDetails = ({ repoID, repoInfo, dirent, path, direntDetail, ...params }) => { - const parent = useMemo(() => getFileParent(dirent, path), [dirent, path]); const direntPath = useMemo(() => getDirentPath(dirent, path), [dirent, path]); + const { enableExtendedProperties } = useMetadataStatus(); return ( <> - - - - {window.app.pageOptions.enableMetadataManagement && ( + {window.app.pageOptions.enableMetadataManagement && enableExtendedProperties && ( )} diff --git a/frontend/src/components/dirent-detail/dirent-details/file-details.js b/frontend/src/components/dirent-detail/dirent-details/file-details.js index 692f304e440..a9d72250e57 100644 --- a/frontend/src/components/dirent-detail/dirent-details/file-details.js +++ b/frontend/src/components/dirent-detail/dirent-details/file-details.js @@ -1,20 +1,20 @@ import React, { useCallback, useMemo, useState } from 'react'; import PropTypes from 'prop-types'; import { v4 as uuidV4 } from 'uuid'; -import { getDirentPath, getFileParent } from './utils'; +import { getDirentPath } from './utils'; import DetailItem from '../detail-item'; import { CellType } from '../../../metadata/metadata-view/_basic'; import { gettext } from '../../../utils/constants'; import EditFileTagPopover from '../../popover/edit-filetag-popover'; import FileTagList from '../../file-tag-list'; import { Utils } from '../../../utils/utils'; -import { MetadataDetails } from '../../../metadata'; +import { MetadataDetails, useMetadataStatus } from '../../../metadata'; import ObjectUtils from '../../../metadata/metadata-view/utils/object-utils'; const FileDetails = React.memo(({ repoID, repoInfo, dirent, path, direntDetail, onFileTagChanged, repoTags, fileTagList, ...params }) => { const [isEditFileTagShow, setEditFileTagShow] = useState(false); + const { enableExtendedProperties } = useMetadataStatus(); - const parent = useMemo(() => getFileParent(dirent, path), [dirent, path]); const direntPath = useMemo(() => getDirentPath(dirent, path), [dirent, path]); const tagListTitleID = useMemo(() => `detail-list-view-tags-${uuidV4()}`, []); @@ -28,7 +28,6 @@ const FileDetails = React.memo(({ repoID, repoInfo, dirent, path, direntDetail, return ( <> - - {!window.app.pageOptions.enableMetadataManagement && ( + {!window.app.pageOptions.enableMetadataManagement && enableExtendedProperties && ( {Array.isArray(fileTagList) && fileTagList.length > 0 ? ( diff --git a/frontend/src/components/dirent-detail/dirent-details/index.js b/frontend/src/components/dirent-detail/dirent-details/index.js index c91b44996ae..ed77891723e 100644 --- a/frontend/src/components/dirent-detail/dirent-details/index.js +++ b/frontend/src/components/dirent-detail/dirent-details/index.js @@ -91,30 +91,34 @@ class DirentDetails extends React.Component { } } - render() { - const { dirent, direntDetail, collaborators, collaboratorsCache } = this.state; + renderImage = () => { + const { dirent } = this.state; if (!dirent) return null; - const { repoID, path, fileTags } = this.props; - const direntName = dirent.name; - const smallIconUrl = Utils.getDirentIcon(dirent); // let bigIconUrl = Utils.getDirentIcon(dirent, true); - let bigIconUrl = ''; const isImg = Utils.imageCheck(dirent.name); // const isVideo = Utils.videoCheck(dirent.name); - if (isImg) { - bigIconUrl = `${siteRoot}thumbnail/${repoID}/1024` + Utils.encodePath(`${path === '/' ? '' : path}/${dirent.name}`); - } + if (!isImg) return null; + const { repoID, path } = this.props; + const bigIconUrl = `${siteRoot}thumbnail/${repoID}/1024` + Utils.encodePath(`${path === '/' ? '' : path}/${dirent.name}`); + return ( +
+ +
+ ); + }; + + render() { + const { dirent, direntDetail, collaborators, collaboratorsCache } = this.state; + const { repoID, path, fileTags } = this.props; + const direntName = dirent?.name || ''; + const smallIconUrl = Utils.getDirentIcon(dirent); return (
- {isImg && ( -
- -
- )} - {direntDetail && ( + {this.renderImage()} + {dirent && direntDetail && (
{dirent.type !== 'file' ? ( { if (Utils.isMarkdownFile(path)) return path; // column mode: view file - if (dirent.type === 'dir') return path; return Utils.joinPath(path, dirent.name); }; export const getFileParent = (dirent, path) => { const direntPath = getDirentPath(dirent, path); - if (direntPath === '/') return '/'; - const index = direntPath.lastIndexOf('/'); - const positionPath = direntPath.slice(0, index); - return positionPath || '/'; + let position = ''; + if (direntPath !== '/') { + const index = direntPath.lastIndexOf('/'); + const positionPath = direntPath.slice(0, index); + position = position + positionPath; + } + return position; }; diff --git a/frontend/src/metadata/hooks/index.js b/frontend/src/metadata/hooks/index.js new file mode 100644 index 00000000000..68b307d5488 --- /dev/null +++ b/frontend/src/metadata/hooks/index.js @@ -0,0 +1 @@ +export { MetadataStatusProvider, useMetadataStatus } from './metadata-status'; diff --git a/frontend/src/metadata/hooks/metadata-status.js b/frontend/src/metadata/hooks/metadata-status.js new file mode 100644 index 00000000000..9a6b946b14d --- /dev/null +++ b/frontend/src/metadata/hooks/metadata-status.js @@ -0,0 +1,50 @@ +import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react'; +import metadataAPI from '../api'; +import { Utils } from '../../utils/utils'; +import toaster from '../../components/toast'; + +const MetadataStatusContext = React.createContext(null); + +export const MetadataStatusProvider = ({ repoID, children }) => { + const enableMetadataManagement = useMemo(() => { + return window.app.pageOptions.enableMetadataManagement; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [window.app.pageOptions.enableMetadataManagement]); + + + const [enableExtendedProperties, setEnableExtendedProperties] = useState(false); + + useEffect(() => { + if (!enableMetadataManagement) { + setEnableExtendedProperties(false); + return; + } + metadataAPI.getMetadataStatus(repoID).then(res => { + setEnableExtendedProperties(res.data.enabled); + }).catch(error => { + const errorMsg = Utils.getErrorMsg(error, true); + toaster.danger(errorMsg); + setEnableExtendedProperties(false); + }); + }, [repoID, enableMetadataManagement]); + + const updateEnableExtendedProperties = useCallback((newValue) => { + if (newValue === enableExtendedProperties) return; + setEnableExtendedProperties(newValue); + }, [enableExtendedProperties]); + + return ( + + {children} + + ); +}; + +export const useMetadataStatus = () => { + const context = useContext(MetadataStatusContext); + if (!context) { + throw new Error('\'MetadataStatusContext\' is null'); + } + const { enableExtendedProperties, updateEnableExtendedProperties } = context; + return { enableExtendedProperties, updateEnableExtendedProperties }; +}; diff --git a/frontend/src/metadata/index.js b/frontend/src/metadata/index.js index dc4945471d0..4ad4264f278 100644 --- a/frontend/src/metadata/index.js +++ b/frontend/src/metadata/index.js @@ -2,8 +2,12 @@ import SeafileMetadata from './metadata-view'; import MetadataStatusManagementDialog from './metadata-status-manage-dialog'; import MetadataTreeView from './metadata-tree-view'; import MetadataDetails from './metadata-details'; +import metadataAPI from './api'; + +export * from './hooks'; export { + metadataAPI, SeafileMetadata, MetadataStatusManagementDialog, MetadataTreeView, diff --git a/frontend/src/pages/lib-content-view/lib-content-container.js b/frontend/src/pages/lib-content-view/lib-content-container.js index 8f4d2b067df..27f8dbc2781 100644 --- a/frontend/src/pages/lib-content-view/lib-content-container.js +++ b/frontend/src/pages/lib-content-view/lib-content-container.js @@ -1,10 +1,11 @@ -import React, { Fragment } from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; import { gettext } from '../../utils/constants'; import CurDirPath from '../../components/cur-dir-path'; import Detail from '../../components/dirent-detail'; import DirColumnView from '../../components/dir-view-mode/dir-column-view'; import ToolbarForSelectedDirents from '../../components/toolbar/selected-dirents-toolbar'; +import { MetadataStatusProvider } from '../../metadata/hooks'; import '../../css/lib-content-view.css'; @@ -120,12 +121,10 @@ class LibContentContainer extends React.Component { onPathClick = (path) => { this.props.onMainNavBarClick(path); - this.props.closeDirentDetail(); }; onItemClick = (dirent) => { this.props.onItemClick(dirent); - this.props.closeDirentDetail(); }; onDirentClick = (dirent, event) => { @@ -181,7 +180,7 @@ class LibContentContainer extends React.Component { } return ( - +
{this.props.currentRepoInfo.status === 'read-only' &&
@@ -253,7 +252,6 @@ class LibContentContainer extends React.Component {
{!this.props.pathExist && this.errMessage} {this.props.pathExist && ( @@ -335,7 +333,7 @@ class LibContentContainer extends React.Component { )}
- + ); } } diff --git a/frontend/src/utils/utils.js b/frontend/src/utils/utils.js index bbd5951ab00..9abb6dd03fb 100644 --- a/frontend/src/utils/utils.js +++ b/frontend/src/utils/utils.js @@ -391,6 +391,7 @@ export const Utils = { }, getDirentIcon: function (dirent, isBig) { + if (!dirent) return mediaUrl + 'img/file/256/' + this.FILEEXT_ICON_MAP['default']; let size = this.isHiDPI() ? 48 : 24; size = isBig ? 192 : size; if (dirent.isDir()) {