diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/app/app.rs | 2 | ||||
| -rw-r--r-- | src/app/calendar.rs | 19 | ||||
| -rw-r--r-- | src/app/form.rs | 46 | ||||
| -rw-r--r-- | src/app/mod.rs | 2 | ||||
| -rw-r--r-- | src/app/update.rs | 35 | ||||
| -rw-r--r-- | src/db/mod.rs | 10 | ||||
| -rw-r--r-- | src/model/event.rs | 12 | 
7 files changed, 85 insertions, 41 deletions
| diff --git a/src/app/app.rs b/src/app/app.rs index d93b544..b1ee395 100644 --- a/src/app/app.rs +++ b/src/app/app.rs @@ -12,6 +12,7 @@ use crate::app::update::Msg;  use crate::{db, model::event::Event};  pub struct App { +    pub conn: Rc<Connection>,      pub window: Rc<gtk::ApplicationWindow>,      pub grid: gtk::Grid,      pub events: Vec<Event>, @@ -48,6 +49,7 @@ impl App {          });          Self { +            conn,              window,              grid,              events, diff --git a/src/app/calendar.rs b/src/app/calendar.rs index 250101f..fa4ebe6 100644 --- a/src/app/calendar.rs +++ b/src/app/calendar.rs @@ -87,7 +87,7 @@ pub fn day_entry(      vbox.add_css_class("g-Calendar__Day");      let gesture = gtk::GestureClick::new(); -    gesture.connect_pressed(glib::clone!(@strong date => move |_, n, _, _| { +    gesture.connect_pressed(glib::clone!(@strong date, @strong tx => move |_, n, _, _| {          if n == 2 {              update::send(tx.clone(), Msg::ShowAddForm { date });          } @@ -107,7 +107,7 @@ pub fn day_entry(      events.sort_by_key(|e| e.start);      if !events.is_empty() { -        vbox.append(&day_events(events)); +        vbox.append(&day_events(tx, events));      }      let scrolled_window = gtk::ScrolledWindow::builder() @@ -135,7 +135,7 @@ fn day_label(date: &NaiveDate) -> gtk::Label {      label  } -fn day_events(events: Vec<&Event>) -> gtk::Box { +fn day_events(tx: Sender<Msg>, events: Vec<&Event>) -> gtk::Box {      let vbox = gtk::Box::builder()          .orientation(gtk::Orientation::Vertical)          .build(); @@ -147,11 +147,14 @@ fn day_events(events: Vec<&Event>) -> gtk::Box {              .build();          let gesture = gtk::GestureClick::new(); -        let click_event = event.clone(); -        gesture.connect_pressed(move |gesture, _, _, _| { -            gesture.set_state(gtk::EventSequenceState::Claimed); -            println!("Click: {:?}", click_event); -        }); +        gesture.connect_pressed( +            glib::clone!(@strong event, @strong tx => move |gesture, n, _, _| { +                gesture.set_state(gtk::EventSequenceState::Claimed); +                if n == 2 { +                    update::send(tx.clone(), Msg::ShowUpdateForm { event: event.clone() }); +                } +            }), +        );          hbox.add_controller(&gesture);          hbox.add_css_class("g-Calendar__DayEvent"); diff --git a/src/app/form.rs b/src/app/form.rs index 08a2af1..6c42cd0 100644 --- a/src/app/form.rs +++ b/src/app/form.rs @@ -1,25 +1,19 @@  use gtk4 as gtk; -use async_channel::Sender; -use chrono::NaiveDate;  use gtk::glib;  use gtk::prelude::*; -use rusqlite::Connection; -use std::rc::Rc; -use uuid::Uuid; -use crate::{app::update, app::update::Msg, db, model::event}; +use crate::{ +    app::{update, update::Msg, App}, +    db, +    model::{event, event::Event}, +}; -pub async fn show( -    conn: Rc<Connection>, -    tx: Sender<Msg>, -    window: Rc<gtk::ApplicationWindow>, -    date: NaiveDate, -) { +pub async fn show(app: &App, event: Event, is_new: bool) {      let dialog = gtk::Dialog::builder() -        .transient_for(&*window) +        .transient_for(&*app.window)          .modal(true) -        .title("Ajouter") +        .title(if is_new { "Ajouter" } else { "Modifier" })          .css_classes(vec!["g-Form".to_string()])          .build(); @@ -31,30 +25,38 @@ pub async fn show(      vbox.add_css_class("g-Form__Inputs");      content_area.append(&vbox); -    let name = entry(""); +    let name = entry(&event.name);      vbox.append(&label("Événement"));      vbox.append(&name); -    let date = entry(&date.format(event::DATE_FORMAT).to_string()); +    let date = entry(&event.date.format(event::DATE_FORMAT).to_string());      vbox.append(&label("Jour"));      vbox.append(&date); -    let start = entry(""); +    let start = entry( +        &event +            .start +            .map(event::pprint_time) +            .unwrap_or("".to_string()), +    );      vbox.append(&label("Début"));      vbox.append(&start); -    let end = entry(""); +    let end = entry(&event.end.map(event::pprint_time).unwrap_or("".to_string()));      vbox.append(&label("Fin"));      vbox.append(&end);      let button = gtk::Button::with_label("Créer");      vbox.append(&button); +    let conn = app.conn.clone(); +    let tx = app.tx.clone();      button.connect_clicked(glib::clone!(@weak dialog => move |_| { -        match event::validate(Uuid::new_v4(), date.buffer().text(), name.buffer().text(), start.buffer().text(), end.buffer().text()) { -            Some(event) => { -                match db::insert(&conn, &event) { +        match event::validate(event.id, date.buffer().text(), name.buffer().text(), start.buffer().text(), end.buffer().text()) { +            Some(new) => { +                match if is_new { db::insert(&conn, &new) } else { db::update(&conn, &new) } {                      Ok(_) => { -                        update::send(tx.clone(), Msg::AddEvent { event: event }); +                        let msg = if is_new { Msg::AddEvent { new } } else { Msg::UpdateEvent { old: event.clone(), new } }; +                        update::send(tx.clone(), msg);                          dialog.close()                      },                      Err(_) => () diff --git a/src/app/mod.rs b/src/app/mod.rs index 30b59af..c9a7f83 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -24,7 +24,7 @@ pub fn run(conn: Connection) {  fn build_ui(conn: Rc<Connection>, app: >k::Application) {      let (tx, rx) = async_channel::unbounded();      let app = App::new(conn.clone(), app, tx.clone()); -    utils::spawn(update::event_handler(conn, rx, tx, app)) +    utils::spawn(update::event_handler(rx, app))  }  fn load_style() { diff --git a/src/app/update.rs b/src/app/update.rs index e7bf7af..f1576b5 100644 --- a/src/app/update.rs +++ b/src/app/update.rs @@ -1,11 +1,9 @@  use async_channel::{Receiver, Sender};  use chrono::NaiveDate; -use rusqlite::Connection; -use std::rc::Rc;  use crate::{      app::{calendar, form, utils, App}, -    model::event::Event, +    model::{event, event::Event},  };  pub fn send(tx: Sender<Msg>, msg: Msg) { @@ -16,20 +14,39 @@ pub fn send(tx: Sender<Msg>, msg: Msg) {  pub enum Msg {      ShowAddForm { date: NaiveDate }, -    AddEvent { event: Event }, +    ShowUpdateForm { event: Event }, +    AddEvent { new: Event }, +    UpdateEvent { old: Event, new: Event },  } -pub async fn event_handler(conn: Rc<Connection>, rx: Receiver<Msg>, tx: Sender<Msg>, mut app: App) { +pub async fn event_handler(rx: Receiver<Msg>, mut app: App) {      while let Ok(msg) = rx.recv().await {          match msg {              Msg::ShowAddForm { date } => { -                form::show(Rc::clone(&conn), tx.clone(), Rc::clone(&app.window), date).await; +                form::show(&app, event::init(date), true).await;              } -            Msg::AddEvent { event } => { -                let date = event.date.clone(); -                app.events.push(event); +            Msg::ShowUpdateForm { event } => { +                form::show(&app, event, false).await; +            } +            Msg::AddEvent { new } => { +                let date = new.date.clone(); +                app.events.push(new);                  calendar::refresh_date(&app, date);              } +            Msg::UpdateEvent { old, new } => { +                let new_date = new.date.clone(); +                match app.events.iter().position(|e| e.id == new.id) { +                    Some(index) => { +                        app.events.remove(index); +                        app.events.push(new); +                        calendar::refresh_date(&app, new_date); +                        if old.date != new_date { +                            calendar::refresh_date(&app, old.date.clone()) +                        } +                    } +                    None => println!("Event not found when updating from {:?} to {:?}", old, new), +                } +            }          }      }  } diff --git a/src/db/mod.rs b/src/db/mod.rs index 23cec7e..03692e9 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -21,6 +21,16 @@ pub fn insert(conn: &Connection, event: &Event) -> Result<()> {      Ok(())  } +pub fn update(conn: &Connection, event: &Event) -> Result<()> { +    conn.execute( +        "UPDATE events SET date = ?, start = ?, end = ?, name = ?, updated = datetime() where id = ?", +        params![event.date, event.start, event.end, event.name, event.id.to_hyphenated().to_string()] +    )?; + +    Ok(()) +} + +// TODO: Don’t use unwrap  pub fn list(conn: &Connection) -> Result<Vec<Event>> {      let mut stmt = conn.prepare("SELECT id, date, start, end, name FROM events")?; diff --git a/src/model/event.rs b/src/model/event.rs index 27587bc..7ab0244 100644 --- a/src/model/event.rs +++ b/src/model/event.rs @@ -13,6 +13,16 @@ pub struct Event {      pub name: String,  } +pub fn init(date: NaiveDate) -> Event { +    Event { +        id: Uuid::new_v4(), +        date, +        start: None, +        end: None, +        name: "".to_string(), +    } +} +  impl Event {      pub fn pprint(&self) -> String {          let start = self.start.map(pprint_time).unwrap_or_default(); @@ -29,7 +39,7 @@ impl Event {      }  } -fn pprint_time(t: NaiveTime) -> String { +pub fn pprint_time(t: NaiveTime) -> String {      if t.minute() == 0 {          format!("{}h", t.hour())      } else { | 
