diff --git a/src/sheet.rs b/src/sheet.rs index be62852..1dade35 100644 --- a/src/sheet.rs +++ b/src/sheet.rs @@ -75,8 +75,8 @@ impl SheetKindDiscriminants { #[derive(sqlx::FromRow)] pub struct Composer { - id: i64, - name: String, + pub id: i64, + pub name: String, } #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] diff --git a/src/sheet_dao.rs b/src/sheet_dao.rs index a771cd3..3347fa3 100644 --- a/src/sheet_dao.rs +++ b/src/sheet_dao.rs @@ -1,6 +1,6 @@ use crate::{ database::Database, - sheet::{I64DateTime, Pdf, Sheet, SheetKind, SheetKindDiscriminants}, + sheet::{Composer, I64DateTime, Pdf, Sheet, SheetKind, SheetKindDiscriminants}, }; use sqlx::{sqlite::SqliteRow, Row}; use std::path::{Path, PathBuf}; @@ -71,6 +71,16 @@ pub async fn update_sheet_last_opened(database: &Database, sheet: &Sheet) -> sql .map(|_| ()) } +pub async fn get_composer_by_id(database: &Database, id: i64) -> sqlx::Result { + sqlx::query(&format!("SELECT * FROM {} WHERE id = {}", "composers", id)) + .map(|row: SqliteRow| Composer { + id, + name: row.try_get("name").unwrap(), + }) + .fetch_one(&database.connection) + .await +} + pub async fn fetch_all_sheets(database: &Database) -> sqlx::Result> { let mut sheets: Vec = Vec::new(); diff --git a/src/ui/app.rs b/src/ui/app.rs index 6344a24..8f0f1d0 100644 --- a/src/ui/app.rs +++ b/src/ui/app.rs @@ -3,7 +3,7 @@ use std::{path::PathBuf, sync::Arc}; use chrono::Utc; use gtk::prelude::*; use relm4::{ - component::{AsyncComponent, AsyncComponentParts}, + component::{AsyncComponent, AsyncComponentParts, AsyncController}, gtk::Adjustment, prelude::*, AsyncComponentSender, @@ -18,7 +18,7 @@ use crate::{ use super::{ mcdu::McduModel, - sheet_edit_dialog::{SheetEditDialogInput, SheetEditDialogModel}, + sheet_edit_dialog::{SheetEditDialogInit, SheetEditDialogInput, SheetEditDialogModel}, sheet_listing::{SheetListingInput, SheetListingModel, SheetListingOutput}, }; @@ -29,7 +29,7 @@ pub struct AppModel { sheets_listing: Controller, edit_mode: bool, scroll_adjustment: Adjustment, - sheet_edit_dialog: Option>, + sheet_edit_dialog: Option>, } #[derive(Debug)] @@ -163,7 +163,10 @@ impl AsyncComponent for AppModel { self.sheet_edit_dialog = Some( SheetEditDialogModel::builder() .transient_for(&root) - .launch(sheet) + .launch(SheetEditDialogInit { + sheet, + database: Arc::clone(&self.database), + }) .forward(sender.input_sender(), |_| todo!()), ); } else { diff --git a/src/ui/sheet_edit_dialog.rs b/src/ui/sheet_edit_dialog.rs index d221200..6fc5bac 100644 --- a/src/ui/sheet_edit_dialog.rs +++ b/src/ui/sheet_edit_dialog.rs @@ -1,11 +1,16 @@ -use std::borrow::BorrowMut; +use std::{borrow::BorrowMut, sync::Arc}; use gtk::prelude::*; -use relm4::prelude::*; +use relm4::{ + component::{AsyncComponent, AsyncComponentParts}, + prelude::*, + AsyncComponentSender, +}; -use crate::sheet::Sheet; +use crate::{database::Database, sheet::Sheet, sheet_dao}; pub struct SheetEditDialogModel { + database: Arc, hidden: bool, sheet: Option, sheet_name: String, @@ -14,6 +19,11 @@ pub struct SheetEditDialogModel { book_sheets: Vec<(String, String, i64)>, } +pub struct SheetEditDialogInit { + pub database: Arc, + pub sheet: Sheet, +} + #[derive(Debug)] pub enum SheetEditDialogInput { Accept, @@ -25,11 +35,12 @@ pub enum SheetEditDialogOutput { SheetEdited(Sheet), } -#[relm4::component(pub)] -impl SimpleComponent for SheetEditDialogModel { - type Init = Sheet; +#[relm4::component(pub, async)] +impl AsyncComponent for SheetEditDialogModel { + type Init = SheetEditDialogInit; type Input = SheetEditDialogInput; type Output = SheetEditDialogOutput; + type CommandOutput = (); view! { gtk::Window { @@ -54,6 +65,13 @@ impl SimpleComponent for SheetEditDialogModel { #[watch] set_text : &model.sheet_composer, }, + gtk::Label { + set_text: "Book" + }, + gtk::CheckButton { + #[watch] + set_active: model.is_book, + }, gtk::Box { set_orientation: gtk::Orientation::Horizontal, set_margin_top:5, @@ -70,20 +88,26 @@ impl SimpleComponent for SheetEditDialogModel { } } - fn init( + async fn init( params: Self::Init, - root: &Self::Root, - sender: ComponentSender, - ) -> ComponentParts { - let sheet = params; + root: Self::Root, + sender: AsyncComponentSender, + ) -> AsyncComponentParts { + let sheet = params.sheet; let mut sheet_name = String::new(); let mut sheet_composer = String::new(); let mut is_book = false; match &sheet.kind { - crate::sheet::SheetKind::Sheet { name, .. } => { + crate::sheet::SheetKind::Sheet { + name, composer_id, .. + } => { sheet_name = name.to_string(); - // sheet_composer = composer_id.to_string(); + if let Ok(composer) = + sheet_dao::get_composer_by_id(¶ms.database, *composer_id).await + { + sheet_composer = composer.name; + } } crate::sheet::SheetKind::Orphan => { sheet_name = sheet.pdf.get_name().to_string(); @@ -92,10 +116,20 @@ impl SimpleComponent for SheetEditDialogModel { name, composer_id, sheet_ids, - } => todo!("Cannot yet handle books!"), + } => { + is_book = true; + sheet_name = name.to_string(); + if let Ok(composer) = + sheet_dao::get_composer_by_id(¶ms.database, *composer_id).await + { + sheet_composer = composer.name; + } + // TODO: load sheets of book + } }; let model = SheetEditDialogModel { + database: params.database, hidden: false, sheet: Some(sheet), sheet_name, @@ -105,10 +139,17 @@ impl SimpleComponent for SheetEditDialogModel { }; let widgets = view_output!(); - ComponentParts { model, widgets } + AsyncComponentParts { model, widgets } } - fn update(&mut self, msg: Self::Input, sender: ComponentSender) { + // TODO: init_loading_widgets + + async fn update( + &mut self, + msg: Self::Input, + sender: AsyncComponentSender, + _root: &Self::Root, + ) { match msg { SheetEditDialogInput::Accept => { self.hidden = true;