diff --git a/.config/ags/i18n/i18n.js b/.config/ags/i18n/i18n.js new file mode 100755 index 000000000..abb38a9b4 --- /dev/null +++ b/.config/ags/i18n/i18n.js @@ -0,0 +1,55 @@ +const Gio = imports.gi.Gio; +const GLib = imports.gi.GLib; +import configOptions from "../modules/.configuration/user_options.js"; +const { langCode, Extra_logs } = configOptions.i18n +const translations = {}; + +let currentLanguage = langCode || getLanguageCode(); + +function getLanguageCode() { + let langEnv = GLib.getenv('LANG') || GLib.getenv('LANGUAGE') || 'Default.'; + let langCode = langEnv.split('.')[0]; + return langCode; +} + +// Load language file +function loadLanguage(lang) { + if (!translations[lang]) { + try { + let filePath = `~/.config/ags/i18n/locales/${lang}.json`; + filePath = filePath.replace(/^~/, GLib.get_home_dir()); + let file = Gio.File.new_for_path(filePath); + let [success, contents] = file.load_contents(null); + if (success) { + let decoder = new TextDecoder('utf-8'); + let jsonString = decoder.decode(contents); + translations[lang] = JSON.parse(jsonString); + } + } catch (error) { + if (Extra_logs || lang === "Default") + console.warn(`Failed to load language file, language code: ${lang}:\n`, error); + return; + } + } + currentLanguage = currentLanguage || lang; +} + +// Initialize default language +function init() { + try { + loadLanguage(currentLanguage); + if (Extra_logs) + console.log(getString("Initialization complete!") || "Initialization complete!"); + loadLanguage("Default"); + } catch (error) { + console.error('Failed to initialize default language:', error); + } +} + +// Get translation, if no corresponding value, return the key +function getString(key) { + if (key && !translations[currentLanguage]?.[key] && Extra_logs) + console.warn(`${translations[currentLanguage]["Not found"] || "Not found"}:::${key}`); + return translations[currentLanguage]?.[key] || translations['Default']?.[key] || key; +} +export { getString, init }; \ No newline at end of file diff --git a/.config/ags/i18n/locales/Default.json b/.config/ags/i18n/locales/Default.json new file mode 100755 index 000000000..a17750df6 --- /dev/null +++ b/.config/ags/i18n/locales/Default.json @@ -0,0 +1,241 @@ +{ + "No media": "No media", + "Powered by Google": "Powered by Google", + "Uses gemini-pro.\nNot affiliated, endorsed, or sponsored by Google.\n\nPrivacy: Chat messages aren't linked to your account,\n but will be read by human reviewers to improve the model.": "Uses gemini-pro.\nNot affiliated, endorsed, or sponsored by Google.\n\nPrivacy: Chat messages aren't linked to your account,\n but will be read by human reviewers to improve the model.", + "Precise": "Precise", + "Balanced": "Balanced", + "Creative": "Creative", + "Gemini's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "Gemini's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1", + "Enhancements": "Enhancements", + "Tells Gemini:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "Tells Gemini:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points", + "Safety": "Safety", + "When turned off, tells the API (not the model) \nto not block harmful/explicit content": "When turned off, tells the API (not the model) \nto not block harmful/explicit content", + "History": "History", + "Saves chat history\nMessages in previous chats won't show automatically, but they are there": "Saves chat history\nMessages in previous chats won't show automatically, but they are there", + "Key stored in:": "Key stored in:", + "To update this key, type": "To update this key, type", + "Updated API Key at": "Updated API Key at", + "Currently using": "Currently using", + "Select ChatGPT-compatible API provider": "Select ChatGPT-compatible API provider", + "Official OpenAI API.\nPricing: Free for the first $5 or 3 months, whichever is less.": "Official OpenAI API.\nPricing: Free for the first $5 or 3 months, whichever is less.", + "Official Ollama API.\nPricing: Free.": "Official Ollama API.\nPricing: Free.", + "A unified interface for LLMs": "A unified interface for LLMs", + "An API from Tornado Softwares\nPricing: Free: 100/day\nRequires you to join their Discord for a key": "An API from Tornado Softwares\nPricing: Free: 100/day\nRequires you to join their Discord for a key", + "An API from @zukixa on GitHub.\nNote: Keys are IP-locked so it's buggy sometimes\nPricing: Free: 10/min, 800/day.\nRequires you to join their Discord for a key": "An API from @zukixa on GitHub.\nNote: Keys are IP-locked so it's buggy sometimes\nPricing: Free: 10/min, 800/day.\nRequires you to join their Discord for a key", + "Provider shown above": "Provider shown above", + "Uses gpt-3.5-turbo.\nNot affiliated, endorsed, or sponsored by OpenAI.\n\nPrivacy: OpenAI claims they do not use your data\nwhen you use their API. Idk about others.": "Uses gpt-3.5-turbo.\nNot affiliated, endorsed, or sponsored by OpenAI.\n\nPrivacy: OpenAI claims they do not use your data\nwhen you use their API. Idk about others.", + "The model's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "The model's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1", + "An API key is required\nYou can grab one here, then enter it below": "An API key is required\nYou can grab one here, then enter it below", + "Tells the model:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "Tells the model:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points", + "Powered by waifu.im + other APIs": "Powered by waifu.im + other APIs", + "Type tags for a random pic.\nNSFW content will not be returned unless\nyou explicitly request such a tag.\n\nDisclaimer: Not affiliated with the providers\nnor responsible for any of their content.": "Type tags for a random pic.\nNSFW content will not be returned unless\nyou explicitly request such a tag.\n\nDisclaimer: Not affiliated with the providers\nnor responsible for any of their content.", + "Tags →": "Tags →", + "Invalid command.": "Invalid command.", + "Anime booru": "Anime booru", + "Powered by yande.re and konachan": "Powered by yande.re and konachan", + "An image booru. May contain NSFW content.\nWatch your back.\n\nDisclaimer: Not affiliated with the provider\nnor responsible for any of its content.": "An image booru. May contain NSFW content.\nWatch your back.\n\nDisclaimer: Not affiliated with the provider\nnor responsible for any of its content.", + "Lewds": "Lewds", + "Shows naughty stuff when enabled.\nYa like those? Add this to user_options.js:\n\t'sidebar': {\n\t'image': {\n\t\t'allowNsfw': true,\n\t}\n}": "Shows naughty stuff when enabled.\nYa like those? Add this to user_options.js:\n\t'sidebar': {\n\t'image': {\n\t\t'allowNsfw': true,\n\t}\n}", + "Save in folder by tags": "Save in folder by tags", + "Saves images in folders by their tags": "Saves images in folders by their tags", + "Message Gemini...": "Message Gemini...", + "Enter Google AI API Key...": "Enter Google AI API Key...", + "Message the model...": "Message the model...", + "Enter API Key...": "Enter API Key...", + "Enter tags": "Enter tags", + "Quick scripts": "Quick scripts", + "Change screen resolution": "Change screen resolution", + "Update packages": "Update packages", + "Trim system generations to 5": "Trim system generations to 5", + "Trim home manager generations to 5": "Trim home manager generations to 5", + "Remove orphan packages": "Remove orphan packages", + "Uninstall unused flatpak packages": "Uninstall unused flatpak packages", + "Inaccurate Color picker": "Inaccurate Color picker", + "Result": "Result", + "Type to search": "Type to search", + "illogical-impulse": "illogical-impulse", + "RAM Usage": "RAM Usage", + "Swap Usage": "Swap Usage", + "CPU Usage": "CPU Usage", + "Uptime:": "Uptime:", + "Screen snip": "Screen snip", + "Color picker": "Color picker", + "Toggle on-screen keyboard": "Toggle on-screen keyboard", + "Night Light": "Night Light", + "Color inversion": "Color inversion", + "Keep system awake": "Keep system awake", + "Cloudflare WARP": "Cloudflare WARP", + "Session": "Session", + "Bluetooth | Right-click to configure": "Bluetooth | Right-click to configure", + "Wifi | Right-click to configure": "Wifi | Right-click to configure", + "Right-click to configure": "Right-click to configure", + "Unknown": "Unknown", + "Reload Environment config": "Reload Environment config", + "Open Settings": "Open Settings", + "Notifications": "Notifications", + "Audio controls": "Audio controls", + "Bluetooth": "Bluetooth", + "Wifi networks": "Wifi networks", + "Live config": "Live config", + "Silence": "Silence", + "Clear": "Clear", + "No notifications": "No notifications", + "notifications": "notifications", + "Close": "Close", + "Now": "Now", + "Yesterday": "Yesterday", + "No audio source": "No audio source", + "Remove device": "Remove device", + "Connected": "Connected", + "Paired": "Paired", + "More": "More", + "Selected": "Selected", + "Current network": "Current network", + "Authentication": "Authentication", + "Effects": "Effects", + "Transparency": "Transparency", + "[AGS]\nMake shell elements transparent\nBlur is also recommended if you enable this": "[AGS]\nMake shell elements transparent\nBlur is also recommended if you enable this", + "Blur": "Blur", + "[Hyprland]\nEnable blur on transparent elements\nDoesn't affect performance/power consumption unless you have transparent windows.": "[Hyprland]\nEnable blur on transparent elements\nDoesn't affect performance/power consumption unless you have transparent windows.", + "X-ray": "X-ray", + "[Hyprland]\nMake everything behind a window/layer except the wallpaper not rendered on its blurred surface\nRecommended to improve performance (if you don't abuse transparency/blur) ": "[Hyprland]\nMake everything behind a window/layer except the wallpaper not rendered on its blurred surface\nRecommended to improve performance (if you don't abuse transparency/blur) ", + "Size": "Size", + "[Hyprland]\nAdjust the blur radius. Generally doesn't affect performance\nHigher = more color spread": "[Hyprland]\nAdjust the blur radius. Generally doesn't affect performance\nHigher = more color spread", + "Passes": "Passes", + "[Hyprland] Adjust the number of runs of the blur algorithm\nMore passes = more spread and power consumption\n4 is recommended\n2- would look weird and 6+ would look lame.": "[Hyprland] Adjust the number of runs of the blur algorithm\nMore passes = more spread and power consumption\n4 is recommended\n2- would look weird and 6+ would look lame.", + "Animations": "Animations", + "[Hyprland] [GTK]\nEnable animations": "[Hyprland] [GTK]\nEnable animations", + "Choreography delay": "Choreography delay", + "In milliseconds, the delay between animations of a series": "In milliseconds, the delay between animations of a series", + "Developer": "Developer", + "Show FPS": "Show FPS", + "[Hyprland]\nShow FPS overlay on top-left corner": "[Hyprland]\nShow FPS overlay on top-left corner", + "Log to stdout": "Log to stdout", + "[Hyprland]\nPrint LOG, ERR, WARN, etc. messages to the console": "[Hyprland]\nPrint LOG, ERR, WARN, etc. messages to the console", + "Damage tracking": "Damage tracking", + "[Hyprland]\nEnable damage tracking\nGenerally, leave it on.\nTurn off only when a shader doesn't work": "[Hyprland]\nEnable damage tracking\nGenerally, leave it on.\nTurn off only when a shader doesn't work", + "Damage blink": "Damage blink", + "[Hyprland] [Epilepsy warning!]\nShow screen damage flashes": "[Hyprland] [Epilepsy warning!]\nShow screen damage flashes", + "Not all changes are saved": "Not all changes are saved", + "Mo": "Mo", + "Tu": "Tu", + "We": "We", + "Th": "Th", + "Fr": "Fr", + "Sa": "Sa", + "Su": "Su", + "Calendar": "Calendar", + "To Do": "To Do", + "Unfinished": "Unfinished", + "Done": "Done", + "Finished tasks will go here": "Finished tasks will go here", + "Nothing here!": "Nothing here!", + "+ New task": "+ New task", + "Add a task...": "Add a task...", + "Color scheme": "Color scheme", + "Options": "Options", + "Dark Mode": "Dark Mode", + "Ya should go to sleep!": "Ya should go to sleep!", + "Use Gradience": "Use Gradience", + "Theme GTK apps using accent color\n(drawback: dark/light mode switching requires restart)": "Theme GTK apps using accent color\n(drawback: dark/light mode switching requires restart)", + "Scheme styles": "Scheme styles", + "Vibrant": "Vibrant", + "Vibrant+": "Vibrant+", + "Expressive": "Expressive", + "Monochrome": "Monochrome", + "Rainbow": "Rainbow", + "Fidelity": "Fidelity", + "Fruit Salad": "Fruit Salad", + "Tonal Spot": "Tonal Spot", + "Content": "Content", + "Use arrow keys to navigate.\nEnter to select, Esc to cancel.": "Use arrow keys to navigate.\nEnter to select, Esc to cancel.", + "Lock": "Lock", + "Logout": "Logout", + "Sleep": "Sleep", + "Hibernate": "Hibernate", + "Shutdown": "Shutdown", + "Reboot": "Reboot", + "Cancel": "Cancel", + "Cheat sheet": "Cheat sheet", + "Keybinds": "Keybinds", + "Periodic table": "Periodic table", + "Essentials for beginners": "Essentials for beginners", + "Make shell elements transparent": "Make shell elements transparent", + "Actions": "Actions", + "Window management": "Window management", + "Window arrangement": "Window arrangement", + "Workspace management": "Workspace management", + "Workspace navigation": "Workspace navigation", + "Widgets": "Widgets", + "Media": "Media", + "Apps": "Apps", + "Neutral": "Neutral", + "Launch foot (terminal)": "Launch foot (terminal)", + "Open app launcher": "Open app launcher", + "Change wallpaper": "Change wallpaper", + "Clipboard history >> clipboard": "Clipboard history >> clipboard", + "Pick emoji >> clipboard": "Pick emoji >> clipboard", + "Screen snip >> edit": "Screen snip >> edit", + "Screen snip to text >> clipboard": "Screen snip to text >> clipboard", + "Pick color (Hex) >> clipboard": "Pick color (Hex) >> clipboard", + "Screenshot >> clipboard": "Screenshot >> clipboard", + "Screenshot >> clipboard & file": "Screenshot >> clipboard & file", + "Record region (no sound)": "Record region (no sound)", + "Record screen (with sound)": "Record screen (with sound)", + "Suspend system": "Suspend system", + "Move focus in direction": "Move focus in direction", + "Move window": "Move window", + "Resize window": "Resize window", + "Close window": "Close window", + "Pick and kill a window": "Pick and kill a window", + "Window: move in direction": "Window: move in direction", + "Window: split ratio +/- 0.1": "Window: split ratio +/- 0.1", + "Float/unfloat window": "Float/unfloat window", + "Toggle fake fullscreen": "Toggle fake fullscreen", + "Toggle fullscreen": "Toggle fullscreen", + "Toggle maximization": "Toggle maximization", + "Focus workspace # (1, 2, 3, 4, ...)": "Focus workspace # (1, 2, 3, 4, ...)", + "Workspace: focus left/right": "Workspace: focus left/right", + "Workspace: toggle special": "Workspace: toggle special", + "Window: move to workspace # (1, 2, 3, 4, ...)": "Window: move to workspace # (1, 2, 3, 4, ...)", + "Window: move to workspace left/right": "Window: move to workspace left/right", + "Window: move to workspace special": "Window: move to workspace special", + "Window: pin (show on all workspaces)": "Window: pin (show on all workspaces)", + "Restart widgets": "Restart widgets", + "Cycle bar mode (normal, focus)": "Cycle bar mode (normal, focus)", + "Toggle overview/launcher": "Toggle overview/launcher", + "Show cheatsheet": "Show cheatsheet", + "Toggle left sidebar": "Toggle left sidebar", + "Toggle right sidebar": "Toggle right sidebar", + "Toggle music controls": "Toggle music controls", + "View color scheme and options": "View color scheme and options", + "Toggle power menu": "Toggle power menu", + "Toggle crosshair": "Toggle crosshair", + "Next track": "Next track", + "Previous track": "Previous track", + "Play/pause media": "Play/pause media", + "Launch Zed (editor)": "Launch Zed (editor)", + "Launch VSCode (editor)": "Launch VSCode (editor)", + "Launch Nautilus (file manager)": "Launch Nautilus (file manager)", + "Launch Firefox (browser)": "Launch Firefox (browser)", + "Launch GNOME Text Editor": "Launch GNOME Text Editor", + "Launch WPS Office": "Launch WPS Office", + "Launch GNOME Settings": "Launch GNOME Settings", + "Launch pavucontrol (volume mixer)": "Launch pavucontrol (volume mixer)", + "Launch EasyEffects (equalizer & other audio effects)": "Launch EasyEffects (equalizer & other audio effects)", + "Launch GNOME System monitor": "Launch GNOME System monitor", + "Toggle fallback launcher: anyrun": "Toggle fallback launcher: anyrun", + "Toggle fallback launcher: fuzzel": "Toggle fallback launcher: fuzzel", + "Initialization complete!": "Initialization complete!", + "Not found": "Not found:", + "Calling API": "Calling API", + "Downloading image": "Downloading image", + "Finished!": "Finished!", + "Error": "Error", + "Not found!": "Not found!", + "Go to file url": "Go to file url", + "Save image": "Save image", + "Hoard": "Hoard", + "Open externally": "Open externally", + "You are an assistant on a sidebar of a Wayland Linux desktop. Please always use a casual tone when answering your questions, unless requested otherwise or making writing suggestions. These are the steps you should take to respond to the user's queries:\n1. If it's a writing- or grammar-related question or a sentence in quotation marks, Please point out errors and correct when necessary using underlines, and make the writing more natural where appropriate without making too major changes. If you're given a sentence in quotes but is grammatically correct, explain briefly concepts that are uncommon.\n2. If it's a question about system tasks, give a bash command in a code block with brief explanation.\n3. Otherwise, when asked to summarize information or explaining concepts, you are should use bullet points and headings. For mathematics expressions, you *have to* use LaTeX within a code block with the language set as \"latex\". \nNote: Use casual language, be short, while ensuring the factual correctness of your response. If you are unsure or don’t have enough information to provide a confident answer, simply say “I don’t know” or “I’m not sure.”. \nThanks!": "You are an assistant on a sidebar of a Wayland Linux desktop. Please always use a casual tone when answering your questions, unless requested otherwise or making writing suggestions. These are the steps you should take to respond to the user's queries:\n1. If it's a writing- or grammar-related question or a sentence in quotation marks, Please point out errors and correct when necessary using underlines, and make the writing more natural where appropriate without making too major changes. If you're given a sentence in quotes but is grammatically correct, explain briefly concepts that are uncommon.\n2. If it's a question about system tasks, give a bash command in a code block with brief explanation.\n3. Otherwise, when asked to summarize information or explaining concepts, you are should use bullet points and headings. For mathematics expressions, you *have to* use LaTeX within a code block with the language set as \"latex\". \nNote: Use casual language, be short, while ensuring the factual correctness of your response. If you are unsure or don’t have enough information to provide a confident answer, simply say “I don’t know” or “I’m not sure.”. \nThanks!" +} \ No newline at end of file diff --git a/.config/ags/i18n/locales/zh_CN.json b/.config/ags/i18n/locales/zh_CN.json new file mode 100755 index 000000000..d686b1333 --- /dev/null +++ b/.config/ags/i18n/locales/zh_CN.json @@ -0,0 +1,241 @@ +{ + "No media": "无媒体活动", + "Powered by Google": "由 Google 提供技术支持", + "Uses gemini-pro.\nNot affiliated, endorsed, or sponsored by Google.\n\nPrivacy: Chat messages aren't linked to your account,\n but will be read by human reviewers to improve the model.": "使用 Gemini Pro\n不隶属于、不受 Google 赞助或支持。\n\n隐私:聊天信息不会与你的账户关联,\n但会被人类审阅者阅读,用于改进模型。", + "Precise": "精确", + "Balanced": "平衡", + "Creative": "创意", + "Gemini's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "Gemini 的 temperature 值\n 精确 = 0\n 平衡 = 0.5\n 创意 = 1", + "Enhancements": "增强功能", + "Tells Gemini:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "告诉 Gemini:\n- 它是一个 Linux 侧边栏助手\n- 保持简洁并使用项目符号", + "Safety": "安全", + "When turned off, tells the API (not the model) \nto not block harmful/explicit content": "当关闭时,告诉 API(而不是模型)\n不要屏蔽有害/显露的内容", + "History": "历史", + "Saves chat history\nMessages in previous chats won't show automatically, but they are there": "保存聊天历史\n以前聊天中的消息不会自动显示,但它们仍然存在", + "Key stored in:": "密钥值储存在:", + "To update this key, type": "要更新此密钥,请输入", + "Updated API Key at": "更新了 API 密钥于", + "Currently using": "当前使用", + "Select ChatGPT-compatible API provider": "选择与 ChatGPT 兼容的 API 提供商", + "Official OpenAI API.\nPricing: Free for the first $5 or 3 months, whichever is less.": "官方 OpenAI API。\n定价:前 $5 或前 3 个月免费,取较小者。", + "Official Ollama API.\nPricing: Free.": "官方 Ollama API。\n定价:免费。", + "A unified interface for LLMs": "LLM 的统一接口", + "An API from Tornado Softwares\nPricing: Free: 100/day\nRequires you to join their Discord for a key": "来自 Tornado Softwares 的 API\n定价:免费:每天 100 次请求\n需要加入他们的 Discord 以获取密钥", + "An API from @zukixa on GitHub.\nNote: Keys are IP-locked so it's buggy sometimes\nPricing: Free: 10/min, 800/day.\nRequires you to join their Discord for a key": "来自 GitHub 上的 @zukixa 的 API。\n注意:密钥与 IP 绑定,所以有时会出错。\n定价:免费:每分钟 10 次,每天 800 次。\n需要加入他们的 Discord 才能获得密钥。", + "Provider shown above": "上述显示的提供商", + "Uses gpt-3.5-turbo.\nNot affiliated, endorsed, or sponsored by OpenAI.\n\nPrivacy: OpenAI claims they do not use your data\nwhen you use their API. Idk about others.": "使用 gpt-3.5-turbo。\n与 OpenAI 无关联,未获得其认可或赞助。\n\n隐私:OpenAI 声明,当您使用他们的 API 时,他们不会使用您的数据。\n我不清楚其他人的情况。", + "The model's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1": "模型的 temperature 值。\n 精确 = 0\n 平衡 = 0.5\n 创意 = 1", + "An API key is required\nYou can grab one here, then enter it below": "需要 API 密钥\n您可以在这里获取一个,然后在下面输入", + "Tells the model:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points": "告诉模型:\n- 它是一个 Linux 侧边栏助手\n- 保持简洁并使用项目符号", + "Powered by waifu.im + other APIs": "由 waifu.im + 其他 API 提供支持", + "Type tags for a random pic.\nNSFW content will not be returned unless\nyou explicitly request such a tag.\n\nDisclaimer: Not affiliated with the providers\nnor responsible for any of their content.": "输入标签以获取随机图片。\n除非您明确请求,否则不会返回 NSFW 内容。\n\n免责声明:与提供商无关联\n我也不对他们的任何内容负责。", + "Tags →": "标签 →", + "Invalid command.": "无效命令。", + "Anime booru": "动漫图库", + "Powered by yande.re and konachan": "由 yande.re 和 konachan 提供支持", + "An image booru. May contain NSFW content.\nWatch your back.\n\nDisclaimer: Not affiliated with the provider\nnor responsible for any of its content.": "一个图片图库。可能包含 NSFW 内容。\n小心。\n\n免责声明:与提供商无关联\n也不对它的任何内容负责。", + "Lewds": "不雅内容", + "Shows naughty stuff when enabled.\nYa like those? Add this to user_options.js:\n\t'sidebar': {\n\t'image': {\n\t\t'allowNsfw': true,\n\t}\n}": "启用时显示不雅内容。\n你喜欢这些?添加到 user_options.js 中:\n'sidebar': {\n\t'image': {\n\t\t'allowNsfw': true,\n\t}\n}", + "Save in folder by tags": "按标签保存到文件夹", + "Saves images in folders by their tags": "按标签将图片保存到文件夹中", + "Message Gemini...": "向 Gemini 发送消息...", + "Enter Google AI API Key...": "输入 Google AI API 密钥...", + "Message the model...": "向模型发送消息...", + "Enter API Key...": "输入 API 密钥...", + "Enter tags": "输入标签", + "Quick scripts": "快速脚本", + "Change screen resolution": "更改屏幕分辨率", + "Update packages": "更新软件包", + "Trim system generations to 5": "将系统代数修剪为 5", + "Trim home manager generations to 5": "将 home manager 代数修剪为 5", + "Remove orphan packages": "移除孤立软件包", + "Uninstall unused flatpak packages": "卸载未使用的 Flatpak 软件包", + "Inaccurate Color picker": "不准确 颜色选择器", + "Result": "结果", + "Type to search": "输入以搜索", + "illogical-impulse": "illogical-impulse", + "RAM Usage": "RAM 使用情况", + "Swap Usage": "Swap 使用情况", + "CPU Usage": "CPU 使用情况", + "Uptime:": "运行时间:", + "Screen snip": "屏幕截图", + "Color picker": "颜色选择器", + "Toggle on-screen keyboard": "切换屏幕键盘", + "Night Light": "夜灯", + "Color inversion": "颜色反转", + "Keep system awake": "保持系统唤醒", + "Cloudflare WARP": "Cloudflare WARP", + "Session": "会话", + "Bluetooth | Right-click to configure": "蓝牙 | 右键单击以配置", + "Wifi | Right-click to configure": "Wi-Fi | 右键单击以配置", + "Right-click to configure": "右键单击以配置", + "Unknown": "未知", + "Reload Environment config": "重新加载环境配置", + "Open Settings": "打开设置", + "Notifications": "通知", + "Audio controls": "音频控制", + "Bluetooth": "蓝牙", + "Wifi networks": "Wi-Fi 网络", + "Live config": "实时配置", + "Silence": "静音", + "Clear": "清除", + "No notifications": "无通知", + "notifications": "条通知", + "Close": "关闭", + "Now": "现在", + "Yesterday": "昨天", + "No audio source": "没有音频源", + "Remove device": "移除设备", + "Connected": "已连接", + "Paired": "已配对", + "More": "更多", + "Selected": "已选中", + "Current network": "当前网络", + "Authentication": "身份验证", + "Effects": "效果", + "Transparency": "透明度", + "[AGS]\nMake shell elements transparent\nBlur is also recommended if you enable this": "[AGS]\n使外壳元素透明\n如果启用此功能,也建议使用模糊效果", + "Blur": "模糊", + "[Hyprland]\nEnable blur on transparent elements\nDoesn't affect performance/power consumption unless you have transparent windows.": "[Hyprland]\n在透明元素上启用模糊效果\n除非您有透明窗口,否则不会影响性能/功耗。", + "X-ray": "X-ray", + "[Hyprland]\nMake everything behind a window/layer except the wallpaper not rendered on its blurred surface\nRecommended to improve performance (if you don't abuse transparency/blur) ": "[Hyprland]\n使窗口/图层后面的所有内容(除了壁纸)在其模糊表面上不渲染\n建议提高性能(如果您不滥用透明度/模糊)", + "Size": "大小", + "[Hyprland]\nAdjust the blur radius. Generally doesn't affect performance\nHigher = more color spread": "[Hyprland]\n调整模糊半径。通常不会影响性能\n数值越高 = 颜色扩散越大", + "Passes": "次数", + "[Hyprland] Adjust the number of runs of the blur algorithm\nMore passes = more spread and power consumption\n4 is recommended\n2- would look weird and 6+ would look lame.": "[Hyprland]\n调整模糊算法的运行次数\n次数越多 = 扩散越大,功耗越高\n建议使用 4 次\n2 次看起来很奇怪,6 次以上看起来很糟糕。", + "Animations": "动画", + "[Hyprland] [GTK]\nEnable animations": "[Hyprland] [GTK]\n启用动画", + "Choreography delay": "间隔", + "In milliseconds, the delay between animations of a series": "以毫秒为单位,一系列动画之间的延迟", + "Developer": "开发者选项", + "Show FPS": "显示 FPS", + "[Hyprland]\nShow FPS overlay on top-left corner": "[Hyprland]\n在左上角显示 FPS 叠加层", + "Log to stdout": "输出日志", + "[Hyprland]\nPrint LOG, ERR, WARN, etc. messages to the console": "[Hyprland]\n将 LOG、ERR、WARN 等消息打印到控制台", + "Damage tracking": "Damage tracking", + "[Hyprland]\nEnable damage tracking\nGenerally, leave it on.\nTurn off only when a shader doesn't work": "[Hyprland]\n启用 Damage tracking \n通常情况下,保持启用状态\n仅当着色器无法正常工作时才禁用", + "Damage blink": "显示视图更新", + "[Hyprland] [Epilepsy warning!]\nShow screen damage flashes": "[Hyprland] [癫痫警告!]\n屏幕视图更新时闪烁", + "Not all changes are saved": "并非所有更改都已保存", + "Mo": "一", + "Tu": "二", + "We": "三", + "Th": "四", + "Fr": "五", + "Sa": "六", + "Su": "日", + "Calendar": "日历", + "To Do": "待办", + "Unfinished": "未完成", + "Done": "已完成", + "Finished tasks will go here": "已完成的任务将显示在此处", + "Nothing here!": "这里什么也没有!", + "+ New task": "+ 新任务", + "Add a task...": "添加任务...", + "Color scheme": "配色方案", + "Options": "选项", + "Dark Mode": "深色模式", + "Ya should go to sleep!": "你应该去睡觉!", + "Use Gradience": "GTK 主题", + "Theme GTK apps using accent color\n(drawback: dark/light mode switching requires restart)": "使用强调色对 GTK 应用程序进行主题化\n(缺点:深色/浅色模式切换需要重启)", + "Scheme styles": "样式方案", + "Vibrant": "鲜艳", + "Vibrant+": "鲜艳+", + "Expressive": "表现力", + "Monochrome": "黑白", + "Rainbow": "彩虹", + "Fidelity": "保真度", + "Fruit Salad": "水果沙拉", + "Tonal Spot": "色调点", + "Content": "内容", + "Use arrow keys to navigate.\nEnter to select, Esc to cancel.": "使用箭头键导航。\n回车键选择,Esc 键取消。", + "Lock": "锁屏", + "Logout": "注销", + "Sleep": "睡眠", + "Hibernate": "休眠", + "Shutdown": "关机", + "Reboot": "重启", + "Cancel": "取消", + "Cheat sheet": "备忘单", + "Keybinds": "按键绑定", + "Periodic table": "元素周期表", + "Essentials for beginners": "初学者必备", + "Make shell elements transparent": "使外壳元素透明", + "Actions": "操作", + "Window management": "窗口管理", + "Window arrangement": "窗口排列", + "Workspace management": "工作区管理", + "Workspace navigation": "工作区导航", + "Widgets": "小部件", + "Media": "媒体", + "Apps": "应用程序", + "Neutral": "中性", + "Launch foot (terminal)": "启动终端(foot)", + "Open app launcher": "打开应用程序启动器", + "Change wallpaper": "更改壁纸", + "Clipboard history >> clipboard": "剪贴板历史 >> 剪贴板", + "Pick emoji >> clipboard": "选择表情符号 >> 剪贴板", + "Screen snip >> edit": "屏幕截图 >> 编辑", + "Screen snip to text >> clipboard": "屏幕截图转文字 >> 剪贴板", + "Pick color (Hex) >> clipboard": "选择颜色(十六进制)>> 剪贴板", + "Screenshot >> clipboard": "屏幕截图 >> 剪贴板", + "Screenshot >> clipboard & file": "屏幕截图 >> 剪贴板和文件", + "Record region (no sound)": "录制区域(无声音)", + "Record screen (with sound)": "录制屏幕(带声音)", + "Suspend system": "挂起系统", + "Move focus in direction": "在方向上移动焦点", + "Move window": "移动窗口", + "Resize window": "调整窗口大小", + "Close window": "关闭窗口", + "Pick and kill a window": "选择并关闭一个窗口", + "Window: move in direction": "窗口:在方向上移动", + "Window: split ratio +/- 0.1": "窗口:分割比例 +/- 0.1", + "Float/unfloat window": "浮动/取消浮动窗口", + "Toggle fake fullscreen": "切换伪全屏", + "Toggle fullscreen": "切换全屏", + "Toggle maximization": "切换最大化", + "Focus workspace # (1, 2, 3, 4, ...)": "聚焦工作区 #(1, 2, 3, 4, ...)", + "Workspace: focus left/right": "工作区:聚焦左右", + "Workspace: toggle special": "工作区:切换特殊工作区", + "Window: move to workspace # (1, 2, 3, 4, ...)": "窗口:移动到工作区 #(1, 2, 3, 4, ...)", + "Window: move to workspace left/right": "窗口:移动到左右工作区", + "Window: move to workspace special": "窗口:移动到特殊工作区", + "Window: pin (show on all workspaces)": "窗口:固定(在所有工作区显示)", + "Restart widgets": "重启小部件", + "Cycle bar mode (normal, focus)": "循环栏模式(正常,聚焦)", + "Toggle overview/launcher": "切换概览/启动器", + "Show cheatsheet": "显示快捷键表", + "Toggle left sidebar": "切换左侧边栏", + "Toggle right sidebar": "切换右侧边栏", + "Toggle music controls": "切换音乐控制", + "View color scheme and options": "查看配色方案和选项", + "Toggle power menu": "切换电源菜单", + "Toggle crosshair": "切换准星", + "Next track": "下一曲目", + "Previous track": "上一曲目", + "Play/pause media": "播放/暂停媒体", + "Launch Zed (editor)": "启动 Zed(编辑器)", + "Launch VSCode (editor)": "启动 VSCode(编辑器)", + "Launch Nautilus (file manager)": "启动 Nautilus(文件管理器)", + "Launch Firefox (browser)": "启动 Firefox(浏览器)", + "Launch GNOME Text Editor": "启动 GNOME 文本编辑器", + "Launch WPS Office": "启动 WPS 办公软件", + "Launch GNOME Settings": "启动 GNOME 设置", + "Launch pavucontrol (volume mixer)": "启动 pavucontrol(音量混合器)", + "Launch EasyEffects (equalizer & other audio effects)": "启动 EasyEffects(均衡器和其他音频效果)", + "Launch GNOME System monitor": "启动 GNOME 系统监视器", + "Toggle fallback launcher: anyrun": "切换备用启动器:anyrun", + "Toggle fallback launcher: fuzzel": "切换备用启动器:fuzzel", + "Initialization complete!": "初始化完成!", + "Not found": "未找到", + "Calling API": "调用 API", + "Downloading image": "正在下载图片", + "Finished!": "完成!", + "Error": "错误", + "Not found!": "未找到!", + "Go to file url": "前往文件链接", + "Save image": "保存图片", + "Hoard": "保存", + "Open externally": "在外部打开", + "You are an assistant on a sidebar of a Wayland Linux desktop. Please always use a casual tone when answering your questions, unless requested otherwise or making writing suggestions. These are the steps you should take to respond to the user's queries:\n1. If it's a writing- or grammar-related question or a sentence in quotation marks, Please point out errors and correct when necessary using underlines, and make the writing more natural where appropriate without making too major changes. If you're given a sentence in quotes but is grammatically correct, explain briefly concepts that are uncommon.\n2. If it's a question about system tasks, give a bash command in a code block with brief explanation.\n3. Otherwise, when asked to summarize information or explaining concepts, you are should use bullet points and headings. For mathematics expressions, you *have to* use LaTeX within a code block with the language set as \"latex\". \nNote: Use casual language, be short, while ensuring the factual correctness of your response. If you are unsure or don’t have enough information to provide a confident answer, simply say “I don’t know” or “I’m not sure.”. \nThanks!": "你是 Wayland Linux 桌面侧边栏上的助手。除非有其他要求或提供建议,否则请始终保持轻松的语气回答问题。这是你回答用户查询的步骤:\n1. 如果是写作或语法相关的问题,或者引号中的句子,请指出错误并在必要时进行更正,使用下划线,并在适当的地方使写作更自然,不要进行太大更改。如果你给出的句子在引号中但语法正确,请简要解释不常见概念。\n2. 如果是关于系统任务的问题,请给出bash命令,并在代码块中简要说明。\n3. 否则,在总结信息或解释概念时,你应该使用项目符号和标题。对于数学表达式,你必须在代码块中使用 LaTeX,并将语言设置为\"latex\"。\n注意:使用轻松的语言,简洁,同时确保回答的事实正确性。如果你不确定或没有足够的信息来提供自信的答案,只需说“我不知道”或“我不确定”。\n谢谢!" +} \ No newline at end of file diff --git a/.config/ags/init.js b/.config/ags/init.js index 07c837b50..48c56ddac 100644 --- a/.config/ags/init.js +++ b/.config/ags/init.js @@ -2,9 +2,7 @@ import GLib from 'gi://GLib'; import App from 'resource:///com/github/Aylur/ags/app.js' import * as Utils from 'resource:///com/github/Aylur/ags/utils.js' import { darkMode } from './modules/.miscutils/system.js'; - export const COMPILED_STYLE_DIR = `${GLib.get_user_cache_dir()}/ags/user/generated` - globalThis['handleStyles'] = (resetMusic) => { // Reset Utils.exec(`mkdir -p "${GLib.get_user_state_dir()}/ags/scss"`); @@ -15,7 +13,7 @@ globalThis['handleStyles'] = (resetMusic) => { // Generate overrides let lightdark = darkMode.value ? "dark" : "light"; Utils.writeFileSync( -`@mixin symbolic-icon { + `@mixin symbolic-icon { -gtk-icon-theme: '${userOptions.icons.symbolicIconTheme[lightdark]}'; } `, diff --git a/.config/ags/modules/.commonwidgets/notification.js b/.config/ags/modules/.commonwidgets/notification.js index 57840ff7c..85ee86bad 100644 --- a/.config/ags/modules/.commonwidgets/notification.js +++ b/.config/ags/modules/.commonwidgets/notification.js @@ -29,11 +29,11 @@ const getFriendlyNotifTimeString = (timeObject) => { const messageTime = GLib.DateTime.new_from_unix_local(timeObject); const oneMinuteAgo = GLib.DateTime.new_now_local().add_seconds(-60); if (messageTime.compare(oneMinuteAgo) > 0) - return 'Now'; + return getString('Now'); else if (messageTime.get_day_of_year() == GLib.DateTime.new_now_local().get_day_of_year()) return messageTime.format(userOptions.time.format); else if (messageTime.get_day_of_year() == GLib.DateTime.new_now_local().get_day_of_year() - 1) - return 'Yesterday'; + return getString('Yesterday'); else return messageTime.format(userOptions.time.dateFormat); } @@ -198,7 +198,7 @@ export default ({ onClicked: () => destroyWithAnims(), setup: setupCursorHover, child: Label({ - label: 'Close', + label: getString('Close'), }), }), ...notifObject.actions.map(action => Widget.Button({ diff --git a/.config/ags/modules/.configuration/user_options.js b/.config/ags/modules/.configuration/user_options.js index 13be1e91d..c7c19eafa 100644 --- a/.config/ags/modules/.configuration/user_options.js +++ b/.config/ags/modules/.configuration/user_options.js @@ -69,6 +69,10 @@ let configOptions = { 'color': 'rgba(113,227,32,0.9)', }, }, + 'i18n': { + 'langCode': "",//Customize the locale, such as zh_CN,Optional value references "~/.config/ags/i18n/locales/" + 'extraLogs': false + }, 'monitors': { 'scaleMethod': "division", // Either "division" [default] or "gdk" }, diff --git a/.config/ags/modules/bar/normal/music.js b/.config/ags/modules/bar/normal/music.js index 1df922351..35fb8288d 100644 --- a/.config/ags/modules/bar/normal/music.js +++ b/.config/ags/modules/bar/normal/music.js @@ -145,7 +145,7 @@ export default () => { if (mpris) label.label = `${trimTrackTitle(mpris.trackTitle)} • ${mpris.trackArtists.join(', ')}`; else - label.label = 'No media'; + label.label = getString('No media'); }), }) const musicStuff = Box({ @@ -183,7 +183,7 @@ export default () => { } else return BarGroup({ child: Box({ children: [ - BarResource('RAM Usage', 'memory', `LANG=C free | awk '/^Mem/ {printf("%.2f\\n", ($3/$2) * 100)}'`, + BarResource(getString('RAM Usage'), 'memory', `LANG=C free | awk '/^Mem/ {printf("%.2f\\n", ($3/$2) * 100)}'`, 'bar-ram-circprog', 'bar-ram-txt', 'bar-ram-icon'), Revealer({ revealChild: true, @@ -192,9 +192,9 @@ export default () => { child: Box({ className: 'spacing-h-10 margin-left-10', children: [ - BarResource('Swap Usage', 'swap_horiz', `LANG=C free | awk '/^Swap/ {if ($2 > 0) printf("%.2f\\n", ($3/$2) * 100); else print "0";}'`, + BarResource(getString('Swap Usage'), 'swap_horiz', `LANG=C free | awk '/^Swap/ {if ($2 > 0) printf("%.2f\\n", ($3/$2) * 100); else print "0";}'`, 'bar-swap-circprog', 'bar-swap-txt', 'bar-swap-icon'), - BarResource('CPU Usage', 'settings_motion_mode', `LANG=C top -bn1 | grep Cpu | sed 's/\\,/\\./g' | awk '{print $2}'`, + BarResource(getString('CPU Usage'), 'settings_motion_mode', `LANG=C top -bn1 | grep Cpu | sed 's/\\,/\\./g' | awk '{print $2}'`, 'bar-cpu-circprog', 'bar-cpu-txt', 'bar-cpu-icon'), ] }), diff --git a/.config/ags/modules/bar/normal/system.js b/.config/ags/modules/bar/normal/system.js index 82a5bc384..6e4907eb2 100644 --- a/.config/ags/modules/bar/normal/system.js +++ b/.config/ags/modules/bar/normal/system.js @@ -74,18 +74,18 @@ const Utilities = () => Box({ className: 'spacing-h-4', children: [ UtilButton({ - name: 'Screen snip', icon: 'screenshot_region', onClicked: () => { + name: getString('Screen snip'), icon: 'screenshot_region', onClicked: () => { Utils.execAsync(`${App.configDir}/scripts/grimblast.sh copy area`) .catch(print) } }), UtilButton({ - name: 'Color picker', icon: 'colorize', onClicked: () => { + name: getString('Color picker'), icon: 'colorize', onClicked: () => { Utils.execAsync(['hyprpicker', '-a']).catch(print) } }), UtilButton({ - name: 'Toggle on-screen keyboard', icon: 'keyboard', onClicked: () => { + name: getString('Toggle on-screen keyboard'), icon: 'keyboard', onClicked: () => { toggleWindowOnAllMonitors('osk'); } }), diff --git a/.config/ags/modules/cheatsheet/keybinds.js b/.config/ags/modules/cheatsheet/keybinds.js index 09cd100ae..2464f0a6c 100644 --- a/.config/ags/modules/cheatsheet/keybinds.js +++ b/.config/ags/modules/cheatsheet/keybinds.js @@ -12,8 +12,8 @@ const getKeybindList = () => { let data = Utils.exec(`${App.configDir}/scripts/hyprland/get_keybinds.py --path ${HYPRLAND_KEYBIND_CONFIG_FILE}`); if (data == "\"error\"") { Utils.timeout(2000, () => Utils.execAsync(['notify-send', - 'Update path to keybinds', - 'Keybinds hyprland config file not found. Check your user options.', + 'Update path to keybinds', + 'Keybinds hyprland config file not found. Check your user options.', '-a', 'ags', ]).catch(print)) return { children: [] }; @@ -45,7 +45,7 @@ const Keybind = (keybindData, type) => { // type: either "keys" or "actions" }); const Action = (text) => Label({ // Binds xalign: 0, - label: text, + label: getString(text), className: "txt txt-small cheatsheet-action", }) return Widget.Box({ @@ -74,7 +74,7 @@ const Section = (sectionData, scope) => { const name = Label({ xalign: 0, className: "cheatsheet-category-title txt margin-bottom-10", - label: sectionData.name, + label: getString(sectionData.name), }) const binds = Box({ className: 'spacing-h-10', diff --git a/.config/ags/modules/cheatsheet/main.js b/.config/ags/modules/cheatsheet/main.js index 65fe7c922..4c6bb063f 100644 --- a/.config/ags/modules/cheatsheet/main.js +++ b/.config/ags/modules/cheatsheet/main.js @@ -9,12 +9,12 @@ import clickCloseRegion from '../.commonwidgets/clickcloseregion.js'; const cheatsheets = [ { - name: 'Keybinds', + name: getString('Keybinds'), materialIcon: 'keyboard', contentWidget: Keybinds, }, { - name: 'Periodic table', + name: getString('Periodic table'), materialIcon: 'experiment', contentWidget: PeriodicTable, }, @@ -35,7 +35,7 @@ const CheatsheetHeader = () => Widget.CenterBox({ hpack: 'center', css: 'margin-right: 0.682rem;', className: 'txt-title', - label: 'Cheat sheet', + label: getString('Cheat sheet'), }), Widget.Label({ vpack: 'center', diff --git a/.config/ags/modules/indicators/colorscheme.js b/.config/ags/modules/indicators/colorscheme.js index b91375b5d..bb00558ef 100644 --- a/.config/ags/modules/indicators/colorscheme.js +++ b/.config/ags/modules/indicators/colorscheme.js @@ -78,22 +78,22 @@ function calculateSchemeInitIndex(optionsArr, searchValue = 'vibrant') { const schemeOptionsArr = [ [ - { name: 'Tonal Spot', value: 'tonalspot' }, - { name: 'Fruit Salad', value: 'fruitsalad' }, - { name: 'Fidelity', value: 'fidelity' }, - { name: 'Rainbow', value: 'rainbow' }, + { name: getString('Tonal Spot'), value: 'tonalspot' }, + { name: getString('Fruit Salad'), value: 'fruitsalad' }, + { name: getString('Fidelity'), value: 'fidelity' }, + { name: getString('Rainbow'), value: 'rainbow' }, ], [ - { name: 'Neutral', value: 'neutral' }, - { name: 'Monochrome', value: 'monochrome' }, - { name: 'Expressive', value: 'expressive' }, - { name: 'Vibrant', value: 'vibrant' }, + { name: getString('Neutral'), value: 'neutral' }, + { name: getString('Monochrome'), value: 'monochrome' }, + { name: getString('Expressive'), value: 'expressive' }, + { name: getString('Vibrant'), value: 'vibrant' }, ], [ - { name: 'Vibrant+', value: 'morevibrant' }, + { name: getString('Vibrant+'), value: 'morevibrant' }, ], //[ - // { name: 'Content', value: 'content' }, + // { name: getString('Content'), value: 'content' }, //] ]; @@ -114,14 +114,14 @@ const ColorSchemeSettings = () => Widget.Box({ Widget.Label({ xalign: 0, className: 'txt-norm titlefont txt', - label: 'Options', + label: getString('Options'), hpack: 'center', }), ////////////////// ConfigToggle({ icon: 'dark_mode', - name: 'Dark Mode', - desc: 'Ya should go to sleep!', + name: getString('Dark Mode'), + desc: getString('Ya should go to sleep!'), initValue: darkMode.value, onChange: (_, newValue) => { darkMode.value = !!newValue; @@ -132,8 +132,8 @@ const ColorSchemeSettings = () => Widget.Box({ }), ConfigToggle({ icon: 'border_clear', - name: 'Transparency', - desc: 'Make shell elements transparent', + name: getString('Transparency'), + desc: getString('Make shell elements transparent'), initValue: initTransparencyVal, onChange: (self, newValue) => { let transparency = newValue == 0 ? "opaque" : "transparent"; @@ -143,13 +143,13 @@ const ColorSchemeSettings = () => Widget.Box({ }, }), Widget.Box({ - tooltipText: 'Theme GTK apps using accent color\n(drawback: dark/light mode switching requires restart)', + tooltipText: getString('Theme GTK apps using accent color\n(drawback: dark/light mode switching requires restart)'), className: 'txt spacing-h-5 configtoggle-box', children: [ MaterialIcon('imagesearch_roller', 'norm'), Widget.Label({ className: 'txt txt-small', - label: 'Use Gradience', + label: getString('Use Gradience'), }), Widget.Box({ hexpand: true }), ConfigMulipleSelection({ @@ -179,7 +179,7 @@ const ColorSchemeSettings = () => Widget.Box({ Widget.Label({ xalign: 0, className: 'txt-norm titlefont txt margin-top-5', - label: 'Scheme styles', + label: getString('Scheme styles'), hpack: 'center', }), ////////////////// @@ -207,7 +207,7 @@ const ColorschemeContent = () => Widget.Box({ Widget.Label({ xalign: 0, className: 'txt-norm titlefont txt', - label: 'Color scheme', + label: getString('Color scheme'), hpack: 'center', }), Widget.Box({ diff --git a/.config/ags/modules/overview/windowcontent.js b/.config/ags/modules/overview/windowcontent.js index 5eb6bb568..23e839395 100644 --- a/.config/ags/modules/overview/windowcontent.js +++ b/.config/ags/modules/overview/windowcontent.js @@ -70,7 +70,7 @@ export const SearchAndWindows = () => { hpack: 'center', child: Widget.Label({ className: 'overview-search-prompt txt-small txt', - label: 'Type to search' + label: getString('Type to search') }), }); diff --git a/.config/ags/modules/session/sessionscreen.js b/.config/ags/modules/session/sessionscreen.js index 1160047ff..007878b6e 100644 --- a/.config/ags/modules/session/sessionscreen.js +++ b/.config/ags/modules/session/sessionscreen.js @@ -61,14 +61,14 @@ const SessionButton = (name, icon, command, props = {}, colorid = 0) => { export default ({ id = 0 }) => { // lock, logout, sleep - const lockButton = SessionButton('Lock', 'lock', () => { closeWindowOnAllMonitors('session'); execAsync(['loginctl', 'lock-session']).catch(print) }, {}, 1); - const logoutButton = SessionButton('Logout', 'logout', () => { closeWindowOnAllMonitors('session'); execAsync(['bash', '-c', 'pkill Hyprland || pkill sway || pkill niri || loginctl terminate-user $USER']).catch(print) }, {}, 2); - const sleepButton = SessionButton('Sleep', 'sleep', () => { closeWindowOnAllMonitors('session'); execAsync(['bash', '-c', 'systemctl suspend || loginctl suspend']).catch(print) }, {}, 3); + const lockButton = SessionButton(getString('Lock'), 'lock', () => { closeWindowOnAllMonitors('session'); execAsync(['loginctl', 'lock-session']).catch(print) }, {}, 1); + const logoutButton = SessionButton(getString('Logout'), 'logout', () => { closeWindowOnAllMonitors('session'); execAsync(['bash', '-c', 'pkill Hyprland || pkill sway || pkill niri || loginctl terminate-user $USER']).catch(print) }, {}, 2); + const sleepButton = SessionButton(getString('Sleep'), 'sleep', () => { closeWindowOnAllMonitors('session'); execAsync(['bash', '-c', 'systemctl suspend || loginctl suspend']).catch(print) }, {}, 3); // hibernate, shutdown, reboot - const hibernateButton = SessionButton('Hibernate', 'downloading', () => { closeWindowOnAllMonitors('session'); execAsync(['bash', '-c', 'systemctl hibernate || loginctl hibernate']).catch(print) }, {}, 4); - const shutdownButton = SessionButton('Shutdown', 'power_settings_new', () => { closeWindowOnAllMonitors('session'); execAsync(['bash', '-c', 'systemctl poweroff || loginctl poweroff']).catch(print) }, {}, 5); - const rebootButton = SessionButton('Reboot', 'restart_alt', () => { closeWindowOnAllMonitors('session'); execAsync(['bash', '-c', 'systemctl reboot || loginctl reboot']).catch(print) }, {}, 6); - const cancelButton = SessionButton('Cancel', 'close', () => closeWindowOnAllMonitors('session'), { className: 'session-button-cancel' }, 7); + const hibernateButton = SessionButton(getString('Hibernate'), 'downloading', () => { closeWindowOnAllMonitors('session'); execAsync(['bash', '-c', 'systemctl hibernate || loginctl hibernate']).catch(print) }, {}, 4); + const shutdownButton = SessionButton(getString('Shutdown'), 'power_settings_new', () => { closeWindowOnAllMonitors('session'); execAsync(['bash', '-c', 'systemctl poweroff || loginctl poweroff']).catch(print) }, {}, 5); + const rebootButton = SessionButton(getString('Reboot'), 'restart_alt', () => { closeWindowOnAllMonitors('session'); execAsync(['bash', '-c', 'systemctl reboot || loginctl reboot']).catch(print) }, {}, 6); + const cancelButton = SessionButton(getString('Cancel'), 'close', () => closeWindowOnAllMonitors('session'), { className: 'session-button-cancel' }, 7); const sessionDescription = Widget.Box({ vertical: true, @@ -76,12 +76,12 @@ export default ({ id = 0 }) => { children: [ Widget.Label({ className: 'txt-title txt', - label: 'Session', + label: getString('Session'), }), Widget.Label({ justify: Gtk.Justification.CENTER, className: 'txt-small txt', - label: 'Use arrow keys to navigate.\nEnter to select, Esc to cancel.' + label: getString('Use arrow keys to navigate.\nEnter to select, Esc to cancel.') }), ] }); diff --git a/.config/ags/modules/sideleft/apis/booru.js b/.config/ags/modules/sideleft/apis/booru.js index 340c5d344..564a625db 100644 --- a/.config/ags/modules/sideleft/apis/booru.js +++ b/.config/ags/modules/sideleft/apis/booru.js @@ -67,12 +67,12 @@ const BooruInfo = () => { className: 'txt-smallie txt-subtext', wrap: true, justify: Gtk.Justification.CENTER, - label: 'Powered by yande.re and konachan', + label: getString('Powered by yande.re and konachan'), }), Button({ className: 'txt-subtext txt-norm icon-material', label: 'info', - tooltipText: 'An image booru. May contain NSFW content.\nWatch your back.\n\nDisclaimer: Not affiliated with the provider\nnor responsible for any of its content.', + tooltipText: getString('An image booru. May contain NSFW content.\nWatch your back.\n\nDisclaimer: Not affiliated with the provider\nnor responsible for any of its content.'), setup: setupCursorHoverInfo, }), ] @@ -95,13 +95,8 @@ export const BooruSettings = () => MarginRevealer({ children: [ ConfigToggle({ icon: 'menstrual_health', - name: 'Lewds', - desc: `Shows naughty stuff when enabled.\nYa like those? Add this to user_options.js: -'sidebar': { - 'image': { - 'allowNsfw': true, - } -},`, + name: getString('Lewds'), + desc: getString("Shows naughty stuff when enabled.\nYa like those? Add this to user_options.js:\n\t'sidebar': {\n\t'image': {\n\t\t'allowNsfw': true,\n\t}\n}"), initValue: BooruService.nsfw, onChange: (self, newValue) => { BooruService.nsfw = newValue; @@ -112,8 +107,8 @@ export const BooruSettings = () => MarginRevealer({ }), ConfigToggle({ icon: 'sell', - name: 'Save in folder by tags', - desc: 'Saves images in folders by their tags', + name: getString('Save in folder by tags'), + desc: getString('Saves images in folders by their tags'), initValue: userOptions.sidebar.image.saveInFolderByTags, onChange: (self, newValue) => { userOptions.sidebar.image.saveInFolderByTags = newValue; @@ -217,17 +212,17 @@ const BooruPage = (taglist, serviceName = 'Booru') => { children: [ Box({ hexpand: true }), ImageAction({ - name: 'Go to file url', + name: getString('Go to file url'), icon: 'file_open', action: () => execAsync(['xdg-open', `${data.file_url}`]).catch(print), }), ImageAction({ - name: 'Go to source', + name: getString('Go to source'), icon: 'open_in_new', action: () => execAsync(['xdg-open', `${data.source}`]).catch(print), }), ImageAction({ - name: 'Save image', + name: getString('Save image'), icon: 'save', action: (self) => { const currentTags = BooruService.queries.at(-1).realTagList.filter(tag => !tag.includes('rating:')); @@ -263,10 +258,10 @@ const BooruPage = (taglist, serviceName = 'Booru') => { transition: 'slide_up_down', transitionDuration: userOptions.animations.durationSmall, children: { - 'api': PageState('api', 'Calling API'), - 'download': PageState('downloading', 'Downloading image'), - 'done': PageState('done', 'Finished!'), - 'error': PageState('error', 'Error'), + 'api': PageState('api', getString('Calling API')), + 'download': PageState('downloading', getString('Downloading image')), + 'done': PageState('done', getString('Finished!')), + 'error': PageState('error', getString('Error')), }, }); const downloadIndicator = MarginRevealer({ @@ -469,7 +464,7 @@ export const booruCommands = Box({ self.pack_start(Button({ className: 'sidebar-chat-chip-toggle', setup: setupCursorHover, - label: 'Tags →', + label: getString('Tags →'), onClicked: () => { booruTags.revealChild = !booruTags.revealChild; } diff --git a/.config/ags/modules/sideleft/apis/chatgpt.js b/.config/ags/modules/sideleft/apis/chatgpt.js index a223b1227..6bdc3828a 100644 --- a/.config/ags/modules/sideleft/apis/chatgpt.js +++ b/.config/ags/modules/sideleft/apis/chatgpt.js @@ -53,7 +53,7 @@ const ProviderSwitcher = () => { } const indicatorChevron = MaterialIcon('expand_more', 'norm'); const indicatorButton = Button({ - tooltipText: 'Select ChatGPT-compatible API provider', + tooltipText: getString('Select ChatGPT-compatible API provider'), child: Box({ className: 'spacing-h-10 txt', children: [ @@ -121,7 +121,7 @@ const GPTInfo = () => { className: 'txt txt-title-small sidebar-chat-welcome-txt', wrap: true, justify: Gtk.Justification.CENTER, - label: 'Assistant (GPTs)', + label: `Assistant (GPTs)`, }), Box({ className: 'spacing-h-5', @@ -131,12 +131,12 @@ const GPTInfo = () => { className: 'txt-smallie txt-subtext', wrap: true, justify: Gtk.Justification.CENTER, - label: 'Provider shown above', + label: getString('Provider shown above'), }), Button({ className: 'txt-subtext txt-norm icon-material', label: 'info', - tooltipText: 'Uses gpt-3.5-turbo.\nNot affiliated, endorsed, or sponsored by OpenAI.\n\nPrivacy: OpenAI claims they do not use your data\nwhen you use their API. Idk about others.', + tooltipText: getString('Uses gpt-3.5-turbo.\nNot affiliated, endorsed, or sponsored by OpenAI.\n\nPrivacy: OpenAI claims they do not use your data\nwhen you use their API. Idk about others.'), setup: setupCursorHoverInfo, }), ] @@ -164,11 +164,11 @@ const GPTSettings = () => MarginRevealer({ hpack: 'center', icon: 'casino', name: 'Randomness', - desc: 'The model\'s temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1', + desc: getString('The model\'s temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1'), options: [ - { value: 0.00, name: 'Precise', }, - { value: 0.50, name: 'Balanced', }, - { value: 1.00, name: 'Creative', }, + { value: 0.00, name: getString('Precise'), }, + { value: 0.50, name: getString('Balanced'), }, + { value: 1.00, name: getString('Creative'), }, ], initIndex: 2, onChange: (value, name) => { @@ -183,8 +183,8 @@ const GPTSettings = () => MarginRevealer({ children: [ ConfigToggle({ icon: 'model_training', - name: 'Enhancements', - desc: 'Tells the model:\n- It\'s a Linux sidebar assistant\n- Be brief and use bullet points', + name: getString('Enhancements'), + desc: getString('Tells the model:\n- It\'s a Linux sidebar assistant\n- Be brief and use bullet points'), initValue: GPTService.assistantPrompt, onChange: (self, newValue) => { GPTService.assistantPrompt = newValue; @@ -212,7 +212,7 @@ export const OpenaiApiKeyInstructions = () => Box({ wrap: true, className: 'txt sidebar-chat-welcome-txt', justify: Gtk.Justification.CENTER, - label: 'An API key is required\nYou can grab one here, then enter it below' + label: getString('An API key is required\nYou can grab one here, then enter it below') }), setup: setupCursorHover, onClicked: () => { @@ -287,7 +287,7 @@ export const sendMessage = (text) => { // Commands if (text.startsWith('/')) { if (text.startsWith('/clear')) clearChat(); - else if (text.startsWith('/model')) chatContent.add(SystemMessage(`Currently using \`${GPTService.modelName}\``, '/model', chatGPTView)) + else if (text.startsWith('/model')) chatContent.add(SystemMessage(`${getString("Currently using")} \`${GPTService.modelName}\``, '/model', chatGPTView)) else if (text.startsWith('/prompt')) { const firstSpaceIndex = text.indexOf(' '); const prompt = text.slice(firstSpaceIndex + 1); @@ -301,18 +301,18 @@ export const sendMessage = (text) => { else if (text.startsWith('/key')) { const parts = text.split(' '); if (parts.length == 1) chatContent.add(SystemMessage( - `Key stored in:\n\`${GPTService.keyPath}\`\nTo update this key, type \`/key YOUR_API_KEY\``, + `${getString("Key stored in:")}\n\`${GPTService.keyPath}\`\n${getString("To update this key, type")} \`/key YOUR_API_KEY\``, '/key', chatGPTView)); else { GPTService.key = parts[1]; - chatContent.add(SystemMessage(`Updated API Key at\n\`${GPTService.keyPath}\``, '/key', chatGPTView)); + chatContent.add(SystemMessage(`${getString("Updated API Key at")}\n\`${GPTService.keyPath}\``, '/key', chatGPTView)); } } else if (text.startsWith('/test')) chatContent.add(SystemMessage(markdownTest, `Markdown test`, chatGPTView)); else - chatContent.add(SystemMessage(`Invalid command.`, 'Error', chatGPTView)) + chatContent.add(SystemMessage(getString("Invalid command."), 'Error', chatGPTView)) } else { GPTService.send(text); @@ -346,7 +346,7 @@ export const chatGPTView = Box({ // Always scroll to bottom with new content const adjustment = scrolledWindow.get_vadjustment(); adjustment.connect("changed", () => { - if(!chatEntry.hasFocus) return; + if (!chatEntry.hasFocus) return; adjustment.set_value(adjustment.get_upper() - adjustment.get_page_size()); }) } diff --git a/.config/ags/modules/sideleft/apis/gemini.js b/.config/ags/modules/sideleft/apis/gemini.js index 8fd8923e9..2f7de59b6 100644 --- a/.config/ags/modules/sideleft/apis/gemini.js +++ b/.config/ags/modules/sideleft/apis/gemini.js @@ -34,7 +34,7 @@ const GeminiInfo = () => { className: 'txt txt-title-small sidebar-chat-welcome-txt', wrap: true, justify: Gtk.Justification.CENTER, - label: 'Assistant (Gemini)', + label: `Assistant (Gemini)`, }), Box({ className: 'spacing-h-5', @@ -44,12 +44,12 @@ const GeminiInfo = () => { className: 'txt-smallie txt-subtext', wrap: true, justify: Gtk.Justification.CENTER, - label: 'Powered by Google', + label: getString('Powered by Google'), }), Button({ className: 'txt-subtext txt-norm icon-material', label: 'info', - tooltipText: 'Uses gemini-pro.\nNot affiliated, endorsed, or sponsored by Google.\n\nPrivacy: Chat messages aren\'t linked to your account,\n but will be read by human reviewers to improve the model.', + tooltipText: getString("Uses gemini-pro.\nNot affiliated, endorsed, or sponsored by Google.\n\nPrivacy: Chat messages aren't linked to your account,\n but will be read by human reviewers to improve the model."), setup: setupCursorHoverInfo, }), ] @@ -77,11 +77,11 @@ export const GeminiSettings = () => MarginRevealer({ hpack: 'center', icon: 'casino', name: 'Randomness', - desc: 'Gemini\'s temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1', + desc: getString("Gemini's temperature value.\n Precise = 0\n Balanced = 0.5\n Creative = 1"), options: [ - { value: 0.00, name: 'Precise', }, - { value: 0.50, name: 'Balanced', }, - { value: 1.00, name: 'Creative', }, + { value: 0.00, name: getString('Precise'), }, + { value: 0.50, name: getString('Balanced'), }, + { value: 1.00, name: getString('Creative'), }, ], initIndex: 2, onChange: (value, name) => { @@ -96,8 +96,8 @@ export const GeminiSettings = () => MarginRevealer({ children: [ ConfigToggle({ icon: 'model_training', - name: 'Enhancements', - desc: 'Tells Gemini:\n- It\'s a Linux sidebar assistant\n- Be brief and use bullet points', + name: getString('Enhancements'), + desc: getString("Tells Gemini:\n- It's a Linux sidebar assistant\n- Be brief and use bullet points"), initValue: GeminiService.assistantPrompt, onChange: (self, newValue) => { GeminiService.assistantPrompt = newValue; @@ -105,8 +105,8 @@ export const GeminiSettings = () => MarginRevealer({ }), ConfigToggle({ icon: 'shield', - name: 'Safety', - desc: 'When turned off, tells the API (not the model) \nto not block harmful/explicit content', + name: getString('Safety'), + desc: getString("When turned off, tells the API (not the model) \nto not block harmful/explicit content"), initValue: GeminiService.safe, onChange: (self, newValue) => { GeminiService.safe = newValue; @@ -114,8 +114,8 @@ export const GeminiSettings = () => MarginRevealer({ }), ConfigToggle({ icon: 'history', - name: 'History', - desc: 'Saves chat history\nMessages in previous chats won\'t show automatically, but they are there', + name: getString('History'), + desc: getString("Saves chat history\nMessages in previous chats won't show automatically, but they are there"), initValue: GeminiService.useHistory, onChange: (self, newValue) => { GeminiService.useHistory = newValue; @@ -223,7 +223,7 @@ export const sendMessage = (text) => { clearChat(); GeminiService.loadHistory(); } - else if (text.startsWith('/model')) chatContent.add(SystemMessage(`Currently using \`${GeminiService.modelName}\``, '/model', geminiView)) + else if (text.startsWith('/model')) chatContent.add(SystemMessage(`${getString("Currently using")} \`${GeminiService.modelName}\``, '/model', geminiView)) else if (text.startsWith('/prompt')) { const firstSpaceIndex = text.indexOf(' '); const prompt = text.slice(firstSpaceIndex + 1); @@ -237,18 +237,18 @@ export const sendMessage = (text) => { else if (text.startsWith('/key')) { const parts = text.split(' '); if (parts.length == 1) chatContent.add(SystemMessage( - `Key stored in:\n\`${GeminiService.keyPath}\`\nTo update this key, type \`/key YOUR_API_KEY\``, + `${getString("Key stored in:")} \n\`${GeminiService.keyPath}\`\n${getString("To update this key, type")} \`/key YOUR_API_KEY\``, '/key', geminiView)); else { GeminiService.key = parts[1]; - chatContent.add(SystemMessage(`Updated API Key at\n\`${GeminiService.keyPath}\``, '/key', geminiView)); + chatContent.add(SystemMessage(`${getString("Updated API Key at")}\n\`${GeminiService.keyPath}\``, '/key', geminiView)); } } else if (text.startsWith('/test')) chatContent.add(SystemMessage(markdownTest, `Markdown test`, geminiView)); else - chatContent.add(SystemMessage(`Invalid command.`, 'Error', geminiView)) + chatContent.add(SystemMessage(getString(`Invalid command.`), 'Error', geminiView)) } else { GeminiService.send(text); @@ -280,7 +280,7 @@ export const geminiView = Box({ // Always scroll to bottom with new content const adjustment = scrolledWindow.get_vadjustment(); adjustment.connect("changed", () => Utils.timeout(1, () => { - if(!chatEntry.hasFocus) return; + if (!chatEntry.hasFocus) return; adjustment.set_value(adjustment.get_upper() - adjustment.get_page_size()); })) } diff --git a/.config/ags/modules/sideleft/apis/waifu.js b/.config/ags/modules/sideleft/apis/waifu.js index d7bc524b8..89684d9a1 100644 --- a/.config/ags/modules/sideleft/apis/waifu.js +++ b/.config/ags/modules/sideleft/apis/waifu.js @@ -71,12 +71,12 @@ const WaifuInfo = () => { className: 'txt-smallie txt-subtext', wrap: true, justify: Gtk.Justification.CENTER, - label: 'Powered by waifu.im + other APIs', + label: getString('Powered by waifu.im + other APIs'), }), Button({ className: 'txt-subtext txt-norm icon-material', label: 'info', - tooltipText: 'Type tags for a random pic.\nNSFW content will not be returned unless\nyou explicitly request such a tag.\n\nDisclaimer: Not affiliated with the providers\nnor responsible for any of their content.', + tooltipText: getString('Type tags for a random pic.\nNSFW content will not be returned unless\nyou explicitly request such a tag.\n\nDisclaimer: Not affiliated with the providers\nnor responsible for any of their content.'), setup: setupCursorHoverInfo, }), ] @@ -123,11 +123,11 @@ const WaifuImage = (taglist) => { transition: 'slide_up_down', transitionDuration: userOptions.animations.durationSmall, children: { - 'api': ImageState('api', 'Calling API'), - 'download': ImageState('downloading', 'Downloading image'), - 'done': ImageState('done', 'Finished!'), - 'error': ImageState('error', 'Error'), - 'notfound': ImageState('error', 'Not found!'), + 'api': ImageState('api', getString('Calling API')), + 'download': ImageState('downloading', getString('Downloading image')), + 'done': ImageState('done', getString('Finished!')), + 'error': ImageState('error', getString('Error')), + 'notfound': ImageState('error', getString('Not found!')), }, }); const downloadIndicator = MarginRevealer({ @@ -156,12 +156,12 @@ const WaifuImage = (taglist) => { children: [ Box({ hexpand: true }), ImageAction({ - name: 'Go to source', + name: getString('Go to source'), icon: 'link', action: () => execAsync(['xdg-open', `${thisBlock.attribute.imageData.source}`]).catch(print), }), ImageAction({ - name: 'Hoard', + name: getString('Hoard'), icon: 'save', action: (self) => { execAsync(['bash', '-c', `mkdir -p $(xdg-user-dir PICTURES)/homework${thisBlock.attribute.isNsfw ? '/🌶️' : ''} && cp ${thisBlock.attribute.imagePath} $(xdg-user-dir PICTURES)/homework${thisBlock.attribute.isNsfw ? '/🌶️/' : ''}`]) @@ -170,7 +170,7 @@ const WaifuImage = (taglist) => { }, }), ImageAction({ - name: 'Open externally', + name: getString('Open externally'), icon: 'open_in_new', action: () => execAsync([IMAGE_VIEWER_APP, `${thisBlock.attribute.imagePath}`]).catch(print), }), @@ -368,7 +368,7 @@ export const waifuCommands = Box({ self.pack_start(Button({ className: 'sidebar-chat-chip-toggle', setup: setupCursorHover, - label: 'Tags →', + label: getString('Tags →'), onClicked: () => { waifuTags.revealChild = !waifuTags.revealChild; } diff --git a/.config/ags/modules/sideleft/apiwidgets.js b/.config/ags/modules/sideleft/apiwidgets.js index a4884e354..14b335bb9 100644 --- a/.config/ags/modules/sideleft/apiwidgets.js +++ b/.config/ags/modules/sideleft/apiwidgets.js @@ -26,7 +26,7 @@ const APILIST = { contentWidget: geminiView, commandBar: geminiCommands, tabIcon: geminiTabIcon, - placeholderText: 'Message Gemini...', + placeholderText: getString('Message Gemini...'), }, 'gpt': { name: 'Assistant (GPTs)', @@ -34,7 +34,7 @@ const APILIST = { contentWidget: chatGPTView, commandBar: chatGPTCommands, tabIcon: chatGPTTabIcon, - placeholderText: 'Message the model...', + placeholderText: getString('Message the model...'), }, 'waifu': { name: 'Waifus', @@ -42,7 +42,7 @@ const APILIST = { contentWidget: waifuView, commandBar: waifuCommands, tabIcon: waifuTabIcon, - placeholderText: 'Enter tags', + placeholderText: getString('Enter tags'), }, 'booru': { name: 'Booru', @@ -50,7 +50,7 @@ const APILIST = { contentWidget: booruView, commandBar: booruCommands, tabIcon: booruTabIcon, - placeholderText: 'Enter tags', + placeholderText: getString('Enter tags'), }, } const APIS = userOptions.sidebar.pages.apis.order.map((apiName) => APILIST[apiName]); @@ -83,11 +83,11 @@ export const chatEntry = TextView({ }) .hook(GPTService, (self) => { if (APIS[currentApiId].name != 'Assistant (GPTs)') return; - self.placeholderText = (GPTService.key.length > 0 ? 'Message the model...' : 'Enter API Key...'); + self.placeholderText = (GPTService.key.length > 0 ? getString('Message the model...') : getString('Enter API Key...')); }, 'hasKey') .hook(Gemini, (self) => { if (APIS[currentApiId].name != 'Assistant (Gemini Pro)') return; - self.placeholderText = (Gemini.key.length > 0 ? 'Message Gemini...' : 'Enter Google AI API Key...'); + self.placeholderText = (Gemini.key.length > 0 ? getString('Message Gemini...') : getString('Enter Google AI API Key...')); }, 'hasKey') .on("key-press-event", (widget, event) => { // Don't send when Shift+Enter diff --git a/.config/ags/modules/sideleft/tools/colorpicker.js b/.config/ags/modules/sideleft/tools/colorpicker.js index f8c0c8592..b2fde2c16 100644 --- a/.config/ags/modules/sideleft/tools/colorpicker.js +++ b/.config/ags/modules/sideleft/tools/colorpicker.js @@ -174,7 +174,7 @@ export default () => { css: `background-color: ${hslToHex(selectedColor.hue, selectedColor.xAxis, selectedColor.yAxis / (1 + selectedColor.xAxis / 100))};`, children: [Label({ className: 'txt txt-small', - label: 'Result', + label: getString('Result'), }),], attribute: { update: (self) => { @@ -269,7 +269,7 @@ export default () => { }) return SidebarModule({ icon: MaterialIcon('colorize', 'norm'), - name: 'Inaccurate Color picker', + name: getString('Inaccurate Color picker'), revealChild: false, child: Box({ className: 'spacing-h-5', diff --git a/.config/ags/modules/sideleft/tools/name.js b/.config/ags/modules/sideleft/tools/name.js index 72eb198d1..a5cca936e 100644 --- a/.config/ags/modules/sideleft/tools/name.js +++ b/.config/ags/modules/sideleft/tools/name.js @@ -10,7 +10,7 @@ export default () => Box({ className: 'txt sidebar-module techfont', children: [ Label({ - label: 'illogical-impulse' + label: getString('illogical-impulse') }), Box({ hexpand: true }), Button({ diff --git a/.config/ags/modules/sideleft/tools/quickscripts.js b/.config/ags/modules/sideleft/tools/quickscripts.js index 09fdb1b15..e3ffafe62 100644 --- a/.config/ags/modules/sideleft/tools/quickscripts.js +++ b/.config/ags/modules/sideleft/tools/quickscripts.js @@ -12,50 +12,50 @@ import { distroID, isArchDistro, isDebianDistro, hasFlatpak } from '../../.miscu const scripts = [ { - icon: 'desktop-symbolic', - name: 'Change screen resolution', - command: `bash ${App.configDir}/modules/sideleft/tools/changeres.sh`, - enabled: true, - }, + icon: 'desktop-symbolic', + name: getString('Change screen resolution'), + command: `bash ${App.configDir}/modules/sideleft/tools/changeres.sh`, + enabled: true, + }, { icon: 'nixos-symbolic', - name: 'Trim system generations to 5', + name: getString('Trim system generations to 5'), command: `sudo ${App.configDir}/scripts/quickscripts/nixos-trim-generations.sh 5 0 system`, enabled: distroID == 'nixos', }, { icon: 'nixos-symbolic', - name: 'Trim home manager generations to 5', + name: getString('Trim home manager generations to 5'), command: `${App.configDir}/scripts/quickscripts/nixos-trim-generations.sh 5 0 home-manager`, enabled: distroID == 'nixos', }, { icon: 'ubuntu-symbolic', - name: 'Update packages', + name: getString('Update packages'), command: `sudo apt update && sudo apt upgrade -y`, enabled: isDebianDistro, }, { icon: 'fedora-symbolic', - name: 'Update packages', + name: getString('Update packages'), command: `sudo dnf upgrade -y`, enabled: distroID == 'fedora', }, { icon: 'arch-symbolic', - name: 'Update packages', + name: getString('Update packages'), command: `sudo pacman -Syyu`, enabled: isArchDistro, }, { icon: 'arch-symbolic', - name: 'Remove orphan packages', + name: getString('Remove orphan packages'), command: `sudo pacman -R $(pacman -Qdtq)`, enabled: isArchDistro, }, { icon: 'flatpak-symbolic', - name: 'Uninstall unused flatpak packages', + name: getString('Uninstall unused flatpak packages'), command: `flatpak uninstall --unused`, enabled: hasFlatpak, }, @@ -63,7 +63,7 @@ const scripts = [ export default () => SidebarModule({ icon: MaterialIcon('code', 'norm'), - name: 'Quick scripts', + name: getString('Quick scripts'), child: Box({ vertical: true, className: 'spacing-v-5', diff --git a/.config/ags/modules/sideright/calendar.js b/.config/ags/modules/sideright/calendar.js index db66df1b8..b44090491 100644 --- a/.config/ags/modules/sideright/calendar.js +++ b/.config/ags/modules/sideright/calendar.js @@ -30,13 +30,13 @@ function getDateInXMonthsTime(x) { } const weekDays = [ // MONDAY IS THE FIRST DAY OF THE WEEK :HESRIGHTYOUKNOW: - { day: 'Mo', today: 0 }, - { day: 'Tu', today: 0 }, - { day: 'We', today: 0 }, - { day: 'Th', today: 0 }, - { day: 'Fr', today: 0 }, - { day: 'Sa', today: 0 }, - { day: 'Su', today: 0 }, + { day: getString('Mo'), today: 0 }, + { day: getString('Tu'), today: 0 }, + { day: getString('We'), today: 0 }, + { day: getString('Th'), today: 0 }, + { day: getString('Fr'), today: 0 }, + { day: getString('Sa'), today: 0 }, + { day: getString('Su'), today: 0 }, ] const CalendarDay = (day, today) => Widget.Button({ @@ -192,8 +192,8 @@ export const ModuleCalendar = () => Box({ vertical: true, className: 'sidebar-navrail spacing-v-10', children: [ - StackButton('calendar', 'calendar_month', 'Calendar'), - StackButton('todo', 'done_outline', 'To Do'), + StackButton('calendar', 'calendar_month', getString('Calendar')), + StackButton('todo', 'done_outline', getString('To Do')), // StackButton(box, 'stars', 'star', 'GitHub'), ] }), false, false, 0); diff --git a/.config/ags/modules/sideright/centermodules/audiocontrols.js b/.config/ags/modules/sideright/centermodules/audiocontrols.js index c73fab6c5..d992e1e27 100644 --- a/.config/ags/modules/sideright/centermodules/audiocontrols.js +++ b/.config/ags/modules/sideright/centermodules/audiocontrols.js @@ -165,7 +165,7 @@ export default (props) => { className: 'spacing-v-5 txt-subtext', children: [ MaterialIcon('brand_awareness', 'gigantic'), - Label({ label: 'No audio source', className: 'txt-small' }), + Label({ label: getString('No audio source'), className: 'txt-small' }), ] }), ] diff --git a/.config/ags/modules/sideright/centermodules/bluetooth.js b/.config/ags/modules/sideright/centermodules/bluetooth.js index b9ec738d3..b0f410aa8 100644 --- a/.config/ags/modules/sideright/centermodules/bluetooth.js +++ b/.config/ags/modules/sideright/centermodules/bluetooth.js @@ -43,7 +43,7 @@ const BluetoothDevice = (device) => { label: device.connected ? 'Connected' : (device.paired ? 'Paired' : ''), className: 'txt-subtext', setup: (self) => self.hook(device, (self) => { - self.label = device.connected ? 'Connected' : (device.paired ? 'Paired' : ''); + self.label = device.connected ? getString('Connected') : (device.paired ? getString('Paired') : ''); }), }), ] @@ -64,7 +64,7 @@ const BluetoothDevice = (device) => { vpack: 'center', className: 'sidebar-bluetooth-device-remove', child: MaterialIcon('delete', 'norm'), - tooltipText: 'Remove device', + tooltipText: getString('Remove device'), setup: setupCursorHover, onClicked: () => execAsync(['bluetoothctl', 'remove', device.address]).catch(print), }); @@ -144,7 +144,7 @@ export default (props) => { execAsync(['bash', '-c', userOptions.apps.bluetooth]).catch(print); closeEverything(); }, - label: 'More', + label: getString('More'), setup: setupCursorHover, })], }) diff --git a/.config/ags/modules/sideright/centermodules/configure.js b/.config/ags/modules/sideright/centermodules/configure.js index b53556c7f..f78608aa2 100644 --- a/.config/ags/modules/sideright/centermodules/configure.js +++ b/.config/ags/modules/sideright/centermodules/configure.js @@ -60,11 +60,11 @@ export default (props) => { className: 'spacing-v-10', children: [ ConfigSection({ - name: 'Effects', children: [ + name: getString('Effects'), children: [ ConfigToggle({ icon: 'border_clear', - name: 'Transparency', - desc: '[AGS]\nMake shell elements transparent\nBlur is also recommended if you enable this', + name: getString('Transparency'), + desc: getString('[AGS]\nMake shell elements transparent\nBlur is also recommended if you enable this'), initValue: exec(`bash -c "sed -n \'2p\' ${GLib.get_user_state_dir()}/ags/user/colormode.txt"`) == "transparent", onChange: (self, newValue) => { const transparency = newValue == 0 ? "opaque" : "transparent"; @@ -74,22 +74,22 @@ export default (props) => { .catch(print); }, }), - HyprlandToggle({ icon: 'blur_on', name: 'Blur', desc: "[Hyprland]\nEnable blur on transparent elements\nDoesn't affect performance/power consumption unless you have transparent windows.", option: "decoration:blur:enabled" }), + HyprlandToggle({ icon: 'blur_on', name: getString('Blur'), desc: getString("[Hyprland]\nEnable blur on transparent elements\nDoesn't affect performance/power consumption unless you have transparent windows."), option: "decoration:blur:enabled" }), Subcategory([ - HyprlandToggle({ icon: 'stack_off', name: 'X-ray', desc: "[Hyprland]\nMake everything behind a window/layer except the wallpaper not rendered on its blurred surface\nRecommended to improve performance (if you don't abuse transparency/blur) ", option: "decoration:blur:xray" }), - HyprlandSpinButton({ icon: 'target', name: 'Size', desc: '[Hyprland]\nAdjust the blur radius. Generally doesn\'t affect performance\nHigher = more color spread', option: 'decoration:blur:size', minValue: 1, maxValue: 1000 }), - HyprlandSpinButton({ icon: 'repeat', name: 'Passes', desc: '[Hyprland] Adjust the number of runs of the blur algorithm\nMore passes = more spread and power consumption\n4 is recommended\n2- would look weird and 6+ would look lame.', option: 'decoration:blur:passes', minValue: 1, maxValue: 10 }), + HyprlandToggle({ icon: 'stack_off', name: getString('X-ray'), desc: getString("[Hyprland]\nMake everything behind a window/layer except the wallpaper not rendered on its blurred surface\nRecommended to improve performance (if you don't abuse transparency/blur) "), option: "decoration:blur:xray" }), + HyprlandSpinButton({ icon: 'target', name: getString('Size'), desc: getString('[Hyprland]\nAdjust the blur radius. Generally doesn\'t affect performance\nHigher = more color spread'), option: 'decoration:blur:size', minValue: 1, maxValue: 1000 }), + HyprlandSpinButton({ icon: 'repeat', name: getString('Passes'), desc: getString('[Hyprland] Adjust the number of runs of the blur algorithm\nMore passes = more spread and power consumption\n4 is recommended\n2- would look weird and 6+ would look lame.'), option: 'decoration:blur:passes', minValue: 1, maxValue: 10 }), ]), ConfigGap({}), HyprlandToggle({ - icon: 'animation', name: 'Animations', desc: '[Hyprland] [GTK]\nEnable animations', option: 'animations:enabled', + icon: 'animation', name: getString('Animations'), desc: getString('[Hyprland] [GTK]\nEnable animations'), option: 'animations:enabled', extraOnChange: (self, newValue) => execAsync(['gsettings', 'set', 'org.gnome.desktop.interface', 'enable-animations', `${newValue}`]) }), Subcategory([ ConfigSpinButton({ icon: 'clear_all', - name: 'Choreography delay', - desc: 'In milliseconds, the delay between animations of a series', + name: getString('Choreography delay'), + desc: getString('In milliseconds, the delay between animations of a series'), initValue: userOptions.animations.choreographyDelay, step: 10, minValue: 0, maxValue: 1000, onChange: (self, newValue) => { @@ -100,11 +100,11 @@ export default (props) => { ] }), ConfigSection({ - name: 'Developer', children: [ - HyprlandToggle({ icon: 'speed', name: 'Show FPS', desc: "[Hyprland]\nShow FPS overlay on top-left corner", option: "debug:overlay" }), - HyprlandToggle({ icon: 'sort', name: 'Log to stdout', desc: "[Hyprland]\nPrint LOG, ERR, WARN, etc. messages to the console", option: "debug:enable_stdout_logs" }), - HyprlandToggle({ icon: 'motion_sensor_active', name: 'Damage tracking', desc: "[Hyprland]\nEnable damage tracking\nGenerally, leave it on.\nTurn off only when a shader doesn't work", option: "debug:damage_tracking", enableValue: 2 }), - HyprlandToggle({ icon: 'destruction', name: 'Damage blink', desc: "[Hyprland] [Epilepsy warning!]\nShow screen damage flashes", option: "debug:damage_blink" }), + name: getString('Developer'), children: [ + HyprlandToggle({ icon: 'speed', name: getString('Show FPS'), desc: getString("[Hyprland]\nShow FPS overlay on top-left corner"), option: "debug:overlay" }), + HyprlandToggle({ icon: 'sort', name: getString('Log to stdout'), desc: getString("[Hyprland]\nPrint LOG, ERR, WARN, etc. messages to the console"), option: "debug:enable_stdout_logs" }), + HyprlandToggle({ icon: 'motion_sensor_active', name: getString('Damage tracking'), desc: getString("[Hyprland]\nEnable damage tracking\nGenerally, leave it on.\nTurn off only when a shader doesn't work"), option: "debug:damage_tracking", enableValue: 2 }), + HyprlandToggle({ icon: 'destruction', name: getString('Damage blink'), desc: getString("[Hyprland] [Epilepsy warning!]\nShow screen damage flashes"), option: "debug:damage_blink" }), ] }), ] @@ -115,7 +115,7 @@ export default (props) => { children: [Label({ hpack: 'center', className: 'txt txt-italic txt-subtext margin-5', - label: 'Not all changes are saved', + label: getString('Not all changes are saved'), })] }) return Box({ diff --git a/.config/ags/modules/sideright/centermodules/notificationlist.js b/.config/ags/modules/sideright/centermodules/notificationlist.js index 8007034a3..c13633d60 100644 --- a/.config/ags/modules/sideright/centermodules/notificationlist.js +++ b/.config/ags/modules/sideright/centermodules/notificationlist.js @@ -22,7 +22,7 @@ export default (props) => { className: 'spacing-v-5 txt-subtext', children: [ MaterialIcon('notifications_active', 'gigantic'), - Label({ label: 'No notifications', className: 'txt-small' }), + Label({ label: getString('No notifications'), className: 'txt-small' }), ] }), ] @@ -82,7 +82,7 @@ export default (props) => { }), setup: setupCursorHover, }); - const silenceButton = ListActionButton('notifications_paused', 'Silence', (self) => { + const silenceButton = ListActionButton('notifications_paused', getString('Silence'), (self) => { Notifications.dnd = !Notifications.dnd; self.toggleClassName('notif-listaction-btn-enabled', Notifications.dnd); }); @@ -101,7 +101,7 @@ export default (props) => { setup: (self) => self.hook(Notifications, (self) => { self.revealChild = Notifications.notifications.length > 0; }), - child: ListActionButton('clear_all', 'Clear', () => { + child: ListActionButton('clear_all', getString('Clear'), () => { Notifications.clear(); const kids = notificationList.get_children(); for (let i = 0; i < kids.length; i++) { @@ -114,7 +114,7 @@ export default (props) => { attribute: { updateCount: (self) => { const count = Notifications.notifications.length; - if (count > 0) self.label = `${count} notifications`; + if (count > 0) self.label = `${count} ${getString("notifications")}`; else self.label = ''; }, }, diff --git a/.config/ags/modules/sideright/centermodules/wifinetworks.js b/.config/ags/modules/sideright/centermodules/wifinetworks.js index 4a68c91a9..50b8be038 100644 --- a/.config/ags/modules/sideright/centermodules/wifinetworks.js +++ b/.config/ags/modules/sideright/centermodules/wifinetworks.js @@ -29,7 +29,7 @@ const WifiNetwork = (accessPoint) => { accessPoint.active ? Label({ hpack: 'start', className: 'txt-smaller txt-subtext', - label: "Selected", + label: getString("Selected"), }) : null, ] }); @@ -69,7 +69,7 @@ const CurrentNetwork = () => { Label({ hpack: 'start', className: 'txt-smaller txt-subtext', - label: "Current network", + label: getString("Current network"), }), Label({ hpack: 'start', @@ -101,7 +101,7 @@ const CurrentNetwork = () => { Label({ className: 'margin-left-5', hpack: 'start', - label: "Authentication", + label: getString("Authentication"), }), Entry({ className: 'sidebar-wifinetworks-auth-entry', @@ -199,7 +199,7 @@ export default (props) => { execAsync(['bash', '-c', userOptions.apps.network]).catch(print); closeEverything(); }, - label: 'More', + label: getString('More'), setup: setupCursorHover, })], }) diff --git a/.config/ags/modules/sideright/quicktoggles.js b/.config/ags/modules/sideright/quicktoggles.js index e37b79b79..3aabca647 100644 --- a/.config/ags/modules/sideright/quicktoggles.js +++ b/.config/ags/modules/sideright/quicktoggles.js @@ -13,7 +13,7 @@ import { sidebarOptionsStack } from './sideright.js'; export const ToggleIconWifi = (props = {}) => Widget.Button({ className: 'txt-small sidebar-iconbutton', - tooltipText: 'Wifi | Right-click to configure', + tooltipText: getString('Wifi | Right-click to configure'), onClicked: () => Network.toggleWifi(), onSecondaryClickRelease: () => { execAsync(['bash', '-c', `${userOptions.apps.network}`]).catch(print); @@ -24,7 +24,7 @@ export const ToggleIconWifi = (props = {}) => Widget.Button({ setupCursorHover(self); self.hook(Network, button => { button.toggleClassName('sidebar-button-active', [Network.wifi?.internet, Network.wired?.internet].includes('connected')) - button.tooltipText = (`${Network.wifi?.ssid} | Right-click to configure` || 'Unknown'); + button.tooltipText = (`${Network.wifi?.ssid} | ${getString("Right-click to configure")}` || getString('Unknown')); }); }, ...props, @@ -32,7 +32,7 @@ export const ToggleIconWifi = (props = {}) => Widget.Button({ export const ToggleIconBluetooth = (props = {}) => Widget.Button({ className: 'txt-small sidebar-iconbutton', - tooltipText: 'Bluetooth | Right-click to configure', + tooltipText: getString('Bluetooth | Right-click to configure'), onClicked: () => { const status = Bluetooth?.enabled; if (status) @@ -86,7 +86,7 @@ export const ModuleNightLight = async (props = {}) => { enabled: false, }, className: 'txt-small sidebar-iconbutton', - tooltipText: 'Night Light', + tooltipText: getString('Night Light'), onClicked: (self) => { self.attribute.enabled = !self.attribute.enabled; self.toggleClassName('sidebar-button-active', self.attribute.enabled); @@ -122,7 +122,7 @@ export const ModuleCloudflareWarp = async (props = {}) => { enabled: false, }, className: 'txt-small sidebar-iconbutton', - tooltipText: 'Cloudflare WARP', + tooltipText: getString('Cloudflare WARP'), onClicked: (self) => { self.attribute.enabled = !self.attribute.enabled; self.toggleClassName('sidebar-button-active', self.attribute.enabled); @@ -147,7 +147,7 @@ export const ModuleInvertColors = async (props = {}) => { const Hyprland = (await import('resource:///com/github/Aylur/ags/service/hyprland.js')).default; return Widget.Button({ className: 'txt-small sidebar-iconbutton', - tooltipText: 'Color inversion', + tooltipText: getString('Color inversion'), onClicked: (button) => { // const shaderPath = JSON.parse(exec('hyprctl -j getoption decoration:screen_shader')).str; Hyprland.messageAsync('j/getoption decoration:screen_shader') @@ -208,7 +208,7 @@ export const ModuleIdleInhibitor = (props = {}) => Widget.Button({ // TODO: Make enabled: false, }, className: 'txt-small sidebar-iconbutton', - tooltipText: 'Keep system awake', + tooltipText: getString('Keep system awake'), onClicked: (self) => { self.attribute.enabled = !self.attribute.enabled; self.toggleClassName('sidebar-button-active', self.attribute.enabled); @@ -227,7 +227,7 @@ export const ModuleIdleInhibitor = (props = {}) => Widget.Button({ // TODO: Make export const ModuleReloadIcon = (props = {}) => Widget.Button({ ...props, className: 'txt-small sidebar-iconbutton', - tooltipText: 'Reload Environment config', + tooltipText: getString('Reload Environment config'), onClicked: () => { execAsync(['bash', '-c', 'hyprctl reload || swaymsg reload &']); App.closeWindow('sideright'); @@ -241,7 +241,7 @@ export const ModuleReloadIcon = (props = {}) => Widget.Button({ export const ModuleSettingsIcon = (props = {}) => Widget.Button({ ...props, className: 'txt-small sidebar-iconbutton', - tooltipText: 'Open Settings', + tooltipText: getString('Open Settings'), onClicked: () => { execAsync(['bash', '-c', `${userOptions.apps.settings}`, '&']); App.closeWindow('sideright'); @@ -255,7 +255,7 @@ export const ModuleSettingsIcon = (props = {}) => Widget.Button({ export const ModulePowerIcon = (props = {}) => Widget.Button({ ...props, className: 'txt-small sidebar-iconbutton', - tooltipText: 'Session', + tooltipText: getString('Session'), onClicked: () => { closeEverything(); Utils.timeout(1, () => openWindowOnAllMonitors('session')); diff --git a/.config/ags/modules/sideright/sideright.js b/.config/ags/modules/sideright/sideright.js index 24630b2f5..aa922b0ab 100644 --- a/.config/ags/modules/sideright/sideright.js +++ b/.config/ags/modules/sideright/sideright.js @@ -28,28 +28,28 @@ import { checkKeybind } from '../.widgetutils/keybind.js'; const centerWidgets = [ { - name: 'Notifications', + name: getString('Notifications'), materialIcon: 'notifications', contentWidget: ModuleNotificationList, }, { - name: 'Audio controls', + name: getString('Audio controls'), materialIcon: 'volume_up', contentWidget: ModuleAudioControls, }, { - name: 'Bluetooth', + name: getString('Bluetooth'), materialIcon: 'bluetooth', contentWidget: ModuleBluetooth, }, { - name: 'Wifi networks', + name: getString('Wifi networks'), materialIcon: 'wifi', contentWidget: ModuleWifiNetworks, onFocus: () => execAsync('nmcli dev wifi list').catch(print), }, { - name: 'Live config', + name: getString('Live config'), materialIcon: 'tune', contentWidget: ModuleConfigure, }, @@ -66,43 +66,44 @@ const timeRow = Box({ hpack: 'center', className: 'txt-small txt', setup: (self) => { - const getUptime = async () => { - try { - await execAsync(['bash', '-c', 'uptime -p']); + const getUptime = async () => { + try { + await execAsync(['bash', '-c', 'uptime -p']); return execAsync(['bash', '-c', `uptime -p | sed -e 's/...//;s/ day\\| days/d/;s/ hour\\| hours/h/;s/ minute\\| minutes/m/;s/,[^,]*//2'`]); } catch { return execAsync(['bash', '-c', 'uptime']).then(output => { - const uptimeRegex = /up\s+((\d+)\s+days?,\s+)?((\d+):(\d+)),/; - const matches = uptimeRegex.exec(output); + const uptimeRegex = /up\s+((\d+)\s+days?,\s+)?((\d+):(\d+)),/; + const matches = uptimeRegex.exec(output); if (matches) { - const days = matches[2] ? parseInt(matches[2]) : 0; + const days = matches[2] ? parseInt(matches[2]) : 0; const hours = matches[4] ? parseInt(matches[4]) : 0; const minutes = matches[5] ? parseInt(matches[5]) : 0; let formattedUptime = ''; if (days > 0) { - formattedUptime += `${days} d `; + formattedUptime += `${days} d `; } if (hours > 0) { - formattedUptime += `${hours} h `; + formattedUptime += `${hours} h `; } formattedUptime += `${minutes} m`; return formattedUptime; } else { - throw new Error('Failed to parse uptime output'); + throw new Error('Failed to parse uptime output'); } }); } }; self.poll(5000, label => { - getUptime().then(upTimeString => { - label.label = `Uptime: ${upTimeString}`; + getUptime().then(upTimeString => { + label.label = `${getString("Uptime:" + )} ${upTimeString}`; }).catch(err => { - console.error(`Failed to fetch uptime: ${err}`); + console.error(`Failed to fetch uptime: ${err}`); }); }); }, diff --git a/.config/ags/modules/sideright/todolist.js b/.config/ags/modules/sideright/todolist.js index 30008a327..39ccc500a 100644 --- a/.config/ags/modules/sideright/todolist.js +++ b/.config/ags/modules/sideright/todolist.js @@ -108,7 +108,7 @@ const todoItems = (isDone) => Widget.Scrollable({ className: 'txt txt-subtext', children: [ MaterialIcon(`${isDone ? 'checklist' : 'check_circle'}`, 'gigantic'), - Label({ label: `${isDone ? 'Finished tasks will go here' : 'Nothing here!'}` }) + Label({ label: `${isDone ? getString('Finished tasks will go here') : getString('Nothing here!')}` }) ] }) ] @@ -132,7 +132,7 @@ const UndoneTodoList = () => { className: 'txt-small sidebar-todo-new', halign: 'end', vpack: 'center', - label: '+ New task', + label: getString('+ New task'), setup: setupCursorHover, onClicked: (self) => { newTaskButton.revealChild = false; @@ -166,7 +166,7 @@ const UndoneTodoList = () => { // hexpand: true, vpack: 'center', className: 'txt-small sidebar-todo-entry', - placeholderText: 'Add a task...', + placeholderText: getString('Add a task...'), onAccept: ({ text }) => { if (text == '') return; Todo.add(text) @@ -216,7 +216,7 @@ const UndoneTodoList = () => { export const TodoWidget = () => TabContainer({ icons: ['format_list_bulleted', 'task_alt'], - names: ['Unfinished', 'Done'], + names: [getString('Unfinished'), getString('Done')], children: [ UndoneTodoList(), todoItems(true), diff --git a/.config/ags/services/gpt.js b/.config/ags/services/gpt.js index ffd6ce3d9..ffe2aeea4 100644 --- a/.config/ags/services/gpt.js +++ b/.config/ags/services/gpt.js @@ -10,7 +10,7 @@ const PROVIDERS = Object.assign({ // There's this list hmm https://github.com/zu 'openai': { 'name': 'OpenAI', 'logo_name': 'openai-symbolic', - 'description': 'Official OpenAI API.\nPricing: Free for the first $5 or 3 months, whichever is less.', + 'description': getString('Official OpenAI API.\nPricing: Free for the first $5 or 3 months, whichever is less.'), 'base_url': 'https://api.openai.com/v1/chat/completions', 'key_get_url': 'https://platform.openai.com/api-keys', 'key_file': 'openai_key.txt', @@ -19,7 +19,7 @@ const PROVIDERS = Object.assign({ // There's this list hmm https://github.com/zu 'ollama': { 'name': 'Ollama (Llama 3)', 'logo_name': 'ollama-symbolic', - 'description': 'Official Ollama API.\nPricing: Free.', + 'description': getString('Official Ollama API.\nPricing: Free.'), 'base_url': 'http://localhost:11434/v1/chat/completions', 'key_get_url': 'it\'s just ollama', 'key_file': 'ollama_key.txt', @@ -28,7 +28,7 @@ const PROVIDERS = Object.assign({ // There's this list hmm https://github.com/zu 'openrouter': { 'name': 'OpenRouter (Llama-3-70B)', 'logo_name': 'openrouter-symbolic', - 'description': 'A unified interface for LLMs', + 'description': getString('A unified interface for LLMs'), 'base_url': 'https://openrouter.ai/api/v1/chat/completions', 'key_get_url': 'https://openrouter.ai/keys', 'key_file': 'openrouter_key.txt', @@ -37,7 +37,7 @@ const PROVIDERS = Object.assign({ // There's this list hmm https://github.com/zu 'oxygen4o': { 'name': 'Oxygen (GPT-4o)', 'logo_name': 'ai-oxygen-symbolic', - 'description': 'An API from Tornado Softwares\nPricing: Free: 100/day\nRequires you to join their Discord for a key', + 'description': getString('An API from Tornado Softwares\nPricing: Free: 100/day\nRequires you to join their Discord for a key'), 'base_url': 'https://app.oxyapi.uk/v1/chat/completions', 'key_get_url': 'https://discord.com/invite/kM6MaCqGKA', 'key_file': 'oxygen_key.txt', @@ -46,7 +46,7 @@ const PROVIDERS = Object.assign({ // There's this list hmm https://github.com/zu 'zukijourney': { 'name': 'zukijourney (GPT-3.5)', 'logo_name': 'ai-zukijourney', - 'description': 'An API from @zukixa on GitHub.\nNote: Keys are IP-locked so it\'s buggy sometimes\nPricing: Free: 10/min, 800/day.\nRequires you to join their Discord for a key', + 'description': getString("An API from @zukixa on GitHub.\nNote: Keys are IP-locked so it's buggy sometimes\nPricing: Free: 10/min, 800/day.\nRequires you to join their Discord for a key"), 'base_url': 'https://zukijourney.xyzbot.net/v1/chat/completions', 'key_get_url': 'https://discord.com/invite/Y4J6XXnmQ6', 'key_file': 'zuki_key.txt', @@ -57,7 +57,7 @@ const PROVIDERS = Object.assign({ // There's this list hmm https://github.com/zu // Custom prompt const initMessages = [ - { role: "user", content: "You are an assistant on a sidebar of a Wayland Linux desktop. Please always use a casual tone when answering your questions, unless requested otherwise or making writing suggestions. These are the steps you should take to respond to the user's queries:\n1. If it's a writing- or grammar-related question or a sentence in quotation marks, Please point out errors and correct when necessary using underlines, and make the writing more natural where appropriate without making too major changes. If you're given a sentence in quotes but is grammatically correct, explain briefly concepts that are uncommon.\n2. If it's a question about system tasks, give a bash command in a code block with brief explanation.\n3. Otherwise, when asked to summarize information or explaining concepts, you are should use bullet points and headings. For mathematics expressions, you *have to* use LaTeX within a code block with the language set as \"latex\". \nNote: Use casual language, be short, while ensuring the factual correctness of your response. If you are unsure or don’t have enough information to provide a confident answer, simply say “I don’t know” or “I’m not sure.”. \nThanks!", }, + { role: "user", content: getString("You are an assistant on a sidebar of a Wayland Linux desktop. Please always use a casual tone when answering your questions, unless requested otherwise or making writing suggestions. These are the steps you should take to respond to the user's queries:\n1. If it's a writing- or grammar-related question or a sentence in quotation marks, Please point out errors and correct when necessary using underlines, and make the writing more natural where appropriate without making too major changes. If you're given a sentence in quotes but is grammatically correct, explain briefly concepts that are uncommon.\n2. If it's a question about system tasks, give a bash command in a code block with brief explanation.\n3. Otherwise, when asked to summarize information or explaining concepts, you are should use bullet points and headings. For mathematics expressions, you *have to* use LaTeX within a code block with the language set as \"latex\". \nNote: Use casual language, be short, while ensuring the factual correctness of your response. If you are unsure or don’t have enough information to provide a confident answer, simply say “I don’t know” or “I’m not sure.”. \nThanks!"), }, { role: "assistant", content: "- Got it!", }, { role: "user", content: "\"He rushed to where the event was supposed to be hold, he didn't know it got calceled\"", }, { role: "assistant", content: "## Grammar correction\nErrors:\n\"He rushed to where the event was supposed to be __hold____,__ he didn't know it got calceled\"\nCorrection + minor improvements:\n\"He rushed to the place where the event was supposed to be __held____, but__ he didn't know that it got calceled\"", }, diff --git a/.config/ags/variables.js b/.config/ags/variables.js index bf6a9ff6f..347d006d0 100644 --- a/.config/ags/variables.js +++ b/.config/ags/variables.js @@ -5,7 +5,9 @@ import Mpris from 'resource:///com/github/Aylur/ags/service/mpris.js'; import Variable from 'resource:///com/github/Aylur/ags/variable.js'; import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'; const { exec, execAsync } = Utils; - +import { init as i18n_init, getString } from './i18n/i18n.js' +//init i18n, Load language file +i18n_init() Gtk.IconTheme.get_default().append_search_path(`${App.configDir}/assets/icons`); // Global vars for external control (through keybinds) @@ -14,7 +16,7 @@ export const showColorScheme = Variable(false, {}) globalThis['openMusicControls'] = showMusicControls; globalThis['openColorScheme'] = showColorScheme; globalThis['mpris'] = Mpris; - +globalThis['getString'] = getString // load monitor shell modes from userOptions const initialMonitorShellModes = () => { const numberOfMonitors = Gdk.Display.get_default()?.get_n_monitors() || 1;