3030from imdb import IMDb
3131from unidecode import unidecode
3232
33- from common import Manager , Provider , MOVIES_GROUP , PROVIDERS_PATH , SERIES_GROUP , TV_GROUP ,\
33+ from common import Manager , Provider , Channel , MOVIES_GROUP , PROVIDERS_PATH , SERIES_GROUP , TV_GROUP ,\
3434 async_function , idle_function
3535
3636
@@ -127,6 +127,7 @@ def __init__(self, application):
127127 self .icon_theme = Gtk .IconTheme .get_default ()
128128 self .manager = Manager (self .settings )
129129 self .providers = []
130+ self .favorite_data = []
130131 self .active_provider = None
131132 self .active_group = None
132133 self .active_serie = None
@@ -140,6 +141,8 @@ def __init__(self, application):
140141 self .mpv = None
141142 self .ia = IMDb ()
142143
144+ self .page_is_loading = False # used to ignore signals while we set widget states
145+
143146 self .video_properties = {}
144147 self .audio_properties = {}
145148
@@ -262,6 +265,7 @@ def __init__(self, application):
262265 "audio_properties_label" ,
263266 "layout_properties_box" ,
264267 "layout_properties_label" ,
268+ "favorite_button" ,
265269 ]
266270
267271 for name in widget_names :
@@ -293,6 +297,7 @@ def __init__(self, application):
293297 self .tv_button .connect ("clicked" , self .show_groups , TV_GROUP )
294298 self .movies_button .connect ("clicked" , self .show_groups , MOVIES_GROUP )
295299 self .series_button .connect ("clicked" , self .show_groups , SERIES_GROUP )
300+ self .favorites_button .connect ("clicked" , self .show_favorites )
296301 self .providers_button .connect ("clicked" , self .open_providers )
297302 self .preferences_button .connect ("clicked" , self .open_preferences )
298303 self .go_back_button .connect ("clicked" , self .on_go_back_button )
@@ -317,6 +322,8 @@ def __init__(self, application):
317322
318323 self .channels_listbox .connect ("row-activated" , self .on_channel_activated )
319324
325+ self .favorite_button .connect ("toggled" , self .on_favorite_button_toggled )
326+
320327 # Settings widgets
321328 self .bind_setting_widget ("user-agent" , self .useragent_entry )
322329 self .bind_setting_widget ("http-referer" , self .referer_entry )
@@ -329,7 +336,7 @@ def __init__(self, application):
329336 if os .path .exists (os .path .expanduser ("~/.cache/hypnotix/yt-dlp/yt-dlp" )):
330337 self .ytdlp_local_version_label .set_text (subprocess .getoutput ("~/.cache/hypnotix/yt-dlp/yt-dlp --version" ))
331338 self .ytdlp_update_button .connect ("clicked" , self .update_ytdlp )
332-
339+
333340 # Dark mode manager
334341 # keep a reference to it (otherwise it gets randomly garbage collected)
335342 self .dark_mode_manager = XApp .DarkModeManager .new (prefer_dark_mode = True )
@@ -507,6 +514,15 @@ def on_category_button_clicked(self, widget, group):
507514 else :
508515 self .show_vod (self .active_provider .series )
509516
517+ def show_favorites (self , widget ):
518+ channels = []
519+ for line in self .favorite_data :
520+ info , url = line .split (":::" )
521+ channel = Channel (None , info )
522+ channel .url = url
523+ channels .append (channel )
524+ self .show_channels (channels )
525+
510526 def show_channels (self , channels ):
511527 self .navigate_to ("channels_page" )
512528 if self .content_type == TV_GROUP :
@@ -835,6 +851,19 @@ def open_keyboard_shortcuts(self, widget):
835851 window .set_title (_ ("Hypnotix" ))
836852 window .show ()
837853
854+ def on_favorite_button_toggled (self , widget ):
855+ if self .page_is_loading :
856+ return
857+ name = self .active_channel .name
858+ data = f"{ self .active_channel .info } :::{ self .active_channel .url } "
859+ if widget .get_active () and data not in self .favorite_data :
860+ print (f"Adding { name } to favorites" )
861+ self .favorite_data .append (data )
862+ elif widget .get_active () == False and data in self .favorite_data :
863+ print (f"Removing { name } from favorites" )
864+ self .favorite_data .remove (data )
865+ self .manager .save_favorites (self .favorite_data )
866+
838867 def on_channel_activated (self , box , widget ):
839868 self .active_channel = widget .channel
840869 self .play_async (self .active_channel )
@@ -881,6 +910,16 @@ def before_play(self, channel):
881910 self .label_channel_name .set_text (channel .name )
882911 self .label_channel_url .set_text (channel .url )
883912
913+ self .page_is_loading = True
914+ data = f"{ channel .info } :::{ channel .url } "
915+ if data in self .favorite_data :
916+ self .favorite_button .set_active (True )
917+ self .favorite_button .set_tooltip_text (_ ("Remove from favorites" ))
918+ else :
919+ self .favorite_button .set_active (False )
920+ self .favorite_button .set_tooltip_text (_ ("Add to favorites" ))
921+ self .page_is_loading = False
922+
884923 @idle_function
885924 def after_play (self , channel ):
886925 self .mpv_stack .set_visible_child_name ("player_page" )
@@ -1456,6 +1495,7 @@ def on_key_press_event(self, widget, event):
14561495
14571496 @async_function
14581497 def reload (self , page = None , refresh = False ):
1498+ self .favorite_data = self .manager .load_favorites ()
14591499 self .status (_ ("Loading providers..." ))
14601500 self .providers = []
14611501 for provider_info in self .settings .get_strv ("providers" ):
0 commit comments