ui stuff from laptop
This commit is contained in:
Generated
+3481
File diff suppressed because it is too large
Load Diff
@@ -19,8 +19,10 @@
|
||||
"eslint": "^8.28.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-svelte3": "^4.0.0",
|
||||
"node-sass": "^8.0.0",
|
||||
"prettier": "^2.8.0",
|
||||
"prettier-plugin-svelte": "^2.8.1",
|
||||
"sass": "^1.57.1",
|
||||
"svelte": "^3.54.0",
|
||||
"svelte-check": "^2.9.2",
|
||||
"tslib": "^2.4.1",
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import type UIState from "$lib/models/uistate";
|
||||
|
||||
export default async function fetchLucifer<T>(path: string, init?: RequestInit): Promise<T> {
|
||||
const url = import.meta.env.VITE_LUCIFER4_BACKEND_URL + "/" + path;
|
||||
console.log(url);
|
||||
|
||||
const res = await fetch(url, init);
|
||||
if (res.status !== 200) {
|
||||
if (res.headers.get("Content-Type")?.includes("application/json")) {
|
||||
throw await res.json();
|
||||
} else {
|
||||
throw await res.text();
|
||||
}
|
||||
}
|
||||
|
||||
const json = await res.json();
|
||||
|
||||
return json as T;
|
||||
}
|
||||
|
||||
export async function fetchUIState(): Promise<UIState> {
|
||||
return fetchLucifer("state");
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<script lang="ts">
|
||||
import { rgbString } from "$lib/models/color";
|
||||
import type { Palette } from "$lib/models/palette";
|
||||
|
||||
export let palette: Palette
|
||||
</script>
|
||||
|
||||
<div class="palette">
|
||||
{#each palette as p (p.value)}
|
||||
<div title={p.label} class="color" style="background-color: {rgbString(p.rgb)}"></div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<style lang="sass">
|
||||
div.palette
|
||||
display: flex
|
||||
flex-direction: row
|
||||
|
||||
div.color
|
||||
margin: 0.05em
|
||||
width: 1ch
|
||||
height: 0.5em
|
||||
</style>
|
||||
@@ -1,76 +1,162 @@
|
||||
<script lang="ts">
|
||||
import type { ColorRGB } from "../models/color";
|
||||
import { getSelectedContext } from "$lib/contexts/SelectContext.svelte";
|
||||
import type Device from "$lib/models/device";
|
||||
import { SupportFlags } from "$lib/models/device";
|
||||
import { rgb, type ColorRGB } from "../models/color";
|
||||
|
||||
export let selected: boolean = false;
|
||||
export let title: string;
|
||||
export let color: ColorRGB;
|
||||
export let intensity: number;
|
||||
export let device: Device;
|
||||
|
||||
const {selectedMap, toggleSelection} = getSelectedContext();
|
||||
|
||||
function onSelect() {
|
||||
toggleSelection(device.id);
|
||||
}
|
||||
|
||||
// Process device
|
||||
let deviceTitle: string;
|
||||
let iconColor: ColorRGB | null;
|
||||
let barColor: ColorRGB | null;
|
||||
let barPercentage: number | null;
|
||||
let roundboiText: string | null;
|
||||
$: {
|
||||
// TODO: Fix device.name on the backend
|
||||
const nameAlias = device.aliases.find(a => a.startsWith("lucifer:name:"));
|
||||
if (nameAlias != null) {
|
||||
deviceTitle = nameAlias.slice("lucifer:name:".length);
|
||||
} else {
|
||||
deviceTitle = "";
|
||||
}
|
||||
|
||||
barPercentage = null;
|
||||
barColor = null;
|
||||
iconColor = null;
|
||||
|
||||
if (device.hwState) {
|
||||
const hws = device.hwState;
|
||||
const sflags = hws.supportFlags;
|
||||
|
||||
if (deviceTitle == "") {
|
||||
deviceTitle = device.hwState.internalName;
|
||||
}
|
||||
|
||||
if (sflags & SupportFlags.Color) {
|
||||
iconColor = device.activeColorRgb;
|
||||
} else {
|
||||
iconColor = null;
|
||||
}
|
||||
|
||||
if (sflags & SupportFlags.SensorPresence) {
|
||||
barColor = rgb(0.5,0.5,0.5);
|
||||
barPercentage = Math.max(0, (300 - (device.sensors.lastMotion||300))/300) * 100;
|
||||
}
|
||||
|
||||
if (sflags & SupportFlags.Temperature) {
|
||||
barColor = rgb(1.000,0.2,0.2);
|
||||
barPercentage = Math.min(1, Math.max(0, (device.desiredState.temperature||0) - 5) / 35) * 100;
|
||||
}
|
||||
|
||||
if (sflags & SupportFlags.Intensity) {
|
||||
if (sflags & SupportFlags.Color) {
|
||||
barColor = device.activeColorRgb;
|
||||
} else {
|
||||
barColor = rgb(1.000,0.671,0.355);
|
||||
}
|
||||
|
||||
barPercentage = device.desiredState.intensity;
|
||||
}
|
||||
|
||||
if (sflags & SupportFlags.SensorTemperature && !!device.sensors.temperature) {
|
||||
roundboiText = `${device.sensors.temperature.toFixed(0)}°`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make title visible
|
||||
let displayTitle: string;
|
||||
$: {
|
||||
if (title.length > 12) {
|
||||
let last = title.split(" ").pop() || title;
|
||||
if (deviceTitle.length > 12) {
|
||||
let last = deviceTitle.split(" ").pop() || deviceTitle;
|
||||
if (last.length > 4) {
|
||||
last = last.slice(-3);
|
||||
}
|
||||
|
||||
displayTitle = `${(title.split(" ").shift()||"").slice(0, 10 - last.length)}... ${last}`
|
||||
displayTitle = `${(deviceTitle.split(" ").shift()||"").slice(0, 10 - last.length)}... ${last}`
|
||||
} else {
|
||||
displayTitle = title;
|
||||
displayTitle = deviceTitle;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="lamp" class:selected>
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<div class="lamp" class:selected={$selectedMap[device.id]} on:click={onSelect}>
|
||||
<div class="row">
|
||||
<div style="background-color: rgb({color.red*255},{color.green*255},{color.blue*255})" class="roundboi"></div>
|
||||
{#if iconColor != null}
|
||||
<div style="background-color: rgb({iconColor.red*255},{iconColor.green*255},{iconColor.blue*255})" class="roundboi"></div>
|
||||
{:else}
|
||||
<div style="background-color: #223)" class="roundboi">
|
||||
{#if !!roundboiText}
|
||||
<div class="roundboi-text">{roundboiText}</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="title">{displayTitle}</div>
|
||||
</div>
|
||||
<div class="flatboi">
|
||||
<div style="width: {intensity*100}%; background-color: rgb({color.red*255},{color.green*255},{color.blue*255})" class="flatboi2"></div>
|
||||
{#if barColor != null && barPercentage != null}
|
||||
<div style="width: {barPercentage*100}%; background-color: rgb({barColor.red*255},{barColor.green*255},{barColor.blue*255})" class="flatboi2"></div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
div.lamp {
|
||||
width: 15ch;
|
||||
height: 2em;
|
||||
margin: 0.25em;
|
||||
background: #18181c;
|
||||
color: #84888f;
|
||||
border-radius: 0.25em;
|
||||
border-top-right-radius: 1em;
|
||||
overflow: hidden;
|
||||
}
|
||||
div.lamp.selected {
|
||||
background: #282833;
|
||||
color: #cde;
|
||||
}
|
||||
div.lamp > div.row {
|
||||
display: flex;
|
||||
}
|
||||
div.lamp > div.row > div.roundboi {
|
||||
width: 1.25em;
|
||||
height: 1.25em;
|
||||
margin-left: 0.25em;
|
||||
margin-top: 0.30em;
|
||||
border-radius: 2em;
|
||||
box-sizing: border-box;
|
||||
border: 0.5px solid #000;
|
||||
}
|
||||
div.lamp > div.row > div.title {
|
||||
font-size: 0.9em;
|
||||
text-align: left;
|
||||
margin-top: 0.4em;
|
||||
margin-left: 0.75ch;
|
||||
margin-right: 1ch;
|
||||
height: 1.6em;
|
||||
}
|
||||
div.lamp > div.flatboi {
|
||||
height: 0.2em;
|
||||
background-color: #040408;
|
||||
}
|
||||
div.lamp > div.flatboi > div.flatboi2 {
|
||||
height: 0.2em;
|
||||
}
|
||||
<style lang="sass">
|
||||
div.lamp
|
||||
cursor: pointer
|
||||
width: 19ch
|
||||
height: 2em
|
||||
margin: 0.25em
|
||||
background: #18181c
|
||||
color: #84888f
|
||||
border-radius: 0.25em
|
||||
border-top-right-radius: 1em
|
||||
overflow: hidden
|
||||
box-shadow: 1px 1px 1px #000
|
||||
|
||||
@media screen and (max-width: 700px)
|
||||
width: 100%
|
||||
|
||||
&.selected
|
||||
background: #282833
|
||||
color: #cde
|
||||
|
||||
> div.row
|
||||
display: flex
|
||||
|
||||
> div.roundboi
|
||||
width: 1.25em
|
||||
height: 1.25em
|
||||
margin-left: 0.25em
|
||||
margin-top: 0.30em
|
||||
border-radius: 2em
|
||||
box-sizing: border-box
|
||||
border: 0.5px solid #000
|
||||
|
||||
> div.roundboi-text
|
||||
color: #abc
|
||||
margin-top: 0.2em
|
||||
font-size: 0.8em
|
||||
|
||||
> div.title
|
||||
font-size: 0.9em
|
||||
text-align: left
|
||||
margin-top: 0.4em
|
||||
margin-left: 0.75ch
|
||||
margin-right: 1ch
|
||||
height: 1.6em
|
||||
|
||||
> div.flatboi
|
||||
height: 0.2em
|
||||
|
||||
> div.flatboi2
|
||||
height: 0.2em
|
||||
</style>
|
||||
@@ -0,0 +1,75 @@
|
||||
<script lang="ts">
|
||||
import { getSelectedContext } from "$lib/contexts/SelectContext.svelte";
|
||||
import { getStateContext } from "$lib/contexts/StateContext.svelte";
|
||||
import type Device from "$lib/models/device";
|
||||
import { KELVIN_PALETTE, RGB_PALETTE } from "$lib/models/palette";
|
||||
import ColorPalette from "./ColorPalette.svelte";
|
||||
|
||||
const {deviceList} = getStateContext();
|
||||
const {selectedMap} = getSelectedContext();
|
||||
|
||||
let selected: Device[];
|
||||
let unselected: Device[];
|
||||
$: selected = $deviceList.filter(d => !!$selectedMap[d.id]);
|
||||
$: unselected = $deviceList.filter(d => !$selectedMap[d.id]);
|
||||
|
||||
let assignment: string;
|
||||
$: {
|
||||
assignment = "";
|
||||
if (selected.length > 0) {
|
||||
for (const alias of selected[0].aliases) {
|
||||
if (!selected.find(d => !d.aliases.includes(alias)) && !unselected.find(d => d.aliases.includes(alias))) {
|
||||
assignment = alias;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (assignment === "") {
|
||||
if (selected.length == 1) {
|
||||
assignment = selected[0].id;
|
||||
} else {
|
||||
let prefix = selected[0].id;
|
||||
for (const device of selected) {
|
||||
for (let i = 0; i < prefix.length; i++) {
|
||||
if (device.id.charAt(i) !== prefix.charAt(i)) {
|
||||
prefix = prefix.slice(0, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (prefix.length > 0) {
|
||||
assignment = `${prefix}{${selected.map(d => d.id.slice(prefix.length)).join("|")}}`
|
||||
}
|
||||
}
|
||||
|
||||
if (assignment === "") {
|
||||
assignment = `{${selected.map(d => d.id).join("|")}}`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="toolbar">
|
||||
<ColorPalette palette={RGB_PALETTE} />
|
||||
</div>
|
||||
|
||||
<style lang="sass">
|
||||
div.toolbar
|
||||
position: fixed
|
||||
bottom: 0
|
||||
|
||||
width: 100%
|
||||
height: 2em
|
||||
padding: 0.35em 1ch
|
||||
box-sizing: border-box
|
||||
font-size: 1.5em
|
||||
background: #18181c
|
||||
color: #abc
|
||||
box-shadow: 1px 1px 1px #000
|
||||
|
||||
display: flex
|
||||
flex-direction: row
|
||||
flex-wrap: wrap
|
||||
</style>
|
||||
@@ -0,0 +1,54 @@
|
||||
<script lang="ts" context="module">
|
||||
import { getContext, setContext } from "svelte";
|
||||
import { writable, type Readable } from "svelte/store";
|
||||
import { getStateContext } from "./StateContext.svelte";
|
||||
|
||||
const ctxKey = {ctx: "SelectContext"};
|
||||
|
||||
export interface SelectContextData {
|
||||
toggleSelection(id: string): void
|
||||
selectedList: Readable<string[]>
|
||||
selectedMap: Readable<{[id:string]: boolean}>
|
||||
}
|
||||
|
||||
export function getSelectedContext(): SelectContextData {
|
||||
return getContext(ctxKey) as SelectContextData;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
const selectedList = writable<string[]>([]);
|
||||
const selectedMap = writable<{[id:string]: boolean}>({});
|
||||
|
||||
const {state} = getStateContext();
|
||||
|
||||
function toggleSelection(id: string) {
|
||||
selectedMap.update(m => ({...m, [id]: !m[id]}));
|
||||
}
|
||||
|
||||
// Effect: remove non-existent devices
|
||||
$: {
|
||||
const newMap = {...$selectedMap};
|
||||
for (const id in newMap) {
|
||||
if (!Object.hasOwn(newMap, id)) {
|
||||
continue;
|
||||
}
|
||||
if (!$state?.devices[id]) {
|
||||
delete newMap[id];
|
||||
}
|
||||
}
|
||||
|
||||
$selectedMap = newMap;
|
||||
}
|
||||
|
||||
// Effect: sync list
|
||||
$: $selectedList = Object.keys($selectedMap).filter(id => !!$selectedMap[id]);
|
||||
|
||||
setContext(ctxKey, {
|
||||
selectedList: {subscribe: selectedList.subscribe},
|
||||
selectedMap: {subscribe: selectedMap.subscribe},
|
||||
toggleSelection,
|
||||
});
|
||||
</script>
|
||||
|
||||
<slot></slot>
|
||||
@@ -0,0 +1,57 @@
|
||||
<script lang="ts" context="module">
|
||||
import { fetchUIState } from "$lib/client/lucifer";
|
||||
import type Device from "$lib/models/device";
|
||||
import type UIState from "$lib/models/uistate";
|
||||
import { getContext, onMount, setContext } from "svelte";
|
||||
import { derived, writable, type Readable } from "svelte/store";
|
||||
|
||||
const ctxKey = {ctx: "StateContext"};
|
||||
|
||||
export interface StateContextData {
|
||||
reload(): Promise<void>
|
||||
state: Readable<UIState | null>
|
||||
error: Readable<string | null>
|
||||
deviceList: Readable<Device[]>
|
||||
}
|
||||
|
||||
export function getStateContext(): StateContextData {
|
||||
return getContext(ctxKey) as StateContextData;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
const state = writable<UIState | null>(null);
|
||||
const error = writable<string | null>(null);
|
||||
|
||||
const deviceList = derived(state, state => {
|
||||
if (state == null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return Object.keys(state.devices)
|
||||
.map(k => state.devices[k])
|
||||
.sort((a,b) => a.id.localeCompare(b.id));
|
||||
})
|
||||
|
||||
async function reload() {
|
||||
error.set(null);
|
||||
|
||||
try {
|
||||
const newState = await fetchUIState();
|
||||
state.set(newState);
|
||||
} catch(err) {
|
||||
error.set(err?.toString ? err.toString() : String(err))
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => { reload(); });
|
||||
|
||||
setContext<StateContextData>(ctxKey, {
|
||||
reload,
|
||||
error: { subscribe: error.subscribe },
|
||||
state: { subscribe: state.subscribe },
|
||||
deviceList,
|
||||
});
|
||||
</script>
|
||||
|
||||
<slot></slot>
|
||||
@@ -4,6 +4,18 @@ export interface ColorRGB {
|
||||
blue: number
|
||||
}
|
||||
|
||||
export enum ColorFlags {
|
||||
CFlagXY = 1 << 0,
|
||||
CFlagRGB = 1 << 1,
|
||||
CFlagHS = 1 << 2,
|
||||
CFlagHSK = 1 << 3,
|
||||
CFlagKelvin = 1 << 4,
|
||||
}
|
||||
|
||||
export function rgbString({red,green,blue}: ColorRGB) {
|
||||
return `rgb(${red*255},${green*255},${blue*255})`
|
||||
}
|
||||
|
||||
export function rgb(red: number, green: number, blue: number): ColorRGB {
|
||||
return {red, green, blue};
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import type { ColorFlags, ColorRGB } from "./color"
|
||||
|
||||
export default interface Device {
|
||||
id: string
|
||||
name: string
|
||||
hwMetadata: HardwareMetadata | null
|
||||
hwState: HardwareState | null
|
||||
activeColorRgb: ColorRGB | null
|
||||
desiredState: State,
|
||||
aliases: string[],
|
||||
assignment: string,
|
||||
sensors: Sensors
|
||||
}
|
||||
|
||||
export interface Sensors {
|
||||
lastMotion?: number
|
||||
temperature?: number
|
||||
}
|
||||
|
||||
export interface HardwareState {
|
||||
id: string
|
||||
internalName: string
|
||||
supportFlags: SupportFlags
|
||||
colorFlags: ColorFlags
|
||||
buttons: string[] | null
|
||||
state: State
|
||||
batteryPercentage: number
|
||||
unreachable: boolean
|
||||
}
|
||||
|
||||
export interface HardwareMetadata {
|
||||
firmwareVersion?: string
|
||||
}
|
||||
|
||||
export interface State {
|
||||
power: boolean | null
|
||||
temperature: number | null
|
||||
intensity: number | null
|
||||
color: string | null
|
||||
}
|
||||
|
||||
export enum SupportFlags {
|
||||
Power = 1 << 0,
|
||||
Intensity = 1 << 1,
|
||||
Color = 1 << 2,
|
||||
Temperature = 1 << 3,
|
||||
SensorButtons = 1 << 4,
|
||||
SensorTemperature = 1 << 5,
|
||||
SensorLightLevel = 1 << 6,
|
||||
SensorPresence = 1 << 7,
|
||||
}
|
||||
|
||||
|
||||
export const BLANK_STATE: State = (Object.seal||(v=>v))({
|
||||
power: null,
|
||||
temperature: null,
|
||||
intensity: null,
|
||||
color: null,
|
||||
});
|
||||
@@ -0,0 +1,60 @@
|
||||
import { rgb, type ColorRGB } from "./color"
|
||||
|
||||
export type Palette = { value: string, label: string, rgb: ColorRGB }[];
|
||||
|
||||
export const RGB_PALETTE: Palette = [
|
||||
{value: "hs:235.00,0.550", label: "Sky Blue", rgb: rgb(0.450,0.496,1.000) },
|
||||
{value: "hs:235.00,0.330", label: "Sky Blue 2", rgb: rgb(0.670,0.698,1.000) },
|
||||
{value: "xy:0.2721,0.1908", label: "Lilac", rgb: rgb(0.792,0.500,1.000) },
|
||||
{value: "hs:220,0.1", label: "Bluish White", rgb: rgb(0.900,0.933,1.000)}
|
||||
]
|
||||
|
||||
export const KELVIN_PALETTE: Palette = [
|
||||
{value: "k:1500", label: "1500 K", rgb: rgb(1.000,0.427,0.000)},
|
||||
{value: "k:1625", label: "1625 K", rgb: rgb(1.000,0.469,0.000)},
|
||||
{value: "k:1750", label: "1750 K", rgb: rgb(1.000,0.484,0.000)},
|
||||
{value: "k:1875", label: "1875 K", rgb: rgb(1.000,0.499,0.000)},
|
||||
{value: "k:2000", label: "2000 K", rgb: rgb(1.000,0.541,0.071)},
|
||||
{value: "k:2125", label: "2125 K", rgb: rgb(1.000,0.571,0.162)},
|
||||
{value: "k:2250", label: "2250 K", rgb: rgb(1.000,0.586,0.193)},
|
||||
{value: "k:2375", label: "2375 K", rgb: rgb(1.000,0.601,0.221)},
|
||||
{value: "k:2500", label: "2500 K", rgb: rgb(1.000,0.631,0.282)},
|
||||
{value: "k:2625", label: "2625 K", rgb: rgb(1.000,0.659,0.333)},
|
||||
{value: "k:2750", label: "2750 K", rgb: rgb(1.000,0.671,0.355)},
|
||||
{value: "k:2875", label: "2875 K", rgb: rgb(1.000,0.682,0.376)},
|
||||
{value: "k:3000", label: "3000 K", rgb: rgb(1.000,0.706,0.420)},
|
||||
{value: "k:3125", label: "3125 K", rgb: rgb(1.000,0.730,0.465)},
|
||||
{value: "k:3250", label: "3250 K", rgb: rgb(1.000,0.739,0.482)},
|
||||
{value: "k:3375", label: "3375 K", rgb: rgb(1.000,0.748,0.500)},
|
||||
{value: "k:3500", label: "3500 K", rgb: rgb(1.000,0.769,0.537)},
|
||||
{value: "k:3625", label: "3625 K", rgb: rgb(1.000,0.786,0.575)},
|
||||
{value: "k:3750", label: "3750 K", rgb: rgb(1.000,0.794,0.590)},
|
||||
{value: "k:3875", label: "3875 K", rgb: rgb(1.000,0.802,0.606)},
|
||||
{value: "k:4000", label: "4000 K", rgb: rgb(1.000,0.820,0.639)},
|
||||
{value: "k:4125", label: "4125 K", rgb: rgb(1.000,0.833,0.673)},
|
||||
{value: "k:4250", label: "4250 K", rgb: rgb(1.000,0.839,0.686)},
|
||||
{value: "k:4375", label: "4375 K", rgb: rgb(1.000,0.845,0.699)},
|
||||
{value: "k:4500", label: "4500 K", rgb: rgb(1.000,0.859,0.729)},
|
||||
{value: "k:4625", label: "4625 K", rgb: rgb(1.000,0.873,0.757)},
|
||||
{value: "k:4750", label: "4750 K", rgb: rgb(1.000,0.879,0.768)},
|
||||
{value: "k:4875", label: "4875 K", rgb: rgb(1.000,0.884,0.780)},
|
||||
{value: "k:5000", label: "5000 K", rgb: rgb(1.000,0.894,0.808)},
|
||||
{value: "k:5125", label: "5125 K", rgb: rgb(1.000,0.908,0.832)},
|
||||
{value: "k:5250", label: "5250 K", rgb: rgb(1.000,0.912,0.843)},
|
||||
{value: "k:5375", label: "5375 K", rgb: rgb(1.000,0.916,0.854)},
|
||||
{value: "k:5500", label: "5500 K", rgb: rgb(1.000,0.925,0.878)},
|
||||
{value: "k:5625", label: "5625 K", rgb: rgb(1.000,0.936,0.899)},
|
||||
{value: "k:5750", label: "5750 K", rgb: rgb(1.000,0.939,0.908)},
|
||||
{value: "k:5875", label: "5875 K", rgb: rgb(1.000,0.943,0.917)},
|
||||
{value: "k:6000", label: "6000 K", rgb: rgb(1.000,0.953,0.937)},
|
||||
{value: "k:6125", label: "6125 K", rgb: rgb(1.000,0.960,0.958)},
|
||||
{value: "k:6250", label: "6250 K", rgb: rgb(1.000,0.963,0.965)},
|
||||
{value: "k:6375", label: "6375 K", rgb: rgb(1.000,0.967,0.973)},
|
||||
{value: "k:6500", label: "6500 K", rgb: rgb(1.000,0.976,0.992)},
|
||||
{value: "k:7000", label: "7000 K", rgb: rgb(0.961,0.953,1.000)},
|
||||
{value: "k:8000", label: "8000 K", rgb: rgb(0.890,0.914,1.000)},
|
||||
{value: "k:9000", label: "9000 K", rgb: rgb(0.839,0.882,1.000)},
|
||||
{value: "k:10000", label: "10000 K", rgb: rgb(0.812,0.855,1.000)},
|
||||
{value: "k:11000", label: "11000 K", rgb: rgb(0.784,0.835,1.000)},
|
||||
{value: "k:12000", label: "12000 K", rgb: rgb(0.765,0.820,1.000)},
|
||||
];
|
||||
@@ -0,0 +1,5 @@
|
||||
import type Device from "./device";
|
||||
|
||||
export default interface UIState {
|
||||
devices: {[id: string]: Device}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<script lang="ts">
|
||||
import SelectContext from "$lib/contexts/SelectContext.svelte";
|
||||
import StateContext from "$lib/contexts/StateContext.svelte";
|
||||
</script>
|
||||
|
||||
<StateContext>
|
||||
<SelectContext>
|
||||
<slot></slot>
|
||||
</SelectContext>
|
||||
</StateContext>
|
||||
@@ -1,22 +1,17 @@
|
||||
<script lang="ts">
|
||||
import Lamp from "$lib/components/Lamp.svelte";
|
||||
import { rgb } from "$lib/models/color";
|
||||
import Toolbar from "$lib/components/Toolbar.svelte";
|
||||
import { getStateContext } from "$lib/contexts/StateContext.svelte";
|
||||
|
||||
const {deviceList} = getStateContext();
|
||||
</script>
|
||||
|
||||
<div class="page">
|
||||
<Lamp title="Hexagon 1" color={rgb(1.000,0.541,0.071)} intensity={0.3} />
|
||||
<Lamp title="Hexagon 2" color={rgb(1.000,0.541,0.071)} intensity={0.4} />
|
||||
<Lamp title="Hexagon 3" color={rgb(1.000,0.541,0.071)} intensity={0.5} />
|
||||
<Lamp title="Hexagon 4" color={rgb(1.000,0.631,0.282)} selected intensity={0.1} />
|
||||
<Lamp title="Lamp with an equally absurd name" color={rgb(0.500,0.542,1.000)} selected intensity={0.3} />
|
||||
<Lamp title="Hexagon 5" color={rgb(1.000,0.631,0.282)} selected intensity={0.66} />
|
||||
<Lamp title="Hexagon 6" color={rgb(1.000,0.700,0.408)} selected intensity={0.92} />
|
||||
<Lamp title="Hexagon 7" color={rgb(1.000,0.700,0.408)} intensity={1} />
|
||||
<Lamp title="Hexagon 8" color={rgb(1.000,0.700,0.408)} intensity={0.9} />
|
||||
<Lamp title="Hexagon 9" color={rgb(1.000,0.700,0.408)} intensity={0.5} />
|
||||
<Lamp title="Signe Table Lamp 1" color={rgb(0.765,0.820,1.000)} selected intensity={0.79} />
|
||||
{#each $deviceList as device (device.id) }
|
||||
<Lamp device={device} />
|
||||
{/each}
|
||||
</div>
|
||||
<Toolbar />
|
||||
|
||||
<style>
|
||||
div.page {
|
||||
|
||||
Reference in New Issue
Block a user