1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-04-04 04:42:05 -04:00

i18n: decouple time and language locale

fixes #1876
This commit is contained in:
bbedward
2026-03-01 15:17:15 -05:00
parent f4a10de790
commit db53a9a719
5 changed files with 349 additions and 114 deletions

View File

@@ -1,5 +1,6 @@
pragma Singleton
pragma ComponentBehavior: Bound
import QtQuick
import Qt.labs.folderlistmodel
import Quickshell
@@ -24,7 +25,9 @@ Singleton {
readonly property url translationsFolder: Qt.resolvedUrl("../translations/poexports")
readonly property alias folder: dir.folder
property var presentLocales: ({ "en": Qt.locale("en") })
property var presentLocales: ({
"en": Qt.locale("en")
})
property var translations: ({})
property bool translationsLoaded: false
@@ -65,7 +68,9 @@ Singleton {
}
function locale() {
return presentLocales[_resolvedLocale] ?? presentLocales["en"];
if (SessionData.timeLocale)
return Qt.locale(SessionData.timeLocale);
return Qt.locale();
}
function _loadPresentLocales() {
@@ -84,7 +89,8 @@ Singleton {
function _pickTranslation() {
for (let i = 0; i < _candidates.length; i++) {
const cand = _candidates[i];
if (presentLocales[cand] === undefined) continue;
if (presentLocales[cand] === undefined)
continue;
_resolvedLocale = cand;
useLocale(cand, cand.startsWith("en") ? "" : translationsFolder + "/" + cand + ".json");
return;

View File

@@ -129,6 +129,7 @@ Singleton {
property var hiddenInputDeviceNames: []
property string locale: ""
property string timeLocale: ""
property string launcherLastMode: "all"
property string appDrawerLastMode: "apps"

View File

@@ -80,6 +80,7 @@ var SPEC = {
hiddenInputDeviceNames: { def: [] },
locale: { def: "", onChange: "updateLocale" },
timeLocale: { def: "" },
launcherLastMode: { def: "all" },
appDrawerLastMode: { def: "apps" },

View File

@@ -1,6 +1,5 @@
import QtQuick
import qs.Common
import qs.Services
import qs.Widgets
import qs.Modules.Settings.Widgets
@@ -9,17 +8,25 @@ Item {
readonly property string _systemDefaultLabel: I18n.tr("System Default")
function capitalizeNativeLanguageName(localeCode) {
if (I18n.presentLocales[localeCode] == undefined) {
function _localeDisplayName(localeCode) {
if (!I18n.presentLocales[localeCode])
return;
}
const nativeName = I18n.presentLocales[localeCode].nativeLanguageName;
return nativeName[0].toUpperCase() + nativeName.slice(1);
}
function _displayValue() {
if (!SessionData.locale) return _systemDefaultLabel;
return capitalizeNativeLanguageName(SessionData.locale);
function _allLocaleOptions() {
return [_systemDefaultLabel].concat(Object.keys(I18n.presentLocales).map(_localeDisplayName));
}
function _codeForDisplayName(displayName) {
if (displayName === _systemDefaultLabel)
return "";
for (const code of Object.keys(I18n.presentLocales)) {
if (_localeDisplayName(code) === displayName)
return code;
}
return "";
}
DankFlickable {
@@ -48,24 +55,34 @@ Item {
settingKey: "locale"
text: I18n.tr("Current Locale")
description: I18n.tr("Change the locale used by the DMS interface.")
options: [localeTab._systemDefaultLabel].concat(Object.keys(I18n.presentLocales).map(localeTab.capitalizeNativeLanguageName))
options: localeTab._allLocaleOptions()
enableFuzzySearch: true
Component.onCompleted: {
currentValue = localeTab._displayValue();
currentValue = SessionData.locale ? localeTab._localeDisplayName(SessionData.locale) : localeTab._systemDefaultLabel;
}
onValueChanged: value => {
if (value === localeTab._systemDefaultLabel) {
SessionData.set("locale", "");
return;
}
for (let code of Object.keys(I18n.presentLocales)) {
if (localeTab.capitalizeNativeLanguageName(code) === value) {
SessionData.set("locale", code);
return;
}
}
SessionData.set("locale", localeTab._codeForDisplayName(value));
}
}
SettingsDropdownRow {
id: timeLocaleDropdown
tab: "locale"
tags: ["locale", "time", "date", "format", "region"]
settingKey: "timeLocale"
text: I18n.tr("Time & Date Locale")
description: I18n.tr("Change the locale used for date and time formatting, independent of the interface language.")
options: localeTab._allLocaleOptions()
enableFuzzySearch: true
Component.onCompleted: {
currentValue = SessionData.timeLocale ? localeTab._localeDisplayName(SessionData.timeLocale) : localeTab._systemDefaultLabel;
}
onValueChanged: value => {
SessionData.set("timeLocale", localeTab._codeForDisplayName(value));
}
}
}

View File

@@ -733,6 +733,26 @@
],
"icon": "toolbar"
},
{
"section": "barShadowDirectionSource",
"label": "Direction Source",
"tabIndex": 3,
"category": "Dank Bar",
"keywords": [
"bar",
"choose",
"dank",
"direction",
"panel",
"resolves",
"shadow",
"source",
"statusbar",
"taskbar",
"topbar"
],
"description": "Choose how this bar resolves shadow direction"
},
{
"section": "barDisplay",
"label": "Display Assignment",
@@ -752,6 +772,25 @@
],
"icon": "display_settings"
},
{
"section": "barShadowDirectionManual",
"label": "Manual Direction",
"tabIndex": 3,
"category": "Dank Bar",
"keywords": [
"bar",
"dank",
"direction",
"fixed",
"manual",
"panel",
"shadow",
"statusbar",
"taskbar",
"topbar"
],
"description": "Use a fixed shadow direction for this bar"
},
{
"section": "barPosition",
"label": "Position",
@@ -769,18 +808,23 @@
},
{
"section": "barShadow",
"label": "Shadow",
"label": "Shadow Override",
"tabIndex": 3,
"category": "Dank Bar",
"keywords": [
"bar",
"dank",
"global",
"override",
"panel",
"settings",
"shadow",
"statusbar",
"taskbar",
"topbar"
],
"icon": "layers"
"icon": "layers",
"description": "Override the global shadow with per-bar settings"
},
{
"section": "barSpacing",
@@ -2252,6 +2296,33 @@
],
"icon": "schedule"
},
{
"section": "barElevationEnabled",
"label": "Bar Shadows",
"tabIndex": 10,
"category": "Theme & Colors",
"keywords": [
"appearance",
"bar",
"bars",
"colors",
"elevation",
"look",
"m3",
"navigation",
"panel",
"panels",
"scheme",
"shadow",
"shadows",
"statusbar",
"style",
"taskbar",
"theme",
"topbar"
],
"description": "Shadow elevation on bars and panels"
},
{
"section": "niriLayoutBorderSize",
"label": "Border Size",
@@ -2416,74 +2487,6 @@
],
"description": "0 = square corners"
},
{
"section": "m3ElevationEnabled",
"label": "M3 Elevation & Shadows",
"tabIndex": 10,
"category": "Theme & Colors",
"keywords": [
"appearance",
"elevation",
"lift",
"material",
"m3",
"shadow",
"shadows",
"theme"
],
"description": "Material Design 3 shadows and elevation on modals, popouts, and dialogs"
},
{
"section": "modalElevationEnabled",
"label": "Modal Shadows",
"tabIndex": 10,
"category": "Theme & Colors",
"keywords": [
"dialog",
"elevation",
"m3",
"material",
"modal",
"shadow",
"shadows"
],
"description": "Shadow elevation on modals and dialogs"
},
{
"section": "popoutElevationEnabled",
"label": "Popout Shadows",
"tabIndex": 10,
"category": "Theme & Colors",
"keywords": [
"dropdown",
"elevation",
"m3",
"material",
"osd",
"popout",
"popup",
"shadow",
"shadows"
],
"description": "Shadow elevation on popouts, OSDs, and dropdowns"
},
{
"section": "barElevationEnabled",
"label": "Bar Shadows",
"tabIndex": 10,
"category": "Theme & Colors",
"keywords": [
"bar",
"elevation",
"m3",
"material",
"navigation",
"panel",
"shadow",
"shadows"
],
"description": "Shadow elevation on bars and panels"
},
{
"section": "cursorSize",
"label": "Cursor Size",
@@ -2758,6 +2761,32 @@
"tint"
]
},
{
"section": "m3ElevationLightDirection",
"label": "Light Direction",
"tabIndex": 10,
"category": "Theme & Colors",
"keywords": [
"advanced",
"appearance",
"cast",
"colors",
"controls",
"day",
"direction",
"elevation",
"layers",
"light",
"light mode",
"look",
"m3",
"scheme",
"shadow",
"style",
"theme"
],
"description": "Controls shadow cast direction for elevation layers"
},
{
"section": "isLightMode",
"label": "Light Mode",
@@ -2898,6 +2927,29 @@
"icon": "layers",
"description": "Show darkened overlay behind modal dialogs"
},
{
"section": "modalElevationEnabled",
"label": "Modal Shadows",
"tabIndex": 10,
"category": "Theme & Colors",
"keywords": [
"appearance",
"colors",
"dialog",
"dialogs",
"elevation",
"look",
"m3",
"modal",
"modals",
"scheme",
"shadow",
"shadows",
"style",
"theme"
],
"description": "Shadow elevation on modals and dialogs"
},
{
"section": "niriLayout",
"label": "Niri Layout Overrides",
@@ -3158,6 +3210,32 @@
],
"description": "Use custom gaps instead of bar spacing"
},
{
"section": "popoutElevationEnabled",
"label": "Popout Shadows",
"tabIndex": 10,
"category": "Theme & Colors",
"keywords": [
"appearance",
"colors",
"dropdown",
"dropdowns",
"elevation",
"look",
"m3",
"osd",
"osds",
"popout",
"popouts",
"popup",
"scheme",
"shadow",
"shadows",
"style",
"theme"
],
"description": "Shadow elevation on popouts, OSDs, and dropdowns"
},
{
"section": "popupTransparency",
"label": "Popup Transparency",
@@ -3222,6 +3300,105 @@
"user"
]
},
{
"section": "m3ElevationColorMode",
"label": "Shadow Color",
"tabIndex": 10,
"category": "Theme & Colors",
"keywords": [
"appearance",
"applied",
"base",
"color",
"colors",
"colour",
"elevation",
"hue",
"look",
"m3",
"scheme",
"shadow",
"shadows",
"style",
"theme",
"tint"
],
"description": "Base color for shadows (opacity is applied automatically)"
},
{
"section": "m3ElevationIntensity",
"label": "Shadow Intensity",
"tabIndex": 10,
"category": "Theme & Colors",
"keywords": [
"appearance",
"base",
"blur",
"colors",
"controls",
"elevation",
"intensity",
"look",
"m3",
"offset",
"radius",
"scheme",
"shadow",
"shadows",
"style",
"theme"
],
"description": "Controls the base blur radius and offset of shadows"
},
{
"section": "m3ElevationOpacity",
"label": "Shadow Opacity",
"tabIndex": 10,
"category": "Theme & Colors",
"keywords": [
"alpha",
"appearance",
"colors",
"controls",
"elevation",
"look",
"m3",
"opacity",
"scheme",
"shadow",
"style",
"theme",
"translucent",
"transparency",
"transparent"
],
"description": "Controls the transparency of the shadow"
},
{
"section": "m3ElevationEnabled",
"label": "Shadows",
"tabIndex": 10,
"category": "Theme & Colors",
"keywords": [
"appearance",
"colors",
"dialogs",
"elevation",
"inspired",
"lift",
"look",
"m3",
"material",
"modals",
"popouts",
"scheme",
"shadow",
"shadows",
"style",
"theme"
],
"description": "Material inspired shadows and elevation on modals, popouts, and dialogs"
},
{
"section": "syncModeWithPortal",
"label": "Sync Mode with Portal",
@@ -4038,27 +4215,6 @@
],
"description": "Automatically lock the screen when DMS starts"
},
{
"section": "lockBeforeSuspend",
"label": "Lock before suspend",
"tabIndex": 11,
"category": "Lock Screen",
"keywords": [
"automatic",
"automatically",
"before",
"lock",
"login",
"password",
"prepares",
"screen",
"security",
"sleep",
"suspend",
"system"
],
"description": "Automatically lock the screen when the system prepares to suspend"
},
{
"section": "lockScreenNotificationMode",
"label": "Notification Display",
@@ -5358,20 +5514,33 @@
"keywords": [
"alert",
"alerts",
"appearance",
"colors",
"colour",
"colours",
"drop",
"elevation",
"enabled",
"hue",
"look",
"messages",
"notif",
"notification",
"notifications",
"palette",
"popup",
"popups",
"radius",
"requires",
"rounded",
"shadow",
"show",
"style",
"theme",
"tint",
"toast"
],
"description": "Show drop shadow on notification popups"
"description": "Show drop shadow on notification popups. Requires M3 Elevation to be enabled in Theme & Colors."
},
{
"section": "notificationPopupPrivacyMode",
@@ -6023,6 +6192,27 @@
"icon": "schedule",
"description": "Gradually fade the screen before locking with a configurable grace period"
},
{
"section": "lockBeforeSuspend",
"label": "Lock before suspend",
"tabIndex": 21,
"category": "Power & Sleep",
"keywords": [
"automatically",
"before",
"energy",
"lock",
"power",
"prepares",
"screen",
"security",
"shutdown",
"sleep",
"suspend",
"system"
],
"description": "Automatically lock the screen when the system prepares to suspend"
},
{
"section": "fadeToLockGracePeriod",
"label": "Lock fade grace period",
@@ -6618,5 +6808,25 @@
],
"icon": "language",
"description": "Change the locale used by the DMS interface."
},
{
"section": "timeLocale",
"label": "Time & Date Locale",
"tabIndex": 30,
"category": "Locale",
"keywords": [
"change",
"country",
"date",
"format",
"formatting",
"independent",
"interface",
"language",
"locale",
"region",
"time"
],
"description": "Change the locale used for date and time formatting, independent of the interface language."
}
]