mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-26 07:22:34 +00:00
Face recognition top toolbar (#8180)
* [metadata] 'face recognition' view: add a top toolbar for the selected photo(s) * [metadata] 'face recognition' view: update for 'add photos to group' * [metadata] 'face recognition' view: update for the top toolbar
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import ItemDropdownMenu from '../dropdown-menu/item-dropdown-menu';
|
||||
import { gettext } from '../../utils/constants';
|
||||
import { EVENT_BUS_TYPE, GALLERY_OPERATION_KEYS } from '../../metadata/constants';
|
||||
import { useFileOperations } from '../../hooks/file-operations';
|
||||
|
||||
const FaceRecognitionFilesToolbar = () => {
|
||||
const [selectedRecordIds, setSelectedRecordIds] = useState([]);
|
||||
const [selectedRecords, setSelectedRecords] = useState([]);
|
||||
const [isSomeone, setIsSomeone] = useState(false);
|
||||
const menuRef = useRef(null);
|
||||
const { handleDownload: handleDownloadAPI } = useFileOperations();
|
||||
const eventBus = window.sfMetadataContext && window.sfMetadataContext.eventBus;
|
||||
|
||||
const checkCanDeleteRow = window.sfMetadataContext.checkCanDeleteRow();
|
||||
const canRemovePhotoFromPeople = window.sfMetadataContext.canRemovePhotoFromPeople();
|
||||
const canAddPhotoToPeople = window.sfMetadataContext.canAddPhotoToPeople();
|
||||
const canSetPeoplePhoto = window.sfMetadataContext.canSetPeoplePhoto();
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribeSelectedFileIds = eventBus && eventBus.subscribe(EVENT_BUS_TYPE.SELECT_RECORDS, (ids, metadata, selectedRecords, isSomeone) => {
|
||||
setSelectedRecordIds(ids);
|
||||
setSelectedRecords(selectedRecords);
|
||||
setIsSomeone(isSomeone);
|
||||
});
|
||||
|
||||
return () => {
|
||||
unsubscribeSelectedFileIds && unsubscribeSelectedFileIds();
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const unSelect = useCallback(() => {
|
||||
setSelectedRecordIds([]);
|
||||
eventBus && eventBus.dispatch(EVENT_BUS_TYPE.UPDATE_SELECTED_RECORD_IDS, []);
|
||||
eventBus.dispatch(EVENT_BUS_TYPE.SELECT_NONE);
|
||||
}, [eventBus]);
|
||||
|
||||
const handleDownload = useCallback(() => {
|
||||
const list = selectedRecords.map(record => {
|
||||
const { parentDir, name: fileName } = record || {};
|
||||
const name = parentDir === '/' ? fileName : `${parentDir}/${fileName}`;
|
||||
return { name };
|
||||
});
|
||||
handleDownloadAPI('/', list);
|
||||
}, [selectedRecords, handleDownloadAPI]);
|
||||
|
||||
const deleteRecords = useCallback(() => {
|
||||
eventBus && eventBus.dispatch(EVENT_BUS_TYPE.DELETE_FACE_RECOGNITION_RECORDS, selectedRecords, {
|
||||
success_callback: () => {
|
||||
eventBus.dispatch(EVENT_BUS_TYPE.SELECT_NONE);
|
||||
}
|
||||
});
|
||||
}, [eventBus, selectedRecords]);
|
||||
|
||||
const opList = useMemo(() => {
|
||||
const list = [];
|
||||
if (isSomeone && canRemovePhotoFromPeople) {
|
||||
list.push({
|
||||
key: GALLERY_OPERATION_KEYS.REMOVE_PHOTO_FROM_CURRENT_SET,
|
||||
value: gettext('Remove from this group')
|
||||
});
|
||||
}
|
||||
if (!isSomeone && canAddPhotoToPeople) {
|
||||
list.push({
|
||||
key: GALLERY_OPERATION_KEYS.ADD_PHOTO_TO_GROUPS,
|
||||
value: gettext('Add to groups')
|
||||
});
|
||||
}
|
||||
if (canSetPeoplePhoto && selectedRecordIds.length == 1) {
|
||||
list.push({
|
||||
key: GALLERY_OPERATION_KEYS.SET_PHOTO_AS_COVER,
|
||||
value: gettext('Set as cover photo')
|
||||
});
|
||||
}
|
||||
return list;
|
||||
}, [isSomeone, selectedRecordIds, canRemovePhotoFromPeople, canAddPhotoToPeople, canSetPeoplePhoto]);
|
||||
|
||||
const getMenuList = useCallback(() => {
|
||||
return opList;
|
||||
}, [opList]);
|
||||
|
||||
const onMenuItemClick = useCallback((operation) => {
|
||||
switch (operation) {
|
||||
case GALLERY_OPERATION_KEYS.REMOVE_PHOTO_FROM_CURRENT_SET:
|
||||
eventBus && eventBus.dispatch(EVENT_BUS_TYPE.REMOVE_PHOTOS_FROM_CURRENT_SET, selectedRecords);
|
||||
break;
|
||||
case GALLERY_OPERATION_KEYS.ADD_PHOTO_TO_GROUPS:
|
||||
eventBus && eventBus.dispatch(EVENT_BUS_TYPE.ADD_PHOTO_TO_GROUPS);
|
||||
break;
|
||||
case GALLERY_OPERATION_KEYS.SET_PHOTO_AS_COVER:
|
||||
eventBus && eventBus.dispatch(EVENT_BUS_TYPE.SET_PHOTO_AS_COVER, selectedRecords[0]);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}, [eventBus, selectedRecords]);
|
||||
|
||||
const length = selectedRecordIds.length;
|
||||
return (
|
||||
<div className="selected-dirents-toolbar">
|
||||
<span className="cur-view-path-btn px-2" onClick={unSelect}>
|
||||
<span className="sf3-font-x-01 sf3-font mr-2" aria-label={gettext('Unselect')} title={gettext('Unselect')}></span>
|
||||
<span>{length}{' '}{gettext('selected')}</span>
|
||||
</span>
|
||||
<span className="cur-view-path-btn" onClick={handleDownload}>
|
||||
<span className="sf3-font-download1 sf3-font" aria-label={gettext('Download')} title={gettext('Download')}></span>
|
||||
</span>
|
||||
{checkCanDeleteRow &&
|
||||
<span className="cur-view-path-btn" onClick={deleteRecords}>
|
||||
<span className="sf3-font-delete1 sf3-font" aria-label={gettext('Delete')} title={gettext('Delete')}></span>
|
||||
</span>
|
||||
}
|
||||
<ItemDropdownMenu
|
||||
ref={menuRef}
|
||||
item={{}}
|
||||
toggleClass="cur-view-path-btn sf3-font-more sf3-font"
|
||||
onMenuItemClick={onMenuItemClick}
|
||||
getMenuList={getMenuList}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default FaceRecognitionFilesToolbar;
|
@@ -8,6 +8,7 @@ import AllTagsToolbar from './all-tags-toolbar';
|
||||
import TagFilesToolbar from './tag-files-toolbar';
|
||||
import TableFilesToolbar from './table-files-toolbar';
|
||||
import GalleryFilesToolbar from './gallery-files-toolbar';
|
||||
import FaceRecognitionFilesToolbar from './face-recognition-files-toolbar';
|
||||
|
||||
const MetadataPathToolbar = ({ repoID, repoInfo, mode, path, viewId }) => {
|
||||
const { idViewMap } = useMetadata();
|
||||
@@ -20,6 +21,10 @@ const MetadataPathToolbar = ({ repoID, repoInfo, mode, path, viewId }) => {
|
||||
);
|
||||
}
|
||||
|
||||
if (type === VIEW_TYPE.FACE_RECOGNITION) {
|
||||
return <FaceRecognitionFilesToolbar />;
|
||||
}
|
||||
|
||||
if (type === VIEW_TYPE.TABLE) {
|
||||
return (
|
||||
<TableFilesToolbar repoID={repoID} />
|
||||
|
@@ -85,6 +85,12 @@ export const EVENT_BUS_TYPE = {
|
||||
MODIFY_GALLERY_ZOOM_GEAR: 'modify_gallery_zoom_gear',
|
||||
SWITCH_GALLERY_GROUP_BY: 'switch_gallery_group_by',
|
||||
|
||||
// face recognition
|
||||
DELETE_FACE_RECOGNITION_RECORDS: 'delete_face_recognition_records',
|
||||
REMOVE_PHOTOS_FROM_CURRENT_SET: 'remove_photos_from_current_set',
|
||||
SET_PHOTO_AS_COVER: 'set_photo_as_cover',
|
||||
ADD_PHOTO_TO_GROUPS: 'add_photo_to_groups',
|
||||
|
||||
// kanban
|
||||
TOGGLE_KANBAN_SETTINGS: 'toggle_kanban_settings',
|
||||
OPEN_KANBAN_SETTINGS: 'open_kanban_settings',
|
||||
|
@@ -22,8 +22,8 @@ export const STORAGE_GALLERY_ZOOM_GEAR_KEY = 'gallery_zoom_gear';
|
||||
export const GALLERY_OPERATION_KEYS = {
|
||||
DOWNLOAD: 'download',
|
||||
DELETE: 'delete',
|
||||
DUPLICATE: 'duplicate',
|
||||
REMOVE: 'remove',
|
||||
SET_PEOPLE_PHOTO: 'set_people_photo',
|
||||
COPY: 'copy',
|
||||
REMOVE_PHOTO_FROM_CURRENT_SET: 'remove_photo_from_current_set',
|
||||
SET_PHOTO_AS_COVER: 'set_photo_as_cover',
|
||||
ADD_PHOTO_TO_GROUPS: 'add_photo_to_groups'
|
||||
};
|
||||
|
@@ -296,10 +296,14 @@ export const MetadataViewProvider = ({
|
||||
storeRef.current.updateFileTags(data);
|
||||
}, [storeRef, modifyLocalFileTags]);
|
||||
|
||||
const updateSelectedRecordIds = useCallback((ids) => {
|
||||
const updateSelectedRecordIds = useCallback((ids, records, isSomeone) => {
|
||||
toggleShowDirentToolbar(ids.length > 0);
|
||||
setTimeout(() => {
|
||||
if (records != undefined) {
|
||||
window.sfMetadataContext && window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.SELECT_RECORDS, ids, metadata, records, isSomeone);
|
||||
} else {
|
||||
window.sfMetadataContext && window.sfMetadataContext.eventBus.dispatch(EVENT_BUS_TYPE.SELECT_RECORDS, ids, metadata);
|
||||
}
|
||||
}, 0);
|
||||
}, [metadata, toggleShowDirentToolbar]);
|
||||
|
||||
|
@@ -237,12 +237,14 @@ const PeoplePhotos = ({ view, people, onClose, onDeletePeoplePhotos, onAddPeople
|
||||
const eventBus = window?.sfMetadataContext?.eventBus;
|
||||
if (!eventBus) return;
|
||||
const unsubscribeViewChange = eventBus.subscribe(EVENT_BUS_TYPE.UPDATE_SERVER_VIEW, onViewChange);
|
||||
const unsubscribeDeleteRecords = eventBus.subscribe(EVENT_BUS_TYPE.DELETE_FACE_RECOGNITION_RECORDS, handleDelete);
|
||||
const localRecordChangedSubscribe = eventBus.subscribe(EVENT_BUS_TYPE.LOCAL_RECORD_CHANGED, onRecordChange);
|
||||
return () => {
|
||||
unsubscribeViewChange && unsubscribeViewChange();
|
||||
unsubscribeDeleteRecords && unsubscribeDeleteRecords();
|
||||
localRecordChangedSubscribe && localRecordChangedSubscribe();
|
||||
};
|
||||
}, [onViewChange, onRecordChange]);
|
||||
}, [onViewChange, handleDelete, onRecordChange]);
|
||||
|
||||
if (isLoading) return (<CenteredLoading />);
|
||||
|
||||
@@ -256,6 +258,7 @@ const PeoplePhotos = ({ view, people, onClose, onDeletePeoplePhotos, onAddPeople
|
||||
onRemoveImage={people._is_someone ? handleRemove : null}
|
||||
onAddImage={!people._is_someone ? handleAdd : null}
|
||||
onSetPeoplePhoto={handleSetPeoplePhoto}
|
||||
isSomeone={people._is_someone}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@@ -1,16 +1,12 @@
|
||||
import React, { useMemo, useCallback, useState } from 'react';
|
||||
import React, { useMemo, useCallback } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import ContextMenu from '../../../components/context-menu';
|
||||
import ModalPortal from '../../../../components/modal-portal';
|
||||
import PeoplesDialog from '../../../components/dialog/peoples-dialog';
|
||||
import { gettext } from '../../../../utils/constants';
|
||||
import { Dirent } from '../../../../models';
|
||||
import { useFileOperations } from '../../../../hooks/file-operations';
|
||||
import { GALLERY_OPERATION_KEYS } from '../../../constants';
|
||||
|
||||
const GalleryContextMenu = ({ selectedImages, onDelete, onDuplicate, onRemoveImage, onAddImage, onSetPeoplePhoto }) => {
|
||||
const [isPeoplesDialogShow, setPeoplesDialogShow] = useState(false);
|
||||
|
||||
const { handleDownload: handleDownloadAPI, handleCopy: handleCopyAPI } = useFileOperations();
|
||||
|
||||
const checkCanDeleteRow = window.sfMetadataContext.checkCanDeleteRow();
|
||||
@@ -22,22 +18,39 @@ const GalleryContextMenu = ({ selectedImages, onDelete, onDuplicate, onRemoveIma
|
||||
const options = useMemo(() => {
|
||||
let validOptions = [{ value: GALLERY_OPERATION_KEYS.DOWNLOAD, label: gettext('Download') }];
|
||||
if (onDelete && checkCanDeleteRow) {
|
||||
validOptions.push({ value: GALLERY_OPERATION_KEYS.DELETE, label: gettext('Delete') });
|
||||
validOptions.push({
|
||||
value: GALLERY_OPERATION_KEYS.DELETE,
|
||||
label: gettext('Delete')
|
||||
});
|
||||
}
|
||||
if (onDuplicate && canDuplicateRow && selectedImages.length === 1) {
|
||||
validOptions.push({ value: GALLERY_OPERATION_KEYS.DUPLICATE, label: gettext('Copy') });
|
||||
validOptions.push({
|
||||
value: GALLERY_OPERATION_KEYS.COPY,
|
||||
label: gettext('Copy')
|
||||
});
|
||||
}
|
||||
if (onRemoveImage && canRemovePhotoFromPeople) {
|
||||
validOptions.push({ value: GALLERY_OPERATION_KEYS.REMOVE, label: gettext('Remove from this group') });
|
||||
validOptions.push({
|
||||
value: GALLERY_OPERATION_KEYS.REMOVE_PHOTO_FROM_CURRENT_SET,
|
||||
label: gettext('Remove from this group')
|
||||
});
|
||||
}
|
||||
if (onAddImage && canAddPhotoToPeople) {
|
||||
validOptions.push({ value: GALLERY_OPERATION_KEYS.ADD_PHOTO_TO_GROUPS, label: gettext('Add to groups') });
|
||||
validOptions.push({
|
||||
value: GALLERY_OPERATION_KEYS.ADD_PHOTO_TO_GROUPS,
|
||||
label: gettext('Add to groups')
|
||||
});
|
||||
}
|
||||
if (onSetPeoplePhoto && canSetPeoplePhoto) {
|
||||
validOptions.push({ value: GALLERY_OPERATION_KEYS.SET_PEOPLE_PHOTO, label: gettext('Set as cover photo') });
|
||||
if (onSetPeoplePhoto && canSetPeoplePhoto && selectedImages.length === 1) {
|
||||
validOptions.push({
|
||||
value: GALLERY_OPERATION_KEYS.SET_PHOTO_AS_COVER,
|
||||
label: gettext('Set as cover photo')
|
||||
});
|
||||
}
|
||||
return validOptions;
|
||||
}, [checkCanDeleteRow, canDuplicateRow, canRemovePhotoFromPeople, canAddPhotoToPeople, selectedImages, onDuplicate, onDelete, onRemoveImage, onAddImage, canSetPeoplePhoto, onSetPeoplePhoto]);
|
||||
}, [checkCanDeleteRow, canDuplicateRow, canRemovePhotoFromPeople,
|
||||
canAddPhotoToPeople, selectedImages, onDuplicate, onDelete,
|
||||
onRemoveImage, onAddImage, canSetPeoplePhoto, onSetPeoplePhoto]);
|
||||
|
||||
const handleDuplicate = useCallback((destRepo, dirent, destPath, nodeParentPath, isByDialog) => {
|
||||
const selectedImage = selectedImages[0];
|
||||
@@ -68,44 +81,29 @@ const GalleryContextMenu = ({ selectedImages, onDelete, onDuplicate, onRemoveIma
|
||||
case GALLERY_OPERATION_KEYS.DELETE:
|
||||
onDelete(selectedImages);
|
||||
break;
|
||||
case GALLERY_OPERATION_KEYS.DUPLICATE:
|
||||
case GALLERY_OPERATION_KEYS.COPY:
|
||||
handleCopy();
|
||||
break;
|
||||
case GALLERY_OPERATION_KEYS.REMOVE:
|
||||
case GALLERY_OPERATION_KEYS.REMOVE_PHOTO_FROM_CURRENT_SET:
|
||||
onRemoveImage(selectedImages);
|
||||
break;
|
||||
case GALLERY_OPERATION_KEYS.ADD_PHOTO_TO_GROUPS:
|
||||
setPeoplesDialogShow(true);
|
||||
onAddImage();
|
||||
break;
|
||||
case GALLERY_OPERATION_KEYS.SET_PEOPLE_PHOTO:
|
||||
case GALLERY_OPERATION_KEYS.SET_PHOTO_AS_COVER:
|
||||
onSetPeoplePhoto(selectedImages[0]);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}, [handleDownload, onDelete, selectedImages, handleCopy, onRemoveImage, onSetPeoplePhoto]);
|
||||
|
||||
const closePeoplesDialog = useCallback(() => {
|
||||
setPeoplesDialogShow(false);
|
||||
}, []);
|
||||
|
||||
const addPeople = useCallback((peopleIds, addedImages, callback) => {
|
||||
onAddImage(peopleIds, addedImages, callback);
|
||||
}, [onAddImage]);
|
||||
}, [handleDownload, onDelete, selectedImages, handleCopy, onRemoveImage, onAddImage, onSetPeoplePhoto]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<ContextMenu
|
||||
options={options}
|
||||
ignoredTriggerElements={['.metadata-gallery-image-item', '.metadata-gallery-grid-image']}
|
||||
onOptionClick={handleOptionClick}
|
||||
/>
|
||||
{isPeoplesDialogShow && (
|
||||
<ModalPortal>
|
||||
<PeoplesDialog selectedImages={selectedImages} onToggle={closePeoplesDialog} onSubmit={addPeople} />
|
||||
</ModalPortal>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
@@ -15,12 +15,13 @@ import { getEventClassName } from '../../../utils/dom';
|
||||
import { getColumns, getImageSize, getRowHeight } from './utils';
|
||||
import ObjectUtils from '../../../utils/object';
|
||||
import { openFile } from '../../utils/file';
|
||||
import PeoplesDialog from '../../components/dialog/peoples-dialog';
|
||||
|
||||
import './index.css';
|
||||
|
||||
const OVER_SCAN_ROWS = 20;
|
||||
|
||||
const Main = ({ isLoadingMore, metadata, onDelete, onLoadMore, duplicateRecord, onRemoveImage, onAddImage, onSetPeoplePhoto }) => {
|
||||
const Main = ({ isLoadingMore, metadata, onDelete, onLoadMore, duplicateRecord, onRemoveImage, onAddImage, onSetPeoplePhoto, isSomeone }) => {
|
||||
const [isFirstLoading, setFirstLoading] = useState(true);
|
||||
const [zoomGear, setZoomGear] = useState(0);
|
||||
const [containerWidth, setContainerWidth] = useState(0);
|
||||
@@ -30,6 +31,7 @@ const Main = ({ isLoadingMore, metadata, onDelete, onLoadMore, duplicateRecord,
|
||||
const [imageIndex, setImageIndex] = useState(0);
|
||||
const [selectedImages, setSelectedImages] = useState([]);
|
||||
const [lastSelectedImage, setLastSelectedImage] = useState(null);
|
||||
const [isPeoplesDialogShow, setPeoplesDialogShow] = useState(false);
|
||||
|
||||
const containerRef = useRef(null);
|
||||
const scrollContainer = useRef(null);
|
||||
@@ -193,8 +195,12 @@ const Main = ({ isLoadingMore, metadata, onDelete, onLoadMore, duplicateRecord,
|
||||
|
||||
const updateSelectedImages = useCallback((selectedImages) => {
|
||||
const ids = selectedImages.map(item => item.id);
|
||||
if (isSomeone != undefined) { // 'face recognition'
|
||||
updateSelectedRecordIds(ids, selectedImages, isSomeone);
|
||||
} else {
|
||||
updateSelectedRecordIds(ids);
|
||||
}, [updateSelectedRecordIds]);
|
||||
}
|
||||
}, [isSomeone, updateSelectedRecordIds]);
|
||||
|
||||
const handleClick = useCallback((event, image) => {
|
||||
if (event.metaKey || event.ctrlKey) {
|
||||
@@ -301,7 +307,22 @@ const Main = ({ isLoadingMore, metadata, onDelete, onLoadMore, duplicateRecord,
|
||||
});
|
||||
}, [onRemoveImage, updateCurrentDirent, updateSelectedImages]);
|
||||
|
||||
const handleMakeSelectedAsCoverPhoto = useCallback((selectedImage) => {
|
||||
const handleAddPhotoToGroup = useCallback((selectedImages) => {
|
||||
setPeoplesDialogShow(true);
|
||||
}, []);
|
||||
|
||||
const closePeoplesDialog = useCallback(() => {
|
||||
setPeoplesDialogShow(false);
|
||||
}, []);
|
||||
|
||||
const addPhotoToGroup = useCallback((peopleIds, addedImages, callback) => {
|
||||
onAddImage(peopleIds, addedImages, callback);
|
||||
updateCurrentDirent();
|
||||
setSelectedImages([]);
|
||||
updateSelectedImages([]);
|
||||
}, [onAddImage, updateCurrentDirent, updateSelectedImages]);
|
||||
|
||||
const setSelectedImageAsCover = useCallback((selectedImage) => {
|
||||
onSetPeoplePhoto(selectedImage, {
|
||||
success_callback: () => {
|
||||
updateCurrentDirent();
|
||||
@@ -409,11 +430,17 @@ const Main = ({ isLoadingMore, metadata, onDelete, onLoadMore, duplicateRecord,
|
||||
});
|
||||
|
||||
const unsubscribeSelectNone = window.sfMetadataContext.eventBus.subscribe(EVENT_BUS_TYPE.SELECT_NONE, selectNone);
|
||||
const unsubscribeRemovePhotosFromCurrentSet = window.sfMetadataContext.eventBus.subscribe(EVENT_BUS_TYPE.REMOVE_PHOTOS_FROM_CURRENT_SET, handleRemoveSelectedImages);
|
||||
const unsubscribeSetPhotoAsCover = window.sfMetadataContext.eventBus.subscribe(EVENT_BUS_TYPE.SET_PHOTO_AS_COVER, setSelectedImageAsCover);
|
||||
const unsubscribeAddPhotoToGroups = window.sfMetadataContext.eventBus.subscribe(EVENT_BUS_TYPE.ADD_PHOTO_TO_GROUPS, handleAddPhotoToGroup);
|
||||
|
||||
return () => {
|
||||
container && resizeObserver.unobserve(container);
|
||||
modifyGalleryZoomGearSubscribe();
|
||||
unsubscribeSelectNone();
|
||||
unsubscribeRemovePhotosFromCurrentSet();
|
||||
unsubscribeSetPhotoAsCover();
|
||||
unsubscribeAddPhotoToGroups();
|
||||
switchGalleryModeSubscribe();
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
@@ -481,8 +508,8 @@ const Main = ({ isLoadingMore, metadata, onDelete, onLoadMore, duplicateRecord,
|
||||
onDelete={handleDeleteSelectedImages}
|
||||
onDuplicate={duplicateRecord}
|
||||
onRemoveImage={onRemoveImage ? handleRemoveSelectedImages : null}
|
||||
onAddImage={onAddImage}
|
||||
onSetPeoplePhoto={handleMakeSelectedAsCoverPhoto}
|
||||
onAddImage={onAddImage ? handleAddPhotoToGroup : null}
|
||||
onSetPeoplePhoto={setSelectedImageAsCover}
|
||||
/>
|
||||
{isImagePopupOpen && (
|
||||
<ModalPortal>
|
||||
@@ -498,6 +525,11 @@ const Main = ({ isLoadingMore, metadata, onDelete, onLoadMore, duplicateRecord,
|
||||
/>
|
||||
</ModalPortal>
|
||||
)}
|
||||
{isPeoplesDialogShow && (
|
||||
<ModalPortal>
|
||||
<PeoplesDialog selectedImages={selectedImages} onToggle={closePeoplesDialog} onSubmit={addPhotoToGroup} />
|
||||
</ModalPortal>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@@ -2473,7 +2473,13 @@ class LibContentView extends React.Component {
|
||||
})}>
|
||||
{isDirentSelected ? (
|
||||
currentMode === TAGS_MODE || currentMode === METADATA_MODE ? (
|
||||
<MetadataPathToolbar repoID={repoID} repoInfo={currentRepoInfo} mode={currentMode} path={path} viewId={viewId} />
|
||||
<MetadataPathToolbar
|
||||
repoID={repoID}
|
||||
repoInfo={currentRepoInfo}
|
||||
mode={currentMode}
|
||||
path={path}
|
||||
viewId={viewId}
|
||||
/>
|
||||
) : (
|
||||
<SelectedDirentsToolbar
|
||||
repoID={this.props.repoID}
|
||||
|
Reference in New Issue
Block a user