mirror of
https://github.com/johrpan/musicus.git
synced 2025-10-26 11:47:25 +01:00
Handle import errors
This commit is contained in:
parent
aa2fb7ec08
commit
f92a80be87
2 changed files with 167 additions and 73 deletions
|
|
@ -2,95 +2,174 @@
|
||||||
<interface>
|
<interface>
|
||||||
<requires lib="gtk" version="4.0"/>
|
<requires lib="gtk" version="4.0"/>
|
||||||
<requires lib="libadwaita" version="1.0"/>
|
<requires lib="libadwaita" version="1.0"/>
|
||||||
<object class="GtkBox" id="widget">
|
<object class="GtkStack" id="widget">
|
||||||
<property name="orientation">vertical</property>
|
<property name="transition-type">crossfade</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="AdwHeaderBar">
|
<object class="GtkStackPage">
|
||||||
<property name="show-start-title-buttons">false</property>
|
<property name="name">content</property>
|
||||||
<property name="show-end-title-buttons">false</property>
|
<property name="child">
|
||||||
<property name="title-widget">
|
<object class="GtkBox">
|
||||||
<object class="AdwWindowTitle" id="window_title">
|
<property name="orientation">vertical</property>
|
||||||
<property name="title" translatable="yes">Preview</property>
|
|
||||||
</object>
|
|
||||||
</property>
|
|
||||||
<child>
|
|
||||||
<object class="GtkButton" id="back_button">
|
|
||||||
<property name="icon-name">go-previous-symbolic</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<child type="end">
|
|
||||||
<object class="GtkButton" id="import_button">
|
|
||||||
<property name="sensitive">False</property>
|
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkStack" id="done_stack">
|
<object class="AdwHeaderBar">
|
||||||
<property name="transition-type">crossfade</property>
|
<property name="show-start-title-buttons">false</property>
|
||||||
<property name="interpolate-size">true</property>
|
<property name="show-end-title-buttons">false</property>
|
||||||
<property name="hhomogeneous">false</property>
|
<property name="title-widget">
|
||||||
|
<object class="AdwWindowTitle" id="window_title">
|
||||||
|
<property name="title" translatable="yes">Preview</property>
|
||||||
|
</object>
|
||||||
|
</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkStackPage">
|
<object class="GtkButton" id="back_button">
|
||||||
<property name="name">loading</property>
|
<property name="icon-name">go-previous-symbolic</property>
|
||||||
<property name="child">
|
|
||||||
<object class="GtkSpinner">
|
|
||||||
<property name="spinning">True</property>
|
|
||||||
</object>
|
|
||||||
</property>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child type="end">
|
||||||
<object class="GtkStackPage">
|
<object class="GtkButton" id="import_button">
|
||||||
<property name="name">ready</property>
|
<property name="sensitive">False</property>
|
||||||
<property name="child">
|
<child>
|
||||||
<object class="GtkLabel">
|
<object class="GtkStack" id="done_stack">
|
||||||
<property name="label" translatable="yes">Import</property>
|
<property name="transition-type">crossfade</property>
|
||||||
|
<property name="interpolate-size">true</property>
|
||||||
|
<property name="hhomogeneous">false</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkStackPage">
|
||||||
|
<property name="name">loading</property>
|
||||||
|
<property name="child">
|
||||||
|
<object class="GtkSpinner">
|
||||||
|
<property name="spinning">True</property>
|
||||||
|
</object>
|
||||||
|
</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkStackPage">
|
||||||
|
<property name="name">ready</property>
|
||||||
|
<property name="child">
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label" translatable="yes">Import</property>
|
||||||
|
</object>
|
||||||
|
</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</property>
|
</child>
|
||||||
|
<style>
|
||||||
|
<class name="suggested-action"/>
|
||||||
|
</style>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child type="end">
|
||||||
|
<object class="GtkButton" id="edit_button">
|
||||||
|
<property name="icon-name">document-edit-symbolic</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkScrolledWindow">
|
||||||
|
<property name="vexpand">True</property>
|
||||||
|
<child>
|
||||||
|
<object class="AdwClamp">
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="margin-start">6</property>
|
||||||
|
<property name="margin-end">6</property>
|
||||||
|
<property name="margin-bottom">6</property>
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="name_label">
|
||||||
|
<property name="halign">start</property>
|
||||||
|
<property name="margin-top">12</property>
|
||||||
|
<property name="margin-bottom">6</property>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="weight" value="bold"/>
|
||||||
|
</attributes>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkBox" id="medium_box">
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<style>
|
|
||||||
<class name="suggested-action"/>
|
|
||||||
</style>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</property>
|
||||||
<child type="end">
|
|
||||||
<object class="GtkButton" id="edit_button">
|
|
||||||
<property name="icon-name">document-edit-symbolic</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkScrolledWindow">
|
<object class="GtkStackPage">
|
||||||
<property name="vexpand">True</property>
|
<property name="name">loading</property>
|
||||||
<child>
|
<property name="child">
|
||||||
<object class="AdwClamp">
|
<object class="GtkBox">
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox">
|
<object class="AdwHeaderBar">
|
||||||
<property name="margin-start">6</property>
|
<property name="show-start-title-buttons">false</property>
|
||||||
<property name="margin-end">6</property>
|
<property name="show-end-title-buttons">false</property>
|
||||||
<property name="margin-bottom">6</property>
|
<property name="title-widget">
|
||||||
<property name="orientation">vertical</property>
|
<object class="AdwWindowTitle">
|
||||||
<child>
|
<property name="title" translatable="true">Loading</property>
|
||||||
<object class="GtkLabel" id="name_label">
|
|
||||||
<property name="halign">start</property>
|
|
||||||
<property name="margin-top">12</property>
|
|
||||||
<property name="margin-bottom">6</property>
|
|
||||||
<attributes>
|
|
||||||
<attribute name="weight" value="bold"/>
|
|
||||||
</attributes>
|
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkSpinner">
|
||||||
|
<property name="hexpand">true</property>
|
||||||
|
<property name="vexpand">true</property>
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="valign">center</property>
|
||||||
|
<property name="width-request">32</property>
|
||||||
|
<property name="height-request">32</property>
|
||||||
|
<property name="spinning">true</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkStackPage">
|
||||||
|
<property name="name">error</property>
|
||||||
|
<property name="child">
|
||||||
|
<object class="GtkBox">
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<child>
|
||||||
|
<object class="AdwHeaderBar">
|
||||||
|
<property name="show-start-title-buttons">false</property>
|
||||||
|
<property name="show-end-title-buttons">false</property>
|
||||||
|
<property name="title-widget">
|
||||||
|
<object class="AdwWindowTitle">
|
||||||
|
<property name="title" translatable="yes">Error</property>
|
||||||
|
</object>
|
||||||
|
</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="AdwStatusPage" id="status_page">
|
||||||
|
<property name="icon-name">dialog-error-symbolic</property>
|
||||||
|
<property name="title">Error</property>
|
||||||
|
<property name="vexpand">true</property>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkBox" id="medium_box">
|
<object class="GtkButton" id="try_again_button">
|
||||||
<property name="orientation">vertical</property>
|
<property name="label" translatable="yes">Try again</property>
|
||||||
|
<property name="hexpand">true</property>
|
||||||
|
<property name="vexpand">true</property>
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="valign">center</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</property>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
</object>
|
</object>
|
||||||
</interface>
|
</interface>
|
||||||
|
|
@ -18,11 +18,12 @@ pub struct MediumPreview {
|
||||||
handle: NavigationHandle<()>,
|
handle: NavigationHandle<()>,
|
||||||
session: Arc<ImportSession>,
|
session: Arc<ImportSession>,
|
||||||
medium: RefCell<Option<Medium>>,
|
medium: RefCell<Option<Medium>>,
|
||||||
widget: gtk::Box,
|
widget: gtk::Stack,
|
||||||
import_button: gtk::Button,
|
import_button: gtk::Button,
|
||||||
done_stack: gtk::Stack,
|
done_stack: gtk::Stack,
|
||||||
name_label: gtk::Label,
|
name_label: gtk::Label,
|
||||||
medium_box: gtk::Box,
|
medium_box: gtk::Box,
|
||||||
|
status_page: libadwaita::StatusPage,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Screen<(Arc<ImportSession>, Medium), ()> for MediumPreview {
|
impl Screen<(Arc<ImportSession>, Medium), ()> for MediumPreview {
|
||||||
|
|
@ -35,13 +36,15 @@ impl Screen<(Arc<ImportSession>, Medium), ()> for MediumPreview {
|
||||||
|
|
||||||
let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/medium_preview.ui");
|
let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/medium_preview.ui");
|
||||||
|
|
||||||
get_widget!(builder, gtk::Box, widget);
|
get_widget!(builder, gtk::Stack, widget);
|
||||||
get_widget!(builder, gtk::Button, back_button);
|
get_widget!(builder, gtk::Button, back_button);
|
||||||
get_widget!(builder, gtk::Button, edit_button);
|
get_widget!(builder, gtk::Button, edit_button);
|
||||||
get_widget!(builder, gtk::Button, import_button);
|
get_widget!(builder, gtk::Button, import_button);
|
||||||
get_widget!(builder, gtk::Stack, done_stack);
|
get_widget!(builder, gtk::Stack, done_stack);
|
||||||
get_widget!(builder, gtk::Box, medium_box);
|
get_widget!(builder, gtk::Box, medium_box);
|
||||||
get_widget!(builder, gtk::Label, name_label);
|
get_widget!(builder, gtk::Label, name_label);
|
||||||
|
get_widget!(builder, libadwaita::StatusPage, status_page);
|
||||||
|
get_widget!(builder, gtk::Button, try_again_button);
|
||||||
|
|
||||||
let this = Rc::new(Self {
|
let this = Rc::new(Self {
|
||||||
handle,
|
handle,
|
||||||
|
|
@ -52,6 +55,7 @@ impl Screen<(Arc<ImportSession>, Medium), ()> for MediumPreview {
|
||||||
done_stack,
|
done_stack,
|
||||||
name_label,
|
name_label,
|
||||||
medium_box,
|
medium_box,
|
||||||
|
status_page,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Connect signals and callbacks
|
// Connect signals and callbacks
|
||||||
|
|
@ -71,12 +75,23 @@ impl Screen<(Arc<ImportSession>, Medium), ()> for MediumPreview {
|
||||||
|
|
||||||
this.import_button
|
this.import_button
|
||||||
.connect_clicked(clone!(@weak this => move |_| {
|
.connect_clicked(clone!(@weak this => move |_| {
|
||||||
|
this.widget.set_visible_child_name("loading");
|
||||||
|
|
||||||
spawn!(@clone this, async move {
|
spawn!(@clone this, async move {
|
||||||
this.import().await.unwrap();
|
match this.import().await {
|
||||||
this.handle.pop(Some(()));
|
Ok(()) => this.handle.pop(Some(())),
|
||||||
|
Err(err) => {
|
||||||
|
this.widget.set_visible_child_name("error");
|
||||||
|
this.status_page.set_description(Some(&err.to_string()));
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
try_again_button.connect_clicked(clone!(@weak this => move |_| {
|
||||||
|
this.widget.set_visible_child_name("content");
|
||||||
|
}));
|
||||||
|
|
||||||
this.set_medium(medium);
|
this.set_medium(medium);
|
||||||
|
|
||||||
this.handle_state(&this.session.state());
|
this.handle_state(&this.session.state());
|
||||||
|
|
@ -200,7 +215,7 @@ impl MediumPreview {
|
||||||
// Create a new directory in the music library path for the imported medium.
|
// Create a new directory in the music library path for the imported medium.
|
||||||
|
|
||||||
let music_library_path = self.handle.backend.get_music_library_path().unwrap();
|
let music_library_path = self.handle.backend.get_music_library_path().unwrap();
|
||||||
|
|
||||||
let directory_name = sanitize_filename::sanitize_with_options(
|
let directory_name = sanitize_filename::sanitize_with_options(
|
||||||
&medium.name,
|
&medium.name,
|
||||||
sanitize_filename::Options {
|
sanitize_filename::Options {
|
||||||
|
|
@ -209,7 +224,7 @@ impl MediumPreview {
|
||||||
replacement: "",
|
replacement: "",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let directory = PathBuf::from(&directory_name);
|
let directory = PathBuf::from(&directory_name);
|
||||||
std::fs::create_dir(&music_library_path.join(&directory))?;
|
std::fs::create_dir(&music_library_path.join(&directory))?;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue