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 {
width: 75%;
}
.hidden-channels {
width: 300px;
height: 200px;
}

View File

@@ -122,6 +122,8 @@
"Redirect homepage to feed: ": "Redirect homepage to feed: ",
"preferences_max_results_label": "Number of videos shown in feed: ",
"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 - reverse": "published - reverse",
"alphabetically": "alphabetically",

View File

@@ -78,6 +78,8 @@
"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_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 - reverse": "fecha de publicación: orden inverso",
"alphabetically": "alfabéticamente",

View File

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

View File

@@ -35,6 +35,7 @@ module Invidious::Routes::Feeds
locale = env.get("preferences").as(Preferences).locale
if CONFIG.popular_enabled
preferences = env.get("preferences").as(Preferences)
templated "feeds/popular"
else
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 = 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
preferences = Preferences.from_json({
annotations: annotations,
@@ -180,6 +204,7 @@ module Invidious::Routes::PreferencesRoute
vr_mode: vr_mode,
show_nick: show_nick,
save_player_pos: save_player_pos,
hidden_channels: hidden_channels,
}.to_json)
if user = env.get? "user"

View File

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

View File

@@ -13,6 +13,11 @@
<div class="pure-g">
<% popular_videos.each do |item| %>
<%
if hidden_channels = preferences.hidden_channels
next if hidden_channels.any? { |ucid| ucid == item.ucid }
end
%>
<%= rendered "components/item" %>
<% end %>
</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 %>>
</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" %>
<legend><%= translate(locale, "preferences_category_subscription") %></legend>