added search bar to albums and artists

This commit is contained in:
JISAUAY committed 2025-09-10 13:44:23 -05:00
1 parent 200ef9b1e7
commit da82bfa3b9
3 files changed
+54 -11

No files matched your search

+2
View File
@@ -31,6 +31,7 @@ class Album:
title: str title: str
name: str name: str
album: str album: str
artist: str
coverArtId: str coverArtId: str
duration: int duration: int
artistId: str artistId: str
@@ -44,6 +45,7 @@ class Album:
self.title = album_info['title'] self.title = album_info['title']
self.name = album_info['name'] self.name = album_info['name']
self.album = album_info['album'] self.album = album_info['album']
self.artist = album_info['artist']
self.coverArtId = album_info['coverArt'] self.coverArtId = album_info['coverArt']
self.duration = int(album_info['duration']) self.duration = int(album_info['duration'])
self.artistId = album_info['artistId'] self.artistId = album_info['artistId']
+44 -11
View File
@@ -29,9 +29,9 @@ from rich.table import Table, Column
from textual import on, events, work from textual import on, events, work
from textual.reactive import reactive from textual.reactive import reactive
from textual.app import App, ComposeResult, RenderResult from textual.app import App, ComposeResult, RenderResult
from textual.widgets import Footer, Header, OptionList, DataTable, ProgressBar, Label from textual.widgets import Footer, Header, OptionList, DataTable, ProgressBar, Label, Input
from textual.widget import Widget from textual.widget import Widget
from textual.containers import Horizontal, Vertical, Container, VerticalScroll from textual.containers import Horizontal, Vertical, Container
from textual.screen import Screen from textual.screen import Screen
from textual.widgets.option_list import Option from textual.widgets.option_list import Option
from textual.timer import Timer from textual.timer import Timer
@@ -141,15 +141,21 @@ class ArtistAlbums(Screen):
class Artists(Screen): class Artists(Screen):
artists: list[SubSonic.Artist]
def compose(self) -> ComposeResult: def compose(self) -> ComposeResult:
yield Header(icon='')
with Vertical(id="artistContainer"):
yield Input(placeholder="Search")
yield OptionList(id="Artists") yield OptionList(id="Artists")
yield Footer() yield Footer()
def on_mount(self) -> None: def on_mount(self) -> None:
artists = conn.getArtists() app.sub_title = 'Artists'
self.artists = conn.getArtists()
artistList = self.query_one(OptionList) artistList = self.query_one(OptionList)
for artist in artists: for artist in self.artists:
artistList.add_option(Option(artist.name, artist.id)) artistList.add_option(Option(artist.name, artist.id))
@on(OptionList.OptionSelected) @on(OptionList.OptionSelected)
@@ -157,28 +163,57 @@ class Artists(Screen):
app.install_screen(ArtistAlbums(event.option_id), 'artistAlbums') app.install_screen(ArtistAlbums(event.option_id), 'artistAlbums')
app.push_screen('artistAlbums') app.push_screen('artistAlbums')
@on(Input.Submitted)
def search_submit(self, event: Input.Submitted) -> None:
search_value = event.value.lower()
artist_list = self.query_one(OptionList)
artist_list.clear_options()
for artist in self.artists:
if search_value in artist.name.lower():
artist_list.add_option(Option(artist.name, artist.id))
class Albums(Screen): class Albums(Screen):
albums: list[SubSonic.Album]
def compose(self) -> ComposeResult: def compose(self) -> ComposeResult:
yield DataTable() yield Header(icon='')
with Vertical(id="albumContainer"):
yield Input(placeholder="Search", id="albumSearchBar")
yield DataTable(id="albumList")
yield Footer() yield Footer()
def on_mount(self) -> None: def on_mount(self) -> None:
albums = conn.getAllAlbums() app.sub_title = "Albums"
self.albums = conn.getAllAlbums()
albumTable = self.query_one(DataTable) albumTable = self.query_one(DataTable)
albumTable.cursor_type = 'row' albumTable.cursor_type = 'row'
albumTable.add_columns("Title", "Songs", "Plays", "Year", "Time") albumTable.add_columns("Title", "Artist", "Songs", "Plays", "Year", "Time")
for album in albums: for album in self.albums:
albumTable.add_row(album.title, album.songCount, album.playCount, album.year, album.duration, key=album.id) albumTable.add_row(album.title, album.artist, album.songCount, album.playCount, album.year, album.duration, key=album.id)
@on(DataTable.RowSelected) @on(DataTable.RowSelected)
def album_selected(self, event: DataTable.RowSelected) -> None: def album_selected(self, event: DataTable.RowSelected) -> None:
app.install_screen(AlbumSongs(event.row_key.value), 'albumSongs') app.install_screen(AlbumSongs(event.row_key.value), 'albumSongs')
app.push_screen('albumSongs') app.push_screen('albumSongs')
@on(Input.Submitted)
def search_submit(self, event: Input.Submitted) -> None:
search_value = event.value.lower()
album_table = self.query_one(DataTable)
album_table.clear()
for album in self.albums:
if search_value in album.title.lower() or search_value in album.artist.lower():
album_table.add_row(album.title, album.artist, album.songCount, album.playCount, album.year, album.duration, key=album.id)
class Playlists(Screen): class Playlists(Screen):
playlists: list[SubSonic.Playlist] | None = None playlists: list[SubSonic.Playlist] | None = None
selected_playlist_id: str = None selected_playlist_id: str = None
@@ -438,8 +473,6 @@ class QueueTable(Widget):
# Update the visual queue table # Update the visual queue table
self.update_queue() self.update_queue()
# Fine to be a static renderable because it's not big enough to need a scroll # Fine to be a static renderable because it's not big enough to need a scroll
class NowPlayingInfo(Container): class NowPlayingInfo(Container):
song = reactive[SubSonic.Song | None](None, layout=True) song = reactive[SubSonic.Song | None](None, layout=True)
+8
View File
@@ -11,3 +11,11 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
#albumContainer {
height: 100%;
}
#artistContainer {
height: 100%;
}