mirror of
https://codeberg.org/vlw/still-alive.git
synced 2025-09-13 16:03:41 +02:00
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.
This commit is contained in:
parent
cad5e2fb27
commit
3ef9e82d79
5 changed files with 90 additions and 72 deletions
93
assets/js/modules/WindowManager.mjs → assets/js/modules/PlayerManager.mjs
Executable file → Normal file
93
assets/js/modules/WindowManager.mjs → assets/js/modules/PlayerManager.mjs
Executable file → Normal file
|
@ -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());
|
||||
});
|
||||
}
|
||||
}
|
61
assets/js/modules/PlayerWindow.mjs
Normal file
61
assets/js/modules/PlayerWindow.mjs
Normal file
|
@ -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"]]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
3
monkeydo.json
Normal file
3
monkeydo.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"tasks": []
|
||||
}
|
Loading…
Add table
Reference in a new issue