Improved support for Linux

This commit is contained in:
Markil3
2021-09-04 15:11:36 -06:00
parent 5e4ae23978
commit c24d6c2367
11 changed files with 297 additions and 174 deletions

View File

@@ -0,0 +1,209 @@
console.log("Hello from Universal Music addon!")
const tabMessages = new Map();
var numTabMessages = 0;
/*
On startup, connect to the "ping_pong" app.
*/
var interfacePort = browser.runtime.connectNative("universalmusic");
var tabPort = null;
function setupTab(port)
{
if (port.sender)
{
console.info("Tab " + port.sender.tab.url + " loaded.");
}
else
{
console.info("Tab loaded");
}
tabPort = port;
tabPort.onDisconnect.addListener(e => {
tabPort = null;
if (e.error)
{
console.error("Tab error: ", e.error)
}
else
{
console.info("Tab " + e.sender.tab.url + " disconnected.");
}
browser.tabs.remove(e.sender.tab.id);
});
tabPort.onMessage.addListener(message => {
if (typeof message == "object")
{
if (message.type == "response")
{
tabMessages.set(message.num, message.data);
}
else if (message.type == "update")
{
returnValue = {
"messageNum": -1,
"message": message.data
}
console.trace("Sending update ", returnValue)
interfacePort.postMessage(returnValue);
}
}
});
return true;
}
function queryTab(message)
{
let num = numTabMessages++;
let promise = new Promise((resolve, reject) => {
tabPort.postMessage({
num: num,
data: message
});
(function awaitResponse() {
if (tabMessages.has(num))
{
response = tabMessages.get(num);
tabMessages.delete(num);
return resolve(response);
}
else
{
setTimeout(awaitResponse, 30);
}
})();
});
tabMessages.set(numTabMessages, promise);
numTabMessages++;
return promise;
}
var listeners = [function (message, returnValue) {
if (typeof message == "object" && "type" in message)
{
let type = message.type;
lastPeriod = type.lastIndexOf(".");
if (lastPeriod != -1)
{
type = type.substring(lastPeriod + 1);
}
switch (type)
{
case "CommandLoadSong":
returnValue = () => {
if (message.song)
{
browser.tabs.create({url: message.song});
}
}
if (tabPort)
{
console.log("Replacing tab");
/*
* Closes the existing tab first
*/
returnValue = browser.tabs.remove(tabPort.sender.tab.id).then(returnValue);
}
else
{
console.log("Opening tab");
returnValue = returnValue();
}
break;
case "QueryStatus":
if (!tabPort)
{
returnValue = "EMPTY";
break;
}
case "QueryTime":
case "QueryLength":
case "CommandSetPlayback":
case "CommandSeek":
returnValue = queryTab(message);
break;
case "CommandQuit":
returnValue = quit();
break;
}
}
else if (message == "quit")
{
returnValue = quit();
}
if (returnValue == null)
{
returnValue = "pong";
}
return returnValue;
}];
function quit()
{
console.log("Quitting browser");
return browser.tabs.query({}).then(tabs => {
for (let tab of tabs)
{
browser.tabs.remove(tab.id);
}
});
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function handleMessage(message)
{
return new Promise((resolve, reject) => {
var returnValue = null;
try
{
for (index in listeners)
{
returnValue = listeners[index](message, returnValue);
}
console.debug("Message returned ", returnValue);
if (returnValue instanceof Promise)
{
returnValue.then(resolve).catch(reject);
}
else
{
resolve(returnValue);
}
}
catch (e)
{
reject(e);
}
})
}
/*
* Listen for messages from the app.
*/
interfacePort.onMessage.addListener((message) => {
console.log("Received from interface: ", message);
handleMessage(message.message).then((response) => {
returnValue = {
"messageNum": message.messageNum,
"message": {
"type": "edu.regis.universeplayer.browserCommands.CommandReturn",
"returnValue": response,
"confirmation": {
type: "edu.regis.universeplayer.browserCommands.CommandConfirmation",
message: "Done",
errorCode: null
}
}
}
console.log("Sending ", returnValue)
interfacePort.postMessage(returnValue);
}).catch(error => {
console.error("Error in evaluating message: ", error)
});
});
browser.runtime.onConnect.addListener(setupTab);

View File

@@ -0,0 +1,92 @@
console.debug("Loading foreground.js")
let background;
function handleMessage(message)
{
if (typeof message == "object" && "type" in message)
{
let type = message.type;
lastPeriod = type.lastIndexOf(".");
if (lastPeriod != -1)
{
type = type.substring(lastPeriod + 1);
}
switch (type)
{
case "QueryStatus":
return getState();
case "QueryTime":
return getTime();
case "QueryLength":
return getLength();
case "CommandSetPlayback":
switch (message.status)
{
case "PLAY":
return play();
case "PAUSE":
return pause();
}
return false;
case "CommandSeek":
return seek(message.time);
}
}
}
function onStatusUpdate(status, time, songData)
{
sendUpdate({
type: "edu.regis.universeplayer.PlaybackInfo",
currentSong: songData,
status: status,
playTime: time
});
}
function sendUpdate(response)
{
post = data => background.postMessage({
type: "update",
data: data
});
if (response instanceof Promise)
{
response.then(post);
}
else
{
post(response);
}
}
background = browser.runtime.connect({name:"universalMusic"});
background.onMessage.addListener(message => {
let num = message.num;
response = handleMessage(message.data);
post = data => background.postMessage({
type: "response",
num: num,
data: data
});
if (response instanceof Promise)
{
response.then(post);
}
else
{
post(response);
}
});
if (document.readyState === "complete")
{
sendUpdate("loaded");
}
else
{
sendUpdate("loaded");
window.addEventListener("load", () => {
sendUpdate("loaded");
});
}

View File

@@ -0,0 +1,111 @@
console.debug("Loading youtube.js")
var video;
function onload()
{
video = document.getElementsByClassName('video-stream html5-main-video')[0];
statusUpdate = e => {
return onStatusUpdate(getState(), e.srcElement.currentTime, getSongData());
};
// video.addListener("timeupdate", statusUpdate);
// video.addListener("play", statusUpdate);
// video.addListener("pause", statusUpdate);
// video.addListener("ended", statusUpdate);
video.ontimeupdate = statusUpdate;
video.onplay = statusUpdate;
video.onpause = statusUpdate;
video.onended = statusUpdate;
}
function getSongData()
{
return {
type: "edu.regis.universeplayer.browser.InternetSong",
location: "window.location.href",
title: getTitle(),
artists: getArtists(),
trackNum: 0,
discNum: 0,
duration: parseInt(getLength() * 1000),
album: null
}
}
function getState()
{
if (!video)
{
return "EMPTY";
}
else if (video.ended)
{
return "FINISHED";
}
else if (video.paused)
{
return "PAUSED";
}
else
{
return "PLAYING";
}
}
function getTime()
{
return video.currentTime;
}
function getLength()
{
return video.duration;
}
function getTitle()
{
return document.getElementsByTagName("meta").title.content;
}
function getArtists()
{
return [document.getElementById("channel-name").getElementsByTagName("a")[0].text];
}
function play()
{
if (video != null)
{
video.play();
return true;
}
return false;
}
function pause()
{
if (video != null)
{
video.pause();
return true;
}
return false;
}
function seek(time)
{
if (video != null)
{
video.currentTime = time;
return true;
}
return false;
}
if (document.readyState === "complete")
{
onload();
}
else
{
window.addEventListener("load", onload);
}