mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): rename gallery boards on double click
This commit is contained in:
parent
48a57f0da8
commit
a7c44b4a98
@ -9,6 +9,7 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
useDisclosure,
|
useDisclosure,
|
||||||
|
useEditableControls,
|
||||||
} from '@invoke-ai/ui-library';
|
} from '@invoke-ai/ui-library';
|
||||||
import { skipToken } from '@reduxjs/toolkit/query';
|
import { skipToken } from '@reduxjs/toolkit/query';
|
||||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||||
@ -18,7 +19,8 @@ import { AutoAddBadge } from 'features/gallery/components/Boards/AutoAddBadge';
|
|||||||
import BoardContextMenu from 'features/gallery/components/Boards/BoardContextMenu';
|
import BoardContextMenu from 'features/gallery/components/Boards/BoardContextMenu';
|
||||||
import { BoardTotalsTooltip } from 'features/gallery/components/Boards/BoardsList/BoardTotalsTooltip';
|
import { BoardTotalsTooltip } from 'features/gallery/components/Boards/BoardsList/BoardTotalsTooltip';
|
||||||
import { autoAddBoardIdChanged, boardIdSelected } from 'features/gallery/store/gallerySlice';
|
import { autoAddBoardIdChanged, boardIdSelected } from 'features/gallery/store/gallerySlice';
|
||||||
import { memo, useCallback, useMemo, useState } from 'react';
|
import type { MouseEvent, MouseEventHandler, MutableRefObject } from 'react';
|
||||||
|
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { PiArchiveBold, PiImageSquare } from 'react-icons/pi';
|
import { PiArchiveBold, PiImageSquare } from 'react-icons/pi';
|
||||||
import { useUpdateBoardMutation } from 'services/api/endpoints/boards';
|
import { useUpdateBoardMutation } from 'services/api/endpoints/boards';
|
||||||
@ -49,15 +51,19 @@ const GalleryBoard = ({ board, isSelected, setBoardToDelete }: GalleryBoardProps
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const autoAddBoardId = useAppSelector((s) => s.gallery.autoAddBoardId);
|
const autoAddBoardId = useAppSelector((s) => s.gallery.autoAddBoardId);
|
||||||
const autoAssignBoardOnClick = useAppSelector((s) => s.gallery.autoAssignBoardOnClick);
|
const autoAssignBoardOnClick = useAppSelector((s) => s.gallery.autoAssignBoardOnClick);
|
||||||
|
const selectedBoardId = useAppSelector((s) => s.gallery.selectedBoardId);
|
||||||
const editingDisclosure = useDisclosure();
|
const editingDisclosure = useDisclosure();
|
||||||
const [localBoardName, setLocalBoardName] = useState(board.board_name);
|
const [localBoardName, setLocalBoardName] = useState(board.board_name);
|
||||||
|
const onStartEditingRef = useRef<MouseEventHandler | undefined>(undefined);
|
||||||
|
|
||||||
const handleSelectBoard = useCallback(() => {
|
const onClick = useCallback(() => {
|
||||||
|
if (selectedBoardId !== board.board_id) {
|
||||||
dispatch(boardIdSelected({ boardId: board.board_id }));
|
dispatch(boardIdSelected({ boardId: board.board_id }));
|
||||||
if (autoAssignBoardOnClick) {
|
}
|
||||||
|
if (autoAssignBoardOnClick && autoAddBoardId !== board.board_id) {
|
||||||
dispatch(autoAddBoardIdChanged(board.board_id));
|
dispatch(autoAddBoardIdChanged(board.board_id));
|
||||||
}
|
}
|
||||||
}, [dispatch, board.board_id, autoAssignBoardOnClick]);
|
}, [selectedBoardId, board.board_id, autoAssignBoardOnClick, autoAddBoardId, dispatch]);
|
||||||
|
|
||||||
const [updateBoard, { isLoading: isUpdateBoardLoading }] = useUpdateBoardMutation();
|
const [updateBoard, { isLoading: isUpdateBoardLoading }] = useUpdateBoardMutation();
|
||||||
|
|
||||||
@ -70,7 +76,7 @@ const GalleryBoard = ({ board, isSelected, setBoardToDelete }: GalleryBoardProps
|
|||||||
[board.board_id]
|
[board.board_id]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleSubmit = useCallback(
|
const onSubmit = useCallback(
|
||||||
async (newBoardName: string) => {
|
async (newBoardName: string) => {
|
||||||
if (!newBoardName.trim()) {
|
if (!newBoardName.trim()) {
|
||||||
// empty strings are not allowed
|
// empty strings are not allowed
|
||||||
@ -96,10 +102,16 @@ const GalleryBoard = ({ board, isSelected, setBoardToDelete }: GalleryBoardProps
|
|||||||
[board.board_id, board.board_name, editingDisclosure, updateBoard]
|
[board.board_id, board.board_name, editingDisclosure, updateBoard]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleChange = useCallback((newBoardName: string) => {
|
const onChange = useCallback((newBoardName: string) => {
|
||||||
setLocalBoardName(newBoardName);
|
setLocalBoardName(newBoardName);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const onDoubleClick = useCallback((e: MouseEvent<HTMLDivElement>) => {
|
||||||
|
if (onStartEditingRef.current) {
|
||||||
|
onStartEditingRef.current(e);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BoardContextMenu board={board} setBoardToDelete={setBoardToDelete}>
|
<BoardContextMenu board={board} setBoardToDelete={setBoardToDelete}>
|
||||||
{(ref) => (
|
{(ref) => (
|
||||||
@ -110,7 +122,8 @@ const GalleryBoard = ({ board, isSelected, setBoardToDelete }: GalleryBoardProps
|
|||||||
<Flex
|
<Flex
|
||||||
position="relative"
|
position="relative"
|
||||||
ref={ref}
|
ref={ref}
|
||||||
onClick={handleSelectBoard}
|
onClick={onClick}
|
||||||
|
onDoubleClick={onDoubleClick}
|
||||||
w="full"
|
w="full"
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
borderRadius="base"
|
borderRadius="base"
|
||||||
@ -131,10 +144,12 @@ const GalleryBoard = ({ board, isSelected, setBoardToDelete }: GalleryBoardProps
|
|||||||
value={localBoardName}
|
value={localBoardName}
|
||||||
isDisabled={isUpdateBoardLoading}
|
isDisabled={isUpdateBoardLoading}
|
||||||
submitOnBlur={true}
|
submitOnBlur={true}
|
||||||
onChange={handleChange}
|
onChange={onChange}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={onSubmit}
|
||||||
|
isPreviewFocusable={false}
|
||||||
>
|
>
|
||||||
<EditablePreview
|
<EditablePreview
|
||||||
|
cursor="pointer"
|
||||||
p={0}
|
p={0}
|
||||||
fontSize="md"
|
fontSize="md"
|
||||||
textOverflow="ellipsis"
|
textOverflow="ellipsis"
|
||||||
@ -145,6 +160,7 @@ const GalleryBoard = ({ board, isSelected, setBoardToDelete }: GalleryBoardProps
|
|||||||
fontWeight={isSelected ? 'semibold' : 'normal'}
|
fontWeight={isSelected ? 'semibold' : 'normal'}
|
||||||
/>
|
/>
|
||||||
<EditableInput sx={editableInputStyles} />
|
<EditableInput sx={editableInputStyles} />
|
||||||
|
<JankEditableHijack onStartEditingRef={onStartEditingRef} />
|
||||||
</Editable>
|
</Editable>
|
||||||
{autoAddBoardId === board.board_id && !editingDisclosure.isOpen && <AutoAddBadge />}
|
{autoAddBoardId === board.board_id && !editingDisclosure.isOpen && <AutoAddBadge />}
|
||||||
{board.archived && !editingDisclosure.isOpen && <Icon as={PiArchiveBold} fill="base.300" />}
|
{board.archived && !editingDisclosure.isOpen && <Icon as={PiArchiveBold} fill="base.300" />}
|
||||||
@ -158,6 +174,16 @@ const GalleryBoard = ({ board, isSelected, setBoardToDelete }: GalleryBoardProps
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const JankEditableHijack = memo((props: { onStartEditingRef: MutableRefObject<MouseEventHandler | undefined> }) => {
|
||||||
|
const editableControls = useEditableControls();
|
||||||
|
useEffect(() => {
|
||||||
|
props.onStartEditingRef.current = editableControls.getEditButtonProps().onClick;
|
||||||
|
}, [props, editableControls]);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
JankEditableHijack.displayName = 'JankEditableHijack';
|
||||||
|
|
||||||
export default memo(GalleryBoard);
|
export default memo(GalleryBoard);
|
||||||
|
|
||||||
const CoverImage = ({ board }: { board: BoardDTO }) => {
|
const CoverImage = ({ board }: { board: BoardDTO }) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user