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 | import { combineReducers, UnknownAction, Action } from "@reduxjs/toolkit"; import undoable from "redux-undo"; import { TRACKER_REDO, TRACKER_UNDO } from "consts"; import clipboard from "store/features/clipboard/clipboardState"; import editor from "store/features/editor/editorState"; import music from "store/features/music/musicState"; import navigation from "store/features/navigation/navigationState"; import tracker from "store/features/tracker/trackerState"; import trackerDocument from "store/features/trackerDocument/trackerDocumentState"; import { musicAssetsReducer } from "./features/musicAssets/musicAssetsState"; let lastTrackerUndoStateTime = 0; const UNDO_THROTTLE = 300; const makeStaticUndoReducer = <TState, TAction extends Action = UnknownAction>( innerReducer: (state: TState | undefined, action: TAction) => TState, ) => ( state: | { past: TState[]; present: TState; future: TState[]; } | undefined, action: TAction, ) => { const present = innerReducer(state?.present, action); return { past: state?.past ?? [], present, future: state?.future ?? [], }; }; const noopReducer = <T>(initialState: T) => (state: T = initialState): T => state; const entitiesReducer = combineReducers({ music: musicAssetsReducer, backgrounds: noopReducer({ ids: [], entities: {} }), scenes: noopReducer({ ids: [], entities: {} }), spriteSheets: noopReducer({ ids: [], entities: {} }), palettes: noopReducer({ ids: [], entities: {} }), customEvents: noopReducer({ ids: [], entities: {} }), sounds: noopReducer({ ids: [], entities: {} }), fonts: noopReducer({ ids: [], entities: {} }), avatars: noopReducer({ ids: [], entities: {} }), emotes: noopReducer({ ids: [], entities: {} }), actorPrefabs: noopReducer({ ids: [], entities: {} }), triggerPrefabs: noopReducer({ ids: [], entities: {} }), }); const projectPresentReducer = combineReducers({ entities: entitiesReducer, settings: noopReducer({}), metadata: noopReducer({}), }); const projectReducer = makeStaticUndoReducer(projectPresentReducer); const rootReducer = combineReducers({ editor, clipboard, music, navigation, tracker, musicAssets: musicAssetsReducer, project: projectReducer, trackerDocument: undoable(trackerDocument, { limit: 20, initTypes: [ "trackerDocument/loadSong/pending", "trackerDocument/unloadSong", ], filter: (action, currentState, previousHistory) => { Iif ( action.type.startsWith("trackerDocument/loadSong/fulfilled") || action.type.startsWith("trackerDocument/addSequence") || action.type.startsWith("trackerDocument/removeSequence") ) { return true; } const shouldStoreUndo = currentState !== previousHistory.present && Date.now() > lastTrackerUndoStateTime + UNDO_THROTTLE; Iif (!shouldStoreUndo) { return false; } lastTrackerUndoStateTime = Date.now(); return ( action.type.startsWith("trackerDocument/") && !action.type.startsWith("trackerDocument/loadSong") && !action.type.startsWith("trackerDocument/saveSong") && !action.type.startsWith("trackerDocument/addNewSong") && !action.type.startsWith("trackerDocument/requestAddNewSong") && !action.type.startsWith("trackerDocument/setSongFilename") ); }, ignoreInitialState: true, undoType: TRACKER_UNDO, redoType: TRACKER_REDO, }), }); export default rootReducer; |