ambient-display 1.1.0 → 1.1.2
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/build/client/_app/immutable/assets/0.Dl9__I4E.css +1 -0
- package/build/client/_app/immutable/assets/0.Dl9__I4E.css.br +0 -0
- package/build/client/_app/immutable/assets/0.Dl9__I4E.css.gz +0 -0
- package/build/client/_app/immutable/assets/2.BtzFOBtk.css +1 -0
- package/build/client/_app/immutable/assets/2.BtzFOBtk.css.br +0 -0
- package/build/client/_app/immutable/assets/2.BtzFOBtk.css.gz +0 -0
- package/build/client/_app/immutable/assets/3.BvcZlbFP.css +1 -0
- package/build/client/_app/immutable/assets/3.BvcZlbFP.css.br +0 -0
- package/build/client/_app/immutable/assets/3.BvcZlbFP.css.gz +0 -0
- package/build/client/_app/immutable/assets/LoadingIndicator.D0m6rSKQ.css +1 -0
- package/build/client/_app/immutable/assets/LoadingIndicator.D0m6rSKQ.css.br +0 -0
- package/build/client/_app/immutable/assets/LoadingIndicator.D0m6rSKQ.css.gz +0 -0
- package/build/client/_app/immutable/assets/PlayingTracker.9uM5nyWg.css +1 -0
- package/build/client/_app/immutable/assets/PlayingTracker.9uM5nyWg.css.br +0 -0
- package/build/client/_app/immutable/assets/PlayingTracker.9uM5nyWg.css.gz +0 -0
- package/build/client/_app/immutable/assets/_layout.Dl9__I4E.css +1 -0
- package/build/client/_app/immutable/assets/_layout.Dl9__I4E.css.br +0 -0
- package/build/client/_app/immutable/assets/_layout.Dl9__I4E.css.gz +0 -0
- package/build/client/_app/immutable/assets/_page.BtzFOBtk.css +1 -0
- package/build/client/_app/immutable/assets/_page.BtzFOBtk.css.br +0 -0
- package/build/client/_app/immutable/assets/_page.BtzFOBtk.css.gz +0 -0
- package/build/client/_app/immutable/assets/_page.BvcZlbFP.css +1 -0
- package/build/client/_app/immutable/assets/_page.BvcZlbFP.css.br +0 -0
- package/build/client/_app/immutable/assets/_page.BvcZlbFP.css.gz +0 -0
- package/build/client/_app/immutable/chunks/LoadingIndicator.COVTk436.js +1 -0
- package/build/client/_app/immutable/chunks/LoadingIndicator.COVTk436.js.br +0 -0
- package/build/client/_app/immutable/chunks/LoadingIndicator.COVTk436.js.gz +0 -0
- package/build/client/_app/immutable/chunks/PlayingTracker.Cymhk9j5.js +5 -0
- package/build/client/_app/immutable/chunks/PlayingTracker.Cymhk9j5.js.br +0 -0
- package/build/client/_app/immutable/chunks/PlayingTracker.Cymhk9j5.js.gz +0 -0
- package/build/client/_app/immutable/chunks/disclose-version.N57b1q78.js +1 -0
- package/build/client/_app/immutable/chunks/disclose-version.N57b1q78.js.br +0 -0
- package/build/client/_app/immutable/chunks/disclose-version.N57b1q78.js.gz +0 -0
- package/build/client/_app/immutable/chunks/entry.CTcSu7Oh.js +3 -0
- package/build/client/_app/immutable/chunks/entry.CTcSu7Oh.js.br +0 -0
- package/build/client/_app/immutable/chunks/entry.CTcSu7Oh.js.gz +0 -0
- package/build/client/_app/immutable/chunks/index-client.DV07uIiZ.js +1 -0
- package/build/client/_app/immutable/chunks/index-client.DV07uIiZ.js.br +0 -0
- package/build/client/_app/immutable/chunks/index-client.DV07uIiZ.js.gz +0 -0
- package/build/client/_app/immutable/chunks/index.DFULH2AN.js +1 -0
- package/build/client/_app/immutable/chunks/index.DFULH2AN.js.br +0 -0
- package/build/client/_app/immutable/chunks/index.DFULH2AN.js.gz +0 -0
- package/build/client/_app/immutable/chunks/index.DLR8Bvs6.js +4 -0
- package/build/client/_app/immutable/chunks/index.DLR8Bvs6.js.br +0 -0
- package/build/client/_app/immutable/chunks/index.DLR8Bvs6.js.gz +0 -0
- package/build/client/_app/immutable/chunks/legacy.DZgMwYuQ.js +1 -0
- package/build/client/_app/immutable/chunks/legacy.DZgMwYuQ.js.br +0 -0
- package/build/client/_app/immutable/chunks/legacy.DZgMwYuQ.js.gz +0 -0
- package/build/client/_app/immutable/chunks/props.DYfFZGja.js +1 -0
- package/build/client/_app/immutable/chunks/props.DYfFZGja.js.br +0 -0
- package/build/client/_app/immutable/chunks/props.DYfFZGja.js.gz +0 -0
- package/build/client/_app/immutable/chunks/snippet.BVSCguOu.js +1 -0
- package/build/client/_app/immutable/chunks/snippet.BVSCguOu.js.br +0 -0
- package/build/client/_app/immutable/chunks/snippet.BVSCguOu.js.gz +0 -0
- package/build/client/_app/immutable/chunks/this.EZLWgc5v.js +1 -0
- package/build/client/_app/immutable/chunks/this.EZLWgc5v.js.br +0 -0
- package/build/client/_app/immutable/chunks/this.EZLWgc5v.js.gz +0 -0
- package/build/client/_app/immutable/chunks/utils.BXcQV2KO.js +1 -0
- package/build/client/_app/immutable/chunks/utils.BXcQV2KO.js.br +0 -0
- package/build/client/_app/immutable/chunks/utils.BXcQV2KO.js.gz +0 -0
- package/build/client/_app/immutable/entry/app.DHMJZPqS.js +2 -0
- package/build/client/_app/immutable/entry/app.DHMJZPqS.js.br +0 -0
- package/build/client/_app/immutable/entry/app.DHMJZPqS.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.BGJKS9mR.js +1 -0
- package/build/client/_app/immutable/entry/start.BGJKS9mR.js.br +2 -0
- package/build/client/_app/immutable/entry/start.BGJKS9mR.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.DaJoi3FK.js +2 -0
- package/build/client/_app/immutable/nodes/0.DaJoi3FK.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.DaJoi3FK.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.0EwG4xPT.js +1 -0
- package/build/client/_app/immutable/nodes/1.0EwG4xPT.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.0EwG4xPT.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.CIcrK0Mf.js +1 -0
- package/build/client/_app/immutable/nodes/2.CIcrK0Mf.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.CIcrK0Mf.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.vzk8SJSG.js +1 -0
- package/build/client/_app/immutable/nodes/3.vzk8SJSG.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.vzk8SJSG.js.gz +0 -0
- package/build/client/_app/version.json +1 -0
- package/build/client/_app/version.json.br +0 -0
- package/build/client/_app/version.json.gz +0 -0
- package/build/client/manifest.json.br +0 -0
- package/build/client/manifest.json.gz +0 -0
- package/build/env.js +45 -0
- package/build/handler.js +1375 -0
- package/build/index.js +334 -0
- package/build/server/chunks/0-D_yciAvo.js +91 -0
- package/build/server/chunks/0-D_yciAvo.js.map +1 -0
- package/build/server/chunks/1-BA-qTHOy.js +9 -0
- package/build/server/chunks/1-BA-qTHOy.js.map +1 -0
- package/build/server/chunks/2-DPsIhdeI.js +9 -0
- package/build/server/chunks/2-DPsIhdeI.js.map +1 -0
- package/build/server/chunks/3-CZREXwZu.js +9 -0
- package/build/server/chunks/3-CZREXwZu.js.map +1 -0
- package/build/server/chunks/LoadingIndicator-CTUFEPkL.js +10 -0
- package/build/server/chunks/LoadingIndicator-CTUFEPkL.js.map +1 -0
- package/build/server/chunks/LoadingIndicator.svelte_svelte_type_style_lang-CVdBHA1v.js +172 -0
- package/build/server/chunks/LoadingIndicator.svelte_svelte_type_style_lang-CVdBHA1v.js.map +1 -0
- package/build/server/chunks/PlayingTracker-BIq1bdv_.js +18 -0
- package/build/server/chunks/PlayingTracker-BIq1bdv_.js.map +1 -0
- package/build/server/chunks/_layout.svelte-BoFI04Ng.js +24 -0
- package/build/server/chunks/_layout.svelte-BoFI04Ng.js.map +1 -0
- package/build/server/chunks/_page.svelte-C3Mw7ZhL.js +115 -0
- package/build/server/chunks/_page.svelte-C3Mw7ZhL.js.map +1 -0
- package/build/server/chunks/_page.svelte-CzGyTA7b.js +368 -0
- package/build/server/chunks/_page.svelte-CzGyTA7b.js.map +1 -0
- package/build/server/chunks/error.svelte-BZE1ioPX.js +116 -0
- package/build/server/chunks/error.svelte-BZE1ioPX.js.map +1 -0
- package/build/server/chunks/exports-DAjI6ZSp.js +125 -0
- package/build/server/chunks/exports-DAjI6ZSp.js.map +1 -0
- package/build/server/chunks/index2-BA59f76P.js +1214 -0
- package/build/server/chunks/index2-BA59f76P.js.map +1 -0
- package/build/server/index.js +4868 -0
- package/build/server/index.js.map +1 -0
- package/build/server/manifest.js +50 -0
- package/build/server/manifest.js.map +1 -0
- package/build/shims.js +32 -0
- package/package.json +9 -2
- package/server/index.js +4 -0
- package/server/spotify_auth.json +1 -0
- package/.prettierignore +0 -4
- package/.prettierrc +0 -17
- package/CHANGELOG.md +0 -34
- package/env.template +0 -2
- package/eslint.config.js +0 -24
- package/jsconfig.json +0 -19
- package/screenshot.png +0 -0
- package/src/app.d.ts +0 -13
- package/src/app.html +0 -12
- package/src/lib/actions/qr.svelte.js +0 -23
- package/src/lib/comms.js +0 -25
- package/src/lib/components/AuthenticateTrigger.svelte +0 -74
- package/src/lib/components/Controls.svelte +0 -91
- package/src/lib/components/ImageLoad.svelte +0 -79
- package/src/lib/components/LoadingIndicator.svelte +0 -75
- package/src/lib/components/MediaItem.svelte +0 -75
- package/src/lib/components/PlayingTracker.svelte +0 -94
- package/src/lib/components/ResultsList.svelte +0 -80
- package/src/lib/components/Toast/Item.svelte +0 -71
- package/src/lib/components/Toast/Manager.svelte +0 -34
- package/src/lib/icons/disc.svg +0 -1
- package/src/lib/index.js +0 -1
- package/src/lib/store.js +0 -146
- package/src/lib/styles.scss +0 -166
- package/src/lib/toast.js +0 -57
- package/src/lib/utils.js +0 -723
- package/src/routes/+layout.server.js +0 -25
- package/src/routes/+layout.svelte +0 -72
- package/src/routes/+page.svelte +0 -381
- package/src/routes/player/+page.svelte +0 -294
- package/svelte.config.js +0 -19
- package/tools/BuildManifest.js +0 -87
- package/vite.config.js +0 -46
- /package/{static → build/client}/favicon.ico +0 -0
- /package/{static → build/client}/favicon.png +0 -0
- /package/{static → build/client}/icons/144.favicon.png +0 -0
- /package/{static → build/client}/icons/168.favicon.png +0 -0
- /package/{static → build/client}/icons/192.favicon.png +0 -0
- /package/{static → build/client}/icons/48.favicon.png +0 -0
- /package/{static → build/client}/icons/72.favicon.png +0 -0
- /package/{static → build/client}/icons/96.favicon.png +0 -0
- /package/{static → build/client}/manifest.json +0 -0
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import ImageLoad from './ImageLoad.svelte';
|
|
3
|
-
|
|
4
|
-
const { id, image, title, subtitle, uri, action = null } = $props();
|
|
5
|
-
</script>
|
|
6
|
-
|
|
7
|
-
<div class="item" data-id={id} class:withAction={!!action}>
|
|
8
|
-
<div class="item-image">
|
|
9
|
-
<ImageLoad full={image.full.url} low={image.low.url} />
|
|
10
|
-
</div>
|
|
11
|
-
|
|
12
|
-
<div class="item-content">
|
|
13
|
-
<span class="item-content-title ellipsis">{title}</span>
|
|
14
|
-
<span class="item-content-subtitle ellipsis color-2">{subtitle}</span>
|
|
15
|
-
</div>
|
|
16
|
-
|
|
17
|
-
{#if action}
|
|
18
|
-
<div class="item-action">
|
|
19
|
-
{@render action()}
|
|
20
|
-
</div>
|
|
21
|
-
{/if}
|
|
22
|
-
</div>
|
|
23
|
-
|
|
24
|
-
<style lang="scss">
|
|
25
|
-
.item {
|
|
26
|
-
display: grid;
|
|
27
|
-
|
|
28
|
-
align-items: center;
|
|
29
|
-
grid-template-areas: 'image content';
|
|
30
|
-
grid-template-columns: var(--media-image, 64px) 1fr;
|
|
31
|
-
grid-template-rows: auto;
|
|
32
|
-
column-gap: var(--spacing-normal);
|
|
33
|
-
row-gap: var(--spacing-small);
|
|
34
|
-
|
|
35
|
-
&.withAction {
|
|
36
|
-
grid-template-areas:
|
|
37
|
-
'image content'
|
|
38
|
-
'image action';
|
|
39
|
-
grid-template-rows: 1fr auto;
|
|
40
|
-
align-items: flex-start;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
&-image {
|
|
44
|
-
grid-area: image;
|
|
45
|
-
|
|
46
|
-
isolation: isolate;
|
|
47
|
-
|
|
48
|
-
overflow: hidden;
|
|
49
|
-
border-radius: var(--border-radius-normal);
|
|
50
|
-
|
|
51
|
-
line-height: 0;
|
|
52
|
-
|
|
53
|
-
align-self: flex-start;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
&-content {
|
|
57
|
-
grid-area: content;
|
|
58
|
-
|
|
59
|
-
display: flex;
|
|
60
|
-
|
|
61
|
-
flex-direction: column;
|
|
62
|
-
|
|
63
|
-
min-width: 0;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
&-content-title,
|
|
67
|
-
&-content-subtitle {
|
|
68
|
-
font-size: var(--media-font-size, var(--font-size-body-1));
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
&-action {
|
|
72
|
-
grid-area: action;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
</style>
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { socket } from '$lib/comms';
|
|
3
|
-
import { api } from '$lib/store';
|
|
4
|
-
import Vibrant from 'node-vibrant';
|
|
5
|
-
import * as DataTypes from '$server/types/data.js';
|
|
6
|
-
|
|
7
|
-
let {
|
|
8
|
-
playing = $bindable(null),
|
|
9
|
-
polling = false,
|
|
10
|
-
pollingTime = 5000,
|
|
11
|
-
activate = $bindable()
|
|
12
|
-
} = $props();
|
|
13
|
-
|
|
14
|
-
/** @type {{'--color-1'?: string,'--color-2'?: string,'--color-3'?: string,'--color-bg'?: string}} */
|
|
15
|
-
let palette = $state({});
|
|
16
|
-
|
|
17
|
-
$effect(() => {
|
|
18
|
-
Object.entries(palette).forEach(([prop, value]) => {
|
|
19
|
-
document.documentElement.style.setProperty(prop, value);
|
|
20
|
-
});
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
*
|
|
25
|
-
* @param {string} image
|
|
26
|
-
*/
|
|
27
|
-
async function getPalette(image) {
|
|
28
|
-
const img = new Image();
|
|
29
|
-
img.crossOrigin = 'Anonymous';
|
|
30
|
-
img.src = image; // + '?not-from-cache-please';
|
|
31
|
-
|
|
32
|
-
const palette = await Vibrant.from(img).getPalette();
|
|
33
|
-
|
|
34
|
-
if (!palette) {
|
|
35
|
-
return {};
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return {
|
|
39
|
-
'--color-1': palette.LightVibrant?.hex,
|
|
40
|
-
'--color-2': palette.DarkVibrant?.hex,
|
|
41
|
-
'--color-3': palette.Muted?.hex,
|
|
42
|
-
'--color-bg': palette.DarkMuted?.hex,
|
|
43
|
-
'--color-highlight': palette.Vibrant?.hex
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
*
|
|
49
|
-
* @param {DataTypes.ApiInfoResponse} newData
|
|
50
|
-
*/
|
|
51
|
-
async function update(newData) {
|
|
52
|
-
if (newData?.track?.uri !== playing?.track?.uri) {
|
|
53
|
-
// is different
|
|
54
|
-
|
|
55
|
-
if (newData?.track?.normalised) {
|
|
56
|
-
palette = await getPalette(newData.track.normalised.image.low.url);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
playing = newData;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
async function getPlaying() {
|
|
64
|
-
const data = await $api.info();
|
|
65
|
-
|
|
66
|
-
update(data);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function automateLoop() {
|
|
70
|
-
const run = async () => {
|
|
71
|
-
await getPlaying();
|
|
72
|
-
int.current = window.setTimeout(run, pollingTime);
|
|
73
|
-
};
|
|
74
|
-
const int = { current: 0 };
|
|
75
|
-
|
|
76
|
-
run();
|
|
77
|
-
|
|
78
|
-
return () => {
|
|
79
|
-
clearTimeout(int.current);
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
$effect(() => {
|
|
84
|
-
if (polling) {
|
|
85
|
-
return automateLoop();
|
|
86
|
-
} else {
|
|
87
|
-
$socket?.on('info', (track) => {
|
|
88
|
-
update(track);
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
activate = getPlaying;
|
|
93
|
-
});
|
|
94
|
-
</script>
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import MediaItem from './MediaItem.svelte';
|
|
3
|
-
import * as DataTypes from '$server/types/data.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @typedef {object} ResultsListProps
|
|
7
|
-
* @property {boolean} [expanded]
|
|
8
|
-
* @property {() => void} onActivate
|
|
9
|
-
* @property {DataTypes.ApiTrack[]} items
|
|
10
|
-
* @property {string} title
|
|
11
|
-
* @property {import('svelte').Snippet<[DataTypes.ApiNormalisedItem]>} action
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
/** @type {ResultsListProps} */
|
|
15
|
-
const { expanded = false, onActivate, items, title, action: ListItemAction } = $props();
|
|
16
|
-
</script>
|
|
17
|
-
|
|
18
|
-
<div class="results-list">
|
|
19
|
-
<button onclick={onActivate} class:active={expanded} class="btn-reset results-list-top"
|
|
20
|
-
>{title}</button
|
|
21
|
-
>
|
|
22
|
-
{#if expanded}
|
|
23
|
-
<div class="results-list-items">
|
|
24
|
-
{#each items as item}
|
|
25
|
-
<MediaItem {...item.normalised}>
|
|
26
|
-
{#snippet action()}
|
|
27
|
-
{@render ListItemAction(item.normalised)}
|
|
28
|
-
{/snippet}
|
|
29
|
-
</MediaItem>
|
|
30
|
-
{/each}
|
|
31
|
-
</div>
|
|
32
|
-
{/if}
|
|
33
|
-
</div>
|
|
34
|
-
|
|
35
|
-
<style lang="scss">
|
|
36
|
-
.results-list {
|
|
37
|
-
display: grid;
|
|
38
|
-
|
|
39
|
-
grid-template-rows: auto 1fr;
|
|
40
|
-
|
|
41
|
-
flex: 1;
|
|
42
|
-
min-height: 0;
|
|
43
|
-
|
|
44
|
-
&:not(:last-child) .results-list-items {
|
|
45
|
-
border-bottom: 1px solid var(--color-1);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
&-top {
|
|
49
|
-
padding: var(--spacing-normal);
|
|
50
|
-
|
|
51
|
-
border-bottom: 1px solid var(--color-1);
|
|
52
|
-
|
|
53
|
-
text-align: left;
|
|
54
|
-
|
|
55
|
-
&:not(.active):hover,
|
|
56
|
-
&:not(.active):focus-visible {
|
|
57
|
-
background-color: var(--color-2);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
&.active {
|
|
61
|
-
background-color: var(--color-1);
|
|
62
|
-
color: var(--color-bg);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
&-items {
|
|
67
|
-
padding: var(--spacing-normal);
|
|
68
|
-
|
|
69
|
-
overflow: auto;
|
|
70
|
-
|
|
71
|
-
min-height: 0;
|
|
72
|
-
|
|
73
|
-
display: flex;
|
|
74
|
-
|
|
75
|
-
flex-direction: column;
|
|
76
|
-
|
|
77
|
-
gap: var(--spacing-normal);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
</style>
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { fade, fly } from 'svelte/transition';
|
|
3
|
-
|
|
4
|
-
import { Disc, InformationCircle, Warning } from 'svelte-ionicons';
|
|
5
|
-
|
|
6
|
-
const { id, message, type = 'info', time = 2500, onEnd } = $props();
|
|
7
|
-
|
|
8
|
-
let timerId = $state(0);
|
|
9
|
-
|
|
10
|
-
$effect(() => {
|
|
11
|
-
return () => clearTimeout(timerId);
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
function startTimer() {
|
|
15
|
-
timerId = window.setTimeout(() => {
|
|
16
|
-
onEnd(id);
|
|
17
|
-
}, time);
|
|
18
|
-
}
|
|
19
|
-
</script>
|
|
20
|
-
|
|
21
|
-
<div in:fly={{ y: -50 }} out:fade onintroend={startTimer} class="item bg-color-3 color-bg">
|
|
22
|
-
<div class="item-icon">
|
|
23
|
-
{#if type === 'track'}
|
|
24
|
-
<Disc />
|
|
25
|
-
{/if}
|
|
26
|
-
{#if type === 'info'}
|
|
27
|
-
<InformationCircle />
|
|
28
|
-
{/if}
|
|
29
|
-
{#if type === 'error'}
|
|
30
|
-
<Warning />
|
|
31
|
-
{/if}
|
|
32
|
-
</div>
|
|
33
|
-
|
|
34
|
-
<div class="item-message size-small-2">
|
|
35
|
-
{@html message}
|
|
36
|
-
</div>
|
|
37
|
-
</div>
|
|
38
|
-
|
|
39
|
-
<style lang="scss">
|
|
40
|
-
.item {
|
|
41
|
-
display: grid;
|
|
42
|
-
|
|
43
|
-
grid-template-columns: 32px 1fr;
|
|
44
|
-
|
|
45
|
-
align-items: center;
|
|
46
|
-
|
|
47
|
-
gap: var(--spacing-small);
|
|
48
|
-
|
|
49
|
-
max-width: 250px;
|
|
50
|
-
|
|
51
|
-
padding: var(--spacing-small);
|
|
52
|
-
border-radius: var(--border-radius-normal);
|
|
53
|
-
|
|
54
|
-
&-icon {
|
|
55
|
-
line-height: 0;
|
|
56
|
-
|
|
57
|
-
:global(svg) {
|
|
58
|
-
fill: currentColor;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
&-message {
|
|
63
|
-
padding-right: var(--spacing-normal);
|
|
64
|
-
|
|
65
|
-
:global(em) {
|
|
66
|
-
font-style: normal;
|
|
67
|
-
color: var(--color-bg);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
</style>
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { toastItems } from '$lib/toast';
|
|
3
|
-
import { flip } from 'svelte/animate';
|
|
4
|
-
import Item from './Item.svelte';
|
|
5
|
-
</script>
|
|
6
|
-
|
|
7
|
-
<div class="manager">
|
|
8
|
-
{#each $toastItems as item (item.id)}
|
|
9
|
-
<div animate:flip>
|
|
10
|
-
<Item onEnd={toastItems.removeItem} {...item} />
|
|
11
|
-
</div>
|
|
12
|
-
{/each}
|
|
13
|
-
</div>
|
|
14
|
-
|
|
15
|
-
<style lang="scss">
|
|
16
|
-
.manager {
|
|
17
|
-
position: fixed;
|
|
18
|
-
|
|
19
|
-
top: 0;
|
|
20
|
-
left: 50%;
|
|
21
|
-
|
|
22
|
-
transform: translateX(-50%);
|
|
23
|
-
|
|
24
|
-
z-index: 10;
|
|
25
|
-
|
|
26
|
-
display: flex;
|
|
27
|
-
|
|
28
|
-
align-items: center;
|
|
29
|
-
flex-direction: column;
|
|
30
|
-
gap: var(--spacing-normal);
|
|
31
|
-
|
|
32
|
-
padding: var(--spacing-normal);
|
|
33
|
-
}
|
|
34
|
-
</style>
|
package/src/lib/icons/disc.svg
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512"><path d="M256 176a80 80 0 1080 80 80.09 80.09 0 00-80-80zm0 112a32 32 0 1132-32 32 32 0 01-32 32z"/><path d="M414.39 97.61A224 224 0 1097.61 414.39 224 224 0 10414.39 97.61zM256 368a112 112 0 11112-112 112.12 112.12 0 01-112 112z"/></svg>
|
package/src/lib/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
// place files you want to import through the `$lib` alias in this folder.
|
package/src/lib/store.js
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
import { derived, writable } from 'svelte/store';
|
|
2
|
-
import { toastItems } from './toast';
|
|
3
|
-
import * as OptionsTypes from '$server/types/options';
|
|
4
|
-
|
|
5
|
-
export const liveData = writable(false);
|
|
6
|
-
export const authenticated = writable(false);
|
|
7
|
-
export const settled = writable(false);
|
|
8
|
-
|
|
9
|
-
/** @type {import("svelte/store").Writable<OptionsTypes.Config>}} */
|
|
10
|
-
export const config = writable({});
|
|
11
|
-
export const siteUrl = derived([config], ([$config]) =>
|
|
12
|
-
[$config?.protocol, $config?.origin].join('')
|
|
13
|
-
);
|
|
14
|
-
export const sitePort = derived([config], ([$config]) => $config.protocol);
|
|
15
|
-
|
|
16
|
-
const objectHasValues = (obj) => Object.values(obj).length > 0;
|
|
17
|
-
|
|
18
|
-
export const address = derived(
|
|
19
|
-
[liveData, siteUrl, sitePort],
|
|
20
|
-
([$liveData, $siteUrl, $sitePort]) => {
|
|
21
|
-
const full = `${typeof window !== 'undefined' ? window.location.protocol : 'http:'}//${$siteUrl}:${$sitePort}`;
|
|
22
|
-
|
|
23
|
-
return {
|
|
24
|
-
full,
|
|
25
|
-
naked: [$siteUrl, $sitePort].join(':'),
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
*
|
|
29
|
-
* @param {string} route
|
|
30
|
-
* @returns {string}
|
|
31
|
-
*/
|
|
32
|
-
get(route) {
|
|
33
|
-
return `${full}${route}`;
|
|
34
|
-
},
|
|
35
|
-
|
|
36
|
-
endpoint: $liveData || !$siteUrl ? '' : `${$siteUrl}:3000`,
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
*
|
|
40
|
-
* @param {string} route
|
|
41
|
-
* @returns {string}
|
|
42
|
-
*/
|
|
43
|
-
server(route) {
|
|
44
|
-
return `${this.endpoint}${route}`;
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
export const api = derived([address], ([$address]) => {
|
|
51
|
-
/**
|
|
52
|
-
*
|
|
53
|
-
* @param {string} route
|
|
54
|
-
* @param {Record<string, any>} [data]
|
|
55
|
-
* @param {RequestInit} opts
|
|
56
|
-
*/
|
|
57
|
-
const f = async (route, data = {}, opts = {}) => {
|
|
58
|
-
try {
|
|
59
|
-
const url = new URL(
|
|
60
|
-
[
|
|
61
|
-
$address.endpoint.startsWith('http') ? '' : window.location.origin,
|
|
62
|
-
$address.endpoint,
|
|
63
|
-
'/api',
|
|
64
|
-
route
|
|
65
|
-
].join('')
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
if (opts.method === 'POST' && objectHasValues(data)) {
|
|
69
|
-
opts.body = JSON.stringify(data);
|
|
70
|
-
} else if (objectHasValues(data)) {
|
|
71
|
-
url.search = new URLSearchParams(data).toString();
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const resp = await fetch(url, opts);
|
|
75
|
-
const result = await resp.json();
|
|
76
|
-
|
|
77
|
-
if (resp.status !== 200) {
|
|
78
|
-
throw new Error(result);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return result;
|
|
82
|
-
} catch (e) {
|
|
83
|
-
toastItems.addItem({
|
|
84
|
-
message: 'Api Error',
|
|
85
|
-
type: 'error'
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
throw e;
|
|
89
|
-
}
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
return {
|
|
93
|
-
health() {
|
|
94
|
-
return f('/health');
|
|
95
|
-
},
|
|
96
|
-
info() {
|
|
97
|
-
return f('/info');
|
|
98
|
-
},
|
|
99
|
-
/**
|
|
100
|
-
*
|
|
101
|
-
* @param {string} q
|
|
102
|
-
*/
|
|
103
|
-
search(q) {
|
|
104
|
-
return f('/search', { q });
|
|
105
|
-
},
|
|
106
|
-
/**
|
|
107
|
-
*
|
|
108
|
-
* @param {string} id
|
|
109
|
-
*/
|
|
110
|
-
artist(id) {
|
|
111
|
-
return f(`/artist/${id}`);
|
|
112
|
-
},
|
|
113
|
-
/**
|
|
114
|
-
*
|
|
115
|
-
* @param {string} id
|
|
116
|
-
*/
|
|
117
|
-
album(id) {
|
|
118
|
-
return f(`/album/${id}`);
|
|
119
|
-
},
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
*
|
|
123
|
-
* @param {string} uri
|
|
124
|
-
* @param {string} [name]
|
|
125
|
-
*/
|
|
126
|
-
addTrack(uri, name) {
|
|
127
|
-
return f(`/add`, { uri, name });
|
|
128
|
-
},
|
|
129
|
-
|
|
130
|
-
play() {
|
|
131
|
-
return f('/play');
|
|
132
|
-
},
|
|
133
|
-
|
|
134
|
-
pause() {
|
|
135
|
-
return f('/pause');
|
|
136
|
-
},
|
|
137
|
-
|
|
138
|
-
skipForward() {
|
|
139
|
-
return f('/skipForward');
|
|
140
|
-
},
|
|
141
|
-
|
|
142
|
-
skipBackward() {
|
|
143
|
-
return f('/skipBackward');
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
});
|
package/src/lib/styles.scss
DELETED
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
:root {
|
|
3
|
-
--font-family: system-ui;
|
|
4
|
-
|
|
5
|
-
--font-weight-headline-bold: 900;
|
|
6
|
-
--font-weight-headline: 700;
|
|
7
|
-
--font-weight-body: 600;
|
|
8
|
-
|
|
9
|
-
--font-size-level-headline-1: 36px;
|
|
10
|
-
--font-size-level-headline-2: 28px;
|
|
11
|
-
--font-size-level-headline-3: 21px;
|
|
12
|
-
--font-size-level-body: 16px;
|
|
13
|
-
--font-size-level-small-1: 10px;
|
|
14
|
-
--font-size-level-small-2: 12px;
|
|
15
|
-
|
|
16
|
-
--easing: cubic-bezier(0.4, 0, 0.2, 1);
|
|
17
|
-
|
|
18
|
-
--color-bg: white;
|
|
19
|
-
--color-1: black;
|
|
20
|
-
--color-2: grey;
|
|
21
|
-
--color-3: lightgrey;
|
|
22
|
-
--color-highlight: blue;
|
|
23
|
-
|
|
24
|
-
--border-radius-large: 10px;
|
|
25
|
-
--border-radius-normal: 5px;
|
|
26
|
-
|
|
27
|
-
--spacing-x-large: 50px;
|
|
28
|
-
--spacing-large: 20px;
|
|
29
|
-
--spacing-normal: 10px;
|
|
30
|
-
--spacing-small: 5px;
|
|
31
|
-
|
|
32
|
-
-ms-text-size-adjust: 100%;
|
|
33
|
-
-webkit-text-size-adjust: 100%;
|
|
34
|
-
-moz-osx-font-smoothing: grayscale;
|
|
35
|
-
-webkit-font-smoothing: antialiased;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
*,
|
|
39
|
-
*:before,
|
|
40
|
-
*:after {
|
|
41
|
-
box-sizing: border-box;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
html,
|
|
45
|
-
body {
|
|
46
|
-
font-size: var(--font-size-normal);
|
|
47
|
-
font-family: var(--font-family);
|
|
48
|
-
font-weight: var(--font-weight-body);
|
|
49
|
-
line-height: 1.2;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
h1,
|
|
53
|
-
.headline-1 {
|
|
54
|
-
font-size: var(--font-size-level-headline-1);
|
|
55
|
-
font-weight: var(--font-weight-headline-bold);
|
|
56
|
-
margin: 0;
|
|
57
|
-
line-height: 1;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
h2,
|
|
61
|
-
.headline-2 {
|
|
62
|
-
font-size: var(--font-size-level-headline-2);
|
|
63
|
-
font-weight: var(--font-weight-headline);
|
|
64
|
-
margin: 0;
|
|
65
|
-
line-height: 1;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
h3,
|
|
69
|
-
.headline-3 {
|
|
70
|
-
font-size: var(--font-size-level-headline-3);
|
|
71
|
-
font-weight: var(--font-weight-headline);
|
|
72
|
-
margin: 0;
|
|
73
|
-
line-height: 1;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
p a {
|
|
77
|
-
text-decoration: none;
|
|
78
|
-
color: var(--color-highlight);
|
|
79
|
-
|
|
80
|
-
&:hover,
|
|
81
|
-
&:focus-visible {
|
|
82
|
-
opacity: 0.75;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
img {
|
|
87
|
-
max-width: 100%;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
.btn-reset {
|
|
91
|
-
outline: none;
|
|
92
|
-
border: none;
|
|
93
|
-
|
|
94
|
-
padding: 0;
|
|
95
|
-
margin: 0;
|
|
96
|
-
|
|
97
|
-
text-transform: inherit;
|
|
98
|
-
|
|
99
|
-
cursor: pointer;
|
|
100
|
-
|
|
101
|
-
background-color: transparent;
|
|
102
|
-
font-weight: inherit;
|
|
103
|
-
color: inherit;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
.color-bg {
|
|
107
|
-
color: var(--color-bg);
|
|
108
|
-
}
|
|
109
|
-
.color-1 {
|
|
110
|
-
color: var(--color-1);
|
|
111
|
-
}
|
|
112
|
-
.color-2 {
|
|
113
|
-
color: var(--color-2);
|
|
114
|
-
}
|
|
115
|
-
.color-3 {
|
|
116
|
-
color: var(--color-3);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
.bg-color-bg {
|
|
120
|
-
background-color: var(--color-bg);
|
|
121
|
-
}
|
|
122
|
-
.bg-color-1 {
|
|
123
|
-
background-color: var(--color-1);
|
|
124
|
-
}
|
|
125
|
-
.bg-color-2 {
|
|
126
|
-
background-color: var(--color-2);
|
|
127
|
-
}
|
|
128
|
-
.bg-color-3 {
|
|
129
|
-
background-color: var(--color-3);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
.size-headline-1 {
|
|
134
|
-
font-size: var(--font-size-level-headline-1);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
.size-headline-2 {
|
|
138
|
-
font-size: var(--font-size-level-headline-2);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
.size-headline-3 {
|
|
142
|
-
font-size: var(--font-size-level-headline-3);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
.size-body {
|
|
146
|
-
font-size: var(--font-size-level-body);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
.size-small-1 {
|
|
150
|
-
font-size: var(--font-size-level-small-1);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
.size-small-2 {
|
|
154
|
-
font-size: var(--font-size-level-small-2);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
.ellipsis {
|
|
158
|
-
white-space: nowrap;
|
|
159
|
-
overflow: hidden;
|
|
160
|
-
text-overflow: ellipsis;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
.idle {
|
|
165
|
-
cursor: none;
|
|
166
|
-
}
|