summaryrefslogtreecommitdiff
path: root/src/modules/popdowns/sideright.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/popdowns/sideright.tsx')
-rw-r--r--src/modules/popdowns/sideright.tsx127
1 files changed, 127 insertions, 0 deletions
diff --git a/src/modules/popdowns/sideright.tsx b/src/modules/popdowns/sideright.tsx
new file mode 100644
index 0000000..86c0547
--- /dev/null
+++ b/src/modules/popdowns/sideright.tsx
@@ -0,0 +1,127 @@
+import { bind } from "astal";
+import { Astal, Gtk, type Gdk } from "astal/gtk3";
+import SWeather, { type WeatherData } from "../../services/weather";
+import { ellipsize } from "../../utils/strings";
+import { bindCurrentTime } from "../../utils/system";
+import { Calendar as WCal } from "../../utils/widgets";
+import PopupWindow from "../../widgets/popupwindow";
+
+const getHoursFromUpdate = (data: WeatherData, hours: number) => {
+ const updateTime = data.location.localtime_epoch;
+ const updateHourStart = updateTime - (updateTime % 3600);
+
+ let nextHour = new Date((updateHourStart + hours * 3600) * 1000).getHours();
+ if (nextHour >= 24) nextHour -= 24;
+
+ return nextHour;
+};
+
+const Time = () => (
+ <box className="time">
+ <box hexpand halign={Gtk.Align.CENTER}>
+ <label label={bindCurrentTime("%I:%M:%S")} />
+ <label className="ampm" label={bindCurrentTime("%p", c => (c.get_hour() < 12 ? "AM" : "PM"))} />
+ </box>
+ </box>
+);
+
+const Calendar = () => (
+ <box className="calendar">
+ <eventbox
+ setup={self => {
+ self.connect("button-press-event", (_, event: Gdk.Event) => {
+ if (event.get_button()[1] === Astal.MouseButton.MIDDLE) {
+ const now = new Date();
+ const child = self.get_child() as WCal | null;
+ if (!child) return;
+ child.select_month(now.getMonth(), now.getFullYear());
+ }
+ });
+ }}
+ >
+ <WCal
+ hexpand
+ showDetails={false}
+ day={0}
+ setup={self => {
+ const update = () => {
+ const now = new Date();
+ if (self.month === now.getMonth() && self.year === now.getFullYear()) self.day = now.getDate();
+ else self.day = 0;
+ };
+ self.connect("month-changed", update);
+ self.connect("next-month", update);
+ self.connect("prev-month", update);
+ self.connect("next-year", update);
+ self.connect("prev-year", update);
+ update();
+ }}
+ />
+ </eventbox>
+ </box>
+);
+
+const Weather = () => {
+ const weather = SWeather.get_default();
+
+ return (
+ <box vertical className="weather">
+ <centerbox className="current">
+ <label
+ halign={Gtk.Align.START}
+ valign={Gtk.Align.CENTER}
+ className="status-icon"
+ label={bind(weather, "icon")}
+ />
+ <box vertical halign={Gtk.Align.CENTER} valign={Gtk.Align.CENTER} className="status">
+ <box halign={Gtk.Align.CENTER} className="temperature">
+ <label label={bind(weather, "temperature").as(t => `${Math.round(t)}°C`)} />
+ <label
+ className={bind(weather, "tempColour").as(c => `temp-icon ${c}`)}
+ label={bind(weather, "tempIcon")}
+ />
+ </box>
+ <label label={bind(weather, "condition").as(c => ellipsize(c, 16))} />
+ </box>
+ <box vertical halign={Gtk.Align.END} valign={Gtk.Align.CENTER} className="other-data">
+ <label xalign={0} label={bind(weather, "wind").as(w => ` ${Math.round(w)} kph`)} />
+ <label xalign={0} label={bind(weather, "rainChance").as(r => ` ${r}%`)} />
+ </box>
+ </centerbox>
+ <box className="separator" />
+ <box className="forecast">
+ {Array.from({ length: 4 }).map((_, i) => (
+ <box vertical hexpand className="hour">
+ <label
+ label={bind(weather, "raw").as(r => {
+ const hour = getHoursFromUpdate(r, i + 1);
+ return `${hour % 12 || 12}${hour < 12 ? "AM" : "PM"}`;
+ })}
+ />
+ <label
+ className="icon"
+ label={bind(weather, "raw").as(r =>
+ weather.getIcon(weather.forecast[getHoursFromUpdate(r, i + 1)]?.condition.text ?? "")
+ )}
+ />
+ <label
+ label={bind(weather, "raw").as(
+ r => `${Math.round(weather.forecast[getHoursFromUpdate(r, i + 1)]?.temp_c) ?? "-"}°C`
+ )}
+ />
+ </box>
+ ))}
+ </box>
+ </box>
+ );
+};
+
+export default () => (
+ <PopupWindow name="sideright">
+ <box vertical className="sideright">
+ <Time />
+ <Calendar />
+ <Weather />
+ </box>
+ </PopupWindow>
+);