Socket update handling done except deletion messages, currently not implemented in the server side

This commit is contained in:
Claudio Maggioni (maggicl) 2020-05-03 19:51:00 +02:00
parent c7dc34eedc
commit 770469ade3
6 changed files with 74 additions and 17 deletions

View file

@ -5,21 +5,17 @@ import { Card, Segment, Header, Icon } from "semantic-ui-react";
import Device from "../../components/dashboard/devices/Device"; import Device from "../../components/dashboard/devices/Device";
class HostsPanel extends Component { class HostsPanel extends Component {
constructor(props) {
super(props);
}
componentDidUpdate(oldProps) { componentDidUpdate(oldProps) {
if ( if (
oldProps.activeHost !== this.props.activeHost && oldProps.activeHost !== this.props.activeHost &&
this.props.activeHost !== -1 this.props.activeHost !== -1
) { ) {
this.props.fetchDevices(null, this.props.activeHost).catch(console.error); this.props.fetchDevices(null, this.props.activeHost).catch(console.error);
this.props.fetchAllRooms(this.props.activeHost).catch(console.error);
} }
} }
render() { render() {
console.log(this.props.hostDevices);
return ( return (
<Card.Group centered style={{ paddingTop: "3rem" }}> <Card.Group centered style={{ paddingTop: "3rem" }}>
{this.props.isActiveDefaultHost && ( {this.props.isActiveDefaultHost && (

View file

@ -130,7 +130,7 @@ class Thermostats extends Component {
) : null} ) : null}
<div style={stateTagContainer}> <div style={stateTagContainer}>
<span style={stateTag}> <span style={stateTag}>
{this.props.tab === "Devices" {this.props.tab !== "Scenes"
? this.props.device.mode ? this.props.device.mode
: this.props.stateOrDevice.on : this.props.stateOrDevice.on
? "WILL TURN ON" ? "WILL TURN ON"

View file

@ -31,7 +31,11 @@ function getRoomName(state, ownProps) {
case "Devices": case "Devices":
return (state.rooms[getDevice(state, ownProps).roomId] || {}).name; return (state.rooms[getDevice(state, ownProps).roomId] || {}).name;
case "Hosts": case "Hosts":
return "Room Name not implemented yet"; const hostRooms = state.hostRooms[ownProps.hostId];
if (!hostRooms) return "";
const room = hostRooms[getDevice(state, ownProps).roomId];
if (!room) return "";
return room.name;
default: default:
throw new Error( throw new Error(
`room name has no value in tab "${state.active.activeTab}"` `room name has no value in tab "${state.active.activeTab}"`

View file

@ -261,13 +261,22 @@ export const RemoteService = {
/** /**
* Fetches all rooms that belong to this user. This call does not * Fetches all rooms that belong to this user. This call does not
* populate the devices attribute in rooms. * populate the devices attribute in rooms.
* @param {Number|null} hostId the user id of the host we need to fetch the rooms from.
* Null if we need to fetch our own rooms.
* @returns {Promise<Undefined, RemoteError>} promise that resolves to void and rejects * @returns {Promise<Undefined, RemoteError>} promise that resolves to void and rejects
* with user-fiendly errors as a RemoteError * with user-fiendly errors as a RemoteError
*/ */
fetchAllRooms: () => { fetchAllRooms: (hostId = null) => {
return (dispatch) => { return (dispatch) => {
return Endpoint.get("/room") return Endpoint.get("/room", hostId ? { hostId } : null)
.then((res) => void dispatch(actions.roomsUpdate(res.data))) .then(
(res) =>
void dispatch(
hostId
? actions.hostRoomsUpdate(hostId, res.data)
: actions.roomsUpdate(res.data)
)
)
.catch((err) => { .catch((err) => {
console.error("Fetch all rooms error", err); console.error("Fetch all rooms error", err);
throw new RemoteError(["Network error"]); throw new RemoteError(["Network error"]);

View file

@ -99,6 +99,20 @@ function reducer(previousState, action) {
createOrUpdateRoom(room); createOrUpdateRoom(room);
} }
break; break;
case "HOST_ROOMS_UPDATE":
change = {
hostRooms: {
[action.hostId]: { $set: {} },
},
};
const rooms = change.hostRooms[action.hostId].$set;
for (const room of action.rooms) {
rooms[room.id] = room;
}
newState = update(previousState, change);
break;
case "SCENES_UPDATE": case "SCENES_UPDATE":
newState = previousState; newState = previousState;
for (const scene of action.scenes) { for (const scene of action.scenes) {
@ -256,18 +270,25 @@ function reducer(previousState, action) {
newState = update(newState, change); newState = update(newState, change);
break; break;
case "HOST_DEVICES_UPDATE": case "HOST_DEVICES_UPDATE":
newState = action.partial
? previousState
: update(previousState, {
hostDevices: { [action.hostId]: { $set: {} } },
});
newState.hostDevices[action.hostId] =
newState.hostDevices[action.hostId] || {};
change = { change = {
hostDevices: { hostDevices: {
[action.hostId]: { $set: {} }, [action.hostId]: {},
}, },
}; };
const deviceMap = change.hostDevices[action.hostId].$set; const deviceMap = change.hostDevices[action.hostId];
for (const device of action.devices) { for (const device of action.devices) {
deviceMap[device.id] = device; deviceMap[device.id] = { $set: device };
} }
newState = update(previousState, change); newState = update(newState, change);
break; break;
case "AUTOMATION_UPDATE": case "AUTOMATION_UPDATE":
const automations = {}; const automations = {};
@ -456,14 +477,34 @@ function reducer(previousState, action) {
}); });
break; break;
case "REDUX_WEBSOCKET::MESSAGE": case "REDUX_WEBSOCKET::MESSAGE":
const devices = JSON.parse(action.payload.message); const allDevices = JSON.parse(action.payload.message);
//console.log("socket", JSON.stringify(devices, null, 2)); const devices = allDevices.filter(
(d) =>
(d.fromHostId === null || d.fromHostId === undefined) && !d.deleted
);
const hostDevicesMapByHostId = allDevices
.filter((d) => d.fromHostId && !d.deleted)
.reduce((a, e) => {
const hostId = e.fromHostId;
//delete e.fromHostId;
a[hostId] = a[hostId] || [];
a[hostId].push(e);
return a;
}, {});
newState = reducer(previousState, { newState = reducer(previousState, {
type: "DEVICES_UPDATE", type: "DEVICES_UPDATE",
partial: true, partial: true,
devices, devices,
}); });
for (const hostId in hostDevicesMapByHostId) {
newState = reducer(newState, {
type: "HOST_DEVICES_UPDATE",
devices: hostDevicesMapByHostId[hostId],
partial: true,
hostId,
});
}
break; break;
case "HG_UPDATE": case "HG_UPDATE":
newState = update(previousState, { newState = update(previousState, {
@ -509,8 +550,10 @@ const initState = {
guests: [], guests: [],
/** @type {User[]} */ /** @type {User[]} */
hosts: [], hosts: [],
/** @type {[integer]HostDevice} */ /** @type {[integer]Device} */
hostDevices: {}, hostDevices: {},
/** @type {[integer]Eoom} */
hostRooms: {},
}; };
function createSmartHutStore() { function createSmartHutStore() {

View file

@ -76,6 +76,11 @@ const actions = {
type: "ROOMS_UPDATE", type: "ROOMS_UPDATE",
rooms, rooms,
}), }),
hostRoomsUpdate: (hostId, rooms) => ({
type: "HOST_ROOMS_UPDATE",
hostId,
rooms,
}),
roomDelete: (roomId) => ({ roomDelete: (roomId) => ({
type: "ROOM_DELETE", type: "ROOM_DELETE",
roomId, roomId,