Minor formatting changes

pull/530/head
Omar Roth 6 years ago
parent 22b9bbe702
commit 1a9360ca75
No known key found for this signature in database
GPG Key ID: B8254FB7EC3D37F2

@ -28,8 +28,8 @@ function swap_comments(source) {
} }
} }
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;
}); });

@ -309,7 +309,7 @@ def template_youtube_comments(comments, locale, thin_mode)
html += <<-END_HTML html += <<-END_HTML
<div class="pure-g"> <div class="pure-g">
<div class="pure-u-4-24 pure-u-md-2-24"> <div class="pure-u-4-24 pure-u-md-2-24">
<img style="width:90%; padding-right:1em; padding-top:1em;" src="#{author_thumbnail}"> <img style="width:90%;padding-right:1em;padding-top:1em" src="#{author_thumbnail}">
</div> </div>
<div class="pure-u-20-24 pure-u-md-22-24"> <div class="pure-u-20-24 pure-u-md-22-24">
<p> <p>

@ -105,7 +105,7 @@ def template_mix(mix)
</div> </div>
<p style="width:100%">#{video["title"]}</p> <p style="width:100%">#{video["title"]}</p>
<p> <p>
<b style="width: 100%">#{video["author"]}</b> <b style="width:100%">#{video["author"]}</b>
</p> </p>
</a> </a>
</li> </li>

@ -248,7 +248,7 @@ def template_playlist(playlist)
</div> </div>
<p style="width:100%">#{video["title"]}</p> <p style="width:100%">#{video["title"]}</p>
<p> <p>
<b style="width: 100%">#{video["author"]}</b> <b style="width:100%">#{video["author"]}</b>
</p> </p>
</a> </a>
</li> </li>

@ -3,7 +3,7 @@
<% end %> <% end %>
<% if env.get? "access_token" %> <% if env.get? "access_token" %>
<div class="pure-g h-box"> <div class="pure-g h-box">
<div class="pure-u-1-3"> <div class="pure-u-1-3">
<h3> <h3>
<%= translate(locale, "Token") %> <%= translate(locale, "Token") %>
@ -19,15 +19,15 @@
<a href="/preferences"><%= translate(locale, "Preferences") %></a> <a href="/preferences"><%= translate(locale, "Preferences") %></a>
</h3> </h3>
</div> </div>
</div> </div>
<div class="h-box"> <div class="h-box">
<h4 style="padding-left:0.5em"> <h4 style="padding-left:0.5em">
<code><%= env.get "access_token" %></code> <code><%= env.get "access_token" %></code>
</h4> </h4>
</div> </div>
<% else %> <% else %>
<div class="h-box"> <div class="h-box">
<form class="pure-form pure-form-aligned" action="/authorize_token" method="post"> <form class="pure-form pure-form-aligned" action="/authorize_token" method="post">
<% if callback_url %> <% if callback_url %>
<legend><%= translate(locale, "Authorize token for `x`?", "#{callback_url.scheme}://#{callback_url.host}") %></legend> <legend><%= translate(locale, "Authorize token for `x`?", "#{callback_url.scheme}://#{callback_url.host}") %></legend>
@ -74,5 +74,5 @@
<input type="hidden" name="csrf_token" value="<%= URI.escape(csrf_token) %>"> <input type="hidden" name="csrf_token" value="<%= URI.escape(csrf_token) %>">
</form> </form>
</div> </div>
<% end %> <% end %>

@ -7,7 +7,7 @@
<div class="pure-u-2-3"> <div class="pure-u-2-3">
<h3><%= author %></h3> <h3><%= author %></h3>
</div> </div>
<div class="pure-u-1-3" style="text-align:right;"> <div class="pure-u-1-3" style="text-align:right">
<h3> <h3>
<a href="/feed/channel/<%= ucid %>"><i class="icon ion-logo-rss"></i></a> <a href="/feed/channel/<%= ucid %>"><i class="icon ion-logo-rss"></i></a>
</h3> </h3>
@ -15,8 +15,8 @@
</div> </div>
<div class="h-box"> <div class="h-box">
<% sub_count_text = number_to_short_text(sub_count) %> <% sub_count_text = number_to_short_text(sub_count) %>
<%= rendered "components/subscribe_widget" %> <%= rendered "components/subscribe_widget" %>
</div> </div>
<div class="pure-g h-box"> <div class="pure-g h-box">
@ -35,10 +35,9 @@
<% end %> <% end %>
</div> </div>
</div> </div>
<div class="pure-u-1-3"></div>
<div class="pure-u-1-3"> <div class="pure-u-1-3">
</div> <div class="pure-g" style="text-align:right">
<div class="pure-u-1-3">
<div class="pure-g" style="text-align:right;">
<% sort_options.each do |sort| %> <% sort_options.each do |sort| %>
<div class="pure-u-1 pure-md-1-3"> <div class="pure-u-1 pure-md-1-3">
<% if sort_by == sort %> <% if sort_by == sort %>
@ -59,11 +58,11 @@
</div> </div>
<div class="pure-g"> <div class="pure-g">
<% items.each_slice(4) do |slice| %> <% items.each_slice(4) do |slice| %>
<% slice.each do |item| %> <% slice.each do |item| %>
<%= rendered "components/item" %> <%= rendered "components/item" %>
<% end %> <% end %>
<% end %> <% end %>
</div> </div>
<div class="pure-g h-box"> <div class="pure-g h-box">
@ -75,7 +74,7 @@
<% end %> <% end %>
</div> </div>
<div class="pure-u-1 pure-u-lg-3-5"></div> <div class="pure-u-1 pure-u-lg-3-5"></div>
<div style="text-align:right" class="pure-u-1 pure-u-lg-1-5"> <div class="pure-u-1 pure-u-lg-1-5" style="text-align:right">
<% if count == 60 %> <% if count == 60 %>
<a href="/channel/<%= ucid %>?page=<%= page + 1 %><% if sort_by != "newest" %>&sort_by=<%= sort_by %><% end %>"> <a href="/channel/<%= ucid %>?page=<%= page + 1 %><% if sort_by != "newest" %>&sort_by=<%= sort_by %><% end %>">
<%= translate(locale, "Next page") %> <%= translate(locale, "Next page") %>

@ -8,7 +8,7 @@
<% end %> <% end %>
<% feed_menu.each do |feed| %> <% feed_menu.each do |feed| %>
<div class="pure-u-1-2 pure-u-md-1-<%= feed_menu.size %>"> <div class="pure-u-1-2 pure-u-md-1-<%= feed_menu.size %>">
<a href="/feed/<%= feed.downcase %>" style="text-align:center;" class="pure-menu-heading"> <a href="/feed/<%= feed.downcase %>" class="pure-menu-heading" style="text-align:center">
<%= translate(locale, feed) %> <%= translate(locale, feed) %>
</a> </a>
</div> </div>

