diff --git a/res/ui/window.ui b/res/ui/window.ui
index 6423fe1..2985cd4 100644
--- a/res/ui/window.ui
+++ b/res/ui/window.ui
@@ -473,7 +473,6 @@
in
diff --git a/src/backend.rs b/src/backend.rs
index 3835b31..5e90d26 100644
--- a/src/backend.rs
+++ b/src/backend.rs
@@ -17,6 +17,7 @@ enum BackendAction {
DeleteEnsemble(i64, Sender>),
GetEnsembles(Sender>),
UpdateRecording(RecordingInsertion, Sender>),
+ GetRecordingsForPerson(i64, Sender>),
}
use BackendAction::*;
@@ -126,6 +127,12 @@ impl Backend {
.send(Ok(()))
.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))
.expect("Failed to send action to database thread!");
}
+
+ pub fn get_recordings_for_person) -> () + 'static>(
+ &self,
+ id: i64,
+ callback: F,
+ ) {
+ let (sender, receiver) =
+ glib::MainContext::channel::>(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!");
+ }
}
diff --git a/src/database/database.rs b/src/database/database.rs
index 8ce18e2..caae52d 100644
--- a/src/database/database.rs
+++ b/src/database/database.rs
@@ -315,6 +315,21 @@ impl Database {
}
}
+ pub fn get_recordings_for_person(&self, id: i64) -> Vec {
+ 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::(&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) {
diesel::delete(recordings::table.filter(recordings::id.eq(id)))
.execute(&self.c)
diff --git a/src/database/models.rs b/src/database/models.rs
index e36f27c..09371cd 100644
--- a/src/database/models.rs
+++ b/src/database/models.rs
@@ -135,6 +135,18 @@ pub struct RecordingDescription {
pub performances: Vec,
}
+impl RecordingDescription {
+ pub fn get_performers(&self) -> String {
+ let texts: Vec = self
+ .performances
+ .iter()
+ .map(|performance| performance.get_title())
+ .collect();
+
+ texts.join(", ")
+ }
+}
+
#[derive(Debug, Clone)]
pub struct RecordingInsertion {
pub recording: Recording,
diff --git a/src/window.rs b/src/window.rs
index 7848e50..9dda915 100644
--- a/src/window.rs
+++ b/src/window.rs
@@ -260,7 +260,12 @@ impl Window {
self.backend.get_work_descriptions(
person.id,
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);
}
+ for child in self.recording_list.get_children() {
+ self.recording_list.remove(&child);
+ }
+
if works.is_empty() {
self.work_box.hide();
} else {
@@ -293,6 +302,28 @@ impl Window {
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.stack.set_visible_child_name("person_screen");
self.leaflet.set_visible_child_name("content");