the queue now actually works

This commit is contained in:
JISAUAY committed 2025-01-24 17:04:06 -06:00
1 parent 2d97c921af
commit c1c640f837
5 files changed
+96 -27

No files matched your search

+77 -15
View File
@@ -16,12 +16,15 @@ import SubSonic
os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide"
import pygame
from textual import on, events
from textual.app import App, ComposeResult
from textual import on, events, work
from textual.app import App, ComposeResult, RenderResult
from textual.widgets import Footer, Header, OptionList, DataTable, ProgressBar, Label
from textual.containers import Horizontal, Vertical
from textual.containers import Horizontal, Vertical, Container
from textual.screen import Screen
from textual.widgets.option_list import Option
from textual.timer import Timer
from rich_pixels import Pixels
u = 'pseudo'
p = 'telegram9dock-MICHEL'
@@ -241,7 +244,13 @@ class PlaylistSongs(Screen):
return i
class Favourites(Screen):
BINDINGS = [
('p', 'play()', 'Play Song'),
('q', 'queue()', 'Queue Song')
]
songs: list[SubSonic.Song] | None = None
selected_song_id: str | None = None
def compose(self) -> ComposeResult:
yield Header(icon="")
@@ -259,13 +268,52 @@ class Favourites(Screen):
for song in self.songs:
songTable.add_row(song.title, song.album, song.artist, song.playCount, song.duration, song.bitRate, key=song.id)
@on(DataTable.RowHighlighted)
def row_highlighted(self, event: DataTable.RowHighlighted) -> None:
self.selected_song_id = event.row_key.value
def action_play(self) -> None:
song_index = self._find_selected_song()
app.play_song(self.songs[song_index])
app.song_queue = self.songs[song_index + 1:]
def action_queue(self) -> None:
app.queue_song(self._find_selected_song())
# Returns index of selected song
def _find_selected_song(self) -> int:
for i, song in enumerate(self.songs):
if song.id == self.selected_song_id:
return i
# TODO : Maybe should just take bytes instead of saving it as a file
class CoverArtPixels(Container):
def __init__(self, cover_art_id: str):
super().__init__()
self.cover_art_id = cover_art_id
conn.getCoverArt(cover_art_id, path=f'art/{cover_art_id}.png')
def render(self) -> RenderResult:
# Make the size square
width, height = self.size
if width > height:
width = height
elif height > width:
height = width
return Pixels().from_image_path(f'art/{self.cover_art_id}.png', resize=(width, height))
class MainView(Screen):
CSS_PATH = 'main.tcss'
def compose(self) -> ComposeResult:
yield Header(icon="")
with Horizontal():
with Vertical(classes="info"):
with Vertical(classes="info", id='info'):
yield Label("Playing")
yield DataTable(id="currently_playing")
yield ProgressBar()
@@ -284,12 +332,8 @@ class MainView(Screen):
currentlyPlaying.cursor_type = "row"
currentlyPlaying.add_columns("", "")
@on(events.ScreenSuspend)
def sus(self, event: events.ScreenSuspend) -> None:
logging.debug('sus')
@on(events.ScreenResume)
def screen_resumed(self, event: events.ScreenResume) -> None:
async def screen_resumed(self, event: events.ScreenResume) -> None:
app.sub_title = "Overview"
# Update Queue Table
@@ -315,6 +359,8 @@ class MainView(Screen):
currentlyPlaying.add_row("Track Number", song.trackNumber)
currentlyPlaying.add_row("Bit Rate", song.bitRate)
await self.query_one('#info').mount(CoverArtPixels(app.currently_playing.id))
def _clear_table(self, table_id: str) -> None:
table: DataTable = self.query_one(table_id)
@@ -347,9 +393,10 @@ class TextualSubpyPlayer(App):
currently_playing: SubSonic.Song | None = None
song_queue: list[SubSonic.Song] = []
user_queue: list[SubSonic.Song] = []
isPlaying: bool = False
is_paused: bool = False
place: int = 0
check_playing_timer: Timer | None = None
def on_mount(self) -> None:
self.title = "SubPy"
@@ -359,9 +406,10 @@ class TextualSubpyPlayer(App):
# logging.debug(f'Key Pressed {event.name}')
pass
def play_song(self, song: SubSonic.Song) -> None:
@work(exclusive=True)
async def play_song(self, song: SubSonic.Song) -> None:
self.currently_playing = song
self.isPlaying = True
self.is_paused = False
logging.debug(f"Playing song {song.title} by {song.artist}.")
self.notify(f"Playing \"{song.title}\" by {song.artist}.")
@@ -372,17 +420,31 @@ class TextualSubpyPlayer(App):
pygame.mixer.music.load(audio_data)
pygame.mixer.music.play()
self.check_playing_timer = self.set_interval(1 / 5, self.check_done_playing, pause=False)
# playingLabel: Label = self.query_one(Label)
# playingLabel.
# Set callback loop for progress bar
# self.progress_timer = self.set_interval(1 / 10, self.update_progress, pause=False)
def check_done_playing(self) -> None:
if not pygame.mixer.music.get_busy() and not self.is_paused:
queue = self.user_queue
queue.extend(self.song_queue)
next_song = queue.pop(0)
self.play_song(next_song)
self.check_playing_timer.stop()
# def update_progress(self) -> None:
# self.query_one(ProgressBar).advance(1)
def queue_song(self, song: SubSonic.Song) -> None:
logging.debug(f'Queue\'d song "{song.title}" by {song.artist}.')
self.notify(f'Queue\'d song "{song.title}" by {song.artist}.')
self.user_queue.append(song)
def action_play_pause_song(self) -> None:
@@ -392,13 +454,13 @@ class TextualSubpyPlayer(App):
if not self.currently_playing:
return None
if self.isPlaying:
if not self.is_paused:
self.place = pygame.mixer.music.get_pos()
pygame.mixer.music.pause()
self.isPlaying = False
self.is_paused = True
else:
pygame.mixer.music.unpause()
self.isPlaying = True
self.is_paused = False
if __name__ == '__main__':
app = TextualSubpyPlayer()