@ -2,11 +2,10 @@
<div class="h-box"> <div class="h-box">
<% case item when %> <% case item when %>
<% when SearchChannel %> <% when SearchChannel %>
<a style="width:100%;" href="/channel/<%= item.ucid %>"> <a style="width:100%" href="/channel/<%= item.ucid %>">
<% if env.get("preferences").as(Preferences).thin_mode %> <% if !env.get("preferences").as(Preferences).thin_mode %>
<% else %>
<center> <center>
<img style="width:56.25%;" src="/ggpht<%= URI.parse(item.author_thumbnail).full_path %>"/> <img style="width:56.25%" src="/ggpht<%= URI.parse(item.author_thumbnail).full_path %>"/>
</center> </center>
<% end %> <% end %>
<p><%= item.author %></p> <p><%= item.author %></p>
@ -20,9 +19,9 @@
<% else %> <% else %>
<% url = "/playlist?list=#{item.id}" %> <% url = "/playlist?list=#{item.id}" %>
<% end %> <% end %>
<a style="width:100%;" href="<%= url %>">
<% if env.get("preferences").as(Preferences).thin_mode %> <a style="width:100%" href="<%= url %>">
<% else %> <% if !env.get("preferences").as(Preferences).thin_mode %>
<div class="thumbnail"> <div class="thumbnail">
<img class="thumbnail" src="/vi/<%= item.thumbnail_id %>/mqdefault.jpg"/> <img class="thumbnail" src="/vi/<%= item.thumbnail_id %>/mqdefault.jpg"/>
<p class="length"><%= number_with_separator(item.video_count) %> videos</p> <p class="length"><%= number_with_separator(item.video_count) %> videos</p>
@ -31,12 +30,13 @@
<p><%= item.title %></p> <p><%= item.title %></p>
</a> </a>
<p> <p>
<b><a style="width:100%;" href="/channel/<%= item.ucid %>"><%= item.author %></a></b> <b>
<a style="width:100%" href="/channel/<%= item.ucid %>"><%= item.author %></a>
</b>
</p> </p>
<% when MixVideo %> <% when MixVideo %>
<a style="width:100%;" href="/watch?v=<%= item.id %>&list=<%= item.mixes[0] %>"> <a style="width:100%" href="/watch?v=<%= item.id %>&list=<%= item.mixes[0] %>">
<% if env.get("preferences").as(Preferences).thin_mode %> <% if !env.get("preferences").as(Preferences).thin_mode %>
<% else %>
<div class="thumbnail"> <div class="thumbnail">
<img class="thumbnail" src="/vi/<%= item.id %>/mqdefault.jpg"/> <img class="thumbnail" src="/vi/<%= item.id %>/mqdefault.jpg"/>
<% if item.length_seconds != 0 %> <% if item.length_seconds != 0 %>
@ -47,12 +47,13 @@
<p><%= item.title %></p> <p><%= item.title %></p>
</a> </a>
<p> <p>
<b><a style="width:100%;" href="/channel/<%= item.ucid %>"><%= item.author %></a></b> <b>
<a style="width:100%" href="/channel/<%= item.ucid %>"><%= item.author %></a>
</b>
</p> </p>
<% when PlaylistVideo %> <% when PlaylistVideo %>
<a style="width:100%;" href="/watch?v=<%= item.id %>&list=<%= item.playlists[0] %>"> <a style="width:100%" href="/watch?v=<%= item.id %>&list=<%= item.playlists[0] %>">
<% if env.get("preferences").as(Preferences).thin_mode %> <% if !env.get("preferences").as(Preferences).thin_mode %>
<% else %>
<div class="thumbnail"> <div class="thumbnail">
<img class="thumbnail" src="/vi/<%= item.id %>/mqdefault.jpg"/> <img class="thumbnail" src="/vi/<%= item.id %>/mqdefault.jpg"/>
<% if item.responds_to?(:live_now) && item.live_now %> <% if item.responds_to?(:live_now) && item.live_now %>
@ -65,7 +66,9 @@
<p><%= item.title %></p> <p><%= item.title %></p>
</a> </a>
<p> <p>
<b><a style="width:100%;" href="/channel/<%= item.ucid %>"><%= item.author %></a></b> <b>
<a style="width:100%" href="/channel/<%= item.ucid %>"><%= item.author %></a>
</b>
</p> </p>
<h5 class="pure-g"> <h5 class="pure-g">
@ -77,18 +80,17 @@
<div class="pure-u-2-3"></div> <div class="pure-u-2-3"></div>
<% end %> <% end %>
<div class="pure-u-1-3" style="text-align: right"> <div class="pure-u-1-3" style="text-align:right">
<%= item.responds_to?(:views) ? translate(locale, "`x` views", number_to_short_text(item.views)) : "" %> <%= item.responds_to?(:views) ? translate(locale, "`x` views", number_to_short_text(item.views)) : "" %>
</div> </div>
</h5> </h5>
<% else %> <% else %>
<% if env.get("preferences").as(Preferences).thin_mode %> <% if !env.get("preferences").as(Preferences).thin_mode %>
<% else %> <a style="width:100%" href="/watch?v=<%= item.id %>">
<a style="width:100%;" href="/watch?v=<%= item.id %>">
<div class="thumbnail"> <div class="thumbnail">
<img class="thumbnail" src="/vi/<%= item.id %>/mqdefault.jpg"/> <img class="thumbnail" src="/vi/<%= item.id %>/mqdefault.jpg"/>
<% if env.get? "show_watched" %> <% if env.get? "show_watched" %>
<form onsubmit="return false;" action="/watch_ajax?action_mark_watched=1&id=<%= item.id %>&referer=<%= env.get("current_page") %>" method="post"> <form onsubmit="return false" action="/watch_ajax?action_mark_watched=1&id=<%= item.id %>&referer=<%= env.get("current_page") %>" method="post">
<input type="hidden" name="csrf_token" value="<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>"> <input type="hidden" name="csrf_token" value="<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>">
<p class="watched"> <p class="watched">
<a onclick="mark_watched(this)" data-id="<%= item.id %>" href="#"> <a onclick="mark_watched(this)" data-id="<%= item.id %>" href="#">
@ -102,6 +104,7 @@
</p> </p>
</form> </form>
<% end %> <% end %>
<% if item.responds_to?(:live_now) && item.live_now %> <% if item.responds_to?(:live_now) && item.live_now %>
<p class="length"><i class="icon ion-ios-play-circle"></i> <%= translate(locale, "LIVE") %></p> <p class="length"><i class="icon ion-ios-play-circle"></i> <%= translate(locale, "LIVE") %></p>
<% elsif item.length_seconds != 0 %> <% elsif item.length_seconds != 0 %>
@ -112,7 +115,9 @@
<% end %> <% end %>
<p><a href="/watch?v=<%= item.id %>"><%= item.title %></a></p> <p><a href="/watch?v=<%= item.id %>"><%= item.title %></a></p>
<p> <p>
<b><a style="width:100%;" href="/channel/<%= item.ucid %>"><%= item.author %></a></b> <b>
<a style="width:100%" href="/channel/<%= item.ucid %>"><%= item.author %></a>
</b>
</p> </p>
<h5 class="pure-g"> <h5 class="pure-g">
@ -124,7 +129,7 @@
<div class="pure-u-2-3"></div> <div class="pure-u-2-3"></div>
<% end %> <% end %>
<div class="pure-u-1-3" style="text-align: right"> <div class="pure-u-1-3" style="text-align:right">
<%= item.responds_to?(:views) ? translate(locale, "`x` views", number_to_short_text(item.views)) : "" %> <%= item.responds_to?(:views) ? translate(locale, "`x` views", number_to_short_text(item.views)) : "" %>
</div> </div>
</h5> </h5>

