Add multi-language support (#820)

This commit is contained in:
end-4
2024-10-16 22:04:59 +02:00
committed by GitHub
32 changed files with 748 additions and 211 deletions
@@ -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({
@@ -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"
},
+4 -4
View File
@@ -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'),
]
}),
+3 -3
View File
@@ -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');
}
}),
+4 -4
View File
@@ -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',
+3 -3
View File
@@ -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',
+19 -19
View File
@@ -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({
@@ -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')
}),
});
+9 -9
View File
@@ -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.')
}),
]
});
+14 -19
View File
@@ -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;
}
+16 -16
View File
@@ -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 <u>here</u>, then enter it below'
label: getString('An API key is required\nYou can grab one <u>here</u>, 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());
})
}
+18 -18
View File
@@ -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());
}))
}
+11 -11
View File
@@ -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;
}
+6 -6
View File
@@ -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
@@ -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: '<span strikethrough="true">Inaccurate</span> Color picker',
name: getString('<span strikethrough="true">Inaccurate</span> Color picker'),
revealChild: false,
child: Box({
className: 'spacing-h-5',
+1 -1
View File
@@ -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({
@@ -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',
+9 -9
View File
@@ -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);
@@ -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' }),
]
}),
]
@@ -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,
})],
})
@@ -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({
@@ -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 = '';
},
},
@@ -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,
})],
})
+10 -10
View File
@@ -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'));
+18 -17
View File
@@ -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}`);
});
});
},
+4 -4
View File
@@ -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),