Channels: Add sort options to streams (#4224)

This commit is contained in:
Samantaz Fox 2024-07-10 22:28:22 +02:00
commit bad92093bf
No known key found for this signature in database
GPG Key ID: F42821059186176E
3 changed files with 26 additions and 22 deletions

View File

@ -1,4 +1,4 @@
def produce_channel_videos_continuation(ucid, page = 1, auto_generated = nil, sort_by = "newest", v2 = false) def produce_channel_content_continuation(ucid, content_type, page = 1, auto_generated = nil, sort_by = "newest", v2 = false)
object_inner_2 = { object_inner_2 = {
"2:0:embedded" => { "2:0:embedded" => {
"1:0:varint" => 0_i64, "1:0:varint" => 0_i64,
@ -16,6 +16,13 @@ def produce_channel_videos_continuation(ucid, page = 1, auto_generated = nil, so
.try { |i| Base64.urlsafe_encode(i) } .try { |i| Base64.urlsafe_encode(i) }
.try { |i| URI.encode_www_form(i) } .try { |i| URI.encode_www_form(i) }
content_type_numerical =
case content_type
when "videos" then 15
when "livestreams" then 14
else 15 # Fallback to "videos"
end
sort_by_numerical = sort_by_numerical =
case sort_by case sort_by
when "newest" then 1_i64 when "newest" then 1_i64
@ -27,7 +34,7 @@ def produce_channel_videos_continuation(ucid, page = 1, auto_generated = nil, so
object_inner_1 = { object_inner_1 = {
"110:embedded" => { "110:embedded" => {
"3:embedded" => { "3:embedded" => {
"15:embedded" => { "#{content_type_numerical}:embedded" => {
"1:embedded" => { "1:embedded" => {
"1:string" => object_inner_2_encoded, "1:string" => object_inner_2_encoded,
}, },
@ -62,6 +69,10 @@ def produce_channel_videos_continuation(ucid, page = 1, auto_generated = nil, so
return continuation return continuation
end end
def make_initial_content_ctoken(ucid, content_type, sort_by) : String
return produce_channel_content_continuation(ucid, content_type, sort_by: sort_by)
end
module Invidious::Channel::Tabs module Invidious::Channel::Tabs
extend self extend self
@ -69,10 +80,6 @@ module Invidious::Channel::Tabs
# Regular videos # Regular videos
# ------------------- # -------------------
def make_initial_video_ctoken(ucid, sort_by) : String
return produce_channel_videos_continuation(ucid, sort_by: sort_by)
end
# Wrapper for AboutChannel, as we still need to call get_videos with # Wrapper for AboutChannel, as we still need to call get_videos with
# an author name and ucid directly (e.g in RSS feeds). # an author name and ucid directly (e.g in RSS feeds).
# TODO: figure out how to get rid of that # TODO: figure out how to get rid of that
@ -94,7 +101,7 @@ module Invidious::Channel::Tabs
end end
def get_videos(author : String, ucid : String, *, continuation : String? = nil, sort_by = "newest") def get_videos(author : String, ucid : String, *, continuation : String? = nil, sort_by = "newest")
continuation ||= make_initial_video_ctoken(ucid, sort_by) continuation ||= make_initial_content_ctoken(ucid, "videos", sort_by)
initial_data = YoutubeAPI.browse(continuation: continuation) initial_data = YoutubeAPI.browse(continuation: continuation)
return extract_items(initial_data, author, ucid) return extract_items(initial_data, author, ucid)
@ -138,21 +145,18 @@ module Invidious::Channel::Tabs
# Livestreams # Livestreams
# ------------------- # -------------------
def get_livestreams(channel : AboutChannel, continuation : String? = nil) def get_livestreams(channel : AboutChannel, continuation : String? = nil, sort_by = "newest")
if continuation.nil? continuation ||= make_initial_content_ctoken(channel.ucid, "livestreams", sort_by)
# EgdzdHJlYW1z8gYECgJ6AA%3D%3D is the protobuf object to load "streams"
initial_data = YoutubeAPI.browse(channel.ucid, params: "EgdzdHJlYW1z8gYECgJ6AA%3D%3D") initial_data = YoutubeAPI.browse(continuation: continuation)
else
initial_data = YoutubeAPI.browse(continuation: continuation)
end
return extract_items(initial_data, channel.author, channel.ucid) return extract_items(initial_data, channel.author, channel.ucid)
end end
def get_60_livestreams(channel : AboutChannel, continuation : String? = nil) def get_60_livestreams(channel : AboutChannel, *, continuation : String? = nil, sort_by = "newest")
if continuation.nil? if continuation.nil?
# Fetch the first "page" of streams # Fetch the first "page" of stream
items, next_continuation = get_livestreams(channel) items, next_continuation = get_livestreams(channel, sort_by: sort_by)
else else
# Fetch a "page" of streams using the given continuation token # Fetch a "page" of streams using the given continuation token
items, next_continuation = get_livestreams(channel, continuation: continuation) items, next_continuation = get_livestreams(channel, continuation: continuation)

View File

@ -208,11 +208,12 @@ module Invidious::Routes::API::V1::Channels
get_channel() get_channel()
# Retrieve continuation from URL parameters # Retrieve continuation from URL parameters
sort_by = env.params.query["sort_by"]?.try &.downcase || "newest"
continuation = env.params.query["continuation"]? continuation = env.params.query["continuation"]?
begin begin
videos, next_continuation = Channel::Tabs.get_60_livestreams( videos, next_continuation = Channel::Tabs.get_60_livestreams(
channel, continuation: continuation channel, continuation: continuation, sort_by: sort_by
) )
rescue ex rescue ex
return error_json(500, ex) return error_json(500, ex)

View File

@ -81,13 +81,12 @@ module Invidious::Routes::Channels
return env.redirect "/channel/#{channel.ucid}" return env.redirect "/channel/#{channel.ucid}"
end end
# TODO: support sort option for livestreams sort_by = env.params.query["sort_by"]?.try &.downcase || "newest"
sort_by = "" sort_options = {"newest", "oldest", "popular"}
sort_options = [] of String
# Fetch items and continuation token # Fetch items and continuation token
items, next_continuation = Channel::Tabs.get_60_livestreams( items, next_continuation = Channel::Tabs.get_60_livestreams(
channel, continuation: continuation channel, continuation: continuation, sort_by: sort_by
) )
selected_tab = Frontend::ChannelPage::TabsAvailable::Streams selected_tab = Frontend::ChannelPage::TabsAvailable::Streams