Properly sync associated items of recordings and works

This commit is contained in:
Elias Projahn 2020-11-29 01:29:03 +01:00
parent bec0dfbf56
commit 37f21c582d
7 changed files with 103 additions and 89 deletions

View file

@ -115,6 +115,34 @@ impl Database {
let recording_id = &recording.id;
self.delete_recording(recording_id)?;
// Add associated items from the server, if they don't already exist.
if self.get_work(&recording.work.id)?.is_none() {
self.update_work(recording.work.clone())?;
}
for performance in &recording.performances {
if let Some(person) = &performance.person {
if self.get_person(&person.id)?.is_none() {
self.update_person(person.clone())?;
}
}
if let Some(ensemble) = &performance.ensemble {
if self.get_ensemble(&ensemble.id)?.is_none() {
self.update_ensemble(ensemble.clone())?;
}
}
if let Some(role) = &performance.role {
if self.get_instrument(&role.id)?.is_none() {
self.update_instrument(role.clone())?;
}
}
}
// Add the actual recording.
let row: RecordingRow = recording.clone().into();
diesel::insert_into(recordings::table)
.values(row)

View file

@ -100,6 +100,28 @@ impl Database {
let work_id = &work.id;
self.delete_work(work_id)?;
// Add associated items from the server, if they don't already exist.
if self.get_person(&work.composer.id)?.is_none() {
self.update_person(work.composer.clone())?;
}
for instrument in &work.instruments {
if self.get_instrument(&instrument.id)?.is_none() {
self.update_instrument(instrument.clone())?;
}
}
for part in &work.parts {
if let Some(person) = &part.composer {
if self.get_person(&person.id)?.is_none() {
self.update_person(person.clone())?;
}
}
}
// Add the actual work.
let row: WorkRow = work.clone().into();
diesel::insert_into(works::table)
.values(row)

View file

@ -89,7 +89,6 @@ sources = files(
'widgets/list.rs',
'widgets/mod.rs',
'widgets/navigator.rs',
'widgets/person_list.rs',
'widgets/player_bar.rs',
'widgets/poe_list.rs',
'widgets/selector_row.rs',

View file

@ -4,9 +4,6 @@ pub use list::*;
pub mod navigator;
pub use navigator::*;
pub mod person_list;
pub use person_list::*;
pub mod player_bar;
pub use player_bar::*;

View file

@ -1,82 +0,0 @@
use super::*;
use crate::backend::Backend;
use crate::database::*;
use gettextrs::gettext;
use glib::clone;
use gtk::prelude::*;
use gtk_macros::get_widget;
use std::rc::Rc;
pub struct PersonList {
pub widget: gtk::Box,
list: Rc<List<Person>>,
backend: Rc<Backend>,
stack: gtk::Stack,
}
impl PersonList {
pub fn new(backend: Rc<Backend>) -> Rc<Self> {
let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/person_list.ui");
get_widget!(builder, gtk::Box, widget);
get_widget!(builder, gtk::SearchEntry, search_entry);
get_widget!(builder, gtk::Stack, stack);
get_widget!(builder, gtk::ScrolledWindow, scrolled_window);
let list = List::new(&gettext("No persons found."));
list.set_make_widget(|person: &Person| {
let label = gtk::Label::new(Some(&person.name_lf()));
label.set_halign(gtk::Align::Start);
label.set_margin_start(6);
label.set_margin_end(6);
label.set_margin_top(6);
label.set_margin_bottom(6);
label.upcast()
});
list.set_filter(clone!(@strong search_entry => move |person: &Person| {
let search = search_entry.get_text().to_string().to_lowercase();
let name = person.name_fl().to_lowercase();
search.is_empty() || name.contains(&search)
}));
scrolled_window.add(&list.widget);
let result = Rc::new(Self {
widget,
list,
backend,
stack,
});
search_entry.connect_search_changed(clone!(@strong result => move |_| {
result.list.invalidate_filter();
}));
result.clone().reload();
result
}
pub fn set_selected<S>(&self, selected: S)
where
S: Fn(&Person) -> () + 'static,
{
self.list.set_selected(selected);
}
pub fn reload(self: Rc<Self>) {
self.stack.set_visible_child_name("loading");
let context = glib::MainContext::default();
let backend = self.backend.clone();
let list = self.list.clone();
context.spawn_local(async move {
let persons = backend.db().get_persons().await.unwrap();
list.show_items(persons);
self.stack.set_visible_child_name("content");
});
}
}