forked from Shinonome/dots-hyprland
Merge branch 'main' into patch-1
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
\`\`\`
|
||||
`;
|
||||
`;
|
||||
|
||||
@@ -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}`)
|
||||
|
||||
@@ -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`,
|
||||
});
|
||||
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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: [
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user