1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-11 11:51:27 +00:00

feat: face view support move (#7137)

* feat: face view support move

* feat: optimize code

* feat: optimize code

---------

Co-authored-by: 杨国璇 <ygx@Hello-word.local>
This commit is contained in:
杨国璇
2024-12-04 10:05:17 +08:00
committed by GitHub
parent 44d0c2c3db
commit 1d117bf647
6 changed files with 34 additions and 47 deletions

View File

@@ -17,8 +17,7 @@ const VIEW_OPTIONS = [
}, { }, {
key: 'kanban', key: 'kanban',
type: VIEW_TYPE.KANBAN, type: VIEW_TYPE.KANBAN,
}, }, {
{
key: 'map', key: 'map',
type: VIEW_TYPE.MAP, type: VIEW_TYPE.MAP,
} }

View File

@@ -70,6 +70,7 @@ export const VIEW_TYPE_DEFAULT_BASIC_FILTER = {
export const VIEW_TYPE_DEFAULT_SORTS = { export const VIEW_TYPE_DEFAULT_SORTS = {
[VIEW_TYPE.TABLE]: [], [VIEW_TYPE.TABLE]: [],
[VIEW_TYPE.GALLERY]: [{ column_key: PRIVATE_COLUMN_KEY.FILE_CTIME, sort_type: SORT_TYPE.DOWN }], [VIEW_TYPE.GALLERY]: [{ column_key: PRIVATE_COLUMN_KEY.FILE_CTIME, sort_type: SORT_TYPE.DOWN }],
[VIEW_TYPE.FACE_RECOGNITION]: [],
[VIEW_TYPE.KANBAN]: [], [VIEW_TYPE.KANBAN]: [],
[VIEW_TYPE.MAP]: [], [VIEW_TYPE.MAP]: [],
}; };
@@ -77,6 +78,7 @@ export const VIEW_TYPE_DEFAULT_SORTS = {
export const VIEW_SORT_COLUMN_RULES = { export const VIEW_SORT_COLUMN_RULES = {
[VIEW_TYPE.TABLE]: (column) => SORT_COLUMN_OPTIONS.includes(column.type), [VIEW_TYPE.TABLE]: (column) => SORT_COLUMN_OPTIONS.includes(column.type),
[VIEW_TYPE.GALLERY]: (column) => GALLERY_SORT_COLUMN_OPTIONS.includes(column.type) || GALLERY_SORT_PRIVATE_COLUMN_KEYS.includes(column.key), [VIEW_TYPE.GALLERY]: (column) => GALLERY_SORT_COLUMN_OPTIONS.includes(column.type) || GALLERY_SORT_PRIVATE_COLUMN_KEYS.includes(column.key),
[VIEW_TYPE.FACE_RECOGNITION]: () => {},
[VIEW_TYPE.KANBAN]: (column) => SORT_COLUMN_OPTIONS.includes(column.type), [VIEW_TYPE.KANBAN]: (column) => SORT_COLUMN_OPTIONS.includes(column.type),
[VIEW_TYPE.MAP]: () => {}, [VIEW_TYPE.MAP]: () => {},
}; };
@@ -84,6 +86,7 @@ export const VIEW_SORT_COLUMN_RULES = {
export const VIEW_FIRST_SORT_COLUMN_RULES = { export const VIEW_FIRST_SORT_COLUMN_RULES = {
[VIEW_TYPE.TABLE]: (column) => SORT_COLUMN_OPTIONS.includes(column.type), [VIEW_TYPE.TABLE]: (column) => SORT_COLUMN_OPTIONS.includes(column.type),
[VIEW_TYPE.GALLERY]: (column) => GALLERY_FIRST_SORT_COLUMN_OPTIONS.includes(column.type) || GALLERY_FIRST_SORT_PRIVATE_COLUMN_KEYS.includes(column.key), [VIEW_TYPE.GALLERY]: (column) => GALLERY_FIRST_SORT_COLUMN_OPTIONS.includes(column.type) || GALLERY_FIRST_SORT_PRIVATE_COLUMN_KEYS.includes(column.key),
[VIEW_TYPE.FACE_RECOGNITION]: () => {},
[VIEW_TYPE.KANBAN]: (column) => SORT_COLUMN_OPTIONS.includes(column.type), [VIEW_TYPE.KANBAN]: (column) => SORT_COLUMN_OPTIONS.includes(column.type),
[VIEW_TYPE.MAP]: () => {}, [VIEW_TYPE.MAP]: () => {},
}; };

View File

@@ -15,7 +15,6 @@ export const MetadataProvider = ({ repoID, currentPath, repoInfo, hideMetadataVi
const [isLoading, setLoading] = useState(true); const [isLoading, setLoading] = useState(true);
const [enableFaceRecognition, setEnableFaceRecognition] = useState(false); const [enableFaceRecognition, setEnableFaceRecognition] = useState(false);
const [navigation, setNavigation] = useState([]); const [navigation, setNavigation] = useState([]);
const [staticView, setStaticView] = useState([]);
const [, setCount] = useState(0); const [, setCount] = useState(0);
const viewsMap = useRef({}); const viewsMap = useRef({});
@@ -23,14 +22,6 @@ export const MetadataProvider = ({ repoID, currentPath, repoInfo, hideMetadataVi
const { enableMetadata, isBeingBuilt, setIsBeingBuilt } = useMetadataStatus(); const { enableMetadata, isBeingBuilt, setIsBeingBuilt } = useMetadataStatus();
const updateEnableFaceRecognition = useCallback((newValue) => {
if (newValue === enableFaceRecognition) return;
setEnableFaceRecognition(newValue);
if (newValue) {
toaster.success(gettext('Recognizing portraits. Please refresh the page later.'));
}
}, [enableFaceRecognition]);
// views // views
useEffect(() => { useEffect(() => {
setLoading(true); setLoading(true);
@@ -42,11 +33,6 @@ export const MetadataProvider = ({ repoID, currentPath, repoInfo, hideMetadataVi
viewsMap.current[view._id] = view; viewsMap.current[view._id] = view;
}); });
} }
viewsMap.current[FACE_RECOGNITION_VIEW_ID] = {
_id: FACE_RECOGNITION_VIEW_ID,
name: gettext('Photos - classified by people'),
type: VIEW_TYPE.FACE_RECOGNITION,
};
setNavigation(navigation); setNavigation(navigation);
setLoading(false); setLoading(false);
}).catch(error => { }).catch(error => {
@@ -59,7 +45,6 @@ export const MetadataProvider = ({ repoID, currentPath, repoInfo, hideMetadataVi
hideMetadataView && hideMetadataView(); hideMetadataView && hideMetadataView();
setEnableFaceRecognition(false); setEnableFaceRecognition(false);
viewsMap.current = {}; viewsMap.current = {};
setStaticView([]);
setNavigation([]); setNavigation([]);
setLoading(false); setLoading(false);
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -67,7 +52,6 @@ export const MetadataProvider = ({ repoID, currentPath, repoInfo, hideMetadataVi
useEffect(() => { useEffect(() => {
if (!enableMetadata) { if (!enableMetadata) {
setStaticView([]);
setEnableFaceRecognition(false); setEnableFaceRecognition(false);
return; return;
} }
@@ -79,14 +63,6 @@ export const MetadataProvider = ({ repoID, currentPath, repoInfo, hideMetadataVi
}); });
}, [repoID, enableMetadata]); }, [repoID, enableMetadata]);
useEffect(() => {
if (!enableFaceRecognition) {
setStaticView([]);
return;
}
setStaticView([{ _id: FACE_RECOGNITION_VIEW_ID, type: 'view' }]);
}, [enableFaceRecognition]);
const selectView = useCallback((view, isSelected) => { const selectView = useCallback((view, isSelected) => {
if (isSelected) return; if (isSelected) return;
const node = { const node = {
@@ -176,6 +152,24 @@ export const MetadataProvider = ({ repoID, currentPath, repoInfo, hideMetadataVi
}); });
}, [repoID]); }, [repoID]);
const updateEnableFaceRecognition = useCallback((newValue) => {
if (newValue === enableFaceRecognition) return;
if (newValue) {
toaster.success(gettext('Recognizing portraits. Please refresh the page later.'));
addView(gettext('Photos - classified by people'), VIEW_TYPE.FACE_RECOGNITION, () => {}, () => {});
} else {
if (viewsMap.current[FACE_RECOGNITION_VIEW_ID]) {
let isSelected = false;
if (currentPath.includes('/' + PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES + '/')) {
const currentViewId = currentPath.split('/').pop();
isSelected = currentViewId === FACE_RECOGNITION_VIEW_ID;
}
deleteView(FACE_RECOGNITION_VIEW_ID, isSelected);
}
}
setEnableFaceRecognition(newValue);
}, [enableFaceRecognition, currentPath, addView, deleteView]);
useEffect(() => { useEffect(() => {
if (isLoading) return; if (isLoading) return;
if (isBeingBuilt) { if (isBeingBuilt) {
@@ -228,7 +222,6 @@ export const MetadataProvider = ({ repoID, currentPath, repoInfo, hideMetadataVi
isBeingBuilt, isBeingBuilt,
setIsBeingBuilt, setIsBeingBuilt,
navigation, navigation,
staticView,
viewsMap: viewsMap.current, viewsMap: viewsMap.current,
selectView, selectView,
addView, addView,

View File

@@ -22,9 +22,7 @@ const MetadataTreeView = ({ userPerm, currentPath }) => {
}, [userPerm]); }, [userPerm]);
const [, setState] = useState(0); const [, setState] = useState(0);
const { const {
enableFaceRecognition,
navigation, navigation,
staticView,
viewsMap, viewsMap,
selectView, selectView,
addView, addView,
@@ -136,20 +134,6 @@ const MetadataTreeView = ({ userPerm, currentPath }) => {
/> />
</div> </div>
)} )}
{enableFaceRecognition && staticView.map((item) => {
const view = viewsMap[item._id];
const viewPath = '/' + PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES + '/' + view._id;
const isSelected = currentPath === viewPath;
return (
<ViewItem
key={view._id}
userPerm="r"
view={view}
isSelected={isSelected}
onClick={(view) => selectView(view, isSelected)}
/>
);
})}
{canAdd && ( {canAdd && (
<div id="sf-metadata-view-popover"> <div id="sf-metadata-view-popover">
<CustomizeAddTool <CustomizeAddTool

View File

@@ -7,7 +7,7 @@ import Icon from '../../../components/icon';
import ItemDropdownMenu from '../../../components/dropdown-menu/item-dropdown-menu'; import ItemDropdownMenu from '../../../components/dropdown-menu/item-dropdown-menu';
import { Utils, isMobile } from '../../../utils/utils'; import { Utils, isMobile } from '../../../utils/utils';
import { useMetadata } from '../../hooks'; import { useMetadata } from '../../hooks';
import { VIEW_TYPE_ICON } from '../../constants'; import { FACE_RECOGNITION_VIEW_ID, VIEW_TYPE_ICON } from '../../constants';
import { isValidViewName } from '../../utils/validate'; import { isValidViewName } from '../../utils/validate';
import { isEnter } from '../../utils/hotkey'; import { isEnter } from '../../utils/hotkey';
import toaster from '../../../components/toast'; import toaster from '../../../components/toast';
@@ -49,6 +49,11 @@ const ViewItem = ({
const operations = useMemo(() => { const operations = useMemo(() => {
if (!canUpdate) return []; if (!canUpdate) return [];
if (view._id === FACE_RECOGNITION_VIEW_ID) {
return [
{ key: 'rename', value: gettext('Rename') },
];
}
let value = [ let value = [
{ key: 'rename', value: gettext('Rename') }, { key: 'rename', value: gettext('Rename') },
{ key: 'duplicate', value: gettext('Duplicate') } { key: 'duplicate', value: gettext('Duplicate') }
@@ -57,7 +62,7 @@ const ViewItem = ({
value.push({ key: 'delete', value: gettext('Delete') }); value.push({ key: 'delete', value: gettext('Delete') });
} }
return value; return value;
}, [canUpdate, canDelete]); }, [view, canUpdate, canDelete]);
const onMouseEnter = useCallback(() => { const onMouseEnter = useCallback(() => {
if (freeze) return; if (freeze) return;

View File

@@ -17,7 +17,10 @@ def generate_random_string_lower_digits(length):
return random_string return random_string
def generate_view_id(length, view_ids=None): def generate_view_id(length, type, view_ids=None):
if type == 'face_recognition':
return '_face_recognition'
if not view_ids: if not view_ids:
return generate_random_string_lower_digits(length) return generate_random_string_lower_digits(length)
@@ -81,7 +84,7 @@ class RepoView(object):
def init_view(self, view_ids=None): def init_view(self, view_ids=None):
self.view_json = { self.view_json = {
"_id": generate_view_id(4, view_ids), "_id": generate_view_id(4, self.type, view_ids),
"table_id": '0001', # by default "table_id": '0001', # by default
"name": self.name, "name": self.name,
"filters": [], "filters": [],