From ba7342e4f355585116d10e2e8111e44ac3bc79b3 Mon Sep 17 00:00:00 2001 From: flathead Date: Fri, 27 Mar 2026 16:28:41 +0300 Subject: [PATCH 1/9] feat: add internationalization (i18n) system with EN, RU, ES support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduces a full i18n infrastructure and migrates all hardcoded UI strings across the codebase to use the new translation system. ## New files - modules/services/I18n.qml — singleton service that loads JSON translation files at runtime based on system locale or config - translations/en.json — English (base, ~637 keys) - translations/ru.json — Russian translation - translations/es.json — Spanish translation - translations/languages.json — language metadata registry ## Infrastructure - I18n.qml detects locale via Qt.locale(), falls back to "en" - Config.qml: added `language` property (default "auto") for manual language override; added `rus` bool to OCR config - config/defaults/system.js: added language and rus defaults - .pragma library JS files (notification_utils.js, notes_utils.js) receive `t` as a parameter from callers since they cannot access QML singletons directly ## String migration All hardcoded UI strings across 67 files replaced with I18n.t("key"): - Bar: battery, layout selector, controls button, tools button - Clock: month/day names (fixes Qt.locale() genitive case in RU), weather day labels, pomodoro controls - Dashboard controls: all settings panels (Compositor, Theme, Shell, System, Binds, Color Picker, Wallpapers, Audio, Bluetooth, WiFi, EasyEffects, Gradient editor, Variant editor) - Dashboard widgets: calendar, clipboard (relative timestamps), notes (relative timestamps), notifications, launcher, overview, tmux, emoji, metrics, full/compact player, quick controls, presets, power menu - Tools: screenshot overlay/tool, screen recorder - Sidebar: AI assistant slash command descriptions - Dock, Desktop, CodeBlock, ModelSelectorPopup ## Bug fixes included - ToolsMenu.qml: fixed `i18n()` calls (undefined function) that caused OCR panel crash — replaced with `I18n.t()` - WallpapersTab.qml: fixed Tint label showing "OLED" (key mismatch) - CompositorPanel, ThemePanel, SystemPanel: subsection titles now translated dynamically (was using raw capitalize() fallback) - SchemeSelector.qml: added missing `import qs.modules.services` ## Translation notes - Russian: uses nominative month names (not genitive from Qt.locale()) - All 637 keys verified present in all three locale files - Dynamic key patterns (e.g. settings.shell.{sectionId}) verified --- config/Config.qml | 2 + config/defaults/system.js | 90 +-- modules/bar/BarContent.qml | 4 +- modules/bar/BatteryIndicator.qml | 6 +- modules/bar/ControlsButton.qml | 2 +- modules/bar/LayoutSelectorButton.qml | 2 +- modules/bar/ToolsButton.qml | 2 +- modules/bar/clock/Clock.qml | 52 +- modules/bar/clock/Pomodoro.qml | 12 +- modules/bar/clock/Weather.qml | 9 +- modules/desktop/Desktop.qml | 6 +- modules/dock/DockContent.qml | 8 +- .../notifications/NotificationDelegate.qml | 4 +- modules/notifications/NotificationGroup.qml | 2 +- modules/notifications/notification_utils.js | 17 +- modules/services/I18n.qml | 114 ++++ modules/services/PowerProfile.qml | 6 +- modules/services/WeatherService.qml | 13 +- modules/sidebar/AssistantSidebar.qml | 26 +- modules/sidebar/CodeBlock.qml | 3 +- modules/sidebar/ModelSelectorPopup.qml | 4 +- modules/tools/ScreenrecordTool.qml | 12 +- modules/tools/ScreenshotOverlay.qml | 8 +- modules/tools/ScreenshotTool.qml | 6 +- modules/widgets/config/AiPanel.qml | 32 +- modules/widgets/dashboard/LauncherButton.qml | 2 +- .../dashboard/clipboard/ClipboardTab.qml | 67 +- .../dashboard/controls/AudioMixerPanel.qml | 16 +- .../dashboard/controls/AudioVolumeEntry.qml | 2 +- .../widgets/dashboard/controls/BindsPanel.qml | 39 +- .../controls/BluetoothDeviceItem.qml | 10 +- .../dashboard/controls/BluetoothPanel.qml | 8 +- .../dashboard/controls/ColorButton.qml | 3 +- .../dashboard/controls/ColorPickerPopup.qml | 5 +- .../dashboard/controls/ColorPickerView.qml | 5 +- .../dashboard/controls/ColorSelector.qml | 5 +- .../dashboard/controls/CompositorPanel.qml | 103 +-- .../dashboard/controls/EasyEffectsPanel.qml | 18 +- .../controls/GradientStopsEditor.qml | 15 +- .../dashboard/controls/SettingsIndex.qml | 310 ++++----- .../dashboard/controls/SettingsTab.qml | 22 +- .../widgets/dashboard/controls/ShellPanel.qml | 254 +++---- .../dashboard/controls/SystemPanel.qml | 195 ++++-- .../widgets/dashboard/controls/ThemePanel.qml | 53 +- .../dashboard/controls/VariantEditor.qml | 19 +- .../dashboard/controls/WifiNetworkItem.qml | 12 +- .../widgets/dashboard/controls/WifiPanel.qml | 12 +- modules/widgets/dashboard/emoji/EmojiTab.qml | 4 +- .../widgets/dashboard/metrics/MetricsTab.qml | 2 +- modules/widgets/dashboard/notes/NotesTab.qml | 20 +- .../widgets/dashboard/notes/notes_utils.js | 20 +- modules/widgets/dashboard/tmux/TmuxTab.qml | 16 +- .../dashboard/wallpapers/FilterBar.qml | 3 +- .../dashboard/wallpapers/SchemeSelector.qml | 21 +- .../dashboard/wallpapers/WallpapersTab.qml | 8 +- .../widgets/dashboard/widgets/FullPlayer.qml | 6 +- .../dashboard/widgets/NotificationHistory.qml | 2 +- .../dashboard/widgets/QuickControls.qml | 14 +- .../dashboard/widgets/calendar/Calendar.qml | 25 +- modules/widgets/defaultview/CompactPlayer.qml | 8 +- modules/widgets/launcher/LauncherView.qml | 8 +- modules/widgets/overview/OverviewButton.qml | 2 +- modules/widgets/overview/OverviewPopup.qml | 2 +- modules/widgets/powermenu/PowerButton.qml | 2 +- modules/widgets/powermenu/PowerMenu.qml | 12 +- modules/widgets/presets/PresetsButton.qml | 2 +- modules/widgets/presets/PresetsTab.qml | 34 +- modules/widgets/tools/ToolsMenu.qml | 39 +- translations/en.json | 639 ++++++++++++++++++ translations/es.json | 639 ++++++++++++++++++ translations/languages.json | 5 + translations/ru.json | 639 ++++++++++++++++++ 72 files changed, 3025 insertions(+), 764 deletions(-) create mode 100644 modules/services/I18n.qml create mode 100644 translations/en.json create mode 100644 translations/es.json create mode 100644 translations/languages.json create mode 100644 translations/ru.json diff --git a/config/Config.qml b/config/Config.qml index 76bab09b7..268715077 100644 --- a/config/Config.qml +++ b/config/Config.qml @@ -1039,6 +1039,7 @@ Singleton { property bool chi_sim: false property bool chi_tra: false property bool kor: false + property bool rus: false } property JsonObject pomodoro: JsonObject { property int workTime: 1500 @@ -1046,6 +1047,7 @@ Singleton { property bool autoStart: false property bool syncSpotify: false } + property string language: "auto" } } diff --git a/config/defaults/system.js b/config/defaults/system.js index e36191027..aa34f66da 100644 --- a/config/defaults/system.js +++ b/config/defaults/system.js @@ -1,48 +1,50 @@ .pragma library var data = { - "disks": ["/"], - "updateServiceEnabled": true, - "idle": { - "general": { - "lock_cmd": "ambxst lock", - "before_sleep_cmd": "loginctl lock-session", - "after_sleep_cmd": "ambxst screen on" - }, - "listeners": [ - { - "timeout": 150, - "onTimeout": "ambxst brightness 10 -s", - "onResume": "ambxst brightness -r" - }, - { - "timeout": 300, - "onTimeout": "loginctl lock-session" - }, - { - "timeout": 330, - "onTimeout": "ambxst screen off", - "onResume": "ambxst screen on" - }, - { - "timeout": 1800, - "onTimeout": "ambxst suspend" - } - ] - }, - "ocr": { - "eng": true, - "spa": true, - "lat": false, - "jpn": false, - "chi_sim": false, - "chi_tra": false, - "kor": false - }, - "pomodoro": { - "workTime": 1500, - "restTime": 300, - "autoStart": false, - "syncSpotify": false - } + "disks": ["/"], + "updateServiceEnabled": true, + "idle": { + "general": { + "lock_cmd": "ambxst lock", + "before_sleep_cmd": "loginctl lock-session", + "after_sleep_cmd": "ambxst screen on" + }, + "listeners": [ + { + "timeout": 150, + "onTimeout": "ambxst brightness 10 -s", + "onResume": "ambxst brightness -r" + }, + { + "timeout": 300, + "onTimeout": "loginctl lock-session" + }, + { + "timeout": 330, + "onTimeout": "ambxst screen off", + "onResume": "ambxst screen on" + }, + { + "timeout": 1800, + "onTimeout": "ambxst suspend" + } + ] + }, + "ocr": { + "eng": true, + "spa": true, + "lat": false, + "jpn": false, + "chi_sim": false, + "chi_tra": false, + "kor": false, + "rus": false + }, + "pomodoro": { + "workTime": 1500, + "restTime": 300, + "autoStart": false, + "syncSpotify": false + }, + "language": "auto" } diff --git a/modules/bar/BarContent.qml b/modules/bar/BarContent.qml index b9e57ca75..c3a0f5918 100644 --- a/modules/bar/BarContent.qml +++ b/modules/bar/BarContent.qml @@ -454,7 +454,7 @@ Item { StyledToolTip { show: pinButton.hovered - tooltipText: root.pinned ? "Unpin bar" : "Pin bar" + tooltipText: root.pinned ? I18n.t("bar.tooltip.unpin_bar") : I18n.t("bar.tooltip.pin_bar") } } } @@ -708,7 +708,7 @@ Item { StyledToolTip { show: pinButtonV.hovered - tooltipText: root.pinned ? "Unpin bar" : "Pin bar" + tooltipText: root.pinned ? I18n.t("bar.tooltip.unpin_bar") : I18n.t("bar.tooltip.pin_bar") } } } diff --git a/modules/bar/BatteryIndicator.qml b/modules/bar/BatteryIndicator.qml index a4b3fae1f..873a45ac3 100644 --- a/modules/bar/BatteryIndicator.qml +++ b/modules/bar/BatteryIndicator.qml @@ -186,7 +186,7 @@ Item { StyledToolTip { visible: root.isHovered && !root.popupOpen - tooltipText: Battery.available ? ("Battery: " + Math.round(Battery.percentage) + "%" + (Battery.isCharging ? " (Charging)" : "")) : ("Power Profile: " + PowerProfile.getProfileDisplayName(PowerProfile.currentProfile)) + tooltipText: Battery.available ? I18n.t("battery.status", Math.round(Battery.percentage)) : I18n.t("battery.power_profile", PowerProfile.getProfileDisplayName(PowerProfile.currentProfile)) } } @@ -240,7 +240,7 @@ Item { Text { Layout.fillWidth: true - text: Battery.isPluggedIn ? (Battery.isCharging ? "Charging" : "Full") : "On battery" + text: Battery.isPluggedIn ? (Battery.isCharging ? I18n.t("battery.charging") : I18n.t("battery.full")) : I18n.t("battery.on_battery") font.family: Styling.defaultFont font.pixelSize: Styling.fontSize(0) font.bold: true @@ -248,7 +248,7 @@ Item { } Text { - text: Battery.isPluggedIn ? (Battery.timeToFull !== "" ? "Full in " + Battery.timeToFull : "Fully charged") : (Battery.timeToEmpty !== "" ? Battery.timeToEmpty + " remaining" : "") + text: Battery.isPluggedIn ? (Battery.timeToFull !== "" ? I18n.t("battery.full_in", Battery.timeToFull) : I18n.t("battery.fully_charged")) : (Battery.timeToEmpty !== "" ? I18n.t("battery.remaining", Battery.timeToEmpty) : "") font.family: Styling.defaultFont font.pixelSize: Styling.fontSize(-1) color: Colors.overBackground diff --git a/modules/bar/ControlsButton.qml b/modules/bar/ControlsButton.qml index 687f077be..68577a929 100644 --- a/modules/bar/ControlsButton.qml +++ b/modules/bar/ControlsButton.qml @@ -30,7 +30,7 @@ Item { StyledToolTip { show: root.isHovered && !root.popupOpen - tooltipText: "Audio & Brightness Controls" + tooltipText: I18n.t("bar.tooltip.controls") } HoverHandler { diff --git a/modules/bar/LayoutSelectorButton.qml b/modules/bar/LayoutSelectorButton.qml index 0fc925097..ebb9a0f18 100644 --- a/modules/bar/LayoutSelectorButton.qml +++ b/modules/bar/LayoutSelectorButton.qml @@ -103,7 +103,7 @@ Item { StyledToolTip { visible: root.isHovered && !root.popupOpen - tooltipText: "Layout: " + root.getLayoutDisplayName(GlobalStates.compositorLayout) + tooltipText: I18n.t("bar.tooltip.layout", root.getLayoutDisplayName(GlobalStates.compositorLayout)) } } diff --git a/modules/bar/ToolsButton.qml b/modules/bar/ToolsButton.qml index 2450c6817..085553845 100644 --- a/modules/bar/ToolsButton.qml +++ b/modules/bar/ToolsButton.qml @@ -6,7 +6,7 @@ import qs.modules.services ToggleButton { id: toolsButton buttonIcon: Icons.toolbox - tooltipText: "Tools" + tooltipText: I18n.t("bar.tooltip.tools") onToggle: function () { if (Visibilities.currentActiveModule === "tools") { Visibilities.setActiveModule(""); diff --git a/modules/bar/clock/Clock.qml b/modules/bar/clock/Clock.qml index 1cad557db..993046877 100644 --- a/modules/bar/clock/Clock.qml +++ b/modules/bar/clock/Clock.qml @@ -214,10 +214,16 @@ Item { anchors.topMargin: 16 spacing: 4 - // Helper function to capitalize first letter - function capitalizeMonth(date) { - var month = date.toLocaleDateString(Qt.locale(), "MMMM"); - return month.charAt(0).toUpperCase() + month.slice(1); + function getMonthName(date) { + var keys = [ + "calendar.month.january", "calendar.month.february", + "calendar.month.march", "calendar.month.april", + "calendar.month.may", "calendar.month.june", + "calendar.month.july", "calendar.month.august", + "calendar.month.september", "calendar.month.october", + "calendar.month.november", "calendar.month.december" + ]; + return I18n.t(keys[date.getMonth()]); } // Header row: Month and events count @@ -229,7 +235,7 @@ Item { id: monthText anchors.left: parent.left anchors.leftMargin: 4 - text: calendarContent.capitalizeMonth(calendarWrapper.currentDate) + text: calendarContent.getMonthName(calendarWrapper.currentDate) color: Colors.outline font.family: Config.theme.font font.pixelSize: Styling.fontSize(0) @@ -270,13 +276,16 @@ Item { } property bool isToday: index === calendarWrapper.currentDayOfWeek - // Day abbreviation from locale Text { anchors.horizontalCenter: parent.horizontalCenter text: { - var dayName = dayColumn.dayDate.toLocaleDateString(Qt.locale(), "ddd"); - // Capitalize first letter and limit to 2 chars - return (dayName.charAt(0).toUpperCase() + dayName.slice(1, 2)).replace(".", ""); + var keys = [ + "calendar.day.mon", "calendar.day.tue", + "calendar.day.wed", "calendar.day.thu", + "calendar.day.fri", "calendar.day.sat", + "calendar.day.sun" + ]; + return I18n.t(keys[dayColumn.index]); } color: Colors.overBackground font.family: Config.theme.font @@ -631,9 +640,28 @@ Item { function updateDay() { var now = new Date(); - var day = Qt.formatDateTime(now, Qt.locale(), "ddd"); - root.currentDayAbbrev = day.slice(0, 3).charAt(0).toUpperCase() + day.slice(1, 3); - root.currentFullDate = Qt.formatDateTime(now, Qt.locale(), "dddd, MMMM d, yyyy"); + var dayKeys = [ + "calendar.day.sun", "calendar.day.mon", "calendar.day.tue", + "calendar.day.wed", "calendar.day.thu", "calendar.day.fri", + "calendar.day.sat" + ]; + var dayFullKeys = [ + "calendar.day_full.sunday", "calendar.day_full.monday", + "calendar.day_full.tuesday", "calendar.day_full.wednesday", + "calendar.day_full.thursday", "calendar.day_full.friday", + "calendar.day_full.saturday" + ]; + var monthKeys = [ + "calendar.month.january", "calendar.month.february", + "calendar.month.march", "calendar.month.april", + "calendar.month.may", "calendar.month.june", + "calendar.month.july", "calendar.month.august", + "calendar.month.september", "calendar.month.october", + "calendar.month.november", "calendar.month.december" + ]; + root.currentDayAbbrev = I18n.t(dayKeys[now.getDay()]); + root.currentFullDate = I18n.t(dayFullKeys[now.getDay()]) + ", " + + I18n.t(monthKeys[now.getMonth()]) + " " + now.getDate() + ", " + now.getFullYear(); scheduleNextDayUpdate(); } diff --git a/modules/bar/clock/Pomodoro.qml b/modules/bar/clock/Pomodoro.qml index 5f64c1a4d..01e8304e3 100644 --- a/modules/bar/clock/Pomodoro.qml +++ b/modules/bar/clock/Pomodoro.qml @@ -240,7 +240,7 @@ Item { Text { anchors.centerIn: parent - text: root.isWorkSession ? "Work Session" : "Rest Session" + text: root.isWorkSession ? I18n.t("pomodoro.work_session") : I18n.t("pomodoro.rest_session") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Bold @@ -361,7 +361,7 @@ Item { spacing: 12 ControlBtn { - text: "-1m" + text: I18n.t("pomodoro.minus_1m") onClicked: { if (root.timeLeft >= 60) { root.timeLeft -= 60; @@ -383,7 +383,7 @@ Item { Text { anchors.centerIn: parent - text: root.alarmActive ? "STOP ALARM" : (root.isRunning ? "PAUSE" : (root.isResuming ? "RESUME" : "START " + (root.isWorkSession ? "WORK" : "REST"))) + text: root.alarmActive ? I18n.t("pomodoro.stop_alarm") : (root.isRunning ? I18n.t("pomodoro.pause") : (root.isResuming ? I18n.t("pomodoro.resume") : (root.isWorkSession ? I18n.t("pomodoro.start_work") : I18n.t("pomodoro.start_rest")))) font.family: Config.theme.font font.pixelSize: Styling.fontSize(0) font.weight: Font.Black @@ -398,7 +398,7 @@ Item { } ControlBtn { - text: "+1m" + text: I18n.t("pomodoro.plus_1m") onClicked: { root.timeLeft += 60; if (!root.isRunning) { @@ -420,7 +420,7 @@ Item { RowLayout { spacing: 8 Text { - text: "Auto" + text: I18n.t("common.auto") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) color: Colors.outline @@ -450,7 +450,7 @@ Item { RowLayout { spacing: 8 Text { - text: "Sync Spotify" + text: I18n.t("pomodoro.sync_spotify") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) color: Colors.outline diff --git a/modules/bar/clock/Weather.qml b/modules/bar/clock/Weather.qml index 0043e338a..53987e35b 100644 --- a/modules/bar/clock/Weather.qml +++ b/modules/bar/clock/Weather.qml @@ -4,6 +4,7 @@ import Quickshell.Io import qs.config import qs.modules.theme import qs.modules.components +import qs.modules.services StyledRect { id: weatherContainer @@ -182,8 +183,12 @@ StyledRect { function updateDay() { var now = new Date(); - var day = Qt.formatDateTime(now, Qt.locale(), "ddd"); - weatherContainer.currentDayAbbrev = day.slice(0, 3).charAt(0).toUpperCase() + day.slice(1, 3); + var dayKeys = [ + "calendar.day.sun", "calendar.day.mon", "calendar.day.tue", + "calendar.day.wed", "calendar.day.thu", "calendar.day.fri", + "calendar.day.sat" + ]; + weatherContainer.currentDayAbbrev = I18n.t(dayKeys[now.getDay()]); scheduleNextDayUpdate(); } diff --git a/modules/desktop/Desktop.qml b/modules/desktop/Desktop.qml index 7444afa8c..cb32d04bd 100644 --- a/modules/desktop/Desktop.qml +++ b/modules/desktop/Desktop.qml @@ -105,7 +105,7 @@ PanelWindow { console.log("Context menu requested for:", itemName); Visibilities.contextMenu.openCustomMenu([ { - text: "Open", + text: I18n.t("desktop.open"), icon: Icons.launch, isSeparator: false, onTriggered: function () { @@ -121,7 +121,7 @@ PanelWindow { text: "" }, { - text: "Delete", + text: I18n.t("desktop.delete"), icon: Icons.trash, textColor: Colors.overError, highlightColor: Colors.error, @@ -239,7 +239,7 @@ PanelWindow { Text { anchors.centerIn: parent - text: "Loading desktop..." + text: I18n.t("lockscreen.loading") color: "white" font.family: Config.defaultFont font.pixelSize: Styling.fontSize(0) diff --git a/modules/dock/DockContent.qml b/modules/dock/DockContent.qml index a6b31db30..7a4c36b4d 100644 --- a/modules/dock/DockContent.qml +++ b/modules/dock/DockContent.qml @@ -453,7 +453,7 @@ Item { StyledToolTip { show: pinButton.hovered - tooltipText: root.pinned ? "Unpin dock" : "Pin dock" + tooltipText: root.pinned ? I18n.t("dock.tooltip.unpin_dock") : I18n.t("dock.tooltip.pin_dock") } } } @@ -527,7 +527,7 @@ Item { StyledToolTip { show: overviewButton.hovered - tooltipText: "Overview" + tooltipText: I18n.t("bar.tooltip.overview") } } } @@ -587,7 +587,7 @@ Item { StyledToolTip { show: pinButtonV.hovered - tooltipText: root.pinned ? "Unpin dock" : "Pin dock" + tooltipText: root.pinned ? I18n.t("dock.tooltip.unpin_dock") : I18n.t("dock.tooltip.pin_dock") } } } @@ -661,7 +661,7 @@ Item { StyledToolTip { show: overviewButtonV.hovered - tooltipText: "Overview" + tooltipText: I18n.t("bar.tooltip.overview") } } } diff --git a/modules/notifications/NotificationDelegate.qml b/modules/notifications/NotificationDelegate.qml index 82848296f..b14da8e7e 100644 --- a/modules/notifications/NotificationDelegate.qml +++ b/modules/notifications/NotificationDelegate.qml @@ -207,7 +207,7 @@ Item { // Timestamp a la derecha Text { id: timestampText - text: latestNotification ? NotificationUtils.getFriendlyNotifTimeString(latestNotification.time) : "" + text: latestNotification ? NotificationUtils.getFriendlyNotifTimeString(latestNotification.time, I18n.t) : "" font.family: Config.theme.font font.pixelSize: Config.theme.fontSize font.weight: Font.Bold @@ -303,7 +303,7 @@ Item { } Text { - text: latestNotification ? NotificationUtils.getFriendlyNotifTimeString(latestNotification.time) : "" + text: latestNotification ? NotificationUtils.getFriendlyNotifTimeString(latestNotification.time, I18n.t) : "" font.family: Config.theme.font font.pixelSize: Config.theme.fontSize font.weight: Font.Bold diff --git a/modules/notifications/NotificationGroup.qml b/modules/notifications/NotificationGroup.qml index 22701ddd8..e59be6ddd 100644 --- a/modules/notifications/NotificationGroup.qml +++ b/modules/notifications/NotificationGroup.qml @@ -235,7 +235,7 @@ Item { id: timeText Layout.rightMargin: 10 horizontalAlignment: Text.AlignLeft - text: root.multipleNotifications ? "" : NotificationUtils.getFriendlyNotifTimeString(notificationGroup?.time) + text: root.multipleNotifications ? "" : NotificationUtils.getFriendlyNotifTimeString(notificationGroup?.time, I18n.t) font.family: Config.theme.font font.pixelSize: Config.theme.fontSize color: Colors.overBackground diff --git a/modules/notifications/notification_utils.js b/modules/notifications/notification_utils.js index fc8fc20a8..621bac302 100644 --- a/modules/notifications/notification_utils.js +++ b/modules/notifications/notification_utils.js @@ -1,4 +1,4 @@ -const getFriendlyNotifTimeString = (timestamp) => { +const getFriendlyNotifTimeString = (timestamp, t) => { if (!timestamp) return ''; const messageTime = new Date(timestamp); const now = new Date(); @@ -6,7 +6,7 @@ const getFriendlyNotifTimeString = (timestamp) => { // Less than 1 minute if (diffMs < 60000) - return 'Now'; + return t ? t("notifications.now") : 'Now'; // Same day - show relative time if (messageTime.toDateString() === now.toDateString()) { @@ -28,9 +28,20 @@ const getFriendlyNotifTimeString = (timestamp) => { // Yesterday (fallback, shouldn't reach here normally) if (messageTime.toDateString() === new Date(now.getTime() - 86400000).toDateString()) - return 'Yesterday'; + return t ? t("notifications.yesterday") : 'Yesterday'; // Older dates (fallback for very old notifications) + if (t) { + const monthKeys = [ + "calendar.month.january", "calendar.month.february", + "calendar.month.march", "calendar.month.april", + "calendar.month.may", "calendar.month.june", + "calendar.month.july", "calendar.month.august", + "calendar.month.september", "calendar.month.october", + "calendar.month.november", "calendar.month.december" + ]; + return t(monthKeys[messageTime.getMonth()]) + " " + messageTime.getDate(); + } return Qt.formatDateTime(messageTime, "MMMM dd"); }; diff --git a/modules/services/I18n.qml b/modules/services/I18n.qml new file mode 100644 index 000000000..49e5ce1b9 --- /dev/null +++ b/modules/services/I18n.qml @@ -0,0 +1,114 @@ +pragma Singleton + +import QtQuick +import Quickshell +import Quickshell.Io +import qs.config + +Singleton { + id: root + + readonly property string configLanguage: Config.system?.language ?? "auto" + property string resolvedLanguage: "en" + property var strings: ({}) + property var fallback: ({}) + property var availableLanguages: ({}) + property bool ready: false + + function t(key) { + let str = root.strings[key] ?? root.fallback[key] ?? key; + for (let i = 1; i < arguments.length; i++) + str = str.replace("%" + i, arguments[i]); + return str; + } + + function detectSystemLanguage() { + const sources = [ + Qt.locale().name, + Quickshell.env("LC_MESSAGES"), + Quickshell.env("LC_ALL"), + Quickshell.env("LANG") + ]; + for (const src of sources) { + if (src && src.length >= 2) { + const code = src.substring(0, 2).toLowerCase(); + if (code !== "c" && code !== "po") + return code; + } + } + return "en"; + } + + function resolveLanguage() { + const lang = root.configLanguage === "auto" + ? detectSystemLanguage() + : root.configLanguage; + + if (root.availableLanguages[lang]) + return lang; + return "en"; + } + + onConfigLanguageChanged: { + root.resolvedLanguage = resolveLanguage(); + } + +FileView { + id: languagesLoader + path: Qt.resolvedUrl("../../translations/languages.json") + preload: true + onLoaded: { + try { + root.availableLanguages = JSON.parse(text()); + root.resolvedLanguage = root.resolveLanguage(); + } catch (e) { + console.warn("I18n: failed to parse languages.json:", e); + root.availableLanguages = { "en": "English" }; + } + } + } + + FileView { + id: fallbackLoader + path: Qt.resolvedUrl("../../translations/en.json") + preload: true + onLoaded: { + try { + root.fallback = JSON.parse(text()); + if (root.resolvedLanguage === "en") { + root.strings = root.fallback; + root.ready = true; + } + } catch (e) { + console.warn("I18n: failed to parse en.json:", e); + } + } + } + + FileView { + id: langLoader + path: root.resolvedLanguage !== "en" + ? Qt.resolvedUrl("../../translations/" + root.resolvedLanguage + ".json") + : "" + onLoaded: { + if (root.resolvedLanguage === "en") return; + try { + root.strings = JSON.parse(text()); + root.ready = true; + } catch (e) { + console.warn("I18n: failed to parse " + root.resolvedLanguage + ".json:", e); + root.strings = root.fallback; + root.ready = true; + } + } + } + + onResolvedLanguageChanged: { + if (resolvedLanguage === "en") { + root.strings = root.fallback; + root.ready = Object.keys(root.fallback).length > 0; + } else { + langLoader.reload(); + } + } +} diff --git a/modules/services/PowerProfile.qml b/modules/services/PowerProfile.qml index b61f5438a..f4b7e4681 100644 --- a/modules/services/PowerProfile.qml +++ b/modules/services/PowerProfile.qml @@ -315,11 +315,11 @@ Singleton { function getProfileDisplayName(profileName) { if (profileName === "power-saver") - return "Power Save"; + return I18n.t("power_profile.power_save"); if (profileName === "balanced") - return "Balanced"; + return I18n.t("power_profile.balanced"); if (profileName === "performance") - return "Performance"; + return I18n.t("power_profile.performance"); return profileName; } } diff --git a/modules/services/WeatherService.qml b/modules/services/WeatherService.qml index fb493bca6..2a4b7384c 100644 --- a/modules/services/WeatherService.qml +++ b/modules/services/WeatherService.qml @@ -439,8 +439,17 @@ Singleton { var day = parseInt(dateParts[2]); var dayDate = new Date(year, month, day); - var rawDayName = i === 0 ? "Today" : dayDate.toLocaleDateString(Qt.locale(), "ddd"); - var dayName = rawDayName.charAt(0).toUpperCase() + rawDayName.slice(1); + var dayName; + if (i === 0) { + dayName = I18n.t("weather.today"); + } else { + var dayKeys = [ + "calendar.day.sun", "calendar.day.mon", "calendar.day.tue", + "calendar.day.wed", "calendar.day.thu", "calendar.day.fri", + "calendar.day.sat" + ]; + dayName = I18n.t(dayKeys[dayDate.getDay()]); + } forecastData.push({ date: daily.time[i], dayName: dayName, diff --git a/modules/sidebar/AssistantSidebar.qml b/modules/sidebar/AssistantSidebar.qml index be201de33..1e769e81a 100644 --- a/modules/sidebar/AssistantSidebar.qml +++ b/modules/sidebar/AssistantSidebar.qml @@ -29,23 +29,23 @@ Item { property var slashCommands: [ { name: "model", - description: "Switch AI model" + description: I18n.t("ai.cmd_switch_model") }, { name: "help", - description: "Show help" + description: I18n.t("ai.cmd_show_help") }, { name: "new", - description: "Start new chat" + description: I18n.t("ai.cmd_start_new_chat") }, { name: "key", - description: "Set API key" + description: I18n.t("ai.cmd_set_api_key") }, { name: "prompt", - description: "Set system prompt" + description: I18n.t("ai.cmd_set_system_prompt") } ] @@ -413,7 +413,7 @@ Item { spacing: 8 Text { - text: "Chat History" + text: I18n.t("ai.chat_history") color: Colors.overSurface font.family: Config.theme.font font.pixelSize: 18 @@ -647,7 +647,7 @@ Item { spacing: 8 Text { - text: "Hello, " + mainChatArea.username + "." + text: I18n.t("ai.hello_user", mainChatArea.username) font.family: Config.theme.font font.pixelSize: 32 font.weight: Font.Bold @@ -991,7 +991,7 @@ Item { } Text { - text: "Run Command" + text: I18n.t("ai.run_command") color: Styling.srItem("overprimary") font.family: Config.theme.font font.weight: Font.Bold @@ -1021,7 +1021,7 @@ Item { spacing: 8 Button { - text: "Reject" + text: I18n.t("ai.reject") highlighted: true flat: true onClicked: Ai.rejectCommand(index) @@ -1042,7 +1042,7 @@ Item { } Button { - text: "Approve" + text: I18n.t("ai.approve") highlighted: true flat: true onClicked: Ai.approveCommand(index) @@ -1065,14 +1065,14 @@ Item { Text { visible: modelData.functionApproved === true - text: "Command Approved" + text: I18n.t("ai.command_approved") color: Colors.success font.pixelSize: 12 } Text { visible: modelData.functionApproved === false && !modelData.functionPending - text: "Command Rejected" + text: I18n.t("ai.command_rejected") color: Colors.error font.pixelSize: 12 } @@ -1413,7 +1413,7 @@ Item { id: inputField focus: true activeFocusOnTab: true - placeholderText: mainChatArea.isWelcome ? "Ask AI or type /help..." : "Message AI..." + placeholderText: mainChatArea.isWelcome ? I18n.t("ai.ask_or_help") : I18n.t("ai.message") placeholderTextColor: Colors.outline font.pixelSize: 14 color: Colors.overBackground diff --git a/modules/sidebar/CodeBlock.qml b/modules/sidebar/CodeBlock.qml index 73a2458ad..4711975cd 100644 --- a/modules/sidebar/CodeBlock.qml +++ b/modules/sidebar/CodeBlock.qml @@ -6,6 +6,7 @@ import Quickshell.Io import qs.modules.theme import qs.config import qs.modules.components +import qs.modules.services import org.kde.syntaxhighlighting ColumnLayout { @@ -77,7 +78,7 @@ ColumnLayout { Text { id: copyFeedback - text: "Copied!" + text: I18n.t("common.copied") font.family: Config.theme.font font.pixelSize: 10 color: Colors.success diff --git a/modules/sidebar/ModelSelectorPopup.qml b/modules/sidebar/ModelSelectorPopup.qml index c5e77af12..a5fb2a167 100644 --- a/modules/sidebar/ModelSelectorPopup.qml +++ b/modules/sidebar/ModelSelectorPopup.qml @@ -115,7 +115,7 @@ Popup { SearchInput { id: searchInput Layout.fillWidth: true - placeholderText: "Search models..." + placeholderText: I18n.t("ai.search_models") iconText: "" // Removed icon as requested onSearchTextChanged: text => { @@ -233,7 +233,7 @@ Popup { Layout.fillWidth: true Layout.fillHeight: true verticalAlignment: Text.AlignVCenter - text: "Refresh?" + text: I18n.t("ai.refresh_models") font.family: Config.theme.font font.pixelSize: 13 font.weight: Font.Bold diff --git a/modules/tools/ScreenrecordTool.qml b/modules/tools/ScreenrecordTool.qml index 870dd7490..58bcc5f38 100644 --- a/modules/tools/ScreenrecordTool.qml +++ b/modules/tools/ScreenrecordTool.qml @@ -40,14 +40,14 @@ PanelWindow { { name: "audio", icon: recordAudioOutput ? Icons.speakerHigh : Icons.speakerSlash, - tooltip: "Toggle Audio Output", + tooltip: I18n.t("tools.toggle_audio"), type: "toggle", variant: recordAudioOutput ? "primary" : "focus" }, { name: "mic", icon: recordAudioInput ? Icons.mic : Icons.micSlash, - tooltip: "Toggle Microphone", + tooltip: I18n.t("tools.toggle_mic"), type: "toggle", variant: recordAudioInput ? "primary" : "focus" }, @@ -57,25 +57,25 @@ PanelWindow { { name: "region", icon: Icons.regionScreenshot, - tooltip: ScreenRecorder.canRecordDirectly ? "Region" : "Region (Unavailable on NixOS without config)", + tooltip: ScreenRecorder.canRecordDirectly ? I18n.t("tools.screenrecord_region") : I18n.t("tools.screenrecord_region_unavailable"), enabled: ScreenRecorder.canRecordDirectly }, { name: "window", icon: Icons.windowScreenshot, - tooltip: ScreenRecorder.canRecordDirectly ? "Window" : "Window (Unavailable on NixOS without config)", + tooltip: ScreenRecorder.canRecordDirectly ? I18n.t("tools.screenrecord_window") : I18n.t("tools.screenrecord_window_unavailable"), enabled: ScreenRecorder.canRecordDirectly }, { name: "screen", icon: Icons.fullScreenshot, - tooltip: ScreenRecorder.canRecordDirectly ? "Screen" : "Screen (Unavailable on NixOS without config)", + tooltip: ScreenRecorder.canRecordDirectly ? I18n.t("tools.screenrecord_screen") : I18n.t("tools.screenrecord_screen_unavailable"), enabled: ScreenRecorder.canRecordDirectly }, { name: "portal", icon: Icons.aperture, - tooltip: "Portal" + tooltip: I18n.t("tools.screenrecord_portal") } ]; } diff --git a/modules/tools/ScreenshotOverlay.qml b/modules/tools/ScreenshotOverlay.qml index 24d2cd847..bd7d38ecc 100644 --- a/modules/tools/ScreenshotOverlay.qml +++ b/modules/tools/ScreenshotOverlay.qml @@ -203,7 +203,7 @@ PanelWindow { StyledToolTip { show: parent.containsMouse - tooltipText: "Copy" + tooltipText: I18n.t("common.copy") } } @@ -214,7 +214,7 @@ PanelWindow { } StyledToolTip { show: parent.containsMouse - tooltipText: "Save & Close" + tooltipText: I18n.t("common.save_close") } } @@ -230,7 +230,7 @@ PanelWindow { } StyledToolTip { show: parent.containsMouse - tooltipText: "Edit with Gradia" + tooltipText: I18n.t("wallpapers.edit_gradia") } } @@ -249,7 +249,7 @@ PanelWindow { } StyledToolTip { show: parent.containsMouse - tooltipText: "Delete" + tooltipText: I18n.t("common.delete") } } } diff --git a/modules/tools/ScreenshotTool.qml b/modules/tools/ScreenshotTool.qml index eaacd81bc..be98cc821 100644 --- a/modules/tools/ScreenshotTool.qml +++ b/modules/tools/ScreenshotTool.qml @@ -79,17 +79,17 @@ PanelWindow { { name: "region", icon: Icons.regionScreenshot, - tooltip: "Region" + tooltip: I18n.t("screenshot.region") }, { name: "window", icon: Icons.windowScreenshot, - tooltip: "Window" + tooltip: I18n.t("screenshot.window") }, { name: "screen", icon: Icons.fullScreenshot, - tooltip: "Screen" + tooltip: I18n.t("screenshot.screen") } ] diff --git a/modules/widgets/config/AiPanel.qml b/modules/widgets/config/AiPanel.qml index 891692a42..aa5e0a329 100644 --- a/modules/widgets/config/AiPanel.qml +++ b/modules/widgets/config/AiPanel.qml @@ -28,7 +28,7 @@ Item { spacing: 24 Text { - text: "AI & API Keys" + text: I18n.t("ai.panel_title") font.family: Config.theme.font font.pixelSize: 24 font.weight: Font.Bold @@ -66,7 +66,7 @@ Item { Layout.fillWidth: true } Text { - text: KeyStore.hasKey(modelData) ? "Key Configured" : "Not Configured" + text: KeyStore.hasKey(modelData) ? I18n.t("binds.key_configured") : I18n.t("binds.not_configured") font.family: Config.theme.font font.pixelSize: 12 color: KeyStore.hasKey(modelData) ? Colors.success : Colors.outline @@ -81,7 +81,7 @@ Item { visible: modelData !== "ollama" id: keyInput Layout.fillWidth: true - placeholderText: "Enter API Key..." + placeholderText: I18n.t("ai.enter_api_key") echoMode: TextInput.Password font.family: Config.theme.font color: Colors.overSurface @@ -101,7 +101,7 @@ Item { } Button { id: saveButton - text: modelData === "ollama" ? (KeyStore.hasKey("ollama") ? "Configured" : "Enable") : "Save" + text: modelData === "ollama" ? (KeyStore.hasKey("ollama") ? "Configured" : "Enable") : I18n.t("common.save") visible: modelData === "ollama" ? !KeyStore.hasKey("ollama") : true hoverEnabled: true leftPadding: 6 @@ -142,7 +142,7 @@ Item { Button { id: clearButton visible: KeyStore.hasKey(modelData) - text: modelData === "ollama" ? "Disable" : "Clear" + text: modelData === "ollama" ? "Disable" : I18n.t("common.clear") leftPadding: 6 rightPadding: 6 topPadding: 4 @@ -178,7 +178,7 @@ Item { // Custom Provider Text { - text: "Custom Provider" + text: I18n.t("ai.custom_provider") font.family: Config.theme.font font.pixelSize: 20 font.weight: Font.Bold @@ -203,7 +203,7 @@ Item { RowLayout { Layout.fillWidth: true Text { - text: "Custom Provider API Key" + text: I18n.t("ai.custom_provider_key") font.family: Config.theme.font font.pixelSize: 14 font.weight: Font.Bold @@ -211,7 +211,7 @@ Item { Layout.fillWidth: true } Text { - text: KeyStore.hasKey("custom") ? "Key Configured" : "Not Configured" + text: KeyStore.hasKey("custom") ? I18n.t("binds.key_configured") : I18n.t("binds.not_configured") font.family: Config.theme.font font.pixelSize: 12 color: KeyStore.hasKey("custom") ? Colors.success : Colors.outline @@ -225,7 +225,7 @@ Item { TextField { id: customKeyInput Layout.fillWidth: true - placeholderText: "Enter API Key..." + placeholderText: I18n.t("ai.enter_api_key") echoMode: TextInput.Password font.family: Config.theme.font color: Colors.overSurface @@ -245,7 +245,7 @@ Item { } Button { id: customSaveButton - text: "Save" + text: I18n.t("common.save") hoverEnabled: true leftPadding: 6 rightPadding: 6 @@ -283,7 +283,7 @@ Item { Button { id: customClearButton visible: KeyStore.hasKey("custom") - text: "Clear" + text: I18n.t("common.clear") leftPadding: 6 rightPadding: 6 topPadding: 4 @@ -324,7 +324,7 @@ Item { } Text { - text: "Custom Endpoint" + text: I18n.t("ai.custom_endpoint") font.family: Config.theme.font font.pixelSize: 14 color: Colors.overSurface @@ -334,7 +334,7 @@ Item { id: endpointInput Layout.fillWidth: true text: Config.ai.customEndpoint !== undefined ? Config.ai.customEndpoint : "" - placeholderText: "e.g. https://api.example.com/v1/chat/completions" + placeholderText: I18n.t("ai.endpoint_placeholder") font.family: Config.theme.font color: Colors.overSurface padding: 6 @@ -359,7 +359,7 @@ Item { } Text { - text: "Custom cURL Template" + text: I18n.t("ai.custom_curl") font.family: Config.theme.font font.pixelSize: 14 color: Colors.overSurface @@ -367,7 +367,7 @@ Item { } Text { - text: "Placeholders: {{ENDPOINT}}, {{API_KEY}}, {{BODY_PATH}}" + text: I18n.t("ai.curl_placeholders") font.family: Config.theme.font font.pixelSize: 12 color: Colors.outline @@ -377,7 +377,7 @@ Item { id: curlInput Layout.fillWidth: true text: Config.ai.customCurlTemplate !== undefined ? Config.ai.customCurlTemplate : "" - placeholderText: "curl -X POST {{ENDPOINT}} -H 'Authorization: Bearer {{API_KEY}}' -d @{{BODY_PATH}}" + placeholderText: I18n.t("ai.curl_placeholder") font.family: "Monospace" color: Colors.overSurface padding: 6 diff --git a/modules/widgets/dashboard/LauncherButton.qml b/modules/widgets/dashboard/LauncherButton.qml index 9515fbe24..6efef1d89 100644 --- a/modules/widgets/dashboard/LauncherButton.qml +++ b/modules/widgets/dashboard/LauncherButton.qml @@ -9,7 +9,7 @@ ToggleButton { iconTint: Config.bar.launcherIconTint iconFullTint: Config.bar.launcherIconFullTint iconSize: Config.bar.launcherIconSize - tooltipText: "Open Launcher" + tooltipText: I18n.t("bar.tooltip.launcher") onToggle: function () { if (GlobalStates.launcherOpen) { diff --git a/modules/widgets/dashboard/clipboard/ClipboardTab.qml b/modules/widgets/dashboard/clipboard/ClipboardTab.qml index 258151427..b820e7db3 100644 --- a/modules/widgets/dashboard/clipboard/ClipboardTab.qml +++ b/modules/widgets/dashboard/clipboard/ClipboardTab.qml @@ -719,7 +719,7 @@ Item { width: parent.width - clearButton.width - parent.spacing height: parent.height text: root.searchText - placeholderText: "Search in clipboard..." + placeholderText: I18n.t("clipboard.search") prefixIcon: root.prefixIcon onSearchTextChanged: text => { @@ -946,7 +946,7 @@ Item { Text { width: parent.width - 32 - parent.spacing height: parent.height - text: "Clear all?" + text: I18n.t("clipboard.clear_all_confirm") font.family: Config.theme.font font.weight: Font.Bold font.pixelSize: Config.theme.fontSize @@ -1759,7 +1759,7 @@ Item { model: { var options = [ { - text: "Copy", + text: I18n.t("common.copy"), icon: Icons.copy, highlightColor: Styling.srItem("overprimary"), textColor: Styling.srItem("primary"), @@ -1773,7 +1773,7 @@ Item { // Add Open option for files, images, and URLs if (modelData.isFile || modelData.isImage || ClipboardUtils.isUrl(modelData.preview)) { options.push({ - text: "Open", + text: I18n.t("common.open"), icon: Icons.popOpen, highlightColor: Styling.srItem("overprimary"), textColor: Styling.srItem("primary"), @@ -1784,7 +1784,7 @@ Item { } options.push({ - text: modelData.pinned ? "Unpin" : "Pin", + text: modelData.pinned ? I18n.t("clipboard.unpin") : I18n.t("clipboard.pin"), icon: modelData.pinned ? Icons.unpin : Icons.pin, highlightColor: Styling.srItem("overprimary"), textColor: Styling.srItem("primary"), @@ -1794,7 +1794,7 @@ Item { root.expandedItemIndex = -1; } }, { - text: "Alias", + text: I18n.t("clipboard.alias"), icon: Icons.edit, highlightColor: Colors.secondary, textColor: Styling.srItem("secondary"), @@ -1803,7 +1803,7 @@ Item { root.expandedItemIndex = -1; } }, { - text: "Delete", + text: I18n.t("common.delete"), icon: Icons.trash, highlightColor: Colors.error, textColor: Styling.srItem("error"), @@ -2275,15 +2275,23 @@ Item { var diffDays = Math.floor(diffHours / 24); if (diffMins < 1) - return "Just now"; + return I18n.t("clipboard.just_now"); if (diffMins < 60) - return diffMins + " min ago"; + return I18n.t("clipboard.min_ago", diffMins); if (diffHours < 24) - return diffHours + " hour" + (diffHours > 1 ? "s" : "") + " ago"; + return I18n.t("clipboard.hours_ago", diffHours); if (diffDays < 7) - return diffDays + " day" + (diffDays > 1 ? "s" : "") + " ago"; - - return Qt.formatDateTime(date, "MMM dd, yyyy"); + return I18n.t("clipboard.days_ago", diffDays); + + var monthKeys = [ + "calendar.month.january", "calendar.month.february", + "calendar.month.march", "calendar.month.april", + "calendar.month.may", "calendar.month.june", + "calendar.month.july", "calendar.month.august", + "calendar.month.september", "calendar.month.october", + "calendar.month.november", "calendar.month.december" + ]; + return I18n.t(monthKeys[date.getMonth()]) + " " + date.getDate() + ", " + date.getFullYear(); } color: { if (isInDeleteMode) { @@ -2404,7 +2412,7 @@ Item { } Text { - text: "No clipboard history" + text: I18n.t("clipboard.no_history") font.family: Config.theme.font font.pixelSize: Config.theme.fontSize font.weight: Font.Bold @@ -2413,7 +2421,7 @@ Item { } Text { - text: "Copy something to get started" + text: I18n.t("clipboard.copy_to_start") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-2) color: Colors.outline @@ -2990,7 +2998,7 @@ Item { } Text { - text: "Loading preview..." + text: I18n.t("clipboard.loading_preview") font.family: Config.theme.font font.pixelSize: Config.theme.fontSize color: Colors.outline @@ -3100,7 +3108,7 @@ Item { spacing: 4 Text { - text: "Link" + text: I18n.t("clipboard.link") font.family: Config.theme.font font.pixelSize: Config.theme.fontSize - 1 font.weight: Font.Medium @@ -3292,7 +3300,7 @@ Item { spacing: 2 Text { - text: "MIME Type" + text: I18n.t("clipboard.mime_type") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-2) font.weight: Font.Medium @@ -3315,7 +3323,7 @@ Item { spacing: 2 Text { - text: "Size" + text: I18n.t("clipboard.size") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-2) font.weight: Font.Medium @@ -3351,7 +3359,7 @@ Item { spacing: 2 Text { - text: "Date" + text: I18n.t("clipboard.date") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-2) font.weight: Font.Medium @@ -3361,9 +3369,22 @@ Item { Text { text: { if (!previewPanel.currentItem || !previewPanel.currentItem.createdAt) - return "Unknown"; + return I18n.t("player.unknown"); var date = new Date(previewPanel.currentItem.createdAt); - return Qt.formatDateTime(date, "MMM dd, yyyy hh:mm:ss AP"); + var monthKeys = [ + "calendar.month.january", "calendar.month.february", + "calendar.month.march", "calendar.month.april", + "calendar.month.may", "calendar.month.june", + "calendar.month.july", "calendar.month.august", + "calendar.month.september", "calendar.month.october", + "calendar.month.november", "calendar.month.december" + ]; + var h = date.getHours(); + var m = String(date.getMinutes()).padStart(2, "0"); + var s = String(date.getSeconds()).padStart(2, "0"); + var ap = h >= 12 ? "PM" : "AM"; + var h12 = h % 12 || 12; + return I18n.t(monthKeys[date.getMonth()]) + " " + date.getDate() + ", " + date.getFullYear() + " " + h12 + ":" + m + ":" + s + " " + ap; } font.family: Config.theme.font font.pixelSize: Config.theme.fontSize @@ -3377,7 +3398,7 @@ Item { spacing: 2 Text { - text: "Checksum" + text: I18n.t("clipboard.checksum") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-2) font.weight: Font.Medium diff --git a/modules/widgets/dashboard/controls/AudioMixerPanel.qml b/modules/widgets/dashboard/controls/AudioMixerPanel.qml index b0dab3660..af82ba42b 100644 --- a/modules/widgets/dashboard/controls/AudioMixerPanel.qml +++ b/modules/widgets/dashboard/controls/AudioMixerPanel.qml @@ -41,19 +41,19 @@ Item { id: titlebar width: root.contentWidth anchors.horizontalCenter: parent.horizontalCenter - title: "Sound" + title: I18n.t("mixer.title") actions: [ { icon: Audio.protectionEnabled ? Icons.shieldCheck : Icons.shield, - tooltip: Audio.protectionEnabled ? "Volume protection enabled" : "Volume protection disabled", + tooltip: Audio.protectionEnabled ? I18n.t("mixer.protection_enabled") : I18n.t("mixer.protection_disabled"), onClicked: function () { Audio.setProtectionEnabled(!Audio.protectionEnabled); } }, { icon: Icons.popOpen, - tooltip: "Open PipeWire Volume Control", + tooltip: I18n.t("mixer.open_pavucontrol"), onClicked: function () { Quickshell.execDetached(["pavucontrol"]); } @@ -89,7 +89,7 @@ Item { } Text { - text: "Output" + text: I18n.t("mixer.output") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -133,7 +133,7 @@ Item { } Text { - text: "Input" + text: I18n.t("mixer.input") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -168,7 +168,7 @@ Item { // Section: Devices Text { - text: root.showOutput ? "Output Device" : "Input Device" + text: root.showOutput ? I18n.t("mixer.output_device") : I18n.t("mixer.input_device") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -203,7 +203,7 @@ Item { // Section: Volume Mixer Text { - text: "Volume Mixer" + text: I18n.t("mixer.volume_mixer") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -233,7 +233,7 @@ Item { // Empty state for apps Text { visible: (root.showOutput ? Audio.outputAppNodes : Audio.inputAppNodes).length === 0 - text: "No applications using audio" + text: I18n.t("mixer.no_apps") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) color: Colors.outline diff --git a/modules/widgets/dashboard/controls/AudioVolumeEntry.qml b/modules/widgets/dashboard/controls/AudioVolumeEntry.qml index 17b761471..289b6f4b0 100644 --- a/modules/widgets/dashboard/controls/AudioVolumeEntry.qml +++ b/modules/widgets/dashboard/controls/AudioVolumeEntry.qml @@ -144,7 +144,7 @@ Item { StyledToolTip { visible: parent.visible && protectionIndicatorMa.containsMouse - tooltipText: "Volume protection active" + tooltipText: I18n.t("controls.volume_protection") } MouseArea { diff --git a/modules/widgets/dashboard/controls/BindsPanel.qml b/modules/widgets/dashboard/controls/BindsPanel.qml index 6655f2052..8f53e7312 100644 --- a/modules/widgets/dashboard/controls/BindsPanel.qml +++ b/modules/widgets/dashboard/controls/BindsPanel.qml @@ -6,6 +6,7 @@ import QtQuick.Layouts import Quickshell.Io import qs.modules.theme import qs.modules.components +import qs.modules.services import qs.config import "../../../../config/KeybindActions.js" as KeybindActions @@ -76,7 +77,7 @@ Item { readonly property var actionOptions: { const options = KeybindActions.getActionOptions(); if (editActionId === "legacy.dispatcher") { - return options.concat([{ id: "legacy.dispatcher", label: "Legacy Dispatcher", category: "Advanced" }]); + return options.concat([{ id: "legacy.dispatcher", label: I18n.t("binds.legacy_dispatcher"), category: "Advanced" }]); } return options; } @@ -396,12 +397,12 @@ Item { readonly property var categories: [ { id: "ambxst", - label: "Ambxst", + label: I18n.t("binds.ambxst"), icon: Icons.widgets }, { id: "custom", - label: "Custom", + label: I18n.t("binds.custom"), icon: Icons.gear } ] @@ -578,20 +579,20 @@ Item { id: titlebar width: root.contentWidth anchors.horizontalCenter: parent.horizontalCenter - title: "Keybinds" + title: I18n.t("settings.binds") statusText: "" actions: [ { icon: Icons.plus, - tooltip: "Add keybind", + tooltip: I18n.t("binds.add_keybind"), onClicked: function () { root.addNewBind(); } }, { icon: Icons.sync, - tooltip: "Reload binds", + tooltip: I18n.t("binds.reload_binds"), onClicked: function () { Config.keybindsLoader.reload(); } @@ -935,7 +936,7 @@ Item { StyledToolTip { visible: deleteButtonArea.containsMouse - tooltipText: "Delete keybind" + tooltipText: I18n.t("binds.delete_keybind") } } @@ -962,7 +963,7 @@ Item { } Text { - text: "Reset to default" + text: I18n.t("common.reset_default") font.family: Config.theme.font font.pixelSize: Styling.fontSize(0) font.weight: Font.Medium @@ -1027,7 +1028,7 @@ Item { } Text { - text: "Save" + text: I18n.t("common.save") font.family: Config.theme.font font.pixelSize: Styling.fontSize(0) font.weight: Font.Medium @@ -1065,7 +1066,7 @@ Item { visible: !root.isEditingAmbxst Text { - text: "Name (optional)" + text: I18n.t("binds.name_optional") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -1097,7 +1098,7 @@ Item { Text { anchors.verticalCenter: parent.verticalCenter visible: !nameInput.text && !nameInput.activeFocus - text: "e.g. Open Terminal, Switch to Workspace 1..." + text: I18n.t("binds.keybind_name_placeholder") font: nameInput.font color: Colors.overSurfaceVariant } @@ -1159,7 +1160,7 @@ Item { spacing: 8 Text { - text: "Key Combination" + text: I18n.t("binds.key_combination") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -1296,7 +1297,7 @@ Item { StyledToolTip { visible: addKeyBtnArea.containsMouse - tooltipText: "Add another key" + tooltipText: I18n.t("binds.add_key") } } } @@ -1374,7 +1375,7 @@ Item { Text { anchors.verticalCenter: parent.verticalCenter visible: !keyInput.text && !keyInput.activeFocus - text: "e.g. R, TAB, ESCAPE, mouse:272..." + text: I18n.t("binds.key_placeholder") font: keyInput.font color: Colors.overSurfaceVariant } @@ -1396,7 +1397,7 @@ Item { spacing: 8 Text { - text: "Action" + text: I18n.t("binds.action") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -1533,13 +1534,13 @@ Item { StyledToolTip { visible: addActionBtnArea.containsMouse - tooltipText: "Add another action" + tooltipText: I18n.t("binds.add_action") } } } Text { - text: "Action" + text: I18n.t("binds.action") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -1690,7 +1691,7 @@ Item { // LAYOUT SELECTOR (for AxctlService) // ===================== Text { - text: "Layouts (AxctlService)" + text: I18n.t("binds.layouts_axctl") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -1699,7 +1700,7 @@ Item { } Text { - text: "Leave all unselected to work in all layouts" + text: I18n.t("binds.layouts_hint") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-2) color: Colors.overSurfaceVariant diff --git a/modules/widgets/dashboard/controls/BluetoothDeviceItem.qml b/modules/widgets/dashboard/controls/BluetoothDeviceItem.qml index d35908ed1..42b51be69 100644 --- a/modules/widgets/dashboard/controls/BluetoothDeviceItem.qml +++ b/modules/widgets/dashboard/controls/BluetoothDeviceItem.qml @@ -104,11 +104,11 @@ Item { text: { let status = ""; if (root.device?.connected) { - status = "Connected"; + status = I18n.t("bluetooth.connected"); } else if (root.device?.paired) { - status = "Paired"; + status = I18n.t("bluetooth.paired"); } else { - status = "Not paired"; + status = I18n.t("bluetooth.not_paired"); } if (root.device?.batteryAvailable) { @@ -193,7 +193,7 @@ Item { } contentItem: Text { - text: "Forget" + text: I18n.t("bluetooth.forget") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) color: Styling.srItem("error") @@ -221,7 +221,7 @@ Item { } contentItem: Text { - text: root.device?.connected ? "Disconnect" : "Connect" + text: root.device?.connected ? I18n.t("bluetooth.disconnect") : I18n.t("bluetooth.connect") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) color: root.device?.connected ? Colors.overSurfaceVariant : Styling.srItem("primary") diff --git a/modules/widgets/dashboard/controls/BluetoothPanel.qml b/modules/widgets/dashboard/controls/BluetoothPanel.qml index 462f39f62..8570c9395 100644 --- a/modules/widgets/dashboard/controls/BluetoothPanel.qml +++ b/modules/widgets/dashboard/controls/BluetoothPanel.qml @@ -55,21 +55,21 @@ Item { id: titlebar width: root.contentWidth anchors.horizontalCenter: parent.horizontalCenter - title: "Bluetooth" + title: I18n.t("settings.bluetooth") showToggle: true toggleChecked: BluetoothService.enabled actions: [ { icon: Icons.popOpen, - tooltip: "Open Blueman", + tooltip: I18n.t("bluetooth.open_manager"), onClicked: function () { Quickshell.execDetached(["blueman-manager"]); } }, { icon: Icons.sync, - tooltip: "Scan for devices", + tooltip: I18n.t("bluetooth.scan"), enabled: BluetoothService.enabled, loading: BluetoothService.discovering || BluetoothService.isUpdating, onClicked: function () { @@ -104,7 +104,7 @@ Item { Text { anchors.centerIn: parent visible: deviceList.count === 0 && !BluetoothService.discovering - text: BluetoothService.enabled ? "No devices found" : "Bluetooth is disabled" + text: BluetoothService.enabled ? I18n.t("bluetooth.no_devices") : I18n.t("bluetooth.disabled") font.family: Config.theme.font font.pixelSize: Config.theme.fontSize color: Colors.overSurfaceVariant diff --git a/modules/widgets/dashboard/controls/ColorButton.qml b/modules/widgets/dashboard/controls/ColorButton.qml index 34fa1a2e0..35c5312f4 100644 --- a/modules/widgets/dashboard/controls/ColorButton.qml +++ b/modules/widgets/dashboard/controls/ColorButton.qml @@ -4,6 +4,7 @@ import QtQuick.Controls import QtQuick.Layouts import qs.modules.theme import qs.modules.components +import qs.modules.services import qs.config // Reusable color picker button with preview and label @@ -30,7 +31,7 @@ StyledRect { readonly property string displayName: { if (!currentColor) return ""; const val = currentColor.toString(); - return val.startsWith("#") ? "Custom" : val; + return val.startsWith("#") ? I18n.t("theme.custom") : val; } RowLayout { diff --git a/modules/widgets/dashboard/controls/ColorPickerPopup.qml b/modules/widgets/dashboard/controls/ColorPickerPopup.qml index 56c4e0890..9c493201f 100644 --- a/modules/widgets/dashboard/controls/ColorPickerPopup.qml +++ b/modules/widgets/dashboard/controls/ColorPickerPopup.qml @@ -4,6 +4,7 @@ import QtQuick.Controls import QtQuick.Layouts import QtQuick.Dialogs import qs.modules.theme +import qs.modules.services import qs.config Popup { @@ -125,7 +126,7 @@ Popup { } Text { - text: "Custom" + text: I18n.t("theme.custom") font.family: Styling.defaultFont font.pixelSize: Styling.fontSize(-1) color: Colors.overBackground @@ -154,7 +155,7 @@ Popup { onClicked: colorDialog.open() ToolTip.visible: hovered - ToolTip.text: "Color picker" + ToolTip.text: I18n.t("theme.color_picker") ToolTip.delay: 500 } } diff --git a/modules/widgets/dashboard/controls/ColorPickerView.qml b/modules/widgets/dashboard/controls/ColorPickerView.qml index 28025d00b..9bd2ad02b 100644 --- a/modules/widgets/dashboard/controls/ColorPickerView.qml +++ b/modules/widgets/dashboard/controls/ColorPickerView.qml @@ -5,6 +5,7 @@ import QtQuick.Layouts import QtQuick.Dialogs import qs.modules.theme import qs.modules.components +import qs.modules.services import qs.config // Inline color picker view for ThemePanel @@ -171,7 +172,7 @@ Item { } Text { - text: "Custom" + text: I18n.t("color_picker.custom") font.family: Styling.defaultFont font.pixelSize: Styling.fontSize(-1) color: Colors.overBackground @@ -204,7 +205,7 @@ Item { StyledToolTip { visible: pickerMouseArea.containsMouse - text: "Color picker" + text: I18n.t("color_picker.picker") } } } diff --git a/modules/widgets/dashboard/controls/ColorSelector.qml b/modules/widgets/dashboard/controls/ColorSelector.qml index cfbf9d180..29194333c 100644 --- a/modules/widgets/dashboard/controls/ColorSelector.qml +++ b/modules/widgets/dashboard/controls/ColorSelector.qml @@ -4,6 +4,7 @@ import QtQuick.Controls import QtQuick.Layouts import QtQuick.Dialogs import qs.modules.theme +import qs.modules.services import qs.config Item { @@ -307,14 +308,14 @@ Item { onClicked: colorDialog.open() ToolTip.visible: hovered - ToolTip.text: "Open color picker" + ToolTip.text: I18n.t("theme.open_color_picker") ToolTip.delay: 500 } } ColorDialog { id: colorDialog - title: "Select Color" + title: I18n.t("theme.select_color") selectedColor: Config.resolveColor(root.currentValueStr) onAccepted: { diff --git a/modules/widgets/dashboard/controls/CompositorPanel.qml b/modules/widgets/dashboard/controls/CompositorPanel.qml index dfa858be6..2347b0b80 100644 --- a/modules/widgets/dashboard/controls/CompositorPanel.qml +++ b/modules/widgets/dashboard/controls/CompositorPanel.qml @@ -8,6 +8,7 @@ import Quickshell import qs.modules.theme import qs.modules.components import qs.modules.globals +import qs.modules.services import qs.config Item { @@ -343,7 +344,7 @@ Item { Layout.fillWidth: true } Text { - text: "Right click to remove" + text: I18n.t("compositor.right_click_remove") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-2) color: Colors.overSurfaceVariant @@ -556,7 +557,7 @@ Item { id: titlebar width: root.contentWidth anchors.horizontalCenter: parent.horizontalCenter - title: root.currentSection === "" ? "Compositor" : (root.currentSection.charAt(0).toUpperCase() + root.currentSection.slice(1)) + title: root.currentSection === "" ? I18n.t("settings.compositor") : I18n.t("compositor." + root.currentSection) statusText: GlobalStates.compositorHasChanges ? "Unsaved changes" : "" statusColor: Colors.error @@ -564,7 +565,7 @@ Item { let baseActions = [ { icon: Icons.arrowCounterClockwise, - tooltip: "Discard changes", + tooltip: I18n.t("compositor.discard"), enabled: GlobalStates.compositorHasChanges, onClicked: function () { GlobalStates.discardCompositorChanges(); @@ -572,7 +573,7 @@ Item { }, { icon: Icons.disk, - tooltip: "Apply changes", + tooltip: I18n.t("compositor.apply"), enabled: GlobalStates.compositorHasChanges, onClicked: function () { GlobalStates.applyCompositorChanges(); @@ -584,7 +585,7 @@ Item { return [ { icon: Icons.arrowLeft, - tooltip: "Back", + tooltip: I18n.t("compositor.back"), onClicked: function () { root.currentSection = ""; } @@ -608,14 +609,14 @@ Item { spacing: 8 CompositorTabButton { - label: "AxctlService" + label: I18n.t("settings.compositor.axctl") image: "../../../../assets/compositors/hyprland.svg" isSelected: stackLayout.currentIndex === 0 onClicked: stackLayout.currentIndex = 0 } CompositorTabButton { - label: "Coming Soon" + label: I18n.t("common.coming_soon") icon: Icons.clock isSelected: stackLayout.currentIndex === 1 onClicked: stackLayout.currentIndex = 1 @@ -650,19 +651,19 @@ Item { spacing: 8 SectionButton { - text: "General" + text: I18n.t("compositor.general") sectionId: "general" } SectionButton { - text: "Colors" + text: I18n.t("compositor.colors") sectionId: "colors" } SectionButton { - text: "Shadows" + text: I18n.t("compositor.shadows") sectionId: "shadows" } SectionButton { - text: "Blur" + text: I18n.t("compositor.blur") sectionId: "blur" } } @@ -674,7 +675,7 @@ Item { spacing: 8 Text { - text: "General" + text: I18n.t("compositor.general") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -683,7 +684,7 @@ Item { } ToggleRow { - label: "Sync Border Size" + label: I18n.t("compositor.sync_border_size") checked: Config.compositor.syncBorderWidth ?? false onToggled: value => { GlobalStates.markCompositorChanged(); @@ -692,7 +693,7 @@ Item { } NumberInputRow { - label: "Border Size" + label: I18n.t("settings.compositor.border_size") value: Config.compositor.borderSize ?? 2 minValue: 0 maxValue: 999 @@ -705,7 +706,7 @@ Item { } ToggleRow { - label: "Sync Rounding" + label: I18n.t("compositor.sync_rounding") checked: Config.compositor.syncRoundness ?? true onToggled: value => { GlobalStates.markCompositorChanged(); @@ -714,7 +715,7 @@ Item { } NumberInputRow { - label: "Rounding" + label: I18n.t("compositor.rounding") value: Config.compositor.rounding ?? 16 minValue: 0 maxValue: 999 @@ -727,7 +728,7 @@ Item { } NumberInputRow { - label: "Gaps In" + label: I18n.t("compositor.gaps_in") value: Config.compositor.gapsIn ?? 5 minValue: 0 maxValue: 50 @@ -739,7 +740,7 @@ Item { } NumberInputRow { - label: "Gaps Out" + label: I18n.t("compositor.gaps_out") value: Config.compositor.gapsOut ?? 10 minValue: 0 maxValue: 50 @@ -751,7 +752,7 @@ Item { } NumberInputRow { - label: "Border Angle" + label: I18n.t("compositor.border_angle") value: Config.compositor.borderAngle ?? 45 minValue: 0 maxValue: 360 @@ -763,7 +764,7 @@ Item { } NumberInputRow { - label: "Inactive Angle" + label: I18n.t("compositor.inactive_angle") value: Config.compositor.inactiveBorderAngle ?? 45 minValue: 0 maxValue: 360 @@ -787,7 +788,7 @@ Item { spacing: 8 Text { - text: "Colors" + text: I18n.t("compositor.colors") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -796,7 +797,7 @@ Item { } ToggleRow { - label: "Sync Border Color" + label: I18n.t("compositor.sync_border_color") checked: Config.compositor.syncBorderColor ?? false onToggled: value => { GlobalStates.markCompositorChanged(); @@ -806,7 +807,7 @@ Item { // Active Border Color BorderGradientRow { - label: "Active Border" + label: I18n.t("compositor.active_border") colors: Config.compositor.activeBorderColor || ["primary"] dialogTitle: "Edit Active Border Color" enabled: !Config.compositor.syncBorderColor @@ -818,7 +819,7 @@ Item { // Inactive Border Color BorderGradientRow { - label: "Inactive Border" + label: I18n.t("compositor.inactive_border") colors: Config.compositor.inactiveBorderColor || ["surface"] dialogTitle: "Edit Inactive Border Color" onColorsEdited: newColors => { @@ -840,7 +841,7 @@ Item { spacing: 8 Text { - text: "Shadows" + text: I18n.t("compositor.shadows") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -849,7 +850,7 @@ Item { } ToggleRow { - label: "Enabled" + label: I18n.t("settings.compositor.shadows_enabled") checked: Config.compositor.shadowEnabled ?? true onToggled: value => { GlobalStates.markCompositorChanged(); @@ -858,7 +859,7 @@ Item { } ToggleRow { - label: "Sync Color" + label: I18n.t("settings.compositor.sync_shadow_color") checked: Config.compositor.syncShadowColor ?? false onToggled: value => { GlobalStates.markCompositorChanged(); @@ -867,7 +868,7 @@ Item { } ToggleRow { - label: "Sync Opacity" + label: I18n.t("settings.compositor.sync_shadow_opacity") checked: Config.compositor.syncShadowOpacity ?? false onToggled: value => { GlobalStates.markCompositorChanged(); @@ -876,7 +877,7 @@ Item { } NumberInputRow { - label: "Range" + label: I18n.t("settings.compositor.shadow_range") value: Config.compositor.shadowRange ?? 4 minValue: 0 maxValue: 100 @@ -888,7 +889,7 @@ Item { } NumberInputRow { - label: "Offset X" + label: I18n.t("compositor.offset_x") value: parseInt((Config.compositor.shadowOffset ?? "0 0").split(" ")[0]) || 0 minValue: -50 maxValue: 50 @@ -902,7 +903,7 @@ Item { } NumberInputRow { - label: "Offset Y" + label: I18n.t("compositor.offset_y") value: parseInt((Config.compositor.shadowOffset ?? "0 0").split(" ")[1]) || 0 minValue: -50 maxValue: 50 @@ -916,7 +917,7 @@ Item { } NumberInputRow { - label: "Render Power" + label: I18n.t("settings.compositor.shadow_power") value: Config.compositor.shadowRenderPower ?? 3 minValue: 1 maxValue: 4 @@ -927,7 +928,7 @@ Item { } DecimalInputRow { - label: "Scale" + label: I18n.t("settings.compositor.shadow_scale") value: Config.compositor.shadowScale ?? 1.0 minValue: 0.0 maxValue: 1.0 @@ -938,7 +939,7 @@ Item { } DecimalInputRow { - label: "Opacity" + label: I18n.t("compositor.opacity") value: Config.compositor.shadowOpacity ?? 0.5 minValue: 0.0 maxValue: 1.0 @@ -950,7 +951,7 @@ Item { } ToggleRow { - label: "Sharp" + label: I18n.t("compositor.sharp") checked: Config.compositor.shadowSharp ?? false onToggled: value => { GlobalStates.markCompositorChanged(); @@ -959,7 +960,7 @@ Item { } ToggleRow { - label: "Ignore Window" + label: I18n.t("compositor.ignore_window") checked: Config.compositor.shadowIgnoreWindow ?? true onToggled: value => { GlobalStates.markCompositorChanged(); @@ -980,7 +981,7 @@ Item { spacing: 8 Text { - text: "Blur" + text: I18n.t("compositor.blur") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -989,7 +990,7 @@ Item { } ToggleRow { - label: "Enabled" + label: I18n.t("settings.compositor.blur_enabled") checked: Config.compositor.blurEnabled ?? true onToggled: value => { GlobalStates.markCompositorChanged(); @@ -998,7 +999,7 @@ Item { } NumberInputRow { - label: "Size" + label: I18n.t("settings.compositor.blur_size") value: Config.compositor.blurSize ?? 8 minValue: 0 maxValue: 20 @@ -1009,7 +1010,7 @@ Item { } NumberInputRow { - label: "Passes" + label: I18n.t("settings.compositor.blur_passes") value: Config.compositor.blurPasses ?? 1 minValue: 0 maxValue: 4 @@ -1020,7 +1021,7 @@ Item { } ToggleRow { - label: "Xray" + label: I18n.t("settings.compositor.blur_xray") checked: Config.compositor.blurXray ?? false onToggled: value => { GlobalStates.markCompositorChanged(); @@ -1029,7 +1030,7 @@ Item { } ToggleRow { - label: "New Optimizations" + label: I18n.t("settings.compositor.blur_new_optimizations") checked: Config.compositor.blurNewOptimizations ?? true onToggled: value => { GlobalStates.markCompositorChanged(); @@ -1038,7 +1039,7 @@ Item { } ToggleRow { - label: "Ignore Opacity" + label: I18n.t("settings.compositor.blur_ignore_opacity") checked: Config.compositor.blurIgnoreOpacity ?? true onToggled: value => { GlobalStates.markCompositorChanged(); @@ -1047,7 +1048,7 @@ Item { } ToggleRow { - label: "Explicit Ignorealpha" + label: I18n.t("settings.compositor.blur_ignorealpha") checked: Config.compositor.blurExplicitIgnoreAlpha ?? false onToggled: value => { GlobalStates.markCompositorChanged(); @@ -1056,7 +1057,7 @@ Item { } DecimalInputRow { - label: "Ignorealpha Value" + label: I18n.t("settings.compositor.blur_ignorealpha_value") value: Config.compositor.blurIgnoreAlphaValue ?? 0.2 minValue: 0.0 maxValue: 1.0 @@ -1068,7 +1069,7 @@ Item { } DecimalInputRow { - label: "Noise" + label: I18n.t("settings.compositor.blur_noise") value: Config.compositor.blurNoise ?? 0.01 minValue: 0.0 maxValue: 1.0 @@ -1079,7 +1080,7 @@ Item { } DecimalInputRow { - label: "Contrast" + label: I18n.t("settings.compositor.blur_contrast") value: Config.compositor.blurContrast ?? 0.89 minValue: 0.0 maxValue: 2.0 @@ -1090,7 +1091,7 @@ Item { } DecimalInputRow { - label: "Brightness" + label: I18n.t("settings.compositor.blur_brightness") value: Config.compositor.blurBrightness ?? 0.81 minValue: 0.0 maxValue: 2.0 @@ -1101,7 +1102,7 @@ Item { } DecimalInputRow { - label: "Vibrancy" + label: I18n.t("settings.compositor.blur_vibrancy") value: Config.compositor.blurVibrancy ?? 0.17 minValue: 0.0 maxValue: 1.0 @@ -1140,7 +1141,7 @@ Item { } Text { - text: "Coming Soon" + text: I18n.t("common.coming_soon") font.family: Config.theme.font font.pixelSize: Styling.fontSize(2) font.bold: true @@ -1149,7 +1150,7 @@ Item { } Text { - text: "Support for more compositors\nis planned for future updates." + text: I18n.t("compositor.coming_soon_text") font.family: Config.theme.font font.pixelSize: Styling.fontSize(0) color: Colors.overSurfaceVariant diff --git a/modules/widgets/dashboard/controls/EasyEffectsPanel.qml b/modules/widgets/dashboard/controls/EasyEffectsPanel.qml index 8370c8af2..b48af9026 100644 --- a/modules/widgets/dashboard/controls/EasyEffectsPanel.qml +++ b/modules/widgets/dashboard/controls/EasyEffectsPanel.qml @@ -40,8 +40,8 @@ Item { id: titlebar width: root.contentWidth anchors.horizontalCenter: parent.horizontalCenter - title: "EasyEffects" - statusText: EasyEffectsService.bypassed ? "Bypassed" : "" + title: I18n.t("effects.title") + statusText: EasyEffectsService.bypassed ? I18n.t("effects.bypassed") : "" statusColor: Colors.error showToggle: EasyEffectsService.available toggleChecked: !EasyEffectsService.bypassed @@ -49,14 +49,14 @@ Item { actions: EasyEffectsService.available ? [ { icon: Icons.popOpen, - tooltip: "Open EasyEffects", + tooltip: I18n.t("effects.open"), onClicked: function () { EasyEffectsService.openApp(); } }, { icon: Icons.sync, - tooltip: "Refresh", + tooltip: I18n.t("effects.refresh"), onClicked: function () { EasyEffectsService.refresh(); } @@ -85,7 +85,7 @@ Item { // Not available state Text { visible: !EasyEffectsService.available - text: "EasyEffects not installed" + text: I18n.t("effects.not_installed") font.family: Config.theme.font font.pixelSize: Config.theme.fontSize color: Colors.overSurfaceVariant @@ -100,7 +100,7 @@ Item { visible: EasyEffectsService.available && EasyEffectsService.outputPresets.length > 0 Text { - text: "Output Presets" + text: I18n.t("effects.output_presets") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -197,7 +197,7 @@ Item { visible: EasyEffectsService.available && EasyEffectsService.inputPresets.length > 0 Text { - text: "Input Presets" + text: I18n.t("effects.input_presets") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -290,7 +290,7 @@ Item { // Empty state Text { visible: EasyEffectsService.available && EasyEffectsService.outputPresets.length === 0 && EasyEffectsService.inputPresets.length === 0 - text: "No presets configured" + text: I18n.t("presets.no_presets") font.family: Config.theme.font font.pixelSize: Config.theme.fontSize color: Colors.overSurfaceVariant @@ -306,7 +306,7 @@ Item { visible: EasyEffectsService.available && (EasyEffectsService.activeOutputPreset || EasyEffectsService.activeInputPreset) Text { - text: "Active" + text: I18n.t("common.active") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium diff --git a/modules/widgets/dashboard/controls/GradientStopsEditor.qml b/modules/widgets/dashboard/controls/GradientStopsEditor.qml index 383ac1323..74d9c49bb 100644 --- a/modules/widgets/dashboard/controls/GradientStopsEditor.qml +++ b/modules/widgets/dashboard/controls/GradientStopsEditor.qml @@ -3,6 +3,7 @@ import QtQuick import QtQuick.Layouts import qs.modules.theme import qs.modules.components +import qs.modules.services import qs.config import "../../../../config/defaults/theme.js" as ThemeDefaults @@ -101,7 +102,7 @@ Item { spacing: 8 Text { - text: "Gradient Stops (" + root.stops.length + ")" + text: I18n.t("theme.gradient_stops") + " (" + root.stops.length + ")" font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -113,7 +114,7 @@ Item { } Text { - text: "Stop " + (root.selectedStopIndex + 1) + text: I18n.t("theme.stop_n", root.selectedStopIndex + 1) font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -167,7 +168,7 @@ Item { StyledToolTip { visible: addMouseArea.containsMouse - tooltipText: "Add Stop" + tooltipText: I18n.t("theme.add_stop") } } @@ -405,7 +406,7 @@ Item { StyledToolTip { visible: resetMouseArea.containsMouse - tooltipText: "Reset Gradient" + tooltipText: I18n.t("theme.reset_gradient") } } } @@ -424,7 +425,7 @@ Item { Layout.fillWidth: true colorNames: root.colorNames currentColor: (stopEditor.currentStop && stopEditor.currentStop[0]) ? stopEditor.currentStop[0].toString() : "surface" - label: "Color" + label: I18n.t("theme.color") dialogTitle: "Select Stop Color" onColorSelected: color => { if (root.selectedStopIndex >= 0 && root.selectedStopIndex < root.stops.length) { @@ -460,7 +461,7 @@ Item { // Position label Text { - text: "Position" + text: I18n.t("theme.position") font.family: Styling.defaultFont font.pixelSize: Styling.fontSize(-2) font.bold: true @@ -553,7 +554,7 @@ Item { StyledToolTip { visible: deleteMouseArea.containsMouse - text: "Delete stop" + text: I18n.t("theme.delete_stop") } } } diff --git a/modules/widgets/dashboard/controls/SettingsIndex.qml b/modules/widgets/dashboard/controls/SettingsIndex.qml index 6a6064093..4e6a1574d 100644 --- a/modules/widgets/dashboard/controls/SettingsIndex.qml +++ b/modules/widgets/dashboard/controls/SettingsIndex.qml @@ -2,6 +2,7 @@ import QtQuick import qs.modules.theme +import qs.modules.services QtObject { // Array of searchable items @@ -17,197 +18,198 @@ QtObject { readonly property var staticItems: [ // --- Network --- - { label: "Network", keywords: "internet wifi connection ethernet ip", section: 0, subSection: "", subLabel: "", icon: Icons.wifiHigh, isIcon: true }, - + { label: I18n.t("settings.network"), keywords: "internet wifi connection ethernet ip", section: 0, subSection: "", subLabel: "", icon: Icons.wifiHigh, isIcon: true }, + // --- Bluetooth --- - { label: "Bluetooth", keywords: "devices pairing connect", section: 1, subSection: "", subLabel: "", icon: Icons.bluetooth, isIcon: true }, - + { label: I18n.t("settings.bluetooth"), keywords: "devices pairing connect", section: 1, subSection: "", subLabel: "", icon: Icons.bluetooth, isIcon: true }, + // --- Mixer --- - { label: "Audio Mixer", keywords: "sound volume output input mic speaker", section: 2, subSection: "", subLabel: "", icon: Icons.faders, isIcon: true }, - + { label: I18n.t("settings.audio_mixer"), keywords: "sound volume output input mic speaker", section: 2, subSection: "", subLabel: "", icon: Icons.faders, isIcon: true }, + // --- Effects --- - { label: "Audio Effects", keywords: "equalizer bass treble easyeffects", section: 3, subSection: "", subLabel: "", icon: Icons.waveform, isIcon: true }, - + { label: I18n.t("settings.audio_effects"), keywords: "equalizer bass treble easyeffects", section: 3, subSection: "", subLabel: "", icon: Icons.waveform, isIcon: true }, + // --- Theme --- - { label: "Theme", keywords: "appearance look style customize", section: 4, subSection: "", subLabel: "Theme", icon: Icons.paintBrush, isIcon: true }, - + { label: I18n.t("settings.theme"), keywords: "appearance look style customize", section: 4, subSection: "", subLabel: I18n.t("settings.theme"), icon: Icons.paintBrush, isIcon: true }, + // Theme > General - { label: "Wallpapers", keywords: "background image picture desktop", section: 4, subSection: "general", subLabel: "Theme > General", icon: Icons.image, isIcon: true }, - { label: "Tint Icons", keywords: "color icons tint monochrome", section: 4, subSection: "general", subLabel: "Theme > General", icon: Icons.palette, isIcon: true }, - { label: "Enable Corners", keywords: "rounded corners radius screen", section: 4, subSection: "general", subLabel: "Theme > General", icon: Icons.cornersOut, isIcon: true }, - { label: "Animation Duration", keywords: "speed fast slow transition", section: 4, subSection: "general", subLabel: "Theme > General", icon: Icons.clock, isIcon: true }, - { label: "UI Font", keywords: "typography text family size", section: 4, subSection: "general", subLabel: "Theme > General", icon: Icons.textT, isIcon: true }, - { label: "Roundness", keywords: "radius border curve", section: 4, subSection: "general", subLabel: "Theme > General", icon: Icons.circle, isIcon: true }, - + { label: I18n.t("settings.theme.wallpapers"), keywords: "background image picture desktop", section: 4, subSection: "general", subLabel: I18n.t("settings.theme") + " > " + I18n.t("settings.theme.general"), icon: Icons.image, isIcon: true }, + { label: I18n.t("settings.theme.tint_icons"), keywords: "color icons tint monochrome", section: 4, subSection: "general", subLabel: I18n.t("settings.theme") + " > " + I18n.t("settings.theme.general"), icon: Icons.palette, isIcon: true }, + { label: I18n.t("settings.theme.enable_corners"), keywords: "rounded corners radius screen", section: 4, subSection: "general", subLabel: I18n.t("settings.theme") + " > " + I18n.t("settings.theme.general"), icon: Icons.cornersOut, isIcon: true }, + { label: I18n.t("settings.theme.animation_duration"), keywords: "speed fast slow transition", section: 4, subSection: "general", subLabel: I18n.t("settings.theme") + " > " + I18n.t("settings.theme.general"), icon: Icons.clock, isIcon: true }, + { label: I18n.t("settings.theme.ui_font"), keywords: "typography text family size", section: 4, subSection: "general", subLabel: I18n.t("settings.theme") + " > " + I18n.t("settings.theme.general"), icon: Icons.textT, isIcon: true }, + { label: I18n.t("settings.theme.roundness"), keywords: "radius border curve", section: 4, subSection: "general", subLabel: I18n.t("settings.theme") + " > " + I18n.t("settings.theme.general"), icon: Icons.circle, isIcon: true }, + // Theme > Shadow - { label: "Shadow Opacity", keywords: "darkness alpha transparency", section: 4, subSection: "shadow", subLabel: "Theme > Shadow", icon: Icons.drop, isIcon: true }, - { label: "Shadow Blur", keywords: "softness diffusion", section: 4, subSection: "shadow", subLabel: "Theme > Shadow", icon: Icons.drop, isIcon: true }, - { label: "Shadow Offset", keywords: "position x y direction", section: 4, subSection: "shadow", subLabel: "Theme > Shadow", icon: Icons.arrowsOutSimple, isIcon: true }, + { label: I18n.t("settings.theme.shadow_opacity"), keywords: "darkness alpha transparency", section: 4, subSection: "shadow", subLabel: I18n.t("settings.theme") + " > " + I18n.t("settings.theme.shadow"), icon: Icons.drop, isIcon: true }, + { label: I18n.t("settings.theme.shadow_blur"), keywords: "softness diffusion", section: 4, subSection: "shadow", subLabel: I18n.t("settings.theme") + " > " + I18n.t("settings.theme.shadow"), icon: Icons.drop, isIcon: true }, + { label: I18n.t("settings.theme.shadow_offset"), keywords: "position x y direction", section: 4, subSection: "shadow", subLabel: I18n.t("settings.theme") + " > " + I18n.t("settings.theme.shadow"), icon: Icons.arrowsOutSimple, isIcon: true }, // Theme > Colors - { label: "Color Scheme", keywords: "palette variant light dark", section: 4, subSection: "colors", subLabel: "Theme > Colors", icon: Icons.palette, isIcon: true }, - { label: "Color Variant", keywords: "background popup internal bar pane", section: 4, subSection: "colors", subLabel: "Theme > Colors", icon: Icons.palette, isIcon: true }, - { label: "Background Variant", keywords: "wallpaper desktop color", section: 4, subSection: "colors", subLabel: "Theme > Colors", icon: Icons.palette, isIcon: true }, - { label: "Popup Variant", keywords: "dialog modal color", section: 4, subSection: "colors", subLabel: "Theme > Colors", icon: Icons.palette, isIcon: true }, - { label: "Internal BG Variant", keywords: "inside background color", section: 4, subSection: "colors", subLabel: "Theme > Colors", icon: Icons.palette, isIcon: true }, - { label: "Bar BG Variant", keywords: "taskbar panel color", section: 4, subSection: "colors", subLabel: "Theme > Colors", icon: Icons.palette, isIcon: true }, - { label: "Pane Variant", keywords: "sidebar panel color", section: 4, subSection: "colors", subLabel: "Theme > Colors", icon: Icons.palette, isIcon: true }, - { label: "Gradient Mode", keywords: "linear radial halftone", section: 4, subSection: "colors", subLabel: "Theme > Colors", icon: Icons.palette, isIcon: true }, - { label: "Item Color", keywords: "overbackground surface", section: 4, subSection: "colors", subLabel: "Theme > Colors", icon: Icons.palette, isIcon: true }, - { label: "Color Opacity", keywords: "alpha transparency", section: 4, subSection: "colors", subLabel: "Theme > Colors", icon: Icons.palette, isIcon: true }, - { label: "Color Border", keywords: "stroke outline", section: 4, subSection: "colors", subLabel: "Theme > Colors", icon: Icons.palette, isIcon: true }, - { label: "Gradient Stops", keywords: "color position stops", section: 4, subSection: "colors", subLabel: "Theme > Colors", icon: Icons.palette, isIcon: true }, - { label: "Gradient Angle", keywords: "direction rotation degrees", section: 4, subSection: "colors", subLabel: "Theme > Colors", icon: Icons.palette, isIcon: true }, + { label: I18n.t("settings.theme.color_scheme"), keywords: "palette variant light dark", section: 4, subSection: "colors", subLabel: I18n.t("settings.theme") + " > " + I18n.t("settings.theme.colors"), icon: Icons.palette, isIcon: true }, + { label: I18n.t("settings.theme.color_variant"), keywords: "background popup internal bar pane", section: 4, subSection: "colors", subLabel: I18n.t("settings.theme") + " > " + I18n.t("settings.theme.colors"), icon: Icons.palette, isIcon: true }, + { label: I18n.t("settings.theme.background_variant"), keywords: "wallpaper desktop color", section: 4, subSection: "colors", subLabel: I18n.t("settings.theme") + " > " + I18n.t("settings.theme.colors"), icon: Icons.palette, isIcon: true }, + { label: I18n.t("settings.theme.popup_variant"), keywords: "dialog modal color", section: 4, subSection: "colors", subLabel: I18n.t("settings.theme") + " > " + I18n.t("settings.theme.colors"), icon: Icons.palette, isIcon: true }, + { label: I18n.t("settings.theme.internal_bg_variant"), keywords: "inside background color", section: 4, subSection: "colors", subLabel: I18n.t("settings.theme") + " > " + I18n.t("settings.theme.colors"), icon: Icons.palette, isIcon: true }, + { label: I18n.t("settings.theme.bar_bg_variant"), keywords: "taskbar panel color", section: 4, subSection: "colors", subLabel: I18n.t("settings.theme") + " > " + I18n.t("settings.theme.colors"), icon: Icons.palette, isIcon: true }, + { label: I18n.t("settings.theme.pane_variant"), keywords: "sidebar panel color", section: 4, subSection: "colors", subLabel: I18n.t("settings.theme") + " > " + I18n.t("settings.theme.colors"), icon: Icons.palette, isIcon: true }, + { label: I18n.t("theme.gradient_mode"), keywords: "linear radial halftone", section: 4, subSection: "colors", subLabel: I18n.t("settings.theme") + " > " + I18n.t("settings.theme.colors"), icon: Icons.palette, isIcon: true }, + { label: I18n.t("theme.item_color"), keywords: "overbackground surface", section: 4, subSection: "colors", subLabel: I18n.t("settings.theme") + " > " + I18n.t("settings.theme.colors"), icon: Icons.palette, isIcon: true }, + { label: I18n.t("settings.theme.color_opacity"), keywords: "alpha transparency", section: 4, subSection: "colors", subLabel: I18n.t("settings.theme") + " > " + I18n.t("settings.theme.colors"), icon: Icons.palette, isIcon: true }, + { label: I18n.t("settings.theme.color_border"), keywords: "stroke outline", section: 4, subSection: "colors", subLabel: I18n.t("settings.theme") + " > " + I18n.t("settings.theme.colors"), icon: Icons.palette, isIcon: true }, + { label: I18n.t("theme.gradient_stops"), keywords: "color position stops", section: 4, subSection: "colors", subLabel: I18n.t("settings.theme") + " > " + I18n.t("settings.theme.colors"), icon: Icons.palette, isIcon: true }, + { label: I18n.t("settings.theme.gradient_angle"), keywords: "direction rotation degrees", section: 4, subSection: "colors", subLabel: I18n.t("settings.theme") + " > " + I18n.t("settings.theme.colors"), icon: Icons.palette, isIcon: true }, // --- Binds --- - { label: "Key Bindings", keywords: "shortcuts keyboard hotkeys", section: 5, subSection: "", subLabel: "", icon: Icons.keyboard, isIcon: true }, + { label: I18n.t("settings.binds.key_bindings"), keywords: "shortcuts keyboard hotkeys", section: 5, subSection: "", subLabel: "", icon: Icons.keyboard, isIcon: true }, // Binds > Ambxst - { label: "Launcher Keybind", keywords: "app launcher menu shortcut", section: 5, subSection: "", subLabel: "Binds > Ambxst", icon: Icons.rocket, isIcon: true }, - { label: "Dashboard Keybind", keywords: "widgets dashboard shortcut", section: 5, subSection: "", subLabel: "Binds > Ambxst", icon: Icons.squaresFour, isIcon: true }, - { label: "Clipboard Keybind", keywords: "copy paste shortcut super v", section: 5, subSection: "", subLabel: "Binds > Ambxst", icon: Icons.clipboard, isIcon: true }, - { label: "Emoji Keybind", keywords: "picker shortcut super period", section: 5, subSection: "", subLabel: "Binds > Ambxst", icon: Icons.keyboard, isIcon: true }, - { label: "Tmux Keybind", keywords: "terminal shortcut", section: 5, subSection: "", subLabel: "Binds > Ambxst", icon: Icons.keyboard, isIcon: true }, - { label: "Wallpapers Keybind", keywords: "background shortcut super comma", section: 5, subSection: "", subLabel: "Binds > Ambxst", icon: Icons.keyboard, isIcon: true }, - { label: "Assistant Keybind", keywords: "ai help shortcut", section: 5, subSection: "", subLabel: "Binds > Ambxst", icon: Icons.keyboard, isIcon: true }, - { label: "Notes Keybind", keywords: "note shortcut super n", section: 5, subSection: "", subLabel: "Binds > Ambxst", icon: Icons.keyboard, isIcon: true }, - { label: "Overview Keybind", keywords: "workspace shortcut super tab", section: 5, subSection: "", subLabel: "Binds > Ambxst", icon: Icons.keyboard, isIcon: true }, - { label: "Powermenu Keybind", keywords: "logout shutdown shortcut super escape", section: 5, subSection: "", subLabel: "Binds > Ambxst", icon: Icons.power, isIcon: true }, - { label: "Settings Keybind", keywords: "config preferences shortcut", section: 5, subSection: "", subLabel: "Binds > Ambxst", icon: Icons.gear, isIcon: true }, - { label: "Lockscreen Keybind", keywords: "lock security shortcut", section: 5, subSection: "", subLabel: "Binds > Ambxst", icon: Icons.lock, isIcon: true }, - { label: "Tools Keybind", keywords: "utilities tools shortcut", section: 5, subSection: "", subLabel: "Binds > Ambxst", icon: Icons.wrench, isIcon: true }, - { label: "Screenshot Keybind", keywords: "capture screen shortcut print", section: 5, subSection: "", subLabel: "Binds > Ambxst", icon: Icons.camera, isIcon: true }, - { label: "Screenrecord Keybind", keywords: "record video shortcut", section: 5, subSection: "", subLabel: "Binds > Ambxst", icon: Icons.videoCamera, isIcon: true }, - { label: "Lens Keybind", keywords: "magnifier zoom shortcut", section: 5, subSection: "", subLabel: "Binds > Ambxst", icon: Icons.magnifyingGlass, isIcon: true }, - { label: "Reload Keybind", keywords: "refresh restart shortcut", section: 5, subSection: "", subLabel: "Binds > Ambxst", icon: Icons.arrowCounterClockwise, isIcon: true }, - { label: "Quit Keybind", keywords: "exit close shortcut", section: 5, subSection: "", subLabel: "Binds > Ambxst", icon: Icons.signOut, isIcon: true }, + { label: I18n.t("settings.binds.launcher"), keywords: "app launcher menu shortcut", section: 5, subSection: "", subLabel: I18n.t("settings.binds") + " > " + I18n.t("settings.ambxst"), icon: Icons.rocket, isIcon: true }, + { label: I18n.t("settings.binds.dashboard"), keywords: "widgets dashboard shortcut", section: 5, subSection: "", subLabel: I18n.t("settings.binds") + " > " + I18n.t("settings.ambxst"), icon: Icons.squaresFour, isIcon: true }, + { label: I18n.t("settings.binds.clipboard"), keywords: "copy paste shortcut super v", section: 5, subSection: "", subLabel: I18n.t("settings.binds") + " > " + I18n.t("settings.ambxst"), icon: Icons.clipboard, isIcon: true }, + { label: I18n.t("settings.binds.emoji"), keywords: "picker shortcut super period", section: 5, subSection: "", subLabel: I18n.t("settings.binds") + " > " + I18n.t("settings.ambxst"), icon: Icons.keyboard, isIcon: true }, + { label: I18n.t("settings.binds.tmux"), keywords: "terminal shortcut", section: 5, subSection: "", subLabel: I18n.t("settings.binds") + " > " + I18n.t("settings.ambxst"), icon: Icons.keyboard, isIcon: true }, + { label: I18n.t("settings.binds.wallpapers"), keywords: "background shortcut super comma", section: 5, subSection: "", subLabel: I18n.t("settings.binds") + " > " + I18n.t("settings.ambxst"), icon: Icons.keyboard, isIcon: true }, + { label: I18n.t("settings.binds.assistant"), keywords: "ai help shortcut", section: 5, subSection: "", subLabel: I18n.t("settings.binds") + " > " + I18n.t("settings.ambxst"), icon: Icons.keyboard, isIcon: true }, + { label: I18n.t("settings.binds.notes"), keywords: "note shortcut super n", section: 5, subSection: "", subLabel: I18n.t("settings.binds") + " > " + I18n.t("settings.ambxst"), icon: Icons.keyboard, isIcon: true }, + { label: I18n.t("settings.binds.overview"), keywords: "workspace shortcut super tab", section: 5, subSection: "", subLabel: I18n.t("settings.binds") + " > " + I18n.t("settings.ambxst"), icon: Icons.keyboard, isIcon: true }, + { label: I18n.t("settings.binds.powermenu"), keywords: "logout shutdown shortcut super escape", section: 5, subSection: "", subLabel: I18n.t("settings.binds") + " > " + I18n.t("settings.ambxst"), icon: Icons.power, isIcon: true }, + { label: I18n.t("settings.binds.settings"), keywords: "config preferences shortcut", section: 5, subSection: "", subLabel: I18n.t("settings.binds") + " > " + I18n.t("settings.ambxst"), icon: Icons.gear, isIcon: true }, + { label: I18n.t("settings.binds.lockscreen"), keywords: "lock security shortcut", section: 5, subSection: "", subLabel: I18n.t("settings.binds") + " > " + I18n.t("settings.ambxst"), icon: Icons.lock, isIcon: true }, + { label: I18n.t("settings.binds.tools"), keywords: "utilities tools shortcut", section: 5, subSection: "", subLabel: I18n.t("settings.binds") + " > " + I18n.t("settings.ambxst"), icon: Icons.wrench, isIcon: true }, + { label: I18n.t("settings.binds.screenshot"), keywords: "capture screen shortcut print", section: 5, subSection: "", subLabel: I18n.t("settings.binds") + " > " + I18n.t("settings.ambxst"), icon: Icons.camera, isIcon: true }, + { label: I18n.t("settings.binds.screenrecord"), keywords: "record video shortcut", section: 5, subSection: "", subLabel: I18n.t("settings.binds") + " > " + I18n.t("settings.ambxst"), icon: Icons.videoCamera, isIcon: true }, + { label: I18n.t("settings.binds.lens"), keywords: "magnifier zoom shortcut", section: 5, subSection: "", subLabel: I18n.t("settings.binds") + " > " + I18n.t("settings.ambxst"), icon: Icons.magnifyingGlass, isIcon: true }, + { label: I18n.t("settings.binds.reload"), keywords: "refresh restart shortcut", section: 5, subSection: "", subLabel: I18n.t("settings.binds") + " > " + I18n.t("settings.ambxst"), icon: Icons.arrowCounterClockwise, isIcon: true }, + { label: I18n.t("settings.binds.quit"), keywords: "exit close shortcut", section: 5, subSection: "", subLabel: I18n.t("settings.binds") + " > " + I18n.t("settings.ambxst"), icon: Icons.signOut, isIcon: true }, // --- System --- - { label: "System", keywords: "hardware info resources cpu ram", section: 6, subSection: "", subLabel: "System", icon: Icons.circuitry, isIcon: true }, - + { label: I18n.t("settings.system"), keywords: "hardware info resources cpu ram", section: 6, subSection: "", subLabel: I18n.t("settings.system"), icon: Icons.circuitry, isIcon: true }, + // System > Prefixes - { label: "Prefixes", keywords: "shortcuts launcher quick actions", section: 6, subSection: "prefixes", subLabel: "System > Prefixes", icon: Icons.keyboard, isIcon: true }, - { label: "Clipboard Prefix", keywords: "cc copy paste launcher", section: 6, subSection: "prefixes", subLabel: "System > Prefixes", icon: Icons.keyboard, isIcon: true }, - { label: "Emoji Prefix", keywords: "ee picker launcher", section: 6, subSection: "prefixes", subLabel: "System > Prefixes", icon: Icons.keyboard, isIcon: true }, - { label: "Tmux Prefix", keywords: "tt terminal launcher", section: 6, subSection: "prefixes", subLabel: "System > Prefixes", icon: Icons.keyboard, isIcon: true }, - { label: "Wallpapers Prefix", keywords: "ww background launcher", section: 6, subSection: "prefixes", subLabel: "System > Prefixes", icon: Icons.keyboard, isIcon: true }, - { label: "Notes Prefix", keywords: "nn note launcher", section: 6, subSection: "prefixes", subLabel: "System > Prefixes", icon: Icons.keyboard, isIcon: true }, - + { label: I18n.t("settings.system.prefixes"), keywords: "shortcuts launcher quick actions", section: 6, subSection: "prefixes", subLabel: I18n.t("settings.system") + " > " + I18n.t("settings.system.prefixes"), icon: Icons.keyboard, isIcon: true }, + { label: I18n.t("settings.system.clipboard_prefix"), keywords: "cc copy paste launcher", section: 6, subSection: "prefixes", subLabel: I18n.t("settings.system") + " > " + I18n.t("settings.system.prefixes"), icon: Icons.keyboard, isIcon: true }, + { label: I18n.t("settings.system.emoji_prefix"), keywords: "ee picker launcher", section: 6, subSection: "prefixes", subLabel: I18n.t("settings.system") + " > " + I18n.t("settings.system.prefixes"), icon: Icons.keyboard, isIcon: true }, + { label: I18n.t("settings.system.tmux_prefix"), keywords: "tt terminal launcher", section: 6, subSection: "prefixes", subLabel: I18n.t("settings.system") + " > " + I18n.t("settings.system.prefixes"), icon: Icons.keyboard, isIcon: true }, + { label: I18n.t("settings.system.wallpapers_prefix"), keywords: "ww background launcher", section: 6, subSection: "prefixes", subLabel: I18n.t("settings.system") + " > " + I18n.t("settings.system.prefixes"), icon: Icons.keyboard, isIcon: true }, + { label: I18n.t("settings.system.notes_prefix"), keywords: "nn note launcher", section: 6, subSection: "prefixes", subLabel: I18n.t("settings.system") + " > " + I18n.t("settings.system.prefixes"), icon: Icons.keyboard, isIcon: true }, + // System > Weather - { label: "Weather Location", keywords: "city country place gps", section: 6, subSection: "weather", subLabel: "System > Weather", icon: Icons.mapPin, isIcon: true }, - { label: "Temperature Unit", keywords: "celsius fahrenheit scale", section: 6, subSection: "weather", subLabel: "System > Weather", icon: Icons.thermometer, isIcon: true }, + { label: I18n.t("settings.system.weather_location"), keywords: "city country place gps", section: 6, subSection: "weather", subLabel: I18n.t("settings.system") + " > " + I18n.t("settings.system.weather"), icon: Icons.mapPin, isIcon: true }, + { label: I18n.t("settings.system.temperature_unit"), keywords: "celsius fahrenheit scale", section: 6, subSection: "weather", subLabel: I18n.t("settings.system") + " > " + I18n.t("settings.system.weather"), icon: Icons.thermometer, isIcon: true }, + { label: I18n.t("settings.system.language"), keywords: "locale translation i18n localization lang", section: 6, subSection: "language", subLabel: I18n.t("settings.system") + " > " + I18n.t("settings.system.language"), icon: Icons.globe, isIcon: true }, // System > Performance - { label: "Blur Transition", keywords: "animation speed performance effect", section: 6, subSection: "performance", subLabel: "System > Performance", icon: Icons.lightning, isIcon: true }, - { label: "Window Preview", keywords: "thumbnail overview alt-tab", section: 6, subSection: "performance", subLabel: "System > Performance", icon: Icons.windowsLogo, isIcon: true }, - { label: "Wavy Line", keywords: "animated wave effect performance", section: 6, subSection: "performance", subLabel: "System > Performance", icon: Icons.lightning, isIcon: true }, - + { label: I18n.t("settings.system.blur_transition"), keywords: "animation speed performance effect", section: 6, subSection: "performance", subLabel: I18n.t("settings.system") + " > " + I18n.t("settings.system.performance"), icon: Icons.lightning, isIcon: true }, + { label: I18n.t("settings.system.window_preview"), keywords: "thumbnail overview alt-tab", section: 6, subSection: "performance", subLabel: I18n.t("settings.system") + " > " + I18n.t("settings.system.performance"), icon: Icons.windowsLogo, isIcon: true }, + { label: I18n.t("settings.system.wavy_line"), keywords: "animated wave effect performance", section: 6, subSection: "performance", subLabel: I18n.t("settings.system") + " > " + I18n.t("settings.system.performance"), icon: Icons.lightning, isIcon: true }, + // System > Resources - { label: "System Resources", keywords: "cpu ram memory usage monitor", section: 6, subSection: "resources", subLabel: "System > Resources", icon: Icons.circuitry, isIcon: true }, - + { label: I18n.t("settings.system.system_resources"), keywords: "cpu ram memory usage monitor", section: 6, subSection: "resources", subLabel: I18n.t("settings.system") + " > " + I18n.t("settings.system.resources"), icon: Icons.circuitry, isIcon: true }, + // System > Idle - { label: "Idle Settings", keywords: "screen lock timeout sleep suspend", section: 6, subSection: "idle", subLabel: "System > Idle", icon: Icons.moon, isIcon: true }, - { label: "Lock Command", keywords: "ambxst lock screen idle", section: 6, subSection: "idle", subLabel: "System > Idle", icon: Icons.moon, isIcon: true }, - { label: "Before Sleep", keywords: "loginctl lock-session idle", section: 6, subSection: "idle", subLabel: "System > Idle", icon: Icons.moon, isIcon: true }, - { label: "After Sleep", keywords: "screen on resume idle", section: 6, subSection: "idle", subLabel: "System > Idle", icon: Icons.moon, isIcon: true }, - { label: "Idle Listener", keywords: "timeout brightness screen off suspend", section: 6, subSection: "idle", subLabel: "System > Idle", icon: Icons.moon, isIcon: true }, + { label: I18n.t("settings.system.idle_settings"), keywords: "screen lock timeout sleep suspend", section: 6, subSection: "idle", subLabel: I18n.t("settings.system") + " > " + I18n.t("settings.system.idle"), icon: Icons.moon, isIcon: true }, + { label: I18n.t("settings.system.lock_command"), keywords: "ambxst lock screen idle", section: 6, subSection: "idle", subLabel: I18n.t("settings.system") + " > " + I18n.t("settings.system.idle"), icon: Icons.moon, isIcon: true }, + { label: I18n.t("settings.system.before_sleep"), keywords: "loginctl lock-session idle", section: 6, subSection: "idle", subLabel: I18n.t("settings.system") + " > " + I18n.t("settings.system.idle"), icon: Icons.moon, isIcon: true }, + { label: I18n.t("settings.system.after_sleep"), keywords: "screen on resume idle", section: 6, subSection: "idle", subLabel: I18n.t("settings.system") + " > " + I18n.t("settings.system.idle"), icon: Icons.moon, isIcon: true }, + { label: I18n.t("settings.system.idle_listener"), keywords: "timeout brightness screen off suspend", section: 6, subSection: "idle", subLabel: I18n.t("settings.system") + " > " + I18n.t("settings.system.idle"), icon: Icons.moon, isIcon: true }, // --- Compositor --- - { label: "Compositor", keywords: "compositor window manager wm", section: 7, subSection: "", subLabel: "Compositor", icon: Icons.compositor, isIcon: true }, - + { label: I18n.t("settings.compositor"), keywords: "compositor window manager wm", section: 7, subSection: "", subLabel: I18n.t("settings.compositor"), icon: Icons.compositor, isIcon: true }, + // Compositor > AxctlService > General - { label: "Border Size", keywords: "width thickness stroke", section: 7, subSection: "general", subLabel: "Compositor > AxctlService", icon: Icons.frameCorners, isIcon: true }, - { label: "Window Gaps", keywords: "spacing margin padding", section: 7, subSection: "general", subLabel: "Compositor > AxctlService", icon: Icons.squaresFour, isIcon: true }, - + { label: I18n.t("settings.compositor.border_size"), keywords: "width thickness stroke", section: 7, subSection: "general", subLabel: I18n.t("settings.compositor") + " > " + I18n.t("settings.compositor.axctl"), icon: Icons.frameCorners, isIcon: true }, + { label: I18n.t("settings.compositor.window_gaps"), keywords: "spacing margin padding", section: 7, subSection: "general", subLabel: I18n.t("settings.compositor") + " > " + I18n.t("settings.compositor.axctl"), icon: Icons.squaresFour, isIcon: true }, + // Compositor > AxctlService > Colors - { label: "Border Colors", keywords: "active inactive focus", section: 7, subSection: "colors", subLabel: "Compositor > AxctlService", icon: Icons.palette, isIcon: true }, + { label: I18n.t("settings.compositor.border_colors"), keywords: "active inactive focus", section: 7, subSection: "colors", subLabel: I18n.t("settings.compositor") + " > " + I18n.t("settings.compositor.axctl"), icon: Icons.palette, isIcon: true }, // Compositor > AxctlService > Shadows - { label: "Shadows Enabled", keywords: "toggle on off", section: 7, subSection: "shadows", subLabel: "Compositor > AxctlService", icon: Icons.drop, isIcon: true }, - { label: "Sync Shadow Color", keywords: "match border", section: 7, subSection: "shadows", subLabel: "Compositor > AxctlService", icon: Icons.palette, isIcon: true }, - { label: "Sync Shadow Opacity", keywords: "match border alpha", section: 7, subSection: "shadows", subLabel: "Compositor > AxctlService", icon: Icons.drop, isIcon: true }, - { label: "Shadow Range", keywords: "blur radius size", section: 7, subSection: "shadows", subLabel: "Compositor > AxctlService", icon: Icons.circle, isIcon: true }, - { label: "Shadow Offset", keywords: "position x y move", section: 7, subSection: "shadows", subLabel: "Compositor > AxctlService", icon: Icons.arrowsOutSimple, isIcon: true }, - { label: "Shadow Power", keywords: "strength render intensity", section: 7, subSection: "shadows", subLabel: "Compositor > AxctlService", icon: Icons.lightning, isIcon: true }, - { label: "Shadow Scale", keywords: "zoom resize", section: 7, subSection: "shadows", subLabel: "Compositor > AxctlService", icon: Icons.cornersOut, isIcon: true }, + { label: I18n.t("settings.compositor.shadows_enabled"), keywords: "toggle on off", section: 7, subSection: "shadows", subLabel: I18n.t("settings.compositor") + " > " + I18n.t("settings.compositor.axctl"), icon: Icons.drop, isIcon: true }, + { label: I18n.t("settings.compositor.sync_shadow_color"), keywords: "match border", section: 7, subSection: "shadows", subLabel: I18n.t("settings.compositor") + " > " + I18n.t("settings.compositor.axctl"), icon: Icons.palette, isIcon: true }, + { label: I18n.t("settings.compositor.sync_shadow_opacity"), keywords: "match border alpha", section: 7, subSection: "shadows", subLabel: I18n.t("settings.compositor") + " > " + I18n.t("settings.compositor.axctl"), icon: Icons.drop, isIcon: true }, + { label: I18n.t("settings.compositor.shadow_range"), keywords: "blur radius size", section: 7, subSection: "shadows", subLabel: I18n.t("settings.compositor") + " > " + I18n.t("settings.compositor.axctl"), icon: Icons.circle, isIcon: true }, + { label: I18n.t("settings.compositor.shadow_offset"), keywords: "position x y move", section: 7, subSection: "shadows", subLabel: I18n.t("settings.compositor") + " > " + I18n.t("settings.compositor.axctl"), icon: Icons.arrowsOutSimple, isIcon: true }, + { label: I18n.t("settings.compositor.shadow_power"), keywords: "strength render intensity", section: 7, subSection: "shadows", subLabel: I18n.t("settings.compositor") + " > " + I18n.t("settings.compositor.axctl"), icon: Icons.lightning, isIcon: true }, + { label: I18n.t("settings.compositor.shadow_scale"), keywords: "zoom resize", section: 7, subSection: "shadows", subLabel: I18n.t("settings.compositor") + " > " + I18n.t("settings.compositor.axctl"), icon: Icons.cornersOut, isIcon: true }, // Compositor > AxctlService > Blur - { label: "Blur Enabled", keywords: "toggle on off transparency", section: 7, subSection: "blur", subLabel: "Compositor > AxctlService", icon: Icons.drop, isIcon: true }, - { label: "Blur Size", keywords: "radius amount", section: 7, subSection: "blur", subLabel: "Compositor > AxctlService", icon: Icons.circle, isIcon: true }, - { label: "Blur Passes", keywords: "quality iterations", section: 7, subSection: "blur", subLabel: "Compositor > AxctlService", icon: Icons.circle, isIcon: true }, - { label: "Blur Xray", keywords: "transparency see through", section: 7, subSection: "blur", subLabel: "Compositor > AxctlService", icon: Icons.drop, isIcon: true }, - { label: "Blur New Optimizations", keywords: "performance speed", section: 7, subSection: "blur", subLabel: "Compositor > AxctlService", icon: Icons.lightning, isIcon: true }, - { label: "Blur Ignore Opacity", keywords: "transparency alpha", section: 7, subSection: "blur", subLabel: "Compositor > AxctlService", icon: Icons.drop, isIcon: true }, - { label: "Blur Ignorealpha", keywords: "explicit transparency", section: 7, subSection: "blur", subLabel: "Compositor > AxctlService", icon: Icons.drop, isIcon: true }, - { label: "Blur Ignorealpha Value", keywords: "threshold amount", section: 7, subSection: "blur", subLabel: "Compositor > AxctlService", icon: Icons.drop, isIcon: true }, - { label: "Blur Noise", keywords: "grain texture static", section: 7, subSection: "blur", subLabel: "Compositor > AxctlService", icon: Icons.drop, isIcon: true }, - { label: "Blur Contrast", keywords: "intensity difference", section: 7, subSection: "blur", subLabel: "Compositor > AxctlService", icon: Icons.drop, isIcon: true }, - { label: "Blur Brightness", keywords: "light dark level", section: 7, subSection: "blur", subLabel: "Compositor > AxctlService", icon: Icons.drop, isIcon: true }, - { label: "Blur Vibrancy", keywords: "saturation color", section: 7, subSection: "blur", subLabel: "Compositor > AxctlService", icon: Icons.drop, isIcon: true }, + { label: I18n.t("settings.compositor.blur_enabled"), keywords: "toggle on off transparency", section: 7, subSection: "blur", subLabel: I18n.t("settings.compositor") + " > " + I18n.t("settings.compositor.axctl"), icon: Icons.drop, isIcon: true }, + { label: I18n.t("settings.compositor.blur_size"), keywords: "radius amount", section: 7, subSection: "blur", subLabel: I18n.t("settings.compositor") + " > " + I18n.t("settings.compositor.axctl"), icon: Icons.circle, isIcon: true }, + { label: I18n.t("settings.compositor.blur_passes"), keywords: "quality iterations", section: 7, subSection: "blur", subLabel: I18n.t("settings.compositor") + " > " + I18n.t("settings.compositor.axctl"), icon: Icons.circle, isIcon: true }, + { label: I18n.t("settings.compositor.blur_xray"), keywords: "transparency see through", section: 7, subSection: "blur", subLabel: I18n.t("settings.compositor") + " > " + I18n.t("settings.compositor.axctl"), icon: Icons.drop, isIcon: true }, + { label: I18n.t("settings.compositor.blur_new_optimizations"), keywords: "performance speed", section: 7, subSection: "blur", subLabel: I18n.t("settings.compositor") + " > " + I18n.t("settings.compositor.axctl"), icon: Icons.lightning, isIcon: true }, + { label: I18n.t("settings.compositor.blur_ignore_opacity"), keywords: "transparency alpha", section: 7, subSection: "blur", subLabel: I18n.t("settings.compositor") + " > " + I18n.t("settings.compositor.axctl"), icon: Icons.drop, isIcon: true }, + { label: I18n.t("settings.compositor.blur_ignorealpha"), keywords: "explicit transparency", section: 7, subSection: "blur", subLabel: I18n.t("settings.compositor") + " > " + I18n.t("settings.compositor.axctl"), icon: Icons.drop, isIcon: true }, + { label: I18n.t("settings.compositor.blur_ignorealpha_value"), keywords: "threshold amount", section: 7, subSection: "blur", subLabel: I18n.t("settings.compositor") + " > " + I18n.t("settings.compositor.axctl"), icon: Icons.drop, isIcon: true }, + { label: I18n.t("settings.compositor.blur_noise"), keywords: "grain texture static", section: 7, subSection: "blur", subLabel: I18n.t("settings.compositor") + " > " + I18n.t("settings.compositor.axctl"), icon: Icons.drop, isIcon: true }, + { label: I18n.t("settings.compositor.blur_contrast"), keywords: "intensity difference", section: 7, subSection: "blur", subLabel: I18n.t("settings.compositor") + " > " + I18n.t("settings.compositor.axctl"), icon: Icons.drop, isIcon: true }, + { label: I18n.t("settings.compositor.blur_brightness"), keywords: "light dark level", section: 7, subSection: "blur", subLabel: I18n.t("settings.compositor") + " > " + I18n.t("settings.compositor.axctl"), icon: Icons.drop, isIcon: true }, + { label: I18n.t("settings.compositor.blur_vibrancy"), keywords: "saturation color", section: 7, subSection: "blur", subLabel: I18n.t("settings.compositor") + " > " + I18n.t("settings.compositor.axctl"), icon: Icons.drop, isIcon: true }, // --- Ambxst / Shell --- - { label: "Ambxst", keywords: "about info credits version shell", section: 8, subSection: "", subLabel: "", icon: Qt.resolvedUrl("../../../../assets/ambxst/ambxst-icon.svg"), isIcon: false }, - + { label: I18n.t("settings.ambxst"), keywords: "about info credits version shell", section: 8, subSection: "", subLabel: "", icon: Qt.resolvedUrl("../../../../assets/ambxst/ambxst-icon.svg"), isIcon: false }, + // Ambxst > Bar - { label: "Bar", keywords: "panel taskbar top bottom", section: 8, subSection: "bar", subLabel: "Ambxst > Bar", icon: Icons.layout, isIcon: true }, - { label: "Bar Position", keywords: "top bottom left right edge", section: 8, subSection: "bar", subLabel: "Ambxst > Bar", icon: Icons.layout, isIcon: true }, - { label: "Launcher Icon", keywords: "logo symbol path", section: 8, subSection: "bar", subLabel: "Ambxst > Bar", icon: Icons.layout, isIcon: true }, - { label: "Launcher Icon Tint", keywords: "color theme", section: 8, subSection: "bar", subLabel: "Ambxst > Bar", icon: Icons.palette, isIcon: true }, - { label: "Launcher Icon Full Tint", keywords: "monochrome color", section: 8, subSection: "bar", subLabel: "Ambxst > Bar", icon: Icons.palette, isIcon: true }, - { label: "Launcher Icon Size", keywords: "width height pixels", section: 8, subSection: "bar", subLabel: "Ambxst > Bar", icon: Icons.layout, isIcon: true }, - { label: "Pill Style", keywords: "squished roundness radius bar", section: 8, subSection: "bar", subLabel: "Ambxst > Bar", icon: Icons.layout, isIcon: true }, - { label: "Firefox Player", keywords: "browser media music", section: 8, subSection: "bar", subLabel: "Ambxst > Bar", icon: Icons.layout, isIcon: true }, - { label: "Bar Auto-hide", keywords: "autohide hide show reveal", section: 8, subSection: "bar", subLabel: "Ambxst > Bar", icon: Icons.layout, isIcon: true }, - { label: "Pinned on Startup", keywords: "show visible default", section: 8, subSection: "bar", subLabel: "Ambxst > Bar", icon: Icons.layout, isIcon: true }, - { label: "Hover to Reveal", keywords: "mouse show hide edge", section: 8, subSection: "bar", subLabel: "Ambxst > Bar", icon: Icons.layout, isIcon: true }, - { label: "Hover Region Height", keywords: "pixels trigger area", section: 8, subSection: "bar", subLabel: "Ambxst > Bar", icon: Icons.layout, isIcon: true }, - { label: "Show Pin Button", keywords: "toggle pin unpin", section: 8, subSection: "bar", subLabel: "Ambxst > Bar", icon: Icons.layout, isIcon: true }, - { label: "Available on Fullscreen", keywords: "overlay game video", section: 8, subSection: "bar", subLabel: "Ambxst > Bar", icon: Icons.layout, isIcon: true }, - { label: "Show Running Indicators", keywords: "dots active apps", section: 8, subSection: "bar", subLabel: "Ambxst > Bar", icon: Icons.layout, isIcon: true }, - { label: "Show Overview Button", keywords: "workspace switcher", section: 8, subSection: "bar", subLabel: "Ambxst > Bar", icon: Icons.layout, isIcon: true }, - { label: "Bar Screens", keywords: "monitor display eDP", section: 8, subSection: "bar", subLabel: "Ambxst > Bar", icon: Icons.layout, isIcon: true }, - + { label: I18n.t("settings.shell.bar_entry"), keywords: "panel taskbar top bottom", section: 8, subSection: "bar", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.bar"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.bar_position"), keywords: "top bottom left right edge", section: 8, subSection: "bar", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.bar"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.launcher_icon"), keywords: "logo symbol path", section: 8, subSection: "bar", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.bar"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.launcher_icon_tint"), keywords: "color theme", section: 8, subSection: "bar", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.bar"), icon: Icons.palette, isIcon: true }, + { label: I18n.t("settings.shell.launcher_icon_full_tint"), keywords: "monochrome color", section: 8, subSection: "bar", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.bar"), icon: Icons.palette, isIcon: true }, + { label: I18n.t("settings.shell.launcher_icon_size"), keywords: "width height pixels", section: 8, subSection: "bar", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.bar"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.pill_style"), keywords: "squished roundness radius bar", section: 8, subSection: "bar", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.bar"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.firefox_player"), keywords: "browser media music", section: 8, subSection: "bar", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.bar"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.bar_autohide"), keywords: "autohide hide show reveal", section: 8, subSection: "bar", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.bar"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.pinned_on_startup"), keywords: "show visible default", section: 8, subSection: "bar", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.bar"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.hover_to_reveal"), keywords: "mouse show hide edge", section: 8, subSection: "bar", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.bar"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.hover_region_height"), keywords: "pixels trigger area", section: 8, subSection: "bar", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.bar"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.show_pin_button"), keywords: "toggle pin unpin", section: 8, subSection: "bar", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.bar"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.available_on_fullscreen"), keywords: "overlay game video", section: 8, subSection: "bar", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.bar"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.show_running_indicators"), keywords: "dots active apps", section: 8, subSection: "bar", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.bar"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.show_overview_button"), keywords: "workspace switcher", section: 8, subSection: "bar", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.bar"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.bar_screens"), keywords: "monitor display eDP", section: 8, subSection: "bar", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.bar"), icon: Icons.layout, isIcon: true }, + // Ambxst > Notch - { label: "Notch", keywords: "island dynamic island center", section: 8, subSection: "notch", subLabel: "Ambxst > Notch", icon: Icons.layout, isIcon: true }, - + { label: I18n.t("settings.shell.notch_entry"), keywords: "island dynamic island center", section: 8, subSection: "notch", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.notch"), icon: Icons.layout, isIcon: true }, + // Ambxst > Workspaces - { label: "Workspaces", keywords: "virtual desktop spaces", section: 8, subSection: "workspaces", subLabel: "Ambxst > Workspaces", icon: Icons.squaresFour, isIcon: true }, - { label: "Workspaces Shown", keywords: "number count visible", section: 8, subSection: "workspaces", subLabel: "Ambxst > Workspaces", icon: Icons.squaresFour, isIcon: true }, - { label: "Show App Icons", keywords: "application thumbnail workspace", section: 8, subSection: "workspaces", subLabel: "Ambxst > Workspaces", icon: Icons.squaresFour, isIcon: true }, - { label: "Always Show Numbers", keywords: "workspace label index", section: 8, subSection: "workspaces", subLabel: "Ambxst > Workspaces", icon: Icons.squaresFour, isIcon: true }, - { label: "Show Numbers", keywords: "workspace label index", section: 8, subSection: "workspaces", subLabel: "Ambxst > Workspaces", icon: Icons.squaresFour, isIcon: true }, - { label: "Dynamic Workspaces", keywords: "auto add remove flexible", section: 8, subSection: "workspaces", subLabel: "Ambxst > Workspaces", icon: Icons.squaresFour, isIcon: true }, - + { label: I18n.t("settings.shell.workspaces_entry"), keywords: "virtual desktop spaces", section: 8, subSection: "workspaces", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.workspaces"), icon: Icons.squaresFour, isIcon: true }, + { label: I18n.t("settings.shell.workspaces_shown"), keywords: "number count visible", section: 8, subSection: "workspaces", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.workspaces"), icon: Icons.squaresFour, isIcon: true }, + { label: I18n.t("settings.shell.show_app_icons"), keywords: "application thumbnail workspace", section: 8, subSection: "workspaces", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.workspaces"), icon: Icons.squaresFour, isIcon: true }, + { label: I18n.t("settings.shell.always_show_numbers"), keywords: "workspace label index", section: 8, subSection: "workspaces", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.workspaces"), icon: Icons.squaresFour, isIcon: true }, + { label: I18n.t("settings.shell.show_numbers"), keywords: "workspace label index", section: 8, subSection: "workspaces", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.workspaces"), icon: Icons.squaresFour, isIcon: true }, + { label: I18n.t("settings.shell.dynamic_workspaces"), keywords: "auto add remove flexible", section: 8, subSection: "workspaces", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.workspaces"), icon: Icons.squaresFour, isIcon: true }, + // Ambxst > Overview - { label: "Overview", keywords: "expose mission control windows", section: 8, subSection: "overview", subLabel: "Ambxst > Overview", icon: Icons.squaresFour, isIcon: true }, - { label: "Overview Rows", keywords: "grid layout vertical", section: 8, subSection: "overview", subLabel: "Ambxst > Overview", icon: Icons.squaresFour, isIcon: true }, - { label: "Overview Columns", keywords: "grid layout horizontal", section: 8, subSection: "overview", subLabel: "Ambxst > Overview", icon: Icons.squaresFour, isIcon: true }, - { label: "Overview Scale", keywords: "zoom size preview", section: 8, subSection: "overview", subLabel: "Ambxst > Overview", icon: Icons.squaresFour, isIcon: true }, - { label: "Overview Workspace Spacing", keywords: "gap margin distance", section: 8, subSection: "overview", subLabel: "Ambxst > Overview", icon: Icons.squaresFour, isIcon: true }, - + { label: I18n.t("settings.shell.overview_entry"), keywords: "expose mission control windows", section: 8, subSection: "overview", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.overview"), icon: Icons.squaresFour, isIcon: true }, + { label: I18n.t("settings.shell.overview_rows"), keywords: "grid layout vertical", section: 8, subSection: "overview", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.overview"), icon: Icons.squaresFour, isIcon: true }, + { label: I18n.t("settings.shell.overview_columns"), keywords: "grid layout horizontal", section: 8, subSection: "overview", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.overview"), icon: Icons.squaresFour, isIcon: true }, + { label: I18n.t("settings.shell.overview_scale"), keywords: "zoom size preview", section: 8, subSection: "overview", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.overview"), icon: Icons.squaresFour, isIcon: true }, + { label: I18n.t("settings.shell.overview_workspace_spacing"), keywords: "gap margin distance", section: 8, subSection: "overview", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.overview"), icon: Icons.squaresFour, isIcon: true }, + // Ambxst > Dock - { label: "Dock", keywords: "taskbar launcher apps favorites", section: 8, subSection: "dock", subLabel: "Ambxst > Dock", icon: Icons.layout, isIcon: true }, - { label: "Dock Enabled", keywords: "show hide toggle", section: 8, subSection: "dock", subLabel: "Ambxst > Dock", icon: Icons.layout, isIcon: true }, - { label: "Dock Mode", keywords: "default floating integrated style", section: 8, subSection: "dock", subLabel: "Ambxst > Dock", icon: Icons.layout, isIcon: true }, - { label: "Dock Position", keywords: "left bottom right edge", section: 8, subSection: "dock", subLabel: "Ambxst > Dock", icon: Icons.layout, isIcon: true }, - { label: "Dock Height", keywords: "size thickness pixels", section: 8, subSection: "dock", subLabel: "Ambxst > Dock", icon: Icons.layout, isIcon: true }, - { label: "Dock Icon Size", keywords: "width height pixels apps", section: 8, subSection: "dock", subLabel: "Ambxst > Dock", icon: Icons.layout, isIcon: true }, - { label: "Dock Spacing", keywords: "gap between icons", section: 8, subSection: "dock", subLabel: "Ambxst > Dock", icon: Icons.layout, isIcon: true }, - { label: "Dock Margin", keywords: "edge distance offset", section: 8, subSection: "dock", subLabel: "Ambxst > Dock", icon: Icons.layout, isIcon: true }, - { label: "Dock Hover Region Height", keywords: "trigger area pixels", section: 8, subSection: "dock", subLabel: "Ambxst > Dock", icon: Icons.layout, isIcon: true }, - { label: "Dock Pinned on Startup", keywords: "show visible default", section: 8, subSection: "dock", subLabel: "Ambxst > Dock", icon: Icons.layout, isIcon: true }, - + { label: I18n.t("settings.shell.dock_entry"), keywords: "taskbar launcher apps favorites", section: 8, subSection: "dock", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.dock"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.dock_enabled"), keywords: "show hide toggle", section: 8, subSection: "dock", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.dock"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.dock_mode"), keywords: "default floating integrated style", section: 8, subSection: "dock", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.dock"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.dock_position"), keywords: "left bottom right edge", section: 8, subSection: "dock", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.dock"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.dock_height"), keywords: "size thickness pixels", section: 8, subSection: "dock", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.dock"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.dock_icon_size"), keywords: "width height pixels apps", section: 8, subSection: "dock", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.dock"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.dock_spacing"), keywords: "gap between icons", section: 8, subSection: "dock", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.dock"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.dock_margin"), keywords: "edge distance offset", section: 8, subSection: "dock", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.dock"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.dock_hover_region_height"), keywords: "trigger area pixels", section: 8, subSection: "dock", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.dock"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.dock_pinned_on_startup"), keywords: "show visible default", section: 8, subSection: "dock", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.dock"), icon: Icons.layout, isIcon: true }, + // Ambxst > Lockscreen - { label: "Lockscreen", keywords: "lock screen password login", section: 8, subSection: "lockscreen", subLabel: "Ambxst > Lockscreen", icon: Icons.lock, isIcon: true }, - + { label: I18n.t("settings.shell.lockscreen_entry"), keywords: "lock screen password login", section: 8, subSection: "lockscreen", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.lockscreen"), icon: Icons.lock, isIcon: true }, + // Ambxst > Desktop - { label: "Desktop", keywords: "icons wallpaper home", section: 8, subSection: "desktop", subLabel: "Ambxst > Desktop", icon: Icons.layout, isIcon: true }, - { label: "Desktop Enabled", keywords: "show hide icons toggle", section: 8, subSection: "desktop", subLabel: "Ambxst > Desktop", icon: Icons.layout, isIcon: true }, - { label: "Desktop Icon Size", keywords: "width height pixels", section: 8, subSection: "desktop", subLabel: "Ambxst > Desktop", icon: Icons.layout, isIcon: true }, - { label: "Desktop Vertical Spacing", keywords: "gap margin", section: 8, subSection: "desktop", subLabel: "Ambxst > Desktop", icon: Icons.layout, isIcon: true }, - { label: "Desktop Text Color", keywords: "label font", section: 8, subSection: "desktop", subLabel: "Ambxst > Desktop", icon: Icons.palette, isIcon: true }, - + { label: I18n.t("settings.shell.desktop_entry"), keywords: "icons wallpaper home", section: 8, subSection: "desktop", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.desktop"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.desktop_enabled"), keywords: "show hide icons toggle", section: 8, subSection: "desktop", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.desktop"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.desktop_icon_size"), keywords: "width height pixels", section: 8, subSection: "desktop", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.desktop"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.desktop_vertical_spacing"), keywords: "gap margin", section: 8, subSection: "desktop", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.desktop"), icon: Icons.layout, isIcon: true }, + { label: I18n.t("settings.shell.desktop_text_color"), keywords: "label font", section: 8, subSection: "desktop", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.desktop"), icon: Icons.palette, isIcon: true }, + // Ambxst > System - { label: "Shell System", keywords: "config settings ambxst", section: 8, subSection: "system", subLabel: "Ambxst > System", icon: Icons.circuitry, isIcon: true } + { label: I18n.t("settings.shell.system_entry"), keywords: "config settings ambxst", section: 8, subSection: "system", subLabel: I18n.t("settings.ambxst") + " > " + I18n.t("settings.shell.system"), icon: Icons.circuitry, isIcon: true } ] property var items: staticItems.concat(dynamicItems) diff --git a/modules/widgets/dashboard/controls/SettingsTab.qml b/modules/widgets/dashboard/controls/SettingsTab.qml index fcaeef560..9dad9d249 100644 --- a/modules/widgets/dashboard/controls/SettingsTab.qml +++ b/modules/widgets/dashboard/controls/SettingsTab.qml @@ -202,61 +202,61 @@ Rectangle { readonly property var sectionModel: [ { icon: Icons.wifiHigh, - label: "Network", + label: I18n.t("settings.network"), section: 0, isIcon: true }, { icon: Icons.bluetooth, - label: "Bluetooth", + label: I18n.t("settings.bluetooth"), section: 1, isIcon: true }, { icon: Icons.faders, - label: "Mixer", + label: I18n.t("settings.mixer"), section: 2, isIcon: true }, { icon: Icons.robot, - label: "AI", + label: I18n.t("settings.ai"), section: 3, isIcon: true }, { icon: Icons.waveform, - label: "Effects", + label: I18n.t("settings.effects"), section: 4, isIcon: true }, { icon: Icons.paintBrush, - label: "Theme", + label: I18n.t("settings.theme"), section: 5, isIcon: true }, { icon: Icons.keyboard, - label: "Binds", + label: I18n.t("settings.binds"), section: 6, isIcon: true }, { icon: Icons.circuitry, - label: "System", + label: I18n.t("settings.system"), section: 7, isIcon: true }, { icon: Icons.compositor, - label: "Compositor", + label: I18n.t("settings.compositor"), section: 8, isIcon: true }, { icon: Qt.resolvedUrl("../../../../assets/ambxst/ambxst-icon.svg"), - label: "Ambxst", + label: I18n.t("settings.ambxst"), section: 9, isIcon: false } @@ -310,7 +310,7 @@ Rectangle { SearchInput { id: searchInput Layout.fillWidth: true - placeholderText: "Search..." + placeholderText: I18n.t("common.search") clearOnEscape: true onSearchTextChanged: text => { diff --git a/modules/widgets/dashboard/controls/ShellPanel.qml b/modules/widgets/dashboard/controls/ShellPanel.qml index d02bf8cfe..b9586b662 100644 --- a/modules/widgets/dashboard/controls/ShellPanel.qml +++ b/modules/widgets/dashboard/controls/ShellPanel.qml @@ -7,6 +7,7 @@ import Quickshell import qs.modules.theme import qs.modules.components import qs.modules.globals +import qs.modules.services import qs.config Item { @@ -442,7 +443,7 @@ Item { // Inline component for screen list selection component ScreenListRow: ColumnLayout { id: screenListRowRoot - property string label: "Screens" + property string label: I18n.t("shell.screens") property var selectedScreens: [] // Array of screen names signal screensChanged(var newList) @@ -458,7 +459,7 @@ Item { } Text { - text: "Empty = all screens" + text: I18n.t("shell.screens_empty") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-2) color: Colors.outline @@ -568,15 +569,15 @@ Item { id: titlebar width: root.contentWidth anchors.horizontalCenter: parent.horizontalCenter - title: root.currentSection === "" ? "Shell" : (root.currentSection.charAt(0).toUpperCase() + root.currentSection.slice(1)) - statusText: GlobalStates.shellHasChanges ? "Unsaved changes" : "" + title: root.currentSection === "" ? I18n.t("shell.shell") : I18n.t("settings.shell." + root.currentSection) + statusText: GlobalStates.shellHasChanges ? I18n.t("common.unsaved_changes") : "" statusColor: Colors.error actions: { let baseActions = [ { icon: Icons.arrowCounterClockwise, - tooltip: "Discard changes", + tooltip: I18n.t("common.discard_changes"), enabled: GlobalStates.shellHasChanges, onClicked: function () { GlobalStates.discardShellChanges(); @@ -584,7 +585,7 @@ Item { }, { icon: Icons.disk, - tooltip: "Apply changes", + tooltip: I18n.t("common.apply_changes"), enabled: GlobalStates.shellHasChanges, onClicked: function () { GlobalStates.applyShellChanges(); @@ -596,7 +597,7 @@ Item { return [ { icon: Icons.arrowLeft, - tooltip: "Back", + tooltip: I18n.t("common.back"), onClicked: function () { root.currentSection = ""; } @@ -629,43 +630,43 @@ Item { spacing: 8 SectionButton { - text: "Bar" + text: I18n.t("settings.shell.bar") sectionId: "bar" } SectionButton { - text: "Sidebar" + text: I18n.t("settings.shell.sidebar") sectionId: "sidebar" } SectionButton { - text: "Frame" + text: I18n.t("settings.shell.frame") sectionId: "frame" } SectionButton { - text: "Notch" + text: I18n.t("settings.shell.notch") sectionId: "notch" } SectionButton { - text: "Workspaces" + text: I18n.t("settings.shell.workspaces") sectionId: "workspaces" } SectionButton { - text: "Overview" + text: I18n.t("settings.shell.overview") sectionId: "overview" } SectionButton { - text: "Dock" + text: I18n.t("settings.shell.dock") sectionId: "dock" } SectionButton { - text: "Lockscreen" + text: I18n.t("settings.shell.lockscreen") sectionId: "lockscreen" } SectionButton { - text: "Desktop" + text: I18n.t("settings.shell.desktop") sectionId: "desktop" } SectionButton { - text: "System" + text: I18n.t("settings.shell.system") sectionId: "system" } } @@ -679,7 +680,7 @@ Item { spacing: 8 Text { - text: "Bar" + text: I18n.t("settings.shell.bar") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -691,22 +692,22 @@ Item { label: "" options: [ { - label: "Top", + label: I18n.t("common.top"), value: "top", icon: Icons.arrowUp }, { - label: "Bottom", + label: I18n.t("common.bottom"), value: "bottom", icon: Icons.arrowDown }, { - label: "Left", + label: I18n.t("common.left"), value: "left", icon: Icons.arrowLeft }, { - label: "Right", + label: I18n.t("common.right"), value: "right", icon: Icons.arrowRight } @@ -721,9 +722,9 @@ Item { } TextInputRow { - label: "Launcher Icon" + label: I18n.t("shell.launcher_icon") value: Config.bar.launcherIcon ?? "" - placeholder: "Symbol or path to icon..." + placeholder: I18n.t("theme.symbol_or_icon") onValueEdited: newValue => { if (newValue !== Config.bar.launcherIcon) { GlobalStates.markShellChanged(); @@ -733,7 +734,7 @@ Item { } ToggleRow { - label: "Launcher Icon Tint" + label: I18n.t("shell.launcher_icon_tint") checked: Config.bar.launcherIconTint ?? true onToggled: value => { if (value !== Config.bar.launcherIconTint) { @@ -744,7 +745,7 @@ Item { } ToggleRow { - label: "Launcher Icon Full Tint" + label: I18n.t("shell.launcher_icon_full_tint") checked: Config.bar.launcherIconFullTint ?? true onToggled: value => { if (value !== Config.bar.launcherIconFullTint) { @@ -755,7 +756,7 @@ Item { } NumberInputRow { - label: "Launcher Icon Size" + label: I18n.t("shell.launcher_icon_size") value: Config.bar.launcherIconSize ?? 24 minValue: 12 maxValue: 64 @@ -769,14 +770,14 @@ Item { } SelectorRow { - label: "Pill Style" + label: I18n.t("shell.pill_style") options: [ { - label: "Default", + label: I18n.t("common.default"), value: "default" }, { - label: "Squished", + label: I18n.t("shell.squished"), value: "squished" } ] @@ -790,7 +791,7 @@ Item { } ToggleRow { - label: "Use 12h Format" + label: I18n.t("shell.use_12h_format") checked: Config.bar.use12hFormat ?? false onToggled: value => { if (value !== Config.bar.use12hFormat) { @@ -801,7 +802,7 @@ Item { } ToggleRow { - label: "Enable Firefox Player" + label: I18n.t("shell.enable_firefox_player") checked: Config.bar.enableFirefoxPlayer ?? false onToggled: value => { if (value !== Config.bar.enableFirefoxPlayer) { @@ -816,7 +817,7 @@ Item { } Text { - text: "Auto-hide" + text: I18n.t("shell.autohide") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -825,7 +826,7 @@ Item { } ToggleRow { - label: "Pinned on Startup" + label: I18n.t("shell.pinned_on_startup") checked: Config.bar.pinnedOnStartup ?? true onToggled: value => { if (value !== Config.bar.pinnedOnStartup) { @@ -836,7 +837,7 @@ Item { } ToggleRow { - label: "Hover to Reveal" + label: I18n.t("shell.hover_to_reveal") checked: Config.bar.hoverToReveal ?? true onToggled: value => { if (value !== Config.bar.hoverToReveal) { @@ -847,7 +848,7 @@ Item { } NumberInputRow { - label: "Hover Region Height" + label: I18n.t("shell.hover_region_height") value: Config.bar.hoverRegionHeight ?? 8 minValue: 0 maxValue: 32 @@ -861,7 +862,7 @@ Item { } ToggleRow { - label: "Show Pin Button" + label: I18n.t("shell.show_pin_button") checked: Config.bar.showPinButton ?? true onToggled: value => { if (value !== Config.bar.showPinButton) { @@ -872,7 +873,7 @@ Item { } ToggleRow { - label: "Available on Fullscreen" + label: I18n.t("shell.available_on_fullscreen") checked: Config.bar.availableOnFullscreen ?? false onToggled: value => { if (value !== Config.bar.availableOnFullscreen) { @@ -883,7 +884,7 @@ Item { } ScreenListRow { - label: "Screens" + label: I18n.t("shell.screens") selectedScreens: Config.bar.screenList ?? [] onScreensChanged: newList => { GlobalStates.markShellChanged(); @@ -901,7 +902,7 @@ Item { spacing: 8 Text { - text: "Frame" + text: I18n.t("settings.shell.frame") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -910,7 +911,7 @@ Item { } ToggleRow { - label: "Enabled" + label: I18n.t("shell.frame.enabled") checked: Config.bar.frameEnabled ?? false onToggled: value => { if (value !== Config.bar.frameEnabled) { @@ -921,7 +922,7 @@ Item { } NumberInputRow { - label: "Thickness" + label: I18n.t("shell.frame.thickness") value: Config.bar.frameThickness ?? 6 minValue: 0 maxValue: 40 @@ -935,7 +936,7 @@ Item { } ToggleRow { - label: "Contain Bar" + label: I18n.t("shell.frame.contain_bar") checked: Config.bar.containBar ?? false onToggled: value => { if (value !== Config.bar.containBar) { @@ -946,7 +947,7 @@ Item { } ToggleRow { - label: "Keep Bar Shadow" + label: I18n.t("shell.frame.keep_bar_shadow") checked: Config.bar.keepBarShadow ?? false visible: Config.bar.containBar ?? false onToggled: value => { @@ -958,7 +959,7 @@ Item { } ToggleRow { - label: "Keep Bar Border" + label: I18n.t("shell.frame.keep_bar_border") checked: Config.bar.keepBarBorder ?? false visible: Config.bar.containBar ?? false onToggled: value => { @@ -984,7 +985,7 @@ Item { spacing: 8 Text { - text: "Notch" + text: I18n.t("settings.shell.notch") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -996,12 +997,12 @@ Item { label: "" options: [ { - label: "Top", + label: I18n.t("common.top"), value: "top", icon: Icons.arrowUp }, { - label: "Bottom", + label: I18n.t("common.bottom"), value: "bottom", icon: Icons.arrowDown } @@ -1019,11 +1020,11 @@ Item { label: "" options: [ { - label: "Default", + label: I18n.t("common.default"), value: "default" }, { - label: "Island", + label: I18n.t("shell.dock.island"), value: "island" } ] @@ -1037,7 +1038,7 @@ Item { } NumberInputRow { - label: "Hover Region Height" + label: I18n.t("shell.hover_region_height") value: Config.notch.hoverRegionHeight ?? 8 minValue: 0 maxValue: 32 @@ -1051,7 +1052,7 @@ Item { } ToggleRow { - label: "Keep Hidden" + label: I18n.t("shell.notch.keep_hidden") checked: Config.notch.keepHidden ?? false onToggled: value => { if (value !== Config.notch.keepHidden) { @@ -1062,7 +1063,7 @@ Item { } ToggleRow { - label: "Disable Hover Expansion" + label: I18n.t("shell.notch.disable_hover_expansion") checked: Config.notch.disableHoverExpansion ?? true onToggled: value => { if (value !== Config.notch.disableHoverExpansion) { @@ -1077,7 +1078,7 @@ Item { } Text { - text: "No Media Display" + text: I18n.t("shell.no_media_display") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -1089,17 +1090,17 @@ Item { label: "" options: [ { - label: "User@Host", + label: I18n.t("shell.notch.user_host"), value: "userHost", icon: Icons.user }, { - label: "Compositor", + label: I18n.t("shell.notch.compositor"), value: "compositor", icon: Icons.compositor }, { - label: "Custom", + label: I18n.t("theme.custom"), value: "custom", icon: Icons.textT } @@ -1114,10 +1115,10 @@ Item { } TextInputRow { - label: "Custom Text" + label: I18n.t("shell.notch.custom_text") visible: Config.notch.noMediaDisplay === "custom" value: Config.notch.customText ?? "Ambxst" - placeholder: "Enter text..." + placeholder: I18n.t("shell.notch.enter_text") onValueEdited: newValue => { if (newValue !== Config.notch.customText) { GlobalStates.markShellChanged(); @@ -1141,7 +1142,7 @@ Item { spacing: 8 Text { - text: "Workspaces" + text: I18n.t("settings.shell.workspaces") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -1150,7 +1151,7 @@ Item { } NumberInputRow { - label: "Shown" + label: I18n.t("shell.workspaces.shown") value: Config.workspaces.shown ?? 10 minValue: 1 maxValue: 20 @@ -1163,7 +1164,7 @@ Item { } ToggleRow { - label: "Show App Icons" + label: I18n.t("shell.workspaces.show_app_icons") checked: Config.workspaces.showAppIcons ?? true onToggled: value => { if (value !== Config.workspaces.showAppIcons) { @@ -1174,7 +1175,7 @@ Item { } ToggleRow { - label: "Always Show Numbers" + label: I18n.t("shell.workspaces.always_show_numbers") checked: Config.workspaces.alwaysShowNumbers ?? false onToggled: value => { if (value !== Config.workspaces.alwaysShowNumbers) { @@ -1185,7 +1186,7 @@ Item { } ToggleRow { - label: "Show Numbers" + label: I18n.t("shell.workspaces.show_numbers") checked: Config.workspaces.showNumbers ?? false onToggled: value => { if (value !== Config.workspaces.showNumbers) { @@ -1196,7 +1197,7 @@ Item { } ToggleRow { - label: "Dynamic" + label: I18n.t("shell.workspaces.dynamic") checked: Config.workspaces.dynamic ?? false onToggled: value => { if (value !== Config.workspaces.dynamic) { @@ -1221,7 +1222,7 @@ Item { spacing: 8 Text { - text: "Overview" + text: I18n.t("settings.shell.overview") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -1230,7 +1231,7 @@ Item { } NumberInputRow { - label: "Rows" + label: I18n.t("shell.overview.rows") value: Config.overview.rows ?? 2 minValue: 1 maxValue: 5 @@ -1243,7 +1244,7 @@ Item { } NumberInputRow { - label: "Columns" + label: I18n.t("shell.overview.columns") value: Config.overview.columns ?? 5 minValue: 1 maxValue: 10 @@ -1260,7 +1261,7 @@ Item { spacing: 8 Text { - text: "Scale" + text: I18n.t("shell.overview.scale") font.family: Config.theme.font font.pixelSize: Styling.fontSize(0) color: Colors.overBackground @@ -1307,7 +1308,7 @@ Item { } NumberInputRow { - label: "Workspace Spacing" + label: I18n.t("shell.overview.workspace_spacing") value: Config.overview.workspaceSpacing ?? 4 minValue: 0 maxValue: 20 @@ -1335,7 +1336,7 @@ Item { spacing: 8 Text { - text: "Dock" + text: I18n.t("settings.shell.dock") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -1344,7 +1345,7 @@ Item { } ToggleRow { - label: "Enabled" + label: I18n.t("shell.dock.enabled") checked: Config.dock.enabled ?? false onToggled: value => { if (value !== Config.dock.enabled) { @@ -1355,25 +1356,25 @@ Item { } SelectorRow { - label: "Position" + label: I18n.t("shell.position") options: [ { - label: "Top", + label: I18n.t("common.top"), value: "top", icon: Icons.arrowUp }, { - label: "Bottom", + label: I18n.t("common.bottom"), value: "bottom", icon: Icons.arrowDown }, { - label: "Left", + label: I18n.t("common.left"), value: "left", icon: Icons.arrowLeft }, { - label: "Right", + label: I18n.t("common.right"), value: "right", icon: Icons.arrowRight } @@ -1388,18 +1389,18 @@ Item { } SelectorRow { - label: "Theme" + label: I18n.t("shell.dock.theme") options: [ { - label: "Default", + label: I18n.t("common.default"), value: "default" }, { - label: "Floating", + label: I18n.t("shell.dock.floating"), value: "floating" }, { - label: "Integrated", + label: I18n.t("shell.dock.integrated"), value: "integrated" } ] @@ -1413,7 +1414,7 @@ Item { } NumberInputRow { - label: "Height" + label: I18n.t("shell.dock.height") visible: (Config.dock.theme ?? "default") !== "integrated" value: Config.dock.height ?? 48 minValue: 32 @@ -1428,7 +1429,7 @@ Item { } NumberInputRow { - label: "Icon Size" + label: I18n.t("shell.dock.icon_size") visible: (Config.dock.theme ?? "default") !== "integrated" value: Config.dock.iconSize ?? 40 minValue: 24 @@ -1443,7 +1444,7 @@ Item { } NumberInputRow { - label: "Spacing" + label: I18n.t("shell.dock.spacing") visible: (Config.dock.theme ?? "default") !== "integrated" value: Config.dock.spacing ?? 10 minValue: 0 @@ -1458,7 +1459,7 @@ Item { } NumberInputRow { - label: "Margin" + label: I18n.t("shell.dock.margin") visible: (Config.dock.theme ?? "default") !== "integrated" value: Config.dock.margin ?? 8 minValue: 0 @@ -1473,7 +1474,7 @@ Item { } ToggleRow { - label: "Hover to Reveal" + label: I18n.t("shell.hover_to_reveal") visible: (Config.dock.theme ?? "default") !== "integrated" checked: Config.dock.hoverToReveal ?? true onToggled: value => { @@ -1485,7 +1486,7 @@ Item { } NumberInputRow { - label: "Hover Region" + label: I18n.t("shell.dock.hover_region") visible: (Config.dock.theme ?? "default") !== "integrated" value: Config.dock.hoverRegionHeight ?? 8 minValue: 0 @@ -1500,7 +1501,7 @@ Item { } ToggleRow { - label: "Pinned on Startup" + label: I18n.t("shell.pinned_on_startup") visible: (Config.dock.theme ?? "default") !== "integrated" checked: Config.dock.pinnedOnStartup ?? true onToggled: value => { @@ -1512,7 +1513,7 @@ Item { } ToggleRow { - label: "Show Pin Button" + label: I18n.t("shell.show_pin_button") visible: (Config.dock.theme ?? "default") !== "integrated" checked: Config.dock.showPinButton ?? true onToggled: value => { @@ -1524,7 +1525,7 @@ Item { } ToggleRow { - label: "Available on Fullscreen" + label: I18n.t("shell.available_on_fullscreen") visible: (Config.dock.theme ?? "default") !== "integrated" checked: Config.dock.availableOnFullscreen ?? false onToggled: value => { @@ -1536,7 +1537,7 @@ Item { } ToggleRow { - label: "Keep Hidden" + label: I18n.t("shell.dock.keep_hidden") visible: (Config.dock.theme ?? "default") !== "integrated" checked: Config.dock.keepHidden ?? false onToggled: value => { @@ -1548,7 +1549,7 @@ Item { } ToggleRow { - label: "Show Running Indicators" + label: I18n.t("shell.show_running_indicators") visible: (Config.dock.theme ?? "default") !== "integrated" checked: Config.dock.showRunningIndicators ?? true onToggled: value => { @@ -1560,7 +1561,7 @@ Item { } ToggleRow { - label: "Show Overview Button" + label: I18n.t("shell.show_overview_button") visible: (Config.dock.theme ?? "default") !== "integrated" checked: Config.dock.showOverviewButton ?? true onToggled: value => { @@ -1572,7 +1573,7 @@ Item { } ScreenListRow { - label: "Screens" + label: I18n.t("shell.screens") visible: (Config.dock.theme ?? "default") !== "integrated" selectedScreens: Config.dock.screenList ?? [] onScreensChanged: newList => { @@ -1596,7 +1597,7 @@ Item { spacing: 8 Text { - text: "Lockscreen" + text: I18n.t("settings.shell.lockscreen") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -1608,12 +1609,12 @@ Item { label: "" options: [ { - label: "Top", + label: I18n.t("common.top"), value: "top", icon: Icons.arrowUp }, { - label: "Bottom", + label: I18n.t("common.bottom"), value: "bottom", icon: Icons.arrowDown } @@ -1642,7 +1643,7 @@ Item { spacing: 8 Text { - text: "Desktop" + text: I18n.t("settings.shell.desktop") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -1651,7 +1652,7 @@ Item { } ToggleRow { - label: "Enabled" + label: I18n.t("shell.desktop.enabled") checked: Config.desktop.enabled ?? false onToggled: value => { if (value !== Config.desktop.enabled) { @@ -1662,7 +1663,7 @@ Item { } NumberInputRow { - label: "Icon Size" + label: I18n.t("shell.desktop.icon_size") value: Config.desktop.iconSize ?? 40 minValue: 24 maxValue: 96 @@ -1676,7 +1677,7 @@ Item { } NumberInputRow { - label: "Vertical Spacing" + label: I18n.t("shell.desktop.vertical_spacing") value: Config.desktop.spacingVertical ?? 16 minValue: 0 maxValue: 48 @@ -1695,7 +1696,7 @@ Item { spacing: 8 Text { - text: "Text Color" + text: I18n.t("shell.desktop.text_color") font.family: Config.theme.font font.pixelSize: Styling.fontSize(0) color: Colors.overBackground @@ -1708,7 +1709,7 @@ Item { Layout.preferredHeight: 48 colorNames: root.colorNames currentColor: Config.desktop.textColor ?? "overBackground" - dialogTitle: "Desktop Text Color" + dialogTitle: I18n.t("shell.desktop.text_color") compact: false onOpenColorPicker: (colorNames, currentColor, dialogTitle) => { @@ -1737,7 +1738,7 @@ Item { spacing: 8 Text { - text: "System" + text: I18n.t("settings.shell.system") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -1746,7 +1747,7 @@ Item { } ToggleRow { - label: "Update Service" + label: I18n.t("shell.system.update_service") checked: Config.system.updateServiceEnabled ?? true onToggled: value => { if (value !== Config.system.updateServiceEnabled) { @@ -1757,19 +1758,19 @@ Item { } ActionButton { - text: "About Ambxst " + Config.version + text: I18n.t("shell.system.about_ambxst").arg(Config.version) icon: Icons.info onClicked: Quickshell.execDetached(["xdg-open", "https://axeni.de/ambxst"]) } ActionButton { - text: "Donate ❤️" + text: I18n.t("shell.system.donate") icon: Icons.heart onClicked: Quickshell.execDetached(["xdg-open", "https://axeni.de/donate"]) } Text { - text: "OCR Languages" + text: I18n.t("shell.system.ocr_languages") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-2) color: Styling.srItem("overprimary") @@ -1778,7 +1779,7 @@ Item { } ToggleRow { - label: "English" + label: I18n.t("shell.system.ocr_english") checked: Config.system.ocr.eng ?? true onToggled: value => { if (value !== Config.system.ocr.eng) { @@ -1789,7 +1790,7 @@ Item { } ToggleRow { - label: "Spanish" + label: I18n.t("shell.system.ocr_spanish") checked: Config.system.ocr.spa ?? true onToggled: value => { if (value !== Config.system.ocr.spa) { @@ -1800,7 +1801,7 @@ Item { } ToggleRow { - label: "Latin" + label: I18n.t("shell.system.ocr_latin") checked: Config.system.ocr.lat ?? false onToggled: value => { if (value !== Config.system.ocr.lat) { @@ -1811,7 +1812,7 @@ Item { } ToggleRow { - label: "Japanese" + label: I18n.t("shell.system.ocr_japanese") checked: Config.system.ocr.jpn ?? false onToggled: value => { if (value !== Config.system.ocr.jpn) { @@ -1822,7 +1823,7 @@ Item { } ToggleRow { - label: "Chinese (Simplified)" + label: I18n.t("shell.system.ocr_chinese_simplified") checked: Config.system.ocr.chi_sim ?? false onToggled: value => { if (value !== Config.system.ocr.chi_sim) { @@ -1833,7 +1834,7 @@ Item { } ToggleRow { - label: "Chinese (Traditional)" + label: I18n.t("shell.system.ocr_chinese_traditional") checked: Config.system.ocr.chi_tra ?? false onToggled: value => { if (value !== Config.system.ocr.chi_tra) { @@ -1844,7 +1845,7 @@ Item { } ToggleRow { - label: "Korean" + label: I18n.t("shell.system.ocr_korean") checked: Config.system.ocr.kor ?? false onToggled: value => { if (value !== Config.system.ocr.kor) { @@ -1852,6 +1853,17 @@ Item { Config.system.ocr.kor = value; } } + } + + ToggleRow { + label: I18n.t("shell.system.ocr_russian") + checked: Config.system.ocr.rus ?? false + onToggled: value => { + if (value !== Config.system.ocr.rus) { + GlobalStates.markShellChanged(); + Config.system.ocr.rus = value; + } + } } } @@ -1864,7 +1876,7 @@ Item { spacing: 8 Text { - text: "Sidebar" + text: I18n.t("settings.shell.sidebar") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -1873,15 +1885,15 @@ Item { } SelectorRow { - label: "Position" + label: I18n.t("shell.position") options: [ { - label: "Left", + label: I18n.t("common.left"), value: "left", icon: Icons.arrowLeft }, { - label: "Right", + label: I18n.t("common.right"), value: "right", icon: Icons.arrowRight } @@ -1896,7 +1908,7 @@ Item { } NumberInputRow { - label: "Width" + label: I18n.t("shell.sidebar.width") value: Config.ai.sidebarWidth ?? 400 minValue: 300 maxValue: 800 @@ -1910,7 +1922,7 @@ Item { } ToggleRow { - label: "Pinned on Startup" + label: I18n.t("shell.pinned_on_startup") checked: Config.ai.sidebarPinnedOnStartup ?? false onToggled: value => { if (value !== Config.ai.sidebarPinnedOnStartup) { diff --git a/modules/widgets/dashboard/controls/SystemPanel.qml b/modules/widgets/dashboard/controls/SystemPanel.qml index c3bf0421a..f4219b442 100644 --- a/modules/widgets/dashboard/controls/SystemPanel.qml +++ b/modules/widgets/dashboard/controls/SystemPanel.qml @@ -7,6 +7,7 @@ import qs.modules.theme import qs.modules.components import qs.modules.globals import qs.config +import qs.modules.services Item { id: root @@ -83,7 +84,7 @@ Item { id: titlebar width: root.contentWidth anchors.horizontalCenter: parent.horizontalCenter - title: root.currentSection === "" ? "System" : (root.currentSection === "system" ? "System Resources" : (root.currentSection.charAt(0).toUpperCase() + root.currentSection.slice(1))) + title: root.currentSection === "" ? I18n.t("settings.system") : (root.currentSection === "system" ? I18n.t("settings.system.resources") : I18n.t("settings.system." + root.currentSection)) statusText: "" actions: { @@ -91,7 +92,7 @@ Item { return [ { icon: Icons.arrowLeft, - tooltip: "Back", + tooltip: I18n.t("common.back"), onClicked: function () { root.currentSection = ""; } @@ -123,23 +124,27 @@ Item { spacing: 8 SectionButton { - text: "Prefixes" + text: I18n.t("settings.system.prefixes") sectionId: "prefixes" } SectionButton { - text: "Weather" + text: I18n.t("settings.system.weather") sectionId: "weather" } SectionButton { - text: "Performance" + text: I18n.t("settings.system.language") + sectionId: "language" + } + SectionButton { + text: I18n.t("settings.system.performance") sectionId: "performance" } SectionButton { - text: "System Resources" + text: I18n.t("settings.system.resources") sectionId: "system" } SectionButton { - text: "Idle" + text: I18n.t("settings.system.idle") sectionId: "idle" } } @@ -154,7 +159,7 @@ Item { spacing: 8 Text { - text: "Prefixes" + text: I18n.t("settings.system.prefixes") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -163,7 +168,7 @@ Item { } Text { - text: "Keyboard shortcuts for quick actions in launcher" + text: I18n.t("system.prefixes.description") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-2) color: Colors.overSurfaceVariant @@ -173,7 +178,7 @@ Item { // Clipboard prefix PrefixRow { Layout.fillWidth: true - label: "Clipboard" + label: I18n.t("system.prefixes.clipboard") prefixValue: Config.prefix.clipboard onPrefixEdited: newValue => { Config.prefix.clipboard = newValue; @@ -183,7 +188,7 @@ Item { // Emoji prefix PrefixRow { Layout.fillWidth: true - label: "Emoji" + label: I18n.t("system.prefixes.emoji") prefixValue: Config.prefix.emoji onPrefixEdited: newValue => { Config.prefix.emoji = newValue; @@ -193,7 +198,7 @@ Item { // Tmux prefix PrefixRow { Layout.fillWidth: true - label: "Tmux" + label: I18n.t("system.prefixes.tmux") prefixValue: Config.prefix.tmux onPrefixEdited: newValue => { Config.prefix.tmux = newValue; @@ -203,7 +208,7 @@ Item { // Wallpapers prefix PrefixRow { Layout.fillWidth: true - label: "Wallpapers" + label: I18n.t("system.prefixes.wallpapers") prefixValue: Config.prefix.wallpapers onPrefixEdited: newValue => { Config.prefix.wallpapers = newValue; @@ -213,7 +218,7 @@ Item { // Notes prefix PrefixRow { Layout.fillWidth: true - label: "Notes" + label: I18n.t("system.prefixes.notes") prefixValue: Config.prefix.notes onPrefixEdited: newValue => { Config.prefix.notes = newValue; @@ -231,7 +236,7 @@ Item { spacing: 8 Text { - text: "Weather" + text: I18n.t("settings.system.weather") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -245,7 +250,7 @@ Item { spacing: 8 Text { - text: "Location" + text: I18n.t("weather.location") font.family: Config.theme.font font.pixelSize: Styling.fontSize(0) color: Colors.overBackground @@ -288,7 +293,7 @@ Item { Text { anchors.verticalCenter: parent.verticalCenter visible: !locationInput.text && !locationInput.activeFocus - text: "e.g. Buenos Aires, Tokyo..." + text: I18n.t("weather.location_placeholder") font: locationInput.font color: Colors.overSurfaceVariant } @@ -302,7 +307,7 @@ Item { spacing: 8 Text { - text: "Unit" + text: I18n.t("weather.unit") font.family: Config.theme.font font.pixelSize: Styling.fontSize(0) color: Colors.overBackground @@ -316,11 +321,11 @@ Item { model: [ { id: "C", - label: "Celsius" + label: I18n.t("weather.celsius") }, { id: "F", - label: "Fahrenheit" + label: I18n.t("weather.fahrenheit") } ] @@ -361,6 +366,100 @@ Item { } } + // ===================== + // LANGUAGE SECTION + // ===================== + ColumnLayout { + visible: root.currentSection === "language" + property string settingsSection: "language" + Layout.fillWidth: true + spacing: 8 + + Text { + text: I18n.t("settings.system.language") + font.family: Config.theme.font + font.pixelSize: Styling.fontSize(-1) + font.weight: Font.Medium + color: Colors.overSurfaceVariant + } + + Flow { + Layout.fillWidth: true + spacing: 8 + + StyledRect { + id: autoLangButton + + property bool isSelected: Config.system.language === "auto" + property bool isHovered: false + + variant: isSelected ? "primary" : (isHovered ? "focus" : "common") + width: autoLangLabel.width + 24 + height: 36 + radius: Styling.radius(-2) + + Text { + id: autoLangLabel + anchors.centerIn: parent + text: { + const detected = I18n.detectSystemLanguage(); + const name = I18n.availableLanguages[detected] ?? detected; + return I18n.t("language.auto_detected").replace("%1", name); + } + font.family: Config.theme.font + font.pixelSize: Styling.fontSize(0) + font.weight: autoLangButton.isSelected ? Font.Bold : Font.Normal + color: autoLangButton.item + } + + MouseArea { + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onEntered: autoLangButton.isHovered = true + onExited: autoLangButton.isHovered = false + onClicked: Config.system.language = "auto" + } + } + + Repeater { + model: Object.keys(I18n.availableLanguages) + + delegate: StyledRect { + id: langButton + required property string modelData + + property bool isSelected: Config.system.language === modelData + property bool isHovered: false + + variant: isSelected ? "primary" : (isHovered ? "focus" : "common") + width: langLabel.width + 24 + height: 36 + radius: Styling.radius(-2) + + Text { + id: langLabel + anchors.centerIn: parent + text: I18n.availableLanguages[langButton.modelData] ?? langButton.modelData + font.family: Config.theme.font + font.pixelSize: Styling.fontSize(0) + font.weight: langButton.isSelected ? Font.Bold : Font.Normal + color: langButton.item + } + + MouseArea { + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onEntered: langButton.isHovered = true + onExited: langButton.isHovered = false + onClicked: Config.system.language = langButton.modelData + } + } + } + } + } + // ===================== // PERFORMANCE SECTION // ===================== @@ -371,7 +470,7 @@ Item { spacing: 8 Text { - text: "Performance" + text: I18n.t("settings.system.performance") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -380,7 +479,7 @@ Item { } Text { - text: "Toggle visual effects to improve performance" + text: I18n.t("system.performance.description") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-2) color: Colors.overSurfaceVariant @@ -390,8 +489,8 @@ Item { // Blur Transition toggle ToggleRow { Layout.fillWidth: true - label: "Blur Transition" - description: "Animated blur when opening panels" + label: I18n.t("performance.blur_transition") + description: I18n.t("system.performance.blur_transition_desc") checked: Config.performance.blurTransition onToggled: checked => { Config.performance.blurTransition = checked; @@ -401,8 +500,8 @@ Item { // Window Preview toggle ToggleRow { Layout.fillWidth: true - label: "Window Preview" - description: "Show window thumbnails in overview" + label: I18n.t("performance.window_preview") + description: I18n.t("system.performance.window_preview_desc") checked: Config.performance.windowPreview onToggled: checked => { Config.performance.windowPreview = checked; @@ -412,8 +511,8 @@ Item { // Wavy Line toggle ToggleRow { Layout.fillWidth: true - label: "Wavy Line" - description: "Animated wavy line effect" + label: I18n.t("performance.wavy_line") + description: I18n.t("system.performance.wavy_line_desc") checked: Config.performance.wavyLine onToggled: checked => { Config.performance.wavyLine = checked; @@ -423,8 +522,8 @@ Item { // Rotate Cover Art toggle ToggleRow { Layout.fillWidth: true - label: "Disable Cover Art Rotation" - description: "Stop the vinyl disc from spinning" + label: I18n.t("system.performance.disable_cover_rotation") + description: I18n.t("system.performance.disable_cover_rotation_desc") checked: !Config.performance.rotateCoverArt onToggled: checked => { Config.performance.rotateCoverArt = !checked; @@ -442,7 +541,7 @@ Item { spacing: 8 Text { - text: "System Resources" + text: I18n.t("settings.system.resources") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -451,7 +550,7 @@ Item { } Text { - text: "Configure which disks to monitor" + text: I18n.t("system.resources.description") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-2) color: Colors.overSurfaceVariant @@ -504,7 +603,7 @@ Item { Text { anchors.verticalCenter: parent.verticalCenter visible: !diskInput.text && !diskInput.activeFocus - text: "e.g. /, /home..." + text: I18n.t("system.disk_path_placeholder") font: diskInput.font color: Colors.overSurfaceVariant } @@ -542,7 +641,7 @@ Item { StyledToolTip { visible: removeDiskArea.containsMouse - tooltipText: "Remove disk" + tooltipText: I18n.t("system.remove_disk") } } } @@ -570,7 +669,7 @@ Item { } Text { - text: "Add Disk" + text: I18n.t("system.add_disk") font.family: Config.theme.font font.pixelSize: Styling.fontSize(0) color: addDiskButton.item @@ -603,7 +702,7 @@ Item { spacing: 8 Text { - text: "Idle" + text: I18n.t("settings.system.idle") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -612,9 +711,9 @@ Item { } TextInputRow { - label: "Lock Cmd" + label: I18n.t("idle.lock_cmd_label") value: Config.system.idle.general.lock_cmd ?? "" - placeholder: "Command to lock screen" + placeholder: I18n.t("idle.lock_cmd") onValueEdited: newValue => { if (newValue !== Config.system.idle.general.lock_cmd) { GlobalStates.markShellChanged(); @@ -624,9 +723,9 @@ Item { } TextInputRow { - label: "Before Sleep" + label: I18n.t("idle.before_sleep_label") value: Config.system.idle.general.before_sleep_cmd ?? "" - placeholder: "Command before sleep" + placeholder: I18n.t("idle.before_sleep") onValueEdited: newValue => { if (newValue !== Config.system.idle.general.before_sleep_cmd) { GlobalStates.markShellChanged(); @@ -636,9 +735,9 @@ Item { } TextInputRow { - label: "After Sleep" + label: I18n.t("idle.after_sleep_label") value: Config.system.idle.general.after_sleep_cmd ?? "" - placeholder: "Command after sleep" + placeholder: I18n.t("idle.after_sleep") onValueEdited: newValue => { if (newValue !== Config.system.idle.general.after_sleep_cmd) { GlobalStates.markShellChanged(); @@ -648,7 +747,7 @@ Item { } Text { - text: "Listeners" + text: I18n.t("idle.listeners") font.family: Config.theme.font font.pixelSize: Styling.fontSize(0) color: Colors.overBackground @@ -676,7 +775,7 @@ Item { RowLayout { Layout.fillWidth: true Text { - text: "Listener " + (index + 1) + text: I18n.t("idle.listener_n").replace("%1", index + 1) font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.bold: true @@ -717,7 +816,7 @@ Item { } NumberInputRow { - label: "Timeout (s)" + label: I18n.t("idle.timeout") value: modelData.timeout || 0 minValue: 1 maxValue: 7200 @@ -732,7 +831,7 @@ Item { } TextInputRow { - label: "On Timeout" + label: I18n.t("idle.on_timeout") value: modelData.onTimeout || "" onValueEdited: val => { var list = []; @@ -745,7 +844,7 @@ Item { } TextInputRow { - label: "On Resume" + label: I18n.t("idle.on_resume") value: modelData.onResume || "" onValueEdited: val => { var list = []; @@ -768,7 +867,7 @@ Item { Text { anchors.centerIn: parent - text: "Add Listener" + text: I18n.t("idle.add_listener") font.family: Config.theme.font font.pixelSize: Styling.fontSize(0) font.bold: true diff --git a/modules/widgets/dashboard/controls/ThemePanel.qml b/modules/widgets/dashboard/controls/ThemePanel.qml index e622dff34..46ee9a16d 100644 --- a/modules/widgets/dashboard/controls/ThemePanel.qml +++ b/modules/widgets/dashboard/controls/ThemePanel.qml @@ -6,6 +6,7 @@ import QtQuick.Layouts import qs.modules.theme import qs.modules.components import qs.modules.globals +import qs.modules.services import Quickshell import Quickshell.Io import qs.config @@ -185,15 +186,15 @@ Item { id: titlebar width: root.contentWidth anchors.horizontalCenter: parent.horizontalCenter - title: root.currentSection === "" ? "Theme" : (root.currentSection.charAt(0).toUpperCase() + root.currentSection.slice(1)) - statusText: GlobalStates.themeHasChanges ? "Unsaved changes" : "" + title: root.currentSection === "" ? I18n.t("settings.theme") : I18n.t("settings.theme." + root.currentSection) + statusText: GlobalStates.themeHasChanges ? I18n.t("common.unsaved_changes") : "" statusColor: Colors.error actions: { let baseActions = [ { icon: Icons.arrowCounterClockwise, - tooltip: "Discard changes", + tooltip: I18n.t("common.discard_changes"), enabled: GlobalStates.themeHasChanges, onClicked: function () { GlobalStates.discardThemeChanges(); @@ -201,7 +202,7 @@ Item { }, { icon: Icons.disk, - tooltip: "Apply changes", + tooltip: I18n.t("common.apply_changes"), enabled: GlobalStates.themeHasChanges, onClicked: function () { GlobalStates.applyThemeChanges(); @@ -213,7 +214,7 @@ Item { return [ { icon: Icons.arrowLeft, - tooltip: "Back", + tooltip: I18n.t("common.back"), onClicked: function () { root.currentSection = ""; } @@ -246,15 +247,15 @@ Item { spacing: 8 SectionButton { - text: "General" + text: I18n.t("settings.theme.general") sectionId: "general" } SectionButton { - text: "Shadow" + text: I18n.t("settings.theme.shadow") sectionId: "shadow" } SectionButton { - text: "Colors" + text: I18n.t("settings.theme.colors") sectionId: "colors" } } @@ -273,7 +274,7 @@ Item { spacing: 8 Text { - text: "General" + text: I18n.t("settings.theme.general") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -287,7 +288,7 @@ Item { spacing: 8 Text { - text: "Wallpapers" + text: I18n.t("settings.theme.wallpapers") font.family: Config.theme.font font.pixelSize: Styling.fontSize(0) color: Colors.overBackground @@ -315,7 +316,7 @@ Item { Text { anchors.fill: parent verticalAlignment: Text.AlignVCenter - text: "Default" + text: I18n.t("common.default") font: parent.font color: Colors.overSurfaceVariant visible: !parent.text && !parent.activeFocus @@ -339,7 +340,7 @@ Item { spacing: 8 Text { - text: "Tint Icons" + text: I18n.t("settings.theme.tint_icons") font.family: Config.theme.font font.pixelSize: Styling.fontSize(0) color: Colors.overBackground @@ -408,7 +409,7 @@ Item { spacing: 8 Text { - text: "Enable Corners" + text: I18n.t("settings.theme.enable_corners") font.family: Config.theme.font font.pixelSize: Styling.fontSize(0) color: Colors.overBackground @@ -477,7 +478,7 @@ Item { spacing: 8 Text { - text: "Animation" + text: I18n.t("settings.theme.animation") font.family: Config.theme.font font.pixelSize: Styling.fontSize(0) color: Colors.overBackground @@ -528,7 +529,7 @@ Item { } Text { - text: "Fonts" + text: I18n.t("settings.theme.fonts") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -542,7 +543,7 @@ Item { spacing: 8 Text { - text: "UI Font" + text: I18n.t("settings.theme.ui_font") font.family: Config.theme.font font.pixelSize: Styling.fontSize(0) color: Colors.overBackground @@ -641,7 +642,7 @@ Item { spacing: 8 Text { - text: "Mono Font" + text: I18n.t("settings.theme.mono_font") font.family: Config.theme.font font.pixelSize: Styling.fontSize(0) color: Colors.overBackground @@ -739,7 +740,7 @@ Item { } Text { - text: "Roundness" + text: I18n.t("settings.theme.roundness") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -808,7 +809,7 @@ Item { spacing: 8 Text { - text: "Shadow" + text: I18n.t("settings.theme.shadow") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -822,7 +823,7 @@ Item { spacing: 8 Text { - text: "Opacity" + text: I18n.t("theme.shadow.opacity") font.family: Config.theme.font font.pixelSize: Styling.fontSize(0) color: Colors.overBackground @@ -873,7 +874,7 @@ Item { spacing: 8 Text { - text: "Blur" + text: I18n.t("theme.shadow.blur") font.family: Config.theme.font font.pixelSize: Styling.fontSize(0) color: Colors.overBackground @@ -925,7 +926,7 @@ Item { spacing: 8 Text { - text: "Offset X" + text: I18n.t("theme.shadow.offset_x") font.family: Config.theme.font font.pixelSize: Styling.fontSize(0) color: Colors.overBackground @@ -976,7 +977,7 @@ Item { spacing: 8 Text { - text: "Offset Y" + text: I18n.t("theme.shadow.offset_y") font.family: Config.theme.font font.pixelSize: Styling.fontSize(0) color: Colors.overBackground @@ -1028,7 +1029,7 @@ Item { spacing: 8 Text { - text: "Color" + text: I18n.t("theme.shadow.color") font.family: Config.theme.font font.pixelSize: Styling.fontSize(0) color: Colors.overBackground @@ -1129,7 +1130,7 @@ Item { spacing: 8 Text { - text: "Variant" + text: I18n.t("settings.theme.variant") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium @@ -1481,7 +1482,7 @@ Item { spacing: 8 Text { - text: "Editor - " + root.getVariantLabel(root.selectedVariant) + text: I18n.t("theme.editor_label").replace("%1", root.getVariantLabel(root.selectedVariant)) font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) font.weight: Font.Medium diff --git a/modules/widgets/dashboard/controls/VariantEditor.qml b/modules/widgets/dashboard/controls/VariantEditor.qml index d1baba3f7..0bc28d544 100644 --- a/modules/widgets/dashboard/controls/VariantEditor.qml +++ b/modules/widgets/dashboard/controls/VariantEditor.qml @@ -7,6 +7,7 @@ import Quickshell.Widgets import qs.modules.theme import qs.modules.components import qs.modules.globals +import qs.modules.services import qs.config Item { @@ -144,7 +145,7 @@ Item { Layout.preferredWidth: 1 colorNames: root.colorNames currentColor: (root.variantConfig && root.variantConfig.itemColor) ? root.variantConfig.itemColor : "surface" - label: "Item Color" + label: I18n.t("theme.item_color") dialogTitle: "Select Item Color" onColorSelected: color => root.updateProp("itemColor", color) onOpenColorPicker: (names, current, title) => { @@ -192,7 +193,7 @@ Item { Text { Layout.fillWidth: true - text: "Opacity" + text: I18n.t("theme.opacity") font.family: Styling.defaultFont font.pixelSize: Styling.fontSize(-2) font.bold: true @@ -277,7 +278,7 @@ Item { Text { Layout.fillWidth: true - text: "Border" + text: I18n.t("theme.border") font.family: Styling.defaultFont font.pixelSize: Styling.fontSize(-2) font.bold: true @@ -345,7 +346,7 @@ Item { spacing: 2 Text { - text: "Angle" + text: I18n.t("theme.angle") font.family: Styling.defaultFont font.pixelSize: Styling.fontSize(-2) font.bold: true @@ -511,7 +512,7 @@ Item { Layout.fillWidth: true colorNames: root.colorNames currentColor: (root.variantConfig && root.variantConfig.halftoneDotColor) ? root.variantConfig.halftoneDotColor : "surface" - label: "Dot Color" + label: I18n.t("theme.dot_color") circlePreview: true dialogTitle: "Select Dot Color" onColorSelected: color => root.updateProp("halftoneDotColor", color) @@ -527,7 +528,7 @@ Item { Layout.fillWidth: true colorNames: root.colorNames currentColor: (root.variantConfig && root.variantConfig.halftoneBackgroundColor) ? root.variantConfig.halftoneBackgroundColor : "surface" - label: "Background" + label: I18n.t("theme.background") dialogTitle: "Select Background Color" onColorSelected: color => root.updateProp("halftoneBackgroundColor", color) onOpenColorPicker: (names, current, title) => { @@ -578,7 +579,7 @@ Item { } Text { - text: "Angle" + text: I18n.t("theme.angle") font.family: Styling.defaultFont font.pixelSize: Styling.fontSize(0) font.bold: true @@ -634,7 +635,7 @@ Item { } Text { - text: "Size" + text: I18n.t("theme.size") font.family: Styling.defaultFont font.pixelSize: Styling.fontSize(0) font.bold: true @@ -727,7 +728,7 @@ Item { } Text { - text: "Range" + text: I18n.t("theme.range") font.family: Styling.defaultFont font.pixelSize: Styling.fontSize(0) font.bold: true diff --git a/modules/widgets/dashboard/controls/WifiNetworkItem.qml b/modules/widgets/dashboard/controls/WifiNetworkItem.qml index 9b86d816b..825c1f32b 100644 --- a/modules/widgets/dashboard/controls/WifiNetworkItem.qml +++ b/modules/widgets/dashboard/controls/WifiNetworkItem.qml @@ -109,10 +109,10 @@ Item { visible: root.network?.active || root.expanded text: { if (root.network?.active) - return "Connected"; + return I18n.t("wifi.connected"); if (root.network?.isSecure) - return "Secured"; - return "Open"; + return I18n.t("wifi.secured"); + return I18n.t("wifi.open"); } font.family: Config.theme.font font.pixelSize: Styling.fontSize(-2) @@ -138,7 +138,7 @@ Item { Text { anchors.centerIn: parent - text: "5G" + text: I18n.t("wifi.band_5g") font.family: Config.theme.font font.pixelSize: 10 font.weight: Font.Bold @@ -166,7 +166,7 @@ Item { id: passwordInput Layout.fillWidth: true visible: root.network?.askingPassword ?? false - placeholderText: "Enter password..." + placeholderText: I18n.t("wifi.password") passwordMode: true implicitHeight: 40 variant: "internalbg" @@ -200,7 +200,7 @@ Item { } contentItem: Text { - text: root.network?.active ? "Disconnect" : "Connect" + text: root.network?.active ? I18n.t("wifi.disconnect") : I18n.t("wifi.connect") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) color: root.network?.active ? Colors.overSurfaceVariant : Styling.srItem("primary") diff --git a/modules/widgets/dashboard/controls/WifiPanel.qml b/modules/widgets/dashboard/controls/WifiPanel.qml index 5672c5f25..d7bdf1db3 100644 --- a/modules/widgets/dashboard/controls/WifiPanel.qml +++ b/modules/widgets/dashboard/controls/WifiPanel.qml @@ -47,8 +47,8 @@ Item { id: titlebar width: root.contentWidth anchors.horizontalCenter: parent.horizontalCenter - title: "Wi-Fi" - statusText: NetworkService.wifiConnecting ? "Connecting..." : (NetworkService.wifiStatus === "limited" ? "Limited" : "") + title: I18n.t("wifi.title") + statusText: NetworkService.wifiConnecting ? I18n.t("wifi.connecting") : (NetworkService.wifiStatus === "limited" ? I18n.t("wifi.limited") : "") statusColor: NetworkService.wifiStatus === "limited" ? Colors.warning : Styling.srItem("overprimary") showToggle: true toggleChecked: NetworkService.wifiStatus !== "disabled" @@ -56,7 +56,7 @@ Item { actions: [ { icon: Icons.globe, - tooltip: "Open captive portal", + tooltip: I18n.t("wifi.open_portal"), enabled: NetworkService.wifiStatus === "limited", onClicked: function () { NetworkService.openPublicWifiPortal(); @@ -64,14 +64,14 @@ Item { }, { icon: Icons.popOpen, - tooltip: "Network settings", + tooltip: I18n.t("wifi.network_settings"), onClicked: function () { Quickshell.execDetached(["nm-connection-editor"]); } }, { icon: Icons.sync, - tooltip: "Rescan networks", + tooltip: I18n.t("wifi.rescan"), enabled: NetworkService.wifiEnabled, loading: NetworkService.wifiScanning || NetworkService.isUpdating, onClicked: function () { @@ -106,7 +106,7 @@ Item { Text { anchors.centerIn: parent visible: networkList.count === 0 && !NetworkService.wifiScanning - text: NetworkService.wifiEnabled ? "No networks found" : "Wi-Fi is disabled" + text: NetworkService.wifiEnabled ? I18n.t("wifi.no_networks") : I18n.t("wifi.disabled") font.family: Config.theme.font font.pixelSize: Config.theme.fontSize color: Colors.overSurfaceVariant diff --git a/modules/widgets/dashboard/emoji/EmojiTab.qml b/modules/widgets/dashboard/emoji/EmojiTab.qml index d7c7a5043..dab317009 100644 --- a/modules/widgets/dashboard/emoji/EmojiTab.qml +++ b/modules/widgets/dashboard/emoji/EmojiTab.qml @@ -394,7 +394,7 @@ Rectangle { width: parent.width - (clearButton.visible ? clearButton.width + parent.spacing : 0) height: 48 text: root.searchText - placeholderText: "Search emojis..." + placeholderText: I18n.t("emoji.search") prefixIcon: root.prefixIcon onSearchTextChanged: text => root.searchText = text @@ -522,7 +522,7 @@ Rectangle { textFormat: Text.RichText } Text { - text: "Clear recent?" + text: I18n.t("emoji.clear_recent") height: parent.height font.family: Config.theme.font font.weight: Font.Bold diff --git a/modules/widgets/dashboard/metrics/MetricsTab.qml b/modules/widgets/dashboard/metrics/MetricsTab.qml index 97b91b37c..6c3197b92 100644 --- a/modules/widgets/dashboard/metrics/MetricsTab.qml +++ b/modules/widgets/dashboard/metrics/MetricsTab.qml @@ -338,7 +338,7 @@ Rectangle { } Text { - text: "System" + text: I18n.t("settings.system") font.family: Config.theme.font font.pixelSize: Styling.fontSize(-2) color: Colors.overBackground diff --git a/modules/widgets/dashboard/notes/NotesTab.qml b/modules/widgets/dashboard/notes/NotesTab.qml index 01e120bc7..165577741 100644 --- a/modules/widgets/dashboard/notes/NotesTab.qml +++ b/modules/widgets/dashboard/notes/NotesTab.qml @@ -1058,7 +1058,7 @@ Item { height: 48 anchors.top: parent.top text: root.searchText - placeholderText: "Search notes..." + placeholderText: I18n.t("notes.search") prefixIcon: root.prefixIcon handleTabNavigation: true @@ -1769,7 +1769,7 @@ Item { Text { Layout.fillWidth: true - text: modelData.modified ? NotesUtils.formatTimestamp(modelData.modified) : "" + text: modelData.modified ? NotesUtils.formatTimestamp(modelData.modified, I18n.t) : "" font.family: Config.theme.font font.pixelSize: Config.theme.fontSize - 2 color: Qt.rgba(textColor.r, textColor.g, textColor.b, 0.6) @@ -1954,7 +1954,7 @@ Item { property var noteOptions: [ { - text: "Edit", + text: I18n.t("common.edit"), icon: Icons.edit, highlightColor: Styling.srItem("overprimary"), textColor: Styling.srItem("primary"), @@ -1963,7 +1963,7 @@ Item { } }, { - text: "Rename", + text: I18n.t("common.rename"), icon: Icons.edit, highlightColor: Colors.secondary, textColor: Styling.srItem("secondary"), @@ -1973,7 +1973,7 @@ Item { } }, { - text: "Delete", + text: I18n.t("common.delete"), icon: Icons.trash, highlightColor: Colors.error, textColor: Styling.srItem("error"), @@ -1986,7 +1986,7 @@ Item { property var createOptions: [ { - text: "Rich Text", + text: I18n.t("notes.rich_text"), icon: Icons.file, highlightColor: Styling.srItem("overprimary"), textColor: Styling.srItem("primary"), @@ -1996,7 +1996,7 @@ Item { } }, { - text: "Markdown", + text: I18n.t("notes.markdown"), icon: Icons.markdown, highlightColor: Colors.secondary, textColor: Styling.srItem("secondary"), @@ -2696,7 +2696,7 @@ Item { wrapMode: TextEdit.Wrap selectByMouse: true persistentSelection: true - placeholderText: "Start typing..." + placeholderText: I18n.t("notes.start_typing") leftPadding: 8 rightPadding: 8 topPadding: 8 @@ -3277,7 +3277,7 @@ Item { color: Colors.overSurface wrapMode: TextEdit.Wrap selectByMouse: true - placeholderText: "Write markdown here..." + placeholderText: I18n.t("notes.write_markdown") leftPadding: 8 rightPadding: 8 topPadding: 8 @@ -3437,7 +3437,7 @@ Item { Text { anchors.centerIn: parent - text: "Select or create a note" + text: I18n.t("notes.select_or_create") font.family: Config.theme.font font.pixelSize: Config.theme.fontSize color: Colors.outline diff --git a/modules/widgets/dashboard/notes/notes_utils.js b/modules/widgets/dashboard/notes/notes_utils.js index 5c55e3769..ff4504f0c 100644 --- a/modules/widgets/dashboard/notes/notes_utils.js +++ b/modules/widgets/dashboard/notes/notes_utils.js @@ -25,22 +25,32 @@ function getCurrentTimestamp() { * @param {string} isoTimestamp - ISO timestamp string * @returns {string} Formatted date string */ -function formatTimestamp(isoTimestamp) { +function formatTimestamp(isoTimestamp, t) { if (!isoTimestamp) return ""; try { var date = new Date(isoTimestamp); var now = new Date(); var diffMs = now - date; var diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24)); - + if (diffDays === 0) { - // Today - show time return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); } else if (diffDays === 1) { - return "Yesterday"; + return t ? t("notifications.yesterday") : "Yesterday"; } else if (diffDays < 7) { - return diffDays + " days ago"; + return t ? t("notes.days_ago", diffDays) : diffDays + " days ago"; } else { + if (t) { + var monthKeys = [ + "calendar.month.january", "calendar.month.february", + "calendar.month.march", "calendar.month.april", + "calendar.month.may", "calendar.month.june", + "calendar.month.july", "calendar.month.august", + "calendar.month.september", "calendar.month.october", + "calendar.month.november", "calendar.month.december" + ]; + return t(monthKeys[date.getMonth()]) + " " + date.getDate(); + } return date.toLocaleDateString([], { month: 'short', day: 'numeric' }); } } catch (e) { diff --git a/modules/widgets/dashboard/tmux/TmuxTab.qml b/modules/widgets/dashboard/tmux/TmuxTab.qml index 7db449df0..f61415323 100644 --- a/modules/widgets/dashboard/tmux/TmuxTab.qml +++ b/modules/widgets/dashboard/tmux/TmuxTab.qml @@ -588,7 +588,7 @@ Item { height: 48 anchors.top: parent.top text: root.searchText - placeholderText: "Search or create tmux session..." + placeholderText: I18n.t("tmux.search") iconText: "" prefixIcon: root.prefixIcon @@ -1036,7 +1036,7 @@ Item { boundsBehavior: Flickable.StopAtBounds model: [ { - text: "Open", + text: I18n.t("common.open"), icon: Icons.popOpen, highlightColor: Styling.srItem("overprimary"), textColor: Styling.srItem("primary"), @@ -1045,7 +1045,7 @@ Item { } }, { - text: "Rename", + text: I18n.t("common.rename"), icon: Icons.edit, highlightColor: Colors.secondary, textColor: Styling.srItem("secondary"), @@ -1055,7 +1055,7 @@ Item { } }, { - text: "Quit", + text: I18n.t("tmux.quit"), icon: Icons.alert, highlightColor: Colors.error, textColor: Styling.srItem("error"), @@ -2000,7 +2000,7 @@ Item { } Text { - text: "No panes to display" + text: I18n.t("tmux.no_panes") font.family: Config.theme.font font.pixelSize: Config.theme.fontSize color: Colors.outline @@ -2035,7 +2035,7 @@ Item { } Text { - text: "Loading panes..." + text: I18n.t("tmux.loading_panes") font.family: Config.theme.font font.pixelSize: Config.theme.fontSize color: Colors.outline @@ -2174,7 +2174,7 @@ Item { } Text { - text: "No session selected" + text: I18n.t("tmux.no_session") font.family: Config.theme.font font.pixelSize: Config.theme.fontSize font.weight: Font.Bold @@ -2183,7 +2183,7 @@ Item { } Text { - text: "Select a session to preview" + text: I18n.t("tmux.select_session_hint") font.family: Config.theme.font font.pixelSize: Config.theme.fontSize color: Colors.outline diff --git a/modules/widgets/dashboard/wallpapers/FilterBar.qml b/modules/widgets/dashboard/wallpapers/FilterBar.qml index eec82f0a6..b60e1002e 100644 --- a/modules/widgets/dashboard/wallpapers/FilterBar.qml +++ b/modules/widgets/dashboard/wallpapers/FilterBar.qml @@ -4,6 +4,7 @@ import QtQuick.Layouts import qs.modules.theme import qs.modules.components import qs.modules.globals +import qs.modules.services import qs.config // Componente para la barra de filtros de tipo de archivo @@ -290,7 +291,7 @@ FocusScope { Text { id: filterText - text: label + text: type === "image" ? I18n.t("wallpapers.filter_images") : type === "video" ? I18n.t("wallpapers.filter_videos") : label font.family: Config.theme.font font.pixelSize: Config.theme.fontSize color: filterTag.item diff --git a/modules/widgets/dashboard/wallpapers/SchemeSelector.qml b/modules/widgets/dashboard/wallpapers/SchemeSelector.qml index b47a2f029..ae9b7efb6 100644 --- a/modules/widgets/dashboard/wallpapers/SchemeSelector.qml +++ b/modules/widgets/dashboard/wallpapers/SchemeSelector.qml @@ -5,6 +5,7 @@ import Quickshell.Widgets import qs.modules.theme import qs.modules.components import qs.modules.globals +import qs.modules.services import qs.config Item { @@ -118,21 +119,21 @@ Item { function getSchemeDisplayName(scheme) { const map = { - "scheme-content": "Content", - "scheme-expressive": "Expressive", - "scheme-fidelity": "Fidelity", - "scheme-fruit-salad": "Fruit Salad", - "scheme-monochrome": "Monochrome", - "scheme-neutral": "Neutral", - "scheme-rainbow": "Rainbow", - "scheme-tonal-spot": "Tonal Spot" + "scheme-content": I18n.t("wallpapers.scheme_content"), + "scheme-expressive": I18n.t("wallpapers.scheme_expressive"), + "scheme-fidelity": I18n.t("wallpapers.scheme_fidelity"), + "scheme-fruit-salad": I18n.t("wallpapers.scheme_fruit_salad"), + "scheme-monochrome": I18n.t("wallpapers.scheme_monochrome"), + "scheme-neutral": I18n.t("wallpapers.scheme_neutral"), + "scheme-rainbow": I18n.t("wallpapers.scheme_rainbow"), + "scheme-tonal-spot": I18n.t("wallpapers.scheme_tonal_spot") }; return map[scheme] || scheme; } function getCurrentDisplayName() { if (!GlobalStates.wallpaperManager) - return "Select Scheme"; + return I18n.t("wallpapers.select_scheme"); if (GlobalStates.wallpaperManager.activeColorPreset) { return GlobalStates.wallpaperManager.activeColorPreset; @@ -142,7 +143,7 @@ Item { return getSchemeDisplayName(GlobalStates.wallpaperManager.currentMatugenScheme); } - return "Select Scheme"; + return I18n.t("wallpapers.select_scheme"); } // Layout properties (can be overridden by parent) diff --git a/modules/widgets/dashboard/wallpapers/WallpapersTab.qml b/modules/widgets/dashboard/wallpapers/WallpapersTab.qml index e35d928f0..c4118a2f7 100644 --- a/modules/widgets/dashboard/wallpapers/WallpapersTab.qml +++ b/modules/widgets/dashboard/wallpapers/WallpapersTab.qml @@ -258,7 +258,7 @@ FocusScope { Layout.fillWidth: true Layout.alignment: Qt.AlignVCenter text: searchText - placeholderText: "Search wallpapers..." + placeholderText: I18n.t("wallpapers.search") iconText: "" clearOnEscape: false handleTabNavigation: true @@ -519,7 +519,7 @@ FocusScope { Text { anchors.fill: parent - text: "OLED" + text: I18n.t("wallpapers.oled") color: Colors.overSurface font.family: Config.theme.font font.pixelSize: Config.theme.fontSize @@ -666,7 +666,7 @@ FocusScope { Text { anchors.fill: parent - text: "Tint" + text: I18n.t("wallpapers.tint") color: Colors.overSurface font.family: Config.theme.font font.pixelSize: Config.theme.fontSize @@ -973,7 +973,7 @@ FocusScope { x: needsScroll ? 4 : undefined text: { if (parent.parent.isCurrentWallpaper) { - return "CURRENT"; + return I18n.t("wallpapers.current"); } else if (wallpaperGrid.currentIndex >= 0 && wallpaperGrid.currentIndex < filteredWallpapers.length) { return filteredWallpapers[wallpaperGrid.currentIndex].split('/').pop(); } diff --git a/modules/widgets/dashboard/widgets/FullPlayer.qml b/modules/widgets/dashboard/widgets/FullPlayer.qml index 5c701ba55..7ffabe195 100644 --- a/modules/widgets/dashboard/widgets/FullPlayer.qml +++ b/modules/widgets/dashboard/widgets/FullPlayer.qml @@ -374,7 +374,7 @@ StyledRect { Text { Layout.fillWidth: true Layout.preferredHeight: visible ? implicitHeight : 0 - text: player.hasActivePlayer ? (MprisController.activePlayer?.trackTitle ?? "") : "Nothing Playing" + text: player.hasActivePlayer ? (MprisController.activePlayer?.trackTitle ?? "") : I18n.t("player.nothing_playing") color: Colors.overBackground font.pixelSize: Config.theme.fontSize + 2 font.weight: Font.Bold @@ -388,7 +388,7 @@ StyledRect { Text { Layout.fillWidth: true Layout.preferredHeight: visible ? implicitHeight : 0 - text: player.hasActivePlayer ? (MprisController.activePlayer?.trackAlbum ?? "") : "Enjoy the silence" + text: player.hasActivePlayer ? (MprisController.activePlayer?.trackAlbum ?? "") : I18n.t("player.enjoy_silence") color: Colors.overBackground font.pixelSize: Config.theme.fontSize font.family: Config.theme.font @@ -601,7 +601,7 @@ StyledRect { Text { Layout.fillWidth: true - text: (modelData?.trackTitle || modelData?.identity || "Unknown Player") + text: (modelData?.trackTitle || modelData?.identity || I18n.t("player.unknown_player")) color: Colors.overBackground font.family: Config.theme.font elide: Text.ElideRight diff --git a/modules/widgets/dashboard/widgets/NotificationHistory.qml b/modules/widgets/dashboard/widgets/NotificationHistory.qml index 387979366..d28f41d2b 100644 --- a/modules/widgets/dashboard/widgets/NotificationHistory.qml +++ b/modules/widgets/dashboard/widgets/NotificationHistory.qml @@ -104,7 +104,7 @@ Item { Text { anchors.centerIn: parent - text: "Notifications" + text: I18n.t("notifications.panel_title") font.family: Config.defaultFont font.pixelSize: Config.theme.fontSize font.weight: Font.Bold diff --git a/modules/widgets/dashboard/widgets/QuickControls.qml b/modules/widgets/dashboard/widgets/QuickControls.qml index 6886d4e8b..b3c7e0b53 100644 --- a/modules/widgets/dashboard/widgets/QuickControls.qml +++ b/modules/widgets/dashboard/widgets/QuickControls.qml @@ -69,7 +69,7 @@ StyledRect { return Icons.wifiHigh; } isActive: NetworkService.wifiEnabled || root.expandedPanel === 0 - tooltipText: NetworkService.wifiEnabled ? "Wi-Fi: On" : "Wi-Fi: Off" + tooltipText: NetworkService.wifiEnabled ? I18n.t("wifi.tooltip_on") : I18n.t("wifi.tooltip_off") onClicked: NetworkService.toggleWifi() onRightClicked: root.togglePanel(0) onLongPressed: root.togglePanel(0) @@ -88,10 +88,10 @@ StyledRect { isActive: BluetoothService.enabled || root.expandedPanel === 1 tooltipText: { if (!BluetoothService.enabled) - return "Bluetooth: Off"; + return I18n.t("controls.bluetooth_off"); if (BluetoothService.connected) - return "Bluetooth: Connected"; - return "Bluetooth: On"; + return I18n.t("controls.bluetooth_connected"); + return I18n.t("controls.bluetooth_on"); } onClicked: BluetoothService.toggle() onRightClicked: root.togglePanel(1) @@ -103,7 +103,7 @@ StyledRect { Layout.preferredHeight: 48 iconName: Icons.nightLight isActive: NightLightService.active - tooltipText: NightLightService.active ? "Night Light: On" : "Night Light: Off" + tooltipText: NightLightService.active ? I18n.t("controls.night_light_on") : I18n.t("controls.night_light_off") onClicked: NightLightService.toggle() } @@ -112,7 +112,7 @@ StyledRect { Layout.preferredHeight: 48 iconName: Icons.caffeine isActive: CaffeineService.inhibit - tooltipText: CaffeineService.inhibit ? "Caffeine: On" : "Caffeine: Off" + tooltipText: CaffeineService.inhibit ? I18n.t("controls.caffeine_on") : I18n.t("controls.caffeine_off") onClicked: CaffeineService.toggleInhibit() } @@ -121,7 +121,7 @@ StyledRect { Layout.preferredHeight: 48 iconName: Icons.gameMode isActive: GameModeService.toggled - tooltipText: GameModeService.toggled ? "Game Mode: On" : "Game Mode: Off" + tooltipText: GameModeService.toggled ? I18n.t("controls.game_mode_on") : I18n.t("controls.game_mode_off") onClicked: GameModeService.toggle() } } diff --git a/modules/widgets/dashboard/widgets/calendar/Calendar.qml b/modules/widgets/dashboard/widgets/calendar/Calendar.qml index 085d69302..869cabfc9 100644 --- a/modules/widgets/dashboard/widgets/calendar/Calendar.qml +++ b/modules/widgets/dashboard/widgets/calendar/Calendar.qml @@ -2,6 +2,7 @@ import QtQuick import QtQuick.Layouts import qs.modules.theme import qs.modules.components +import qs.modules.services import qs.config import "layout.js" as CalendarLayout @@ -20,13 +21,13 @@ Item { return (now.getDay() + 6) % 7; } - // Helper function to get localized day abbreviation function getDayAbbrev(dayIndex) { - // Create a date for a known Monday (e.g., 2024-01-01 was a Monday) - var d = new Date(2024, 0, 1 + dayIndex); - var dayName = d.toLocaleDateString(Qt.locale(), "ddd"); - // Capitalize first letter and limit to 2 chars - return (dayName.charAt(0).toUpperCase() + dayName.slice(1, 2)).replace(".", ""); + var keys = [ + "calendar.day.mon", "calendar.day.tue", "calendar.day.wed", + "calendar.day.thu", "calendar.day.fri", "calendar.day.sat", + "calendar.day.sun" + ]; + return I18n.t(keys[dayIndex]); } ColumnLayout { @@ -60,7 +61,17 @@ Item { Text { anchors.centerIn: parent - text: viewingDate.toLocaleDateString(Qt.locale(), "MMMM yyyy") + text: { + var monthKeys = [ + "calendar.month.january", "calendar.month.february", + "calendar.month.march", "calendar.month.april", + "calendar.month.may", "calendar.month.june", + "calendar.month.july", "calendar.month.august", + "calendar.month.september", "calendar.month.october", + "calendar.month.november", "calendar.month.december" + ]; + return I18n.t(monthKeys[viewingDate.getMonth()]) + " " + viewingDate.getFullYear(); + } font.family: Config.defaultFont font.pixelSize: Config.theme.fontSize font.weight: Font.Bold diff --git a/modules/widgets/defaultview/CompactPlayer.qml b/modules/widgets/defaultview/CompactPlayer.qml index 265b87e82..f4255e66c 100644 --- a/modules/widgets/defaultview/CompactPlayer.qml +++ b/modules/widgets/defaultview/CompactPlayer.qml @@ -75,13 +75,13 @@ Item { readonly property string noMediaText: { const displayType = Config.notch.noMediaDisplay ?? "userHost"; if (displayType === "userHost") return userHostText; - if (displayType === "compositor") return "AxctlService"; - return Config.notch.customText ?? "Ambxst"; + if (displayType === "compositor") return I18n.t("notch.compositor"); + return Config.notch.customText ?? I18n.t("notch.ambxst"); } readonly property string displayedTitle: { if (player) { - return (player.trackArtist ? player.trackArtist + " - " : "") + (player.trackTitle || "Unknown"); + return (player.trackArtist ? player.trackArtist + " - " : "") + (player.trackTitle || I18n.t("player.unknown")); } return focusedTitle || noMediaText; } @@ -644,7 +644,7 @@ Item { } Text { - text: playerItem.modelData.trackTitle || playerItem.modelData.identity || "Unknown Player" + text: playerItem.modelData.trackTitle || playerItem.modelData.identity || I18n.t("player.unknown_player") font.family: Styling.defaultFont font.pixelSize: Styling.fontSize(0) color: playerItem.item diff --git a/modules/widgets/launcher/LauncherView.qml b/modules/widgets/launcher/LauncherView.qml index 9af6e933f..0f9a071d3 100644 --- a/modules/widgets/launcher/LauncherView.qml +++ b/modules/widgets/launcher/LauncherView.qml @@ -398,7 +398,7 @@ Rectangle { width: parent.width anchors.top: parent.top text: GlobalStates.launcherSearchText - placeholderText: "Search applications..." + placeholderText: I18n.t("launcher.search") iconText: "" onSearchTextChanged: text => { @@ -846,7 +846,7 @@ Rectangle { boundsBehavior: Flickable.StopAtBounds model: [ { - text: "Launch", + text: I18n.t("launcher.launch"), icon: Icons.launch, highlightColor: Styling.srItem("overprimary"), textColor: Styling.srItem("primary"), @@ -856,7 +856,7 @@ Rectangle { } }, { - text: TaskbarApps.isPinned(appId) ? "Unpin from Dock" : "Pin to Dock", + text: TaskbarApps.isPinned(appId) ? I18n.t("launcher.unpin_from_dock") : I18n.t("launcher.pin_to_dock"), icon: TaskbarApps.isPinned(appId) ? Icons.unpin : Icons.pin, highlightColor: TaskbarApps.isPinned(appId) ? Colors.error : Colors.tertiary, textColor: TaskbarApps.isPinned(appId) ? Styling.srItem("error") : Styling.srItem("tertiary"), @@ -866,7 +866,7 @@ Rectangle { } }, { - text: "Create Shortcut", + text: I18n.t("launcher.create_shortcut"), icon: Icons.shortcut, highlightColor: Colors.secondary, textColor: Styling.srItem("secondary"), diff --git a/modules/widgets/overview/OverviewButton.qml b/modules/widgets/overview/OverviewButton.qml index 2e9218dc4..840388cbc 100644 --- a/modules/widgets/overview/OverviewButton.qml +++ b/modules/widgets/overview/OverviewButton.qml @@ -7,7 +7,7 @@ import qs.modules.theme ToggleButton { buttonIcon: Icons.overview - tooltipText: "Open Window Overview" + tooltipText: I18n.t("bar.tooltip.overview") onToggle: function () { if (GlobalStates.overviewOpen) { diff --git a/modules/widgets/overview/OverviewPopup.qml b/modules/widgets/overview/OverviewPopup.qml index 6ad805575..ea23135eb 100644 --- a/modules/widgets/overview/OverviewPopup.qml +++ b/modules/widgets/overview/OverviewPopup.qml @@ -159,7 +159,7 @@ PanelWindow { Layout.alignment: Qt.AlignVCenter variant: "common" - placeholderText: qsTr("Search windows...") + placeholderText: I18n.t("overview.search") handleTabNavigation: true clearOnEscape: false diff --git a/modules/widgets/powermenu/PowerButton.qml b/modules/widgets/powermenu/PowerButton.qml index 119ffacf1..b4c3b2ae0 100644 --- a/modules/widgets/powermenu/PowerButton.qml +++ b/modules/widgets/powermenu/PowerButton.qml @@ -6,7 +6,7 @@ import qs.modules.services ToggleButton { id: powerButton buttonIcon: Icons.shutdown - tooltipText: "Power Menu" + tooltipText: I18n.t("bar.tooltip.powermenu") onToggle: function () { if (Visibilities.currentActiveModule === "powermenu") { Visibilities.setActiveModule(""); diff --git a/modules/widgets/powermenu/PowerMenu.qml b/modules/widgets/powermenu/PowerMenu.qml index ad0af53db..a03eed505 100644 --- a/modules/widgets/powermenu/PowerMenu.qml +++ b/modules/widgets/powermenu/PowerMenu.qml @@ -26,32 +26,32 @@ ActionGrid { actions: [ { icon: Icons.lock, - tooltip: "Lock Session", + tooltip: I18n.t("powermenu.lock_session"), command: "loginctl lock-session" }, { icon: Icons.suspend, - tooltip: "Suspend", + tooltip: I18n.t("powermenu.suspend"), command: "systemctl suspend" }, { icon: Icons.hibernate, - tooltip: "Hibernate", + tooltip: I18n.t("powermenu.hibernate"), command: "systemctl hibernate" }, { icon: Icons.logout, - tooltip: "Exit AxctlService", + tooltip: I18n.t("powermenu.exit_axctl"), command: "axctl system exit" }, { icon: Icons.reboot, - tooltip: "Reboot", + tooltip: I18n.t("powermenu.reboot"), command: "systemctl reboot" }, { icon: Icons.shutdown, - tooltip: "Power Off", + tooltip: I18n.t("powermenu.power_off"), command: "systemctl poweroff" } ] diff --git a/modules/widgets/presets/PresetsButton.qml b/modules/widgets/presets/PresetsButton.qml index af0a83afe..a633aec46 100644 --- a/modules/widgets/presets/PresetsButton.qml +++ b/modules/widgets/presets/PresetsButton.qml @@ -7,7 +7,7 @@ import qs.modules.theme ToggleButton { buttonIcon: Icons.magicWand - tooltipText: "Open Presets Manager" + tooltipText: I18n.t("bar.tooltip.presets") onToggle: function () { if (GlobalStates.presetsOpen) { diff --git a/modules/widgets/presets/PresetsTab.qml b/modules/widgets/presets/PresetsTab.qml index 03d42de46..2f466f5b8 100644 --- a/modules/widgets/presets/PresetsTab.qml +++ b/modules/widgets/presets/PresetsTab.qml @@ -66,7 +66,7 @@ Item { if (preset.authorUrl && preset.authorUrl !== "") { options.push({ - text: "Visit Author", + text: I18n.t("presets.visit_author"), icon: Icons.globe, highlightColor: Colors.primary, textColor: Styling.srItem("primary"), @@ -78,7 +78,7 @@ Item { if (!preset.isOfficial) { options.push({ - text: "Rename", + text: I18n.t("common.rename"), icon: Icons.edit, highlightColor: Colors.secondary, textColor: Styling.srItem("secondary"), @@ -90,7 +90,7 @@ Item { } options.push({ - text: "Update", + text: I18n.t("presets.update"), icon: Icons.arrowCounterClockwise, highlightColor: Colors.tertiary, textColor: Styling.srItem("tertiary"), @@ -102,7 +102,7 @@ Item { if (!preset.isOfficial) { options.push({ - text: "Delete", + text: I18n.t("common.delete"), icon: Icons.trash, highlightColor: Colors.error, textColor: Styling.srItem("error"), @@ -191,7 +191,7 @@ Item { function updateFilteredPresets() { var newFilteredPresets = []; - var createButtonText = "Create new preset"; + var createButtonText = I18n.t("presets.create_new"); var isCreateSpecific = false; var presetNameToCreate = ""; @@ -207,7 +207,7 @@ Item { }); if (!exactMatch && searchText.length > 0) { - createButtonText = `Create preset "${searchText}"`; + createButtonText = I18n.t("presets.create_specific", searchText); isCreateSpecific = true; presetNameToCreate = searchText; } @@ -427,7 +427,7 @@ Item { Layout.fillWidth: true Layout.preferredHeight: 48 text: root.searchText - placeholderText: "Search or create preset..." + placeholderText: I18n.t("presets.search") onSearchTextChanged: text => { root.searchText = text; @@ -1225,9 +1225,9 @@ Item { Text { text: { if (isInDeleteMode && !modelData.isCreateButton && !modelData.isCreateSpecificButton) { - return `Delete "${root.presetToDelete}"?`; + return I18n.t("presets.confirm_delete", root.presetToDelete); } else if (isInUpdateMode && !modelData.isCreateButton && !modelData.isCreateSpecificButton) { - return `Update "${root.presetToUpdate}"`; + return I18n.t("presets.update_title", root.presetToUpdate); } else { return modelData.name; } @@ -1290,9 +1290,9 @@ Item { visible: !isInRenameMode && !isInUpdateMode text: { if (modelData.isCreateButton || modelData.isCreateSpecificButton) { - return "Tap to create"; + return I18n.t("presets.tap_to_create"); } - return modelData.author ? modelData.author : "Unknown"; + return modelData.author ? modelData.author : I18n.t("presets.unknown_author"); } color: root.selectedIndex === index ? Styling.srItem("primary") : Colors.outline opacity: 0.7 @@ -1311,7 +1311,7 @@ Item { Text { anchors.centerIn: parent - text: "OFFICIAL" + text: I18n.t("presets.official") font.family: Config.theme.font font.pixelSize: 10 font.weight: Font.Bold @@ -1330,7 +1330,7 @@ Item { Text { anchors.centerIn: parent - text: "ACTIVE" + text: I18n.t("presets.active") font.family: Config.theme.font font.pixelSize: 10 font.weight: Font.Bold @@ -1556,7 +1556,7 @@ Item { } Text { - text: `Update "${root.presetToUpdate}"` + text: I18n.t("presets.update_title", root.presetToUpdate) font.family: Config.theme.font font.pixelSize: Config.theme.fontSize + 2 font.weight: Font.Bold @@ -1566,7 +1566,7 @@ Item { } Text { - text: "Select config files to update:" + text: I18n.t("presets.select_config_files") color: Colors.outline font.family: Config.theme.font font.pixelSize: Styling.fontSize(-1) @@ -1651,7 +1651,7 @@ Item { Text { anchors.centerIn: parent - text: "Cancel" + text: I18n.t("common.cancel") color: Colors.overSurface font.family: Config.theme.font } @@ -1671,7 +1671,7 @@ Item { Text { anchors.centerIn: parent - text: `Update (${root.selectedConfigFiles.length})` + text: I18n.t("presets.update") + ` (${root.selectedConfigFiles.length})` color: Styling.srItem("tertiary") font.family: Config.theme.font font.weight: Font.Bold diff --git a/modules/widgets/tools/ToolsMenu.qml b/modules/widgets/tools/ToolsMenu.qml index c0b99ab13..66457c01c 100644 --- a/modules/widgets/tools/ToolsMenu.qml +++ b/modules/widgets/tools/ToolsMenu.qml @@ -16,7 +16,7 @@ ActionGrid { id: recordAction property string icon: ScreenRecorder.isRecording ? Icons.stop : Icons.recordScreen property string text: ScreenRecorder.isRecording ? ScreenRecorder.duration : "" - property string tooltip: ScreenRecorder.isRecording ? "Stop Recording" : "Screen Recorder" + property string tooltip: ScreenRecorder.isRecording ? I18n.t("tools.screenrecord_stop") : I18n.t("tools.screenrecord_start") property string command: "" property string variant: ScreenRecorder.isRecording ? "error" : "primary" property string type: "button" @@ -30,12 +30,12 @@ ActionGrid { actions: [ { icon: Icons.camera, - tooltip: "Screenshot", + tooltip: I18n.t("tools.screenshot"), command: "" }, { icon: Icons.screenshots, - tooltip: "Open Screenshots", + tooltip: I18n.t("tools.screenshot_directory"), command: "" }, { @@ -44,7 +44,7 @@ ActionGrid { recordAction, { icon: Icons.recordings, - tooltip: "Open Recordings", + tooltip: I18n.t("tools.screenrecord_directory"), command: "" }, { @@ -52,27 +52,27 @@ ActionGrid { }, { icon: Icons.picker, - tooltip: "Color Picker", + tooltip: I18n.t("tools.color_picker"), command: "" }, { icon: Icons.textT, - tooltip: "OCR", + tooltip: I18n.t("tools.ocr"), command: "" }, { icon: Icons.qrCode, - tooltip: "QR Code", + tooltip: I18n.t("tools.qr"), command: "" }, { icon: Icons.google, - tooltip: "Google Lens", + tooltip: I18n.t("tools.google_lens"), command: "" }, { icon: GlobalStates.mirrorWindowVisible ? Icons.webcamSlash : Icons.webcam, - tooltip: "Mirror", + tooltip: I18n.t("tools.mirror"), command: "" } ] @@ -98,18 +98,18 @@ ActionGrid { onActionTriggered: action => { console.log("Tools action triggered:", action.tooltip); - if (action.tooltip === "Screenshot") { + if (action.tooltip === I18n.t("tools.screenshot")) { Screenshot.initialize(); GlobalStates.screenshotToolVisible = true; root.itemSelected(); - } else if (action.tooltip === "Screen Recorder") { + } else if (action.tooltip === I18n.t("tools.screenrecord_start")) { ScreenRecorder.initialize(); GlobalStates.screenRecordToolVisible = true; root.itemSelected(); - } else if (action.tooltip === "Stop Recording") { + } else if (action.tooltip === I18n.t("tools.screenrecord_stop")) { ScreenRecorder.toggleRecording(); root.itemSelected(); - } else if (action.tooltip === "Open Screenshots") { + } else if (action.tooltip === I18n.t("tools.screenshot_directory")) { // Usamos xdg-user-dir en el comando bash para respetar las rutas del sistema var cmd = "dir=\"$(xdg-user-dir PICTURES)/Screenshots\"; mkdir -p \"$dir\"; nohup xdg-open \"$dir\" > /dev/null 2>&1 &"; @@ -117,7 +117,7 @@ ActionGrid { openFolderProc.running = true; root.itemSelected(); - } else if (action.tooltip === "Open Recordings") { + } else if (action.tooltip === I18n.t("tools.screenrecord_directory")) { // Usamos xdg-user-dir para videos, manteniendo la subcarpeta Recordings var cmd = "dir=\"$(xdg-user-dir VIDEOS)/Recordings\"; mkdir -p \"$dir\"; nohup xdg-open \"$dir\" > /dev/null 2>&1 &"; @@ -125,13 +125,13 @@ ActionGrid { openFolderProc.running = true; root.itemSelected(); - } else if (action.tooltip === "Color Picker") { + } else if (action.tooltip === I18n.t("tools.color_picker")) { var scriptPath = Qt.resolvedUrl("../../../scripts/colorpicker.py").toString().replace("file://", ""); // Run detached so it survives when the menu closes colorPickerProc.command = ["bash", "-c", "nohup python3 \"" + scriptPath + "\" > /dev/null 2>&1 &"]; colorPickerProc.running = true; root.itemSelected(); - } else if (action.tooltip === "OCR") { + } else if (action.tooltip === I18n.t("tools.ocr")) { var scriptPath = Qt.resolvedUrl("../../../scripts/ocr.sh").toString().replace("file://", ""); // Build languages string from Config @@ -146,6 +146,7 @@ ActionGrid { if (ocrConfig.chi_sim === true) langs.push("chi_sim"); if (ocrConfig.chi_tra === true) langs.push("chi_tra"); if (ocrConfig.kor === true) langs.push("kor"); + if (ocrConfig.rus === true) langs.push("rus"); } else { langs = ["eng", "spa"]; } @@ -156,16 +157,16 @@ ActionGrid { ocrProc.command = ["bash", "-c", "nohup \"" + scriptPath + "\" \"" + langString + "\" > /dev/null 2>&1 &"]; ocrProc.running = true; root.itemSelected(); - } else if (action.tooltip === "QR Code") { + } else if (action.tooltip === I18n.t("tools.qr")) { var scriptPath = Qt.resolvedUrl("../../../scripts/qr_scan.sh").toString().replace("file://", ""); qrProc.command = ["bash", "-c", "nohup \"" + scriptPath + "\" > /dev/null 2>&1 &"]; qrProc.running = true; root.itemSelected(); - } else if (action.tooltip === "Google Lens") { + } else if (action.tooltip === I18n.t("tools.google_lens")) { Screenshot.captureMode = "lens"; GlobalStates.screenshotToolVisible = true; root.itemSelected(); - } else if (action.tooltip === "Mirror") { + } else if (action.tooltip === I18n.t("tools.mirror")) { GlobalStates.mirrorWindowVisible = !GlobalStates.mirrorWindowVisible; } } diff --git a/translations/en.json b/translations/en.json new file mode 100644 index 000000000..c7b484193 --- /dev/null +++ b/translations/en.json @@ -0,0 +1,639 @@ +{ + "_meta.direction": "ltr", + "ai.approve": "Approve", + "ai.ask_or_help": "Ask AI or type /help...", + "ai.chat_history": "Chat History", + "ai.cmd_set_api_key": "Set API key", + "ai.cmd_set_system_prompt": "Set system prompt", + "ai.cmd_show_help": "Show help", + "ai.cmd_start_new_chat": "Start new chat", + "ai.cmd_switch_model": "Switch AI model", + "ai.command_approved": "Command Approved", + "ai.command_rejected": "Command Rejected", + "ai.curl_placeholder": "curl -X POST...", + "ai.curl_placeholders": "Placeholders: {{ENDPOINT}}, {{API_KEY}}, {{BODY_PATH}}", + "ai.custom_curl": "Custom cURL Template", + "ai.custom_endpoint": "Custom Endpoint", + "ai.custom_provider": "Custom Provider", + "ai.custom_provider_key": "Custom Provider API Key", + "ai.endpoint_placeholder": "e.g. https://...", + "ai.enter_api_key": "Enter API Key...", + "ai.hello_user": "Hello, %1.", + "ai.message": "Message AI...", + "ai.panel_title": "AI & API Keys", + "ai.refresh_models": "Refresh?", + "ai.reject": "Reject", + "ai.run_command": "Run Command", + "ai.search_models": "Search models...", + "bar.tooltip.audio_switcher": "Audio Device Switcher", + "bar.tooltip.controls": "Audio & Brightness Controls", + "bar.tooltip.keyboard_layout": "Keyboard Layout", + "bar.tooltip.launcher": "Open Launcher", + "bar.tooltip.layout": "Layout: %1", + "bar.tooltip.overview": "Open Window Overview", + "bar.tooltip.pin_bar": "Pin bar", + "bar.tooltip.pin_dock": "Pin dock", + "bar.tooltip.powermenu": "Power Menu", + "bar.tooltip.presets": "Open Presets Manager", + "bar.tooltip.tools": "Tools", + "bar.tooltip.unpin_bar": "Unpin bar", + "bar.tooltip.unpin_dock": "Unpin dock", + "battery.charging": "Charging", + "battery.full": "Full", + "battery.full_in": "Full in %1", + "battery.fully_charged": "Fully charged", + "battery.on_battery": "On battery", + "battery.power_profile": "Power Profile: %1", + "battery.remaining": "%1 remaining", + "battery.status": "Battery: %1%", + "binds.action": "Action", + "binds.add_action": "Add another action", + "binds.add_key": "Add another key", + "binds.add_keybind": "Add keybind", + "binds.ambxst": "Ambxst", + "binds.custom": "Custom", + "binds.delete_keybind": "Delete keybind", + "binds.key_combination": "Key Combination", + "binds.key_configured": "Key Configured", + "binds.key_placeholder": "e.g. R, TAB, ESCAPE, mouse:272...", + "binds.keybind_name_placeholder": "e.g. Open Terminal, Switch to Workspace 1...", + "binds.layouts_axctl": "Layouts (AxctlService)", + "binds.layouts_hint": "Leave all unselected to work in all layouts", + "binds.legacy_dispatcher": "Legacy Dispatcher", + "binds.name_optional": "Name (optional)", + "binds.not_configured": "Not Configured", + "binds.reload_binds": "Reload binds", + "bluetooth.connect": "Connect", + "bluetooth.connected": "Connected", + "bluetooth.connecting": "Connecting...", + "bluetooth.disabled": "Bluetooth is disabled", + "bluetooth.disconnect": "Disconnect", + "bluetooth.forget": "Forget", + "bluetooth.no_devices": "No devices found", + "bluetooth.not_paired": "Not paired", + "bluetooth.open_manager": "Open Blueman", + "bluetooth.paired": "Paired", + "bluetooth.scan": "Scan for devices", + "calendar.day.fri": "Fr", + "calendar.day.mon": "Mo", + "calendar.day.sat": "Sa", + "calendar.day.sun": "Su", + "calendar.day.thu": "Th", + "calendar.day.tue": "Tu", + "calendar.day.wed": "We", + "calendar.day_full.friday": "Friday", + "calendar.day_full.monday": "Monday", + "calendar.day_full.saturday": "Saturday", + "calendar.day_full.sunday": "Sunday", + "calendar.day_full.thursday": "Thursday", + "calendar.day_full.tuesday": "Tuesday", + "calendar.day_full.wednesday": "Wednesday", + "calendar.month.april": "April", + "calendar.month.august": "August", + "calendar.month.december": "December", + "calendar.month.february": "February", + "calendar.month.january": "January", + "calendar.month.july": "July", + "calendar.month.june": "June", + "calendar.month.march": "March", + "calendar.month.may": "May", + "calendar.month.november": "November", + "calendar.month.october": "October", + "calendar.month.september": "September", + "clipboard.alias": "Alias", + "clipboard.checksum": "Checksum", + "clipboard.clear_all_confirm": "Clear all?", + "clipboard.copy_to_start": "Copy to start", + "clipboard.copying": "Copying!", + "clipboard.date": "Date", + "clipboard.days_ago": "%1 day(s) ago", + "clipboard.hours_ago": "%1 hour(s) ago", + "clipboard.just_now": "Just now", + "clipboard.link": "Link", + "clipboard.loading_preview": "Loading preview...", + "clipboard.mime_type": "MIME Type", + "clipboard.min_ago": "%1 min ago", + "clipboard.no_history": "No clipboard history", + "clipboard.pin": "Pin", + "clipboard.search": "Search in clipboard...", + "clipboard.size": "Size", + "clipboard.unpin": "Unpin", + "color_picker.custom": "Custom", + "color_picker.picker": "Color picker", + "common.active": "Active", + "common.add": "Add", + "common.apply_changes": "Apply changes", + "common.auto": "Auto", + "common.back": "Back", + "common.bottom": "Bottom", + "common.cancel": "Cancel", + "common.clear": "Clear", + "common.close": "Close", + "common.coming_soon": "Coming Soon", + "common.copied": "Copied!", + "common.copy": "Copy", + "common.default": "Default", + "common.delete": "Delete", + "common.disabled": "Disabled", + "common.discard_changes": "Discard changes", + "common.edit": "Edit", + "common.enabled": "Enabled", + "common.error": "Error", + "common.left": "Left", + "common.none": "None", + "common.off": "Off", + "common.on": "On", + "common.open": "Open", + "common.remove": "Remove", + "common.rename": "Rename", + "common.reset_default": "Reset to default", + "common.right": "Right", + "common.save": "Save", + "common.save_close": "Save & Close", + "common.search": "Search...", + "common.top": "Top", + "common.unsaved_changes": "Unsaved changes", + "compositor.active_border": "Active Border", + "compositor.apply": "Apply changes", + "compositor.back": "Back", + "compositor.blur": "Blur", + "compositor.border_angle": "Border Angle", + "compositor.colors": "Colors", + "compositor.coming_soon_text": "These are upcoming features. Settings here will expand as compositor integration improves.", + "compositor.discard": "Discard changes", + "compositor.gaps_in": "Gaps In", + "compositor.gaps_out": "Gaps Out", + "compositor.general": "General", + "compositor.ignore_window": "Ignore Window", + "compositor.inactive_angle": "Inactive Angle", + "compositor.inactive_border": "Inactive Border", + "compositor.layout.dwindle": "Dwindle", + "compositor.layout.master": "Master", + "compositor.layout.scrolling": "Scrolling", + "compositor.offset_x": "Offset X", + "compositor.offset_y": "Offset Y", + "compositor.opacity": "Opacity", + "compositor.right_click_remove": "Right click to remove", + "compositor.rounding": "Rounding", + "compositor.shadows": "Shadows", + "compositor.sharp": "Sharp", + "compositor.sync_border_color": "Sync Border Color", + "compositor.sync_border_size": "Sync Border Size", + "compositor.sync_rounding": "Sync Rounding", + "controls.bluetooth_connected": "Bluetooth: Connected", + "controls.bluetooth_off": "Bluetooth: Off", + "controls.bluetooth_on": "Bluetooth: On", + "controls.caffeine_off": "Caffeine: Off", + "controls.caffeine_on": "Caffeine: On", + "controls.game_mode_off": "Game Mode: Off", + "controls.game_mode_on": "Game Mode: On", + "controls.night_light_off": "Night Light: Off", + "controls.night_light_on": "Night Light: On", + "controls.volume_protection": "Volume protection active", + "desktop.delete": "Delete", + "desktop.open": "Open", + "dock.tooltip.pin_dock": "Pin dock", + "dock.tooltip.unpin_dock": "Unpin dock", + "effects.bypassed": "Bypassed", + "effects.input_presets": "Input Presets", + "effects.not_installed": "EasyEffects not installed", + "effects.open": "Open EasyEffects", + "effects.output_presets": "Output Presets", + "effects.refresh": "Refresh", + "effects.title": "EasyEffects", + "emoji.clear_recent": "Clear recent?", + "emoji.search": "Search emojis...", + "idle.add_listener": "Add Listener", + "idle.after_sleep": "Command after sleep", + "idle.after_sleep_label": "After Sleep", + "idle.before_sleep": "Command before sleep", + "idle.before_sleep_label": "Before Sleep", + "idle.listener_n": "Listener %1", + "idle.listeners": "Listeners", + "idle.lock_cmd": "Command to lock screen", + "idle.lock_cmd_label": "Lock Cmd", + "idle.on_resume": "On Resume", + "idle.on_timeout": "On Timeout", + "idle.timeout": "Timeout (s)", + "language.auto": "Auto", + "language.auto_detected": "Auto (%1)", + "launcher.create_shortcut": "Create Shortcut", + "launcher.launch": "Launch", + "launcher.pin_to_dock": "Pin to Dock", + "launcher.search": "Search applications...", + "launcher.unpin_from_dock": "Unpin from Dock", + "lockscreen.loading": "Loading desktop...", + "mixer.input": "Input", + "mixer.input_device": "Input Device", + "mixer.no_apps": "No applications using audio", + "mixer.open_pavucontrol": "Open PipeWire Volume Control", + "mixer.output": "Output", + "mixer.output_device": "Output Device", + "mixer.protection_disabled": "Volume protection disabled", + "mixer.protection_enabled": "Volume protection enabled", + "mixer.title": "Sound", + "mixer.volume_mixer": "Volume Mixer", + "notch.ambxst": "Ambxst", + "notch.compositor": "Compositor", + "notes.days_ago": "%1 days ago", + "notes.markdown": "Markdown", + "notes.rich_text": "Rich Text", + "notes.search": "Search or create note...", + "notes.select_or_create": "Select or create a note", + "notes.start_typing": "Start typing...", + "notes.write_markdown": "Write markdown here...", + "notifications.clear_all": "Clear all", + "notifications.no_notifications": "No notifications", + "notifications.now": "Now", + "notifications.panel_title": "Notifications", + "notifications.yesterday": "Yesterday", + "overview.search": "Search windows...", + "performance.blur_transition": "Blur Transition", + "performance.dashboard_persist": "Persist Dashboard Tabs", + "performance.rotate_cover": "Rotate Cover Art", + "performance.wavy_line": "Wavy Line", + "performance.window_preview": "Window Preview", + "player.enjoy_silence": "Enjoy the silence", + "player.nothing_playing": "Nothing Playing", + "player.unknown": "Unknown", + "player.unknown_player": "Unknown Player", + "pomodoro.minus_1m": "-1m", + "pomodoro.pause": "PAUSE", + "pomodoro.plus_1m": "+1m", + "pomodoro.rest_session": "Rest Session", + "pomodoro.resume": "RESUME", + "pomodoro.start_rest": "START REST", + "pomodoro.start_work": "START WORK", + "pomodoro.stop_alarm": "STOP ALARM", + "pomodoro.sync_spotify": "Sync Spotify", + "pomodoro.work_session": "Work Session", + "power_profile.balanced": "Balanced", + "power_profile.performance": "Performance", + "power_profile.power_save": "Power Save", + "powermenu.exit_axctl": "Exit AxctlService", + "powermenu.hibernate": "Hibernate", + "powermenu.lock_session": "Lock Session", + "powermenu.power_off": "Power Off", + "powermenu.reboot": "Reboot", + "powermenu.suspend": "Suspend", + "presets.active": "ACTIVE", + "presets.confirm_delete": "Delete \"%1\"?", + "presets.create_new": "Create new preset", + "presets.create_specific": "Create preset \"%1\"", + "presets.no_presets": "No presets configured", + "presets.official": "OFFICIAL", + "presets.search": "Search or create preset...", + "presets.select_config_files": "Select config files to update:", + "presets.tap_to_create": "Tap to create", + "presets.unknown_author": "Unknown", + "presets.update": "Update", + "presets.update_title": "Update \"%1\"", + "presets.visit_author": "Visit Author", + "screenshot.region": "Region", + "screenshot.screen": "Screen", + "screenshot.window": "Window", + "settings.ai": "AI", + "settings.ambxst": "Ambxst", + "settings.audio_effects": "Audio Effects", + "settings.audio_mixer": "Audio Mixer", + "settings.binds": "Binds", + "settings.binds.assistant": "Assistant Keybind", + "settings.binds.clipboard": "Clipboard Keybind", + "settings.binds.dashboard": "Dashboard Keybind", + "settings.binds.emoji": "Emoji Keybind", + "settings.binds.key_bindings": "Key Bindings", + "settings.binds.launcher": "Launcher Keybind", + "settings.binds.lens": "Lens Keybind", + "settings.binds.lockscreen": "Lockscreen Keybind", + "settings.binds.notes": "Notes Keybind", + "settings.binds.overview": "Overview Keybind", + "settings.binds.powermenu": "Powermenu Keybind", + "settings.binds.quit": "Quit Keybind", + "settings.binds.reload": "Reload Keybind", + "settings.binds.screenrecord": "Screenrecord Keybind", + "settings.binds.screenshot": "Screenshot Keybind", + "settings.binds.settings": "Settings Keybind", + "settings.binds.tmux": "Tmux Keybind", + "settings.binds.tools": "Tools Keybind", + "settings.binds.wallpapers": "Wallpapers Keybind", + "settings.bluetooth": "Bluetooth", + "settings.compositor": "Compositor", + "settings.compositor.axctl": "AxctlService", + "settings.compositor.blur_brightness": "Blur Brightness", + "settings.compositor.blur_contrast": "Blur Contrast", + "settings.compositor.blur_enabled": "Blur Enabled", + "settings.compositor.blur_ignore_opacity": "Blur Ignore Opacity", + "settings.compositor.blur_ignorealpha": "Blur Ignorealpha", + "settings.compositor.blur_ignorealpha_value": "Blur Ignorealpha Value", + "settings.compositor.blur_new_optimizations": "Blur New Optimizations", + "settings.compositor.blur_noise": "Blur Noise", + "settings.compositor.blur_passes": "Blur Passes", + "settings.compositor.blur_size": "Blur Size", + "settings.compositor.blur_vibrancy": "Blur Vibrancy", + "settings.compositor.blur_xray": "Blur Xray", + "settings.compositor.border_colors": "Border Colors", + "settings.compositor.border_size": "Border Size", + "settings.compositor.shadow_offset": "Shadow Offset", + "settings.compositor.shadow_power": "Shadow Power", + "settings.compositor.shadow_range": "Shadow Range", + "settings.compositor.shadow_scale": "Shadow Scale", + "settings.compositor.shadows_enabled": "Shadows Enabled", + "settings.compositor.sync_shadow_color": "Sync Shadow Color", + "settings.compositor.sync_shadow_opacity": "Sync Shadow Opacity", + "settings.compositor.window_gaps": "Window Gaps", + "settings.effects": "Effects", + "settings.mixer": "Mixer", + "settings.network": "Network", + "settings.shell.always_show_numbers": "Always Show Numbers", + "settings.shell.available_on_fullscreen": "Available on Fullscreen", + "settings.shell.bar": "Bar", + "settings.shell.bar_autohide": "Bar Auto-hide", + "settings.shell.bar_entry": "Bar", + "settings.shell.bar_position": "Bar Position", + "settings.shell.bar_screens": "Bar Screens", + "settings.shell.desktop": "Desktop", + "settings.shell.desktop_enabled": "Desktop Enabled", + "settings.shell.desktop_entry": "Desktop", + "settings.shell.desktop_icon_size": "Desktop Icon Size", + "settings.shell.desktop_text_color": "Desktop Text Color", + "settings.shell.desktop_vertical_spacing": "Desktop Vertical Spacing", + "settings.shell.dock": "Dock", + "settings.shell.dock_enabled": "Dock Enabled", + "settings.shell.dock_entry": "Dock", + "settings.shell.dock_height": "Dock Height", + "settings.shell.dock_hover_region_height": "Dock Hover Region Height", + "settings.shell.dock_icon_size": "Dock Icon Size", + "settings.shell.dock_margin": "Dock Margin", + "settings.shell.dock_mode": "Dock Mode", + "settings.shell.dock_pinned_on_startup": "Dock Pinned on Startup", + "settings.shell.dock_position": "Dock Position", + "settings.shell.dock_spacing": "Dock Spacing", + "settings.shell.dynamic_workspaces": "Dynamic Workspaces", + "settings.shell.firefox_player": "Firefox Player", + "settings.shell.frame": "Frame", + "settings.shell.hover_region_height": "Hover Region Height", + "settings.shell.hover_to_reveal": "Hover to Reveal", + "settings.shell.launcher_icon": "Launcher Icon", + "settings.shell.launcher_icon_full_tint": "Launcher Icon Full Tint", + "settings.shell.launcher_icon_size": "Launcher Icon Size", + "settings.shell.launcher_icon_tint": "Launcher Icon Tint", + "settings.shell.lockscreen": "Lockscreen", + "settings.shell.lockscreen_entry": "Lockscreen", + "settings.shell.notch": "Notch", + "settings.shell.notch_entry": "Notch", + "settings.shell.overview": "Overview", + "settings.shell.overview_columns": "Overview Columns", + "settings.shell.overview_entry": "Overview", + "settings.shell.overview_rows": "Overview Rows", + "settings.shell.overview_scale": "Overview Scale", + "settings.shell.overview_workspace_spacing": "Overview Workspace Spacing", + "settings.shell.pill_style": "Pill Style", + "settings.shell.pinned_on_startup": "Pinned on Startup", + "settings.shell.show_app_icons": "Show App Icons", + "settings.shell.show_numbers": "Show Numbers", + "settings.shell.show_overview_button": "Show Overview Button", + "settings.shell.show_pin_button": "Show Pin Button", + "settings.shell.show_running_indicators": "Show Running Indicators", + "settings.shell.sidebar": "Sidebar", + "settings.shell.system": "System", + "settings.shell.system_entry": "Shell System", + "settings.shell.workspaces": "Workspaces", + "settings.shell.workspaces_entry": "Workspaces", + "settings.shell.workspaces_shown": "Workspaces Shown", + "settings.system": "System", + "settings.system.after_sleep": "After Sleep", + "settings.system.before_sleep": "Before Sleep", + "settings.system.blur_transition": "Blur Transition", + "settings.system.clipboard_prefix": "Clipboard Prefix", + "settings.system.emoji_prefix": "Emoji Prefix", + "settings.system.idle": "Idle", + "settings.system.idle_listener": "Idle Listener", + "settings.system.idle_settings": "Idle Settings", + "settings.system.language": "Language", + "settings.system.lock_command": "Lock Command", + "settings.system.notes_prefix": "Notes Prefix", + "settings.system.performance": "Performance", + "settings.system.prefixes": "Prefixes", + "settings.system.prefixes_entry": "Prefixes", + "settings.system.resources": "System Resources", + "settings.system.system_resources": "System Resources", + "settings.system.temperature_unit": "Temperature Unit", + "settings.system.tmux_prefix": "Tmux Prefix", + "settings.system.wallpapers_prefix": "Wallpapers Prefix", + "settings.system.wavy_line": "Wavy Line", + "settings.system.weather": "Weather", + "settings.system.weather_location": "Weather Location", + "settings.system.window_preview": "Window Preview", + "settings.theme": "Theme", + "settings.theme.animation": "Animation", + "settings.theme.animation_duration": "Animation Duration", + "settings.theme.background_variant": "Background Variant", + "settings.theme.bar_bg_variant": "Bar BG Variant", + "settings.theme.color_border": "Color Border", + "settings.theme.color_opacity": "Color Opacity", + "settings.theme.color_scheme": "Color Scheme", + "settings.theme.color_variant": "Color Variant", + "settings.theme.colors": "Colors", + "settings.theme.duration": "Duration", + "settings.theme.editor": "Editor", + "settings.theme.enable_corners": "Enable Corners", + "settings.theme.fonts": "Fonts", + "settings.theme.general": "General", + "settings.theme.gradient_angle": "Gradient Angle", + "settings.theme.internal_bg_variant": "Internal BG Variant", + "settings.theme.mono_font": "Mono Font", + "settings.theme.pane_variant": "Pane Variant", + "settings.theme.popup_variant": "Popup Variant", + "settings.theme.roundness": "Roundness", + "settings.theme.shadow": "Shadow", + "settings.theme.shadow_blur": "Shadow Blur", + "settings.theme.shadow_offset": "Shadow Offset", + "settings.theme.shadow_opacity": "Shadow Opacity", + "settings.theme.tint_icons": "Tint Icons", + "settings.theme.ui_font": "UI Font", + "settings.theme.variant": "Variant", + "settings.theme.wallpapers": "Wallpapers", + "shell.autohide": "Auto-hide", + "shell.available_on_fullscreen": "Available on Fullscreen", + "shell.desktop.enabled": "Enabled", + "shell.desktop.icon_size": "Icon Size", + "shell.desktop.text_color": "Text Color", + "shell.desktop.vertical_spacing": "Vertical Spacing", + "shell.dock.enabled": "Enabled", + "shell.dock.floating": "Floating", + "shell.dock.height": "Height", + "shell.dock.hover_region": "Hover Region", + "shell.dock.icon_size": "Icon Size", + "shell.dock.integrated": "Integrated", + "shell.dock.island": "Island", + "shell.dock.keep_hidden": "Keep Hidden", + "shell.dock.margin": "Margin", + "shell.dock.spacing": "Spacing", + "shell.dock.theme": "Theme", + "shell.enable_firefox_player": "Enable Firefox Player", + "shell.excluded_sinks": "Excluded Audio Sinks", + "shell.frame.contain_bar": "Contain Bar", + "shell.frame.enabled": "Enabled", + "shell.frame.keep_bar_border": "Keep Bar Border", + "shell.frame.keep_bar_shadow": "Keep Bar Shadow", + "shell.frame.thickness": "Thickness", + "shell.hover_region_height": "Hover Region Height", + "shell.hover_reveal": "Hover to reveal", + "shell.hover_to_reveal": "Hover to Reveal", + "shell.launcher_icon": "Launcher Icon", + "shell.launcher_icon_full_tint": "Launcher Icon Full Tint", + "shell.launcher_icon_size": "Launcher Icon Size", + "shell.launcher_icon_tint": "Launcher Icon Tint", + "shell.lockscreen.position": "Position", + "shell.no_media_display": "No Media Display", + "shell.notch.compositor": "Compositor", + "shell.notch.custom_text": "Custom Text", + "shell.notch.disable_hover_expansion": "Disable Hover Expansion", + "shell.notch.enter_text": "Enter text...", + "shell.notch.keep_hidden": "Keep Hidden", + "shell.notch.user_host": "User@Host", + "shell.overview.columns": "Columns", + "shell.overview.rows": "Rows", + "shell.overview.scale": "Scale", + "shell.overview.workspace_spacing": "Workspace Spacing", + "shell.pill_style": "Pill Style", + "shell.pinned_on_startup": "Pinned on Startup", + "shell.position": "Position", + "shell.screens": "Screens", + "shell.screens_empty": "Empty = all screens", + "shell.shell": "Shell", + "shell.show_audio_switcher": "Show Audio Device Switcher", + "shell.show_keyboard_layout": "Show Keyboard Layout", + "shell.show_overview_button": "Show Overview Button", + "shell.show_pin_button": "Show Pin Button", + "shell.show_running_indicators": "Show Running Indicators", + "shell.sidebar.width": "Width", + "shell.squished": "Squished", + "shell.system.about_ambxst": "About Ambxst %1", + "shell.system.donate": "Donate ❤️", + "shell.system.ocr_chinese_simplified": "Chinese (Simplified)", + "shell.system.ocr_chinese_traditional": "Chinese (Traditional)", + "shell.system.ocr_english": "English", + "shell.system.ocr_japanese": "Japanese", + "shell.system.ocr_korean": "Korean", + "shell.system.ocr_languages": "OCR Languages", + "shell.system.ocr_latin": "Latin", + "shell.system.ocr_russian": "Russian", + "shell.system.ocr_spanish": "Spanish", + "shell.system.update_service": "Update Service", + "shell.use_12h_format": "Use 12h Format", + "shell.workspaces.always_show_numbers": "Always Show Numbers", + "shell.workspaces.dynamic": "Dynamic", + "shell.workspaces.show_app_icons": "Show App Icons", + "shell.workspaces.show_numbers": "Show Numbers", + "shell.workspaces.shown": "Shown", + "system.add_disk": "Add Disk", + "system.disk_path_placeholder": "e.g. /, /home...", + "system.performance.blur_transition_desc": "Animated blur when opening panels", + "system.performance.description": "Toggle visual effects to improve performance", + "system.performance.disable_cover_rotation": "Disable Cover Art Rotation", + "system.performance.disable_cover_rotation_desc": "Stop the vinyl disc from spinning", + "system.performance.wavy_line_desc": "Animated wavy line effect", + "system.performance.window_preview_desc": "Show window thumbnails in overview", + "system.prefixes.clipboard": "Clipboard", + "system.prefixes.description": "Keyboard shortcuts for quick actions in launcher", + "system.prefixes.emoji": "Emoji", + "system.prefixes.notes": "Notes", + "system.prefixes.tmux": "Tmux", + "system.prefixes.wallpapers": "Wallpapers", + "system.remove_disk": "Remove disk", + "system.resources.description": "Configure which disks to monitor", + "theme.add_stop": "Add Stop", + "theme.angle": "Angle", + "theme.background": "Background", + "theme.border": "Border", + "theme.color": "Color", + "theme.color_picker": "Color picker", + "theme.custom": "Custom", + "theme.delete_stop": "Delete stop", + "theme.dot_color": "Dot Color", + "theme.editor_label": "Editor - %1", + "theme.gradient_mode": "Gradient Mode", + "theme.gradient_stops": "Gradient Stops", + "theme.item_color": "Item Color", + "theme.opacity": "Opacity", + "theme.open_color_picker": "Open color picker", + "theme.position": "Position", + "theme.range": "Range", + "theme.reset_gradient": "Reset Gradient", + "theme.select_color": "Select Color", + "theme.shadow.blur": "Blur", + "theme.shadow.color": "Color", + "theme.shadow.offset_x": "Offset X", + "theme.shadow.offset_y": "Offset Y", + "theme.shadow.opacity": "Opacity", + "theme.size": "Size", + "theme.stop_n": "Stop %1", + "theme.symbol_or_icon": "Symbol or path to icon...", + "tmux.loading_panes": "Loading panes...", + "tmux.no_panes": "No panes to display", + "tmux.no_session": "No session selected", + "tmux.open_terminal": "Open Terminal", + "tmux.quit": "Quit", + "tmux.search": "Search or create tmux session...", + "tmux.select_session_hint": "Select a session to preview", + "tools.color_picker": "Color Picker", + "tools.google_lens": "Google Lens", + "tools.mirror": "Mirror", + "tools.ocr": "OCR", + "tools.qr": "QR Code", + "tools.screenrecord_directory": "Open Recordings", + "tools.screenrecord_portal": "Portal", + "tools.screenrecord_region": "Region", + "tools.screenrecord_region_unavailable": "Region (Unavailable on NixOS without config)", + "tools.screenrecord_screen": "Screen", + "tools.screenrecord_screen_unavailable": "Screen (Unavailable on NixOS without config)", + "tools.screenrecord_start": "Screen Recorder", + "tools.screenrecord_stop": "Stop Recording", + "tools.screenrecord_window": "Window", + "tools.screenrecord_window_unavailable": "Window (Unavailable on NixOS without config)", + "tools.screenshot": "Screenshot", + "tools.screenshot_directory": "Open Screenshots", + "tools.toggle_audio": "Toggle Audio Output", + "tools.toggle_mic": "Toggle Microphone", + "wallpapers.current": "CURRENT", + "wallpapers.edit_gradia": "Edit with Gradia", + "wallpapers.filter_images": "Images", + "wallpapers.filter_videos": "Videos", + "wallpapers.oled": "OLED", + "wallpapers.scheme_content": "Content", + "wallpapers.scheme_expressive": "Expressive", + "wallpapers.scheme_fidelity": "Fidelity", + "wallpapers.scheme_fruit_salad": "Fruit Salad", + "wallpapers.scheme_monochrome": "Monochrome", + "wallpapers.scheme_neutral": "Neutral", + "wallpapers.scheme_rainbow": "Rainbow", + "wallpapers.scheme_tonal_spot": "Tonal Spot", + "wallpapers.search": "Search wallpapers...", + "wallpapers.select_scheme": "Select Scheme", + "wallpapers.set": "Set", + "wallpapers.tint": "Tint", + "weather.celsius": "Celsius", + "weather.fahrenheit": "Fahrenheit", + "weather.location": "Location", + "weather.location_placeholder": "e.g. Buenos Aires, Tokyo...", + "weather.today": "Today", + "weather.unit": "Unit", + "wifi.band_5g": "5G", + "wifi.connect": "Connect", + "wifi.connected": "Connected", + "wifi.connecting": "Connecting...", + "wifi.disabled": "Wi-Fi is disabled", + "wifi.disconnect": "Disconnect", + "wifi.limited": "Limited", + "wifi.network_settings": "Network settings", + "wifi.no_networks": "No networks found", + "wifi.open": "Open", + "wifi.open_portal": "Open captive portal", + "wifi.password": "Enter password...", + "wifi.rescan": "Rescan networks", + "wifi.secured": "Secured", + "wifi.title": "Wi-Fi", + "wifi.tooltip_off": "Wi-Fi: Off", + "wifi.tooltip_on": "Wi-Fi: On" +} diff --git a/translations/es.json b/translations/es.json new file mode 100644 index 000000000..75c74feab --- /dev/null +++ b/translations/es.json @@ -0,0 +1,639 @@ +{ + "_meta.direction": "ltr", + "ai.approve": "Aprobar", + "ai.ask_or_help": "Pregunta al AI o escribe /help...", + "ai.chat_history": "Historial de chat", + "ai.cmd_set_api_key": "Establecer clave API", + "ai.cmd_set_system_prompt": "Establecer prompt del sistema", + "ai.cmd_show_help": "Mostrar ayuda", + "ai.cmd_start_new_chat": "Iniciar nuevo chat", + "ai.cmd_switch_model": "Cambiar modelo de AI", + "ai.command_approved": "Comando aprobado", + "ai.command_rejected": "Comando rechazado", + "ai.curl_placeholder": "curl -X POST...", + "ai.curl_placeholders": "Marcadores: {{ENDPOINT}}, {{API_KEY}}, {{BODY_PATH}}", + "ai.custom_curl": "Plantilla cURL personalizada", + "ai.custom_endpoint": "Punto final personalizado", + "ai.custom_provider": "Proveedor personalizado", + "ai.custom_provider_key": "Clave API del proveedor personalizado", + "ai.endpoint_placeholder": "ej. https://...", + "ai.enter_api_key": "Ingresar clave API...", + "ai.hello_user": "Hola, %1.", + "ai.message": "Mensaje al AI...", + "ai.panel_title": "AI y claves API", + "ai.refresh_models": "¿Actualizar?", + "ai.reject": "Rechazar", + "ai.run_command": "Ejecutar comando", + "ai.search_models": "Buscar modelos...", + "bar.tooltip.audio_switcher": "Selector de dispositivo de audio", + "bar.tooltip.controls": "Controles de audio y brillo", + "bar.tooltip.keyboard_layout": "Disposición del teclado", + "bar.tooltip.launcher": "Abrir lanzador", + "bar.tooltip.layout": "Disposición: %1", + "bar.tooltip.overview": "Abrir vista general de ventanas", + "bar.tooltip.pin_bar": "Fijar barra", + "bar.tooltip.pin_dock": "Fijar dock", + "bar.tooltip.powermenu": "Menú de energía", + "bar.tooltip.presets": "Abrir administrador de preajustes", + "bar.tooltip.tools": "Herramientas", + "bar.tooltip.unpin_bar": "Desfijar barra", + "bar.tooltip.unpin_dock": "Desfijar dock", + "battery.charging": "Cargando", + "battery.full": "Completa", + "battery.full_in": "Completa en %1", + "battery.fully_charged": "Completamente cargada", + "battery.on_battery": "Con batería", + "battery.power_profile": "Perfil de energía: %1", + "battery.remaining": "%1 restante", + "battery.status": "Batería: %1%", + "binds.action": "Acción", + "binds.add_action": "Agregar otra acción", + "binds.add_key": "Agregar otra tecla", + "binds.add_keybind": "Agregar atajo", + "binds.ambxst": "Ambxst", + "binds.custom": "Personalizados", + "binds.delete_keybind": "Eliminar atajo de teclado", + "binds.key_combination": "Combinación de teclas", + "binds.key_configured": "Tecla configurada", + "binds.key_placeholder": "ej. R, TAB, ESCAPE, mouse:272...", + "binds.keybind_name_placeholder": "ej. Abrir terminal, Cambiar al espacio de trabajo 1...", + "binds.layouts_axctl": "Disposiciones (AxctlService)", + "binds.layouts_hint": "Dejar todas sin seleccionar para trabajar en todas las disposiciones", + "binds.legacy_dispatcher": "Despachador heredado", + "binds.name_optional": "Nombre (opcional)", + "binds.not_configured": "No configurado", + "binds.reload_binds": "Recargar atajos", + "bluetooth.connect": "Conectar", + "bluetooth.connected": "Conectado", + "bluetooth.connecting": "Conectando...", + "bluetooth.disabled": "Bluetooth está desactivado", + "bluetooth.disconnect": "Desconectar", + "bluetooth.forget": "Olvidar", + "bluetooth.no_devices": "No se encontraron dispositivos", + "bluetooth.not_paired": "No vinculado", + "bluetooth.open_manager": "Abrir Blueman", + "bluetooth.paired": "Vinculado", + "bluetooth.scan": "Buscar dispositivos", + "calendar.day.fri": "Vi", + "calendar.day.mon": "Lu", + "calendar.day.sat": "Sá", + "calendar.day.sun": "Do", + "calendar.day.thu": "Ju", + "calendar.day.tue": "Ma", + "calendar.day.wed": "Mi", + "calendar.day_full.friday": "Viernes", + "calendar.day_full.monday": "Lunes", + "calendar.day_full.saturday": "Sábado", + "calendar.day_full.sunday": "Domingo", + "calendar.day_full.thursday": "Jueves", + "calendar.day_full.tuesday": "Martes", + "calendar.day_full.wednesday": "Miércoles", + "calendar.month.april": "Abril", + "calendar.month.august": "Agosto", + "calendar.month.december": "Diciembre", + "calendar.month.february": "Febrero", + "calendar.month.january": "Enero", + "calendar.month.july": "Julio", + "calendar.month.june": "Junio", + "calendar.month.march": "Marzo", + "calendar.month.may": "Mayo", + "calendar.month.november": "Noviembre", + "calendar.month.october": "Octubre", + "calendar.month.september": "Septiembre", + "clipboard.alias": "Alias", + "clipboard.checksum": "Suma de verificación", + "clipboard.clear_all_confirm": "¿Borrar todo?", + "clipboard.copy_to_start": "Copiar al inicio", + "clipboard.copying": "¡Copiando!", + "clipboard.date": "Fecha", + "clipboard.days_ago": "hace %1 día(s)", + "clipboard.hours_ago": "hace %1 hora(s)", + "clipboard.just_now": "Ahora mismo", + "clipboard.link": "Enlace", + "clipboard.loading_preview": "Cargando vista previa...", + "clipboard.mime_type": "Tipo MIME", + "clipboard.min_ago": "hace %1 min", + "clipboard.no_history": "Sin historial del portapapeles", + "clipboard.pin": "Fijar", + "clipboard.search": "Buscar en el portapapeles...", + "clipboard.size": "Tamaño", + "clipboard.unpin": "Desfijar", + "color_picker.custom": "Personalizado", + "color_picker.picker": "Selector de color", + "common.active": "Activo", + "common.add": "Agregar", + "common.apply_changes": "Aplicar cambios", + "common.auto": "Auto", + "common.back": "Volver", + "common.bottom": "Abajo", + "common.cancel": "Cancelar", + "common.clear": "Limpiar", + "common.close": "Cerrar", + "common.coming_soon": "Próximamente", + "common.copied": "¡Copiado!", + "common.copy": "Copiar", + "common.default": "Predeterminado", + "common.delete": "Eliminar", + "common.disabled": "Deshabilitado", + "common.discard_changes": "Descartar cambios", + "common.edit": "Editar", + "common.enabled": "Habilitado", + "common.error": "Error", + "common.left": "Izquierda", + "common.none": "Ninguno", + "common.off": "Desactivado", + "common.on": "Activado", + "common.open": "Abrir", + "common.remove": "Quitar", + "common.rename": "Renombrar", + "common.reset_default": "Restablecer valores predeterminados", + "common.right": "Derecha", + "common.save": "Guardar", + "common.save_close": "Guardar y cerrar", + "common.search": "Buscar...", + "common.top": "Arriba", + "common.unsaved_changes": "Cambios sin guardar", + "compositor.active_border": "Borde activo", + "compositor.apply": "Aplicar cambios", + "compositor.back": "Volver", + "compositor.blur": "Desenfoque", + "compositor.border_angle": "Ángulo del borde", + "compositor.colors": "Colores", + "compositor.coming_soon_text": "Estas son funciones próximas. Los ajustes aquí se ampliarán conforme mejore la integración con el compositor.", + "compositor.discard": "Descartar cambios", + "compositor.gaps_in": "Espacios internos", + "compositor.gaps_out": "Espacios externos", + "compositor.general": "General", + "compositor.ignore_window": "Ignorar ventana", + "compositor.inactive_angle": "Ángulo inactivo", + "compositor.inactive_border": "Borde inactivo", + "compositor.layout.dwindle": "Dwindle", + "compositor.layout.master": "Master", + "compositor.layout.scrolling": "Desplazamiento", + "compositor.offset_x": "Desplazamiento X", + "compositor.offset_y": "Desplazamiento Y", + "compositor.opacity": "Opacidad", + "compositor.right_click_remove": "Clic derecho para eliminar", + "compositor.rounding": "Redondeo", + "compositor.shadows": "Sombras", + "compositor.sharp": "Agudo", + "compositor.sync_border_color": "Sincr. color del borde", + "compositor.sync_border_size": "Sincr. tamaño del borde", + "compositor.sync_rounding": "Sincr. redondeo", + "controls.bluetooth_connected": "Bluetooth: Conectado", + "controls.bluetooth_off": "Bluetooth: Desactivado", + "controls.bluetooth_on": "Bluetooth: Activado", + "controls.caffeine_off": "Caffeine: Desactivado", + "controls.caffeine_on": "Caffeine: Activado", + "controls.game_mode_off": "Modo juego: Desactivado", + "controls.game_mode_on": "Modo juego: Activado", + "controls.night_light_off": "Luz nocturna: Desactivada", + "controls.night_light_on": "Luz nocturna: Activada", + "controls.volume_protection": "Protección de volumen activa", + "desktop.delete": "Eliminar", + "desktop.open": "Abrir", + "dock.tooltip.pin_dock": "Fijar dock", + "dock.tooltip.unpin_dock": "Desfijar dock", + "effects.bypassed": "Omitido", + "effects.input_presets": "Preajustes de entrada", + "effects.not_installed": "EasyEffects no está instalado", + "effects.open": "Abrir EasyEffects", + "effects.output_presets": "Preajustes de salida", + "effects.refresh": "Actualizar", + "effects.title": "EasyEffects", + "emoji.clear_recent": "¿Borrar recientes?", + "emoji.search": "Buscar emojis...", + "idle.add_listener": "Agregar escucha", + "idle.after_sleep": "Comando después de suspender", + "idle.after_sleep_label": "Después de suspender", + "idle.before_sleep": "Comando antes de suspender", + "idle.before_sleep_label": "Antes de suspender", + "idle.listener_n": "Escucha %1", + "idle.listeners": "Escuchas", + "idle.lock_cmd": "Comando para bloquear pantalla", + "idle.lock_cmd_label": "Cmd de bloqueo", + "idle.on_resume": "Al reanudar", + "idle.on_timeout": "Al agotar tiempo", + "idle.timeout": "Tiempo de espera (s)", + "language.auto": "Auto", + "language.auto_detected": "Auto (%1)", + "launcher.create_shortcut": "Crear acceso directo", + "launcher.launch": "Ejecutar", + "launcher.pin_to_dock": "Fijar al dock", + "launcher.search": "Buscar aplicaciones...", + "launcher.unpin_from_dock": "Desfijar del dock", + "lockscreen.loading": "Cargando escritorio...", + "mixer.input": "Entrada", + "mixer.input_device": "Dispositivo de entrada", + "mixer.no_apps": "Ninguna aplicación usa audio", + "mixer.open_pavucontrol": "Abrir control de volumen PipeWire", + "mixer.output": "Salida", + "mixer.output_device": "Dispositivo de salida", + "mixer.protection_disabled": "Protección de volumen deshabilitada", + "mixer.protection_enabled": "Protección de volumen habilitada", + "mixer.title": "Sonido", + "mixer.volume_mixer": "Mezclador de volumen", + "notch.ambxst": "Ambxst", + "notch.compositor": "Compositor", + "notes.days_ago": "hace %1 días", + "notes.markdown": "Markdown", + "notes.rich_text": "Texto enriquecido", + "notes.search": "Buscar o crear nota...", + "notes.select_or_create": "Selecciona o crea una nota", + "notes.start_typing": "Empieza a escribir...", + "notes.write_markdown": "Escribe markdown aquí...", + "notifications.clear_all": "Limpiar todo", + "notifications.no_notifications": "Sin notificaciones", + "notifications.now": "Ahora", + "notifications.panel_title": "Notificaciones", + "notifications.yesterday": "Ayer", + "overview.search": "Buscar ventanas...", + "performance.blur_transition": "Transición de desenfoque", + "performance.dashboard_persist": "Mantener pestañas del panel", + "performance.rotate_cover": "Rotar carátula", + "performance.wavy_line": "Línea ondulada", + "performance.window_preview": "Vista previa de ventana", + "player.enjoy_silence": "Disfruta el silencio", + "player.nothing_playing": "Nada en reproducción", + "player.unknown": "Desconocido", + "player.unknown_player": "Reproductor desconocido", + "pomodoro.minus_1m": "-1m", + "pomodoro.pause": "PAUSAR", + "pomodoro.plus_1m": "+1m", + "pomodoro.rest_session": "Sesión de descanso", + "pomodoro.resume": "REANUDAR", + "pomodoro.start_rest": "INICIAR DESCANSO", + "pomodoro.start_work": "INICIAR TRABAJO", + "pomodoro.stop_alarm": "DETENER ALARMA", + "pomodoro.sync_spotify": "Sincronizar con Spotify", + "pomodoro.work_session": "Sesión de trabajo", + "power_profile.balanced": "Equilibrado", + "power_profile.performance": "Rendimiento", + "power_profile.power_save": "Ahorro de energía", + "powermenu.exit_axctl": "Salir de AxctlService", + "powermenu.hibernate": "Hibernar", + "powermenu.lock_session": "Bloquear sesión", + "powermenu.power_off": "Apagar", + "powermenu.reboot": "Reiniciar", + "powermenu.suspend": "Suspender", + "presets.active": "ACTIVO", + "presets.confirm_delete": "¿Eliminar \"%1\"?", + "presets.create_new": "Crear nuevo preajuste", + "presets.create_specific": "Crear preajuste \"%1\"", + "presets.no_presets": "No hay preajustes configurados", + "presets.official": "OFICIAL", + "presets.search": "Buscar o crear preajuste...", + "presets.select_config_files": "Seleccionar archivos de configuración para actualizar:", + "presets.tap_to_create": "Tocar para crear", + "presets.unknown_author": "Desconocido", + "presets.update": "Actualizar", + "presets.update_title": "Actualizar \"%1\"", + "presets.visit_author": "Visitar autor", + "screenshot.region": "Región", + "screenshot.screen": "Pantalla", + "screenshot.window": "Ventana", + "settings.ai": "AI", + "settings.ambxst": "Ambxst", + "settings.audio_effects": "Efectos de audio", + "settings.audio_mixer": "Mezclador de audio", + "settings.binds": "Atajos", + "settings.binds.assistant": "Atajo del asistente", + "settings.binds.clipboard": "Atajo del portapapeles", + "settings.binds.dashboard": "Atajo del panel", + "settings.binds.emoji": "Atajo de emoji", + "settings.binds.key_bindings": "Atajos de teclado", + "settings.binds.launcher": "Atajo del lanzador", + "settings.binds.lens": "Atajo de lente", + "settings.binds.lockscreen": "Atajo de pantalla de bloqueo", + "settings.binds.notes": "Atajo de notas", + "settings.binds.overview": "Atajo de vista general", + "settings.binds.powermenu": "Atajo del menú de energía", + "settings.binds.quit": "Atajo de salir", + "settings.binds.reload": "Atajo de recargar", + "settings.binds.screenrecord": "Atajo de grabación de pantalla", + "settings.binds.screenshot": "Atajo de captura de pantalla", + "settings.binds.settings": "Atajo de configuración", + "settings.binds.tmux": "Atajo de tmux", + "settings.binds.tools": "Atajo de herramientas", + "settings.binds.wallpapers": "Atajo de fondos de pantalla", + "settings.bluetooth": "Bluetooth", + "settings.compositor": "Compositor", + "settings.compositor.axctl": "AxctlService", + "settings.compositor.blur_brightness": "Brillo de desenfoque", + "settings.compositor.blur_contrast": "Contraste de desenfoque", + "settings.compositor.blur_enabled": "Desenfoque habilitado", + "settings.compositor.blur_ignore_opacity": "Desenfoque ignorar opacidad", + "settings.compositor.blur_ignorealpha": "Desenfoque ignorar alfa", + "settings.compositor.blur_ignorealpha_value": "Valor de ignorar alfa", + "settings.compositor.blur_new_optimizations": "Nuevas optimizaciones de desenfoque", + "settings.compositor.blur_noise": "Ruido de desenfoque", + "settings.compositor.blur_passes": "Pasadas de desenfoque", + "settings.compositor.blur_size": "Tamaño de desenfoque", + "settings.compositor.blur_vibrancy": "Vibrancia de desenfoque", + "settings.compositor.blur_xray": "Desenfoque Xray", + "settings.compositor.border_colors": "Colores de borde", + "settings.compositor.border_size": "Tamaño de borde", + "settings.compositor.shadow_offset": "Desplazamiento de sombra", + "settings.compositor.shadow_power": "Potencia de sombra", + "settings.compositor.shadow_range": "Alcance de sombra", + "settings.compositor.shadow_scale": "Escala de sombra", + "settings.compositor.shadows_enabled": "Sombras habilitadas", + "settings.compositor.sync_shadow_color": "Sincronizar color de sombra", + "settings.compositor.sync_shadow_opacity": "Sincronizar opacidad de sombra", + "settings.compositor.window_gaps": "Espacios entre ventanas", + "settings.effects": "Efectos", + "settings.mixer": "Mezclador", + "settings.network": "Red", + "settings.shell.always_show_numbers": "Mostrar siempre los números", + "settings.shell.available_on_fullscreen": "Disponible en pantalla completa", + "settings.shell.bar": "Barra", + "settings.shell.bar_autohide": "Ocultamiento automático de barra", + "settings.shell.bar_entry": "Barra", + "settings.shell.bar_position": "Posición de barra", + "settings.shell.bar_screens": "Pantallas de barra", + "settings.shell.desktop": "Escritorio", + "settings.shell.desktop_enabled": "Escritorio habilitado", + "settings.shell.desktop_entry": "Escritorio", + "settings.shell.desktop_icon_size": "Tamaño de icono del escritorio", + "settings.shell.desktop_text_color": "Color del texto del escritorio", + "settings.shell.desktop_vertical_spacing": "Espaciado vertical del escritorio", + "settings.shell.dock": "Dock", + "settings.shell.dock_enabled": "Dock habilitado", + "settings.shell.dock_entry": "Dock", + "settings.shell.dock_height": "Altura del dock", + "settings.shell.dock_hover_region_height": "Altura de región de activación del dock", + "settings.shell.dock_icon_size": "Tamaño de icono del dock", + "settings.shell.dock_margin": "Margen del dock", + "settings.shell.dock_mode": "Modo de dock", + "settings.shell.dock_pinned_on_startup": "Dock fijado al iniciar", + "settings.shell.dock_position": "Posición del dock", + "settings.shell.dock_spacing": "Espaciado del dock", + "settings.shell.dynamic_workspaces": "Espacios de trabajo dinámicos", + "settings.shell.firefox_player": "Reproductor de Firefox", + "settings.shell.frame": "Marco", + "settings.shell.hover_region_height": "Altura de región de activación", + "settings.shell.hover_to_reveal": "Pasar cursor para mostrar", + "settings.shell.launcher_icon": "Icono del lanzador", + "settings.shell.launcher_icon_full_tint": "Tinte completo del icono del lanzador", + "settings.shell.launcher_icon_size": "Tamaño del icono del lanzador", + "settings.shell.launcher_icon_tint": "Tinte del icono del lanzador", + "settings.shell.lockscreen": "Pantalla de bloqueo", + "settings.shell.lockscreen_entry": "Pantalla de bloqueo", + "settings.shell.notch": "Notch", + "settings.shell.notch_entry": "Notch", + "settings.shell.overview": "Vista general", + "settings.shell.overview_columns": "Columnas de vista general", + "settings.shell.overview_entry": "Vista general", + "settings.shell.overview_rows": "Filas de vista general", + "settings.shell.overview_scale": "Escala de vista general", + "settings.shell.overview_workspace_spacing": "Espaciado de espacios de trabajo en vista general", + "settings.shell.pill_style": "Estilo de píldora", + "settings.shell.pinned_on_startup": "Fijado al iniciar", + "settings.shell.show_app_icons": "Mostrar iconos de apps", + "settings.shell.show_numbers": "Mostrar números", + "settings.shell.show_overview_button": "Mostrar botón de vista general", + "settings.shell.show_pin_button": "Mostrar botón de fijar", + "settings.shell.show_running_indicators": "Mostrar indicadores de apps activas", + "settings.shell.sidebar": "Barra lateral", + "settings.shell.system": "Sistema", + "settings.shell.system_entry": "Sistema del shell", + "settings.shell.workspaces": "Espacios de trabajo", + "settings.shell.workspaces_entry": "Espacios de trabajo", + "settings.shell.workspaces_shown": "Espacios de trabajo mostrados", + "settings.system": "Sistema", + "settings.system.after_sleep": "Después de suspender", + "settings.system.before_sleep": "Antes de suspender", + "settings.system.blur_transition": "Transición de desenfoque", + "settings.system.clipboard_prefix": "Prefijo de portapapeles", + "settings.system.emoji_prefix": "Prefijo de emoji", + "settings.system.idle": "Inactividad", + "settings.system.idle_listener": "Escucha de inactividad", + "settings.system.idle_settings": "Ajustes de inactividad", + "settings.system.language": "Idioma", + "settings.system.lock_command": "Comando de bloqueo", + "settings.system.notes_prefix": "Prefijo de notas", + "settings.system.performance": "Rendimiento", + "settings.system.prefixes": "Prefijos", + "settings.system.prefixes_entry": "Prefijos", + "settings.system.resources": "Recursos del sistema", + "settings.system.system_resources": "Recursos del sistema", + "settings.system.temperature_unit": "Unidad de temperatura", + "settings.system.tmux_prefix": "Prefijo de tmux", + "settings.system.wallpapers_prefix": "Prefijo de fondos de pantalla", + "settings.system.wavy_line": "Línea ondulada", + "settings.system.weather": "Clima", + "settings.system.weather_location": "Ubicación del clima", + "settings.system.window_preview": "Vista previa de ventana", + "settings.theme": "Tema", + "settings.theme.animation": "Animación", + "settings.theme.animation_duration": "Duración de animación", + "settings.theme.background_variant": "Variante de fondo", + "settings.theme.bar_bg_variant": "Variante de fondo de barra", + "settings.theme.color_border": "Borde de color", + "settings.theme.color_opacity": "Opacidad de color", + "settings.theme.color_scheme": "Esquema de color", + "settings.theme.color_variant": "Variante de color", + "settings.theme.colors": "Colores", + "settings.theme.duration": "Duración", + "settings.theme.editor": "Editor", + "settings.theme.enable_corners": "Habilitar esquinas", + "settings.theme.fonts": "Fuentes", + "settings.theme.general": "General", + "settings.theme.gradient_angle": "Ángulo de degradado", + "settings.theme.internal_bg_variant": "Variante de fondo interno", + "settings.theme.mono_font": "Fuente monoespaciada", + "settings.theme.pane_variant": "Variante de panel", + "settings.theme.popup_variant": "Variante de ventana emergente", + "settings.theme.roundness": "Redondez", + "settings.theme.shadow": "Sombra", + "settings.theme.shadow_blur": "Desenfoque de sombra", + "settings.theme.shadow_offset": "Desplazamiento de sombra", + "settings.theme.shadow_opacity": "Opacidad de sombra", + "settings.theme.tint_icons": "Colorear iconos", + "settings.theme.ui_font": "Fuente de interfaz", + "settings.theme.variant": "Variante", + "settings.theme.wallpapers": "Fondos de pantalla", + "shell.autohide": "Ocultamiento automático", + "shell.available_on_fullscreen": "Disponible en pantalla completa", + "shell.desktop.enabled": "Habilitado", + "shell.desktop.icon_size": "Tamaño de icono", + "shell.desktop.text_color": "Color del texto", + "shell.desktop.vertical_spacing": "Espaciado vertical", + "shell.dock.enabled": "Habilitado", + "shell.dock.floating": "Flotante", + "shell.dock.height": "Altura", + "shell.dock.hover_region": "Región de activación", + "shell.dock.icon_size": "Tamaño de icono", + "shell.dock.integrated": "Integrado", + "shell.dock.island": "Isla", + "shell.dock.keep_hidden": "Mantener oculto", + "shell.dock.margin": "Margen", + "shell.dock.spacing": "Espaciado", + "shell.dock.theme": "Tema", + "shell.enable_firefox_player": "Habilitar reproductor de Firefox", + "shell.excluded_sinks": "Salidas de audio excluidas", + "shell.frame.contain_bar": "Contener barra", + "shell.frame.enabled": "Habilitado", + "shell.frame.keep_bar_border": "Mantener borde de barra", + "shell.frame.keep_bar_shadow": "Mantener sombra de barra", + "shell.frame.thickness": "Grosor", + "shell.hover_region_height": "Altura de región de activación", + "shell.hover_reveal": "Pasar el cursor para mostrar", + "shell.hover_to_reveal": "Pasar el cursor para mostrar", + "shell.launcher_icon": "Icono del lanzador", + "shell.launcher_icon_full_tint": "Tinte completo del icono del lanzador", + "shell.launcher_icon_size": "Tamaño del icono del lanzador", + "shell.launcher_icon_tint": "Tinte del icono del lanzador", + "shell.lockscreen.position": "Posición", + "shell.no_media_display": "Sin visualización de medios", + "shell.notch.compositor": "Compositor", + "shell.notch.custom_text": "Texto personalizado", + "shell.notch.disable_hover_expansion": "Deshabilitar expansión al pasar cursor", + "shell.notch.enter_text": "Ingresar texto...", + "shell.notch.keep_hidden": "Mantener oculto", + "shell.notch.user_host": "Usuario@Host", + "shell.overview.columns": "Columnas", + "shell.overview.rows": "Filas", + "shell.overview.scale": "Escala", + "shell.overview.workspace_spacing": "Espaciado entre espacios de trabajo", + "shell.pill_style": "Estilo de píldora", + "shell.pinned_on_startup": "Fijado al iniciar", + "shell.position": "Posición", + "shell.screens": "Pantallas", + "shell.screens_empty": "Vacío = todas las pantallas", + "shell.shell": "Shell", + "shell.show_audio_switcher": "Mostrar selector de dispositivo de audio", + "shell.show_keyboard_layout": "Mostrar disposición del teclado", + "shell.show_overview_button": "Mostrar botón de vista general", + "shell.show_pin_button": "Mostrar botón de fijar", + "shell.show_running_indicators": "Mostrar indicadores de apps activas", + "shell.sidebar.width": "Ancho", + "shell.squished": "Comprimido", + "shell.system.about_ambxst": "Acerca de Ambxst %1", + "shell.system.donate": "Donar ❤️", + "shell.system.ocr_chinese_simplified": "Chino (simplificado)", + "shell.system.ocr_chinese_traditional": "Chino (tradicional)", + "shell.system.ocr_english": "Inglés", + "shell.system.ocr_japanese": "Japonés", + "shell.system.ocr_korean": "Coreano", + "shell.system.ocr_languages": "Idiomas de OCR", + "shell.system.ocr_latin": "Latín", + "shell.system.ocr_russian": "Ruso", + "shell.system.ocr_spanish": "Español", + "shell.system.update_service": "Servicio de actualización", + "shell.use_12h_format": "Usar formato de 12h", + "shell.workspaces.always_show_numbers": "Mostrar siempre los números", + "shell.workspaces.dynamic": "Dinámico", + "shell.workspaces.show_app_icons": "Mostrar iconos de apps", + "shell.workspaces.show_numbers": "Mostrar números", + "shell.workspaces.shown": "Mostrados", + "system.add_disk": "Agregar disco", + "system.disk_path_placeholder": "ej. /, /home...", + "system.performance.blur_transition_desc": "Desenfoque animado al abrir paneles", + "system.performance.description": "Activar o desactivar efectos visuales para mejorar el rendimiento", + "system.performance.disable_cover_rotation": "Deshabilitar rotación de carátula", + "system.performance.disable_cover_rotation_desc": "Detener el giro del disco de vinilo", + "system.performance.wavy_line_desc": "Efecto de línea ondulada animada", + "system.performance.window_preview_desc": "Mostrar miniaturas de ventanas en la vista general", + "system.prefixes.clipboard": "Portapapeles", + "system.prefixes.description": "Atajos de teclado para acciones rápidas en el lanzador", + "system.prefixes.emoji": "Emoji", + "system.prefixes.notes": "Notas", + "system.prefixes.tmux": "Tmux", + "system.prefixes.wallpapers": "Fondos de pantalla", + "system.remove_disk": "Quitar disco", + "system.resources.description": "Configurar qué discos monitorear", + "theme.add_stop": "Agregar parada", + "theme.angle": "Ángulo", + "theme.background": "Fondo", + "theme.border": "Borde", + "theme.color": "Color", + "theme.color_picker": "Selector de color", + "theme.custom": "Personalizado", + "theme.delete_stop": "Eliminar parada", + "theme.dot_color": "Color del punto", + "theme.editor_label": "Editor - %1", + "theme.gradient_mode": "Modo de degradado", + "theme.gradient_stops": "Paradas de degradado", + "theme.item_color": "Color del elemento", + "theme.opacity": "Opacidad", + "theme.open_color_picker": "Abrir selector de color", + "theme.position": "Posición", + "theme.range": "Rango", + "theme.reset_gradient": "Restablecer degradado", + "theme.select_color": "Seleccionar color", + "theme.shadow.blur": "Desenfoque", + "theme.shadow.color": "Color", + "theme.shadow.offset_x": "Desplazamiento X", + "theme.shadow.offset_y": "Desplazamiento Y", + "theme.shadow.opacity": "Opacidad", + "theme.size": "Tamaño", + "theme.stop_n": "Parada %1", + "theme.symbol_or_icon": "Símbolo o ruta al icono...", + "tmux.loading_panes": "Cargando paneles...", + "tmux.no_panes": "No hay paneles para mostrar", + "tmux.no_session": "No hay sesión seleccionada", + "tmux.open_terminal": "Abrir terminal", + "tmux.quit": "Salir", + "tmux.search": "Buscar o crear sesión de tmux...", + "tmux.select_session_hint": "Selecciona una sesión para previsualizar", + "tools.color_picker": "Selector de color", + "tools.google_lens": "Google Lens", + "tools.mirror": "Espejo", + "tools.ocr": "OCR", + "tools.qr": "Código QR", + "tools.screenrecord_directory": "Abrir grabaciones", + "tools.screenrecord_portal": "Portal", + "tools.screenrecord_region": "Región", + "tools.screenrecord_region_unavailable": "Región (No disponible en NixOS sin configuración)", + "tools.screenrecord_screen": "Pantalla", + "tools.screenrecord_screen_unavailable": "Pantalla (No disponible en NixOS sin configuración)", + "tools.screenrecord_start": "Grabador de pantalla", + "tools.screenrecord_stop": "Detener grabación", + "tools.screenrecord_window": "Ventana", + "tools.screenrecord_window_unavailable": "Ventana (No disponible en NixOS sin configuración)", + "tools.screenshot": "Captura de pantalla", + "tools.screenshot_directory": "Abrir capturas", + "tools.toggle_audio": "Alternar salida de audio", + "tools.toggle_mic": "Alternar micrófono", + "wallpapers.current": "ACTUAL", + "wallpapers.edit_gradia": "Editar con Gradia", + "wallpapers.filter_images": "Imágenes", + "wallpapers.filter_videos": "Videos", + "wallpapers.oled": "OLED", + "wallpapers.scheme_content": "Contenido", + "wallpapers.scheme_expressive": "Expresivo", + "wallpapers.scheme_fidelity": "Fidelidad", + "wallpapers.scheme_fruit_salad": "Ensalada de frutas", + "wallpapers.scheme_monochrome": "Monocromo", + "wallpapers.scheme_neutral": "Neutral", + "wallpapers.scheme_rainbow": "Arcoíris", + "wallpapers.scheme_tonal_spot": "Punto tonal", + "wallpapers.search": "Buscar fondos de pantalla...", + "wallpapers.select_scheme": "Seleccionar esquema", + "wallpapers.set": "Establecer", + "wallpapers.tint": "Tinte", + "weather.celsius": "Celsius", + "weather.fahrenheit": "Fahrenheit", + "weather.location": "Ubicación", + "weather.location_placeholder": "ej. Buenos Aires, Tokio...", + "weather.today": "Hoy", + "weather.unit": "Unidad", + "wifi.band_5g": "5G", + "wifi.connect": "Conectar", + "wifi.connected": "Conectado", + "wifi.connecting": "Conectando...", + "wifi.disabled": "Wi-Fi está desactivado", + "wifi.disconnect": "Desconectar", + "wifi.limited": "Limitado", + "wifi.network_settings": "Configuración de red", + "wifi.no_networks": "No se encontraron redes", + "wifi.open": "Abierta", + "wifi.open_portal": "Abrir portal cautivo", + "wifi.password": "Ingresar contraseña...", + "wifi.rescan": "Volver a buscar redes", + "wifi.secured": "Segura", + "wifi.title": "Wi-Fi", + "wifi.tooltip_off": "Wi-Fi: Desactivado", + "wifi.tooltip_on": "Wi-Fi: Activado" +} diff --git a/translations/languages.json b/translations/languages.json new file mode 100644 index 000000000..15df5e3a0 --- /dev/null +++ b/translations/languages.json @@ -0,0 +1,5 @@ +{ + "en": "English", + "ru": "Русский", + "es": "Español" +} diff --git a/translations/ru.json b/translations/ru.json new file mode 100644 index 000000000..0e2685d4c --- /dev/null +++ b/translations/ru.json @@ -0,0 +1,639 @@ +{ + "_meta.direction": "ltr", + "ai.approve": "Одобрить", + "ai.ask_or_help": "Спросите AI или введите /help...", + "ai.chat_history": "История чата", + "ai.cmd_set_api_key": "Установить API ключ", + "ai.cmd_set_system_prompt": "Установить системный промпт", + "ai.cmd_show_help": "Показать справку", + "ai.cmd_start_new_chat": "Начать новый чат", + "ai.cmd_switch_model": "Переключить модель AI", + "ai.command_approved": "Команда одобрена", + "ai.command_rejected": "Команда отклонена", + "ai.curl_placeholder": "curl -X POST...", + "ai.curl_placeholders": "Заполнители: {{ENDPOINT}}, {{API_KEY}}, {{BODY_PATH}}", + "ai.custom_curl": "Пользовательский шаблон cURL", + "ai.custom_endpoint": "Пользовательская конечная точка", + "ai.custom_provider": "Пользовательский провайдер", + "ai.custom_provider_key": "API-ключ пользовательского провайдера", + "ai.endpoint_placeholder": "например, https://...", + "ai.enter_api_key": "Введите API-ключ...", + "ai.hello_user": "Привет, %1.", + "ai.message": "Сообщение AI...", + "ai.panel_title": "AI и API-ключи", + "ai.refresh_models": "Обновить?", + "ai.reject": "Отклонить", + "ai.run_command": "Выполнить команду", + "ai.search_models": "Поиск моделей...", + "bar.tooltip.audio_switcher": "Переключатель аудиоустройств", + "bar.tooltip.controls": "Управление звуком и яркостью", + "bar.tooltip.keyboard_layout": "Раскладка клавиатуры", + "bar.tooltip.launcher": "Открыть запуск приложений", + "bar.tooltip.layout": "Раскладка: %1", + "bar.tooltip.overview": "Открыть обзор окон", + "bar.tooltip.pin_bar": "Закрепить панель", + "bar.tooltip.pin_dock": "Закрепить док", + "bar.tooltip.powermenu": "Меню питания", + "bar.tooltip.presets": "Открыть менеджер пресетов", + "bar.tooltip.tools": "Инструменты", + "bar.tooltip.unpin_bar": "Открепить панель", + "bar.tooltip.unpin_dock": "Открепить док", + "battery.charging": "Зарядка", + "battery.full": "Заряжена", + "battery.full_in": "Зарядится через %1", + "battery.fully_charged": "Полностью заряжена", + "battery.on_battery": "От батареи", + "battery.power_profile": "Профиль питания: %1", + "battery.remaining": "Осталось %1", + "battery.status": "Батарея: %1%", + "binds.action": "Действие", + "binds.add_action": "Добавить действие", + "binds.add_key": "Добавить клавишу", + "binds.add_keybind": "Добавить привязку", + "binds.ambxst": "Ambxst", + "binds.custom": "Пользовательские", + "binds.delete_keybind": "Удалить привязку клавиши", + "binds.key_combination": "Комбинация клавиш", + "binds.key_configured": "Ключ настроен", + "binds.key_placeholder": "например, R, TAB, ESCAPE, mouse:272...", + "binds.keybind_name_placeholder": "например, Открыть терминал, Переключиться на рабочее пространство 1...", + "binds.layouts_axctl": "Раскладки (AxctlService)", + "binds.layouts_hint": "Оставьте все невыбранными для работы во всех раскладках", + "binds.legacy_dispatcher": "Legacy Dispatcher", + "binds.name_optional": "Название (необязательно)", + "binds.not_configured": "Не настроено", + "binds.reload_binds": "Перезагрузить привязки", + "bluetooth.connect": "Подключить", + "bluetooth.connected": "Подключено", + "bluetooth.connecting": "Подключение...", + "bluetooth.disabled": "Bluetooth отключён", + "bluetooth.disconnect": "Отключить", + "bluetooth.forget": "Забыть", + "bluetooth.no_devices": "Устройства не найдены", + "bluetooth.not_paired": "Не сопряжено", + "bluetooth.open_manager": "Открыть Blueman", + "bluetooth.paired": "Сопряжено", + "bluetooth.scan": "Поиск устройств", + "calendar.day.fri": "Пт", + "calendar.day.mon": "Пн", + "calendar.day.sat": "Сб", + "calendar.day.sun": "Вс", + "calendar.day.thu": "Чт", + "calendar.day.tue": "Вт", + "calendar.day.wed": "Ср", + "calendar.day_full.friday": "Пятница", + "calendar.day_full.monday": "Понедельник", + "calendar.day_full.saturday": "Суббота", + "calendar.day_full.sunday": "Воскресенье", + "calendar.day_full.thursday": "Четверг", + "calendar.day_full.tuesday": "Вторник", + "calendar.day_full.wednesday": "Среда", + "calendar.month.april": "Апрель", + "calendar.month.august": "Август", + "calendar.month.december": "Декабрь", + "calendar.month.february": "Февраль", + "calendar.month.january": "Январь", + "calendar.month.july": "Июль", + "calendar.month.june": "Июнь", + "calendar.month.march": "Март", + "calendar.month.may": "Май", + "calendar.month.november": "Ноябрь", + "calendar.month.october": "Октябрь", + "calendar.month.september": "Сентябрь", + "clipboard.alias": "Псевдоним", + "clipboard.checksum": "Контрольная сумма", + "clipboard.clear_all_confirm": "Очистить всё?", + "clipboard.copy_to_start": "Копировать в начало", + "clipboard.copying": "Копирование!", + "clipboard.date": "Дата", + "clipboard.days_ago": "%1 дн. назад", + "clipboard.hours_ago": "%1 ч. назад", + "clipboard.just_now": "Только что", + "clipboard.link": "Ссылка", + "clipboard.loading_preview": "Загрузка превью...", + "clipboard.mime_type": "MIME-тип", + "clipboard.min_ago": "%1 мин. назад", + "clipboard.no_history": "История буфера пуста", + "clipboard.pin": "Закрепить", + "clipboard.search": "Поиск в буфере обмена...", + "clipboard.size": "Размер", + "clipboard.unpin": "Открепить", + "color_picker.custom": "Пользовательский", + "color_picker.picker": "Пипетка", + "common.active": "Активно", + "common.add": "Добавить", + "common.apply_changes": "Применить изменения", + "common.auto": "Авто", + "common.back": "Назад", + "common.bottom": "Снизу", + "common.cancel": "Отмена", + "common.clear": "Очистить", + "common.close": "Закрыть", + "common.coming_soon": "Скоро", + "common.copied": "Скопировано!", + "common.copy": "Копировать", + "common.default": "По умолчанию", + "common.delete": "Удалить", + "common.disabled": "Выключено", + "common.discard_changes": "Отменить изменения", + "common.edit": "Изменить", + "common.enabled": "Включено", + "common.error": "Ошибка", + "common.left": "Слева", + "common.none": "Нет", + "common.off": "Выкл", + "common.on": "Вкл", + "common.open": "Открыть", + "common.remove": "Убрать", + "common.rename": "Переименовать", + "common.reset_default": "Сбросить по умолчанию", + "common.right": "Справа", + "common.save": "Сохранить", + "common.save_close": "Сохранить и закрыть", + "common.search": "Поиск...", + "common.top": "Сверху", + "common.unsaved_changes": "Несохранённые изменения", + "compositor.active_border": "Активная граница", + "compositor.apply": "Применить изменения", + "compositor.back": "Назад", + "compositor.blur": "Размытие", + "compositor.border_angle": "Угол границы", + "compositor.colors": "Цвета", + "compositor.coming_soon_text": "Это будущие функции. Настройки здесь будут расширяться по мере улучшения интеграции с композитором.", + "compositor.discard": "Отменить изменения", + "compositor.gaps_in": "Отступы внутри", + "compositor.gaps_out": "Отступы снаружи", + "compositor.general": "Основное", + "compositor.ignore_window": "Игнорировать окно", + "compositor.inactive_angle": "Угол неактивной границы", + "compositor.inactive_border": "Неактивная граница", + "compositor.layout.dwindle": "Dwindle", + "compositor.layout.master": "Master", + "compositor.layout.scrolling": "Scrolling", + "compositor.offset_x": "Смещение X", + "compositor.offset_y": "Смещение Y", + "compositor.opacity": "Прозрачность", + "compositor.right_click_remove": "Правая кнопка для удаления", + "compositor.rounding": "Скругление", + "compositor.shadows": "Тени", + "compositor.sharp": "Резкий", + "compositor.sync_border_color": "Синхр. цвет границы", + "compositor.sync_border_size": "Синхр. размер границы", + "compositor.sync_rounding": "Синхр. скругление", + "controls.bluetooth_connected": "Bluetooth: Подключено", + "controls.bluetooth_off": "Bluetooth: Выкл", + "controls.bluetooth_on": "Bluetooth: Вкл", + "controls.caffeine_off": "Режим кофеина: Выкл", + "controls.caffeine_on": "Режим кофеина: Вкл", + "controls.game_mode_off": "Игровой режим: Выкл", + "controls.game_mode_on": "Игровой режим: Вкл", + "controls.night_light_off": "Ночной свет: Выкл", + "controls.night_light_on": "Ночной свет: Вкл", + "controls.volume_protection": "Защита громкости активна", + "desktop.delete": "Удалить", + "desktop.open": "Открыть", + "dock.tooltip.pin_dock": "Закрепить док", + "dock.tooltip.unpin_dock": "Открепить док", + "effects.bypassed": "Обход", + "effects.input_presets": "Пресеты ввода", + "effects.not_installed": "EasyEffects не установлен", + "effects.open": "Открыть EasyEffects", + "effects.output_presets": "Пресеты вывода", + "effects.refresh": "Обновить", + "effects.title": "EasyEffects", + "emoji.clear_recent": "Очистить недавние?", + "emoji.search": "Поиск эмодзи...", + "idle.add_listener": "Добавить слушатель", + "idle.after_sleep": "Команда после сна", + "idle.after_sleep_label": "После сна", + "idle.before_sleep": "Команда перед сном", + "idle.before_sleep_label": "Перед сном", + "idle.listener_n": "Слушатель %1", + "idle.listeners": "Слушатели", + "idle.lock_cmd": "Команда блокировки экрана", + "idle.lock_cmd_label": "Команда блокировки", + "idle.on_resume": "При возобновлении", + "idle.on_timeout": "При тайм-ауте", + "idle.timeout": "Тайм-аут (с)", + "language.auto": "Авто", + "language.auto_detected": "Авто (%1)", + "launcher.create_shortcut": "Создать ярлык", + "launcher.launch": "Запустить", + "launcher.pin_to_dock": "Закрепить на доке", + "launcher.search": "Поиск приложений...", + "launcher.unpin_from_dock": "Открепить от дока", + "lockscreen.loading": "Загрузка рабочего стола...", + "mixer.input": "Вход", + "mixer.input_device": "Устройство ввода", + "mixer.no_apps": "Нет приложений, использующих звук", + "mixer.open_pavucontrol": "Открыть управление громкостью PipeWire", + "mixer.output": "Выход", + "mixer.output_device": "Устройство вывода", + "mixer.protection_disabled": "Защита громкости выключена", + "mixer.protection_enabled": "Защита громкости включена", + "mixer.title": "Звук", + "mixer.volume_mixer": "Микшер громкости", + "notch.ambxst": "Ambxst", + "notch.compositor": "Композитор", + "notes.days_ago": "%1 дн. назад", + "notes.markdown": "Markdown", + "notes.rich_text": "Форматированный текст", + "notes.search": "Поиск или создание заметки...", + "notes.select_or_create": "Выберите или создайте заметку", + "notes.start_typing": "Начните вводить...", + "notes.write_markdown": "Пишите markdown здесь...", + "notifications.clear_all": "Очистить все", + "notifications.no_notifications": "Нет уведомлений", + "notifications.now": "Сейчас", + "notifications.panel_title": "Уведомления", + "notifications.yesterday": "Вчера", + "overview.search": "Поиск окон...", + "performance.blur_transition": "Переход размытия", + "performance.dashboard_persist": "Сохранять вкладки панели управления", + "performance.rotate_cover": "Вращать обложку", + "performance.wavy_line": "Волнистая линия", + "performance.window_preview": "Предпросмотр окон", + "player.enjoy_silence": "Наслаждайтесь тишиной", + "player.nothing_playing": "Не воспроизводится", + "player.unknown": "Неизвестно", + "player.unknown_player": "Неизвестный плеер", + "pomodoro.minus_1m": "-1м", + "pomodoro.pause": "ПАУЗА", + "pomodoro.plus_1m": "+1м", + "pomodoro.rest_session": "Сессия отдыха", + "pomodoro.resume": "ПРОДОЛЖИТЬ", + "pomodoro.start_rest": "НАЧАТЬ ОТДЫХ", + "pomodoro.start_work": "НАЧАТЬ РАБОТУ", + "pomodoro.stop_alarm": "ОСТАНОВИТЬ БУДИЛЬНИК", + "pomodoro.sync_spotify": "Синхронизировать Spotify", + "pomodoro.work_session": "Рабочая сессия", + "power_profile.balanced": "Сбалансированный", + "power_profile.performance": "Производительность", + "power_profile.power_save": "Экономия энергии", + "powermenu.exit_axctl": "Выйти из AxctlService", + "powermenu.hibernate": "Гибернация", + "powermenu.lock_session": "Заблокировать сессию", + "powermenu.power_off": "Выключить", + "powermenu.reboot": "Перезагрузка", + "powermenu.suspend": "Приостановить", + "presets.active": "АКТИВНЫЙ", + "presets.confirm_delete": "Удалить \"%1\"?", + "presets.create_new": "Создать новый пресет", + "presets.create_specific": "Создать пресет \"%1\"", + "presets.no_presets": "Пресеты не настроены", + "presets.official": "ОФИЦИАЛЬНЫЙ", + "presets.search": "Поиск или создание пресета...", + "presets.select_config_files": "Выберите файлы конфигурации для обновления:", + "presets.tap_to_create": "Нажмите для создания", + "presets.unknown_author": "Неизвестно", + "presets.update": "Обновить", + "presets.update_title": "Обновить \"%1\"", + "presets.visit_author": "Посетить автора", + "screenshot.region": "Область", + "screenshot.screen": "Экран", + "screenshot.window": "Окно", + "settings.ai": "AI", + "settings.ambxst": "Ambxst", + "settings.audio_effects": "Аудиоэффекты", + "settings.audio_mixer": "Аудиомикшер", + "settings.binds": "Горячие клавиши", + "settings.binds.assistant": "Горячая клавиша ассистента", + "settings.binds.clipboard": "Горячая клавиша буфера обмена", + "settings.binds.dashboard": "Горячая клавиша панели управления", + "settings.binds.emoji": "Горячая клавиша эмодзи", + "settings.binds.key_bindings": "Привязки клавиш", + "settings.binds.launcher": "Горячая клавиша запуска", + "settings.binds.lens": "Горячая клавиша Lens", + "settings.binds.lockscreen": "Горячая клавиша экрана блокировки", + "settings.binds.notes": "Горячая клавиша заметок", + "settings.binds.overview": "Горячая клавиша обзора", + "settings.binds.powermenu": "Горячая клавиша меню питания", + "settings.binds.quit": "Горячая клавиша выхода", + "settings.binds.reload": "Горячая клавиша перезагрузки", + "settings.binds.screenrecord": "Горячая клавиша записи экрана", + "settings.binds.screenshot": "Горячая клавиша снимка экрана", + "settings.binds.settings": "Горячая клавиша настроек", + "settings.binds.tmux": "Горячая клавиша Tmux", + "settings.binds.tools": "Горячая клавиша инструментов", + "settings.binds.wallpapers": "Горячая клавиша обоев", + "settings.bluetooth": "Bluetooth", + "settings.compositor": "Композитор", + "settings.compositor.axctl": "AxctlService", + "settings.compositor.blur_brightness": "Яркость размытия", + "settings.compositor.blur_contrast": "Контрастность размытия", + "settings.compositor.blur_enabled": "Размытие включено", + "settings.compositor.blur_ignore_opacity": "Размытие игнорирует прозрачность", + "settings.compositor.blur_ignorealpha": "Ignorealpha размытия", + "settings.compositor.blur_ignorealpha_value": "Значение Ignorealpha размытия", + "settings.compositor.blur_new_optimizations": "Новые оптимизации размытия", + "settings.compositor.blur_noise": "Шум размытия", + "settings.compositor.blur_passes": "Проходы размытия", + "settings.compositor.blur_size": "Размер размытия", + "settings.compositor.blur_vibrancy": "Насыщенность размытия", + "settings.compositor.blur_xray": "Рентгеновское размытие", + "settings.compositor.border_colors": "Цвета границы", + "settings.compositor.border_size": "Размер границы", + "settings.compositor.shadow_offset": "Смещение тени", + "settings.compositor.shadow_power": "Интенсивность тени", + "settings.compositor.shadow_range": "Дальность тени", + "settings.compositor.shadow_scale": "Масштаб тени", + "settings.compositor.shadows_enabled": "Тени включены", + "settings.compositor.sync_shadow_color": "Синхронизировать цвет тени", + "settings.compositor.sync_shadow_opacity": "Синхронизировать прозрачность тени", + "settings.compositor.window_gaps": "Отступы окон", + "settings.effects": "Эффекты", + "settings.mixer": "Микшер", + "settings.network": "Сеть", + "settings.shell.always_show_numbers": "Всегда показывать номера", + "settings.shell.available_on_fullscreen": "Доступно в полноэкранном режиме", + "settings.shell.bar": "Панель", + "settings.shell.bar_autohide": "Автоскрытие панели", + "settings.shell.bar_entry": "Панель", + "settings.shell.bar_position": "Положение панели", + "settings.shell.bar_screens": "Экраны панели", + "settings.shell.desktop": "Рабочий стол", + "settings.shell.desktop_enabled": "Рабочий стол включён", + "settings.shell.desktop_entry": "Рабочий стол", + "settings.shell.desktop_icon_size": "Размер иконок рабочего стола", + "settings.shell.desktop_text_color": "Цвет текста на рабочем столе", + "settings.shell.desktop_vertical_spacing": "Вертикальный отступ на рабочем столе", + "settings.shell.dock": "Док", + "settings.shell.dock_enabled": "Док включён", + "settings.shell.dock_entry": "Док", + "settings.shell.dock_height": "Высота дока", + "settings.shell.dock_hover_region_height": "Высота области наведения дока", + "settings.shell.dock_icon_size": "Размер иконок дока", + "settings.shell.dock_margin": "Поля дока", + "settings.shell.dock_mode": "Режим дока", + "settings.shell.dock_pinned_on_startup": "Док закреплён при запуске", + "settings.shell.dock_position": "Положение дока", + "settings.shell.dock_spacing": "Отступ дока", + "settings.shell.dynamic_workspaces": "Динамические рабочие пространства", + "settings.shell.firefox_player": "Плеер Firefox", + "settings.shell.frame": "Рамка", + "settings.shell.hover_region_height": "Высота области наведения", + "settings.shell.hover_to_reveal": "Показывать при наведении", + "settings.shell.launcher_icon": "Иконка запуска", + "settings.shell.launcher_icon_full_tint": "Полная тонировка иконки запуска", + "settings.shell.launcher_icon_size": "Размер иконки запуска", + "settings.shell.launcher_icon_tint": "Тонировка иконки запуска", + "settings.shell.lockscreen": "Экран блокировки", + "settings.shell.lockscreen_entry": "Экран блокировки", + "settings.shell.notch": "Notch", + "settings.shell.notch_entry": "Notch", + "settings.shell.overview": "Обзор", + "settings.shell.overview_columns": "Столбцы обзора", + "settings.shell.overview_entry": "Обзор", + "settings.shell.overview_rows": "Строки обзора", + "settings.shell.overview_scale": "Масштаб обзора", + "settings.shell.overview_workspace_spacing": "Отступ между рабочими пространствами в обзоре", + "settings.shell.pill_style": "Стиль индикатора", + "settings.shell.pinned_on_startup": "Закреплено при запуске", + "settings.shell.show_app_icons": "Показывать иконки приложений", + "settings.shell.show_numbers": "Показывать номера", + "settings.shell.show_overview_button": "Показывать кнопку обзора", + "settings.shell.show_pin_button": "Показывать кнопку закрепления", + "settings.shell.show_running_indicators": "Показывать индикаторы запущенных приложений", + "settings.shell.sidebar": "Боковая панель", + "settings.shell.system": "Система", + "settings.shell.system_entry": "Система оболочки", + "settings.shell.workspaces": "Рабочие пространства", + "settings.shell.workspaces_entry": "Рабочие пространства", + "settings.shell.workspaces_shown": "Отображаемые рабочие пространства", + "settings.system": "Система", + "settings.system.after_sleep": "После сна", + "settings.system.before_sleep": "Перед сном", + "settings.system.blur_transition": "Переход размытия", + "settings.system.clipboard_prefix": "Префикс буфера обмена", + "settings.system.emoji_prefix": "Префикс эмодзи", + "settings.system.idle": "Простой", + "settings.system.idle_listener": "Слушатель простоя", + "settings.system.idle_settings": "Настройки простоя", + "settings.system.language": "Язык", + "settings.system.lock_command": "Команда блокировки", + "settings.system.notes_prefix": "Префикс заметок", + "settings.system.performance": "Производительность", + "settings.system.prefixes": "Префиксы", + "settings.system.prefixes_entry": "Префиксы", + "settings.system.resources": "Ресурсы системы", + "settings.system.system_resources": "Ресурсы системы", + "settings.system.temperature_unit": "Единица температуры", + "settings.system.tmux_prefix": "Префикс Tmux", + "settings.system.wallpapers_prefix": "Префикс обоев", + "settings.system.wavy_line": "Волнистая линия", + "settings.system.weather": "Погода", + "settings.system.weather_location": "Местоположение для погоды", + "settings.system.window_preview": "Предпросмотр окон", + "settings.theme": "Тема", + "settings.theme.animation": "Анимация", + "settings.theme.animation_duration": "Длительность анимации", + "settings.theme.background_variant": "Вариант фона", + "settings.theme.bar_bg_variant": "Вариант фона панели", + "settings.theme.color_border": "Цветная граница", + "settings.theme.color_opacity": "Прозрачность цвета", + "settings.theme.color_scheme": "Цветовая схема", + "settings.theme.color_variant": "Вариант цвета", + "settings.theme.colors": "Цвета", + "settings.theme.duration": "Длительность", + "settings.theme.editor": "Редактор", + "settings.theme.enable_corners": "Включить скруглённые углы", + "settings.theme.fonts": "Шрифты", + "settings.theme.general": "Основное", + "settings.theme.gradient_angle": "Угол градиента", + "settings.theme.internal_bg_variant": "Вариант внутреннего фона", + "settings.theme.mono_font": "Моноширинный шрифт", + "settings.theme.pane_variant": "Вариант панели", + "settings.theme.popup_variant": "Вариант всплывающего окна", + "settings.theme.roundness": "Скруглённость", + "settings.theme.shadow": "Тень", + "settings.theme.shadow_blur": "Размытие тени", + "settings.theme.shadow_offset": "Смещение тени", + "settings.theme.shadow_opacity": "Прозрачность тени", + "settings.theme.tint_icons": "Тонировать иконки", + "settings.theme.ui_font": "Шрифт интерфейса", + "settings.theme.variant": "Вариант", + "settings.theme.wallpapers": "Обои", + "shell.autohide": "Автоскрытие", + "shell.available_on_fullscreen": "Доступно в полноэкранном режиме", + "shell.desktop.enabled": "Включено", + "shell.desktop.icon_size": "Размер иконок", + "shell.desktop.text_color": "Цвет текста", + "shell.desktop.vertical_spacing": "Вертикальный отступ", + "shell.dock.enabled": "Включено", + "shell.dock.floating": "Плавающий", + "shell.dock.height": "Высота", + "shell.dock.hover_region": "Область наведения", + "shell.dock.icon_size": "Размер иконок", + "shell.dock.integrated": "Встроенный", + "shell.dock.island": "Островной", + "shell.dock.keep_hidden": "Держать скрытым", + "shell.dock.margin": "Поля", + "shell.dock.spacing": "Отступ", + "shell.dock.theme": "Тема", + "shell.enable_firefox_player": "Включить плеер Firefox", + "shell.excluded_sinks": "Исключённые аудиовыходы", + "shell.frame.contain_bar": "Вмещать панель", + "shell.frame.enabled": "Включено", + "shell.frame.keep_bar_border": "Сохранять границу панели", + "shell.frame.keep_bar_shadow": "Сохранять тень панели", + "shell.frame.thickness": "Толщина", + "shell.hover_region_height": "Высота области наведения", + "shell.hover_reveal": "Показывать при наведении", + "shell.hover_to_reveal": "Показывать при наведении", + "shell.launcher_icon": "Иконка запуска", + "shell.launcher_icon_full_tint": "Полная тонировка иконки запуска", + "shell.launcher_icon_size": "Размер иконки запуска", + "shell.launcher_icon_tint": "Тонировка иконки запуска", + "shell.lockscreen.position": "Положение", + "shell.no_media_display": "Нет отображения медиа", + "shell.notch.compositor": "Композитор", + "shell.notch.custom_text": "Пользовательский текст", + "shell.notch.disable_hover_expansion": "Отключить расширение при наведении", + "shell.notch.enter_text": "Введите текст...", + "shell.notch.keep_hidden": "Держать скрытым", + "shell.notch.user_host": "user@host", + "shell.overview.columns": "Столбцы", + "shell.overview.rows": "Строки", + "shell.overview.scale": "Масштаб", + "shell.overview.workspace_spacing": "Отступ между рабочими пространствами", + "shell.pill_style": "Стиль индикатора", + "shell.pinned_on_startup": "Закреплено при запуске", + "shell.position": "Положение", + "shell.screens": "Экраны", + "shell.screens_empty": "Пусто = все экраны", + "shell.shell": "Оболочка", + "shell.show_audio_switcher": "Показывать переключатель аудиоустройств", + "shell.show_keyboard_layout": "Показывать раскладку клавиатуры", + "shell.show_overview_button": "Показывать кнопку обзора", + "shell.show_pin_button": "Показывать кнопку закрепления", + "shell.show_running_indicators": "Показывать индикаторы запущенных приложений", + "shell.sidebar.width": "Ширина", + "shell.squished": "Сжатый", + "shell.system.about_ambxst": "Об Ambxst %1", + "shell.system.donate": "Поддержать ❤️", + "shell.system.ocr_chinese_simplified": "Китайский (упрощённый)", + "shell.system.ocr_chinese_traditional": "Китайский (традиционный)", + "shell.system.ocr_english": "Английский", + "shell.system.ocr_japanese": "Японский", + "shell.system.ocr_korean": "Корейский", + "shell.system.ocr_languages": "Языки OCR", + "shell.system.ocr_latin": "Латинский", + "shell.system.ocr_russian": "Русский", + "shell.system.ocr_spanish": "Испанский", + "shell.system.update_service": "Служба обновлений", + "shell.use_12h_format": "Использовать 12-часовой формат", + "shell.workspaces.always_show_numbers": "Всегда показывать номера", + "shell.workspaces.dynamic": "Динамические", + "shell.workspaces.show_app_icons": "Показывать иконки приложений", + "shell.workspaces.show_numbers": "Показывать номера", + "shell.workspaces.shown": "Отображаются", + "system.add_disk": "Добавить диск", + "system.disk_path_placeholder": "например, /, /home...", + "system.performance.blur_transition_desc": "Анимированное размытие при открытии панелей", + "system.performance.description": "Управление визуальными эффектами для улучшения производительности", + "system.performance.disable_cover_rotation": "Отключить вращение обложки", + "system.performance.disable_cover_rotation_desc": "Остановить вращение виниловой пластинки", + "system.performance.wavy_line_desc": "Эффект анимированной волнистой линии", + "system.performance.window_preview_desc": "Показывать миниатюры окон в обзоре", + "system.prefixes.clipboard": "Буфер обмена", + "system.prefixes.description": "Сочетания клавиш для быстрых действий в запуске приложений", + "system.prefixes.emoji": "Эмодзи", + "system.prefixes.notes": "Заметки", + "system.prefixes.tmux": "Tmux", + "system.prefixes.wallpapers": "Обои", + "system.remove_disk": "Удалить диск", + "system.resources.description": "Настройте, за какими дисками вести наблюдение", + "theme.add_stop": "Добавить точку", + "theme.angle": "Угол", + "theme.background": "Фон", + "theme.border": "Граница", + "theme.color": "Цвет", + "theme.color_picker": "Выбор цвета", + "theme.custom": "Пользовательский", + "theme.delete_stop": "Удалить точку", + "theme.dot_color": "Цвет точки", + "theme.editor_label": "Редактор — %1", + "theme.gradient_mode": "Режим градиента", + "theme.gradient_stops": "Точки градиента", + "theme.item_color": "Цвет элемента", + "theme.opacity": "Прозрачность", + "theme.open_color_picker": "Открыть палитру цветов", + "theme.position": "Положение", + "theme.range": "Диапазон", + "theme.reset_gradient": "Сбросить градиент", + "theme.select_color": "Выберите цвет", + "theme.shadow.blur": "Размытие", + "theme.shadow.color": "Цвет", + "theme.shadow.offset_x": "Смещение X", + "theme.shadow.offset_y": "Смещение Y", + "theme.shadow.opacity": "Прозрачность", + "theme.size": "Размер", + "theme.stop_n": "Точка %1", + "theme.symbol_or_icon": "Символ или путь к иконке...", + "tmux.loading_panes": "Загрузка панелей...", + "tmux.no_panes": "Нет панелей для отображения", + "tmux.no_session": "Сессия не выбрана", + "tmux.open_terminal": "Открыть терминал", + "tmux.quit": "Завершить", + "tmux.search": "Поиск или создание tmux-сессии...", + "tmux.select_session_hint": "Выберите сессию для просмотра", + "tools.color_picker": "Выбор цвета", + "tools.google_lens": "Google Lens", + "tools.mirror": "Зеркало", + "tools.ocr": "OCR", + "tools.qr": "QR-код", + "tools.screenrecord_directory": "Открыть записи", + "tools.screenrecord_portal": "Портал", + "tools.screenrecord_region": "Область", + "tools.screenrecord_region_unavailable": "Область (Недоступно на NixOS без настройки)", + "tools.screenrecord_screen": "Экран", + "tools.screenrecord_screen_unavailable": "Экран (Недоступно на NixOS без настройки)", + "tools.screenrecord_start": "Запись экрана", + "tools.screenrecord_stop": "Остановить запись", + "tools.screenrecord_window": "Окно", + "tools.screenrecord_window_unavailable": "Окно (Недоступно на NixOS без настройки)", + "tools.screenshot": "Скриншот", + "tools.screenshot_directory": "Открыть скриншоты", + "tools.toggle_audio": "Переключить аудиовыход", + "tools.toggle_mic": "Переключить микрофон", + "wallpapers.current": "ТЕКУЩИЙ", + "wallpapers.edit_gradia": "Изменить в Gradia", + "wallpapers.filter_images": "Изображения", + "wallpapers.filter_videos": "Видео", + "wallpapers.oled": "OLED", + "wallpapers.scheme_content": "Содержание", + "wallpapers.scheme_expressive": "Выразительный", + "wallpapers.scheme_fidelity": "Точность", + "wallpapers.scheme_fruit_salad": "Фруктовый салат", + "wallpapers.scheme_monochrome": "Монохромный", + "wallpapers.scheme_neutral": "Нейтральный", + "wallpapers.scheme_rainbow": "Радуга", + "wallpapers.scheme_tonal_spot": "Тональная точка", + "wallpapers.search": "Поиск обоев...", + "wallpapers.select_scheme": "Выбрать схему", + "wallpapers.set": "Установить", + "wallpapers.tint": "Тон", + "weather.celsius": "Цельсий", + "weather.fahrenheit": "Фаренгейт", + "weather.location": "Местоположение", + "weather.location_placeholder": "например, Москва, Санкт-Петербург...", + "weather.today": "Сегодня", + "weather.unit": "Единица", + "wifi.band_5g": "5G", + "wifi.connect": "Подключить", + "wifi.connected": "Подключено", + "wifi.connecting": "Подключение...", + "wifi.disabled": "Wi-Fi отключён", + "wifi.disconnect": "Отключить", + "wifi.limited": "Ограниченный доступ", + "wifi.network_settings": "Настройки сети", + "wifi.no_networks": "Сети не найдены", + "wifi.open": "Открытая", + "wifi.open_portal": "Открыть портал авторизации", + "wifi.password": "Введите пароль...", + "wifi.rescan": "Повторить поиск сетей", + "wifi.secured": "Защищённая", + "wifi.title": "Wi-Fi", + "wifi.tooltip_off": "Wi-Fi: Выкл", + "wifi.tooltip_on": "Wi-Fi: Вкл" +} From 8550136f6b45c3adab84d88bd80e277ebbe9bd9e Mon Sep 17 00:00:00 2001 From: flathead Date: Fri, 27 Mar 2026 22:08:26 +0300 Subject: [PATCH 2/9] fix(i18n): migrate Ai.qml and fix OSD.qml i18n calls OSD.qml: fix i18n.t() -> I18n.t() (lowercase caused empty strings) Ai.qml: migrate hardcoded user-visible strings to I18n.t(): - /model command: model not found, switched to model messages - /help command: full help message - API key missing error (with model name and key_id substitution) - Network request failed error - No response from API message - Command executed successfully (no output) message - Model descriptions for all 6 providers translations: add 13 new keys to en/ru/es (ai.api_key_missing, ai.cmd_no_output, ai.desc_*, ai.env_variable, ai.help_message, ai.model_not_found, ai.network_failed, ai.no_response, ai.switched_to_model) --- modules/services/Ai.qml | 26 +++++++++++++------------- modules/shell/osd/OSD.qml | 6 +++--- translations/en.json | 17 +++++++++++++++++ translations/es.json | 17 +++++++++++++++++ translations/ru.json | 19 ++++++++++++++++++- 5 files changed, 68 insertions(+), 17 deletions(-) diff --git a/modules/services/Ai.qml b/modules/services/Ai.qml index eaedc4404..a3372ca3a 100644 --- a/modules/services/Ai.qml +++ b/modules/services/Ai.qml @@ -257,16 +257,16 @@ Singleton { } } if (!found) { - pushSystemMessage("Model '" + args + "' not found."); + pushSystemMessage(I18n.t("ai.model_not_found").replace("%1", args)); } else { - pushSystemMessage("Switched to model: " + currentModel.name); + pushSystemMessage(I18n.t("ai.switched_to_model").replace("%1", currentModel.name)); } } else { modelSelectionRequested(); } return true; case "/help": - pushSystemMessage("🤖 **Assistant Commands**\n\n" + "**`/new`**\n" + "Starts a fresh conversation context.\n\n" + "**`/model [name]`**\n" + "Switches the active AI model.\n" + "• **List models:** Type `/model` without arguments.\n" + "• **Switch:** Type `/model gemini` or `/model mistral`.\n\n" + "**`/help`**\n" + "Shows this help message.\n\n" + "💡 **Tips:**\n" + "• **Edit:** Click the pen icon on any message to modify it.\n" + "• **Regenerate:** Click the refresh icon to get a new response.\n" + "• **Copy:** Use the copy button to grab code or text."); + pushSystemMessage(I18n.t("ai.help_message")); return true; } @@ -341,7 +341,7 @@ Singleton { function makeRequest() { let apiKey = getApiKey(currentModel); if (!apiKey && currentModel.requires_key) { - lastError = "API Key missing for " + currentModel.name + ". Add it in Settings or set " + (currentModel.key_id || "the environment variable") + "."; + lastError = I18n.t("ai.api_key_missing").replace("%1", currentModel.name).replace("%2", currentModel.key_id || I18n.t("ai.env_variable")); isLoading = false; let errChat = Array.from(currentChat); @@ -531,14 +531,14 @@ Singleton { let lastMsg = root.currentChat[root.currentChat.length - 1]; if (!lastMsg.content) { let newChat = Array.from(root.currentChat); - newChat[newChat.length - 1].content = "No response received from the API."; + newChat[newChat.length - 1].content = I18n.t("ai.no_response"); root.currentChat = newChat; } } root.saveCurrentChat(); } else { - root.lastError = "Network Request Failed: " + curlStderr.text; + root.lastError = I18n.t("ai.network_failed").replace("%1", curlStderr.text); // Update the placeholder message with error let errChat = Array.from(root.currentChat); @@ -566,7 +566,7 @@ Singleton { onExited: exitCode => { let output = cmdStdout.text + "\n" + cmdStderr.text; if (output.trim() === "") - output = "Command executed successfully (no output)."; + output = I18n.t("ai.cmd_no_output"); let msg = currentChat[targetIndex]; let newChat = Array.from(currentChat); @@ -791,7 +791,7 @@ for f in files: let m = aiModelFactory.createObject(root, { name: item.displayName || id, icon: Qt.resolvedUrl("../../../assets/aiproviders/google.svg"), - description: item.description || "Google Gemini Model", + description: item.description || I18n.t("ai.desc_google"), endpoint: "https://generativelanguage.googleapis.com/v1beta", model: id, provider: "gemini", @@ -837,7 +837,7 @@ for f in files: let m = aiModelFactory.createObject(root, { name: id, icon: Qt.resolvedUrl("../../../assets/aiproviders/openai.svg"), - description: "OpenAI Model", + description: I18n.t("ai.desc_openai"), endpoint: "https://api.openai.com", model: id, provider: "openai", @@ -874,7 +874,7 @@ for f in files: let m = aiModelFactory.createObject(root, { name: id, icon: Qt.resolvedUrl("../../../assets/aiproviders/mistral.svg"), - description: "Mistral Model", + description: I18n.t("ai.desc_mistral"), endpoint: "https://api.mistral.ai/v1", model: id, provider: "mistral", @@ -910,7 +910,7 @@ for f in files: let m = aiModelFactory.createObject(root, { name: id, icon: Qt.resolvedUrl("../../../assets/aiproviders/groq.svg"), - description: "Groq Model", + description: I18n.t("ai.desc_groq"), endpoint: "https://api.groq.com/openai/v1", model: id, provider: "groq", @@ -946,7 +946,7 @@ for f in files: let m = aiModelFactory.createObject(root, { name: item.display_name || id, icon: Qt.resolvedUrl("../../../assets/aiproviders/anthropic.svg"), - description: item.description || "Anthropic Model", + description: item.description || I18n.t("ai.desc_anthropic"), endpoint: "https://api.anthropic.com/v1/messages", model: id, provider: "anthropic", @@ -981,7 +981,7 @@ for f in files: let m = aiModelFactory.createObject(root, { name: item.name, icon: Qt.resolvedUrl("../../../assets/aiproviders/ollama.svg"), - description: "Local Ollama Model", + description: I18n.t("ai.desc_ollama"), endpoint: "http://127.0.0.1:11434", model: item.name, provider: "ollama", diff --git a/modules/shell/osd/OSD.qml b/modules/shell/osd/OSD.qml index 432f771d6..f8bb86322 100644 --- a/modules/shell/osd/OSD.qml +++ b/modules/shell/osd/OSD.qml @@ -103,11 +103,11 @@ PanelWindow { Text { text: { if (GlobalStates.osdIndicator === "volume") - return "Volume"; + return I18n.t("osd.volume"); if (GlobalStates.osdIndicator === "mic") - return "Microphone"; + return I18n.t("osd.mic"); if (GlobalStates.osdIndicator === "brightness") - return "Brightness"; + return I18n.t("osd.brightness"); return ""; } font.family: Config.theme.font diff --git a/translations/en.json b/translations/en.json index c7b484193..bf9fb6164 100644 --- a/translations/en.json +++ b/translations/en.json @@ -1,8 +1,10 @@ { "_meta.direction": "ltr", + "ai.api_key_missing": "API Key missing for %1. Add it in Settings or set %2.", "ai.approve": "Approve", "ai.ask_or_help": "Ask AI or type /help...", "ai.chat_history": "Chat History", + "ai.cmd_no_output": "Command executed successfully (no output).", "ai.cmd_set_api_key": "Set API key", "ai.cmd_set_system_prompt": "Set system prompt", "ai.cmd_show_help": "Show help", @@ -10,6 +12,13 @@ "ai.cmd_switch_model": "Switch AI model", "ai.command_approved": "Command Approved", "ai.command_rejected": "Command Rejected", + "ai.desc_anthropic": "Anthropic Model", + "ai.desc_google": "Google Gemini Model", + "ai.desc_groq": "Groq Model", + "ai.desc_mistral": "Mistral Model", + "ai.desc_ollama": "Local Ollama Model", + "ai.desc_openai": "OpenAI Model", + "ai.env_variable": "the environment variable", "ai.curl_placeholder": "curl -X POST...", "ai.curl_placeholders": "Placeholders: {{ENDPOINT}}, {{API_KEY}}, {{BODY_PATH}}", "ai.custom_curl": "Custom cURL Template", @@ -18,13 +27,18 @@ "ai.custom_provider_key": "Custom Provider API Key", "ai.endpoint_placeholder": "e.g. https://...", "ai.enter_api_key": "Enter API Key...", + "ai.help_message": "🤖 **Assistant Commands**\n\n**`/new`**\nStarts a fresh conversation context.\n\n**`/model [name]`**\nSwitches the active AI model.\n- **List models:** Type `/model` without arguments.\n- **Switch:** Type `/model gemini` or `/model mistral`.\n\n**`/help`**\nShows this help message.\n\n💡 **Tips:**\n- **Edit:** Click the pen icon on any message to modify it.\n- **Regenerate:** Click the refresh icon to get a new response.\n- **Copy:** Use the copy button to grab code or text.", "ai.hello_user": "Hello, %1.", + "ai.model_not_found": "Model '%1' not found.", "ai.message": "Message AI...", + "ai.network_failed": "Network Request Failed: %1", + "ai.no_response": "No response received from the API.", "ai.panel_title": "AI & API Keys", "ai.refresh_models": "Refresh?", "ai.reject": "Reject", "ai.run_command": "Run Command", "ai.search_models": "Search models...", + "ai.switched_to_model": "Switched to model: %1", "bar.tooltip.audio_switcher": "Audio Device Switcher", "bar.tooltip.controls": "Audio & Brightness Controls", "bar.tooltip.keyboard_layout": "Keyboard Layout", @@ -247,6 +261,9 @@ "notifications.now": "Now", "notifications.panel_title": "Notifications", "notifications.yesterday": "Yesterday", + "osd.brightness": "Brightness", + "osd.mic": "Microphone", + "osd.volume": "Volume", "overview.search": "Search windows...", "performance.blur_transition": "Blur Transition", "performance.dashboard_persist": "Persist Dashboard Tabs", diff --git a/translations/es.json b/translations/es.json index 75c74feab..4bb1c3801 100644 --- a/translations/es.json +++ b/translations/es.json @@ -1,8 +1,10 @@ { "_meta.direction": "ltr", + "ai.api_key_missing": "Falta la clave API para %1. Agrégala en Configuración o establece %2.", "ai.approve": "Aprobar", "ai.ask_or_help": "Pregunta al AI o escribe /help...", "ai.chat_history": "Historial de chat", + "ai.cmd_no_output": "Comando ejecutado correctamente (sin salida).", "ai.cmd_set_api_key": "Establecer clave API", "ai.cmd_set_system_prompt": "Establecer prompt del sistema", "ai.cmd_show_help": "Mostrar ayuda", @@ -10,6 +12,13 @@ "ai.cmd_switch_model": "Cambiar modelo de AI", "ai.command_approved": "Comando aprobado", "ai.command_rejected": "Comando rechazado", + "ai.desc_anthropic": "Modelo de Anthropic", + "ai.desc_google": "Modelo de Google Gemini", + "ai.desc_groq": "Modelo de Groq", + "ai.desc_mistral": "Modelo de Mistral", + "ai.desc_ollama": "Modelo local de Ollama", + "ai.desc_openai": "Modelo de OpenAI", + "ai.env_variable": "la variable de entorno", "ai.curl_placeholder": "curl -X POST...", "ai.curl_placeholders": "Marcadores: {{ENDPOINT}}, {{API_KEY}}, {{BODY_PATH}}", "ai.custom_curl": "Plantilla cURL personalizada", @@ -18,13 +27,18 @@ "ai.custom_provider_key": "Clave API del proveedor personalizado", "ai.endpoint_placeholder": "ej. https://...", "ai.enter_api_key": "Ingresar clave API...", + "ai.help_message": "🤖 **Comandos del asistente**\n\n**`/new`**\nInicia un nuevo contexto de conversación.\n\n**`/model [nombre]`**\nCambia el modelo de AI activo.\n- **Lista de modelos:** Escribe `/model` sin argumentos.\n- **Cambiar:** Escribe `/model gemini` o `/model mistral`.\n\n**`/help`**\nMuestra este mensaje de ayuda.\n\n💡 **Consejos:**\n- **Editar:** Haz clic en el ícono de lápiz en cualquier mensaje.\n- **Regenerar:** Haz clic en el ícono de actualizar para obtener una nueva respuesta.\n- **Copiar:** Usa el botón de copiar para código o texto.", "ai.hello_user": "Hola, %1.", + "ai.model_not_found": "Modelo '%1' no encontrado.", "ai.message": "Mensaje al AI...", + "ai.network_failed": "Error de red: %1", + "ai.no_response": "La API no devolvió ninguna respuesta.", "ai.panel_title": "AI y claves API", "ai.refresh_models": "¿Actualizar?", "ai.reject": "Rechazar", "ai.run_command": "Ejecutar comando", "ai.search_models": "Buscar modelos...", + "ai.switched_to_model": "Modelo cambiado: %1", "bar.tooltip.audio_switcher": "Selector de dispositivo de audio", "bar.tooltip.controls": "Controles de audio y brillo", "bar.tooltip.keyboard_layout": "Disposición del teclado", @@ -247,6 +261,9 @@ "notifications.now": "Ahora", "notifications.panel_title": "Notificaciones", "notifications.yesterday": "Ayer", + "osd.brightness": "Brillo", + "osd.mic": "Micrófono", + "osd.volume": "Volumen", "overview.search": "Buscar ventanas...", "performance.blur_transition": "Transición de desenfoque", "performance.dashboard_persist": "Mantener pestañas del panel", diff --git a/translations/ru.json b/translations/ru.json index 0e2685d4c..f8137709d 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -1,8 +1,10 @@ { "_meta.direction": "ltr", + "ai.api_key_missing": "API-ключ отсутствует для %1. Добавьте его в настройках или задайте %2.", "ai.approve": "Одобрить", "ai.ask_or_help": "Спросите AI или введите /help...", "ai.chat_history": "История чата", + "ai.cmd_no_output": "Команда выполнена успешно (вывод отсутствует).", "ai.cmd_set_api_key": "Установить API ключ", "ai.cmd_set_system_prompt": "Установить системный промпт", "ai.cmd_show_help": "Показать справку", @@ -10,6 +12,13 @@ "ai.cmd_switch_model": "Переключить модель AI", "ai.command_approved": "Команда одобрена", "ai.command_rejected": "Команда отклонена", + "ai.desc_anthropic": "Модель Anthropic", + "ai.desc_google": "Модель Google Gemini", + "ai.desc_groq": "Модель Groq", + "ai.desc_mistral": "Модель Mistral", + "ai.desc_ollama": "Локальная модель Ollama", + "ai.desc_openai": "Модель OpenAI", + "ai.env_variable": "переменную окружения", "ai.curl_placeholder": "curl -X POST...", "ai.curl_placeholders": "Заполнители: {{ENDPOINT}}, {{API_KEY}}, {{BODY_PATH}}", "ai.custom_curl": "Пользовательский шаблон cURL", @@ -18,13 +27,18 @@ "ai.custom_provider_key": "API-ключ пользовательского провайдера", "ai.endpoint_placeholder": "например, https://...", "ai.enter_api_key": "Введите API-ключ...", + "ai.help_message": "🤖 **Команды ассистента**\n\n**`/new`**\nНачинает новый контекст разговора.\n\n**`/model [название]`**\nПереключает активную модель AI.\n- **Список моделей:** Введите `/model` без аргументов.\n- **Переключение:** Введите `/model gemini` или `/model mistral`.\n\n**`/help`**\nПоказывает это сообщение.\n\n💡 **Советы:**\n- **Редактировать:** Нажмите на значок карандаша у любого сообщения.\n- **Повторить:** Нажмите на значок обновления для нового ответа.\n- **Копировать:** Используйте кнопку копирования для кода или текста.", "ai.hello_user": "Привет, %1.", + "ai.model_not_found": "Модель '%1' не найдена.", "ai.message": "Сообщение AI...", + "ai.network_failed": "Ошибка сети: %1", + "ai.no_response": "API не вернул ответ.", "ai.panel_title": "AI и API-ключи", "ai.refresh_models": "Обновить?", "ai.reject": "Отклонить", "ai.run_command": "Выполнить команду", "ai.search_models": "Поиск моделей...", + "ai.switched_to_model": "Модель переключена: %1", "bar.tooltip.audio_switcher": "Переключатель аудиоустройств", "bar.tooltip.controls": "Управление звуком и яркостью", "bar.tooltip.keyboard_layout": "Раскладка клавиатуры", @@ -247,6 +261,9 @@ "notifications.now": "Сейчас", "notifications.panel_title": "Уведомления", "notifications.yesterday": "Вчера", + "osd.brightness": "Яркость", + "osd.mic": "Микрофон", + "osd.volume": "Громкость", "overview.search": "Поиск окон...", "performance.blur_transition": "Переход размытия", "performance.dashboard_persist": "Сохранять вкладки панели управления", @@ -406,7 +423,7 @@ "settings.system.blur_transition": "Переход размытия", "settings.system.clipboard_prefix": "Префикс буфера обмена", "settings.system.emoji_prefix": "Префикс эмодзи", - "settings.system.idle": "Простой", + "settings.system.idle": "Простой (Idle)", "settings.system.idle_listener": "Слушатель простоя", "settings.system.idle_settings": "Настройки простоя", "settings.system.language": "Язык", From 6eee5bb0faec5f801c488b42aa82c61ff15f3336 Mon Sep 17 00:00:00 2001 From: flathead Date: Fri, 27 Mar 2026 23:34:22 +0300 Subject: [PATCH 3/9] i18n: add resource monitor translation keys (en/ru/es) Adds keys for the new resource monitor settings screen: enabled toggle, location (bar/dashboard), bar side, visible items (CPU/RAM/GPU/disk), disk list title, save/unsaved status, and bar tooltip. Co-Authored-By: Claude Sonnet 4.6 --- translations/en.json | 19 ++++++++++++++++++- translations/es.json | 19 ++++++++++++++++++- translations/ru.json | 19 ++++++++++++++++++- 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/translations/en.json b/translations/en.json index bf9fb6164..b8037c753 100644 --- a/translations/en.json +++ b/translations/en.json @@ -39,6 +39,7 @@ "ai.run_command": "Run Command", "ai.search_models": "Search models...", "ai.switched_to_model": "Switched to model: %1", + "bar.resources.tooltip": "System Resources", "bar.tooltip.audio_switcher": "Audio Device Switcher", "bar.tooltip.controls": "Audio & Brightness Controls", "bar.tooltip.keyboard_layout": "Keyboard Layout", @@ -361,6 +362,7 @@ "settings.effects": "Effects", "settings.mixer": "Mixer", "settings.network": "Network", + "settings.save": "Save", "settings.shell.always_show_numbers": "Always Show Numbers", "settings.shell.available_on_fullscreen": "Available on Fullscreen", "settings.shell.bar": "Bar", @@ -559,7 +561,22 @@ "system.prefixes.tmux": "Tmux", "system.prefixes.wallpapers": "Wallpapers", "system.remove_disk": "Remove disk", - "system.resources.description": "Configure which disks to monitor", + "system.resources.bar_side": "Bar Position", + "system.resources.bar_side_left": "Left", + "system.resources.bar_side_right": "Right", + "system.resources.description": "Configure resource display and monitored disks", + "system.resources.disks_title": "Monitored Disks", + "system.resources.enabled": "Enable Resource Monitor", + "system.resources.location": "Display Location", + "system.resources.location_bar": "Bar", + "system.resources.location_dashboard": "Dashboard", + "system.resources.saved": "Saved", + "system.resources.show_cpu": "CPU", + "system.resources.show_disk": "Disk", + "system.resources.show_gpu": "GPU", + "system.resources.show_items": "Visible Items", + "system.resources.show_ram": "RAM", + "system.resources.unsaved": "Unsaved changes", "theme.add_stop": "Add Stop", "theme.angle": "Angle", "theme.background": "Background", diff --git a/translations/es.json b/translations/es.json index 4bb1c3801..abc1f3d42 100644 --- a/translations/es.json +++ b/translations/es.json @@ -39,6 +39,7 @@ "ai.run_command": "Ejecutar comando", "ai.search_models": "Buscar modelos...", "ai.switched_to_model": "Modelo cambiado: %1", + "bar.resources.tooltip": "Recursos del sistema", "bar.tooltip.audio_switcher": "Selector de dispositivo de audio", "bar.tooltip.controls": "Controles de audio y brillo", "bar.tooltip.keyboard_layout": "Disposición del teclado", @@ -361,6 +362,7 @@ "settings.effects": "Efectos", "settings.mixer": "Mezclador", "settings.network": "Red", + "settings.save": "Guardar", "settings.shell.always_show_numbers": "Mostrar siempre los números", "settings.shell.available_on_fullscreen": "Disponible en pantalla completa", "settings.shell.bar": "Barra", @@ -559,7 +561,22 @@ "system.prefixes.tmux": "Tmux", "system.prefixes.wallpapers": "Fondos de pantalla", "system.remove_disk": "Quitar disco", - "system.resources.description": "Configurar qué discos monitorear", + "system.resources.bar_side": "Posición en la barra", + "system.resources.bar_side_left": "Izquierda", + "system.resources.bar_side_right": "Derecha", + "system.resources.description": "Configurar la visualización de recursos y los discos monitoreados", + "system.resources.disks_title": "Discos monitoreados", + "system.resources.enabled": "Activar monitor de recursos", + "system.resources.location": "Ubicación de visualización", + "system.resources.location_bar": "Barra", + "system.resources.location_dashboard": "Panel", + "system.resources.saved": "Guardado", + "system.resources.show_cpu": "CPU", + "system.resources.show_disk": "Disco", + "system.resources.show_gpu": "GPU", + "system.resources.show_items": "Elementos visibles", + "system.resources.show_ram": "RAM", + "system.resources.unsaved": "Cambios sin guardar", "theme.add_stop": "Agregar parada", "theme.angle": "Ángulo", "theme.background": "Fondo", diff --git a/translations/ru.json b/translations/ru.json index f8137709d..ef0eb3bfa 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -39,6 +39,7 @@ "ai.run_command": "Выполнить команду", "ai.search_models": "Поиск моделей...", "ai.switched_to_model": "Модель переключена: %1", + "bar.resources.tooltip": "Ресурсы системы", "bar.tooltip.audio_switcher": "Переключатель аудиоустройств", "bar.tooltip.controls": "Управление звуком и яркостью", "bar.tooltip.keyboard_layout": "Раскладка клавиатуры", @@ -361,6 +362,7 @@ "settings.effects": "Эффекты", "settings.mixer": "Микшер", "settings.network": "Сеть", + "settings.save": "Сохранить", "settings.shell.always_show_numbers": "Всегда показывать номера", "settings.shell.available_on_fullscreen": "Доступно в полноэкранном режиме", "settings.shell.bar": "Панель", @@ -559,7 +561,22 @@ "system.prefixes.tmux": "Tmux", "system.prefixes.wallpapers": "Обои", "system.remove_disk": "Удалить диск", - "system.resources.description": "Настройте, за какими дисками вести наблюдение", + "system.resources.bar_side": "Расположение на панели", + "system.resources.bar_side_left": "Слева", + "system.resources.bar_side_right": "Справа", + "system.resources.description": "Настройте отображение ресурсов и список наблюдаемых дисков", + "system.resources.disks_title": "Наблюдаемые диски", + "system.resources.enabled": "Включить монитор ресурсов", + "system.resources.location": "Место отображения", + "system.resources.location_bar": "Панель", + "system.resources.location_dashboard": "Дашборд", + "system.resources.saved": "Сохранено", + "system.resources.show_cpu": "ЦП", + "system.resources.show_disk": "Диск", + "system.resources.show_gpu": "ГП", + "system.resources.show_items": "Отображаемые элементы", + "system.resources.show_ram": "ОЗУ", + "system.resources.unsaved": "Несохранённые изменения", "theme.add_stop": "Добавить точку", "theme.angle": "Угол", "theme.background": "Фон", From ac94b10dcdb870736d8ee00f8f479c364ede1a78 Mon Sep 17 00:00:00 2001 From: flathead Date: Sat, 28 Mar 2026 14:56:13 +0300 Subject: [PATCH 4/9] i18n: add location_both key for resource monitor (en/ru/es) Co-Authored-By: Claude Sonnet 4.6 --- translations/en.json | 1 + translations/es.json | 1 + translations/ru.json | 1 + 3 files changed, 3 insertions(+) diff --git a/translations/en.json b/translations/en.json index b8037c753..092a20a8d 100644 --- a/translations/en.json +++ b/translations/en.json @@ -569,6 +569,7 @@ "system.resources.enabled": "Enable Resource Monitor", "system.resources.location": "Display Location", "system.resources.location_bar": "Bar", + "system.resources.location_both": "Both", "system.resources.location_dashboard": "Dashboard", "system.resources.saved": "Saved", "system.resources.show_cpu": "CPU", diff --git a/translations/es.json b/translations/es.json index abc1f3d42..8e176f33f 100644 --- a/translations/es.json +++ b/translations/es.json @@ -569,6 +569,7 @@ "system.resources.enabled": "Activar monitor de recursos", "system.resources.location": "Ubicación de visualización", "system.resources.location_bar": "Barra", + "system.resources.location_both": "Ambos", "system.resources.location_dashboard": "Panel", "system.resources.saved": "Guardado", "system.resources.show_cpu": "CPU", diff --git a/translations/ru.json b/translations/ru.json index ef0eb3bfa..7248d0c1c 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -569,6 +569,7 @@ "system.resources.enabled": "Включить монитор ресурсов", "system.resources.location": "Место отображения", "system.resources.location_bar": "Панель", + "system.resources.location_both": "Везде", "system.resources.location_dashboard": "Дашборд", "system.resources.saved": "Сохранено", "system.resources.show_cpu": "ЦП", From 5c861e2a5e6d9a8faa2a34ec20e833b0f2284813 Mon Sep 17 00:00:00 2001 From: flathead Date: Sat, 28 Mar 2026 15:47:50 +0300 Subject: [PATCH 5/9] feat(i18n): add system.resources.show_temp translation --- translations/en.json | 1 + translations/es.json | 1 + translations/ru.json | 1 + 3 files changed, 3 insertions(+) diff --git a/translations/en.json b/translations/en.json index 092a20a8d..81a546a5c 100644 --- a/translations/en.json +++ b/translations/en.json @@ -577,6 +577,7 @@ "system.resources.show_gpu": "GPU", "system.resources.show_items": "Visible Items", "system.resources.show_ram": "RAM", + "system.resources.show_temp": "Temp", "system.resources.unsaved": "Unsaved changes", "theme.add_stop": "Add Stop", "theme.angle": "Angle", diff --git a/translations/es.json b/translations/es.json index 8e176f33f..5ca6e9957 100644 --- a/translations/es.json +++ b/translations/es.json @@ -577,6 +577,7 @@ "system.resources.show_gpu": "GPU", "system.resources.show_items": "Elementos visibles", "system.resources.show_ram": "RAM", + "system.resources.show_temp": "Temp", "system.resources.unsaved": "Cambios sin guardar", "theme.add_stop": "Agregar parada", "theme.angle": "Ángulo", diff --git a/translations/ru.json b/translations/ru.json index 7248d0c1c..319523449 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -577,6 +577,7 @@ "system.resources.show_gpu": "ГП", "system.resources.show_items": "Отображаемые элементы", "system.resources.show_ram": "ОЗУ", + "system.resources.show_temp": "Темп", "system.resources.unsaved": "Несохранённые изменения", "theme.add_stop": "Добавить точку", "theme.angle": "Угол", From 06f721463616a88af3546e0b81c52809790f0628 Mon Sep 17 00:00:00 2001 From: flathead Date: Wed, 1 Apr 2026 21:48:52 +0300 Subject: [PATCH 6/9] i18n: add calendar feature translation keys (en/ru/es) Adds 39 keys under calendar.bar.*, calendar.event.*, calendar.form.*, and calendar.settings.* namespaces for the calendar integration feature. Covers bar indicator labels, event form fields, validation errors, reminder options, and the barAlwaysShow setting toggle. --- translations/en.json | 39 +++++++++++++++++++++++++++++++++++++++ translations/es.json | 39 +++++++++++++++++++++++++++++++++++++++ translations/ru.json | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+) diff --git a/translations/en.json b/translations/en.json index 81a546a5c..da3f34198 100644 --- a/translations/en.json +++ b/translations/en.json @@ -115,6 +115,45 @@ "calendar.month.november": "November", "calendar.month.october": "October", "calendar.month.september": "September", + "calendar.bar.no_events": "No events today", + "calendar.bar.section_past": "Past", + "calendar.bar.section_upcoming": "Upcoming", + "calendar.bar.time_hours": "in %1h %2m", + "calendar.bar.time_minutes": "in %1 min", + "calendar.bar.time_now": "now", + "calendar.event.all_day": "All day", + "calendar.event.untitled": "Untitled", + "calendar.form.add_event": "+ Add", + "calendar.form.delete": "Delete", + "calendar.form.error_end_after_start": "End time must be after start", + "calendar.form.error_operation_failed": "Operation failed", + "calendar.form.error_time_required": "Start and end time are required", + "calendar.form.error_timeout": "Request timed out — check your connection", + "calendar.form.error_title_required": "Title is required", + "calendar.form.event_singular": "event", + "calendar.form.events_plural": "events", + "calendar.form.label_calendar": "Calendar", + "calendar.form.label_description": "Description", + "calendar.form.label_end": "End", + "calendar.form.label_location": "Location / Link", + "calendar.form.label_meet": "Google Meet", + "calendar.form.label_reminder": "Reminder", + "calendar.form.label_start": "Start", + "calendar.form.label_title": "Title", + "calendar.form.meet_add": "+ Add Meet", + "calendar.form.meet_remove": "Remove Meet", + "calendar.form.no_calendar": "No calendar connected", + "calendar.form.no_events": "No events", + "calendar.form.placeholder_description": "Optional...", + "calendar.form.placeholder_location": "URL or address...", + "calendar.form.placeholder_title": "Event title", + "calendar.form.reminder_1day": "1 day", + "calendar.form.reminder_1hour": "1 hour", + "calendar.form.reminder_minutes": "%1 min", + "calendar.form.reminder_none": "None", + "calendar.form.save": "Save", + "calendar.form.saving": "Saving…", + "calendar.settings.bar_always_show": "Always show in bar", "clipboard.alias": "Alias", "clipboard.checksum": "Checksum", "clipboard.clear_all_confirm": "Clear all?", diff --git a/translations/es.json b/translations/es.json index 5ca6e9957..6bb8d09e7 100644 --- a/translations/es.json +++ b/translations/es.json @@ -115,6 +115,45 @@ "calendar.month.november": "Noviembre", "calendar.month.october": "Octubre", "calendar.month.september": "Septiembre", + "calendar.bar.no_events": "Sin eventos hoy", + "calendar.bar.section_past": "Pasados", + "calendar.bar.section_upcoming": "Próximos", + "calendar.bar.time_hours": "en %1h %2m", + "calendar.bar.time_minutes": "en %1 min", + "calendar.bar.time_now": "ahora", + "calendar.event.all_day": "Todo el día", + "calendar.event.untitled": "Sin título", + "calendar.form.add_event": "+ Agregar", + "calendar.form.delete": "Eliminar", + "calendar.form.error_end_after_start": "El fin debe ser posterior al inicio", + "calendar.form.error_operation_failed": "La operación falló", + "calendar.form.error_time_required": "Se requieren fecha de inicio y fin", + "calendar.form.error_timeout": "Tiempo de espera agotado — verifica tu conexión", + "calendar.form.error_title_required": "El título es obligatorio", + "calendar.form.event_singular": "evento", + "calendar.form.events_plural": "eventos", + "calendar.form.label_calendar": "Calendario", + "calendar.form.label_description": "Descripción", + "calendar.form.label_end": "Fin", + "calendar.form.label_location": "Lugar / enlace", + "calendar.form.label_meet": "Google Meet", + "calendar.form.label_reminder": "Recordatorio", + "calendar.form.label_start": "Inicio", + "calendar.form.label_title": "Título", + "calendar.form.meet_add": "+ Agregar Meet", + "calendar.form.meet_remove": "Quitar Meet", + "calendar.form.no_calendar": "Sin calendario conectado", + "calendar.form.no_events": "Sin eventos", + "calendar.form.placeholder_description": "Opcional...", + "calendar.form.placeholder_location": "URL o dirección...", + "calendar.form.placeholder_title": "Título del evento", + "calendar.form.reminder_1day": "1 día", + "calendar.form.reminder_1hour": "1 hora", + "calendar.form.reminder_minutes": "%1 min", + "calendar.form.reminder_none": "Ninguno", + "calendar.form.save": "Guardar", + "calendar.form.saving": "Guardando…", + "calendar.settings.bar_always_show": "Mostrar siempre en la barra", "clipboard.alias": "Alias", "clipboard.checksum": "Suma de verificación", "clipboard.clear_all_confirm": "¿Borrar todo?", diff --git a/translations/ru.json b/translations/ru.json index 319523449..7a01768c2 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -115,6 +115,45 @@ "calendar.month.november": "Ноябрь", "calendar.month.october": "Октябрь", "calendar.month.september": "Сентябрь", + "calendar.bar.no_events": "Нет событий сегодня", + "calendar.bar.section_past": "Прошедшие", + "calendar.bar.section_upcoming": "Предстоящие", + "calendar.bar.time_hours": "через %1ч %2м", + "calendar.bar.time_minutes": "через %1 мин", + "calendar.bar.time_now": "сейчас", + "calendar.event.all_day": "Весь день", + "calendar.event.untitled": "Без названия", + "calendar.form.add_event": "+ Добавить", + "calendar.form.delete": "Удалить", + "calendar.form.error_end_after_start": "Время окончания должно быть позже начала", + "calendar.form.error_operation_failed": "Операция не выполнена", + "calendar.form.error_time_required": "Укажите время начала и окончания", + "calendar.form.error_timeout": "Превышено время ожидания — проверьте соединение", + "calendar.form.error_title_required": "Название обязательно", + "calendar.form.event_singular": "событие", + "calendar.form.events_plural": "событий", + "calendar.form.label_calendar": "Календарь", + "calendar.form.label_description": "Описание", + "calendar.form.label_end": "Конец", + "calendar.form.label_location": "Место / ссылка", + "calendar.form.label_meet": "Google Meet", + "calendar.form.label_reminder": "Напоминание", + "calendar.form.label_start": "Начало", + "calendar.form.label_title": "Название", + "calendar.form.meet_add": "+ Добавить Meet", + "calendar.form.meet_remove": "Удалить Meet", + "calendar.form.no_calendar": "Нет подключённого календаря", + "calendar.form.no_events": "Нет событий", + "calendar.form.placeholder_description": "Необязательно...", + "calendar.form.placeholder_location": "URL или адрес...", + "calendar.form.placeholder_title": "Название события", + "calendar.form.reminder_1day": "1 день", + "calendar.form.reminder_1hour": "1 час", + "calendar.form.reminder_minutes": "%1 мин", + "calendar.form.reminder_none": "Нет", + "calendar.form.save": "Сохранить", + "calendar.form.saving": "Сохраняю…", + "calendar.settings.bar_always_show": "Всегда показывать в панели", "clipboard.alias": "Псевдоним", "clipboard.checksum": "Контрольная сумма", "clipboard.clear_all_confirm": "Очистить всё?", From 3bbcb20543580481884149377b15c6a85999985e Mon Sep 17 00:00:00 2001 From: flathead Date: Wed, 1 Apr 2026 22:35:42 +0300 Subject: [PATCH 7/9] i18n: add CalendarPanel and EventPopup translation keys Add calendar.panel.* keys for all CalendarPanel UI strings (accounts, settings, form fields, section headers, arrival settings) and missing calendar.form.* keys (new_event, edit_event, time_placeholder) for EventPopup. All three languages: en, ru, es. 37 new keys each. --- translations/en.json | 37 +++++++++++++++++++++++++++++++++++++ translations/es.json | 37 +++++++++++++++++++++++++++++++++++++ translations/ru.json | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+) diff --git a/translations/en.json b/translations/en.json index da3f34198..af12a2107 100644 --- a/translations/en.json +++ b/translations/en.json @@ -154,6 +154,43 @@ "calendar.form.save": "Save", "calendar.form.saving": "Saving…", "calendar.settings.bar_always_show": "Always show in bar", + "calendar.form.edit_event": "Edit Event", + "calendar.form.new_event": "New Event", + "calendar.form.time_placeholder": "HH:MM", + "calendar.panel.add_caldav": "+ CalDAV", + "calendar.panel.add_google": "+ Google OAuth", + "calendar.panel.back": "Back", + "calendar.panel.bar_indicator": "Bar indicator", + "calendar.panel.bar_show_next": "Show next upcoming event", + "calendar.panel.blink_on_arrival": "Blink icon on arrival", + "calendar.panel.caldav_name": "Account name (optional)", + "calendar.panel.caldav_server": "CalDAV Server", + "calendar.panel.connect": "Connect", + "calendar.panel.custom_sound": "Custom sound file", + "calendar.panel.default_reminder": "Default reminder", + "calendar.panel.gcalcli_detected": "A gcalcli token was detected on your system. You can import it to use your Google account.", + "calendar.panel.gcalcli_found": "gcalcli token found", + "calendar.panel.google_client_id": "Google Client ID", + "calendar.panel.google_client_secret": "Google Client Secret", + "calendar.panel.google_credentials_hint": "You need to create OAuth 2.0 credentials in Google Cloud Console.", + "calendar.panel.import_gcalcli": "Import from gcalcli", + "calendar.panel.notifications": "Notifications", + "calendar.panel.oauth_hint": "Enter your OAuth 2.0 credentials to connect a Google account.", + "calendar.panel.password": "Password", + "calendar.panel.remove": "Remove", + "calendar.panel.reset": "Reset", + "calendar.panel.save": "Save", + "calendar.panel.section_accounts": "Accounts", + "calendar.panel.section_arrival": "ARRIVAL ATTENTION", + "calendar.panel.section_calendars": "CALENDARS", + "calendar.panel.section_google": "GOOGLE OAUTH", + "calendar.panel.section_settings": "Settings", + "calendar.panel.sound_hint_default": "Leave empty to use system default", + "calendar.panel.sound_hint_formats": "Supports .oga, .ogg, .wav, .mp3", + "calendar.panel.sound_on_arrival": "Sound on arrival", + "calendar.panel.sync_interval": "Sync interval", + "calendar.panel.sync_now": "Sync now", + "calendar.panel.username": "Username", "clipboard.alias": "Alias", "clipboard.checksum": "Checksum", "clipboard.clear_all_confirm": "Clear all?", diff --git a/translations/es.json b/translations/es.json index 6bb8d09e7..4f4df03f1 100644 --- a/translations/es.json +++ b/translations/es.json @@ -154,6 +154,43 @@ "calendar.form.save": "Guardar", "calendar.form.saving": "Guardando…", "calendar.settings.bar_always_show": "Mostrar siempre en la barra", + "calendar.form.edit_event": "Editar evento", + "calendar.form.new_event": "Nuevo evento", + "calendar.form.time_placeholder": "HH:MM", + "calendar.panel.add_caldav": "+ CalDAV", + "calendar.panel.add_google": "+ Google OAuth", + "calendar.panel.back": "Volver", + "calendar.panel.bar_indicator": "Indicador en barra", + "calendar.panel.bar_show_next": "Mostrar próximo evento", + "calendar.panel.blink_on_arrival": "Parpadear icono al llegar", + "calendar.panel.caldav_name": "Nombre de cuenta (opcional)", + "calendar.panel.caldav_server": "Servidor CalDAV", + "calendar.panel.connect": "Conectar", + "calendar.panel.custom_sound": "Archivo de sonido", + "calendar.panel.default_reminder": "Recordatorio predeterminado", + "calendar.panel.gcalcli_detected": "Se detectó un token de gcalcli en tu sistema. Puedes importarlo para usar tu cuenta de Google.", + "calendar.panel.gcalcli_found": "Token de gcalcli encontrado", + "calendar.panel.google_client_id": "Google Client ID", + "calendar.panel.google_client_secret": "Google Client Secret", + "calendar.panel.google_credentials_hint": "Debes crear credenciales OAuth 2.0 en Google Cloud Console.", + "calendar.panel.import_gcalcli": "Importar desde gcalcli", + "calendar.panel.notifications": "Notificaciones", + "calendar.panel.oauth_hint": "Ingresa tus credenciales OAuth 2.0 para conectar una cuenta de Google.", + "calendar.panel.password": "Contraseña", + "calendar.panel.remove": "Eliminar", + "calendar.panel.reset": "Restablecer", + "calendar.panel.save": "Guardar", + "calendar.panel.section_accounts": "Cuentas", + "calendar.panel.section_arrival": "ATENCIÓN AL LLEGAR", + "calendar.panel.section_calendars": "CALENDARIOS", + "calendar.panel.section_google": "GOOGLE OAUTH", + "calendar.panel.section_settings": "Configuración", + "calendar.panel.sound_hint_default": "Dejar vacío para usar el sonido del sistema", + "calendar.panel.sound_hint_formats": "Compatible con .oga, .ogg, .wav, .mp3", + "calendar.panel.sound_on_arrival": "Sonido al llegar", + "calendar.panel.sync_interval": "Intervalo de sincronización", + "calendar.panel.sync_now": "Sincronizar ahora", + "calendar.panel.username": "Usuario", "clipboard.alias": "Alias", "clipboard.checksum": "Suma de verificación", "clipboard.clear_all_confirm": "¿Borrar todo?", diff --git a/translations/ru.json b/translations/ru.json index 7a01768c2..bc38f2f27 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -154,6 +154,43 @@ "calendar.form.save": "Сохранить", "calendar.form.saving": "Сохраняю…", "calendar.settings.bar_always_show": "Всегда показывать в панели", + "calendar.form.edit_event": "Редактировать событие", + "calendar.form.new_event": "Новое событие", + "calendar.form.time_placeholder": "ЧЧ:ММ", + "calendar.panel.add_caldav": "+ CalDAV", + "calendar.panel.add_google": "+ Google OAuth", + "calendar.panel.back": "Назад", + "calendar.panel.bar_indicator": "Индикатор на панели", + "calendar.panel.bar_show_next": "Показывать следующее событие", + "calendar.panel.blink_on_arrival": "Мигать иконкой при событии", + "calendar.panel.caldav_name": "Название аккаунта (необязательно)", + "calendar.panel.caldav_server": "Сервер CalDAV", + "calendar.panel.connect": "Подключить", + "calendar.panel.custom_sound": "Файл звука", + "calendar.panel.default_reminder": "Напоминание по умолчанию", + "calendar.panel.gcalcli_detected": "На вашей системе обнаружен токен gcalcli. Вы можете импортировать его для использования аккаунта Google.", + "calendar.panel.gcalcli_found": "Токен gcalcli найден", + "calendar.panel.google_client_id": "Google Client ID", + "calendar.panel.google_client_secret": "Google Client Secret", + "calendar.panel.google_credentials_hint": "Создайте учётные данные OAuth 2.0 в Google Cloud Console.", + "calendar.panel.import_gcalcli": "Импорт из gcalcli", + "calendar.panel.notifications": "Уведомления", + "calendar.panel.oauth_hint": "Введите учётные данные OAuth 2.0 для подключения аккаунта Google.", + "calendar.panel.password": "Пароль", + "calendar.panel.remove": "Удалить", + "calendar.panel.reset": "Сбросить", + "calendar.panel.save": "Сохранить", + "calendar.panel.section_accounts": "Аккаунты", + "calendar.panel.section_arrival": "УВЕДОМЛЕНИЯ О СОБЫТИИ", + "calendar.panel.section_calendars": "КАЛЕНДАРИ", + "calendar.panel.section_google": "GOOGLE OAUTH", + "calendar.panel.section_settings": "Настройки", + "calendar.panel.sound_hint_default": "Оставьте пустым для системного звука", + "calendar.panel.sound_hint_formats": "Поддерживаются .oga, .ogg, .wav, .mp3", + "calendar.panel.sound_on_arrival": "Звук при событии", + "calendar.panel.sync_interval": "Интервал синхронизации", + "calendar.panel.sync_now": "Синхронизировать", + "calendar.panel.username": "Имя пользователя", "clipboard.alias": "Псевдоним", "clipboard.checksum": "Контрольная сумма", "clipboard.clear_all_confirm": "Очистить всё?", From 2ced253a22b67cd89dfc445e1db7cc8b1f582401 Mon Sep 17 00:00:00 2001 From: flathead Date: Thu, 2 Apr 2026 00:13:56 +0300 Subject: [PATCH 8/9] i18n: add calendar.panel.title key --- translations/en.json | 1 + translations/es.json | 1 + translations/ru.json | 1 + 3 files changed, 3 insertions(+) diff --git a/translations/en.json b/translations/en.json index af12a2107..f0e9b945e 100644 --- a/translations/en.json +++ b/translations/en.json @@ -191,6 +191,7 @@ "calendar.panel.sync_interval": "Sync interval", "calendar.panel.sync_now": "Sync now", "calendar.panel.username": "Username", + "calendar.panel.title": "Calendar", "clipboard.alias": "Alias", "clipboard.checksum": "Checksum", "clipboard.clear_all_confirm": "Clear all?", diff --git a/translations/es.json b/translations/es.json index 4f4df03f1..0800f0cfe 100644 --- a/translations/es.json +++ b/translations/es.json @@ -191,6 +191,7 @@ "calendar.panel.sync_interval": "Intervalo de sincronización", "calendar.panel.sync_now": "Sincronizar ahora", "calendar.panel.username": "Usuario", + "calendar.panel.title": "Calendario", "clipboard.alias": "Alias", "clipboard.checksum": "Suma de verificación", "clipboard.clear_all_confirm": "¿Borrar todo?", diff --git a/translations/ru.json b/translations/ru.json index bc38f2f27..ef5b7dbac 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -191,6 +191,7 @@ "calendar.panel.sync_interval": "Интервал синхронизации", "calendar.panel.sync_now": "Синхронизировать", "calendar.panel.username": "Имя пользователя", + "calendar.panel.title": "Календарь", "clipboard.alias": "Псевдоним", "clipboard.checksum": "Контрольная сумма", "clipboard.clear_all_confirm": "Очистить всё?", From 49785270a61be55f293bde283c43fc62d4314c8b Mon Sep 17 00:00:00 2001 From: flathead Date: Thu, 2 Apr 2026 00:17:21 +0300 Subject: [PATCH 9/9] i18n: add settings.calendar key --- translations/en.json | 1 + translations/es.json | 1 + translations/ru.json | 1 + 3 files changed, 3 insertions(+) diff --git a/translations/en.json b/translations/en.json index f0e9b945e..ba5d0d4d4 100644 --- a/translations/en.json +++ b/translations/en.json @@ -549,6 +549,7 @@ "settings.theme.ui_font": "UI Font", "settings.theme.variant": "Variant", "settings.theme.wallpapers": "Wallpapers", + "settings.calendar": "Calendar", "shell.autohide": "Auto-hide", "shell.available_on_fullscreen": "Available on Fullscreen", "shell.desktop.enabled": "Enabled", diff --git a/translations/es.json b/translations/es.json index 0800f0cfe..cd38a7e16 100644 --- a/translations/es.json +++ b/translations/es.json @@ -549,6 +549,7 @@ "settings.theme.ui_font": "Fuente de interfaz", "settings.theme.variant": "Variante", "settings.theme.wallpapers": "Fondos de pantalla", + "settings.calendar": "Calendario", "shell.autohide": "Ocultamiento automático", "shell.available_on_fullscreen": "Disponible en pantalla completa", "shell.desktop.enabled": "Habilitado", diff --git a/translations/ru.json b/translations/ru.json index ef5b7dbac..4b2c376b8 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -549,6 +549,7 @@ "settings.theme.ui_font": "Шрифт интерфейса", "settings.theme.variant": "Вариант", "settings.theme.wallpapers": "Обои", + "settings.calendar": "Календарь", "shell.autohide": "Автоскрытие", "shell.available_on_fullscreen": "Доступно в полноэкранном режиме", "shell.desktop.enabled": "Включено",