2121from textual import events , on , work
2222from textual .app import App , ComposeResult
2323from textual .binding import Binding , BindingType
24- from textual .containers import Center , Container , Horizontal , ScrollableContainer , Vertical
24+ from textual .containers import Center , Container , Horizontal , ScrollableContainer , Vertical , Grid
2525from textual .reactive import reactive
2626from textual .screen import ModalScreen
2727from textual .widgets import (
@@ -310,15 +310,21 @@ def compose(self) -> ComposeResult:
310310 )
311311 yield Input (id = "input" , placeholder = "Search for a Anime" )
312312 yield ListView (id = "results" )
313+
313314 with TabPane ("Info" , id = "info" , disabled = True ): # Info "ℹ"
314315 with ScrollableContainer (id = "res_con" ):
315316 yield Horizontal (
316317 Image (id = "image" ),
317318 Markdown (id = "markdown" ),
318319 id = "res_con_2"
319320 )
320-
321+ yield Select .from_values (
322+ [], # Leere Liste zu Beginn
323+ id = "season_filter" ,
324+ prompt = "Alle Staffeln"
325+ )
321326 yield ClickableDataTable (id = "season_list" )
327+
322328 with TabPane ("Settings" , id = "setting" ): # Settings "⚙"
323329 # TODO: dont show unneeded on android
324330 with ScrollableContainer (id = "settings_container" ):
@@ -389,6 +395,56 @@ async def input_changed(self, event: Input.Changed):
389395 if event .control .id == "input" :
390396 self .lookup_anime (event .value )
391397
398+ @on (Select .Changed )
399+ def on_season_filter_changed (self , event : Select .Changed ) -> None :
400+ if event .control .id == "season_filter" :
401+ table = self .query_one ("#season_list" , DataTable )
402+ if not self .current_info :
403+ return
404+
405+ table .clear (columns = True )
406+ table .add_columns ("FT" , "S" , "F" , "Title" , "Hoster" , "Sprache" )
407+
408+ # Liste der gefilterten Episoden speichern
409+ self .filtered_episodes = []
410+
411+ # Temporäre Listen für die Sortierung
412+ regular_episodes = []
413+ movie_episodes = []
414+
415+ # Episoden in reguläre und Filme aufteilen
416+ for ep in self .current_info .episodes :
417+ if event .value == Select .BLANK or str (ep .season ) == event .value :
418+ if str (ep .season ) == "0" :
419+ movie_episodes .append (ep )
420+ else :
421+ regular_episodes .append (ep )
422+
423+ # Zusammenführen der Listen: erst reguläre Episoden, dann Filme
424+ sorted_episodes = regular_episodes + movie_episodes
425+ self .filtered_episodes = sorted_episodes
426+
427+ # Anzeigen der sortierten Episoden
428+ c = 0
429+ for ep in sorted_episodes :
430+ hl = []
431+ for h in ep .available_hoster :
432+ hl .append (hoster .get_key (h ))
433+
434+ ll = []
435+ for l in sort_favorite_lang (ep .available_language , self .language ):
436+ ll .append (l .name )
437+
438+ c += 1
439+ table .add_row (
440+ c ,
441+ "F" if str (ep .season ) == "0" else ep .season ,
442+ ep .episode_number ,
443+ escape (ep .title ),
444+ " " .join (sort_favorite_hoster_by_key (hl , self .hoster )),
445+ " " .join (ll ),
446+ )
447+
392448 @on (SortableTable .SortChanged )
393449 async def sortableTable_sortChanged (
394450 self ,
@@ -637,13 +693,29 @@ async def on_key(self, event: events.Key) -> None:
637693 async def play_selected (self ):
638694 dt = self .query_one ("#season_list" , DataTable )
639695 # TODO: show loading
640- #dt.set_loading(True)
696+ # dt.set_loading(True)
641697 index = self .app .query_one ("#results" , ListView ).index
642698 series_search_result = self .current [index ]
699+
700+ # Verwende filtered_episodes falls vorhanden, sonst current_info.episodes
701+ if hasattr (self , 'filtered_episodes' ) and self .filtered_episodes :
702+ episodes_to_use = self .filtered_episodes
703+ # cursor_row entspricht direkt dem Index in der gefilterten Liste
704+ selected_index = dt .cursor_row
705+ else :
706+ episodes_to_use = self .current_info .episodes
707+ # Finde die entsprechende Episode basierend auf der Tabellenzeile
708+ selected_row = dt .get_row_at (dt .cursor_row )
709+ # Suche die passende Episode anhand der angezeigten Informationen
710+ selected_index = next ((i for i , ep in enumerate (episodes_to_use )
711+ if
712+ (str (ep .season ) if ep .season != 0 else "F" ) == str (selected_row [1 ]) # Prüfe Staffel
713+ and str (ep .episode_number ) == str (selected_row [2 ])), 0 ) # Prüfe Episodennummer
714+
643715 self .play (
644716 series_search_result = series_search_result ,
645- episodes = self . current_info . episodes ,
646- index = dt . cursor_row ,
717+ episodes = episodes_to_use ,
718+ index = selected_index ,
647719 )
648720 #dt.set_loading(False)
649721
@@ -665,6 +737,22 @@ async def open_info(self) -> None:
665737
666738 series = await self .get_series (series_search_result )
667739 self .current_info = series
740+
741+ season_filter = self .query_one ("#season_filter" , Select )
742+ unique_seasons = sorted (set (ep .season for ep in series .episodes ))
743+
744+ # Sortiere die Staffeln so, dass Filme (Staffel 0) am Ende erscheint
745+ regular_seasons = [s for s in unique_seasons if s != 0 ]
746+ movies_season = [s for s in unique_seasons if s == 0 ]
747+ sorted_seasons = regular_seasons + movies_season
748+
749+ season_filter_options = []
750+ for season in sorted_seasons :
751+ label = "Filme" if season == 0 else f"Staffel { season } "
752+ season_filter_options .append ((label , str (season )))
753+ season_filter .set_options (season_filter_options )
754+ season_filter .value = Select .BLANK
755+
668756 await md .update (series .to_markdown ())
669757
670758 if gucken_settings_manager .settings ["settings" ]["image_display" ]:
@@ -677,8 +765,25 @@ async def open_info(self) -> None:
677765 table .clear (columns = True )
678766 table .add_columns ("FT" , "S" , "F" , "Title" , "Hoster" , "Sprache" )
679767
680- c = 0
768+ # Sortiere die Episoden entsprechend
769+
770+ # Sortiere die Episoden entsprechend der gewünschten Reihenfolge
771+ sorted_episodes = []
772+ # Zuerst Specials (S)
681773 for ep in series .episodes :
774+ if ep .season == "S" :
775+ sorted_episodes .append (ep )
776+ # Dann numerische Staffeln
777+ for ep in series .episodes :
778+ if isinstance (ep .season , (int , str )) and ep .season not in ["S" , 0 ]:
779+ sorted_episodes .append (ep )
780+ # Zum Schluss Filme (F)
781+ for ep in series .episodes :
782+ if ep .season == 0 :
783+ sorted_episodes .append (ep )
784+
785+ c = 0
786+ for ep in sorted_episodes :
682787 hl = []
683788 for h in ep .available_hoster :
684789 hl .append (hoster .get_key (h ))
@@ -688,9 +793,17 @@ async def open_info(self) -> None:
688793 ll .append (l .name )
689794
690795 c += 1
796+ # Zeige die Staffeln in der gewünschten Reihenfolge
797+ if ep .season == "S" :
798+ season_display = "S"
799+ elif ep .season == 0 :
800+ season_display = "F"
801+ else :
802+ season_display = ep .season
803+
691804 table .add_row (
692805 c ,
693- ep . season ,
806+ season_display ,
694807 ep .episode_number ,
695808 escape (ep .title ),
696809 " " .join (sort_favorite_hoster_by_key (hl , self .hoster )),
0 commit comments