Skip to content

Commit e1c95d6

Browse files
committed
New Vue based config panel, added latest Butterchurn NPM package, imported latest API changes
1 parent cfe58b9 commit e1c95d6

12 files changed

+216
-166
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ This plugin has been ported from Apple Music Electron to Cider 1.x to Cider 2.x.
2727
The code around this is of *questionable* quality. Mainly ported as proof of concept but will be improved over time as the Cider Plugin API and this plugin matures. As most of the code is a straight import from a JS only project a lot of TS rules have been disabled.
2828

2929
## Future Goals
30-
- Change the configuration UI to use a Vue Web Component
30+
✅ Change the configuration UI to use a Vue Web Component
31+
✅ Integrate properly with the Butterchurn NPM package
3132
- Properly register as an Immersive backdrop instead of overlaying on top of the existing one
32-
- Integrate properly with the Butterchurn NPM package
3333

3434

3535
## Credits

bun.lockb

5.06 KB
Binary file not shown.

index.html

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Vite + Vue + TS</title>
8+
</head>
9+
<body>
10+
<div id="app"></div>
11+
<!-- <script type="module" src="/src/main.ts"></script> -->
12+
<script type="module">
13+
import("http://127.0.0.1:3058/src/main.ts");
14+
</script>
15+
</body>
16+
</html>

package.json

+7-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
},
1111
"dependencies": {
1212
"@paralleldrive/cuid2": "^2.2.2",
13+
"@vueuse/core": "^10.11.0",
14+
"butterchurn": "^2.6.7",
15+
"butterchurn-presets": "^2.4.7",
1316
"lodash": "^4.17.21",
1417
"vue": "^3.4.29"
1518
},
@@ -25,5 +28,8 @@
2528
"vite-tsconfig-paths": "^4.3.2",
2629
"vue-tsc": "^2.0.21",
2730
"yaml": "^2.4.5"
28-
}
31+
},
32+
"trustedDependencies": [
33+
"core-js"
34+
]
2935
}

src/api/Events.ts

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { PAPIEvents } from "./ciderapi-types/PAPIEvents";
2+
3+
/**
4+
* Subscribe to a PAPI event
5+
*
6+
* @param event - The event to subscribe to
7+
* @param cb - The callback to run when the event is emitted
8+
* @param opts - Options for the event listener
9+
* @returns A function to unsubscribe from the event
10+
*
11+
*/
12+
export function subscribeEvent<T>(event: PAPIEvents, cb: (e: T) => void, opts?: Partial<{ once: boolean, passive: boolean, capture: boolean }>) {
13+
// unwrap e.detail in the callback
14+
const wrappedCb = (e: CustomEvent<T>) => cb(e.detail);
15+
__PLUGINSYS__.PAPIInstance.addEventListener(event, wrappedCb, opts);
16+
17+
return () => {
18+
unsubscribeEvent(event, wrappedCb);
19+
}
20+
}
21+
22+
/**
23+
* Wrapper for subscribing to an event once
24+
*/
25+
export function subscribeEventOnce<T>(event: PAPIEvents, cb: (e: T) => void) {
26+
return subscribeEvent(event, cb, { once: true });
27+
}
28+
29+
export function unsubscribeEvent<T>(event: PAPIEvents, cb: (e: T) => void) {
30+
__PLUGINSYS__.PAPIInstance.removeEventListener(event, cb);
31+
}

src/api/ciderapi-types/CiderPluginSystem.d.ts

+5
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,9 @@ declare namespace __PLUGINSYS__ {
2525
const Quasar: {
2626
Dialog: any;
2727
}
28+
29+
const PAPIInstance: {
30+
addEventListener(event: import('./PAPIEvents').PAPIEvents, cb: (e: any) => void, opts?: Partial<{ once: boolean, passive: boolean, capture: boolean }>): void
31+
removeEventListener(event: import('./PAPIEvents').PAPIEvents, cb: (e: any) => void): void
32+
}
2833
}

src/api/ciderapi-types/PAPIEvents.ts

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export type PAPIEvents =
2+
'app:ready' |
3+
'shell:layout_type_changed' |
4+
'immersive:opened' |
5+
'immersive:closed' |
6+
'miniplayer:opened' |
7+
'miniplayer:closed' |
8+
'browser:page_changed'

