use std::{ collections::BTreeSet, io, path::PathBuf, time::{Duration, Instant}, }; use ratatui::{ DefaultTerminal, Frame, crossterm::{ cursor::SetCursorStyle, event::{ self, DisableBracketedPaste, EnableBracketedPaste, Event, KeyCode, KeyEvent, KeyEventKind, }, execute, }, layout::Margin, style::{Color, Style, Stylize}, text::Line, widgets::{Block, Clear, List, ListItem, ListState, Paragraph, Wrap}, }; use serde_json::Value; use tubular::anime::{Identity, Provider}; use crate::{ Options, PreviewMode, config, keys::{Action, Context}, miruro_browser::{self, Episode, Media, Request, Response, Worker}, thumbnail::Thumbnail, ui, video_state::{CollectionKind, State, WatchStatus}, youtube::{PlayerLaunch, Video}, }; #[derive(Clone, Copy, Default)] enum WatchFilter { #[default] All, Unwatched, Watched, } impl WatchFilter { fn next(self) -> Self { match self { Self::All => Self::Unwatched, Self::Unwatched => Self::Watched, Self::Watched => Self::All, } } fn label(self) -> &'static str { match self { Self::All => "All", Self::Unwatched => "Unwatched", Self::Watched => "Watched", } } fn includes(self, watched: bool) -> bool { match self { Self::All => true, Self::Unwatched => !watched, Self::Watched => watched, } } } enum Content { Catalog { query: String, media: Vec, searched: bool, }, Series { media: Media, data: Option>, }, Collection { kind: CollectionKind, filter: WatchFilter, videos: Vec