mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): store active tab as name, not index (#4697)
This fixes an issue with tab changing when some tabs are disabled.
This commit is contained in:
parent
d45c47db81
commit
34c563060f
@ -14,7 +14,7 @@ import { stateSelector } from 'app/store/store';
|
||||
import { useAppDispatch, useAppSelector } from 'app/store/storeHooks';
|
||||
import ImageGalleryContent from 'features/gallery/components/ImageGalleryContent';
|
||||
import NodeEditorPanelGroup from 'features/nodes/components/sidePanel/NodeEditorPanelGroup';
|
||||
import { InvokeTabName, tabMap } from 'features/ui/store/tabMap';
|
||||
import { InvokeTabName } from 'features/ui/store/tabMap';
|
||||
import { setActiveTab } from 'features/ui/store/uiSlice';
|
||||
import { ResourceKey } from 'i18next';
|
||||
import { isEqual } from 'lodash-es';
|
||||
@ -110,7 +110,7 @@ export const NO_GALLERY_TABS: InvokeTabName[] = ['modelManager', 'queue'];
|
||||
export const NO_SIDE_PANEL_TABS: InvokeTabName[] = ['modelManager', 'queue'];
|
||||
|
||||
const InvokeTabs = () => {
|
||||
const activeTab = useAppSelector(activeTabIndexSelector);
|
||||
const activeTabIndex = useAppSelector(activeTabIndexSelector);
|
||||
const activeTabName = useAppSelector(activeTabNameSelector);
|
||||
const enabledTabs = useAppSelector(enabledTabsSelector);
|
||||
const { t } = useTranslation();
|
||||
@ -150,13 +150,13 @@ const InvokeTabs = () => {
|
||||
|
||||
const handleTabChange = useCallback(
|
||||
(index: number) => {
|
||||
const activeTabName = tabMap[index];
|
||||
if (!activeTabName) {
|
||||
const tab = enabledTabs[index];
|
||||
if (!tab) {
|
||||
return;
|
||||
}
|
||||
dispatch(setActiveTab(activeTabName));
|
||||
dispatch(setActiveTab(tab.id));
|
||||
},
|
||||
[dispatch]
|
||||
[dispatch, enabledTabs]
|
||||
);
|
||||
|
||||
const {
|
||||
@ -216,8 +216,8 @@ const InvokeTabs = () => {
|
||||
return (
|
||||
<Tabs
|
||||
variant="appTabs"
|
||||
defaultIndex={activeTab}
|
||||
index={activeTab}
|
||||
defaultIndex={activeTabIndex}
|
||||
index={activeTabIndex}
|
||||
onChange={handleTabChange}
|
||||
sx={{
|
||||
flexGrow: 1,
|
||||
|
@ -1,13 +0,0 @@
|
||||
import { InvokeTabName, tabMap } from './tabMap';
|
||||
import { UIState } from './uiTypes';
|
||||
|
||||
export const setActiveTabReducer = (
|
||||
state: UIState,
|
||||
newActiveTab: number | InvokeTabName
|
||||
) => {
|
||||
if (typeof newActiveTab === 'number') {
|
||||
state.activeTab = newActiveTab;
|
||||
} else {
|
||||
state.activeTab = tabMap.indexOf(newActiveTab);
|
||||
}
|
||||
};
|
@ -1,27 +1,23 @@
|
||||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { RootState } from 'app/store/store';
|
||||
import { isEqual } from 'lodash-es';
|
||||
|
||||
import { InvokeTabName, tabMap } from './tabMap';
|
||||
import { UIState } from './uiTypes';
|
||||
import { isEqual, isString } from 'lodash-es';
|
||||
import { tabMap } from './tabMap';
|
||||
|
||||
export const activeTabNameSelector = createSelector(
|
||||
(state: RootState) => state.ui,
|
||||
(ui: UIState) => tabMap[ui.activeTab] as InvokeTabName,
|
||||
{
|
||||
memoizeOptions: {
|
||||
equalityCheck: isEqual,
|
||||
},
|
||||
}
|
||||
(state: RootState) => state,
|
||||
/**
|
||||
* Previously `activeTab` was an integer, but now it's a string.
|
||||
* Default to first tab in case user has integer.
|
||||
*/
|
||||
({ ui }) => (isString(ui.activeTab) ? ui.activeTab : 'txt2img')
|
||||
);
|
||||
|
||||
export const activeTabIndexSelector = createSelector(
|
||||
(state: RootState) => state.ui,
|
||||
(ui: UIState) => ui.activeTab,
|
||||
{
|
||||
memoizeOptions: {
|
||||
equalityCheck: isEqual,
|
||||
},
|
||||
(state: RootState) => state,
|
||||
({ ui, config }) => {
|
||||
const tabs = tabMap.filter((t) => !config.disabledTabs.includes(t));
|
||||
const idx = tabs.indexOf(ui.activeTab);
|
||||
return idx === -1 ? 0 : idx;
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -2,12 +2,11 @@ import type { PayloadAction } from '@reduxjs/toolkit';
|
||||
import { createSlice } from '@reduxjs/toolkit';
|
||||
import { initialImageChanged } from 'features/parameters/store/generationSlice';
|
||||
import { SchedulerParam } from 'features/parameters/types/parameterSchemas';
|
||||
import { setActiveTabReducer } from './extraReducers';
|
||||
import { InvokeTabName } from './tabMap';
|
||||
import { UIState } from './uiTypes';
|
||||
|
||||
export const initialUIState: UIState = {
|
||||
activeTab: 0,
|
||||
activeTab: 'txt2img',
|
||||
shouldShowImageDetails: false,
|
||||
shouldUseCanvasBetaLayout: false,
|
||||
shouldShowExistingModelsInSearch: false,
|
||||
@ -26,7 +25,7 @@ export const uiSlice = createSlice({
|
||||
initialState: initialUIState,
|
||||
reducers: {
|
||||
setActiveTab: (state, action: PayloadAction<InvokeTabName>) => {
|
||||
setActiveTabReducer(state, action.payload);
|
||||
state.activeTab = action.payload;
|
||||
},
|
||||
setShouldShowImageDetails: (state, action: PayloadAction<boolean>) => {
|
||||
state.shouldShowImageDetails = action.payload;
|
||||
@ -73,7 +72,7 @@ export const uiSlice = createSlice({
|
||||
},
|
||||
extraReducers(builder) {
|
||||
builder.addCase(initialImageChanged, (state) => {
|
||||
setActiveTabReducer(state, 'img2img');
|
||||
state.activeTab = 'img2img';
|
||||
});
|
||||
},
|
||||
});
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { SchedulerParam } from 'features/parameters/types/parameterSchemas';
|
||||
import { InvokeTabName } from './tabMap';
|
||||
|
||||
export type Coordinates = {
|
||||
x: number;
|
||||
@ -13,7 +14,7 @@ export type Dimensions = {
|
||||
export type Rect = Coordinates & Dimensions;
|
||||
|
||||
export interface UIState {
|
||||
activeTab: number;
|
||||
activeTab: InvokeTabName;
|
||||
shouldShowImageDetails: boolean;
|
||||
shouldUseCanvasBetaLayout: boolean;
|
||||
shouldShowExistingModelsInSearch: boolean;
|
||||
|
Loading…
Reference in New Issue
Block a user