Show recordings in main window

This commit is contained in:
Elias Projahn 2020-10-10 00:22:45 +02:00
parent 5a95db69fe
commit baea690ae6
5 changed files with 84 additions and 2 deletions

View file

@ -473,7 +473,6 @@
<property name="shadow-type">in</property> <property name="shadow-type">in</property>
<child> <child>
<object class="GtkListBox" id="recording_list"> <object class="GtkListBox" id="recording_list">
<property name="height-request">200</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
</object> </object>

View file

@ -17,6 +17,7 @@ enum BackendAction {
DeleteEnsemble(i64, Sender<Result<(), String>>), DeleteEnsemble(i64, Sender<Result<(), String>>),
GetEnsembles(Sender<Vec<Ensemble>>), GetEnsembles(Sender<Vec<Ensemble>>),
UpdateRecording(RecordingInsertion, Sender<Result<(), String>>), UpdateRecording(RecordingInsertion, Sender<Result<(), String>>),
GetRecordingsForPerson(i64, Sender<Vec<RecordingDescription>>),
} }
use BackendAction::*; use BackendAction::*;
@ -126,6 +127,12 @@ impl Backend {
.send(Ok(())) .send(Ok(()))
.expect("Failed to send result from database thread!"); .expect("Failed to send result from database thread!");
} }
GetRecordingsForPerson(id, sender) => {
let recordings = db.get_recordings_for_person(id);
sender
.send(recordings)
.expect("Failed to send result from database thread!");
}
} }
} }
}); });
@ -371,4 +378,22 @@ impl Backend {
.send(UpdateRecording(recording, sender)) .send(UpdateRecording(recording, sender))
.expect("Failed to send action to database thread!"); .expect("Failed to send action to database thread!");
} }
pub fn get_recordings_for_person<F: Fn(Vec<RecordingDescription>) -> () + 'static>(
&self,
id: i64,
callback: F,
) {
let (sender, receiver) =
glib::MainContext::channel::<Vec<RecordingDescription>>(glib::PRIORITY_DEFAULT);
receiver.attach(None, move |result| {
callback(result);
glib::Continue(true)
});
self.action_sender
.send(GetRecordingsForPerson(id, sender))
.expect("Failed to send action to database thread!");
}
} }

View file

@ -315,6 +315,21 @@ impl Database {
} }
} }
pub fn get_recordings_for_person(&self, id: i64) -> Vec<RecordingDescription> {
let recordings = recordings::table
.inner_join(performances::table.on(performances::recording.eq(recordings::id)))
.inner_join(persons::table.on(persons::id.nullable().eq(performances::person)))
.filter(persons::id.eq(id))
.select(recordings::table::all_columns())
.load::<Recording>(&self.c)
.expect("Error loading recordings for person!");
recordings
.iter()
.map(|recording| self.get_recording_description_for_recording(recording.clone()))
.collect()
}
pub fn delete_recording(&self, id: i64) { pub fn delete_recording(&self, id: i64) {
diesel::delete(recordings::table.filter(recordings::id.eq(id))) diesel::delete(recordings::table.filter(recordings::id.eq(id)))
.execute(&self.c) .execute(&self.c)

View file

@ -135,6 +135,18 @@ pub struct RecordingDescription {
pub performances: Vec<PerformanceDescription>, pub performances: Vec<PerformanceDescription>,
} }
impl RecordingDescription {
pub fn get_performers(&self) -> String {
let texts: Vec<String> = self
.performances
.iter()
.map(|performance| performance.get_title())
.collect();
texts.join(", ")
}
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct RecordingInsertion { pub struct RecordingInsertion {
pub recording: Recording, pub recording: Recording,

View file

@ -260,7 +260,12 @@ impl Window {
self.backend.get_work_descriptions( self.backend.get_work_descriptions(
person.id, person.id,
clone!(@strong self as self_ => move |works| { clone!(@strong self as self_ => move |works| {
self_.clone().set_state(Person(works, Vec::new())); self_.backend.get_recordings_for_person(
person.id,
clone!(@strong self_ => move |recordings| {
self_.clone().set_state(Person(works.clone(), recordings));
}),
);
}), }),
); );
@ -273,6 +278,10 @@ impl Window {
self.work_list.remove(&child); self.work_list.remove(&child);
} }
for child in self.recording_list.get_children() {
self.recording_list.remove(&child);
}
if works.is_empty() { if works.is_empty() {
self.work_box.hide(); self.work_box.hide();
} else { } else {
@ -293,6 +302,28 @@ impl Window {
self.recording_box.show(); self.recording_box.show();
} }
for (index, recording) in recordings.iter().enumerate() {
let work_label = gtk::Label::new(Some(&format!(
"{}: {}",
recording.work.composer.name_fl(),
recording.work.title
)));
work_label.set_halign(gtk::Align::Start);
let performers_label = gtk::Label::new(Some(&recording.get_performers()));
performers_label.set_opacity(0.5);
performers_label.set_halign(gtk::Align::Start);
let vbox = gtk::Box::new(gtk::Orientation::Vertical, 0);
vbox.add(&work_label);
vbox.add(&performers_label);
let row = SelectorRow::new(index.try_into().unwrap(), &vbox);
row.show_all();
self.recording_list.insert(&row, -1);
}
self.content_stack.set_visible_child_name("content"); self.content_stack.set_visible_child_name("content");
self.stack.set_visible_child_name("person_screen"); self.stack.set_visible_child_name("person_screen");
self.leaflet.set_visible_child_name("content"); self.leaflet.set_visible_child_name("content");