Finish calendar menu

This commit is contained in:
Jas Singh
2024-06-28 00:11:09 -07:00
parent cfaceac4c0
commit 5d9be96cca
4 changed files with 268 additions and 102 deletions

View File

@@ -22,6 +22,15 @@ const defaultWeather = {
day: {
daily_chance_of_rain: 0,
},
hour: [
{
time_epoch: 1719471600,
temp_f: 0,
condition: {
text: "Clear",
},
},
],
},
],
},
@@ -120,116 +129,239 @@ const WeatherWidget = () => {
child: Widget.Box({
class_name: "weather-container-box",
setup: (self) => {
Utils.interval(6000, () => {
Utils.interval(60 * 1000, () => {
Utils.execAsync(
`curl "https://api.weatherapi.com/v1/forecast.json?key=${keyRing.weatherapi}&q=93722&days=1&aqi=no&alerts=no"`,
).then((res) => {
theWeather.value = JSON.parse(res);
});
)
.then((res) => {
theWeather.value = JSON.parse(res);
})
.catch((err) => {
console.error(`Failed to fetch weather: ${err}`);
theWeather.value = defaultWeather;
});
});
return (self.child = Widget.Box({
class_name: "calendar-menu-weather today",
vertical: true,
hexpand: true,
children: [
Widget.Box({
vpack: "center",
hpack: "start",
class_name: "calendar-menu-weather today icon container",
children: [
Widget.Icon({
class_name: "calendar-menu-weather today icon",
icon: theWeather.bind("value").as((v) => {
return icons.weather[
v.current.condition.text
.toLowerCase()
.replaceAll(" ", "_")
];
}),
}),
],
}),
Widget.Box({
class_name: "calendar-menu-weather today",
hexpand: true,
vpack: "center",
hpack: "center",
class_name: "calendar-menu-weather today temp container",
vertical: true,
children: [
Widget.Box({
vpack: "center",
hpack: "start",
class_name: "calendar-menu-weather today icon container",
children: [
Widget.Label({
class_name: "calendar-menu-weather today temp label",
label: theWeather
.bind("value")
.as((v) => `${Math.ceil(v.current.temp_f)}° F`),
}),
Widget.Label({
class_name: theWeather
.bind("value")
.as(
(v) =>
`calendar-menu-weather today temp label icon ${getIcon(Math.ceil(v.current.temp_f)).color}`,
),
label: theWeather
.bind("value")
.as((v) => getIcon(Math.ceil(v.current.temp_f)).icon),
Widget.Icon({
class_name: "calendar-menu-weather today icon",
icon: theWeather.bind("value").as((v) => {
return icons.weather[
v.current.condition.text
.trim()
.toLowerCase()
.replaceAll(" ", "_")
];
}),
}),
],
}),
Widget.Label({
class_name: theWeather
.bind("value")
.as(
(v) =>
`calendar-menu-weather today condition label ${getIcon(Math.ceil(v.current.temp_f)).color}`,
),
label: theWeather
.bind("value")
.as((v) => v.current.condition.text),
Widget.Box({
hpack: "center",
vpack: "center",
vertical: true,
children: [
Widget.Box({
hexpand: true,
vpack: "center",
class_name: "calendar-menu-weather today temp container",
vertical: false,
children: [
Widget.Box({
hexpand: true,
hpack: "center",
children: [
Widget.Label({
class_name:
"calendar-menu-weather today temp label",
label: theWeather
.bind("value")
.as((v) => `${Math.ceil(v.current.temp_f)}° F`),
}),
Widget.Label({
class_name: theWeather
.bind("value")
.as(
(v) =>
`calendar-menu-weather today temp label icon ${getIcon(Math.ceil(v.current.temp_f)).color}`,
),
label: theWeather
.bind("value")
.as(
(v) =>
getIcon(Math.ceil(v.current.temp_f)).icon,
),
}),
],
}),
],
}),
Widget.Box({
hpack: "center",
child: Widget.Label({
max_width_chars: 17,
truncate: "end",
lines: 2,
class_name: theWeather
.bind("value")
.as(
(v) =>
`calendar-menu-weather today condition label ${getIcon(Math.ceil(v.current.temp_f)).color}`,
),
label: theWeather
.bind("value")
.as((v) => v.current.condition.text),
}),
}),
],
}),
Widget.Box({
class_name: "calendar-menu-weather today stats container",
hpack: "end",
vpack: "center",
vertical: true,
children: [
Widget.Box({
class_name: "weather wind",
children: [
Widget.Label({
class_name: "weather wind icon",
label: "",
}),
Widget.Label({
class_name: "weather wind label",
label: theWeather
.bind("value")
.as((v) => `${Math.floor(v.current.wind_mph)} mph`),
}),
],
}),
Widget.Box({
class_name: "weather precip",
children: [
Widget.Label({
class_name: "weather precip icon",
label: "",
}),
Widget.Label({
class_name: "weather precip label",
label: theWeather
.bind("value")
.as(
(v) =>
`${v.forecast.forecastday[0].day.daily_chance_of_rain}%`,
),
}),
],
}),
],
}),
],
}),
Widget.Separator({
class_name: "menu-separator weather",
}),
Widget.Box({
class_name: "calendar-menu-weather today stats container",
hpack: "end",
vpack: "start",
vertical: true,
children: [
Widget.Box({
class_name: "weather wind",
vertical: false,
hexpand: true,
hpack: "fill",
class_name: "hourly-weather-container",
children: [1, 2, 3, 4].map((hoursFromNow) => {
const getNextEpoch = (wthr) => {
const currentEpoch = wthr.location.localtime_epoch;
const epochAtHourStart = currentEpoch - (currentEpoch % 3600);
let nextEpoch = 3600 * hoursFromNow + epochAtHourStart;
const curHour = new Date(currentEpoch * 1000).getHours();
/*
* NOTE: Since the API is only capable of showing the current day; if
* the hours left in the day are less than 4 (aka spilling into the next day),
* then rewind to contain the prediction within the current day.
*/
if (curHour > 20) {
const hoursToRewind = curHour - 19;
nextEpoch =
3600 * hoursFromNow +
epochAtHourStart -
hoursToRewind * 3600;
}
return nextEpoch;
};
return Widget.Box({
class_name: "hourly-weather-item",
hexpand: true,
vertical: true,
children: [
Widget.Label({
class_name: "weather wind icon",
label: "",
class_name: "hourly-weather-time",
label: theWeather.bind("value").as((w) => {
if (!Object.keys(w).length) {
return "-";
}
const nextEpoch = getNextEpoch(w);
const dateAtEpoch = new Date(nextEpoch * 1000);
let hours = dateAtEpoch.getHours();
const ampm = hours >= 12 ? "PM" : "AM";
hours = hours % 12 || 12;
return `${hours}${ampm}`;
}),
}),
Widget.Icon({
class_name: "hourly-weather-icon",
icon: theWeather.bind("value").as((w) => {
if (!Object.keys(w).length) {
return "-";
}
const nextEpoch = getNextEpoch(w);
const weatherAtEpoch =
w.forecast.forecastday[0].hour.find(
(h) => h.time_epoch === nextEpoch,
);
return icons.weather[
weatherAtEpoch.condition.text
.trim()
.toLowerCase()
.replaceAll(" ", "_")
];
}),
}),
Widget.Label({
class_name: "weather wind label",
label: theWeather
.bind("value")
.as((v) => `${Math.floor(v.current.wind_mph)} mph`),
class_name: "hourly-weather-temp",
label: theWeather.bind("value").as((w) => {
if (!Object.keys(w).length) {
return "-";
}
const nextEpoch = getNextEpoch(w);
const weatherAtEpoch =
w.forecast.forecastday[0].hour.find(
(h) => h.time_epoch === nextEpoch,
);
return `${Math.ceil(weatherAtEpoch.temp_f)}° F`;
}),
}),
],
}),
Widget.Box({
class_name: "weather precip",
children: [
Widget.Label({
class_name: "weather precip icon",
label: "",
}),
Widget.Label({
class_name: "weather precip label",
label: theWeather
.bind("value")
.as(
(v) =>
`${v.forecast.forecastday[0].day.daily_chance_of_rain}%`,
),
}),
],
}),
],
});
}),
}),
],
}));