Gisle Aune
1 year ago
7 changed files with 313 additions and 88 deletions
-
21frontend/src/lib/components/Lamp.svelte
-
104frontend/src/lib/components/MetaLamp.svelte
-
25frontend/src/lib/components/RoomHeader.svelte
-
12frontend/src/lib/contexts/SelectContext.svelte
-
42frontend/src/lib/contexts/StateContext.svelte
-
33frontend/src/routes/+page.svelte
-
28services/httpapiv1/service.go
@ -0,0 +1,104 @@ |
|||
<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"; |
|||
import Lamp from "./Lamp.svelte"; |
|||
|
|||
export let name: string |
|||
export let devices: Device[]; |
|||
|
|||
let selected: boolean; |
|||
|
|||
const {selectedMap, toggleMultiSelection} = getSelectedContext(); |
|||
|
|||
function onSelect() { |
|||
toggleMultiSelection(devices.map(d => d.id)); |
|||
} |
|||
|
|||
$: selected = !devices.find(d => !$selectedMap[d.id]) |
|||
</script> |
|||
|
|||
<!-- svelte-ignore a11y-click-events-have-key-events --> |
|||
<div class="metalamp" class:selected> |
|||
<div class="row"> |
|||
<div class="title" on:click={onSelect}>{name}</div> |
|||
</div> |
|||
<div class="row"> |
|||
{#each devices as device (device.id)} |
|||
<Lamp compact device={device} /> |
|||
{/each} |
|||
<div style="width: 3.6ch"></div> |
|||
<div style="width: 3.6ch"></div> |
|||
<div style="width: 3.6ch"></div> |
|||
<div style="width: 3.6ch"></div> |
|||
<div style="width: 3.6ch"></div> |
|||
<div style="width: 3.6ch"></div> |
|||
<div style="width: 3.6ch"></div> |
|||
<div style="width: 3.6ch"></div> |
|||
<div style="width: 3.6ch"></div> |
|||
<div style="width: 3.6ch"></div> |
|||
</div> |
|||
</div> |
|||
|
|||
<style lang="sass"> |
|||
div.metalamp |
|||
user-select: none |
|||
cursor: pointer |
|||
width: 19ch |
|||
margin: 0.5ch |
|||
background: #18181c |
|||
color: #84888f |
|||
border-radius: 0.5ch |
|||
border-top-right-radius: 1em |
|||
overflow: hidden |
|||
box-shadow: 1px 1px 1px #000 |
|||
padding-bottom: 0.5ch |
|||
|
|||
@media screen and (max-width: 1921px) |
|||
width: calc(20% - 1ch) |
|||
|
|||
@media screen and (max-width: 1600px) |
|||
width: calc(25% - 1ch) |
|||
|
|||
@media screen and (max-width: 1200px) |
|||
width: calc(33.3333333% - 1ch) |
|||
|
|||
@media screen and (max-width: 700px) |
|||
width: calc(50% - 1ch) |
|||
margin-top: 0.75ch |
|||
margin-bottom: 0.75ch |
|||
|
|||
@media screen and (max-width: 380px) |
|||
width: 100% |
|||
|
|||
&.selected |
|||
background: #282833 |
|||
color: #cde |
|||
|
|||
> div.row |
|||
width: 100% |
|||
padding: 0 0.4ch |
|||
box-sizing: border-box |
|||
width: 100% |
|||
display: flex |
|||
flex-direction: row |
|||
flex-wrap: wrap |
|||
align-content: center |
|||
justify-content: space-between |
|||
|
|||
> div.title |
|||
font-size: 0.75em |
|||
text-align: left |
|||
margin-top: 0.4em |
|||
margin-right: 1ch |
|||
height: 1.6em |
|||
user-select: none |
|||
margin-left: 0.4ch |
|||
</style> |
@ -0,0 +1,25 @@ |
|||
<script lang="ts"> |
|||
import { getSelectedContext } from "$lib/contexts/SelectContext.svelte"; |
|||
|
|||
export let name: string; |
|||
export let devices: {id: string}[]; |
|||
|
|||
function toggleAll() { |
|||
toggleMultiSelection(devices.map(d => d.id)); |
|||
} |
|||
|
|||
const {toggleMultiSelection} = getSelectedContext(); |
|||
</script> |
|||
|
|||
<div class="room-header"> |
|||
<!-- svelte-ignore a11y-click-events-have-key-events --> |
|||
<div on:click={toggleAll} class="name">{name}</div> |
|||
</div> |
|||
|
|||
<style lang="sass"> |
|||
div.room-header |
|||
user-select: none |
|||
font-size: 2rem |
|||
color: #abc |
|||
border-bottom: 1px solid #123 |
|||
</style> |
@ -1,31 +1,48 @@ |
|||
<script lang="ts"> |
|||
import DeviceIcon from "$lib/components/DeviceIcon.svelte"; |
|||
import Lamp, { DARK_COLOR } from "$lib/components/Lamp.svelte"; |
|||
import MetaLamp from "$lib/components/MetaLamp.svelte"; |
|||
import RoomHeader from "$lib/components/RoomHeader.svelte"; |
|||
import { getStateContext } from "$lib/contexts/StateContext.svelte"; |
|||
import { rgb } from "$lib/models/color"; |
|||
|
|||
const {deviceList, roomList} = getStateContext(); |
|||
const {roomList} = getStateContext(); |
|||
|
|||
$: console.log($roomList); |
|||
</script> |
|||
|
|||
<div class="page"> |
|||
{#each $deviceList as device (device.id) } |
|||
<Lamp compact={device.name.includes("Square")} device={device} /> |
|||
{#each $roomList as room (room.name)} |
|||
<RoomHeader devices={room.devices} name={room.name} /> |
|||
<div class="devices"> |
|||
{#each room.devices as device (device.id) } |
|||
<Lamp device={device} /> |
|||
{/each} |
|||
</div> |
|||
<div class="page" style="font-size: 8em"> |
|||
<DeviceIcon name="hue_go" brightColor={rgb(0.517,0.537,1.000)} darkColor={DARK_COLOR} /> |
|||
</div> |
|||
<div class="devices"> |
|||
{#each room.groups as group (group.name)} |
|||
<MetaLamp name={group.name} devices={group.devices} /> |
|||
{/each} |
|||
</div> |
|||
{/each} |
|||
|
|||
</div> |
|||
|
|||
<style> |
|||
div.page { |
|||
margin: 0 auto; |
|||
width: 100ch; |
|||
width: 200ch; |
|||
max-width: 95%; |
|||
margin-top: 1em; |
|||
font-size: 2em; |
|||
font-size: 1.33rem; |
|||
} |
|||
|
|||
div.devices { |
|||
display: flex; |
|||
flex-direction: row; |
|||
flex-wrap: wrap; |
|||
} |
|||
div.devices + div.devices { |
|||
margin-top: 0.25em; |
|||
} |
|||
</style> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue