@ash9g/redu
v1.0.1
Published
Strongly typed typescript helpers for redux
Downloads
7
Maintainers
Readme
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)