|
import { |
|
Button, |
|
CompositeNumberInput, |
|
Flex, |
|
FormControl, |
|
Popover, |
|
PopoverArrow, |
|
PopoverBody, |
|
PopoverContent, |
|
PopoverTrigger, |
|
useDisclosure, |
|
} from '@invoke-ai/ui-library'; |
|
import { useGalleryPagination } from 'features/gallery/hooks/useGalleryPagination'; |
|
import { memo, useCallback, useEffect, useRef, useState } from 'react'; |
|
import { useHotkeys } from 'react-hotkeys-hook'; |
|
import { useTranslation } from 'react-i18next'; |
|
|
|
export const JumpTo = memo(() => { |
|
const { t } = useTranslation(); |
|
const { goToPage, currentPage, pages } = useGalleryPagination(); |
|
const [newPage, setNewPage] = useState(currentPage); |
|
const { isOpen, onToggle, onClose } = useDisclosure(); |
|
const ref = useRef<HTMLInputElement>(null); |
|
|
|
const onOpen = useCallback(() => { |
|
setNewPage(currentPage); |
|
setTimeout(() => { |
|
const input = ref.current?.querySelector('input'); |
|
input?.focus(); |
|
input?.select(); |
|
}, 0); |
|
}, [currentPage]); |
|
|
|
const onChangeJumpTo = useCallback((v: number) => { |
|
setNewPage(v - 1); |
|
}, []); |
|
|
|
const onClickGo = useCallback(() => { |
|
goToPage(newPage); |
|
onClose(); |
|
}, [newPage, goToPage, onClose]); |
|
|
|
useHotkeys( |
|
'enter', |
|
() => { |
|
onClickGo(); |
|
}, |
|
{ enabled: isOpen, enableOnFormTags: ['input'] }, |
|
[isOpen, onClickGo] |
|
); |
|
|
|
useHotkeys( |
|
'esc', |
|
() => { |
|
setNewPage(currentPage); |
|
onClose(); |
|
}, |
|
{ enabled: isOpen, enableOnFormTags: ['input'] }, |
|
[isOpen, onClose] |
|
); |
|
|
|
useEffect(() => { |
|
setNewPage(currentPage); |
|
}, [currentPage]); |
|
|
|
return ( |
|
<Popover isOpen={isOpen} onClose={onClose} onOpen={onOpen} isLazy lazyBehavior="unmount"> |
|
<PopoverTrigger> |
|
<Button aria-label={t('gallery.jump')} size="sm" onClick={onToggle} variant="outline"> |
|
{t('gallery.jump')} |
|
</Button> |
|
</PopoverTrigger> |
|
<PopoverContent> |
|
<PopoverArrow /> |
|
<PopoverBody> |
|
<Flex gap={2} alignItems="center"> |
|
<FormControl> |
|
<CompositeNumberInput |
|
ref={ref} |
|
size="sm" |
|
maxW="60px" |
|
value={newPage + 1} |
|
min={1} |
|
max={pages} |
|
step={1} |
|
onChange={onChangeJumpTo} |
|
/> |
|
</FormControl> |
|
<Button h="full" size="sm" onClick={onClickGo}> |
|
{t('gallery.go')} |
|
</Button> |
|
</Flex> |
|
</PopoverBody> |
|
</PopoverContent> |
|
</Popover> |
|
); |
|
}); |
|
|
|
JumpTo.displayName = 'JumpTo'; |
|
|