Internationalization (i18n) (#627)

* `feat: added internationalization lib, added english labels`
* `fixes from code review`
* `feat: add crowdin github actions`
* `fix: added support for i18n in testing. Fixed broken tests`
* `fix: missing translations`
* `removed unneded import`
* `more components updated with missing translations`
* `fixed lint issue`
* `Refactor: updated how translations are scoped, updated all references`
* `fixing broken tests`
* `feat: added language switcher, updated some translations`
* `fixed linting issues`
* `reverting vite config`
* `add english group id's to command palette`
* `updated PR template for i18n`
This commit is contained in:
Dan Ditomaso
2025-05-27 08:33:43 -04:00
committed by GitHub
parent 9d74fe2d6e
commit eb2a2717b1
95 changed files with 4651 additions and 1497 deletions
@@ -8,6 +8,7 @@ import { randId } from "@core/utils/randId.ts";
import { MeshDevice } from "@meshtastic/core";
import { TransportWebSerial } from "@meshtastic/transport-web-serial";
import { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useMessageStore } from "../../../core/stores/messageStore/index.ts";
export const Serial = (
@@ -18,6 +19,7 @@ export const Serial = (
const { addDevice } = useDeviceStore();
const messageStore = useMessageStore();
const { setSelectedDevice } = useAppStore();
const { t } = useTranslation();
const updateSerialPortList = useCallback(async () => {
setSerialPorts(await navigator?.serial.getPorts());
@@ -54,24 +56,31 @@ export const Serial = (
<div className="flex h-48 flex-col gap-2 overflow-y-auto">
{serialPorts.map((port, index) => {
const { usbProductId, usbVendorId } = port.getInfo();
const vendor = usbVendorId ?? t("unknown.shortName");
const product = usbProductId ?? t("unknown.shortName");
return (
<Button
key={`${usbVendorId ?? "UNK"}-${usbProductId ?? "UNK"}-${index}`}
key={`${vendor}-${product}-${index}`}
disabled={port.readable !== null}
variant="default"
onClick={async () => {
setConnectionInProgress(true);
await onConnect(port);
// No need to setConnectionInProgress(false) here as closeDialog() unmounts.
}}
>
{`# ${index} - ${usbVendorId ?? "UNK"} - ${
usbProductId ?? "UNK"
}`}
{t("newDeviceDialog.serialConnection.deviceIdentifier", {
index: index,
vendorId: vendor,
productId: product,
})}
</Button>
);
})}
{serialPorts.length === 0 && (
<Mono className="m-auto select-none">No devices paired yet.</Mono>
<Mono className="m-auto select-none">
{t("newDeviceDialog.serialConnection.noDevicesPaired")}
</Mono>
)}
</div>
<Button
@@ -79,15 +88,15 @@ export const Serial = (
onClick={async () => {
await navigator.serial.requestPort().then((port) => {
setSerialPorts(serialPorts.concat(port));
// No need to setConnectionInProgress(false) here if requestPort is quick
}).catch((error) => {
console.error("Error requesting port:", error);
setConnectionInProgress(false);
}).finally(() => {
setConnectionInProgress(false);
});
}}
>
<span>New device</span>
<span>{t("newDeviceDialog.serialConnection.newDeviceButton")}</span>
</Button>
</fieldset>
);