Calendar (WIP): user can select a day

This commit is contained in:
Greg Burri 2025-02-02 12:50:12 +01:00
parent 79a0aeb1b8
commit d8641d4db6
4 changed files with 100 additions and 91 deletions

View file

@ -1,9 +1,6 @@
use std::sync::{
atomic::{AtomicI32, AtomicU32, Ordering},
Arc, Mutex,
};
use std::sync::{Arc, Mutex};
use chrono::{offset::Local, DateTime, Datelike, Days, Months, NaiveDate, Weekday};
use chrono::{offset::Local, DateTime, Datelike, Days, Months, Weekday};
use common::ron_api;
use gloo::{console::log, events::EventListener};
use wasm_bindgen::prelude::*;
@ -12,11 +9,11 @@ use web_sys::Element;
use crate::{
request,
utils::{by_id, selector, SelectorExt},
utils::{by_id, SelectorExt},
};
struct CalendarStateInternal {
current_date: DateTime<Local>,
displayed_date: DateTime<Local>,
selected_date: DateTime<Local>,
}
@ -30,39 +27,33 @@ impl CalendarState {
let current_date = Local::now();
Self {
internal_state: Arc::new(Mutex::new(CalendarStateInternal {
current_date,
displayed_date: current_date,
selected_date: current_date,
})),
}
}
pub fn to_next_month(&self) -> DateTime<Local> {
pub fn displayed_date_next_month(&self) {
let mut locker = self.internal_state.lock().unwrap();
let new_date = locker
.current_date
.checked_add_months(Months::new(1))
.unwrap();
locker.current_date = new_date;
new_date
locker.displayed_date = locker.displayed_date + Months::new(1);
}
pub fn to_previous_month(&self) -> DateTime<Local> {
pub fn displayed_date_previous_month(&self) {
let mut locker = self.internal_state.lock().unwrap();
let new_date = locker
.current_date
.checked_sub_months(Months::new(1))
.unwrap();
locker.current_date = new_date;
new_date
locker.displayed_date = locker.displayed_date - Months::new(1);
}
pub fn get_current_date(&self) -> DateTime<Local> {
self.internal_state.lock().unwrap().current_date
pub fn get_displayed_date(&self) -> DateTime<Local> {
self.internal_state.lock().unwrap().displayed_date
}
pub fn get_selected_date(&self) -> DateTime<Local> {
self.internal_state.lock().unwrap().selected_date
}
pub fn set_selected_date(&self, date: DateTime<Local>) {
self.internal_state.lock().unwrap().selected_date = date;
}
}
pub fn setup(calendar: Element) {
@ -71,55 +62,49 @@ pub fn setup(calendar: Element) {
let state = CalendarState::new();
display_month(&calendar, state.get_current_date());
display_month(&calendar, state.clone());
// Click on previous month.
let calendar_clone = calendar.clone();
let state_clone = state.clone();
EventListener::new(&prev, "click", move |_event| {
let m = state_clone.to_previous_month();
display_month(&calendar_clone, m);
state_clone.displayed_date_previous_month();
display_month(&calendar_clone, state_clone.clone());
})
.forget();
// Click on next month.
let calendar_clone = calendar.clone();
let state_clone = state.clone();
EventListener::new(&next, "click", move |_event| {
let m = state_clone.to_next_month();
display_month(&calendar_clone, m);
state_clone.displayed_date_next_month();
display_month(&calendar_clone, state_clone.clone());
})
.forget();
// let days: Element = calendar.selector(".days");
// let state_clone = state.clone();
// EventListener::new(&days, "click", move |event| {
// log!(event);
// let target: Element = event.target().unwrap().dyn_into().unwrap();
// if
// })
// .forget();
// let calendar_clone = calendar.clone();
// let current_month_clone = current_month.clone();
// let current_year_clone = current_year.clone();
// EventListener::new(&next, "click", move |_event| {
// let mut m = current_month_clone.load(Ordering::Relaxed) + 1;
// if m == 13 {
// current_year_clone.fetch_add(1, Ordering::Relaxed);
// m = 1
// }
// current_month_clone.store(m, Ordering::Relaxed);
// display_month(
// &calendar_clone,
// current_year_clone.load(Ordering::Relaxed),
// m,
// );
// })
// .forget();
// Click on a day of the current month.
let days: Element = calendar.selector(".days");
let calendar_clone = calendar.clone();
let state_clone = state.clone();
EventListener::new(&days, "click", move |event| {
let target: Element = event.target().unwrap().dyn_into().unwrap();
if target.class_name() == "number" {
let first_day = first_grid_day(state_clone.get_displayed_date());
let day_grid_id = target.parent_element().unwrap().id();
let day_offset = day_grid_id[9..10].parse::<u64>().unwrap() * 7
+ day_grid_id[10..11].parse::<u64>().unwrap();
state_clone.set_selected_date(first_day + Days::new(day_offset));
display_month(&calendar_clone, state_clone.clone());
}
})
.forget();
}
const NB_CALENDAR_ROW: u64 = 5;
fn display_month(calendar: &Element, date: DateTime<Local>) {
fn display_month(calendar: &Element, state: CalendarState) {
let date = state.get_displayed_date();
calendar
.selector::<Element>(".year")
.set_inner_html(&date.year().to_string());
@ -136,31 +121,36 @@ fn display_month(calendar: &Element, date: DateTime<Local>) {
}
}
let mut current = date;
let first_day = first_grid_day(date);
let mut current = first_day;
while (current - Days::new(1)).month() == date.month() {
current = current - Days::new(1);
}
while current.weekday() != Weekday::Mon {
current = current - Days::new(1);
}
let first_day = current;
for i in 0..7 {
for j in 0..NB_CALENDAR_ROW {
let day_element: Element = by_id(&format!("day-{}{}", i, j));
for i in 0..NB_CALENDAR_ROW {
for j in 0..7 {
let day_element: Element = by_id(&format!("day-grid-{}{}", i, j));
let day_content: Element = day_element.selector(".number");
day_content.set_inner_html(&current.day().to_string());
if current == Local::now() {
day_element.set_class_name("current-month today");
} else if current.month() == date.month() {
day_element.set_class_name("current-month");
} else {
day_element.set_class_name("");
let mut class_name = String::new();
if current.month() == date.month() {
if !class_name.is_empty() {
class_name += " ";
}
class_name += "current-month";
}
if current.date_naive() == Local::now().date_naive() {
if !class_name.is_empty() {
class_name += " ";
}
class_name += "today";
}
if current.date_naive() == state.get_selected_date().date_naive() {
if !class_name.is_empty() {
class_name += " ";
}
class_name += "selected-day"
}
day_element.set_class_name(&class_name);
current = current + Days::new(1);
}
@ -185,7 +175,15 @@ fn display_month(calendar: &Element, date: DateTime<Local>) {
for recipe in scheduled_recipes.recipes {
log!(recipe.1);
}
// create_tag_elements(recipe_id, &tags.tags);
});
}
fn first_grid_day(mut date: DateTime<Local>) -> DateTime<Local> {
while (date - Days::new(1)).month() == date.month() {
date = date - Days::new(1);
}
while date.weekday() != Weekday::Mon {
date = date - Days::new(1);
}
date
}