aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoris2022-01-09 14:37:35 +0100
committerJoris2022-01-09 14:37:35 +0100
commitd0a9063631e71928484a698f6c585ebb3915e8a2 (patch)
tree9a5fc430684aea73877711dd3392b1845d4b9904
parent5166efe517291f5c9fc6326f30651ef799d6db65 (diff)
downloadcalendar-d0a9063631e71928484a698f6c585ebb3915e8a2.tar.gz
calendar-d0a9063631e71928484a698f6c585ebb3915e8a2.tar.bz2
calendar-d0a9063631e71928484a698f6c585ebb3915e8a2.zip
Allow to update events
-rw-r--r--src/app/app.rs2
-rw-r--r--src/app/calendar.rs19
-rw-r--r--src/app/form.rs46
-rw-r--r--src/app/mod.rs2
-rw-r--r--src/app/update.rs35
-rw-r--r--src/db/mod.rs10
-rw-r--r--src/model/event.rs12
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: &gtk::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 {