diff --git a/modules/dock/components/metrics.py b/modules/dock/components/metrics.py index fa62818..18ecb30 100644 --- a/modules/dock/components/metrics.py +++ b/modules/dock/components/metrics.py @@ -10,6 +10,7 @@ from fabric.widgets.revealer import Revealer from gi.repository import GLib import config.data as data +from utils.animatedcircularprogressbar import AnimatedCircularProgressBar import utils.icons as icons @@ -155,7 +156,7 @@ class SingularMetric: self.icon_markup = icon self.icon = Label(name="metrics-icon", markup=icon) - self.circle = CircularProgressBar( + self.circle = AnimatedCircularProgressBar( name="metrics-circle", value=0, size=28, diff --git a/modules/dock/components/music_player.py b/modules/dock/components/music_player.py index f981613..e889007 100644 --- a/modules/dock/components/music_player.py +++ b/modules/dock/components/music_player.py @@ -292,6 +292,7 @@ class MusicPlayer(Box): continue except Exception as e: + print(f"[DEBUG] Error in get_playing_player: {e}") return None def check_active_player(self): @@ -326,6 +327,7 @@ class MusicPlayer(Box): # If we can't safely compare, assume we should switch should_switch = True except Exception as e: + print(f"[DEBUG] Error comparing players: {e}") should_switch = True if should_switch: @@ -354,6 +356,7 @@ class MusicPlayer(Box): self.update_visibility() except Exception as e: + print(f"[DEBUG] Error in check_active_player: {e}") # Return True to continue the timeout return True @@ -364,6 +367,7 @@ class MusicPlayer(Box): self.manager.init_all_players() self.update_visibility() except Exception as e: + print(f"[DEBUG] Error in delayed music player init: {e}") return False # Don't repeat this timeout def _try_switch_to_alternative_player(self, current_time): @@ -404,6 +408,7 @@ class MusicPlayer(Box): continue except Exception as e: + pass def set_current_player(self, player): """Set the current active player""" @@ -709,6 +714,7 @@ class MusicPlayer(Box): ): return True except Exception as e: + pass # Also check if player is currently playing (even without full metadata) if hasattr(player.props, "playback_status"): @@ -718,11 +724,13 @@ class MusicPlayer(Box): status.value_name == "PLAYERCTL_PLAYBACK_STATUS_PLAYING"): return True except Exception as e: + pass except Exception as e: - continue + pass except Exception as e: + pass return False diff --git a/modules/dock/components/player.py b/modules/dock/components/player.py index 843f3c3..9e4b55f 100644 --- a/modules/dock/components/player.py +++ b/modules/dock/components/player.py @@ -186,7 +186,6 @@ class Player(Box): def on_seek(self, sender, ratio): pos = ratio * self.duration # duration in seconds - print(f"Seeking to {pos:.2f}s") self._player.set_position(int(pos)) def on_metadata(self, sender, metadata, player): @@ -223,7 +222,7 @@ class Player(Box): f"https://img.youtube.com/vi/{video_id}/hqdefault.jpg" ) self.set_style(f"background-image:url('{thumbnail_url}')") - print(f"Using YouTube thumbnail: {thumbnail_url}") + else: # Fallback to default wallpaper self.set_style( @@ -265,7 +264,6 @@ class Player(Box): self.play_pause_button.remove_style_class("pause-track") def on_shuffle(self, sender, player, status): - print("callback status", status) if status == False: self.shuffle_button.get_child().set_markup(icons.shuffle) self.shuffle_button.get_child().set_name("shuffle") @@ -278,10 +276,18 @@ class Player(Box): self.shuffle_button.get_child().set_style("color: white") def handle_next(self, player): - player.next() + try: + player.next() + except Exception: + # Next is not available for this player (common with browsers) + pass def handle_prev(self, player): - player.previous() + try: + player.previous() + except Exception: + # Previous is not available for this player (common with browsers) + pass def handle_play_pause(self, player): is_playing = self.play_pause_button.get_child().get_name() == "play-label" @@ -312,13 +318,15 @@ class Player(Box): logger.warning("Failed to toggle playback:", e) def handle_shuffle(self, shuffle_button, player): - print("shuffle", player.props.shuffle) - if player.props.shuffle == False: - player.set_shuffle(True) - print("setting to true", player.props.player_name) - else: - player.set_shuffle(False) - shuffle_button.get_child().set_style("color: var(--outline)") + try: + if player.props.shuffle == False: + player.set_shuffle(True) + else: + player.set_shuffle(False) + shuffle_button.get_child().set_style("color: var(--outline)") + except Exception: + # Shuffle is not available for this player (common with browsers) + pass class PlayerContainer(Box): @@ -367,15 +375,12 @@ class PlayerContainer(Box): self.manager.init_all_players() def new_player(self, manager, player): - print(player.props.player_name, "new player") - print(player) new_player = Player(player=player) new_player.gtk_wrapper.queue_draw() new_player.set_name(player.props.player_name) self.player.append(new_player) # Store the player object self.player_objects[player.props.player_name] = player - print("stacking player") self.stack.add_named(new_player, player.props.player_name) self.player_switch_container.add_center( @@ -436,7 +441,6 @@ class PlayerContainer(Box): curr = self.stack.get_visible_child() if curr: for btn in self.player_switch_container.center_children: - print(btn.get_name()) if btn.get_name() == curr.get_name(): btn.add_style_class("active") else: diff --git a/services/mpris.py b/services/mpris.py index e79f0bd..e584437 100644 --- a/services/mpris.py +++ b/services/mpris.py @@ -35,7 +35,6 @@ class PlayerService(Service): self._player.connect("shuffle", self.on_shuffle) self._player.connect("metadata", self.on_metadata) self._player.connect("seeked", self.on_seeked) - print(type(player)) self.status = self._player.props.playback_status self.pos_fabricator = Fabricator( @@ -58,12 +57,10 @@ class PlayerService(Service): self.pos_fabricator.start() def set_position(self, pos: float): - print("seeking in the service") self.pos_fabricator.stop() micro_pos = int(pos * 1_000_000) try: self._player.set_position(micro_pos) - print(f"Set position to {micro_pos}") except GLib.Error as e: print(f"Failed to seek: {e}") @@ -132,28 +129,19 @@ class PlayerService(Service): pass def on_play(self, player, status): - print("player is playing: {}".format(player.props.player_name)) self.status = player.props.playback_status self.poll_progress() self.play() def on_pause(self, player, status): - print("player is paused: {}".format(player.props.player_name)) - self.status = player.props.playback_status self.poll_progress() self.pause() def on_shuffle(self, player, status): - print("suffle status changed for: {}".format(player.props.player_name)) - print(type(status), "here is the status type") self.shuffle_toggle(player, status) def on_metadata(self, player, metadata): keys = metadata.keys() - if "xesam:artist" in keys and "xesam:title" in keys: - print( - "{} - {}".format(metadata["xesam:artist"][0], metadata["xesam:title"]) - ) self.meta_change(metadata, player) @@ -171,7 +159,6 @@ class PlayerManager(Service): self._manager.connect( "player-vanished", self._on_player_vanished, self._manager ) - print("playerctl init done") self._players = {} @@ -179,7 +166,6 @@ class PlayerManager(Service): # invoked in the UI for player_obj in self._manager.props.player_names: name_str = player_obj.name - print(f"{name_str} appeared") if name_str in ALLOWED_PLAYERS: player = Playerctl.Player.new_from_name(player_obj) self._manager.manage_player(player) @@ -187,13 +173,10 @@ class PlayerManager(Service): def _on_name_appeared(self, sender, name, manager): name_str = name.name - print(f"{name_str} appeared") if name_str in ALLOWED_PLAYERS: player = Playerctl.Player.new_from_name(name) self._manager.manage_player(player) self.new_player(player) def _on_player_vanished(self, sender, player, manager): - print("player has exited: {}".format(player.props.player_name)) - print(type(player)) self.player_vanish(player) \ No newline at end of file diff --git a/utils/animatedcircularprogressbar.py b/utils/animatedcircularprogressbar.py new file mode 100644 index 0000000..05f3f5a --- /dev/null +++ b/utils/animatedcircularprogressbar.py @@ -0,0 +1,26 @@ +from fabric.widgets.circularprogressbar import CircularProgressBar +from utils.animator import Animator + +class AnimatedCircularProgressBar(CircularProgressBar): + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.animator = ( + Animator( + bezier_curve=(0.15, 0.88, 0.68, 0.95), + duration=0.8, + min_value=self.min_value, + max_value=self.value, + tick_widget=self, + notify_value=lambda p, *_: self.set_value(p.value), + ) + .build() + .play() + .unwrap() + ) + + def animate_value(self, value: float): + self.animator.pause() + self.animator.min_value = self.value + self.animator.max_value = value + self.animator.play() + return \ No newline at end of file diff --git a/utils/animatedscale.py b/utils/animatedscale.py new file mode 100644 index 0000000..db5d411 --- /dev/null +++ b/utils/animatedscale.py @@ -0,0 +1,26 @@ +from fabric.widgets.scale import Scale +from utils.animator import Animator + +class AnimatedScale(Scale): + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.animator = ( + Animator( + bezier_curve=(0.15, 0.88, 0.68, 0.95), + duration=0.3, + min_value=self.min_value, + max_value=self.value, + tick_widget=self, + notify_value=lambda p, *_: self.set_value(p.value), + ) + .build() + .play() + .unwrap() + ) + + def animate_value(self, value: float): + self.animator.pause() + self.animator.min_value = self.value + self.animator.max_value = value + self.animator.play() + return \ No newline at end of file