Merge branch 'main' into patch-1

This commit is contained in:
end-4
2024-03-24 09:16:29 +07:00
committed by GitHub
38 changed files with 879 additions and 448 deletions
@@ -1,5 +1,4 @@
// This file is for the actual widget for each single notification
const { GLib, Gdk, Gtk } = imports.gi;
import Widget from 'resource:///com/github/Aylur/ags/widget.js'
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js'
@@ -9,14 +8,16 @@ import { setupCursorHover } from "../.widgetutils/cursorhover.js";
import { AnimatedCircProg } from "./cairo_circularprogress.js";
function guessMessageType(summary) {
if (summary.includes('recording')) return 'screen_record';
if (summary.includes('battery') || summary.includes('power')) return 'power';
if (summary.includes('screenshot')) return 'screenshot_monitor';
if (summary.includes('welcome')) return 'waving_hand';
if (summary.includes('time')) return 'scheduleb';
if (summary.includes('installed')) return 'download';
if (summary.includes('update')) return 'update';
if (summary.startsWith('file')) return 'folder_copy';
const str = summary.toLowerCase();
if (str.includes('reboot')) return 'restart_alt';
if (str.includes('recording')) return 'screen_record';
if (str.includes('battery') || summary.includes('power')) return 'power';
if (str.includes('screenshot')) return 'screenshot_monitor';
if (str.includes('welcome')) return 'waving_hand';
if (str.includes('time')) return 'scheduleb';
if (str.includes('installed')) return 'download';
if (str.includes('update')) return 'update';
if (str.startsWith('file')) return 'folder_copy';
return 'chat';
}
@@ -92,3 +92,78 @@ export const TabContainer = ({ icons, names, children, className = '', setup = (
return mainBox;
}
export const IconTabContainer = ({
iconWidgets, names, children, className = '',
setup = () => { }, onChange = () => { },
tabsHpack = 'center', tabSwitcherClassName = '',
...rest
}) => {
const shownIndex = Variable(0);
let previousShownIndex = 0;
const count = Math.min(iconWidgets.length, names.length, children.length);
const tabs = Box({
homogeneous: true,
hpack: tabsHpack,
className: `spacing-h-5 ${tabSwitcherClassName}`,
children: iconWidgets.map((icon, i) => Button({
className: 'tab-icon',
tooltipText: names[i],
child: icon,
setup: setupCursorHover,
onClicked: () => shownIndex.value = i,
})),
setup: (self) => self.hook(shownIndex, (self) => {
self.children[previousShownIndex].toggleClassName('tab-icon-active', false);
self.children[shownIndex.value].toggleClassName('tab-icon-active', true);
previousShownIndex = shownIndex.value;
}),
});
const tabSection = Box({
homogeneous: true,
children: [EventBox({
onScrollUp: () => mainBox.prevTab(),
onScrollDown: () => mainBox.nextTab(),
child: Box({
vertical: true,
hexpand: true,
children: [
tabs,
]
})
})]
});
const contentStack = Stack({
transition: 'slide_left_right',
children: children.reduce((acc, currentValue, index) => {
acc[index] = currentValue;
return acc;
}, {}),
setup: (self) => self.hook(shownIndex, (self) => {
self.shown = `${shownIndex.value}`;
}),
});
const mainBox = Box({
attribute: {
children: children,
shown: shownIndex,
names: names,
},
vertical: true,
className: `spacing-v-5 ${className}`,
setup: (self) => {
self.pack_start(tabSection, false, false, 0);
self.pack_end(contentStack, true, true, 0);
setup(self);
self.hook(shownIndex, (self) => onChange(self, shownIndex.value));
},
...rest,
});
mainBox.nextTab = () => shownIndex.value = Math.min(shownIndex.value + 1, count - 1);
mainBox.prevTab = () => shownIndex.value = Math.max(shownIndex.value - 1, 0);
mainBox.cycleTab = () => shownIndex.value = (shownIndex.value + 1) % count;
mainBox.shown = shownIndex;
return mainBox;
}
+15 -26
View File
@@ -59,31 +59,20 @@ export default (text) => {
return output.join('\n');
}
export const markdownTest = `# Heading 1
## Heading 2
### Heading 3
#### Heading 4
##### Heading 5
1. yes
2. no
127. well
- Bulletpoint starting with minus
* Bulletpoint starting with asterisk
---
- __Underline__ __ No underline __
- **Bold** ** No bold **
- _Italics1_ *Italics2* _ No Italics _
- A color: #D6BAFF
- nvidia green: #7ABB08
- sub-item
\`\`\`javascript
// A code block!
myArray = [23, 123, 43, 54, '6969'];
console.log('uwu');
export const markdownTest = `## Inline formatting
- **Bold** *Italics* __Underline__
- \`Monospace text\` 🤓
- Colors
- Nvidia green #7ABB08
- Soundcloud orange #FF5500
## Code block
\`\`\`cpp
#include <bits/stdc++.h>
const std::string GREETING="UwU";
int main() { std::cout << GREETING; }
\`\`\`
- Random instruction thing
- To update arch lincox, run \`sudo pacman -Syu\`
\`\`\`tex
\\frac{d}{dx} \\left( \\frac{x-438}{x^2+23x-7} \\right) = \\frac{-x^2 + 869}{(x^2+23x-7)^2} \\\\ \\frac{d}{dx} \\left( \\frac{x-438}{x^2+23x-7} \\right) = \\frac{-x^2 + 869}{(x^2+23x-7)^2}
## LaTeX
\`\`\`latex
\\frac{d}{dx} \\left( \\frac{x-438}{x^2+23x-7} \\right) = \\frac{-x^2 + 869}{(x^2+23x-7)^2} \\\\\\\\ cos(2x) = 2cos^2(x) - 1 = 1 - 2sin^2(x) = cos^2(x) - sin^2(x)
\`\`\`
`;
`;
+2 -1
View File
@@ -1,4 +1,5 @@
const { GLib } = imports.gi;
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { execAsync, exec } = Utils;
@@ -9,7 +10,7 @@ export const hasFlatpak = !!exec(`bash -c 'command -v flatpak'`);
const LIGHTDARK_FILE_LOCATION = `${GLib.get_user_cache_dir()}/ags/user/colormode.txt`;
const colorMode = Utils.exec('bash -c "sed -n \'1p\' $HOME/.cache/ags/user/colormode.txt"');
export let darkMode = !(Utils.readFile(LIGHTDARK_FILE_LOCATION).split('\n')[0].trim() == 'light');
export let darkMode = Variable(!(Utils.readFile(LIGHTDARK_FILE_LOCATION).split('\n')[0].trim() == 'light'));
export const hasPlasmaIntegration = !!Utils.exec('bash -c "command -v plasma-browser-integration-host"');
export const getDistroIcon = () => {
@@ -187,7 +187,7 @@ const CoverArt = ({ player, ...rest }) => {
}
const coverPath = player.coverPath;
const stylePath = `${player.coverPath}${darkMode ? '' : '-l'}${COVER_COLORSCHEME_SUFFIX}`;
const stylePath = `${player.coverPath}${darkMode.value ? '' : '-l'}${COVER_COLORSCHEME_SUFFIX}`;
if (player.coverPath == lastCoverPath) { // Since 'notify::cover-path' emits on cover download complete
Utils.timeout(200, () => {
// self.attribute.showImage(self, coverPath);
@@ -206,9 +206,9 @@ const CoverArt = ({ player, ...rest }) => {
// Generate colors
execAsync(['bash', '-c',
`${App.configDir}/scripts/color_generation/generate_colors_material.py --path '${coverPath}' --mode ${darkMode ? 'dark' : 'light'} > ${App.configDir}/scss/_musicmaterial.scss`])
`${App.configDir}/scripts/color_generation/generate_colors_material.py --path '${coverPath}' --mode ${darkMode.value ? 'dark' : 'light'} > ${App.configDir}/scss/_musicmaterial.scss`])
.then(() => {
exec(`wal -i "${player.coverPath}" -n -t -s -e -q ${darkMode ? '' : '-l'}`)
exec(`wal -i "${player.coverPath}" -n -t -s -e -q ${darkMode.value ? '' : '-l'}`)
exec(`cp ${GLib.get_user_cache_dir()}/wal/colors.scss ${App.configDir}/scss/_musicwal.scss`);
exec(`sass ${App.configDir}/scss/_music.scss ${stylePath}`);
Utils.timeout(200, () => {
@@ -3,6 +3,7 @@ import App from 'resource:///com/github/Aylur/ags/app.js';
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
const { execAsync, exec } = Utils;
import Todo from "../../services/todo.js";
import { darkMode } from '../.miscutils/system.js';
export function hasUnterminatedBackslash(inputString) {
// Use a regular expression to match a trailing odd number of backslashes
@@ -11,7 +12,7 @@ export function hasUnterminatedBackslash(inputString) {
}
export function launchCustomCommand(command) {
const args = command.split(' ');
const args = command.toLowerCase().split(' ');
if (args[0] == '>raw') { // Mouse raw input
Utils.execAsync('hyprctl -j getoption input:accel_profile')
.then((output) => {
@@ -31,17 +32,21 @@ export function launchCustomCommand(command) {
execAsync([`bash`, `-c`, `${App.configDir}/scripts/color_generation/switchcolor.sh --pick`, `&`]).catch(print);
}
else if (args[0] == '>light') { // Light mode
darkMode.value = false;
execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_cache_dir()}/ags/user && sed -i "1s/.*/light/" ${GLib.get_user_cache_dir()}/ags/user/colormode.txt`])
.then(execAsync(['bash', '-c', `${App.configDir}/scripts/color_generation/switchcolor.sh`]))
.catch(print);
}
else if (args[0] == '>dark') { // Dark mode
darkMode.value = true;
execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_cache_dir()}/ags/user && sed -i "1s/.*/dark/" ${GLib.get_user_cache_dir()}/ags/user/colormode.txt`])
.then(execAsync(['bash', '-c', `${App.configDir}/scripts/color_generation/switchcolor.sh`]))
.catch(print);
}
else if (args[0] == '>badapple') { // Black and white
execAsync([`bash`, `-c`, `${App.configDir}/scripts/color_generation/applycolor.sh --bad-apple`]).catch(print)
execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_cache_dir()}/ags/user && sed -i "3s/.*/monochrome/" ${GLib.get_user_cache_dir()}/ags/user/colormode.txt`])
.then(execAsync(['bash', '-c', `${App.configDir}/scripts/color_generation/switchcolor.sh`]))
.catch(print);
}
else if (args[0] == '>material') { // Use material colors
execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_cache_dir()}/ags/user && echo "material" > ${GLib.get_user_cache_dir()}/ags/user/colorbackend.txt`]).catch(print)
@@ -10,8 +10,8 @@ import md2pango from '../../.miscutils/md2pango.js';
import { darkMode } from "../../.miscutils/system.js";
const LATEX_DIR = `${GLib.get_user_cache_dir()}/ags/media/latex`;
const CUSTOM_SOURCEVIEW_SCHEME_PATH = `${App.configDir}/assets/themes/sourceviewtheme${darkMode ? '' : '-light'}.xml`;
const CUSTOM_SCHEME_ID = `custom${darkMode ? '' : '-light'}`;
const CUSTOM_SOURCEVIEW_SCHEME_PATH = `${App.configDir}/assets/themes/sourceviewtheme${darkMode.value ? '' : '-light'}.xml`;
const CUSTOM_SCHEME_ID = `custom${darkMode.value ? '' : '-light'}`;
const USERNAME = GLib.get_user_name();
/////////////////////// Custom source view colorscheme /////////////////////////
@@ -82,7 +82,7 @@ const Latex = (content = '') => {
const latexViewArea = Box({
// vscroll: 'never',
// hscroll: 'automatic',
homogeneous: true,
// homogeneous: true,
attribute: {
render: async (self, text) => {
if (text.length == 0) return;
@@ -107,7 +107,7 @@ const Latex = (content = '') => {
text=$(cat ${filePath} | sed 's/$/ \\\\\\\\/g' | sed 's/&=/=/g')
LaTeX -headless -input="$text" -output=${outFilePath} -textsize=${fontSize * 1.1} -padding=0 -maxwidth=${latexViewArea.get_allocated_width() * 0.85}
sed -i 's/fill="rgb(0%, 0%, 0%)"/style="fill:#000000"/g' ${outFilePath}
sed -i 's/stroke="rgb(0%, 0%, 0%)"/stroke="${darkMode ? '#ffffff' : '#000000'}"/g' ${outFilePath}
sed -i 's/stroke="rgb(0%, 0%, 0%)"/stroke="${darkMode.value ? '#ffffff' : '#000000'}"/g' ${outFilePath}
`;
Utils.writeFile(renderScript, scriptFilePath).catch(print);
Utils.exec(`chmod a+x ${scriptFilePath}`)
+1 -2
View File
@@ -39,7 +39,6 @@ const CommandButton = (command) => Button({
export const booruTabIcon = Box({
hpack: 'center',
className: 'sidebar-chat-apiswitcher-icon',
homogeneous: true,
children: [
MaterialIcon('gallery_thumbnail', 'norm'),
@@ -349,7 +348,7 @@ export const booruView = Scrollable({
// 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());
})
}
@@ -15,7 +15,6 @@ import { chatEntry } from '../apiwidgets.js';
export const chatGPTTabIcon = Icon({
hpack: 'center',
className: 'sidebar-chat-apiswitcher-icon',
icon: `openai-symbolic`,
});
+9 -1
View File
@@ -16,7 +16,6 @@ const MODEL_NAME = `Gemini`;
export const geminiTabIcon = Icon({
hpack: 'center',
className: 'sidebar-chat-apiswitcher-icon',
icon: `google-gemini-symbolic`,
})
@@ -104,6 +103,15 @@ export const GeminiSettings = () => MarginRevealer({
GeminiService.assistantPrompt = newValue;
},
}),
ConfigToggle({
icon: 'shield',
name: 'Safety',
desc: 'When turned off, tells the API (not the model) \nto not block harmful/explicit content',
initValue: GeminiService.safe,
onChange: (self, newValue) => {
GeminiService.safe = newValue;
},
}),
ConfigToggle({
icon: 'history',
name: 'History',
+1 -3
View File
@@ -39,8 +39,6 @@ const CommandButton = (command) => Button({
export const waifuTabIcon = Box({
hpack: 'center',
className: 'sidebar-chat-apiswitcher-icon',
homogeneous: true,
children: [
MaterialIcon('photo', 'norm'),
]
@@ -251,7 +249,7 @@ const WaifuImage = (taglist) => {
else Utils.execAsync(['bash', '-c', `wget -O '${thisBlock.attribute.imagePath}' '${url}'`])
.then(showImage)
.catch(print);
thisBlock.css = `background-color: mix(${darkMode ? 'black' : 'white'}, ${dominant_color}, 0.97);`;
thisBlock.css = `background-color: mix(${darkMode.value ? 'black' : 'white'}, ${dominant_color}, 0.97);`;
},
},
children: [
+21 -45
View File
@@ -16,6 +16,7 @@ import { checkKeybind } from '../.widgetutils/keybind.js';
const TextView = Widget.subclass(Gtk.TextView, "AgsTextView");
import { widgetContent } from './sideleft.js';
import { IconTabContainer } from '../.commonwidgets/tabcontainer.js';
const EXPAND_INPUT_THRESHOLD = 30;
const APIS = [
@@ -53,7 +54,6 @@ const APIS = [
},
];
let currentApiId = 0;
APIS[currentApiId].tabIcon.toggleClassName('sidebar-chat-apiswitcher-icon-enabled', true);
function apiSendMessage(textView) {
// Get text
@@ -75,6 +75,11 @@ export const chatEntry = TextView({
acceptsTab: false,
className: 'sidebar-chat-entry txt txt-smallie',
setup: (self) => self
.hook(App, (self, currentName, visible) => {
if (visible && currentName === 'sideleft') {
self.grab_focus();
}
})
.hook(GPTService, (self) => {
if (APIS[currentApiId].name != 'Assistant (GPTs)') return;
self.placeholderText = (GPTService.key.length > 0 ? 'Message the model...' : 'Enter API Key...');
@@ -170,16 +175,6 @@ const textboxArea = Box({ // Entry area
]
});
const apiContentStack = Stack({
vexpand: true,
transition: 'slide_left_right',
transitionDuration: userOptions.animations.durationLarge,
children: APIS.reduce((acc, api) => {
acc[api.name] = api.contentWidget;
return acc;
}, {}),
})
const apiCommandStack = Stack({
transition: 'slide_up_down',
transitionDuration: userOptions.animations.durationLarge,
@@ -189,41 +184,23 @@ const apiCommandStack = Stack({
}, {}),
})
function switchToTab(id) {
APIS[currentApiId].tabIcon.toggleClassName('sidebar-chat-apiswitcher-icon-enabled', false);
APIS[id].tabIcon.toggleClassName('sidebar-chat-apiswitcher-icon-enabled', true);
apiContentStack.shown = APIS[id].name;
apiCommandStack.shown = APIS[id].name;
chatPlaceholder.label = APIS[id].placeholderText;
currentApiId = id;
}
const apiSwitcher = EventBox({
onScrollUp: () => apiWidgets.attribute.prevTab(),
onScrollDown: () => apiWidgets.attribute.nextTab(),
child: CenterBox({
centerWidget: Box({
className: 'sidebar-chat-apiswitcher spacing-h-5',
hpack: 'center',
children: APIS.map((api, id) => Button({
child: api.tabIcon,
tooltipText: api.name,
setup: setupCursorHover,
onClicked: () => {
switchToTab(id);
}
})),
}),
endWidget: Button({
hpack: 'end',
className: 'txt-subtext txt-norm icon-material',
label: 'lightbulb',
tooltipText: 'Use PageUp/PageDown to switch between API pages',
setup: setupCursorHoverInfo,
}),
})
export const apiContentStack = IconTabContainer({
tabSwitcherClassName: 'sidebar-chat-apiswitcher',
className: 'margin-top-5',
iconWidgets: APIS.map((api) => api.tabIcon),
names: APIS.map((api) => api.name),
children: APIS.map((api) => api.contentWidget),
onChange: (self, id) => {
apiCommandStack.shown = APIS[id].name;
chatPlaceholder.label = APIS[id].placeholderText;
currentApiId = id;
}
});
function switchToTab(id) {
apiContentStack.shown.value = id;
}
const apiWidgets = Widget.Box({
attribute: {
'nextTab': () => switchToTab(Math.min(currentApiId + 1, APIS.length - 1)),
@@ -233,7 +210,6 @@ const apiWidgets = Widget.Box({
className: 'spacing-v-10',
homogeneous: false,
children: [
apiSwitcher,
apiContentStack,
apiCommandStack,
textboxArea,