Make relm4 app async and update last_opened in db
This commit is contained in:
@ -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)
|
||||
|
11
src/main.rs
11
src/main.rs
@ -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 {
|
||||
|
@ -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();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
pub mod app;
|
||||
pub mod database_worker;
|
||||
pub mod mcdu;
|
||||
pub mod sheet_listing;
|
||||
pub mod sheet_model;
|
||||
|
@ -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(),
|
||||
|
@ -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
|
||||
.path
|
||||
.file_name()
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
SheetModelType::Orphan { orphan } => {
|
||||
orphan
|
||||
.path
|
||||
.file_name()
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.to_string()
|
||||
+ " "
|
||||
+ &orphan.last_opened.to_string()
|
||||
}
|
||||
};
|
||||
|
||||
SheetModel {
|
||||
|
Reference in New Issue
Block a user