From 3ef9e82d79c1eed86b9ec15cfc68c1dcf88bbf7b Mon Sep 17 00:00:00 2001 From: Victor Westerlund Date: Mon, 18 Oct 2021 13:14:39 +0200 Subject: [PATCH] Added functional code before manifest and CSS The JS-part of this demo is now functional to the point where a Monkeydo manifest can be played on the different windows. CSS styling and an actual manifest will still have to be created. --- .../{WindowManager.mjs => PlayerManager.mjs} | 93 +++++-------------- assets/js/modules/PlayerWindow.mjs | 61 ++++++++++++ assets/js/player.mjs | 3 +- assets/js/script.mjs | 2 +- monkeydo.json | 3 + 5 files changed, 90 insertions(+), 72 deletions(-) rename assets/js/modules/{WindowManager.mjs => PlayerManager.mjs} (50%) mode change 100755 => 100644 create mode 100644 assets/js/modules/PlayerWindow.mjs create mode 100644 monkeydo.json diff --git a/assets/js/modules/WindowManager.mjs b/assets/js/modules/PlayerManager.mjs old mode 100755 new mode 100644 similarity index 50% rename from assets/js/modules/WindowManager.mjs rename to assets/js/modules/PlayerManager.mjs index b835224..2564146 --- a/assets/js/modules/WindowManager.mjs +++ b/assets/js/modules/PlayerManager.mjs @@ -1,87 +1,36 @@ +import { default as PlayerWindow } from "./PlayerWindow.mjs"; import { default as Monkeydo } from "./monkeydo/Monkeydo.mjs"; -const windowPositions = { - "#lyrics": { - width: window.innerWidth / 2, - height: window.innerHeight, - top: 0, - left: 0 - }, - "#credits": { - width: window.innerWidth / 2, - height: window.innerHeight / 2, - top: 0, - left: window.innerWidth / 2 - }, - "#art": { - width: window.innerWidth / 2, - height: window.innerHeight / 2, - top: window.innerHeight / 2, - left: window.innerWidth / 2 - } -} - -class PlayerWindow { - constructor(name) { - this.features = { - menubar: false, - location: false, - resizable: false, - scrollbar: false, - status: false - } - - this.url = new URL(window.location.href + "player"); - this.url.hash = name; - - Object.assign(this.features,windowPositions[this.url.hash]); - } - - windowFeatures() { - let output = []; - for(let [key,value] of Object.entries(this.features)) { - if(typeof key === "boolean") { - value = value ? "yes" : "no"; - } - output.push(`${key}=${value}`); - } - return output.join(","); - } - - open() { - const features = this.windowFeatures(); - const open = window.open(this.url.toString(),this.url.hash,features); - - if(!open) { - const channel = new BroadcastChannel(this.url.hash); - channel.postMessage(["WINDOW_ERROR",[this.url.hash,"BLOCKED"]]); - } - } -} - export default class WindowManager { constructor() { const self = this; // Bi-directional communcation to player windows this.channels = { - lyrics: new BroadcastChannel("#lyrics"), - credits: new BroadcastChannel("#credits"), - art: new BroadcastChannel("#art") + "#lyrics": new BroadcastChannel("#lyrics"), + "#credits": new BroadcastChannel("#credits"), + "#art": new BroadcastChannel("#art") }; // Monkeydo methods const methods = { self: self, - pushText: (target,text) => { - const channels = self.channels[target]; - for(const channel of channels) { - channel.postMessage(["PUSH_TEXT",text]); - } + 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]); } } this.player = new Monkeydo(methods); + this.player.loop(-1); } playbackFailed(promiseObject = false) { @@ -115,9 +64,9 @@ export default class WindowManager { // Open player windows and start playback async play() { - const art = this.spawnPlayer("art"); - const credits = this.spawnPlayer("credits"); - const lyrics = this.spawnPlayer("lyrics"); + 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]); @@ -130,6 +79,10 @@ export default class WindowManager { this.playbackFailed(promiseObject); } }); + + // Load Monkeydo manifest and start playback + const manifest = new URL(window.location.href + "monkeydo.json"); + this.player.load(manifest.toString()).then(() => this.player.do()); }); } } \ No newline at end of file diff --git a/assets/js/modules/PlayerWindow.mjs b/assets/js/modules/PlayerWindow.mjs new file mode 100644 index 0000000..7216c7b --- /dev/null +++ b/assets/js/modules/PlayerWindow.mjs @@ -0,0 +1,61 @@ +const windowPositions = { + "#lyrics": { + width: window.innerWidth / 2, + height: window.innerHeight, + top: 0, + left: 0 + }, + "#credits": { + width: window.innerWidth / 2, + height: window.innerHeight / 2, + top: 0, + left: window.innerWidth / 2 + }, + "#art": { + width: window.innerWidth / 2, + height: window.innerHeight / 2, + top: window.innerHeight / 2, + left: window.innerWidth / 2 + } +} + +export default class PlayerWindow { + constructor(name) { + this.features = { + menubar: false, + location: false, + resizable: false, + scrollbar: false, + status: false + } + + this.url = new URL(window.location.href + "player"); + this.url.hash = name; + + // Copy window size rect into windowFeatures + Object.assign(this.features,windowPositions[this.url.hash]); + } + + // Convert windowFeatures object into a CSV DOMString + windowFeatures() { + let output = []; + for(let [key,value] of Object.entries(this.features)) { + if(typeof key === "boolean") { + value = value ? "yes" : "no"; + } + output.push(`${key}=${value}`); + } + return output.join(","); + } + + open() { + const features = this.windowFeatures(); + const open = window.open(this.url.toString(),this.url.hash,features); + + // Window failed to open (usually due to pop-up blocking), tell the WindowManager about this + if(!open) { + const channel = new BroadcastChannel(this.url.hash); + channel.postMessage(["WINDOW_ERROR",[this.url.hash,"BLOCKED"]]); + } + } +} diff --git a/assets/js/player.mjs b/assets/js/player.mjs index 030997d..f598ac7 100644 --- a/assets/js/player.mjs +++ b/assets/js/player.mjs @@ -51,10 +51,11 @@ class StillAlivePlayer { message(event) { const type = event.data[0]; const data = event.data[1]; + console.log(event); switch(type) { case "LINE_FEED": this.lineFeed(); break; - case "CHAR_FEED": this.textFeed(data); break; + case "TEXT_FEED": this.textFeed(data); break; case "DRAW_ART": this.drawArt(data); break; case "BLANK": this.blank(); break; } diff --git a/assets/js/script.mjs b/assets/js/script.mjs index 7ab4a51..554fb52 100755 --- a/assets/js/script.mjs +++ b/assets/js/script.mjs @@ -1,4 +1,4 @@ -import { default as Player } from "./modules/WindowManager.mjs"; +import { default as Player } from "./modules/PlayerManager.mjs"; const play = document.getElementById("play"); const message = document.getElementById("message"); diff --git a/monkeydo.json b/monkeydo.json new file mode 100644 index 0000000..9b9edb7 --- /dev/null +++ b/monkeydo.json @@ -0,0 +1,3 @@ +{ + "tasks": [] +} \ No newline at end of file