diff --git a/assets/css/default.css b/assets/css/default.css index 7e5011e2..80d2dbd0 100644 --- a/assets/css/default.css +++ b/assets/css/default.css @@ -322,13 +322,6 @@ img.thumbnail { object-fit: cover; } -#player { - position: absolute; - left: 0; - top: 0; - height: 100%; -} - .player-dimensions.vjs-fluid { padding-top: 82vh; } @@ -336,8 +329,6 @@ img.thumbnail { #player-container { position: relative; padding-bottom: 82vh; - margin-left: 1em; - margin-right: 1em; height: 0; } diff --git a/src/invidious.cr b/src/invidious.cr index 928beee5..0a2174ce 100644 --- a/src/invidious.cr +++ b/src/invidious.cr @@ -982,12 +982,11 @@ post "/login" do |env| preferences = env.get("preferences").as(Preferences) PG_DB.exec("UPDATE users SET preferences = $1 WHERE email = $2", preferences, user.email) - login.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", value: "", expires: Time.new(1990, 1, 1), - secure: secure, http_only: true) + cookie = env.request.cookies["PREFS"] + cookie.expires = Time.new(1990, 1, 1) + env.response.cookies << cookie end - login.cookies.add_response_headers(env.response.headers) - env.redirect referer rescue ex error_message = translate(locale, "Login failed. This may be because two-factor authentication is not enabled on your account.") @@ -1099,8 +1098,9 @@ post "/login" do |env| # Since this user has already registered, we don't want to overwrite their preferences if env.request.cookies["PREFS"]? - env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", value: "", expires: Time.new(1990, 1, 1), - secure: secure, http_only: true) + cookie = env.request.cookies["PREFS"] + cookie.expires = Time.new(1990, 1, 1) + env.response.cookies << cookie end elsif action == "register" if !config.registration_enabled @@ -1156,11 +1156,12 @@ post "/login" do |env| end if env.request.cookies["PREFS"]? - preferences = env.get("preferences").as(Preferences) + preferences = env.get("preferences").as(Preferences).to_json PG_DB.exec("UPDATE users SET preferences = $1 WHERE email = $2", preferences, user.email) - env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", value: "", expires: Time.new(1990, 1, 1), - secure: secure, http_only: true) + cookie = env.request.cookies["PREFS"] + cookie.expires = Time.new(1990, 1, 1) + env.response.cookies << cookie end end @@ -1193,9 +1194,8 @@ get "/signout" do |env| env.request.cookies.each do |cookie| cookie.expires = Time.new(1990, 1, 1) + env.response.cookies << cookie end - - env.request.cookies.add_response_headers(env.response.headers) end env.redirect referer @@ -1803,8 +1803,8 @@ post "/delete_account" do |env| env.request.cookies.each do |cookie| cookie.expires = Time.new(1990, 1, 1) + env.response.cookies << cookie end - env.request.cookies.add_response_headers(env.response.headers) end env.redirect referer @@ -2471,7 +2471,14 @@ get "/channel/:ucid" do |env| sort_by ||= "last" items, continuation = fetch_channel_playlists(ucid, author, auto_generated, continuation, sort_by) - items.select! { |item| item.is_a?(SearchPlaylist) && !item.videos.empty? } + items.uniq! do |item| + if item.responds_to?(:title) + item.title + elsif item.responds_to?(:author) + item.author + end + end + items.select! { |item| item.responds_to?(:thumbnail_id) && item.thumbnail_id } items = items.map { |item| item.as(SearchPlaylist) } items.each { |item| item.author = "" } else diff --git a/src/invidious/helpers/helpers.cr b/src/invidious/helpers/helpers.cr index 1cd40d41..271aa0c4 100644 --- a/src/invidious/helpers/helpers.cr +++ b/src/invidious/helpers/helpers.cr @@ -232,13 +232,22 @@ def extract_items(nodeset, ucid = nil, author_name = nil) ) end + playlist_thumbnail = node.xpath_node(%q(.//div/span/img)).try &.["data-thumb"]? + playlist_thumbnail ||= node.xpath_node(%q(.//div/span/img)).try &.["src"] + if !playlist_thumbnail || playlist_thumbnail.empty? + thumbnail_id = videos[0]?.try &.id + else + thumbnail_id = playlist_thumbnail.match(/\/vi\/(?[a-zA-Z0-9_-]{11})\/\w+\.jpg/).try &.["video_id"] + end + items << SearchPlaylist.new( title, plid, author, author_id, video_count, - videos + videos, + thumbnail_id ) when .includes? "yt-lockup-channel" author = title.strip @@ -399,13 +408,28 @@ def extract_shelf_items(nodeset, ucid = nil, author_name = nil) playlist_title ||= "" plid ||= "" + playlist_thumbnail = child_node.xpath_node(%q(.//span/img)).try &.["data-thumb"]? + playlist_thumbnail ||= child_node.xpath_node(%q(.//span/img)).try &.["src"] + if !playlist_thumbnail || playlist_thumbnail.empty? + thumbnail_id = videos[0]?.try &.id + else + thumbnail_id = playlist_thumbnail.match(/\/vi\/(?[a-zA-Z0-9_-]{11})\/\w+\.jpg/).try &.["video_id"] + end + + video_count_label = child_node.xpath_node(%q(.//span[@class="formatted-video-count-label"])) + if video_count_label + video_count = video_count_label.content.strip.match(/^\d+/).try &.[0].to_i? + end + video_count ||= 50 + items << SearchPlaylist.new( playlist_title, plid, author_name, ucid, - 50, - Array(SearchPlaylistVideo).new + video_count, + Array(SearchPlaylistVideo).new, + thumbnail_id ) end end @@ -419,7 +443,8 @@ def extract_shelf_items(nodeset, ucid = nil, author_name = nil) author_name, ucid, videos.size, - videos + videos, + videos[0].try &.id ) end end diff --git a/src/invidious/helpers/utils.cr b/src/invidious/helpers/utils.cr index 3123b1d2..eb8fa80a 100644 --- a/src/invidious/helpers/utils.cr +++ b/src/invidious/helpers/utils.cr @@ -162,6 +162,23 @@ def number_with_separator(number) number.to_s.reverse.gsub(/(\d{3})(?=\d)/, "\\1,").reverse end +def short_text_to_number(short_text) + case short_text + when .ends_with? "M" + number = short_text.rstrip(" mM").to_f + number *= 1000000 + when .ends_with? "K" + number = short_text.rstrip(" kK").to_f + number *= 1000 + else + number = short_text.rstrip(" ") + end + + number = number.to_i + + return number +end + def number_to_short_text(number) seperated = number_with_separator(number).gsub(",", ".").split("") text = seperated.first(2).join diff --git a/src/invidious/search.cr b/src/invidious/search.cr index ec97cf85..63cce4de 100644 --- a/src/invidious/search.cr +++ b/src/invidious/search.cr @@ -25,12 +25,13 @@ end class SearchPlaylist add_mapping({ - title: String, - id: String, - author: String, - ucid: String, - video_count: Int32, - videos: Array(SearchPlaylistVideo), + title: String, + id: String, + author: String, + ucid: String, + video_count: Int32, + videos: Array(SearchPlaylistVideo), + thumbnail_id: String?, }) end diff --git a/src/invidious/views/components/item.ecr b/src/invidious/views/components/item.ecr index 51aa7193..fe48834f 100644 --- a/src/invidious/views/components/item.ecr +++ b/src/invidious/views/components/item.ecr @@ -16,7 +16,7 @@
<%= item.description_html %>
<% when SearchPlaylist %> <% if item.id.starts_with? "RD" %> - <% url = "/mix?list=#{item.id}&continuation=#{item.videos[0]?.try &.id}" %> + <% url = "/mix?list=#{item.id}&continuation=#{item.thumbnail_id}" %> <% else %> <% url = "/playlist?list=#{item.id}" %> <% end %> @@ -24,7 +24,7 @@ <% if env.get?("user") && env.get("user").as(User).preferences.thin_mode %> <% else %>
- +

