monorepo/dashboard/src/main.rs

355 lines
9.8 KiB
Rust
Raw Normal View History

2023-08-07 23:06:00 +00:00
/*
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate lazy_static;
2023-08-07 23:06:00 +00:00
*/
2023-08-08 02:35:43 +00:00
use chrono::{Datelike, Duration, NaiveTime};
2023-08-07 23:06:00 +00:00
use glib::Object;
2023-08-08 02:35:43 +00:00
use gtk::{prelude::*, subclass::prelude::*, Orientation};
use ifc::IFC;
use std::{cell::RefCell, f64::consts::PI, ops::Deref, rc::Rc};
2023-08-07 23:06:00 +00:00
/*
use geo_types::{Latitude, Longitude};
2023-08-08 02:35:43 +00:00
*/
mod soluna_client;
2023-08-08 02:35:43 +00:00
use soluna_client::{LunarPhase, SunMoon};
2023-08-08 02:35:43 +00:00
/*
mod solstices;
2023-08-07 23:06:00 +00:00
use solstices::EVENTS;
*/
/*
const EO_TEXT: &'static str = "
day = {$day ->
*[Sunday] Dimanĉo
[Monday] Lundo
[Tuesday] Mardo
[Wednesday] Merkredo
[Thursday] Ĵaŭdo
[Friday] Vendredo
[Saturday] Sabato
[LeapDay] Leap Day
[YearDay] Year Day
}
month = {$month ->
*[January] Januaro
[February] Februaro
[March] Marto
[April] Aprilo
[May] Mayo
[June] Junio
[Sol] Solo
[July] Julio
[August] Aŭgusto
[September] Septembro
[October] Oktobro
[November] Novembro
[December] Decembro
}
spring_equinox = Printempa Ekvinokso
summer_solstice = Somera Solstico
autumn_equinox = Aŭtuna Ekvinokso
winter_solstice = Vintra Solstico
";
fn date(fluent: Arc<fluent_ergonomics::FluentErgo>, today: ifc::IFC) -> impl Render {
let mut day_args = FluentArgs::new();
day_args.set(
"day",
FluentValue::String(Cow::Owned(String::from(today.weekday_ifc()))),
);
let tago = fluent.tr("tago", Some(&day_args)).unwrap();
let mut month_args = FluentArgs::new();
month_args.set(
"month",
FluentValue::String(Cow::Owned(String::from(today.month_ifc()))),
);
let monato = fluent.tr("month", Some(&month_args)).unwrap();
owned_html! {p : format!("{}, {} {}, {}", tago, monato, today.day(), today.year());}
}
*/
/*
fn soluna_desegno<Tz: TimeZone>(sun_moon: SunMoon<Tz>) -> impl Render {
owned_html! {
table {
tr {
th : "Sunleviĝo";
th : "Sunfalo";
th : "Lunleviĝo";
th : "Lunfalo";
}
tr {
td : format!("{}", sun_moon.sunrise.format("%H:%M"));
td : format!("{}", sun_moon.sunset.format("%H:%M"));
td : sun_moon.moonrise.map(|v| format!("{}", v.format("%H:%M"))).unwrap_or("".to_string());
td : sun_moon.moonset.map(|v| format!("{}", v.format("%H:%M"))).unwrap_or("".to_string());
td : format!("{:?}", sun_moon.moon_phase);
}
}
}
}
*/
/*
fn astronomia_eventa_desegno(
fluent: Arc<fluent_ergonomics::FluentErgo>,
event: Option<Event>,
) -> impl Render {
let s = match event {
None => "".to_owned(),
Some(event) => {
let eventa_str = match event {
Event::SpringEquinox(_) => fluent.tr("spring_equinox", None),
Event::SummerSolstice(_) => fluent.tr("summer_solstice", None),
Event::AutumnEquinox(_) => fluent.tr("autumn_equinox", None),
Event::WinterSolstice(_) => fluent.tr("winter_solstice", None),
}
.unwrap();
format!("{} {}", eventa_str, event.date().format("%Y-%m-%d"))
}
};
owned_html! {
div : s.clone();
}
}
*/
2023-08-03 02:44:10 +00:00
/*
fn page_template(
fluent: Arc<fluent_ergonomics::FluentErgo>,
today: ifc::IFC,
sun_moon: SunMoon,
event: Option<solstices::Event>,
) -> String {
format!(
"{}",
html! {
: doctype::HTML;
html {
head {
title: "Superrigardo";
}
body {
h1(id="heading", class="title") : date(fluent.clone(), today);
div : soluna_desegno(sun_moon.clone());
div : astronomia_eventa_desegno(fluent.clone(), event);
// div : cirklo();
}
}
}
)
}
async fn page(
fluent: Arc<fluent_ergonomics::FluentErgo>,
solar_client: Arc<SolunaClient>,
latitude: Latitude,
longitude: Longitude,
) -> Result<Html<String>, Rejection> {
let now = Utc::now();
let d = ifc::IFC::from(now.with_timezone(&New_York).date());
let sun_moon = solar_client
.request(latitude, longitude, now.with_timezone(&New_York).date())
.await;
let next_event = EVENTS.next_event(now);
Ok(warp::reply::html(page_template(
fluent, d, sun_moon, next_event,
)))
}
2023-08-03 02:44:10 +00:00
*/
2023-08-07 23:06:00 +00:00
#[derive(Default)]
pub struct DatePrivate {}
#[glib::object_subclass]
impl ObjectSubclass for DatePrivate {
const NAME: &'static str = "Date";
type Type = Date;
type ParentType = gtk::Box;
}
impl ObjectImpl for DatePrivate {}
impl WidgetImpl for DatePrivate {}
impl BoxImpl for DatePrivate {}
glib::wrapper! {
pub struct Date(ObjectSubclass<DatePrivate>) @extends gtk::Box, gtk::Widget;
}
impl Date {
fn new() -> Self {
let s: Self = Object::builder().build();
2023-08-08 02:35:43 +00:00
let dt = IFC::from(chrono::Local::now().date_naive().with_year(12023).unwrap());
2023-08-07 23:06:00 +00:00
s.append(&gtk::Label::new(Some(
format!(
"{:?}, {:?} {}, {}",
dt.weekday(),
dt.month(),
dt.day(),
dt.year()
)
.as_ref(),
)));
s
}
}
2023-08-08 02:35:43 +00:00
#[derive(Default)]
2023-08-08 03:53:42 +00:00
pub struct ClockPrivate {
2023-08-08 02:35:43 +00:00
info: Rc<RefCell<Option<SunMoon>>>,
}
#[glib::object_subclass]
2023-08-08 03:53:42 +00:00
impl ObjectSubclass for ClockPrivate {
const NAME: &'static str = "Clock";
type Type = Clock;
2023-08-08 02:35:43 +00:00
type ParentType = gtk::DrawingArea;
}
2023-08-08 03:53:42 +00:00
impl ObjectImpl for ClockPrivate {}
impl WidgetImpl for ClockPrivate {}
impl DrawingAreaImpl for ClockPrivate {}
2023-08-08 02:35:43 +00:00
glib::wrapper! {
2023-08-08 03:53:42 +00:00
pub struct Clock(ObjectSubclass<ClockPrivate>) @extends gtk::DrawingArea, gtk::Widget;
2023-08-08 02:35:43 +00:00
}
2023-08-08 03:53:42 +00:00
impl Clock {
2023-08-08 02:35:43 +00:00
pub fn new(sun_moon_info: SunMoon) -> Self {
let s: Self = Object::builder().build();
s.set_width_request(500);
s.set_height_request(500);
*s.imp().info.borrow_mut() = Some(sun_moon_info);
s.set_draw_func({
let s = s.clone();
move |_, context, width, height| {
let info = s.imp().info.borrow();
// context.set_source_rgb(240., 240., 240.);
context.set_source_rgb(0., 0., 0.);
let _ = context.paint();
context.set_line_width(5.);
context.set_source_rgb(0.7, 0., 0.9);
context.arc(width as f64 / 2., height as f64 / 2., 200., 0., PI * 2.);
let _ = context.stroke();
2023-08-08 03:53:42 +00:00
(0..24).for_each(|hour| {
context.translate(width as f64 / 2., height as f64 / 2.);
context.rotate(PI / 12. * hour as f64);
context.move_to(210., 0.);
context.line_to(230., 0.);
context.identity_matrix();
let _ = context.stroke();
});
2023-08-08 02:35:43 +00:00
if let Some(info) = info.deref() {
context.move_to(width as f64 / 2., height as f64 / 2.);
let full_day = Duration::days(1).num_seconds() as f64;
let sunrise = info.sunrise - NaiveTime::from_hms_opt(0, 0, 0).unwrap();
let sunset = info.sunset - NaiveTime::from_hms_opt(0, 0, 0).unwrap();
let start = (PI * 2.) * sunset.num_seconds() as f64 / full_day - (PI / 2.);
let end = (PI * 2.) * sunrise.num_seconds() as f64 / full_day - (PI / 2.);
context.set_source_rgb(0., 0.7, 0.9);
context.arc(width as f64 / 2., height as f64 / 2., 200., start, end);
let _ = context.fill();
}
}
});
s
}
}
2023-08-07 23:06:00 +00:00
pub fn main() {
/*
let runtime = Arc::new(
tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap(),
);
*/
let app = gtk::Application::builder()
.application_id("com.luminescent-dreams.dashboard")
.build();
app.connect_activate(
// let runtime = runtime.clone();
|app| {
let window = gtk::ApplicationWindow::new(app);
window.present();
2023-08-08 02:35:43 +00:00
let layout = gtk::Box::builder()
.orientation(Orientation::Vertical)
.build();
2023-08-07 23:06:00 +00:00
let date = Date::new();
2023-08-08 03:53:42 +00:00
let day = Clock::new(SunMoon {
2023-08-08 02:35:43 +00:00
sunrise: NaiveTime::from_hms_opt(6, 0, 0).unwrap(),
sunset: NaiveTime::from_hms_opt(0, 0, 0).unwrap(),
moonrise: NaiveTime::from_hms_opt(15, 0, 0),
moonset: NaiveTime::from_hms_opt(5, 0, 0),
moon_phase: LunarPhase::WaningCrescent,
});
layout.append(&date);
layout.append(&day);
window.set_child(Some(&layout));
2023-08-07 23:06:00 +00:00
},
);
app.run();
/*
let now = Local::now();
let ifc = ifc::IFC::from(now.date_naive().with_year(12023).unwrap());
let next_event = EVENTS.next_event(now.with_timezone(&Utc)).unwrap();
println!(
"{:?}, {:?} {}, {}",
ifc.weekday(),
ifc.month(),
ifc.day(),
ifc.year()
);
println!("{:?}", next_event);
let latitude = Latitude::from(41.78);
let longitude = Longitude::from(-71.41);
let soluna_client = SolunaClient::new();
let sun_moon = soluna_client
.request(latitude, longitude, Local::now())
.await;
println!(
"Solar Transit: {} -> {}",
sun_moon.sunrise.format("%H:%M").to_string(),
sun_moon.sunset.format("%H:%M").to_string()
);
println!(
"Lunar Transit: {} -> {} [{:?}]",
sun_moon
.moonrise
.map(|time| time.format("%H:%M").to_string())
.unwrap_or(" -- ".to_owned()),
sun_moon
.moonset
.map(|time| time.format("%H:%M").to_string())
.unwrap_or(" -- ".to_owned()),
sun_moon.moon_phase
);
2023-08-07 23:06:00 +00:00
*/
}