···
53
53
context.scope.ondata = (event: any) => setDefaultVolume(event.data.volume.default);
54
54
55
55
effect(() => {
56
56
-
const volume = defaultVolume();
57
57
-
if (volume === undefined) return;
58
58
-
localStorage.setItem(VOLUME_KEY, volume.toString());
56
56
+
if (context.isMainInstance()) {
57
57
+
const volume = defaultVolume();
58
58
+
if (volume === undefined) return;
59
59
+
localStorage.setItem(VOLUME_KEY, volume.toString());
60
60
+
}
59
61
});
60
62
61
63
////////////////////////////////////////////
···
1
1
<script>
2
2
+
import type { Actions } from "@scripts/engine/queue/worker";
2
3
import type { Track } from "@applets/core/types";
3
4
import type { State } from "./types.d.ts";
4
5
5
6
import { register } from "@scripts/applet/common";
7
7
+
import { endpoint } from "@scripts/common";
6
8
7
9
////////////////////////////////////////////
8
10
// SETUP
9
11
////////////////////////////////////////////
12
12
+
const worker = endpoint<Actions>(
13
13
+
new Worker("../../../scripts/engine/queue/worker", { type: "module" }),
14
14
+
);
15
15
+
16
16
+
// Register applet
10
17
const context = register<State>();
11
18
12
19
// Initial state
···
15
22
now: null,
16
23
future: [],
17
24
};
18
18
-
19
19
-
// State helpers
20
20
-
function update(partial: Partial<State>): void {
21
21
-
context.data = { ...context.data, ...partial };
22
22
-
}
23
25
24
26
////////////////////////////////////////////
25
27
// ACTIONS
···
29
31
context.setActionHandler("shift", shift);
30
32
context.setActionHandler("unshift", unshift);
31
33
32
32
-
function add(items: Track[]) {
33
33
-
update({ future: [...context.data.future, ...items] });
34
34
+
async function add(items: Track[]) {
35
35
+
context.data = await worker.call.add(context.data, items);
34
36
}
35
37
36
36
-
// TODO: Shuffle, limit track amount, etc.
37
37
-
function fill(availableItems: Track[]) {
38
38
-
add(availableItems);
39
39
-
40
40
-
// Automatically insert track if there isn't any
41
41
-
if (!context.data.now) shift();
38
38
+
async function fill(availableItems: Track[]) {
39
39
+
context.data = await worker.call.fill(context.data, availableItems);
42
40
}
43
41
44
44
-
function shift() {
45
45
-
const now = context.data.future[0] || null;
46
46
-
const future = context.data.future.slice(1);
47
47
-
const past = context.data.now ? [...context.data.past, context.data.now] : context.data.past;
48
48
-
49
49
-
update({ past, now, future });
50
50
-
51
51
-
return now;
42
42
+
async function shift() {
43
43
+
context.data = await worker.call.shift(context.data);
52
44
}
53
45
54
54
-
function unshift() {
55
55
-
if (context.data.past.length === 0) return;
56
56
-
57
57
-
const past = [...context.data.past];
58
58
-
const [last] = past.splice(past.length - 1, 1);
59
59
-
const now = last ?? null;
60
60
-
const future = context.data.now
61
61
-
? [context.data.now, ...context.data.future]
62
62
-
: context.data.future;
63
63
-
64
64
-
update({ past, now, future });
46
46
+
async function unshift() {
47
47
+
context.data = await worker.call.unshift(context.data);
65
48
}
66
49
</script>
···
1
1
-
import type { Track } from "@applets/core/types";
2
2
-
3
3
-
export interface State<Stats = TrackStats, Tags = TrackTags> {
4
4
-
past: Track<Stats, Tags>[];
5
5
-
now: Track<Stats, Tags> | null;
6
6
-
future: Track<Stats, Tags>[];
7
7
-
}
1
1
+
export * from "@scripts/engine/queue/types.d.ts";
···
27
27
// SETUP
28
28
////////////////////////////////////////////
29
29
const worker = endpoint<Actions>(
30
30
-
new Worker("../../../scripts/input/opensubsonic/worker", {
31
31
-
type: "module",
32
32
-
}),
33
33
-
self as any,
30
30
+
new Worker("../../../scripts/input/opensubsonic/worker", { type: "module" }),
34
31
);
35
32
36
33
// Register applet
···
1
1
+
import type { Track } from "@applets/core/types";
2
2
+
3
3
+
export interface State<Stats = TrackStats, Tags = TrackTags> {
4
4
+
past: Track<Stats, Tags>[];
5
5
+
now: Track<Stats, Tags> | null;
6
6
+
future: Track<Stats, Tags>[];
7
7
+
}
···
1
1
+
import type { Track } from "@applets/core/types.js";
2
2
+
import { expose } from "../../../scripts/common.ts";
3
3
+
import type { State } from "./types";
4
4
+
5
5
+
////////////////////////////////////////////
6
6
+
// ACTIONS
7
7
+
////////////////////////////////////////////
8
8
+
const actions = expose({
9
9
+
add,
10
10
+
fill,
11
11
+
shift,
12
12
+
unshift,
13
13
+
});
14
14
+
15
15
+
export type Actions = typeof actions;
16
16
+
17
17
+
// Actions
18
18
+
19
19
+
function add(state: State, items: Track[]): State {
20
20
+
return { ...state, future: [...state.future, ...items] };
21
21
+
}
22
22
+
23
23
+
// TODO: Shuffle, limit track amount, etc.
24
24
+
function fill(state: State, availableItems: Track[]): State {
25
25
+
state = add(state, availableItems);
26
26
+
27
27
+
// Automatically insert track if there isn't any
28
28
+
if (!state.now) return shift(state);
29
29
+
return state;
30
30
+
}
31
31
+
32
32
+
function shift(state: State): State {
33
33
+
const now = state.future[0] || null;
34
34
+
const future = state.future.slice(1);
35
35
+
const past = state.now ? [...state.past, state.now] : state.past;
36
36
+
37
37
+
return { past, now, future };
38
38
+
}
39
39
+
40
40
+
function unshift(state: State): State {
41
41
+
if (state.past.length === 0) return state;
42
42
+
43
43
+
const past = [...state.past];
44
44
+
const [last] = past.splice(past.length - 1, 1);
45
45
+
const now = last ?? null;
46
46
+
const future = state.now ? [state.now, ...state.future] : state.future;
47
47
+
48
48
+
return { past, now, future };
49
49
+
}