148 lines
4.4 KiB
JavaScript
148 lines
4.4 KiB
JavaScript
import { createStore, applyMiddleware } from "redux";
|
|
import thunk from "redux-thunk";
|
|
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);
|
|
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));
|
|
}
|
|
|
|
const smartHutStore = createSmartHutStore();
|
|
export default smartHutStore;
|