You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

173 lines
4.7 KiB

<script lang="ts" context="module">
export const DARK_COLOR = rgb(0.5176470588235295/2, 0.5333333333333333/2, 0.5607843137254902/1.75);
export const DARK_COLOR_SELECTED = rgb(0.5176470588235295/1.5, 0.5333333333333333/1.5, 0.5607843137254902/1.25);
</script>
<script lang="ts">
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";
import DeviceIcon from "./DeviceIcon.svelte";
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 barFraction: 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 = "";
}
barFraction = 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.desiredColorRgb;
} else {
iconColor = null;
}
if (sflags & SupportFlags.SensorPresence) {
barColor = rgb(0.5,0.5,0.5);
barFraction = Math.max(0, (300 - (device.sensors.lastMotion!=null?device.sensors.lastMotion:300))/300);
}
if (sflags & SupportFlags.Temperature) {
barColor = rgb(1.000,0.2,0.2);
barFraction = Math.min(1, Math.max(0, (device.desiredState.temperature||0) - 5) / 35) * 1;
}
if (sflags & SupportFlags.Intensity) {
if (sflags & SupportFlags.Color) {
barColor = device.desiredColorRgb;
} else {
barColor = rgb(1.000,0.671,0.355);
}
barFraction = device.desiredState.intensity;
}
if (sflags & SupportFlags.SensorTemperature && !!device.sensors.temperature) {
roundboiText = `${device.sensors.temperature.toFixed(0)}°`
}
}
}
// Make title visible
let displayTitle: string;
$: {
if (deviceTitle.length > 12) {
let last = deviceTitle.split(" ").pop() || deviceTitle;
if (last.length > 4) {
last = last.slice(-3);
}
displayTitle = `${(deviceTitle.split(" ").shift()||"").slice(0, 10 - last.length)}... ${last}`
} else {
displayTitle = deviceTitle;
}
}
let darkColor: ColorRGB;
$: darkColor = $selectedMap[device.id] ? DARK_COLOR_SELECTED : DARK_COLOR
</script>
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div class="lamp" class:selected={$selectedMap[device.id]} on:click={onSelect}>
<div class="row">
<div class="row-icon">
{#if iconColor != null}
<DeviceIcon name={device.hwMetadata?.icon||"generic_ball"} brightColor={iconColor} darkColor={darkColor} />
{:else}
<DeviceIcon name={device.hwMetadata?.icon||"generic_ball"} brightColor={darkColor} darkColor={darkColor}>
{#if !!roundboiText}
<div class="roundboi-text">{roundboiText}</div>
{/if}
</DeviceIcon>
{/if}
</div>
<div class="title">{displayTitle}</div>
</div>
<div class="flatboi">
{#if barColor != null && barFraction != null}
<div style="width: {barFraction*100}%; background-color: rgb({barColor.red*255},{barColor.green*255},{barColor.blue*255})" class="flatboi2"></div>
{/if}
</div>
</div>
<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.row-icon
font-size: 1.8em
position: absolute
width: 0
height: 0
div.roundboi-text
width: 0
height: 0
left: 1.4ch
top: 0.9em
text-align: center
position: absolute
font-size: 0.333em
> div.title
font-size: 0.9em
text-align: left
margin-top: 0.4em
margin-left: 2em
margin-right: 1ch
height: 1.6em
> div.flatboi
height: 0.2em
> div.flatboi2
height: 0.2em
</style>