1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-13 22:01:06 +00:00

record the status of detail to local storage (#7194)

* record the status of detail to local storage

* face recognition view support show detail

* feat: optimize code

* fix: bug

---------

Co-authored-by: zhouwenxuan <aries@Mac.local>
Co-authored-by: 杨国璇 <ygx@Hello-word.local>
This commit is contained in:
Aries
2024-12-23 17:47:20 +08:00
committed by GitHub
parent 544c4edbf2
commit 2af78338bf
19 changed files with 81 additions and 86 deletions

View File

@@ -10,7 +10,6 @@ import ViewModes from '../../components/view-modes';
import SortMenu from '../../components/sort-menu'; import SortMenu from '../../components/sort-menu';
import MetadataViewToolBar from '../../metadata/components/view-toolbar'; import MetadataViewToolBar from '../../metadata/components/view-toolbar';
import { PRIVATE_FILE_TYPE } from '../../constants'; import { PRIVATE_FILE_TYPE } from '../../constants';
import { DIRENT_DETAIL_MODE } from '../dir-view-mode/constants';
const propTypes = { const propTypes = {
repoID: PropTypes.string.isRequired, repoID: PropTypes.string.isRequired,
@@ -25,7 +24,7 @@ const propTypes = {
sortOrder: PropTypes.string, sortOrder: PropTypes.string,
sortItems: PropTypes.func, sortItems: PropTypes.func,
viewId: PropTypes.string, viewId: PropTypes.string,
onCloseDetail: PropTypes.func, onToggleDetail: PropTypes.func,
}; };
class DirTool extends React.Component { class DirTool extends React.Component {
@@ -92,14 +91,10 @@ class DirTool extends React.Component {
this.props.sortItems(sortBy, sortOrder); this.props.sortItems(sortBy, sortOrder);
}; };
showDirentDetail = () => {
this.props.switchViewMode(DIRENT_DETAIL_MODE);
};
render() { render() {
const menuItems = this.getMenu(); const menuItems = this.getMenu();
const { isDropdownMenuOpen } = this.state; const { isDropdownMenuOpen } = this.state;
const { repoID, currentMode, currentPath, sortBy, sortOrder, viewId, isCustomPermission } = this.props; const { repoID, currentMode, currentPath, sortBy, sortOrder, viewId, isCustomPermission, onToggleDetail } = this.props;
const propertiesText = TextTranslation.PROPERTIES.value; const propertiesText = TextTranslation.PROPERTIES.value;
const isFileExtended = currentPath.startsWith('/' + PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES + '/'); const isFileExtended = currentPath.startsWith('/' + PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES + '/');
const isTagView = currentPath.startsWith('/' + PRIVATE_FILE_TYPE.TAGS_PROPERTIES + '/'); const isTagView = currentPath.startsWith('/' + PRIVATE_FILE_TYPE.TAGS_PROPERTIES + '/');
@@ -110,8 +105,7 @@ class DirTool extends React.Component {
<MetadataViewToolBar <MetadataViewToolBar
viewId={viewId} viewId={viewId}
isCustomPermission={isCustomPermission} isCustomPermission={isCustomPermission}
showDetail={this.showDirentDetail} onToggleDetail={onToggleDetail}
closeDetail={this.props.onCloseDetail}
/> />
</div> </div>
); );
@@ -130,7 +124,7 @@ class DirTool extends React.Component {
<ViewModes currentViewMode={currentMode} switchViewMode={this.props.switchViewMode} /> <ViewModes currentViewMode={currentMode} switchViewMode={this.props.switchViewMode} />
<SortMenu sortBy={sortBy} sortOrder={sortOrder} onSelectSortOption={this.onSelectSortOption} /> <SortMenu sortBy={sortBy} sortOrder={sortOrder} onSelectSortOption={this.onSelectSortOption} />
{(!isCustomPermission) && {(!isCustomPermission) &&
<div className="cur-view-path-btn" onClick={this.showDirentDetail}> <div className="cur-view-path-btn" onClick={onToggleDetail}>
<span className="sf3-font sf3-font-info" aria-label={propertiesText} title={propertiesText}></span> <span className="sf3-font sf3-font-info" aria-label={propertiesText} title={propertiesText}></span>
</div> </div>
} }

View File

@@ -1,5 +1,4 @@
export const LIST_MODE = 'list'; export const LIST_MODE = 'list';
export const GRID_MODE = 'grid'; export const GRID_MODE = 'grid';
export const DIRENT_DETAIL_MODE = 'detail';
export const METADATA_MODE = 'metadata'; export const METADATA_MODE = 'metadata';
export const TAGS_MODE = 'tags'; export const TAGS_MODE = 'tags';

View File

@@ -83,7 +83,6 @@ const propTypes = {
onItemsScroll: PropTypes.func.isRequired, onItemsScroll: PropTypes.func.isRequired,
eventBus: PropTypes.object, eventBus: PropTypes.object,
updateCurrentDirent: PropTypes.func.isRequired, updateCurrentDirent: PropTypes.func.isRequired,
closeDirentDetail: PropTypes.func.isRequired,
}; };
class DirColumnView extends React.Component { class DirColumnView extends React.Component {
@@ -211,7 +210,6 @@ class DirColumnView extends React.Component {
copyFileCallback={this.props.copyFileCallback} copyFileCallback={this.props.copyFileCallback}
addFolder={this.props.onAddFolder} addFolder={this.props.onAddFolder}
updateCurrentDirent={this.props.updateCurrentDirent} updateCurrentDirent={this.props.updateCurrentDirent}
closeDirentDetail={this.props.closeDirentDetail}
showDirentDetail={this.props.showDirentDetail} showDirentDetail={this.props.showDirentDetail}
/> />
)} )}
@@ -224,7 +222,6 @@ class DirColumnView extends React.Component {
deleteFilesCallback={this.props.deleteFilesCallback} deleteFilesCallback={this.props.deleteFilesCallback}
renameFileCallback={this.props.renameFileCallback} renameFileCallback={this.props.renameFileCallback}
updateCurrentDirent={this.props.updateCurrentDirent} updateCurrentDirent={this.props.updateCurrentDirent}
closeDirentDetail={this.props.closeDirentDetail}
/> />
)} )}
{currentMode === LIST_MODE && {currentMode === LIST_MODE &&

View File

@@ -6,9 +6,10 @@ import ViewDetails from '../../metadata/components/view-details';
import ObjectUtils from '../../metadata/utils/object-utils'; import ObjectUtils from '../../metadata/utils/object-utils';
import { MetadataContext } from '../../metadata'; import { MetadataContext } from '../../metadata';
import { PRIVATE_FILE_TYPE } from '../../constants'; import { PRIVATE_FILE_TYPE } from '../../constants';
import { METADATA_MODE, TAGS_MODE } from '../dir-view-mode/constants';
const Detail = React.memo(({ repoID, path, dirent, currentRepoInfo, repoTags, fileTags, onClose, onFileTagChanged }) => { const Detail = React.memo(({ repoID, path, currentMode, dirent, currentRepoInfo, repoTags, fileTags, onClose, onFileTagChanged }) => {
const isView = useMemo(() => path.startsWith('/' + PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES), [path]); const isView = useMemo(() => currentMode === METADATA_MODE || path.startsWith('/' + PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES), [currentMode, path]);
useEffect(() => { useEffect(() => {
if (isView) return; if (isView) return;
@@ -25,6 +26,8 @@ const Detail = React.memo(({ repoID, path, dirent, currentRepoInfo, repoTags, fi
}; };
}, [repoID, currentRepoInfo, isView]); }, [repoID, currentRepoInfo, isView]);
if (currentMode === TAGS_MODE) return null;
if (isView) { if (isView) {
const viewId = path.split('/').pop(); const viewId = path.split('/').pop();
if (!dirent) return (<ViewDetails viewId={viewId} onClose={onClose} />); if (!dirent) return (<ViewDetails viewId={viewId} onClose={onClose} />);
@@ -60,6 +63,7 @@ const Detail = React.memo(({ repoID, path, dirent, currentRepoInfo, repoTags, fi
Detail.propTypes = { Detail.propTypes = {
repoID: PropTypes.string, repoID: PropTypes.string,
path: PropTypes.string, path: PropTypes.string,
currentMode: PropTypes.string,
dirent: PropTypes.object, dirent: PropTypes.object,
currentRepoInfo: PropTypes.object, currentRepoInfo: PropTypes.object,
repoTags: PropTypes.array, repoTags: PropTypes.array,

View File

@@ -35,7 +35,6 @@ const propTypes = {
unSelectDirent: PropTypes.func.isRequired, unSelectDirent: PropTypes.func.isRequired,
updateDirent: PropTypes.func.isRequired, updateDirent: PropTypes.func.isRequired,
currentMode: PropTypes.string.isRequired, currentMode: PropTypes.string.isRequired,
switchViewMode: PropTypes.func.isRequired,
direntList: PropTypes.array.isRequired, direntList: PropTypes.array.isRequired,
onItemRename: PropTypes.func.isRequired, onItemRename: PropTypes.func.isRequired,
showDirentDetail: PropTypes.func.isRequired, showDirentDetail: PropTypes.func.isRequired,

View File

@@ -43,3 +43,5 @@ export const SYSTEM_FOLDERS = [
'/_Internal', '/_Internal',
'/images' '/images'
]; ];
export const DIRENT_DETAIL_SHOW_KEY = 'sf_dirent_detail_show';

View File

@@ -4,7 +4,7 @@ import { gettext, mediaUrl } from '../../../utils/constants';
import { Detail, Header, Body } from '../../../components/dirent-detail/detail'; import { Detail, Header, Body } from '../../../components/dirent-detail/detail';
import EmptyTip from '../../../components/empty-tip'; import EmptyTip from '../../../components/empty-tip';
import { useMetadata } from '../../hooks'; import { useMetadata } from '../../hooks';
import { VIEW_TYPE } from '../../constants'; import { VIEW_TYPE, VIEW_TYPES_SUPPORT_SHOW_DETAIL } from '../../constants';
import './index.css'; import './index.css';
@@ -13,7 +13,7 @@ const ViewDetails = ({ viewId, onClose }) => {
const view = useMemo(() => idViewMap[viewId], [viewId, idViewMap]); const view = useMemo(() => idViewMap[viewId], [viewId, idViewMap]);
const icon = useMemo(() => { const icon = useMemo(() => {
const type = view.type; const type = view?.type;
if (type === VIEW_TYPE.GALLERY) return `${mediaUrl}favicons/gallery.png`; if (type === VIEW_TYPE.GALLERY) return `${mediaUrl}favicons/gallery.png`;
if (type === VIEW_TYPE.TABLE) return `${mediaUrl}favicons/table.png`; if (type === VIEW_TYPE.TABLE) return `${mediaUrl}favicons/table.png`;
if (type === VIEW_TYPE.FACE_RECOGNITION) return `${mediaUrl}favicons/face-recognition-view.png`; if (type === VIEW_TYPE.FACE_RECOGNITION) return `${mediaUrl}favicons/face-recognition-view.png`;
@@ -21,6 +21,8 @@ const ViewDetails = ({ viewId, onClose }) => {
return `${mediaUrl}img/file/256/file.png`; return `${mediaUrl}img/file/256/file.png`;
}, [view]); }, [view]);
if (!view || !VIEW_TYPES_SUPPORT_SHOW_DETAIL.includes(view.type)) return null;
return ( return (
<Detail className="sf-metadata-view-detail"> <Detail className="sf-metadata-view-detail">
<Header title={view.name} icon={icon} iconSize={28} onClose={onClose} /> <Header title={view.name} icon={icon} iconSize={28} onClose={onClose} />

View File

@@ -4,7 +4,7 @@ import { GalleryGroupBySetter, GallerySliderSetter, SortSetter } from '../../dat
import { gettext } from '../../../../utils/constants'; import { gettext } from '../../../../utils/constants';
import { EVENT_BUS_TYPE, FACE_RECOGNITION_VIEW_ID, VIEW_TYPE } from '../../../constants'; import { EVENT_BUS_TYPE, FACE_RECOGNITION_VIEW_ID, VIEW_TYPE } from '../../../constants';
const FaceRecognitionViewToolbar = ({ readOnly, isCustomPermission, showDetail }) => { const FaceRecognitionViewToolbar = ({ readOnly, isCustomPermission, onToggleDetail }) => {
const [isShow, setShow] = useState(false); const [isShow, setShow] = useState(false);
const [view, setView] = useState({}); const [view, setView] = useState({});
@@ -35,11 +35,11 @@ const FaceRecognitionViewToolbar = ({ readOnly, isCustomPermission, showDetail }
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, []);
if (!isShow) return null;
return ( return (
<> <>
<div className="sf-metadata-tool-left-operations"> <div className="sf-metadata-tool-left-operations">
{isShow && (
<>
<GalleryGroupBySetter view={{ _id: FACE_RECOGNITION_VIEW_ID }} /> <GalleryGroupBySetter view={{ _id: FACE_RECOGNITION_VIEW_ID }} />
<GallerySliderSetter view={{ _id: FACE_RECOGNITION_VIEW_ID }} /> <GallerySliderSetter view={{ _id: FACE_RECOGNITION_VIEW_ID }} />
<SortSetter <SortSetter
@@ -52,8 +52,10 @@ const FaceRecognitionViewToolbar = ({ readOnly, isCustomPermission, showDetail }
columns={viewColumns} columns={viewColumns}
modifySorts={modifySorts} modifySorts={modifySorts}
/> />
</>
)}
{!isCustomPermission && ( {!isCustomPermission && (
<div className="cur-view-path-btn ml-2" onClick={showDetail}> <div className="cur-view-path-btn ml-2" onClick={onToggleDetail}>
<span className="sf3-font sf3-font-info" aria-label={gettext('Properties')} title={gettext('Properties')}></span> <span className="sf3-font sf3-font-info" aria-label={gettext('Properties')} title={gettext('Properties')}></span>
</div> </div>
)} )}
@@ -66,7 +68,7 @@ const FaceRecognitionViewToolbar = ({ readOnly, isCustomPermission, showDetail }
FaceRecognitionViewToolbar.propTypes = { FaceRecognitionViewToolbar.propTypes = {
isCustomPermission: PropTypes.bool, isCustomPermission: PropTypes.bool,
readOnly: PropTypes.bool, readOnly: PropTypes.bool,
showDetail: PropTypes.func, onToggleDetail: PropTypes.func,
}; };
export default FaceRecognitionViewToolbar; export default FaceRecognitionViewToolbar;

View File

@@ -6,7 +6,7 @@ import { gettext } from '../../../../utils/constants';
const GalleryViewToolbar = ({ const GalleryViewToolbar = ({
readOnly, isCustomPermission, view, collaborators, readOnly, isCustomPermission, view, collaborators,
modifyFilters, modifySorts, showDetail, modifyFilters, modifySorts, onToggleDetail,
}) => { }) => {
const viewType = useMemo(() => view.type, [view]); const viewType = useMemo(() => view.type, [view]);
const viewColumns = useMemo(() => { const viewColumns = useMemo(() => {
@@ -48,7 +48,7 @@ const GalleryViewToolbar = ({
modifySorts={modifySorts} modifySorts={modifySorts}
/> />
{!isCustomPermission && ( {!isCustomPermission && (
<div className="cur-view-path-btn ml-2" onClick={showDetail}> <div className="cur-view-path-btn ml-2" onClick={onToggleDetail}>
<span className="sf3-font sf3-font-info" aria-label={gettext('Properties')} title={gettext('Properties')}></span> <span className="sf3-font sf3-font-info" aria-label={gettext('Properties')} title={gettext('Properties')}></span>
</div> </div>
)} )}
@@ -65,7 +65,7 @@ GalleryViewToolbar.propTypes = {
collaborators: PropTypes.array, collaborators: PropTypes.array,
modifyFilters: PropTypes.func, modifyFilters: PropTypes.func,
modifySorts: PropTypes.func, modifySorts: PropTypes.func,
showDetail: PropTypes.func, onToggleDetail: PropTypes.func,
}; };
export default GalleryViewToolbar; export default GalleryViewToolbar;

View File

@@ -9,7 +9,7 @@ import MapViewToolBar from './map-view-toolbar';
import './index.css'; import './index.css';
const ViewToolBar = ({ viewId, isCustomPermission, showDetail, closeDetail }) => { const ViewToolBar = ({ viewId, isCustomPermission, onToggleDetail }) => {
const [view, setView] = useState(null); const [view, setView] = useState(null);
const [collaborators, setCollaborators] = useState([]); const [collaborators, setCollaborators] = useState([]);
@@ -89,14 +89,14 @@ const ViewToolBar = ({ viewId, isCustomPermission, showDetail, closeDetail }) =>
collaborators={collaborators} collaborators={collaborators}
modifyFilters={modifyFilters} modifyFilters={modifyFilters}
modifySorts={modifySorts} modifySorts={modifySorts}
showDetail={showDetail} onToggleDetail={onToggleDetail}
/> />
)} )}
{viewType === VIEW_TYPE.FACE_RECOGNITION && ( {viewType === VIEW_TYPE.FACE_RECOGNITION && (
<FaceRecognitionViewToolbar <FaceRecognitionViewToolbar
isCustomPermission={isCustomPermission} isCustomPermission={isCustomPermission}
view={view} view={view}
showDetail={showDetail} onToggleDetail={onToggleDetail}
/> />
)} )}
{viewType === VIEW_TYPE.KANBAN && ( {viewType === VIEW_TYPE.KANBAN && (
@@ -107,8 +107,7 @@ const ViewToolBar = ({ viewId, isCustomPermission, showDetail, closeDetail }) =>
collaborators={collaborators} collaborators={collaborators}
modifyFilters={modifyFilters} modifyFilters={modifyFilters}
modifySorts={modifySorts} modifySorts={modifySorts}
showDetail={showDetail} onToggleDetail={onToggleDetail}
closeDetail={closeDetail}
/> />
)} )}
{viewType === VIEW_TYPE.MAP && ( {viewType === VIEW_TYPE.MAP && (
@@ -126,8 +125,7 @@ const ViewToolBar = ({ viewId, isCustomPermission, showDetail, closeDetail }) =>
ViewToolBar.propTypes = { ViewToolBar.propTypes = {
viewId: PropTypes.string, viewId: PropTypes.string,
isCustomPermission: PropTypes.bool, isCustomPermission: PropTypes.bool,
showDetail: PropTypes.func, onToggleDetail: PropTypes.func,
closeDetail: PropTypes.func,
}; };
export default ViewToolBar; export default ViewToolBar;

View File

@@ -12,8 +12,7 @@ const KanbanViewToolBar = ({
collaborators, collaborators,
modifyFilters, modifyFilters,
modifySorts, modifySorts,
showDetail, onToggleDetail,
closeDetail,
}) => { }) => {
const viewType = useMemo(() => view.type, [view]); const viewType = useMemo(() => view.type, [view]);
const viewColumns = useMemo(() => { const viewColumns = useMemo(() => {
@@ -26,14 +25,14 @@ const KanbanViewToolBar = ({
}, [viewColumns]); }, [viewColumns]);
const onToggleKanbanSetting = () => { const onToggleKanbanSetting = () => {
closeDetail(); onToggleDetail();
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.TOGGLE_KANBAN_SETTINGS); window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.TOGGLE_KANBAN_SETTINGS);
}; };
const toggleDetails = useCallback(() => { const toggleDetails = useCallback(() => {
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.CLOSE_KANBAN_SETTINGS); window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.CLOSE_KANBAN_SETTINGS);
showDetail(); onToggleDetail();
}, [showDetail]); }, [onToggleDetail]);
return ( return (
<> <>
@@ -88,7 +87,8 @@ KanbanViewToolBar.propTypes = {
view: PropTypes.object, view: PropTypes.object,
collaborators: PropTypes.array, collaborators: PropTypes.array,
modifyFilters: PropTypes.func, modifyFilters: PropTypes.func,
modifySorts: PropTypes.func modifySorts: PropTypes.func,
onToggleDetail: PropTypes.func,
}; };
export default KanbanViewToolBar; export default KanbanViewToolBar;

View File

@@ -123,3 +123,5 @@ export const VIEW_DEFAULT_SETTINGS = {
[KANBAN_SETTINGS_KEYS.COLUMNS]: [], [KANBAN_SETTINGS_KEYS.COLUMNS]: [],
} }
}; };
export const VIEW_TYPES_SUPPORT_SHOW_DETAIL = [VIEW_TYPE.GALLERY, VIEW_TYPE.KANBAN, VIEW_TYPE.FACE_RECOGNITION];

View File

@@ -340,7 +340,6 @@ export const MetadataViewProvider = ({
store: storeRef.current, store: storeRef.current,
isDirentDetailShow: params.isDirentDetailShow, isDirentDetailShow: params.isDirentDetailShow,
updateCurrentDirent: params.updateCurrentDirent, updateCurrentDirent: params.updateCurrentDirent,
closeDirentDetail: params.closeDirentDetail,
showDirentDetail: params.showDirentDetail, showDirentDetail: params.showDirentDetail,
deleteFilesCallback: deleteFilesCallback, deleteFilesCallback: deleteFilesCallback,
renameFileCallback: renameFileCallback, renameFileCallback: renameFileCallback,

View File

@@ -9,7 +9,7 @@ const FaceRecognition = () => {
const [showPeopleFaces, setShowPeopleFaces] = useState(false); const [showPeopleFaces, setShowPeopleFaces] = useState(false);
const peopleRef = useRef(null); const peopleRef = useRef(null);
const { metadata, store } = useMetadataView(); const { metadata, store, updateCurrentDirent } = useMetadataView();
const peoples = useMemo(() => { const peoples = useMemo(() => {
if (!Array.isArray(metadata.rows) || metadata.rows.length === 0) return []; if (!Array.isArray(metadata.rows) || metadata.rows.length === 0) return [];
@@ -21,7 +21,6 @@ const FaceRecognition = () => {
}, [store]); }, [store]);
const onRemovePeoplePhotos = useCallback((peopleId, peoplePhotos, { success_callback }) => { const onRemovePeoplePhotos = useCallback((peopleId, peoplePhotos, { success_callback }) => {
//
store.removePeoplePhotos(peopleId, peoplePhotos, { success_callback }); store.removePeoplePhotos(peopleId, peoplePhotos, { success_callback });
}, [store]); }, [store]);
@@ -33,7 +32,8 @@ const FaceRecognition = () => {
const closePeople = useCallback(() => { const closePeople = useCallback(() => {
peopleRef.current = null; peopleRef.current = null;
setShowPeopleFaces(false); setShowPeopleFaces(false);
}, []); updateCurrentDirent();
}, [updateCurrentDirent]);
const onRename = useCallback((id, newName, oldName) => { const onRename = useCallback((id, newName, oldName) => {
store.renamePeopleName(id, newName, oldName); store.renamePeopleName(id, newName, oldName);

View File

@@ -17,7 +17,7 @@ const Peoples = ({ peoples, onOpenPeople, onRename }) => {
const containerRef = useRef(null); const containerRef = useRef(null);
const { metadata, store, closeDirentDetail } = useMetadataView(); const { metadata, store } = useMetadataView();
const loadMore = useCallback(async () => { const loadMore = useCallback(async () => {
if (isLoadingMore) return; if (isLoadingMore) return;
@@ -63,12 +63,6 @@ const Peoples = ({ peoples, onOpenPeople, onRename }) => {
return () => {}; return () => {};
}, []); }, []);
useEffect(() => {
closeDirentDetail();
return () => {};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
if (!Array.isArray(peoples) || peoples.length === 0) return (<EmptyTip text={gettext('Identifying portraits...')} />); if (!Array.isArray(peoples) || peoples.length === 0) return (<EmptyTip text={gettext('Identifying portraits...')} />);
return ( return (

View File

@@ -158,7 +158,7 @@ const PeoplePhotos = ({ view, people, onClose, onDeletePeoplePhotos, onRemovePeo
useEffect(() => { useEffect(() => {
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.TOGGLE_VIEW_TOOLBAR, true); window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.TOGGLE_VIEW_TOOLBAR, true);
return () => { return () => {
window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.TOGGLE_VIEW_TOOLBAR, false); window?.sfMetadataContext?.eventBus?.dispatch(EVENT_BUS_TYPE.TOGGLE_VIEW_TOOLBAR, false);
}; };
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, []); }, []);

View File

@@ -21,17 +21,16 @@ import FileUploader from '../../components/file-uploader/file-uploader';
import CopyMoveDirentProgressDialog from '../../components/dialog/copy-move-dirent-progress-dialog'; import CopyMoveDirentProgressDialog from '../../components/dialog/copy-move-dirent-progress-dialog';
import DeleteFolderDialog from '../../components/dialog/delete-folder-dialog'; import DeleteFolderDialog from '../../components/dialog/delete-folder-dialog';
import { EVENT_BUS_TYPE } from '../../components/common/event-bus-type'; import { EVENT_BUS_TYPE } from '../../components/common/event-bus-type';
import { PRIVATE_FILE_TYPE } from '../../constants'; import { PRIVATE_FILE_TYPE, DIRENT_DETAIL_SHOW_KEY } from '../../constants';
import { MetadataStatusProvider } from '../../hooks'; import { MetadataStatusProvider } from '../../hooks';
import { MetadataProvider, CollaboratorsProvider } from '../../metadata/hooks'; import { MetadataProvider, CollaboratorsProvider } from '../../metadata/hooks';
import { TagsProvider } from '../../tag/hooks'; import { TagsProvider } from '../../tag/hooks';
import { LIST_MODE, METADATA_MODE, DIRENT_DETAIL_MODE, TAGS_MODE } from '../../components/dir-view-mode/constants'; import { LIST_MODE, METADATA_MODE, TAGS_MODE } from '../../components/dir-view-mode/constants';
import CurDirPath from '../../components/cur-dir-path'; import CurDirPath from '../../components/cur-dir-path';
import DirTool from '../../components/cur-dir-path/dir-tool'; import DirTool from '../../components/cur-dir-path/dir-tool';
import Detail from '../../components/dirent-detail'; import Detail from '../../components/dirent-detail';
import DirColumnView from '../../components/dir-view-mode/dir-column-view'; import DirColumnView from '../../components/dir-view-mode/dir-column-view';
import SelectedDirentsToolbar from '../../components/toolbar/selected-dirents-toolbar'; import SelectedDirentsToolbar from '../../components/toolbar/selected-dirents-toolbar';
import { VIEW_TYPE } from '../../metadata/constants';
import '../../css/lib-content-view.css'; import '../../css/lib-content-view.css';
@@ -53,8 +52,12 @@ class LibContentView extends React.Component {
let isTreePanelShown = true; let isTreePanelShown = true;
const storedTreePanelState = localStorage.getItem('sf_dir_view_tree_panel_open'); const storedTreePanelState = localStorage.getItem('sf_dir_view_tree_panel_open');
if (storedTreePanelState != undefined) { if (storedTreePanelState != undefined) {
isTreePanelShown = storedTreePanelState == 'true'; isTreePanelShown = storedTreePanelState === 'true';
} }
const storedDirentDetailShowState = localStorage.getItem(DIRENT_DETAIL_SHOW_KEY);
const isDirentDetailShow = storedDirentDetailShowState === 'true';
this.state = { this.state = {
currentMode: cookie.load('seafile_view_mode') || LIST_MODE, currentMode: cookie.load('seafile_view_mode') || LIST_MODE,
isTreePanelShown: isTreePanelShown, // display the 'dirent tree' side panel isTreePanelShown: isTreePanelShown, // display the 'dirent tree' side panel
@@ -88,7 +91,7 @@ class LibContentView extends React.Component {
isAllDirentSelected: false, isAllDirentSelected: false,
dirID: '', // for update dir list dirID: '', // for update dir list
errorMsg: '', errorMsg: '',
isDirentDetailShow: false, isDirentDetailShow,
itemsShowLength: 100, itemsShowLength: 100,
isSessionExpired: false, isSessionExpired: false,
isCopyMoveProgressDialogShow: false, isCopyMoveProgressDialogShow: false,
@@ -133,15 +136,22 @@ class LibContentView extends React.Component {
}; };
showDirentDetail = () => { showDirentDetail = () => {
this.setState({ isDirentDetailShow: true }); this.setState({ isDirentDetailShow: true }, () => {
localStorage.setItem(DIRENT_DETAIL_SHOW_KEY, true);
});
}; };
toggleDirentDetail = () => { toggleDirentDetail = () => {
this.setState({ isDirentDetailShow: !this.state.isDirentDetailShow }); const newState = !this.state.isDirentDetailShow;
this.setState({ isDirentDetailShow: newState }, () => {
localStorage.setItem(DIRENT_DETAIL_SHOW_KEY, newState);
});
}; };
closeDirentDetail = () => { closeDirentDetail = () => {
this.setState({ isDirentDetailShow: false }); this.setState({ isDirentDetailShow: false }, () => {
localStorage.setItem(DIRENT_DETAIL_SHOW_KEY, false);
});
}; };
componentDidMount() { componentDidMount() {
@@ -501,14 +511,13 @@ class LibContentView extends React.Component {
window.history.pushState({ url: url, path: filePath }, filePath, url); window.history.pushState({ url: url, path: filePath }, filePath, url);
}; };
showFileMetadata = (filePath, viewId, viewType) => { showFileMetadata = (filePath, viewId) => {
const repoID = this.props.repoID; const repoID = this.props.repoID;
const repoInfo = this.state.currentRepoInfo; const repoInfo = this.state.currentRepoInfo;
this.setState({ this.setState({
currentMode: METADATA_MODE, currentMode: METADATA_MODE,
path: filePath, path: filePath,
viewId: viewId, viewId: viewId,
isDirentDetailShow: viewType === VIEW_TYPE.GALLERY ? this.state.isDirentDetailShow : false,
}); });
const url = `${siteRoot}library/${repoID}/${encodeURIComponent(repoInfo.repo_name)}/?view=${encodeURIComponent(viewId)}`; const url = `${siteRoot}library/${repoID}/${encodeURIComponent(repoInfo.repo_name)}/?view=${encodeURIComponent(viewId)}`;
window.history.pushState({ url: url, path: '' }, '', url); window.history.pushState({ url: url, path: '' }, '', url);
@@ -532,7 +541,6 @@ class LibContentView extends React.Component {
currentMode: TAGS_MODE, currentMode: TAGS_MODE,
path: filePath, path: filePath,
tagId: tagId, tagId: tagId,
isDirentDetailShow: false
}); });
const url = `${siteRoot}library/${repoID}/${encodeURIComponent(repoInfo.repo_name)}/?tag=${encodeURIComponent(tagId)}`; const url = `${siteRoot}library/${repoID}/${encodeURIComponent(repoInfo.repo_name)}/?tag=${encodeURIComponent(tagId)}`;
window.history.pushState({ url: url, path: '' }, '', url); window.history.pushState({ url: url, path: '' }, '', url);
@@ -988,10 +996,7 @@ class LibContentView extends React.Component {
if (mode === this.state.currentMode) { if (mode === this.state.currentMode) {
return; return;
} }
if (mode === DIRENT_DETAIL_MODE) {
this.toggleDirentDetail();
return;
}
cookie.save('seafile_view_mode', mode); cookie.save('seafile_view_mode', mode);
let path = this.state.path; let path = this.state.path;
if (this.state.isTreePanelShown && this.state.isViewFile) { if (this.state.isTreePanelShown && this.state.isViewFile) {
@@ -1869,7 +1874,7 @@ class LibContentView extends React.Component {
} else { } else {
if (Utils.isFileMetadata(node?.object?.type)) { if (Utils.isFileMetadata(node?.object?.type)) {
if (node.path !== this.state.path) { if (node.path !== this.state.path) {
this.showFileMetadata(node.path, node.view_id || '0000', node.view_type || VIEW_TYPE.TABLE); this.showFileMetadata(node.path, node.view_id || '0000');
} }
} else if (Utils.isTags(node?.object?.type)) { } else if (Utils.isTags(node?.object?.type)) {
if (node.path !== this.state.path) { if (node.path !== this.state.path) {
@@ -2001,6 +2006,7 @@ class LibContentView extends React.Component {
isDirentSelected: false, isDirentSelected: false,
isAllDirentSelected: false, isAllDirentSelected: false,
currentMode: nextModel, currentMode: nextModel,
currentDirent: null,
}); });
}; };
@@ -2248,7 +2254,6 @@ class LibContentView extends React.Component {
isGroupOwnedRepo={this.state.isGroupOwnedRepo} isGroupOwnedRepo={this.state.isGroupOwnedRepo}
showDirentDetail={this.showDirentDetail} showDirentDetail={this.showDirentDetail}
currentMode={this.state.currentMode} currentMode={this.state.currentMode}
switchViewMode={this.switchViewMode}
onItemConvert={this.onConvertItem} onItemConvert={this.onConvertItem}
onAddFolder={this.onAddFolder} onAddFolder={this.onAddFolder}
/> />
@@ -2304,7 +2309,7 @@ class LibContentView extends React.Component {
sortItems={this.sortItems} sortItems={this.sortItems}
viewId={this.state.viewId} viewId={this.state.viewId}
viewType={this.props.viewType} viewType={this.props.viewType}
onCloseDetail={this.closeDirentDetail} onToggleDetail={this.toggleDirentDetail}
/> />
</div> </div>
} }
@@ -2378,12 +2383,11 @@ class LibContentView extends React.Component {
onItemsScroll={this.onItemsScroll} onItemsScroll={this.onItemsScroll}
eventBus={this.props.eventBus} eventBus={this.props.eventBus}
updateCurrentDirent={this.updateCurrentDirent} updateCurrentDirent={this.updateCurrentDirent}
closeDirentDetail={this.closeDirentDetail}
/> />
: :
<div className="message err-tip">{gettext('Folder does not exist.')}</div> <div className="message err-tip">{gettext('Folder does not exist.')}</div>
} }
{this.state.isDirentDetailShow && ( {!isCustomPermission && this.state.isDirentDetailShow && (
<Detail <Detail
path={this.state.path} path={this.state.path}
repoID={this.props.repoID} repoID={this.props.repoID}
@@ -2393,6 +2397,7 @@ class LibContentView extends React.Component {
fileTags={this.state.isViewFile ? this.state.fileTags : []} fileTags={this.state.isViewFile ? this.state.fileTags : []}
onFileTagChanged={this.onFileTagChanged} onFileTagChanged={this.onFileTagChanged}
onClose={this.closeDirentDetail} onClose={this.closeDirentDetail}
currentMode={this.state.currentMode}
/> />
)} )}
</div> </div>

View File

@@ -49,7 +49,6 @@ export const TagViewProvider = ({ repoID, tagID, children, ...params }) => {
deleteFilesCallback: params.deleteFilesCallback, deleteFilesCallback: params.deleteFilesCallback,
renameFileCallback: params.renameFileCallback, renameFileCallback: params.renameFileCallback,
updateCurrentDirent: params.updateCurrentDirent, updateCurrentDirent: params.updateCurrentDirent,
closeDirentDetail: params.closeDirentDetail,
}}> }}>
{children} {children}
</TagViewContext.Provider> </TagViewContext.Provider>

View File

@@ -248,7 +248,6 @@ export const TagsProvider = ({ repoID, currentPath, selectTagsView, children, ..
deleteFilesCallback: params.deleteFilesCallback, deleteFilesCallback: params.deleteFilesCallback,
renameFileCallback: params.renameFileCallback, renameFileCallback: params.renameFileCallback,
updateCurrentDirent: params.updateCurrentDirent, updateCurrentDirent: params.updateCurrentDirent,
closeDirentDetail: params.closeDirentDetail,
addTag, addTag,
addTags, addTags,
modifyTags, modifyTags,