mirror of
https://codeberg.org/vlw/still-alive.git
synced 2025-09-13 16:03:41 +02:00
116 lines
No EOL
3.1 KiB
JavaScript
116 lines
No EOL
3.1 KiB
JavaScript
import { default as PlayerWindow } from "./PlayerWindow.mjs";
|
|
import { default as Monkeydo } from "./monkeydo/Monkeydo.mjs";
|
|
|
|
export default class WindowManager {
|
|
constructor(mediaElement) {
|
|
const self = this;
|
|
this.mediaElement = mediaElement;
|
|
|
|
// Bi-directional communcation to player windows
|
|
this.channels = {
|
|
"#lyrics": new BroadcastChannel("#lyrics"),
|
|
"#credits": new BroadcastChannel("#credits"),
|
|
"#art": new BroadcastChannel("#art")
|
|
};
|
|
|
|
for(const channel of Object.values(this.channels)) {
|
|
channel.addEventListener("message",event => this.message(event));
|
|
}
|
|
|
|
// Monkeydo methods
|
|
const methods = {
|
|
blank: (target) => {
|
|
self.channels[target].postMessage(["BLANK",target]);
|
|
},
|
|
lineFeed: (target) => {
|
|
self.channels[target].postMessage(["LINE_FEED"]);
|
|
},
|
|
textFeed: (text,target = "#lyrics") => {
|
|
self.channels[target].postMessage(["TEXT_FEED",text]);
|
|
},
|
|
drawArt: (index,target = "#art") => {
|
|
self.channels[target].postMessage(["DRAW_ART",index]);
|
|
},
|
|
playCredits: () => {
|
|
self.players.credits.play();
|
|
}
|
|
}
|
|
|
|
this.players = {
|
|
lyrics: new Monkeydo(methods),
|
|
credits: new Monkeydo(methods)
|
|
}
|
|
}
|
|
|
|
playbackFailed(promiseObject = false) {
|
|
console.log(promiseObject);
|
|
}
|
|
|
|
// Attempt to open a new window
|
|
async spawnPlayer(type) {
|
|
if(!type in this.channels) {
|
|
throw new Error(`Inavlid player type "${type}"`);
|
|
}
|
|
|
|
return await new Promise((resolve,reject) => {
|
|
const player = new PlayerWindow(type).open();
|
|
const channel = this.channels[type];
|
|
|
|
// Wait for window to emit ready state message before resolving
|
|
const ack = channel.addEventListener("message",event => {
|
|
if(event.data[0] === "WINDOW_READY" || event.data[1] === type) {
|
|
resolve("WINDOW_READY");
|
|
}
|
|
// Window failed to initialize
|
|
if(event.data[0] === "WINDOW_ERROR" || event.data[1][0] === type) {
|
|
reject(event.data[1]);
|
|
}
|
|
return false;
|
|
});
|
|
channel.removeEventListener("message",ack);
|
|
});
|
|
}
|
|
|
|
async play() {
|
|
for(const [key,player] of Object.entries(this.players)) {
|
|
const manifest = new URL(window.location.href + `monkeydo_${key}.json`);
|
|
|
|
await player.load(manifest.toString());
|
|
}
|
|
this.players.lyrics.play();
|
|
this.mediaElement.play();
|
|
}
|
|
|
|
// Open player windows and start playback
|
|
async init() {
|
|
const art = this.spawnPlayer("#art");
|
|
const credits = this.spawnPlayer("#credits");
|
|
const lyrics = this.spawnPlayer("#lyrics");
|
|
|
|
const timeout = new Promise(resolve => setTimeout(() => resolve("TIMEOUT")),3000);
|
|
const windows = await Promise.allSettled([lyrics,credits,art]);
|
|
|
|
// Wait for all windows to open and initialize (or timout and fail)
|
|
const status = Promise.race([windows,timeout]);
|
|
status.then(promises => {
|
|
promises.forEach(promiseObject => {
|
|
if(promiseObject.status !== "fulfilled") {
|
|
this.playbackFailed(promiseObject);
|
|
}
|
|
});
|
|
|
|
// Load Monkeydo manifest and start playback
|
|
this.play();
|
|
});
|
|
}
|
|
|
|
message(event) {
|
|
const type = event.data[0];
|
|
const data = event.data[1];
|
|
|
|
switch(type) {
|
|
case "PLAY": console.log("PLAY",event); break;
|
|
case "WINDOW_CLOSED": console.log("WINDOW_CLOSED",event); break;
|
|
}
|
|
}
|
|
} |