1.0.1 • Published 6 years ago

@ash9g/redu v1.0.1

Weekly downloads
-
License
MIT
Repository
-
Last release
6 years ago

Some examples:

import {createActionFactory} from "@ash9g/redu";
import {LocDim, DskState, WndState} from "./DskState";
import {AppDescriptor, AppHook} from "./App"

export interface XY {
  x: number
  y: number
}

export const DskActions = {
  SetState: createActionFactory("SetState").payload<{ state: DskState, }>(),

  DskMouseMove: createActionFactory("DskMouseMove").payload<{ xy: XY, }>(),
  DskMouseUp: createActionFactory("DskMouseUp").payload(),

  WndTitleDown: createActionFactory("WndTitleDown").payload<{ wndId: number, xy: XY, }>(),

  WndBorderDown: createActionFactory("WndBorderDown").payload<{ wndId: number, xy: XY, direction: string, }>(),
  WndMouseDown: createActionFactory("WndMouseDown").payload<{ wndId: number }>(),

  WndClose: createActionFactory("WndClose").payload<{ wndId: number }>(),
  WndMax: createActionFactory("WndMax").payload<{ wndId: number }>(),
  WndMin: createActionFactory("WndMin").payload<{ wndId: number }>(),

  IcnRun: createActionFactory("IcnRun").payload<{ appId: string, appProps: any }>(),

  AppStart: createActionFactory("AppStart").payload<{ wnd: WndState,  hook: AppHook}>(),
  AppStop: createActionFactory("AppStop").payload<{ wnd: WndState,  hook: AppHook}>(),
  SetAppProps: createActionFactory("SetAppProps").payload<{wndId: number, appProps: any}>(),

  //TODO ADD TYPE TO ONE OF BELOW
}

export type DskAction =
  typeof DskActions.DskMouseMove.at |
  typeof DskActions.DskMouseUp.at |
  typeof DskActions.WndTitleDown.at |
  typeof DskActions.WndBorderDown.at |
  typeof DskActions.WndMouseDown.at |
  typeof DskActions.WndClose.at |
  // typeof DskActions.WndOpen.at |
  typeof DskActions.WndMax.at |
  typeof DskActions.WndMin.at |
  typeof DskActions.IcnRun.at |
  typeof DskActions.SetState.at |
  typeof DskActions.AppStart.at |
  typeof DskActions.AppStop.at |
  typeof DskActions.SetAppProps.at
import {DskAction, DskActions} from "./DskActions";
import {DskState, DskStateHelp, WndState, LocDim, XY} from "./DskState";
import {createReducerSet} from "ash9g/redu";


