Skip to content

Commit

Permalink
feat: custom category colors per source for custom themes
Browse files Browse the repository at this point in the history
  • Loading branch information
Beastwick18 committed Jun 5, 2024
1 parent 4be77c2 commit efcb24c
Show file tree
Hide file tree
Showing 11 changed files with 545 additions and 325 deletions.
49 changes: 27 additions & 22 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,8 +376,12 @@ impl App {
},
Some(rt) = rx_res.recv() => {
match rt {
Ok(SourceResults::Results(rt)) => ctx.results = rt,
Ok(SourceResults::Results(rt)) => {
self.widgets.results.reset();
ctx.results = rt;
}
Ok(SourceResults::Captcha(c)) => {
ctx.results = Results::default();
ctx.mode = Mode::Captcha;
self.widgets.captcha.image = Some(c);
self.widgets.captcha.input.clear();
Expand Down Expand Up @@ -440,22 +444,19 @@ impl App {

self.widgets.search.draw(f, ctx, layout_vertical[0]);
// Dont draw batch pane if empty
match ctx.batch.is_empty() {
true => self.widgets.results.draw(f, ctx, layout_vertical[1]),
false => {
let layout_horizontal = Layout::new(
Direction::Horizontal,
match ctx.mode {
Mode::Batch | Mode::Help => {
[Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)]
}
_ => [Constraint::Ratio(3, 4), Constraint::Ratio(1, 4)],
},
)
.split(layout_vertical[1]);
self.widgets.results.draw(f, ctx, layout_horizontal[0]);
self.widgets.batch.draw(f, ctx, layout_horizontal[1]);
}
if ctx.batch.is_empty() {
self.widgets.results.draw(f, ctx, layout_vertical[1]);
} else {
let layout_horizontal = Layout::new(
Direction::Horizontal,
match ctx.mode {
Mode::Batch | Mode::Help => [Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)],
_ => [Constraint::Ratio(3, 4), Constraint::Ratio(1, 4)],
},
)
.split(layout_vertical[1]);
self.widgets.results.draw(f, ctx, layout_horizontal[0]);
self.widgets.batch.draw(f, ctx, layout_horizontal[1]);
}
self.widgets.draw_popups(ctx, f);
self.widgets.notification.draw(f, ctx, f.size());
Expand Down Expand Up @@ -555,12 +556,16 @@ impl App {
match keys.chars().collect::<Vec<char>>()[..] {
['y', c] => {
let s = self.widgets.results.table.state.selected().unwrap_or(0);
match ctx.results.response.items.get(s) {
match ctx.results.response.items.get(s).cloned() {
Some(item) => {
let link = match c {
't' => item.torrent_link.to_owned(),
'm' => item.magnet_link.to_owned(),
'p' => item.post_link.to_owned(),
't' => item.torrent_link,
'm' => item.magnet_link,
'p' => item.post_link,
'i' => match item.extra.get("imdb").cloned() {
Some(imdb) => imdb,
None => return,
},
_ => return,
};
match clip::copy_to_clipboard(link.to_owned(), ctx.config.clipboard.clone())
Expand All @@ -569,7 +574,7 @@ impl App {
Err(e) => ctx.show_error(e),
}
}
None if ['t', 'm', 'p'].contains(&c) => {
None if ['t', 'm', 'p', 'i'].contains(&c) => {
ctx.show_error("Failed to copy:\nFailed to get item")
}
None => {}
Expand Down
8 changes: 2 additions & 6 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ macro_rules! widgets {
macro_rules! cats {
(
$(
$cats:expr => {$($idx:expr => ($icon:expr, $disp:expr, $conf:expr, $col:ident);)+}
$cats:expr => {$($idx:expr => ($icon:expr, $disp:expr, $conf:expr, $col:tt$(.$colext:tt)*);)+}
)+
) => {{
let v = vec![
Expand All @@ -85,16 +85,12 @@ macro_rules! cats {
$conf,
$idx,
$icon,
ratatui::style::Color::$col,
|theme: &$crate::theme::Theme| {theme.$col$(.$colext)*},
),
)+],
},)+
];
v

// pub static $name: &[&CatStruct] = &[
// $(&$cat,)+
// ];
}}
}

Expand Down
128 changes: 96 additions & 32 deletions src/source/nyaa_html.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{cmp::max, error::Error, time::Duration};
use chrono::{DateTime, Local, NaiveDateTime, TimeZone};
use ratatui::{
layout::{Alignment, Constraint},
style::Stylize as _,
style::{Color, Stylize as _},
};
use reqwest::{StatusCode, Url};
use scraper::{Html, Selector};
Expand All @@ -27,6 +27,70 @@ use super::{
add_protocol, nyaa_rss, Item, ItemType, Source, SourceConfig, SourceInfo, SourceResponse,
};

#[derive(Serialize, Deserialize, Clone, Copy)]
#[serde(default)]
pub struct NyaaTheme {
#[serde(with = "color_to_tui")]
pub anime_english_translated: Color,
#[serde(with = "color_to_tui")]
pub anime_non_english_translated: Color,
#[serde(with = "color_to_tui")]
pub anime_raw: Color,
#[serde(with = "color_to_tui")]
pub anime_music_video: Color,
#[serde(with = "color_to_tui")]
pub audio_lossless: Color,
#[serde(with = "color_to_tui")]
pub audio_lossy: Color,
#[serde(with = "color_to_tui")]
pub literature_english_translated: Color,
#[serde(with = "color_to_tui")]
pub literature_non_english_translated: Color,
#[serde(with = "color_to_tui")]
pub literature_raw: Color,
#[serde(with = "color_to_tui")]
pub live_english_translated: Color,
#[serde(with = "color_to_tui")]
pub live_non_english_translated: Color,
#[serde(with = "color_to_tui")]
pub live_idol_promo_video: Color,
#[serde(with = "color_to_tui")]
pub live_raw: Color,
#[serde(with = "color_to_tui")]
pub picture_graphics: Color,
#[serde(with = "color_to_tui")]
pub picture_photos: Color,
#[serde(with = "color_to_tui")]
pub software_applications: Color,
#[serde(with = "color_to_tui")]
pub software_games: Color,
}

impl Default for NyaaTheme {
fn default() -> Self {
use Color::*;
Self {
anime_english_translated: LightMagenta,
anime_non_english_translated: LightGreen,
anime_raw: Gray,
anime_music_video: Magenta,
audio_lossless: Red,
audio_lossy: Yellow,
literature_english_translated: LightGreen,
literature_non_english_translated: Yellow,
literature_raw: Gray,
live_english_translated: Yellow,
live_non_english_translated: LightCyan,
live_idol_promo_video: LightYellow,
live_raw: Gray,
picture_graphics: LightMagenta,
picture_photos: Magenta,
software_applications: Blue,
software_games: LightBlue,
}
}
}

#[derive(Serialize, Deserialize, Clone)]
#[serde(default)]
pub struct NyaaConfig {
Expand Down Expand Up @@ -113,7 +177,7 @@ popup_enum! {
pub struct NyaaHtmlSource;

pub fn nyaa_table(
items: &[Item],
items: Vec<Item>,
theme: &Theme,
sel_sort: &SelectedSort,
columns: &Option<NyaaColumns>,
Expand Down Expand Up @@ -141,17 +205,17 @@ pub fn nyaa_table(
Alignment::Left,
];
let mut rows: Vec<ResultRow> = items
.iter()
.into_iter()
.map(|item| {
ResultRow::new([
item.icon.label.fg(item.icon.color),
item.title.to_owned().fg(match item.item_type {
item.icon.label.fg((item.icon.color)(theme)),
item.title.fg(match item.item_type {
ItemType::Trusted => theme.success,
ItemType::Remake => theme.error,
ItemType::None => theme.fg,
}),
item.size.clone().fg(theme.fg),
item.date.clone().fg(theme.fg),
item.size.fg(theme.fg),
item.date.fg(theme.fg),
item.seeders.to_string().fg(theme.success),
item.leechers.to_string().fg(theme.error),
shorten_number(item.downloads).fg(theme.fg),
Expand Down Expand Up @@ -387,42 +451,42 @@ impl Source for NyaaHtmlSource {
fn info() -> SourceInfo {
let cats = cats! {
"All Categories" => {
0 => ("---", "All Categories", "AllCategories", White);
0 => ("---", "All Categories", "AllCategories", fg);
}
"Anime" => {
10 => ("Ani", "All Anime", "AllAnime", Gray);
12 => ("Sub", "English Translated", "AnimeEnglishTranslated", LightMagenta);
13 => ("Sub", "Non-English Translated", "AnimeNonEnglishTranslated", LightGreen);
14 => ("Raw", "Raw", "AnimeRaw", Gray);
11 => ("AMV", "Anime Music Video", "AnimeMusicVideo", Magenta);
10 => ("Ani", "All Anime", "AllAnime", fg);
12 => ("Sub", "English Translated", "AnimeEnglishTranslated", nyaa.anime_english_translated);
13 => ("Sub", "Non-English Translated", "AnimeNonEnglishTranslated", nyaa.anime_non_english_translated);
14 => ("Raw", "Raw", "AnimeRaw", nyaa.anime_raw);
11 => ("AMV", "Anime Music Video", "AnimeMusicVideo", nyaa.anime_music_video);
}
"Audio" => {
20 => ("Aud", "All Audio", "AllAudio", Gray);
21 => ("Aud", "Lossless", "AudioLossless", Red);
22 => ("Aud", "Lossy", "AudioLossy", Yellow);
20 => ("Aud", "All Audio", "AllAudio", fg);
21 => ("Aud", "Lossless", "AudioLossless", nyaa.audio_lossless);
22 => ("Aud", "Lossy", "AudioLossy", nyaa.audio_lossy);
}
"Literature" => {
30 => ("Lit", "All Literature", "AllLiterature", Gray);
31 => ("Lit", "English Translated", "LitEnglishTranslated", LightGreen);
32 => ("Lit", "Non-English Translated", "LitNonEnglishTranslated", Yellow);
33 => ("Lit", "Raw", "LitRaw", Gray);
30 => ("Lit", "All Literature", "AllLiterature", fg);
31 => ("Lit", "English Translated", "LitEnglishTranslated", nyaa.literature_english_translated);
32 => ("Lit", "Non-English Translated", "LitNonEnglishTranslated", nyaa.literature_non_english_translated);
33 => ("Lit", "Raw", "LitRaw", nyaa.literature_raw);
}
"Live Action" => {
40 => ("Liv", "All Live Action", "AllLiveAction", Gray);
41 => ("Liv", "English Translated", "LiveEnglishTranslated", Yellow);
43 => ("Liv", "Non-English Translated", "LiveNonEnglishTranslated", LightCyan);
42 => ("Liv", "Idol/Promo Video", "LiveIdolPromoVideo", LightYellow);
44 => ("Liv", "Raw", "LiveRaw", Gray);
40 => ("Liv", "All Live Action", "AllLiveAction", fg);
41 => ("Liv", "English Translated", "LiveEnglishTranslated", nyaa.live_english_translated);
43 => ("Liv", "Non-English Translated", "LiveNonEnglishTranslated", nyaa.live_non_english_translated);
42 => ("Liv", "Idol/Promo Video", "LiveIdolPromoVideo", nyaa.live_idol_promo_video);
44 => ("Liv", "Raw", "LiveRaw", nyaa.live_raw);
}
"Pictures" => {
50 => ("Pic", "All Pictures", "AllPictures", Gray);
51 => ("Pic", "Graphics", "PicGraphics", LightMagenta);
52 => ("Pic", "Photos", "PicPhotos", Magenta);
50 => ("Pic", "All Pictures", "AllPictures", fg);
51 => ("Pic", "Graphics", "PicGraphics", nyaa.picture_graphics);
52 => ("Pic", "Photos", "PicPhotos", nyaa.picture_photos);
}
"Software" => {
60 => ("Sof", "All Software", "AllSoftware", Gray);
61 => ("Sof", "Applications", "SoftApplications", Blue);
62 => ("Sof", "Games", "SoftGames", LightBlue);
60 => ("Sof", "All Software", "AllSoftware", fg);
61 => ("Sof", "Applications", "SoftApplications", nyaa.software_applications);
62 => ("Sof", "Games", "SoftGames", nyaa.software_games);
}
};
SourceInfo {
Expand Down Expand Up @@ -475,6 +539,6 @@ impl Source for NyaaHtmlSource {
theme: &Theme,
) -> ResultTable {
let nyaa = config.nyaa.to_owned().unwrap_or_default();
nyaa_table(items, theme, &search.sort, &nyaa.columns)
nyaa_table(items.into(), theme, &search.sort, &nyaa.columns)
}
}
57 changes: 46 additions & 11 deletions src/source/sukebei_nyaa.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::{error::Error, time::Duration};

use chrono::{DateTime, Local, NaiveDateTime, TimeZone};
use ratatui::style::Color;
use reqwest::{StatusCode, Url};
use scraper::{Html, Selector};
use serde::{Deserialize, Serialize};
Expand All @@ -25,6 +26,40 @@ use super::{
nyaa_rss, Item, ItemType, ResultTable, Source, SourceConfig, SourceInfo, SourceResponse,
};

#[derive(Serialize, Deserialize, Clone, Copy)]
#[serde(default)]
pub struct SukebeiTheme {
#[serde(with = "color_to_tui")]
pub art_anime: Color,
#[serde(with = "color_to_tui")]
pub art_doujinshi: Color,
#[serde(with = "color_to_tui")]
pub art_games: Color,
#[serde(with = "color_to_tui")]
pub art_manga: Color,
#[serde(with = "color_to_tui")]
pub art_pictures: Color,
#[serde(with = "color_to_tui")]
pub real_photos: Color,
#[serde(with = "color_to_tui")]
pub real_videos: Color,
}

impl Default for SukebeiTheme {
fn default() -> Self {
use Color::*;
Self {
art_anime: Magenta,
art_doujinshi: LightMagenta,
art_games: Green,
art_manga: LightGreen,
art_pictures: Gray,
real_photos: Red,
real_videos: Yellow,
}
}
}

#[derive(Serialize, Deserialize, Clone)]
#[serde(default)]
pub struct SukebeiNyaaConfig {
Expand Down Expand Up @@ -259,20 +294,20 @@ impl Source for SukebeiHtmlSource {
fn info() -> SourceInfo {
let cats = cats! {
"All Categories" => {
0 => ("---", "All Categories", "AllCategories", White);
0 => ("---", "All Categories", "AllCategories", fg);
}
"Art" => {
10 => ("Art", "All Art", "AllArt", Gray);
11 => ("Ani", "Anime", "ArtAnime", Magenta);
12 => ("Dou", "Doujinshi", "ArtDoujinshi", LightMagenta);
13 => ("Gam", "Games", "ArtGames", LightMagenta);
14 => ("Man", "Manga", "ArtManga", LightGreen);
15 => ("Pic", "Pictures", "ArtPictures", Gray);
10 => ("Art", "All Art", "AllArt", fg);
11 => ("Ani", "Anime", "ArtAnime", sukebei.art_anime);
12 => ("Dou", "Doujinshi", "ArtDoujinshi", sukebei.art_doujinshi);
13 => ("Gam", "Games", "ArtGames", sukebei.art_games);
14 => ("Man", "Manga", "ArtManga", sukebei.art_manga);
15 => ("Pic", "Pictures", "ArtPictures", sukebei.art_pictures);
}
"Real Life" => {
20 => ("Rea", "All Real Life", "AllReal", Gray);
21 => ("Pho", "Photobooks and Pictures", "RealPhotos", Red);
22 => ("Vid", "Videos", "RealVideos", Yellow);
20 => ("Rea", "All Real Life", "AllReal", fg);
21 => ("Pho", "Photobooks and Pictures", "RealPhotos", sukebei.real_photos);
22 => ("Vid", "Videos", "RealVideos", sukebei.real_videos);
}
};
SourceInfo {
Expand Down Expand Up @@ -325,6 +360,6 @@ impl Source for SukebeiHtmlSource {
theme: &Theme,
) -> ResultTable {
let sukebei = config.sukebei.to_owned().unwrap_or_default();
nyaa_table(items, theme, &search.sort, &sukebei.columns)
nyaa_table(items.into(), theme, &search.sort, &sukebei.columns)
}
}
Loading

0 comments on commit efcb24c

Please sign in to comment.