diff --git a/src/invidious.cr b/src/invidious.cr index 0b014424..1d701342 100644 --- a/src/invidious.cr +++ b/src/invidious.cr @@ -504,7 +504,7 @@ get "/api/v1/comments/:id" do |env| source ||= "youtube" format = env.params.query["format"]? - format ||= "html" + format ||= "json" if source == "youtube" client = make_client(YT_URL) @@ -627,13 +627,20 @@ get "/api/v1/comments/:id" do |env| end env.response.content_type = "application/json" - next comments + if format == "json" + next comments + else + comments = JSON.parse(comments) + content_html = template_youtube_comments(comments) + + {"content_html" => content_html}.to_json + end elsif source == "reddit" client = make_client(REDDIT_URL) headers = HTTP::Headers{"User-Agent" => "web:invidio.us:v0.1.0 (by /u/omarroth)"} begin comments, reddit_thread = get_reddit_comments(id, client, headers) - content_html = template_comments(comments) + content_html = template_reddit_comments(comments) content_html = fill_links(content_html, "https", "www.reddit.com") content_html = add_alt_links(content_html) @@ -1664,6 +1671,9 @@ post "/preferences" do |env| volume = env.params.body["volume"]?.try &.as(String).to_i volume ||= 100 + comments = env.params.body["comments"]? + comments ||= "youtube" + dark_mode = env.params.body["dark_mode"]?.try &.as(String) dark_mode ||= "off" dark_mode = dark_mode == "on" @@ -1688,6 +1698,7 @@ post "/preferences" do |env| "speed" => speed, "quality" => quality, "volume" => volume, + "comments" => comments, "dark_mode" => dark_mode, "thin_mode" => thin_mode, "max_results" => max_results, diff --git a/src/invidious/helpers.cr b/src/invidious/helpers.cr index 793bf077..676b3585 100644 --- a/src/invidious/helpers.cr +++ b/src/invidious/helpers.cr @@ -23,6 +23,7 @@ DEFAULT_USER_PREFERENCES = Preferences.from_json({ "speed" => 1.0, "quality" => "hd720", "volume" => 100, + "comments" => "youtube", "dark_mode" => false, "thin_mode " => false, "max_results" => 40, @@ -157,8 +158,13 @@ class Preferences speed: Float32, quality: String, volume: Int32, - dark_mode: Bool, - thin_mode: { + comments: { + type: String, + nilable: true, + default: "youtube", + }, + dark_mode: Bool, + thin_mode: { type: Bool, nilable: true, default: false, @@ -500,7 +506,56 @@ def get_reddit_comments(id, client, headers) return comments, thread end -def template_comments(root) +def template_youtube_comments(comments) + html = "" + + root = comments["comments"].as_a + root.each do |child| + if child["replies"]? + replies_html = <<-END_HTML +
+
+
+

+ View #{child["replies"]["replyCount"]} replies +

+
+ END_HTML + end + + html += <<-END_HTML +
+
+

+ [ - ] #{child["likeCount"]} #{child["author"]} +

+
+ #{child["content"]} + #{replies_html} +
+
+
+ END_HTML + end + + if comments["continuation"]? + html += <<-END_HTML +
+
+

+ Load more +

+
+
+ END_HTML + end + + return html +end + +def template_reddit_comments(root) html = "" root.each do |child| if child.data.is_a?(RedditComment) @@ -512,7 +567,7 @@ def template_comments(root) replies_html = "" if child.replies.is_a?(RedditThing) replies = child.replies.as(RedditThing) - replies_html = template_comments(replies.data.as(RedditListing).children) + replies_html = template_reddit_comments(replies.data.as(RedditListing).children) end content = <<-END_HTML diff --git a/src/invidious/views/preferences.ecr b/src/invidious/views/preferences.ecr index 50e8b0e9..9fd42d03 100644 --- a/src/invidious/views/preferences.ecr +++ b/src/invidious/views/preferences.ecr @@ -47,6 +47,15 @@ function update_value(element) { <%= user.preferences.volume %>
+
+ + +
+ Visual preferences
diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr index 962c3235..810a43e7 100644 --- a/src/invidious/views/watch.ecr +++ b/src/invidious/views/watch.ecr @@ -124,28 +124,6 @@ player.offset({ end: <%= video_end %> }); -function toggle(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 = ''; - } -}; - -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 = ''; - } -}; - <% if !listen %> var currentSources = player.currentSources(); for ( var i = 0; i < currentSources.length; i++ ) { @@ -158,12 +136,74 @@ for ( var i = 0; i < currentSources.length; i++ ) { player.src(currentSources); <% end %> -fetch("/api/v1/comments/<%= video.id %>?source=reddit") +function toggle(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 = ""; + } +} + +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 = ""; + } +} + +function timeout(ms, promise) { + return new Promise(function(resolve, reject) { + setTimeout(function() { + reject(new Error("timeout")); + }, ms); + promise.then(resolve, reject); + }); +} + +function load_comments(target) { + var continuation = target.getAttribute("data-continuation"); + + var body = target.parentNode.parentNode; + var fallback = body.innerHTML; + body.innerHTML = + '

'; + + var url = + "/api/v1/comments/<%= video.id %>?format=html&continuation=" + continuation; + timeout(5000, fetch(url)) .then(function(response) { - return response.json(); + return response.json(); }) - .then(function(jsonResponse) { - comments = document.getElementById('comments'); + .then( + function(jsonResponse) { + body.innerHTML = jsonResponse.content_html; + }, + function(error) { + body.innerHTML = fallback; + console.log(response); + } + ) + .catch(function(error) { + body.innerHTML = fallback; + console.log(error); + }); +} + +function get_reddit_comments() { + fetch("/api/v1/comments/<%= video.id %>?source=reddit") + .then(function(response) { + return response.json(); + }) + .then( + function(jsonResponse) { + comments = document.getElementById("comments"); comments.innerHTML = `

@@ -175,25 +215,52 @@ fetch("/api/v1/comments/<%= video.id %>?source=reddit")

{content_html}
-
-
`.supplant({ - title: jsonResponse.title, - permalink: jsonResponse.permalink, - content_html: jsonResponse.content_html - }) - }, function(response){ - comments.innerHTML = ""; - }); -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; - } +
`.supplant({ + title: jsonResponse.title, + permalink: jsonResponse.permalink, + content_html: jsonResponse.content_html + }); + }, + function(response) { + get_youtube_comments(); + } ); +} + +function get_youtube_comments() { + fetch("/api/v1/comments/<%= video.id %>?format=html") + .then(function(response) { + return response.json(); + }) + .then( + function(jsonResponse) { + comments = document.getElementById("comments"); + comments.innerHTML = ` +
{content_html}
+
`.supplant({ + content_html: jsonResponse.content_html + }); + }, + function(response) { + comments.innerHTML = ""; + } + ); +} + +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; + }); }; +<% if preferences && preferences.comments == "reddit" %> +get_reddit_comments(); +<% else %> +get_youtube_comments(); +<% end %> +