Make relm4 app async and update last_opened in db

This commit is contained in:
2024-02-07 20:05:20 +01:00
parent 603864e7f6
commit bea97b55f3
6 changed files with 88 additions and 30 deletions

View File

@ -59,6 +59,15 @@ impl Database {
.await
.map(|_| ())
}
pub async fn update_sheet_last_opened(&self, sheet: &Sheet) -> sqlx::Result<()> {
sqlx::query("UPDATE sheets SET last_opened = $1 WHERE id = $2")
.bind(sheet.last_opened.timestamp())
.bind(sheet.id)
.execute(&self.connection)
.await
.map(|_| ())
// TODO: check for success
}
pub async fn fetch_all_sheets(&self) -> sqlx::Result<Vec<Sheet>> {
sqlx::query_as::<_, Sheet>("SELECT * FROM sheets")
@ -82,15 +91,25 @@ impl Database {
.map(|result| result.last_insert_rowid())
}
pub async fn update_orphan_file_path(&self, file: &OrphanFile) -> sqlx::Result<()> {
pub async fn update_orphan_file_path(&self, orphan: &OrphanFile) -> sqlx::Result<()> {
sqlx::query("UPDATE orphan_files SET path = $1 WHERE id = $2")
.bind(file.path.to_str().unwrap().to_string())
.bind(file.id)
.bind(orphan.path.to_str().unwrap().to_string())
.bind(orphan.id)
.execute(&self.connection)
.await
.map(|_| ())
}
pub async fn update_orphan_last_opened(&self, orphan: &OrphanFile) -> sqlx::Result<()> {
sqlx::query("UPDATE orphan_files SET last_opened = $1 WHERE id = $2")
.bind(orphan.last_opened.timestamp())
.bind(orphan.id)
.execute(&self.connection)
.await
.map(|_| ())
// TODO: check for success
}
pub async fn fetch_all_orphan_files(&self) -> sqlx::Result<Vec<OrphanFile>> {
sqlx::query_as::<_, OrphanFile>("SELECT * FROM orphan_files")
.fetch_all(&self.connection)

View File

@ -59,17 +59,22 @@ async fn main() {
let mut sheets = validation_result.validated_sheets;
sheets.append(&mut validation_result.updated_sheets);
let sheets_and_orphans = SheetsAndOrphans { sheets, orphans };
let app_init_data = AppInitData {
sheets,
orphans,
database,
};
let app = RelmApp::new("de.frajul.sheet-organizer");
// Pass empty command line args to allow my own parsing
app.with_args(Vec::new())
.run::<AppModel>(sheets_and_orphans);
.run_async::<AppModel>(app_init_data);
}
pub struct SheetsAndOrphans {
pub struct AppInitData {
sheets: Vec<Sheet>,
orphans: Vec<OrphanFile>,
database: Database,
}
pub struct FileValidationResult {

View File

@ -1,9 +1,15 @@
use chrono::Utc;
use gtk::prelude::*;
use relm4::prelude::*;
use relm4::{
component::{AsyncComponent, AsyncComponentParts},
prelude::*,
AsyncComponentSender,
};
use crate::{
database::Database,
ui::{mcdu::McduOutput, sheet_model::SheetModelType},
SheetsAndOrphans,
AppInitData,
};
use super::{
@ -12,6 +18,7 @@ use super::{
};
pub struct AppModel {
database: Database,
mcdu: Controller<McduModel>,
sheets_and_files_listing: Controller<SheetListingModel>,
new_files_listing: Controller<SheetListingModel>,
@ -24,11 +31,12 @@ pub enum AppInput {
SheetsAndFilesSheetPressed(SheetModelType),
}
#[relm4::component(pub)]
impl SimpleComponent for AppModel {
#[relm4::component(pub, async)]
impl AsyncComponent for AppModel {
type Input = AppInput;
type Output = ();
type Init = SheetsAndOrphans;
type Init = AppInitData;
type CommandOutput = ();
view! {
#[root]
@ -66,11 +74,11 @@ impl SimpleComponent for AppModel {
}
}
fn init(
sheets_and_orphans: Self::Init,
window: &Self::Root,
sender: ComponentSender<Self>,
) -> relm4::ComponentParts<Self> {
async fn init(
init_data: Self::Init,
window: Self::Root,
sender: AsyncComponentSender<Self>,
) -> AsyncComponentParts<Self> {
relm4_icons::initialize_icons();
let mcdu = McduModel::builder()
@ -79,7 +87,7 @@ impl SimpleComponent for AppModel {
McduOutput::SearchStarted(query) => AppInput::SearchStarted(query),
});
let new_files: Vec<SheetModelType> = sheets_and_orphans
let new_files: Vec<SheetModelType> = init_data
.orphans
.iter()
.map(|orphan| SheetModelType::Orphan {
@ -87,12 +95,12 @@ impl SimpleComponent for AppModel {
})
.collect();
let new_files_clone_iter = sheets_and_orphans
let new_files_clone_iter = init_data
.orphans
.into_iter()
.map(|orphan| SheetModelType::Orphan { orphan });
let sheets_and_files: Vec<SheetModelType> = sheets_and_orphans
let sheets_and_files: Vec<SheetModelType> = init_data
.sheets
.into_iter()
.map(|sheet| SheetModelType::Sheet { sheet })
@ -111,6 +119,7 @@ impl SimpleComponent for AppModel {
});
let model = AppModel {
database: init_data.database,
mcdu,
sheets_and_files_listing,
new_files_listing,
@ -118,10 +127,15 @@ impl SimpleComponent for AppModel {
let widgets = view_output!();
ComponentParts { model, widgets }
AsyncComponentParts { model, widgets }
}
fn update(&mut self, message: Self::Input, _sender: ComponentSender<Self>) {
async fn update(
&mut self,
message: Self::Input,
sender: AsyncComponentSender<Self>,
_root: &Self::Root,
) {
// AppInput::SheetPressed(sheet) => opener::open(sheet).unwrap(),
match message {
AppInput::SearchStarted(query) => {
@ -133,7 +147,23 @@ impl SimpleComponent for AppModel {
// TODO
}
AppInput::SheetsAndFilesSheetPressed(sheet_model_type) => {
opener::open(sheet_model_type.get_path()).unwrap()
opener::open(sheet_model_type.get_path()).unwrap();
match sheet_model_type {
SheetModelType::Orphan { mut orphan } => {
orphan.last_opened = Utc::now();
self.database
.update_orphan_last_opened(&orphan)
.await
.unwrap();
}
SheetModelType::Sheet { mut sheet } => {
sheet.last_opened = Utc::now();
self.database
.update_sheet_last_opened(&sheet)
.await
.unwrap();
}
};
}
}
}

View File

@ -1,4 +1,5 @@
pub mod app;
pub mod database_worker;
pub mod mcdu;
pub mod sheet_listing;
pub mod sheet_model;

View File

@ -66,7 +66,6 @@ impl SimpleComponent for SheetListingModel {
}
SheetListingInput::ListBoxRowClicked(index) => {
let x = self.sheets.get(index as usize).unwrap();
debug!("clicked: {}!!!!!", x.label);
sender
.output(SheetModelSelected {
sheet_model_type: x.sheet_model_type.clone(),

View File

@ -64,13 +64,17 @@ impl FactoryComponent for SheetModel {
fn init_model(value: Self::Init, _index: &DynamicIndex, _sender: FactorySender<Self>) -> Self {
let label = match &value {
SheetModelType::Sheet { sheet } => sheet.name.to_string(),
SheetModelType::Orphan { orphan } => orphan
SheetModelType::Orphan { orphan } => {
orphan
.path
.file_name()
.unwrap()
.to_str()
.unwrap()
.to_string(),
.to_string()
+ " "
+ &orphan.last_opened.to_string()
}
};
SheetModel {