Import medium from preview screen

This commit is contained in:
Elias Projahn 2021-04-08 19:56:25 +02:00
parent bd2d7baee0
commit a91eb178c7
3 changed files with 71 additions and 32 deletions

View file

@ -80,7 +80,9 @@ impl ImportScreen {
row.connect_activated(clone!(@weak this => move |_| { row.connect_activated(clone!(@weak this => move |_| {
let medium = medium.clone(); let medium = medium.clone();
spawn!(@clone this, async move { spawn!(@clone this, async move {
push!(this.handle, MediumPreview, (this.session.clone(), medium.clone())).await; if let Some(()) = push!(this.handle, MediumPreview, (this.session.clone(), medium.clone())).await {
this.handle.pop(Some(()));
}
}); });
})); }));
@ -93,7 +95,9 @@ impl ImportScreen {
let this = self; let this = self;
spawn!(@clone this, async move { spawn!(@clone this, async move {
push!(this.handle, MediumPreview, (this.session.clone(), medium)).await; if let Some(()) = push!(this.handle, MediumPreview, (this.session.clone(), medium)).await {
this.handle.pop(Some(()));
}
}); });
} }
} }

View file

@ -131,38 +131,18 @@ impl Screen<Arc<ImportSession>, Medium> for MediumEditor {
} }
impl MediumEditor { impl MediumEditor {
/// Save the medium and possibly upload it to the server. /// Create the medium and, if necessary, upload it to the server.
async fn save(&self) -> Result<Medium> { async fn save(&self) -> Result<Medium> {
let name = self.name_entry.get_text().to_string();
// Create a new directory in the music library path for the imported medium.
let mut path = self.handle.backend.get_music_library_path().unwrap().clone();
path.push(&name);
std::fs::create_dir(&path)?;
// Convert the track set data to real track sets. // Convert the track set data to real track sets.
let mut tracks = Vec::new(); let mut tracks = Vec::new();
let import_tracks = self.session.tracks();
for track_set_data in &*self.track_sets.borrow() { for track_set_data in &*self.track_sets.borrow() {
for track_data in &track_set_data.tracks { for track_data in &track_set_data.tracks {
// Copy the corresponding audio file to the music library.
let import_track = &import_tracks[track_data.track_source];
let mut track_path = path.clone();
track_path.push(import_track.path.file_name().unwrap());
std::fs::copy(&import_track.path, &track_path)?;
// Create the real track.
let track = Track { let track = Track {
recording: track_set_data.recording.clone(), recording: track_set_data.recording.clone(),
work_parts: track_data.work_parts.clone(), work_parts: track_data.work_parts.clone(),
path: track_path.to_str().unwrap().to_owned(), path: String::new(),
}; };
tracks.push(track); tracks.push(track);
@ -181,12 +161,9 @@ impl MediumEditor {
self.handle.backend.cl().post_medium(&medium).await?; self.handle.backend.cl().post_medium(&medium).await?;
} }
self.handle.backend // The medium is not added to the database, because the track paths are not known until the
.db() // medium is actually imported into the music library. This step will be handled by the
.update_medium(medium.clone()) // medium preview dialog.
.await?;
self.handle.backend.library_changed();
Ok(medium) Ok(medium)
} }

View file

@ -1,5 +1,6 @@
use crate::navigator::{NavigationHandle, Screen}; use crate::navigator::{NavigationHandle, Screen};
use crate::widgets::Widget; use crate::widgets::Widget;
use anyhow::Result;
use gettextrs::gettext; use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*; use gtk::prelude::*;
@ -13,6 +14,7 @@ use std::sync::Arc;
pub struct MediumPreview { pub struct MediumPreview {
handle: NavigationHandle<()>, handle: NavigationHandle<()>,
session: Arc<ImportSession>, session: Arc<ImportSession>,
medium: Medium,
widget: gtk::Box, widget: gtk::Box,
import_button: gtk::Button, import_button: gtk::Button,
done_stack: gtk::Stack, done_stack: gtk::Stack,
@ -35,6 +37,7 @@ impl Screen<(Arc<ImportSession>, Medium), ()> for MediumPreview {
let this = Rc::new(Self { let this = Rc::new(Self {
handle, handle,
session, session,
medium,
widget, widget,
import_button, import_button,
done_stack, done_stack,
@ -46,14 +49,21 @@ impl Screen<(Arc<ImportSession>, Medium), ()> for MediumPreview {
this.handle.pop(None); this.handle.pop(None);
})); }));
this.import_button.connect_clicked(clone!(@weak this => move |_| {
spawn!(@clone this, async move {
this.import().await.unwrap();
this.handle.pop(Some(()));
});
}));
// Populate the widget // Populate the widget
name_label.set_text(&medium.name); name_label.set_text(&this.medium.name);
let mut last_recording_id = ""; let mut last_recording_id = "";
let mut last_list = None::<gtk::ListBox>; let mut last_list = None::<gtk::ListBox>;
for track in &medium.tracks { for track in &this.medium.tracks {
if track.recording.id != last_recording_id { if track.recording.id != last_recording_id {
last_recording_id = &track.recording.id; last_recording_id = &track.recording.id;
@ -145,6 +155,54 @@ impl MediumPreview {
State::Error => todo!("Import error!"), State::Error => todo!("Import error!"),
} }
} }
/// Copy the tracks to the music library and add the medium to the database.
async fn import(&self) -> Result<()> {
// Create a new directory in the music library path for the imported medium.
let mut path = self.handle.backend.get_music_library_path().unwrap().clone();
path.push(&self.medium.name);
std::fs::create_dir(&path)?;
// Copy the tracks to the music library.
let mut tracks = Vec::new();
let import_tracks = self.session.tracks();
for (index, track) in self.medium.tracks.iter().enumerate() {
let mut track = track.clone();
// Set the track path to the new audio file location.
let import_track = &import_tracks[index];
let mut track_path = path.clone();
track_path.push(import_track.path.file_name().unwrap());
track.path = track_path.to_str().unwrap().to_owned();
// Copy the corresponding audio file to the music library.
std::fs::copy(&import_track.path, &track_path)?;
tracks.push(track);
}
// Add the modified medium to the database.
let medium = Medium {
id: self.medium.id.clone(),
name: self.medium.name.clone(),
discid: self.medium.discid.clone(),
tracks,
};
self.handle.backend
.db()
.update_medium(medium.clone())
.await?;
self.handle.backend.library_changed();
Ok(())
}
} }
impl Widget for MediumPreview { impl Widget for MediumPreview {