@hashsome/ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +674 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/entities/action-button.d.ts +17 -0
- package/dist/entities/action-button.js +56 -0
- package/dist/entities/action-button.js.map +1 -0
- package/dist/entities/artwork-ring.d.ts +17 -0
- package/dist/entities/artwork-ring.js +89 -0
- package/dist/entities/artwork-ring.js.map +1 -0
- package/dist/entities/climate-tile.d.ts +20 -0
- package/dist/entities/climate-tile.js +98 -0
- package/dist/entities/climate-tile.js.map +1 -0
- package/dist/entities/light-color.d.ts +52 -0
- package/dist/entities/light-color.js +148 -0
- package/dist/entities/light-color.js.map +1 -0
- package/dist/entities/light-tile.d.ts +24 -0
- package/dist/entities/light-tile.js +139 -0
- package/dist/entities/light-tile.js.map +1 -0
- package/dist/entities/media-browser.d.ts +15 -0
- package/dist/entities/media-browser.js +67 -0
- package/dist/entities/media-browser.js.map +1 -0
- package/dist/entities/media-controls.d.ts +20 -0
- package/dist/entities/media-controls.js +53 -0
- package/dist/entities/media-controls.js.map +1 -0
- package/dist/entities/media-player-bar.d.ts +14 -0
- package/dist/entities/media-player-bar.js +78 -0
- package/dist/entities/media-player-bar.js.map +1 -0
- package/dist/entities/media-player-body.d.ts +16 -0
- package/dist/entities/media-player-body.js +18 -0
- package/dist/entities/media-player-body.js.map +1 -0
- package/dist/entities/media-player-column.d.ts +18 -0
- package/dist/entities/media-player-column.js +34 -0
- package/dist/entities/media-player-column.js.map +1 -0
- package/dist/entities/media-player-page.d.ts +12 -0
- package/dist/entities/media-player-page.js +13 -0
- package/dist/entities/media-player-page.js.map +1 -0
- package/dist/entities/media-progress.d.ts +7 -0
- package/dist/entities/media-progress.js +30 -0
- package/dist/entities/media-progress.js.map +1 -0
- package/dist/entities/media-seek.d.ts +9 -0
- package/dist/entities/media-seek.js +19 -0
- package/dist/entities/media-seek.js.map +1 -0
- package/dist/entities/nav-dock.d.ts +13 -0
- package/dist/entities/nav-dock.js +22 -0
- package/dist/entities/nav-dock.js.map +1 -0
- package/dist/entities/nav-rail.d.ts +19 -0
- package/dist/entities/nav-rail.js +18 -0
- package/dist/entities/nav-rail.js.map +1 -0
- package/dist/entities/now-playing.d.ts +20 -0
- package/dist/entities/now-playing.js +34 -0
- package/dist/entities/now-playing.js.map +1 -0
- package/dist/entities/scene-button.d.ts +13 -0
- package/dist/entities/scene-button.js +6 -0
- package/dist/entities/scene-button.js.map +1 -0
- package/dist/entities/seek-line.d.ts +9 -0
- package/dist/entities/seek-line.js +71 -0
- package/dist/entities/seek-line.js.map +1 -0
- package/dist/entities/sensor-readout.d.ts +28 -0
- package/dist/entities/sensor-readout.js +95 -0
- package/dist/entities/sensor-readout.js.map +1 -0
- package/dist/entities/top-bar.d.ts +68 -0
- package/dist/entities/top-bar.js +248 -0
- package/dist/entities/top-bar.js.map +1 -0
- package/dist/entity-handle.d.ts +21 -0
- package/dist/entity-handle.js +16 -0
- package/dist/entity-handle.js.map +1 -0
- package/dist/gallery/fixtures.d.ts +4 -0
- package/dist/gallery/fixtures.js +119 -0
- package/dist/gallery/fixtures.js.map +1 -0
- package/dist/gallery/gallery.d.ts +9 -0
- package/dist/gallery/gallery.js +355 -0
- package/dist/gallery/gallery.js.map +1 -0
- package/dist/gallery/index.d.ts +2 -0
- package/dist/gallery/index.js +2 -0
- package/dist/gallery/index.js.map +1 -0
- package/dist/gallery/props-data.d.ts +10 -0
- package/dist/gallery/props-data.js +718 -0
- package/dist/gallery/props-data.js.map +1 -0
- package/dist/hooks.d.ts +19 -0
- package/dist/hooks.js +53 -0
- package/dist/hooks.js.map +1 -0
- package/dist/icon-data.d.ts +6 -0
- package/dist/icon-data.js +59193 -0
- package/dist/icon-data.js.map +1 -0
- package/dist/icon.d.ts +9 -0
- package/dist/icon.js +28 -0
- package/dist/icon.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/layout/cover.d.ts +5 -0
- package/dist/layout/cover.js +8 -0
- package/dist/layout/cover.js.map +1 -0
- package/dist/layout/date-time-field.d.ts +15 -0
- package/dist/layout/date-time-field.js +108 -0
- package/dist/layout/date-time-field.js.map +1 -0
- package/dist/layout/detail-provider.d.ts +22 -0
- package/dist/layout/detail-provider.js +26 -0
- package/dist/layout/detail-provider.js.map +1 -0
- package/dist/layout/drawer-controls.d.ts +46 -0
- package/dist/layout/drawer-controls.js +93 -0
- package/dist/layout/drawer-controls.js.map +1 -0
- package/dist/layout/energy-chart.d.ts +37 -0
- package/dist/layout/energy-chart.js +85 -0
- package/dist/layout/energy-chart.js.map +1 -0
- package/dist/layout/energy-usage.d.ts +6 -0
- package/dist/layout/energy-usage.js +18 -0
- package/dist/layout/energy-usage.js.map +1 -0
- package/dist/layout/entity-drawer.d.ts +15 -0
- package/dist/layout/entity-drawer.js +77 -0
- package/dist/layout/entity-drawer.js.map +1 -0
- package/dist/layout/fade-scroll.d.ts +14 -0
- package/dist/layout/fade-scroll.js +59 -0
- package/dist/layout/fade-scroll.js.map +1 -0
- package/dist/layout/grid.d.ts +9 -0
- package/dist/layout/grid.js +6 -0
- package/dist/layout/grid.js.map +1 -0
- package/dist/layout/history-section.d.ts +19 -0
- package/dist/layout/history-section.js +39 -0
- package/dist/layout/history-section.js.map +1 -0
- package/dist/layout/hold-progress.d.ts +2 -0
- package/dist/layout/hold-progress.js +9 -0
- package/dist/layout/hold-progress.js.map +1 -0
- package/dist/layout/icon-button-styles.d.ts +9 -0
- package/dist/layout/icon-button-styles.js +28 -0
- package/dist/layout/icon-button-styles.js.map +1 -0
- package/dist/layout/page.d.ts +17 -0
- package/dist/layout/page.js +29 -0
- package/dist/layout/page.js.map +1 -0
- package/dist/layout/plain-button.d.ts +11 -0
- package/dist/layout/plain-button.js +17 -0
- package/dist/layout/plain-button.js.map +1 -0
- package/dist/layout/room-header.d.ts +12 -0
- package/dist/layout/room-header.js +11 -0
- package/dist/layout/room-header.js.map +1 -0
- package/dist/layout/round-button.d.ts +13 -0
- package/dist/layout/round-button.js +19 -0
- package/dist/layout/round-button.js.map +1 -0
- package/dist/layout/sensor-history.d.ts +15 -0
- package/dist/layout/sensor-history.js +91 -0
- package/dist/layout/sensor-history.js.map +1 -0
- package/dist/layout/sensor-stats.d.ts +21 -0
- package/dist/layout/sensor-stats.js +79 -0
- package/dist/layout/sensor-stats.js.map +1 -0
- package/dist/layout/series-chart.d.ts +25 -0
- package/dist/layout/series-chart.js +46 -0
- package/dist/layout/series-chart.js.map +1 -0
- package/dist/layout/stepper.d.ts +10 -0
- package/dist/layout/stepper.js +12 -0
- package/dist/layout/stepper.js.map +1 -0
- package/dist/layout/swatch-row.d.ts +19 -0
- package/dist/layout/swatch-row.js +20 -0
- package/dist/layout/swatch-row.js.map +1 -0
- package/dist/layout/tile.d.ts +67 -0
- package/dist/layout/tile.js +207 -0
- package/dist/layout/tile.js.map +1 -0
- package/dist/layout/use-drawer.d.ts +33 -0
- package/dist/layout/use-drawer.js +34 -0
- package/dist/layout/use-drawer.js.map +1 -0
- package/dist/layout/use-hold.d.ts +21 -0
- package/dist/layout/use-hold.js +61 -0
- package/dist/layout/use-hold.js.map +1 -0
- package/dist/provider.d.ts +37 -0
- package/dist/provider.js +95 -0
- package/dist/provider.js.map +1 -0
- package/dist/status.d.ts +8 -0
- package/dist/status.js +27 -0
- package/dist/status.js.map +1 -0
- package/dist/theme/density.d.ts +16 -0
- package/dist/theme/density.js +7 -0
- package/dist/theme/density.js.map +1 -0
- package/dist/theme/global-styles.d.ts +5 -0
- package/dist/theme/global-styles.js +44 -0
- package/dist/theme/global-styles.js.map +1 -0
- package/dist/theme/index.d.ts +19 -0
- package/dist/theme/index.js +106 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme/overrides.d.ts +28 -0
- package/dist/theme/overrides.js +24 -0
- package/dist/theme/overrides.js.map +1 -0
- package/dist/theme/tokens.d.ts +78 -0
- package/dist/theme/tokens.js +1 -0
- package/dist/theme/tokens.js.map +1 -0
- package/dist/theme/use-typography.d.ts +4 -0
- package/dist/theme/use-typography.js +9 -0
- package/dist/theme/use-typography.js.map +1 -0
- package/dist/use-entity-history.d.ts +12 -0
- package/dist/use-entity-history.js +43 -0
- package/dist/use-entity-history.js.map +1 -0
- package/dist/use-media-browser.d.ts +31 -0
- package/dist/use-media-browser.js +87 -0
- package/dist/use-media-browser.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef, useState } from 'react';
|
|
3
|
+
import { fallbackName } from '../entity-handle.js';
|
|
4
|
+
import { useEntityHandle } from '../hooks.js';
|
|
5
|
+
import { Box, Flex, Typography, useColorByKey } from 'e-prim';
|
|
6
|
+
import { Icon } from '../icon.js';
|
|
7
|
+
import { PowerButton, StepButton, ValueBar } from '../layout/drawer-controls.js';
|
|
8
|
+
import { PlainButton } from '../layout/plain-button.js';
|
|
9
|
+
import { SwatchRow } from '../layout/swatch-row.js';
|
|
10
|
+
import { IconButton, Tile } from '../layout/tile.js';
|
|
11
|
+
import { DEFAULT_COLOR_PRESETS, applyPreset, currentHs, ensureContrast, hexToRgb, isPresetActive, kelvinToRgb, presetCss, resolveLightColor, rgbCss, rgbToHex, rgbToHs, } from './light-color.js';
|
|
12
|
+
const HUE_GRADIENT = 'linear-gradient(to right, hsl(0 100% 50%), hsl(60 100% 50%), hsl(120 100% 50%), hsl(180 100% 50%), hsl(240 100% 50%), hsl(300 100% 50%), hsl(360 100% 50%))';
|
|
13
|
+
const kelvinGradient = (min, max) => `linear-gradient(to right, ${[0, 0.25, 0.5, 0.75, 1]
|
|
14
|
+
.map((f) => rgbCss(kelvinToRgb(min + f * (max - min))))
|
|
15
|
+
.join(', ')})`;
|
|
16
|
+
/** Toggle, drag-to-dim (if dimmable) and a color overlay + drawer picker (if color capable). */
|
|
17
|
+
export function LightTile({ entity, name, icon, energy, history, colors = DEFAULT_COLOR_PRESETS, }) {
|
|
18
|
+
const handle = useEntityHandle('light', entity);
|
|
19
|
+
const [picking, setPicking] = useState(false);
|
|
20
|
+
const [colorOpen, setColorOpen] = useState(false);
|
|
21
|
+
const { status } = handle;
|
|
22
|
+
const light = handle.entity;
|
|
23
|
+
const on = light?.on === true;
|
|
24
|
+
const supportsTemp = light?.capabilities.colorTemperature === true;
|
|
25
|
+
const supportsHs = light?.capabilities.color === true;
|
|
26
|
+
const dimmable = light?.capabilities.brightness === true;
|
|
27
|
+
const color = supportsTemp || supportsHs;
|
|
28
|
+
const brightness = light?.brightness;
|
|
29
|
+
const percent = brightness === undefined ? undefined : Math.round(brightness * 100);
|
|
30
|
+
const rgb = resolveLightColor(light);
|
|
31
|
+
const chipBg = hexToRgb(useColorByKey('surfaceRaised') ?? '');
|
|
32
|
+
const paletteColor = rgb ? rgbCss(chipBg ? ensureContrast(rgb, chipBg) : rgb) : undefined;
|
|
33
|
+
const caps = { colorTemp: supportsTemp, hs: supportsHs };
|
|
34
|
+
const swatches = colors.flatMap((preset) => {
|
|
35
|
+
const data = applyPreset(preset, caps);
|
|
36
|
+
return data ? [{ preset, data }] : [];
|
|
37
|
+
});
|
|
38
|
+
const showPicker = color && status === 'ready';
|
|
39
|
+
return (_jsx(Tile, { label: name ?? light?.name ?? fallbackName(entity), icon: icon ?? (on ? 'lu:lightbulb' : 'lu:lightbulb-off'), kind: "Light", status: status, active: on, secondary: on ? (dimmable && percent !== undefined ? `${percent}%` : undefined) : 'Off', onPress: () => void handle.command('toggle'), detail: _jsx(LightDetailBody, { on: on, percent: dimmable ? percent : undefined, onToggle: () => void handle.command('toggle'), ...(dimmable
|
|
40
|
+
? {
|
|
41
|
+
onBrightness: (next) => void handle.command('setBrightness', { brightness: next / 100 }),
|
|
42
|
+
}
|
|
43
|
+
: {}), colorSection: showPicker ? (_jsx(LightColorSection, { light: light, open: colorOpen, onToggle: () => setColorOpen((open) => !open), supportsTemp: supportsTemp, supportsHs: supportsHs, onKelvin: (kelvin) => void handle.command('setColorTemperature', { kelvin }), onHue: (hue) => void handle.command('setColor', {
|
|
44
|
+
hue,
|
|
45
|
+
saturation: currentHs(light)[1] || 100,
|
|
46
|
+
}), onPicked: (hex) => {
|
|
47
|
+
const picked = hexToRgb(hex);
|
|
48
|
+
if (picked) {
|
|
49
|
+
const [hue, saturation] = rgbToHs(picked);
|
|
50
|
+
void handle.command('setColor', { hue, saturation });
|
|
51
|
+
}
|
|
52
|
+
} })) : null }), ...(energy ? { energy } : {}), ...(history ? { history } : {}), ...(dimmable
|
|
53
|
+
? {
|
|
54
|
+
fill: on ? (brightness ?? 1) : 0,
|
|
55
|
+
onFillChange: (fill) => void handle.command('setBrightness', { brightness: fill }),
|
|
56
|
+
}
|
|
57
|
+
: {}), ...(showPicker && picking
|
|
58
|
+
? {
|
|
59
|
+
// A render prop `Tile` calls, not a component of its own.
|
|
60
|
+
// oxlint-disable-next-line react/no-unstable-nested-components
|
|
61
|
+
overlay: ({ openDetail }) => (_jsx(SwatchRow, { items: swatches.map(({ preset, data }) => ({
|
|
62
|
+
key: preset.label,
|
|
63
|
+
label: preset.label,
|
|
64
|
+
selected: isPresetActive(data, light),
|
|
65
|
+
color: presetCss(preset),
|
|
66
|
+
onPick: () => {
|
|
67
|
+
void (data.command === 'setColorTemperature'
|
|
68
|
+
? handle.command('setColorTemperature', data.args)
|
|
69
|
+
: handle.command('setColor', data.args));
|
|
70
|
+
setPicking(false);
|
|
71
|
+
},
|
|
72
|
+
})), customLabel: "Custom color", onCustom: () => {
|
|
73
|
+
setPicking(false);
|
|
74
|
+
setColorOpen(true);
|
|
75
|
+
openDetail();
|
|
76
|
+
} })),
|
|
77
|
+
}
|
|
78
|
+
: {}), trailing: showPicker ? (_jsx(IconButton, { icon: picking ? 'lu:x' : 'lu:palette', label: picking ? 'Close colors' : 'Color', active: false, onClick: () => setPicking((open) => !open), size: 16, ...(on && paletteColor && !picking ? { color: paletteColor } : {}) })) : null }));
|
|
79
|
+
}
|
|
80
|
+
/** The drawer's collapsible "Color" card: temperature and hue bars. `custom` from the card's
|
|
81
|
+
* swatch overlay opens the drawer with this already expanded. */
|
|
82
|
+
function LightColorSection({ light, open, onToggle, supportsTemp, supportsHs, onKelvin, onHue, onPicked, }) {
|
|
83
|
+
const minK = light?.capabilities.kelvinRange?.min ?? 2000;
|
|
84
|
+
const maxK = light?.capabilities.kelvinRange?.max ?? 6500;
|
|
85
|
+
const rgb = resolveLightColor(light);
|
|
86
|
+
const kelvin = Math.min(maxK, Math.max(minK, light?.color?.mode === 'temperature' ? light.color.kelvin : 2700));
|
|
87
|
+
const hue = rgb ? rgbToHs(rgb)[0] : 0;
|
|
88
|
+
const [pickedHex, setPickedHex] = useState(null);
|
|
89
|
+
const pickTimer = useRef(undefined);
|
|
90
|
+
useEffect(() => () => clearTimeout(pickTimer.current), []);
|
|
91
|
+
const hex = pickedHex ?? (rgb ? rgbToHex(rgb) : '#ffffff');
|
|
92
|
+
const [dragK, setDragK] = useState(null);
|
|
93
|
+
const [dragH, setDragH] = useState(null);
|
|
94
|
+
if (dragK !== null && dragK === kelvin) {
|
|
95
|
+
setDragK(null);
|
|
96
|
+
}
|
|
97
|
+
if (dragH !== null && dragH === hue) {
|
|
98
|
+
setDragH(null);
|
|
99
|
+
}
|
|
100
|
+
return (_jsxs(Flex, { direction: "column", gap: 2, background: "surfaceRaised", radius: "row", py: 3.5, px: 4, children: [_jsxs(PlainButton, { "aria-expanded": open, onClick: onToggle, justify: "space-between", align: "center", color: "text", children: [_jsx(Typography, { as: "span", variant: "bodyStrong", children: "Color" }), _jsxs(Flex, { align: "center", gap: 2, children: [rgb ? (_jsx(Box, { as: "span", width: 16, height: 16, radius: "full", "aria-hidden": "true", css: { background: rgbCss(rgb) } })) : null, _jsx(Icon, { name: open ? 'lu:chevron-up' : 'lu:chevron-down', size: 16 })] })] }), open ? (_jsxs(Flex, { direction: "column", gap: 3, pt: 1, children: [supportsTemp ? (_jsxs(Flex, { direction: "column", gap: 2, children: [_jsxs(Flex, { justify: "space-between", align: "center", children: [_jsx(Typography, { as: "span", variant: "secondary", color: "textMuted", children: "Temperature" }), _jsxs(Typography, { as: "span", variant: "secondary", color: "textMuted", children: [dragK ?? kelvin, " K"] })] }), _jsx(ValueBar, { label: "Color temperature", value: dragK ?? kelvin, min: minK, max: maxK, keyStep: 100, round: 50, gradient: kelvinGradient(minK, maxK), onDrag: setDragK, onCommit: (next) => {
|
|
101
|
+
setDragK(next);
|
|
102
|
+
onKelvin(next);
|
|
103
|
+
} })] })) : null, supportsHs ? (_jsxs(Flex, { direction: "column", gap: 2, children: [_jsx(Typography, { as: "span", variant: "secondary", color: "textMuted", children: "Hue" }), _jsx(ValueBar, { label: "Hue", value: dragH ?? hue, min: 0, max: 360, keyStep: 10, gradient: HUE_GRADIENT, onDrag: setDragH, onCommit: (next) => {
|
|
104
|
+
setDragH(next);
|
|
105
|
+
onHue(next);
|
|
106
|
+
} }), _jsxs(Flex, { justify: "space-between", align: "center", children: [_jsx(Typography, { as: "span", variant: "secondary", color: "textMuted", children: "Any color" }), _jsx(Flex, { align: "center", gap: 2, children: _jsx(Box, { as: "input", width: 16, height: 16, p: 0, radius: "full", cursor: "pointer", css: {
|
|
107
|
+
background: 'none',
|
|
108
|
+
'&::-webkit-color-swatch-wrapper': { padding: 0 },
|
|
109
|
+
'&::-webkit-color-swatch': { border: 0, borderRadius: '50%' },
|
|
110
|
+
'&::-moz-color-swatch': { border: 0, borderRadius: '50%' },
|
|
111
|
+
}, type: "color", "aria-label": "Pick any color", title: "Open the color picker", value: hex, onChange: (event) => {
|
|
112
|
+
const next = event.target.value;
|
|
113
|
+
setPickedHex(next);
|
|
114
|
+
clearTimeout(pickTimer.current);
|
|
115
|
+
pickTimer.current = setTimeout(() => onPicked(next), 200);
|
|
116
|
+
} }) })] })] })) : null] })) : null] }));
|
|
117
|
+
}
|
|
118
|
+
function LightDetailBody({ on, percent, onToggle, onBrightness, colorSection, }) {
|
|
119
|
+
const [drag, setDrag] = useState(null);
|
|
120
|
+
const shown = on ? (percent ?? 100) : 0;
|
|
121
|
+
if (drag !== null && drag === shown) {
|
|
122
|
+
setDrag(null);
|
|
123
|
+
}
|
|
124
|
+
const value = drag ?? shown;
|
|
125
|
+
const commit = (next) => {
|
|
126
|
+
setDrag(next);
|
|
127
|
+
onBrightness?.(next);
|
|
128
|
+
};
|
|
129
|
+
const latest = useRef(value);
|
|
130
|
+
useEffect(() => {
|
|
131
|
+
latest.current = value;
|
|
132
|
+
}, [value]);
|
|
133
|
+
const step = (delta) => {
|
|
134
|
+
const next = Math.min(100, Math.max(0, latest.current + delta));
|
|
135
|
+
latest.current = next;
|
|
136
|
+
commit(next);
|
|
137
|
+
};
|
|
138
|
+
return (_jsxs(Flex, { direction: "column", gap: 2, children: [_jsxs(Flex, { justify: "space-between", align: "center", background: "surfaceRaised", radius: "row", py: 3.5, px: 4, children: [_jsxs(Flex, { direction: "column", children: [_jsx(Typography, { as: "span", variant: "bodyStrong", children: "Power" }), _jsx(Typography, { as: "span", variant: "secondary", color: "textMuted", children: on ? (percent !== undefined ? `On · ${percent}%` : 'On') : 'Off' })] }), _jsx(PowerButton, { on: on, onToggle: onToggle })] }), onBrightness ? (_jsxs(Flex, { direction: "column", gap: 2, background: "surfaceRaised", radius: "row", py: 3.5, px: 4, children: [_jsxs(Flex, { justify: "space-between", align: "center", children: [_jsx(Typography, { as: "span", variant: "bodyStrong", children: "Brightness" }), _jsxs(Typography, { as: "span", variant: "secondary", color: "textMuted", children: [value, "%"] })] }), _jsxs(Flex, { align: "center", gap: 2, children: [_jsx(StepButton, { icon: "lu:minus", label: "Decrease brightness", delta: -1, onStep: step }), _jsx(Box, { grow: 1, children: _jsx(ValueBar, { label: "Brightness", value: value, min: 0, max: 100, keyStep: 5, onDrag: setDrag, onCommit: commit }) }), _jsx(StepButton, { icon: "lu:plus", label: "Increase brightness", delta: 1, onStep: step })] })] })) : null, colorSection] }));
|
|
139
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"light-tile.js","sourceRoot":"","sources":["../../src/entities/light-tile.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** @jsxImportSource @emotion/react */
|
|
2
|
+
import type { BrowseItem, EntityRef } from '@hashsome/core';
|
|
3
|
+
export interface MediaBrowserProps {
|
|
4
|
+
/** The media player whose own library to browse, as a ref like `ma:living_room`. The backend that owns the player is the media source, so a Music Assistant player lists Music Assistant's library and a Home Assistant player Home Assistant's. */
|
|
5
|
+
entity: EntityRef;
|
|
6
|
+
/** Called after something is started, e.g. to close a drawer the browser sits in. */
|
|
7
|
+
onPlay?: (item: BrowseItem) => void;
|
|
8
|
+
/** How items are laid out. `list` is rows, compact enough for a narrow drawer. `theater` is a single row of large cards that scrolls sideways, for a wide space. `auto` is `theater` inside an expanded drawer and `list` anywhere else. Default `list`. */
|
|
9
|
+
layout?: 'list' | 'theater' | 'auto';
|
|
10
|
+
}
|
|
11
|
+
/** The library of a media player, in the app's own style: shelves, albums, playlists and the rest
|
|
12
|
+
* as rows with artwork. Tap a folder to open it, a track or station to play it, or the play button
|
|
13
|
+
* on an album, playlist or artist to play all of it. A search box appears when the library can be
|
|
14
|
+
* searched. */
|
|
15
|
+
export declare function MediaBrowser({ entity, onPlay, layout }: MediaBrowserProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
2
|
+
import { Box, Flex, Typography } from 'e-prim';
|
|
3
|
+
import { Icon } from '../icon.js';
|
|
4
|
+
import { useEntityHandle } from '../hooks.js';
|
|
5
|
+
import { useDetail } from '../layout/detail-provider.js';
|
|
6
|
+
import { Cover } from '../layout/cover.js';
|
|
7
|
+
import { ChipRow } from '../layout/drawer-controls.js';
|
|
8
|
+
import { FadeScroll } from '../layout/fade-scroll.js';
|
|
9
|
+
import { PlainButton } from '../layout/plain-button.js';
|
|
10
|
+
import { IconButton } from '../layout/tile.js';
|
|
11
|
+
import { useMediaBrowser } from '../use-media-browser.js';
|
|
12
|
+
const KIND_ICONS = {
|
|
13
|
+
folder: 'lu:folder',
|
|
14
|
+
artist: 'lu:mic-vocal',
|
|
15
|
+
album: 'lu:disc-3',
|
|
16
|
+
playlist: 'lu:list-music',
|
|
17
|
+
track: 'lu:music',
|
|
18
|
+
radio: 'lu:radio',
|
|
19
|
+
other: 'lu:music',
|
|
20
|
+
};
|
|
21
|
+
/** The library of a media player, in the app's own style: shelves, albums, playlists and the rest
|
|
22
|
+
* as rows with artwork. Tap a folder to open it, a track or station to play it, or the play button
|
|
23
|
+
* on an album, playlist or artist to play all of it. A search box appears when the library can be
|
|
24
|
+
* searched. */
|
|
25
|
+
export function MediaBrowser({ entity, onPlay, layout = 'list' }) {
|
|
26
|
+
const handle = useEntityHandle('mediaPlayer', entity);
|
|
27
|
+
const { detail } = useDetail();
|
|
28
|
+
const theater = layout === 'theater' || (layout === 'auto' && detail?.expanded === true);
|
|
29
|
+
const browser = useMediaBrowser(entity);
|
|
30
|
+
const player = handle.entity;
|
|
31
|
+
const play = (item) => {
|
|
32
|
+
void handle.command('playMedia', { item: item.id });
|
|
33
|
+
onPlay?.(item);
|
|
34
|
+
};
|
|
35
|
+
/** Something is open inside the selected shelf (not a search): the tab shows the way back. */
|
|
36
|
+
const inside = browser.canGoBack && !browser.searching;
|
|
37
|
+
const header = (_jsxs(Flex, { align: "center", gap: 2, css: { flexShrink: 0 }, children: [browser.canGoBack ? (_jsx(IconButton, { icon: "lu:arrow-left", label: "Back", glyph: 16, onClick: browser.back })) : null, _jsx(Typography, { as: "h2", variant: "heading", grow: 1, m: 0, children: browser.title ?? 'Library' })] }));
|
|
38
|
+
const search = player?.capabilities.search ? (_jsxs(Flex, { align: "center", gap: 2, background: "surfaceRaised", radius: "full", px: 3, height: 36, color: "textMuted",
|
|
39
|
+
// Fixed height: when the list takes all the room, the search keeps its size and the list scrolls.
|
|
40
|
+
css: { flexShrink: 0 }, children: [_jsx(Icon, { name: "lu:search", size: 16 }), _jsx(Box, { as: "input", type: "search", "aria-label": "Search the library", placeholder: "Search", typography: "body", color: "text", grow: 1, minWidth: 0, value: browser.query, onChange: (event) => browser.search(event.target.value), css: { background: 'none', outline: 'none' } }), browser.query !== '' ? (_jsx(PlainButton, { "aria-label": "Clear search", title: "Clear search", onClick: () => browser.search(''), center: true, css: { flex: 'none' }, children: _jsx(Icon, { name: "lu:x", size: 16 }) })) : null] })) : null;
|
|
41
|
+
return (_jsxs(Flex, { direction: "column", gap: 3, minHeight: 0, children: [browser.tabs === undefined ? header : null, search, browser.tabs ? (_jsx(ChipRow, { tabs: true, options: browser.tabs.map((item) =>
|
|
42
|
+
// Inside a shelf the selected tab becomes the way back, so nothing is added to the
|
|
43
|
+
// layout and nothing below it moves.
|
|
44
|
+
item.id === browser.activeTab && inside
|
|
45
|
+
? {
|
|
46
|
+
value: item.id,
|
|
47
|
+
label: browser.title ?? item.title,
|
|
48
|
+
icon: 'lu:arrow-left',
|
|
49
|
+
ariaLabel: 'Back',
|
|
50
|
+
}
|
|
51
|
+
: { value: item.id, label: item.title }), value: browser.activeTab, onChange: (id) => id === browser.activeTab && inside ? browser.back() : browser.selectTab(id) })) : null, browser.error ? (_jsx(Typography, { as: "p", variant: "body", color: "danger", role: "alert", children: browser.error })) : browser.loading ? (_jsx(Typography, { as: "p", variant: "body", color: "textMuted", children: "Loading\u2026" })) : browser.items.length === 0 ? (_jsx(Typography, { as: "p", variant: "body", color: "textMuted", children: browser.searching ? 'Nothing found.' : 'Nothing here.' })) : theater ? (_jsx(FadeScroll, { as: "ul", gap: 4, m: 0, p: 0, pb: 2, css: { listStyle: 'none', scrollSnapType: 'x proximity' }, children: browser.items.map((item) => (_jsx("li", { css: { flex: 'none', scrollSnapAlign: 'start' }, children: _jsx(BrowseCard, { item: item, onOpen: () => browser.open(item), onPlay: () => play(item) }) }, item.id))) })) : (_jsx(Flex, { direction: "column", gap: 1, as: "ul", m: 0, p: 0, minHeight: 0, css: { listStyle: 'none', overflowY: 'auto' }, children: browser.items.map((item) => (_jsx("li", { css: { flex: 'none' }, children: _jsx(BrowseRow, { item: item, onOpen: () => browser.open(item), onPlay: () => play(item) }) }, item.id))) }))] }));
|
|
52
|
+
}
|
|
53
|
+
function BrowseRow({ item, onOpen, onPlay, }) {
|
|
54
|
+
// A row opens what can be opened and otherwise plays; an openable thing that can also be played
|
|
55
|
+
// (an album) gets its own play button.
|
|
56
|
+
const main = item.expandable ? onOpen : item.playable ? onPlay : undefined;
|
|
57
|
+
return (_jsxs(Flex, { align: "center", gap: 2, children: [_jsxs(PlainButton, { align: "center", gap: 3, grow: 1, minWidth: 0, radius: "row", py: 1.5, px: 2, cursor: main ? 'pointer' : 'default', disabled: !main, "aria-label": item.expandable ? `Open ${item.title}` : `Play ${item.title}`, onClick: main, css: ({ palette }) => ({ '&:hover:not(:disabled)': { background: palette.surfaceRaised } }), children: [_jsx(Flex, { align: "center", justify: "center", background: "surfaceRaised", color: "textMuted", radius: "small", width: 44, height: 44, overflow: "hidden", css: { flex: 'none' }, children: item.artworkUrl ? (_jsx(Cover, { src: item.artworkUrl })) : (_jsx(Icon, { name: KIND_ICONS[item.kind], size: 20 })) }), _jsxs(Flex, { direction: "column", minWidth: 0, children: [_jsx(Typography, { as: "span", variant: "bodyStrong", noWrap: true, textOverflow: "ellipsis", overflow: "hidden", children: item.title }), item.subtitle ? (_jsx(Typography, { as: "span", variant: "secondary", color: "textMuted", noWrap: true, textOverflow: "ellipsis", overflow: "hidden", children: item.subtitle })) : null] })] }), item.expandable && item.playable ? (_jsx(IconButton, { icon: "lu:play", label: `Play ${item.title}`, glyph: 16, onClick: onPlay })) : null] }));
|
|
58
|
+
}
|
|
59
|
+
/** The width and height of a theater card's artwork. */
|
|
60
|
+
const CARD = 200;
|
|
61
|
+
/** An item as a large card for the theater layout: big artwork (round for an artist), then the
|
|
62
|
+
* title and subtitle. It opens or plays like a row does, and an album or playlist gets its play
|
|
63
|
+
* button over the artwork's corner. */
|
|
64
|
+
function BrowseCard({ item, onOpen, onPlay, }) {
|
|
65
|
+
const main = item.expandable ? onOpen : item.playable ? onPlay : undefined;
|
|
66
|
+
return (_jsxs(Box, { position: "relative", width: CARD, children: [_jsxs(PlainButton, { direction: "column", gap: 2, width: "100%", cursor: main ? 'pointer' : 'default', disabled: !main, "aria-label": item.expandable ? `Open ${item.title}` : `Play ${item.title}`, onClick: main, children: [_jsx(Flex, { align: "center", justify: "center", background: "surfaceRaised", color: "textMuted", radius: item.kind === 'artist' ? 'full' : 'card', overflow: "hidden", width: CARD, height: CARD, children: item.artworkUrl ? (_jsx(Cover, { src: item.artworkUrl })) : (_jsx(Icon, { name: KIND_ICONS[item.kind], size: 56 })) }), _jsxs(Flex, { direction: "column", minWidth: 0, px: 1, children: [_jsx(Typography, { as: "span", variant: "bodyStrong", noWrap: true, textOverflow: "ellipsis", overflow: "hidden", children: item.title }), item.subtitle ? (_jsx(Typography, { as: "span", variant: "secondary", color: "textMuted", noWrap: true, textOverflow: "ellipsis", overflow: "hidden", children: item.subtitle })) : null] })] }), item.expandable && item.playable ? (_jsx(Box, { position: "absolute", css: { right: 10, top: CARD - 54 }, children: _jsx(IconButton, { icon: "lu:play", label: `Play ${item.title}`, glyph: 16, onClick: onPlay }) })) : null] }));
|
|
67
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media-browser.js","sourceRoot":"","sources":["../../src/entities/media-browser.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { EntityHandle } from '../entity-handle.ts';
|
|
2
|
+
type Handle = EntityHandle<'mediaPlayer'>;
|
|
3
|
+
/** The volume of a player as a 0..100 level plus the drag in progress: what to draw, and what a
|
|
4
|
+
* drag, a commit and the mute button each ask the player to do. 0 is mute and anything above it
|
|
5
|
+
* is audible, so a commit can unmute. */
|
|
6
|
+
export declare function useVolumeControl(handle: Handle): {
|
|
7
|
+
level: number;
|
|
8
|
+
muted: boolean;
|
|
9
|
+
shown: number;
|
|
10
|
+
drag: import("react").Dispatch<import("react").SetStateAction<number | null>>;
|
|
11
|
+
commit: (next: number) => void;
|
|
12
|
+
toggleMute: () => void;
|
|
13
|
+
};
|
|
14
|
+
/** A press that changes nothing visible until the player reports back (a skip) confirms itself:
|
|
15
|
+
* the button dims while the call is in flight, then flashes, or turns red on failure. */
|
|
16
|
+
export declare function usePressFeedback(): {
|
|
17
|
+
feedbackFor: (key: string) => "done" | "error" | "pending" | undefined;
|
|
18
|
+
press: (key: string, action: () => Promise<void>) => void;
|
|
19
|
+
};
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { useEffect, useRef, useState } from 'react';
|
|
2
|
+
/** Unmuting while the level is 0 would restore silence, so it jumps to this instead. */
|
|
3
|
+
const UNMUTE_FROM_ZERO = 0.15;
|
|
4
|
+
/** The volume of a player as a 0..100 level plus the drag in progress: what to draw, and what a
|
|
5
|
+
* drag, a commit and the mute button each ask the player to do. 0 is mute and anything above it
|
|
6
|
+
* is audible, so a commit can unmute. */
|
|
7
|
+
export function useVolumeControl(handle) {
|
|
8
|
+
const player = handle.entity;
|
|
9
|
+
const level = Math.round((player?.volume ?? 0) * 100);
|
|
10
|
+
const muted = player?.muted === true;
|
|
11
|
+
const [drag, setDrag] = useState(null);
|
|
12
|
+
if (drag !== null && drag === level) {
|
|
13
|
+
setDrag(null);
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
level,
|
|
17
|
+
muted,
|
|
18
|
+
shown: drag ?? level,
|
|
19
|
+
drag: setDrag,
|
|
20
|
+
commit: (next) => {
|
|
21
|
+
setDrag(next);
|
|
22
|
+
void handle.command('setVolume', { volume: next / 100 });
|
|
23
|
+
if ((next === 0) !== muted) {
|
|
24
|
+
void handle.command('setMuted', { muted: !muted });
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
toggleMute: () => {
|
|
28
|
+
if (muted && level === 0) {
|
|
29
|
+
void handle.command('setVolume', { volume: UNMUTE_FROM_ZERO });
|
|
30
|
+
}
|
|
31
|
+
void handle.command('setMuted', { muted: !muted });
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/** A press that changes nothing visible until the player reports back (a skip) confirms itself:
|
|
36
|
+
* the button dims while the call is in flight, then flashes, or turns red on failure. */
|
|
37
|
+
export function usePressFeedback() {
|
|
38
|
+
const [feedback, setFeedback] = useState(null);
|
|
39
|
+
const timer = useRef(undefined);
|
|
40
|
+
useEffect(() => () => clearTimeout(timer.current), []);
|
|
41
|
+
return {
|
|
42
|
+
feedbackFor: (key) => (feedback?.key === key ? feedback.state : undefined),
|
|
43
|
+
press: (key, action) => {
|
|
44
|
+
clearTimeout(timer.current);
|
|
45
|
+
setFeedback({ key, state: 'pending' });
|
|
46
|
+
action()
|
|
47
|
+
.then(() => setFeedback({ key, state: 'done' }), () => setFeedback({ key, state: 'error' }))
|
|
48
|
+
.finally(() => {
|
|
49
|
+
timer.current = setTimeout(() => setFeedback(null), 700);
|
|
50
|
+
});
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media-controls.js","sourceRoot":"","sources":["../../src/entities/media-controls.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** @jsxImportSource @emotion/react */
|
|
2
|
+
import type { EntityRef } from '@hashsome/core';
|
|
3
|
+
import { type ReactNode } from 'react';
|
|
4
|
+
import { type EntityHandle } from '../entity-handle.ts';
|
|
5
|
+
export interface MediaPlayerBarProps {
|
|
6
|
+
/** A media player, as a ref like `ha:media_player.living_room` or `ma:living_room`, or a handle (a custom source). */
|
|
7
|
+
entity: EntityRef | EntityHandle<'mediaPlayer'>;
|
|
8
|
+
/** What to call the player: the drawer's title and the name shown when nothing is playing. Defaults to the player's own name. */
|
|
9
|
+
name?: string;
|
|
10
|
+
/** Content for the media browser shown with the player in the drawer. Holding the card or pressing the artwork opens the drawer; the browse button opens it expanded. By default a `MediaBrowser` over the player's own library, shown only for a ref whose player has one; pass your own content to replace it, or `false` for no browse button. */
|
|
11
|
+
browse?: ReactNode | false;
|
|
12
|
+
}
|
|
13
|
+
/** Now playing with previous / play-pause / next and a volume control, for a media player entity. */
|
|
14
|
+
export declare function MediaPlayerBar({ entity, name, browse }: MediaPlayerBarProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
2
|
+
import { Flex, Typography } from 'e-prim';
|
|
3
|
+
import { motion } from 'motion/react';
|
|
4
|
+
import { useState } from 'react';
|
|
5
|
+
import { Icon } from '../icon.js';
|
|
6
|
+
import { ValueBar } from '../layout/drawer-controls.js';
|
|
7
|
+
import { fallbackName } from '../entity-handle.js';
|
|
8
|
+
import { useEntityHandle } from '../hooks.js';
|
|
9
|
+
import { DrawerTrigger } from '../layout/use-drawer.js';
|
|
10
|
+
import { HoldProgress } from '../layout/hold-progress.js';
|
|
11
|
+
import { useHold } from '../layout/use-hold.js';
|
|
12
|
+
import { IconButton } from '../layout/tile.js';
|
|
13
|
+
import { statusLabels } from '../status.js';
|
|
14
|
+
import { usePressFeedback, useVolumeControl } from './media-controls.js';
|
|
15
|
+
import { Cover } from '../layout/cover.js';
|
|
16
|
+
import { PlainButton } from '../layout/plain-button.js';
|
|
17
|
+
import { MediaBrowser } from './media-browser.js';
|
|
18
|
+
import { MediaPlayerBody } from './media-player-body.js';
|
|
19
|
+
import { formatDuration, useMediaPosition } from './media-progress.js';
|
|
20
|
+
import { useSeekHold } from './media-seek.js';
|
|
21
|
+
import { SeekLine } from './seek-line.js';
|
|
22
|
+
/** Glyph size inside the player's 44px circles — smaller than an icon's default so there is breathing room around it. */
|
|
23
|
+
const MEDIA_GLYPH = 18;
|
|
24
|
+
/** The ring around the artwork (the size of an icon circle): a button when there is somewhere to
|
|
25
|
+
* go, otherwise just the ring. */
|
|
26
|
+
function Ring({ onOpen, children }) {
|
|
27
|
+
return (_jsx(Flex, { ...(onOpen
|
|
28
|
+
? {
|
|
29
|
+
as: 'button',
|
|
30
|
+
type: 'button',
|
|
31
|
+
'aria-label': 'Open player',
|
|
32
|
+
title: 'Open player',
|
|
33
|
+
onClick: onOpen,
|
|
34
|
+
cursor: 'pointer',
|
|
35
|
+
}
|
|
36
|
+
: { as: 'span' }), center: true, position: "relative", p: 0, border: true, radius: "full", css: ({ density }) => ({
|
|
37
|
+
width: density.iconCircle,
|
|
38
|
+
height: density.iconCircle,
|
|
39
|
+
flex: 'none',
|
|
40
|
+
background: 'none',
|
|
41
|
+
}), children: children }));
|
|
42
|
+
}
|
|
43
|
+
/** The same spring the swatch rows pop in with, so the volume overlay opens like they do. */
|
|
44
|
+
const VOLUME_SPRING = { type: 'spring', stiffness: 520, damping: 26 };
|
|
45
|
+
/** The bar itself. Holding it (anywhere but on a button or slider) opens the drawer, with a thin
|
|
46
|
+
* line along the top that fills while the press is timed, like a tile's. */
|
|
47
|
+
function HoldCard({ open, status, children, }) {
|
|
48
|
+
const hold = useHold(() => open?.(), open !== undefined);
|
|
49
|
+
return (_jsxs(Flex, { position: "relative", align: "center", gap: 3, pl: 2.25, pr: 3, background: "surface", radius: "full", overflow: "hidden", "data-status": status, css: ({ density }) => ({ minHeight: density.tileHeight }), ...hold.handlers, children: [children, hold.holding ? _jsx(HoldProgress, {}) : null] }));
|
|
50
|
+
}
|
|
51
|
+
/** Now playing with previous / play-pause / next and a volume control, for a media player entity. */
|
|
52
|
+
export function MediaPlayerBar({ entity, name, browse }) {
|
|
53
|
+
const handle = useEntityHandle('mediaPlayer', entity);
|
|
54
|
+
const player = handle.entity;
|
|
55
|
+
const status = handle.status;
|
|
56
|
+
const [volumeOpen, setVolumeOpen] = useState(false);
|
|
57
|
+
const ready = status === 'ready';
|
|
58
|
+
const playing = player?.playback === 'playing';
|
|
59
|
+
const muted = player?.muted === true;
|
|
60
|
+
const caps = player?.capabilities;
|
|
61
|
+
const { feedbackFor, press } = usePressFeedback();
|
|
62
|
+
const volume = useVolumeControl(handle);
|
|
63
|
+
const artwork = (_jsx(Flex, { as: "span", center: true, width: 30, height: 30, radius: "full", overflow: "hidden", background: "surfaceRaised", color: "textMuted", children: player?.media?.artworkUrl ? (_jsx(Cover, { src: player.media.artworkUrl })) : (_jsx(Icon, { name: "lu:music", size: 14 })) }));
|
|
64
|
+
const position = useMediaPosition(player);
|
|
65
|
+
const seek = useSeekHold(ready ? position : undefined, caps?.seek ? (next) => void handle.command('seek', { position: next }) : undefined);
|
|
66
|
+
const duration = ready ? player?.duration : undefined;
|
|
67
|
+
const timed = seek.shown !== undefined && duration !== undefined && duration > 0;
|
|
68
|
+
const ref = typeof entity === 'string' ? entity : undefined;
|
|
69
|
+
const browser = browse === false
|
|
70
|
+
? undefined
|
|
71
|
+
: (browse ?? (ref && caps?.browse ? _jsx(MediaBrowser, { entity: ref, layout: "auto" }) : undefined));
|
|
72
|
+
const bar = (open, openExpanded) => (_jsxs(HoldCard, { open: open, status: status, children: [_jsx(Ring, { onOpen: open, children: artwork }), volumeOpen && ready ? (_jsxs(Flex, { as: motion.div, align: "center", gap: 2, grow: 1, minWidth: 0, initial: { opacity: 0 }, animate: { opacity: 1 }, transition: { duration: 0.15 }, children: [_jsx(PlainButton, { as: motion.button, initial: { scale: 0, opacity: 0 }, animate: { scale: 1, opacity: 1 }, transition: VOLUME_SPRING, "aria-label": muted ? 'Unmute' : 'Mute', "aria-pressed": muted, title: muted ? 'Unmute' : 'Mute', onClick: volume.toggleMute, center: true, color: muted ? 'accent' : 'textMuted', css: { flex: 'none' }, children: _jsx(Icon, { name: muted ? 'lu:volume-x' : 'lu:volume-2', size: 16 }) }), _jsx(Flex, { as: motion.div, grow: 1, minWidth: 0, initial: { scaleX: 0.4, opacity: 0 }, animate: { scaleX: 1, opacity: 1 }, transition: { ...VOLUME_SPRING, delay: 0.04 }, css: { transformOrigin: 'left center' }, children: _jsx(ValueBar, { label: "Volume level", value: volume.shown, min: 0, max: 100, keyStep: 5, height: 10, onDrag: volume.drag, onCommit: volume.commit }) }), _jsxs(Typography, { as: motion.span, variant: "secondary", color: "textMuted", minWidth: 32, align: "right", css: { flex: 'none' }, initial: { opacity: 0 }, animate: { opacity: 1 }, transition: { duration: 0.2, delay: 0.1 }, children: [volume.shown, "%"] })] })) : (_jsxs(_Fragment, { children: [_jsxs(Flex, { direction: "column", grow: 1, minWidth: 0, ...(ready ? {} : { color: 'textMuted' }), children: [_jsxs(Flex, { align: "center", gap: 1.5, minWidth: 0, children: [_jsx(Typography, { as: "span", variant: "label", noWrap: true, textOverflow: "ellipsis", children: ready
|
|
73
|
+
? (player?.media?.title ?? 'Nothing playing')
|
|
74
|
+
: statusLabels[status] }), ready && caps?.shuffle ? (_jsx(PlainButton, { "aria-label": "Shuffle", "aria-pressed": player?.shuffle === true, title: "Shuffle", onClick: () => void handle.command('setShuffle', { shuffle: player?.shuffle !== true }), center: true, color: player?.shuffle === true ? 'accent' : 'textMuted', css: { flex: 'none' }, children: _jsx(Icon, { name: "lu:shuffle", size: 14 }) })) : null] }), ready && player?.media?.artist ? (_jsx(Typography, { as: "span", variant: "secondary", color: "textMuted", noWrap: true, textOverflow: "ellipsis", children: player.media.artist })) : null] }), timed ? (_jsxs(Typography, { as: "span", variant: "secondary", color: "textMuted", noWrap: true, css: { flex: 'none', fontVariantNumeric: 'tabular-nums' }, children: [formatDuration(seek.shown ?? 0), " / ", formatDuration(duration ?? 0)] })) : null] })), _jsx(IconButton, { icon: volumeOpen ? 'lu:x' : muted ? 'lu:volume-x' : 'lu:volume-2', label: volumeOpen ? 'Close volume' : 'Volume', glyph: MEDIA_GLYPH, disabled: !ready || (caps?.volume === false && caps.mute === false), onClick: () => setVolumeOpen((current) => !current) }), open && browser !== undefined ? (_jsx(IconButton, { icon: "lu:library", label: "Browse media", glyph: MEDIA_GLYPH, onClick: openExpanded ?? open })) : null, _jsx(IconButton, { icon: "lu:skip-back", label: "Previous", glyph: MEDIA_GLYPH, disabled: !ready || caps?.previous === false, feedback: feedbackFor('previous'), onClick: () => press('previous', () => handle.command('previous')) }), _jsx(IconButton, { icon: playing ? 'lu:pause' : 'lu:play', label: playing ? 'Pause' : 'Play', glyph: MEDIA_GLYPH, disabled: !ready, primary: true, onClick: () => void handle.command('togglePlay') }), _jsx(IconButton, { icon: "lu:skip-forward", label: "Next", glyph: MEDIA_GLYPH, disabled: !ready || caps?.next === false, feedback: feedbackFor('next'), onClick: () => press('next', () => handle.command('next')) }), timed ? (_jsx(SeekLine, { seek: seek, duration: duration ?? 0, seekable: caps?.seek === true })) : null] }));
|
|
75
|
+
// Holding the card, the artwork and the browse button open the same drawer: the player laid out
|
|
76
|
+
// like the vertical one, with the library below it.
|
|
77
|
+
return ready ? (_jsx(DrawerTrigger, { icon: "lu:music", label: name ?? player?.name ?? fallbackName(entity), kind: "Media", body: _jsx(MediaPlayerBody, { entity: entity, ...(name !== undefined ? { name } : {}), ...(browser !== undefined ? { browser } : {}) }), children: (open, openExpanded) => bar(open, openExpanded) })) : (bar());
|
|
78
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media-player-bar.js","sourceRoot":"","sources":["../../src/entities/media-player-bar.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** @jsxImportSource @emotion/react */
|
|
2
|
+
import type { EntityRef } from '@hashsome/core';
|
|
3
|
+
import type { ReactNode } from 'react';
|
|
4
|
+
import { type EntityHandle } from '../entity-handle.ts';
|
|
5
|
+
/** The big player: the player centered at the top, and the library (or whatever `browser` is)
|
|
6
|
+
* below it. This one layout is the drawer, at every width, and the full page, so the two are the
|
|
7
|
+
* same thing and cannot drift apart. Not exported from the package; `MediaPlayerPage` and the
|
|
8
|
+
* media cards' drawers draw it. */
|
|
9
|
+
export declare function MediaPlayerBody({ entity, browser, wide, name, }: {
|
|
10
|
+
entity: EntityRef | EntityHandle<'mediaPlayer'>;
|
|
11
|
+
browser?: ReactNode;
|
|
12
|
+
/** Calls the player this instead of the name it reports. */
|
|
13
|
+
name?: string;
|
|
14
|
+
/** Gives the library the whole width, for one laid out to use it (the theater layout). Defaults to whether the drawer is expanded. */
|
|
15
|
+
wide?: boolean;
|
|
16
|
+
}): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
2
|
+
import { Box, Flex } from 'e-prim';
|
|
3
|
+
import { fallbackName } from '../entity-handle.js';
|
|
4
|
+
import { useEntityHandle } from '../hooks.js';
|
|
5
|
+
import { useDetail } from '../layout/detail-provider.js';
|
|
6
|
+
import { NowPlaying } from './now-playing.js';
|
|
7
|
+
/** The artwork ring's diameter in a full-size player, against the usual 168px. */
|
|
8
|
+
const FULL_SIZE = 260;
|
|
9
|
+
/** The big player: the player centered at the top, and the library (or whatever `browser` is)
|
|
10
|
+
* below it. This one layout is the drawer, at every width, and the full page, so the two are the
|
|
11
|
+
* same thing and cannot drift apart. Not exported from the package; `MediaPlayerPage` and the
|
|
12
|
+
* media cards' drawers draw it. */
|
|
13
|
+
export function MediaPlayerBody({ entity, browser, wide, name, }) {
|
|
14
|
+
const handle = useEntityHandle('mediaPlayer', entity);
|
|
15
|
+
const { detail } = useDetail();
|
|
16
|
+
const full = wide ?? detail?.expanded === true;
|
|
17
|
+
return (_jsxs(Flex, { direction: "column", gap: 5, grow: 1, minHeight: 0, children: [_jsx(Flex, { align: "center", justify: "center", ...(full ? { grow: 1 } : {}), css: { flexShrink: 0 }, children: _jsx(Box, { width: "100%", maxWidth: full ? 560 : 420, children: _jsx(NowPlaying, { handle: handle, fallback: fallbackName(entity), ...(name !== undefined ? { name } : {}), shuffle: "title", ...(full ? { size: FULL_SIZE } : {}) }) }) }), browser !== undefined ? (_jsxs(_Fragment, { children: [_jsx(Box, { height: 1, background: "border", css: { flexShrink: 0 } }), _jsx(Flex, { direction: "column", width: "100%", minHeight: 0, ...(full ? {} : { maxWidth: 960, mx: 'auto' }), children: browser })] })) : null] }));
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media-player-body.js","sourceRoot":"","sources":["../../src/entities/media-player-body.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAEnC,OAAO,EAAE,YAAY,EAAqB,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA+B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAmB,CAAC;AAE/C,kFAAkF;AAClF,MAAM,SAAS,GAAG,GAAG,CAAC;AAEtB;;;mCAGmC;AACnC,MAAM,UAAU,eAAe,CAAC,EAC9B,MAAM,EACN,OAAO,EACP,IAAI,EACJ,IAAI,GAUL;IACC,MAAM,MAAM,GAAG,eAAe,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IACtD,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAG,IAAI,IAAI,MAAM,EAAE,QAAQ,KAAK,IAAI,CAAC;IAC/C,OAAO,CACL,MAAC,IAAI,IAAC,SAAS,EAAC,QAAQ,EAAC,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,aAGpD,KAAC,IAAI,IAAC,KAAK,EAAC,QAAQ,EAAC,OAAO,EAAC,QAAQ,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,YACzF,KAAC,GAAG,IAAC,KAAK,EAAC,MAAM,EAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,YAC1C,KAAC,UAAU,IACT,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,YAAY,CAAC,MAAM,CAAC,KAC1B,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EACxC,OAAO,EAAC,OAAO,KACX,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GACrC,GACE,GACD,EACN,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,CACvB,8BACE,KAAC,GAAG,IAAC,MAAM,EAAE,CAAC,EAAE,UAAU,EAAC,QAAQ,EAAC,GAAG,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,GAAI,EAI9D,KAAC,IAAI,IACH,SAAS,EAAC,QAAQ,EAClB,KAAK,EAAC,MAAM,EACZ,SAAS,EAAE,CAAC,KACR,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,YAE9C,OAAO,GACH,IACN,CACJ,CAAC,CAAC,CAAC,IAAI,IACH,CACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** @jsxImportSource @emotion/react */
|
|
2
|
+
import type { EntityRef } from '@hashsome/core';
|
|
3
|
+
import type { ReactNode } from 'react';
|
|
4
|
+
import { type EntityHandle } from '../entity-handle.ts';
|
|
5
|
+
export interface MediaPlayerColumnProps {
|
|
6
|
+
/** A media player, as a ref like `ma:kitchen` or `ha:media_player.kitchen`, or a handle (a custom source). */
|
|
7
|
+
entity: EntityRef | EntityHandle<'mediaPlayer'>;
|
|
8
|
+
/** What to call the player: the drawer's title and the name shown when nothing is playing. Defaults to the player's own name. */
|
|
9
|
+
name?: string;
|
|
10
|
+
/** Content for the media browser shown with the player in the drawer. By default a `MediaBrowser` over the player's own library, shown only for a ref whose player has one; pass your own content to replace it, or `false` for no drawer. */
|
|
11
|
+
browse?: ReactNode | false;
|
|
12
|
+
}
|
|
13
|
+
/** The player as an upright card for a narrow column beside a dashboard (a quarter to a third of
|
|
14
|
+
* the width): the artwork in a ring that shows (and seeks) the position, title, transport and a
|
|
15
|
+
* volume bar that is always visible. It is only as tall as it needs to be. Holding the card or
|
|
16
|
+
* pressing the artwork opens the drawer with the player and its library; the browse button opens
|
|
17
|
+
* that drawer expanded. */
|
|
18
|
+
export declare function MediaPlayerColumn({ entity, name, browse }: MediaPlayerColumnProps): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
|
|
2
|
+
import { Flex } from 'e-prim';
|
|
3
|
+
import { fallbackName } from '../entity-handle.js';
|
|
4
|
+
import { useEntityHandle } from '../hooks.js';
|
|
5
|
+
import { HoldProgress } from '../layout/hold-progress.js';
|
|
6
|
+
import { IconButton } from '../layout/tile.js';
|
|
7
|
+
import { DrawerTrigger } from '../layout/use-drawer.js';
|
|
8
|
+
import { useHold } from '../layout/use-hold.js';
|
|
9
|
+
import { MediaBrowser } from './media-browser.js';
|
|
10
|
+
import { MediaPlayerBody } from './media-player-body.js';
|
|
11
|
+
import { NowPlaying } from './now-playing.js';
|
|
12
|
+
/** The player as an upright card for a narrow column beside a dashboard (a quarter to a third of
|
|
13
|
+
* the width): the artwork in a ring that shows (and seeks) the position, title, transport and a
|
|
14
|
+
* volume bar that is always visible. It is only as tall as it needs to be. Holding the card or
|
|
15
|
+
* pressing the artwork opens the drawer with the player and its library; the browse button opens
|
|
16
|
+
* that drawer expanded. */
|
|
17
|
+
export function MediaPlayerColumn({ entity, name, browse }) {
|
|
18
|
+
const handle = useEntityHandle('mediaPlayer', entity);
|
|
19
|
+
const player = handle.entity;
|
|
20
|
+
const ref = typeof entity === 'string' ? entity : undefined;
|
|
21
|
+
const browser = browse === false
|
|
22
|
+
? undefined
|
|
23
|
+
: (browse ??
|
|
24
|
+
(ref && player?.capabilities.browse ? (_jsx(MediaBrowser, { entity: ref, layout: "auto" })) : undefined));
|
|
25
|
+
const fallback = fallbackName(entity);
|
|
26
|
+
return browser !== undefined && handle.status === 'ready' ? (_jsx(DrawerTrigger, { icon: "lu:music", label: name ?? player?.name ?? fallback, kind: "Media", body: _jsx(MediaPlayerBody, { entity: entity, browser: browser, ...(name !== undefined ? { name } : {}) }), children: (open, openExpanded) => (_jsx(Card, { open: open, children: _jsx(NowPlaying, { handle: handle, fallback: fallback, ...(name !== undefined ? { name } : {}), onOpenArtwork: open, extra: _jsx(IconButton, { icon: "lu:library", label: "Browse media", glyph: 18, onClick: openExpanded }) }) })) })) : (_jsx(Card, { children: _jsx(NowPlaying, { handle: handle, fallback: fallback, ...(name !== undefined ? { name } : {}) }) }));
|
|
27
|
+
}
|
|
28
|
+
/** The card itself; with `open`, holding it (anywhere but on a control) calls it. */
|
|
29
|
+
function Card({ open, children }) {
|
|
30
|
+
const hold = useHold(() => open?.(), open !== undefined);
|
|
31
|
+
return (_jsxs(Flex, { direction: "column", background: "surface", radius: "card", p: 4, width: "100%",
|
|
32
|
+
// Only as tall as it needs, even in a parent that stretches its children.
|
|
33
|
+
css: { alignSelf: 'flex-start', position: 'relative', overflow: 'hidden' }, ...hold.handlers, children: [children, hold.holding ? _jsx(HoldProgress, {}) : null] }));
|
|
34
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media-player-column.js","sourceRoot":"","sources":["../../src/entities/media-player-column.tsx"],"names":[],"mappings":"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"}
|