@ -94,7 +94,7 @@ var player = videojs("player", options, function() {
} }
} }
}, },
// Go backward 5 seconds // Go backward 10 seconds
backward: { backward: {
key: function(e) { key: function(e) {
return e.which === 74; return e.which === 74;
@ -103,7 +103,7 @@ var player = videojs("player", options, function() {
player.currentTime(player.currentTime() - 10); player.currentTime(player.currentTime() - 10);
} }
}, },
// Go forward 5 seconds // Go forward 10 seconds
forward: { forward: {
key: function(e) { key: function(e) {
return e.which === 76; return e.which === 76;
@ -141,16 +141,18 @@ var player = videojs("player", options, function() {
player.on('error', function(event) { player.on('error', function(event) {
if (player.error().code === 2 || player.error().code === 4) { if (player.error().code === 2 || player.error().code === 4) {
setInterval(setTimeout(function (event) { setInterval(setTimeout(function (event) {
console.log("An error occured in the player, reloading..."); console.log('An error occured in the player, reloading...');
var currentTime = player.currentTime(); var currentTime = player.currentTime();
var playbackRate = player.playbackRate(); var playbackRate = player.playbackRate();
var paused = player.paused(); var paused = player.paused();
player.load(); player.load();
if (currentTime > 0.5) { if (currentTime > 0.5) {
currentTime -= 0.5; currentTime -= 0.5;
} }
player.currentTime(currentTime); player.currentTime(currentTime);
player.playbackRate(playbackRate); player.playbackRate(playbackRate);
@ -164,20 +166,20 @@ player.on('error', function(event) {
<% if params.video_start > 0 || params.video_end > 0 %> <% if params.video_start > 0 || params.video_end > 0 %>
player.markers({ player.markers({
onMarkerReached: function(marker) { onMarkerReached: function(marker) {
if (marker.text === "End") { if (marker.text === 'End') {
if (player.loop()) { if (player.loop()) {
player.markers.prev("Start"); player.markers.prev('Start');
} else { } else {
player.pause(); player.pause();
} }
} }
}, },
markers: [ markers: [
{ time: <%= params.video_start %>, text: "Start" }, { time: <%= params.video_start %>, text: 'Start' },
<% if params.video_end < 0 %> <% if params.video_end < 0 %>
{ time: <%= video.info["length_seconds"].to_f - 0.5 %>, text: "End" } { time: <%= video.info["length_seconds"].to_f - 0.5 %>, text: 'End' }
<% else %> <% else %>
{ time: <%= params.video_end %>, text: "End" } { time: <%= params.video_end %>, text: 'End' }
<% end %> <% end %>
] ]
}); });
@ -216,17 +218,17 @@ player.httpSourceSelector();
<% end %> <% end %>
<% if !params.listen && params.annotations %> <% if !params.listen && params.annotations %>
var video_container = document.getElementById("player"); var video_container = document.getElementById('player');
let xhr = new XMLHttpRequest(); let xhr = new XMLHttpRequest();
xhr.responseType = "text"; xhr.responseType = 'text';
xhr.timeout = 60000; xhr.timeout = 60000;
xhr.open("GET", "/api/v1/annotations/<%= video.id %>", true); xhr.open('GET', '/api/v1/annotations/<%= video.id %>', true);
xhr.send(); xhr.send();
xhr.onreadystatechange = function () { xhr.onreadystatechange = function () {
if (xhr.readyState === 4) { if (xhr.readyState === 4) {
if (xhr.status === 200) { if (xhr.status === 200) {
videojs.registerPlugin("youtubeAnnotationsPlugin", youtubeAnnotationsPlugin); videojs.registerPlugin('youtubeAnnotationsPlugin', youtubeAnnotationsPlugin);
if (!player.paused()) { if (!player.paused()) {
player.youtubeAnnotationsPlugin({annotationXml: xhr.response, videoContainer: video_container}); player.youtubeAnnotationsPlugin({annotationXml: xhr.response, videoContainer: video_container});
} else { } else {
@ -238,22 +240,20 @@ xhr.onreadystatechange = function () {
} }
}; };
window.addEventListener("__ar_annotation_click", e => { window.addEventListener('__ar_annotation_click', e => {
const { url, target, seconds } = e.detail; const { url, target, seconds } = e.detail;
var path = new URL(url); var path = new URL(url);
if (path.href.startsWith("https://www.youtube.com/watch?") && seconds) { if (path.href.startsWith('https://www.youtube.com/watch?') && seconds) {
path.search += "&t=" + seconds; path.search += '&t=' + seconds;
} }
path = path.pathname + path.search; path = path.pathname + path.search;
if (target === "current") { if (target === 'current') {
window.location.href = path; window.location.href = path;
} } else if (target === 'new') {
else if (target === "new") { window.open(path, '_blank');
window.open(path, "_blank");
} }
}); });
<% end %> <% end %>

@ -8,11 +8,13 @@
<script src="/js/videojs.hotkeys.min.js"></script> <script src="/js/videojs.hotkeys.min.js"></script>
<script src="/js/videojs-markers.min.js"></script> <script src="/js/videojs-markers.min.js"></script>
<script src="/js/videojs-share.min.js"></script> <script src="/js/videojs-share.min.js"></script>
<% if params.annotations %> <% if params.annotations %>
<link rel="stylesheet" href="/css/videojs-youtube-annotations.min.css"> <link rel="stylesheet" href="/css/videojs-youtube-annotations.min.css">
<script src="/js/videojs-youtube-annotations.min.js"></script> <script src="/js/videojs-youtube-annotations.min.js"></script>
<% end %> <% end %>
<% if params.listen || params.quality != "dash" %> <% if params.listen || params.quality != "dash" %>
<link rel="stylesheet" href="/css/quality-selector.css"> <link rel="stylesheet" href="/css/quality-selector.css">
<script src="/js/silvermine-videojs-quality-selector.min.js"></script> <script src="/js/silvermine-videojs-quality-selector.min.js"></script>
<% end %> <% end %>

@ -1,7 +1,7 @@
<% if user %> <% if user %>
<% if subscriptions.includes? ucid %> <% if subscriptions.includes? ucid %>
<p> <p>
<form onsubmit="return false;" action="/subscription_ajax?action_remove_subscriptions=1&c=<%= ucid %>&referer=<%= env.get("current_page") %>" method="post"> <form onsubmit="return false" action="/subscription_ajax?action_remove_subscriptions=1&c=<%= ucid %>&referer=<%= env.get("current_page") %>" method="post">
<input type="hidden" name="csrf_token" value="<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>"> <input type="hidden" name="csrf_token" value="<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>">
<a id="subscribe" onclick="unsubscribe()" class="pure-button pure-button-primary" href="#"> <a id="subscribe" onclick="unsubscribe()" class="pure-button pure-button-primary" href="#">
<b><input style="all:unset" type="submit" value="<%= translate(locale, "Unsubscribe") %> | <%= sub_count_text %>"></b> <b><input style="all:unset" type="submit" value="<%= translate(locale, "Unsubscribe") %> | <%= sub_count_text %>"></b>
@ -10,7 +10,7 @@
</p> </p>
<% else %> <% else %>
<p> <p>
<form onsubmit="return false;" action="/subscription_ajax?action_create_subscription_to_channel=1&c=<%= ucid %>&referer=<%= env.get("current_page") %>" method="post"> <form onsubmit="return false" action="/subscription_ajax?action_create_subscription_to_channel=1&c=<%= ucid %>&referer=<%= env.get("current_page") %>" method="post">
<input type="hidden" name="csrf_token" value="<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>"> <input type="hidden" name="csrf_token" value="<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>">
<a id="subscribe" onclick="subscribe()" class="pure-button pure-button-primary" href="#"> <a id="subscribe" onclick="subscribe()" class="pure-button pure-button-primary" href="#">
<b><input style="all:unset" type="submit" value="<%= translate(locale, "Subscribe") %> | <%= sub_count_text %>"></b> <b><input style="all:unset" type="submit" value="<%= translate(locale, "Subscribe") %> | <%= sub_count_text %>"></b>

@ -1,27 +1,29 @@
subscribe_button = document.getElementById("subscribe"); subscribe_button = document.getElementById('subscribe');
if (subscribe_button.getAttribute('onclick')) { if (subscribe_button.getAttribute('onclick')) {
subscribe_button["href"] = "javascript:void(0)"; subscribe_button['href'] = 'javascript:void(0)';
} }
function subscribe(timeouts = 0) { function subscribe(timeouts = 0) {
subscribe_button = document.getElementById("subscribe"); subscribe_button = document.getElementById('subscribe');
if (timeouts > 10) { if (timeouts > 10) {
console.log("Failed to subscribe."); console.log('Failed to subscribe.');
return; return;
} }
var url = "/subscription_ajax?action_create_subscription_to_channel=1&redirect=false&c=<%= ucid %>&referer=<%= env.get("current_page") %>"; var url = '/subscription_ajax?action_create_subscription_to_channel=1&redirect=false' +
'&c=<%= ucid %>&referer=<%= env.get("current_page") %>';
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.responseType = "json"; xhr.responseType = 'json';
xhr.timeout = 20000; xhr.timeout = 20000;
xhr.open("POST", url, true); xhr.open('POST', url, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send("csrf_token=<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>"); xhr.send('csrf_token=<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>');
var fallback = subscribe_button.innerHTML; var fallback = subscribe_button.innerHTML;
subscribe_button.onclick = unsubscribe; subscribe_button.onclick = unsubscribe;
subscribe_button.innerHTML = '<b><%= translate(locale, "Unsubscribe").gsub("'", "\\'") %> | <%= sub_count_text %></b>' subscribe_button.innerHTML = '<b><%= translate(locale, "Unsubscribe").gsub("'", "\\'") %> | <%= sub_count_text %></b>';
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
if (xhr.readyState == 4) { if (xhr.readyState == 4) {
@ -33,31 +35,31 @@ function subscribe(timeouts = 0) {
} }
xhr.ontimeout = function() { xhr.ontimeout = function() {
console.log("Subscribing timed out."); console.log('Subscribing timed out.');
subscribe(timeouts + 1); subscribe(timeouts + 1);
}; };
} }
function unsubscribe(timeouts = 0) { function unsubscribe(timeouts = 0) {
subscribe_button = document.getElementById("subscribe"); subscribe_button = document.getElementById('subscribe');
if (timeouts > 10) { if (timeouts > 10) {
console.log("Failed to subscribe"); console.log('Failed to subscribe');
return; return;
} }
var url = "/subscription_ajax?action_remove_subscriptions=1&redirect=false&c=<%= ucid %>&referer=<%= env.get("current_page") %>"; var url = '/subscription_ajax?action_remove_subscriptions=1&redirect=false' +
'&c=<%= ucid %>&referer=<%= env.get("current_page") %>';
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.responseType = "json"; xhr.responseType = 'json';
xhr.timeout = 20000; xhr.timeout = 20000;
xhr.open("POST", url, true); xhr.open('POST', url, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send("csrf_token=<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>"); xhr.send('csrf_token=<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>');
var fallback = subscribe_button.innerHTML; var fallback = subscribe_button.innerHTML;
subscribe_button.onclick = subscribe; subscribe_button.onclick = subscribe;
subscribe_button.innerHTML = '<b><%= translate(locale, "Subscribe").gsub("'", "\\'") %> | <%= sub_count_text %></b>' subscribe_button.innerHTML = '<b><%= translate(locale, "Subscribe").gsub("'", "\\'") %> | <%= sub_count_text %></b>';
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
if (xhr.readyState == 4) { if (xhr.readyState == 4) {
@ -69,8 +71,7 @@ function unsubscribe(timeouts = 0) {
} }
xhr.ontimeout = function() { xhr.ontimeout = function() {
console.log("Unsubscribing timed out."); console.log('Unsubscribing timed out.');
unsubscribe(timeouts + 1); unsubscribe(timeouts + 1);
}; };
} }

@ -27,24 +27,26 @@
<script> <script>
<% if plid %> <% if plid %>
function get_playlist(timeouts = 0) { function get_playlist(plid, timeouts = 0) {
if (timeouts > 10) { if (timeouts > 10) {
console.log("Failed to pull playlist"); console.log('Failed to pull playlist');
return; return;
} }
var plid = "<%= plid %>" if (plid.startsWith('RD')) {
var plid_url = '/api/v1/mixes/' + plid +
if (plid.startsWith("RD")) { '?continuation=<%= video.id %>' +
var plid_url = "/api/v1/mixes/<%= plid %>?continuation=<%= video.id %>&format=html&hl=<%= env.get("preferences").as(Preferences).locale %>"; '&format=html&hl=<%= env.get("preferences").as(Preferences).locale %>';
} else { } else {
var plid_url = "/api/v1/playlists/<%= plid %>?continuation=<%= video.id %>&format=html&hl=<%= env.get("preferences").as(Preferences).locale %>"; var plid_url = '/api/v1/playlists/' + plid +
'?continuation=<%= video.id %>' +
'&format=html&hl=<%= env.get("preferences").as(Preferences).locale %>';
} }
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.responseType = "json"; xhr.responseType = 'json';
xhr.timeout = 20000; xhr.timeout = 20000;
xhr.open("GET", plid_url, true); xhr.open('GET', plid_url, true);
xhr.send(); xhr.send();
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
@ -52,18 +54,18 @@ function get_playlist(timeouts = 0) {
if (xhr.status == 200) { if (xhr.status == 200) {
if (xhr.response.nextVideo) { if (xhr.response.nextVideo) {
player.on('ended', function() { player.on('ended', function() {
location.assign("/embed/" location.assign('/watch?v=' + xhr.response.nextVideo +
+ xhr.response.nextVideo '&list=' + plid +
+ "?list=<%= plid %>"
<% if params.listen != preferences.listen %> <% if params.listen != preferences.listen %>
+ "&listen=<%= params.listen %>" '&listen=<%= params.listen %>' +
<% end %> <% end %>
<% if params.autoplay || params.continue_autoplay %> <% if params.autoplay || params.continue_autoplay %>
+ "&autoplay=1" '&autoplay=1' +
<% end %> <% end %>
<% if params.speed != preferences.speed %> <% if params.speed != preferences.speed %>
+ "&speed=<%= params.speed %>" '&speed=<%= params.speed %>' +
<% end %> <% end %>
''
); );
}); });
} }
@ -72,28 +74,28 @@ function get_playlist(timeouts = 0) {
}; };
xhr.ontimeout = function() { xhr.ontimeout = function() {
console.log("Pulling playlist timed out."); console.log('Pulling playlist timed out.');
get_playlist(timeouts + 1); get_playlist(plid, timeouts + 1);
}; };
} }
get_playlist(); get_playlist('<%= plid %>');
<% elsif video_series %> <% elsif video_series %>
player.on('ended', function() { player.on('ended', function() {
location.assign("/embed/" location.assign('/embed/<%= video_series.shift %>' +
+ "<%= video_series.shift %>"
<% if !video_series.empty? %> <% if !video_series.empty? %>
+ "?playlist=<%= video_series.join(",") %>" '?playlist=<%= video_series.join(",") %>' +
<% end %> <% end %>
<% if params.listen != preferences.listen %> <% if params.listen != preferences.listen %>
+ "&listen=<%= params.listen %>" '&listen=<%= params.listen %>' +
<% end %> <% end %>
<% if params.autoplay || params.continue_autoplay %> <% if params.autoplay || params.continue_autoplay %>
+ "&autoplay=1" '&autoplay=1' +
<% end %> <% end %>
<% if params.speed != preferences.speed %> <% if params.speed != preferences.speed %>
+ "&speed=<%= params.speed %>" '&speed=<%= params.speed %>' +
<% end %> <% end %>
''
); );
}); });
<% end %> <% end %>

@ -3,5 +3,5 @@
<% end %> <% end %>
<div class="h-box"> <div class="h-box">
<%= error_message %> <%= error_message %>
</div> </div>

@ -6,12 +6,12 @@
<div class="pure-u-1-3"> <div class="pure-u-1-3">
<h3><%= translate(locale, "`x` videos", %(<span id="count">#{user.watched.size}</span>)) %></h3> <h3><%= translate(locale, "`x` videos", %(<span id="count">#{user.watched.size}</span>)) %></h3>
</div> </div>
<div class="pure-u-1-3" style="text-align:center;"> <div class="pure-u-1-3" style="text-align:center">
<h3> <h3>
<a href="/feed/subscriptions"><%= translate(locale, "`x` subscriptions", %(<span id="count">#{user.subscriptions.size}</span>)) %></a> <a href="/feed/subscriptions"><%= translate(locale, "`x` subscriptions", %(<span id="count">#{user.subscriptions.size}</span>)) %></a>
</h3> </h3>
</div> </div>
<div class="pure-u-1-3" style="text-align:right;"> <div class="pure-u-1-3" style="text-align:right">
<h3> <h3>
<a href="/clear_watch_history"><%= translate(locale, "Clear watch history") %></a> <a href="/clear_watch_history"><%= translate(locale, "Clear watch history") %></a>
</h3> </h3>
@ -23,9 +23,8 @@
<% slice.each do |item| %> <% slice.each do |item| %>
<div class="pure-u-1 pure-u-md-1-4"> <div class="pure-u-1 pure-u-md-1-4">
<div class="h-box"> <div class="h-box">
<a style="width:100%;" href="/watch?v=<%= item %>"> <a style="width:100%" href="/watch?v=<%= item %>">
<% if env.get("preferences").as(Preferences).thin_mode %> <% if !env.get("preferences").as(Preferences).thin_mode %>
<% else %>
<div class="thumbnail"> <div class="thumbnail">
<img class="thumbnail" src="/vi/<%= item %>/mqdefault.jpg"/> <img class="thumbnail" src="/vi/<%= item %>/mqdefault.jpg"/>
<form onsubmit="return false;" action="/watch_ajax?action_mark_unwatched=1&id=<%= item %>&referer=<%= env.get("current_page") %>" method="post"> <form onsubmit="return false;" action="/watch_ajax?action_mark_unwatched=1&id=<%= item %>&referer=<%= env.get("current_page") %>" method="post">
@ -52,22 +51,23 @@
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.innerText = count.innerText - 1; count.innerText = count.innerText - 1;
var url = "/watch_ajax?action_mark_unwatched=1&redirect=false&id=" + target.getAttribute("data-id"); var url = '/watch_ajax?action_mark_unwatched=1&redirect=false' +
'&id=' + target.getAttribute('data-id');
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.responseType = "json"; xhr.responseType = 'json';
xhr.timeout = 20000; xhr.timeout = 20000;
xhr.open("POST", url, true); xhr.open('POST', url, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send("csrf_token=<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>"); xhr.send('csrf_token=<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>');
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
if (xhr.readyState == 4) { if (xhr.readyState == 4) {
if (xhr.status != 200) { if (xhr.status != 200) {
count.innerText = count.innerText - 1 + 2; count.innerText = count.innerText - 1 + 2;
tile.style.display = ""; tile.style.display = '';
} }
} }
} }
@ -83,7 +83,7 @@ function mark_unwatched(target) {
<% end %> <% end %>
</div> </div>
<div class="pure-u-1 pure-u-lg-3-5"></div> <div class="pure-u-1 pure-u-lg-3-5"></div>
<div style="text-align:right;" class="pure-u-1 pure-u-lg-1-5"> <div class="pure-u-1 pure-u-lg-1-5" style="text-align:right">
<% if watched.size >= limit %> <% if watched.size >= limit %>
<a href="/feed/history?page=<%= page + 1 %>"> <a href="/feed/history?page=<%= page + 1 %>">
<%= translate(locale, "Next page") %> <%= translate(locale, "Next page") %>

@ -18,7 +18,9 @@
</a> </a>
</div> </div>
</div> </div>
<hr> <hr>
<% if account_type == "invidious" %> <% if account_type == "invidious" %>
<form class="pure-form pure-form-stacked" action="/login?referer=<%= URI.escape(referer) %>&type=invidious" method="post"> <form class="pure-form pure-form-stacked" action="/login?referer=<%= URI.escape(referer) %>&type=invidious" method="post">
<fieldset> <fieldset>

@ -6,7 +6,7 @@
<div class="pure-u-2-3"> <div class="pure-u-2-3">
<h3><%= mix.title %></h3> <h3><%= mix.title %></h3>
</div> </div>
<div class="pure-u-1-3" style="text-align:right;"> <div class="pure-u-1-3" style="text-align:right">
<h3> <h3>
<a href="/feed/playlist/<%= mix.id %>"><i class="icon ion-logo-rss"></i></a> <a href="/feed/playlist/<%= mix.id %>"><i class="icon ion-logo-rss"></i></a>
</h3> </h3>
@ -14,9 +14,9 @@
</div> </div>
<div class="pure-g"> <div class="pure-g">
<% mix.videos.each_slice(4) do |slice| %> <% mix.videos.each_slice(4) do |slice| %>
<% slice.each do |item| %> <% slice.each do |item| %>
<%= rendered "components/item" %> <%= rendered "components/item" %>
<% end %> <% end %>
<% end %> <% end %>
</div> </div>

@ -7,12 +7,13 @@
<div class="pure-u-2-3"> <div class="pure-u-2-3">
<h3><%= playlist.title %></h3> <h3><%= playlist.title %></h3>
</div> </div>
<div class="pure-u-1-3" style="text-align:right;"> <div class="pure-u-1-3" style="text-align:right">
<h3> <h3>
<a href="/feed/playlist/<%= plid %>"><i class="icon ion-logo-rss"></i></a> <a href="/feed/playlist/<%= plid %>"><i class="icon ion-logo-rss"></i></a>
</h3> </h3>
</div> </div>
</div> </div>
<div class="pure-g h-box"> <div class="pure-g h-box">
<div class="pure-u-1 pure-u-md-1-4"> <div class="pure-u-1 pure-u-md-1-4">
<a href="/channel/<%= playlist.ucid %>"> <a href="/channel/<%= playlist.ucid %>">
@ -26,11 +27,11 @@
</div> </div>
<div class="pure-g"> <div class="pure-g">
<% videos.each_slice(4) do |slice| %> <% videos.each_slice(4) do |slice| %>
<% slice.each do |item| %> <% slice.each do |item| %>
<%= rendered "components/item" %> <%= rendered "components/item" %>
<% end %> <% end %>
<% end %> <% end %>
</div> </div>
<div class="pure-g h-box"> <div class="pure-g h-box">
@ -42,7 +43,7 @@
<% end %> <% end %>
</div> </div>
<div class="pure-u-1 pure-u-lg-3-5"></div> <div class="pure-u-1 pure-u-lg-3-5"></div>
<div style="text-align:right;" class="pure-u-1 pure-u-lg-1-5"> <div class="pure-u-1 pure-u-lg-1-5" style="text-align:right">
<% if videos.size == 100 %> <% if videos.size == 100 %>
<a href="/playlist?list=<%= playlist.id %>&page=<%= page + 1 %>"> <a href="/playlist?list=<%= playlist.id %>&page=<%= page + 1 %>">
<%= translate(locale, "Next page") %> <%= translate(locale, "Next page") %>

@ -6,7 +6,7 @@
<div class="pure-u-2-3"> <div class="pure-u-2-3">
<h3><%= author %></h3> <h3><%= author %></h3>
</div> </div>
<div class="pure-u-1-3" style="text-align:right;"> <div class="pure-u-1-3" style="text-align:right">
<h3> <h3>
<a href="/feed/channel/<%= ucid %>"><i class="icon ion-logo-rss"></i></a> <a href="/feed/channel/<%= ucid %>"><i class="icon ion-logo-rss"></i></a>
</h3> </h3>
@ -14,8 +14,8 @@
</div> </div>
<div class="h-box"> <div class="h-box">
<% sub_count_text = number_to_short_text(sub_count) %> <% sub_count_text = number_to_short_text(sub_count) %>
<%= rendered "components/subscribe_widget" %> <%= rendered "components/subscribe_widget" %>
</div> </div>
<div class="pure-g h-box"> <div class="pure-g h-box">
@ -32,10 +32,9 @@
<% end %> <% end %>
</div> </div>
</div> </div>
<div class="pure-u-1-3"></div>
<div class="pure-u-1-3"> <div class="pure-u-1-3">
</div> <div class="pure-g" style="text-align:right">
<div class="pure-u-1-3">
<div class="pure-g" style="text-align:right;">
<% {"last", "oldest", "newest"}.each do |sort| %> <% {"last", "oldest", "newest"}.each do |sort| %>
<div class="pure-u-1 pure-md-1-3"> <div class="pure-u-1 pure-md-1-3">
<% if sort_by == sort %> <% if sort_by == sort %>
@ -56,16 +55,16 @@
</div> </div>
<div class="pure-g"> <div class="pure-g">
<% items.each_slice(4) do |slice| %> <% items.each_slice(4) do |slice| %>
<% slice.each do |item| %> <% slice.each do |item| %>
<%= rendered "components/item" %> <%= rendered "components/item" %>
<% end %> <% end %>
<% end %> <% end %>
</div> </div>
<div class="pure-g h-box"> <div class="pure-g h-box">
<div class="pure-u-1 pure-u-md-4-5"></div> <div class="pure-u-1 pure-u-md-4-5"></div>
<div style="text-align:right;" class="pure-u-1 pure-u-lg-1-5"> <div class="pure-u-1 pure-u-lg-1-5" style="text-align:right">
<% if items.size >= 28 %> <% if items.size >= 28 %>
<a href="/channel/<%= ucid %>/playlists?continuation=<%= continuation %><% if sort_by != "last" %>&sort_by=<%= sort_by %><% end %>"> <a href="/channel/<%= ucid %>/playlists?continuation=<%= continuation %><% if sort_by != "last" %>&sort_by=<%= sort_by %><% end %>">
<%= translate(locale, "Next page") %> <%= translate(locale, "Next page") %>

@ -1,14 +1,20 @@
<% content_for "header" do %> <% content_for "header" do %>
<meta name="description" content="<%= translate(locale, "An alternative front-end to YouTube") %>"> <meta name="description" content="<%= translate(locale, "An alternative front-end to YouTube") %>">
<title><% if config.default_home != "Popular" %><%= translate(locale, "Popular") %> - <% end %>Invidious</title> <title>
<% if config.default_home != "Popular" %>
<%= translate(locale, "Popular") %> - Invidious
<% else %>
Invidious
<% end %>
</title>
<% end %> <% end %>
<%= rendered "components/feed_menu" %> <%= rendered "components/feed_menu" %>
<div class="pure-g"> <div class="pure-g">
<% popular_videos.each_slice(4) do |slice| %> <% popular_videos.each_slice(4) do |slice| %>
<% slice.each do |item| %> <% slice.each do |item| %>
<%= rendered "components/item" %> <%= rendered "components/item" %>
<% end %> <% end %>
<% end %> <% end %>
</div> </div>

@ -3,7 +3,7 @@
<% end %> <% end %>
<div class="h-box"> <div class="h-box">
<%= Markdown.to_html(<<-END_PRIVACY_POLICY <%= Markdown.to_html(<<-END_PRIVACY_POLICY
## Privacy ## Privacy
This document concerns what data you provide to this website, the purpose of the data, how the data is stored, and how the data can be removed. This document concerns what data you provide to this website, the purpose of the data, how the data is stored, and how the data can be removed.
@ -71,5 +71,5 @@
To remove data that has been stored in the website's database, you can use the [delete my account](/delete_account) page. To remove data that has been stored in the website's database, you can use the [delete my account](/delete_account) page.
END_PRIVACY_POLICY END_PRIVACY_POLICY
) )
%> %>
</div> </div>

@ -3,11 +3,11 @@
<% end %> <% end %>
<div class="pure-g"> <div class="pure-g">
<% videos.each_slice(4) do |slice| %> <% videos.each_slice(4) do |slice| %>
<% slice.each do |item| %> <% slice.each do |item| %>
<%= rendered "components/item" %> <%= rendered "components/item" %>
<% end %> <% end %>
<% end %> <% end %>
</div> </div>
<div class="pure-g h-box"> <div class="pure-g h-box">
@ -19,7 +19,7 @@
<% end %> <% end %>
</div> </div>
<div class="pure-u-1 pure-u-lg-3-5"></div> <div class="pure-u-1 pure-u-lg-3-5"></div>
<div style="text-align:right;" class="pure-u-1 pure-u-lg-1-5"> <div class="pure-u-1 pure-u-lg-1-5" style="text-align:right">
<% if count >= 20 %> <% if count >= 20 %>
<a href="/search?q=<%= HTML.escape(query.not_nil!) %>&page=<%= page + 1 %>"> <a href="/search?q=<%= HTML.escape(query.not_nil!) %>&page=<%= page + 1 %>">
<%= translate(locale, "Next page") %> <%= translate(locale, "Next page") %>

@ -5,23 +5,29 @@
<div class="pure-g h-box"> <div class="pure-g h-box">
<div class="pure-u-1-3"> <div class="pure-u-1-3">
<h3> <h3>
<a href="/feed/subscriptions"><%= translate(locale, "`x` subscriptions", %(<span id="count">#{subscriptions.size}</span>)) %></a> <a href="/feed/subscriptions">
<%= translate(locale, "`x` subscriptions", %(<span id="count">#{subscriptions.size}</span>)) %>
</a>
</h3> </h3>
</div> </div>
<div class="pure-u-1-3" style="text-align:center"> <div class="pure-u-1-3" style="text-align:center">
<h3> <h3>
<a href="/feed/history"><%= translate(locale, "Watch history") %></a> <a href="/feed/history">
<%= translate(locale, "Watch history") %>
</a>
</h3> </h3>
</div> </div>
<div class="pure-u-1-3" style="text-align:right"> <div class="pure-u-1-3" style="text-align:right">
<h3> <h3>
<a href="/data_control?referer=<%= referer %>"><%= translate(locale, "Import/export") %></a> <a href="/data_control?referer=<%= referer %>">
<%= translate(locale, "Import/export") %>
</a>
</h3> </h3>
</div> </div>
</div> </div>
<% subscriptions.each do |channel| %> <% subscriptions.each do |channel| %>
<div class="h-box"> <div class="h-box">
<div class="pure-g<% if channel.deleted %> deleted <% end %>"> <div class="pure-g<% if channel.deleted %> deleted <% end %>">
<div class="pure-u-2-5"> <div class="pure-u-2-5">
<h3 style="padding-left:0.5em"> <h3 style="padding-left:0.5em">
@ -44,29 +50,31 @@
<% if subscriptions[-1].author != channel.author %> <% if subscriptions[-1].author != channel.author %>
<hr> <hr>
<% end %> <% end %>
</div> </div>
<% end %> <% end %>
<script> <script>
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.innerText = count.innerText - 1; count.innerText = count.innerText - 1;
var url = "/subscription_ajax?action_remove_subscriptions=1&redirect=false&referer=<%= env.get("current_page") %>&c=" + target.getAttribute("data-ucid"); var url = '/subscription_ajax?action_remove_subscriptions=1&redirect=false' +
'&referer=<%= env.get("current_page") %>' +
'&c=' + target.getAttribute('data-ucid');
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.responseType = "json"; xhr.responseType = 'json';
xhr.timeout = 20000; xhr.timeout = 20000;
xhr.open("POST", url, true); xhr.open('POST', url, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send("csrf_token=<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>"); xhr.send('csrf_token=<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>');
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
if (xhr.readyState == 4) { if (xhr.readyState == 4) {
if (xhr.status != 200) { if (xhr.status != 200) {
count.innerText = count.innerText - 1 + 2; count.innerText = parseInt(count.innerText) + 1;
row.style.display = ""; row.style.display = '';
} }
} }
} }

@ -11,32 +11,34 @@
<a href="/subscription_manager"><%= translate(locale, "Manage subscriptions") %></a> <a href="/subscription_manager"><%= translate(locale, "Manage subscriptions") %></a>
</h3> </h3>
</div> </div>
<div class="pure-u-1-3" style="text-align:center;"> <div class="pure-u-1-3" style="text-align:center">
<h3> <h3>
<a href="/feed/history"><%= translate(locale, "Watch history") %></a> <a href="/feed/history"><%= translate(locale, "Watch history") %></a>
</h3> </h3>
</div> </div>
<div class="pure-u-1-3" style="text-align:right;"> <div class="pure-u-1-3" style="text-align:right">
<h3> <h3>
<a href="/feed/private?token=<%= token %>"><i class="icon ion-logo-rss"></i></a> <a href="/feed/private?token=<%= token %>"><i class="icon ion-logo-rss"></i></a>
</h3> </h3>
</div> </div>
</div> </div>
<center><%= translate(locale, "`x` unseen notifications", "#{notifications.size}") %></center> <center>
<%= translate(locale, "`x` unseen notifications", "#{notifications.size}") %>
</center>
<% if !notifications.empty? %> <% if !notifications.empty? %>
<div class="h-box"> <div class="h-box">
<hr> <hr>
</div> </div>
<% end %> <% end %>
<div class="pure-g"> <div class="pure-g">
<% notifications.each_slice(4) do |slice| %> <% notifications.each_slice(4) do |slice| %>
<% slice.each do |item| %> <% slice.each do |item| %>
<%= rendered "components/item" %> <%= rendered "components/item" %>
<% end %> <% end %>
<% end %> <% end %>
</div> </div>
<div class="h-box"> <div class="h-box">
@ -44,30 +46,31 @@
</div> </div>
<div class="pure-g"> <div class="pure-g">
<% videos.each_slice(4) do |slice| %> <% videos.each_slice(4) do |slice| %>
<% slice.each do |item| %> <% slice.each do |item| %>
<%= rendered "components/item" %> <%= rendered "components/item" %>
<% end %> <% end %>
<% end %> <% end %>
</div> </div>
<script> <script>
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=1&redirect=false&id=" + target.getAttribute("data-id"); var url = '/watch_ajax?action_mark_watched=1&redirect=false' +
'&id=' + target.getAttribute('data-id');
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.responseType = "json"; xhr.responseType = 'json';
xhr.timeout = 20000; xhr.timeout = 20000;
xhr.open("POST", url, true); xhr.open('POST', url, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send("csrf_token=<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>"); xhr.send('csrf_token=<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>');
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
if (xhr.readyState == 4) { if (xhr.readyState == 4) {
if (xhr.status != 200) { if (xhr.status != 200) {
tile.style.display = ""; tile.style.display = '';
} }
} }
} }
@ -83,7 +86,7 @@ function mark_watched(target) {
<% end %> <% end %>
</div> </div>
<div class="pure-u-1 pure-u-lg-3-5"></div> <div class="pure-u-1 pure-u-lg-3-5"></div>
<div style="text-align:right;" class="pure-u-1 pure-u-lg-1-5"> <div class="pure-u-1 pure-u-lg-1-5" style="text-align:right">
<% if (videos.size + notifications.size) == max_results %> <% if (videos.size + notifications.size) == max_results %>
<a href="/feed/subscriptions?max_results=<%= max_results %>&page=<%= page + 1 %>"> <a href="/feed/subscriptions?max_results=<%= max_results %>&page=<%= page + 1 %>">
<%= translate(locale, "Next page") %> <%= translate(locale, "Next page") %>

@ -38,7 +38,7 @@
<div class="pure-u-1 pure-u-md-12-24 searchbar"> <div class="pure-u-1 pure-u-md-12-24 searchbar">
<form class="pure-form" action="/search" method="get"> <form class="pure-form" action="/search" method="get">
<fieldset> <fieldset>
<input type="search" style="width:100%;" name="q" placeholder="<%= translate(locale, "search") %>" value="<%= env.get?("search").try {|x| HTML.escape(x.as(String)) } || env.params.query["q"]?.try {|x| HTML.escape(x)} %>"> <input type="search" style="width:100%" name="q" placeholder="<%= translate(locale, "search") %>" value="<%= env.get?("search").try {|x| HTML.escape(x.as(String)) } || env.params.query["q"]?.try {|x| HTML.escape(x)} %>">
</fieldset> </fieldset>
</form> </form>
</div> </div>
@ -101,12 +101,15 @@
<% end %> <% end %>
</div> </div>
</div> </div>
<% if CONFIG.banner %> <% if CONFIG.banner %>
<div class="h-box"> <div class="h-box">
<h3><%= CONFIG.banner %></h3> <h3><%= CONFIG.banner %></h3>
</div> </div>
<% end %> <% end %>
<%= content %> <%= content %>
<div class="footer"> <div class="footer">
<div class="pure-g"> <div class="pure-g">
<div class="pure-u-1 pure-u-md-1-3"> <div class="pure-u-1 pure-u-md-1-3">
@ -116,10 +119,12 @@
</div> </div>
<div class="pure-u-1 pure-u-md-1-3"> <div class="pure-u-1 pure-u-md-1-3">
<i class="icon ion-logo-bitcoin"></i> <i class="icon ion-logo-bitcoin"></i>
BTC: 356DpZyMXu6rYd55Yqzjs29n79kGKWcYrY</div> BTC: 356DpZyMXu6rYd55Yqzjs29n79kGKWcYrY
</div>
<div class="pure-u-1 pure-u-md-1-3"> <div class="pure-u-1 pure-u-md-1-3">
<i class="icon ion-logo-bitcoin"></i> <i class="icon ion-logo-bitcoin"></i>
BCH: qq4ptclkzej5eza6a50et5ggc58hxsq5aylqut2npk</div> BCH: qq4ptclkzej5eza6a50et5ggc58hxsq5aylqut2npk
</div>
<div class="pure-u-1 pure-u-md-1-3"> <div class="pure-u-1 pure-u-md-1-3">
<i class="icon ion-logo-usd"></i> <i class="icon ion-logo-usd"></i>
<a href="https://liberapay.com/omarroth">Liberapay</a> <a href="https://liberapay.com/omarroth">Liberapay</a>
@ -141,7 +146,8 @@
<i class="icon ion-logo-github"></i> <i class="icon ion-logo-github"></i>
<%= translate(locale, "Current version: ") %> <%= CURRENT_VERSION %>-<%= CURRENT_COMMIT %> <%= translate(locale, "Current version: ") %> <%= CURRENT_VERSION %>-<%= CURRENT_COMMIT %>
<i class="icon ion-logo-github"></i> <i class="icon ion-logo-github"></i>
<%= CURRENT_BRANCH %></div> <%= CURRENT_BRANCH %>
</div>
</div> </div>
</div> </div>
</div> </div>

@ -48,23 +48,25 @@
<script> <script>
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.innerText = count.innerText - 1; count.innerText = count.innerText - 1;
var url = "/token_ajax?action_revoke_token=1&redirect=false&referer=<%= env.get("current_page") %>&session=" + target.getAttribute("data-session"); var url = '/token_ajax?action_revoke_token=1&redirect=false' +
'&referer=<%= env.get("current_page") %>' +
'&session=' + target.getAttribute('data-session');
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.responseType = "json"; xhr.responseType = 'json';
xhr.timeout = 20000; xhr.timeout = 20000;
xhr.open("POST", url, true); xhr.open('POST', url, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send("csrf_token=<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>"); xhr.send('csrf_token=<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>');
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
if (xhr.readyState == 4) { if (xhr.readyState == 4) {
if (xhr.status != 200) { if (xhr.status != 200) {
count.innerText = count.innerText - 1 + 2; count.innerText = parseInt(count.innerText) + 1;
row.style.display = ""; row.style.display = '';
} }
} }
} }

@ -1,14 +1,20 @@
<% content_for "header" do %> <% content_for "header" do %>
<meta name="description" content="<%= translate(locale, "An alternative front-end to YouTube") %>"> <meta name="description" content="<%= translate(locale, "An alternative front-end to YouTube") %>">
<title><% if config.default_home != "Top" %><%= translate(locale, "Top") %> - <% end %>Invidious</title> <title>
<% if config.default_home != "Top" %>
<%= translate(locale, "Top") %> - Invidious
<% else %>
Invidious
<% end %>
</title>
<% end %> <% end %>
<%= rendered "components/feed_menu" %> <%= rendered "components/feed_menu" %>
<div class="pure-g"> <div class="pure-g">
<% top_videos.each_slice(4) do |slice| %> <% top_videos.each_slice(4) do |slice| %>
<% slice.each do |item| %> <% slice.each do |item| %>
<%= rendered "components/item" %> <%= rendered "components/item" %>
<% end %> <% end %>
<% end %> <% end %>
</div> </div>

@ -1,6 +1,12 @@
<% content_for "header" do %> <% content_for "header" do %>
<meta name="description" content="<%= translate(locale, "An alternative front-end to YouTube") %>"> <meta name="description" content="<%= translate(locale, "An alternative front-end to YouTube") %>">
<title><% if config.default_home != "Trending" %><%= translate(locale, "Trending") %> - <% end %>Invidious</title> <title>
<% if config.default_home != "Trending" %>
<%= translate(locale, "Trending") %> - Invidious
<% else %>
Invidious
<% end %>
</title>
<% end %> <% end %>
<%= rendered "components/feed_menu" %> <%= rendered "components/feed_menu" %>
@ -8,11 +14,13 @@
<div class="pure-g h-box"> <div class="pure-g h-box">
<div style="align-self:flex-end" class="pure-u-2-3"> <div style="align-self:flex-end" class="pure-u-2-3">
<% if plid %> <% if plid %>
<a href="/playlist?list=<%= plid %>"><%= translate(locale, "View as playlist") %></a> <a href="/playlist?list=<%= plid %>">
<%= translate(locale, "View as playlist") %>
</a>
<% end %> <% end %>
</div> </div>
<div class="pure-u-1-3"> <div class="pure-u-1-3">
<div class="pure-g" style="text-align:right;"> <div class="pure-g" style="text-align:right">
<% {"Default", "Music", "Gaming", "News", "Movies"}.each do |option| %> <% {"Default", "Music", "Gaming", "News", "Movies"}.each do |option| %>
<div class="pure-u-1 pure-md-1-3"> <div class="pure-u-1 pure-md-1-3">
<% if trending_type == option %> <% if trending_type == option %>
@ -33,9 +41,9 @@
</div> </div>
<div class="pure-g"> <div class="pure-g">
<% trending.each_slice(4) do |slice| %> <% trending.each_slice(4) do |slice| %>
<% slice.each do |item| %> <% slice.each do |item| %>
<%= rendered "components/item" %> <%= rendered "components/item" %>
<% end %> <% end %>
<% end %> <% end %>
</div> </div>

@ -32,7 +32,7 @@
</div> </div>
<div class="h-box"> <div class="h-box">
<h1> <h1>
<%= HTML.escape(video.title) %> <%= HTML.escape(video.title) %>
<% if params.listen %> <% if params.listen %>
<a title="<%=translate(locale, "Video mode")%>" href="/watch?<%= env.params.query %>&listen=0"> <a title="<%=translate(locale, "Video mode")%>" href="/watch?<%= env.params.query %>&listen=0">
@ -43,19 +43,27 @@
<i class="icon ion-md-headset"></i> <i class="icon ion-md-headset"></i>
</a> </a>
<% end %> <% end %>
</h1> </h1>
<% if !video.is_listed %>
<h3><i class="icon ion-ios-lock"></i> <%= translate(locale, "Unlisted") %></h3> <% if !video.is_listed %>
<% end %> <h3>
<% if !reason.empty? %> <i class="icon ion-ios-lock"></i> <%= translate(locale, "Unlisted") %>
<h3><%= reason %></h3> </h3>
<% end %> <% end %>
<% if !reason.empty? %>
<h3>
<%= reason %>
</h3>
<% end %>
</div> </div>
<div class="pure-g"> <div class="pure-g">
<div class="pure-u-1 pure-u-lg-1-5"> <div class="pure-u-1 pure-u-lg-1-5">
<div class="h-box"> <div class="h-box">
<p><a href="https://www.youtube.com/watch?v=<%= video.id %>"><%= translate(locale, "Watch on YouTube") %></a></p> <p>
<a href="https://www.youtube.com/watch?v=<%= video.id %>"><%= translate(locale, "Watch on YouTube") %></a>
</p>
<p> <p>
<% if params.annotations %> <% if params.annotations %>
<a href="/watch?<%= env.params.query %>&iv_load_policy=3"> <a href="/watch?<%= env.params.query %>&iv_load_policy=3">
@ -69,7 +77,7 @@
</p> </p>
<% if CONFIG.dmca_content.includes? video.id %> <% if CONFIG.dmca_content.includes? video.id %>
<p>Download is disabled.</p> <p><%= translate(locale, "Download is disabled.") %></p>
<% else %> <% else %>
<form class="pure-form pure-form-stacked" action="/latest_version" method="get" rel="noopener" target="_blank"> <form class="pure-form pure-form-stacked" action="/latest_version" method="get" rel="noopener" target="_blank">
<div class="pure-control-group"> <div class="pure-control-group">
@ -107,7 +115,7 @@
<p><i class="icon ion-ios-eye"></i> <%= number_with_separator(video.views) %></p> <p><i class="icon ion-ios-eye"></i> <%= number_with_separator(video.views) %></p>
<p><i class="icon ion-ios-thumbs-up"></i> <%= number_with_separator(video.likes) %></p> <p><i class="icon ion-ios-thumbs-up"></i> <%= number_with_separator(video.likes) %></p>
<p><i class="icon ion-ios-thumbs-down"></i> <%= number_with_separator(video.dislikes) %></p> <p><i class="icon ion-ios-thumbs-down"></i> <%= number_with_separator(video.dislikes) %></p>
<p id="Genre"><%= translate(locale, "Genre: ") %> <p id="genre"><%= translate(locale, "Genre: ") %>
<% if video.genre_url.empty? %> <% if video.genre_url.empty? %>
<%= video.genre %> <%= video.genre %>
<% else %> <% else %>
@ -115,14 +123,14 @@
<% end %> <% end %>
</p> </p>
<% if !video.license.empty? %> <% if !video.license.empty? %>
<p id="License"><%= translate(locale, "License: ") %><%= video.license %></p> <p id="license"><%= translate(locale, "License: ") %><%= video.license %></p>
<% end %> <% end %>
<p id="FamilyFriendly"><%= translate(locale, "Family friendly? ") %><%= translate_bool(locale, video.is_family_friendly) %></p> <p id="family_friendly"><%= translate(locale, "Family friendly? ") %><%= translate_bool(locale, video.is_family_friendly) %></p>
<p id="Wilson"><%= translate(locale, "Wilson score: ") %><%= video.wilson_score.round(4) %></p> <p id="wilson"><%= translate(locale, "Wilson score: ") %><%= video.wilson_score.round(4) %></p>
<p id="Rating"><%= translate(locale, "Rating: ") %><%= rating.round(4) %> / 5</p> <p id="rating"><%= translate(locale, "Rating: ") %><%= rating.round(4) %> / 5</p>
<p id="Engagement"><%= translate(locale, "Engagement: ") %><%= engagement.round(2) %>%</p> <p id="engagement"><%= translate(locale, "Engagement: ") %><%= engagement.round(2) %>%</p>
<% if video.allowed_regions.size != REGIONS.size %> <% if video.allowed_regions.size != REGIONS.size %>
<p id="AllowedRegions"> <p id="allowed_regions">
<% if video.allowed_regions.size < REGIONS.size / 2 %> <% if video.allowed_regions.size < REGIONS.size / 2 %>
<%= translate(locale, "Whitelisted regions: ") %><%= video.allowed_regions.join(", ") %> <%= translate(locale, "Whitelisted regions: ") %><%= video.allowed_regions.join(", ") %>
<% else %> <% else %>
@ -140,17 +148,22 @@
<h3><%= video.author %></h3> <h3><%= video.author %></h3>
</a> </a>
</p> </p>
<% ucid = video.ucid %> <% ucid = video.ucid %>
<% author = video.author %> <% author = video.author %>
<% sub_count_text = video.sub_count_text %> <% sub_count_text = video.sub_count_text %>
<%= rendered "components/subscribe_widget" %> <%= rendered "components/subscribe_widget" %>
<p> <p>
<b><%= translate(locale, "Shared `x`", video.published.to_s("%B %-d, %Y")) %></b> <b><%= translate(locale, "Shared `x`", video.published.to_s("%B %-d, %Y")) %></b>
</p> </p>
<div> <div>
<%= video.description %> <%= video.description %>
</div> </div>
<hr> <hr>
<div id="comments"> <div id="comments">
<% if nojs %> <% if nojs %>
<%= comment_html %> <%= comment_html %>
@ -164,16 +177,15 @@
</div> </div>
</div> </div>
</div> </div>
<% if params.related_videos || plid %> <% if params.related_videos || plid %>
<div class="pure-u-1 pure-u-lg-1-5"> <div class="pure-u-1 pure-u-lg-1-5">
<% if plid %> <% if plid %>
<div id="playlist" class="h-box"> <div id="playlist" class="h-box"></div>
</div>
<% end %> <% end %>
<% if params.related_videos %> <% if params.related_videos %>
<div class="h-box"> <div class="h-box">
<% if !rvs.empty? %> <% if !rvs.empty? %>
<div <% if plid %>style="display:none"<% end %>> <div <% if plid %>style="display:none"<% end %>>
<div class="pure-control-group"> <div class="pure-control-group">
@ -187,8 +199,7 @@
<% rvs.each do |rv| %> <% rvs.each do |rv| %>
<% if rv["id"]? %> <% if rv["id"]? %>
<a href="/watch?v=<%= rv["id"] %>"> <a href="/watch?v=<%= rv["id"] %>">
<% if env.get("preferences").as(Preferences).thin_mode %> <% if !env.get("preferences").as(Preferences).thin_mode %>
<% else %>
<div class="thumbnail"> <div class="thumbnail">
<img class="thumbnail" src="/vi/<%= rv["id"] %>/mqdefault.jpg"> <img class="thumbnail" src="/vi/<%= rv["id"] %>/mqdefault.jpg">
<p class="length"><%= recode_length_seconds(rv["length_seconds"]?.try &.to_i? || 0) %></p> <p class="length"><%= recode_length_seconds(rv["length_seconds"]?.try &.to_i? || 0) %></p>
@ -218,18 +229,19 @@
<script> <script>
<% if !rvs.empty? && !plid && params.continue %> <% if !rvs.empty? && !plid && params.continue %>
player.on('ended', function() { player.on('ended', function() {
location.assign("/watch?v=" location.assign('/watch?v=' +
+ "<%= rvs.select { |rv| rv["id"]? }[0]?.try &.["id"] %>" '<%= rvs.select { |rv| rv["id"]? }[0]?.try &.["id"] %>' +
+ "&continue=1" '&continue=1' +
<% if params.listen != preferences.listen %> <% if params.listen != preferences.listen %>
+ "&listen=<%= params.listen %>" '&listen=<%= params.listen %>' +
<% end %> <% end %>
<% if params.autoplay || params.continue_autoplay %> <% if params.autoplay || params.continue_autoplay %>
+ "&autoplay=1" '&autoplay=1' +
<% end %> <% end %>
<% if params.speed != preferences.speed %> <% if params.speed != preferences.speed %>
+ "&speed=<%= params.speed %>" '&speed=<%= params.speed %>' +
<% end %> <% end %>
''
); );
}); });
<% end %> <% end %>
@ -237,18 +249,19 @@ player.on('ended', function() {
function continue_autoplay(target) { function continue_autoplay(target) {
if (target.checked) { if (target.checked) {
player.on('ended', function() { player.on('ended', function() {
location.assign("/watch?v=" location.assign('/watch?v=' +
+ "<%= rvs.select { |rv| rv["id"]? }[0]?.try &.["id"] %>" '<%= rvs.select { |rv| rv["id"]? }[0]?.try &.["id"] %>' +
+ "&continue=1" '&continue=1' +
<% if params.listen != preferences.listen %> <% if params.listen != preferences.listen %>
+ "&listen=<%= params.listen %>" '&listen=<%= params.listen %>' +
<% end %> <% end %>
<% if params.autoplay || params.continue_autoplay %> <% if params.autoplay || params.continue_autoplay %>
+ "&autoplay=1" '&autoplay=1' +
<% end %> <% end %>
<% if params.speed != preferences.speed %> <% if params.speed != preferences.speed %>
+ "&speed=<%= params.speed %>" '&speed=<%= params.speed %>' +
<% end %> <% end %>
''
); );
}); });
} else { } else {
@ -269,12 +282,12 @@ function number_with_separator(val) {
<%= rendered "components/subscribe_widget_script" %> <%= rendered "components/subscribe_widget_script" %>
<% if plid %> <% if plid %>
function get_playlist(timeouts = 0) { function get_playlist(plid, timeouts = 0) {
playlist = document.getElementById("playlist"); playlist = document.getElementById('playlist');
if (timeouts > 10) { if (timeouts > 10) {
console.log("Failed to pull playlist"); console.log('Failed to pull playlist');
playlist.innerHTML = ""; playlist.innerHTML = '';
return; return;
} }
@ -282,18 +295,20 @@ function get_playlist(timeouts = 0) {
<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> \
<hr>' <hr>'
var plid = "<%= plid %>" if (plid.startsWith('RD')) {
var plid_url = '/api/v1/mixes/' + plid +
if (plid.startsWith("RD")) { '?continuation=<%= video.id %>' +
var plid_url = "/api/v1/mixes/<%= plid %>?continuation=<%= video.id %>&format=html&hl=<%= env.get("preferences").as(Preferences).locale %>"; '&format=html&hl=<%= env.get("preferences").as(Preferences).locale %>';
} else { } else {
var plid_url = "/api/v1/playlists/<%= plid %>?continuation=<%= video.id %>&format=html&hl=<%= env.get("preferences").as(Preferences).locale %>"; var plid_url = '/api/v1/playlists/' + plid +
'?continuation=<%= video.id %>' +
'&format=html&hl=<%= env.get("preferences").as(Preferences).locale %>';
} }
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.responseType = "json"; xhr.responseType = 'json';
xhr.timeout = 20000; xhr.timeout = 20000;
xhr.open("GET", plid_url, true); xhr.open('GET', plid_url, true);
xhr.send(); xhr.send();
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
@ -303,47 +318,46 @@ function get_playlist(timeouts = 0) {
if (xhr.response.nextVideo) { if (xhr.response.nextVideo) {
player.on('ended', function() { player.on('ended', function() {
location.assign("/watch?v=" location.assign('/watch?v=' + xhr.response.nextVideo +
+ xhr.response.nextVideo '&list=' + plid +
+ "&list=<%= plid %>"
<% if params.listen != preferences.listen %> <% if params.listen != preferences.listen %>
+ "&listen=<%= params.listen %>" '&listen=<%= params.listen %>' +
<% end %> <% end %>
<% if params.autoplay || params.continue_autoplay %> <% if params.autoplay || params.continue_autoplay %>
+ "&autoplay=1" '&autoplay=1' +
<% end %> <% end %>
<% if params.speed != preferences.speed %> <% if params.speed != preferences.speed %>
+ "&speed=<%= params.speed %>" '&speed=<%= params.speed %>' +
<% end %> <% end %>
''
); );
}); });
} }
} else { } else {
playlist.innerHTML = ""; playlist.innerHTML = '';
document.getElementById('continue').style.display = ""; document.getElementById('continue').style.display = '';
} }
} }
}; };
xhr.ontimeout = function() { xhr.ontimeout = function() {
console.log("Pulling playlist timed out."); console.log('Pulling playlist timed out.');
playlist = document.getElementById('playlist');
playlist = document.getElementById("playlist");
playlist.innerHTML = playlist.innerHTML =
'<h3 style="text-align:center"><div class="loading"><i class="icon ion-ios-refresh"></i></div></h3><hr>'; '<h3 style="text-align:center"><div class="loading"><i class="icon ion-ios-refresh"></i></div></h3><hr>';
get_playlist(timeouts + 1); get_playlist(plid, timeouts + 1);
}; };
} }
get_playlist(); get_playlist('<%= plid %>');
<% end %> <% end %>
function get_reddit_comments(timeouts = 0) { function get_reddit_comments(timeouts = 0) {
comments = document.getElementById("comments"); comments = document.getElementById('comments');
if (timeouts > 10) { if (timeouts > 10) {
console.log("Failed to pull comments"); console.log('Failed to pull comments');
comments.innerHTML = ""; comments.innerHTML = '';
return; return;
} }
@ -351,11 +365,13 @@ function get_reddit_comments(timeouts = 0) {
comments.innerHTML = comments.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/comments/<%= video.id %>?source=reddit&format=html&hl=<%= env.get("preferences").as(Preferences).locale %>"; var url = '/api/v1/comments/<%= video.id %>' +
'?source=reddit&format=html' +
'&hl=<%= env.get("preferences").as(Preferences).locale %>';
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.responseType = "json"; xhr.responseType = 'json';
xhr.timeout = 20000; xhr.timeout = 20000;
xhr.open("GET", url, true); xhr.open('GET', url, true);
xhr.send(); xhr.send();
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
@ -395,18 +411,17 @@ function get_reddit_comments(timeouts = 0) {
}; };
xhr.ontimeout = function() { xhr.ontimeout = function() {
console.log("Pulling comments timed out."); console.log('Pulling comments timed out.');
get_reddit_comments(timeouts + 1); get_reddit_comments(timeouts + 1);
}; };
} }
function get_youtube_comments(timeouts = 0) { function get_youtube_comments(timeouts = 0) {
comments = document.getElementById("comments"); comments = document.getElementById('comments');
if (timeouts > 10) { if (timeouts > 10) {
console.log("Failed to pull comments"); console.log('Failed to pull comments');
comments.innerHTML = ""; comments.innerHTML = '';
return; return;
} }
@ -414,11 +429,14 @@ function get_youtube_comments(timeouts = 0) {
comments.innerHTML = comments.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/comments/<%= video.id %>?format=html&hl=<%= env.get("preferences").as(Preferences).locale %>&thin_mode=<%= env.get("preferences").as(Preferences).thin_mode %>"; var url = '/api/v1/comments/<%= video.id %>' +
'?format=html' +
'&hl=<%= env.get("preferences").as(Preferences).locale %>' +
'&thin_mode=<%= env.get("preferences").as(Preferences).thin_mode %>';
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.responseType = "json"; xhr.responseType = 'json';
xhr.timeout = 20000; xhr.timeout = 20000;
xhr.open("GET", url, true); xhr.open('GET', url, true);
xhr.send(); xhr.send();
xhr.onreadystatechange = function() { xhr.onreadystatechange = function() {
@ -449,15 +467,14 @@ function get_youtube_comments(timeouts = 0) {
<% if preferences && preferences.comments[1] == "youtube" %> <% if preferences && preferences.comments[1] == "youtube" %>
get_youtube_comments(timeouts + 1); get_youtube_comments(timeouts + 1);
<% else %> <% else %>
comments.innerHTML = ""; comments.innerHTML = '';
<% end %> <% end %>
} }
} }
}; };
xhr.ontimeout = function() { xhr.ontimeout = function() {
console.log("Pulling comments timed out."); console.log('Pulling comments timed out.');
comments.innerHTML = comments.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>';
get_youtube_comments(timeouts + 1); get_youtube_comments(timeouts + 1);
@ -472,8 +489,11 @@ function get_youtube_replies(target, load_more) {
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/comments/<%= video.id %>?format=html&hl=<%= env.get("preferences").as(Preferences).locale %>&thin_mode=<%= env.get("preferences").as(Preferences).thin_mode %>&continuation=' + var url = '/api/v1/comments/<%= video.id %>' +
continuation; '?format=html' +
'&hl=<%= env.get("preferences").as(Preferences).locale %>' +
'&thin_mode=<%= env.get("preferences").as(Preferences).thin_mode %>' +
'&continuation=' + continuation;
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.responseType = 'json'; xhr.responseType = 'json';
xhr.timeout = 20000; xhr.timeout = 20000;
@ -504,7 +524,6 @@ function get_youtube_replies(target, load_more) {
xhr.ontimeout = function() { xhr.ontimeout = function() {
console.log('Pulling comments timed out.'); console.log('Pulling comments timed out.');
body.innerHTML = fallback; body.innerHTML = fallback;
}; };
} }
@ -520,11 +539,11 @@ function get_youtube_replies(target, load_more) {
<% elsif preferences.comments[1] == "reddit" %> <% elsif preferences.comments[1] == "reddit" %>
get_reddit_comments(); get_reddit_comments();
<% else %> <% else %>
comments = document.getElementById("comments"); comments = document.getElementById('comments');
comments.innerHTML = ""; comments.innerHTML = '';
<% end %> <% end %>
<% end %> <% end %>
<% else %> <% else %>
get_youtube_comments(); get_youtube_comments();
<% end %> <% end %>
</script> </script>

Loading…
Cancel
Save