frontend: Add support for shorts and livestreams
This commit is contained in:
parent
5d6abd5301
commit
6c9754e663
|
@ -404,9 +404,7 @@
|
|||
"`x` marked it with a ❤": "`x` marked it with a ❤",
|
||||
"Audio mode": "Audio mode",
|
||||
"Video mode": "Video mode",
|
||||
"Videos": "Videos",
|
||||
"Playlists": "Playlists",
|
||||
"Community": "Community",
|
||||
"search_filters_title": "Filters",
|
||||
"search_filters_date_label": "Upload date",
|
||||
"search_filters_date_option_none": "Any date",
|
||||
|
@ -472,5 +470,10 @@
|
|||
"crash_page_read_the_faq": "read the <a href=\"`x`\">Frequently Asked Questions (FAQ)</a>",
|
||||
"crash_page_search_issue": "searched for <a href=\"`x`\">existing issues on GitHub</a>",
|
||||
"crash_page_report_issue": "If none of the above helped, please <a href=\"`x`\">open a new issue on GitHub</a> (preferably in English) and include the following text in your message (do NOT translate that text):",
|
||||
"error_video_not_in_playlist": "The requested video doesn't exist in this playlist. <a href=\"`x`\">Click here for the playlist home page.</a>"
|
||||
"error_video_not_in_playlist": "The requested video doesn't exist in this playlist. <a href=\"`x`\">Click here for the playlist home page.</a>",
|
||||
"channel_tab_videos_label": "Videos",
|
||||
"channel_tab_shorts_label": "Shorts",
|
||||
"channel_tab_streams_label": "Livestreams",
|
||||
"channel_tab_playlists_label": "Playlists",
|
||||
"channel_tab_community_label": "Community"
|
||||
}
|
||||
|
|
|
@ -104,8 +104,14 @@ def get_about_info(ucid, locale) : AboutChannel
|
|||
|
||||
if tabs_json = initdata["contents"]["twoColumnBrowseResultsRenderer"]["tabs"]?
|
||||
# Get the name of the tabs available on this channel
|
||||
tab_names = tabs_json.as_a
|
||||
.compact_map(&.dig?("tabRenderer", "title").try &.as_s.downcase)
|
||||
tab_names = tabs_json.as_a.compact_map do |entry|
|
||||
name = entry.dig?("tabRenderer", "title").try &.as_s.downcase
|
||||
|
||||
# This is a small fix to not add extra code on the HTML side
|
||||
# I.e, the URL for the "live" tab is .../streams, so use "streams"
|
||||
# everywhere for the sake of simplicity
|
||||
(name == "live") ? "streams" : name
|
||||
end
|
||||
|
||||
# Get the currently active tab ("About")
|
||||
about_tab = extract_selected_tab(tabs_json)
|
||||
|
|
43
src/invidious/frontend/channel_page.cr
Normal file
43
src/invidious/frontend/channel_page.cr
Normal file
|
@ -0,0 +1,43 @@
|
|||
module Invidious::Frontend::ChannelPage
|
||||
extend self
|
||||
|
||||
enum TabsAvailable
|
||||
Videos
|
||||
Shorts
|
||||
Streams
|
||||
Playlists
|
||||
Community
|
||||
end
|
||||
|
||||
def generate_tabs_links(locale : String, channel : AboutChannel, selected_tab : TabsAvailable)
|
||||
return String.build(1500) do |str|
|
||||
base_url = "/channel/#{channel.ucid}"
|
||||
|
||||
TabsAvailable.each do |tab|
|
||||
# Ignore playlists, as it is not supported for auto-generated channels yet
|
||||
next if (tab.playlists? && channel.auto_generated)
|
||||
|
||||
tab_name = tab.to_s.downcase
|
||||
|
||||
if channel.tabs.includes? tab_name
|
||||
str << %(<div class="pure-u-1 pure-md-1-3">\n)
|
||||
|
||||
if tab == selected_tab
|
||||
str << "\t<b>"
|
||||
str << translate(locale, "channel_tab_#{tab_name}_label")
|
||||
str << "</b>\n"
|
||||
else
|
||||
# Video tab doesn't have the last path component
|
||||
url = tab.videos? ? base_url : "#{base_url}/#{tab_name}"
|
||||
|
||||
str << %(\t<a href=") << url << %(">)
|
||||
str << translate(locale, "channel_tab_#{tab_name}_label")
|
||||
str << "</a>\n"
|
||||
end
|
||||
|
||||
str << "</div>"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -18,7 +18,7 @@ module Invidious::Routes::Channels
|
|||
sort_options = {"last", "oldest", "newest"}
|
||||
sort_by ||= "last"
|
||||
|
||||
items, continuation = fetch_channel_playlists(channel.ucid, channel.author, continuation, sort_by)
|
||||
items, next_continuation = fetch_channel_playlists(channel.ucid, channel.author, continuation, sort_by)
|
||||
items.uniq! do |item|
|
||||
if item.responds_to?(:title)
|
||||
item.title
|
||||
|
@ -32,11 +32,59 @@ module Invidious::Routes::Channels
|
|||
sort_options = {"newest", "oldest", "popular"}
|
||||
sort_by ||= "newest"
|
||||
|
||||
items, continuation = Channel::Tabs.get_60_videos(
|
||||
# Fetch items and continuation token
|
||||
items, next_continuation = Channel::Tabs.get_videos(
|
||||
channel, continuation: continuation, sort_by: sort_by
|
||||
)
|
||||
end
|
||||
|
||||
selected_tab = Frontend::ChannelPage::TabsAvailable::Videos
|
||||
templated "channel"
|
||||
end
|
||||
|
||||
def self.shorts(env)
|
||||
data = self.fetch_basic_information(env)
|
||||
return data if !data.is_a?(Tuple)
|
||||
|
||||
locale, user, subscriptions, continuation, ucid, channel = data
|
||||
|
||||
if !channel.tabs.includes? "shorts"
|
||||
return env.redirect "/channel/#{channel.ucid}"
|
||||
end
|
||||
|
||||
# TODO: support sort option for shorts
|
||||
sort_by = ""
|
||||
sort_options = [] of String
|
||||
|
||||
# Fetch items and continuation token
|
||||
items, next_continuation = Channel::Tabs.get_shorts(
|
||||
channel, continuation: continuation
|
||||
)
|
||||
|
||||
selected_tab = Frontend::ChannelPage::TabsAvailable::Shorts
|
||||
templated "channel"
|
||||
end
|
||||
|
||||
def self.streams(env)
|
||||
data = self.fetch_basic_information(env)
|
||||
return data if !data.is_a?(Tuple)
|
||||
|
||||
locale, user, subscriptions, continuation, ucid, channel = data
|
||||
|
||||
if !channel.tabs.includes? "streams"
|
||||
return env.redirect "/channel/#{channel.ucid}"
|
||||
end
|
||||
|
||||
# TODO: support sort option for livestreams
|
||||
sort_by = ""
|
||||
sort_options = [] of String
|
||||
|
||||
# Fetch items and continuation token
|
||||
items, next_continuation = Channel::Tabs.get_60_livestreams(
|
||||
channel, continuation: continuation
|
||||
)
|
||||
|
||||
selected_tab = Frontend::ChannelPage::TabsAvailable::Streams
|
||||
templated "channel"
|
||||
end
|
||||
|
||||
|
@ -124,7 +172,7 @@ module Invidious::Routes::Channels
|
|||
end
|
||||
|
||||
selected_tab = env.request.path.split("/")[-1]
|
||||
if ["home", "videos", "playlists", "community", "channels", "about"].includes? selected_tab
|
||||
if {"home", "videos", "shorts", "streams", "playlists", "community", "channels", "about"}.includes? selected_tab
|
||||
url = "/channel/#{ucid}/#{selected_tab}"
|
||||
else
|
||||
url = "/channel/#{ucid}"
|
||||
|
|
|
@ -115,6 +115,8 @@ module Invidious::Routing
|
|||
get "/channel/:ucid", Routes::Channels, :home
|
||||
get "/channel/:ucid/home", Routes::Channels, :home
|
||||
get "/channel/:ucid/videos", Routes::Channels, :videos
|
||||
get "/channel/:ucid/shorts", Routes::Channels, :shorts
|
||||
get "/channel/:ucid/streams", Routes::Channels, :streams
|
||||
get "/channel/:ucid/playlists", Routes::Channels, :playlists
|
||||
get "/channel/:ucid/community", Routes::Channels, :community
|
||||
get "/channel/:ucid/about", Routes::Channels, :about
|
||||
|
@ -122,7 +124,7 @@ module Invidious::Routing
|
|||
get "/user/:user/live", Routes::Channels, :live
|
||||
get "/c/:user/live", Routes::Channels, :live
|
||||
|
||||
["", "/videos", "/playlists", "/community", "/about"].each do |path|
|
||||
{"", "/videos", "/shorts", "/streams", "/playlists", "/community", "/about"}.each do |path|
|
||||
# /c/LinusTechTips
|
||||
get "/c/:user#{path}", Routes::Channels, :brand_redirect
|
||||
# /user/linustechtips | Not always the same as /c/
|
||||
|
|
|
@ -64,23 +64,8 @@
|
|||
<a href="https://redirect.invidious.io<%= env.request.path %>"><%= translate(locale, "Switch Invidious Instance") %></a>
|
||||
<% end %>
|
||||
</div>
|
||||
<% if !channel.auto_generated %>
|
||||
<div class="pure-u-1 pure-md-1-3">
|
||||
<b><%= translate(locale, "Videos") %></b>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="pure-u-1 pure-md-1-3">
|
||||
<% if channel.auto_generated %>
|
||||
<b><%= translate(locale, "Playlists") %></b>
|
||||
<% else %>
|
||||
<a href="/channel/<%= ucid %>/playlists"><%= translate(locale, "Playlists") %></a>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="pure-u-1 pure-md-1-3">
|
||||
<% if channel.tabs.includes? "community" %>
|
||||
<a href="/channel/<%= ucid %>/community"><%= translate(locale, "Community") %></a>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= Invidious::Frontend::ChannelPage.generate_tabs_links(locale, channel, selected_tab) %>
|
||||
</div>
|
||||
<div class="pure-u-1-3"></div>
|
||||
<div class="pure-u-1-3">
|
||||
|
@ -111,7 +96,12 @@
|
|||
</div>
|
||||
|
||||
<div class="pure-g h-box">
|
||||
<div class="pure-u-1 pure-u-lg-1-5"></div>
|
||||
<div class="pure-u-1 pure-u-lg-3-5"></div>
|
||||
<div class="pure-u-1 pure-u-lg-1-5"></div>
|
||||
<div class="pure-u-1 pure-u-md-4-5"></div>
|
||||
<div class="pure-u-1 pure-u-lg-1-5" style="text-align:right">
|
||||
<% if next_continuation %>
|
||||
<a href="/channel/<%= ucid %>/<%= selected_tab %>?continuation=<%= next_continuation %><% if sort_by != "last" %>&sort_by=<%= URI.encode_www_form(sort_by) %><% end %>">
|
||||
<%= translate(locale, "Next page") %>
|
||||
</a>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -50,19 +50,8 @@
|
|||
<a href="https://redirect.invidious.io<%= env.request.resource %>"><%= translate(locale, "Switch Invidious Instance") %></a>
|
||||
<% end %>
|
||||
</div>
|
||||
<% if !channel.auto_generated %>
|
||||
<div class="pure-u-1 pure-md-1-3">
|
||||
<a href="/channel/<%= channel.ucid %>"><%= translate(locale, "Videos") %></a>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="pure-u-1 pure-md-1-3">
|
||||
<a href="/channel/<%= channel.ucid %>/playlists"><%= translate(locale, "Playlists") %></a>
|
||||
</div>
|
||||
<div class="pure-u-1 pure-md-1-3">
|
||||
<% if channel.tabs.includes? "community" %>
|
||||
<b><%= translate(locale, "Community") %></b>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= Invidious::Frontend::ChannelPage.generate_tabs_links(locale, channel, Invidious::Frontend::ChannelPage::TabsAvailable::Community) %>
|
||||
</div>
|
||||
<div class="pure-u-2-3"></div>
|
||||
</div>
|
||||
|
|
|
@ -54,19 +54,7 @@
|
|||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="pure-u-1 pure-md-1-3">
|
||||
<a href="/channel/<%= ucid %>"><%= translate(locale, "Videos") %></a>
|
||||
</div>
|
||||
<div class="pure-u-1 pure-md-1-3">
|
||||
<% if !channel.auto_generated %>
|
||||
<b><%= translate(locale, "Playlists") %></b>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="pure-u-1 pure-md-1-3">
|
||||
<% if channel.tabs.includes? "community" %>
|
||||
<a href="/channel/<%= ucid %>/community"><%= translate(locale, "Community") %></a>
|
||||
<% end %>
|
||||
</div>
|
||||
<%= Invidious::Frontend::ChannelPage.generate_tabs_links(locale, channel, Invidious::Frontend::ChannelPage::TabsAvailable::Playlists) %>
|
||||
</div>
|
||||
<div class="pure-u-1-3"></div>
|
||||
<div class="pure-u-1-3">
|
||||
|
|
Loading…
Reference in a new issue