<%= number_with_separator(item.video_count) %> videos

<% end %> diff --git a/src/invidious/views/components/player.ecr b/src/invidious/views/components/player.ecr index 7bcb5e42..fef3f728 100644 --- a/src/invidious/views/components/player.ecr +++ b/src/invidious/views/components/player.ecr @@ -79,9 +79,9 @@ var player = videojs("player", options, function() { seekStep: 5, enableModifiersForNumbers: false, customKeys: { + // Toggle play with K Key play: { key: function(e) { - // Toggle play with K Key return e.which === 75; }, handler: function(player, options, e) { @@ -92,23 +92,45 @@ var player = videojs("player", options, function() { } } }, + // Go backward 5 seconds backward: { key: function(e) { - // Go backward 5 seconds return e.which === 74; }, handler: function(player, options, e) { player.currentTime(player.currentTime() - 5); } }, + // Go forward 5 seconds forward: { key: function(e) { - // Go forward 5 seconds return e.which === 76; }, handler: function(player, options, e) { player.currentTime(player.currentTime() + 5); } + }, + // Increase speed + increase_speed: { + key: function(e) { + return e.which === 190; + }, + 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; + }, + handler: function(player, _, e) { + size = options.playbackRates.length; + index = options.playbackRates.indexOf(player.playbackRate()); + player.playbackRate(options.playbackRates[(size + index - 1) % size]); + } } } }); diff --git a/src/invidious/views/embed.ecr b/src/invidious/views/embed.ecr index 8daf62a5..f32a6685 100644 --- a/src/invidious/views/embed.ecr +++ b/src/invidious/views/embed.ecr @@ -9,8 +9,7 @@ <%= HTML.escape(video.title) %> - Invidious