aboutsummaryrefslogtreecommitdiffstats
path: root/widgets/details.lua
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-10-18 14:35:05 +0200
committerDanilo M. <danix@danix.xyz>2026-10-18 14:35:05 +0200
commitc72ee8bce374294eca0c14c3f0db142fad40c360 (patch)
tree96c21bd4b2fa19053702582ea5123dc60f039d49 /widgets/details.lua
parent9aba9551e70d8956dee6f030ed7b293348aa299e (diff)
downloadconky-theme-udt-c72ee8bce374294eca0c14c3f0db142fad40c360.tar.gz
conky-theme-udt-c72ee8bce374294eca0c14c3f0db142fad40c360.zip
feat(details): wind, humidity, UV and AQI card adapted from Conky-Mirage
UV and the European AQI carry the ok/warning/critical roles, which puts critical back on the board. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Diffstat (limited to 'widgets/details.lua')
-rw-r--r--widgets/details.lua77
1 files changed, 77 insertions, 0 deletions
diff --git a/widgets/details.lua b/widgets/details.lua
new file mode 100644
index 0000000..a1063a4
--- /dev/null
+++ b/widgets/details.lua
@@ -0,0 +1,77 @@
+-- Details: wind, humidity, UV and air quality, over a wind compass.
+--
+-- Adapted from the Conky-Mirage theme's details tiles by alexsson-xexpanderx
+-- (see lib/weather.lua). UV and AQI are the measured quantities here, so they
+-- carry the ok / warning / critical roles.
+
+local card = require 'lib.card'
+local data = require 'lib.data'
+local weather = require 'lib.weather'
+
+local M = {}
+
+local function draw_compass(cr, x, y, w, h, colors, deg, S)
+ local r = math.min(w, h) / 2 - S * 0.1
+ if r < 24 then return end
+ local cx, cy = x + w / 2, y + h / 2
+ card.rgba(cr, colors.rule, 0.8)
+ cairo_set_line_width(cr, 1)
+ cairo_new_path(cr)
+ cairo_arc(cr, cx, cy, r, 0, math.pi * 2)
+ cairo_stroke(cr)
+
+ local size = math.max(9, r * 0.2)
+ card.font(cr, card.FONT_MONO, size, false)
+ card.rgba(cr, colors.label)
+ for i, p in ipairs({ 'N', 'E', 'S', 'W' }) do
+ local a = (i - 1) * math.pi / 2
+ card.text_centre(cr, cx + (r - size) * math.sin(a),
+ cy - (r - size) * math.cos(a) + size * 0.35, p)
+ end
+
+ if type(deg) ~= 'number' then return end
+ -- Open-Meteo gives where the wind comes FROM; the needle points where it goes.
+ local a = math.rad(deg + 180)
+ local tip = r - size * 2
+ local tx, ty = cx + tip * math.sin(a), cy - tip * math.cos(a)
+ card.rgba(cr, colors.highlight)
+ cairo_set_line_width(cr, math.max(2, r * 0.04))
+ cairo_move_to(cr, cx - tip * 0.6 * math.sin(a), cy + tip * 0.6 * math.cos(a))
+ cairo_line_to(cr, tx, ty)
+ cairo_stroke(cr)
+ cairo_new_path(cr)
+ cairo_arc(cr, tx, ty, math.max(3, r * 0.06), 0, math.pi * 2)
+ cairo_fill(cr)
+end
+
+function M.draw(cr, rect, colors)
+ local inner = card.card(cr, rect, colors)
+ local w = weather.parse(data.slurp(weather.CACHE))
+ if not w then
+ card.notice(cr, inner, colors, 'DETAILS', 'no weather data', 'bin/weather-fetch.sh')
+ return
+ end
+
+ local c = w.current
+ -- UV is the forecast for the current hour; Open-Meteo's current block has none.
+ local uv = (w.hours[1] or {}).uv
+ local aqi = w.air and w.air.aqi
+ local wind = '--'
+ if type(c.wind) == 'number' then
+ wind = weather.num(c.wind) .. ' ' .. weather.wind_unit(w.units)
+ .. ' ' .. (weather.compass(c.wind_deg) or '')
+ end
+ local rows = {
+ { 'WIND', wind },
+ { 'HUMIDITY', weather.num(c.humidity, '%') },
+ { 'UV', type(uv) == 'number' and string.format('%.1f', uv) or '--',
+ colors[weather.uv_role(uv)] },
+ { 'AIR (EAQI)', weather.num(aqi), colors[weather.aqi_role(aqi)] },
+ }
+ local y, S = card.standard(cr, inner, colors, {
+ icon = card.ICON.details, title = 'DETAILS', rows = rows, share = 0.6,
+ })
+ draw_compass(cr, inner.x, y, inner.w, inner.y + inner.h - y, colors, c.wind_deg, S)
+end
+
+return M