Formatting

This commit is contained in:
rockerBOO 2025-04-30 20:41:51 -04:00
parent 1f7ce1890a
commit 70b36ed1a1
No known key found for this signature in database
GPG Key ID: 0D4EAF00DCABC97B
19 changed files with 4429 additions and 1583 deletions

View File

@ -1,41 +1,55 @@
'use strict'; "use strict";
// Contains only auxiliary methods // Contains only auxiliary methods
// May be included and executed unlimited number of times without any consequences // May be included and executed unlimited number of times without any consequences
// Polyfills for IE11 // Polyfills for IE11
Array.prototype.find = Array.prototype.find || function (condition) { Array.prototype.find =
Array.prototype.find ||
function (condition) {
return this.filter(condition)[0]; return this.filter(condition)[0];
}; };
Array.from = Array.from || function (source) { Array.from =
Array.from ||
function (source) {
return Array.prototype.slice.call(source); return Array.prototype.slice.call(source);
}; };
NodeList.prototype.forEach = NodeList.prototype.forEach || function (callback) { NodeList.prototype.forEach =
NodeList.prototype.forEach ||
function (callback) {
Array.from(this).forEach(callback); Array.from(this).forEach(callback);
}; };
String.prototype.includes = String.prototype.includes || function (searchString) { String.prototype.includes =
String.prototype.includes ||
function (searchString) {
return this.indexOf(searchString) >= 0; return this.indexOf(searchString) >= 0;
}; };
String.prototype.startsWith = String.prototype.startsWith || function (prefix) { String.prototype.startsWith =
String.prototype.startsWith ||
function (prefix) {
return this.substr(0, prefix.length) === prefix; return this.substr(0, prefix.length) === prefix;
}; };
Math.sign = Math.sign || function(x) { Math.sign =
Math.sign ||
function (x) {
x = +x; x = +x;
if (!x) return x; // 0 and NaN if (!x) return x; // 0 and NaN
return x > 0 ? 1 : -1; return x > 0 ? 1 : -1;
}; };
if (!window.hasOwnProperty('HTMLDetailsElement') && !window.hasOwnProperty('mockHTMLDetailsElement')) { if (
!window.hasOwnProperty("HTMLDetailsElement") &&
!window.hasOwnProperty("mockHTMLDetailsElement")
) {
window.mockHTMLDetailsElement = true; window.mockHTMLDetailsElement = true;
const style = 'details:not([open]) > :not(summary) {display: none}'; const style = "details:not([open]) > :not(summary) {display: none}";
document.head.appendChild(document.createElement('style')).textContent = style; document.head.appendChild(document.createElement("style")).textContent =
style;
addEventListener('click', function (e) { addEventListener("click", function (e) {
if (e.target.nodeName !== 'SUMMARY') return; if (e.target.nodeName !== "SUMMARY") return;
const details = e.target.parentElement; const details = e.target.parentElement;
if (details.hasAttribute('open')) if (details.hasAttribute("open")) details.removeAttribute("open");
details.removeAttribute('open'); else details.setAttribute("open", "");
else
details.setAttribute('open', '');
}); });
} }
@ -51,13 +65,13 @@ window.helpers = window.helpers || {
*/ */
clamp: function (num, min, max) { clamp: function (num, min, max) {
if (max < min) { if (max < min) {
var t = max; max = min; min = t; // swap max and min var t = max;
max = min;
min = t; // swap max and min
} }
if (max < num) if (max < num) return max;
return max; if (min > num) return min;
if (min > num)
return min;
return num; return num;
}, },
@ -67,57 +81,48 @@ window.helpers = window.helpers || {
xhr.open(method, url); xhr.open(method, url);
// Default options // Default options
xhr.responseType = 'json'; xhr.responseType = "json";
xhr.timeout = 10000; xhr.timeout = 10000;
// Default options redefining // Default options redefining
if (options.responseType) if (options.responseType) xhr.responseType = options.responseType;
xhr.responseType = options.responseType; if (options.timeout) xhr.timeout = options.timeout;
if (options.timeout)
xhr.timeout = options.timeout;
if (method === 'POST') if (method === "POST")
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// better than onreadystatechange because of 404 codes https://stackoverflow.com/a/36182963 // better than onreadystatechange because of 404 codes https://stackoverflow.com/a/36182963
xhr.onloadend = function () { xhr.onloadend = function () {
if (xhr.status === 200) { if (xhr.status === 200) {
if (callbacks.on200) { if (callbacks.on200) {
// fix for IE11. It doesn't convert response to JSON // fix for IE11. It doesn't convert response to JSON
if (xhr.responseType === '' && typeof(xhr.response) === 'string') if (xhr.responseType === "" && typeof xhr.response === "string")
callbacks.on200(JSON.parse(xhr.response)); callbacks.on200(JSON.parse(xhr.response));
else else callbacks.on200(xhr.response);
callbacks.on200(xhr.response);
} }
} else { } else {
// handled by onerror // handled by onerror
if (xhr.status === 0) return; if (xhr.status === 0) return;
if (callbacks.onNon200) if (callbacks.onNon200) callbacks.onNon200(xhr);
callbacks.onNon200(xhr);
} }
}; };
xhr.ontimeout = function () { xhr.ontimeout = function () {
if (callbacks.onTimeout) if (callbacks.onTimeout) callbacks.onTimeout(xhr);
callbacks.onTimeout(xhr);
}; };
xhr.onerror = function () { xhr.onerror = function () {
if (callbacks.onError) if (callbacks.onError) callbacks.onError(xhr);
callbacks.onError(xhr);
}; };
if (options.payload) if (options.payload) xhr.send(options.payload);
xhr.send(options.payload); else xhr.send();
else
xhr.send();
}, },
/** @private */ /** @private */
_xhrRetry: function (method, url, options, callbacks) { _xhrRetry: function (method, url, options, callbacks) {
if (options.retries <= 0) { if (options.retries <= 0) {
console.warn('Failed to pull', options.entity_name); console.warn("Failed to pull", options.entity_name);
if (callbacks.onTotalFail) if (callbacks.onTotalFail) callbacks.onTotalFail();
callbacks.onTotalFail();
return; return;
} }
helpers._xhr(method, url, options, callbacks); helpers._xhr(method, url, options, callbacks);
@ -153,13 +158,20 @@ window.helpers = window.helpers || {
return; return;
} }
if (!options.entity_name) options.entity_name = 'unknown'; if (!options.entity_name) options.entity_name = "unknown";
if (!options.retry_timeout) options.retry_timeout = 1000; if (!options.retry_timeout) options.retry_timeout = 1000;
const retries_total = options.retries; const retries_total = options.retries;
let currentTry = 1; let currentTry = 1;
const retry = function () { const retry = function () {
console.warn('Pulling ' + options.entity_name + ' failed... ' + (currentTry++) + '/' + retries_total); console.warn(
"Pulling " +
options.entity_name +
" failed... " +
currentTry++ +
"/" +
retries_total,
);
setTimeout(function () { setTimeout(function () {
options.retries--; options.retries--;
helpers._xhrRetry(method, url, options, callbacks); helpers._xhrRetry(method, url, options, callbacks);
@ -169,14 +181,12 @@ window.helpers = window.helpers || {
// Pack retry() call into error handlers // Pack retry() call into error handlers
callbacks._onError = callbacks.onError; callbacks._onError = callbacks.onError;
callbacks.onError = function (xhr) { callbacks.onError = function (xhr) {
if (callbacks._onError) if (callbacks._onError) callbacks._onError(xhr);
callbacks._onError(xhr);
retry(); retry();
}; };
callbacks._onTimeout = callbacks.onTimeout; callbacks._onTimeout = callbacks.onTimeout;
callbacks.onTimeout = function (xhr) { callbacks.onTimeout = function (xhr) {
if (callbacks._onTimeout) if (callbacks._onTimeout) callbacks._onTimeout(xhr);
callbacks._onTimeout(xhr);
retry(); retry();
}; };
@ -197,12 +207,14 @@ window.helpers = window.helpers || {
storage: (function () { storage: (function () {
// access to localStorage throws exception in Tor Browser, so try is needed // access to localStorage throws exception in Tor Browser, so try is needed
let localStorageIsUsable = false; let localStorageIsUsable = false;
try{localStorageIsUsable = !!localStorage.setItem;}catch(e){} try {
localStorageIsUsable = !!localStorage.setItem;
} catch (e) {}
if (localStorageIsUsable) { if (localStorageIsUsable) {
return { return {
get: function (key) { get: function (key) {
let storageItem = localStorage.getItem(key) let storageItem = localStorage.getItem(key);
if (!storageItem) return; if (!storageItem) return;
try { try {
return JSON.parse(decodeURIComponent(storageItem)); return JSON.parse(decodeURIComponent(storageItem));
@ -212,22 +224,28 @@ window.helpers = window.helpers || {
} }
}, },
set: function (key, value) { set: function (key, value) {
let encoded_value = encodeURIComponent(JSON.stringify(value)) let encoded_value = encodeURIComponent(JSON.stringify(value));
localStorage.setItem(key, encoded_value); localStorage.setItem(key, encoded_value);
}, },
remove: function (key) { localStorage.removeItem(key); } remove: function (key) {
localStorage.removeItem(key);
},
}; };
} }
// TODO: fire 'storage' event for cookies // TODO: fire 'storage' event for cookies
console.info('Storage: localStorage is disabled or unaccessible. Cookies used as fallback'); console.info(
"Storage: localStorage is disabled or unaccessible. Cookies used as fallback",
);
return { return {
get: function (key) { get: function (key) {
const cookiePrefix = key + '='; const cookiePrefix = key + "=";
function findCallback(cookie) {return cookie.startsWith(cookiePrefix);} function findCallback(cookie) {
const matchedCookie = document.cookie.split('; ').find(findCallback); return cookie.startsWith(cookiePrefix);
}
const matchedCookie = document.cookie.split("; ").find(findCallback);
if (matchedCookie) { if (matchedCookie) {
const cookieBody = matchedCookie.replace(cookiePrefix, ''); const cookieBody = matchedCookie.replace(cookiePrefix, "");
if (cookieBody.length === 0) return; if (cookieBody.length === 0) return;
try { try {
return JSON.parse(decodeURIComponent(cookieBody)); return JSON.parse(decodeURIComponent(cookieBody));
@ -244,11 +262,12 @@ window.helpers = window.helpers || {
const date = new Date(); const date = new Date();
date.setFullYear(date.getFullYear() + 2); date.setFullYear(date.getFullYear() + 2);
document.cookie = key + '=' + cookie_data + '; expires=' + date.toGMTString(); document.cookie =
key + "=" + cookie_data + "; expires=" + date.toGMTString();
}, },
remove: function (key) { remove: function (key) {
document.cookie = key + '=; Max-Age=0'; document.cookie = key + "=; Max-Age=0";
} },
}; };
})() })(),
}; };

View File

@ -1,81 +1,91 @@
var video_data = JSON.parse(document.getElementById('video_data').textContent); var video_data = JSON.parse(document.getElementById("video_data").textContent);
var spinnerHTML = '<div class="loading"><i class="icon ion-ios-refresh"></i></div>'; var spinnerHTML =
var spinnerHTMLwithHR = spinnerHTML + '<hr>'; '<div class="loading"><i class="icon ion-ios-refresh"></i></div>';
var spinnerHTMLwithHR = spinnerHTML + "<hr>";
String.prototype.supplant = function (o) { String.prototype.supplant = function (o) {
return this.replace(/{([^{}]*)}/g, function (a, b) { return this.replace(/{([^{}]*)}/g, function (a, b) {
var r = o[b]; var r = o[b];
return typeof r === 'string' || typeof r === 'number' ? r : a; return typeof r === "string" || typeof r === "number" ? r : a;
}); });
}; };
function toggle_comments(event) { function toggle_comments(event) {
const target = event.target; const target = event.target;
const comments = document.querySelector(".comments"); const comments = document.querySelector(".comments");
if (comments.style.display === 'none') { if (comments.style.display === "none") {
target.textContent = ''; target.textContent = "";
comments.style.display = ''; comments.style.display = "";
} else { } else {
target.textContent = '+'; target.textContent = "+";
comments.style.display = 'none'; comments.style.display = "none";
} }
} }
function hide_youtube_replies(event) { function hide_youtube_replies(event) {
var target = event.target; var target = event.target;
var sub_text = target.getAttribute('data-inner-text'); var sub_text = target.getAttribute("data-inner-text");
var inner_text = target.getAttribute('data-sub-text'); var inner_text = target.getAttribute("data-sub-text");
var body = target.parentNode.parentNode.children[1]; var body = target.parentNode.parentNode.children[1];
body.style.display = 'none'; body.style.display = "none";
target.textContent = sub_text; target.textContent = sub_text;
target.onclick = show_youtube_replies; target.onclick = show_youtube_replies;
target.setAttribute('data-inner-text', inner_text); target.setAttribute("data-inner-text", inner_text);
target.setAttribute('data-sub-text', sub_text); target.setAttribute("data-sub-text", sub_text);
} }
function show_youtube_replies(event) { function show_youtube_replies(event) {
var target = event.target; var target = event.target;
console.log(target); console.log(target);
var sub_text = target.getAttribute('data-inner-text'); var sub_text = target.getAttribute("data-inner-text");
var inner_text = target.getAttribute('data-sub-text'); var inner_text = target.getAttribute("data-sub-text");
var body = target.parentNode.parentNode.children[1]; var body = target.parentNode.parentNode.children[1];
body.style.display = ''; body.style.display = "";
target.textContent = sub_text; target.textContent = sub_text;
target.onclick = hide_youtube_replies; target.onclick = hide_youtube_replies;
target.setAttribute('data-inner-text', inner_text); target.setAttribute("data-inner-text", inner_text);
target.setAttribute('data-sub-text', sub_text); target.setAttribute("data-sub-text", sub_text);
} }
function get_youtube_comments() { function get_youtube_comments() {
var comments = document.getElementById('comments'); var comments = document.getElementById("comments");
var fallback = comments.innerHTML; var fallback = comments.innerHTML;
comments.innerHTML = spinnerHTML; comments.innerHTML = spinnerHTML;
var baseUrl = video_data.base_url || '/api/v1/comments/'+ video_data.id var baseUrl = video_data.base_url || "/api/v1/comments/" + video_data.id;
var url = baseUrl + var url =
'?format=html' + baseUrl +
'&hl=' + video_data.preferences.locale + "?format=html" +
'&thin_mode=' + video_data.preferences.thin_mode; "&hl=" +
video_data.preferences.locale +
"&thin_mode=" +
video_data.preferences.thin_mode;
if (video_data.ucid) { if (video_data.ucid) {
url += '&ucid=' + video_data.ucid url += "&ucid=" + video_data.ucid;
} }
var onNon200 = function (xhr) { comments.innerHTML = fallback; }; var onNon200 = function (xhr) {
if (video_data.params.comments[1] === 'youtube') comments.innerHTML = fallback;
onNon200 = function (xhr) {}; };
if (video_data.params.comments[1] === "youtube") onNon200 = function (xhr) {};
helpers.xhr('GET', url, {retries: 5, entity_name: 'comments'}, { helpers.xhr(
"GET",
url,
{ retries: 5, entity_name: "comments" },
{
on200: function (response) { on200: function (response) {
var commentInnerHtml = ' \ var commentInnerHtml =
' \
<nav class="comments-header"> \ <nav class="comments-header"> \
<ul> \ <ul> \
<li> \ <li> \
@ -83,17 +93,19 @@ function get_youtube_comments() {
{commentsText} \ {commentsText} \
</li> \ </li> \
\ \
<li>' <li>';
if (video_data.support_reddit) { if (video_data.support_reddit) {
commentInnerHtml += ' <button data-comments="reddit"> \ commentInnerHtml +=
' <button data-comments="reddit"> \
{redditComments} \ {redditComments} \
</button> \ </button> \
' ';
} }
commentInnerHtml += ' </li> \ commentInnerHtml +=
' </li> \
</ul> \ </ul> \
</nav> \ </nav> \
<div class="comments">{contentHtml}</div>' <div class="comments">{contentHtml}</div>';
commentInnerHtml = commentInnerHtml.supplant({ commentInnerHtml = commentInnerHtml.supplant({
contentHtml: response.contentHtml, contentHtml: response.contentHtml,
redditComments: video_data.reddit_comments_text, redditComments: video_data.reddit_comments_text,
@ -102,8 +114,8 @@ function get_youtube_comments() {
// '1,234,567.89' for user with English locale // '1,234,567.89' for user with English locale
// '1 234 567,89' for user with Russian locale // '1 234 567,89' for user with Russian locale
// '1.234.567,89' for user with Portuguese locale // '1.234.567,89' for user with Portuguese locale
commentCount: response.commentCount.toLocaleString() commentCount: response.commentCount.toLocaleString(),
}) }),
}); });
comments.innerHTML = commentInnerHtml; comments.innerHTML = commentInnerHtml;
document.getElementById("toggle-comments").onclick = toggle_comments; document.getElementById("toggle-comments").onclick = toggle_comments;
@ -117,47 +129,56 @@ function get_youtube_comments() {
}, },
onTimeout: function (xhr) { onTimeout: function (xhr) {
comments.innerHTML = spinnerHTML; comments.innerHTML = spinnerHTML;
} },
}); },
);
} }
function get_youtube_replies(target, load_more, load_replies) { function get_youtube_replies(target, load_more, load_replies) {
var continuation = target.getAttribute('data-continuation'); var continuation = target.getAttribute("data-continuation");
var body = target.parentNode; var body = target.parentNode;
var fallback = body.innerHTML; var fallback = body.innerHTML;
body.innerHTML = spinnerHTML; body.innerHTML = spinnerHTML;
var baseUrl = video_data.base_url || '/api/v1/comments/'+ video_data.id var baseUrl = video_data.base_url || "/api/v1/comments/" + video_data.id;
var url = baseUrl + var url =
'?format=html' + baseUrl +
'&hl=' + video_data.preferences.locale + "?format=html" +
'&thin_mode=' + video_data.preferences.thin_mode + "&hl=" +
'&continuation=' + continuation; video_data.preferences.locale +
"&thin_mode=" +
video_data.preferences.thin_mode +
"&continuation=" +
continuation;
if (video_data.ucid) { if (video_data.ucid) {
url += '&ucid=' + video_data.ucid url += "&ucid=" + video_data.ucid;
} }
if (load_replies) url += '&action=action_get_comment_replies'; if (load_replies) url += "&action=action_get_comment_replies";
helpers.xhr('GET', url, {}, { helpers.xhr(
"GET",
url,
{},
{
on200: function (response) { on200: function (response) {
if (load_more) { if (load_more) {
body = body.parentNode; body = body.parentNode;
body.removeChild(body.lastElementChild); body.removeChild(body.lastElementChild);
body.insertAdjacentHTML('beforeend', response.contentHtml); body.insertAdjacentHTML("beforeend", response.contentHtml);
} else { } else {
body.removeChild(body.lastElementChild); body.removeChild(body.lastElementChild);
var div = document.createElement('div'); var div = document.createElement("div");
var button = document.createElement('button'); var button = document.createElement("button");
div.appendChild(button); div.appendChild(button);
button.onclick = hide_youtube_replies; button.onclick = hide_youtube_replies;
button.setAttribute('data-sub-text', video_data.hide_replies_text); button.setAttribute("data-sub-text", video_data.hide_replies_text);
button.setAttribute('data-inner-text', video_data.show_replies_text); button.setAttribute("data-inner-text", video_data.show_replies_text);
button.textContent = video_data.hide_replies_text; button.textContent = video_data.hide_replies_text;
var div = document.createElement('div'); var div = document.createElement("div");
div.innerHTML = response.contentHtml; div.innerHTML = response.contentHtml;
body.appendChild(div); body.appendChild(div);
@ -167,8 +188,9 @@ function get_youtube_replies(target, load_more, load_replies) {
body.innerHTML = fallback; body.innerHTML = fallback;
}, },
onTimeout: function (xhr) { onTimeout: function (xhr) {
console.warn('Pulling comments failed'); console.warn("Pulling comments failed");
body.innerHTML = fallback; body.innerHTML = fallback;
} },
}); },
);
} }

View File

@ -1,51 +1,62 @@
'use strict'; "use strict";
var community_data = JSON.parse(document.getElementById('community_data').textContent); var community_data = JSON.parse(
document.getElementById("community_data").textContent,
);
function hide_youtube_replies(event) { function hide_youtube_replies(event) {
var target = event.target; var target = event.target;
var sub_text = target.getAttribute('data-inner-text'); var sub_text = target.getAttribute("data-inner-text");
var inner_text = target.getAttribute('data-sub-text'); var inner_text = target.getAttribute("data-sub-text");
var body = target.parentNode.parentNode.children[1]; var body = target.parentNode.parentNode.children[1];
body.style.display = 'none'; body.style.display = "none";
target.innerHTML = sub_text; target.innerHTML = sub_text;
target.onclick = show_youtube_replies; target.onclick = show_youtube_replies;
target.setAttribute('data-inner-text', inner_text); target.setAttribute("data-inner-text", inner_text);
target.setAttribute('data-sub-text', sub_text); target.setAttribute("data-sub-text", sub_text);
} }
function show_youtube_replies(event) { function show_youtube_replies(event) {
var target = event.target; var target = event.target;
var sub_text = target.getAttribute('data-inner-text'); var sub_text = target.getAttribute("data-inner-text");
var inner_text = target.getAttribute('data-sub-text'); var inner_text = target.getAttribute("data-sub-text");
var body = target.parentNode.parentNode.children[1]; var body = target.parentNode.parentNode.children[1];
body.style.display = ''; body.style.display = "";
target.innerHTML = sub_text; target.innerHTML = sub_text;
target.onclick = hide_youtube_replies; target.onclick = hide_youtube_replies;
target.setAttribute('data-inner-text', inner_text); target.setAttribute("data-inner-text", inner_text);
target.setAttribute('data-sub-text', sub_text); target.setAttribute("data-sub-text", sub_text);
} }
function get_youtube_replies(target, load_more) { function get_youtube_replies(target, load_more) {
var continuation = target.getAttribute('data-continuation'); var continuation = target.getAttribute("data-continuation");
var body = target.parentNode.parentNode; var body = target.parentNode.parentNode;
var fallback = body.innerHTML; var fallback = body.innerHTML;
body.innerHTML = body.innerHTML =
'<h3 style="text-align:center"><div class="loading"><i class="icon ion-ios-refresh"></i></div></h3>'; '<h3 style="text-align:center"><div class="loading"><i class="icon ion-ios-refresh"></i></div></h3>';
var url = '/api/v1/channels/comments/' + community_data.ucid + var url =
'?format=html' + "/api/v1/channels/comments/" +
'&hl=' + community_data.preferences.locale + community_data.ucid +
'&thin_mode=' + community_data.preferences.thin_mode + "?format=html" +
'&continuation=' + continuation; "&hl=" +
community_data.preferences.locale +
"&thin_mode=" +
community_data.preferences.thin_mode +
"&continuation=" +
continuation;
helpers.xhr('GET', url, {}, { helpers.xhr(
"GET",
url,
{},
{
on200: function (response) { on200: function (response) {
if (load_more) { if (load_more) {
body = body.parentNode.parentNode; body = body.parentNode.parentNode;
@ -54,17 +65,17 @@ function get_youtube_replies(target, load_more) {
} else { } else {
body.removeChild(body.lastElementChild); body.removeChild(body.lastElementChild);
var p = document.createElement('p'); var p = document.createElement("p");
var a = document.createElement('a'); var a = document.createElement("a");
p.appendChild(a); p.appendChild(a);
a.href = 'javascript:void(0)'; a.href = "javascript:void(0)";
a.onclick = hide_youtube_replies; a.onclick = hide_youtube_replies;
a.setAttribute('data-sub-text', community_data.hide_replies_text); a.setAttribute("data-sub-text", community_data.hide_replies_text);
a.setAttribute('data-inner-text', community_data.show_replies_text); a.setAttribute("data-inner-text", community_data.show_replies_text);
a.textContent = community_data.hide_replies_text; a.textContent = community_data.hide_replies_text;
var div = document.createElement('div'); var div = document.createElement("div");
div.innerHTML = response.contentHtml; div.innerHTML = response.contentHtml;
body.appendChild(p); body.appendChild(p);
@ -75,8 +86,9 @@ function get_youtube_replies(target, load_more) {
body.innerHTML = fallback; body.innerHTML = fallback;
}, },
onTimeout: function (xhr) { onTimeout: function (xhr) {
console.warn('Pulling comments failed'); console.warn("Pulling comments failed");
body.innerHTML = fallback; body.innerHTML = fallback;
} },
}); },
);
} }

View File

@ -1,62 +1,77 @@
'use strict'; "use strict";
var video_data = JSON.parse(document.getElementById('video_data').textContent); var video_data = JSON.parse(document.getElementById("video_data").textContent);
function get_playlist(plid) { function get_playlist(plid) {
var plid_url; var plid_url;
if (plid.startsWith('RD')) { if (plid.startsWith("RD")) {
plid_url = '/api/v1/mixes/' + plid + plid_url =
'?continuation=' + video_data.id + "/api/v1/mixes/" +
'&format=html&hl=' + video_data.preferences.locale; plid +
"?continuation=" +
video_data.id +
"&format=html&hl=" +
video_data.preferences.locale;
} else { } else {
plid_url = '/api/v1/playlists/' + plid + plid_url =
'?index=' + video_data.index + "/api/v1/playlists/" +
'&continuation' + video_data.id + plid +
'&format=html&hl=' + video_data.preferences.locale; "?index=" +
video_data.index +
"&continuation" +
video_data.id +
"&format=html&hl=" +
video_data.preferences.locale;
} }
helpers.xhr('GET', plid_url, {retries: 5, entity_name: 'playlist'}, { helpers.xhr(
"GET",
plid_url,
{ retries: 5, entity_name: "playlist" },
{
on200: function (response) { on200: function (response) {
if (!response.nextVideo) if (!response.nextVideo) return;
return;
player.on('ended', function () { player.on("ended", function () {
var url = new URL('https://example.com/embed/' + response.nextVideo); var url = new URL("https://example.com/embed/" + response.nextVideo);
url.searchParams.set('list', plid); url.searchParams.set("list", plid);
if (!plid.startsWith('RD')) if (!plid.startsWith("RD"))
url.searchParams.set('index', response.index); url.searchParams.set("index", response.index);
if (video_data.params.autoplay || video_data.params.continue_autoplay) if (video_data.params.autoplay || video_data.params.continue_autoplay)
url.searchParams.set('autoplay', '1'); url.searchParams.set("autoplay", "1");
if (video_data.params.listen !== video_data.preferences.listen) if (video_data.params.listen !== video_data.preferences.listen)
url.searchParams.set('listen', video_data.params.listen); url.searchParams.set("listen", video_data.params.listen);
if (video_data.params.speed !== video_data.preferences.speed) if (video_data.params.speed !== video_data.preferences.speed)
url.searchParams.set('speed', video_data.params.speed); url.searchParams.set("speed", video_data.params.speed);
if (video_data.params.local !== video_data.preferences.local) if (video_data.params.local !== video_data.preferences.local)
url.searchParams.set('local', video_data.params.local); url.searchParams.set("local", video_data.params.local);
location.assign(url.pathname + url.search); location.assign(url.pathname + url.search);
}); });
} },
}); },
);
} }
addEventListener('load', function (e) { addEventListener("load", function (e) {
if (video_data.plid) { if (video_data.plid) {
get_playlist(video_data.plid); get_playlist(video_data.plid);
} else if (video_data.video_series) { } else if (video_data.video_series) {
player.on('ended', function () { player.on("ended", function () {
var url = new URL('https://example.com/embed/' + video_data.video_series.shift()); var url = new URL(
"https://example.com/embed/" + video_data.video_series.shift(),
);
if (video_data.params.autoplay || video_data.params.continue_autoplay) if (video_data.params.autoplay || video_data.params.continue_autoplay)
url.searchParams.set('autoplay', '1'); url.searchParams.set("autoplay", "1");
if (video_data.params.listen !== video_data.preferences.listen) if (video_data.params.listen !== video_data.preferences.listen)
url.searchParams.set('listen', video_data.params.listen); url.searchParams.set("listen", video_data.params.listen);
if (video_data.params.speed !== video_data.preferences.speed) if (video_data.params.speed !== video_data.preferences.speed)
url.searchParams.set('speed', video_data.params.speed); url.searchParams.set("speed", video_data.params.speed);
if (video_data.params.local !== video_data.preferences.local) if (video_data.params.local !== video_data.preferences.local)
url.searchParams.set('local', video_data.params.local); url.searchParams.set("local", video_data.params.local);
if (video_data.video_series.length !== 0) if (video_data.video_series.length !== 0)
url.searchParams.set('playlist', video_data.video_series.join(',')); url.searchParams.set("playlist", video_data.video_series.join(","));
location.assign(url.pathname + url.search); location.assign(url.pathname + url.search);
}); });

View File

@ -1,32 +1,40 @@
'use strict'; "use strict";
(function () { (function () {
var video_player = document.getElementById('player_html5_api'); var video_player = document.getElementById("player_html5_api");
if (video_player) { if (video_player) {
video_player.onmouseenter = function () { video_player['data-title'] = video_player['title']; video_player['title'] = ''; }; video_player.onmouseenter = function () {
video_player.onmouseleave = function () { video_player['title'] = video_player['data-title']; video_player['data-title'] = ''; }; video_player["data-title"] = video_player["title"];
video_player.oncontextmenu = function () { video_player['title'] = video_player['data-title']; }; video_player["title"] = "";
};
video_player.onmouseleave = function () {
video_player["title"] = video_player["data-title"];
video_player["data-title"] = "";
};
video_player.oncontextmenu = function () {
video_player["title"] = video_player["data-title"];
};
} }
// For dynamically inserted elements // For dynamically inserted elements
addEventListener('click', function (e) { addEventListener("click", function (e) {
if (!e || !e.target) return; if (!e || !e.target) return;
var t = e.target; var t = e.target;
var handler_name = t.getAttribute('data-onclick'); var handler_name = t.getAttribute("data-onclick");
switch (handler_name) { switch (handler_name) {
case 'jump_to_time': case "jump_to_time":
e.preventDefault(); e.preventDefault();
var time = t.getAttribute('data-jump-time'); var time = t.getAttribute("data-jump-time");
player.currentTime(time); player.currentTime(time);
break; break;
case 'get_youtube_replies': case "get_youtube_replies":
var load_more = t.getAttribute('data-load-more') !== null; var load_more = t.getAttribute("data-load-more") !== null;
var load_replies = t.getAttribute('data-load-replies') !== null; var load_replies = t.getAttribute("data-load-replies") !== null;
get_youtube_replies(t, load_more, load_replies); get_youtube_replies(t, load_more, load_replies);
break; break;
case 'toggle_parent': case "toggle_parent":
e.preventDefault(); e.preventDefault();
toggle_parent(t); toggle_parent(t);
break; break;
@ -35,98 +43,161 @@
} }
}); });
document.querySelectorAll('[data-mouse="switch_classes"]').forEach(function (el) { document
var classes = el.getAttribute('data-switch-classes').split(','); .querySelectorAll('[data-mouse="switch_classes"]')
.forEach(function (el) {
var classes = el.getAttribute("data-switch-classes").split(",");
var classOnEnter = classes[0]; var classOnEnter = classes[0];
var classOnLeave = classes[1]; var classOnLeave = classes[1];
function toggle_classes(toAdd, toRemove) { function toggle_classes(toAdd, toRemove) {
el.classList.add(toAdd); el.classList.add(toAdd);
el.classList.remove(toRemove); el.classList.remove(toRemove);
} }
el.onmouseenter = function () { toggle_classes(classOnEnter, classOnLeave); }; el.onmouseenter = function () {
el.onmouseleave = function () { toggle_classes(classOnLeave, classOnEnter); }; toggle_classes(classOnEnter, classOnLeave);
};
el.onmouseleave = function () {
toggle_classes(classOnLeave, classOnEnter);
};
}); });
document.querySelectorAll('[data-onsubmit="return_false"]').forEach(function (el) { document
el.onsubmit = function () { return false; }; .querySelectorAll('[data-onsubmit="return_false"]')
.forEach(function (el) {
el.onsubmit = function () {
return false;
};
}); });
document.querySelectorAll('[data-onclick="mark_watched"]').forEach(function (el) { document
el.onclick = function () { mark_watched(el); }; .querySelectorAll('[data-onclick="mark_watched"]')
.forEach(function (el) {
el.onclick = function () {
mark_watched(el);
};
}); });
document.querySelectorAll('[data-onclick="mark_unwatched"]').forEach(function (el) { document
el.onclick = function () { mark_unwatched(el); }; .querySelectorAll('[data-onclick="mark_unwatched"]')
.forEach(function (el) {
el.onclick = function () {
mark_unwatched(el);
};
}); });
document.querySelectorAll('[data-onclick="add_playlist_video"]').forEach(function (el) { document
el.onclick = function (e) { add_playlist_video(e); }; .querySelectorAll('[data-onclick="add_playlist_video"]')
.forEach(function (el) {
el.onclick = function (e) {
add_playlist_video(e);
};
}); });
document.querySelectorAll('[data-onclick="add_playlist_item"]').forEach(function (el) { document
el.onclick = function (e) { add_playlist_item(e); }; .querySelectorAll('[data-onclick="add_playlist_item"]')
.forEach(function (el) {
el.onclick = function (e) {
add_playlist_item(e);
};
}); });
document.querySelectorAll('[data-onclick="remove_playlist_item"]').forEach(function (el) { document
el.onclick = function (e) { remove_playlist_item(e); }; .querySelectorAll('[data-onclick="remove_playlist_item"]')
.forEach(function (el) {
el.onclick = function (e) {
remove_playlist_item(e);
};
}); });
document.querySelectorAll('[data-onclick="revoke_token"]').forEach(function (el) { document
el.onclick = function () { revoke_token(el); }; .querySelectorAll('[data-onclick="revoke_token"]')
.forEach(function (el) {
el.onclick = function () {
revoke_token(el);
};
}); });
document.querySelectorAll('[data-onclick="remove_subscription"]').forEach(function (el) { document
el.onclick = function () { remove_subscription(el); }; .querySelectorAll('[data-onclick="remove_subscription"]')
.forEach(function (el) {
el.onclick = function () {
remove_subscription(el);
};
}); });
document.querySelectorAll('[data-onclick="notification_requestPermission"]').forEach(function (el) { document
el.onclick = function () { Notification.requestPermission(); }; .querySelectorAll('[data-onclick="notification_requestPermission"]')
.forEach(function (el) {
el.onclick = function () {
Notification.requestPermission();
};
}); });
document.querySelectorAll('[data-onrange="update_volume_value"]').forEach(function (el) { document
.querySelectorAll('[data-onrange="update_volume_value"]')
.forEach(function (el) {
function update_volume_value() { function update_volume_value() {
document.getElementById('volume-value').textContent = el.value; document.getElementById("volume-value").textContent = el.value;
} }
el.oninput = update_volume_value; el.oninput = update_volume_value;
el.onchange = update_volume_value; el.onchange = update_volume_value;
}); });
function revoke_token(target) { function revoke_token(target) {
var row = target.parentNode.parentNode.parentNode.parentNode.parentNode; var row = target.parentNode.parentNode.parentNode.parentNode.parentNode;
row.style.display = 'none'; row.style.display = "none";
var count = document.getElementById('count'); var count = document.getElementById("count");
count.textContent--; count.textContent--;
var url = '/token_ajax?action=revoke_token&redirect=false' + var url =
'&referer=' + encodeURIComponent(location.href) + "/token_ajax?action=revoke_token&redirect=false" +
'&session=' + target.getAttribute('data-session'); "&referer=" +
encodeURIComponent(location.href) +
"&session=" +
target.getAttribute("data-session");
var payload = 'csrf_token=' + target.parentNode.querySelector('input[name="csrf_token"]').value; var payload =
"csrf_token=" +
target.parentNode.querySelector('input[name="csrf_token"]').value;
helpers.xhr('POST', url, {payload: payload}, { helpers.xhr(
"POST",
url,
{ payload: payload },
{
onNon200: function (xhr) { onNon200: function (xhr) {
count.textContent++; count.textContent++;
row.style.display = ''; row.style.display = "";
} },
}); },
);
} }
function remove_subscription(target) { function remove_subscription(target) {
var row = target.parentNode.parentNode.parentNode.parentNode.parentNode; var row = target.parentNode.parentNode.parentNode.parentNode.parentNode;
row.style.display = 'none'; row.style.display = "none";
var count = document.getElementById('count'); var count = document.getElementById("count");
count.textContent--; count.textContent--;
var url = '/subscription_ajax?action=remove_subscriptions&redirect=false' + var url =
'&referer=' + encodeURIComponent(location.href) + "/subscription_ajax?action=remove_subscriptions&redirect=false" +
'&c=' + target.getAttribute('data-ucid'); "&referer=" +
encodeURIComponent(location.href) +
"&c=" +
target.getAttribute("data-ucid");
var payload = 'csrf_token=' + target.parentNode.querySelector('input[name="csrf_token"]').value; var payload =
"csrf_token=" +
target.parentNode.querySelector('input[name="csrf_token"]').value;
helpers.xhr('POST', url, {payload: payload}, { helpers.xhr(
"POST",
url,
{ payload: payload },
{
onNon200: function (xhr) { onNon200: function (xhr) {
count.textContent++; count.textContent++;
row.style.display = ''; row.style.display = "";
} },
}); },
);
} }
// Handle keypresses // Handle keypresses
addEventListener('keydown', function (event) { addEventListener("keydown", function (event) {
// Ignore modifier keys // Ignore modifier keys
if (event.ctrlKey || event.metaKey) return; if (event.ctrlKey || event.metaKey) return;
@ -134,15 +205,15 @@
let focused_tag = document.activeElement.tagName.toLowerCase(); let focused_tag = document.activeElement.tagName.toLowerCase();
const allowed = /^(button|checkbox|file|radio|submit)$/; const allowed = /^(button|checkbox|file|radio|submit)$/;
if (focused_tag === 'textarea') return; if (focused_tag === "textarea") return;
if (focused_tag === 'input') { if (focused_tag === "input") {
let focused_type = document.activeElement.type.toLowerCase(); let focused_type = document.activeElement.type.toLowerCase();
if (!allowed.test(focused_type)) return; if (!allowed.test(focused_type)) return;
} }
// Focus search bar on '/' // Focus search bar on '/'
if (event.key === '/') { if (event.key === "/") {
document.getElementById('searchbox').focus(); document.getElementById("searchbox").focus();
event.preventDefault(); event.preventDefault();
} }
}); });

View File

@ -31,7 +31,11 @@ async function get_subscriptions_call() {
} }
// Start the retry mechanism // Start the retry mechanism
const get_subscriptions = exponential_backoff(get_subscriptions_call, 100, 1000); const get_subscriptions = exponential_backoff(
get_subscriptions_call,
100,
1000,
);
function create_notification_stream(subscriptions) { function create_notification_stream(subscriptions) {
// sse.js can't be replaced to EventSource in place as it lack support of payload and headers // sse.js can't be replaced to EventSource in place as it lack support of payload and headers
@ -96,7 +100,6 @@ function create_notification_stream(subscriptions) {
"Something went wrong with notifications, trying to reconnect...", "Something went wrong with notifications, trying to reconnect...",
); );
notifications = notifications_mock; notifications = notifications_mock;
}); });
notifications.stream(); notifications.stream();
@ -193,5 +196,5 @@ function exponential_backoff(
console.log("Max retries reached. Operation failed:", error); console.log("Max retries reached. Operation failed:", error);
} }
}); });
} };
} }

View File

@ -1,6 +1,8 @@
'use strict'; "use strict";
const CURRENT_CONTINUATION = (new URL(document.location)).searchParams.get("continuation"); const CURRENT_CONTINUATION = new URL(document.location).searchParams.get(
"continuation",
);
const CONT_CACHE_KEY = `continuation_cache_${encodeURIComponent(window.location.pathname)}`; const CONT_CACHE_KEY = `continuation_cache_${encodeURIComponent(window.location.pathname)}`;
function get_data() { function get_data() {
@ -42,20 +44,20 @@ function button_press(){
let url = set_continuation(prev_ctoken); let url = set_continuation(prev_ctoken);
window.location.href = url; window.location.href = url;
}; }
// Method to set the current page's continuation token // Method to set the current page's continuation token
// Removes the continuation parameter when a continuation token is not given // Removes the continuation parameter when a continuation token is not given
function set_continuation(prev_ctoken = null) { function set_continuation(prev_ctoken = null) {
let url = window.location.href.split('?')[0]; let url = window.location.href.split("?")[0];
let params = window.location.href.split('?')[1]; let params = window.location.href.split("?")[1];
let url_params = new URLSearchParams(params); let url_params = new URLSearchParams(params);
if (prev_ctoken) { if (prev_ctoken) {
url_params.set("continuation", prev_ctoken); url_params.set("continuation", prev_ctoken);
} else { } else {
url_params.delete('continuation'); url_params.delete("continuation");
}; }
if (Array.from(url_params).length > 0) { if (Array.from(url_params).length > 0) {
return `${url}?${url_params.toString()}`; return `${url}?${url_params.toString()}`;
@ -64,12 +66,16 @@ function set_continuation(prev_ctoken = null){
} }
} }
addEventListener('DOMContentLoaded', function(){ addEventListener("DOMContentLoaded", function () {
const pagination_data = JSON.parse(document.getElementById('pagination-data').textContent); const pagination_data = JSON.parse(
const next_page_containers = document.getElementsByClassName("page-next-container"); document.getElementById("pagination-data").textContent,
);
const next_page_containers = document.getElementsByClassName(
"page-next-container",
);
for (let container of next_page_containers) { for (let container of next_page_containers) {
const next_page_button = container.getElementsByClassName("pure-button") const next_page_button = container.getElementsByClassName("pure-button");
// exists? // exists?
if (next_page_button.length > 0) { if (next_page_button.length > 0) {
@ -79,15 +85,19 @@ addEventListener('DOMContentLoaded', function(){
// Only add previous page buttons when not on the first page // Only add previous page buttons when not on the first page
if (CURRENT_CONTINUATION) { if (CURRENT_CONTINUATION) {
const prev_page_containers = document.getElementsByClassName("page-prev-container") const prev_page_containers = document.getElementsByClassName(
"page-prev-container",
);
for (let container of prev_page_containers) { for (let container of prev_page_containers) {
if (pagination_data.is_rtl) { if (pagination_data.is_rtl) {
container.innerHTML = `<button class="pure-button pure-button-secondary">${pagination_data.prev_page}&nbsp;&nbsp;<i class="icon ion-ios-arrow-forward"></i></button>` container.innerHTML = `<button class="pure-button pure-button-secondary">${pagination_data.prev_page}&nbsp;&nbsp;<i class="icon ion-ios-arrow-forward"></i></button>`;
} else { } else {
container.innerHTML = `<button class="pure-button pure-button-secondary"><i class="icon ion-ios-arrow-back"></i>&nbsp;&nbsp;${pagination_data.prev_page}</button>` container.innerHTML = `<button class="pure-button pure-button-secondary"><i class="icon ion-ios-arrow-back"></i>&nbsp;&nbsp;${pagination_data.prev_page}</button>`;
} }
container.getElementsByClassName("pure-button")[0].addEventListener("click", button_press); container
.getElementsByClassName("pure-button")[0]
.addEventListener("click", button_press);
} }
} }
}); });

File diff suppressed because it is too large Load Diff

View File

@ -1,55 +1,83 @@
'use strict'; "use strict";
var playlist_data = JSON.parse(document.getElementById('playlist_data').textContent); var playlist_data = JSON.parse(
var payload = 'csrf_token=' + playlist_data.csrf_token; document.getElementById("playlist_data").textContent,
);
var payload = "csrf_token=" + playlist_data.csrf_token;
function add_playlist_video(event) { function add_playlist_video(event) {
const target = event.target; const target = event.target;
var select = document.querySelector("#playlists"); var select = document.querySelector("#playlists");
var option = select.children[select.selectedIndex]; var option = select.children[select.selectedIndex];
var url = '/playlist_ajax?action=add_video&redirect=false' + var url =
'&video_id=' + target.getAttribute('data-id') + "/playlist_ajax?action=add_video&redirect=false" +
'&playlist_id=' + option.getAttribute('data-plid'); "&video_id=" +
target.getAttribute("data-id") +
"&playlist_id=" +
option.getAttribute("data-plid");
helpers.xhr('POST', url, {payload: payload}, { helpers.xhr(
"POST",
url,
{ payload: payload },
{
on200: function (response) { on200: function (response) {
option.textContent = '✓ ' + option.textContent; option.textContent = "✓ " + option.textContent;
} },
}); },
);
} }
function add_playlist_item(event) { function add_playlist_item(event) {
event.preventDefault(); event.preventDefault();
const target = event.target; const target = event.target;
const video_id = target.getAttribute('data-id'); const video_id = target.getAttribute("data-id");
var card = document.querySelector(`#video-card-${video_id}`); var card = document.querySelector(`#video-card-${video_id}`);
card.classList.add("hide"); card.classList.add("hide");
var url = '/playlist_ajax?action=add_video&redirect=false' + var url =
'&video_id=' + target.getAttribute('data-id') + "/playlist_ajax?action=add_video&redirect=false" +
'&playlist_id=' + target.getAttribute('data-plid'); "&video_id=" +
target.getAttribute("data-id") +
"&playlist_id=" +
target.getAttribute("data-plid");
helpers.xhr('POST', url, {payload: payload}, { helpers.xhr(
"POST",
url,
{ payload: payload },
{
onNon200: function (xhr) { onNon200: function (xhr) {
card.classList.remove("hide"); card.classList.remove("hide");
} },
}); },
);
} }
function remove_playlist_item(event) { function remove_playlist_item(event) {
event.preventDefault(); event.preventDefault();
const target = event.target; const target = event.target;
const video_index = target.getAttribute('data-index'); const video_index = target.getAttribute("data-index");
const card = document.querySelector(`.video-card [data-index="${video_index}"]`) const card = document.querySelector(
`.video-card [data-index="${video_index}"]`,
);
card.classList.add("hide"); card.classList.add("hide");
var url = '/playlist_ajax?action=remove_video&redirect=false' + var url =
'&set_video_id=' + target.getAttribute('data-index') + "/playlist_ajax?action=remove_video&redirect=false" +
'&playlist_id=' + target.getAttribute('data-plid'); "&set_video_id=" +
target.getAttribute("data-index") +
"&playlist_id=" +
target.getAttribute("data-plid");
helpers.xhr('POST', url, {payload: payload}, { helpers.xhr(
"POST",
url,
{ payload: payload },
{
onNon200: function (xhr) { onNon200: function (xhr) {
card.classList.remove("hide"); card.classList.remove("hide");
} },
}); },
);
} }

View File

@ -1,3 +1,3 @@
addEventListener('load', function (e) { addEventListener("load", function (e) {
get_youtube_comments(); get_youtube_comments();
}); });

File diff suppressed because one or more lines are too long

View File

@ -17,16 +17,16 @@ var SSE = function (url, options) {
options = options || {}; options = options || {};
this.headers = options.headers || {}; this.headers = options.headers || {};
this.payload = options.payload !== undefined ? options.payload : ''; this.payload = options.payload !== undefined ? options.payload : "";
this.method = options.method || (this.payload && 'POST' || 'GET'); this.method = options.method || (this.payload && "POST") || "GET";
this.FIELD_SEPARATOR = ':'; this.FIELD_SEPARATOR = ":";
this.listeners = {}; this.listeners = {};
this.xhr = null; this.xhr = null;
this.readyState = this.INITIALIZING; this.readyState = this.INITIALIZING;
this.progress = 0; this.progress = 0;
this.chunk = ''; this.chunk = "";
this.addEventListener = function (type, listener) { this.addEventListener = function (type, listener) {
if (this.listeners[type] === undefined) { if (this.listeners[type] === undefined) {
@ -63,7 +63,7 @@ var SSE = function (url, options) {
e.source = this; e.source = this;
var onHandler = 'on' + e.type; var onHandler = "on" + e.type;
if (this.hasOwnProperty(onHandler)) { if (this.hasOwnProperty(onHandler)) {
this[onHandler].call(this, e); this[onHandler].call(this, e);
if (e.defaultPrevented) { if (e.defaultPrevented) {
@ -82,16 +82,16 @@ var SSE = function (url, options) {
}; };
this._setReadyState = function (state) { this._setReadyState = function (state) {
var event = new CustomEvent('readystatechange'); var event = new CustomEvent("readystatechange");
event.readyState = state; event.readyState = state;
this.readyState = state; this.readyState = state;
this.dispatchEvent(event); this.dispatchEvent(event);
}; };
this._onStreamFailure = function (e) { this._onStreamFailure = function (e) {
this.dispatchEvent(new CustomEvent('error')); this.dispatchEvent(new CustomEvent("error"));
this.close(); this.close();
} };
this._onStreamProgress = function (e) { this._onStreamProgress = function (e) {
if (this.xhr.status !== 200 && this.readyState !== this.CLOSED) { if (this.xhr.status !== 200 && this.readyState !== this.CLOSED) {
@ -100,20 +100,22 @@ var SSE = function (url, options) {
} }
if (this.readyState == this.CONNECTING) { if (this.readyState == this.CONNECTING) {
this.dispatchEvent(new CustomEvent('open')); this.dispatchEvent(new CustomEvent("open"));
this._setReadyState(this.OPEN); this._setReadyState(this.OPEN);
} }
var data = this.xhr.responseText.substring(this.progress); var data = this.xhr.responseText.substring(this.progress);
this.progress += data.length; this.progress += data.length;
data.split(/(\r\n|\r|\n){2}/g).forEach(function(part) { data.split(/(\r\n|\r|\n){2}/g).forEach(
function (part) {
if (part.trim().length === 0) { if (part.trim().length === 0) {
this.dispatchEvent(this._parseEventChunk(this.chunk.trim())); this.dispatchEvent(this._parseEventChunk(this.chunk.trim()));
this.chunk = ''; this.chunk = "";
} else { } else {
this.chunk += part; this.chunk += part;
} }
}.bind(this)); }.bind(this),
);
}; };
this._onStreamLoaded = function (e) { this._onStreamLoaded = function (e) {
@ -121,7 +123,7 @@ var SSE = function (url, options) {
// Parse the last chunk. // Parse the last chunk.
this.dispatchEvent(this._parseEventChunk(this.chunk)); this.dispatchEvent(this._parseEventChunk(this.chunk));
this.chunk = ''; this.chunk = "";
}; };
/** /**
@ -132,8 +134,9 @@ var SSE = function (url, options) {
return null; return null;
} }
var e = {'id': null, 'retry': null, 'data': '', 'event': 'message'}; var e = { id: null, retry: null, data: "", event: "message" };
chunk.split(/\n|\r\n|\r/).forEach(function(line) { chunk.split(/\n|\r\n|\r/).forEach(
function (line) {
line = line.trimRight(); line = line.trimRight();
var index = line.indexOf(this.FIELD_SEPARATOR); var index = line.indexOf(this.FIELD_SEPARATOR);
if (index <= 0) { if (index <= 0) {
@ -148,12 +151,13 @@ var SSE = function (url, options) {
} }
var value = line.substring(index + 1).trimLeft(); var value = line.substring(index + 1).trimLeft();
if (field === 'data') { if (field === "data") {
e[field] += value; e[field] += value;
} else { } else {
e[field] = value; e[field] = value;
} }
}.bind(this)); }.bind(this),
);
var event = new CustomEvent(e.event); var event = new CustomEvent(e.event);
event.data = e.data; event.data = e.data;
@ -171,11 +175,14 @@ var SSE = function (url, options) {
this._setReadyState(this.CONNECTING); this._setReadyState(this.CONNECTING);
this.xhr = new XMLHttpRequest(); this.xhr = new XMLHttpRequest();
this.xhr.addEventListener('progress', this._onStreamProgress.bind(this)); this.xhr.addEventListener("progress", this._onStreamProgress.bind(this));
this.xhr.addEventListener('load', this._onStreamLoaded.bind(this)); this.xhr.addEventListener("load", this._onStreamLoaded.bind(this));
this.xhr.addEventListener('readystatechange', this._checkStreamClosed.bind(this)); this.xhr.addEventListener(
this.xhr.addEventListener('error', this._onStreamFailure.bind(this)); "readystatechange",
this.xhr.addEventListener('abort', this._onStreamFailure.bind(this)); this._checkStreamClosed.bind(this),
);
this.xhr.addEventListener("error", this._onStreamFailure.bind(this));
this.xhr.addEventListener("abort", this._onStreamFailure.bind(this));
this.xhr.open(this.method, this.url); this.xhr.open(this.method, this.url);
for (var header in this.headers) { for (var header in this.headers) {
this.xhr.setRequestHeader(header, this.headers[header]); this.xhr.setRequestHeader(header, this.headers[header]);
@ -195,6 +202,6 @@ var SSE = function (url, options) {
}; };
// Export our SSE module for npm.js // Export our SSE module for npm.js
if (typeof exports !== 'undefined') { if (typeof exports !== "undefined") {
exports.SSE = SSE; exports.SSE = SSE;
} }

View File

@ -1,10 +1,12 @@
'use strict'; "use strict";
var subscribe_data = JSON.parse(document.getElementById('subscribe_data').textContent); var subscribe_data = JSON.parse(
var payload = 'csrf_token=' + subscribe_data.csrf_token; document.getElementById("subscribe_data").textContent,
);
var payload = "csrf_token=" + subscribe_data.csrf_token;
var subscribe_button = document.getElementById('subscribe'); var subscribe_button = document.getElementById("subscribe");
if (subscribe_button.getAttribute('data-type') === 'subscribe') { if (subscribe_button.getAttribute("data-type") === "subscribe") {
subscribe_button.onclick = subscribe; subscribe_button.onclick = subscribe;
} else { } else {
subscribe_button.onclick = unsubscribe; subscribe_button.onclick = unsubscribe;
@ -16,13 +18,15 @@ function toggleSubscribeButton() {
subscribe_button.classList.remove("unsubscribe"); subscribe_button.classList.remove("unsubscribe");
subscribe_button.classList.remove("subscribe"); subscribe_button.classList.remove("subscribe");
if (subscribe_button.getAttribute('data-type') === 'subscribe') { if (subscribe_button.getAttribute("data-type") === "subscribe") {
subscribe_button.textContent = subscribe_data.unsubscribe_text + ' | ' + subscribe_data.sub_count_text; subscribe_button.textContent =
subscribe_data.unsubscribe_text + " | " + subscribe_data.sub_count_text;
subscribe_button.onclick = unsubscribe; subscribe_button.onclick = unsubscribe;
subscribe_button.classList.add("secondary"); subscribe_button.classList.add("secondary");
subscribe_button.classList.add("unsubscribe"); subscribe_button.classList.add("unsubscribe");
} else { } else {
subscribe_button.textContent = subscribe_data.subscribe_text + ' | ' + subscribe_data.sub_count_text; subscribe_button.textContent =
subscribe_data.subscribe_text + " | " + subscribe_data.sub_count_text;
subscribe_button.onclick = subscribe; subscribe_button.onclick = subscribe;
subscribe_button.classList.add("primary"); subscribe_button.classList.add("primary");
subscribe_button.classList.add("subscribe"); subscribe_button.classList.add("subscribe");
@ -34,15 +38,22 @@ function subscribe(e) {
var fallback = subscribe_button.textContent; var fallback = subscribe_button.textContent;
toggleSubscribeButton(); toggleSubscribeButton();
var url = '/subscription_ajax?action=create_subscription_to_channel&redirect=false' + var url =
'&c=' + subscribe_data.ucid; "/subscription_ajax?action=create_subscription_to_channel&redirect=false" +
"&c=" +
subscribe_data.ucid;
helpers.xhr('POST', url, {payload: payload, retries: 5, entity_name: 'subscribe request'}, { helpers.xhr(
"POST",
url,
{ payload: payload, retries: 5, entity_name: "subscribe request" },
{
onNon200: function (xhr) { onNon200: function (xhr) {
subscribe_button.onclick = subscribe; subscribe_button.onclick = subscribe;
subscribe_button.textContent = fallback; subscribe_button.textContent = fallback;
} },
}); },
);
} }
function unsubscribe(e) { function unsubscribe(e) {
@ -50,13 +61,20 @@ function unsubscribe(e) {
var fallback = subscribe_button.textContent; var fallback = subscribe_button.textContent;
toggleSubscribeButton(); toggleSubscribeButton();
var url = '/subscription_ajax?action=remove_subscriptions&redirect=false' + var url =
'&c=' + subscribe_data.ucid; "/subscription_ajax?action=remove_subscriptions&redirect=false" +
"&c=" +
subscribe_data.ucid;
helpers.xhr('POST', url, {payload: payload, retries: 5, entity_name: 'unsubscribe request'}, { helpers.xhr(
"POST",
url,
{ payload: payload, retries: 5, entity_name: "unsubscribe request" },
{
onNon200: function (xhr) { onNon200: function (xhr) {
subscribe_button.onclick = unsubscribe; subscribe_button.onclick = unsubscribe;
subscribe_button.textContent = fallback; subscribe_button.textContent = fallback;
} },
}); },
);
} }

View File

@ -1,18 +1,18 @@
'use strict'; "use strict";
var toggle_theme = document.getElementById('toggle_theme'); var toggle_theme = document.getElementById("toggle_theme");
const STORAGE_KEY_THEME = 'dark_mode'; const STORAGE_KEY_THEME = "dark_mode";
const THEME_DARK = 'dark'; const THEME_DARK = "dark";
const THEME_LIGHT = 'light'; const THEME_LIGHT = "light";
// TODO: theme state controlled by system // TODO: theme state controlled by system
toggle_theme.addEventListener('click', function (e) { toggle_theme.addEventListener("click", function (e) {
e.preventDefault(); e.preventDefault();
const isDarkTheme = helpers.storage.get(STORAGE_KEY_THEME) === THEME_DARK; const isDarkTheme = helpers.storage.get(STORAGE_KEY_THEME) === THEME_DARK;
const newTheme = isDarkTheme ? THEME_LIGHT : THEME_DARK; const newTheme = isDarkTheme ? THEME_LIGHT : THEME_DARK;
setTheme(newTheme); setTheme(newTheme);
helpers.storage.set(STORAGE_KEY_THEME, newTheme); helpers.storage.set(STORAGE_KEY_THEME, newTheme);
helpers.xhr('GET', '/toggle_theme?redirect=false', {}, {}); helpers.xhr("GET", "/toggle_theme?redirect=false", {}, {});
}); });
/** @param {THEME_DARK|THEME_LIGHT} theme */ /** @param {THEME_DARK|THEME_LIGHT} theme */
@ -20,25 +20,25 @@ function setTheme(theme) {
// By default body element has .no-theme class that uses OS theme via CSS @media rules // By default body element has .no-theme class that uses OS theme via CSS @media rules
// It rewrites using hard className below // It rewrites using hard className below
if (theme === THEME_DARK) { if (theme === THEME_DARK) {
toggle_theme.children[0].className = 'icon ion-ios-sunny'; toggle_theme.children[0].className = "icon ion-ios-sunny";
document.body.className = 'dark-theme'; document.body.className = "dark-theme";
} else if (theme === THEME_LIGHT) { } else if (theme === THEME_LIGHT) {
toggle_theme.children[0].className = 'icon ion-ios-moon'; toggle_theme.children[0].className = "icon ion-ios-moon";
document.body.className = 'light-theme'; document.body.className = "light-theme";
} else { } else {
document.body.className = 'no-theme'; document.body.className = "no-theme";
} }
} }
// Handles theme change event caused by other tab // Handles theme change event caused by other tab
addEventListener('storage', function (e) { addEventListener("storage", function (e) {
if (e.key === STORAGE_KEY_THEME) if (e.key === STORAGE_KEY_THEME)
setTheme(helpers.storage.get(STORAGE_KEY_THEME)); setTheme(helpers.storage.get(STORAGE_KEY_THEME));
}); });
// Set theme from preferences on page load // Set theme from preferences on page load
addEventListener('DOMContentLoaded', function () { addEventListener("DOMContentLoaded", function () {
const prefTheme = document.getElementById('dark_mode_pref').textContent; const prefTheme = document.getElementById("dark_mode_pref").textContent;
if (prefTheme) { if (prefTheme) {
setTheme(prefTheme); setTheme(prefTheme);
helpers.storage.set(STORAGE_KEY_THEME, prefTheme); helpers.storage.set(STORAGE_KEY_THEME, prefTheme);

File diff suppressed because one or more lines are too long

View File

@ -1,77 +1,90 @@
'use strict'; "use strict";
function toggle_parent(target) { function toggle_parent(target) {
var body = target.parentNode.parentNode.children[1]; var body = target.parentNode.parentNode.children[1];
if (body.style.display === 'none') { if (body.style.display === "none") {
target.textContent = '[ ]'; target.textContent = "[ ]";
body.style.display = ''; body.style.display = "";
} else { } else {
target.textContent = '[ + ]'; target.textContent = "[ + ]";
body.style.display = 'none'; body.style.display = "none";
} }
} }
function swap_comments(event) { function swap_comments(event) {
var source = event.target.getAttribute('data-comments'); var source = event.target.getAttribute("data-comments");
if (source === 'youtube') { if (source === "youtube") {
get_youtube_comments(); get_youtube_comments();
} else if (source === 'reddit') { } else if (source === "reddit") {
get_reddit_comments(); get_reddit_comments();
} }
} }
var continue_button = document.getElementById('continue'); var continue_button = document.getElementById("continue");
if (continue_button) { if (continue_button) {
continue_button.onclick = continue_autoplay; continue_button.onclick = continue_autoplay;
} }
function next_video() { function next_video() {
var url = new URL('https://example.com/watch?v=' + video_data.next_video); var url = new URL("https://example.com/watch?v=" + video_data.next_video);
if (video_data.params.autoplay || video_data.params.continue_autoplay) if (video_data.params.autoplay || video_data.params.continue_autoplay)
url.searchParams.set('autoplay', '1'); url.searchParams.set("autoplay", "1");
if (video_data.params.listen !== video_data.preferences.listen) if (video_data.params.listen !== video_data.preferences.listen)
url.searchParams.set('listen', video_data.params.listen); url.searchParams.set("listen", video_data.params.listen);
if (video_data.params.speed !== video_data.preferences.speed) if (video_data.params.speed !== video_data.preferences.speed)
url.searchParams.set('speed', video_data.params.speed); url.searchParams.set("speed", video_data.params.speed);
if (video_data.params.local !== video_data.preferences.local) if (video_data.params.local !== video_data.preferences.local)
url.searchParams.set('local', video_data.params.local); url.searchParams.set("local", video_data.params.local);
url.searchParams.set('continue', '1'); url.searchParams.set("continue", "1");
location.assign(url.pathname + url.search); location.assign(url.pathname + url.search);
} }
function continue_autoplay(event) { function continue_autoplay(event) {
if (event.target.checked) { if (event.target.checked) {
player.on('ended', next_video); player.on("ended", next_video);
} else { } else {
player.off('ended'); player.off("ended");
} }
} }
function get_playlist(plid) { function get_playlist(plid) {
var playlist = document.getElementById('playlist'); var playlist = document.getElementById("playlist");
playlist.innerHTML = spinnerHTMLwithHR; playlist.innerHTML = spinnerHTMLwithHR;
var plid_url; var plid_url;
if (plid.startsWith('RD')) { if (plid.startsWith("RD")) {
plid_url = '/api/v1/mixes/' + plid + plid_url =
'?continuation=' + video_data.id + "/api/v1/mixes/" +
'&format=html&hl=' + video_data.preferences.locale; plid +
"?continuation=" +
video_data.id +
"&format=html&hl=" +
video_data.preferences.locale;
} else { } else {
plid_url = '/api/v1/playlists/' + plid + plid_url =
'?index=' + video_data.index + "/api/v1/playlists/" +
'&continuation=' + video_data.id + plid +
'&format=html&hl=' + video_data.preferences.locale; "?index=" +
video_data.index +
"&continuation=" +
video_data.id +
"&format=html&hl=" +
video_data.preferences.locale;
} }
if (video_data.params.listen) { if (video_data.params.listen) {
plid_url += '&listen=1' plid_url += "&listen=1";
} }
helpers.xhr('GET', plid_url, {retries: 5, entity_name: 'playlist'}, { helpers.xhr(
"GET",
plid_url,
{ retries: 5, entity_name: "playlist" },
{
on200: function (response) { on200: function (response) {
if (response === null) return; if (response === null) return;
@ -82,52 +95,63 @@ function get_playlist(plid) {
var nextVideo = document.getElementById(response.nextVideo); var nextVideo = document.getElementById(response.nextVideo);
nextVideo.parentNode.parentNode.scrollTop = nextVideo.offsetTop; nextVideo.parentNode.parentNode.scrollTop = nextVideo.offsetTop;
player.on('ended', function () { player.on("ended", function () {
var url = new URL('https://example.com/watch?v=' + response.nextVideo); var url = new URL(
"https://example.com/watch?v=" + response.nextVideo,
);
url.searchParams.set('list', plid); url.searchParams.set("list", plid);
if (!plid.startsWith('RD')) if (!plid.startsWith("RD"))
url.searchParams.set('index', response.index); url.searchParams.set("index", response.index);
if (video_data.params.autoplay || video_data.params.continue_autoplay) if (video_data.params.autoplay || video_data.params.continue_autoplay)
url.searchParams.set('autoplay', '1'); url.searchParams.set("autoplay", "1");
if (video_data.params.listen !== video_data.preferences.listen) if (video_data.params.listen !== video_data.preferences.listen)
url.searchParams.set('listen', video_data.params.listen); url.searchParams.set("listen", video_data.params.listen);
if (video_data.params.speed !== video_data.preferences.speed) if (video_data.params.speed !== video_data.preferences.speed)
url.searchParams.set('speed', video_data.params.speed); url.searchParams.set("speed", video_data.params.speed);
if (video_data.params.local !== video_data.preferences.local) if (video_data.params.local !== video_data.preferences.local)
url.searchParams.set('local', video_data.params.local); url.searchParams.set("local", video_data.params.local);
location.assign(url.pathname + url.search); location.assign(url.pathname + url.search);
}); });
}, },
onNon200: function (xhr) { onNon200: function (xhr) {
playlist.innerHTML = ''; playlist.innerHTML = "";
document.getElementById('continue').style.display = ''; document.getElementById("continue").style.display = "";
}, },
onError: function (xhr) { onError: function (xhr) {
playlist.innerHTML = spinnerHTMLwithHR; playlist.innerHTML = spinnerHTMLwithHR;
}, },
onTimeout: function (xhr) { onTimeout: function (xhr) {
playlist.innerHTML = spinnerHTMLwithHR; playlist.innerHTML = spinnerHTMLwithHR;
} },
}); },
);
} }
function get_reddit_comments() { function get_reddit_comments() {
var comments = document.getElementById('comments'); var comments = document.getElementById("comments");
var fallback = comments.innerHTML; var fallback = comments.innerHTML;
comments.innerHTML = spinnerHTML; comments.innerHTML = spinnerHTML;
var url = '/api/v1/comments/' + video_data.id + var url =
'?source=reddit&format=html' + "/api/v1/comments/" +
'&hl=' + video_data.preferences.locale; video_data.id +
"?source=reddit&format=html" +
"&hl=" +
video_data.preferences.locale;
var onNon200 = function (xhr) { comments.innerHTML = fallback; }; var onNon200 = function (xhr) {
if (video_data.params.comments[1] === 'youtube') comments.innerHTML = fallback;
onNon200 = function (xhr) {}; };
if (video_data.params.comments[1] === "youtube") onNon200 = function (xhr) {};
helpers.xhr('GET', url, {retries: 5, entity_name: ''}, { helpers.xhr(
"GET",
url,
{ retries: 5, entity_name: "" },
{
on200: function (response) { on200: function (response) {
comments.innerHTML = ' \ comments.innerHTML = ' \
<div> \ <div> \
@ -152,48 +176,48 @@ function get_reddit_comments() {
youtubeCommentsText: video_data.youtube_comments_text, youtubeCommentsText: video_data.youtube_comments_text,
redditPermalinkText: video_data.reddit_permalink_text, redditPermalinkText: video_data.reddit_permalink_text,
permalink: response.permalink, permalink: response.permalink,
contentHtml: response.contentHtml contentHtml: response.contentHtml,
}); });
comments.children[0].children[0].children[0].onclick = toggle_comments; comments.children[0].children[0].children[0].onclick = toggle_comments;
comments.children[0].children[1].children[0].onclick = swap_comments; comments.children[0].children[1].children[0].onclick = swap_comments;
}, },
onNon200: onNon200, // declared above onNon200: onNon200, // declared above
}); },
);
} }
if (video_data.play_next) { if (video_data.play_next) {
player.on('ended', function () { player.on("ended", function () {
var url = new URL('https://example.com/watch?v=' + video_data.next_video); var url = new URL("https://example.com/watch?v=" + video_data.next_video);
if (video_data.params.autoplay || video_data.params.continue_autoplay) if (video_data.params.autoplay || video_data.params.continue_autoplay)
url.searchParams.set('autoplay', '1'); url.searchParams.set("autoplay", "1");
if (video_data.params.listen !== video_data.preferences.listen) if (video_data.params.listen !== video_data.preferences.listen)
url.searchParams.set('listen', video_data.params.listen); url.searchParams.set("listen", video_data.params.listen);
if (video_data.params.speed !== video_data.preferences.speed) if (video_data.params.speed !== video_data.preferences.speed)
url.searchParams.set('speed', video_data.params.speed); url.searchParams.set("speed", video_data.params.speed);
if (video_data.params.local !== video_data.preferences.local) if (video_data.params.local !== video_data.preferences.local)
url.searchParams.set('local', video_data.params.local); url.searchParams.set("local", video_data.params.local);
url.searchParams.set('continue', '1'); url.searchParams.set("continue", "1");
location.assign(url.pathname + url.search); location.assign(url.pathname + url.search);
}); });
} }
addEventListener('load', function (e) { addEventListener("load", function (e) {
if (video_data.plid) if (video_data.plid) get_playlist(video_data.plid);
get_playlist(video_data.plid);
if (video_data.params.comments[0] === 'youtube') { if (video_data.params.comments[0] === "youtube") {
get_youtube_comments(); get_youtube_comments();
} else if (video_data.params.comments[0] === 'reddit') { } else if (video_data.params.comments[0] === "reddit") {
get_reddit_comments(); get_reddit_comments();
} else if (video_data.params.comments[1] === 'youtube') { } else if (video_data.params.comments[1] === "youtube") {
get_youtube_comments(); get_youtube_comments();
} else if (video_data.params.comments[1] === 'reddit') { } else if (video_data.params.comments[1] === "reddit") {
get_reddit_comments(); get_reddit_comments();
} else { } else {
var comments = document.getElementById('comments'); var comments = document.getElementById("comments");
comments.innerHTML = ''; comments.innerHTML = "";
} }
}); });

View File

@ -1,11 +1,11 @@
'use strict'; "use strict";
var save_player_pos_key = 'save_player_pos'; var save_player_pos_key = "save_player_pos";
function get_all_video_times() { function get_all_video_times() {
return helpers.storage.get(save_player_pos_key) || {}; return helpers.storage.get(save_player_pos_key) || {};
} }
document.querySelectorAll('.watched-indicator').forEach(function (indicator) { document.querySelectorAll(".watched-indicator").forEach(function (indicator) {
var watched_part = get_all_video_times()[indicator.dataset.id]; var watched_part = get_all_video_times()[indicator.dataset.id];
var total = parseInt(indicator.dataset.length, 10); var total = parseInt(indicator.dataset.length, 10);
if (watched_part === undefined) { if (watched_part === undefined) {
@ -20,5 +20,5 @@ document.querySelectorAll('.watched-indicator').forEach(function (indicator) {
percentage = 100; percentage = 100;
} }
indicator.style.width = percentage + '%'; indicator.style.width = percentage + "%";
}); });

View File

@ -1,34 +1,50 @@
'use strict'; "use strict";
var watched_data = JSON.parse(document.getElementById('watched_data').textContent); var watched_data = JSON.parse(
var payload = 'csrf_token=' + watched_data.csrf_token; document.getElementById("watched_data").textContent,
);
var payload = "csrf_token=" + watched_data.csrf_token;
function mark_watched(target) { function mark_watched(target) {
var tile = target.parentNode.parentNode.parentNode.parentNode.parentNode; var tile = target.parentNode.parentNode.parentNode.parentNode.parentNode;
tile.style.display = 'none'; tile.style.display = "none";
var url = '/watch_ajax?action=mark_watched&redirect=false' + var url =
'&id=' + target.getAttribute('data-id'); "/watch_ajax?action=mark_watched&redirect=false" +
"&id=" +
target.getAttribute("data-id");
helpers.xhr('POST', url, {payload: payload}, { helpers.xhr(
"POST",
url,
{ payload: payload },
{
onNon200: function (xhr) { onNon200: function (xhr) {
tile.style.display = ''; tile.style.display = "";
} },
}); },
);
} }
function mark_unwatched(target) { function mark_unwatched(target) {
var tile = target.parentNode.parentNode.parentNode.parentNode.parentNode; var tile = target.parentNode.parentNode.parentNode.parentNode.parentNode;
tile.style.display = 'none'; tile.style.display = "none";
var count = document.getElementById('count'); var count = document.getElementById("count");
count.textContent--; count.textContent--;
var url = '/watch_ajax?action=mark_unwatched&redirect=false' + var url =
'&id=' + target.getAttribute('data-id'); "/watch_ajax?action=mark_unwatched&redirect=false" +
"&id=" +
target.getAttribute("data-id");
helpers.xhr('POST', url, {payload: payload}, { helpers.xhr(
"POST",
url,
{ payload: payload },
{
onNon200: function (xhr) { onNon200: function (xhr) {
count.textContent++; count.textContent++;
tile.style.display = ''; tile.style.display = "";
} },
}); },
);
} }

View File

@ -89,13 +89,6 @@ module Invidious::Frontend::Pagination
end end
def nav_ctoken(locale : String?, *, base_url : String | URI, ctoken : String?, first_page : Bool, params : URI::Params) def nav_ctoken(locale : String?, *, base_url : String | URI, ctoken : String?, first_page : Bool, params : URI::Params)
return String.build do |str|
if !ctoken.nil?
str << %(<nav class="pagination">\n<ul>\n)
str << %(<li>)
params_next = URI::Params{"continuation" => ctoken}
url_next = HttpServer::Utils.add_params_to_url(base_url, params_next)
return String.build do |str| return String.build do |str|
str << %(<nav class="pagination">\n<ul>\n) str << %(<nav class="pagination">\n<ul>\n)
str << %(<li>) str << %(<li>)
@ -106,6 +99,7 @@ module Invidious::Frontend::Pagination
if !ctoken.nil? if !ctoken.nil?
params["continuation"] = ctoken params["continuation"] = ctoken
url_next = HttpServer::Utils.add_params_to_url(base_url, params) url_next = HttpServer::Utils.add_params_to_url(base_url, params)
end
self.next_page(str, locale, url_next.to_s) self.next_page(str, locale, url_next.to_s)
@ -115,4 +109,3 @@ module Invidious::Frontend::Pagination
end end
end end
end end
end