[SCRIPT] Updated
This commit is contained in:
@@ -0,0 +1,202 @@
|
||||
import os
|
||||
import ignis
|
||||
from ignis.widgets import Widget
|
||||
from ignis.services.mpris import MprisService, MprisPlayer
|
||||
from ignis.utils import Utils
|
||||
from services.material import MaterialService
|
||||
from ignis.app import IgnisApp
|
||||
from ignis.exceptions import StylePathNotFoundError
|
||||
|
||||
|
||||
mpris = MprisService.get_default()
|
||||
app = IgnisApp.get_default()
|
||||
material = MaterialService.get_default()
|
||||
|
||||
MEDIA_TEMPLATE = Utils.get_current_dir() + "/../../scss/media.scss"
|
||||
MEDIA_SCSS_CACHE_DIR = ignis.CACHE_DIR + "/media" # type: ignore
|
||||
MEDIA_ART_FALLBACK = Utils.get_current_dir() + "/../../misc/media-art-fallback.png"
|
||||
os.makedirs(MEDIA_SCSS_CACHE_DIR, exist_ok=True)
|
||||
|
||||
|
||||
PLAYER_ICONS = {"spotify": "", "firefox": "", "chrome": "", None: ""}
|
||||
|
||||
|
||||
class Player(Widget.Revealer):
|
||||
def __init__(self, player: MprisPlayer) -> None:
|
||||
self._player = player
|
||||
self._colors_path = f"{MEDIA_SCSS_CACHE_DIR}/{self._player.desktop_entry}.scss"
|
||||
player.connect("closed", lambda x: self.destroy())
|
||||
player.connect("notify::art-url", lambda x, y: self.load_colors())
|
||||
self.load_colors()
|
||||
|
||||
super().__init__(
|
||||
transition_type="slide_down",
|
||||
reveal_child=False,
|
||||
css_classes=[self.get_css("media")],
|
||||
child=Widget.Overlay(
|
||||
child=Widget.Box(css_classes=[self.get_css("media-image")]),
|
||||
overlays=[
|
||||
Widget.Box(
|
||||
hexpand=True,
|
||||
vexpand=True,
|
||||
css_classes=[self.get_css("media-image-gradient")],
|
||||
),
|
||||
Widget.Label(
|
||||
label=self.get_player_icon(),
|
||||
halign="start",
|
||||
valign="start",
|
||||
css_classes=[self.get_css("media-player-icon")],
|
||||
),
|
||||
Widget.Box(
|
||||
vertical=True,
|
||||
hexpand=True,
|
||||
css_classes=[self.get_css("media-content")],
|
||||
child=[
|
||||
Widget.Box(
|
||||
vexpand=True,
|
||||
valign="center",
|
||||
child=[
|
||||
Widget.Box(
|
||||
hexpand=True,
|
||||
vertical=True,
|
||||
child=[
|
||||
Widget.Label(
|
||||
ellipsize="end",
|
||||
label=player.bind("title"),
|
||||
max_width_chars=30,
|
||||
halign="start",
|
||||
css_classes=[
|
||||
self.get_css("media-title")
|
||||
],
|
||||
),
|
||||
Widget.Label(
|
||||
label=player.bind("artist"),
|
||||
max_width_chars=30,
|
||||
ellipsize="end",
|
||||
halign="start",
|
||||
css_classes=[
|
||||
self.get_css("media-artist")
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
Widget.Button(
|
||||
child=Widget.Icon(
|
||||
image=player.bind(
|
||||
"playback_status",
|
||||
lambda value: "media-playback-pause-symbolic"
|
||||
if value == "Playing"
|
||||
else "media-playback-start-symbolic",
|
||||
),
|
||||
pixel_size=18,
|
||||
),
|
||||
on_click=lambda x: player.play_pause(),
|
||||
visible=player.bind("can_play"),
|
||||
css_classes=player.bind(
|
||||
"playback_status",
|
||||
lambda value: [
|
||||
self.get_css("media-playback-button"),
|
||||
"playing",
|
||||
]
|
||||
if value == "Playing"
|
||||
else [
|
||||
self.get_css("media-playback-button"),
|
||||
"paused",
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
Widget.Box(
|
||||
vexpand=True,
|
||||
valign="end",
|
||||
style="padding: 1rem;",
|
||||
child=[
|
||||
Widget.Scale(
|
||||
value=player.bind("position"),
|
||||
max=player.bind("length"),
|
||||
hexpand=True,
|
||||
css_classes=[self.get_css("media-scale")],
|
||||
on_change=lambda x: player.set_position(x.value),
|
||||
visible=player.bind(
|
||||
"position", lambda value: value != -1
|
||||
),
|
||||
),
|
||||
Widget.Button(
|
||||
child=Widget.Icon(
|
||||
image="media-skip-backward-symbolic",
|
||||
pixel_size=20,
|
||||
),
|
||||
css_classes=[self.get_css("media-skip-button")],
|
||||
on_click=lambda x: player.previous(),
|
||||
visible=player.bind("can_go_previous"),
|
||||
style="margin-left: 1rem;",
|
||||
),
|
||||
Widget.Button(
|
||||
child=Widget.Icon(
|
||||
image="media-skip-forward-symbolic",
|
||||
pixel_size=20,
|
||||
),
|
||||
css_classes=[self.get_css("media-skip-button")],
|
||||
on_click=lambda x: player.next(),
|
||||
visible=player.bind("can_go_next"),
|
||||
style="margin-left: 1rem;",
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
||||
def get_player_icon(self) -> str:
|
||||
if self._player.desktop_entry == "firefox":
|
||||
return PLAYER_ICONS["firefox"]
|
||||
elif self._player.desktop_entry == "spotify":
|
||||
return PLAYER_ICONS["spotify"]
|
||||
elif "chromium" in self._player.track_id or "chrome" in self._player.track_id:
|
||||
return PLAYER_ICONS["chrome"]
|
||||
else:
|
||||
return PLAYER_ICONS[None]
|
||||
|
||||
def destroy(self) -> None:
|
||||
self.set_reveal_child(False)
|
||||
Utils.Timeout(self.transition_duration, super().unparent)
|
||||
|
||||
def get_css(self, class_name: str) -> str:
|
||||
return f"{class_name}-{self._player.desktop_entry}"
|
||||
|
||||
def load_colors(self) -> None:
|
||||
if not self._player.art_url:
|
||||
art_url = MEDIA_ART_FALLBACK
|
||||
else:
|
||||
art_url = self._player.art_url
|
||||
|
||||
try:
|
||||
app.remove_css(self._colors_path)
|
||||
except StylePathNotFoundError:
|
||||
pass
|
||||
|
||||
colors = material.get_colors_from_img(art_url, True)
|
||||
colors["art_url"] = art_url
|
||||
colors["desktop_entry"] = self._player.desktop_entry
|
||||
material.render_template(
|
||||
colors, input_file=MEDIA_TEMPLATE, output_file=self._colors_path
|
||||
)
|
||||
app.apply_css(self._colors_path)
|
||||
|
||||
|
||||
def media() -> Widget.Box:
|
||||
def add_player(box: Widget.Box, obj: MprisPlayer) -> None:
|
||||
player = Player(obj)
|
||||
box.append(player)
|
||||
player.set_reveal_child(True)
|
||||
|
||||
return Widget.Box(
|
||||
vertical=True,
|
||||
setup=lambda self: mpris.connect(
|
||||
"player_added", lambda x, player: add_player(self, player)
|
||||
),
|
||||
css_classes=["rec-unset"],
|
||||
)
|
||||
Reference in New Issue
Block a user