Skip to content

Commit

Permalink
create castState utility
Browse files Browse the repository at this point in the history
  • Loading branch information
grahamlangford committed Nov 12, 2024
1 parent bbd062d commit ef11d01
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 27 deletions.
28 changes: 28 additions & 0 deletions applications/browser-extension/src/pageEditor/store/castState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (C) 2024 PixieBrix, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import { EditorState } from "@/pageEditor/store/editor/pageEditorTypes";
import { SidebarState } from "@/types/sidebarTypes";
import { Draft } from "immer";

function castState(state: Draft<EditorState>): EditorState;
function castState(state: Draft<SidebarState>): SidebarState;
function castState<T>(state: Draft<T>): T {
return state as T;
}

export default castState;
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ import {
initialEphemeralState,
initialState,
} from "@/store/editorInitialState";
import castEditorState from "@/pageEditor/store/castState";

/* eslint-disable security/detect-object-injection -- lots of immer-style code here dealing with Records */

Expand Down Expand Up @@ -381,7 +382,7 @@ export const editorSlice = createSlice({
const modComponentId = action.payload;
const getModComponentFormStateByModComponentId =
selectGetModComponentFormStateByModComponentId({
editor: state as EditorState,
editor: castEditorState(state),
});
const modComponentFormState =
getModComponentFormStateByModComponentId(modComponentId);
Expand Down Expand Up @@ -483,7 +484,9 @@ export const editorSlice = createSlice({
) {
const { modId, modMetadata } = action.payload;
const getModComponentFormStatesForMod =
selectGetModComponentFormStatesForMod({ editor: state as EditorState });
selectGetModComponentFormStatesForMod({
editor: castEditorState(state),
});
const modComponentFormStatesForMod =
getModComponentFormStatesForMod(modId);

Expand All @@ -504,7 +507,9 @@ export const editorSlice = createSlice({
markModAsCleanById(state, action: PayloadAction<RegistryId>) {
const modId = action.payload;
const getModComponentFormStatesForMod =
selectGetModComponentFormStatesForMod({ editor: state as EditorState });
selectGetModComponentFormStatesForMod({
editor: castEditorState(state),
});
const modComponentFormStatesForMod =
getModComponentFormStatesForMod(modId);

Expand All @@ -527,7 +532,9 @@ export const editorSlice = createSlice({
const modId = action.payload;

const getModComponentFormStatesForMod =
selectGetModComponentFormStatesForMod({ editor: state as EditorState });
selectGetModComponentFormStatesForMod({
editor: castEditorState(state),
});
const modComponentFormStatesForMod =
getModComponentFormStatesForMod(modId);

Expand Down Expand Up @@ -658,7 +665,7 @@ export const editorSlice = createSlice({

const getModComponentFormStateByModComponentId =
selectGetModComponentFormStateByModComponentId({
editor: state as EditorState,
editor: castEditorState(state),
});
const modComponentFormState =
getModComponentFormStateByModComponentId(modComponentId);
Expand Down Expand Up @@ -740,7 +747,7 @@ export const editorSlice = createSlice({

const getModComponentFormStateByModComponentId =
selectGetModComponentFormStateByModComponentId({
editor: state as EditorState,
editor: castEditorState(state),
});
const modComponentFormState = getModComponentFormStateByModComponentId(
state.activeModComponentId,
Expand Down Expand Up @@ -794,15 +801,15 @@ export const editorSlice = createSlice({
) {
const { nodeId, direction } = action.payload;
const activeModComponentFormState = selectActiveModComponentFormState({
editor: state as EditorState,
editor: castEditorState(state),
});
assertNotNullish(
activeModComponentFormState,
"Active mod component form state not found",
);

const activeBrickPipelineUIState = selectActiveBrickPipelineUIState({
editor: state as EditorState,
editor: castEditorState(state),
});
const node = activeBrickPipelineUIState?.pipelineMap[nodeId];
assertNotNullish(node, `Node not found in pipeline map: ${nodeId}`);
Expand Down Expand Up @@ -837,15 +844,15 @@ export const editorSlice = createSlice({
removeNode(state, action: PayloadAction<UUID>) {
const nodeIdToRemove = action.payload;
const activeModComponentFormState = selectActiveModComponentFormState({
editor: state as EditorState,
editor: castEditorState(state),
});
assertNotNullish(
activeModComponentFormState,
"Active mod component form state not found",
);

const activeBrickPipelineUIState = selectActiveBrickPipelineUIState({
editor: state as EditorState,
editor: castEditorState(state),
});
assertNotNullish(
activeBrickPipelineUIState,
Expand Down Expand Up @@ -905,7 +912,7 @@ export const editorSlice = createSlice({
{ payload }: PayloadAction<{ id: string; isExpanded: boolean }>,
) {
const uiState = selectActiveBrickConfigurationUIState({
editor: state as EditorState,
editor: castEditorState(state),
});
assertNotNullish(uiState, "Active node UI state not found");

Expand Down Expand Up @@ -988,7 +995,9 @@ export const editorSlice = createSlice({
setDataPanelTabFindQuery(state, action: PayloadAction<{ query: string }>) {
const { query } = action.payload;

const currentModId = selectCurrentModId({ editor: state as EditorState });
const currentModId = selectCurrentModId({
editor: castEditorState(state),
});
assertNotNullish(currentModId, "Expected currentModId");

state.findInModQueryByModId[currentModId] = { query };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { clearModComponentTraces } from "@/telemetry/trace";
import { assertNotNullish } from "@/utils/nullishUtils";
import { remove } from "lodash";
import { selectGetModComponentFormStateByModComponentId } from "@/pageEditor/store/editor/editorSelectors";
import castEditorState from "@/pageEditor/store/castState";

/* eslint-disable security/detect-object-injection -- lots of immer-style code here dealing with Records */

Expand All @@ -44,7 +45,7 @@ export function ensureBrickPipelineUIState(

const modComponentFormState =
selectGetModComponentFormStateByModComponentId({
editor: state as EditorState,
editor: castEditorState(state),
})(modComponentId);
const pipeline = modComponentFormState?.modComponent.brickPipeline;

Expand Down
29 changes: 15 additions & 14 deletions applications/browser-extension/src/store/sidebar/sidebarSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import resolveTemporaryPanel from "@/store/sidebar/thunks/resolveTemporaryPanel"
import { initialSidebarState } from "@/store/sidebar/initialState";
import removeFormPanel from "@/store/sidebar/thunks/removeFormPanel";
import { type ModComponentRef } from "@/types/modComponentTypes";
import castSidebarState from "@/pageEditor/store/castState";

function findNextActiveKey(
state: SidebarState,
Expand Down Expand Up @@ -207,7 +208,7 @@ const sidebarSlice = createSlice({
selectTab(state, action: PayloadAction<string>) {
// We were seeing some automatic calls to selectTab with a stale event key...
// Calling selectTab with a stale event key shouldn't change the current tab
if (eventKeyExists(state as SidebarState, action.payload)) {
if (eventKeyExists(castSidebarState(state), action.payload)) {
state.activeKey = action.payload;
state.closedTabs[action.payload] = false;
}
Expand All @@ -221,7 +222,7 @@ const sidebarSlice = createSlice({
const entry = remove(state.forms, (form) => form.nonce === nonce)[0];

fixActiveTabOnRemoveInPlace(
state as SidebarState,
castSidebarState(state),
entry as FormPanelEntry,
);
},
Expand Down Expand Up @@ -271,7 +272,7 @@ const sidebarSlice = createSlice({
activatePanel(state, { payload }: PayloadAction<ActivatePanelOptions>) {
state.pendingActivePanel = null;

const visiblePanelCount = getVisiblePanelCount(state as SidebarState);
const visiblePanelCount = getVisiblePanelCount(castSidebarState(state));
const isModLauncherOnlyTabVisible =
visiblePanelCount === 1 &&
!state.closedTabs[eventKeyForEntry(MOD_LAUNCHER)];
Expand All @@ -288,7 +289,7 @@ const sidebarSlice = createSlice({
state.closedTabs[eventKeyForEntry(MOD_LAUNCHER)] = true;
}

const next = findNextActiveKey(state as SidebarState, payload);
const next = findNextActiveKey(castSidebarState(state), payload);

if (next) {
state.activeKey = next;
Expand Down Expand Up @@ -320,7 +321,7 @@ const sidebarSlice = createSlice({
// Try fulfilling the pendingActivePanel request
if (state.pendingActivePanel) {
const next = findNextActiveKey(
state as SidebarState,
castSidebarState(state),
state.pendingActivePanel,
);
if (next) {
Expand All @@ -331,9 +332,9 @@ const sidebarSlice = createSlice({
}

// If a panel is no longer available, reset the current tab to a valid tab.
if (!eventKeyExists(state as SidebarState, state.activeKey)) {
if (!eventKeyExists(castSidebarState(state), state.activeKey)) {
state.activeKey = defaultEventKey(
state as SidebarState,
castSidebarState(state),
state.closedTabs,
);
}
Expand All @@ -352,26 +353,26 @@ const sidebarSlice = createSlice({
const { modActivationPanel: entry, closedTabs } = state;
state.modActivationPanel = null;

if (getVisiblePanelCount(state as SidebarState) === 0) {
if (getVisiblePanelCount(castSidebarState(state)) === 0) {
closedTabs[eventKeyForEntry(MOD_LAUNCHER)] = false;
}

fixActiveTabOnRemoveInPlace(state as SidebarState, entry);
fixActiveTabOnRemoveInPlace(castSidebarState(state), entry);
},
closeTab(state, action: PayloadAction<string>) {
state.closedTabs[action.payload] = true;

const modLauncherEventKey = eventKeyForEntry(MOD_LAUNCHER);
if (
getVisiblePanelCount(state as SidebarState) === 0 &&
getVisiblePanelCount(castSidebarState(state)) === 0 &&
action.payload !== modLauncherEventKey
) {
state.closedTabs[eventKeyForEntry(MOD_LAUNCHER)] = false;
}

if (state.activeKey === action.payload) {
state.activeKey = defaultEventKey(
state as SidebarState,
castSidebarState(state),
state.closedTabs,
);
}
Expand All @@ -395,7 +396,7 @@ const sidebarSlice = createSlice({
const { removedEntry, forms } = action.payload;

state.forms = castDraft(forms);
fixActiveTabOnRemoveInPlace(state as SidebarState, removedEntry);
fixActiveTabOnRemoveInPlace(castSidebarState(state), removedEntry);
}
})
.addCase(addTemporaryPanel.fulfilled, (state, action) => {
Expand All @@ -410,15 +411,15 @@ const sidebarSlice = createSlice({
const { removedEntry, temporaryPanels } = action.payload;

state.temporaryPanels = castDraft(temporaryPanels);
fixActiveTabOnRemoveInPlace(state as SidebarState, removedEntry);
fixActiveTabOnRemoveInPlace(castSidebarState(state), removedEntry);
}
})
.addCase(resolveTemporaryPanel.fulfilled, (state, action) => {
if (action.payload) {
const { resolvedEntry, temporaryPanels } = action.payload;

state.temporaryPanels = castDraft(temporaryPanels);
fixActiveTabOnRemoveInPlace(state as SidebarState, resolvedEntry);
fixActiveTabOnRemoveInPlace(castSidebarState(state), resolvedEntry);
}
});
},
Expand Down

0 comments on commit ef11d01

Please sign in to comment.