mirror of
https://github.com/ajnart/homarr.git
synced 2026-02-08 15:47:01 +01:00
chore(release): automatic release v1.4.0
This commit is contained in:
@@ -32,7 +32,4 @@ DB_URL='FULL_PATH_TO_YOUR_SQLITE_DB_FILE'
|
||||
# If it is used, please use the full path to the directory where the certificates are stored.
|
||||
# LOCAL_CERTIFICATE_PATH='FULL_PATH_TO_CERTIFICATES'
|
||||
|
||||
TURBO_TELEMETRY_DISABLED=1
|
||||
|
||||
# Configure logging to use winston logger
|
||||
NODE_OPTIONS='-r @homarr/log/override'
|
||||
TURBO_TELEMETRY_DISABLED=1
|
||||
1
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
1
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -31,6 +31,7 @@ body:
|
||||
label: Version
|
||||
description: What version of Homarr are you running?
|
||||
options:
|
||||
- 1.3.1
|
||||
- 1.3.0
|
||||
- 1.2.0
|
||||
- 1.1.0
|
||||
|
||||
@@ -63,6 +63,7 @@ ENV DB_URL='/appdata/db/db.sqlite'
|
||||
ENV DB_DIALECT='sqlite'
|
||||
ENV DB_DRIVER='better-sqlite3'
|
||||
ENV AUTH_PROVIDERS='credentials'
|
||||
ENV NODE_ENV='production'
|
||||
|
||||
ENTRYPOINT [ "/app/entrypoint.sh" ]
|
||||
CMD ["sh", "run.sh"]
|
||||
@@ -51,9 +51,9 @@
|
||||
"@million/lint": "1.0.14",
|
||||
"@t3-oss/env-nextjs": "^0.12.0",
|
||||
"@tabler/icons-react": "^3.29.0",
|
||||
"@tanstack/react-query": "^5.65.1",
|
||||
"@tanstack/react-query-devtools": "^5.65.1",
|
||||
"@tanstack/react-query-next-experimental": "^5.65.1",
|
||||
"@tanstack/react-query": "^5.66.0",
|
||||
"@tanstack/react-query-devtools": "^5.66.0",
|
||||
"@tanstack/react-query-next-experimental": "^5.66.0",
|
||||
"@trpc/client": "next",
|
||||
"@trpc/next": "next",
|
||||
"@trpc/react-query": "next",
|
||||
@@ -67,7 +67,7 @@
|
||||
"dotenv": "^16.4.7",
|
||||
"flag-icons": "^7.3.2",
|
||||
"glob": "^11.0.1",
|
||||
"jotai": "^2.11.1",
|
||||
"jotai": "^2.11.2",
|
||||
"mantine-react-table": "2.0.0-beta.8",
|
||||
"next": "15.1.6",
|
||||
"postcss-preset-mantine": "^1.17.0",
|
||||
@@ -86,12 +86,12 @@
|
||||
"@homarr/eslint-config": "workspace:^0.2.0",
|
||||
"@homarr/prettier-config": "workspace:^0.1.0",
|
||||
"@homarr/tsconfig": "workspace:^0.1.0",
|
||||
"@types/chroma-js": "3.1.0",
|
||||
"@types/chroma-js": "3.1.1",
|
||||
"@types/node": "^22.12.0",
|
||||
"@types/prismjs": "^1.26.5",
|
||||
"@types/react": "19.0.8",
|
||||
"@types/react-dom": "19.0.3",
|
||||
"@types/swagger-ui-react": "^4.19.0",
|
||||
"@types/swagger-ui-react": "^5.18.0",
|
||||
"concurrently": "^9.1.2",
|
||||
"eslint": "^9.19.0",
|
||||
"node-loader": "^2.1.0",
|
||||
|
||||
@@ -18,8 +18,8 @@ import superjson from "superjson";
|
||||
import type { SuperJSONResult } from "superjson";
|
||||
|
||||
import type { AppRouter } from "@homarr/api";
|
||||
import { clientApi, getTrpcUrl } from "@homarr/api/client";
|
||||
import { createHeadersCallbackForSource } from "@homarr/api/shared";
|
||||
import { clientApi } from "@homarr/api/client";
|
||||
import { createHeadersCallbackForSource, getTrpcUrl } from "@homarr/api/shared";
|
||||
|
||||
import { env } from "~/env";
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import "~/styles/gridstack.scss";
|
||||
import { IntegrationProvider } from "@homarr/auth/client";
|
||||
import { auth } from "@homarr/auth/next";
|
||||
import { getIntegrationsWithPermissionsAsync } from "@homarr/auth/server";
|
||||
import { isNullOrWhitespace } from "@homarr/common";
|
||||
import { getI18n } from "@homarr/translation/server";
|
||||
|
||||
import { createMetaTitle } from "~/metadata";
|
||||
@@ -48,11 +49,13 @@ export const createBoardContentPage = <TParams extends Record<string, unknown>>(
|
||||
return {
|
||||
title: board.metaTitle ?? createMetaTitle(t("board.content.metaTitle", { boardName: board.name })),
|
||||
icons: {
|
||||
icon: board.faviconImageUrl ?? undefined,
|
||||
apple: board.faviconImageUrl ?? undefined,
|
||||
icon: !isNullOrWhitespace(board.faviconImageUrl) ? board.faviconImageUrl : undefined,
|
||||
apple: !isNullOrWhitespace(board.faviconImageUrl) ? board.faviconImageUrl : undefined,
|
||||
},
|
||||
appleWebApp: {
|
||||
startupImage: { url: board.faviconImageUrl ?? "/logo/logo.png" },
|
||||
startupImage: {
|
||||
url: !isNullOrWhitespace(board.faviconImageUrl) ? board.faviconImageUrl : "/logo/logo.png",
|
||||
},
|
||||
},
|
||||
};
|
||||
} catch (error) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
|
||||
|
||||
import { appRouter, createTRPCContext } from "@homarr/api";
|
||||
import { trpcPath } from "@homarr/api/shared";
|
||||
import { auth } from "@homarr/auth/next";
|
||||
import { logger } from "@homarr/log";
|
||||
|
||||
@@ -25,7 +26,7 @@ export function OPTIONS() {
|
||||
|
||||
const handler = auth(async (req) => {
|
||||
const response = await fetchRequestHandler({
|
||||
endpoint: "/api/trpc",
|
||||
endpoint: trpcPath,
|
||||
router: appRouter,
|
||||
req,
|
||||
createContext: () => createTRPCContext({ session: req.auth, headers: req.headers }),
|
||||
|
||||
@@ -4,7 +4,7 @@ import { createTRPCClient, httpLink } from "@trpc/client";
|
||||
import SuperJSON from "superjson";
|
||||
|
||||
import type { AppRouter } from "@homarr/api";
|
||||
import { createHeadersCallbackForSource } from "@homarr/api/shared";
|
||||
import { createHeadersCallbackForSource, getTrpcUrl } from "@homarr/api/shared";
|
||||
import { createI18nMiddleware } from "@homarr/translation/middleware";
|
||||
|
||||
export async function middleware(request: NextRequest) {
|
||||
@@ -34,7 +34,7 @@ export const config = {
|
||||
export const serverFetchApi = createTRPCClient<AppRouter>({
|
||||
links: [
|
||||
httpLink({
|
||||
url: `http://${process.env.HOSTNAME ?? "localhost"}:3000/api/trpc`,
|
||||
url: getTrpcUrl(),
|
||||
transformer: SuperJSON,
|
||||
headers: createHeadersCallbackForSource("server-fetch"),
|
||||
}),
|
||||
|
||||
@@ -5,7 +5,7 @@ import { createTRPCReact } from "@trpc/react-query";
|
||||
import SuperJSON from "superjson";
|
||||
|
||||
import type { AppRouter } from ".";
|
||||
import { createHeadersCallbackForSource } from "./shared";
|
||||
import { createHeadersCallbackForSource, getTrpcUrl } from "./shared";
|
||||
|
||||
export const clientApi = createTRPCReact<AppRouter>();
|
||||
export const fetchApi = createTRPCClient<AppRouter>({
|
||||
@@ -17,16 +17,3 @@ export const fetchApi = createTRPCClient<AppRouter>({
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
function getBaseUrl() {
|
||||
if (typeof window !== "undefined") return window.location.origin;
|
||||
return `http://localhost:${process.env.PORT ?? 3000}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the full url for the trpc api endpoint
|
||||
* @returns
|
||||
*/
|
||||
export function getTrpcUrl() {
|
||||
return `${getBaseUrl()}/api/trpc`;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { createTRPCRouter, publicProcedure } from "../../trpc";
|
||||
export const weatherRouter = createTRPCRouter({
|
||||
atLocation: publicProcedure.input(validation.widget.weather.atLocationInput).query(async ({ input }) => {
|
||||
const res = await fetchWithTimeout(
|
||||
`https://api.open-meteo.com/v1/forecast?latitude=${input.latitude}&longitude=${input.longitude}&daily=weathercode,temperature_2m_max,temperature_2m_min¤t_weather=true&timezone=auto`,
|
||||
`https://api.open-meteo.com/v1/forecast?latitude=${input.latitude}&longitude=${input.longitude}&daily=weathercode,temperature_2m_max,temperature_2m_min,sunrise,sunset,wind_speed_10m_max,wind_gusts_10m_max¤t_weather=true&timezone=auto`,
|
||||
);
|
||||
const json: unknown = await res.json();
|
||||
const weather = await validation.widget.weather.atLocationOutput.parseAsync(json);
|
||||
@@ -18,6 +18,10 @@ export const weatherRouter = createTRPCRouter({
|
||||
weatherCode: weather.daily.weathercode[index] ?? 404,
|
||||
maxTemp: weather.daily.temperature_2m_max[index],
|
||||
minTemp: weather.daily.temperature_2m_min[index],
|
||||
sunrise: weather.daily.sunrise[index],
|
||||
sunset: weather.daily.sunset[index],
|
||||
maxWindSpeed: weather.daily.wind_speed_10m_max[index],
|
||||
maxWindGusts: weather.daily.wind_gusts_10m_max[index],
|
||||
};
|
||||
}),
|
||||
};
|
||||
|
||||
@@ -36,3 +36,18 @@ async function importCookiesAsync() {
|
||||
.map(({ name, value }) => `${name}=${value}`)
|
||||
.join(";");
|
||||
}
|
||||
|
||||
function getBaseUrl() {
|
||||
if (typeof window !== "undefined") return window.location.origin;
|
||||
return `http://${process.env.HOSTNAME ?? "localhost"}:3000`;
|
||||
}
|
||||
|
||||
export const trpcPath = "/api/trpc";
|
||||
|
||||
/**
|
||||
* Creates the full url for the trpc api endpoint
|
||||
* @returns
|
||||
*/
|
||||
export function getTrpcUrl() {
|
||||
return `${getBaseUrl()}${trpcPath}`;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
export const capitalize = <T extends string>(str: T) => {
|
||||
return (str.charAt(0).toUpperCase() + str.slice(1)) as Capitalize<T>;
|
||||
};
|
||||
|
||||
export const isNullOrWhitespace = (value: string | null): value is null => {
|
||||
return value == null || value.trim() === "";
|
||||
};
|
||||
|
||||
@@ -47,8 +47,8 @@
|
||||
"@testcontainers/mysql": "^10.17.2",
|
||||
"better-sqlite3": "^11.8.1",
|
||||
"dotenv": "^16.4.7",
|
||||
"drizzle-kit": "^0.30.3",
|
||||
"drizzle-orm": "^0.39.0",
|
||||
"drizzle-kit": "^0.30.4",
|
||||
"drizzle-orm": "^0.39.1",
|
||||
"drizzle-zod": "^0.7.0",
|
||||
"mysql2": "3.12.0"
|
||||
},
|
||||
|
||||
@@ -77,6 +77,8 @@ const optionMapping: OptionMapping = {
|
||||
forecastDayCount: (oldOptions) => oldOptions.forecastDays,
|
||||
hasForecast: (oldOptions) => oldOptions.displayWeekly,
|
||||
isFormatFahrenheit: (oldOptions) => oldOptions.displayInFahrenheit,
|
||||
disableTemperatureDecimals: () => undefined,
|
||||
showCurrentWindSpeed: () => undefined,
|
||||
location: (oldOptions) => oldOptions.location,
|
||||
showCity: (oldOptions) => oldOptions.displayCityName,
|
||||
dateFormat: (oldOptions) => (oldOptions.dateFormat === "hide" ? undefined : oldOptions.dateFormat),
|
||||
|
||||
@@ -22,8 +22,10 @@
|
||||
},
|
||||
"prettier": "@homarr/prettier-config",
|
||||
"dependencies": {
|
||||
"@homarr/certificates": "workspace:^0.1.0",
|
||||
"@homarr/common": "workspace:^0.1.0",
|
||||
"@homarr/log": "workspace:^0.1.0"
|
||||
"@homarr/log": "workspace:^0.1.0",
|
||||
"pretty-print-error": "^1.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@homarr/eslint-config": "workspace:^0.2.0",
|
||||
|
||||
@@ -1,13 +1,34 @@
|
||||
import { extractErrorMessage, fetchWithTimeout } from "@homarr/common";
|
||||
import { formatError } from "pretty-print-error";
|
||||
import type { fetch } from "undici";
|
||||
|
||||
import { fetchWithTrustedCertificatesAsync } from "@homarr/certificates/server";
|
||||
import { logger } from "@homarr/log";
|
||||
|
||||
export const sendPingRequestAsync = async (url: string) => {
|
||||
try {
|
||||
return await fetchWithTimeout(url).then((response) => ({ statusCode: response.status }));
|
||||
return await fetchWithTimeoutAndCertificates(url).then((response) => ({ statusCode: response.status }));
|
||||
} catch (error) {
|
||||
logger.error("packages/ping/src/index.ts:", error);
|
||||
logger.error("packages/ping/src/index.ts:", formatError(error));
|
||||
return {
|
||||
error: extractErrorMessage(error),
|
||||
error: formatError(error),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Same as fetch, but with a timeout of 10 seconds.
|
||||
* Also respects certificates.
|
||||
* https://stackoverflow.com/questions/46946380/fetch-api-request-timeout
|
||||
* @param param0 fetch arguments
|
||||
* @returns fetch response
|
||||
*/
|
||||
export const fetchWithTimeoutAndCertificates = (...[url, requestInit]: Parameters<typeof fetch>) => {
|
||||
const controller = new AbortController();
|
||||
|
||||
// 10 seconds timeout:
|
||||
const timeoutId = setTimeout(() => controller.abort(), 10000);
|
||||
|
||||
return fetchWithTrustedCertificatesAsync(url, { signal: controller.signal, ...requestInit }).finally(() => {
|
||||
clearTimeout(timeoutId);
|
||||
});
|
||||
};
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
"@mantine/hooks": "^7.16.2",
|
||||
"@mantine/spotlight": "^7.16.2",
|
||||
"@tabler/icons-react": "^3.29.0",
|
||||
"jotai": "^2.11.1",
|
||||
"jotai": "^2.11.2",
|
||||
"next": "15.1.6",
|
||||
"react": "19.0.0",
|
||||
"react-dom": "19.0.0",
|
||||
|
||||
3247
packages/translation/src/lang/ca.json
Normal file
3247
packages/translation/src/lang/ca.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": "华氏温度"
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": "天气位置"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": "日期应该是什么样的"
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "晴朗",
|
||||
"mainlyClear": "晴朗为主",
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": "Teplota ve Fahrenheitech"
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": "Lokalita pro počasí"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": "Jak by datum mělo vypadat"
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Jasno",
|
||||
"mainlyClear": "Převážně jasno",
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": "Temperatur i Fahrenheit"
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": "Deaktiver temperaturdecimaler"
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "Vis aktuel vindhastighed",
|
||||
"description": "Kun på nuværende vejr"
|
||||
},
|
||||
"location": {
|
||||
"label": "Vejr lokation"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": "Hvordan datoen skal se ud"
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "{currentWindSpeed} km/t",
|
||||
"dailyForecast": {
|
||||
"sunrise": "Solopgang",
|
||||
"sunset": "Solnedgang",
|
||||
"maxWindSpeed": "Maks. vindhastighed: {maxWindSpeed} km/t",
|
||||
"maxWindGusts": "Maks. vindstød {maxWindGusts} km/t"
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Skyfrit",
|
||||
"mainlyClear": "Hovedsageligt skyfrit",
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": "Temperatur in Fahrenheit"
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": "Wetterstandort"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": "Wie das Datum aussehen sollte"
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Klar",
|
||||
"mainlyClear": "Überwiegend klar",
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": ""
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": "Τοποθεσία καιρού"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Καθαρός",
|
||||
"mainlyClear": "Κυρίως καθαρός",
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": "Temperature in Fahrenheit"
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": "Disable temperature decimals"
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "Show current wind speed",
|
||||
"description": "Only on current weather"
|
||||
},
|
||||
"location": {
|
||||
"label": "Weather location"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": "How the date should look like"
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "{currentWindSpeed} km/h",
|
||||
"dailyForecast": {
|
||||
"sunrise": "Sunrise",
|
||||
"sunset": "Sunset",
|
||||
"maxWindSpeed": "Max wind speed: {maxWindSpeed} km/h",
|
||||
"maxWindGusts": "Max wind gusts: {maxWindGusts} km/h"
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Clear",
|
||||
"mainlyClear": "Mainly clear",
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": ""
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": "Ubicación"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Despejado",
|
||||
"mainlyClear": "Mayormente despejado",
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": ""
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": ""
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "",
|
||||
"mainlyClear": "",
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": ""
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": "Lieu de la météo"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Clair",
|
||||
"mainlyClear": "Principalement clair",
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": "טמפרטורה בפרנהייט"
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": "מיקום מזג האוויר"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": "איך צריך להיראות התאריך"
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "בהיר",
|
||||
"mainlyClear": "בהיר בעיקר",
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": ""
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": "Lokacija vremenske prognoze"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Vedro",
|
||||
"mainlyClear": "Uglavnom vedro",
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": ""
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": "Időjárás helye"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": "Hogyan nézzen ki a dátum"
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Tiszta",
|
||||
"mainlyClear": "Főként tiszta",
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": ""
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": "Località meteo"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Sereno",
|
||||
"mainlyClear": "Per lo più sereno",
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": ""
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": "天候の場所"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "クリア",
|
||||
"mainlyClear": "主なクリア事項",
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": ""
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": "날씨 위치"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "맑음",
|
||||
"mainlyClear": "대체로 맑음",
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": ""
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": ""
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "",
|
||||
"mainlyClear": "",
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": ""
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": "Laikapstākļu atrašānās vieta"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Skaidrs",
|
||||
"mainlyClear": "Galvenokārt skaidrs",
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": "Temperatuur in fahrenheit"
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": "Weerlocatie"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": "Hoe de datum eruit moet zien"
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Wissen",
|
||||
"mainlyClear": "Overwegend helder",
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": "Temperatur i Fahrenheit"
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": "Vær plassering"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": "Hvordan datoen skal se ut"
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Tøm",
|
||||
"mainlyClear": "Klar himmel",
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": "Temperatura w Fahrenheit"
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": "Lokalizacja pogody"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": "Jak powinna wyglądać data"
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Bezchmurnie",
|
||||
"mainlyClear": "Częściowe zachmurzenie",
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": ""
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": "Localização do tempo"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Limpar",
|
||||
"mainlyClear": "Principalmente claro",
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": ""
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": "Locație meteo"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Senin",
|
||||
"mainlyClear": "Parțial noros",
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": "Температура в градусах Фаренгейта"
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": "Местоположение"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": "Как должна отображаться дата"
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Ясно",
|
||||
"mainlyClear": "Преимущественно ясно",
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": "Teplota vo stupňoch Fahrenheita"
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": "Poloha počasia"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": "Ako by mal dátum vyzerať"
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Jasno",
|
||||
"mainlyClear": "Prevažne jasno",
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": ""
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": "Lokacija vremena"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Počisti",
|
||||
"mainlyClear": "Večinoma jasno",
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": ""
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": "Plats för väder"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Klart",
|
||||
"mainlyClear": "Främst klart",
|
||||
|
||||
@@ -153,10 +153,10 @@
|
||||
"label": "Pingler İçin Simgeler Kullanın"
|
||||
},
|
||||
"defaultSearchEngine": {
|
||||
"label": ""
|
||||
"label": "Öntanımlı arama motoru"
|
||||
},
|
||||
"openSearchInNewTab": {
|
||||
"label": ""
|
||||
"label": "Arama sonucunu yeni sekmede aç"
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
@@ -219,10 +219,10 @@
|
||||
"changeSearchPreferences": {
|
||||
"notification": {
|
||||
"success": {
|
||||
"message": ""
|
||||
"message": "Arama tercihleri başarıyla değiştirildi"
|
||||
},
|
||||
"error": {
|
||||
"message": ""
|
||||
"message": "Arama tercihleri değiştirilemiyor"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": "Fahrenheit cinsinden sıcaklık"
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": "Sıcaklık ondalıklarını devre dışı bırak"
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "Mevcut rüzgar hızını göster",
|
||||
"description": "Yalnızca mevcut hava durumunda"
|
||||
},
|
||||
"location": {
|
||||
"label": "Hava durumu konumu"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": "Tarihin nasıl görüneceği"
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "{currentWindSpeed} km/s",
|
||||
"dailyForecast": {
|
||||
"sunrise": "Gün Doğumu",
|
||||
"sunset": "Gün Batımı",
|
||||
"maxWindSpeed": "Maks. Rüzgar Hızı: {maxWindSpeed} km/s",
|
||||
"maxWindGusts": "Maks. Rüzgar Hamlesi: {maxWindGusts} km/h"
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Temiz",
|
||||
"mainlyClear": "Genel olarak açık",
|
||||
@@ -2287,7 +2301,7 @@
|
||||
"mobile": "Mobil"
|
||||
}
|
||||
},
|
||||
"search": "",
|
||||
"search": "Ara",
|
||||
"firstDayOfWeek": "Haftanın ilk günü",
|
||||
"accessibility": "Erişilebilirlik"
|
||||
}
|
||||
|
||||
@@ -153,10 +153,10 @@
|
||||
"label": "Використовувати значки для ping"
|
||||
},
|
||||
"defaultSearchEngine": {
|
||||
"label": ""
|
||||
"label": "Стандартна система пошуку"
|
||||
},
|
||||
"openSearchInNewTab": {
|
||||
"label": ""
|
||||
"label": "Відкрити результати пошуку в новій вкладці"
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
@@ -222,7 +222,7 @@
|
||||
"message": ""
|
||||
},
|
||||
"error": {
|
||||
"message": ""
|
||||
"message": "Не вдалося змінити налаштування пошуку"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": "Температура за Фаренгейтом"
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": "Погодна локація"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Ясно",
|
||||
"mainlyClear": "Здебільшого ясно",
|
||||
@@ -1575,8 +1589,8 @@
|
||||
}
|
||||
},
|
||||
"mediaServer": {
|
||||
"name": "",
|
||||
"description": "",
|
||||
"name": "Поточні потоки медіасервера",
|
||||
"description": "Показує поточні потоки з ваших медіасерверів",
|
||||
"option": {},
|
||||
"items": {
|
||||
"user": "Користувач",
|
||||
@@ -1674,7 +1688,7 @@
|
||||
},
|
||||
"state": {
|
||||
"columnTitle": "Стан",
|
||||
"detailsTitle": ""
|
||||
"detailsTitle": "Стан"
|
||||
},
|
||||
"time": {
|
||||
"columnTitle": "Час завершення",
|
||||
@@ -1682,7 +1696,7 @@
|
||||
},
|
||||
"type": {
|
||||
"columnTitle": "Тип",
|
||||
"detailsTitle": ""
|
||||
"detailsTitle": "Тип клієнта"
|
||||
},
|
||||
"upSpeed": {
|
||||
"columnTitle": "Віддача",
|
||||
@@ -1696,10 +1710,10 @@
|
||||
"completed": "Завершено",
|
||||
"failed": "Невдало",
|
||||
"processing": "В обробці",
|
||||
"leeching": "",
|
||||
"leeching": "Завантажується",
|
||||
"stalled": "",
|
||||
"unknown": "Невідомо",
|
||||
"seeding": ""
|
||||
"seeding": "Роздається"
|
||||
},
|
||||
"actions": {
|
||||
"clients": {
|
||||
@@ -1828,7 +1842,7 @@
|
||||
}
|
||||
},
|
||||
"rssFeed": {
|
||||
"name": "",
|
||||
"name": "RSS-канали",
|
||||
"description": "",
|
||||
"option": {
|
||||
"feedUrls": {
|
||||
@@ -2079,20 +2093,20 @@
|
||||
"rename": {
|
||||
"label": "Перейменувати дошку",
|
||||
"description": "",
|
||||
"button": "",
|
||||
"button": "Змінити назву",
|
||||
"modal": {
|
||||
"title": ""
|
||||
"title": "Перейменувати дошку"
|
||||
}
|
||||
},
|
||||
"visibility": {
|
||||
"label": "",
|
||||
"label": "Змінити видимість дошки",
|
||||
"description": {
|
||||
"public": "",
|
||||
"private": ""
|
||||
"public": "Ця дошка є загальнодоступною.",
|
||||
"private": "Ця дошка є приватною."
|
||||
},
|
||||
"button": {
|
||||
"public": "",
|
||||
"private": ""
|
||||
"public": "Зробити приватною",
|
||||
"private": "Зробити загальнодоступною"
|
||||
},
|
||||
"confirm": {
|
||||
"public": {
|
||||
@@ -2281,13 +2295,13 @@
|
||||
"item": {
|
||||
"language": "Мова та Регіон",
|
||||
"board": {
|
||||
"title": "",
|
||||
"title": "Домашня дошка",
|
||||
"type": {
|
||||
"general": "",
|
||||
"mobile": ""
|
||||
"mobile": "Мобільна"
|
||||
}
|
||||
},
|
||||
"search": "",
|
||||
"search": "Пошук",
|
||||
"firstDayOfWeek": "Перший день тижня",
|
||||
"accessibility": "Доступність"
|
||||
}
|
||||
@@ -2304,11 +2318,11 @@
|
||||
"title": "Користувачі"
|
||||
},
|
||||
"edit": {
|
||||
"metaTitle": ""
|
||||
"metaTitle": "Редагувати користувача {username}"
|
||||
},
|
||||
"create": {
|
||||
"metaTitle": "Створити користувача",
|
||||
"title": "",
|
||||
"title": "Створити нового користувача",
|
||||
"step": {
|
||||
"personalInformation": {
|
||||
"label": ""
|
||||
@@ -2317,23 +2331,23 @@
|
||||
"label": "Безпека"
|
||||
},
|
||||
"groups": {
|
||||
"label": "",
|
||||
"title": "",
|
||||
"label": "Групи",
|
||||
"title": "Виберіть усі групи, учасником яких має бути користувач",
|
||||
"description": ""
|
||||
},
|
||||
"review": {
|
||||
"label": ""
|
||||
},
|
||||
"completed": {
|
||||
"title": ""
|
||||
"title": "Користувача створено"
|
||||
},
|
||||
"error": {
|
||||
"title": ""
|
||||
"title": "Не вдалося створити користувача"
|
||||
}
|
||||
},
|
||||
"action": {
|
||||
"createAnother": "",
|
||||
"back": ""
|
||||
"createAnother": "Створити іншого користувача",
|
||||
"back": "Повернутися до списку користувачів"
|
||||
}
|
||||
},
|
||||
"invite": {
|
||||
@@ -2371,23 +2385,23 @@
|
||||
}
|
||||
},
|
||||
"group": {
|
||||
"back": "",
|
||||
"back": "Назад до груп",
|
||||
"setting": {
|
||||
"general": {
|
||||
"title": "Загальне",
|
||||
"owner": "Власник",
|
||||
"ownerOfGroup": "",
|
||||
"ownerOfGroupDeleted": ""
|
||||
"ownerOfGroup": "Власник цієї групи",
|
||||
"ownerOfGroupDeleted": "Власника цієї групи видалено. Наразі не має власника."
|
||||
},
|
||||
"members": {
|
||||
"title": "",
|
||||
"search": "",
|
||||
"notFound": ""
|
||||
"title": "Учасники",
|
||||
"search": "Знайти учасника",
|
||||
"notFound": "Учасників не знайдено"
|
||||
},
|
||||
"permissions": {
|
||||
"title": "",
|
||||
"title": "Дозволи",
|
||||
"form": {
|
||||
"unsavedChanges": ""
|
||||
"unsavedChanges": "У вас є незбережені зміни!"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2477,7 +2491,7 @@
|
||||
},
|
||||
"tool": {
|
||||
"tasks": {
|
||||
"title": "",
|
||||
"title": "Завдання",
|
||||
"status": {
|
||||
"idle": "",
|
||||
"running": "Запущено",
|
||||
@@ -2485,13 +2499,13 @@
|
||||
},
|
||||
"job": {
|
||||
"minecraftServerStatus": {
|
||||
"label": ""
|
||||
"label": "Статус сервера Minecraft"
|
||||
},
|
||||
"iconsUpdater": {
|
||||
"label": ""
|
||||
},
|
||||
"analytics": {
|
||||
"label": ""
|
||||
"label": "Аналітика"
|
||||
},
|
||||
"smartHomeEntityState": {
|
||||
"label": ""
|
||||
@@ -2591,7 +2605,7 @@
|
||||
"table": {
|
||||
"updated": "Оновлено {when}",
|
||||
"search": "",
|
||||
"selected": ""
|
||||
"selected": "Вибрано {selectCount} із {totalCount} контейнерів"
|
||||
},
|
||||
"field": {
|
||||
"name": {
|
||||
@@ -2852,25 +2866,25 @@
|
||||
}
|
||||
},
|
||||
"integration": {
|
||||
"title": ""
|
||||
"title": "Інтеграції"
|
||||
}
|
||||
}
|
||||
},
|
||||
"command": {
|
||||
"help": "",
|
||||
"help": "Активувати командний режим",
|
||||
"group": {
|
||||
"localCommand": {
|
||||
"title": ""
|
||||
"title": "Локальні команди"
|
||||
},
|
||||
"globalCommand": {
|
||||
"title": "",
|
||||
"option": {
|
||||
"colorScheme": {
|
||||
"light": "",
|
||||
"dark": ""
|
||||
"light": "Перемикнути на світлу тему",
|
||||
"dark": "Перемикнути на темну тему"
|
||||
},
|
||||
"language": {
|
||||
"label": "",
|
||||
"label": "Змінити мову",
|
||||
"children": {
|
||||
"detail": {
|
||||
"title": ""
|
||||
@@ -2881,53 +2895,53 @@
|
||||
"label": "Створити нову дошку"
|
||||
},
|
||||
"importBoard": {
|
||||
"label": ""
|
||||
"label": "Імпортувати дошку"
|
||||
},
|
||||
"newApp": {
|
||||
"label": ""
|
||||
"label": "Створити новий додаток"
|
||||
},
|
||||
"newIntegration": {
|
||||
"label": "",
|
||||
"label": "Створити нову інтеграцію",
|
||||
"children": {
|
||||
"detail": {
|
||||
"title": ""
|
||||
"title": "Виберіть тип інтеграції, який потрібно створити"
|
||||
}
|
||||
}
|
||||
},
|
||||
"newUser": {
|
||||
"label": ""
|
||||
"label": "Створити нового користувача"
|
||||
},
|
||||
"newInvite": {
|
||||
"label": "Створити нове запрошення"
|
||||
},
|
||||
"newGroup": {
|
||||
"label": ""
|
||||
"label": "Створити нову групу"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"media": {
|
||||
"requestMovie": "",
|
||||
"requestSeries": "",
|
||||
"openIn": ""
|
||||
"requestMovie": "Запросити фільм",
|
||||
"requestSeries": "Запросити серіал",
|
||||
"openIn": "Відкрити в {kind}"
|
||||
},
|
||||
"external": {
|
||||
"help": "Використовувати зовнішню пошукову систему",
|
||||
"group": {
|
||||
"searchEngine": {
|
||||
"title": "",
|
||||
"title": "Пошукові системи",
|
||||
"children": {
|
||||
"action": {
|
||||
"search": {
|
||||
"label": ""
|
||||
"label": "Шукати з {name}"
|
||||
}
|
||||
},
|
||||
"detail": {
|
||||
"title": ""
|
||||
"title": "Виберіть дію для пошукової системи"
|
||||
},
|
||||
"searchResults": {
|
||||
"title": ""
|
||||
"title": "Виберіть результат пошуку для дій"
|
||||
}
|
||||
},
|
||||
"option": {
|
||||
@@ -3053,7 +3067,7 @@
|
||||
"label": "Про програму"
|
||||
},
|
||||
"homeBoard": {
|
||||
"label": ""
|
||||
"label": "Домашня дошка"
|
||||
},
|
||||
"preferences": {
|
||||
"label": "Ваші уподобання"
|
||||
@@ -3139,21 +3153,21 @@
|
||||
}
|
||||
},
|
||||
"edit": {
|
||||
"title": "",
|
||||
"title": "Редагувати систему пошуку",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
"title": "Зміни успішно застосовано",
|
||||
"message": "Пошукову систему успішно збережено"
|
||||
},
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
"title": "Не вдалося застосувати зміни",
|
||||
"message": "Не вдалося зберегти пошукову систему"
|
||||
}
|
||||
},
|
||||
"configControl": "",
|
||||
"configControl": "Конфігурація",
|
||||
"searchEngineType": {
|
||||
"generic": "",
|
||||
"fromIntegration": ""
|
||||
"fromIntegration": "З інтеграції"
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
@@ -3182,7 +3196,7 @@
|
||||
}
|
||||
},
|
||||
"button": {
|
||||
"send": ""
|
||||
"send": "Надіслати запит"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3195,36 +3209,36 @@
|
||||
"title": "",
|
||||
"description": "",
|
||||
"noResults": {
|
||||
"title": ""
|
||||
"title": "Сертифікати відсутні"
|
||||
},
|
||||
"expires": ""
|
||||
}
|
||||
},
|
||||
"action": {
|
||||
"create": {
|
||||
"label": "",
|
||||
"label": "Додати сертифікат",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
"title": "Додано сертифікат",
|
||||
"message": "Сертифікат було успішно додано"
|
||||
},
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
"title": "Не вдалося додати сертифікат",
|
||||
"message": "Не вдалося додати сертифікат"
|
||||
}
|
||||
}
|
||||
},
|
||||
"remove": {
|
||||
"label": "",
|
||||
"confirm": "",
|
||||
"label": "Видалити сертифікат",
|
||||
"confirm": "Ви впевнені, що хочете видалити сертифікат?",
|
||||
"notification": {
|
||||
"success": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
"title": "Сертифікат видалено",
|
||||
"message": "Сертифікат успішно видалено"
|
||||
},
|
||||
"error": {
|
||||
"title": "",
|
||||
"message": ""
|
||||
"title": "Сертификат не видалено",
|
||||
"message": "Не вдалося видалити сертифікат"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": ""
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": "Vị trí thời tiết"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Quang đãng",
|
||||
"mainlyClear": "Thông thoáng",
|
||||
|
||||
@@ -153,10 +153,10 @@
|
||||
"label": "為 Pings 使用 icon"
|
||||
},
|
||||
"defaultSearchEngine": {
|
||||
"label": ""
|
||||
"label": "預設搜尋引擎"
|
||||
},
|
||||
"openSearchInNewTab": {
|
||||
"label": ""
|
||||
"label": "於新分頁中開啟搜尋結果"
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
@@ -219,10 +219,10 @@
|
||||
"changeSearchPreferences": {
|
||||
"notification": {
|
||||
"success": {
|
||||
"message": ""
|
||||
"message": "搜尋設定更改成功"
|
||||
},
|
||||
"error": {
|
||||
"message": ""
|
||||
"message": "無法更改搜尋設定"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1373,6 +1373,13 @@
|
||||
"isFormatFahrenheit": {
|
||||
"label": "華氏溫度"
|
||||
},
|
||||
"disableTemperatureDecimals": {
|
||||
"label": ""
|
||||
},
|
||||
"showCurrentWindSpeed": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"location": {
|
||||
"label": "天氣位置"
|
||||
},
|
||||
@@ -1391,6 +1398,13 @@
|
||||
"description": "日期應該是什麼樣式"
|
||||
}
|
||||
},
|
||||
"currentWindSpeed": "",
|
||||
"dailyForecast": {
|
||||
"sunrise": "",
|
||||
"sunset": "",
|
||||
"maxWindSpeed": "",
|
||||
"maxWindGusts": ""
|
||||
},
|
||||
"kind": {
|
||||
"clear": "晴朗",
|
||||
"mainlyClear": "大多晴朗",
|
||||
@@ -1426,8 +1440,8 @@
|
||||
"name": "系統健康監測",
|
||||
"description": "顯示系統運行狀態",
|
||||
"tab": {
|
||||
"system": "",
|
||||
"cluster": ""
|
||||
"system": "系統",
|
||||
"cluster": "叢集"
|
||||
},
|
||||
"option": {
|
||||
"fahrenheit": {
|
||||
@@ -2287,7 +2301,7 @@
|
||||
"mobile": "移動裝置"
|
||||
}
|
||||
},
|
||||
"search": "",
|
||||
"search": "搜尋",
|
||||
"firstDayOfWeek": "一周的第一天",
|
||||
"accessibility": "無障礙服務"
|
||||
}
|
||||
|
||||
@@ -9,12 +9,17 @@ export const atLocationOutput = z.object({
|
||||
current_weather: z.object({
|
||||
weathercode: z.number(),
|
||||
temperature: z.number(),
|
||||
windspeed: z.number(),
|
||||
}),
|
||||
daily: z.object({
|
||||
time: z.array(z.string()),
|
||||
weathercode: z.array(z.number()),
|
||||
temperature_2m_max: z.array(z.number()),
|
||||
temperature_2m_min: z.array(z.number()),
|
||||
sunrise: z.array(z.string()),
|
||||
sunset: z.array(z.string()),
|
||||
wind_speed_10m_max: z.array(z.number()),
|
||||
wind_gusts_10m_max: z.array(z.number()),
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@@ -44,21 +44,21 @@
|
||||
"@mantine/core": "^7.16.2",
|
||||
"@mantine/hooks": "^7.16.2",
|
||||
"@tabler/icons-react": "^3.29.0",
|
||||
"@tiptap/extension-color": "2.11.3",
|
||||
"@tiptap/extension-highlight": "2.11.3",
|
||||
"@tiptap/extension-image": "2.11.3",
|
||||
"@tiptap/extension-link": "^2.11.3",
|
||||
"@tiptap/extension-table": "2.11.3",
|
||||
"@tiptap/extension-table-cell": "2.11.3",
|
||||
"@tiptap/extension-table-header": "2.11.3",
|
||||
"@tiptap/extension-table-row": "2.11.3",
|
||||
"@tiptap/extension-task-item": "2.11.3",
|
||||
"@tiptap/extension-task-list": "2.11.3",
|
||||
"@tiptap/extension-text-align": "2.11.3",
|
||||
"@tiptap/extension-text-style": "2.11.3",
|
||||
"@tiptap/extension-underline": "2.11.3",
|
||||
"@tiptap/react": "^2.11.3",
|
||||
"@tiptap/starter-kit": "^2.11.3",
|
||||
"@tiptap/extension-color": "2.11.5",
|
||||
"@tiptap/extension-highlight": "2.11.5",
|
||||
"@tiptap/extension-image": "2.11.5",
|
||||
"@tiptap/extension-link": "^2.11.5",
|
||||
"@tiptap/extension-table": "2.11.5",
|
||||
"@tiptap/extension-table-cell": "2.11.5",
|
||||
"@tiptap/extension-table-header": "2.11.5",
|
||||
"@tiptap/extension-table-row": "2.11.5",
|
||||
"@tiptap/extension-task-item": "2.11.5",
|
||||
"@tiptap/extension-task-list": "2.11.5",
|
||||
"@tiptap/extension-text-align": "2.11.5",
|
||||
"@tiptap/extension-text-style": "2.11.5",
|
||||
"@tiptap/extension-underline": "2.11.5",
|
||||
"@tiptap/react": "^2.11.5",
|
||||
"@tiptap/starter-kit": "^2.11.5",
|
||||
"clsx": "^2.1.1",
|
||||
"dayjs": "^1.11.13",
|
||||
"mantine-react-table": "2.0.0-beta.8",
|
||||
|
||||
@@ -318,14 +318,15 @@ export const matchFileSystemAndSmart = (fileSystems: FileSystem[], smartData: Sm
|
||||
|
||||
const CpuRing = ({ cpuUtilization }: { cpuUtilization: number }) => {
|
||||
const { width, ref } = useElementSize();
|
||||
const fallbackWidth = width || 1; // See https://github.com/homarr-labs/homarr/issues/2196
|
||||
|
||||
return (
|
||||
<Box ref={ref} w="100%" h="100%" className="health-monitoring-cpu">
|
||||
<RingProgress
|
||||
className="health-monitoring-cpu-utilization"
|
||||
roundCaps
|
||||
size={width * 0.95}
|
||||
thickness={width / 10}
|
||||
size={fallbackWidth * 0.95}
|
||||
thickness={fallbackWidth / 10}
|
||||
label={
|
||||
<Center style={{ flexDirection: "column" }}>
|
||||
<Text
|
||||
@@ -348,13 +349,14 @@ const CpuRing = ({ cpuUtilization }: { cpuUtilization: number }) => {
|
||||
|
||||
const CpuTempRing = ({ fahrenheit, cpuTemp }: { fahrenheit: boolean; cpuTemp: number }) => {
|
||||
const { width, ref } = useElementSize();
|
||||
const fallbackWidth = width || 1; // See https://github.com/homarr-labs/homarr/issues/2196
|
||||
return (
|
||||
<Box ref={ref} w="100%" h="100%" className="health-monitoring-cpu-temperature">
|
||||
<RingProgress
|
||||
className="health-monitoring-cpu-temp"
|
||||
roundCaps
|
||||
size={width * 0.95}
|
||||
thickness={width / 10}
|
||||
size={fallbackWidth * 0.95}
|
||||
thickness={fallbackWidth / 10}
|
||||
label={
|
||||
<Center style={{ flexDirection: "column" }}>
|
||||
<Text className="health-monitoring-cpu-temp-value" size="3cqmin">
|
||||
@@ -376,6 +378,7 @@ const CpuTempRing = ({ fahrenheit, cpuTemp }: { fahrenheit: boolean; cpuTemp: nu
|
||||
|
||||
const MemoryRing = ({ available, used }: { available: string; used: string }) => {
|
||||
const { width, ref } = useElementSize();
|
||||
const fallbackWidth = width || 1; // See https://github.com/homarr-labs/homarr/issues/2196
|
||||
const memoryUsage = formatMemoryUsage(available, used);
|
||||
|
||||
return (
|
||||
@@ -383,8 +386,8 @@ const MemoryRing = ({ available, used }: { available: string; used: string }) =>
|
||||
<RingProgress
|
||||
className="health-monitoring-memory-use"
|
||||
roundCaps
|
||||
size={width * 0.95}
|
||||
thickness={width / 10}
|
||||
size={fallbackWidth * 0.95}
|
||||
thickness={fallbackWidth / 10}
|
||||
label={
|
||||
<Center style={{ flexDirection: "column" }}>
|
||||
<Text className="health-monitoring-memory-value" size="3cqmin">
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
"use client";
|
||||
|
||||
import { Box, Group, HoverCard, Space, Stack, Text } from "@mantine/core";
|
||||
import { IconArrowDownRight, IconArrowUpRight, IconMapPin } from "@tabler/icons-react";
|
||||
import { IconArrowDownRight, IconArrowUpRight, IconMapPin, IconWind } from "@tabler/icons-react";
|
||||
import combineClasses from "clsx";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
import type { RouterOutputs } from "@homarr/api";
|
||||
import { clientApi } from "@homarr/api/client";
|
||||
import { useScopedI18n } from "@homarr/translation/client";
|
||||
|
||||
import type { WidgetComponentProps } from "../definition";
|
||||
import { WeatherDescription, WeatherIcon } from "./icon";
|
||||
@@ -47,6 +48,7 @@ interface WeatherProps extends Pick<WidgetComponentProps<"weather">, "options">
|
||||
}
|
||||
|
||||
const DailyWeather = ({ options, weather }: WeatherProps) => {
|
||||
const t = useScopedI18n("widget.weather");
|
||||
return (
|
||||
<>
|
||||
<Group className="weather-day-group" gap="1cqmin">
|
||||
@@ -60,15 +62,32 @@ const DailyWeather = ({ options, weather }: WeatherProps) => {
|
||||
<WeatherDescription weatherOnly weatherCode={weather.current.weathercode} />
|
||||
</HoverCard.Dropdown>
|
||||
</HoverCard>
|
||||
<Text fz="17.5cqmin">{getPreferredUnit(weather.current.temperature, options.isFormatFahrenheit)}</Text>
|
||||
<Text fz="17.5cqmin">
|
||||
{getPreferredUnit(
|
||||
weather.current.temperature,
|
||||
options.isFormatFahrenheit,
|
||||
options.disableTemperatureDecimals,
|
||||
)}
|
||||
</Text>
|
||||
</Group>
|
||||
<Space h="1cqmin" />
|
||||
{options.showCurrentWindSpeed && (
|
||||
<Group className="weather-current-wind-speed-group" wrap="nowrap" gap="1cqmin">
|
||||
<IconWind size="12.5cqmin" />
|
||||
<Text fz="10cqmin">{t("currentWindSpeed", { currentWindSpeed: weather.current.windspeed })}</Text>
|
||||
</Group>
|
||||
)}
|
||||
<Space h="1cqmin" />
|
||||
<Group className="weather-max-min-temp-group" wrap="nowrap" gap="1cqmin">
|
||||
<IconArrowUpRight size="12.5cqmin" />
|
||||
<Text fz="10cqmin">{getPreferredUnit(weather.daily[0]?.maxTemp, options.isFormatFahrenheit)}</Text>
|
||||
<Text fz="10cqmin">
|
||||
{getPreferredUnit(weather.daily[0]?.maxTemp, options.isFormatFahrenheit, options.disableTemperatureDecimals)}
|
||||
</Text>
|
||||
<Space w="2.5cqmin" />
|
||||
<IconArrowDownRight size="12.5cqmin" />
|
||||
<Text fz="10cqmin">{getPreferredUnit(weather.daily[0]?.minTemp, options.isFormatFahrenheit)}</Text>
|
||||
<Text fz="10cqmin">
|
||||
{getPreferredUnit(weather.daily[0]?.minTemp, options.isFormatFahrenheit, options.disableTemperatureDecimals)}
|
||||
</Text>
|
||||
</Group>
|
||||
{options.showCity && (
|
||||
<>
|
||||
@@ -108,7 +127,13 @@ const WeeklyForecast = ({ options, weather }: WeatherProps) => {
|
||||
<WeatherDescription weatherOnly weatherCode={weather.current.weathercode} />
|
||||
</HoverCard.Dropdown>
|
||||
</HoverCard>
|
||||
<Text fz="20cqmin">{getPreferredUnit(weather.current.temperature, options.isFormatFahrenheit)}</Text>
|
||||
<Text fz="20cqmin">
|
||||
{getPreferredUnit(
|
||||
weather.current.temperature,
|
||||
options.isFormatFahrenheit,
|
||||
options.disableTemperatureDecimals,
|
||||
)}
|
||||
</Text>
|
||||
</Group>
|
||||
<Space h="2.5cqmin" />
|
||||
<Forecast weather={weather} options={options} />
|
||||
@@ -134,7 +159,9 @@ function Forecast({ weather, options }: WeatherProps) {
|
||||
>
|
||||
<Text fz="10cqmin">{dayjs(dayWeather.time).format("dd")}</Text>
|
||||
<WeatherIcon size="15cqmin" code={dayWeather.weatherCode} />
|
||||
<Text fz="10cqmin">{getPreferredUnit(dayWeather.maxTemp, options.isFormatFahrenheit)}</Text>
|
||||
<Text fz="10cqmin">
|
||||
{getPreferredUnit(dayWeather.maxTemp, options.isFormatFahrenheit, options.disableTemperatureDecimals)}
|
||||
</Text>
|
||||
</Stack>
|
||||
</HoverCard.Target>
|
||||
<HoverCard.Dropdown>
|
||||
@@ -142,8 +169,20 @@ function Forecast({ weather, options }: WeatherProps) {
|
||||
dateFormat={dateFormat}
|
||||
time={dayWeather.time}
|
||||
weatherCode={dayWeather.weatherCode}
|
||||
maxTemp={getPreferredUnit(dayWeather.maxTemp, options.isFormatFahrenheit)}
|
||||
minTemp={getPreferredUnit(dayWeather.minTemp, options.isFormatFahrenheit)}
|
||||
maxTemp={getPreferredUnit(
|
||||
dayWeather.maxTemp,
|
||||
options.isFormatFahrenheit,
|
||||
options.disableTemperatureDecimals,
|
||||
)}
|
||||
minTemp={getPreferredUnit(
|
||||
dayWeather.minTemp,
|
||||
options.isFormatFahrenheit,
|
||||
options.disableTemperatureDecimals,
|
||||
)}
|
||||
sunrise={dayjs(dayWeather.sunrise).format("HH:mm")}
|
||||
sunset={dayjs(dayWeather.sunset).format("HH:mm")}
|
||||
maxWindSpeed={dayWeather.maxWindSpeed}
|
||||
maxWindGusts={dayWeather.maxWindGusts}
|
||||
/>
|
||||
</HoverCard.Dropdown>
|
||||
</HoverCard>
|
||||
@@ -152,5 +191,9 @@ function Forecast({ weather, options }: WeatherProps) {
|
||||
);
|
||||
}
|
||||
|
||||
const getPreferredUnit = (value?: number, isFahrenheit = false): string =>
|
||||
value ? (isFahrenheit ? `${(value * (9 / 5) + 32).toFixed(1)}°F` : `${value.toFixed(1)}°C`) : "?";
|
||||
const getPreferredUnit = (value?: number, isFahrenheit = false, disableTemperatureDecimals = false): string =>
|
||||
value
|
||||
? isFahrenheit
|
||||
? `${(value * (9 / 5) + 32).toFixed(disableTemperatureDecimals ? 0 : 1)}°F`
|
||||
: `${value.toFixed(disableTemperatureDecimals ? 0 : 1)}°C`
|
||||
: "?";
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
import { Stack, Text } from "@mantine/core";
|
||||
import { List, Stack, Text } from "@mantine/core";
|
||||
import {
|
||||
IconCloud,
|
||||
IconCloudFog,
|
||||
IconCloudRain,
|
||||
IconCloudSnow,
|
||||
IconCloudStorm,
|
||||
IconMoon,
|
||||
IconQuestionMark,
|
||||
IconSnowflake,
|
||||
IconSun,
|
||||
IconTemperatureMinus,
|
||||
IconTemperaturePlus,
|
||||
IconWind,
|
||||
} from "@tabler/icons-react";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
@@ -41,6 +45,10 @@ interface WeatherDescriptionProps {
|
||||
weatherCode: number;
|
||||
maxTemp?: string;
|
||||
minTemp?: string;
|
||||
sunrise?: string;
|
||||
sunset?: string;
|
||||
maxWindSpeed?: number;
|
||||
maxWindGusts?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,6 +58,10 @@ interface WeatherDescriptionProps {
|
||||
* @param weatherCode weather code from api
|
||||
* @param maxTemp preformatted string for max temperature
|
||||
* @param minTemp preformatted string for min temperature
|
||||
* @param sunrise preformatted string for sunrise time
|
||||
* @param sunset preformatted string for sunset time
|
||||
* @param maxWindSpeed maximum wind speed
|
||||
* @param maxWindGusts maximum wind gusts
|
||||
* @returns Content for a HoverCard dropdown presenting weather information
|
||||
*/
|
||||
export const WeatherDescription = ({
|
||||
@@ -59,6 +71,10 @@ export const WeatherDescription = ({
|
||||
weatherCode,
|
||||
maxTemp,
|
||||
minTemp,
|
||||
sunrise,
|
||||
sunset,
|
||||
maxWindSpeed,
|
||||
maxWindGusts,
|
||||
}: WeatherDescriptionProps) => {
|
||||
const t = useScopedI18n("widget.weather");
|
||||
const tCommon = useScopedI18n("common");
|
||||
@@ -73,8 +89,14 @@ export const WeatherDescription = ({
|
||||
<Stack align="center" gap="0">
|
||||
<Text fz="24px">{dayjs(time).format(dateFormat)}</Text>
|
||||
<Text fz="16px">{t(`kind.${name}`)}</Text>
|
||||
<Text fz="16px">{`${tCommon("information.max")}: ${maxTemp}`}</Text>
|
||||
<Text fz="16px">{`${tCommon("information.min")}: ${minTemp}`}</Text>
|
||||
<List>
|
||||
<List.Item icon={<IconTemperaturePlus size={15} />}>{`${tCommon("information.max")}: ${maxTemp}`}</List.Item>
|
||||
<List.Item icon={<IconTemperatureMinus size={15} />}>{`${tCommon("information.min")}: ${minTemp}`}</List.Item>
|
||||
<List.Item icon={<IconSun size={15} />}>{`${t("dailyForecast.sunrise")}: ${sunrise}`}</List.Item>
|
||||
<List.Item icon={<IconMoon size={15} />}>{`${t("dailyForecast.sunset")}: ${sunset}`}</List.Item>
|
||||
<List.Item icon={<IconWind size={15} />}>{t("dailyForecast.maxWindSpeed", { maxWindSpeed })}</List.Item>
|
||||
<List.Item icon={<IconWind size={15} />}>{t("dailyForecast.maxWindGusts", { maxWindGusts })}</List.Item>
|
||||
</List>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -10,6 +10,8 @@ export const { definition, componentLoader } = createWidgetDefinition("weather",
|
||||
options: optionsBuilder.from(
|
||||
(factory) => ({
|
||||
isFormatFahrenheit: factory.switch(),
|
||||
disableTemperatureDecimals: factory.switch(),
|
||||
showCurrentWindSpeed: factory.switch({ withDescription: true }),
|
||||
location: factory.location({
|
||||
defaultValue: {
|
||||
name: "Paris",
|
||||
|
||||
586
pnpm-lock.yaml
generated
586
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user