room groups and grouping.
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
state: Readable<UIState>
|
||||
error: Readable<string | null>
|
||||
deviceList: Readable<Device[]>
|
||||
roomList: Readable<{name: string, devices: Device[]}[]>
|
||||
roomList: Readable<{name: string, groups: {name: string, devices: Device[]}[], devices: Device[]}[]>
|
||||
}
|
||||
|
||||
export function getStateContext(): StateContextData {
|
||||
@@ -44,22 +44,44 @@
|
||||
|
||||
const roomList = derived(state, state => {
|
||||
const roomMap: Record<string, Device[]> = {};
|
||||
const groupMap: Record<string, string> = {};
|
||||
for (const id in state.devices) {
|
||||
if (!state.devices.hasOwnProperty(id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const roomAlias = state.devices[id].aliases.find(a => a.startsWith("lucifer:room:"));
|
||||
const groupAlias = state.devices[id].aliases.find(a => a.startsWith("lucifer:group:"));
|
||||
const roomName = roomAlias?.slice("lucifer:room:".length) || "Unroomed";
|
||||
const groupName = groupAlias?.slice("lucifer:group:".length) || "";
|
||||
|
||||
if (!roomMap[roomName]) {
|
||||
roomMap[roomName] = [];
|
||||
}
|
||||
if (groupAlias) {
|
||||
groupMap[id] = groupName;
|
||||
}
|
||||
|
||||
roomMap[roomName].push(state.devices[id]);
|
||||
}
|
||||
|
||||
return Object.keys(roomMap)
|
||||
.map(k => ({ name: k, devices: roomMap[k] }))
|
||||
.map(k => ({
|
||||
name: k,
|
||||
devices: roomMap[k].filter(d => !groupMap[d.id]).sort((a,b) => a.name.localeCompare(b.name)),
|
||||
groups: roomMap[k].filter(d => !!groupMap[d.id]).reduce<{name: string, devices: Device[]}[]>((p, d) => {
|
||||
const g = p.find(e => e.name === groupMap[d.id]);
|
||||
if (g == null) {
|
||||
p.push({name:groupMap[d.id], devices: [d]})
|
||||
} else {
|
||||
g.devices.push(d);
|
||||
}
|
||||
|
||||
return p;
|
||||
}, [])
|
||||
.map(g => ({...g, devices: g.devices.sort((a,b) => a.name.localeCompare(b.name))}))
|
||||
.sort((a,b) => a.name.localeCompare(b.name))
|
||||
}))
|
||||
.sort((a,b) => a.name.localeCompare(b.name));
|
||||
});
|
||||
|
||||
@@ -83,103 +105,105 @@
|
||||
const currSocket = new WebSocket(url);
|
||||
|
||||
currSocket.onmessage = (msg) => {
|
||||
const patch: UIStatePatch = JSON.parse(msg.data);
|
||||
const patches: UIStatePatch[] = JSON.parse(msg.data);
|
||||
|
||||
state.update(s => {
|
||||
if (patch.device) {
|
||||
if (patch.device.delete) {
|
||||
const devices = {...s.devices};
|
||||
delete devices[patch.device.id];
|
||||
return {...s, devices};
|
||||
} else {
|
||||
return {
|
||||
...s,
|
||||
devices: {
|
||||
...s.devices,
|
||||
[patch.device.id]: ((patch) => {
|
||||
if (patch.addAlias) {
|
||||
const aliases = [...(s.devices[patch.id].aliases || [])];
|
||||
const exclPrefix = ["lucifer:icon:", "lucifer:group:", "lucifer:name:"].find(p => patch.addAlias?.startsWith(p));
|
||||
const exclExisting = exclPrefix && aliases.find(a => a.startsWith(exclPrefix));
|
||||
for (const patch of patches) {
|
||||
if (patch.device) {
|
||||
if (patch.device.delete) {
|
||||
const devices = {...s.devices};
|
||||
delete devices[patch.device.id];
|
||||
s = {...s, devices};
|
||||
} else {
|
||||
s = {
|
||||
...s,
|
||||
devices: {
|
||||
...s.devices,
|
||||
[patch.device.id]: ((patch) => {
|
||||
if (patch.addAlias) {
|
||||
const aliases = [...(s.devices[patch.id].aliases || [])];
|
||||
const exclPrefix = ["lucifer:icon:", "lucifer:group:", "lucifer:name:"].find(p => patch.addAlias?.startsWith(p));
|
||||
const exclExisting = exclPrefix && aliases.find(a => a.startsWith(exclPrefix));
|
||||
|
||||
if (patch.addAlias.startsWith("lucifer:name:")) {
|
||||
patch.name = patch.addAlias.slice("lucifer:name:".length)
|
||||
}
|
||||
if (patch.addAlias.startsWith("lucifer:icon:")) {
|
||||
patch.icon = patch.addAlias.slice("lucifer:icon:".length) as IconName
|
||||
}
|
||||
if (patch.addAlias.startsWith("lucifer:name:")) {
|
||||
patch.name = patch.addAlias.slice("lucifer:name:".length)
|
||||
}
|
||||
if (patch.addAlias.startsWith("lucifer:icon:")) {
|
||||
patch.icon = patch.addAlias.slice("lucifer:icon:".length) as IconName
|
||||
}
|
||||
|
||||
if (exclExisting) {
|
||||
if (exclExisting) {
|
||||
return {
|
||||
...s.devices[patch.id],
|
||||
aliases: [...aliases.filter(a => a != exclExisting), patch.addAlias].sort(),
|
||||
name: patch.name || s.devices[patch.id].name,
|
||||
icon: patch.icon || s.devices[patch.id].icon,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
...s.devices[patch.id],
|
||||
aliases: [...aliases, patch.addAlias].sort(),
|
||||
name: patch.name || s.devices[patch.id].name,
|
||||
icon: patch.icon || s.devices[patch.id].icon,
|
||||
};
|
||||
}
|
||||
} else if (patch.removeAlias != null) {
|
||||
const aliases = [...(s.devices[patch.id].aliases || [])];
|
||||
return {
|
||||
...s.devices[patch.id],
|
||||
aliases: [...aliases.filter(a => a != exclExisting), patch.addAlias].sort(),
|
||||
name: patch.name || s.devices[patch.id].name,
|
||||
icon: patch.icon || s.devices[patch.id].icon,
|
||||
aliases: aliases.filter(a => a !== patch.removeAlias),
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
...s.devices[patch.id],
|
||||
aliases: [...aliases, patch.addAlias].sort(),
|
||||
name: patch.name || s.devices[patch.id].name,
|
||||
icon: patch.icon || s.devices[patch.id].icon,
|
||||
...patch,
|
||||
};
|
||||
}
|
||||
} else if (patch.removeAlias != null) {
|
||||
const aliases = [...(s.devices[patch.id].aliases || [])];
|
||||
return {
|
||||
...s.devices[patch.id],
|
||||
aliases: aliases.filter(a => a !== patch.removeAlias),
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
...s.devices[patch.id],
|
||||
...patch,
|
||||
};
|
||||
})(patch.device)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (patch.assignment) {
|
||||
if (patch.assignment.delete) {
|
||||
const assignments = {...s.assignments};
|
||||
delete assignments[patch.assignment.id];
|
||||
s = {...s, assignments};
|
||||
} else {
|
||||
s = {
|
||||
...s,
|
||||
assignments: {
|
||||
...s.assignments,
|
||||
[patch.assignment.id]: {
|
||||
...s.assignments[patch.assignment.id],
|
||||
...patch.assignment,
|
||||
}
|
||||
})(patch.device)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (patch.assignment) {
|
||||
if (patch.assignment.delete) {
|
||||
const assignments = {...s.assignments};
|
||||
delete assignments[patch.assignment.id];
|
||||
return {...s, assignments};
|
||||
} else {
|
||||
return {
|
||||
...s,
|
||||
assignments: {
|
||||
...s.assignments,
|
||||
[patch.assignment.id]: {
|
||||
...s.assignments[patch.assignment.id],
|
||||
...patch.assignment,
|
||||
if (patch.script) {
|
||||
if (patch.script.delete) {
|
||||
const scripts = {...s.scripts};
|
||||
delete scripts[patch.script.id];
|
||||
s = {...s, scripts};
|
||||
} else {
|
||||
s = {
|
||||
...s,
|
||||
scripts: {
|
||||
...s.scripts,
|
||||
[patch.script.id]: {
|
||||
...s.scripts[patch.script.id],
|
||||
...patch.script,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (patch.script) {
|
||||
if (patch.script.delete) {
|
||||
const scripts = {...s.scripts};
|
||||
delete scripts[patch.script.id];
|
||||
return {...s, scripts};
|
||||
} else {
|
||||
return {
|
||||
...s,
|
||||
scripts: {
|
||||
...s.scripts,
|
||||
[patch.script.id]: {
|
||||
...s.scripts[patch.script.id],
|
||||
...patch.script,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return s;
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user