Minor formatting changes

This commit is contained in:
Omar Roth 2019-05-01 20:03:39 -05:00
parent 22b9bbe702
commit 1a9360ca75
No known key found for this signature in database
GPG Key ID: B8254FB7EC3D37F2
31 changed files with 1406 additions and 1337 deletions

View File

@ -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;
}); });

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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 %>

View File

@ -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") %>

View File

@ -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>

View File

@ -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>

View File

@ -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 %>

View File

@ -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 %>

View File

@ -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>

View File

@ -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);
}; };
} }

View File

@ -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 %>

View File

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

View File

@ -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") %>

View File

@ -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>

View File

@ -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>

View File

@ -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") %>

View File

@ -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") %>

View File

@ -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>

View File

@ -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>

View File

@ -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") %>

View File

@ -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 = '';
} }
} }
} }

View File

@ -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") %>

View File

@ -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>

View File

@ -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 = '';
} }
} }
} }

View File

@ -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>

View File

@ -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>

View File

@ -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>