Files
sublime-music/sublime/ui/state.py
2020-05-13 21:55:41 -06:00

94 lines
2.7 KiB
Python

from dataclasses import dataclass, field
from datetime import timedelta
from enum import Enum
from typing import Dict, Optional, Tuple
from sublime.adapters import AlbumSearchQuery
from sublime.adapters.api_objects import Genre, Song
class RepeatType(Enum):
NO_REPEAT = 0
REPEAT_QUEUE = 1
REPEAT_SONG = 2
@property
def icon(self) -> str:
icon_name = ["repeat-symbolic", "repeat-symbolic", "repeat-song-symbolic"][
self.value
]
return f"media-playlist-{icon_name}"
def as_mpris_loop_status(self) -> str:
return ["None", "Playlist", "Track"][self.value]
@staticmethod
def from_mpris_loop_status(loop_status: str) -> "RepeatType":
return {
"None": RepeatType.NO_REPEAT,
"Track": RepeatType.REPEAT_SONG,
"Playlist": RepeatType.REPEAT_QUEUE,
}[loop_status]
@dataclass
class UIState:
"""Represents the UI state of the application."""
version: int = 1
playing: bool = False
current_song_index: int = -1
play_queue: Tuple[str, ...] = field(default_factory=tuple)
old_play_queue: Tuple[str, ...] = field(default_factory=tuple)
_volume: Dict[str, float] = field(default_factory=lambda: {"this device": 100.0})
is_muted: bool = False
repeat_type: RepeatType = RepeatType.NO_REPEAT
shuffle_on: bool = False
song_progress: timedelta = timedelta()
current_device: str = "this device"
current_tab: str = "albums"
selected_album_id: Optional[str] = None
selected_artist_id: Optional[str] = None
selected_browse_element_id: Optional[str] = None
selected_playlist_id: Optional[str] = None
class _DefaultGenre(Genre):
def __init__(self):
self.name = "Rock"
# State for Album sort.
current_album_search_query: AlbumSearchQuery = AlbumSearchQuery(
AlbumSearchQuery.Type.RANDOM, genre=_DefaultGenre(), year_range=(2010, 2020),
)
active_playlist_id: Optional[str] = None
def migrate(self):
pass
_current_song: Optional[Song] = None
@property
def current_song(self) -> Optional[Song]:
from sublime.adapters import AdapterManager
if not self.play_queue or self.current_song_index < 0:
return None
current_song_id = self.play_queue[self.current_song_index]
if not self._current_song or self._current_song.id != current_song_id:
self._current_song = AdapterManager.get_song_details(
current_song_id
).result()
return self._current_song
@property
def volume(self) -> float:
return self._volume.get(self.current_device, 100.0)
@volume.setter
def volume(self, value: float):
self._volume[self.current_device] = value