feat(weather-widget): add imperial windspeed option (#4253)
This commit is contained in:
@@ -47,3 +47,8 @@ export const humanFileSize = (size: number, concat = ""): string => {
|
||||
}
|
||||
return "∞";
|
||||
};
|
||||
|
||||
const IMPERIAL_MULTIPLIER = 1.609344;
|
||||
|
||||
export const metricToImperial = (metricValue: number) => metricValue / IMPERIAL_MULTIPLIER;
|
||||
export const imperialToMetric = (imperialValue: number) => imperialValue * IMPERIAL_MULTIPLIER;
|
||||
|
||||
@@ -88,6 +88,7 @@ const optionMapping: OptionMapping = {
|
||||
location: (oldOptions) => oldOptions.location,
|
||||
showCity: (oldOptions) => oldOptions.displayCityName,
|
||||
dateFormat: (oldOptions) => (oldOptions.dateFormat === "hide" ? undefined : oldOptions.dateFormat),
|
||||
useImperialSpeed: () => undefined,
|
||||
},
|
||||
iframe: {
|
||||
embedUrl: (oldOptions) => oldOptions.embedUrl,
|
||||
|
||||
@@ -1145,6 +1145,12 @@
|
||||
"groupNameTaken": "Group name already taken"
|
||||
}
|
||||
}
|
||||
},
|
||||
"unit": {
|
||||
"speed": {
|
||||
"kilometersPerHour": "km/h",
|
||||
"milesPerHour": "mph"
|
||||
}
|
||||
}
|
||||
},
|
||||
"section": {
|
||||
@@ -1744,6 +1750,9 @@
|
||||
"label": "Show current wind speed",
|
||||
"description": "Only on current weather"
|
||||
},
|
||||
"useImperialSpeed": {
|
||||
"label": "Use mph for windspeed"
|
||||
},
|
||||
"location": {
|
||||
"label": "Weather location"
|
||||
},
|
||||
@@ -1762,12 +1771,12 @@
|
||||
"description": "How the date should look like"
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "{currentWindSpeed} km/h",
|
||||
"currentWindSpeed": "{currentWindSpeed} {unit}",
|
||||
"dailyForecast": {
|
||||
"sunrise": "Sunrise",
|
||||
"sunset": "Sunset",
|
||||
"maxWindSpeed": "Max wind speed: {maxWindSpeed} km/h",
|
||||
"maxWindGusts": "Max wind gusts: {maxWindGusts} km/h"
|
||||
"maxWindSpeed": "Max wind speed: {maxWindSpeed} {unit}",
|
||||
"maxWindGusts": "Max wind gusts: {maxWindGusts} {unit}"
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Clear",
|
||||
|
||||
@@ -7,6 +7,7 @@ import dayjs from "dayjs";
|
||||
|
||||
import type { RouterOutputs } from "@homarr/api";
|
||||
import { clientApi } from "@homarr/api/client";
|
||||
import { metricToImperial } from "@homarr/common";
|
||||
import { useScopedI18n } from "@homarr/translation/client";
|
||||
|
||||
import type { WidgetComponentProps } from "../definition";
|
||||
@@ -52,6 +53,7 @@ interface WeatherProps extends Pick<WidgetComponentProps<"weather">, "options">
|
||||
|
||||
const DailyWeather = ({ options, weather }: WeatherProps) => {
|
||||
const t = useScopedI18n("widget.weather");
|
||||
const tCommon = useScopedI18n("common");
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -78,7 +80,17 @@ const DailyWeather = ({ options, weather }: WeatherProps) => {
|
||||
{options.showCurrentWindSpeed && (
|
||||
<Group className="weather-current-wind-speed-group" wrap="nowrap" gap="xs">
|
||||
<IconWind size={16} />
|
||||
<Text fz={16}>{t("currentWindSpeed", { currentWindSpeed: String(weather.current.windspeed) })}</Text>
|
||||
<Text fz={16}>
|
||||
{t("currentWindSpeed", {
|
||||
currentWindSpeed: (options.useImperialSpeed
|
||||
? metricToImperial(weather.current.windspeed)
|
||||
: weather.current.windspeed
|
||||
).toFixed(1),
|
||||
unit: options.useImperialSpeed
|
||||
? tCommon("unit.speed.milesPerHour")
|
||||
: tCommon("unit.speed.kilometersPerHour"),
|
||||
})}
|
||||
</Text>
|
||||
</Group>
|
||||
)}
|
||||
<Group className="weather-max-min-temp-group" wrap="nowrap" gap="sm">
|
||||
@@ -180,6 +192,7 @@ function Forecast({ weather, options }: WeatherProps) {
|
||||
</HoverCard.Target>
|
||||
<HoverCard.Dropdown>
|
||||
<WeatherDescription
|
||||
useImperialSpeed={options.useImperialSpeed}
|
||||
dateFormat={dateFormat}
|
||||
time={dayWeather.time}
|
||||
weatherCode={dayWeather.weatherCode}
|
||||
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
} from "@tabler/icons-react";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
import { metricToImperial } from "@homarr/common";
|
||||
import type { TranslationObject } from "@homarr/translation";
|
||||
import { useScopedI18n } from "@homarr/translation/client";
|
||||
import type { TablerIcon } from "@homarr/ui";
|
||||
@@ -40,6 +41,7 @@ export const WeatherIcon = ({ code, size = 50 }: WeatherIconProps) => {
|
||||
|
||||
interface WeatherDescriptionProps {
|
||||
weatherOnly?: boolean;
|
||||
useImperialSpeed?: boolean;
|
||||
dateFormat?: WidgetProps<"weather">["options"]["dateFormat"];
|
||||
time?: string;
|
||||
weatherCode: number;
|
||||
@@ -66,6 +68,7 @@ interface WeatherDescriptionProps {
|
||||
*/
|
||||
export const WeatherDescription = ({
|
||||
weatherOnly,
|
||||
useImperialSpeed,
|
||||
dateFormat,
|
||||
time,
|
||||
weatherCode,
|
||||
@@ -96,12 +99,18 @@ export const WeatherDescription = ({
|
||||
<List.Item icon={<IconMoon size={15} />}>{`${t("dailyForecast.sunset")}: ${sunset}`}</List.Item>
|
||||
{maxWindSpeed !== undefined && (
|
||||
<List.Item icon={<IconWind size={15} />}>
|
||||
{t("dailyForecast.maxWindSpeed", { maxWindSpeed: String(maxWindSpeed) })}
|
||||
{t("dailyForecast.maxWindSpeed", {
|
||||
maxWindSpeed: (useImperialSpeed ? metricToImperial(maxWindSpeed) : maxWindSpeed).toFixed(1),
|
||||
unit: useImperialSpeed ? tCommon("unit.speed.milesPerHour") : tCommon("unit.speed.kilometersPerHour"),
|
||||
})}
|
||||
</List.Item>
|
||||
)}
|
||||
{maxWindGusts !== undefined && (
|
||||
<List.Item icon={<IconWind size={15} />}>
|
||||
{t("dailyForecast.maxWindGusts", { maxWindGusts: String(maxWindGusts) })}
|
||||
{t("dailyForecast.maxWindGusts", {
|
||||
maxWindGusts: (useImperialSpeed ? metricToImperial(maxWindGusts) : maxWindGusts).toFixed(1),
|
||||
unit: useImperialSpeed ? tCommon("unit.speed.milesPerHour") : tCommon("unit.speed.kilometersPerHour"),
|
||||
})}
|
||||
</List.Item>
|
||||
)}
|
||||
</List>
|
||||
|
||||
@@ -13,6 +13,7 @@ export const { definition, componentLoader } = createWidgetDefinition("weather",
|
||||
isFormatFahrenheit: factory.switch(),
|
||||
disableTemperatureDecimals: factory.switch(),
|
||||
showCurrentWindSpeed: factory.switch({ withDescription: true }),
|
||||
useImperialSpeed: factory.switch(),
|
||||
location: factory.location({
|
||||
defaultValue: {
|
||||
name: "Paris",
|
||||
|
||||
Reference in New Issue
Block a user