diff --git a/i18n/en/api.json b/i18n/en/api.json new file mode 100644 index 000000000..c70c4b850 --- /dev/null +++ b/i18n/en/api.json @@ -0,0 +1,37 @@ +{ + "commands": { + "errorExecuting": "An Error occurred while executing command \"{name}\"" + }, + "notifications": { + "dismissNotification": "Dismiss Notification", + "noNotifications": "No notifications yet", + "notificationLog": "Notification Log", + "notificationSettings": "Notification Settings", + "logs": { + "title": "Are you sure?", + "body_zero": "No notification selected.", + "body_one": "This will permanently remove {count} notification. This action cannot be undone.", + "body_other": "This will permanently remove {count} notifications. This action cannot be undone.", + "confirm": "Do it!", + "cancel": "Nevermind", + "clearNotificationLog": "Clear Notification Log" + }, + "missedNotifications": { + "title": "While you were away", + "body_one": "{count} notification received", + "body_other": "{count} notifications received" + } + }, + "memberListDecorators": { + "fallback": "Failed to render {key} Member List Decorator" + }, + "messageAccessories": { + "fallback": "Failed to render {key} Message Accessory" + }, + "messageDecorations": { + "fallback": "Failed to render {key} Message Decoration" + }, + "notices": { + "fallback": "Error Showing Notice" + } +} \ No newline at end of file diff --git a/i18n/en/vencord.json b/i18n/en/vencord.json index 859842681..84b9adb71 100644 --- a/i18n/en/vencord.json +++ b/i18n/en/vencord.json @@ -25,13 +25,35 @@ "cloud": { "integrations": { "header": "Cloud Integrations", - "reauthenticateOtherClient": "We've noticed you have cloud integrations enabled in another client! Due to limitations, you will need to re-authenticate to continue using them. Click here to go to the settings page to do so!" + "reauthenticateOtherClient": "We've noticed you have cloud integrations enabled in another client! Due to limitations, you will need to re-authenticate to continue using them. Click here to go to the settings page to do so!", + "failedToRetrieveOAuth": "Setup failed (couldn't retrieve OAuth configuration).", + "enabled": "Cloud integrations enabled!", + "noSecret": "Setup failed (no secret returned?).", + "error": "Setup failed ({e})" }, "settings": { "header": "Cloud Settings", - "updatedRemote": "Your settings have been updated! Click here to restart to fully apply changes!" + "updatedRemote": "Your settings have been updated! Click here to restart to fully apply changes!", + "apiReject": "Could not synchronize settings to cloud (API returned {e}).", + "success": "Synchronized settings to the cloud!", + "failedToSync": "Could not synchronize settings to the cloud ({e}).", + "accountChanged": "Cloud sync was disabled because this account isn't connected to the cloud App. You can enable it again by connecting this account in Cloud Settings. (note: it will store your preferences separately)", + "noSettings": "There are no settings in the cloud.", + "upToDate": "Your settings are up to date.", + "newerThanCloud": "Your local settings are newer than the cloud ones.", + "updated": "Your settings have been updated! Click here to restart to fully apply changes!", + "syncFromCloud": "Could not synchronize settings from the cloud ({e}).", + "apiDelete": "Could not delete settings (API returned {e}).", + "deleted": "Settings deleted from cloud!", + "failedToDelete": "Could not delete settings ({e}).", + "apiEraseAll": "Could not erase all data (API returned {e}), please contact support.", + "erased": "Successfully erased all data." } }, + "settingsSync": { + "imported": "Settings successfully imported. Restart to apply changes!", + "failedToImport": "Failed to import settings: {e}" + }, "contributorCard": { "contributionsButton": "See what you've contributed to", "description": "Since you've contributed to Equicord you now have a cool new badge!", @@ -42,7 +64,7 @@ "donated": { "vencordDescription": "All Vencord users can see your badge! You can manage your perks by messaging @{v}.", "equicordDescription": "All Equicord users can see your badge! You can manage your perks by making a ticket in Equicord's server.", - "description": "All Vencord users can see your Vencord donor badge, and Equicord users can see your Equicord donor badge. To change your Vencord donor badge, contact @vending.machine. For your Equicord donor badge, make a ticket in Equicord's server..", + "description": "All Vencord users can see your Vencord donor badge, and Equicord users can see your Equicord donor badge. To change your Vencord donor badge, contact @vending.machine. For your Equicord donor badge, make a ticket in Equicord's server.", "subtitle": "Thank you for donating!", "title": "Donations" }, diff --git a/src/api/Commands/index.ts b/src/api/Commands/index.ts index b52df9424..e02ca8287 100644 --- a/src/api/Commands/index.ts +++ b/src/api/Commands/index.ts @@ -18,6 +18,7 @@ import { Logger } from "@utils/Logger"; import { makeCodeblock } from "@utils/text"; +import { t } from "@utils/translation"; import { CommandArgument, CommandContext, CommandOption } from "@vencord/discord-types"; import { sendBotMessage } from "./commandHelpers"; @@ -68,7 +69,7 @@ export const _handleCommand = function (cmd: VencordCommand, args: CommandArgume const handleError = (err: any) => { // TODO: cancel send if cmd.inputType === BUILT_IN_TEXT - const msg = `An Error occurred while executing command "${cmd.name}"`; + const msg = t("api.commands.errorExecuting", { name: cmd.name }); const reason = err instanceof Error ? err.stack || err.message : String(err); console.error(msg, err); diff --git a/src/api/MemberListDecorators.tsx b/src/api/MemberListDecorators.tsx index 74f16800b..4b9ee9ecd 100644 --- a/src/api/MemberListDecorators.tsx +++ b/src/api/MemberListDecorators.tsx @@ -17,6 +17,7 @@ */ import ErrorBoundary from "@components/ErrorBoundary"; +import { t } from "@utils/translation"; import { Channel, User } from "@vencord/discord-types"; import { JSX } from "react"; @@ -50,7 +51,7 @@ export function __getDecorators(props: DecoratorProps, type: "guild" | "dm"): JS return null; return ( - + ); diff --git a/src/api/MessageAccessories.tsx b/src/api/MessageAccessories.tsx index d2bc081e7..07eaec055 100644 --- a/src/api/MessageAccessories.tsx +++ b/src/api/MessageAccessories.tsx @@ -17,6 +17,7 @@ */ import ErrorBoundary from "@components/ErrorBoundary"; +import { t } from "@utils/translation"; import { JSX, ReactNode } from "react"; export type MessageAccessoryFactory = (props: Record) => ReactNode; @@ -48,7 +49,7 @@ export function _modifyAccessories( ) { for (const [key, accessory] of accessories.entries()) { const res = ( - + ); diff --git a/src/api/MessageDecorations.tsx b/src/api/MessageDecorations.tsx index 8cf492c70..dd9b0954f 100644 --- a/src/api/MessageDecorations.tsx +++ b/src/api/MessageDecorations.tsx @@ -17,6 +17,7 @@ */ import ErrorBoundary from "@components/ErrorBoundary"; +import { t } from "@utils/translation"; import { Channel, Message } from "@vencord/discord-types"; import { JSX } from "react"; @@ -62,7 +63,7 @@ export function __addDecorationsToMessage(props: MessageDecorationProps): JSX.El const decorations = Array.from( decorationsFactories.entries(), ([key, Decoration]) => ( - + ) diff --git a/src/api/Notices.tsx b/src/api/Notices.tsx index 5285ca148..d5674b3c7 100644 --- a/src/api/Notices.tsx +++ b/src/api/Notices.tsx @@ -18,6 +18,7 @@ import ErrorBoundary from "@components/ErrorBoundary"; import { isPrimitiveReactNode } from "@utils/react"; +import { t } from "@utils/translation"; import { waitFor } from "@webpack"; import { ReactNode } from "react"; @@ -42,7 +43,7 @@ export function nextNotice() { export function showNotice(message: ReactNode, buttonText: string, onOkClick: () => void) { const notice = isPrimitiveReactNode(message) ? message - : "Error Showing Notice"}>{message}; + : t("api.notices.fallback")}>{message}; noticesQueue.push(["GENERIC", notice, buttonText, onOkClick]); if (!currentNotice) nextNotice(); diff --git a/src/api/Notifications/NotificationComponent.tsx b/src/api/Notifications/NotificationComponent.tsx index e8f0cc206..e2f53d3f3 100644 --- a/src/api/Notifications/NotificationComponent.tsx +++ b/src/api/Notifications/NotificationComponent.tsx @@ -21,6 +21,7 @@ import "./styles.css"; import { useSettings } from "@api/Settings"; import ErrorBoundary from "@components/ErrorBoundary"; import { classes } from "@utils/misc"; +import { t } from "@utils/translation"; import { React, useEffect, useRef, useState } from "@webpack/common"; import { NotificationData } from "./Notifications"; @@ -111,7 +112,7 @@ export default ErrorBoundary.wrap(function NotificationComponent({ role="img" aria-labelledby="vc-notification-dismiss-title" > - Dismiss Notification + {t("api.notifications.dismissNotification")} diff --git a/src/api/Notifications/Notifications.tsx b/src/api/Notifications/Notifications.tsx index 4fd8c3d93..c7d6c10ab 100644 --- a/src/api/Notifications/Notifications.tsx +++ b/src/api/Notifications/Notifications.tsx @@ -18,6 +18,7 @@ import { Settings } from "@api/Settings"; import { Queue } from "@utils/Queue"; +import { t } from "@utils/translation"; import { createRoot, WindowStore } from "@webpack/common"; import type { ReactNode } from "react"; import type { Root } from "react-dom/client"; @@ -36,8 +37,8 @@ window.addEventListener("focus", () => { if (!missed) return; if (missedCount > 0 && timeout > 0 && useNative === "never") { showNotification({ - title: "While you were away", - body: `${missedCount} notifications received`, + title: t("api.notifications.missedNotifications.title"), + body: t("api.notifications.missedNotifications.body", { count: missedCount }), onClick: () => openNotificationLogModal(), }); missedCount = 0; diff --git a/src/api/Notifications/notificationLog.tsx b/src/api/Notifications/notificationLog.tsx index 40958a724..6b294bf5a 100644 --- a/src/api/Notifications/notificationLog.tsx +++ b/src/api/Notifications/notificationLog.tsx @@ -25,6 +25,7 @@ import { Paragraph } from "@components/Paragraph"; import { openNotificationSettingsModal } from "@components/settings/tabs/vencord/NotificationSettings"; import { closeModal, ModalCloseButton, ModalFooter, ModalHeader, ModalProps, ModalRoot, ModalSize, openModal } from "@utils/modal"; import { useAwaiter } from "@utils/react"; +import { t } from "@utils/translation"; import { Alerts, Button, ListScrollerThin, React, Timestamp, useEffect, useReducer, useState } from "@webpack/common"; import { nanoid } from "nanoid"; import type { DispatchWithoutAction } from "react"; @@ -135,7 +136,7 @@ export function NotificationLog({ log, pending }: { log: PersistentNotificationD
- No notifications yet + {t("api.notifications.noNotifications")}
); @@ -158,7 +159,7 @@ function LogModal({ modalProps, close }: { modalProps: ModalProps; close(): void return ( - Notification Log + {t("api.notifications.notificationLog")} @@ -169,7 +170,7 @@ function LogModal({ modalProps, close }: { modalProps: ModalProps; close(): void diff --git a/src/api/PluginManager.ts b/src/api/PluginManager.ts index 2d57a4e59..51f2597f5 100644 --- a/src/api/PluginManager.ts +++ b/src/api/PluginManager.ts @@ -147,7 +147,6 @@ export function subscribePluginFluxEvents(p: Plugin, fluxDispatcher: typeof Flux logger.debug("Subscribing to flux events of plugin", p.name); for (const [event, handler] of Object.entries(p.flux)) { const wrappedHandler = p.flux[event] = function () { - if (p.name === "Encryptcord" && event === "MESSAGE_CREATE") return; try { const res = handler!.apply(p, arguments as any); return res instanceof Promise diff --git a/src/api/SettingsSync/cloudSetup.tsx b/src/api/SettingsSync/cloudSetup.tsx index 20a21859d..4af8cd5e2 100644 --- a/src/api/SettingsSync/cloudSetup.tsx +++ b/src/api/SettingsSync/cloudSetup.tsx @@ -9,6 +9,7 @@ import { showNotification } from "@api/Notifications"; import { Settings } from "@api/Settings"; import { Logger } from "@utils/Logger"; import { openModal } from "@utils/modal"; +import { t } from "@utils/translation"; import { OAuth2AuthorizeModal, UserStore } from "@webpack/common"; export const logger = new Logger("SettingsSync:CloudSetup", "#39b7e0"); @@ -71,8 +72,8 @@ export async function authorizeCloud() { var { clientId, redirectUri } = await oauthConfiguration.json(); } catch { showNotification({ - title: "Cloud Integration", - body: "Setup failed (couldn't retrieve OAuth configuration)." + title: t("vencord.cloud.integrations.header"), + body: t("vencord.cloud.integrations.failedToRetrieveOAuth") }); Settings.cloud.authenticated = false; return; @@ -101,22 +102,22 @@ export async function authorizeCloud() { logger.info("Authorized with secret"); await setAuthorization(secret); showNotification({ - title: "Cloud Integration", - body: "Cloud integrations enabled!" + title: t("vencord.cloud.integrations.header"), + body: t("vencord.cloud.integrations.enabled") }); Settings.cloud.authenticated = true; } else { showNotification({ - title: "Cloud Integration", - body: "Setup failed (no secret returned?)." + title: t("vencord.cloud.integrations.header"), + body: t("vencord.cloud.integrations.noSecret") }); Settings.cloud.authenticated = false; } } catch (e: any) { logger.error("Failed to authorize", e); showNotification({ - title: "Cloud Integration", - body: `Setup failed (${e.toString()}).` + title: t("vencord.cloud.integrations.header"), + body: t("vencord.cloud.integrations.error", { e: e.toString() }) }); Settings.cloud.authenticated = false; } diff --git a/src/api/SettingsSync/cloudSync.ts b/src/api/SettingsSync/cloudSync.ts index 3dfab39b4..cc289b0ef 100644 --- a/src/api/SettingsSync/cloudSync.ts +++ b/src/api/SettingsSync/cloudSync.ts @@ -34,7 +34,7 @@ export async function putCloudSettings(manual?: boolean) { logger.error(`Failed to sync up, API returned ${res.status}`); showNotification({ title: t("vencord.cloud.settings.header"), - body: `Could not synchronize settings to cloud (API returned ${res.status}).`, + body: t("vencord.cloud.settings.apiReject", { e: res.status }), color: "var(--red-360)" }); return; @@ -49,7 +49,7 @@ export async function putCloudSettings(manual?: boolean) { if (manual) { showNotification({ title: t("vencord.cloud.settings.header"), - body: "Synchronized settings to the cloud!", + body: t("vencord.cloud.settings.success"), noPersist: true, }); } @@ -57,7 +57,7 @@ export async function putCloudSettings(manual?: boolean) { logger.error("Failed to sync up", e); showNotification({ title: t("vencord.cloud.settings.header"), - body: `Could not synchronize settings to the cloud (${e.toString()}).`, + body: t("vencord.cloud.settings.faildToSync", { e: e.toString() }), color: "var(--red-360)" }); } @@ -78,7 +78,7 @@ export async function getCloudSettings(shouldNotify = true, force = false) { // User switched to an account that isn't connected to cloud showNotification({ title: t("vencord.cloud.settings.header"), - body: "Cloud sync was disabled because this account isn't connected to the cloud App. You can enable it again by connecting this account in Cloud Settings. (note: it will store your preferences separately)", + body: t("vencord.cloud.settings.accountChanged"), color: "var(--yellow-360)", onClick: () => SettingsRouter.open("VencordCloud") }); @@ -92,7 +92,7 @@ export async function getCloudSettings(shouldNotify = true, force = false) { if (shouldNotify) showNotification({ title: t("vencord.cloud.settings.header"), - body: "There are no settings in the cloud.", + body: t("vencord.cloud.settings.noSettings"), noPersist: true }); return false; @@ -103,7 +103,7 @@ export async function getCloudSettings(shouldNotify = true, force = false) { if (shouldNotify) showNotification({ title: t("vencord.cloud.settings.header"), - body: "Your settings are up to date.", + body: t("vencord.cloud.settings.upToDate"), noPersist: true }); return false; @@ -113,7 +113,7 @@ export async function getCloudSettings(shouldNotify = true, force = false) { logger.error(`Failed to sync down, API returned ${res.status}`); showNotification({ title: t("vencord.cloud.settings.header"), - body: `Could not synchronize settings from the cloud (API returned ${res.status}).`, + body: t("vencord.cloud.settings.apiReject", { e: res.status }), color: "var(--red-360)" }); return false; @@ -127,7 +127,7 @@ export async function getCloudSettings(shouldNotify = true, force = false) { if (shouldNotify) showNotification({ title: t("vencord.cloud.settings.header"), - body: "Your local settings are newer than the cloud ones.", + body: t("vencord.cloud.settings.newerThanCloud"), noPersist: true, }); return; @@ -146,7 +146,7 @@ export async function getCloudSettings(shouldNotify = true, force = false) { if (shouldNotify) showNotification({ title: t("vencord.cloud.settings.header"), - body: "Your settings have been updated! Click here to restart to fully apply changes!", + body: t("vencord.cloud.settings.updated"), color: "var(--green-360)", onClick: IS_WEB ? () => location.reload() : relaunch, noPersist: true @@ -157,7 +157,7 @@ export async function getCloudSettings(shouldNotify = true, force = false) { logger.error("Failed to sync down", e); showNotification({ title: t("vencord.cloud.settings.header"), - body: `Could not synchronize settings from the cloud (${e.toString()}).`, + body: t("vencord.cloud.settings.syncFromCloud", { e: e.toString() }), color: "var(--red-360)" }); @@ -176,7 +176,7 @@ export async function deleteCloudSettings() { logger.error(`Failed to delete, API returned ${res.status}`); showNotification({ title: t("vencord.cloud.settings.header"), - body: `Could not delete settings (API returned ${res.status}).`, + body: t("vencord.cloud.settings.apiDelete", { e: res.status }), color: "var(--red-360)" }); return; @@ -185,14 +185,14 @@ export async function deleteCloudSettings() { logger.info("Settings deleted from cloud successfully"); showNotification({ title: t("vencord.cloud.settings.header"), - body: "Settings deleted from cloud!", + body: t("vencord.cloud.settings.deleted"), color: "var(--green-360)" }); } catch (e: any) { logger.error("Failed to delete", e); showNotification({ title: t("vencord.cloud.settings.header"), - body: `Could not delete settings (${e.toString()}).`, + body: t("vencord.cloud.settings.failedToDelete", { e: e.toString() }), color: "var(--red-360)" }); } @@ -208,7 +208,7 @@ export async function eraseAllCloudData() { logger.error(`Failed to erase data, API returned ${res.status}`); showNotification({ title: t("vencord.cloud.integrations.header"), - body: `Could not erase all data (API returned ${res.status}), please contact support.`, + body: t("vencord.cloud.settings.apiEraseAll", { e: res.status }), color: "var(--red-360)" }); return; @@ -219,7 +219,7 @@ export async function eraseAllCloudData() { showNotification({ title: t("vencord.cloud.integrations.header"), - body: "Successfully erased all data.", + body: t("vencord.cloud.settings.erased"), color: "var(--green-360)" }); } diff --git a/src/api/SettingsSync/offline.ts b/src/api/SettingsSync/offline.ts index 12fa9001c..ef651e435 100644 --- a/src/api/SettingsSync/offline.ts +++ b/src/api/SettingsSync/offline.ts @@ -6,6 +6,7 @@ import { PlainSettings } from "@api/Settings"; import { Logger } from "@utils/Logger"; +import { t } from "@utils/translation"; import { chooseFile, saveFile } from "@utils/web"; import { moment, Toasts } from "@webpack/common"; @@ -19,10 +20,10 @@ const toast = (type: string, message: string) => }); const toastSuccess = () => - toast(Toasts.Type.SUCCESS, "Settings successfully imported. Restart to apply changes!"); + toast(Toasts.Type.SUCCESS, t("vencord.settingsSync.imported")); const toastFailure = (err: any) => - toast(Toasts.Type.FAILURE, `Failed to import settings: ${String(err)}`); + toast(Toasts.Type.FAILURE, t("vencord.settingsSync.failedToImport", { e: String(err) })); const logger = new Logger("SettingsSync:Offline", "#39b7e0");