From 72ce2395925884c1d5e61debf7abb40424efd6f9 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Tue, 7 May 2024 08:06:19 +1000 Subject: [PATCH] revert(ui): remove floating viewer There are unresolved platform-specific issues with this component, and its utility is debatable. Should be easy to just revert this commit to add it back in the future if desired. --- invokeai/frontend/web/package.json | 1 - invokeai/frontend/web/pnpm-lock.yaml | 43 ---- .../frontend/web/src/app/components/App.tsx | 2 - .../ImageViewer/FloatingImageViewer.tsx | 190 ------------------ .../features/gallery/store/gallerySlice.ts | 5 - .../web/src/features/gallery/store/types.ts | 1 - .../src/features/ui/components/InvokeTabs.tsx | 2 - 7 files changed, 244 deletions(-) delete mode 100644 invokeai/frontend/web/src/features/gallery/components/ImageViewer/FloatingImageViewer.tsx diff --git a/invokeai/frontend/web/package.json b/invokeai/frontend/web/package.json index a598d0a2c7..78e8ca44ca 100644 --- a/invokeai/frontend/web/package.json +++ b/invokeai/frontend/web/package.json @@ -89,7 +89,6 @@ "react-konva": "^18.2.10", "react-redux": "9.1.2", "react-resizable-panels": "^2.0.19", - "react-rnd": "^10.4.10", "react-select": "5.8.0", "react-use": "^17.5.0", "react-virtuoso": "^4.7.10", diff --git a/invokeai/frontend/web/pnpm-lock.yaml b/invokeai/frontend/web/pnpm-lock.yaml index 2a3710ae9c..2703477200 100644 --- a/invokeai/frontend/web/pnpm-lock.yaml +++ b/invokeai/frontend/web/pnpm-lock.yaml @@ -122,9 +122,6 @@ dependencies: react-resizable-panels: specifier: ^2.0.19 version: 2.0.19(react-dom@18.3.1)(react@18.3.1) - react-rnd: - specifier: ^10.4.10 - version: 10.4.10(react-dom@18.3.1)(react@18.3.1) react-select: specifier: 5.8.0 version: 5.8.0(@types/react@18.3.1)(react-dom@18.3.1)(react@18.3.1) @@ -7208,11 +7205,6 @@ packages: requiresBuild: true dev: true - /clsx@1.2.1: - resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} - engines: {node: '>=6'} - dev: false - /color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} dependencies: @@ -10814,16 +10806,6 @@ packages: unpipe: 1.0.0 dev: true - /re-resizable@6.9.14(react-dom@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-2UbPrpezMr6gkHKNCRA/N6QGGU237SKOZ78yMHId204A/oXWSAREAIuGZNQ9qlrJosewzcsv2CphZH3u7hC6ng==} - peerDependencies: - react: ^16.13.1 || ^17.0.0 || ^18.0.0 - react-dom: ^16.13.1 || ^17.0.0 || ^18.0.0 - dependencies: - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - dev: false - /react-clientside-effect@1.2.6(react@18.3.1): resolution: {integrity: sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg==} peerDependencies: @@ -10877,18 +10859,6 @@ packages: react: 18.3.1 scheduler: 0.23.2 - /react-draggable@4.4.6(react-dom@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-LtY5Xw1zTPqHkVmtM3X8MUOxNDOUhv/khTgBgrUvwaS064bwVvxT+q5El0uUFNx5IEPKXuRejr7UqLwBIg5pdw==} - peerDependencies: - react: '>= 16.3.0' - react-dom: '>= 16.3.0' - dependencies: - clsx: 1.2.1 - prop-types: 15.8.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - dev: false - /react-dropzone@14.2.3(react@18.3.1): resolution: {integrity: sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==} engines: {node: '>= 10.13'} @@ -11099,19 +11069,6 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false - /react-rnd@10.4.10(react-dom@18.3.1)(react@18.3.1): - resolution: {integrity: sha512-YjQAgEeSbNUoOXSD9ZBvIiLVizFb+bNhpDk8DbIRHA557NW02CXbwsAeOTpJQnsdhEL+NP2I+Ssrwejqcodtjg==} - peerDependencies: - react: '>=16.3.0' - react-dom: '>=16.3.0' - dependencies: - re-resizable: 6.9.14(react-dom@18.3.1)(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-draggable: 4.4.6(react-dom@18.3.1)(react@18.3.1) - tslib: 2.6.2 - dev: false - /react-select@5.7.7(@types/react@18.3.1)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-HhashZZJDRlfF/AKj0a0Lnfs3sRdw/46VJIRd8IbB9/Ovr74+ZIwkAdSBjSPXsFMG+u72c5xShqwLSKIJllzqw==} peerDependencies: diff --git a/invokeai/frontend/web/src/app/components/App.tsx b/invokeai/frontend/web/src/app/components/App.tsx index 03c854bb48..30d8f41200 100644 --- a/invokeai/frontend/web/src/app/components/App.tsx +++ b/invokeai/frontend/web/src/app/components/App.tsx @@ -12,7 +12,6 @@ import { useGlobalHotkeys } from 'common/hooks/useGlobalHotkeys'; import ChangeBoardModal from 'features/changeBoardModal/components/ChangeBoardModal'; import DeleteImageModal from 'features/deleteImageModal/components/DeleteImageModal'; import { DynamicPromptsModal } from 'features/dynamicPrompts/components/DynamicPromptsPreviewModal'; -import { FloatingImageViewer } from 'features/gallery/components/ImageViewer/FloatingImageViewer'; import { useStarterModelsToast } from 'features/modelManagerV2/hooks/useStarterModelsToast'; import { configChanged } from 'features/system/store/configSlice'; import { languageSelector } from 'features/system/store/systemSelectors'; @@ -97,7 +96,6 @@ const App = ({ config = DEFAULT_CONFIG, selectedImage }: Props) => { - ); }; diff --git a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/FloatingImageViewer.tsx b/invokeai/frontend/web/src/features/gallery/components/ImageViewer/FloatingImageViewer.tsx deleted file mode 100644 index 1d91dafd1c..0000000000 --- a/invokeai/frontend/web/src/features/gallery/components/ImageViewer/FloatingImageViewer.tsx +++ /dev/null @@ -1,190 +0,0 @@ -import { Flex, IconButton, Spacer, Text, useShiftModifier } from '@invoke-ai/ui-library'; -import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; -import CurrentImagePreview from 'features/gallery/components/ImageViewer/CurrentImagePreview'; -import { isFloatingImageViewerOpenChanged } from 'features/gallery/store/gallerySlice'; -import { memo, useCallback, useLayoutEffect, useRef } from 'react'; -import { flushSync } from 'react-dom'; -import { useTranslation } from 'react-i18next'; -import { PiHourglassBold, PiXBold } from 'react-icons/pi'; -import { Rnd } from 'react-rnd'; - -const defaultDim = 256; -const maxDim = 512; -const defaultSize = { width: defaultDim, height: defaultDim + 24 }; -const maxSize = { width: maxDim, height: maxDim + 24 }; -const rndDefault = { x: 0, y: 0, ...defaultSize }; - -const rndStyles = { - zIndex: 11, -}; - -const enableResizing = { - top: false, - right: false, - bottom: false, - left: false, - topRight: false, - bottomRight: true, - bottomLeft: false, - topLeft: false, -}; - -const FloatingImageViewerComponent = memo(() => { - const { t } = useTranslation(); - const dispatch = useAppDispatch(); - const shift = useShiftModifier(); - const rndRef = useRef(null); - const imagePreviewRef = useRef(null); - const onClose = useCallback(() => { - dispatch(isFloatingImageViewerOpenChanged(false)); - }, [dispatch]); - - const fitToScreen = useCallback(() => { - if (!imagePreviewRef.current || !rndRef.current) { - return; - } - const el = imagePreviewRef.current; - const rnd = rndRef.current; - - const { top, right, bottom, left, width, height } = el.getBoundingClientRect(); - const { innerWidth, innerHeight } = window; - - const newPosition = rnd.getDraggablePosition(); - - if (top < 0) { - newPosition.y = 0; - } - if (left < 0) { - newPosition.x = 0; - } - if (bottom > innerHeight) { - newPosition.y = innerHeight - height; - } - if (right > innerWidth) { - newPosition.x = innerWidth - width; - } - rnd.updatePosition(newPosition); - }, []); - - const onDoubleClick = useCallback(() => { - if (!rndRef.current || !imagePreviewRef.current) { - return; - } - const { width, height } = imagePreviewRef.current.getBoundingClientRect(); - if (width === defaultSize.width && height === defaultSize.height) { - rndRef.current.updateSize(maxSize); - } else { - rndRef.current.updateSize(defaultSize); - } - flushSync(fitToScreen); - }, [fitToScreen]); - - useLayoutEffect(() => { - window.addEventListener('resize', fitToScreen); - return () => { - window.removeEventListener('resize', fitToScreen); - }; - }, [fitToScreen]); - - useLayoutEffect(() => { - // Set the initial position - if (!imagePreviewRef.current || !rndRef.current) { - return; - } - - const { width, height } = imagePreviewRef.current.getBoundingClientRect(); - - const initialPosition = { - // 54 = width of left-hand vertical bar of tab icons - // 430 = width of parameters panel - x: 54 + 430 / 2 - width / 2, - // 16 = just a reasonable bottom padding - y: window.innerHeight - height - 16, - }; - - rndRef.current.updatePosition(initialPosition); - }, [fitToScreen]); - - return ( - - - - - {t('common.viewer')} - - - } size="sm" variant="link" onClick={onClose} /> - - - - - - - ); -}); - -FloatingImageViewerComponent.displayName = 'FloatingImageViewerComponent'; - -export const FloatingImageViewer = memo(() => { - const isOpen = useAppSelector((s) => s.gallery.isFloatingImageViewerOpen); - - if (!isOpen) { - return null; - } - - return ; -}); - -FloatingImageViewer.displayName = 'FloatingImageViewer'; - -export const ToggleFloatingImageViewerButton = memo(() => { - const { t } = useTranslation(); - const dispatch = useAppDispatch(); - const isOpen = useAppSelector((s) => s.gallery.isFloatingImageViewerOpen); - - const onToggle = useCallback(() => { - dispatch(isFloatingImageViewerOpenChanged(!isOpen)); - }, [dispatch, isOpen]); - - return ( - } - size="sm" - onClick={onToggle} - variant="link" - colorScheme={isOpen ? 'invokeBlue' : 'base'} - boxSize={8} - /> - ); -}); - -ToggleFloatingImageViewerButton.displayName = 'ToggleFloatingImageViewerButton'; diff --git a/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts b/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts index 16e0dd9770..744dc09f3f 100644 --- a/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts +++ b/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts @@ -24,7 +24,6 @@ const initialGalleryState: GalleryState = { limit: INITIAL_IMAGE_LIMIT, offset: 0, isImageViewerOpen: false, - isFloatingImageViewerOpen: false, }; export const gallerySlice = createSlice({ @@ -82,9 +81,6 @@ export const gallerySlice = createSlice({ isImageViewerOpenChanged: (state, action: PayloadAction) => { state.isImageViewerOpen = action.payload; }, - isFloatingImageViewerOpenChanged: (state, action: PayloadAction) => { - state.isFloatingImageViewerOpen = action.payload; - }, }, extraReducers: (builder) => { builder.addCase(setActiveTab, (state) => { @@ -129,7 +125,6 @@ export const { moreImagesLoaded, alwaysShowImageSizeBadgeChanged, isImageViewerOpenChanged, - isFloatingImageViewerOpenChanged, } = gallerySlice.actions; const isAnyBoardDeleted = isAnyOf( diff --git a/invokeai/frontend/web/src/features/gallery/store/types.ts b/invokeai/frontend/web/src/features/gallery/store/types.ts index 9c258060c9..0e86d2d4be 100644 --- a/invokeai/frontend/web/src/features/gallery/store/types.ts +++ b/invokeai/frontend/web/src/features/gallery/store/types.ts @@ -21,5 +21,4 @@ export type GalleryState = { limit: number; alwaysShowImageSizeBadge: boolean; isImageViewerOpen: boolean; - isFloatingImageViewerOpen: boolean; }; diff --git a/invokeai/frontend/web/src/features/ui/components/InvokeTabs.tsx b/invokeai/frontend/web/src/features/ui/components/InvokeTabs.tsx index 4152f4065b..42df03872c 100644 --- a/invokeai/frontend/web/src/features/ui/components/InvokeTabs.tsx +++ b/invokeai/frontend/web/src/features/ui/components/InvokeTabs.tsx @@ -4,7 +4,6 @@ import { createMemoizedSelector } from 'app/store/createMemoizedSelector'; import { $customNavComponent } from 'app/store/nanostores/customNavComponent'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import ImageGalleryContent from 'features/gallery/components/ImageGalleryContent'; -import { ToggleFloatingImageViewerButton } from 'features/gallery/components/ImageViewer/FloatingImageViewer'; import { ImageViewer } from 'features/gallery/components/ImageViewer/ImageViewer'; import NodeEditorPanelGroup from 'features/nodes/components/sidePanel/NodeEditorPanelGroup'; import InvokeAILogoComponent from 'features/system/components/InvokeAILogoComponent'; @@ -224,7 +223,6 @@ const InvokeTabs = () => { - {customNavComponent ? customNavComponent : }