frontend: Add support for the "featured channels" page

This commit is contained in:
Samantaz Fox 2022-12-05 00:50:04 +01:00
parent b6a4de66a5
commit 4e3a930626
No known key found for this signature in database
GPG Key ID: F42821059186176E
7 changed files with 37 additions and 63 deletions

View File

@ -475,5 +475,6 @@
"channel_tab_shorts_label": "Shorts", "channel_tab_shorts_label": "Shorts",
"channel_tab_streams_label": "Livestreams", "channel_tab_streams_label": "Livestreams",
"channel_tab_playlists_label": "Playlists", "channel_tab_playlists_label": "Playlists",
"channel_tab_community_label": "Community" "channel_tab_community_label": "Community",
"channel_tab_channels_label": "Channels"
} }

View File

@ -16,12 +16,6 @@ record AboutChannel,
tabs : Array(String), tabs : Array(String),
verified : Bool verified : Bool
record AboutRelatedChannel,
ucid : String,
author : String,
author_url : String,
author_thumbnail : String
def get_about_info(ucid, locale) : AboutChannel def get_about_info(ucid, locale) : AboutChannel
begin begin
# "EgVhYm91dA==" is the base64-encoded protobuf object {"2:string":"about"} # "EgVhYm91dA==" is the base64-encoded protobuf object {"2:string":"about"}
@ -165,41 +159,15 @@ def get_about_info(ucid, locale) : AboutChannel
) )
end end
def fetch_related_channels(about_channel : AboutChannel) : Array(AboutRelatedChannel) def fetch_related_channels(about_channel : AboutChannel, continuation : String? = nil) : {Array(SearchChannel), String?}
# params is {"2:string":"channels"} encoded if continuation.nil?
channels = YoutubeAPI.browse(browse_id: about_channel.ucid, params: "EghjaGFubmVscw%3D%3D") # params is {"2:string":"channels"} encoded
initial_data = YoutubeAPI.browse(browse_id: about_channel.ucid, params: "EghjaGFubmVscw%3D%3D")
tabs = channels.dig?("contents", "twoColumnBrowseResultsRenderer", "tabs").try(&.as_a?) || [] of JSON::Any else
tab = tabs.find(&.dig?("tabRenderer", "title").try(&.as_s?).try(&.== "Channels")) initial_data = YoutubeAPI.browse(continuation)
return [] of AboutRelatedChannel if tab.nil?
items = tab.dig?(
"tabRenderer", "content",
"sectionListRenderer", "contents", 0,
"itemSectionRenderer", "contents", 0,
"gridRenderer", "items"
).try &.as_a?
related = [] of AboutRelatedChannel
return related if (items.nil? || items.empty?)
items.each do |item|
renderer = item["gridChannelRenderer"]?
next if !renderer
related_id = renderer.dig("channelId").as_s
related_title = renderer.dig("title", "simpleText").as_s
related_author_url = renderer.dig("navigationEndpoint", "browseEndpoint", "canonicalBaseUrl").as_s
related_author_thumbnail = HelperExtractors.get_thumbnails(renderer)
related << AboutRelatedChannel.new(
ucid: related_id,
author: related_title,
author_url: related_author_url,
author_thumbnail: related_author_thumbnail,
)
end end
return related items, continuation = extract_items(initial_data)
return items.select(SearchChannel), continuation
end end

View File

@ -7,6 +7,7 @@ module Invidious::Frontend::ChannelPage
Streams Streams
Playlists Playlists
Community Community
Channels
end end
def generate_tabs_links(locale : String, channel : AboutChannel, selected_tab : TabsAvailable) def generate_tabs_links(locale : String, channel : AboutChannel, selected_tab : TabsAvailable)

View File

@ -102,31 +102,13 @@ module Invidious::Routes::API::V1::Channels
json.array do json.array do
# Fetch related channels # Fetch related channels
begin begin
related_channels = fetch_related_channels(channel) related_channels, _ = fetch_related_channels(channel)
rescue ex rescue ex
related_channels = [] of AboutRelatedChannel related_channels = [] of SearchChannel
end end
related_channels.each do |related_channel| related_channels.each do |related_channel|
json.object do related_channel.to_json(locale, json)
json.field "author", related_channel.author
json.field "authorId", related_channel.ucid
json.field "authorUrl", related_channel.author_url
json.field "authorThumbnails" do
json.array do
qualities = {32, 48, 76, 100, 176, 512}
qualities.each do |quality|
json.object do
json.field "url", related_channel.author_thumbnail.gsub(/=\d+/, "=s#{quality}")
json.field "width", quality
json.field "height", quality
end
end
end
end
end
end end
end end
end # relatedChannels end # relatedChannels

View File

@ -147,6 +147,26 @@ module Invidious::Routes::Channels
templated "community" templated "community"
end end
def self.channels(env)
data = self.fetch_basic_information(env)
return data if !data.is_a?(Tuple)
locale, user, subscriptions, continuation, ucid, channel = data
if channel.auto_generated
return env.redirect "/channel/#{channel.ucid}"
end
items, next_continuation = fetch_related_channels(channel, continuation)
# Featured/related channels can't be sorted
sort_options = [] of String
sort_by = nil
selected_tab = Frontend::ChannelPage::TabsAvailable::Channels
templated "channel"
end
def self.about(env) def self.about(env)
data = self.fetch_basic_information(env) data = self.fetch_basic_information(env)
if !data.is_a?(Tuple) if !data.is_a?(Tuple)

View File

@ -119,6 +119,7 @@ module Invidious::Routing
get "/channel/:ucid/streams", Routes::Channels, :streams get "/channel/:ucid/streams", Routes::Channels, :streams
get "/channel/:ucid/playlists", Routes::Channels, :playlists get "/channel/:ucid/playlists", Routes::Channels, :playlists
get "/channel/:ucid/community", Routes::Channels, :community get "/channel/:ucid/community", Routes::Channels, :community
get "/channel/:ucid/channels", Routes::Channels, :channels
get "/channel/:ucid/about", Routes::Channels, :about get "/channel/:ucid/about", Routes::Channels, :about
get "/channel/:ucid/live", Routes::Channels, :live get "/channel/:ucid/live", Routes::Channels, :live
get "/user/:user/live", Routes::Channels, :live get "/user/:user/live", Routes::Channels, :live

View File

@ -8,6 +8,7 @@
when .shorts? then "/channel/#{ucid}/shorts" when .shorts? then "/channel/#{ucid}/shorts"
when .streams? then "/channel/#{ucid}/streams" when .streams? then "/channel/#{ucid}/streams"
when .playlists? then "/channel/#{ucid}/playlists" when .playlists? then "/channel/#{ucid}/playlists"
when .channels? then "/channel/#{ucid}/channels"
else else
"/channel/#{ucid}" "/channel/#{ucid}"
end end