dialog: Make composer be read from database

This commit is contained in:
Julian Mutter 2024-05-26 09:14:39 +02:00
parent ee8a887caa
commit a7db35e8ac
4 changed files with 77 additions and 23 deletions

View File

@ -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)]

View File

@ -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<Composer> {
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<Vec<Sheet>> {
let mut sheets: Vec<Sheet> = Vec::new();

View File

@ -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<SheetListingModel>,
edit_mode: bool,
scroll_adjustment: Adjustment,
sheet_edit_dialog: Option<Controller<SheetEditDialogModel>>,
sheet_edit_dialog: Option<AsyncController<SheetEditDialogModel>>,
}
#[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 {

View File

@ -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<Database>,
hidden: bool,
sheet: Option<Sheet>,
sheet_name: String,
@ -14,6 +19,11 @@ pub struct SheetEditDialogModel {
book_sheets: Vec<(String, String, i64)>,
}
pub struct SheetEditDialogInit {
pub database: Arc<Database>,
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<Self>,
) -> ComponentParts<Self> {
let sheet = params;
root: Self::Root,
sender: AsyncComponentSender<Self>,
) -> AsyncComponentParts<Self> {
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(&params.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(&params.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<Self>) {
// TODO: init_loading_widgets
async fn update(
&mut self,
msg: Self::Input,
sender: AsyncComponentSender<Self>,
_root: &Self::Root,
) {
match msg {
SheetEditDialogInput::Accept => {
self.hidden = true;