const DskReducers = {

  SetStateReducer: DskActions.SetState.reducer<DskState>((s, a) => {
    return a.state
  }),

  DskMouseMoveReducer: DskActions.DskMouseMove.reducer<DskState>((s, a) => {
    if (s.ops.moveeWid != -1) {
      const dx = a.xy.x - s.ops.startPageXY.x
      const dy = a.xy.y - s.ops.startPageXY.y

      const wid = s.ops.moveeWid
      const wnd = s.wnds.wnds.get(wid)
      s = s.setIn(["wnds", "wnds"], s.wnds.wnds.updateIn([wid, "nextLoc"], nl => {
        const x = Math.max(wnd.loc.x + dx, 0)
        const y = Math.max(wnd.loc.y + dy, 0)
        return nl.merge({x, y})
      }))

      return s
    }

    if (s.ops.resizeeWid != -1) {
      const dir = s.ops.resizeDir
      const wid = s.ops.resizeeWid
      const wnd = DskStateHelp.getWndOrNull(s, wid)

      if (dir != "") {
        let mdx = 0
        if (dir != "N" && dir != "S") {
          mdx = a.xy.x - s.ops.startPageXY.x
        }

        let mdy = 0
        if (dir != "E" && dir != "W") {
          mdy = a.xy.y - s.ops.startPageXY.y
        }

        let width: any
        let height: any
        let top: any
        let left: any

        if (dir == "N" || dir == "NE" || dir == "NW") {
          top = (mdy + wnd.loc.y)
          if (top < 0) {
            //If the top goes off the top of screen while resizing 
            //just cap it & height
            top = 0
            height = wnd.loc.y + wnd.loc.height
          } else {
            height = (-mdy + wnd.loc.height)
          }
        } else if (dir == "S" || dir == "SE" || dir == "SW") {
          height = (mdy + wnd.loc.height)
        }

        if (dir == "E" || dir == "NE" || dir == "SE") {
          width = (mdx + wnd.loc.width)
        } else if (dir == "W" || dir == "NW" || dir == "SW") {
          left = (mdx + wnd.loc.x)
          if (left < 0) {
            left = 0
            width = wnd.loc.x + wnd.loc.width
          } else {
            width = (-mdx + wnd.loc.width)
          }

        }

        const heightOk = height != null && !isNaN(height) && height >= 0
        const widthOk = width != null && !isNaN(width) && width >= 0
        const topOk = top != null && !isNaN(top)
        const leftOk = left != null && !isNaN(left)

        let nextLoc = wnd.nextLoc

        if (heightOk) {
          nextLoc = nextLoc.set("height", height)
        }
        if (widthOk) {
          nextLoc = nextLoc.set("width", width)
        }
        if (topOk) {
          nextLoc = nextLoc.set("y", top)
        }
        if (leftOk) {
          nextLoc = nextLoc.set("x", left)
        }

        s = s.setIn(["wnds", "wnds"], s.wnds.wnds.set(wid, wnd.set("nextLoc", nextLoc)))

        return s
      }
    }
    return null
  }),


  DskMouseUpReducer: DskActions.DskMouseUp.reducer<DskState>((s, a) => {

    let ops = s.ops.set("allowSelect", true)

    if (s.ops.moveeWid != -1) {
      const wid = s.ops.moveeWid
      const wnd = DskStateHelp.getWndOrNull(s, wid)

      s = s.setIn(["wnds", "wnds"], s.wnds.wnds.set(wid, wnd.merge({
        moving: false,
        loc: wnd.nextLoc || wnd.loc,
        nextLoc: null,
      })))

      s = s.set("ops", ops.merge({
        moveeWid: -1,
        startPageXY: null,
      }))
    }

    if (s.ops.resizeeWid != -1) {
      const wid = s.ops.resizeeWid
      const wnd = DskStateHelp.getWndOrNull(s, wid)

      s = s.setIn(["wnds", "wnds"], s.wnds.wnds.set(wid, wnd.merge({
        loc: wnd.nextLoc || wnd.loc,
        nextLoc: null,
      })))

      s = s.set("ops", ops.merge({
        resizeeWid: -1,
        resizeDir: "",
        startPageXY: null,
      }))

    }


    return s
  }),

  WndTitleDownReducer: DskActions.WndTitleDown.reducer<DskState>((s, a) => {
    const wid = a.wndId
    const wnd = DskStateHelp.getWndOrNull(s, wid)
    if (wnd != null) {
      let ops = s.ops.set("allowSelect", false)
      s = s.set("ops", ops)

      s = DskStateHelp.raiseWnd(s, wid)

      s = s.setIn(["wnds", "wnds"], s.wnds.wnds.update(wid, w => w.merge({
        moving: true,
        nextLoc: wnd.loc,
      })))

      s = s.set("ops", s.ops.merge({
        moveeWid: wid,
        startPageXY: new XY(a.xy),
      }))
    }
    return s
  }),

  WndBorderDownReducer: DskActions.WndBorderDown.reducer<DskState>((s, a) => {
    const wid = a.wndId
    const wnd = DskStateHelp.getWndOrNull(s, wid)
    if (wnd != null) {
      let ops = s.ops.set("allowSelect", false)
      s = s.set("ops", ops)

      s = DskStateHelp.raiseWnd(s, wid)

      s = s.setIn(["wnds", "wnds"], s.wnds.wnds.update(wid, w => w.merge({
        nextLoc: wnd.loc,
      })))

      s = s.set("ops", s.ops.merge({
        resizeeWid: wid,
        startPageXY: new XY(a.xy),
        resizeDir: a.direction,
      }))
    }
    return s
  }),

  WndDownReducer: DskActions.WndMouseDown.reducer<DskState>((s, a) => {
    return DskStateHelp.raiseWnd(s, a.wndId)
  }),

  WndCloseReducer: DskActions.WndClose.reducer<DskState>((s, a) => {
    return s.set("wnds", s.wnds.set("wnds", s.wnds.wnds.remove(a.wndId)))
  }),

  // WndOpenReducer: DskActions.WndOpen.reducer<DskState>((s, a) => {
  //   console.error("Wndopen no longer supported")
  //   return s
  // }),


  IcnRunReducer: DskActions.IcnRun.reducer<DskState>((s, a) => {
    const app = s.appRegistry.get(a.appId)
    if (app) {
      const appDescriptor = app
      const appProps = a.appProps
      const wndId = s.ops.nextWndId
      const x = 100 + (wndId * 20) % 200
      const y = x
      s = s.setIn(["ops", "nextWndId"], wndId + 1)

      const wnd = new WndState({
        wndId,
        appDescriptor,
        appProps,
        wndTitle: appDescriptor.title,
        loc: new LocDim({
          x, y,
          height: 480,
          width: 640,
        }),
      })
      s = s.setIn(["wnds", "wnds", wndId], wnd)

      s = DskStateHelp.raiseWnd(s, wndId)
    } else {
      console.error(`Unable to locate cmd[${a.appId}] for icn click`)
    }
    return s;
  }),

  SetAppPropsReducer: DskActions.SetAppProps.reducer<DskState>((s, a) => {
    s = DskStateHelp.updateWnd(s, a.wndId, wnd => wnd.set("appProps", a.appProps))
    return s
  })
}


export const DskReducerSet = createReducerSet<DskState, DskAction>(DskReducers)