From a294e8e0fd856a433eb5d9c8f1525a122eaeb315 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Mon, 23 Jun 2025 22:16:18 +1000 Subject: [PATCH] chore(ui): lint --- .../middleware/listenerMiddleware/index.ts | 6 -- .../listeners/imagesStarred.ts | 25 ------- .../listeners/imagesUnstarred.ts | 25 ------- .../ImageViewer/CurrentImageButtons.tsx | 2 +- .../ImageViewer/CurrentImagePreview.tsx | 2 +- .../ImageViewer/ImageViewerPanel.tsx | 73 +------------------ .../ToggleMetadataViewerButton.tsx | 2 +- .../components/ImageViewer/context.tsx | 70 ++++++++++++++++++ 8 files changed, 76 insertions(+), 129 deletions(-) delete mode 100644 invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imagesStarred.ts delete mode 100644 invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imagesUnstarred.ts create mode 100644 invokeai/frontend/web/src/features/gallery/components/ImageViewer/context.tsx diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/index.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/index.ts index aaf4c52c7a..856dc31ec7 100644 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/index.ts +++ b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/index.ts @@ -15,8 +15,6 @@ import { addGalleryOffsetChangedListener } from 'app/store/middleware/listenerMi import { addGetOpenAPISchemaListener } from 'app/store/middleware/listenerMiddleware/listeners/getOpenAPISchema'; import { addImageAddedToBoardFulfilledListener } from 'app/store/middleware/listenerMiddleware/listeners/imageAddedToBoard'; import { addImageRemovedFromBoardFulfilledListener } from 'app/store/middleware/listenerMiddleware/listeners/imageRemovedFromBoard'; -import { addImagesStarredListener } from 'app/store/middleware/listenerMiddleware/listeners/imagesStarred'; -import { addImagesUnstarredListener } from 'app/store/middleware/listenerMiddleware/listeners/imagesUnstarred'; import { addImageUploadedFulfilledListener } from 'app/store/middleware/listenerMiddleware/listeners/imageUploaded'; import { addModelSelectedListener } from 'app/store/middleware/listenerMiddleware/listeners/modelSelected'; import { addModelsLoadedListener } from 'app/store/middleware/listenerMiddleware/listeners/modelsLoaded'; @@ -47,10 +45,6 @@ addImageUploadedFulfilledListener(startAppListening); // Image deleted addDeleteBoardAndImagesFulfilledListener(startAppListening); -// Image starred -addImagesStarredListener(startAppListening); -addImagesUnstarredListener(startAppListening); - // Gallery addGalleryImageClickedListener(startAppListening); addGalleryOffsetChangedListener(startAppListening); diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imagesStarred.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imagesStarred.ts deleted file mode 100644 index f4d014b055..0000000000 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imagesStarred.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'; -import { imagesApi } from 'services/api/endpoints/images'; - -export const addImagesStarredListener = (startAppListening: AppStartListening) => { - startAppListening({ - matcher: imagesApi.endpoints.starImages.matchFulfilled, - effect: (action, { dispatch, getState }) => { - // const { updated_image_names: starredImages } = action.payload; - // const state = getState(); - // const { selection } = state.gallery; - // const updatedSelection: ImageDTO[] = []; - // selection.forEach((selectedImageDTO) => { - // if (starredImages.includes(selectedImageDTO.image_name)) { - // updatedSelection.push({ - // ...selectedImageDTO, - // starred: true, - // }); - // } else { - // updatedSelection.push(selectedImageDTO); - // } - // }); - // dispatch(selectionChanged(updatedSelection)); - }, - }); -}; diff --git a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imagesUnstarred.ts b/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imagesUnstarred.ts deleted file mode 100644 index 00aaf28e91..0000000000 --- a/invokeai/frontend/web/src/app/store/middleware/listenerMiddleware/listeners/imagesUnstarred.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type { AppStartListening } from 'app/store/middleware/listenerMiddleware'; -import { imagesApi } from 'services/api/endpoints/images'; - -export const addImagesUnstarredListener = (startAppListening: AppStartListening) => { - startAppListening({ - matcher: imagesApi.endpoints.unstarImages.matchFulfilled, - effect: (action, { dispatch, getState }) => { - // const { updated_image_names: unstarredImages } = action.payload; - // const state = getState(); - // const { selection } = state.gallery; - // const updatedSelection: ImageDTO[] = []; - // selection.forEach((selectedImageDTO) => { - // if (unstarredImages.includes(selectedImageDTO.image_name)) { - // updatedSelection.push({ - // ...selectedImageDTO, - // starred: false, - // }); - // } else { - // updatedSelection.push(selectedImageDTO); - // } - // }); - // dispatch(selectionChanged(updatedSelection)); - }, - }); -}; diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/CurrentImageButtons.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/CurrentImageButtons.tsx index ee2fe1e884..987b6cd911 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/CurrentImageButtons.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/CurrentImageButtons.tsx @@ -23,7 +23,7 @@ import { } from 'react-icons/pi'; import { useImageDTO } from 'services/api/endpoints/images'; -import { useImageViewerContext } from './ImageViewerPanel'; +import { useImageViewerContext } from './context'; export const CurrentImageButtons = memo(() => { const { t } = useTranslation(); diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/CurrentImagePreview.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/CurrentImagePreview.tsx index 652ebd9381..faa0bd91ad 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/CurrentImagePreview.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/CurrentImagePreview.tsx @@ -18,7 +18,7 @@ import { NoContentForViewer } from './NoContentForViewer'; import { ProgressImage } from './ProgressImage2'; import { ProgressIndicator } from './ProgressIndicator2'; -export const CurrentImagePreview = memo(({ imageDTO }: { imageDTO?: ImageDTO }) => { +export const CurrentImagePreview = memo(({ imageDTO }: { imageDTO: ImageDTO | null }) => { const shouldShowImageDetails = useAppSelector(selectShouldShowImageDetails); const shouldShowProgressInViewer = useAppSelector(selectShouldShowProgressInViewer); diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ImageViewerPanel.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ImageViewerPanel.tsx index bc7cda66b2..b15e19c9e1 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ImageViewerPanel.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ImageViewerPanel.tsx @@ -1,14 +1,9 @@ import { Divider, Flex } from '@invoke-ai/ui-library'; -import { useStore } from '@nanostores/react'; import { ImageViewer } from 'features/gallery/components/ImageViewer/ImageViewer'; import { ViewerToolbar } from 'features/gallery/components/ImageViewer/ViewerToolbar'; -import type { ProgressImage as ProgressImageType } from 'features/nodes/types/common'; -import { type Atom, atom, computed } from 'nanostores'; -import type { PropsWithChildren } from 'react'; -import { createContext, memo, useCallback, useContext, useEffect, useMemo, useState } from 'react'; -import type { ImageDTO, S } from 'services/api/types'; -import { $socket } from 'services/events/stores'; -import { assert } from 'tsafe'; +import { memo } from 'react'; + +import { ImageViewerContextProvider } from './context'; export const ImageViewerPanel = memo(() => { return ( @@ -22,65 +17,3 @@ export const ImageViewerPanel = memo(() => { ); }); ImageViewerPanel.displayName = 'ImageViewerPanel'; - -type ImageViewerContextValue = { - $progressEvent: Atom; - $progressImage: Atom; - $hasProgressImage: Atom; - onLoadImage: (imageDTO: ImageDTO) => void; -}; - -const ImageViewerContext = createContext(null); - -const ImageViewerContextProvider = memo((props: PropsWithChildren) => { - const socket = useStore($socket); - const $progressEvent = useState(() => atom(null))[0]; - const $progressImage = useState(() => atom(null))[0]; - const $hasProgressImage = useState(() => computed($progressImage, (progressImage) => progressImage !== null))[0]; - - useEffect(() => { - if (!socket) { - return; - } - - const onInvocationProgress = (data: S['InvocationProgressEvent']) => { - $progressEvent.set(data); - if (data.image) { - $progressImage.set(data.image); - } - }; - - socket.on('invocation_progress', onInvocationProgress); - - return () => { - socket.off('invocation_progress', onInvocationProgress); - }; - }, [$progressEvent, $progressImage, socket]); - - const onLoadImage = useCallback( - (imageDTO: ImageDTO) => { - const progressEvent = $progressEvent.get(); - if (!progressEvent || !imageDTO) { - return; - } - if (progressEvent.session_id === imageDTO.session_id) { - $progressImage.set(null); - } - }, - [$progressEvent, $progressImage] - ); - - const value = useMemo( - () => ({ $progressEvent, $progressImage, $hasProgressImage, onLoadImage }), - [$hasProgressImage, $progressEvent, $progressImage, onLoadImage] - ); - - return {props.children}; -}); -ImageViewerContextProvider.displayName = 'ImageViewerContextProvider'; - -export const useImageViewerContext = () => { - const value = useContext(ImageViewerContext); - assert(value !== null, 'useImageViewerContext must be used within a ImageViewerContextProvider'); - return value; -}; diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ToggleMetadataViewerButton.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ToggleMetadataViewerButton.tsx index 1824ca1353..983895e26e 100644 --- a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ToggleMetadataViewerButton.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/ToggleMetadataViewerButton.tsx @@ -9,7 +9,7 @@ import { memo, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { PiInfoBold } from 'react-icons/pi'; -import { useImageViewerContext } from './ImageViewerPanel'; +import { useImageViewerContext } from './context'; export const ToggleMetadataViewerButton = memo(() => { const dispatch = useAppDispatch(); diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/context.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/context.tsx new file mode 100644 index 0000000000..f664448bfe --- /dev/null +++ b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/context.tsx @@ -0,0 +1,70 @@ +import { useStore } from '@nanostores/react'; +import type { ProgressImage as ProgressImageType } from 'features/nodes/types/common'; +import { type Atom, atom, computed } from 'nanostores'; +import type { PropsWithChildren } from 'react'; +import { createContext, memo, useCallback, useContext, useEffect, useMemo, useState } from 'react'; +import type { ImageDTO, S } from 'services/api/types'; +import { $socket } from 'services/events/stores'; +import { assert } from 'tsafe'; + +type ImageViewerContextValue = { + $progressEvent: Atom; + $progressImage: Atom; + $hasProgressImage: Atom; + onLoadImage: (imageDTO: ImageDTO) => void; +}; + +const ImageViewerContext = createContext(null); + +export const ImageViewerContextProvider = memo((props: PropsWithChildren) => { + const socket = useStore($socket); + const $progressEvent = useState(() => atom(null))[0]; + const $progressImage = useState(() => atom(null))[0]; + const $hasProgressImage = useState(() => computed($progressImage, (progressImage) => progressImage !== null))[0]; + + useEffect(() => { + if (!socket) { + return; + } + + const onInvocationProgress = (data: S['InvocationProgressEvent']) => { + $progressEvent.set(data); + if (data.image) { + $progressImage.set(data.image); + } + }; + + socket.on('invocation_progress', onInvocationProgress); + + return () => { + socket.off('invocation_progress', onInvocationProgress); + }; + }, [$progressEvent, $progressImage, socket]); + + const onLoadImage = useCallback( + (imageDTO: ImageDTO) => { + const progressEvent = $progressEvent.get(); + if (!progressEvent || !imageDTO) { + return; + } + if (progressEvent.session_id === imageDTO.session_id) { + $progressImage.set(null); + } + }, + [$progressEvent, $progressImage] + ); + + const value = useMemo( + () => ({ $progressEvent, $progressImage, $hasProgressImage, onLoadImage }), + [$hasProgressImage, $progressEvent, $progressImage, onLoadImage] + ); + + return {props.children}; +}); +ImageViewerContextProvider.displayName = 'ImageViewerContextProvider'; + +export const useImageViewerContext = () => { + const value = useContext(ImageViewerContext); + assert(value !== null, 'useImageViewerContext must be used within a ImageViewerContextProvider'); + return value; +};