feat: add experimental support to hide channels from the popular page

This commit is contained in:
Fijxu
2025-09-06 22:00:43 -04:00
parent acedcb7303
commit acba0c9091
9 changed files with 50 additions and 0 deletions

View File

@@ -1069,3 +1069,8 @@ h1, h2, h3, h4, h5, p,
.video-transcript > footer select { .video-transcript > footer select {
width: 75%; width: 75%;
} }
.hidden-channels {
width: 300px;
height: 200px;
}

View File

@@ -122,6 +122,8 @@
"Redirect homepage to feed: ": "Redirect homepage to feed: ", "Redirect homepage to feed: ": "Redirect homepage to feed: ",
"preferences_max_results_label": "Number of videos shown in feed: ", "preferences_max_results_label": "Number of videos shown in feed: ",
"preferences_sort_label": "Sort videos by: ", "preferences_sort_label": "Sort videos by: ",
"preferences_hidden_channels": "Hidden channels",
"preferences_hidden_channels_label": "(Experimental) Channel ID list separated by ENTER key. This only hides channels from the popular page for now. You can get the ID of the channel clicking on the channel and copying the part that starts with 'UC' in the channel link. Example: /channel/<b>UCw-aR42z5gUcarpPGN5OKfA</b>",
"published": "published", "published": "published",
"published - reverse": "published - reverse", "published - reverse": "published - reverse",
"alphabetically": "alphabetically", "alphabetically": "alphabetically",

View File

@@ -78,6 +78,8 @@
"Redirect homepage to feed: ": "Redirigir la página de inicio a la fuente: ", "Redirect homepage to feed: ": "Redirigir la página de inicio a la fuente: ",
"preferences_max_results_label": "Número de videos mostrados en la fuente: ", "preferences_max_results_label": "Número de videos mostrados en la fuente: ",
"preferences_sort_label": "Ordenar los videos por: ", "preferences_sort_label": "Ordenar los videos por: ",
"preferences_hidden_channels": "Canales ocultos",
"preferences_hidden_channels_label": "(Experimental) Lista de IDs de canales separados por la tecla ENTER. Por ahora, esto solo oculta canales de la pagina popular. Puedes conseguir la ID del canal entrando al canal y copiando la parte que empieza por 'UC' en el enlace. Ejemplo: /channel/<b>UCw-aR42z5gUcarpPGN5OKfA</b>",
"published": "fecha de publicación", "published": "fecha de publicación",
"published - reverse": "fecha de publicación: orden inverso", "published - reverse": "fecha de publicación: orden inverso",
"alphabetically": "alfabéticamente", "alphabetically": "alfabéticamente",

View File

@@ -53,6 +53,8 @@ struct ConfigPreferences
property show_nick : Bool = true property show_nick : Bool = true
property save_player_pos : Bool = false property save_player_pos : Bool = false
property enable_dearrow : Bool = false property enable_dearrow : Bool = false
@[YAML::Field(ignore: true)]
property hidden_channels : Array(String)? = nil
def to_tuple def to_tuple
{% begin %} {% begin %}

View File

@@ -35,6 +35,7 @@ module Invidious::Routes::Feeds
locale = env.get("preferences").as(Preferences).locale locale = env.get("preferences").as(Preferences).locale
if CONFIG.popular_enabled if CONFIG.popular_enabled
preferences = env.get("preferences").as(Preferences)
templated "feeds/popular" templated "feeds/popular"
else else
message = translate(locale, "The Popular feed has been disabled by the administrator.") message = translate(locale, "The Popular feed has been disabled by the administrator.")

View File

@@ -144,6 +144,30 @@ module Invidious::Routes::PreferencesRoute
notifications_only ||= "off" notifications_only ||= "off"
notifications_only = notifications_only == "on" notifications_only = notifications_only == "on"
hidden_channels = env.params.body["hidden_channels"]?.try &.as(String)
if hidden_channels
hidden_channels = hidden_channels.split("\n")
delete = [] of Int32
hidden_channels.each_with_index do |ucid, idx|
u = ucid.rstrip("\r")
if (u == "") || (u == "\r")
delete << idx
next
end
# 24 is the length of channel UCIDs
if u.size != 24
raise InfoException.new("Channel ID has to be 25 characters long!")
else
hidden_channels[idx] = u
end
end
delete.reverse_each { |i| hidden_channels.delete_at(i) }
end
# Convert to JSON and back again to take advantage of converters used for compatibility # Convert to JSON and back again to take advantage of converters used for compatibility
preferences = Preferences.from_json({ preferences = Preferences.from_json({
annotations: annotations, annotations: annotations,
@@ -180,6 +204,7 @@ module Invidious::Routes::PreferencesRoute
vr_mode: vr_mode, vr_mode: vr_mode,
show_nick: show_nick, show_nick: show_nick,
save_player_pos: save_player_pos, save_player_pos: save_player_pos,
hidden_channels: hidden_channels,
}.to_json) }.to_json)
if user = env.get? "user" if user = env.get? "user"

View File

@@ -56,6 +56,7 @@ struct Preferences
property extend_desc : Bool = CONFIG.default_user_preferences.extend_desc property extend_desc : Bool = CONFIG.default_user_preferences.extend_desc
property volume : Int32 = CONFIG.default_user_preferences.volume property volume : Int32 = CONFIG.default_user_preferences.volume
property save_player_pos : Bool = CONFIG.default_user_preferences.save_player_pos property save_player_pos : Bool = CONFIG.default_user_preferences.save_player_pos
property hidden_channels : Array(String)? = nil
module BoolToString module BoolToString
def self.to_json(value : String, json : JSON::Builder) def self.to_json(value : String, json : JSON::Builder)

View File

@@ -13,6 +13,11 @@
<div class="pure-g"> <div class="pure-g">
<% popular_videos.each do |item| %> <% popular_videos.each do |item| %>
<%
if hidden_channels = preferences.hidden_channels
next if hidden_channels.any? { |ucid| ucid == item.ucid }
end
%>
<%= rendered "components/item" %> <%= rendered "components/item" %>
<% end %> <% end %>
</div> </div>

View File

@@ -211,6 +211,13 @@
<input name="automatic_instance_redirect" id="automatic_instance_redirect" type="checkbox" <% if preferences.automatic_instance_redirect %>checked<% end %>> <input name="automatic_instance_redirect" id="automatic_instance_redirect" type="checkbox" <% if preferences.automatic_instance_redirect %>checked<% end %>>
</div> </div>
<div class="pure-control-group">
<label for="hidden_channels"><%= translate(locale, "preferences_hidden_channels") %></label>
<% hidden_channels = preferences.hidden_channels %>
<textarea name="hidden_channels" id="hidden_channels" class="hidden-channels"><%= hidden_channels[0...].join("\n") if hidden_channels %></textarea>
<label for="hidden_channels"><%= translate(locale, "preferences_hidden_channels_label") %></label>
</div>
<% if env.get? "user" %> <% if env.get? "user" %>
<legend><%= translate(locale, "preferences_category_subscription") %></legend> <legend><%= translate(locale, "preferences_category_subscription") %></legend>