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

fix: face ui (#6994)

* fix: face ui

* feat: optimize code

* feat: optimize code

---------

Co-authored-by: 杨国璇 <ygx@192.168.1.8>
Co-authored-by: 杨国璇 <ygx@Hello-word.local>
This commit is contained in:
杨国璇
2024-11-06 11:48:54 +08:00
committed by GitHub
parent cc625f7815
commit 770192ebda
4 changed files with 39 additions and 58 deletions

View File

@@ -126,7 +126,6 @@ export const MetadataProvider = ({ repoID, currentRepoInfo, hideMetadataView, se
const selectView = useCallback((view, isSelected) => { const selectView = useCallback((view, isSelected) => {
if (isSelected) return; if (isSelected) return;
const isFaceRecognitionView = view.type === PRIVATE_FILE_TYPE.FACE_RECOGNITION;
const node = { const node = {
children: [], children: [],
path: '/' + PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES + '/' + view._id, path: '/' + PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES + '/' + view._id,
@@ -135,9 +134,8 @@ export const MetadataProvider = ({ repoID, currentRepoInfo, hideMetadataView, se
isPreload: true, isPreload: true,
object: { object: {
file_tags: [], file_tags: [],
id: isFaceRecognitionView ? PRIVATE_FILE_TYPE.FACE_RECOGNITION : PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES, id: view._id,
name: isFaceRecognitionView ? gettext('Photos - classfied by people') : gettext('File extended properties'), type: PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES,
type: isFaceRecognitionView ? PRIVATE_FILE_TYPE.FACE_RECOGNITION : PRIVATE_FILE_TYPE.FILE_EXTENDED_PROPERTIES,
isDir: () => false, isDir: () => false,
}, },
parentNode: {}, parentNode: {},

View File

@@ -3,6 +3,7 @@
width: 48%; width: 48%;
flex-shrink: 0; flex-shrink: 0;
overflow: visible; overflow: visible;
border-radius: 3px;
} }
.sf-metadata-peoples-container .sf-metadata-people-info:hover { .sf-metadata-peoples-container .sf-metadata-people-info:hover {
@@ -28,7 +29,6 @@
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: space-between;
padding: 6px 0; padding: 6px 0;
overflow: hidden;
} }
.sf-metadata-peoples-container .sf-metadata-people-info .sf-metadata-people-info-name { .sf-metadata-peoples-container .sf-metadata-people-info .sf-metadata-people-info-name {
@@ -43,7 +43,7 @@
white-space: nowrap; white-space: nowrap;
} }
.sf-metadata-peoples-container .sf-metadata-people-info .sf-metadata-people-info-renaming { .sf-metadata-peoples-container .sf-metadata-people-info .rename-container input {
box-sizing: border-box; box-sizing: border-box;
padding: 2px 3px; padding: 2px 3px;
width: 20rem; width: 20rem;
@@ -56,7 +56,7 @@
border: 1px solid #ccc; border: 1px solid #ccc;
} }
.sf-metadata-peoples-container .sf-metadata-people-info .sf-metadata-people-info-renaming:focus { .sf-metadata-peoples-container .sf-metadata-people-info .rename-container input {
border-color: #1991eb; border-color: #1991eb;
} }

View File

@@ -1,13 +1,11 @@
import React, { useCallback, useMemo, useState } from 'react'; import React, { useCallback, useMemo, useState } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Input } from 'reactstrap';
import classNames from 'classnames'; import classNames from 'classnames';
import isHotkey from 'is-hotkey';
import { gettext, siteRoot, thumbnailDefaultSize } from '../../../../../utils/constants'; import { gettext, siteRoot, thumbnailDefaultSize } from '../../../../../utils/constants';
import OpMenu from './op-menu'; import OpMenu from './op-menu';
import { isEnter } from '../../../../utils/hotkey';
import { Utils } from '../../../../../utils/utils'; import { Utils } from '../../../../../utils/utils';
import { getFileNameFromRecord, getParentDirFromRecord } from '../../../../utils/cell'; import { getFileNameFromRecord, getParentDirFromRecord } from '../../../../utils/cell';
import Rename from '../../../../../components/rename';
import './index.css'; import './index.css';
@@ -27,7 +25,8 @@ const People = ({ haveFreezed, people, onOpenPeople, onRename, onFreezed, onUnFr
return Array.isArray(people._photo_links) ? people._photo_links.length : 0; return Array.isArray(people._photo_links) ? people._photo_links.length : 0;
}, [people._photo_links]); }, [people._photo_links]);
const [name, setName] = useState(people._name || gettext('Person image')); const name = useMemo(() => people._name || gettext('Person image'), [people._name]);
const [renaming, setRenaming] = useState(false); const [renaming, setRenaming] = useState(false);
const [active, setActive] = useState(false); const [active, setActive] = useState(false);
const readonly = !window.sfMetadataContext.canModify(); const readonly = !window.sfMetadataContext.canModify();
@@ -47,37 +46,29 @@ const People = ({ haveFreezed, people, onOpenPeople, onRename, onFreezed, onUnFr
setRenaming(true); setRenaming(true);
}, [onFreezed]); }, [onFreezed]);
const onBlur = useCallback(() => { const onRenameConfirm = useCallback((newName) => {
if (!name) return; if (newName !== name) {
setRenaming(false);
if (name !== (people._name || gettext('Person image'))) {
onUnFreezed(); onUnFreezed();
onRename(people._id, name, people._name); onRename(people._id, newName, name);
} }
setRenaming(false);
}, [people, name, onRename, onUnFreezed]); }, [people, name, onRename, onUnFreezed]);
const onChange = useCallback((event) => { const onRenameCancel = useCallback(() => {
const value = event.target.value;
if (value === name) return;
setName(value);
}, [name]);
const onKeyDown = useCallback((event) => {
if (isEnter(event)) {
onBlur();
return;
} else if (isHotkey('esc', event)) {
setName(people.name);
setRenaming(false);
return;
}
}, [people, onBlur]);
const _onUnFreezed = useCallback(() => {
onUnFreezed(); onUnFreezed();
setActive(false); setRenaming(false);
}, [onUnFreezed]); }, [onUnFreezed]);
const handelUnFreezed = useCallback((keepActive) => {
onUnFreezed();
!keepActive && setActive(false);
}, [onUnFreezed]);
const handelClick = useCallback(() => {
if (renaming) return;
setTimeout(() => onOpenPeople(people), 1);
}, [renaming, people, onOpenPeople]);
return ( return (
<div <div
className={classNames('sf-metadata-people-info px-3 d-flex justify-content-between align-items-center', { className={classNames('sf-metadata-people-info px-3 d-flex justify-content-between align-items-center', {
@@ -85,15 +76,15 @@ const People = ({ haveFreezed, people, onOpenPeople, onRename, onFreezed, onUnFr
})} })}
onMouseEnter={onMouseEnter} onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave} onMouseLeave={onMouseLeave}
onDoubleClick={haveFreezed ? () => {} : () => onOpenPeople(people)} onClick={handelClick}
> >
<div className="sf-metadata-people-info-img mr-2"> <div className="sf-metadata-people-info-img mr-2">
<img src={similarPhotoURL} alt={name} height={36} width={36} /> <img src={similarPhotoURL} alt={name} height={36} width={36} />
</div> </div>
<div className="sf-metadata-people-info-name-count"> <div className={classNames('sf-metadata-people-info-name-count', { 'o-hidden': !renaming })}>
<div className="sf-metadata-people-info-name"> <div className="sf-metadata-people-info-name">
{renaming ? ( {renaming ? (
<Input className="sf-metadata-people-info-renaming" autoFocus value={name} onChange={onChange} onBlur={onBlur} onKeyDown={onKeyDown} /> <Rename name={name} onRenameConfirm={onRenameConfirm} onRenameCancel={onRenameCancel} />
) : ( ) : (
<div className="sf-metadata-people-info-name-display">{name}</div> <div className="sf-metadata-people-info-name-display">{name}</div>
)} )}
@@ -104,8 +95,8 @@ const People = ({ haveFreezed, people, onOpenPeople, onRename, onFreezed, onUnFr
</div> </div>
{!readonly && people._is_someone && ( {!readonly && people._is_someone && (
<div className="sf-metadata-people-info-op"> <div className="sf-metadata-people-info-op">
{active && ( {active && !renaming && (
<OpMenu onRename={setRenamingState} onFreezed={onFreezed} onUnFreezed={_onUnFreezed} /> <OpMenu onRename={setRenamingState} onFreezed={onFreezed} onUnFreezed={handelUnFreezed} />
)} )}
</div> </div>
)} )}

View File

@@ -7,27 +7,20 @@ const OpMenu = ({ onRename, onFreezed, onUnFreezed }) => {
let [isShow, setShow] = useState(false); let [isShow, setShow] = useState(false);
const toggle = useCallback((event) => { const toggle = useCallback((event) => {
const dataset = event.target ? event.target.dataset : null; event.stopPropagation();
if (dataset && dataset.toggle && dataset.toggle === 'rename') {
onRename();
setShow(!isShow);
return;
}
if (isShow) { if (isShow) {
onUnFreezed(); const isClickToggleBtn = event.target.className?.includes('face-recognition-more-operations-toggle');
onUnFreezed(isClickToggleBtn);
} else { } else {
onFreezed(); onFreezed();
} }
setShow(!isShow); setShow(!isShow);
}, [isShow, onRename, onFreezed, onUnFreezed, setShow]); }, [isShow, onFreezed, onUnFreezed, setShow]);
const onClick = useCallback((event) => { const handleRename = useCallback(() => {
toggle(event); onRename();
}, [toggle]); setShow(false);
}, [onRename, setShow]);
const onItemClick = useCallback((event) => {
toggle(event);
}, [toggle]);
useEffect(() => { useEffect(() => {
return () => { return () => {
@@ -42,14 +35,13 @@ const OpMenu = ({ onRename, onFreezed, onUnFreezed }) => {
tag="i" tag="i"
role="button" role="button"
tabIndex="0" tabIndex="0"
className="sf-dropdown-toggle sf3-font-more sf3-font" className="sf-dropdown-toggle sf3-font-more sf3-font face-recognition-more-operations-toggle"
title={gettext('More operations')} title={gettext('More operations')}
aria-label={gettext('More operations')} aria-label={gettext('More operations')}
onClick={onClick}
data-toggle="dropdown" data-toggle="dropdown"
/> />
<DropdownMenu> <DropdownMenu>
<DropdownItem data-toggle="rename" onClick={onItemClick}>{gettext('Rename')}</DropdownItem> <DropdownItem onClick={handleRename}>{gettext('Rename')}</DropdownItem>
</DropdownMenu> </DropdownMenu>
</Dropdown> </Dropdown>
); );