summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--assets/js/watch.js68
-rw-r--r--src/invidious/comments.cr2
-rw-r--r--src/invidious/mixes.cr2
-rw-r--r--src/invidious/playlists.cr2
-rw-r--r--src/invidious/views/authorize_token.ecr126
-rw-r--r--src/invidious/views/channel.ecr79
-rw-r--r--src/invidious/views/components/feed_menu.ecr14
-rw-r--r--src/invidious/views/components/item.ecr243
-rw-r--r--src/invidious/views/components/player.ecr320
-rw-r--r--src/invidious/views/components/player_sources.ecr12
-rw-r--r--src/invidious/views/components/subscribe_widget.ecr32
-rw-r--r--src/invidious/views/components/subscribe_widget_script.ecr43
-rw-r--r--src/invidious/views/embed.ecr68
-rw-r--r--src/invidious/views/error.ecr2
-rw-r--r--src/invidious/views/history.ecr84
-rw-r--r--src/invidious/views/licenses.ecr8
-rw-r--r--src/invidious/views/login.ecr156
-rw-r--r--src/invidious/views/mix.ecr10
-rw-r--r--src/invidious/views/playlist.ecr33
-rw-r--r--src/invidious/views/playlists.ecr55
-rw-r--r--src/invidious/views/popular.ecr18
-rw-r--r--src/invidious/views/preferences.ecr262
-rw-r--r--src/invidious/views/privacy.ecr92
-rw-r--r--src/invidious/views/search.ecr30
-rw-r--r--src/invidious/views/subscription_manager.ecr78
-rw-r--r--src/invidious/views/subscriptions.ecr61
-rw-r--r--src/invidious/views/template.ecr130
-rw-r--r--src/invidious/views/token_manager.ecr24
-rw-r--r--src/invidious/views/top.ecr18
-rw-r--r--src/invidious/views/trending.ecr32
-rw-r--r--src/invidious/views/watch.ecr651
31 files changed, 1412 insertions, 1343 deletions
diff --git a/assets/js/watch.js b/assets/js/watch.js
index 7a68c30c..799d6af9 100644
--- a/assets/js/watch.js
+++ b/assets/js/watch.js
@@ -1,52 +1,52 @@
function toggle_parent(target) {
- body = target.parentNode.parentNode.children[1];
- if (body.style.display === null || body.style.display === "") {
- target.innerHTML = "[ + ]";
- body.style.display = "none";
- } else {
- target.innerHTML = "[ - ]";
- body.style.display = "";
- }
+ body = target.parentNode.parentNode.children[1];
+ if (body.style.display === null || body.style.display === "") {
+ target.innerHTML = "[ + ]";
+ body.style.display = "none";
+ } else {
+ target.innerHTML = "[ - ]";
+ body.style.display = "";
+ }
}
function toggle_comments(target) {
- body = target.parentNode.parentNode.parentNode.children[1];
- if (body.style.display === null || body.style.display === "") {
- target.innerHTML = "[ + ]";
- body.style.display = "none";
- } else {
- target.innerHTML = "[ - ]";
- body.style.display = "";
- }
+ body = target.parentNode.parentNode.parentNode.children[1];
+ if (body.style.display === null || body.style.display === "") {
+ target.innerHTML = "[ + ]";
+ body.style.display = "none";
+ } else {
+ target.innerHTML = "[ - ]";
+ body.style.display = "";
+ }
}
function swap_comments(source) {
- if (source == "youtube") {
- get_youtube_comments();
- } else if (source == "reddit") {
- get_reddit_comments();
- }
+ if (source == "youtube") {
+ get_youtube_comments();
+ } else if (source == "reddit") {
+ get_reddit_comments();
+ }
}
-String.prototype.supplant = function(o) {
- return this.replace(/{([^{}]*)}/g, function(a, b) {
- var r = o[b];
- return typeof r === "string" || typeof r === "number" ? r : a;
- });
+String.prototype.supplant = function (o) {
+ return this.replace(/{([^{}]*)}/g, function (a, b) {
+ var r = o[b];
+ return typeof r === "string" || typeof r === "number" ? r : a;
+ });
};
function show_youtube_replies(target, inner_text, sub_text) {
- body = target.parentNode.parentNode.children[1];
- body.style.display = "";
+ body = target.parentNode.parentNode.children[1];
+ body.style.display = "";
- target.innerHTML = inner_text;
- target.setAttribute("onclick", "hide_youtube_replies(this, \'" + inner_text + "\', \'" + sub_text + "\')");
+ target.innerHTML = inner_text;
+ target.setAttribute("onclick", "hide_youtube_replies(this, \'" + inner_text + "\', \'" + sub_text + "\')");
}
function hide_youtube_replies(target, inner_text, sub_text) {
- body = target.parentNode.parentNode.children[1];
- body.style.display = "none";
+ body = target.parentNode.parentNode.children[1];
+ body.style.display = "none";
- target.innerHTML = sub_text;
- target.setAttribute("onclick", "show_youtube_replies(this, \'" + inner_text + "\', \'" + sub_text + "\')");
+ target.innerHTML = sub_text;
+ target.setAttribute("onclick", "show_youtube_replies(this, \'" + inner_text + "\', \'" + sub_text + "\')");
}
diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr
index e1d8604d..df8d5ca4 100644
--- a/src/invidious/comments.cr
+++ b/src/invidious/comments.cr
@@ -309,7 +309,7 @@ def template_youtube_comments(comments, locale, thin_mode)
html += <<-END_HTML
<div class="pure-g">
<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 class="pure-u-20-24 pure-u-md-22-24">
<p>
diff --git a/src/invidious/mixes.cr b/src/invidious/mixes.cr
index 65e03a06..47c480d7 100644
--- a/src/invidious/mixes.cr
+++ b/src/invidious/mixes.cr
@@ -105,7 +105,7 @@ def template_mix(mix)
</div>
<p style="width:100%">#{video["title"]}</p>
<p>
- <b style="width: 100%">#{video["author"]}</b>
+ <b style="width:100%">#{video["author"]}</b>
</p>
</a>
</li>
diff --git a/src/invidious/playlists.cr b/src/invidious/playlists.cr
index 6015e5ec..92d9b977 100644
--- a/src/invidious/playlists.cr
+++ b/src/invidious/playlists.cr
@@ -248,7 +248,7 @@ def template_playlist(playlist)
</div>
<p style="width:100%">#{video["title"]}</p>
<p>
- <b style="width: 100%">#{video["author"]}</b>
+ <b style="width:100%">#{video["author"]}</b>
</p>
</a>
</li>
diff --git a/src/invidious/views/authorize_token.ecr b/src/invidious/views/authorize_token.ecr
index d00335e2..267f8ad9 100644
--- a/src/invidious/views/authorize_token.ecr
+++ b/src/invidious/views/authorize_token.ecr
@@ -3,76 +3,76 @@
<% end %>
<% if env.get? "access_token" %>
-<div class="pure-g h-box">
- <div class="pure-u-1-3">
- <h3>
- <%= translate(locale, "Token") %>
- </h3>
- </div>
- <div class="pure-u-1-3" style="text-align:center">
- <h3>
- <a href="/token_manager"><%= translate(locale, "Token manager") %></a>
- </h3>
- </div>
- <div class="pure-u-1-3" style="text-align:right">
- <h3>
- <a href="/preferences"><%= translate(locale, "Preferences") %></a>
- </h3>
+ <div class="pure-g h-box">
+ <div class="pure-u-1-3">
+ <h3>
+ <%= translate(locale, "Token") %>
+ </h3>
+ </div>
+ <div class="pure-u-1-3" style="text-align:center">
+ <h3>
+ <a href="/token_manager"><%= translate(locale, "Token manager") %></a>
+ </h3>
+ </div>
+ <div class="pure-u-1-3" style="text-align:right">
+ <h3>
+ <a href="/preferences"><%= translate(locale, "Preferences") %></a>
+ </h3>
+ </div>
</div>
-</div>
-<div class="h-box">
- <h4 style="padding-left:0.5em">
- <code><%= env.get "access_token" %></code>
- </h4>
-</div>
+ <div class="h-box">
+ <h4 style="padding-left:0.5em">
+ <code><%= env.get "access_token" %></code>
+ </h4>
+ </div>
<% else %>
-<div class="h-box">
- <form class="pure-form pure-form-aligned" action="/authorize_token" method="post">
- <% if callback_url %>
- <legend><%= translate(locale, "Authorize token for `x`?", "#{callback_url.scheme}://#{callback_url.host}") %></legend>
- <% else %>
- <legend><%= translate(locale, "Authorize token?") %></legend>
- <% end %>
+ <div class="h-box">
+ <form class="pure-form pure-form-aligned" action="/authorize_token" method="post">
+ <% if callback_url %>
+ <legend><%= translate(locale, "Authorize token for `x`?", "#{callback_url.scheme}://#{callback_url.host}") %></legend>
+ <% else %>
+ <legend><%= translate(locale, "Authorize token?") %></legend>
+ <% end %>
- <div class="pure-g">
- <div class="pure-u-1">
- <ul>
- <% scopes.each do |scope| %>
- <li><%= scope %></li>
- <% end %>
- </ul>
+ <div class="pure-g">
+ <div class="pure-u-1">
+ <ul>
+ <% scopes.each do |scope| %>
+ <li><%= scope %></li>
+ <% end %>
+ </ul>
+ </div>
</div>
- </div>
- <div class="pure-g">
- <div class="pure-u-1-2">
- <button type="submit" name="submit" value="clear_watch_history" class="pure-button pure-button-primary">
- <%= translate(locale, "Yes") %>
- </button>
- </div>
- <div class="pure-u-1-2">
- <% if callback_url %>
- <a class="pure-button" href="<%= callback_url %>">
- <% else %>
- <a class="pure-button" href="/">
- <% end %>
+ <div class="pure-g">
+ <div class="pure-u-1-2">
+ <button type="submit" name="submit" value="clear_watch_history" class="pure-button pure-button-primary">
+ <%= translate(locale, "Yes") %>
+ </button>
+ </div>
+ <div class="pure-u-1-2">
+ <% if callback_url %>
+ <a class="pure-button" href="<%= callback_url %>">
+ <% else %>
+ <a class="pure-button" href="/">
+ <% end %>
<%= translate(locale, "No") %>
- </a>
+ </a>
+ </div>
</div>
- </div>
- <% scopes.each_with_index do |scope, i| %>
- <input type="hidden" name="scopes[<%= i %>]" value="<%= scope %>">
- <% end %>
- <% if callback_url %>
- <input type="hidden" name="callbackUrl" value="<%= callback_url %>">
- <% end %>
- <% if expire %>
- <input type="hidden" name="expire" value="<%= expire %>">
- <% end %>
+ <% scopes.each_with_index do |scope, i| %>
+ <input type="hidden" name="scopes[<%= i %>]" value="<%= scope %>">
+ <% end %>
+ <% if callback_url %>
+ <input type="hidden" name="callbackUrl" value="<%= callback_url %>">
+ <% end %>
+ <% if expire %>
+ <input type="hidden" name="expire" value="<%= expire %>">
+ <% end %>
- <input type="hidden" name="csrf_token" value="<%= URI.escape(csrf_token) %>">
- </form>
-</div>
-<% end %> \ No newline at end of file
+ <input type="hidden" name="csrf_token" value="<%= URI.escape(csrf_token) %>">
+ </form>
+ </div>
+<% end %>
diff --git a/src/invidious/views/channel.ecr b/src/invidious/views/channel.ecr
index d52c01ca..6737c0d2 100644
--- a/src/invidious/views/channel.ecr
+++ b/src/invidious/views/channel.ecr
@@ -7,7 +7,7 @@
<div class="pure-u-2-3">
<h3><%= author %></h3>
</div>
- <div class="pure-u-1-3" style="text-align:right;">
+ <div class="pure-u-1-3" style="text-align:right">
<h3>
<a href="/feed/channel/<%= ucid %>"><i class="icon ion-logo-rss"></i></a>
</h3>
@@ -15,41 +15,40 @@
</div>
<div class="h-box">
-<% sub_count_text = number_to_short_text(sub_count) %>
-<%= rendered "components/subscribe_widget" %>
+ <% sub_count_text = number_to_short_text(sub_count) %>
+ <%= rendered "components/subscribe_widget" %>
</div>
<div class="pure-g h-box">
<div class="pure-u-1-3">
<a href="https://www.youtube.com/channel/<%= ucid %>"><%= translate(locale, "View channel on YouTube") %></a>
<% if !auto_generated %>
- <div class="pure-u-1 pure-md-1-3">
- <b><%= translate(locale, "Videos") %></b>
- </div>
+ <div class="pure-u-1 pure-md-1-3">
+ <b><%= translate(locale, "Videos") %></b>
+ </div>
<% end %>
<div class="pure-u-1 pure-md-1-3">
- <% if auto_generated %>
- <b><%= translate(locale, "Playlists") %></b>
- <% else %>
- <a href="/channel/<%= ucid %>/playlists"><%= translate(locale, "Playlists") %></a>
- <% end %>
+ <% if auto_generated %>
+ <b><%= translate(locale, "Playlists") %></b>
+ <% else %>
+ <a href="/channel/<%= ucid %>/playlists"><%= translate(locale, "Playlists") %></a>
+ <% end %>
</div>
</div>
+ <div class="pure-u-1-3"></div>
<div class="pure-u-1-3">
- </div>
- <div class="pure-u-1-3">
- <div class="pure-g" style="text-align:right;">
- <% sort_options.each do |sort| %>
- <div class="pure-u-1 pure-md-1-3">
- <% if sort_by == sort %>
- <b><%= translate(locale, sort) %></b>
- <% else %>
- <a href="/channel/<%= ucid %>?page=<%= page %>&sort_by=<%= sort %>">
- <%= translate(locale, sort) %>
- </a>
- <% end %>
- </div>
- <% end %>
+ <div class="pure-g" style="text-align:right">
+ <% sort_options.each do |sort| %>
+ <div class="pure-u-1 pure-md-1-3">
+ <% if sort_by == sort %>
+ <b><%= translate(locale, sort) %></b>
+ <% else %>
+ <a href="/channel/<%= ucid %>?page=<%= page %>&sort_by=<%= sort %>">
+ <%= translate(locale, sort) %>
+ </a>
+ <% end %>
+ </div>
+ <% end %>
</div>
</div>
</div>
@@ -59,28 +58,28 @@
</div>
<div class="pure-g">
-<% items.each_slice(4) do |slice| %>
- <% slice.each do |item| %>
- <%= rendered "components/item" %>
+ <% items.each_slice(4) do |slice| %>
+ <% slice.each do |item| %>
+ <%= rendered "components/item" %>
+ <% end %>
<% end %>
-<% end %>
</div>
<div class="pure-g h-box">
<div class="pure-u-1 pure-u-lg-1-5">
- <% if page >= 2 %>
- <a href="/channel/<%= ucid %>?page=<%= page - 1 %><% if sort_by != "newest" %>&sort_by=<%= sort_by %><% end %>">
- <%= translate(locale, "Previous page") %>
- </a>
- <% end %>
+ <% if page >= 2 %>
+ <a href="/channel/<%= ucid %>?page=<%= page - 1 %><% if sort_by != "newest" %>&sort_by=<%= sort_by %><% end %>">
+ <%= translate(locale, "Previous page") %>
+ </a>
+ <% end %>
</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">
- <% if count == 60 %>
- <a href="/channel/<%= ucid %>?page=<%= page + 1 %><% if sort_by != "newest" %>&sort_by=<%= sort_by %><% end %>">
- <%= translate(locale, "Next page") %>
- </a>
- <% end %>
+ <div class="pure-u-1 pure-u-lg-1-5" style="text-align:right">
+ <% if count == 60 %>
+ <a href="/channel/<%= ucid %>?page=<%= page + 1 %><% if sort_by != "newest" %>&sort_by=<%= sort_by %><% end %>">
+ <%= translate(locale, "Next page") %>
+ </a>
+ <% end %>
</div>
</div>
diff --git a/src/invidious/views/components/feed_menu.ecr b/src/invidious/views/components/feed_menu.ecr
index 378601a1..9867f56f 100644
--- a/src/invidious/views/components/feed_menu.ecr
+++ b/src/invidious/views/components/feed_menu.ecr
@@ -4,16 +4,16 @@
<div class="pure-g">
<% feed_menu = config.feed_menu.dup %>
<% if !env.get?("user") %>
- <% feed_menu.reject! {|feed| feed == "Subscriptions"} %>
+ <% feed_menu.reject! {|feed| feed == "Subscriptions"} %>
<% end %>
<% feed_menu.each do |feed| %>
- <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">
- <%= translate(locale, feed) %>
- </a>
- </div>
+ <div class="pure-u-1-2 pure-u-md-1-<%= feed_menu.size %>">
+ <a href="/feed/<%= feed.downcase %>" class="pure-menu-heading" style="text-align:center">
+ <%= translate(locale, feed) %>
+ </a>
+ </div>
<% end %>
</div>
</div>
<div class="pure-u-1 pure-u-md-1-4"></div>
-</div> \ No newline at end of file
+</div>
diff --git a/src/invidious/views/components/item.ecr b/src/invidious/views/components/item.ecr
index 484a340f..e9f03982 100644
--- a/src/invidious/views/components/item.ecr
+++ b/src/invidious/views/components/item.ecr
@@ -1,133 +1,138 @@
<div class="pure-u-1 pure-u-md-1-4">
<div class="h-box">
- <% case item when %>
- <% when SearchChannel %>
- <a style="width:100%;" href="/channel/<%= item.ucid %>">
- <% if env.get("preferences").as(Preferences).thin_mode %>
- <% else %>
- <center>
- <img style="width:56.25%;" src="/ggpht<%= URI.parse(item.author_thumbnail).full_path %>"/>
- </center>
- <% end %>
- <p><%= item.author %></p>
- </a>
- <p><%= translate(locale, "`x` subscribers", number_with_separator(item.subscriber_count)) %></p>
- <p><%= translate(locale, "`x` videos", number_with_separator(item.video_count)) %></p>
- <h5><%= item.description_html %></h5>
- <% when SearchPlaylist %>
- <% if item.id.starts_with? "RD" %>
- <% url = "/mix?list=#{item.id}&continuation=#{item.thumbnail_id}" %>
- <% else %>
- <% url = "/playlist?list=#{item.id}" %>
- <% end %>
- <a style="width:100%;" href="<%= url %>">
- <% if env.get("preferences").as(Preferences).thin_mode %>
+ <% case item when %>
+ <% when SearchChannel %>
+ <a style="width:100%" href="/channel/<%= item.ucid %>">
+ <% if !env.get("preferences").as(Preferences).thin_mode %>
+ <center>
+ <img style="width:56.25%" src="/ggpht<%= URI.parse(item.author_thumbnail).full_path %>"/>
+ </center>
+ <% end %>
+ <p><%= item.author %></p>
+ </a>
+ <p><%= translate(locale, "`x` subscribers", number_with_separator(item.subscriber_count)) %></p>
+ <p><%= translate(locale, "`x` videos", number_with_separator(item.video_count)) %></p>
+ <h5><%= item.description_html %></h5>
+ <% when SearchPlaylist %>
+ <% if item.id.starts_with? "RD" %>
+ <% url = "/mix?list=#{item.id}&continuation=#{item.thumbnail_id}" %>
<% else %>
- <div class="thumbnail">
- <img class="thumbnail" src="/vi/<%= item.thumbnail_id %>/mqdefault.jpg"/>
- <p class="length"><%= number_with_separator(item.video_count) %> videos</p>
- </div>
+ <% url = "/playlist?list=#{item.id}" %>
<% end %>
- <p><%= item.title %></p>
- </a>
- <p>
- <b><a style="width:100%;" href="/channel/<%= item.ucid %>"><%= item.author %></a></b>
- </p>
- <% when MixVideo %>
- <a style="width:100%;" href="/watch?v=<%= item.id %>&list=<%= item.mixes[0] %>">
- <% if env.get("preferences").as(Preferences).thin_mode %>
- <% else %>
- <div class="thumbnail">
- <img class="thumbnail" src="/vi/<%= item.id %>/mqdefault.jpg"/>
- <% if item.length_seconds != 0 %>
- <p class="length"><%= recode_length_seconds(item.length_seconds) %></p>
+
+ <a style="width:100%" href="<%= url %>">
+ <% if !env.get("preferences").as(Preferences).thin_mode %>
+ <div class="thumbnail">
+ <img class="thumbnail" src="/vi/<%= item.thumbnail_id %>/mqdefault.jpg"/>
+ <p class="length"><%= number_with_separator(item.video_count) %> videos</p>
+ </div>
<% end %>
- </div>
- <% end %>
- <p><%= item.title %></p>
- </a>
- <p>
- <b><a style="width:100%;" href="/channel/<%= item.ucid %>"><%= item.author %></a></b>
- </p>
- <% when PlaylistVideo %>
- <a style="width:100%;" href="/watch?v=<%= item.id %>&list=<%= item.playlists[0] %>">
- <% if env.get("preferences").as(Preferences).thin_mode %>
- <% else %>
- <div class="thumbnail">
- <img class="thumbnail" src="/vi/<%= item.id %>/mqdefault.jpg"/>
- <% if item.responds_to?(:live_now) && item.live_now %>
- <p class="length"><i class="icon ion-ios-play-circle"></i> <%= translate(locale, "LIVE") %></p>
- <% elsif item.length_seconds != 0 %>
- <p class="length"><%= recode_length_seconds(item.length_seconds) %></p>
+ <p><%= item.title %></p>
+ </a>
+ <p>
+ <b>
+ <a style="width:100%" href="/channel/<%= item.ucid %>"><%= item.author %></a>
+ </b>
+ </p>
+ <% when MixVideo %>
+ <a style="width:100%" href="/watch?v=<%= item.id %>&list=<%= item.mixes[0] %>">
+ <% if !env.get("preferences").as(Preferences).thin_mode %>
+ <div class="thumbnail">
+ <img class="thumbnail" src="/vi/<%= item.id %>/mqdefault.jpg"/>
+ <% if item.length_seconds != 0 %>
+ <p class="length"><%= recode_length_seconds(item.length_seconds) %></p>
+ <% end %>
+ </div>
<% end %>
- </div>
- <% end %>
- <p><%= item.title %></p>
- </a>
- <p>
- <b><a style="width:100%;" href="/channel/<%= item.ucid %>"><%= item.author %></a></b>
- </p>
+ <p><%= item.title %></p>
+ </a>
+ <p>
+ <b>
+ <a style="width:100%" href="/channel/<%= item.ucid %>"><%= item.author %></a>
+ </b>
+ </p>
+ <% when PlaylistVideo %>
+ <a style="width:100%" href="/watch?v=<%= item.id %>&list=<%= item.playlists[0] %>">
+ <% if !env.get("preferences").as(Preferences).thin_mode %>
+ <div class="thumbnail">
+ <img class="thumbnail" src="/vi/<%= item.id %>/mqdefault.jpg"/>
+ <% if item.responds_to?(:live_now) && item.live_now %>
+ <p class="length"><i class="icon ion-ios-play-circle"></i> <%= translate(locale, "LIVE") %></p>
+ <% elsif item.length_seconds != 0 %>
+ <p class="length"><%= recode_length_seconds(item.length_seconds) %></p>
+ <% end %>
+ </div>
+ <% end %>
+ <p><%= item.title %></p>
+ </a>
+ <p>
+ <b>
+ <a style="width:100%" href="/channel/<%= item.ucid %>"><%= item.author %></a>
+ </b>
+ </p>
- <h5 class="pure-g">
- <% if item.responds_to?(:premiere_timestamp) && item.premiere_timestamp && item.premiere_timestamp.not_nil! > Time.now %>
- <%= translate(locale, "Premieres in `x`", recode_date((item.premiere_timestamp.as(Time) - Time.now).ago, locale)) %></h5>
- <% elsif Time.now - item.published > 1.minute %>
- <div class="pure-u-2-3"><%= translate(locale, "Shared `x` ago", recode_date(item.published, locale)) %></div>
- <% else %>
- <div class="pure-u-2-3"></div>
- <% end %>
+ <h5 class="pure-g">
+ <% if item.responds_to?(:premiere_timestamp) && item.premiere_timestamp && item.premiere_timestamp.not_nil! > Time.now %>
+ <%= translate(locale, "Premieres in `x`", recode_date((item.premiere_timestamp.as(Time) - Time.now).ago, locale)) %></h5>
+ <% elsif Time.now - item.published > 1.minute %>
+ <div class="pure-u-2-3"><%= translate(locale, "Shared `x` ago", recode_date(item.published, locale)) %></div>
+ <% else %>
+ <div class="pure-u-2-3"></div>
+ <% end %>
- <div class="pure-u-1-3" style="text-align: right">
- <%= item.responds_to?(:views) ? translate(locale, "`x` views", number_to_short_text(item.views)) : "" %>
- </div>
- </h5>
- <% else %>
- <% if env.get("preferences").as(Preferences).thin_mode %>
+ <div class="pure-u-1-3" style="text-align:right">
+ <%= item.responds_to?(:views) ? translate(locale, "`x` views", number_to_short_text(item.views)) : "" %>
+ </div>
+ </h5>
<% else %>
- <a style="width:100%;" href="/watch?v=<%= item.id %>">
- <div class="thumbnail">
- <img class="thumbnail" src="/vi/<%= item.id %>/mqdefault.jpg"/>
- <% 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">
- <input type="hidden" name="csrf_token" value="<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>">
- <p class="watched">
- <a onclick="mark_watched(this)" data-id="<%= item.id %>" href="#">
- <button type="submit" style="all:unset">
- <i onmouseenter='this.setAttribute("class", "icon ion-ios-eye-off")'
- onmouseleave='this.setAttribute("class", "icon ion-ios-eye")'
- class="icon ion-ios-eye">
- </i>
- </button>
- </a>
- </p>
- </form>
- <% end %>
- <% if item.responds_to?(:live_now) && item.live_now %>
- <p class="length"><i class="icon ion-ios-play-circle"></i> <%= translate(locale, "LIVE") %></p>
- <% elsif item.length_seconds != 0 %>
- <p class="length"><%= recode_length_seconds(item.length_seconds) %></p>
- <% end %>
- </div>
- </a>
- <% end %>
- <p><a href="/watch?v=<%= item.id %>"><%= item.title %></a></p>
- <p>
- <b><a style="width:100%;" href="/channel/<%= item.ucid %>"><%= item.author %></a></b>
- </p>
+ <% if !env.get("preferences").as(Preferences).thin_mode %>
+ <a style="width:100%" href="/watch?v=<%= item.id %>">
+ <div class="thumbnail">
+ <img class="thumbnail" src="/vi/<%= item.id %>/mqdefault.jpg"/>
+ <% 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">
+ <input type="hidden" name="csrf_token" value="<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>">
+ <p class="watched">
+ <a onclick="mark_watched(this)" data-id="<%= item.id %>" href="#">
+ <button type="submit" style="all:unset">
+ <i onmouseenter='this.setAttribute("class", "icon ion-ios-eye-off")'
+ onmouseleave='this.setAttribute("class", "icon ion-ios-eye")'
+ class="icon ion-ios-eye">
+ </i>
+ </button>
+ </a>
+ </p>
+ </form>
+ <% end %>
- <h5 class="pure-g">
- <% if item.responds_to?(:premiere_timestamp) && item.premiere_timestamp && item.premiere_timestamp.not_nil! > Time.now %>
- <%= translate(locale, "Premieres in `x`", recode_date((item.premiere_timestamp.as(Time) - Time.now).ago, locale)) %></h5>
- <% elsif Time.now - item.published > 1.minute %>
- <div class="pure-u-2-3"><%= translate(locale, "Shared `x` ago", recode_date(item.published, locale)) %></div>
- <% else %>
- <div class="pure-u-2-3"></div>
+ <% if item.responds_to?(:live_now) && item.live_now %>
+ <p class="length"><i class="icon ion-ios-play-circle"></i> <%= translate(locale, "LIVE") %></p>
+ <% elsif item.length_seconds != 0 %>
+ <p class="length"><%= recode_length_seconds(item.length_seconds) %></p>
+ <% end %>
+ </div>
+ </a>
<% end %>
+ <p><a href="/watch?v=<%= item.id %>"><%= item.title %></a></p>
+ <p>
+ <b>
+ <a style="width:100%" href="/channel/<%= item.ucid %>"><%= item.author %></a>
+ </b>
+ </p>
- <div class="pure-u-1-3" style="text-align: right">
- <%= item.responds_to?(:views) ? translate(locale, "`x` views", number_to_short_text(item.views)) : "" %>
- </div>
- </h5>
- <% end %>
+ <h5 class="pure-g">
+ <% if item.responds_to?(:premiere_timestamp) && item.premiere_timestamp && item.premiere_timestamp.not_nil! > Time.now %>
+ <%= translate(locale, "Premieres in `x`", recode_date((item.premiere_timestamp.as(Time) - Time.now).ago, locale)) %></h5>
+ <% elsif Time.now - item.published > 1.minute %>
+ <div class="pure-u-2-3"><%= translate(locale, "Shared `x` ago", recode_date(item.published, locale)) %></div>
+ <% else %>
+ <div class="pure-u-2-3"></div>
+ <% end %>
+
+ <div class="pure-u-1-3" style="text-align:right">
+ <%= item.responds_to?(:views) ? translate(locale, "`x` views", number_to_short_text(item.views)) : "" %>
+ </div>
+ </h5>
+ <% end %>
</div>
</div>
diff --git a/src/invidious/views/components/player.ecr b/src/invidious/views/components/player.ecr
index eecaf160..6ad70033 100644
--- a/src/invidious/views/components/player.ecr
+++ b/src/invidious/views/components/player.ecr
@@ -25,161 +25,163 @@
<source src="/latest_version?id=<%= video.id %>&itag=<%= fmt["itag"] %><% if params.local %>&local=true<% end %>" type='<%= fmt["type"] %>' label="<%= fmt["label"] %>" selected="<%= i == 0 ? true : false %>">
<% end %>
<% end %>
- <% end %>
+ <% end %>
<% preferred_captions.each_with_index do |caption, i| %>
- <track kind="captions" src="/api/v1/captions/<%= video.id %>?label=<%= caption.name.simpleText %>&hl=<%= env.get("preferences").as(Preferences).locale %>"
- label="<%= caption.name.simpleText %>" <% if i == 0 %>default<% end %>>
+ <track kind="captions" src="/api/v1/captions/<%= video.id %>?label=<%= caption.name.simpleText %>&hl=<%= env.get("preferences").as(Preferences).locale %>"
+ label="<%= caption.name.simpleText %>" <% if i == 0 %>default<% end %>>
<% end %>
<% captions.each do |caption| %>
- <track kind="captions" src="/api/v1/captions/<%= video.id %>?label=<%= caption.name.simpleText %>&hl=<%= env.get("preferences").as(Preferences).locale %>"
- label="<%= caption.name.simpleText %>">
+ <track kind="captions" src="/api/v1/captions/<%= video.id %>?label=<%= caption.name.simpleText %>&hl=<%= env.get("preferences").as(Preferences).locale %>"
+ label="<%= caption.name.simpleText %>">
<% end %>
<% end %>
</video>
<script>
var options = {
- <% if aspect_ratio %>
- aspectRatio: "<%= aspect_ratio %>",
- <% end %>
- preload: "auto",
- playbackRates: [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 2.0],
- controlBar: {
- children: [
- "playToggle",
- "volumePanel",
- "currentTimeDisplay",
- "timeDivider",
- "durationDisplay",
- "progressControl",
- "remainingTimeDisplay",
- "captionsButton",
- "qualitySelector",
- "playbackRateMenuButton",
- "fullscreenToggle"
- ]
- }
+ <% if aspect_ratio %>
+ aspectRatio: "<%= aspect_ratio %>",
+ <% end %>
+ preload: "auto",
+ playbackRates: [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 2.0],
+ controlBar: {
+ children: [
+ "playToggle",
+ "volumePanel",
+ "currentTimeDisplay",
+ "timeDivider",
+ "durationDisplay",
+ "progressControl",
+ "remainingTimeDisplay",
+ "captionsButton",
+ "qualitySelector",
+ "playbackRateMenuButton",
+ "fullscreenToggle"
+ ]
+ }
};
var shareOptions = {
- socials: ["fbFeed", "tw", "reddit", "email"],
+ socials: ["fbFeed", "tw", "reddit", "email"],
- url: window.location.href,
- title: "<%= video.title.dump_unquoted %>",
- description: "<%= description %>",
- image: "<%= thumbnail %>",
- embedCode: "<iframe id='ivplayer' type='text/html' width='640' height='360' \
- src='<%= host_url %>/embed/<%= video.id %>?<%= host_params %>' frameborder='0'></iframe>"
+ url: window.location.href,
+ title: "<%= video.title.dump_unquoted %>",
+ description: "<%= description %>",
+ image: "<%= thumbnail %>",
+ embedCode: "<iframe id='ivplayer' type='text/html' width='640' height='360' \
+ src='<%= host_url %>/embed/<%= video.id %>?<%= host_params %>' frameborder='0'></iframe>"
};
var player = videojs("player", options, function() {
- this.hotkeys({
- volumeStep: 0.1,
- seekStep: 5,
- enableModifiersForNumbers: false,
- enableHoverScroll: true,
- customKeys: {
- // Toggle play with K Key
- play: {
- key: function(e) {
- return e.which === 75;
- },
- handler: function(player, options, e) {
- if (player.paused()) {
- player.play();
- } else {
- player.pause();
- }
- }
- },
- // Go backward 5 seconds
- backward: {
- key: function(e) {
- return e.which === 74;
- },
- handler: function(player, options, e) {
- player.currentTime(player.currentTime() - 10);
- }
- },
- // Go forward 5 seconds
- forward: {
- key: function(e) {
- return e.which === 76;
- },
- handler: function(player, options, e) {
- player.currentTime(player.currentTime() + 10);
+ this.hotkeys({
+ volumeStep: 0.1,
+ seekStep: 5,
+ enableModifiersForNumbers: false,
+ enableHoverScroll: true,
+ customKeys: {
+ // Toggle play with K Key
+ play: {
+ key: function(e) {
+ return e.which === 75;
+ },
+ handler: function(player, options, e) {
+ if (player.paused()) {
+ player.play();
+ } else {
+ player.pause();
+ }
+ }
+ },
+ // Go backward 10 seconds
+ backward: {
+ key: function(e) {
+ return e.which === 74;
+ },
+ handler: function(player, options, e) {
+ player.currentTime(player.currentTime() - 10);
+ }
+ },
+ // Go forward 10 seconds
+ forward: {
+ key: function(e) {
+ return e.which === 76;
+ },
+ handler: function(player, options, e) {
+ player.currentTime(player.currentTime() + 10);
+ }
+ },
+ // Increase speed
+ increase_speed: {
+ key: function(e) {
+ return (e.which === 190 && e.shiftKey);
+ },
+ handler: function(player, _, e) {
+ size = options.playbackRates.length;
+ index = options.playbackRates.indexOf(player.playbackRate());
+ player.playbackRate(options.playbackRates[(index + 1) % size]);
+ }
+ },
+ // Decrease speed
+ decrease_speed: {
+ key: function(e) {
+ return (e.which === 188 && e.shiftKey);
+ },
+ handler: function(player, _, e) {
+ size = options.playbackRates.length;
+ index = options.playbackRates.indexOf(player.playbackRate());
+ player.playbackRate(options.playbackRates[(size + index - 1) % size]);
+ }
+ }
}
- },
- // Increase speed
- increase_speed: {
- key: function(e) {
- return (e.which === 190 && e.shiftKey);
- },
- handler: function(player, _, e) {
- size = options.playbackRates.length;
- index = options.playbackRates.indexOf(player.playbackRate());
- player.playbackRate(options.playbackRates[(index + 1) % size]);
- }
- },
- // Decrease speed
- decrease_speed: {
- key: function(e) {
- return (e.which === 188 && e.shiftKey);
- },
- handler: function(player, _, e) {
- size = options.playbackRates.length;
- index = options.playbackRates.indexOf(player.playbackRate());
- player.playbackRate(options.playbackRates[(size + index - 1) % size]);
- }
- }
- }
- });
+ });
});
player.on('error', function(event) {
- if (player.error().code === 2 || player.error().code === 4) {
- setInterval(setTimeout(function (event) {
- console.log("An error occured in the player, reloading...");
+ if (player.error().code === 2 || player.error().code === 4) {
+ setInterval(setTimeout(function (event) {
+ console.log('An error occured in the player, reloading...');
+
+ var currentTime = player.currentTime();
+ var playbackRate = player.playbackRate();
+ var paused = player.paused();
- var currentTime = player.currentTime();
- var playbackRate = player.playbackRate();
- var paused = player.paused();
+ player.load();
- player.load();
- if (currentTime > 0.5) {
- currentTime -= 0.5;
- }
- player.currentTime(currentTime);
- player.playbackRate(playbackRate);
+ if (currentTime > 0.5) {
+ currentTime -= 0.5;
+ }
- if (!paused) {
- player.play();
- }
- }, 5000), 5000);
- }
+ player.currentTime(currentTime);
+ player.playbackRate(playbackRate);
+
+ if (!paused) {
+ player.play();
+ }
+ }, 5000), 5000);
+ }
});
<% if params.video_start > 0 || params.video_end > 0 %>
player.markers({
- onMarkerReached: function(marker) {
- if (marker.text === "End") {
- if (player.loop()) {
- player.markers.prev("Start");
- } else {
- player.pause();
- }
- }
- },
- markers: [
- { time: <%= params.video_start %>, text: "Start" },
- <% if params.video_end < 0 %>
- { time: <%= video.info["length_seconds"].to_f - 0.5 %>, text: "End" }
- <% else %>
- { time: <%= params.video_end %>, text: "End" }
- <% end %>
- ]
+ onMarkerReached: function(marker) {
+ if (marker.text === 'End') {
+ if (player.loop()) {
+ player.markers.prev('Start');
+ } else {
+ player.pause();
+ }
+ }
+ },
+ markers: [
+ { time: <%= params.video_start %>, text: 'Start' },
+ <% if params.video_end < 0 %>
+ { time: <%= video.info["length_seconds"].to_f - 0.5 %>, text: 'End' }
+ <% else %>
+ { time: <%= params.video_end %>, text: 'End' }
+ <% end %>
+ ]
});
player.currentTime(<%= params.video_start %>);
@@ -192,20 +194,20 @@ player.playbackRate(<%= params.speed %>);
var bpb = player.getChild('bigPlayButton');
if (bpb) {
- bpb.hide();
+ bpb.hide();
- player.ready(function() {
- new Promise(function(resolve, reject) {
- setTimeout(() => resolve(1), 1);
- }).then(function(result) {
- var promise = player.play();
+ player.ready(function() {
+ new Promise(function(resolve, reject) {
+ setTimeout(() => resolve(1), 1);
+ }).then(function(result) {
+ var promise = player.play();
- if (promise !== undefined) {
- promise.then(_ => {
- }).catch(error => {
- bpb.show();
- });
- }
+ if (promise !== undefined) {
+ promise.then(_ => {
+ }).catch(error => {
+ bpb.show();
+ });
+ }
});
});
}
@@ -216,44 +218,42 @@ player.httpSourceSelector();
<% end %>
<% if !params.listen && params.annotations %>
-var video_container = document.getElementById("player");
+var video_container = document.getElementById('player');
let xhr = new XMLHttpRequest();
-xhr.responseType = "text";
+xhr.responseType = 'text';
xhr.timeout = 60000;
-xhr.open("GET", "/api/v1/annotations/<%= video.id %>", true);
+xhr.open('GET', '/api/v1/annotations/<%= video.id %>', true);
xhr.send();
xhr.onreadystatechange = function () {
- if (xhr.readyState === 4) {
- if (xhr.status === 200) {
- videojs.registerPlugin("youtubeAnnotationsPlugin", youtubeAnnotationsPlugin);
- if (!player.paused()) {
- player.youtubeAnnotationsPlugin({annotationXml: xhr.response, videoContainer: video_container});
- } else {
- player.one('play', function(event) {
- player.youtubeAnnotationsPlugin({annotationXml: xhr.response, videoContainer: video_container});
- });
- }
+ if (xhr.readyState === 4) {
+ if (xhr.status === 200) {
+ videojs.registerPlugin('youtubeAnnotationsPlugin', youtubeAnnotationsPlugin);
+ if (!player.paused()) {
+ player.youtubeAnnotationsPlugin({annotationXml: xhr.response, videoContainer: video_container});
+ } else {
+ player.one('play', function(event) {
+ player.youtubeAnnotationsPlugin({annotationXml: xhr.response, videoContainer: video_container});
+ });
+ }
+ }
}
- }
};
-window.addEventListener("__ar_annotation_click", e => {
+window.addEventListener('__ar_annotation_click', e => {
const { url, target, seconds } = e.detail;
-
var path = new URL(url);
- if (path.href.startsWith("https://www.youtube.com/watch?") && seconds) {
- path.search += "&t=" + seconds;
+ if (path.href.startsWith('https://www.youtube.com/watch?') && seconds) {
+ path.search += '&t=' + seconds;
}
path = path.pathname + path.search;
- if (target === "current") {
+ if (target === 'current') {
window.location.href = path;
- }
- else if (target === "new") {
- window.open(path, "_blank");
+ } else if (target === 'new') {
+ window.open(path, '_blank');
}
});
<% end %>
diff --git a/src/invidious/views/components/player_sources.ecr b/src/invidious/views/components/player_sources.ecr
index d51697c1..f446248e 100644
--- a/src/invidious/views/components/player_sources.ecr
+++ b/src/invidious/views/components/player_sources.ecr
@@ -8,11 +8,13 @@
<script src="/js/videojs.hotkeys.min.js"></script>
<script src="/js/videojs-markers.min.js"></script>
<script src="/js/videojs-share.min.js"></script>
+
<% if params.annotations %>
-<link rel="stylesheet" href="/css/videojs-youtube-annotations.min.css">
-<script src="/js/videojs-youtube-annotations.min.js"></script>
+ <link rel="stylesheet" href="/css/videojs-youtube-annotations.min.css">
+ <script src="/js/videojs-youtube-annotations.min.js"></script>
<% end %>
+
<% if params.listen || params.quality != "dash" %>
-<link rel="stylesheet" href="/css/quality-selector.css">
-<script src="/js/silvermine-videojs-quality-selector.min.js"></script>
-<% end %> \ No newline at end of file
+ <link rel="stylesheet" href="/css/quality-selector.css">
+ <script src="/js/silvermine-videojs-quality-selector.min.js"></script>
+<% end %>
diff --git a/src/invidious/views/components/subscribe_widget.ecr b/src/invidious/views/components/subscribe_widget.ecr
index 7988d2f1..a3d6a55f 100644
--- a/src/invidious/views/components/subscribe_widget.ecr
+++ b/src/invidious/views/components/subscribe_widget.ecr
@@ -1,22 +1,22 @@
<% if user %>
<% if subscriptions.includes? ucid %>
- <p>
- <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) || "") %>">
- <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>
- </a>
- </form>
- </p>
+ <p>
+ <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) || "") %>">
+ <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>
+ </a>
+ </form>
+ </p>
<% else %>
- <p>
- <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) || "") %>">
- <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>
- </a>
- </form>
- </p>
+ <p>
+ <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) || "") %>">
+ <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>
+ </a>
+ </form>
+ </p>
<% end %>
<% else %>
<p>
diff --git a/src/invidious/views/components/subscribe_widget_script.ecr b/src/invidious/views/components/subscribe_widget_script.ecr
index f8c7416a..107bd3a2 100644
--- a/src/invidious/views/components/subscribe_widget_script.ecr
+++ b/src/invidious/views/components/subscribe_widget_script.ecr
@@ -1,27 +1,29 @@
-subscribe_button = document.getElementById("subscribe");
+subscribe_button = document.getElementById('subscribe');
+
if (subscribe_button.getAttribute('onclick')) {
- subscribe_button["href"] = "javascript:void(0)";
+ subscribe_button['href'] = 'javascript:void(0)';
}
function subscribe(timeouts = 0) {
- subscribe_button = document.getElementById("subscribe");
+ subscribe_button = document.getElementById('subscribe');
if (timeouts > 10) {
- console.log("Failed to subscribe.");
+ console.log('Failed to subscribe.');
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();
- xhr.responseType = "json";
+ xhr.responseType = 'json';
xhr.timeout = 20000;
- xhr.open("POST", url, true);
+ xhr.open('POST', url, true);
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;
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() {
if (xhr.readyState == 4) {
@@ -33,31 +35,31 @@ function subscribe(timeouts = 0) {
}
xhr.ontimeout = function() {
- console.log("Subscribing timed out.");
-
+ console.log('Subscribing timed out.');
subscribe(timeouts + 1);
};
}
function unsubscribe(timeouts = 0) {
- subscribe_button = document.getElementById("subscribe");
+ subscribe_button = document.getElementById('subscribe');
if (timeouts > 10) {
- console.log("Failed to subscribe");
+ console.log('Failed to subscribe');
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();
- xhr.responseType = "json";
+ xhr.responseType = 'json';
xhr.timeout = 20000;
- xhr.open("POST", url, true);
- xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
- xhr.send("csrf_token=<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>");
+ xhr.open('POST', url, true);
+ xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+ xhr.send('csrf_token=<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>');
var fallback = subscribe_button.innerHTML;
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() {
if (xhr.readyState == 4) {
@@ -69,8 +71,7 @@ function unsubscribe(timeouts = 0) {
}
xhr.ontimeout = function() {
- console.log("Unsubscribing timed out.");
-
+ console.log('Unsubscribing timed out.');
unsubscribe(timeouts + 1);
};
}
diff --git a/src/invidious/views/embed.ecr b/src/invidious/views/embed.ecr
index 51097df1..e08bad02 100644
--- a/src/invidious/views/embed.ecr
+++ b/src/invidious/views/embed.ecr
@@ -27,24 +27,26 @@
<script>
<% if plid %>
-function get_playlist(timeouts = 0) {
+function get_playlist(plid, timeouts = 0) {
if (timeouts > 10) {
- console.log("Failed to pull playlist");
+ console.log('Failed to pull playlist');
return;
}
- var plid = "<%= plid %>"
-
- if (plid.startsWith("RD")) {
- var plid_url = "/api/v1/mixes/<%= plid %>?continuation=<%= video.id %>&format=html&hl=<%= env.get("preferences").as(Preferences).locale %>";
+ if (plid.startsWith('RD')) {
+ var plid_url = '/api/v1/mixes/' + plid +
+ '?continuation=<%= video.id %>' +
+ '&format=html&hl=<%= env.get("preferences").as(Preferences).locale %>';
} 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();
- xhr.responseType = "json";
+ xhr.responseType = 'json';
xhr.timeout = 20000;
- xhr.open("GET", plid_url, true);
+ xhr.open('GET', plid_url, true);
xhr.send();
xhr.onreadystatechange = function() {
@@ -52,18 +54,18 @@ function get_playlist(timeouts = 0) {
if (xhr.status == 200) {
if (xhr.response.nextVideo) {
player.on('ended', function() {
- location.assign("/embed/"
- + xhr.response.nextVideo
- + "?list=<%= plid %>"
+ location.assign('/watch?v=' + xhr.response.nextVideo +
+ '&list=' + plid +
<% if params.listen != preferences.listen %>
- + "&listen=<%= params.listen %>"
+ '&listen=<%= params.listen %>' +
<% end %>
<% if params.autoplay || params.continue_autoplay %>
- + "&autoplay=1"
+ '&autoplay=1' +
<% end %>
<% if params.speed != preferences.speed %>
- + "&speed=<%= params.speed %>"
+ '&speed=<%= params.speed %>' +
<% end %>
+ ''
);
});
}
@@ -72,29 +74,29 @@ function get_playlist(timeouts = 0) {
};
xhr.ontimeout = function() {
- console.log("Pulling playlist timed out.");
- get_playlist(timeouts + 1);
+ console.log('Pulling playlist timed out.');
+ get_playlist(plid, timeouts + 1);
};
}
-get_playlist();
+get_playlist('<%= plid %>');
<% elsif video_series %>
player.on('ended', function() {
- location.assign("/embed/"
- + "<%= video_series.shift %>"
- <% if !video_series.empty? %>
- + "?playlist=<%= video_series.join(",") %>"
- <% end %>
- <% if params.listen != preferences.listen %>
- + "&listen=<%= params.listen %>"
- <% end %>
- <% if params.autoplay || params.continue_autoplay %>
- + "&autoplay=1"
- <% end %>
- <% if params.speed != preferences.speed %>
- + "&speed=<%= params.speed %>"
- <% end %>
- );
+ location.assign('/embed/<%= video_series.shift %>' +
+ <% if !video_series.empty? %>
+ '?playlist=<%= video_series.join(",") %>' +
+ <% end %>
+ <% if params.listen != preferences.listen %>
+ '&listen=<%= params.listen %>' +
+ <% end %>
+ <% if params.autoplay || params.continue_autoplay %>
+ '&autoplay=1' +
+ <% end %>
+ <% if params.speed != preferences.speed %>
+ '&speed=<%= params.speed %>' +
+ <% end %>
+ ''
+ );
});
<% end %>
</script>
diff --git a/src/invidious/views/error.ecr b/src/invidious/views/error.ecr
index e5572776..d0752e5b 100644
--- a/src/invidious/views/error.ecr
+++ b/src/invidious/views/error.ecr
@@ -3,5 +3,5 @@
<% end %>
<div class="h-box">
-<%= error_message %>
+ <%= error_message %>
</div>
diff --git a/src/invidious/views/history.ecr b/src/invidious/views/history.ecr
index a207145b..e7bf06d1 100644
--- a/src/invidious/views/history.ecr
+++ b/src/invidious/views/history.ecr
@@ -6,12 +6,12 @@
<div class="pure-u-1-3">
<h3><%= translate(locale, "`x` videos", %(<span id="count">#{user.watched.size}</span>)) %></h3>
</div>
- <div class="pure-u-1-3" style="text-align:center;">
+ <div class="pure-u-1-3" style="text-align:center">
<h3>
<a href="/feed/subscriptions"><%= translate(locale, "`x` subscriptions", %(<span id="count">#{user.subscriptions.size}</span>)) %></a>
</h3>
</div>
- <div class="pure-u-1-3" style="text-align:right;">
+ <div class="pure-u-1-3" style="text-align:right">
<h3>
<a href="/clear_watch_history"><%= translate(locale, "Clear watch history") %></a>
</h3>
@@ -21,29 +21,28 @@
<div class="pure-g">
<% watched.each_slice(4) do |slice| %>
<% slice.each do |item| %>
- <div class="pure-u-1 pure-u-md-1-4">
- <div class="h-box">
- <a style="width:100%;" href="/watch?v=<%= item %>">
- <% if env.get("preferences").as(Preferences).thin_mode %>
- <% else %>
- <div class="thumbnail">
- <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">
- <input type="hidden" name="csrf_token" value="<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>">
- <p class="watched">
- <a onclick="mark_unwatched(this)" data-id="<%= item %>" href="#">
- <button type="submit" style="all:unset">
- <i class="icon ion-md-trash"></i>
- </button>
- </a>
- </p>
- </form>
- </div>
- <p></p>
- <% end %>
- </a>
+ <div class="pure-u-1 pure-u-md-1-4">
+ <div class="h-box">
+ <a style="width:100%" href="/watch?v=<%= item %>">
+ <% if !env.get("preferences").as(Preferences).thin_mode %>
+ <div class="thumbnail">
+ <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">
+ <input type="hidden" name="csrf_token" value="<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>">
+ <p class="watched">
+ <a onclick="mark_unwatched(this)" data-id="<%= item %>" href="#">
+ <button type="submit" style="all:unset">
+ <i class="icon ion-md-trash"></i>
+ </button>
+ </a>
+ </p>
+ </form>
+ </div>
+ <p></p>
+ <% end %>
+ </a>
+ </div>
</div>
- </div>
<% end %>
<% end %>
</div>
@@ -52,22 +51,23 @@
function mark_unwatched(target) {
var tile = target.parentNode.parentNode.parentNode.parentNode.parentNode;
tile.style.display = "none";
- var count = document.getElementById("count")
+ var count = document.getElementById('count')
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();
- xhr.responseType = "json";
+ xhr.responseType = 'json';
xhr.timeout = 20000;
- xhr.open("POST", url, true);
- xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
- xhr.send("csrf_token=<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>");
+ xhr.open('POST', url, true);
+ xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+ xhr.send('csrf_token=<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>');
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status != 200) {
count.innerText = count.innerText - 1 + 2;
- tile.style.display = "";
+ tile.style.display = '';
}
}
}
@@ -76,18 +76,18 @@ function mark_unwatched(target) {
<div class="pure-g h-box">
<div class="pure-u-1 pure-u-lg-1-5">
- <% if page >= 2 %>
- <a href="/feed/history?page=<%= page - 1 %>">
- <%= translate(locale, "Previous page") %>
- </a>
- <% end %>
+ <% if page >= 2 %>
+ <a href="/feed/history?page=<%= page - 1 %>">
+ <%= translate(locale, "Previous page") %>
+ </a>
+ <% end %>
</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">
- <% if watched.size >= limit %>
- <a href="/feed/history?page=<%= page + 1 %>">
- <%= translate(locale, "Next page") %>
- </a>
- <% end %>
+ <div class="pure-u-1 pure-u-lg-1-5" style="text-align:right">
+ <% if watched.size >= limit %>
+ <a href="/feed/history?page=<%= page + 1 %>">
+ <%= translate(locale, "Next page") %>
+ </a>
+ <% end %>
</div>
</div>
diff --git a/src/invidious/views/licenses.ecr b/src/invidious/views/licenses.ecr
index a7798ff0..bab7762a 100644
--- a/src/invidious/views/licenses.ecr
+++ b/src/invidious/views/licenses.ecr
@@ -2,8 +2,8 @@
<html lang="en-US">
<head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
@@ -59,7 +59,7 @@
<td>
<a href="http://www.jclark.com/xml/copying.txt">Expat</a>
</td>
-
+
<td>
<a href="https://github.com/jfujita/videojs-http-source-selector"><%= translate(locale, "source") %></a>
</td>
@@ -136,4 +136,4 @@
</tr>
</table>
</body>
-</html> \ No newline at end of file
+</html>
diff --git a/src/invidious/views/login.ecr b/src/invidious/views/login.ecr
index 3acb2501..7fa25278 100644
--- a/src/invidious/views/login.ecr
+++ b/src/invidious/views/login.ecr
@@ -18,95 +18,97 @@
</a>
</div>
</div>
- <hr>
- <% if account_type == "invidious" %>
- <form class="pure-form pure-form-stacked" action="/login?referer=<%= URI.escape(referer) %>&type=invidious" method="post">
- <fieldset>
- <% if email %>
- <input name="email" type="hidden" value="<%= email %>">
- <% else %>
- <label for="email"><%= translate(locale, "User ID") %> :</label>
- <input required class="pure-input-1" name="email" type="text" placeholder="<%= translate(locale, "User ID") %>">
- <% end %>
- <% if password %>
- <input name="password" type="hidden" value="<%= password %>">
- <% else %>
- <label for="password"><%= translate(locale, "Password") %> :</label>
- <input required class="pure-input-1" name="password" type="password" placeholder="<%= translate(locale, "Password") %>">
- <% end %>
+ <hr>
- <% if captcha %>
- <% case captcha_type when %>
- <% when "image" %>
- <% captcha = captcha.not_nil! %>
- <img style="width:100%" src='<%= captcha[:question] %>'/>
- <% captcha[:tokens].each_with_index do |token, i| %>
- <input type="hidden" name="token[<%= i %>]" value="<%= URI.escape(token) %>">
+ <% if account_type == "invidious" %>
+ <form class="pure-form pure-form-stacked" action="/login?referer=<%= URI.escape(referer) %>&type=invidious" method="post">
+ <fieldset>
+ <% if email %>
+ <input name="email" type="hidden" value="<%= email %>">
+ <% else %>
+ <label for="email"><%= translate(locale, "User ID") %> :</label>
+ <input required class="pure-input-1" name="email" type="text" placeholder="<%= translate(locale, "User ID") %>">
<% end %>
- <input type="hidden" name="captcha_type" value="image">
- <label for="answer"><%= translate(locale, "Time (h:mm:ss):") %></label>
- <input type="text" name="answer" type="text" placeholder="h:mm:ss">
- <% when "text" %>
- <% captcha = captcha.not_nil! %>
- <% captcha[:tokens].each_with_index do |token, i| %>
- <input type="hidden" name="token[<%= i %>]" value="<%= URI.escape(token) %>">
+
+ <% if password %>
+ <input name="password" type="hidden" value="<%= password %>">
+ <% else %>
+ <label for="password"><%= translate(locale, "Password") %> :</label>
+ <input required class="pure-input-1" name="password" type="password" placeholder="<%= translate(locale, "Password") %>">
<% end %>
- <input type="hidden" name="captcha_type" value="text">
- <label for="answer"><%= captcha[:question] %></label>
- <input type="text" name="answer" type="text" placeholder="<%= translate(locale, "Answer") %>">
- <% end %>
- <button type="submit" name="action" value="signin" class="pure-button pure-button-primary">
- <%= translate(locale, "Register") %>
- </button>
+ <% if captcha %>
+ <% case captcha_type when %>
+ <% when "image" %>
+ <% captcha = captcha.not_nil! %>
+ <img style="width:100%" src='<%= captcha[:question] %>'/>
+ <% captcha[:tokens].each_with_index do |token, i| %>
+ <input type="hidden" name="token[<%= i %>]" value="<%= URI.escape(token) %>">
+ <% end %>
+ <input type="hidden" name="captcha_type" value="image">
+ <label for="answer"><%= translate(locale, "Time (h:mm:ss):") %></label>
+ <input type="text" name="answer" type="text" placeholder="h:mm:ss">
+ <% when "text" %>
+ <% captcha = captcha.not_nil! %>
+ <% captcha[:tokens].each_with_index do |token, i| %>
+ <input type="hidden" name="token[<%= i %>]" value="<%= URI.escape(token) %>">
+ <% end %>
+ <input type="hidden" name="captcha_type" value="text">
+ <label for="answer"><%= captcha[:question] %></label>
+ <input type="text" name="answer" type="text" placeholder="<%= translate(locale, "Answer") %>">
+ <% end %>
- <% case captcha_type when %>
- <% when "image" %>
- <label>
- <button type="submit" name="change_type" class="pure-button pure-button-primary" value="text">
- <%= translate(locale, "Text CAPTCHA") %>
+ <button type="submit" name="action" value="signin" class="pure-button pure-button-primary">
+ <%= translate(locale, "Register") %>
</button>
- </label>
- <% when "text" %>
- <label>
- <button type="submit" name="change_type" class="pure-button pure-button-primary" value="image">
- <%= translate(locale, "Image CAPTCHA") %>
+
+ <% case captcha_type when %>
+ <% when "image" %>
+ <label>
+ <button type="submit" name="change_type" class="pure-button pure-button-primary" value="text">
+ <%= translate(locale, "Text CAPTCHA") %>
+ </button>
+ </label>
+ <% when "text" %>
+ <label>
+ <button type="submit" name="change_type" class="pure-button pure-button-primary" value="image">
+ <%= translate(locale, "Image CAPTCHA") %>
+ </button>
+ </label>
+ <% end %>
+ <% else %>
+ <button type="submit" name="action" value="signin" class="pure-button pure-button-primary">
+ <%= translate(locale, "Sign In") %>/<%= translate(locale, "Register") %>
</button>
- </label>
- <% end %>
- <% else %>
- <button type="submit" name="action" value="signin" class="pure-button pure-button-primary">
- <%= translate(locale, "Sign In") %>/<%= translate(locale, "Register") %>
- </button>
- <% end %>
- </fieldset>
- </form>
+ <% end %>
+ </fieldset>
+ </form>
<% elsif account_type == "google" %>
- <form class="pure-form pure-form-stacked" action="/login?referer=<%= URI.escape(referer) %>&type=google" method="post">
- <fieldset>
- <% if email %>
- <input name="email" type="hidden" value="<%= email %>">
- <% else %>
- <label for="email"><%= translate(locale, "E-mail") %> :</label>
- <input required class="pure-input-1" name="email" type="email" placeholder="<%= translate(locale, "E-mail") %>">
- <% end %>
+ <form class="pure-form pure-form-stacked" action="/login?referer=<%= URI.escape(referer) %>&type=google" method="post">
+ <fieldset>
+ <% if email %>
+ <input name="email" type="hidden" value="<%= email %>">
+ <% else %>
+ <label for="email"><%= translate(locale, "E-mail") %> :</label>
+ <input required class="pure-input-1" name="email" type="email" placeholder="<%= translate(locale, "E-mail") %>">
+ <% end %>
- <% if password %>
- <input name="password" type="hidden" value="<%= password %>">
- <% else %>
- <label for="password"><%= translate(locale, "Password") %> :</label>
- <input required class="pure-input-1" name="password" type="password" placeholder="<%= translate(locale, "Password") %>">
- <% end %>
+ <% if password %>
+ <input name="password" type="hidden" value="<%= password %>">
+ <% else %>
+ <label for="password"><%= translate(locale, "Password") %> :</label>
+ <input required class="pure-input-1" name="password" type="password" placeholder="<%= translate(locale, "Password") %>">
+ <% end %>
- <% if tfa %>
- <label for="tfa"><%= translate(locale, "Google verification code") %> :</label>
- <input required class="pure-input-1" name="tfa" type="text" placeholder="<%= translate(locale, "Google verification code") %>">
- <% end %>
+ <% if tfa %>
+ <label for="tfa"><%= translate(locale, "Google verification code") %> :</label>
+ <input required class="pure-input-1" name="tfa" type="text" placeholder="<%= translate(locale, "Google verification code") %>">
+ <% end %>
- <button type="submit" class="pure-button pure-button-primary"><%= translate(locale, "Sign In") %></button>
- </fieldset>
- </form>
+ <button type="submit" class="pure-button pure-button-primary"><%= translate(locale, "Sign In") %></button>
+ </fieldset>
+ </form>
<% end %>
</div>
</div>
diff --git a/src/invidious/views/mix.ecr b/src/invidious/views/mix.ecr
index 0e88b263..e9c0dcbc 100644
--- a/src/invidious/views/mix.ecr
+++ b/src/invidious/views/mix.ecr
@@ -6,7 +6,7 @@
<div class="pure-u-2-3">
<h3><%= mix.title %></h3>
</div>
- <div class="pure-u-1-3" style="text-align:right;">
+ <div class="pure-u-1-3" style="text-align:right">
<h3>
<a href="/feed/playlist/<%= mix.id %>"><i class="icon ion-logo-rss"></i></a>
</h3>
@@ -14,9 +14,9 @@
</div>
<div class="pure-g">
-<% mix.videos.each_slice(4) do |slice| %>
- <% slice.each do |item| %>
- <%= rendered "components/item" %>
+ <% mix.videos.each_slice(4) do |slice| %>
+ <% slice.each do |item| %>
+ <%= rendered "components/item" %>
+ <% end %>
<% end %>
-<% end %>
</div>
diff --git a/src/invidious/views/playlist.ecr b/src/invidious/views/playlist.ecr
index 6bd0dc9e..b43bd89c 100644
--- a/src/invidious/views/playlist.ecr
+++ b/src/invidious/views/playlist.ecr
@@ -7,12 +7,13 @@
<div class="pure-u-2-3">
<h3><%= playlist.title %></h3>
</div>
- <div class="pure-u-1-3" style="text-align:right;">
+ <div class="pure-u-1-3" style="text-align:right">
<h3>
<a href="/feed/playlist/<%= plid %>"><i class="icon ion-logo-rss"></i></a>
</h3>
</div>
</div>
+
<div class="pure-g h-box">
<div class="pure-u-1 pure-u-md-1-4">
<a href="/channel/<%= playlist.ucid %>">
@@ -26,27 +27,27 @@
</div>
<div class="pure-g">
-<% videos.each_slice(4) do |slice| %>
- <% slice.each do |item| %>
- <%= rendered "components/item" %>
+ <% videos.each_slice(4) do |slice| %>
+ <% slice.each do |item| %>
+ <%= rendered "components/item" %>
+ <% end %>
<% end %>
-<% end %>
</div>
<div class="pure-g h-box">
<div class="pure-u-1 pure-u-lg-1-5">
- <% if page >= 2 %>
- <a href="/playlist?list=<%= playlist.id %>&page=<%= page - 1 %>">
- <%= translate(locale, "Previous page") %>
- </a>
- <% end %>
+ <% if page >= 2 %>
+ <a href="/playlist?list=<%= playlist.id %>&page=<%= page - 1 %>">
+ <%= translate(locale, "Previous page") %>
+ </a>
+ <% end %>
</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">
- <% if videos.size == 100 %>
- <a href="/playlist?list=<%= playlist.id %>&page=<%= page + 1 %>">
- <%= translate(locale, "Next page") %>
- </a>
- <% end %>
+ <div class="pure-u-1 pure-u-lg-1-5" style="text-align:right">
+ <% if videos.size == 100 %>
+ <a href="/playlist?list=<%= playlist.id %>&page=<%= page + 1 %>">
+ <%= translate(locale, "Next page") %>
+ </a>
+ <% end %>
</div>
</div>
diff --git a/src/invidious/views/playlists.ecr b/src/invidious/views/playlists.ecr
index ee7918e7..88d51268 100644
--- a/src/invidious/views/playlists.ecr
+++ b/src/invidious/views/playlists.ecr
@@ -6,7 +6,7 @@
<div class="pure-u-2-3">
<h3><%= author %></h3>
</div>
- <div class="pure-u-1-3" style="text-align:right;">
+ <div class="pure-u-1-3" style="text-align:right">
<h3>
<a href="/feed/channel/<%= ucid %>"><i class="icon ion-logo-rss"></i></a>
</h3>
@@ -14,8 +14,8 @@
</div>
<div class="h-box">
-<% sub_count_text = number_to_short_text(sub_count) %>
-<%= rendered "components/subscribe_widget" %>
+ <% sub_count_text = number_to_short_text(sub_count) %>
+ <%= rendered "components/subscribe_widget" %>
</div>
<div class="pure-g h-box">
@@ -28,25 +28,24 @@
</div>
<div class="pure-u-1 pure-md-1-3">
<% if !auto_generated %>
- <b><%= translate(locale, "Playlists") %></b>
+ <b><%= translate(locale, "Playlists") %></b>
<% end %>
</div>
</div>
+ <div class="pure-u-1-3"></div>
<div class="pure-u-1-3">
- </div>
- <div class="pure-u-1-3">
- <div class="pure-g" style="text-align:right;">
- <% {"last", "oldest", "newest"}.each do |sort| %>
- <div class="pure-u-1 pure-md-1-3">
- <% if sort_by == sort %>
- <b><%= translate(locale, sort) %></b>
- <% else %>
- <a href="/channel/<%= ucid %>/playlists?sort_by=<%= sort %>">
- <%= translate(locale, sort) %>
- </a>
- <% end %>
- </div>
- <% end %>
+ <div class="pure-g" style="text-align:right">
+ <% {"last", "oldest", "newest"}.each do |sort| %>
+ <div class="pure-u-1 pure-md-1-3">
+ <% if sort_by == sort %>
+ <b><%= translate(locale, sort) %></b>
+ <% else %>
+ <a href="/channel/<%= ucid %>/playlists?sort_by=<%= sort %>">
+ <%= translate(locale, sort) %>
+ </a>
+ <% end %>
+ </div>
+ <% end %>
</div>
</div>
</div>
@@ -56,21 +55,21 @@
</div>
<div class="pure-g">
-<% items.each_slice(4) do |slice| %>
- <% slice.each do |item| %>
- <%= rendered "components/item" %>
+ <% items.each_slice(4) do |slice| %>
+ <% slice.each do |item| %>
+ <%= rendered "components/item" %>
+ <% end %>
<% end %>
-<% end %>
</div>
<div class="pure-g h-box">
<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">
- <% if items.size >= 28 %>
- <a href="/channel/<%= ucid %>/playlists?continuation=<%= continuation %><% if sort_by != "last" %>&sort_by=<%= sort_by %><% end %>">
- <%= translate(locale, "Next page") %>
- </a>
- <% end %>
+ <div class="pure-u-1 pure-u-lg-1-5" style="text-align:right">
+ <% if items.size >= 28 %>
+ <a href="/channel/<%= ucid %>/playlists?continuation=<%= continuation %><% if sort_by != "last" %>&sort_by=<%= sort_by %><% end %>">
+ <%= translate(locale, "Next page") %>
+ </a>
+ <% end %>
</div>
</div>
diff --git a/src/invidious/views/popular.ecr b/src/invidious/views/popular.ecr
index d60ae557..88c49582 100644
--- a/src/invidious/views/popular.ecr
+++ b/src/invidious/views/popular.ecr
@@ -1,14 +1,20 @@
<% content_for "header" do %>
<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 %>
<%= rendered "components/feed_menu" %>
<div class="pure-g">
-<% popular_videos.each_slice(4) do |slice| %>
- <% slice.each do |item| %>
- <%= rendered "components/item" %>
- <% end %>
-<% end %>
+ <% popular_videos.each_slice(4) do |slice| %>
+ <% slice.each do |item| %>
+ <%= rendered "components/item" %>
+ <% end %>
+ <% end %>
</div>
diff --git a/src/invidious/views/preferences.ecr b/src/invidious/views/preferences.ecr
index 9128c3f5..12513a64 100644
--- a/src/invidious/views/preferences.ecr
+++ b/src/invidious/views/preferences.ecr
@@ -46,18 +46,18 @@ function update_value(element) {
<div class="pure-control-group">
<label for="speed"><%= translate(locale, "Default speed: ") %></label>
<select name="speed" id="speed">
- <% {2.0, 1.5, 1.25, 1.0, 0.75, 0.5, 0.25}.each do |option| %>
- <option <% if preferences.speed == option %> selected <% end %>><%= option %></option>
- <% end %>
+ <% {2.0, 1.5, 1.25, 1.0, 0.75, 0.5, 0.25}.each do |option| %>
+ <option <% if preferences.speed == option %> selected <% end %>><%= option %></option>
+ <% end %>
</select>
</div>
<div class="pure-control-group">
<label for="quality"><%= translate(locale, "Preferred video quality: ") %></label>
<select name="quality" id="quality">
- <% {"dash", "hd720", "medium", "small"}.each do |option| %>
- <option value="<%= option %>" <% if preferences.quality == option %> selected <% end %>><%= translate(locale, option) %></option>
- <% end %>
+ <% {"dash", "hd720", "medium", "small"}.each do |option| %>
+ <option value="<%= option %>" <% if preferences.quality == option %> selected <% end %>><%= translate(locale, option) %></option>
+ <% end %>
</select>
</div>
@@ -70,22 +70,22 @@ function update_value(element) {
<div class="pure-control-group">
<label for="comments[0]"><%= translate(locale, "Default comments: ") %></label>
<% preferences.comments.each_with_index do |comments, index| %>
- <select name="comments[<%= index %>]" id="comments[<%= index %>]">
- <% {"", "youtube", "reddit"}.each do |option| %>
- <option value="<%= option %>" <% if preferences.comments[index] == option %> selected <% end %>><%= translate(locale, option) %></option>
- <% end %>
- </select>
+ <select name="comments[<%= index %>]" id="comments[<%= index %>]">
+ <% {"", "youtube", "reddit"}.each do |option| %>
+ <option value="<%= option %>" <% if preferences.comments[index] == option %> selected <% end %>><%= translate(locale, option) %></option>
+ <% end %>
+ </select>
<% end %>
</div>
<div class="pure-control-group">
<label for="captions[0]"><%= translate(locale, "Default captions: ") %></label>
<% preferences.captions.each_with_index do |caption, index| %>
- <select class="pure-u-1-6" name="captions[<%= index %>]" id="captions[<%= index %>]">
- <% CAPTION_LANGUAGES.each do |option| %>
- <option value="<%= option %>" <% if preferences.captions[index] == option %> selected <% end %>><%= translate(locale, option) %></option>
- <% end %>
- </select>
+ <select class="pure-u-1-6" name="captions[<%= index %>]" id="captions[<%= index %>]">
+ <% CAPTION_LANGUAGES.each do |option| %>
+ <option value="<%= option %>" <% if preferences.captions[index] == option %> selected <% end %>><%= translate(locale, option) %></option>
+ <% end %>
+ </select>
<% end %>
</div>
@@ -104,9 +104,9 @@ function update_value(element) {
<div class="pure-control-group">
<label for="locale"><%= translate(locale, "Language: ") %></label>
<select name="locale" id="locale">
- <% LOCALES.each_key do |option| %>
- <option value="<%= option %>" <% if preferences.locale == option %> selected <% end %>><%= option %></option>
- <% end %>
+ <% LOCALES.each_key do |option| %>
+ <option value="<%= option %>" <% if preferences.locale == option %> selected <% end %>><%= option %></option>
+ <% end %>
</select>
</div>
@@ -121,131 +121,131 @@ function update_value(element) {
</div>
<% if env.get? "user" %>
- <legend><%= translate(locale, "Subscription preferences") %></legend>
-
- <div class="pure-control-group">
- <label for="annotations_subscribed"><%= translate(locale, "Show annotations by default for subscribed channels? ") %></label>
- <input name="annotations_subscribed" id="annotations_subscribed" type="checkbox" <% if preferences.annotations_subscribed %>checked<% end %>>
- </div>
-
- <div class="pure-control-group">
- <label for="redirect_feed"><%= translate(locale, "Redirect homepage to feed: ") %></label>
- <input name="redirect_feed" id="redirect_feed" type="checkbox" <% if preferences.redirect_feed %>checked<% end %>>
- </div>
-
- <div class="pure-control-group">
- <label for="max_results"><%= translate(locale, "Number of videos shown in feed: ") %></label>
- <input name="max_results" id="max_results" type="number" value="<%= preferences.max_results %>">
- </div>
-
- <div class="pure-control-group">
- <label for="sort"><%= translate(locale, "Sort videos by: ") %></label>
- <select name="sort" id="sort">
- <% {"published", "published - reverse", "alphabetically", "alphabetically - reverse", "channel name", "channel name - reverse"}.each do |option| %>
- <option value="<%= option %>" <% if preferences.sort == option %> selected <% end %>><%= translate(locale, option) %></option>
- <% end %>
- </select>
- </div>
-
- <div class="pure-control-group">
- <% if preferences.unseen_only %>
- <label for="latest_only"><%= translate(locale, "Only show latest unwatched video from channel: ") %></label>
- <% else %>
- <label for="latest_only"><%= translate(locale, "Only show latest video from channel: ") %></label>
- <% end %>
- <input name="latest_only" id="latest_only" type="checkbox" <% if preferences.latest_only %>checked<% end %>>
- </div>
-
- <div class="pure-control-group">
- <label for="unseen_only"><%= translate(locale, "Only show unwatched: ") %></label>
- <input name="unseen_only" id="unseen_only" type="checkbox" <% if preferences.unseen_only %>checked<% end %>>
- </div>
-
- <div class="pure-control-group">
- <label for="notifications_only"><%= translate(locale, "Only show notifications (if there are any): ") %></label>
- <input name="notifications_only" id="notifications_only" type="checkbox" <% if preferences.notifications_only %>checked<% end %>>
- </div>
+ <legend><%= translate(locale, "Subscription preferences") %></legend>
+
+ <div class="pure-control-group">
+ <label for="annotations_subscribed"><%= translate(locale, "Show annotations by default for subscribed channels? ") %></label>
+ <input name="annotations_subscribed" id="annotations_subscribed" type="checkbox" <% if preferences.annotations_subscribed %>checked<% end %>>
+ </div>
+
+ <div class="pure-control-group">
+ <label for="redirect_feed"><%= translate(locale, "Redirect homepage to feed: ") %></label>
+ <input name="redirect_feed" id="redirect_feed" type="checkbox" <% if preferences.redirect_feed %>checked<% end %>>
+ </div>
+
+ <div class="pure-control-group">
+ <label for="max_results"><%= translate(locale, "Number of videos shown in feed: ") %></label>
+ <input name="max_results" id="max_results" type="number" value="<%= preferences.max_results %>">
+ </div>
+
+ <div class="pure-control-group">
+ <label for="sort"><%= translate(locale, "Sort videos by: ") %></label>
+ <select name="sort" id="sort">
+ <% {"published", "published - reverse", "alphabetically", "alphabetically - reverse", "channel name", "channel name - reverse"}.each do |option| %>
+ <option value="<%= option %>" <% if preferences.sort == option %> selected <% end %>><%= translate(locale, option) %></option>
+ <% end %>
+ </select>
+ </div>
+
+ <div class="pure-control-group">
+ <% if preferences.unseen_only %>
+ <label for="latest_only"><%= translate(locale, "Only show latest unwatched video from channel: ") %></label>
+ <% else %>
+ <label for="latest_only"><%= translate(locale, "Only show latest video from channel: ") %></label>
+ <% end %>
+ <input name="latest_only" id="latest_only" type="checkbox" <% if preferences.latest_only %>checked<% end %>>
+ </div>
+
+ <div class="pure-control-group">
+ <label for="unseen_only"><%= translate(locale, "Only show unwatched: ") %></label>
+ <input name="unseen_only" id="unseen_only" type="checkbox" <% if preferences.unseen_only %>checked<% end %>>
+ </div>
+
+ <div class="pure-control-group">
+ <label for="notifications_only"><%= translate(locale, "Only show notifications (if there are any): ") %></label>
+ <input name="notifications_only" id="notifications_only" type="checkbox" <% if preferences.notifications_only %>checked<% end %>>
+ </div>
<% end %>
<% if env.get?("user") && config.admins.includes? env.get?("user").as(User).email %>
- <legend><%= translate(locale, "Administrator preferences") %></legend>
-
- <div class="pure-control-group">
- <label for="default_home"><%= translate(locale, "Default homepage: ") %></label>
- <select name="default_home" id="default_home">
- <% {"Popular", "Top", "Trending", "Subscriptions"}.each do |option| %>
- <option value="<%= option %>" <% if config.default_home == option %> selected <% end %>><%= translate(locale, option) %></option>
- <% end %>
- </select>
- </div>
-
- <div class="pure-control-group">
- <label for="feed_menu"><%= translate(locale, "Feed menu: ") %></label>
- <% 4.times do |index| %>
- <select name="feed_menu[<%= index %>]" id="feed_menu[<%= index %>]">
- <% {"", "Popular", "Top", "Trending", "Subscriptions"}.each do |option| %>
- <option value="<%= option %>" <% if config.feed_menu[index]? == option %> selected <% end %>><%= translate(locale, option) %></option>
- <% end %>
- </select>
- <% end %>
- </div>
-
- <div class="pure-control-group">
- <label for="top_enabled"><%= translate(locale, "Top enabled? ") %></label>
- <input name="top_enabled" id="top_enabled" type="checkbox" <% if config.top_enabled %>checked<% end %>>
- </div>
-
- <div class="pure-control-group">
- <label for="captcha_enabled"><%= translate(locale, "CAPTCHA enabled? ") %></label>
- <input name="captcha_enabled" id="captcha_enabled" type="checkbox" <% if config.captcha_enabled %>checked<% end %>>
- </div>
-
- <div class="pure-control-group">
- <label for="login_enabled"><%= translate(locale, "Login enabled? ") %></label>
- <input name="login_enabled" id="login_enabled" type="checkbox" <% if config.login_enabled %>checked<% end %>>
- </div>
-
- <div class="pure-control-group">
- <label for="registration_enabled"><%= translate(locale, "Registration enabled? ") %></label>
- <input name="registration_enabled" id="registration_enabled" type="checkbox" <% if config.registration_enabled %>checked<% end %>>
- </div>
-
- <div class="pure-control-group">
- <label for="statistics_enabled"><%= translate(locale, "Report statistics? ") %></label>
- <input name="statistics_enabled" id="statistics_enabled" type="checkbox" <% if config.statistics_enabled %>checked<% end %>>
- </div>
+ <legend><%= translate(locale, "Administrator preferences") %></legend>
+
+ <div class="pure-control-group">
+ <label for="default_home"><%= translate(locale, "Default homepage: ") %></label>
+ <select name="default_home" id="default_home">
+ <% {"Popular", "Top", "Trending", "Subscriptions"}.each do |option| %>
+ <option value="<%= option %>" <% if config.default_home == option %> selected <% end %>><%= translate(locale, option) %></option>
+ <% end %>
+ </select>
+ </div>
+
+ <div class="pure-control-group">
+ <label for="feed_menu"><%= translate(locale, "Feed menu: ") %></label>
+ <% 4.times do |index| %>
+ <select name="feed_menu[<%= index %>]" id="feed_menu[<%= index %>]">
+ <% {"", "Popular", "Top", "Trending", "Subscriptions"}.each do |option| %>
+ <option value="<%= option %>" <% if config.feed_menu[index]? == option %> selected <% end %>><%= translate(locale, option) %></option>
+ <% end %>
+ </select>
+ <% end %>
+ </div>
+
+ <div class="pure-control-group">
+ <label for="top_enabled"><%= translate(locale, "Top enabled? ") %></label>
+ <input name="top_enabled" id="top_enabled" type="checkbox" <% if config.top_enabled %>checked<% end %>>
+ </div>
+
+ <div class="pure-control-group">
+ <label for="captcha_enabled"><%= translate(locale, "CAPTCHA enabled? ") %></label>
+ <input name="captcha_enabled" id="captcha_enabled" type="checkbox" <% if config.captcha_enabled %>checked<% end %>>
+ </div>
+
+ <div class="pure-control-group">
+ <label for="login_enabled"><%= translate(locale, "Login enabled? ") %></label>
+ <input name="login_enabled" id="login_enabled" type="checkbox" <% if config.login_enabled %>checked<% end %>>
+ </div>
+
+ <div class="pure-control-group">
+ <label for="registration_enabled"><%= translate(locale, "Registration enabled? ") %></label>
+ <input name="registration_enabled" id="registration_enabled" type="checkbox" <% if config.registration_enabled %>checked<% end %>>
+ </div>
+
+ <div class="pure-control-group">
+ <label for="statistics_enabled"><%= translate(locale, "Report statistics? ") %></label>
+ <input name="statistics_enabled" id="statistics_enabled" type="checkbox" <% if config.statistics_enabled %>checked<% end %>>
+ </div>
<% end %>
<% if env.get? "user" %>
- <legend><%= translate(locale, "Data preferences") %></legend>
+ <legend><%= translate(locale, "Data preferences") %></legend>
- <div class="pure-control-group">
- <a href="/clear_watch_history?referer=<%= URI.escape(referer) %>"><%= translate(locale, "Clear watch history") %></a>
- </div>
+ <div class="pure-control-group">
+ <a href="/clear_watch_history?referer=<%= URI.escape(referer) %>"><%= translate(locale, "Clear watch history") %></a>
+ </div>
- <div class="pure-control-group">
- <a href="/change_password?referer=<%= URI.escape(referer) %>"><%= translate(locale, "Change password") %></a>
- </div>
+ <div class="pure-control-group">
+ <a href="/change_password?referer=<%= URI.escape(referer) %>"><%= translate(locale, "Change password") %></a>
+ </div>
- <div class="pure-control-group">
- <a href="/data_control?referer=<%= URI.escape(referer) %>"><%= translate(locale, "Import/export data") %></a>
- </div>
+ <div class="pure-control-group">
+ <a href="/data_control?referer=<%= URI.escape(referer) %>"><%= translate(locale, "Import/export data") %></a>
+ </div>
- <div class="pure-control-group">
- <a href="/subscription_manager"><%= translate(locale, "Manage subscriptions") %></a>
- </div>
+ <div class="pure-control-group">
+ <a href="/subscription_manager"><%= translate(locale, "Manage subscriptions") %></a>
+ </div>
- <div class="pure-control-group">
- <a href="/token_manager"><%= translate(locale, "Manage tokens") %></a>
- </div>
+ <div class="pure-control-group">
+ <a href="/token_manager"><%= translate(locale, "Manage tokens") %></a>
+ </div>
- <div class="pure-control-group">
- <a href="/feed/history"><%= translate(locale, "Watch history") %></a>
- </div>
+ <div class="pure-control-group">
+ <a href="/feed/history"><%= translate(locale, "Watch history") %></a>
+ </div>
- <div class="pure-control-group">
- <a href="/delete_account?referer=<%= URI.escape(referer) %>"><%= translate(locale, "Delete account") %></a>
- </div>
+ <div class="pure-control-group">
+ <a href="/delete_account?referer=<%= URI.escape(referer) %>"><%= translate(locale, "Delete account") %></a>
+ </div>
<% end %>
<div class="pure-controls">
diff --git a/src/invidious/views/privacy.ecr b/src/invidious/views/privacy.ecr
index 79206c56..f273b250 100644
--- a/src/invidious/views/privacy.ecr
+++ b/src/invidious/views/privacy.ecr
@@ -3,73 +3,73 @@
<% end %>
<div class="h-box">
-<%= Markdown.to_html(<<-END_PRIVACY_POLICY
- ## Privacy
+ <%= Markdown.to_html(<<-END_PRIVACY_POLICY
+ ## 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.
- ### Data you directly provide
+ ### Data you directly provide
- Data that you provide to the website for the purpose of the site's operation (for example: an account name, account password, or channel subscription) will be stored in the website's database until the user decides to remove it. This data will not be intentionally shared with anyone or anything.
+ Data that you provide to the website for the purpose of the site's operation (for example: an account name, account password, or channel subscription) will be stored in the website's database until the user decides to remove it. This data will not be intentionally shared with anyone or anything.
- Information stored about a registered user is limited to:
+ Information stored about a registered user is limited to:
- - a list of session tokens for remaining logged in across devices
- - the last time an account was updated (to provide accurate notifications)
- - a list of video IDs identifying notifications from a user's subscriptions
- - a list of channel UCIDs the user is subscribed to
- - a user ID (for persistent storage of subscriptions and preferences)
- - a json object containing user preferences
- - a hashed password if applicable (not present on google accounts)
- - a randomly generated token for providing an RSS feed of a user's subscriptions
- - a list of video IDs identifying watched videos
+ - a list of session tokens for remaining logged in across devices
+ - the last time an account was updated (to provide accurate notifications)
+ - a list of video IDs identifying notifications from a user's subscriptions
+ - a list of channel UCIDs the user is subscribed to
+ - a user ID (for persistent storage of subscriptions and preferences)
+ - a json object containing user preferences
+ - a hashed password if applicable (not present on google accounts)
+ - a randomly generated token for providing an RSS feed of a user's subscriptions
+ - a list of video IDs identifying watched videos
- The above list reflects [this code](https://github.com/omarroth/invidious/blob/master/src/invidious/users.cr#L14-L51).
+ The above list reflects [this code](https://github.com/omarroth/invidious/blob/master/src/invidious/users.cr#L14-L51).
- Users can clear their watch history using the [clear watch history](/clear_watch_history) page.
+ Users can clear their watch history using the [clear watch history](/clear_watch_history) page.
- If a user is logged in with a Google account, no password will ever be stored. This website uses the session token provided by Google to identify a user, but does not store the information required to make requests on a user's behalf without their knowledge or consent.
+ If a user is logged in with a Google account, no password will ever be stored. This website uses the session token provided by Google to identify a user, but does not store the information required to make requests on a user's behalf without their knowledge or consent.
- ### Data you passively provide
+ ### Data you passively provide
- When you request any resource from this website (for example: a page, a font, an image, or an API endpoint) information about the request may be logged.
+ When you request any resource from this website (for example: a page, a font, an image, or an API endpoint) information about the request may be logged.
- Information about a request is limited to:
+ Information about a request is limited to:
- - the time the request was made
- - the status code of the response
- - the method of the request
- - the requested URL
- - how long it took to complete the request.
+ - the time the request was made
+ - the status code of the response
+ - the method of the request
+ - the requested URL
+ - how long it took to complete the request.
- No identifying information is logged, such as the visitor's cookie, user-agent, or IP address. Here are a couple lines to serve as an example:
+ No identifying information is logged, such as the visitor's cookie, user-agent, or IP address. Here are a couple lines to serve as an example:
- ```
- 2019-01-19 16:37:47 +00:00 200 GET /api/v1/comments/xrlETJYzH-c?format=html&hl=en-US 1345.88ms
- 2019-01-19 16:37:53 +00:00 200 GET /vi/r5P-f5arPXE/maxres.jpg 1085.41ms
- 2019-01-19 16:37:54 +00:00 200 GET /watch 7.04ms
- ```
+ ```
+ 2019-01-19 16:37:47 +00:00 200 GET /api/v1/comments/xrlETJYzH-c?format=html&hl=en-US 1345.88ms
+ 2019-01-19 16:37:53 +00:00 200 GET /vi/r5P-f5arPXE/maxres.jpg 1085.41ms
+ 2019-01-19 16:37:54 +00:00 200 GET /watch 7.04ms
+ ```
- This website does not store the visitor's user-agent or IP address and does not use fingerprinting, advertisements, or tracking of any form.
+ This website does not store the visitor's user-agent or IP address and does not use fingerprinting, advertisements, or tracking of any form.
- This website provides links to googlevideo.com to provide audio and video playback. googlevideo.com is owned by Google and is subject to their [privacy policy](https://policies.google.com/privacy).
+ This website provides links to googlevideo.com to provide audio and video playback. googlevideo.com is owned by Google and is subject to their [privacy policy](https://policies.google.com/privacy).
- ### Data stored in your browser
+ ### Data stored in your browser
- This website uses browser cookies to authenticate registered users. This data consists of:
+ This website uses browser cookies to authenticate registered users. This data consists of:
- - An account token to keep you logged into the website between visits, which is sent when any page is loaded while you are logged in
+ - An account token to keep you logged into the website between visits, which is sent when any page is loaded while you are logged in
- This website also provides an option to store site preferences, such as the theme or locale, without an account. Using this feature will store a cookie in the visitor's browser containing their preferences. This cookie is sent on every request and does not contain any identifying information.
+ This website also provides an option to store site preferences, such as the theme or locale, without an account. Using this feature will store a cookie in the visitor's browser containing their preferences. This cookie is sent on every request and does not contain any identifying information.
- You can remove this data from your browser by logging out of this website, or by using your browser's cookie-related controls to delete the data.
+ You can remove this data from your browser by logging out of this website, or by using your browser's cookie-related controls to delete the data.
- ### Removal of data
+ ### Removal of data
- To remove data stored in your browser, you can log out of the website, or you can use your browser's cookie-related controls to delete the data.
+ To remove data stored in your browser, you can log out of the website, or you can use your browser's cookie-related controls to delete the data.
- 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
- )
-%>
-</div> \ No newline at end of file
+ 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
+ )
+ %>
+</div>
diff --git a/src/invidious/views/search.ecr b/src/invidious/views/search.ecr
index 4d943127..f08444b3 100644
--- a/src/invidious/views/search.ecr
+++ b/src/invidious/views/search.ecr
@@ -3,27 +3,27 @@
<% end %>
<div class="pure-g">
-<% videos.each_slice(4) do |slice| %>
- <% slice.each do |item| %>
- <%= rendered "components/item" %>
+ <% videos.each_slice(4) do |slice| %>
+ <% slice.each do |item| %>
+ <%= rendered "components/item" %>
+ <% end %>
<% end %>
-<% end %>
</div>
<div class="pure-g h-box">
<div class="pure-u-1 pure-u-lg-1-5">
- <% if page >= 2 %>
- <a href="/search?q=<%= HTML.escape(query.not_nil!) %>&page=<%= page - 1 %>">
- <%= translate(locale, "Previous page") %>
- </a>
- <% end %>
+ <% if page >= 2 %>
+ <a href="/search?q=<%= HTML.escape(query.not_nil!) %>&page=<%= page - 1 %>">
+ <%= translate(locale, "Previous page") %>
+ </a>
+ <% end %>
</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">
- <% if count >= 20 %>
- <a href="/search?q=<%= HTML.escape(query.not_nil!) %>&page=<%= page + 1 %>">
- <%= translate(locale, "Next page") %>
- </a>
- <% end %>
+ <div class="pure-u-1 pure-u-lg-1-5" style="text-align:right">
+ <% if count >= 20 %>
+ <a href="/search?q=<%= HTML.escape(query.not_nil!) %>&page=<%= page + 1 %>">
+ <%= translate(locale, "Next page") %>
+ </a>
+ <% end %>
</div>
</div>
diff --git a/src/invidious/views/subscription_manager.ecr b/src/invidious/views/subscription_manager.ecr
index ad572968..6e015738 100644
--- a/src/invidious/views/subscription_manager.ecr
+++ b/src/invidious/views/subscription_manager.ecr
@@ -5,70 +5,78 @@
<div class="pure-g h-box">
<div class="pure-u-1-3">
<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>
</div>
<div class="pure-u-1-3" style="text-align:center">
<h3>
- <a href="/feed/history"><%= translate(locale, "Watch history") %></a>
+ <a href="/feed/history">
+ <%= translate(locale, "Watch history") %>
+ </a>
</h3>
</div>
<div class="pure-u-1-3" style="text-align:right">
<h3>
- <a href="/data_control?referer=<%= referer %>"><%= translate(locale, "Import/export") %></a>
+ <a href="/data_control?referer=<%= referer %>">
+ <%= translate(locale, "Import/export") %>
+ </a>
</h3>
</div>
</div>
<% subscriptions.each do |channel| %>
-<div class="h-box">
- <div class="pure-g<% if channel.deleted %> deleted <% end %>">
- <div class="pure-u-2-5">
- <h3 style="padding-left:0.5em">
- <a href="/channel/<%= channel.id %>"><%= channel.author %></a>
- </h3>
+ <div class="h-box">
+ <div class="pure-g<% if channel.deleted %> deleted <% end %>">
+ <div class="pure-u-2-5">
+ <h3 style="padding-left:0.5em">
+ <a href="/channel/<%= channel.id %>"><%= channel.author %></a>
+ </h3>
+ </div>
+ <div class="pure-u-2-5"></div>
+ <div class="pure-u-1-5" style="text-align:right">
+ <h3 style="padding-right:0.5em">
+ <form onsubmit="return false" action="/subscription_ajax?action_remove_subscriptions=1&c=<%= channel.id %>&referer=<%= env.get("current_page") %>" method="post">
+ <input type="hidden" name="csrf_token" value="<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>">
+ <a onclick="remove_subscription(this)" data-ucid="<%= channel.id %>" href="#">
+ <input style="all:unset" type="submit" value="<%= translate(locale, "unsubscribe") %>">
+ </a>
+ </form>
+ </h3>
+ </div>
</div>
- <div class="pure-u-2-5"></div>
- <div class="pure-u-1-5" style="text-align:right">
- <h3 style="padding-right:0.5em">
- <form onsubmit="return false" action="/subscription_ajax?action_remove_subscriptions=1&c=<%= channel.id %>&referer=<%= env.get("current_page") %>" method="post">
- <input type="hidden" name="csrf_token" value="<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>">
- <a onclick="remove_subscription(this)" data-ucid="<%= channel.id %>" href="#">
- <input style="all:unset" type="submit" value="<%= translate(locale, "unsubscribe") %>">
- </a>
- </form>
- </h3>
- </div>
- </div>
- <% if subscriptions[-1].author != channel.author %>
- <hr>
- <% end %>
-</div>
+ <% if subscriptions[-1].author != channel.author %>
+ <hr>
+ <% end %>
+ </div>
<% end %>
<script>
function remove_subscription(target) {
var row = target.parentNode.parentNode.parentNode.parentNode.parentNode;
- row.style.display = "none";
- var count = document.getElementById("count")
+ row.style.display = 'none';
+ var count = document.getElementById('count');
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();
- xhr.responseType = "json";
+ xhr.responseType = 'json';
xhr.timeout = 20000;
- xhr.open("POST", url, true);
- xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
- xhr.send("csrf_token=<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>");
+ xhr.open('POST', url, true);
+ xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+ xhr.send('csrf_token=<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>');
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status != 200) {
- count.innerText = count.innerText - 1 + 2;
- row.style.display = "";
+ count.innerText = parseInt(count.innerText) + 1;
+ row.style.display = '';
}
}
}
}
-</script> \ No newline at end of file
+</script>
diff --git a/src/invidious/views/subscriptions.ecr b/src/invidious/views/subscriptions.ecr
index 5f0f7680..806e6124 100644
--- a/src/invidious/views/subscriptions.ecr
+++ b/src/invidious/views/subscriptions.ecr
@@ -11,32 +11,34 @@
<a href="/subscription_manager"><%= translate(locale, "Manage subscriptions") %></a>
</h3>
</div>
- <div class="pure-u-1-3" style="text-align:center;">
+ <div class="pure-u-1-3" style="text-align:center">
<h3>
<a href="/feed/history"><%= translate(locale, "Watch history") %></a>
</h3>
</div>
- <div class="pure-u-1-3" style="text-align:right;">
+ <div class="pure-u-1-3" style="text-align:right">
<h3>
<a href="/feed/private?token=<%= token %>"><i class="icon ion-logo-rss"></i></a>
</h3>
</div>
</div>
-<center><%= translate(locale, "`x` unseen notifications", "#{notifications.size}") %></center>
+<center>
+ <%= translate(locale, "`x` unseen notifications", "#{notifications.size}") %>
+</center>
<% if !notifications.empty? %>
-<div class="h-box">
- <hr>
-</div>
+ <div class="h-box">
+ <hr>
+ </div>
<% end %>
<div class="pure-g">
-<% notifications.each_slice(4) do |slice| %>
- <% slice.each do |item| %>
- <%= rendered "components/item" %>
- <% end %>
-<% end %>
+ <% notifications.each_slice(4) do |slice| %>
+ <% slice.each do |item| %>
+ <%= rendered "components/item" %>
+ <% end %>
+ <% end %>
</div>
<div class="h-box">
@@ -44,30 +46,31 @@
</div>
<div class="pure-g">
-<% videos.each_slice(4) do |slice| %>
- <% slice.each do |item| %>
- <%= rendered "components/item" %>
- <% end %>
-<% end %>
+ <% videos.each_slice(4) do |slice| %>
+ <% slice.each do |item| %>
+ <%= rendered "components/item" %>
+ <% end %>
+ <% end %>
</div>
<script>
function mark_watched(target) {
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();
- xhr.responseType = "json";
+ xhr.responseType = 'json';
xhr.timeout = 20000;
- xhr.open("POST", url, true);
- xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
- xhr.send("csrf_token=<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>");
+ xhr.open('POST', url, true);
+ xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+ xhr.send('csrf_token=<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>');
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status != 200) {
- tile.style.display = "";
+ tile.style.display = '';
}
}
}
@@ -76,14 +79,14 @@ function mark_watched(target) {
<div class="pure-g h-box">
<div class="pure-u-1 pure-u-lg-1-5">
- <% if page >= 2 %>
- <a href="/feed/subscriptions?max_results=<%= max_results %>&page=<%= page - 1 %>">
- <%= translate(locale, "Previous page") %>
- </a>
- <% end %>
+ <% if page >= 2 %>
+ <a href="/feed/subscriptions?max_results=<%= max_results %>&page=<%= page - 1 %>">
+ <%= translate(locale, "Previous page") %>
+ </a>
+ <% end %>
</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 %>
<a href="/feed/subscriptions?max_results=<%= max_results %>&page=<%= page + 1 %>">
<%= translate(locale, "Next page") %>
diff --git a/src/invidious/views/template.ecr b/src/invidious/views/template.ecr
index 3244fdc7..f489821c 100644
--- a/src/invidious/views/template.ecr
+++ b/src/invidious/views/template.ecr
@@ -38,75 +38,78 @@
<div class="pure-u-1 pure-u-md-12-24 searchbar">
<form class="pure-form" action="/search" method="get">
<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>
</form>
</div>
<div class="pure-u-1 pure-u-md-8-24 user-field">
- <% if env.get? "user" %>
- <div class="pure-u-1-4">
- <a href="/toggle_theme?referer=<%= env.get?("current_page") %>" class="pure-menu-heading">
- <% if env.get("preferences").as(Preferences).dark_mode %>
- <i class="icon ion-ios-sunny"></i>
- <% else %>
- <i class="icon ion-ios-moon"></i>
+ <% if env.get? "user" %>
+ <div class="pure-u-1-4">
+ <a href="/toggle_theme?referer=<%= env.get?("current_page") %>" class="pure-menu-heading">
+ <% if env.get("preferences").as(Preferences).dark_mode %>
+ <i class="icon ion-ios-sunny"></i>
+ <% else %>
+ <i class="icon ion-ios-moon"></i>
+ <% end %>
+ </a>
+ </div>
+ <div class="pure-u-1-4">
+ <a title="<%= translate(locale, "Subscriptions") %>" href="/feed/subscriptions" class="pure-menu-heading">
+ <% notification_count = env.get("user").as(User).notifications.size %>
+ <% if notification_count > 0 %>
+ <%= notification_count %> <i class="icon ion-ios-notifications"></i>
+ <% else %>
+ <i class="icon ion-ios-notifications-outline"></i>
+ <% end %>
+ </a>
+ </div>
+ <div class="pure-u-1-4">
+ <a title="<%= translate(locale, "Preferences") %>" href="/preferences?referer=<%= env.get?("current_page") %>" class="pure-menu-heading">
+ <i class="icon ion-ios-cog"></i>
+ </a>
+ </div>
+ <div class="pure-u-1-4">
+ <form action="/signout?referer=<%= env.get?("current_page") %>" method="post">
+ <input type="hidden" name="csrf_token" value="<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>">
+ <a class="pure-menu-heading" href="#">
+ <input style="all:unset" type="submit" value="<%= translate(locale, "Log out") %>">
+ </a>
+ </form>
+ </div>
+ <% else %>
+ <div class="pure-u-1-3">
+ <a href="/toggle_theme?referer=<%= env.get?("current_page") %>" class="pure-menu-heading">
+ <% if env.get("preferences").as(Preferences).dark_mode %>
+ <i class="icon ion-ios-sunny"></i>
+ <% else %>
+ <i class="icon ion-ios-moon"></i>
+ <% end %>
+ </a>
+ </div>
+ <div class="pure-u-1-3">
+ <a title="<%= translate(locale, "Preferences") %>" href="/preferences?referer=<%= env.get?("current_page") %>" class="pure-menu-heading">
+ <i class="icon ion-ios-cog"></i>
+ </a>
+ </div>
+ <% if config.login_enabled %>
+ <div class="pure-u-1-3">
+ <a href="/login?referer=<%= env.get?("current_page") %>" class="pure-menu-heading">
+ <%= translate(locale, "Log in") %>
+ </a>
+ </div>
<% end %>
- </a>
- </div>
- <div class="pure-u-1-4">
- <a title="<%= translate(locale, "Subscriptions") %>" href="/feed/subscriptions" class="pure-menu-heading">
- <% notification_count = env.get("user").as(User).notifications.size %>
- <% if notification_count > 0 %>
- <%= notification_count %> <i class="icon ion-ios-notifications"></i>
- <% else %>
- <i class="icon ion-ios-notifications-outline"></i>
- <% end %>
- </a>
- </div>
- <div class="pure-u-1-4">
- <a title="<%= translate(locale, "Preferences") %>" href="/preferences?referer=<%= env.get?("current_page") %>" class="pure-menu-heading">
- <i class="icon ion-ios-cog"></i>
- </a>
- </div>
- <div class="pure-u-1-4">
- <form action="/signout?referer=<%= env.get?("current_page") %>" method="post">
- <input type="hidden" name="csrf_token" value="<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>">
- <a class="pure-menu-heading" href="#">
- <input style="all:unset" type="submit" value="<%= translate(locale, "Log out") %>">
- </a>
- </form>
- </div>
- <% else %>
- <div class="pure-u-1-3">
- <a href="/toggle_theme?referer=<%= env.get?("current_page") %>" class="pure-menu-heading">
- <% if env.get("preferences").as(Preferences).dark_mode %>
- <i class="icon ion-ios-sunny"></i>
- <% else %>
- <i class="icon ion-ios-moon"></i>
- <% end %>
- </a>
- </div>
- <div class="pure-u-1-3">
- <a title="<%= translate(locale, "Preferences") %>" href="/preferences?referer=<%= env.get?("current_page") %>" class="pure-menu-heading">
- <i class="icon ion-ios-cog"></i>
- </a>
- </div>
- <% if config.login_enabled %>
- <div class="pure-u-1-3">
- <a href="/login?referer=<%= env.get?("current_page") %>" class="pure-menu-heading">
- <%= translate(locale, "Log in") %>
- </a>
- </div>
- <% end %>
- <% end %>
+ <% end %>
</div>
</div>
+
<% if CONFIG.banner %>
- <div class="h-box">
- <h3><%= CONFIG.banner %></h3>
- </div>
+ <div class="h-box">
+ <h3><%= CONFIG.banner %></h3>
+ </div>
<% end %>
+
<%= content %>
+
<div class="footer">
<div class="pure-g">
<div class="pure-u-1 pure-u-md-1-3">
@@ -116,10 +119,12 @@
</div>
<div class="pure-u-1 pure-u-md-1-3">
<i class="icon ion-logo-bitcoin"></i>
- BTC: 356DpZyMXu6rYd55Yqzjs29n79kGKWcYrY</div>
+ BTC: 356DpZyMXu6rYd55Yqzjs29n79kGKWcYrY
+ </div>
<div class="pure-u-1 pure-u-md-1-3">
<i class="icon ion-logo-bitcoin"></i>
- BCH: qq4ptclkzej5eza6a50et5ggc58hxsq5aylqut2npk</div>
+ BCH: qq4ptclkzej5eza6a50et5ggc58hxsq5aylqut2npk
+ </div>
<div class="pure-u-1 pure-u-md-1-3">
<i class="icon ion-logo-usd"></i>
<a href="https://liberapay.com/omarroth">Liberapay</a>
@@ -141,7 +146,8 @@
<i class="icon ion-logo-github"></i>
<%= translate(locale, "Current version: ") %> <%= CURRENT_VERSION %>-<%= CURRENT_COMMIT %>
<i class="icon ion-logo-github"></i>
- <%= CURRENT_BRANCH %></div>
+ <%= CURRENT_BRANCH %>
+ </div>
</div>
</div>
</div>
diff --git a/src/invidious/views/token_manager.ecr b/src/invidious/views/token_manager.ecr
index 91d0ddb4..713873dc 100644
--- a/src/invidious/views/token_manager.ecr
+++ b/src/invidious/views/token_manager.ecr
@@ -40,7 +40,7 @@
</div>
<% if tokens[-1].try &.[:session]? != token[:session] %>
- <hr>
+ <hr>
<% end %>
</div>
<% end %>
@@ -48,25 +48,27 @@
<script>
function revoke_token(target) {
var row = target.parentNode.parentNode.parentNode.parentNode.parentNode;
- row.style.display = "none";
- var count = document.getElementById("count")
+ row.style.display = 'none';
+ var count = document.getElementById('count');
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();
- xhr.responseType = "json";
+ xhr.responseType = 'json';
xhr.timeout = 20000;
- xhr.open("POST", url, true);
- xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
- xhr.send("csrf_token=<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>");
+ xhr.open('POST', url, true);
+ xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+ xhr.send('csrf_token=<%= URI.escape(env.get?("csrf_token").try &.as(String) || "") %>');
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status != 200) {
- count.innerText = count.innerText - 1 + 2;
- row.style.display = "";
+ count.innerText = parseInt(count.innerText) + 1;
+ row.style.display = '';
}
}
}
}
-</script> \ No newline at end of file
+</script>
diff --git a/src/invidious/views/top.ecr b/src/invidious/views/top.ecr
index 44faf706..d5fb3de6 100644
--- a/src/invidious/views/top.ecr
+++ b/src/invidious/views/top.ecr
@@ -1,14 +1,20 @@
<% content_for "header" do %>
<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 %>
<%= rendered "components/feed_menu" %>
<div class="pure-g">
-<% top_videos.each_slice(4) do |slice| %>
- <% slice.each do |item| %>
- <%= rendered "components/item" %>
- <% end %>
-<% end %>
+ <% top_videos.each_slice(4) do |slice| %>
+ <% slice.each do |item| %>
+ <%= rendered "components/item" %>
+ <% end %>
+ <% end %>
</div>
diff --git a/src/invidious/views/trending.ecr b/src/invidious/views/trending.ecr
index d6c25266..d7784928 100644
--- a/src/invidious/views/trending.ecr
+++ b/src/invidious/views/trending.ecr
@@ -1,6 +1,12 @@
<% content_for "header" do %>
<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 %>
<%= rendered "components/feed_menu" %>
@@ -8,19 +14,21 @@
<div class="pure-g h-box">
<div style="align-self:flex-end" class="pure-u-2-3">
<% 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 %>
</div>
<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| %>
<div class="pure-u-1 pure-md-1-3">
<% if trending_type == option %>
- <b><%= translate(locale, option) %></b>
+ <b><%= translate(locale, option) %></b>
<% else %>
- <a href="/feed/trending?type=<%= option %>&region=<%= region %>">
- <%= translate(locale, option) %>
- </a>
+ <a href="/feed/trending?type=<%= option %>&region=<%= region %>">
+ <%= translate(locale, option) %>
+ </a>
<% end %>
</div>
<% end %>
@@ -33,9 +41,9 @@
</div>
<div class="pure-g">
-<% trending.each_slice(4) do |slice| %>
- <% slice.each do |item| %>
- <%= rendered "components/item" %>
- <% end %>
-<% end %>
+ <% trending.each_slice(4) do |slice| %>
+ <% slice.each do |item| %>
+ <%= rendered "components/item" %>
+ <% end %>
+ <% end %>
</div>
diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr
index f74cf594..856752ce 100644
--- a/src/invidious/views/watch.ecr
+++ b/src/invidious/views/watch.ecr
@@ -28,106 +28,114 @@
<% end %>
<div id="player-container" class="h-box">
- <%= rendered "components/player" %>
+ <%= rendered "components/player" %>
</div>
<div class="h-box">
-<h1>
- <%= HTML.escape(video.title) %>
- <% if params.listen %>
- <a title="<%=translate(locale, "Video mode")%>" href="/watch?<%= env.params.query %>&listen=0">
- <i class="icon ion-ios-videocam"></i>
- </a>
- <% else %>
- <a title="<%=translate(locale, "Audio mode")%>" href="/watch?<%= env.params.query %>&listen=1">
- <i class="icon ion-md-headset"></i>
- </a>
+ <h1>
+ <%= HTML.escape(video.title) %>
+ <% if params.listen %>
+ <a title="<%=translate(locale, "Video mode")%>" href="/watch?<%= env.params.query %>&listen=0">
+ <i class="icon ion-ios-videocam"></i>
+ </a>
+ <% else %>
+ <a title="<%=translate(locale, "Audio mode")%>" href="/watch?<%= env.params.query %>&listen=1">
+ <i class="icon ion-md-headset"></i>
+ </a>
+ <% end %>
+ </h1>
+
+ <% if !video.is_listed %>
+ <h3>
+ <i class="icon ion-ios-lock"></i> <%= translate(locale, "Unlisted") %>
+ </h3>
+ <% end %>
+
+ <% if !reason.empty? %>
+ <h3>
+ <%= reason %>
+ </h3>
<% end %>
-</h1>
-<% if !video.is_listed %>
-<h3><i class="icon ion-ios-lock"></i> <%= translate(locale, "Unlisted") %></h3>
-<% end %>
-<% if !reason.empty? %>
-<h3><%= reason %></h3>
-<% end %>
</div>
<div class="pure-g">
<div class="pure-u-1 pure-u-lg-1-5">
<div class="h-box">
- <p><a href="https://www.youtube.com/watch?v=<%= video.id %>"><%= translate(locale, "Watch on YouTube") %></a></p>
<p>
- <% if params.annotations %>
- <a href="/watch?<%= env.params.query %>&iv_load_policy=3">
- <%= translate(locale, "Hide annotations") %>
- </a>
- <% else %>
- <a href="/watch?<%= env.params.query %>&iv_load_policy=1">
- <%=translate(locale, "Show annotations")%>
- </a>
- <% end %>
+ <a href="https://www.youtube.com/watch?v=<%= video.id %>"><%= translate(locale, "Watch on YouTube") %></a>
+ </p>
+ <p>
+ <% if params.annotations %>
+ <a href="/watch?<%= env.params.query %>&iv_load_policy=3">
+ <%= translate(locale, "Hide annotations") %>
+ </a>
+ <% else %>
+ <a href="/watch?<%= env.params.query %>&iv_load_policy=1">
+ <%=translate(locale, "Show annotations")%>
+ </a>
+ <% end %>
</p>
<% if CONFIG.dmca_content.includes? video.id %>
- <p>Download is disabled.</p>
+ <p><%= translate(locale, "Download is disabled.") %></p>
<% else %>
- <form class="pure-form pure-form-stacked" action="/latest_version" method="get" rel="noopener" target="_blank">
- <div class="pure-control-group">
- <label for="download_widget"><%= translate(locale, "Download as: ") %></label>
- <select style="width:100%" name="download_widget" id="download_widget">
- <% fmt_stream.each do |option| %>
- <option value='{"id":"<%= video.id %>","itag":"<%= option["itag"] %>","title":"<%= URI.escape(video.title) %>-<%= video.id %>.<%= option["type"].split(";")[0].split("/")[1] %>"}'>
- <%= itag_to_metadata?(option["itag"]).try &.["height"]? || "~240" %>p - <%= option["type"].split(";")[0] %>
- </option>
- <% end %>
- <% video_streams.each do |option| %>
- <option value='{"id":"<%= video.id %>","itag":"<%= option["itag"] %>","title":"<%= URI.escape(video.title) %>-<%= video.id %>.<%= option["type"].split(";")[0].split("/")[1] %>"}'>
- <%= option["quality_label"] %> - <%= option["type"].split(";")[0] %> @ <%= option["fps"] %>fps - video only
- </option>
- <% end %>
- <% audio_streams.each do |option| %>
- <option value='{"id":"<%= video.id %>","itag":"<%= option["itag"] %>","title":"<%= URI.escape(video.title) %>-<%= video.id %>.<%= option["type"].split(";")[0].split("/")[1] %>"}'>
- <%= option["type"].split(";")[0] %> @ <%= option["bitrate"] %>k - audio only
- </option>
- <% end %>
- <% captions.each do |caption| %>
- <option value='{"id":"<%= video.id %>","label":"<%= caption.name.simpleText %>","title":"<%= URI.escape(video.title) %>-<%= video.id %>.<%= caption.languageCode %>.vtt"}'>
- <%= translate(locale, "Subtitles - `x` (.vtt)", caption.name.simpleText) %>
- </option>
- <% end %>
- </select>
- </div>
+ <form class="pure-form pure-form-stacked" action="/latest_version" method="get" rel="noopener" target="_blank">
+ <div class="pure-control-group">
+ <label for="download_widget"><%= translate(locale, "Download as: ") %></label>
+ <select style="width:100%" name="download_widget" id="download_widget">
+ <% fmt_stream.each do |option| %>
+ <option value='{"id":"<%= video.id %>","itag":"<%= option["itag"] %>","title":"<%= URI.escape(video.title) %>-<%= video.id %>.<%= option["type"].split(";")[0].split("/")[1] %>"}'>
+ <%= itag_to_metadata?(option["itag"]).try &.["height"]? || "~240" %>p - <%= option["type"].split(";")[0] %>
+ </option>
+ <% end %>
+ <% video_streams.each do |option| %>
+ <option value='{"id":"<%= video.id %>","itag":"<%= option["itag"] %>","title":"<%= URI.escape(video.title) %>-<%= video.id %>.<%= option["type"].split(";")[0].split("/")[1] %>"}'>
+ <%= option["quality_label"] %> - <%= option["type"].split(";")[0] %> @ <%= option["fps"] %>fps - video only
+ </option>
+ <% end %>
+ <% audio_streams.each do |option| %>
+ <option value='{"id":"<%= video.id %>","itag":"<%= option["itag"] %>","title":"<%= URI.escape(video.title) %>-<%= video.id %>.<%= option["type"].split(";")[0].split("/")[1] %>"}'>
+ <%= option["type"].split(";")[0] %> @ <%= option["bitrate"] %>k - audio only
+ </option>
+ <% end %>
+ <% captions.each do |caption| %>
+ <option value='{"id":"<%= video.id %>","label":"<%= caption.name.simpleText %>","title":"<%= URI.escape(video.title) %>-<%= video.id %>.<%= caption.languageCode %>.vtt"}'>
+ <%= translate(locale, "Subtitles - `x` (.vtt)", caption.name.simpleText) %>
+ </option>
+ <% end %>
+ </select>
+ </div>
- <button type="submit" class="pure-button pure-button-primary">
- <b><%= translate(locale, "Download") %></b>
- </button>
- </form>
+ <button type="submit" class="pure-button pure-button-primary">
+ <b><%= translate(locale, "Download") %></b>
+ </button>
+ </form>
<% end %>
<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-down"></i> <%= number_with_separator(video.dislikes) %></p>
- <p id="Genre"><%= translate(locale, "Genre: ") %>
- <% if video.genre_url.empty? %>
- <%= video.genre %>
- <% else %>
- <a href="<%= video.genre_url %>"><%= video.genre %></a>
- <% end %>
+ <p id="genre"><%= translate(locale, "Genre: ") %>
+ <% if video.genre_url.empty? %>
+ <%= video.genre %>
+ <% else %>
+ <a href="<%= video.genre_url %>"><%= video.genre %></a>
+ <% end %>
</p>
<% if !video.license.empty? %>
- <p id="License"><%= translate(locale, "License: ") %><%= video.license %></p>
+ <p id="license"><%= translate(locale, "License: ") %><%= video.license %></p>
<% end %>
- <p id="FamilyFriendly"><%= 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="Rating"><%= translate(locale, "Rating: ") %><%= rating.round(4) %> / 5</p>
- <p id="Engagement"><%= translate(locale, "Engagement: ") %><%= engagement.round(2) %>%</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="rating"><%= translate(locale, "Rating: ") %><%= rating.round(4) %> / 5</p>
+ <p id="engagement"><%= translate(locale, "Engagement: ") %><%= engagement.round(2) %>%</p>
<% if video.allowed_regions.size != REGIONS.size %>
- <p id="AllowedRegions">
- <% if video.allowed_regions.size < REGIONS.size / 2 %>
- <%= translate(locale, "Whitelisted regions: ") %><%= video.allowed_regions.join(", ") %>
- <% else %>
- <%= translate(locale, "Blacklisted regions: ") %><%= (REGIONS.to_a - video.allowed_regions).join(", ") %>
- <% end %>
+ <p id="allowed_regions">
+ <% if video.allowed_regions.size < REGIONS.size / 2 %>
+ <%= translate(locale, "Whitelisted regions: ") %><%= video.allowed_regions.join(", ") %>
+ <% else %>
+ <%= translate(locale, "Blacklisted regions: ") %><%= (REGIONS.to_a - video.allowed_regions).join(", ") %>
+ <% end %>
</p>
<% end %>
</div>
@@ -140,96 +148,100 @@
<h3><%= video.author %></h3>
</a>
</p>
+
<% ucid = video.ucid %>
<% author = video.author %>
<% sub_count_text = video.sub_count_text %>
<%= rendered "components/subscribe_widget" %>
+
<p>
<b><%= translate(locale, "Shared `x`", video.published.to_s("%B %-d, %Y")) %></b>
</p>
+
<div>
<%= video.description %>
</div>
+
<hr>
+
<div id="comments">
<% if nojs %>
<%= comment_html %>
<% else %>
- <noscript>
- <a href="/watch?<%= env.params.query %>&nojs=1">
- <%= translate(locale, "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.") %>
- </a>
- </noscript>
+ <noscript>
+ <a href="/watch?<%= env.params.query %>&nojs=1">
+ <%= translate(locale, "Hi! Looks like you have JavaScript turned off. Click here to view comments, keep in mind they may take a bit longer to load.") %>
+ </a>
+ </noscript>
<% end %>
</div>
</div>
</div>
- <% if params.related_videos || plid %>
- <div class="pure-u-1 pure-u-lg-1-5">
- <% if plid %>
- <div id="playlist" class="h-box">
- </div>
- <% end %>
- <% if params.related_videos %>
- <div class="h-box">
-
- <% if !rvs.empty? %>
- <div <% if plid %>style="display:none"<% end %>>
- <div class="pure-control-group">
- <label for="continue"><%= translate(locale, "Autoplay next video: ") %></label>
- <input name="continue" onclick="continue_autoplay(this)" id="continue" type="checkbox" <% if params.continue %>checked<% end %>>
- </div>
- <hr>
- </div>
- <% end %>
+ <% if params.related_videos || plid %>
+ <div class="pure-u-1 pure-u-lg-1-5">
+ <% if plid %>
+ <div id="playlist" class="h-box"></div>
+ <% end %>
- <% rvs.each do |rv| %>
- <% if rv["id"]? %>
- <a href="/watch?v=<%= rv["id"] %>">
- <% if env.get("preferences").as(Preferences).thin_mode %>
- <% else %>
- <div class="thumbnail">
- <img class="thumbnail" src="/vi/<%= rv["id"] %>/mqdefault.jpg">
- <p class="length"><%= recode_length_seconds(rv["length_seconds"]?.try &.to_i? || 0) %></p>
- </div>
- <% end %>
- <p style="width:100%"><%= rv["title"] %></p>
- <h5 class="pure-g">
- <div class="pure-u-14-24">
- <b style="width:100%"><%= rv["author"] %></b>
- </div>
+ <% if params.related_videos %>
+ <div class="h-box">
+ <% if !rvs.empty? %>
+ <div <% if plid %>style="display:none"<% end %>>
+ <div class="pure-control-group">
+ <label for="continue"><%= translate(locale, "Autoplay next video: ") %></label>
+ <input name="continue" onclick="continue_autoplay(this)" id="continue" type="checkbox" <% if params.continue %>checked<% end %>>
+ </div>
+ <hr>
+ </div>
+ <% end %>
- <div class="pure-u-10-24" style="text-align:right">
- <% if views = rv["short_view_count_text"]?.try &.delete(", views") %>
- <b class="width:100%"><%= translate(locale, "`x` views", views) %></b>
+ <% rvs.each do |rv| %>
+ <% if rv["id"]? %>
+ <a href="/watch?v=<%= rv["id"] %>">
+ <% if !env.get("preferences").as(Preferences).thin_mode %>
+ <div class="thumbnail">
+ <img class="thumbnail" src="/vi/<%= rv["id"] %>/mqdefault.jpg">
+ <p class="length"><%= recode_length_seconds(rv["length_seconds"]?.try &.to_i? || 0) %></p>
+ </div>
+ <% end %>
+ <p style="width:100%"><%= rv["title"] %></p>
+ <h5 class="pure-g">
+ <div class="pure-u-14-24">
+ <b style="width:100%"><%= rv["author"] %></b>
+ </div>
+
+ <div class="pure-u-10-24" style="text-align:right">
+ <% if views = rv["short_view_count_text"]?.try &.delete(", views") %>
+ <b class="width:100%"><%= translate(locale, "`x` views", views) %></b>
+ <% end %>
+ </div>
+ </h5>
+ </a>
<% end %>
- </div>
- </h5>
- </a>
+ <% end %>
+ </div>
<% end %>
- <% end %>
</div>
- <% end %>
- </div>
<% end %>
</div>
<script>
<% if !rvs.empty? && !plid && params.continue %>
player.on('ended', function() {
- location.assign("/watch?v="
- + "<%= rvs.select { |rv| rv["id"]? }[0]?.try &.["id"] %>"
- + "&continue=1"
+ location.assign('/watch?v=' +
+ '<%= rvs.select { |rv| rv["id"]? }[0]?.try &.["id"] %>' +
+ '&continue=1' +
<% if params.listen != preferences.listen %>
- + "&listen=<%= params.listen %>"
+ '&listen=<%= params.listen %>' +
<% end %>
<% if params.autoplay || params.continue_autoplay %>
- + "&autoplay=1"
+ '&autoplay=1' +
<% end %>
<% if params.speed != preferences.speed %>
- + "&speed=<%= params.speed %>"
+ '&speed=<%= params.speed %>' +
<% end %>
+ ''
);
});
<% end %>
@@ -237,18 +249,19 @@ player.on('ended', function() {
function continue_autoplay(target) {
if (target.checked) {
player.on('ended', function() {
- location.assign("/watch?v="
- + "<%= rvs.select { |rv| rv["id"]? }[0]?.try &.["id"] %>"
- + "&continue=1"
+ location.assign('/watch?v=' +
+ '<%= rvs.select { |rv| rv["id"]? }[0]?.try &.["id"] %>' +
+ '&continue=1' +
<% if params.listen != preferences.listen %>
- + "&listen=<%= params.listen %>"
+ '&listen=<%= params.listen %>' +
<% end %>
<% if params.autoplay || params.continue_autoplay %>
- + "&autoplay=1"
+ '&autoplay=1' +
<% end %>
<% if params.speed != preferences.speed %>
- + "&speed=<%= params.speed %>"
+ '&speed=<%= params.speed %>' +
<% end %>
+ ''
);
});
} else {
@@ -257,10 +270,10 @@ function continue_autoplay(target) {
}
function number_with_separator(val) {
- while (/(\d+)(\d{3})/.test(val.toString())) {
- val = val.toString().replace(/(\d+)(\d{3})/, "$1" + "," + "$2");
- }
- return val;
+ while (/(\d+)(\d{3})/.test(val.toString())) {
+ val = val.toString().replace(/(\d+)(\d{3})/, "$1" + "," + "$2");
+ }
+ return val;
}
<% ucid = video.ucid %>
@@ -269,31 +282,33 @@ function number_with_separator(val) {
<%= rendered "components/subscribe_widget_script" %>
<% if plid %>
-function get_playlist(timeouts = 0) {
- playlist = document.getElementById("playlist");
+function get_playlist(plid, timeouts = 0) {
+ playlist = document.getElementById('playlist');
if (timeouts > 10) {
- console.log("Failed to pull playlist");
- playlist.innerHTML = "";
+ console.log('Failed to pull playlist');
+ playlist.innerHTML = '';
return;
}
playlist.innerHTML = ' \
- <h3 style="text-align:center"><div class="loading"><i class="icon ion-ios-refresh"></i></div></h3> \
- <hr>'
-
- var plid = "<%= plid %>"
+ <h3 style="text-align:center"><div class="loading"><i class="icon ion-ios-refresh"></i></div></h3> \
+ <hr>'
- if (plid.startsWith("RD")) {
- var plid_url = "/api/v1/mixes/<%= plid %>?continuation=<%= video.id %>&format=html&hl=<%= env.get("preferences").as(Preferences).locale %>";
+ if (plid.startsWith('RD')) {
+ var plid_url = '/api/v1/mixes/' + plid +
+ '?continuation=<%= video.id %>' +
+ '&format=html&hl=<%= env.get("preferences").as(Preferences).locale %>';
} 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();
- xhr.responseType = "json";
+ xhr.responseType = 'json';
xhr.timeout = 20000;
- xhr.open("GET", plid_url, true);
+ xhr.open('GET', plid_url, true);
xhr.send();
xhr.onreadystatechange = function() {
@@ -303,228 +318,232 @@ function get_playlist(timeouts = 0) {
if (xhr.response.nextVideo) {
player.on('ended', function() {
- location.assign("/watch?v="
- + xhr.response.nextVideo
- + "&list=<%= plid %>"
+ location.assign('/watch?v=' + xhr.response.nextVideo +
+ '&list=' + plid +
<% if params.listen != preferences.listen %>
- + "&listen=<%= params.listen %>"
+ '&listen=<%= params.listen %>' +
<% end %>
<% if params.autoplay || params.continue_autoplay %>
- + "&autoplay=1"
+ '&autoplay=1' +
<% end %>
<% if params.speed != preferences.speed %>
- + "&speed=<%= params.speed %>"
+ '&speed=<%= params.speed %>' +
<% end %>
+ ''
);
});
}
} else {
- playlist.innerHTML = "";
- document.getElementById('continue').style.display = "";
+ playlist.innerHTML = '';
+ document.getElementById('continue').style.display = '';
}
}
};
xhr.ontimeout = function() {
- console.log("Pulling playlist timed out.");
-
- playlist = document.getElementById("playlist");
+ console.log('Pulling playlist timed out.');
+ playlist = document.getElementById('playlist');
playlist.innerHTML =
'<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 %>
function get_reddit_comments(timeouts = 0) {
- comments = document.getElementById("comments");
-
- if (timeouts > 10) {
- console.log("Failed to pull comments");
- comments.innerHTML = "";
- return;
- }
-
- var fallback = comments.innerHTML;
- comments.innerHTML =
- '<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 xhr = new XMLHttpRequest();
- xhr.responseType = "json";
- xhr.timeout = 20000;
- xhr.open("GET", url, true);
- xhr.send();
-
- xhr.onreadystatechange = function() {
- if (xhr.readyState == 4) {
- if (xhr.status == 200) {
- comments.innerHTML = ' \
- <div> \
- <h3> \
- <a href="javascript:void(0)" onclick="toggle_comments(this)">[ - ]</a> \
- {title} \
- </h3> \
- <p> \
- <b> \
- <a href="javascript:void(0)" onclick="swap_comments(\'youtube\')"> \
- <%= translate(locale, "View YouTube comments") %> \
- </a> \
- </b> \
- </p> \
- <b> \
- <a rel="noopener" target="_blank" href="https://reddit.com{permalink}"><%= translate(locale, "View more comments on Reddit") %></a> \
- </b> \
- </div> \
- <div>{contentHtml}</div> \
- <hr>'.supplant({
- title: xhr.response.title,
- permalink: xhr.response.permalink,
- contentHtml: xhr.response.contentHtml
- });
- } else {
- <% if preferences && preferences.comments[1] == "youtube" %>
- get_youtube_comments(timeouts + 1);
- <% else %>
- comments.innerHTML = fallback;
- <% end %>
- }
+ comments = document.getElementById('comments');
+
+ if (timeouts > 10) {
+ console.log('Failed to pull comments');
+ comments.innerHTML = '';
+ return;
}
- };
- xhr.ontimeout = function() {
- console.log("Pulling comments timed out.");
+ var fallback = comments.innerHTML;
+ comments.innerHTML =
+ '<h3 style="text-align:center"><div class="loading"><i class="icon ion-ios-refresh"></i></div></h3>';
- get_reddit_comments(timeouts + 1);
- };
-}
+ var url = '/api/v1/comments/<%= video.id %>' +
+ '?source=reddit&format=html' +
+ '&hl=<%= env.get("preferences").as(Preferences).locale %>';
+ var xhr = new XMLHttpRequest();
+ xhr.responseType = 'json';
+ xhr.timeout = 20000;
+ xhr.open('GET', url, true);
+ xhr.send();
-function get_youtube_comments(timeouts = 0) {
- comments = document.getElementById("comments");
-
- if (timeouts > 10) {
- console.log("Failed to pull comments");
- comments.innerHTML = "";
- return;
- }
-
- var fallback = comments.innerHTML;
- comments.innerHTML =
- '<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 xhr = new XMLHttpRequest();
- xhr.responseType = "json";
- xhr.timeout = 20000;
- xhr.open("GET", url, true);
- xhr.send();
-
- xhr.onreadystatechange = function() {
- if (xhr.readyState == 4) {
- if (xhr.status == 200) {
- if (xhr.response.commentCount > 0) {
- comments.innerHTML = ' \
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 200) {
+ comments.innerHTML = ' \
<div> \
<h3> \
<a href="javascript:void(0)" onclick="toggle_comments(this)">[ - ]</a> \
- <%= translate(locale, "View `x` comments", "{commentCount}") %> \
+ {title} \
</h3> \
+ <p> \
+ <b> \
+ <a href="javascript:void(0)" onclick="swap_comments(\'youtube\')"> \
+ <%= translate(locale, "View YouTube comments") %> \
+ </a> \
+ </b> \
+ </p> \
<b> \
- <a href="javascript:void(0)" onclick="swap_comments(\'reddit\')"> \
- <%= translate(locale, "View Reddit comments") %> \
- </a> \
+ <a rel="noopener" target="_blank" href="https://reddit.com{permalink}"><%= translate(locale, "View more comments on Reddit") %></a> \
</b> \
</div> \
<div>{contentHtml}</div> \
<hr>'.supplant({
- contentHtml: xhr.response.contentHtml,
- commentCount: number_with_separator(xhr.response.commentCount)
- });
- } else {
- comments.innerHTML = "";
+ title: xhr.response.title,
+ permalink: xhr.response.permalink,
+ contentHtml: xhr.response.contentHtml
+ });
+ } else {
+ <% if preferences && preferences.comments[1] == "youtube" %>
+ get_youtube_comments(timeouts + 1);
+ <% else %>
+ comments.innerHTML = fallback;
+ <% end %>
+ }
}
- } else {
- <% if preferences && preferences.comments[1] == "youtube" %>
- get_youtube_comments(timeouts + 1);
- <% else %>
- comments.innerHTML = "";
- <% end %>
- }
- }
- };
+ };
+
+ xhr.ontimeout = function() {
+ console.log('Pulling comments timed out.');
+ get_reddit_comments(timeouts + 1);
+ };
+}
- xhr.ontimeout = function() {
- console.log("Pulling comments timed out.");
+function get_youtube_comments(timeouts = 0) {
+ comments = document.getElementById('comments');
+ if (timeouts > 10) {
+ console.log('Failed to pull comments');
+ comments.innerHTML = '';
+ return;
+ }
+
+ var fallback = comments.innerHTML;
comments.innerHTML =
- '<h3 style="text-align:center"><div class="loading"><i class="icon ion-ios-refresh"></i></div></h3>';
- get_youtube_comments(timeouts + 1);
- };
+ '<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 xhr = new XMLHttpRequest();
+ xhr.responseType = 'json';
+ xhr.timeout = 20000;
+ xhr.open('GET', url, true);
+ xhr.send();
+
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 200) {
+ if (xhr.response.commentCount > 0) {
+ comments.innerHTML = ' \
+ <div> \
+ <h3> \
+ <a href="javascript:void(0)" onclick="toggle_comments(this)">[ - ]</a> \
+ <%= translate(locale, "View `x` comments", "{commentCount}") %> \
+ </h3> \
+ <b> \
+ <a href="javascript:void(0)" onclick="swap_comments(\'reddit\')"> \
+ <%= translate(locale, "View Reddit comments") %> \
+ </a> \
+ </b> \
+ </div> \
+ <div>{contentHtml}</div> \
+ <hr>'.supplant({
+ contentHtml: xhr.response.contentHtml,
+ commentCount: number_with_separator(xhr.response.commentCount)
+ });
+ } else {
+ comments.innerHTML = "";
+ }
+ } else {
+ <% if preferences && preferences.comments[1] == "youtube" %>
+ get_youtube_comments(timeouts + 1);
+ <% else %>
+ comments.innerHTML = '';
+ <% end %>
+ }
+ }
+ };
+
+ xhr.ontimeout = function() {
+ console.log('Pulling comments timed out.');
+ comments.innerHTML =
+ '<h3 style="text-align:center"><div class="loading"><i class="icon ion-ios-refresh"></i></div></h3>';
+ get_youtube_comments(timeouts + 1);
+ };
}
function get_youtube_replies(target, load_more) {
- var continuation = target.getAttribute('data-continuation');
-
- var body = target.parentNode.parentNode;
- var fallback = body.innerHTML;
- body.innerHTML =
- '<h3 style="text-align:center"><div class="loading"><i class="icon ion-ios-refresh"></i></div></h3>';
+ var continuation = target.getAttribute('data-continuation');
+
+ var body = target.parentNode.parentNode;
+ var fallback = body.innerHTML;
+ body.innerHTML =
+ '<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=' + continuation;
+ var xhr = new XMLHttpRequest();
+ xhr.responseType = 'json';
+ xhr.timeout = 20000;
+ xhr.open('GET', url, true);
+ xhr.send();
- 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=' +
- continuation;
- var xhr = new XMLHttpRequest();
- xhr.responseType = 'json';
- xhr.timeout = 20000;
- xhr.open('GET', url, true);
- xhr.send();
-
- xhr.onreadystatechange = function() {
- if (xhr.readyState == 4) {
- if (xhr.status == 200) {
- if (load_more) {
- body = body.parentNode.parentNode;
- body.removeChild(body.lastElementChild);
- body.innerHTML += xhr.response.contentHtml;
- } else {
- body.innerHTML = ' \
- <p><a href="javascript:void(0)" \
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4) {
+ if (xhr.status == 200) {
+ if (load_more) {
+ body = body.parentNode.parentNode;
+ body.removeChild(body.lastElementChild);
+ body.innerHTML += xhr.response.contentHtml;
+ } else {
+ body.innerHTML = ' \
+ <p><a href="javascript:void(0)" \
onclick="hide_youtube_replies(this, \'<%= translate(locale, "Hide replies") %>\', \'<%= translate(locale, "Show replies") %>\')"><%= translate(locale, "Hide replies") %> \
- </a></p> \
- <div>{contentHtml}</div>'.supplant({
- contentHtml: xhr.response.contentHtml,
- });
+ </a></p> \
+ <div>{contentHtml}</div>'.supplant({
+ contentHtml: xhr.response.contentHtml,
+ });
+ }
+ } else {
+ body.innerHTML = fallback;
+ }
}
- } else {
- body.innerHTML = fallback;
- }
- }
- };
-
- xhr.ontimeout = function() {
- console.log('Pulling comments timed out.');
+ };
- body.innerHTML = fallback;
- };
+ xhr.ontimeout = function() {
+ console.log('Pulling comments timed out.');
+ body.innerHTML = fallback;
+ };
}
<% if preferences %>
<% if preferences.comments[0] == "youtube" %>
- get_youtube_comments();
+ get_youtube_comments();
<% elsif preferences.comments[0] == "reddit" %>
- get_reddit_comments();
+ get_reddit_comments();
<% else %>
<% if preferences.comments[1] == "youtube" %>
- get_youtube_comments();
+ get_youtube_comments();
<% elsif preferences.comments[1] == "reddit" %>
- get_reddit_comments();
+ get_reddit_comments();
<% else %>
- comments = document.getElementById("comments");
- comments.innerHTML = "";
+ comments = document.getElementById('comments');
+ comments.innerHTML = '';
<% end %>
<% end %>
<% else %>
-get_youtube_comments();
+ get_youtube_comments();
<% end %>
</script>