termusiclib/
types.rs

1use std::sync::Arc;
2
3use crate::config::v2::tui::{keys::KeyBinding, theme::styles::ColorTermusic};
4use crate::invidious::{Instance, YoutubeVideo};
5use crate::podcast::{EpData, PodcastFeed, PodcastNoId};
6use crate::songtag::SongTag;
7use anyhow::{anyhow, Result};
8use image::DynamicImage;
9
10#[derive(Clone, PartialEq, Eq, Debug)]
11pub enum Msg {
12    // AppClose,
13    ConfigEditor(ConfigEditorMsg),
14    DataBase(DBMsg),
15    DeleteConfirmCloseCancel,
16    DeleteConfirmCloseOk,
17    DeleteConfirmShow,
18    Download(DLMsg),
19    ErrorPopupClose,
20    GeneralSearch(GSMsg),
21    HelpPopupShow,
22    HelpPopupClose,
23    LayoutTreeView,
24    LayoutDataBase,
25    LayoutPodCast,
26    Library(LIMsg),
27    LyricMessage(LyricMsg),
28    LyricCycle,
29    LyricAdjustDelay(i64),
30    PlayerToggleGapless,
31    PlayerTogglePause,
32    PlayerVolumeUp,
33    PlayerVolumeDown,
34    PlayerSpeedUp,
35    PlayerSpeedDown,
36    PlayerSeekForward,
37    PlayerSeekBackward,
38    Playlist(PLMsg),
39    Podcast(PCMsg),
40    QuitPopupCloseCancel,
41    QuitPopupCloseOk,
42    QuitPopupShow,
43    SavePlaylistPopupShow,
44    SavePlaylistPopupCloseCancel,
45    SavePlaylistPopupUpdate(String),
46    SavePlaylistPopupCloseOk(String),
47    SavePlaylistConfirmCloseCancel,
48    SavePlaylistConfirmCloseOk(String),
49    TagEditor(TEMsg),
50    UpdatePhoto,
51    YoutubeSearch(YSMsg),
52    Xywh(XYWHMsg),
53
54    /// Force a redraw because of some change.
55    ///
56    /// This is necessary as `Components` do not have access to `Model.redraw`.
57    ///
58    /// For example pushing ARROW DOWN to change the selection in a table.
59    ForceRedraw,
60}
61
62#[derive(Clone, Copy, PartialEq, Eq, Debug)]
63pub enum XYWHMsg {
64    /// Toggle the hidden / shown status of the displayed image.
65    ToggleHidden,
66    MoveLeft,
67    MoveRight,
68    MoveUp,
69    MoveDown,
70    ZoomIn,
71    ZoomOut,
72}
73
74pub type DLMsgURL = Arc<str>;
75
76#[derive(Clone, PartialEq, Eq, Debug)]
77pub enum DLMsg {
78    /// Indicates a Start of a download.
79    ///
80    /// `(Url, Title)`
81    DownloadRunning(DLMsgURL, String),
82    /// Indicates the Download was a Success, though termusic post-processing is not done yet.
83    ///
84    /// `(Url)`
85    DownloadSuccess(DLMsgURL),
86    /// Indicates the Download thread finished in both Success or Error.
87    ///
88    /// `(Url, Filename)`
89    DownloadCompleted(DLMsgURL, Option<String>),
90    /// Indicates that the Download has Errored and has been aborted.
91    ///
92    /// `(Url, Title, ErrorAsString)`
93    DownloadErrDownload(DLMsgURL, String, String),
94    /// Indicates that the Download was a Success, but termusic post-processing failed.
95    /// Like re-saving tags after editing.
96    ///
97    /// `(Url, Title)`
98    DownloadErrEmbedData(DLMsgURL, String),
99
100    // TODO: The Following 2 things have absolutely nothing to-do with Download
101    /// Show a status message in the TUI.
102    ///
103    /// `((Title, Text))`
104    MessageShow((String, String)),
105    /// Hide a status message in the TUI.
106    ///
107    /// `((Title, Text))`
108    MessageHide((String, String)),
109
110    // TODO: The Following 2 things have absolutely nothing to-do with Download
111    /// Fetching & loading the image was a success, with the image.
112    FetchPhotoSuccess(ImageWrapper),
113    /// Fetching & loading the image has failed, with error message.
114    /// `(ErrorAsString)`
115    FetchPhotoErr(String),
116}
117
118#[derive(Clone, Copy, PartialEq, Eq, Debug)]
119pub enum LyricMsg {
120    LyricTextAreaBlurUp,
121    LyricTextAreaBlurDown,
122}
123
124#[derive(Clone, PartialEq, Eq, Debug)]
125pub enum ConfigEditorMsg {
126    PodcastDirBlurDown,
127    PodcastDirBlurUp,
128    PodcastSimulDownloadBlurDown,
129    PodcastSimulDownloadBlurUp,
130    PodcastMaxRetriesBlurDown,
131    PodcastMaxRetriesBlurUp,
132
133    AlbumPhotoAlignBlurDown,
134    AlbumPhotoAlignBlurUp,
135    ChangeLayout,
136    CloseCancel,
137    CloseOk,
138    ColorChanged(IdConfigEditor, ColorTermusic),
139    SymbolChanged(IdConfigEditor, String),
140    ConfigChanged,
141    ConfigSaveOk,
142    ConfigSaveCancel,
143    ExitConfirmationBlurDown,
144    ExitConfirmationBlurUp,
145    Open,
146    KeyFocus(KFMsg),
147    MusicDirBlurDown,
148    MusicDirBlurUp,
149
150    PlaylistDisplaySymbolBlurDown,
151    PlaylistDisplaySymbolBlurUp,
152    PlaylistRandomTrackBlurDown,
153    PlaylistRandomTrackBlurUp,
154    PlaylistRandomAlbumBlurDown,
155    PlaylistRandomAlbumBlurUp,
156
157    LibraryForegroundBlurDown,
158    LibraryForegroundBlurUp,
159    LibraryBackgroundBlurDown,
160    LibraryBackgroundBlurUp,
161    LibraryBorderBlurDown,
162    LibraryBorderBlurUp,
163    LibraryHighlightBlurDown,
164    LibraryHighlightBlurUp,
165    LibraryHighlightSymbolBlurDown,
166    LibraryHighlightSymbolBlurUp,
167
168    PlaylistForegroundBlurDown,
169    PlaylistForegroundBlurUp,
170    PlaylistBackgroundBlurDown,
171    PlaylistBackgroundBlurUp,
172    PlaylistBorderBlurDown,
173    PlaylistBorderBlurUp,
174    PlaylistHighlightBlurDown,
175    PlaylistHighlightBlurUp,
176    PlaylistHighlightSymbolBlurDown,
177    PlaylistHighlightSymbolBlurUp,
178
179    ProgressForegroundBlurDown,
180    ProgressForegroundBlurUp,
181    ProgressBackgroundBlurDown,
182    ProgressBackgroundBlurUp,
183    ProgressBorderBlurDown,
184    ProgressBorderBlurUp,
185
186    LyricForegroundBlurDown,
187    LyricForegroundBlurUp,
188    LyricBackgroundBlurDown,
189    LyricBackgroundBlurUp,
190    LyricBorderBlurDown,
191    LyricBorderBlurUp,
192
193    ThemeSelectBlurDown,
194    ThemeSelectBlurUp,
195    ThemeSelectLoad(usize),
196
197    KeyChange(IdKey, KeyBinding),
198    SaveLastPositionBlurDown,
199    SaveLastPosotionBlurUp,
200    SeekStepBlurDown,
201    SeekStepBlurUp,
202    KillDaemonBlurDown,
203    KillDaemonBlurUp,
204
205    PlayerUseMprisBlurDown,
206    PlayerUseMprisBlurUp,
207    PlayerUseDiscordBlurDown,
208    PlayerUseDiscordBlurUp,
209    PlayerPortBlurDown,
210    PlayerPortBlurUp,
211
212    CurrentlyPlayingTrackSymbolBlurDown,
213    CurrentlyPlayingTrackSymbolBlurUp,
214
215    ImportantPopupForegroundBlurDown,
216    ImportantPopupForegroundBlurUp,
217    ImportantPopupBackgroundBlurDown,
218    ImportantPopupBackgroundBlurUp,
219    ImportantPopupBorderBlurDown,
220    ImportantPopupBorderBlurUp,
221
222    FallbackForegroundBlurDown,
223    FallbackForegroundBlurUp,
224    FallbackBackgroundBlurDown,
225    FallbackBackgroundBlurUp,
226    FallbackBorderBlurDown,
227    FallbackBorderBlurUp,
228    FallbackHighlightBlurDown,
229    FallbackHighlightBlurUp,
230}
231
232#[derive(Clone, Copy, Debug, PartialEq, Eq)]
233pub enum KFMsg {
234    DatabaseAddAllBlurDown,
235    DatabaseAddAllBlurUp,
236    DatabaseAddSelectedBlurDown,
237    DatabaseAddSelectedBlurUp,
238    GlobalConfigBlurDown,
239    GlobalConfigBlurUp,
240    GlobalDownBlurDown,
241    GlobalDownBlurUp,
242    GlobalGotoBottomBlurDown,
243    GlobalGotoBottomBlurUp,
244    GlobalGotoTopBlurDown,
245    GlobalGotoTopBlurUp,
246    GlobalHelpBlurDown,
247    GlobalHelpBlurUp,
248    GlobalLayoutTreeviewBlurDown,
249    GlobalLayoutTreeviewBlurUp,
250    GlobalLayoutDatabaseBlurDown,
251    GlobalLayoutDatabaseBlurUp,
252    GlobalLeftBlurDown,
253    GlobalLeftBlurUp,
254    GlobalLyricAdjustForwardBlurDown,
255    GlobalLyricAdjustForwardBlurUp,
256    GlobalLyricAdjustBackwardBlurDown,
257    GlobalLyricAdjustBackwardBlurUp,
258    GlobalLyricCycleBlurDown,
259    GlobalLyricCycleBlurUp,
260    GlobalPlayerNextBlurDown,
261    GlobalPlayerNextBlurUp,
262    GlobalPlayerPreviousBlurDown,
263    GlobalPlayerPreviousBlurUp,
264    GlobalPlayerSeekForwardBlurDown,
265    GlobalPlayerSeekForwardBlurUp,
266    GlobalPlayerSeekBackwardBlurDown,
267    GlobalPlayerSeekBackwardBlurUp,
268    GlobalPlayerSpeedUpBlurDown,
269    GlobalPlayerSpeedUpBlurUp,
270    GlobalPlayerSpeedDownBlurDown,
271    GlobalPlayerSpeedDownBlurUp,
272    GlobalPlayerToggleGaplessBlurDown,
273    GlobalPlayerToggleGaplessBlurUp,
274    GlobalPlayerTogglePauseBlurDown,
275    GlobalPlayerTogglePauseBlurUp,
276    GlobalQuitBlurDown,
277    GlobalQuitBlurUp,
278    GlobalRightBlurDown,
279    GlobalRightBlurUp,
280    GlobalUpBlurDown,
281    GlobalUpBlurUp,
282    GlobalVolumeDownBlurDown,
283    GlobalVolumeDownBlurUp,
284    GlobalVolumeUpBlurDown,
285    GlobalVolumeUpBlurUp,
286    GlobalSavePlaylistBlurDown,
287    GlobalSavePlaylistBlurUp,
288    LibraryDeleteBlurDown,
289    LibraryDeleteBlurUp,
290    LibraryLoadDirBlurDown,
291    LibraryLoadDirBlurUp,
292    LibraryPasteBlurDown,
293    LibraryPasteBlurUp,
294    LibrarySearchBlurDown,
295    LibrarySearchBlurUp,
296    LibrarySearchYoutubeBlurDown,
297    LibrarySearchYoutubeBlurUp,
298    LibraryTagEditorBlurDown,
299    LibraryTagEditorBlurUp,
300    LibraryYankBlurDown,
301    LibraryYankBlurUp,
302    PlaylistDeleteBlurDown,
303    PlaylistDeleteBlurUp,
304    PlaylistDeleteAllBlurDown,
305    PlaylistDeleteAllBlurUp,
306    PlaylistShuffleBlurDown,
307    PlaylistShuffleBlurUp,
308    PlaylistModeCycleBlurDown,
309    PlaylistModeCycleBlurUp,
310    PlaylistPlaySelectedBlurDown,
311    PlaylistPlaySelectedBlurUp,
312    PlaylistSearchBlurDown,
313    PlaylistSearchBlurUp,
314    PlaylistSwapDownBlurDown,
315    PlaylistSwapDownBlurUp,
316    PlaylistSwapUpBlurDown,
317    PlaylistSwapUpBlurUp,
318    PlaylistAddRandomAlbumBlurDown,
319    PlaylistAddRandomAlbumBlurUp,
320    PlaylistAddRandomTracksBlurDown,
321    PlaylistAddRandomTracksBlurUp,
322    LibrarySwitchRootBlurDown,
323    LibrarySwitchRootBlurUp,
324    LibraryAddRootBlurDown,
325    LibraryAddRootBlurUp,
326    LibraryRemoveRootBlurDown,
327    LibraryRemoveRootBlurUp,
328    GlobalLayoutPodcastBlurDown,
329    GlobalLayoutPodcastBlurUp,
330    GlobalXywhMoveLeftBlurDown,
331    GlobalXywhMoveLeftBlurUp,
332    GlobalXywhMoveRightBlurDown,
333    GlobalXywhMoveRightBlurUp,
334    GlobalXywhMoveUpBlurDown,
335    GlobalXywhMoveUpBlurUp,
336    GlobalXywhMoveDownBlurDown,
337    GlobalXywhMoveDownBlurUp,
338    GlobalXywhZoomInBlurDown,
339    GlobalXywhZoomInBlurUp,
340    GlobalXywhZoomOutBlurDown,
341    GlobalXywhZoomOutBlurUp,
342    GlobalXywhHideBlurDown,
343    GlobalXywhHideBlurUp,
344    PodcastMarkPlayedBlurDown,
345    PodcastMarkPlayedBlurUp,
346    PodcastMarkAllPlayedBlurDown,
347    PodcastMarkAllPlayedBlurUp,
348    PodcastEpDownloadBlurDown,
349    PodcastEpDownloadBlurUp,
350    PodcastEpDeleteFileBlurDown,
351    PodcastEpDeleteFileBlurUp,
352    PodcastDeleteFeedBlurDown,
353    PodcastDeleteFeedBlurUp,
354    PodcastDeleteAllFeedsBlurDown,
355    PodcastDeleteAllFeedsBlurUp,
356    PodcastSearchAddFeedBlurDown,
357    PodcastSearchAddFeedBlurUp,
358    PodcastRefreshFeedBlurDown,
359    PodcastRefreshFeedBlurUp,
360    PodcastRefreshAllFeedsBlurDown,
361    PodcastRefreshAllFeedsBlurUp,
362}
363
364#[derive(Clone, Debug, PartialEq, Eq)]
365pub enum LIMsg {
366    TreeStepInto(String),
367    TreeStepOut,
368    TreeBlur,
369    Yank,
370    Paste,
371    SwitchRoot,
372    AddRoot,
373    RemoveRoot,
374}
375
376#[derive(Clone, Copy, Debug, PartialEq, Eq)]
377pub enum DBMsg {
378    AddAllToPlaylist,
379    AddPlaylist(usize),
380    CriteriaBlurDown,
381    CriteriaBlurUp,
382    SearchResult(usize),
383    SearchResultBlurDown,
384    SearchResultBlurUp,
385    SearchTrack(usize),
386    SearchTracksBlurDown,
387    SearchTracksBlurUp,
388}
389
390#[derive(Clone, Debug, PartialEq, Eq)]
391pub enum PCMsg {
392    PodcastBlurDown,
393    PodcastBlurUp,
394    EpisodeBlurDown,
395    EpisodeBlurUp,
396    PodcastAddPopupShow,
397    PodcastAddPopupCloseOk(String),
398    PodcastAddPopupCloseCancel,
399    SyncData((i64, PodcastNoId)),
400    NewData(PodcastNoId),
401    Error(PodcastFeed),
402    PodcastSelected(usize),
403    DescriptionUpdate,
404    EpisodeAdd(usize),
405    EpisodeMarkPlayed(usize),
406    EpisodeMarkAllPlayed,
407    PodcastRefreshOne(usize),
408    PodcastRefreshAll,
409    FetchPodcastStart(String),
410    EpisodeDownload(usize),
411    DLStart(EpData),
412    DLComplete(EpData),
413    DLResponseError(EpData),
414    DLFileCreateError(EpData),
415    DLFileWriteError(EpData),
416    EpisodeDeleteFile(usize),
417    FeedDeleteShow,
418    FeedDeleteCloseOk,
419    FeedDeleteCloseCancel,
420    FeedsDeleteShow,
421    FeedsDeleteCloseOk,
422    FeedsDeleteCloseCancel,
423    SearchItunesCloseCancel,
424    SearchItunesCloseOk(usize),
425    SearchSuccess(Vec<PodcastFeed>),
426    SearchError(String),
427}
428
429/// Playlist Library View messages
430#[derive(Clone, Debug, PartialEq, Eq)]
431pub enum PLMsg {
432    NextSong,
433    PrevSong,
434    /// Change focus to the next view
435    PlaylistTableBlurDown,
436    /// Change focus to the previous view
437    PlaylistTableBlurUp,
438    /// Add a directory / file to the playlist
439    Add(String),
440    /// Remove INDEX from playlist
441    Delete(usize),
442    /// Clear the Playlist
443    DeleteAll,
444    /// Select the next mode in the list
445    ///
446    /// see `termusicplayback::playlist::Loop` for all modes
447    LoopModeCycle,
448    /// Play a specific index
449    PlaySelected(usize),
450    /// Shuffle the current items in the playlist
451    Shuffle,
452    /// Swap a entry at INDEX with +1 (down)
453    SwapDown(usize),
454    /// Swap a entry at INDEX with -1 (up)
455    SwapUp(usize),
456    /// Start choosing random albums to be added to the playlist
457    AddRandomAlbum,
458    /// Start choosing random tracks to be added to the playlist
459    AddRandomTracks,
460}
461#[derive(Clone, Debug, PartialEq, Eq)]
462pub enum GSMsg {
463    PopupShowDatabase,
464    PopupShowLibrary,
465    PopupShowPlaylist,
466    PopupShowEpisode,
467    PopupShowPodcast,
468    PopupCloseCancel,
469    InputBlur,
470    PopupUpdateDatabase(String),
471    PopupUpdateLibrary(String),
472    PopupUpdatePlaylist(String),
473    PopupUpdateEpisode(String),
474    PopupUpdatePodcast(String),
475    TableBlur,
476    PopupCloseEpisodeAddPlaylist,
477    PopupCloseDatabaseAddPlaylist,
478    PopupCloseLibraryAddPlaylist,
479    PopupCloseOkLibraryLocate,
480    PopupClosePlaylistPlaySelected,
481    PopupCloseOkPlaylistLocate,
482    PopupCloseOkEpisodeLocate,
483    PopupCloseOkPodcastLocate,
484}
485
486#[derive(Clone, Debug, PartialEq, Eq)]
487pub enum YSMsg {
488    InputPopupShow,
489    InputPopupCloseCancel,
490    InputPopupCloseOk(String),
491    TablePopupNext,
492    TablePopupPrevious,
493    TablePopupCloseCancel,
494    TablePopupCloseOk(usize),
495
496    /// The youtube search was a success, with all values.
497    YoutubeSearchSuccess(YoutubeOptions),
498    /// Indicates that the youtube search has failed, with error message.
499    ///
500    /// `(ErrorAsString)`
501    YoutubeSearchFail(String),
502}
503#[derive(Clone, Debug, PartialEq, Eq)]
504pub enum TEMsg {
505    TagEditorRun(String),
506    TagEditorClose(Option<String>),
507    TECounterDeleteOk,
508    TEDownload(usize),
509    TEEmbed(usize),
510    TEFocus(TFMsg),
511    TERename,
512    TESearch,
513    TESelectLyricOk(usize),
514}
515
516#[derive(Clone, Copy, Debug, PartialEq, Eq)]
517pub enum TFMsg {
518    CounterDeleteBlurDown,
519    CounterDeleteBlurUp,
520    InputArtistBlurDown,
521    InputArtistBlurUp,
522    InputTitleBlurDown,
523    InputTitleBlurUp,
524    InputAlbumBlurDown,
525    InputAlbumBlurUp,
526    InputGenreBlurDown,
527    InputGenreBlurUp,
528    SelectLyricBlurDown,
529    SelectLyricBlurUp,
530    TableLyricOptionsBlurDown,
531    TableLyricOptionsBlurUp,
532    TextareaLyricBlurDown,
533    TextareaLyricBlurUp,
534}
535
536#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)]
537pub enum Id {
538    ConfigEditor(IdConfigEditor),
539    DBListCriteria,
540    DBListSearchResult,
541    DBListSearchTracks,
542    DeleteConfirmRadioPopup,
543    DeleteConfirmInputPopup,
544    DownloadSpinner,
545    Episode,
546    ErrorPopup,
547    GeneralSearchInput,
548    GeneralSearchTable,
549    GlobalListener,
550    HelpPopup,
551    Label,
552    Library,
553    Lyric,
554    MessagePopup,
555    Playlist,
556    Podcast,
557    PodcastAddPopup,
558    PodcastSearchTablePopup,
559    FeedDeleteConfirmRadioPopup,
560    FeedDeleteConfirmInputPopup,
561    Progress,
562    QuitPopup,
563    SavePlaylistPopup,
564    SavePlaylistLabel,
565    SavePlaylistConfirm,
566    TagEditor(IdTagEditor),
567    YoutubeSearchInputPopup,
568    YoutubeSearchTablePopup,
569}
570
571#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)]
572pub enum IdTagEditor {
573    CounterDelete,
574    LabelHint,
575    InputArtist,
576    InputTitle,
577    InputAlbum,
578    InputGenre,
579    SelectLyric,
580    TableLyricOptions,
581    TextareaLyric,
582}
583
584#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)]
585pub enum IdConfigEditor {
586    AlbumPhotoAlign,
587    CEThemeSelect,
588    ConfigSavePopup,
589    ExitConfirmation,
590    Footer,
591    Header,
592    Key(IdKey),
593    KillDamon,
594
595    LibraryBackground,
596    LibraryBorder,
597    LibraryForeground,
598    LibraryHighlight,
599    LibraryHighlightSymbol,
600    LibraryLabel,
601
602    LyricBackground,
603    LyricBorder,
604    LyricForeground,
605    LyricLabel,
606
607    MusicDir,
608    PlayerPort,
609    PlayerUseDiscord,
610    PlayerUseMpris,
611
612    PlaylistBackground,
613    PlaylistBorder,
614    PlaylistDisplaySymbol,
615    PlaylistForeground,
616    PlaylistHighlight,
617    PlaylistHighlightSymbol,
618    PlaylistLabel,
619    PlaylistRandomAlbum,
620    PlaylistRandomTrack,
621
622    CurrentlyPlayingTrackSymbol,
623
624    PodcastDir,
625    PodcastMaxRetries,
626    PodcastSimulDownload,
627
628    ProgressBackground,
629    ProgressBorder,
630    ProgressForeground,
631    ProgressLabel,
632
633    SaveLastPosition,
634    SeekStep,
635
636    ImportantPopupLabel,
637    ImportantPopupBackground,
638    ImportantPopupBorder,
639    ImportantPopupForeground,
640
641    FallbackBackground,
642    FallbackBorder,
643    FallbackForeground,
644    FallbackHighlight,
645    FallbackLabel,
646}
647
648#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)]
649pub enum IdKey {
650    DatabaseAddAll,
651    DatabaseAddSelected,
652    GlobalConfig,
653    GlobalDown,
654    GlobalGotoBottom,
655    GlobalGotoTop,
656    GlobalHelp,
657    GlobalLayoutTreeview,
658    GlobalLayoutDatabase,
659    GlobalLeft,
660    GlobalLyricAdjustForward,
661    GlobalLyricAdjustBackward,
662    GlobalLyricCycle,
663    GlobalPlayerToggleGapless,
664    GlobalPlayerTogglePause,
665    GlobalPlayerNext,
666    GlobalPlayerPrevious,
667    GlobalPlayerSeekForward,
668    GlobalPlayerSeekBackward,
669    GlobalPlayerSpeedUp,
670    GlobalPlayerSpeedDown,
671    GlobalQuit,
672    GlobalRight,
673    GlobalUp,
674    GlobalVolumeDown,
675    GlobalVolumeUp,
676    GlobalSavePlaylist,
677    LibraryDelete,
678    LibraryLoadDir,
679    LibraryPaste,
680    LibrarySearch,
681    LibrarySearchYoutube,
682    LibraryTagEditor,
683    LibraryYank,
684    PlaylistDelete,
685    PlaylistDeleteAll,
686    PlaylistShuffle,
687    PlaylistModeCycle,
688    PlaylistPlaySelected,
689    PlaylistSearch,
690    PlaylistSwapDown,
691    PlaylistSwapUp,
692    PlaylistAddRandomAlbum,
693    PlaylistAddRandomTracks,
694    LibrarySwitchRoot,
695    LibraryAddRoot,
696    LibraryRemoveRoot,
697    GlobalLayoutPodcast,
698    GlobalXywhMoveLeft,
699    GlobalXywhMoveRight,
700    GlobalXywhMoveUp,
701    GlobalXywhMoveDown,
702    GlobalXywhZoomIn,
703    GlobalXywhZoomOut,
704    GlobalXywhHide,
705    PodcastMarkPlayed,
706    PodcastMarkAllPlayed,
707    PodcastEpDownload,
708    PodcastEpDeleteFile,
709    PodcastDeleteFeed,
710    PodcastDeleteAllFeeds,
711    PodcastSearchAddFeed,
712    PodcastRefreshFeed,
713    PodcastRefreshAllFeeds,
714}
715pub enum SearchLyricState {
716    Finish(Vec<SongTag>),
717}
718
719#[derive(Clone, PartialEq, Debug)]
720pub struct ImageWrapper {
721    pub data: DynamicImage,
722}
723impl Eq for ImageWrapper {}
724
725#[derive(Clone, PartialEq, Eq, Debug)]
726pub struct YoutubeOptions {
727    pub items: Vec<YoutubeVideo>,
728    pub page: u32,
729    pub invidious_instance: Instance,
730}
731
732impl Default for YoutubeOptions {
733    fn default() -> Self {
734        Self {
735            items: Vec::new(),
736            page: 1,
737            invidious_instance: crate::invidious::Instance::default(),
738        }
739    }
740}
741
742impl YoutubeOptions {
743    pub fn get_by_index(&self, index: usize) -> Result<&YoutubeVideo> {
744        if let Some(item) = self.items.get(index) {
745            return Ok(item);
746        }
747        Err(anyhow!("index not found"))
748    }
749
750    pub async fn prev_page(&mut self) -> Result<()> {
751        if self.page > 1 {
752            self.page -= 1;
753            self.items = self.invidious_instance.get_search_query(self.page).await?;
754        }
755        Ok(())
756    }
757
758    pub async fn next_page(&mut self) -> Result<()> {
759        self.page += 1;
760        self.items = self.invidious_instance.get_search_query(self.page).await?;
761        Ok(())
762    }
763
764    #[must_use]
765    pub const fn page(&self) -> u32 {
766        self.page
767    }
768}