diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/src/routes/ui/sort.rs | 151 |
1 files changed, 99 insertions, 52 deletions
diff --git a/server/src/routes/ui/sort.rs b/server/src/routes/ui/sort.rs index d8a44b2..dc017a2 100644 --- a/server/src/routes/ui/sort.rs +++ b/server/src/routes/ui/sort.rs @@ -11,67 +11,97 @@ pub struct NodeFilterSort { sort_order: Option<SortOrder>, } -#[rustfmt::skip] -#[derive(FromFormField, UriDisplayQuery, Clone, PartialEq, Eq)] -enum FilterProperty { - #[field(value = "fed_local")] FederationLocal, - #[field(value = "fed_remote")] FederationRemote, - #[field(value = "kind_movie")] KindMovie, - #[field(value = "kind_video")] KindVideo, - #[field(value = "kind_collection")] KindCollection, - #[field(value = "kind_channel")] KindChannel, - #[field(value = "kind_show")] KindShow, - #[field(value = "kind_series")] KindSeries, - #[field(value = "kind_season")] KindSeason, - #[field(value = "kind_episode")] KindEpisode, +macro_rules! form_enum { + (enum $i:ident { $($vi:ident = $vk:literal),*, }) => { + #[derive(FromFormField, UriDisplayQuery, Clone, PartialEq, Eq)] + enum $i { $(#[field(value = $vk)] $vi),* } + impl $i { #[allow(unused)] const ALL: &'static [$i] = &[$($i::$vi),*]; } + }; } -#[rustfmt::skip] -#[derive(FromFormField, UriDisplayQuery, Clone, PartialEq, Eq)] -enum SortProperty { - #[field(value = "release_date")] ReleaseDate, - #[field(value = "title")] Title, - #[field(value = "rating_rt")] RatingRottenTomatoes, - #[field(value = "rating_mc")] RatingMetacritic, - #[field(value = "rating_imdb")] RatingImdb, - #[field(value = "rating_yt_views")] RatingYoutubeViews, - #[field(value = "rating_yt_likes")] RatingYoutubeLikes, - #[field(value = "rating_yt_followers")] RatingYoutubeFollowers, -} +form_enum!( + enum FilterProperty { + FederationLocal = "fed_local", + FederationRemote = "fed_remote", + KindMovie = "kind_movie", + KindVideo = "kind_video", + KindCollection = "kind_collection", + KindChannel = "kind_channel", + KindShow = "kind_show", + KindSeries = "kind_series", + KindSeason = "kind_season", + KindEpisode = "kind_episode", + } +); + +form_enum!( + enum SortProperty { + ReleaseDate = "release_date", + Title = "title", + RatingRottenTomatoes = "rating_rt", + RatingMetacritic = "rating_mc", + RatingImdb = "rating_imdb", + RatingTmdb = "rating_tmdb", + RatingYoutubeViews = "rating_yt_views", + RatingYoutubeLikes = "rating_yt_likes", + RatingYoutubeFollowers = "rating_yt_followers", + } +); impl SortProperty { - const ALL: &'static [(SortProperty, &'static str)] = { + const CATS: &'static [(&'static str, &'static [(SortProperty, &'static str)])] = { use SortProperty::*; &[ - (Title, "Title"), - (ReleaseDate, "Release Date"), - (RatingImdb, "IMDb Rating"), - (RatingMetacritic, "Metacritic Rating"), - (RatingRottenTomatoes, "Rotten Tomatoes"), - (RatingYoutubeFollowers, "Youtube Subscribers"), - (RatingYoutubeLikes, "Youtube Likes"), - (RatingYoutubeViews, "Youtube Views"), + ( + "General", + &[(Title, "Title"), (ReleaseDate, "Release Date")], + ), + ( + "By Rating", + &[ + (RatingImdb, "IMDb Rating"), + (RatingTmdb, "TMDB Rating"), + (RatingMetacritic, "Metacritic Rating"), + (RatingRottenTomatoes, "Rotten Tomatoes"), + (RatingYoutubeFollowers, "Youtube Subscribers"), + (RatingYoutubeLikes, "Youtube Likes"), + (RatingYoutubeViews, "Youtube Views"), + ], + ), ] }; } impl FilterProperty { - const ALL: &'static [(FilterProperty, &'static str)] = { + const CATS: &'static [(&'static str, &'static [(FilterProperty, &'static str)])] = { use FilterProperty::*; &[ - (FederationLocal, "Local"), - (FederationRemote, "Remote"), - (KindMovie, "Movie"), - (KindVideo, "Video"), - (KindCollection, "Collection"), - (KindChannel, "Channel"), - (KindShow, "Show"), - (KindSeries, "Series"), - (KindSeason, "Season"), - (KindEpisode, "Episode"), + ( + "By Kind", + &[ + (KindMovie, "Movie"), + (KindVideo, "Video"), + (KindCollection, "Collection"), + (KindChannel, "Channel"), + (KindShow, "Show"), + (KindSeries, "Series"), + (KindSeason, "Season"), + (KindEpisode, "Episode"), + ], + ), + ( + "By Federation", + &[(FederationLocal, "Local"), (FederationRemote, "Remote")], + ), ] }; } +impl NodeFilterSort { + pub fn is_open(&self) -> bool { + self.filter_kind.is_some() || self.sort_by.is_some() + } +} + #[rustfmt::skip] #[derive(FromFormField, UriDisplayQuery, Clone, Copy, PartialEq, Eq)] enum SortOrder { @@ -86,7 +116,7 @@ pub fn filter_and_sort_nodes( nodes.retain(|(_id, node, _udata)| { let mut o = true; if let Some(prop) = &f.filter_kind { - for (p, _) in FilterProperty::ALL { + for p in FilterProperty::ALL { if prop.contains(p) { continue; } @@ -124,6 +154,9 @@ pub fn filter_and_sort_nodes( SortProperty::RatingImdb => nodes.sort_by_cached_key(|(_, n, _)| { SortAnyway(*n.ratings.get(&Rating::Imdb).unwrap_or(&0.)) }), + SortProperty::RatingTmdb => nodes.sort_by_cached_key(|(_, n, _)| { + SortAnyway(*n.ratings.get(&Rating::Tmdb).unwrap_or(&0.)) + }), SortProperty::RatingYoutubeViews => nodes.sort_by_cached_key(|(_, n, _)| { SortAnyway(*n.ratings.get(&Rating::YoutubeViews).unwrap_or(&0.)) }), @@ -143,19 +176,33 @@ pub fn filter_and_sort_nodes( markup::define! { NodeFilterSortForm<'a>(f: &'a NodeFilterSort) { - details.filtersort { + details.filtersort[open=f.is_open()] { summary { "Filter and Sort" } form[method="GET", action=""] { fieldset.filter { legend { "Filter" } - @for (value, label) in FilterProperty::ALL { - label { input[type="checkbox", name="filter_kind", value=value, checked=f.filter_kind.as_ref().map(|k|k.contains(&value)).unwrap_or(true)]; @label } br; + .categories { + @for (cname, cat) in FilterProperty::CATS { + .category { + h3 { @cname } + @for (value, label) in *cat { + label { input[type="checkbox", name="filter_kind", value=value, checked=f.filter_kind.as_ref().map(|k|k.contains(&value)).unwrap_or(true)]; @label } br; + } + } + } } } fieldset.sortby { - legend { "Sort By" } - @for (value, label) in SortProperty::ALL { - label { input[type="radio", name="sort_by", value=value, checked=Some(value)==f.sort_by.as_ref()]; @label } br; + legend { "Sort" } + .categories { + @for (cname, cat) in SortProperty::CATS { + .category { + h3 { @cname } + @for (value, label) in *cat { + label { input[type="radio", name="sort_by", value=value, checked=Some(value)==f.sort_by.as_ref()]; @label } br; + } + } + } } } fieldset.sortorder { |