Files
Curator/src/ui/dialogs/libraries.rs
T

177 lines
6.9 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! The library organizer (name + kind of each top-level pool folder) and the
//! choice of libraries feeding miniDLNA generation.
use std::collections::HashSet;
use std::fs;
use super::{DialogState, Env, Event, modal, ok_cancel_row};
use crate::core::file_manager::{FileManager, Library, LibraryKind};
use crate::ui::common::{GREY, RED};
pub struct LibraryOrganizerDialog {
rows: Vec<(String, LibraryKind)>,
selected: Option<usize>,
}
impl LibraryOrganizerDialog {
pub fn new(fm: &FileManager) -> Self {
Self {
rows: fm
.libraries()
.into_iter()
.map(|l| (l.name, l.kind))
.collect(),
selected: None,
}
}
pub fn show(&mut self, ctx: &egui::Context, env: &mut Env) -> DialogState {
let mut ok = None;
let (_, close) = modal(ctx, "libraries", "Knihovny poolu", 560.0, |ui| {
ui.label("Knihovny = složky v kořeni poolu, každá je jedna knihovna v Jellyfinu.\nTyp určuje, jak Curator složku zpracuje.");
ui.add_space(6.0);
egui::Grid::new("lib_rows")
.striped(true)
.num_columns(3)
.show(ui, |ui| {
ui.strong("");
ui.strong("Název složky");
ui.strong("Typ");
ui.end_row();
for (i, (name, kind)) in self.rows.iter_mut().enumerate() {
ui.radio_value(&mut self.selected, Some(i), "");
crate::ui::common::sized(ui, 240.0, egui::TextEdit::singleline(name));
egui::ComboBox::from_id_salt(("kind", i))
.selected_text(kind.label())
.show_ui(ui, |ui| {
for k in LibraryKind::ALL {
ui.selectable_value(kind, k, k.label());
}
});
ui.end_row();
}
});
ui.horizontal(|ui| {
if ui.button("➕ Přidat knihovnu").clicked() {
self.rows.push((String::new(), LibraryKind::Movie));
}
if ui.button("➖ Odebrat").clicked()
&& let Some(i) = self.selected.take().filter(|i| *i < self.rows.len())
{
self.rows.remove(i);
}
});
ui.add(egui::Label::new(egui::RichText::new(
"Pozn.: „Mix“ zpracuje filmy (v kořeni) i seriály (v podsložkách); „Domácí videa“ se do miniDLNA zrcadlí celé. Po uložení nabídnu smazání prázdných složek, které už nejsou knihovnou (s obsahem nechám být).",
).color(GREY)).wrap());
ok = ok_cancel_row(ui);
});
match ok {
Some(true) => {
let specs: Vec<Library> = self
.rows
.iter()
.filter(|(n, _)| !n.trim().is_empty())
.map(|(n, k)| Library::new(n.trim(), *k))
.collect();
if let Err(e) = env.fm.set_libraries(specs) {
env.warn("Knihovny", e.to_string());
return DialogState::Open;
}
if let Some(pool) = env.fm.pool_dir() {
for lib in env.fm.libraries() {
let _ = fs::create_dir_all(pool.join(&lib.name));
}
}
let names: Vec<String> = env
.fm
.libraries()
.iter()
.map(|l| format!("{} ({})", l.name, l.kind.as_str()))
.collect();
env.events
.push(Event::Status(format!("Knihovny: {}", names.join(", "))));
env.events.push(Event::LibrariesChanged);
DialogState::Closed
}
Some(false) => DialogState::Closed,
None if close => DialogState::Closed,
None => DialogState::Open,
}
}
}
pub struct MinidlnaLibrariesDialog {
rows: Vec<(String, LibraryKind, bool)>,
}
impl MinidlnaLibrariesDialog {
pub fn new(fm: &FileManager) -> Self {
let chosen: Option<HashSet<String>> =
fm.minidlna_libraries().map(|v| v.into_iter().collect());
Self {
rows: fm
.libraries()
.into_iter()
.map(|l| {
let on = chosen.as_ref().is_none_or(|c| c.contains(&l.name));
(l.name, l.kind, on)
})
.collect(),
}
}
pub fn show(&mut self, ctx: &egui::Context, env: &mut Env) -> DialogState {
let mut ok = None;
let (_, close) = modal(
ctx,
"minidlna_libs",
"Knihovny pro generování miniDLNA",
440.0,
|ui| {
ui.add(egui::Label::new("Které knihovny se mají promítnout do miniDLNA stromu (žánry, Tipy dne, Nově přidané, zrcadlené seriály)?").wrap());
ui.add(egui::Label::new(egui::RichText::new("⚠ Odškrtnutá knihovna: její odkazy ve stromu se při dalším generování odeberou jako zastaralé, dokud ji znovu nezaškrtneš.").color(RED)).wrap());
ui.add_space(6.0);
for (name, kind, on) in &mut self.rows {
ui.checkbox(on, format!("{name} ({})", kind.as_str()));
}
ui.horizontal(|ui| {
if ui.button("Vše").clicked() {
self.rows.iter_mut().for_each(|r| r.2 = true);
}
if ui.button("Nic").clicked() {
self.rows.iter_mut().for_each(|r| r.2 = false);
}
});
ok = ok_cancel_row(ui);
},
);
match ok {
Some(true) => {
let chosen: Vec<String> = self
.rows
.iter()
.filter(|r| r.2)
.map(|r| r.0.clone())
.collect();
let all = chosen.len() == self.rows.len();
if let Err(e) =
env.fm
.set_minidlna_libraries(if all { None } else { Some(chosen.clone()) })
{
env.warn("miniDLNA", e.to_string());
}
env.events.push(Event::Status(format!(
"miniDLNA: {}/{} knihoven vybráno pro generování.",
chosen.len(),
self.rows.len()
)));
DialogState::Closed
}
Some(false) => DialogState::Closed,
None if close => DialogState::Closed,
None => DialogState::Open,
}
}
}