| 
									
										
										
										
											2025-03-01 09:57:01 +01:00
										 |  |  | use std::{cell::RefCell, path::Path};
 | 
					
						
							| 
									
										
										
										
											2023-06-18 14:02:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-16 14:06:57 +01:00
										 |  |  | use adw::{prelude::*, subclass::prelude::*};
 | 
					
						
							| 
									
										
										
										
											2025-03-23 09:59:28 +01:00
										 |  |  | use anyhow::{anyhow, Result};
 | 
					
						
							| 
									
										
										
										
											2025-03-16 14:06:57 +01:00
										 |  |  | use gettextrs::gettext;
 | 
					
						
							|  |  |  | use gtk::{gio, glib, glib::clone};
 | 
					
						
							| 
									
										
										
										
											2025-01-17 09:38:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-01 09:57:01 +01:00
										 |  |  | use crate::{
 | 
					
						
							| 
									
										
										
										
											2025-03-02 08:03:31 +01:00
										 |  |  |     config,
 | 
					
						
							|  |  |  |     editor::tracks::TracksEditor,
 | 
					
						
							| 
									
										
										
										
											2025-03-23 16:04:14 +01:00
										 |  |  |     empty_page::EmptyPage,
 | 
					
						
							| 
									
										
										
										
											2025-03-02 08:03:31 +01:00
										 |  |  |     library::{Library, LibraryQuery},
 | 
					
						
							|  |  |  |     library_manager::LibraryManager,
 | 
					
						
							|  |  |  |     player::Player,
 | 
					
						
							|  |  |  |     player_bar::PlayerBar,
 | 
					
						
							|  |  |  |     playlist_page::PlaylistPage,
 | 
					
						
							| 
									
										
										
										
											2025-03-16 14:06:57 +01:00
										 |  |  |     preferences_dialog::PreferencesDialog,
 | 
					
						
							| 
									
										
										
										
											2025-03-03 11:31:38 +01:00
										 |  |  |     process_manager::ProcessManager,
 | 
					
						
							| 
									
										
										
										
											2025-03-02 08:03:31 +01:00
										 |  |  |     search_page::SearchPage,
 | 
					
						
							| 
									
										
										
										
											2025-03-23 09:59:28 +01:00
										 |  |  |     util,
 | 
					
						
							| 
									
										
										
										
											2025-03-02 08:03:31 +01:00
										 |  |  |     welcome_page::WelcomePage,
 | 
					
						
							| 
									
										
										
										
											2025-03-01 09:57:01 +01:00
										 |  |  | };
 | 
					
						
							| 
									
										
										
										
											2025-01-17 09:38:00 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-18 14:02:21 +02:00
										 |  |  | mod imp {
 | 
					
						
							|  |  |  |     use super::*;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     #[derive(Debug, Default, gtk::CompositeTemplate)]
 | 
					
						
							| 
									
										
										
										
											2023-09-24 13:58:05 +02:00
										 |  |  |     #[template(file = "data/ui/window.blp")]
 | 
					
						
							| 
									
										
										
										
											2025-03-01 09:57:01 +01:00
										 |  |  |     pub struct Window {
 | 
					
						
							|  |  |  |         pub library: RefCell<Option<Library>>,
 | 
					
						
							|  |  |  |         pub player: Player,
 | 
					
						
							| 
									
										
										
										
											2025-03-03 11:31:38 +01:00
										 |  |  |         pub process_manager: ProcessManager,
 | 
					
						
							| 
									
										
										
										
											2023-09-29 21:18:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-09 14:27:50 +01:00
										 |  |  |         #[template_child]
 | 
					
						
							|  |  |  |         pub toast_overlay: TemplateChild<adw::ToastOverlay>,
 | 
					
						
							| 
									
										
										
										
											2023-09-24 11:57:16 +02:00
										 |  |  |         #[template_child]
 | 
					
						
							|  |  |  |         pub stack: TemplateChild<gtk::Stack>,
 | 
					
						
							| 
									
										
										
										
											2023-06-18 14:02:21 +02:00
										 |  |  |         #[template_child]
 | 
					
						
							| 
									
										
										
										
											2023-09-13 14:58:31 +02:00
										 |  |  |         pub navigation_view: TemplateChild<adw::NavigationView>,
 | 
					
						
							| 
									
										
										
										
											2023-09-21 17:19:31 +02:00
										 |  |  |         #[template_child]
 | 
					
						
							|  |  |  |         pub player_bar_revealer: TemplateChild<gtk::Revealer>,
 | 
					
						
							| 
									
										
										
										
											2023-06-18 14:02:21 +02:00
										 |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     #[glib::object_subclass]
 | 
					
						
							| 
									
										
										
										
											2025-03-01 09:57:01 +01:00
										 |  |  |     impl ObjectSubclass for Window {
 | 
					
						
							| 
									
										
										
										
											2023-06-18 14:02:21 +02:00
										 |  |  |         const NAME: &'static str = "MusicusWindow";
 | 
					
						
							| 
									
										
										
										
											2025-03-01 09:57:01 +01:00
										 |  |  |         type Type = super::Window;
 | 
					
						
							| 
									
										
										
										
											2023-06-18 14:02:21 +02:00
										 |  |  |         type ParentType = adw::ApplicationWindow;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         fn class_init(klass: &mut Self::Class) {
 | 
					
						
							| 
									
										
										
										
											2025-03-01 09:57:01 +01:00
										 |  |  |             WelcomePage::static_type();
 | 
					
						
							| 
									
										
										
										
											2023-06-18 14:02:21 +02:00
										 |  |  |             klass.bind_template();
 | 
					
						
							| 
									
										
										
										
											2023-09-15 10:12:36 +02:00
										 |  |  |             klass.bind_template_instance_callbacks();
 | 
					
						
							| 
									
										
										
										
											2023-06-18 14:02:21 +02:00
										 |  |  |         }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
 | 
					
						
							|  |  |  |             obj.init_template();
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-01 09:57:01 +01:00
										 |  |  |     impl ObjectImpl for Window {
 | 
					
						
							| 
									
										
										
										
											2023-09-13 14:58:31 +02:00
										 |  |  |         fn constructed(&self) {
 | 
					
						
							|  |  |  |             self.parent_constructed();
 | 
					
						
							| 
									
										
										
										
											2023-09-21 17:49:25 +02:00
										 |  |  |             self.obj().load_window_state();
 | 
					
						
							| 
									
										
										
										
											2023-09-29 21:18:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-23 14:59:26 +02:00
										 |  |  |             if config::PROFILE == "development" {
 | 
					
						
							|  |  |  |                 self.obj().add_css_class("devel");
 | 
					
						
							|  |  |  |             }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-09 10:00:46 +01:00
										 |  |  |             let obj = self.obj().to_owned();
 | 
					
						
							|  |  |  |             let import_action = gio::ActionEntry::builder("import")
 | 
					
						
							|  |  |  |                 .activate(move |_, _, _| {
 | 
					
						
							|  |  |  |                     if let Some(library) = &*obj.imp().library.borrow() {
 | 
					
						
							|  |  |  |                         let editor = TracksEditor::new(&obj.imp().navigation_view, library, None);
 | 
					
						
							|  |  |  |                         obj.imp().navigation_view.push(&editor);
 | 
					
						
							|  |  |  |                     }
 | 
					
						
							|  |  |  |                 })
 | 
					
						
							|  |  |  |                 .build();
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             let obj = self.obj().to_owned();
 | 
					
						
							| 
									
										
										
										
											2023-11-07 16:21:47 +01:00
										 |  |  |             let library_action = gio::ActionEntry::builder("library")
 | 
					
						
							| 
									
										
										
										
											2025-02-09 10:00:46 +01:00
										 |  |  |                 .activate(move |_, _, _| {
 | 
					
						
							|  |  |  |                     if let Some(library) = &*obj.imp().library.borrow() {
 | 
					
						
							| 
									
										
										
										
											2025-03-03 11:31:38 +01:00
										 |  |  |                         let library_manager = LibraryManager::new(
 | 
					
						
							|  |  |  |                             &obj.imp().navigation_view,
 | 
					
						
							|  |  |  |                             library,
 | 
					
						
							|  |  |  |                             &obj.imp().process_manager,
 | 
					
						
							|  |  |  |                         );
 | 
					
						
							| 
									
										
										
										
											2025-02-09 10:00:46 +01:00
										 |  |  |                         obj.imp().navigation_view.push(&library_manager);
 | 
					
						
							|  |  |  |                     }
 | 
					
						
							| 
									
										
										
										
											2023-11-07 16:21:47 +01:00
										 |  |  |                 })
 | 
					
						
							|  |  |  |                 .build();
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-16 14:06:57 +01:00
										 |  |  |             let obj = self.obj().to_owned();
 | 
					
						
							|  |  |  |             let preferences_action = gio::ActionEntry::builder("preferences")
 | 
					
						
							|  |  |  |                 .activate(move |_, _, _| {
 | 
					
						
							|  |  |  |                     PreferencesDialog::show(&obj);
 | 
					
						
							|  |  |  |                 })
 | 
					
						
							|  |  |  |                 .build();
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-02-09 10:00:46 +01:00
										 |  |  |             self.obj()
 | 
					
						
							| 
									
										
										
										
											2025-03-16 14:06:57 +01:00
										 |  |  |                 .add_action_entries([import_action, library_action, preferences_action]);
 | 
					
						
							| 
									
										
										
										
											2023-11-07 16:21:47 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-27 12:32:40 +02:00
										 |  |  |             let player_bar = PlayerBar::new(&self.player);
 | 
					
						
							|  |  |  |             self.player_bar_revealer.set_child(Some(&player_bar));
 | 
					
						
							| 
									
										
										
										
											2023-10-25 17:45:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-01 09:57:01 +01:00
										 |  |  |             let playlist_page = PlaylistPage::new(&self.player);
 | 
					
						
							| 
									
										
										
										
											2023-10-25 17:45:32 +02:00
										 |  |  |             self.stack.add_named(&playlist_page, Some("playlist"));
 | 
					
						
							| 
									
										
										
										
											2023-10-27 12:32:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-27 14:15:05 +02:00
										 |  |  |             let stack = self.stack.get();
 | 
					
						
							| 
									
										
										
										
											2024-07-18 15:01:30 +02:00
										 |  |  |             playlist_page.connect_close(clone!(
 | 
					
						
							|  |  |  |                 #[weak]
 | 
					
						
							|  |  |  |                 player_bar,
 | 
					
						
							|  |  |  |                 #[weak]
 | 
					
						
							|  |  |  |                 stack,
 | 
					
						
							|  |  |  |                 move |_| {
 | 
					
						
							|  |  |  |                     stack.set_visible_child_name("navigation");
 | 
					
						
							|  |  |  |                     player_bar.playlist_hidden();
 | 
					
						
							|  |  |  |                 }
 | 
					
						
							|  |  |  |             ));
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             player_bar.connect_show_playlist(clone!(
 | 
					
						
							|  |  |  |                 #[weak]
 | 
					
						
							|  |  |  |                 playlist_page,
 | 
					
						
							|  |  |  |                 #[weak]
 | 
					
						
							|  |  |  |                 stack,
 | 
					
						
							|  |  |  |                 move |_, show| {
 | 
					
						
							| 
									
										
										
										
											2023-11-03 18:59:47 +01:00
										 |  |  |                     if show {
 | 
					
						
							|  |  |  |                         playlist_page.scroll_to_current();
 | 
					
						
							|  |  |  |                         stack.set_visible_child_name("playlist");
 | 
					
						
							|  |  |  |                     } else {
 | 
					
						
							|  |  |  |                         stack.set_visible_child_name("navigation");
 | 
					
						
							|  |  |  |                     };
 | 
					
						
							| 
									
										
										
										
											2024-07-18 15:01:30 +02:00
										 |  |  |                 }
 | 
					
						
							|  |  |  |             ));
 | 
					
						
							| 
									
										
										
										
											2023-10-27 12:32:40 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             self.player
 | 
					
						
							|  |  |  |                 .bind_property("active", &self.player_bar_revealer.get(), "reveal-child")
 | 
					
						
							|  |  |  |                 .sync_create()
 | 
					
						
							|  |  |  |                 .build();
 | 
					
						
							| 
									
										
										
										
											2023-11-03 18:59:47 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             let obj = self.obj().to_owned();
 | 
					
						
							|  |  |  |             self.player.connect_raise(move |_| obj.present());
 | 
					
						
							| 
									
										
										
										
											2023-11-03 19:48:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-23 14:59:26 +02:00
										 |  |  |             let settings = gio::Settings::new(config::APP_ID);
 | 
					
						
							| 
									
										
										
										
											2023-11-03 19:48:27 +01:00
										 |  |  |             let library_path = settings.string("library-path").to_string();
 | 
					
						
							|  |  |  |             if !library_path.is_empty() {
 | 
					
						
							| 
									
										
										
										
											2025-03-23 09:59:28 +01:00
										 |  |  |                 if let Err(err) = self.obj().load_library(&library_path) {
 | 
					
						
							|  |  |  |                     util::error_toast("Failed to open music library", err, &self.toast_overlay);
 | 
					
						
							|  |  |  |                 }
 | 
					
						
							| 
									
										
										
										
											2023-11-03 19:48:27 +01:00
										 |  |  |             }
 | 
					
						
							| 
									
										
										
										
											2023-09-13 14:58:31 +02:00
										 |  |  |         }
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-01 09:57:01 +01:00
										 |  |  |     impl WidgetImpl for Window {}
 | 
					
						
							| 
									
										
										
										
											2023-09-21 17:49:25 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-01 09:57:01 +01:00
										 |  |  |     impl WindowImpl for Window {
 | 
					
						
							| 
									
										
										
										
											2023-09-24 14:19:07 +02:00
										 |  |  |         fn close_request(&self) -> glib::signal::Propagation {
 | 
					
						
							| 
									
										
										
										
											2025-03-03 11:31:38 +01:00
										 |  |  |             if self.process_manager.any_ongoing() {
 | 
					
						
							|  |  |  |                 let dialog = adw::AlertDialog::builder()
 | 
					
						
							|  |  |  |                     .heading(&gettext("Close window?"))
 | 
					
						
							|  |  |  |                     .body(&gettext(
 | 
					
						
							|  |  |  |                         "There are ongoing processes that will be canceled.",
 | 
					
						
							|  |  |  |                     ))
 | 
					
						
							|  |  |  |                     .build();
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 dialog.add_responses(&[
 | 
					
						
							|  |  |  |                     ("cancel", &gettext("Keep open")),
 | 
					
						
							|  |  |  |                     ("close", &gettext("Close window")),
 | 
					
						
							|  |  |  |                 ]);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 dialog.set_response_appearance("close", adw::ResponseAppearance::Destructive);
 | 
					
						
							|  |  |  |                 dialog.set_close_response("cancel");
 | 
					
						
							|  |  |  |                 dialog.set_default_response(Some("cancel"));
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 let obj = self.obj().to_owned();
 | 
					
						
							|  |  |  |                 glib::spawn_future_local(async move {
 | 
					
						
							|  |  |  |                     if dialog.choose_future(&obj).await == "close" {
 | 
					
						
							|  |  |  |                         obj.destroy();
 | 
					
						
							|  |  |  |                     }
 | 
					
						
							|  |  |  |                 });
 | 
					
						
							| 
									
										
										
										
											2023-09-21 17:49:25 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-03 11:31:38 +01:00
										 |  |  |                 glib::signal::Propagation::Stop
 | 
					
						
							|  |  |  |             } else {
 | 
					
						
							|  |  |  |                 if let Err(err) = self.obj().save_window_state() {
 | 
					
						
							| 
									
										
										
										
											2025-03-13 18:44:01 +01:00
										 |  |  |                     log::warn!("Failed to save window state: {err:?}");
 | 
					
						
							| 
									
										
										
										
											2025-03-03 11:31:38 +01:00
										 |  |  |                 }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 glib::signal::Propagation::Proceed
 | 
					
						
							|  |  |  |             }
 | 
					
						
							| 
									
										
										
										
											2023-09-21 17:49:25 +02:00
										 |  |  |         }
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-01 09:57:01 +01:00
										 |  |  |     impl ApplicationWindowImpl for Window {}
 | 
					
						
							|  |  |  |     impl AdwApplicationWindowImpl for Window {}
 | 
					
						
							| 
									
										
										
										
											2023-06-18 14:02:21 +02:00
										 |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | glib::wrapper! {
 | 
					
						
							| 
									
										
										
										
											2025-03-01 09:57:01 +01:00
										 |  |  |     pub struct Window(ObjectSubclass<imp::Window>)
 | 
					
						
							| 
									
										
										
										
											2023-09-13 14:58:31 +02:00
										 |  |  |         @extends gtk::Widget, gtk::Window, gtk::ApplicationWindow, adw::ApplicationWindow,
 | 
					
						
							|  |  |  |         @implements gio::ActionGroup, gio::ActionMap;
 | 
					
						
							| 
									
										
										
										
											2023-06-18 14:02:21 +02:00
										 |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-15 10:12:36 +02:00
										 |  |  | #[gtk::template_callbacks]
 | 
					
						
							| 
									
										
										
										
											2025-03-01 09:57:01 +01:00
										 |  |  | impl Window {
 | 
					
						
							| 
									
										
										
										
											2024-04-01 18:47:44 +02:00
										 |  |  |     pub fn new<P: IsA<gtk::Application>>(application: &P) -> Self {
 | 
					
						
							| 
									
										
										
										
											2023-06-18 14:02:21 +02:00
										 |  |  |         glib::Object::builder()
 | 
					
						
							|  |  |  |             .property("application", application)
 | 
					
						
							|  |  |  |             .build()
 | 
					
						
							|  |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2023-09-15 10:12:36 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-21 17:49:25 +02:00
										 |  |  |     pub fn load_window_state(&self) {
 | 
					
						
							| 
									
										
										
										
											2024-06-23 14:59:26 +02:00
										 |  |  |         let settings = gio::Settings::new(config::APP_ID);
 | 
					
						
							| 
									
										
										
										
											2023-09-21 17:49:25 +02:00
										 |  |  |         self.set_default_size(settings.int("window-width"), settings.int("window-height"));
 | 
					
						
							|  |  |  |         self.set_property("maximized", settings.boolean("is-maximized"));
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     pub fn save_window_state(&self) -> Result<(), glib::BoolError> {
 | 
					
						
							| 
									
										
										
										
											2024-06-23 14:59:26 +02:00
										 |  |  |         let settings = gio::Settings::new(config::APP_ID);
 | 
					
						
							| 
									
										
										
										
											2023-09-21 17:49:25 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         let size = self.default_size();
 | 
					
						
							|  |  |  |         settings.set_int("window-width", size.0)?;
 | 
					
						
							|  |  |  |         settings.set_int("window-height", size.1)?;
 | 
					
						
							|  |  |  |         settings.set_boolean("is-maximized", self.is_maximized())?;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Ok(())
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-15 10:12:36 +02:00
										 |  |  |     #[template_callback]
 | 
					
						
							| 
									
										
										
										
											2025-01-17 09:38:00 +01:00
										 |  |  |     pub fn set_library_folder(&self, folder: &gio::File) {
 | 
					
						
							| 
									
										
										
										
											2023-09-30 18:26:11 +02:00
										 |  |  |         let path = folder.path().unwrap();
 | 
					
						
							| 
									
										
										
										
											2023-11-03 19:48:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-23 09:59:28 +01:00
										 |  |  |         match self.load_library(&path) {
 | 
					
						
							|  |  |  |             Ok(_) => {
 | 
					
						
							|  |  |  |                 if let Err(err) = self.save_library_path(path) {
 | 
					
						
							|  |  |  |                     util::error_toast(
 | 
					
						
							|  |  |  |                         "Failed to save library folder",
 | 
					
						
							|  |  |  |                         err,
 | 
					
						
							|  |  |  |                         &self.imp().toast_overlay,
 | 
					
						
							|  |  |  |                     );
 | 
					
						
							|  |  |  |                 }
 | 
					
						
							|  |  |  |             }
 | 
					
						
							|  |  |  |             Err(err) => {
 | 
					
						
							|  |  |  |                 util::error_toast(
 | 
					
						
							|  |  |  |                     "Failed to open music library",
 | 
					
						
							|  |  |  |                     err,
 | 
					
						
							|  |  |  |                     &self.imp().toast_overlay,
 | 
					
						
							|  |  |  |                 );
 | 
					
						
							|  |  |  |             }
 | 
					
						
							|  |  |  |         }
 | 
					
						
							| 
									
										
										
										
											2023-11-03 19:48:27 +01:00
										 |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-23 09:59:28 +01:00
										 |  |  |     fn load_library(&self, path: impl AsRef<Path>) -> Result<()> {
 | 
					
						
							|  |  |  |         let library = Library::new(path)?;
 | 
					
						
							| 
									
										
										
										
											2025-03-02 15:46:23 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         library.connect_changed(clone!(
 | 
					
						
							|  |  |  |             #[weak(rename_to = obj)]
 | 
					
						
							|  |  |  |             self,
 | 
					
						
							|  |  |  |             move |_| obj.reset_view()
 | 
					
						
							|  |  |  |         ));
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-10 16:57:36 +02:00
										 |  |  |         self.imp().player.set_library(&library);
 | 
					
						
							| 
									
										
										
										
											2025-03-23 16:04:14 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         let is_empty = library.is_empty()?;
 | 
					
						
							| 
									
										
										
										
											2025-03-02 15:46:23 +01:00
										 |  |  |         self.imp().library.replace(Some(library));
 | 
					
						
							| 
									
										
										
										
											2025-03-23 16:04:14 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if is_empty {
 | 
					
						
							|  |  |  |             let navigation = self.imp().navigation_view.get();
 | 
					
						
							|  |  |  |             let empty_page = EmptyPage::new(
 | 
					
						
							|  |  |  |                 self.imp().library.borrow().as_ref().unwrap(),
 | 
					
						
							|  |  |  |                 &self.imp().process_manager,
 | 
					
						
							|  |  |  |             );
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             empty_page.connect_ready(clone!(
 | 
					
						
							|  |  |  |                 #[weak(rename_to = obj)]
 | 
					
						
							|  |  |  |                 self,
 | 
					
						
							|  |  |  |                 move |_| {
 | 
					
						
							|  |  |  |                     obj.reset_view();
 | 
					
						
							|  |  |  |                 }
 | 
					
						
							|  |  |  |             ));
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             navigation.replace(&[empty_page.into()]);
 | 
					
						
							|  |  |  |         } else {
 | 
					
						
							|  |  |  |             self.reset_view();
 | 
					
						
							|  |  |  |         }
 | 
					
						
							| 
									
										
										
										
											2025-03-23 09:59:28 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         Ok(())
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     fn save_library_path(&self, path: impl AsRef<Path>) -> Result<()> {
 | 
					
						
							|  |  |  |         let settings = gio::Settings::new(config::APP_ID);
 | 
					
						
							|  |  |  |         settings.set_string(
 | 
					
						
							|  |  |  |             "library-path",
 | 
					
						
							|  |  |  |             path.as_ref()
 | 
					
						
							|  |  |  |                 .to_str()
 | 
					
						
							|  |  |  |                 .ok_or_else(|| anyhow!("Failed to convert path to string"))?,
 | 
					
						
							|  |  |  |         )?;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Ok(())
 | 
					
						
							| 
									
										
										
										
											2025-03-02 15:46:23 +01:00
										 |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2023-11-07 16:21:47 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-02 15:46:23 +01:00
										 |  |  |     fn reset_view(&self) {
 | 
					
						
							| 
									
										
										
										
											2024-06-05 19:03:04 +02:00
										 |  |  |         let navigation = self.imp().navigation_view.get();
 | 
					
						
							| 
									
										
										
										
											2025-03-02 08:03:31 +01:00
										 |  |  |         navigation.replace(&[SearchPage::new(
 | 
					
						
							| 
									
										
										
										
											2025-03-09 14:27:50 +01:00
										 |  |  |             &self.imp().toast_overlay,
 | 
					
						
							| 
									
										
										
										
											2025-03-02 08:03:31 +01:00
										 |  |  |             &navigation,
 | 
					
						
							| 
									
										
										
										
											2025-03-02 15:46:23 +01:00
										 |  |  |             self.imp().library.borrow().as_ref().unwrap(),
 | 
					
						
							| 
									
										
										
										
											2025-03-02 08:03:31 +01:00
										 |  |  |             &self.imp().player,
 | 
					
						
							|  |  |  |             LibraryQuery::default(),
 | 
					
						
							|  |  |  |         )
 | 
					
						
							|  |  |  |         .into()]);
 | 
					
						
							| 
									
										
										
										
											2023-09-15 10:12:36 +02:00
										 |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2023-06-18 14:02:21 +02:00
										 |  |  | }
 |