feat: add weather unit preferences
Some checks failed
CI / Lint, test, typecheck and build (push) Has been cancelled

This commit is contained in:
zv
2026-07-04 20:16:11 +02:00
parent ab6b7b414f
commit 91acdb39b8
27 changed files with 623 additions and 76 deletions

View File

@@ -8,10 +8,12 @@ import { warningMatchesCounty } from "@/lib/warning-regions";
import {
DEFAULT_TEMPERATURE_UNIT,
DEFAULT_WIND_SPEED_UNIT,
DEFAULT_PRECIPITATION_UNIT,
formatPrecipitation as formatDisplayPrecipitation,
formatTemperature as formatDisplayTemperature,
formatWindSpeed,
} from "@/lib/weather-utils";
import type { TemperatureUnit, WindSpeedUnit } from "@/types/units";
import type { PrecipitationUnit, TemperatureUnit, WindSpeedUnit } from "@/types/units";
export type WeatherBriefSeverity = "normal" | "attention" | "warning";
@@ -33,19 +35,10 @@ interface BuildWeatherBriefInput {
language: Language;
temperatureUnit?: TemperatureUnit;
windSpeedUnit?: WindSpeedUnit;
precipitationUnit?: PrecipitationUnit;
now?: Date;
}
function formatNumber(value: number, language: Language, digits = 0) {
return new Intl.NumberFormat(language === "pl" ? "pl-PL" : "en-GB", {
maximumFractionDigits: digits,
}).format(value);
}
function formatRainfall(value: number, language: Language) {
return `${formatNumber(value, language, 1)} mm`;
}
function formatHour(value: string) {
return value.slice(11, 16);
}
@@ -237,6 +230,7 @@ export function buildWeatherBrief({
language,
temperatureUnit = DEFAULT_TEMPERATURE_UNIT,
windSpeedUnit = DEFAULT_WIND_SPEED_UNIT,
precipitationUnit = DEFAULT_PRECIPITATION_UNIT,
now = new Date(),
}: BuildWeatherBriefInput): WeatherBrief | null {
const hours = getUpcomingHours(forecast.hourly, now, 24);
@@ -313,8 +307,8 @@ export function buildWeatherBrief({
: "";
body.push(
language === "pl"
? `Opad: ${rainfallTotal === null ? "brak pełnych danych" : formatRainfall(rainfallTotal, language)}, maks. szansa ${maximumProbability === null ? "brak danych" : `${maximumProbability}%`}.${rainWindow}`
: `Rainfall: ${rainfallTotal === null ? "not fully available" : formatRainfall(rainfallTotal, language)}, max chance ${maximumProbability === null ? "unavailable" : `${maximumProbability}%`}.${rainWindow}`,
? `Opad: ${rainfallTotal === null ? "brak pełnych danych" : formatDisplayPrecipitation(rainfallTotal, language, precipitationUnit)}, maks. szansa ${maximumProbability === null ? "brak danych" : `${maximumProbability}%`}.${rainWindow}`
: `Rainfall: ${rainfallTotal === null ? "not fully available" : formatDisplayPrecipitation(rainfallTotal, language, precipitationUnit)}, max chance ${maximumProbability === null ? "unavailable" : `${maximumProbability}%`}.${rainWindow}`,
);
}
if (maximumWind !== null) {
@@ -371,6 +365,7 @@ export function buildTomorrowWeatherBrief({
language,
temperatureUnit = DEFAULT_TEMPERATURE_UNIT,
windSpeedUnit = DEFAULT_WIND_SPEED_UNIT,
precipitationUnit = DEFAULT_PRECIPITATION_UNIT,
now = new Date(),
}: BuildWeatherBriefInput): WeatherBrief | null {
const targetDateKey = getWarsawDateKey(now, 1);
@@ -453,8 +448,8 @@ export function buildTomorrowWeatherBrief({
: "";
body.push(
language === "pl"
? `Opad: ${rainfallTotal === null ? "brak pełnych danych" : formatRainfall(rainfallTotal, language)}, maks. szansa ${maximumProbability === null ? "brak danych" : `${maximumProbability}%`}.${rainWindow}`
: `Precipitation: ${rainfallTotal === null ? "not fully available" : formatRainfall(rainfallTotal, language)}, max chance ${maximumProbability === null ? "unavailable" : `${maximumProbability}%`}.${rainWindow}`,
? `Opad: ${rainfallTotal === null ? "brak pełnych danych" : formatDisplayPrecipitation(rainfallTotal, language, precipitationUnit)}, maks. szansa ${maximumProbability === null ? "brak danych" : `${maximumProbability}%`}.${rainWindow}`
: `Precipitation: ${rainfallTotal === null ? "not fully available" : formatDisplayPrecipitation(rainfallTotal, language, precipitationUnit)}, max chance ${maximumProbability === null ? "unavailable" : `${maximumProbability}%`}.${rainWindow}`,
);
} else {
body.push(language === "pl" ? "Bez istotnego opadu w prognozie." : "No significant precipitation in the forecast.");
@@ -469,7 +464,7 @@ export function buildTomorrowWeatherBrief({
const rainPushPart =
(hasRainSignal || (rainfallTotal ?? 0) > 0.1) && rainfallTotal !== null
? formatRainfall(rainfallTotal, language)
? formatDisplayPrecipitation(rainfallTotal, language, precipitationUnit)
: null;
const pushParts = [
`${locationName}:`,