From e5b7dd63e9494ad5ccb74286c23b4196bc226861 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Tue, 9 May 2023 23:39:29 +1000 Subject: [PATCH 01/13] fix(nodes): temporarily disable librarygraphs - Do not retrieve graph from DB until we resolve the issue of changing node schemas causing application to fail to start up due to invalid graphs --- invokeai/app/services/default_graphs.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/invokeai/app/services/default_graphs.py b/invokeai/app/services/default_graphs.py index 0ac6b08b4d..5eda5e957d 100644 --- a/invokeai/app/services/default_graphs.py +++ b/invokeai/app/services/default_graphs.py @@ -48,13 +48,14 @@ def create_text_to_image() -> LibraryGraph: def create_system_graphs(graph_library: ItemStorageABC[LibraryGraph]) -> list[LibraryGraph]: """Creates the default system graphs, or adds new versions if the old ones don't match""" - + + # TODO: Uncomment this when we are ready to fix this up to prevent breaking changes graphs: list[LibraryGraph] = list() # text_to_image = graph_library.get(default_text_to_image_graph_id) - # TODO: Check if the graph is the same as the default one, and if not, update it - #if text_to_image is None: + # # TODO: Check if the graph is the same as the default one, and if not, update it + # #if text_to_image is None: text_to_image = create_text_to_image() graph_library.set(text_to_image) From ad0bb3f61a6f832ef4d770a51e2339f334c52e9b Mon Sep 17 00:00:00 2001 From: Eugene Date: Tue, 9 May 2023 23:52:07 -0400 Subject: [PATCH 02/13] fix: queue error should not crash InvocationProcessor 1. if retrieving an item from the queue raises an exception, the InvocationProcessor thread crashes, but the API continues running in a non-functional state. This fixes the issue 2. when there are no items in the queue, sleep 1 second before checking again. 3. Also ensures the thread isn't crashed if an exception is raised from invoker, and emits the error event Intentionally using base Exceptions because for now we don't know which specific exception to expect. Fixes (sort of)? #3222 --- invokeai/app/services/processor.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/invokeai/app/services/processor.py b/invokeai/app/services/processor.py index 35cbcd5068..5d292af3c9 100644 --- a/invokeai/app/services/processor.py +++ b/invokeai/app/services/processor.py @@ -1,3 +1,4 @@ +import time import traceback from threading import Event, Thread, BoundedSemaphore @@ -6,6 +7,7 @@ from .invocation_queue import InvocationQueueItem from .invoker import InvocationProcessorABC, Invoker from ..models.exceptions import CanceledException +import invokeai.backend.util.logging as logger class DefaultInvocationProcessor(InvocationProcessorABC): __invoker_thread: Thread __stop_event: Event @@ -34,8 +36,14 @@ class DefaultInvocationProcessor(InvocationProcessorABC): try: self.__threadLimit.acquire() while not stop_event.is_set(): - queue_item: InvocationQueueItem = self.__invoker.services.queue.get() + try: + queue_item: InvocationQueueItem = self.__invoker.services.queue.get() + except Exception as e: + logger.debug("Exception while getting from queue: %s" % e) + if not queue_item: # Probably stopping + # do not hammer the queue + time.sleep(1) continue graph_execution_state = ( @@ -124,7 +132,16 @@ class DefaultInvocationProcessor(InvocationProcessorABC): # Queue any further commands if invoking all is_complete = graph_execution_state.is_complete() if queue_item.invoke_all and not is_complete: - self.__invoker.invoke(graph_execution_state, invoke_all=True) + try: + self.__invoker.invoke(graph_execution_state, invoke_all=True) + except Exception as e: + logger.error("Error while invoking: %s" % e) + self.__invoker.services.events.emit_invocation_error( + graph_execution_state_id=graph_execution_state.id, + node=invocation.dict(), + source_node_id=source_node_id, + error=traceback.format_exc() + ) elif is_complete: self.__invoker.services.events.emit_graph_execution_complete( graph_execution_state.id From 63db3fc22fb83b06cc0208d6d1a917700e9e87f5 Mon Sep 17 00:00:00 2001 From: Eugene Brodsky Date: Fri, 12 May 2023 17:45:01 -0400 Subject: [PATCH 03/13] reduce queue check interval to 0.5s --- invokeai/app/services/processor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/invokeai/app/services/processor.py b/invokeai/app/services/processor.py index 5d292af3c9..9e3b5a0a30 100644 --- a/invokeai/app/services/processor.py +++ b/invokeai/app/services/processor.py @@ -43,7 +43,7 @@ class DefaultInvocationProcessor(InvocationProcessorABC): if not queue_item: # Probably stopping # do not hammer the queue - time.sleep(1) + time.sleep(0.5) continue graph_execution_state = ( From 47a088d685d1d3cc82482317ea5356a60af077f4 Mon Sep 17 00:00:00 2001 From: Mary Hipp Date: Fri, 12 May 2023 12:49:59 -0400 Subject: [PATCH 04/13] rehydrate selectedImage URL when results and uploads are fetched --- .../features/gallery/store/gallerySlice.ts | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts b/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts index 81705086b3..1ae5ee8aee 100644 --- a/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts +++ b/invokeai/frontend/web/src/features/gallery/store/gallerySlice.ts @@ -2,6 +2,10 @@ import type { PayloadAction } from '@reduxjs/toolkit'; import { createSlice } from '@reduxjs/toolkit'; import { Image } from 'app/types/invokeai'; import { imageReceived, thumbnailReceived } from 'services/thunks/image'; +import { + receivedResultImagesPage, + receivedUploadImagesPage, +} from '../../../services/thunks/gallery'; type GalleryImageObjectFitType = 'contain' | 'cover'; @@ -86,6 +90,30 @@ export const gallerySlice = createSlice({ state.selectedImage.thumbnail = thumbnailPath; } }); + builder.addCase(receivedResultImagesPage.fulfilled, (state, action) => { + // rehydrate selectedImage URL when results list comes in + // solves case when outdated URL is in local storage + if (state.selectedImage) { + const selectedImageInResults = action.payload.items.find( + (image) => image.image_name === state.selectedImage!.name + ); + if (selectedImageInResults) { + state.selectedImage.url = selectedImageInResults.image_url; + } + } + }); + builder.addCase(receivedUploadImagesPage.fulfilled, (state, action) => { + // rehydrate selectedImage URL when results list comes in + // solves case when outdated URL is in local storage + if (state.selectedImage) { + const selectedImageInResults = action.payload.items.find( + (image) => image.image_name === state.selectedImage!.name + ); + if (selectedImageInResults) { + state.selectedImage.url = selectedImageInResults.image_url; + } + } + }); }, }); From 026d3260b4128fe4f2fc603ae9cfbd7ca18b7fae Mon Sep 17 00:00:00 2001 From: blessedcoolant <54517381+blessedcoolant@users.noreply.github.com> Date: Sat, 13 May 2023 02:43:32 +1200 Subject: [PATCH 05/13] Add Heun Karras Scheduler --- invokeai/backend/args.py | 1 + invokeai/backend/stable_diffusion/schedulers/schedulers.py | 3 ++- invokeai/backend/web/modules/parameters.py | 1 + invokeai/frontend/web/src/app/constants.ts | 1 + invokeai/frontend/web/src/app/types/invokeai.ts | 1 + 5 files changed, 6 insertions(+), 1 deletion(-) diff --git a/invokeai/backend/args.py b/invokeai/backend/args.py index db6fbe08df..6a29847c6e 100644 --- a/invokeai/backend/args.py +++ b/invokeai/backend/args.py @@ -113,6 +113,7 @@ SAMPLER_CHOICES = [ "lms", "pndm", "heun", + "heun_k", "euler", "euler_k", "euler_a", diff --git a/invokeai/backend/stable_diffusion/schedulers/schedulers.py b/invokeai/backend/stable_diffusion/schedulers/schedulers.py index fab28aca8c..08f85cf559 100644 --- a/invokeai/backend/stable_diffusion/schedulers/schedulers.py +++ b/invokeai/backend/stable_diffusion/schedulers/schedulers.py @@ -9,7 +9,8 @@ SCHEDULER_MAP = dict( deis=(DEISMultistepScheduler, dict()), lms=(LMSDiscreteScheduler, dict()), pndm=(PNDMScheduler, dict()), - heun=(HeunDiscreteScheduler, dict()), + heun=(HeunDiscreteScheduler, dict(use_karras_sigmas=False)), + heun_k=(HeunDiscreteScheduler, dict(use_karras_sigmas=True)), euler=(EulerDiscreteScheduler, dict(use_karras_sigmas=False)), euler_k=(EulerDiscreteScheduler, dict(use_karras_sigmas=True)), euler_a=(EulerAncestralDiscreteScheduler, dict()), diff --git a/invokeai/backend/web/modules/parameters.py b/invokeai/backend/web/modules/parameters.py index 72211857a3..9a4bc0aec3 100644 --- a/invokeai/backend/web/modules/parameters.py +++ b/invokeai/backend/web/modules/parameters.py @@ -9,6 +9,7 @@ SAMPLER_CHOICES = [ "lms", "pndm", "heun", + 'heun_k', "euler", "euler_k", "euler_a", diff --git a/invokeai/frontend/web/src/app/constants.ts b/invokeai/frontend/web/src/app/constants.ts index 189fbc9dd4..6ecd20d7fe 100644 --- a/invokeai/frontend/web/src/app/constants.ts +++ b/invokeai/frontend/web/src/app/constants.ts @@ -7,6 +7,7 @@ export const DIFFUSERS_SCHEDULERS: Array = [ 'lms', 'pndm', 'heun', + 'heun_k', 'euler', 'euler_k', 'euler_a', diff --git a/invokeai/frontend/web/src/app/types/invokeai.ts b/invokeai/frontend/web/src/app/types/invokeai.ts index d0e5437d36..f684dc1ccf 100644 --- a/invokeai/frontend/web/src/app/types/invokeai.ts +++ b/invokeai/frontend/web/src/app/types/invokeai.ts @@ -52,6 +52,7 @@ export type CommonGeneratedImageMetadata = { | 'lms' | 'pndm' | 'heun' + | 'heun_k' | 'euler' | 'euler_k' | 'euler_a' From d2ebc6741b22eef6363565635c31edfaa7416442 Mon Sep 17 00:00:00 2001 From: blessedcoolant <54517381+blessedcoolant@users.noreply.github.com> Date: Sat, 13 May 2023 08:17:45 +1200 Subject: [PATCH 06/13] feat: Add setting to hide / display schedulers --- invokeai/frontend/web/public/locales/en.json | 5 +- invokeai/frontend/web/src/app/constants.ts | 22 +++---- .../Parameters/Core/ParamSampler.tsx | 16 ++--- .../SettingsModal/SettingsModal.tsx | 11 +++- .../SettingsModal/SettingsSchedulers.tsx | 59 +++++++++++++++++++ .../web/src/features/ui/store/uiSlice.ts | 7 +++ .../web/src/features/ui/store/uiTypes.ts | 1 + 7 files changed, 98 insertions(+), 23 deletions(-) create mode 100644 invokeai/frontend/web/src/features/system/components/SettingsModal/SettingsSchedulers.tsx diff --git a/invokeai/frontend/web/public/locales/en.json b/invokeai/frontend/web/public/locales/en.json index 3592e141d0..f82b3af677 100644 --- a/invokeai/frontend/web/public/locales/en.json +++ b/invokeai/frontend/web/public/locales/en.json @@ -540,7 +540,10 @@ "consoleLogLevel": "Log Level", "shouldLogToConsole": "Console Logging", "developer": "Developer", - "general": "General" + "general": "General", + "generation": "Generation", + "ui": "User Interface", + "availableSchedulers": "Available Schedulers" }, "toast": { "serverError": "Server Error", diff --git a/invokeai/frontend/web/src/app/constants.ts b/invokeai/frontend/web/src/app/constants.ts index 6ecd20d7fe..b74c67befd 100644 --- a/invokeai/frontend/web/src/app/constants.ts +++ b/invokeai/frontend/web/src/app/constants.ts @@ -1,30 +1,24 @@ // TODO: use Enums? -export const DIFFUSERS_SCHEDULERS: Array = [ +export const SCHEDULERS: Array = [ 'ddim', - 'ddpm', - 'deis', 'lms', - 'pndm', - 'heun', - 'heun_k', 'euler', 'euler_k', 'euler_a', - 'kdpm_2', - 'kdpm_2_a', 'dpmpp_2s', 'dpmpp_2m', 'dpmpp_2m_k', + 'kdpm_2', + 'kdpm_2_a', + 'deis', + 'ddpm', + 'pndm', + 'heun', + 'heun_k', 'unipc', ]; -export const IMG2IMG_DIFFUSERS_SCHEDULERS = DIFFUSERS_SCHEDULERS.filter( - (scheduler) => { - return scheduler !== 'dpmpp_2s'; - } -); - // Valid image widths export const WIDTHS: Array = Array.from(Array(64)).map( (_x, i) => (i + 1) * 64 diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamSampler.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamSampler.tsx index 9bd22d9abe..bd31a73829 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamSampler.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamSampler.tsx @@ -1,7 +1,3 @@ -import { - DIFFUSERS_SCHEDULERS, - IMG2IMG_DIFFUSERS_SCHEDULERS, -} from 'app/constants'; import { RootState } from 'app/store/store'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import IAISelect from 'common/components/IAISelect'; @@ -17,6 +13,12 @@ const ParamSampler = () => { const activeTabName = useAppSelector(activeTabNameSelector); + const schedulers = useAppSelector((state: RootState) => state.ui.schedulers); + + const img2imgSchedulers = schedulers.filter((scheduler) => { + return !['dpmpp_2s'].includes(scheduler); + }); + const dispatch = useAppDispatch(); const { t } = useTranslation(); @@ -31,9 +33,9 @@ const ParamSampler = () => { value={sampler} onChange={handleChange} validValues={ - activeTabName === 'img2img' || activeTabName == 'unifiedCanvas' - ? IMG2IMG_DIFFUSERS_SCHEDULERS - : DIFFUSERS_SCHEDULERS + ['img2img', 'unifiedCanvas'].includes(activeTabName) + ? img2imgSchedulers + : schedulers } minWidth={36} /> diff --git a/invokeai/frontend/web/src/features/system/components/SettingsModal/SettingsModal.tsx b/invokeai/frontend/web/src/features/system/components/SettingsModal/SettingsModal.tsx index 58e6684b04..aa3d274dc3 100644 --- a/invokeai/frontend/web/src/features/system/components/SettingsModal/SettingsModal.tsx +++ b/invokeai/frontend/web/src/features/system/components/SettingsModal/SettingsModal.tsx @@ -40,6 +40,7 @@ import { useTranslation } from 'react-i18next'; import { VALID_LOG_LEVELS } from 'app/logging/useLogger'; import { LogLevelName } from 'roarr'; import { LOCALSTORAGE_KEYS, LOCALSTORAGE_PREFIX } from 'app/store/constants'; +import SettingsSchedulers from './SettingsSchedulers'; const selector = createSelector( [systemSelector, uiSelector], @@ -171,7 +172,6 @@ const SettingsModal = ({ children }: SettingsModalProps) => { {t('settings.general')} - { dispatch(setShouldConfirmOnDelete(e.target.checked)) } /> + + + + {t('settings.generation')} + + + + + {t('settings.ui')} state.ui.schedulers); + + const dispatch = useAppDispatch(); + const { t } = useTranslation(); + + const schedulerSettingsHandler = (v: string | string[]) => { + if (isArray(v)) dispatch(setSchedulers(v.sort())); + }; + + const renderSchedulerMenuItems = () => { + const schedulerMenuItemsToRender: ReactNode[] = []; + + SCHEDULERS.forEach((scheduler) => { + schedulerMenuItemsToRender.push( + + {scheduler} + + ); + }); + + return schedulerMenuItemsToRender; + }; + + return ( + + + {t('settings.availableSchedulers')} + + + + {renderSchedulerMenuItems()} + + + + ); +} diff --git a/invokeai/frontend/web/src/features/ui/store/uiSlice.ts b/invokeai/frontend/web/src/features/ui/store/uiSlice.ts index b99ebb2c51..6c3eb95a31 100644 --- a/invokeai/frontend/web/src/features/ui/store/uiSlice.ts +++ b/invokeai/frontend/web/src/features/ui/store/uiSlice.ts @@ -5,6 +5,7 @@ import { InvokeTabName, tabMap } from './tabMap'; import { AddNewModelType, Coordinates, Rect, UIState } from './uiTypes'; import { initialImageSelected } from 'features/parameters/store/actions'; import { initialImageChanged } from 'features/parameters/store/generationSlice'; +import { SCHEDULERS } from 'app/constants'; export const initialUIState: UIState = { activeTab: 0, @@ -27,6 +28,7 @@ export const initialUIState: UIState = { shouldShowProgressImages: false, shouldShowProgressInViewer: false, shouldShowImageParameters: false, + schedulers: SCHEDULERS, }; export const uiSlice = createSlice({ @@ -146,6 +148,10 @@ export const uiSlice = createSlice({ ) => { state.shouldShowImageParameters = action.payload; }, + setSchedulers: (state, action: PayloadAction) => { + state.schedulers = []; + state.schedulers = action.payload; + }, }, extraReducers(builder) { builder.addCase(initialImageChanged, (state) => { @@ -179,6 +185,7 @@ export const { setShouldShowProgressImages, setShouldShowProgressInViewer, shouldShowImageParametersChanged, + setSchedulers, } = uiSlice.actions; export default uiSlice.reducer; diff --git a/invokeai/frontend/web/src/features/ui/store/uiTypes.ts b/invokeai/frontend/web/src/features/ui/store/uiTypes.ts index 030ec4f1ce..db9c60e292 100644 --- a/invokeai/frontend/web/src/features/ui/store/uiTypes.ts +++ b/invokeai/frontend/web/src/features/ui/store/uiTypes.ts @@ -33,4 +33,5 @@ export interface UIState { shouldShowProgressImages: boolean; shouldShowProgressInViewer: boolean; shouldShowImageParameters: boolean; + schedulers: string[]; } From 0e9470503fe117621a35aed934037564639d840f Mon Sep 17 00:00:00 2001 From: blessedcoolant <54517381+blessedcoolant@users.noreply.github.com> Date: Sat, 13 May 2023 08:18:16 +1200 Subject: [PATCH 07/13] fix: Rework the layout of the parameters scrollbar --- .../src/features/ui/components/ParametersPinnedWrapper.tsx | 7 ++++++- .../features/ui/components/common/OverlayScrollable.tsx | 6 +++--- .../ui/components/tabs/ImageToImage/ImageToImageTab.tsx | 2 +- .../ui/components/tabs/TextToImage/TextToImageTab.tsx | 2 +- .../ui/components/tabs/UnifiedCanvas/UnifiedCanvasTab.tsx | 2 +- 5 files changed, 12 insertions(+), 7 deletions(-) diff --git a/invokeai/frontend/web/src/features/ui/components/ParametersPinnedWrapper.tsx b/invokeai/frontend/web/src/features/ui/components/ParametersPinnedWrapper.tsx index 407187294c..cfb2ad267c 100644 --- a/invokeai/frontend/web/src/features/ui/components/ParametersPinnedWrapper.tsx +++ b/invokeai/frontend/web/src/features/ui/components/ParametersPinnedWrapper.tsx @@ -43,13 +43,18 @@ const ParametersPinnedWrapper = (props: ParametersPinnedWrapperProps) => { h: 'full', w: 'full', position: 'absolute', + paddingRight: 4, }} > {props.children} ); diff --git a/invokeai/frontend/web/src/features/ui/components/common/OverlayScrollable.tsx b/invokeai/frontend/web/src/features/ui/components/common/OverlayScrollable.tsx index 71413fd01a..a993f02ce6 100644 --- a/invokeai/frontend/web/src/features/ui/components/common/OverlayScrollable.tsx +++ b/invokeai/frontend/web/src/features/ui/components/common/OverlayScrollable.tsx @@ -8,9 +8,9 @@ const OverlayScrollable = (props: PropsWithChildren) => { style={{ height: '100%', width: '100%' }} options={{ scrollbars: { - visibility: 'auto', - autoHide: 'move', - autoHideDelay: 1300, + visibility: 'visible', + autoHide: 'never', + autoHideDelay: 500, theme: 'os-theme-dark', }, overflow: { x: 'hidden' }, diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ImageToImage/ImageToImageTab.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/ImageToImage/ImageToImageTab.tsx index cbd261f455..46d416204d 100644 --- a/invokeai/frontend/web/src/features/ui/components/tabs/ImageToImage/ImageToImageTab.tsx +++ b/invokeai/frontend/web/src/features/ui/components/tabs/ImageToImage/ImageToImageTab.tsx @@ -23,7 +23,7 @@ const ImageToImageTab = () => { }, []); return ( - + diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/TextToImage/TextToImageTab.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/TextToImage/TextToImageTab.tsx index 87e77cc3ba..6c140172be 100644 --- a/invokeai/frontend/web/src/features/ui/components/tabs/TextToImage/TextToImageTab.tsx +++ b/invokeai/frontend/web/src/features/ui/components/tabs/TextToImage/TextToImageTab.tsx @@ -6,7 +6,7 @@ import ParametersPinnedWrapper from '../../ParametersPinnedWrapper'; const TextToImageTab = () => { return ( - + diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasTab.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasTab.tsx index 2d591d1ecc..aa8c1c6a76 100644 --- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasTab.tsx +++ b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasTab.tsx @@ -20,7 +20,7 @@ const UnifiedCanvasTab = () => { const { shouldUseCanvasBetaLayout } = useAppSelector(selector); return ( - + From 6d3e8507cc5a9750a0003d1c05bca59a3f30cacf Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Sat, 13 May 2023 21:15:19 +1000 Subject: [PATCH 08/13] fix(ui): fix "no image" fallbacks --- .../gallery/components/CurrentImageDisplay.tsx | 4 ++-- .../Parameters/ImageToImage/InitialImagePreview.tsx | 13 +++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/invokeai/frontend/web/src/features/gallery/components/CurrentImageDisplay.tsx b/invokeai/frontend/web/src/features/gallery/components/CurrentImageDisplay.tsx index 36451cfb2c..9b928d45c4 100644 --- a/invokeai/frontend/web/src/features/gallery/components/CurrentImageDisplay.tsx +++ b/invokeai/frontend/web/src/features/gallery/components/CurrentImageDisplay.tsx @@ -4,10 +4,10 @@ import { useAppSelector } from 'app/store/storeHooks'; import { systemSelector } from 'features/system/store/systemSelectors'; import { isEqual } from 'lodash-es'; -import { MdPhoto } from 'react-icons/md'; import { selectedImageSelector } from '../store/gallerySelectors'; import CurrentImageButtons from './CurrentImageButtons'; import CurrentImagePreview from './CurrentImagePreview'; +import { FaImage } from 'react-icons/fa'; export const currentImageDisplaySelector = createSelector( [systemSelector, selectedImageSelector], @@ -61,7 +61,7 @@ const CurrentImageDisplay = () => { ) : ( { )} - {!initialImage?.url && } + {!initialImage?.url && ( + + )} ); }; From 37da0fc0753a0588045027f425cda26689b92ac6 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Sat, 13 May 2023 21:15:45 +1000 Subject: [PATCH 09/13] feat(ui): IAICustomSelect v1 --- .../src/common/components/IAICustomSelect.tsx | 163 ++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 invokeai/frontend/web/src/common/components/IAICustomSelect.tsx diff --git a/invokeai/frontend/web/src/common/components/IAICustomSelect.tsx b/invokeai/frontend/web/src/common/components/IAICustomSelect.tsx new file mode 100644 index 0000000000..dd1b7ab5e2 --- /dev/null +++ b/invokeai/frontend/web/src/common/components/IAICustomSelect.tsx @@ -0,0 +1,163 @@ +import { CheckIcon, ChevronUpIcon } from '@chakra-ui/icons'; +import { + Flex, + FormControl, + FormControlProps, + FormLabel, + Grid, + GridItem, + Input, + List, + ListItem, + Select, + Spacer, + Text, +} from '@chakra-ui/react'; +import { useEnsureOnScreen } from 'common/hooks/useEnsureOnScreen'; +import { useSelect } from 'downshift'; +import { OverlayScrollbarsComponent } from 'overlayscrollbars-react'; + +import { memo, useRef } from 'react'; +import { useIntersection } from 'react-use'; + +const BUTTON_BG = 'base.900'; +const BORDER_HOVER = 'base.700'; +const BORDER_FOCUS = 'accent.600'; + +type IAICustomSelectProps = { + label?: string; + items: string[]; + selectedItem: string; + setSelectedItem: (v: string | null | undefined) => void; + withCheckIcon?: boolean; + formControlProps?: FormControlProps; +}; + +const IAICustomSelect = (props: IAICustomSelectProps) => { + const { + label, + items, + setSelectedItem, + selectedItem, + withCheckIcon, + formControlProps, + } = props; + + const { + isOpen, + getToggleButtonProps, + getLabelProps, + getMenuProps, + highlightedIndex, + getItemProps, + } = useSelect({ + items, + selectedItem, + onSelectedItemChange: ({ selectedItem: newSelectedItem }) => + setSelectedItem(newSelectedItem), + }); + + const toggleButtonRef = useRef(null); + const menuRef = useRef(null); + + return ( + + {label && ( + { + toggleButtonRef.current && toggleButtonRef.current.focus(); + }} + > + {label} + + )} + + + + {isOpen && + items.map((item, index) => ( + + {withCheckIcon ? ( + + + {selectedItem === item && } + + + + {item} + + + + ) : ( + + {item} + + )} + + ))} + + + + ); +}; + +export default memo(IAICustomSelect); From 658b556544be6f00e5033673f216f4a3788b6778 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Sat, 13 May 2023 23:46:47 +1000 Subject: [PATCH 10/13] feat(ui): IAICustomSelect v2, implement for scheduler & model --- .../src/common/components/IAICustomSelect.tsx | 205 +++++++++--------- .../Parameters/Core/ParamSampler.tsx | 18 +- .../Core/ParamSchedulerAndModel.tsx | 19 ++ .../parameters/store/generationSlice.ts | 13 +- .../system/components/ModelSelect.tsx | 33 +-- .../ImageToImageTabCoreParameters.tsx | 23 +- .../TextToImageTabCoreParameters.tsx | 23 +- .../UnifiedCanvasCoreParameters.tsx | 23 +- 8 files changed, 181 insertions(+), 176 deletions(-) create mode 100644 invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamSchedulerAndModel.tsx diff --git a/invokeai/frontend/web/src/common/components/IAICustomSelect.tsx b/invokeai/frontend/web/src/common/components/IAICustomSelect.tsx index dd1b7ab5e2..d9610346ec 100644 --- a/invokeai/frontend/web/src/common/components/IAICustomSelect.tsx +++ b/invokeai/frontend/web/src/common/components/IAICustomSelect.tsx @@ -1,28 +1,25 @@ -import { CheckIcon, ChevronUpIcon } from '@chakra-ui/icons'; +import { CheckIcon } from '@chakra-ui/icons'; import { + Box, Flex, + FlexProps, FormControl, FormControlProps, FormLabel, Grid, GridItem, - Input, List, ListItem, Select, - Spacer, Text, + Tooltip, + TooltipProps, } from '@chakra-ui/react'; -import { useEnsureOnScreen } from 'common/hooks/useEnsureOnScreen'; +import { autoUpdate, offset, shift, useFloating } from '@floating-ui/react-dom'; import { useSelect } from 'downshift'; import { OverlayScrollbarsComponent } from 'overlayscrollbars-react'; -import { memo, useRef } from 'react'; -import { useIntersection } from 'react-use'; - -const BUTTON_BG = 'base.900'; -const BORDER_HOVER = 'base.700'; -const BORDER_FOCUS = 'accent.600'; +import { memo } from 'react'; type IAICustomSelectProps = { label?: string; @@ -31,6 +28,9 @@ type IAICustomSelectProps = { setSelectedItem: (v: string | null | undefined) => void; withCheckIcon?: boolean; formControlProps?: FormControlProps; + buttonProps?: FlexProps; + tooltip?: string; + tooltipProps?: Omit; }; const IAICustomSelect = (props: IAICustomSelectProps) => { @@ -41,6 +41,9 @@ const IAICustomSelect = (props: IAICustomSelectProps) => { selectedItem, withCheckIcon, formControlProps, + tooltip, + buttonProps, + tooltipProps, } = props; const { @@ -57,105 +60,111 @@ const IAICustomSelect = (props: IAICustomSelectProps) => { setSelectedItem(newSelectedItem), }); - const toggleButtonRef = useRef(null); - const menuRef = useRef(null); + const { refs, floatingStyles } = useFloating({ + whileElementsMounted: autoUpdate, + middleware: [offset(4), shift({ crossAxis: true, padding: 8 })], + }); return ( - + {label && ( { - toggleButtonRef.current && toggleButtonRef.current.focus(); + refs.floating.current && refs.floating.current.focus(); }} > {label} )} - - - - {isOpen && - items.map((item, index) => ( - - {withCheckIcon ? ( - - - {selectedItem === item && } - - - - {item} - - - - ) : ( - - {item} - - )} - - ))} - - + + + + + {isOpen && ( + + + {items.map((item, index) => ( + + {withCheckIcon ? ( + + + {selectedItem === item && } + + + + {item} + + + + ) : ( + + {item} + + )} + + ))} + + + )} + ); }; diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamSampler.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamSampler.tsx index bd31a73829..b3dd4a0f27 100644 --- a/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamSampler.tsx +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamSampler.tsx @@ -1,5 +1,6 @@ import { RootState } from 'app/store/store'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; +import IAICustomSelect from 'common/components/IAICustomSelect'; import IAISelect from 'common/components/IAISelect'; import { setSampler } from 'features/parameters/store/generationSlice'; import { activeTabNameSelector } from 'features/ui/store/uiSelectors'; @@ -23,21 +24,26 @@ const ParamSampler = () => { const { t } = useTranslation(); const handleChange = useCallback( - (e: ChangeEvent) => dispatch(setSampler(e.target.value)), + (v: string | null | undefined) => { + if (!v) { + return; + } + dispatch(setSampler(v)); + }, [dispatch] ); return ( - ); }; diff --git a/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamSchedulerAndModel.tsx b/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamSchedulerAndModel.tsx new file mode 100644 index 0000000000..489d4fad55 --- /dev/null +++ b/invokeai/frontend/web/src/features/parameters/components/Parameters/Core/ParamSchedulerAndModel.tsx @@ -0,0 +1,19 @@ +import { Box, Flex } from '@chakra-ui/react'; +import { memo } from 'react'; +import ParamSampler from './ParamSampler'; +import ModelSelect from 'features/system/components/ModelSelect'; + +const ParamSchedulerAndModel = () => { + return ( + + + + + + + + + ); +}; + +export default memo(ParamSchedulerAndModel); diff --git a/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts b/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts index 5ad0e4973c..604aabbc9b 100644 --- a/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts +++ b/invokeai/frontend/web/src/features/parameters/store/generationSlice.ts @@ -2,8 +2,9 @@ import type { PayloadAction } from '@reduxjs/toolkit'; import { createSlice } from '@reduxjs/toolkit'; import * as InvokeAI from 'app/types/invokeai'; import promptToString from 'common/util/promptToString'; -import { clamp } from 'lodash-es'; +import { clamp, sample } from 'lodash-es'; import { setAllParametersReducer } from './setAllParametersReducer'; +import { receivedModels } from 'services/thunks/model'; export interface GenerationState { cfgScale: number; @@ -236,6 +237,16 @@ export const generationSlice = createSlice({ state.model = action.payload; }, }, + extraReducers: (builder) => { + builder.addCase(receivedModels.fulfilled, (state, action) => { + if (!state.model) { + const randomModel = sample(action.payload); + if (randomModel) { + state.model = randomModel.name; + } + } + }); + }, }); export const { diff --git a/invokeai/frontend/web/src/features/system/components/ModelSelect.tsx b/invokeai/frontend/web/src/features/system/components/ModelSelect.tsx index e38fda2676..520e30b60a 100644 --- a/invokeai/frontend/web/src/features/system/components/ModelSelect.tsx +++ b/invokeai/frontend/web/src/features/system/components/ModelSelect.tsx @@ -1,21 +1,20 @@ import { createSelector } from '@reduxjs/toolkit'; -import { ChangeEvent, memo } from 'react'; +import { memo, useCallback } from 'react'; import { isEqual } from 'lodash-es'; import { useTranslation } from 'react-i18next'; import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; -import IAISelect from 'common/components/IAISelect'; import { selectModelsById, selectModelsIds } from '../store/modelSlice'; import { RootState } from 'app/store/store'; import { modelSelected } from 'features/parameters/store/generationSlice'; import { generationSelector } from 'features/parameters/store/generationSelectors'; +import IAICustomSelect from 'common/components/IAICustomSelect'; const selector = createSelector( [(state: RootState) => state, generationSelector], (state, generation) => { - // const selectedModel = selectedModelSelector(state); const selectedModel = selectModelsById(state, generation.model); - const allModelNames = selectModelsIds(state); + const allModelNames = selectModelsIds(state).map((id) => String(id)); return { allModelNames, selectedModel, @@ -32,19 +31,25 @@ const ModelSelect = () => { const dispatch = useAppDispatch(); const { t } = useTranslation(); const { allModelNames, selectedModel } = useAppSelector(selector); - const handleChangeModel = (e: ChangeEvent) => { - dispatch(modelSelected(e.target.value)); - }; + const handleChangeModel = useCallback( + (v: string | null | undefined) => { + if (!v) { + return; + } + dispatch(modelSelected(v)); + }, + [dispatch] + ); return ( - ); }; diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ImageToImage/ImageToImageTabCoreParameters.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/ImageToImage/ImageToImageTabCoreParameters.tsx index aba85646af..c4161154bb 100644 --- a/invokeai/frontend/web/src/features/ui/components/tabs/ImageToImage/ImageToImageTabCoreParameters.tsx +++ b/invokeai/frontend/web/src/features/ui/components/tabs/ImageToImage/ImageToImageTabCoreParameters.tsx @@ -1,5 +1,5 @@ import { memo } from 'react'; -import { Box, Flex } from '@chakra-ui/react'; +import { Flex } from '@chakra-ui/react'; import { createSelector } from '@reduxjs/toolkit'; import { uiSelector } from 'features/ui/store/uiSelectors'; import { useAppSelector } from 'app/store/storeHooks'; @@ -9,11 +9,10 @@ import ParamSteps from 'features/parameters/components/Parameters/Core/ParamStep import ParamCFGScale from 'features/parameters/components/Parameters/Core/ParamCFGScale'; import ParamWidth from 'features/parameters/components/Parameters/Core/ParamWidth'; import ParamHeight from 'features/parameters/components/Parameters/Core/ParamHeight'; -import ParamSampler from 'features/parameters/components/Parameters/Core/ParamSampler'; -import ModelSelect from 'features/system/components/ModelSelect'; import ImageToImageStrength from 'features/parameters/components/Parameters/ImageToImage/ImageToImageStrength'; import ImageToImageFit from 'features/parameters/components/Parameters/ImageToImage/ImageToImageFit'; import { generationSelector } from 'features/parameters/store/generationSelectors'; +import ParamSchedulerAndModel from 'features/parameters/components/Parameters/Core/ParamSchedulerAndModel'; const selector = createSelector( [uiSelector, generationSelector], @@ -48,14 +47,7 @@ const ImageToImageTabCoreParameters = () => { - - - - - - - - + ) : ( @@ -64,14 +56,7 @@ const ImageToImageTabCoreParameters = () => { - - - - - - - - + diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/TextToImage/TextToImageTabCoreParameters.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/TextToImage/TextToImageTabCoreParameters.tsx index d7edef148c..59512775bc 100644 --- a/invokeai/frontend/web/src/features/ui/components/tabs/TextToImage/TextToImageTabCoreParameters.tsx +++ b/invokeai/frontend/web/src/features/ui/components/tabs/TextToImage/TextToImageTabCoreParameters.tsx @@ -3,14 +3,13 @@ import ParamSteps from 'features/parameters/components/Parameters/Core/ParamStep import ParamCFGScale from 'features/parameters/components/Parameters/Core/ParamCFGScale'; import ParamWidth from 'features/parameters/components/Parameters/Core/ParamWidth'; import ParamHeight from 'features/parameters/components/Parameters/Core/ParamHeight'; -import ParamSampler from 'features/parameters/components/Parameters/Core/ParamSampler'; -import ModelSelect from 'features/system/components/ModelSelect'; -import { Box, Flex } from '@chakra-ui/react'; +import { Flex } from '@chakra-ui/react'; import { useAppSelector } from 'app/store/storeHooks'; import { createSelector } from '@reduxjs/toolkit'; import { uiSelector } from 'features/ui/store/uiSelectors'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; import { memo } from 'react'; +import ParamSchedulerAndModel from 'features/parameters/components/Parameters/Core/ParamSchedulerAndModel'; const selector = createSelector( uiSelector, @@ -42,14 +41,7 @@ const TextToImageTabCoreParameters = () => { - - - - - - - - + ) : ( @@ -58,14 +50,7 @@ const TextToImageTabCoreParameters = () => { - - - - - - - - + diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasCoreParameters.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasCoreParameters.tsx index 74949a399d..f2529e5529 100644 --- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasCoreParameters.tsx +++ b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasCoreParameters.tsx @@ -1,10 +1,9 @@ import { memo } from 'react'; -import { Box, Flex } from '@chakra-ui/react'; +import { Flex } from '@chakra-ui/react'; import { createSelector } from '@reduxjs/toolkit'; import { uiSelector } from 'features/ui/store/uiSelectors'; import { useAppSelector } from 'app/store/storeHooks'; import { defaultSelectorOptions } from 'app/store/util/defaultMemoizeOptions'; -import ModelSelect from 'features/system/components/ModelSelect'; import ParamIterations from 'features/parameters/components/Parameters/Core/ParamIterations'; import ParamSteps from 'features/parameters/components/Parameters/Core/ParamSteps'; import ParamCFGScale from 'features/parameters/components/Parameters/Core/ParamCFGScale'; @@ -12,7 +11,7 @@ import ParamWidth from 'features/parameters/components/Parameters/Core/ParamWidt import ParamHeight from 'features/parameters/components/Parameters/Core/ParamHeight'; import ImageToImageStrength from 'features/parameters/components/Parameters/ImageToImage/ImageToImageStrength'; import ImageToImageFit from 'features/parameters/components/Parameters/ImageToImage/ImageToImageFit'; -import ParamSampler from 'features/parameters/components/Parameters/Core/ParamSampler'; +import ParamSchedulerAndModel from 'features/parameters/components/Parameters/Core/ParamSchedulerAndModel'; const selector = createSelector( uiSelector, @@ -46,14 +45,7 @@ const UnifiedCanvasCoreParameters = () => { - - - - - - - - + ) : ( @@ -62,14 +54,7 @@ const UnifiedCanvasCoreParameters = () => { - - - - - - - - + From 0020457fc706715bb79a1a6fc9e03e92817b16a8 Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Sat, 13 May 2023 23:59:03 +1000 Subject: [PATCH 11/13] fix(ui): tweak settings scheduler styling --- .../SettingsModal/SettingsSchedulers.tsx | 26 ++++++------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/invokeai/frontend/web/src/features/system/components/SettingsModal/SettingsSchedulers.tsx b/invokeai/frontend/web/src/features/system/components/SettingsModal/SettingsSchedulers.tsx index dd0dac284a..7e44257408 100644 --- a/invokeai/frontend/web/src/features/system/components/SettingsModal/SettingsSchedulers.tsx +++ b/invokeai/frontend/web/src/features/system/components/SettingsModal/SettingsSchedulers.tsx @@ -1,4 +1,5 @@ import { + Box, Menu, MenuButton, MenuItemOption, @@ -12,8 +13,7 @@ import { useAppDispatch, useAppSelector } from 'app/store/storeHooks'; import IAIButton from 'common/components/IAIButton'; import { setSchedulers } from 'features/ui/store/uiSlice'; import { isArray } from 'lodash-es'; - -import { ReactNode } from 'react'; +import { OverlayScrollbarsComponent } from 'overlayscrollbars-react'; import { useTranslation } from 'react-i18next'; export default function SettingsSchedulers() { @@ -26,32 +26,22 @@ export default function SettingsSchedulers() { if (isArray(v)) dispatch(setSchedulers(v.sort())); }; - const renderSchedulerMenuItems = () => { - const schedulerMenuItemsToRender: ReactNode[] = []; - - SCHEDULERS.forEach((scheduler) => { - schedulerMenuItemsToRender.push( - - {scheduler} - - ); - }); - - return schedulerMenuItemsToRender; - }; - return ( {t('settings.availableSchedulers')} - + - {renderSchedulerMenuItems()} + {SCHEDULERS.map((scheduler) => ( + + {scheduler} + + ))} From 5a7b687c84fbf5be4e1f42bc80da923dd60bad7c Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Sat, 13 May 2023 23:59:20 +1000 Subject: [PATCH 12/13] fix(ui): add missing packages --- invokeai/frontend/web/package.json | 2 ++ invokeai/frontend/web/yarn.lock | 46 ++++++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/invokeai/frontend/web/package.json b/invokeai/frontend/web/package.json index 13f79f4a44..404d20d937 100644 --- a/invokeai/frontend/web/package.json +++ b/invokeai/frontend/web/package.json @@ -62,11 +62,13 @@ "@dagrejs/graphlib": "^2.1.12", "@emotion/react": "^11.10.6", "@emotion/styled": "^11.10.6", + "@floating-ui/react-dom": "^2.0.0", "@fontsource/inter": "^4.5.15", "@reduxjs/toolkit": "^1.9.5", "@roarr/browser-log-writer": "^1.1.5", "chakra-ui-contextmenu": "^1.0.5", "dateformat": "^5.0.3", + "downshift": "^7.6.0", "formik": "^2.2.9", "framer-motion": "^10.12.4", "fuse.js": "^6.6.2", diff --git a/invokeai/frontend/web/yarn.lock b/invokeai/frontend/web/yarn.lock index 2313cf91c7..de2925ae8c 100644 --- a/invokeai/frontend/web/yarn.lock +++ b/invokeai/frontend/web/yarn.lock @@ -57,7 +57,7 @@ dependencies: regenerator-runtime "^0.13.11" -"@babel/runtime@^7.1.2": +"@babel/runtime@^7.1.2", "@babel/runtime@^7.14.8": version "7.21.5" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.5.tgz#8492dddda9644ae3bda3b45eabe87382caee7200" integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q== @@ -1198,6 +1198,25 @@ resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.39.0.tgz#58b536bcc843f4cd1e02a7e6171da5c040f4d44b" integrity sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng== +"@floating-ui/core@^1.2.6": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.2.6.tgz#d21ace437cc919cdd8f1640302fa8851e65e75c0" + integrity sha512-EvYTiXet5XqweYGClEmpu3BoxmsQ4hkj3QaYA6qEnigCWffTP3vNRwBReTdrwDwo7OoJ3wM8Uoe9Uk4n+d4hfg== + +"@floating-ui/dom@^1.2.7": + version "1.2.7" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.2.7.tgz#c123e4db014b07b97e996cd459245fa217049c6b" + integrity sha512-DyqylONj1ZaBnzj+uBnVfzdjjCkFCL2aA9ESHLyUOGSqb03RpbLMImP1ekIQXYs4KLk9jAjJfZAU8hXfWSahEg== + dependencies: + "@floating-ui/core" "^1.2.6" + +"@floating-ui/react-dom@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.0.0.tgz#7514baac526c818892bbcc84e1c3115008c029f9" + integrity sha512-Ke0oU3SeuABC2C4OFu2mSAwHIP5WUiV98O9YWoHV4Q5aT6E9k06DV0Khi5uYspR8xmmBk08t8ZDcz3TR3ARkEg== + dependencies: + "@floating-ui/dom" "^1.2.7" + "@fontsource/inter@^4.5.15": version "4.5.15" resolved "https://registry.yarnpkg.com/@fontsource/inter/-/inter-4.5.15.tgz#eed1873d68755d3b52d6fcfcfa3493118430a512" @@ -2680,6 +2699,11 @@ compute-scroll-into-view@1.0.20: resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz#1768b5522d1172754f5d0c9b02de3af6be506a43" integrity sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg== +compute-scroll-into-view@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-2.0.4.tgz#2b444b2b9e4724819d2531efacb7ac094155fdf6" + integrity sha512-y/ZA3BGnxoM/QHHQ2Uy49CLtnWPbt4tTPpEEZiEmmiWBFKjej7nEyH8Ryz54jH0MLXflUYA3Er2zUxPSJu5R+g== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -3131,6 +3155,17 @@ dot-prop@^5.2.0: dependencies: is-obj "^2.0.0" +downshift@^7.6.0: + version "7.6.0" + resolved "https://registry.yarnpkg.com/downshift/-/downshift-7.6.0.tgz#de04fb2962bd6c4ea94589c797c91f34aa9816f3" + integrity sha512-VSoTVynTAsabou/hbZ6HJHUVhtBiVOjQoBsCPcQq5eAROIGP+9XKMp9asAKQ3cEcUP4oe0fFdD2pziUjhFY33Q== + dependencies: + "@babel/runtime" "^7.14.8" + compute-scroll-into-view "^2.0.4" + prop-types "^15.7.2" + react-is "^17.0.2" + tslib "^2.3.0" + duplexer3@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e" @@ -5356,7 +5391,7 @@ pretty-ms@^7.0.1: dependencies: parse-ms "^2.1.0" -prop-types@^15.6.2, prop-types@^15.8.1: +prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -5517,6 +5552,11 @@ react-is@^16.13.1, react-is@^16.7.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react-is@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + react-is@^18.0.0: version "18.2.0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" @@ -6485,7 +6525,7 @@ tslib@^1.10.0, tslib@^1.8.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0: +tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== From d3a7fea9396f5cee15374e54ecdcab84fd4108ad Mon Sep 17 00:00:00 2001 From: psychedelicious <4822129+psychedelicious@users.noreply.github.com> Date: Sat, 13 May 2023 23:59:30 +1000 Subject: [PATCH 13/13] Revert "fix: Rework the layout of the parameters scrollbar" This reverts commit 6f1fc397f75fe0fdb3a50639cfad52bf98604146. --- .../src/features/ui/components/ParametersPinnedWrapper.tsx | 7 +------ .../features/ui/components/common/OverlayScrollable.tsx | 6 +++--- .../ui/components/tabs/ImageToImage/ImageToImageTab.tsx | 2 +- .../ui/components/tabs/TextToImage/TextToImageTab.tsx | 2 +- .../ui/components/tabs/UnifiedCanvas/UnifiedCanvasTab.tsx | 2 +- 5 files changed, 7 insertions(+), 12 deletions(-) diff --git a/invokeai/frontend/web/src/features/ui/components/ParametersPinnedWrapper.tsx b/invokeai/frontend/web/src/features/ui/components/ParametersPinnedWrapper.tsx index cfb2ad267c..407187294c 100644 --- a/invokeai/frontend/web/src/features/ui/components/ParametersPinnedWrapper.tsx +++ b/invokeai/frontend/web/src/features/ui/components/ParametersPinnedWrapper.tsx @@ -43,18 +43,13 @@ const ParametersPinnedWrapper = (props: ParametersPinnedWrapperProps) => { h: 'full', w: 'full', position: 'absolute', - paddingRight: 4, }} > {props.children} ); diff --git a/invokeai/frontend/web/src/features/ui/components/common/OverlayScrollable.tsx b/invokeai/frontend/web/src/features/ui/components/common/OverlayScrollable.tsx index a993f02ce6..71413fd01a 100644 --- a/invokeai/frontend/web/src/features/ui/components/common/OverlayScrollable.tsx +++ b/invokeai/frontend/web/src/features/ui/components/common/OverlayScrollable.tsx @@ -8,9 +8,9 @@ const OverlayScrollable = (props: PropsWithChildren) => { style={{ height: '100%', width: '100%' }} options={{ scrollbars: { - visibility: 'visible', - autoHide: 'never', - autoHideDelay: 500, + visibility: 'auto', + autoHide: 'move', + autoHideDelay: 1300, theme: 'os-theme-dark', }, overflow: { x: 'hidden' }, diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/ImageToImage/ImageToImageTab.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/ImageToImage/ImageToImageTab.tsx index 46d416204d..cbd261f455 100644 --- a/invokeai/frontend/web/src/features/ui/components/tabs/ImageToImage/ImageToImageTab.tsx +++ b/invokeai/frontend/web/src/features/ui/components/tabs/ImageToImage/ImageToImageTab.tsx @@ -23,7 +23,7 @@ const ImageToImageTab = () => { }, []); return ( - + diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/TextToImage/TextToImageTab.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/TextToImage/TextToImageTab.tsx index 6c140172be..87e77cc3ba 100644 --- a/invokeai/frontend/web/src/features/ui/components/tabs/TextToImage/TextToImageTab.tsx +++ b/invokeai/frontend/web/src/features/ui/components/tabs/TextToImage/TextToImageTab.tsx @@ -6,7 +6,7 @@ import ParametersPinnedWrapper from '../../ParametersPinnedWrapper'; const TextToImageTab = () => { return ( - + diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasTab.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasTab.tsx index aa8c1c6a76..2d591d1ecc 100644 --- a/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasTab.tsx +++ b/invokeai/frontend/web/src/features/ui/components/tabs/UnifiedCanvas/UnifiedCanvasTab.tsx @@ -20,7 +20,7 @@ const UnifiedCanvasTab = () => { const { shouldUseCanvasBetaLayout } = useAppSelector(selector); return ( - +