diff --git a/src/app/ReactDockableApp.tsx b/src/app/ReactDockableApp.tsx index 5c44c54..63b641b 100644 --- a/src/app/ReactDockableApp.tsx +++ b/src/app/ReactDockableApp.tsx @@ -1,4 +1,4 @@ -import React, {useState /*, useReducer*/} from 'react'; +import React, {useState, useReducer} from 'react'; import {createRoot} from 'react-dom/client'; import {PanelState} from 'react-dockable-ts'; @@ -22,7 +22,12 @@ import { import {mapMaker} from './breaditor/documents/MapDocument'; import {textMaker} from './breaditor/documents/TextDocument'; import {spriteMaker} from './breaditor/documents/SpriteDocument'; -import {TOOLS} from './breaditor/tools/constants'; +// import {TOOLS} from './breaditor/tools/constants'; + +import { + breaditorReducer, + getInitialState, +} from './state-management/in-memory/main_reducer'; import {DocumentInfo, WidgetInfo} from '../../types/global'; @@ -192,6 +197,12 @@ function getDocumentState() { } function App() { + const [state, dispatch] = useReducer(breaditorReducer, getInitialState()); + + if (dispatch == undefined) { + console.info(state); + } + const [panelState, setPanelState] = useState( createInitialPanelState(), ); @@ -225,9 +236,7 @@ function App() { data-testid="breaditor-browser-app" > { - console.log('I am a fake dispatch in ReactDockableApp. Yay.', foo); - }} + dispatch={dispatch} widgets={getCurrentPanels()} hidden={ { @@ -237,11 +246,8 @@ function App() { getMenu={getMenu} /> { - console.log('Another fake dispatch that was passed: ', bar); - }} - tool={TOOLS.Brush} + state={{tool: {activeTool: 0}}} + dispatch={dispatch} view={{}} />
- { - console.log('A fake dispatch that was passed: ', foo); - }} - /> +
- + ); diff --git a/src/app/layout/components/MenuBar.tsx b/src/app/layout/components/MenuBar.tsx index 05b698f..48732ad 100644 --- a/src/app/layout/components/MenuBar.tsx +++ b/src/app/layout/components/MenuBar.tsx @@ -10,7 +10,7 @@ import css from './MenuBar.module.css'; interface MenuBarProps { dispatch: ({}: any) => void; widgets: WidgetInfo[]; - hidden: {}; + hidden: any; getMenu: () => any; } diff --git a/src/app/layout/components/PropertyBar.tsx b/src/app/layout/components/PropertyBar.tsx index b4424c1..25af211 100644 --- a/src/app/layout/components/PropertyBar.tsx +++ b/src/app/layout/components/PropertyBar.tsx @@ -9,18 +9,35 @@ import css from './PropertyBar.module.css'; import * as icons from '../../ui/icons'; +// interface BrushToolState {} + +interface PropertyBarState { + tool: { + activeTool: number; + brush?: any; //BrushToolState; + }; +} + interface PropertyBarProps { dispatch: ({}: any) => void; - state: {}; - tool: {}; - view: {}; + state: PropertyBarState; + view: any; } const PropertyBar: React.FC = (props) => { function getProperties() { - switch (props.tool) { + const {activeTool} = props.state.tool; + const {dispatch, state, view} = props; + + switch (activeTool) { case TOOLS.Brush: - return ; + return ( + + ); /* case TOOLS.Zoom: return ; @@ -77,7 +94,7 @@ interface BrushPropertiesProps { } const BrushProperties: React.FC = (props) => { let brush: BrushToolProps; - if (props.state.brush) { + if (props.state && props.state.brush) { brush = props.state.brush; } else { brush = { diff --git a/src/app/layout/components/StatusBar.tsx b/src/app/layout/components/StatusBar.tsx index 4140d3c..cc90198 100644 --- a/src/app/layout/components/StatusBar.tsx +++ b/src/app/layout/components/StatusBar.tsx @@ -6,6 +6,7 @@ import css from './PropertyBar.module.css'; interface StatusBarProps { initialStatuses: string[]; + dispatch: ({}: any) => void; } let _stateUpdate = (data: any) => { diff --git a/src/app/state-management/in-memory/main_reducer.ts b/src/app/state-management/in-memory/main_reducer.ts new file mode 100644 index 0000000..7e12500 --- /dev/null +++ b/src/app/state-management/in-memory/main_reducer.ts @@ -0,0 +1,32 @@ +import {createReducer} from './reducer.inc'; +import {toolsReducer} from './reducers/tools.reducer'; + +//import documentsReducer from './reducers/documents.reducer.js'; +//import workspaceReducer from './reducers/workspace.reducer.js'; + +//import widgetsReducer from './reducers/widgets.reducer.js'; + +const breaditorReducer = createReducer( + {}, + { + foo: createReducer( + {}, + { + FOO_ACTION: (state: any, action: any) => { + return {...state, a: state.a + action.foo}; + }, + }, + ), + //tools: toolsReducer, + }, +); + +const taco = function () { + toolsReducer; +}; + +const getInitialState = function () { + return breaditorReducer({}, {action: 'INITIALIZE_STATE'}); +}; + +export {breaditorReducer, getInitialState, createReducer, taco}; diff --git a/src/app/state-management/in-memory/reducer.inc.ts b/src/app/state-management/in-memory/reducer.inc.ts new file mode 100644 index 0000000..ab7509f --- /dev/null +++ b/src/app/state-management/in-memory/reducer.inc.ts @@ -0,0 +1,37 @@ +type StringToAnyMap = {[key: string]: any}; +type GenericState = StringToAnyMap; + +type GenericAction = { + [key: string]: any; + type: string; +}; + +type ReducerMap = { + [key: string]: (state: S, action: A) => S; +}; + +type Reducer = (state?: S, action?: A) => S; + +function createReducer( + initialState: S, + handlers: ReducerMap, +): Reducer { + const myHandlers = handlers; + const myInitialState = initialState; + + return function (state: S = myInitialState, action?: A): S { + if (action == null) { + return myInitialState; + } else { + if (action && myHandlers.hasOwnProperty(action.type)) { + return myHandlers[action.type](state, action); + } else { + // console.error(`Unhandled action: ${action.type} `); + } + return state; + } + }; +} + +export type {StringToAnyMap, Reducer}; +export {createReducer}; diff --git a/src/app/state-management/in-memory/reducer.ts b/src/app/state-management/in-memory/reducer.ts deleted file mode 100644 index 11beb90..0000000 --- a/src/app/state-management/in-memory/reducer.ts +++ /dev/null @@ -1,16 +0,0 @@ -//import documentsReducer from './reducers/documents.reducer.js'; -//import workspaceReducer from './reducers/workspace.reducer.js'; -//import toolsReducer from './reducers/tools.reducer.js'; -//import widgetsReducer from './reducers/widgets.reducer.js'; - -export default function reducer(state: any, action: any, ...rest: any[]) { - console.log(state, action, rest); - return { - // tools: toolsReducer(state && state.tools, action, ...rest), - // documents: documentsReducer(state && state.documents, action, ...rest), - // workspace: workspaceReducer(state && state.workspace, action, ...rest), - // widgets: widgetsReducer(state && state.widgets, action, ...rest), - }; -} - -export {reducer}; diff --git a/src/app/state-management/in-memory/reducers/tools.reducer.test.ts b/src/app/state-management/in-memory/reducers/tools.reducer.test.ts new file mode 100644 index 0000000..77424ce --- /dev/null +++ b/src/app/state-management/in-memory/reducers/tools.reducer.test.ts @@ -0,0 +1,24 @@ +import { + toolsReducer, + initialToolState, + /*Reducer /*GenericAction, Reducer*/ +} from './tools.reducer'; + +test('toolsReducer INIT', () => { + const result = toolsReducer(); + + expect(result.a).toBe(0); + expect(result.b).toBe(0); +}); + +test('toolsReducer INC_A', () => { + const result = toolsReducer(initialToolState, {type: 'INC_A', foo: 2}); + + expect(result.a).toBe(2); +}); + +test('toolsReducer INC_A', () => { + const result = toolsReducer(initialToolState, {type: 'INC_B', bar: 7}); + + expect(result.b).toBe(7); +}); diff --git a/src/app/state-management/in-memory/reducers/tools.reducer.ts b/src/app/state-management/in-memory/reducers/tools.reducer.ts new file mode 100644 index 0000000..8ba152c --- /dev/null +++ b/src/app/state-management/in-memory/reducers/tools.reducer.ts @@ -0,0 +1,47 @@ +import { + createReducer, + Reducer /*GenericAction, Reducer*/, +} from '../reducer.inc'; + +import {TOOLS} from '../../../breaditor/tools/constants'; //TODO: This should be in *THIS* file, right? +// TODO: and should have a concrete union type I think? + +interface ToolState { + activeTool: number; // Tool index, really + tool: any; // how to type this? + a: number; + b: number; +} + +interface ToolActionIncA { + foo: number; + type: 'INC_A'; +} + +interface ToolActionIncB { + bar: number; + type: 'INC_B'; +} + +type ToolAction = ToolActionIncA | ToolActionIncB; + +const initialToolState: ToolState = { + activeTool: TOOLS.Brush, + tool: {}, + a: 0, + b: 0, +}; + +const toolsReducer: Reducer = createReducer( + initialToolState, + { + INC_A: (state, action: ToolActionIncA) => { + return {...state, a: state.a + action.foo}; + }, + INC_B: (state, action: ToolActionIncB) => { + return {...state, b: state.b + action.bar}; + }, + }, +); + +export {initialToolState, toolsReducer}; diff --git a/src/app/state-management/in-memory/store.tsx b/src/app/state-management/in-memory/store.tsx index b86dc85..9486356 100644 --- a/src/app/state-management/in-memory/store.tsx +++ b/src/app/state-management/in-memory/store.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import reducer from './reducer.js'; +import reducer from './main_reducer.js'; class Store { state = reducer(null, {}); // initialize?