All files / src/store/features/entities entitiesMiddleware.ts

21.81% Statements 12/55
20.93% Branches 9/43
33.33% Functions 3/9
19.23% Lines 10/52

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119    1x 1x 1x     1x 1x                                               1x                           1x               1x                                                                                                                       1x     1x  
import { Dispatch, Middleware } from "@reduxjs/toolkit";
import { RootState } from "store/storeTypes";
import entitiesActions from "./entitiesActions";
import { selectScriptEventDefs } from "store/features/scriptEventDefs/scriptEventDefsState";
import settingsActions from "store/features/settings/settingsActions";
 
const entitiesMiddleware: Middleware<Dispatch, RootState> =
  (store) => (next) => (action) => {
    Iif (
      entitiesActions.editScriptEvent.match(action) ||
      entitiesActions.toggleScriptEventComment.match(action) ||
      entitiesActions.editScriptEventArg.match(action) ||
      entitiesActions.removeScriptEvent.match(action) ||
      entitiesActions.addScriptEvents.match(action)
    ) {
      const result = next(action); // Keep before refreshCustomEventArgs() otherwise values are "off by one" update
 
      const state = store.getState();
      const editorType = state.editor.type;
      const entityId = state.editor.entityId;
      const scriptEventDefs = selectScriptEventDefs(state);
 
      if (editorType === "customEvent") {
        store.dispatch(
          entitiesActions.refreshCustomEventArgs({
            customEventId: entityId,
            scriptEventDefs,
          }),
        );
      }
 
      return result;
    } else Iif (settingsActions.editScriptEventPreset.match(action)) {
      // Fetch values of preset from before change
      // to modify any unchanged uses of the preset
      const state = store.getState();
      const previousArgs =
        state.project.present.settings.scriptEventPresets[action.payload.id]?.[
          action.payload.presetId
        ]?.args ?? {};
      store.dispatch(
        entitiesActions.applyScriptEventPresetChanges({
          ...action.payload,
          previousArgs,
        }),
      );
    } else Iif (settingsActions.removeScriptEventPreset.match(action)) {
      // Fetch values of preset from before change
      // to modify any unchanged uses of the preset
      store.dispatch(
        entitiesActions.removeScriptEventPresetReferences({
          ...action.payload,
        }),
      );
    } else Iif (entitiesActions.removeUnusedPalettes.match(action)) {
      const state = store.getState();
      const eventDefs = selectScriptEventDefs(state);
 
      const paletteIds = state.project.present.entities.palettes.ids;
      const settings = state.project.present.settings;
      const usedPaletteIds = new Set<string>();
 
      const addUsedPaletteIds = (ids: string[]) => {
        ids.forEach((pid) => usedPaletteIds.add(pid));
      };
 
      // Find Palettes referenced by settings
      addUsedPaletteIds(settings.defaultBackgroundPaletteIds);
      addUsedPaletteIds(settings.defaultSpritePaletteIds);
 
      // Find Palettes referenced by Scenes
      for (const sceneId of state.project.present.entities.scenes.ids) {
        const scene = state.project.present.entities.scenes.entities[sceneId];
        const background =
          state.project.present.entities.backgrounds.entities[
            scene.backgroundId
          ];
        if (background?.autoColor) {
          usedPaletteIds.add(scene.paletteIds[7]); // UI Palette
        } else {
          addUsedPaletteIds(scene.paletteIds);
        }
        addUsedPaletteIds(scene.spritePaletteIds);
      }
 
      // Find Palettes referenced by Script Events
      for (const eventId of state.project.present.entities.scriptEvents.ids) {
        const event =
          state.project.present.entities.scriptEvents.entities[eventId];
        const eventDef = eventDefs[event.command];
        if (eventDef) {
          const paletteFieldKeys = Object.values(eventDef.fieldsLookup)
            .filter((f) => f.type === "palette")
            .map((f) => f.key) as string[];
          paletteFieldKeys.forEach((key) => {
            const paletteId = event.args?.[key];
            if (typeof paletteId === "string") {
              usedPaletteIds.add(paletteId);
            }
          });
        }
      }
 
      const unusedPaletteIds = paletteIds.filter(
        (pid) => !usedPaletteIds.has(pid) && !pid.startsWith("default-"),
      );
 
      store.dispatch(
        entitiesActions.removePalettes({
          paletteIds: unusedPaletteIds,
        }),
      );
    }
 
    return next(action);
  };
 
export default entitiesMiddleware;