From 936405d9d21c3735f8274fbe0090fc11903be57c Mon Sep 17 00:00:00 2001 From: Jas Singh Date: Fri, 26 Jul 2024 19:25:37 -0700 Subject: [PATCH] Added the ability to specify location in the weather settings. --- modules/menus/calendar/weather/index.js | 147 ++++++++++---------- options.ts | 1 + widget/settings/pages/config/menus/clock.ts | 5 +- 3 files changed, 80 insertions(+), 73 deletions(-) diff --git a/modules/menus/calendar/weather/index.js b/modules/menus/calendar/weather/index.js index 7c7a4dd..13328d8 100644 --- a/modules/menus/calendar/weather/index.js +++ b/modules/menus/calendar/weather/index.js @@ -4,89 +4,94 @@ import { TodayStats } from "./stats/index.js"; import { TodayTemperature } from "./temperature/index.js"; import { Hourly } from "./hourly/index.js"; -const { key, interval } = options.menus.clock.weather; +const { key, interval, location } = options.menus.clock.weather; const defaultWeather = { - location: { - localtime_epoch: 1719471600, - }, - current: { - temp_f: 0, - wind_mph: 0, - condition: { - text: "Clear", + location: { + localtime_epoch: 1719471600, }, - }, - forecast: { - forecastday: [ - { - day: { - daily_chance_of_rain: 0, + current: { + temp_f: 0, + wind_mph: 0, + condition: { + text: "Clear", }, - hour: [ - { - time_epoch: 1719471600, - temp_f: 0, - condition: { - text: "Clear", + }, + forecast: { + forecastday: [ + { + day: { + daily_chance_of_rain: 0, + }, + hour: [ + { + time_epoch: 1719471600, + temp_f: 0, + condition: { + text: "Clear", + }, + }, + ], }, - }, ], - }, - ], - }, + }, }; const theWeather = Variable(defaultWeather); const WeatherWidget = () => { - return Widget.Box({ - class_name: "calendar-menu-item-container weather", - child: Widget.Box({ - class_name: "weather-container-box", - setup: (self) => { - Utils.merge( - [key.bind("value"), interval.bind("value")], - (weatherKey, weatherInterval) => { - Utils.interval(weatherInterval, () => { - Utils.execAsync( - `curl "https://api.weatherapi.com/v1/forecast.json?key=${weatherKey}&q=93722&days=1&aqi=no&alerts=no"`, - ) - .then((res) => { - if (typeof res === "string") { - theWeather.value = JSON.parse(res); - } - }) - .catch((err) => { - console.error(`Failed to fetch weather: ${err}`); - theWeather.value = defaultWeather; - }); - }); - }, - ); + return Widget.Box({ + class_name: "calendar-menu-item-container weather", + child: Widget.Box({ + class_name: "weather-container-box", + setup: (self) => { + Utils.merge( + [key.bind("value"), interval.bind("value"), location.bind("value")], + (weatherKey, weatherInterval, loc) => { + Utils.interval(weatherInterval, () => { + const formattedLocation = loc.replace(" ", "%20"); + Utils.execAsync( + `curl "https://api.weatherapi.com/v1/forecast.json?key=${weatherKey}&q=${formattedLocation}&days=1&aqi=no&alerts=no"`, + ) + .then((res) => { + try { + if (typeof res === "string") { + theWeather.value = JSON.parse(res); + } + } catch (error) { + console.error(`Failed to parse weather data: ${error}`); + } + }) + .catch((err) => { + console.error(`Failed to fetch weather: ${err}`); + theWeather.value = defaultWeather; + }); + }); + }, + ); - return (self.child = Widget.Box({ - vertical: true, - hexpand: true, - children: [ - Widget.Box({ - class_name: "calendar-menu-weather today", - hexpand: true, - children: [ - TodayIcon(theWeather), - TodayTemperature(theWeather), - TodayStats(theWeather), - ], - }), - Widget.Separator({ - class_name: "menu-separator weather", - }), - Hourly(theWeather), - ], - })); - }, - }), - }); + return (self.child = Widget.Box({ + vertical: true, + hexpand: true, + children: [ + Widget.Box({ + class_name: "calendar-menu-weather today", + hexpand: true, + children: [ + TodayIcon(theWeather), + TodayTemperature(theWeather), + TodayStats(theWeather), + ], + }), + Widget.Separator({ + class_name: "menu-separator weather", + }), + Hourly(theWeather), + ], + })); + }, + }), + }); }; export { WeatherWidget }; diff --git a/options.ts b/options.ts index 46ea3a7..590a0fa 100644 --- a/options.ts +++ b/options.ts @@ -691,6 +691,7 @@ const options = mkOptions(OPTIONS, { weather: { interval: opt(60000), unit: opt<"metric" | "imperial">("imperial"), + location: opt("Los Angeles"), key: opt( JSON.parse(Utils.readFile(`${App.configDir}/.weather.json`) || "{}")?.weather_api_key || "", ), diff --git a/widget/settings/pages/config/menus/clock.ts b/widget/settings/pages/config/menus/clock.ts index f4172d4..11aa8e8 100644 --- a/widget/settings/pages/config/menus/clock.ts +++ b/widget/settings/pages/config/menus/clock.ts @@ -12,9 +12,10 @@ export const ClockMenuSettings = () => { Option({ opt: options.menus.clock.time.military, title: 'Use 24hr time', type: 'boolean' }), Header('Weather'), - Option({ opt: options.menus.clock.weather.interval, title: 'Weather Fetching Interval (ms)', subtitle: 'May require AGS restart.', type: 'number' }), - Option({ opt: options.menus.clock.weather.unit, title: 'Units', type: 'enum', enums: ['imperial', 'metric'] }), + Option({ opt: options.menus.clock.weather.location, title: 'Location', subtitle: 'Zip Code, Postal Code, City, etc.', type: 'string' }), Option({ opt: options.menus.clock.weather.key, title: 'Weather API Key', subtitle: 'May require AGS restart. https://weatherapi.com/', type: 'string' }), + Option({ opt: options.menus.clock.weather.unit, title: 'Units', type: 'enum', enums: ['imperial', 'metric'] }), + Option({ opt: options.menus.clock.weather.interval, title: 'Weather Fetching Interval (ms)', subtitle: 'May require AGS restart.', type: 'number' }), ] }) }