diff --git a/invokeai/frontend/web/src/features/ui/components/InvokeTabs.tsx b/invokeai/frontend/web/src/features/ui/components/InvokeTabs.tsx index 1968c64161..2774079ed4 100644 --- a/invokeai/frontend/web/src/features/ui/components/InvokeTabs.tsx +++ b/invokeai/frontend/web/src/features/ui/components/InvokeTabs.tsx @@ -11,7 +11,7 @@ import StatusIndicator from 'features/system/components/StatusIndicator'; import { selectConfigSlice } from 'features/system/store/configSlice'; import FloatingGalleryButton from 'features/ui/components/FloatingGalleryButton'; import FloatingParametersPanelButtons from 'features/ui/components/FloatingParametersPanelButtons'; -import ParametersPanelTextToImage from 'features/ui/components/ParametersPanelTextToImage'; +import ParametersPanelTextToImage from 'features/ui/components/ParametersPanels/ParametersPanelTextToImage'; import ModelManagerTab from 'features/ui/components/tabs/ModelManagerTab'; import NodesTab from 'features/ui/components/tabs/NodesTab'; import QueueTab from 'features/ui/components/tabs/QueueTab'; @@ -28,19 +28,22 @@ import type { CSSProperties, MouseEvent, ReactElement, ReactNode } from 'react'; import { memo, useCallback, useMemo, useRef } from 'react'; import { useHotkeys } from 'react-hotkeys-hook'; import { useTranslation } from 'react-i18next'; +import { MdZoomOutMap } from 'react-icons/md'; import { PiFlowArrowBold } from 'react-icons/pi'; import { RiBox2Line, RiBrushLine, RiInputMethodLine, RiPlayList2Fill } from 'react-icons/ri'; import type { ImperativePanelGroupHandle } from 'react-resizable-panels'; import { Panel, PanelGroup } from 'react-resizable-panels'; -import ParametersPanel from './ParametersPanel'; +import ParametersPanelCanvas from './ParametersPanels/ParametersPanelCanvas'; import ResizeHandle from './tabs/ResizeHandle'; +import UpscalingTab from './tabs/UpscalingTab'; type TabData = { id: InvokeTabName; translationKey: string; icon: ReactElement; content: ReactNode; + parametersPanel?: ReactNode; }; const TAB_DATA: Record = { @@ -49,18 +52,27 @@ const TAB_DATA: Record = { translationKey: 'ui.tabs.generation', icon: , content: , + parametersPanel: , }, canvas: { id: 'canvas', translationKey: 'ui.tabs.canvas', icon: , content: , + parametersPanel: , + }, + upscaling: { + id: 'upscaling', + translationKey: 'ui.tabs.upscaling', + icon: , + content: , }, workflows: { id: 'workflows', translationKey: 'ui.tabs.workflows', icon: , content: , + parametersPanel: , }, models: { id: 'models', @@ -81,7 +93,6 @@ const enabledTabsSelector = createMemoizedSelector(selectConfigSlice, (config) = ); const NO_GALLERY_PANEL_TABS: InvokeTabName[] = ['models', 'queue']; -const NO_OPTIONS_PANEL_TABS: InvokeTabName[] = ['models', 'queue']; const panelStyles: CSSProperties = { height: '100%', width: '100%' }; const GALLERY_MIN_SIZE_PX = 310; const GALLERY_MIN_SIZE_PCT = 20; @@ -103,7 +114,6 @@ const InvokeTabs = () => { e.target.blur(); } }, []); - const shouldShowOptionsPanel = useMemo(() => !NO_OPTIONS_PANEL_TABS.includes(activeTabName), [activeTabName]); const shouldShowGalleryPanel = useMemo(() => !NO_GALLERY_PANEL_TABS.includes(activeTabName), [activeTabName]); const tabs = useMemo( @@ -232,7 +242,7 @@ const InvokeTabs = () => { style={panelStyles} storage={panelStorage} > - {shouldShowOptionsPanel && ( + {!!TAB_DATA[activeTabName].parametersPanel && ( <> { onExpand={optionsPanel.onExpand} collapsible > - + {TAB_DATA[activeTabName].parametersPanel} { )} - {shouldShowOptionsPanel && } + {!!TAB_DATA[activeTabName].parametersPanel && } {shouldShowGalleryPanel && } ); }; export default memo(InvokeTabs); - -const ParametersPanelComponent = memo(() => { - const activeTabName = useAppSelector(activeTabNameSelector); - - if (activeTabName === 'workflows') { - return ; - } - if (activeTabName === 'generation') { - return ; - } - return ; -}); -ParametersPanelComponent.displayName = 'ParametersPanelComponent'; diff --git a/invokeai/frontend/web/src/features/ui/components/ParametersPanel.tsx b/invokeai/frontend/web/src/features/ui/components/ParametersPanels/ParametersPanelCanvas.tsx similarity index 86% rename from invokeai/frontend/web/src/features/ui/components/ParametersPanel.tsx rename to invokeai/frontend/web/src/features/ui/components/ParametersPanels/ParametersPanelCanvas.tsx index e8f73fd786..622ed96696 100644 --- a/invokeai/frontend/web/src/features/ui/components/ParametersPanel.tsx +++ b/invokeai/frontend/web/src/features/ui/components/ParametersPanels/ParametersPanelCanvas.tsx @@ -10,7 +10,6 @@ import { ControlSettingsAccordion } from 'features/settingsAccordions/components import { GenerationSettingsAccordion } from 'features/settingsAccordions/components/GenerationSettingsAccordion/GenerationSettingsAccordion'; import { ImageSettingsAccordion } from 'features/settingsAccordions/components/ImageSettingsAccordion/ImageSettingsAccordion'; import { RefinerSettingsAccordion } from 'features/settingsAccordions/components/RefinerSettingsAccordion/RefinerSettingsAccordion'; -import { activeTabNameSelector } from 'features/ui/store/uiSelectors'; import { OverlayScrollbarsComponent } from 'overlayscrollbars-react'; import type { CSSProperties } from 'react'; import { memo } from 'react'; @@ -20,8 +19,7 @@ const overlayScrollbarsStyles: CSSProperties = { width: '100%', }; -const ParametersPanel = () => { - const activeTabName = useAppSelector(activeTabNameSelector); +const ParametersPanelCanvas = () => { const isSDXL = useAppSelector((s) => s.generation.model?.base === 'sdxl'); return ( @@ -34,8 +32,8 @@ const ParametersPanel = () => { {isSDXL ? : } - {activeTabName !== 'generation' && } - {activeTabName === 'canvas' && } + + {isSDXL && } @@ -46,4 +44,4 @@ const ParametersPanel = () => { ); }; -export default memo(ParametersPanel); +export default memo(ParametersPanelCanvas); diff --git a/invokeai/frontend/web/src/features/ui/components/ParametersPanelTextToImage.tsx b/invokeai/frontend/web/src/features/ui/components/ParametersPanels/ParametersPanelTextToImage.tsx similarity index 100% rename from invokeai/frontend/web/src/features/ui/components/ParametersPanelTextToImage.tsx rename to invokeai/frontend/web/src/features/ui/components/ParametersPanels/ParametersPanelTextToImage.tsx diff --git a/invokeai/frontend/web/src/features/ui/components/tabs/UpscalingTab.tsx b/invokeai/frontend/web/src/features/ui/components/tabs/UpscalingTab.tsx new file mode 100644 index 0000000000..8d4c916c2a --- /dev/null +++ b/invokeai/frontend/web/src/features/ui/components/tabs/UpscalingTab.tsx @@ -0,0 +1,15 @@ +import { Box } from '@invoke-ai/ui-library'; +import { ImageViewer } from 'features/gallery/components/ImageViewer/ImageViewer'; +import { useImageViewer } from 'features/gallery/components/ImageViewer/useImageViewer'; +import { memo } from 'react'; + +const UpscalingTab = () => { + const imageViewer = useImageViewer(); + return ( + + {imageViewer.isOpen && } + + ); +}; + +export default memo(UpscalingTab); diff --git a/invokeai/frontend/web/src/features/ui/store/tabMap.tsx b/invokeai/frontend/web/src/features/ui/store/tabMap.tsx index 526a55b069..5cf97b2d3e 100644 --- a/invokeai/frontend/web/src/features/ui/store/tabMap.tsx +++ b/invokeai/frontend/web/src/features/ui/store/tabMap.tsx @@ -1,3 +1,3 @@ -export const TAB_NUMBER_MAP = ['generation', 'canvas', 'workflows', 'models', 'queue'] as const; +export const TAB_NUMBER_MAP = ['generation', 'canvas', 'upscaling', 'workflows', 'models', 'queue'] as const; export type InvokeTabName = (typeof TAB_NUMBER_MAP)[number];