forked from midou/invidious
frontend: Add support for the "featured channels" page
This commit is contained in:
parent
b6a4de66a5
commit
4e3a930626
@ -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"
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user