diff options
| -rw-r--r-- | assets/css/default.css | 13 | ||||
| -rw-r--r-- | src/invidious.cr | 69 | ||||
| -rw-r--r-- | src/invidious/helpers.cr | 28 | ||||
| -rw-r--r-- | src/invidious/views/watch.ecr | 63 |
4 files changed, 128 insertions, 45 deletions
diff --git a/assets/css/default.css b/assets/css/default.css index 6d776074..7908025a 100644 --- a/assets/css/default.css +++ b/assets/css/default.css @@ -12,3 +12,16 @@ div { overflow-wrap: break-word; word-wrap: break-word; } + +.loading { + animation: spin 2s linear infinite; +} + +@keyframes spin { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} diff --git a/src/invidious.cr b/src/invidious.cr index 80458a5c..251769ae 100644 --- a/src/invidious.cr +++ b/src/invidious.cr @@ -274,6 +274,20 @@ get "/watch" do |env| next env.redirect "/" end + autoplay = env.params.query["autoplay"]?.try &.to_i + video_loop = env.params.query["video_loop"]?.try &.to_i + + if preferences + autoplay ||= preferences.autoplay.to_unsafe + video_loop ||= preferences.video_loop.to_unsafe + end + + autoplay ||= 0 + video_loop ||= 0 + + autoplay = autoplay == 1 + video_loop = video_loop == 1 + if env.params.query["start"]? video_start = decode_time(env.params.query["start"]) end @@ -374,19 +388,6 @@ get "/watch" do |env| k2 = k2.join(", ") end - reddit_client = make_client(REDDIT_URL) - headers = HTTP::Headers{"User-Agent" => "web:invidio.us:v0.1.0 (by /u/omarroth)"} - begin - reddit_comments, reddit_thread = get_reddit_comments(id, reddit_client, headers) - reddit_html = template_comments(reddit_comments) - - reddit_html = fill_links(reddit_html, "https", "www.reddit.com") - reddit_html = add_alt_links(reddit_html) - rescue ex - reddit_thread = nil - reddit_html = "" - end - video.description = fill_links(video.description, "https", "www.youtube.com") video.description = add_alt_links(video.description) @@ -395,6 +396,40 @@ get "/watch" do |env| templated "watch" end +get "/comments/:id" do |env| + id = env.params.url["id"] + + source = env.params.query["source"]? + source ||= "youtube" + + format = env.params.query["format"]? + format ||= "html" + + if source == "reddit" + reddit_client = make_client(REDDIT_URL) + headers = HTTP::Headers{"User-Agent" => "web:invidio.us:v0.1.0 (by /u/omarroth)"} + begin + reddit_comments, reddit_thread = get_reddit_comments(id, reddit_client, headers) + reddit_html = template_comments(reddit_comments) + + reddit_html = fill_links(reddit_html, "https", "www.reddit.com") + reddit_html = add_alt_links(reddit_html) + rescue ex + reddit_thread = nil + reddit_html = "" + end + end + + if !reddit_thread + halt env, status_code: 404 + end + + env.response.content_type = "application/json" + {"title" => reddit_thread.title, + "permalink" => reddit_thread.permalink, + "content_html" => reddit_html}.to_json +end + get "/embed/:id" do |env| if env.params.url["id"]? id = env.params.url["id"] @@ -761,12 +796,12 @@ post "/login" do |env| user = PG_DB.query_one?("SELECT * FROM users WHERE email = $1 AND password IS NOT NULL", email, as: User) if !user - error_message = "Cannot find user with ID #{email}." + error_message = "Invalid username or password" next templated "error" end if !user.password - error_message = "Account appears to be a Google account." + error_message = "Please sign in using 'Sign in with Google'" next templated "error" end @@ -782,13 +817,13 @@ post "/login" do |env| env.response.cookies["SID"] = HTTP::Cookie.new(name: "SID", value: sid, expires: Time.now + 2.years, secure: secure, http_only: true) else - error_message = "Invalid password" + error_message = "Invalid username or password" next templated "error" end elsif action == "register" user = PG_DB.query_one?("SELECT * FROM users WHERE email = $1 AND password IS NOT NULL", email, as: User) if user - error_message = "User already exists, please sign in" + error_message = "Please sign in" next templated "error" end diff --git a/src/invidious/helpers.cr b/src/invidious/helpers.cr index 6af9cb6f..2172b032 100644 --- a/src/invidious/helpers.cr +++ b/src/invidious/helpers.cr @@ -222,20 +222,34 @@ def elapsed_text(elapsed) end def fetch_video(id, client) - info = client.get("/get_video_info?video_id=#{id}&el=detailpage&ps=default&eurl=&gl=US&hl=en&disable_polymer=1").body - html = client.get("/watch?v=#{id}&bpctr=#{Time.new.epoch + 2000}&disable_polymer=1").body + info_channel = Channel(HTTP::Params).new + html_channel = Channel(XML::Node).new - html = XML.parse_html(html) - info = HTTP::Params.parse(info) + spawn do + html = client.get("/watch?v=#{id}&bpctr=#{Time.new.epoch + 2000}&disable_polymer=1").body + html = XML.parse_html(html) + + html_channel.send(html) + end - if info["reason"]? - info = client.get("/get_video_info?video_id=#{id}&ps=default&eurl=&gl=US&hl=en&disable_polymer=1").body + spawn do + info = client.get("/get_video_info?video_id=#{id}&el=detailpage&ps=default&eurl=&gl=US&hl=en&disable_polymer=1").body info = HTTP::Params.parse(info) + if info["reason"]? - raise info["reason"] + info = client.get("/get_video_info?video_id=#{id}&ps=default&eurl=&gl=US&hl=en&disable_polymer=1").body + info = HTTP::Params.parse(info) + if info["reason"]? + raise info["reason"] + end end + + info_channel.send(info) end + html = html_channel.receive + info = info_channel.receive + title = info["title"] views = info["view_count"].to_i64 author = info["author"] diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr index 3fb7ecda..82087c53 100644 --- a/src/invidious/views/watch.ecr +++ b/src/invidious/views/watch.ecr @@ -12,10 +12,8 @@ <div class="h-box"> <video style="width:100%" playsinline poster="<%= thumbnail %>" title="<%= HTML.escape(video.title) %>" id="player" class="video-js vjs-16-9" data-setup="{}" - <% if preferences %> - <% if preferences.autoplay %>autoplay<% end %> - <% if preferences.video_loop %>loop<% end %> - <% end %> + <% if autoplay %>autoplay<% end %> + <% if video_loop %>loop<% end %> controls> <% if listen %> <% audio_streams.each_with_index do |fmt, i| %> @@ -49,6 +47,7 @@ var options = { ], }, }; + var player = videojs('player', options, function() { this.hotkeys({ volumeStep: 0.1, @@ -133,6 +132,43 @@ for ( var i = 0; i < currentSources.length; i++ ) { player.src(currentSources); <% end %> + +fetch("/comments/<%= video.id %>?source=reddit") + .then(function(response) { + return response.json(); + }) + .then(function(jsonResponse) { + comments = document.getElementById('comments'); + comments.innerHTML = ` + <div> + <h3> + <a href="javascript:void(0)" onclick="toggle_comments(this)">[ - ]</a> + {title} + </h3> + <b> + <a target="_blank" href="https://reddit.com{permalink}">View more comments on Reddit</a> + </b> + </div> + <div>{content_html}</div> + </div> + <hr style="margin-left:1em; margin-right:1em;">`.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; + } + ); +}; + </script> <div class="h-box"> @@ -207,26 +243,11 @@ player.src(currentSources); <%= video.description %> </div> <hr style="margin-left:1em; margin-right:1em;"> - <% if reddit_thread && !reddit_html.empty? %> - <div id="Comments"> - <div> - <h3> - <a href="javascript:void(0)" onclick="toggle_comments(this)">[ - ]</a> - <%= reddit_thread.title %> - </h3> - <b> - <a target="_blank" href="https://reddit.com<%= reddit_thread.permalink %>">View more comments on Reddit</a> - </b> - </div> - <div> - <%= reddit_html %> - </div> + <div id="comments"> + <h3><center><i class="loading fas fa-spinner"></i></center></h3> </div> - <hr style="margin-left:1em; margin-right:1em;"> - <% end %> </div> </div> - <div class="pure-u-1 pure-u-md-1-5"> <div class="h-box"> <% rvs.each do |rv| %> |
