frontend/smart-hut/src/store.js

148 lines
4.4 KiB
JavaScript
Raw Normal View History

import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
2020-04-07 10:46:55 +00:00
import actions from "./storeActions";
function reducer(previousState, action) {
let newState = Object.assign({}, previousState);
const createOrUpdateRoom = (room) => {
if (!(room.id in newState.rooms)) {
newState.rooms[room.id] = room;
newState.rooms[room.id].devices = new Set();
} else {
newState.rooms[room.id].name = room.name;
newState.rooms[room.id].image = room.image;
newState.rooms[room.id].icon = room.icon;
}
};
switch (action.type) {
case "LOGIN_UPDATE":
newState.login = action.login;
delete newState.errors.login;
break;
case "USER_INFO_UPDATE":
newState.user = action.user;
delete newState.errors.userInfo;
break;
case "ROOMS_UPDATE":
for (const room of action.rooms) {
createOrUpdateRoom(room);
}
delete newState.errors.rooms;
break;
case "DEVICES_UPDATE":
// if room is given, delete all devices in that room
// and remove any join between that room and deleted
// devices
if (action.roomId) {
const room = newState.rooms[action.roomId];
for (const deviceId of room.devices) {
delete newState.devices[deviceId];
}
room.devices = [];
} else if (action.partial) {
// if the update is partial and caused by an operation on an input
// device (like /switch/operate), iteratively remove deleted
// devices and their join with their corresponding room.
for (const device of action.devices) {
const room = newState.rooms[newState.devices[device.id].roomId];
room.devices.delete(device.id);
delete newState.devices[device.id];
}
} else {
// otherwise, just delete all devices and all joins
// between rooms and devices
newState.devices = {};
for (const room of newState.rooms) {
room.devices = [];
}
}
for (const device of action.devices) {
newState.devices[device.id] = device;
if (device.roomId in newState.rooms) {
newState.rooms[device.roomId].devices.add(device.id);
} else {
console.warn(
"Cannot join device",
device,
`in room ${device.roomId} since that
room has not been fetched`
);
}
}
delete newState.errors.devices;
break;
case "ROOM_SAVE":
createOrUpdateRoom(action.room);
break;
case "ROOM_DELETE":
if (!(actions.roomId in newState.rooms)) {
console.warn(`Room to delete ${actions.roomId} does not exist`);
break;
}
// This update does not ensure the consistent update of switchId/dimmerId properties
// on output devices connected to an input device in this room. Please manually request
// all devices again if consistent update is desired
for (const id of newState.rooms[action.roomId].devices) {
delete newState.devices[id];
}
delete newState.rooms[action.roomId];
break;
case "DEVICE_DELETE":
if (!(actions.deviceId in newState.devices)) {
console.warn(`Device to delete ${actions.deviceId} does not exist`);
break;
}
newState.rooms[newState.devices[actions.deviceId].roomId].devices.delete(
actions.deviceId
);
delete newState.devices[actions.deviceId];
break;
case "LOGOUT":
newState.login = { token: null, loggedIn: false };
newState.rooms = [];
newState.devices = [];
delete newState.errors.login;
break;
default:
console.warn(`Action type ${action.type} unknown`, action);
}
console.log("new state: ", newState);
2020-04-07 10:46:55 +00:00
return newState;
}
function createSmartHutStore() {
const token = localStorage.getItem("token");
const exp = localStorage.getItem("exp");
const initialState = {
login: {
token: token,
},
userInfo: null,
/** @type {[integer]Room} */
rooms: {},
/** @type {[integer]Device} */
devices: {},
};
initialState.login.loggedIn = token && exp > new Date().getTime();
if (!initialState.login.loggedIn) {
localStorage.removeItem("token");
localStorage.removeItem("exp");
initialState.login.token = null;
}
return createStore(reducer, initialState, applyMiddleware(thunk));
}
2020-04-07 10:46:55 +00:00
const smartHutStore = createSmartHutStore();
2020-04-07 10:46:55 +00:00
export default smartHutStore;