diff --git a/extension/background.js b/extension/background.js
index 745d6ef..43a6cd6 100644
--- a/extension/background.js
+++ b/extension/background.js
@@ -84,44 +84,50 @@ async function getCookieState() {
return response;
}
-// send ping to server, return response
+// send ping to server
async function verifyConnection() {
const path = 'api/ping/';
- let response = await sendGet(path);
- console.log('verify connection: ' + JSON.stringify(response));
+ let message = await sendGet(path);
+ console.log('verify connection: ' + JSON.stringify(message));
- return response;
+ if (message?.response === 'pong') {
+ return true;
+ } else if (message?.detail) {
+ throw new Error(message.detail);
+ } else {
+ throw new Error(`got unknown message ${JSON.stringify(message)}`);
+ }
}
// send youtube link from injected buttons
-async function youtubeLink(youtubeMessage) {
- let path;
- let payload;
-
- if (youtubeMessage.action === 'download') {
- path = 'api/download/';
- payload = {
+async function download(url) {
+ return await sendData(
+ 'api/download/',
+ {
data: [
{
- youtube_id: youtubeMessage.url,
+ youtube_id: url,
status: 'pending',
},
],
- };
- } else if (youtubeMessage.action === 'subscribe') {
- path = 'api/channel/';
- payload = {
+ },
+ 'POST'
+ );
+}
+
+async function subscribe(url) {
+ return await sendData(
+ 'api/channel/',
+ {
data: [
{
- channel_id: youtubeMessage.url,
+ channel_id: url,
channel_subscribed: true,
},
],
- };
- }
-
- let response = await sendData(path, payload, 'POST');
- return response;
+ },
+ 'POST'
+ );
}
async function cookieStr(cookieLines) {
@@ -172,33 +178,56 @@ async function sendCookies() {
return response;
}
-// process and return message if needed
+/*
+process and return message if needed
+the following messages are supported:
+type Message =
+ | { type: 'verify' }
+ | { type: 'cookieState' }
+ | { type: 'sendCookie' }
+ | { type: 'download', url: string }
+ | { type: 'subscribe', url: string }
+*/
function handleMessage(request, sender, sendResponse) {
- console.log('message background.js listener: ' + JSON.stringify(request));
+ console.log('message background.js listener got message', request);
- if (request.verify === true) {
- let response = verifyConnection();
- response.then(message => {
- sendResponse(message);
+ // this function must return the value `true` in chrome to signal the response will be async;
+ // it cannot return a promise
+ // so in order to use async/await, we need a wrapper
+ (async () => {
+ switch (request.type) {
+ case 'verify': {
+ return await verifyConnection();
+ }
+ case 'cookieState': {
+ return await getCookieState();
+ }
+ case 'sendCookie': {
+ return await sendCookies();
+ }
+ case 'download': {
+ return await download(request.url);
+ }
+ case 'subscribe': {
+ return await subscribe(request.url);
+ }
+ default: {
+ let err = new Error(`unknown message type ${JSON.stringify(request.type)}`);
+ console.log(err);
+ throw err;
+ }
+ }
+ })()
+ .then(value => sendResponse({ success: true, value }))
+ .catch(e => {
+ console.error(e);
+ let message = e?.message ?? e;
+ if (message === 'Failed to fetch') {
+ // chrome's error message for failed `fetch` is not very user-friendly
+ message = 'Could not connect to server';
+ }
+ sendResponse({ success: false, value: message });
});
- } else if (request.youtube) {
- let response = youtubeLink(request.youtube);
- response.then(message => {
- sendResponse(message);
- });
- } else if (request.cookieState) {
- let response = getCookieState();
- response.then(message => {
- sendResponse(message);
- });
- } else if (request.sendCookie) {
- console.log('backgound: ' + JSON.stringify(request));
- let response = sendCookies();
- response.then(message => {
- sendResponse(message);
- });
- }
-
return true;
}
diff --git a/extension/index.html b/extension/index.html
index f3f52dd..5dea72a 100644
--- a/extension/index.html
+++ b/extension/index.html
@@ -26,6 +26,7 @@
☐
+
Options:
diff --git a/extension/popup.js b/extension/popup.js
index 9e591d5..a3c60ec 100644
--- a/extension/popup.js
+++ b/extension/popup.js
@@ -15,29 +15,52 @@ function getBrowser() {
return chrome;
}
} else {
- console.log('failed to dedect browser');
+ console.log('failed to detect browser');
throw 'browser detection error';
}
}
+async function sendMessage(message) {
+ let { success, value } = await browserType.runtime.sendMessage(message);
+ if (!success) {
+ throw value;
+ }
+ return value;
+}
+
+let errorOut = document.getElementById('error-out');
+function setError(message) {
+ errorOut.style.display = 'initial';
+ errorOut.innerText = message;
+}
+
+function clearError() {
+ errorOut.style.display = 'none';
+}
+
// store access details
document.getElementById('save-login').addEventListener('click', function () {
let url = document.getElementById('full-url').value;
if (!url.includes('://')) {
url = 'http://' + url;
}
- let parsed = new URL(url);
- let toStore = {
- access: {
- url: `${parsed.protocol}//${parsed.hostname}`,
- port: parsed.port || (parsed.protocol === 'https:' ? '443' : '80'),
- apiKey: document.getElementById('api-key').value,
- },
- };
- browserType.storage.local.set(toStore, function () {
- console.log('Stored connection details: ' + JSON.stringify(toStore));
- pingBackend();
- });
+ try {
+ clearError();
+ let parsed = new URL(url);
+ let toStore = {
+ access: {
+ url: `${parsed.protocol}//${parsed.hostname}`,
+ port: parsed.port || (parsed.protocol === 'https:' ? '443' : '80'),
+ apiKey: document.getElementById('api-key').value,
+ },
+ };
+ browserType.storage.local.set(toStore, function () {
+ console.log('Stored connection details: ' + JSON.stringify(toStore));
+ pingBackend();
+ });
+ } catch (e) {
+ setError(e.message);
+ }
});
// verify connection status
@@ -52,6 +75,7 @@ document.getElementById('sendCookies').addEventListener('click', function () {
function sendCookie() {
console.log('popup send cookie');
+ clearError();
function handleResponse(message) {
console.log('handle cookie response: ' + JSON.stringify(message));
@@ -61,6 +85,7 @@ function sendCookie() {
function handleError(error) {
console.log(`Error: ${error}`);
+ setError(error);
}
let checked = document.getElementById('sendCookies').checked;
@@ -75,26 +100,26 @@ function sendCookie() {
if (checked === false) {
return;
}
- let sending = browserType.runtime.sendMessage({ sendCookie: true });
+ let sending = sendMessage({ type: 'sendCookie' });
sending.then(handleResponse, handleError);
}
// send ping message to TA backend
function pingBackend() {
- function handleResponse(message) {
- if (message.response === 'pong') {
- setStatusIcon(true);
- console.log('connection validated');
- }
+ clearError();
+ function handleResponse() {
+ console.log('connection validated');
+ setStatusIcon(true);
}
function handleError(error) {
- console.log(`Error: ${error}`);
+ console.log(`Verify got error: ${error}`);
setStatusIcon(false);
+ setError(error);
}
console.log('ping TA server');
- let sending = browserType.runtime.sendMessage({ verify: true });
+ let sending = sendMessage({ type: 'verify' });
sending.then(handleResponse, handleError);
}
@@ -105,6 +130,7 @@ function addUrl(access) {
}
function setCookieState() {
+ clearError();
function handleResponse(message) {
console.log(message);
document.getElementById('sendCookies').checked = message.cookie_enabled;
@@ -115,10 +141,11 @@ function setCookieState() {
function handleError(error) {
console.log(`Error: ${error}`);
+ setError(error);
}
console.log('set cookie state');
- let sending = browserType.runtime.sendMessage({ cookieState: true });
+ let sending = sendMessage({ type: 'cookieState' });
sending.then(handleResponse, handleError);
document.getElementById('sendCookies').checked = true;
}
diff --git a/extension/script.js b/extension/script.js
index 7cbaf55..c9a511b 100644
--- a/extension/script.js
+++ b/extension/script.js
@@ -22,6 +22,14 @@ function getBrowser() {
}
}
+async function sendMessage(message) {
+ let { success, value } = await browserType.runtime.sendMessage(message);
+ if (!success) {
+ throw value;
+ }
+ return value;
+}
+
const downloadIcon = `