src/api/ciderapi-types/PAPITypes.d.ts

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
declare namespace PAPITypes {
2+
declare namespace App {
3+
type Ready = {}
4+
}
5+
declare namespace Shell {
6+
type LayoutTypeChanged = {
7+
type: 'immersive' | 'miniplayer' | 'browser'
8+
}
9+
type ImmersiveOpened = {}
10+
type ImmersiveClosed = {}
11+
type MiniplayerOpened = {}
12+
type MiniplayerClosed = {}
13+
}
14+
}

src/components/VizSettings.vue

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
<script setup lang="ts">
2+
import { _amOT } from "../imported/port";
3+
import { useLocalStorage } from "@vueuse/core";
4+
5+
const selected = useLocalStorage<string>(
6+
"bc-selected",
7+
"Flexi, martin + geiss - dedicated to the sherwin maxawow"
8+
);
9+
const presets = computed(() => {
10+
console.log(_amOT.viz.presets);
11+
return _amOT.viz.presets;
12+
});
13+
14+
const renderScale = useLocalStorage<number>("bc-scale", 1);
15+
const favorites = useLocalStorage<string[]>("viz-favorites", []);
16+
const showRemove = computed(() => favorites.value.includes(selected.value));
17+
18+
watch(selected, (newVal) => {
19+
// @ts-ignore
20+
_amOT.viz.visualizer.loadPreset(_amOT.viz.presets[newVal]);
21+
});
22+
23+
watch(renderScale, () => {
24+
_amOT.RedrawViz();
25+
});
26+
27+
function fullscreen() {
28+
document.documentElement.requestFullscreen();
29+
}
30+
31+
function addToFavorites() {
32+
if (!favorites.value.includes(selected.value)) {
33+
favorites.value.push(selected.value);
34+
}
35+
}
36+
37+
function removeFromFavorites() {
38+
const index = favorites.value.indexOf(selected.value);
39+
if (index > -1) {
40+
favorites.value.splice(index, 1);
41+
}
42+
}
43+
</script>
44+
45+
<template>
46+
<div class="plugin-base q-mt-sm">
47+
<div class="row flex-gap-2">
48+
<div class="col">
49+
<div class="shelf-title">Available</div>
50+
<select v-model="selected" class="options-list" size="3">
51+
<option v-for="(_, index) in presets" :key="index">
52+
{{ index }}
53+
</option>
54+
</select>
55+
<button class="full-width q-my-sm" @click="addToFavorites">
56+
⭐ Add To Favorites
57+
</button>
58+
</div>
59+
<div class="col">
60+
<div class="shelf-title">Favorites</div>
61+
<select v-model="selected" class="options-list" size="3">
62+
<option v-for="(fav, index) in favorites" :key="index">
63+
{{ fav }}
64+
</option>
65+
</select>
66+
<button
67+
@click="removeFromFavorites"
68+
v-if="showRemove"
69+
class="full-width q-my-sm"
70+
>
71+
❌ Remove From Favorites
72+
</button>
73+
</div>
74+
</div>
75+
76+
<div>
77+
<div class="shelf-title">Render Scale</div>
78+
<input
79+
type="number"
80+
class="full-width"
81+
min="0.1"
82+
max="2"
83+
step="0.1"
84+
v-model="renderScale"
85+
/>
86+
</div>
87+
88+
<div class="row flex-gap-2 q-mt-sm">
89+
<button class="full-width c-btn" @click="fullscreen">Fullscreen</button>
90+
<button class="full-width c-btn" @click="_amOT.VizConfig">
91+
Close Visualizer
92+
</button>
93+
</div>
94+
</div>
95+
</template>
96+
97+
<style lang="scss" scoped>
98+
.options-list {
99+
min-width: 0;
100+
width: 100%;
101+
height: 300px;
102+
display: inline-flex;
103+
overflow: hidden;
104+
overflow-y: scroll;
105+
font-size: inherit;
106+
option {
107+
padding: 3px;
108+
font-size: inherit;
109+
}
110+
}
111+
</style>

src/imported/plugin-visualizer-butterchurn.ts

-11
This file was deleted.

0 commit comments

Comments
 (0)