mirror of
https://github.com/danbulant/dots-hyprland
synced 2026-05-24 12:22:09 +00:00
i18n:Replace qstr with Translation.tr and update the translation file
This commit is contained in:
parent
af5d25b575
commit
fb0d3f7f40
8 changed files with 196 additions and 20 deletions
170
.config/quickshell/ii/Translation.qml
Normal file
170
.config/quickshell/ii/Translation.qml
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
pragma Singleton
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import "root:/modules/common/"
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
property var translations: ({})
|
||||
property string currentLanguage: "en_US"
|
||||
property var availableLanguages: ["en_US"]
|
||||
property bool isScanning: false
|
||||
property bool isLoading: false
|
||||
|
||||
Process {
|
||||
id: scanLanguagesProcess
|
||||
command: ["find", Qt.resolvedUrl(Directories.config + "/quickshell/translations/").toString().replace("file://", ""), "-name", "*.json", "-exec", "basename", "{}", ".json", ";"]
|
||||
running: false
|
||||
|
||||
stdout: SplitParser {
|
||||
onRead: data => {
|
||||
if (data.trim().length === 0) return
|
||||
|
||||
var files = data.trim().split('\n')
|
||||
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
var lang = files[i].trim()
|
||||
if (lang.length > 0 && root.availableLanguages.indexOf(lang) === -1) {
|
||||
root.availableLanguages.push(lang)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onExited: (exitCode, exitStatus) => {
|
||||
root.isScanning = false
|
||||
if (exitCode !== 0) {
|
||||
root.availableLanguages = ["en_US"]
|
||||
}
|
||||
root.loadTranslations()
|
||||
}
|
||||
}
|
||||
|
||||
FileView {
|
||||
id: translationFileView
|
||||
onLoaded: {
|
||||
var textContent = ""
|
||||
try {
|
||||
textContent = text()
|
||||
} catch (e) {
|
||||
root.translations = {}
|
||||
root.isLoading = false
|
||||
return
|
||||
}
|
||||
|
||||
if (textContent.length === 0) {
|
||||
root.translations = {}
|
||||
root.isLoading = false
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
var jsonData = JSON.parse(textContent)
|
||||
root.translations = jsonData
|
||||
root.isLoading = false
|
||||
} catch (e) {
|
||||
root.translations = {}
|
||||
root.isLoading = false
|
||||
}
|
||||
}
|
||||
onLoadFailed: (error) => {
|
||||
root.translations = {}
|
||||
root.isLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
function detectSystemLanguage() {
|
||||
var locale = Qt.locale().name
|
||||
return locale
|
||||
}
|
||||
|
||||
function getLanguageCode() {
|
||||
var configLang = "auto"
|
||||
try {
|
||||
configLang = ConfigOptions.language.ui
|
||||
} catch (e) {
|
||||
configLang = "auto"
|
||||
}
|
||||
|
||||
if (configLang === "auto") {
|
||||
return detectSystemLanguage()
|
||||
} else {
|
||||
if (root.availableLanguages.indexOf(configLang) !== -1) {
|
||||
return configLang
|
||||
} else {
|
||||
return detectSystemLanguage()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function loadTranslations() {
|
||||
if (root.isScanning) {
|
||||
return
|
||||
}
|
||||
|
||||
var targetLang = getLanguageCode()
|
||||
root.currentLanguage = targetLang
|
||||
|
||||
// Use empty translations for English (default language)
|
||||
if (targetLang === "en_US" || targetLang === "en") {
|
||||
root.translations = {}
|
||||
return
|
||||
}
|
||||
|
||||
// Check if target language is available
|
||||
if (root.availableLanguages.indexOf(targetLang) === -1) {
|
||||
root.currentLanguage = "en_US"
|
||||
root.translations = {}
|
||||
return
|
||||
}
|
||||
|
||||
// Load translation file
|
||||
root.isLoading = true
|
||||
var translationsPath = Qt.resolvedUrl(Directories.config + "/quickshell/translations/" + targetLang + ".json")
|
||||
translationFileView.path = translationsPath
|
||||
}
|
||||
|
||||
function tr(text) {
|
||||
if (!text) {
|
||||
return ""
|
||||
}
|
||||
|
||||
var key = text.toString()
|
||||
|
||||
if (root.isLoading) {
|
||||
return key
|
||||
}
|
||||
|
||||
if (root.currentLanguage === "en_US" || root.currentLanguage === "en" || !root.translations) {
|
||||
return key
|
||||
}
|
||||
|
||||
if (root.translations.hasOwnProperty(key)) {
|
||||
var translation = root.translations[key]
|
||||
if (translation && translation.toString().trim().length > 0) {
|
||||
return translation.toString()
|
||||
} else {
|
||||
return translation.toString()
|
||||
}
|
||||
}
|
||||
|
||||
return key // Fallback to key name
|
||||
}
|
||||
|
||||
function reloadTranslations() {
|
||||
root.scanLanguages()
|
||||
}
|
||||
|
||||
function scanLanguages() {
|
||||
var translationsDir = Qt.resolvedUrl(Directories.config + "/quickshell/translations/").toString().replace("file://", "")
|
||||
root.isScanning = true
|
||||
scanLanguagesProcess.running = true
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
root.scanLanguages()
|
||||
}
|
||||
}
|
||||
|
|
@ -73,7 +73,7 @@ Item {
|
|||
},
|
||||
{
|
||||
name: "save",
|
||||
description: qsTr("Save chat"),
|
||||
description: Translation.tr("Save chat"),
|
||||
execute: (args) => {
|
||||
const joinedArgs = args.join(" ")
|
||||
if (joinedArgs.trim().length == 0) {
|
||||
|
|
@ -85,7 +85,7 @@ Item {
|
|||
},
|
||||
{
|
||||
name: "load",
|
||||
description: qsTr("Load chat"),
|
||||
description: Translation.tr("Load chat"),
|
||||
execute: (args) => {
|
||||
const joinedArgs = args.join(" ")
|
||||
if (joinedArgs.trim().length == 0) {
|
||||
|
|
@ -97,7 +97,7 @@ Item {
|
|||
},
|
||||
{
|
||||
name: "clear",
|
||||
description: qsTr("Clear chat history"),
|
||||
description: Translation.tr("Clear chat history"),
|
||||
execute: () => {
|
||||
Ai.clearMessages();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ Item { // Tag suggestion description
|
|||
}
|
||||
StyledText {
|
||||
visible: root.showArrows && root.showTab
|
||||
text: qsTr("or")
|
||||
text: Translation.tr("or")
|
||||
font.pixelSize: Appearance.font.pixelSize.smaller
|
||||
}
|
||||
KeyboardKey {
|
||||
|
|
|
|||
|
|
@ -19,9 +19,9 @@ Item {
|
|||
required property var scopeRoot
|
||||
anchors.fill: parent
|
||||
property var tabButtonList: [
|
||||
...(Config.options.policies.ai !== 0 ? [{"icon": "neurology", "name": qsTr("Intelligence")}] : []),
|
||||
{"icon": "translate", "name": qsTr("Translator")},
|
||||
...(Config.options.policies.weeb === 1 ? [{"icon": "bookmark_heart", "name": qsTr("Anime")}] : [])
|
||||
...(Config.options.policies.ai !== 0 ? [{"icon": "neurology", "name": Translation.tr("Intelligence")}] : []),
|
||||
{"icon": "translate", "name": Translation.tr("Translator")},
|
||||
...(Config.options.policies.weeb === 1 ? [{"icon": "bookmark_heart", "name": Translation.tr("Anime")}] : [])
|
||||
]
|
||||
property int selectedTab: 0
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ Rectangle {
|
|||
property int selectedTab: 0
|
||||
property bool collapsed: Persistent.states.sidebar.bottomGroup.collapsed
|
||||
property var tabs: [
|
||||
{"type": "calendar", "name": "Calendar", "icon": "calendar_month", "widget": calendarWidget},
|
||||
{"type": "todo", "name": "To Do", "icon": "done_outline", "widget": todoWidget}
|
||||
{"type": "calendar", "name": Translation.tr("Calendar"), "icon": "calendar_month", "widget": calendarWidget},
|
||||
{"type": "todo", "name": Translation.tr("To Do"), "icon": "done_outline", "widget": todoWidget}
|
||||
]
|
||||
|
||||
Behavior on implicitHeight {
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ Item {
|
|||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.leftMargin: 10
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: `${Notifications.list.length} notifications`
|
||||
text: `${Notifications.list.length} ${Translation.tr("notifications")}`
|
||||
|
||||
opacity: Notifications.list.length > 0 ? 1 : 0
|
||||
visible: opacity > 0
|
||||
|
|
|
|||
|
|
@ -96,8 +96,6 @@
|
|||
"Run command": "Run command",
|
||||
"Save": "Save",
|
||||
"Save to Downloads": "Save to Downloads",
|
||||
"Scroll to change brightness": "Scroll to change brightness",
|
||||
"Scroll to change volume": "Scroll to change volume",
|
||||
"Search": "Search",
|
||||
"Search the web": "Search the web",
|
||||
"Search, calculate or run": "Search, calculate or run",
|
||||
|
|
@ -106,8 +104,6 @@
|
|||
"Set API key": "Set API key",
|
||||
"Set temperature (randomness) of the model. Values range between 0 to 2 for Gemini, 0 to 1 for other models. Default is 0.5.": "Set temperature (randomness) of the model. Values range between 0 to 2 for Gemini, 0 to 1 for other models. Default is 0.5.",
|
||||
"Set the current API provider": "Set the current API provider",
|
||||
"Shell configuration created": "Shell configuration created",
|
||||
"Shell configuration failed to load": "Shell configuration failed to load",
|
||||
"Shutdown": "Shutdown",
|
||||
"Silent": "Silent",
|
||||
"Sleep": "Sleep",
|
||||
|
|
@ -169,5 +165,12 @@
|
|||
"Experimental | Online | Google's model\nCan do a little more but doesn't search quickly": "Experimental | Online | Google's model\nCan do a little more but doesn't search quickly",
|
||||
"Message the model... \"{0}\" for commands": "Message the model... \"{0}\" for commands",
|
||||
"To set an API key, pass it with the command\n\nTo view the key, pass \"get\" with the command<br/>\n\n### For {0}:\n\n**Link**: {1}\n\n{2}": "To set an API key, pass it with the command\n\nTo view the key, pass \"get\" with the command<br/>\n\n### For {0}:\n\n**Link**: {1}\n\n{2}",
|
||||
"Settings": "Settings"
|
||||
"Settings": "Settings",
|
||||
"Save chat": "Save chat",
|
||||
"Load chat": "Load chat",
|
||||
"or": "or",
|
||||
"Set the system prompt for the model.": "Set the system prompt for the model.",
|
||||
"To Do": "To Do",
|
||||
"Calendar": "Calendar",
|
||||
"notifications": "notifications"
|
||||
}
|
||||
|
|
@ -96,8 +96,6 @@
|
|||
"Run command": "运行命令",
|
||||
"Save": "保存",
|
||||
"Save to Downloads": "保存到下载文件夹",
|
||||
"Scroll to change brightness": "滚动调节亮度",
|
||||
"Scroll to change volume": "滚动调节音量",
|
||||
"Search": "搜索",
|
||||
"Search the web": "搜索网络",
|
||||
"Search, calculate or run": "搜索、计算或运行",
|
||||
|
|
@ -106,8 +104,6 @@
|
|||
"Set API key": "设置 API 密钥",
|
||||
"Set temperature (randomness) of the model. Values range between 0 to 2 for Gemini, 0 to 1 for other models. Default is 0.5.": "设置模型的温度(随机性)。Gemini 模型范围为 0 到 2,其他模型为 0 到 1。默认值为 0.5。",
|
||||
"Set the current API provider": "设置当前 API 提供商",
|
||||
"Shell configuration created": "Shell 配置已创建",
|
||||
"Shell configuration failed to load": "Shell 配置加载失败",
|
||||
"Shutdown": "关机",
|
||||
"Silent": "静音",
|
||||
"Sleep": "睡眠",
|
||||
|
|
@ -169,5 +165,12 @@
|
|||
"Online via {0} | {1}'s model": "通过 {0} 在线 | {1} 的模型",
|
||||
"That didn't work. Tips:\n- Check your tags and NSFW settings\n- If you don't have a tag in mind, type a page number": "没有找到结果。提示:\n- 检查您的标签和 NSFW 设置\n- 如果没有想到标签,请输入页码",
|
||||
"Online | Google's model\nGives up-to-date information with search.": "在线 | Google 模型\n通过搜索提供最新信息。",
|
||||
"Settings": "设置"
|
||||
"Settings": "设置",
|
||||
"Save chat": "保存对话",
|
||||
"Load chat": "加载对话",
|
||||
"or": "或",
|
||||
"Set the system prompt for the model.": "为模型设置系统提示。",
|
||||
"To Do": "待办",
|
||||
"Calendar": "日历",
|
||||
"notifications": "条通知"
|
||||
}
|
||||
Loading…
Reference in a new issue