mirror of
https://github.com/danbulant/dots-hyprland
synced 2026-05-24 12:22:09 +00:00
Merge branch 'end-4:illogical-impulse' into illogical-impulse
This commit is contained in:
commit
e9cf364aa5
6 changed files with 108 additions and 28 deletions
|
|
@ -420,6 +420,14 @@
|
|||
margin-bottom: 1.023rem;
|
||||
}
|
||||
|
||||
.width-10 {
|
||||
min-width: 0.682rem;
|
||||
}
|
||||
|
||||
.height-10 {
|
||||
min-width: 0.682rem;
|
||||
}
|
||||
|
||||
.invisible {
|
||||
opacity: 0;
|
||||
background-color: transparent;
|
||||
|
|
|
|||
|
|
@ -139,12 +139,10 @@ $elevation_margin: 0.476rem;
|
|||
}
|
||||
|
||||
@mixin fluent_decel {
|
||||
// Used for small transitions, as this looks clear
|
||||
transition: 200ms cubic-bezier(0.1, 1, 0, 1);
|
||||
}
|
||||
|
||||
@mixin fluent_decel_long {
|
||||
// Used for small transitions, as this looks clear
|
||||
transition: 1000ms cubic-bezier(0.1, 1, 0, 1);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -523,6 +523,14 @@ $onChatgpt: $onPrimary;
|
|||
min-width: 0rem;
|
||||
}
|
||||
|
||||
.sidebar-chat-wrapper {
|
||||
transition: 400ms cubic-bezier(0.1, 1, 0, 1);
|
||||
}
|
||||
|
||||
.sidebar-chat-wrapper-extended {
|
||||
min-height: 7.500rem;
|
||||
}
|
||||
|
||||
.sidebar-chat-send {
|
||||
@include menu_decel;
|
||||
min-width: 1.705rem;
|
||||
|
|
|
|||
|
|
@ -83,12 +83,14 @@ class WaifuService extends Service {
|
|||
|
||||
async fetch(msg) {
|
||||
// Init
|
||||
const userArgs = msg.split(' ');
|
||||
const userArgs = msg.split(/\s+/);
|
||||
|
||||
let taglist = [];
|
||||
this._nsfw = false;
|
||||
// Construct body/headers
|
||||
for (let i = 0; i < userArgs.length; i++) {
|
||||
const thisArg = userArgs[i];
|
||||
const thisArg = userArgs[i].trim();
|
||||
if(thisArg.length == 0) continue;
|
||||
if (thisArg == '--im') this._mode = 'im';
|
||||
else if (thisArg == '--nekos') this._mode = 'nekos';
|
||||
else if (thisArg.includes('pics')) this._mode = 'pics';
|
||||
|
|
|
|||
|
|
@ -1,16 +1,28 @@
|
|||
const { Gtk, Gdk } = imports.gi;
|
||||
import App from 'resource:///com/github/Aylur/ags/app.js';
|
||||
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
||||
import AgsWidget from "resource:///com/github/Aylur/ags/widgets/widget.js";
|
||||
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
|
||||
const { Box, Button, CenterBox, Entry, EventBox, Icon, Label, Revealer, Scrollable, Stack } = Widget;
|
||||
const { Box, Button, CenterBox, Entry, EventBox, Icon, Label, Overlay, Revealer, Scrollable, Stack } = Widget;
|
||||
const { execAsync, exec } = Utils;
|
||||
import { setupCursorHover, setupCursorHoverInfo } from "../../lib/cursorhover.js";
|
||||
import { contentStack } from './sideleft.js';
|
||||
// APIs
|
||||
import ChatGPT from '../../services/chatgpt.js';
|
||||
import Gemini from '../../services/gemini.js';
|
||||
import { geminiView, geminiCommands, sendMessage as geminiSendMessage, geminiTabIcon } from './apis/gemini.js';
|
||||
import { chatGPTView, chatGPTCommands, sendMessage as chatGPTSendMessage, chatGPTTabIcon } from './apis/chatgpt.js';
|
||||
import { waifuView, waifuCommands, sendMessage as waifuSendMessage, waifuTabIcon } from './apis/waifu.js';
|
||||
class AgsTextView extends AgsWidget(Gtk.TextView, "AgsTextView") {
|
||||
static { AgsWidget.register(this, {}); }
|
||||
constructor(params) {
|
||||
super(params);
|
||||
}
|
||||
}
|
||||
const TextView = Widget.createCtor(AgsTextView);
|
||||
|
||||
|
||||
const EXPAND_INPUT_THRESHOLD = 30;
|
||||
const APIS = [
|
||||
{
|
||||
name: 'Assistant (ChatGPT 3.5)',
|
||||
|
|
@ -40,9 +52,25 @@ const APIS = [
|
|||
let currentApiId = 0;
|
||||
APIS[currentApiId].tabIcon.toggleClassName('sidebar-chat-apiswitcher-icon-enabled', true);
|
||||
|
||||
export const chatEntry = Entry({
|
||||
className: 'sidebar-chat-entry',
|
||||
function apiSendMessage(textView) {
|
||||
// Get text
|
||||
const buffer = textView.get_buffer();
|
||||
const [start, end] = buffer.get_bounds();
|
||||
const text = buffer.get_text(start, end, true).trimStart();
|
||||
if (!text || text.length == 0) return;
|
||||
// Send
|
||||
APIS[currentApiId].sendCommand(text)
|
||||
// Reset
|
||||
buffer.set_text("", -1);
|
||||
chatEntryWrapper.toggleClassName('sidebar-chat-wrapper-extended', false);
|
||||
chatEntry.set_valign(Gtk.Align.CENTER);
|
||||
}
|
||||
|
||||
export const chatEntry = TextView({
|
||||
hexpand: true,
|
||||
wrapMode: Gtk.WrapMode.WORD_CHAR,
|
||||
acceptsTab: false,
|
||||
className: 'sidebar-chat-entry',
|
||||
setup: (self) => self
|
||||
.hook(ChatGPT, (self) => {
|
||||
if (APIS[currentApiId].name != 'Assistant (ChatGPT 3.5)') return;
|
||||
|
|
@ -52,31 +80,66 @@ export const chatEntry = Entry({
|
|||
if (APIS[currentApiId].name != 'Assistant (Gemini Pro)') return;
|
||||
self.placeholderText = (Gemini.key.length > 0 ? 'Message Gemini...' : 'Enter Google AI API Key...');
|
||||
}, 'hasKey')
|
||||
.on("key-press-event", (widget, event) => {
|
||||
const keyval = event.get_keyval()[1];
|
||||
if (event.get_keyval()[1] === Gdk.KEY_Return && event.get_state()[1] == Gdk.ModifierType.MOD2_MASK) {
|
||||
apiSendMessage(widget);
|
||||
return true;
|
||||
}
|
||||
// Global keybinds
|
||||
if (!(event.get_state()[1] & Gdk.ModifierType.CONTROL_MASK) &&
|
||||
event.get_keyval()[1] === Gdk.KEY_Page_Down) {
|
||||
const toSwitchTab = contentStack.get_visible_child();
|
||||
toSwitchTab.attribute.nextTab();
|
||||
}
|
||||
else if (!(event.get_state()[1] & Gdk.ModifierType.CONTROL_MASK) &&
|
||||
event.get_keyval()[1] === Gdk.KEY_Page_Up) {
|
||||
const toSwitchTab = contentStack.get_visible_child();
|
||||
toSwitchTab.attribute.prevTab();
|
||||
}
|
||||
})
|
||||
,
|
||||
onChange: (entry) => {
|
||||
chatSendButton.toggleClassName('sidebar-chat-send-available', entry.text.length > 0);
|
||||
},
|
||||
onAccept: (entry) => {
|
||||
APIS[currentApiId].sendCommand(entry.text)
|
||||
entry.text = '';
|
||||
},
|
||||
});
|
||||
|
||||
chatEntry.get_buffer().connect("changed", (buffer) => {
|
||||
const bufferText = buffer.get_text(buffer.get_start_iter(), buffer.get_end_iter(), true);
|
||||
chatSendButton.toggleClassName('sidebar-chat-send-available', bufferText.length > 0);
|
||||
if (buffer.get_line_count() > 1 || bufferText.length > EXPAND_INPUT_THRESHOLD) {
|
||||
chatEntryWrapper.toggleClassName('sidebar-chat-wrapper-extended', true);
|
||||
chatEntry.set_valign(Gtk.Align.FILL);
|
||||
}
|
||||
else {
|
||||
chatEntryWrapper.toggleClassName('sidebar-chat-wrapper-extended', false);
|
||||
chatEntry.set_valign(Gtk.Align.CENTER);
|
||||
}
|
||||
});
|
||||
|
||||
const chatEntryWrapper = Scrollable({
|
||||
className: 'sidebar-chat-wrapper',
|
||||
hscroll: 'never',
|
||||
vscroll: 'always',
|
||||
child: chatEntry,
|
||||
});
|
||||
|
||||
const chatSendButton = Button({
|
||||
className: 'txt-norm icon-material sidebar-chat-send',
|
||||
vpack: 'center',
|
||||
vpack: 'end',
|
||||
label: 'arrow_upward',
|
||||
setup: setupCursorHover,
|
||||
onClicked: (self) => {
|
||||
APIS[currentApiId].sendCommand(chatEntry.text);
|
||||
chatEntry.text = '';
|
||||
APIS[currentApiId].sendCommand(chatEntry.get_buffer().text);
|
||||
chatEntry.get_buffer().set_text("", -1);
|
||||
},
|
||||
});
|
||||
|
||||
const textboxArea = Box({ // Entry area
|
||||
className: 'sidebar-chat-textarea spacing-h-10',
|
||||
className: 'sidebar-chat-textarea',
|
||||
children: [
|
||||
chatEntry,
|
||||
Overlay({
|
||||
passThrough: true,
|
||||
child: chatEntryWrapper,
|
||||
}),
|
||||
Box({ className: 'width-10' }),
|
||||
chatSendButton,
|
||||
]
|
||||
});
|
||||
|
|
@ -97,8 +160,8 @@ function switchToTab(id) {
|
|||
APIS[id].tabIcon.toggleClassName('sidebar-chat-apiswitcher-icon-enabled', true);
|
||||
apiContentStack.shown = APIS[id].name;
|
||||
apiCommandStack.shown = APIS[id].name;
|
||||
chatEntry.placeholderText = APIS[id].placeholderText,
|
||||
currentApiId = id;
|
||||
chatEntry.placeholderText = APIS[id].placeholderText;
|
||||
currentApiId = id;
|
||||
}
|
||||
|
||||
const apiSwitcher = CenterBox({
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ const contents = [
|
|||
]
|
||||
let currentTabId = 0;
|
||||
|
||||
const contentStack = Stack({
|
||||
export const contentStack = Stack({
|
||||
vexpand: true,
|
||||
transition: 'slide_left_right',
|
||||
items: contents.map(item => [item.name, item.content]),
|
||||
|
|
@ -117,9 +117,9 @@ const pinButton = Button({
|
|||
vpack: 'start',
|
||||
className: 'sidebar-pin',
|
||||
child: MaterialIcon('push_pin', 'larger'),
|
||||
tooltipText: 'Pin sidebar',
|
||||
tooltipText: 'Pin sidebar (Ctrl+P)',
|
||||
onClicked: (self) => self.attribute.toggle(self),
|
||||
// QoL: Focus Pin button on open. Hit keybind -> space/enter = toggle pin state
|
||||
// Focus Pin button on open. Hit keybind -> space/enter = toggle pin state
|
||||
setup: (self) => self
|
||||
.hook(App, (self, currentName, visible) => {
|
||||
if (currentName === 'sideleft' && visible)
|
||||
|
|
@ -163,7 +163,7 @@ export default () => Box({
|
|||
],
|
||||
setup: (self) => self
|
||||
.on('key-press-event', (widget, event) => { // Handle keybinds
|
||||
if (event.get_state()[1] & Gdk.ModifierType.CONTROL_MASK) {
|
||||
if (event.get_state()[1] & Gdk.ModifierType.CONTROL_MASK) { // Ctrl held
|
||||
// Pin sidebar
|
||||
if (event.get_keyval()[1] == Gdk.KEY_p)
|
||||
pinButton.attribute.toggle(pinButton);
|
||||
|
|
@ -176,7 +176,7 @@ export default () => Box({
|
|||
switchToTab(Math.min(currentTabId + 1, contents.length - 1));
|
||||
}
|
||||
if (contentStack.shown == 'apis') { // If api tab is focused
|
||||
// Automatically focus entry when typing
|
||||
// Focus entry when typing
|
||||
if ((
|
||||
!(event.get_state()[1] & Gdk.ModifierType.CONTROL_MASK) &&
|
||||
event.get_keyval()[1] >= 32 && event.get_keyval()[1] <= 126 &&
|
||||
|
|
@ -186,8 +186,9 @@ export default () => Box({
|
|||
event.get_keyval()[1] === Gdk.KEY_v)
|
||||
) {
|
||||
chatEntry.grab_focus();
|
||||
chatEntry.set_text(chatEntry.text + String.fromCharCode(event.get_keyval()[1]));
|
||||
chatEntry.set_position(-1);
|
||||
const buffer = chatEntry.get_buffer();
|
||||
buffer.set_text(buffer.text + String.fromCharCode(event.get_keyval()[1]), -1);
|
||||
buffer.place_cursor(buffer.get_iter_at_offset(-1));
|
||||
}
|
||||
// Switch API type
|
||||
else if (!(event.get_state()[1] & Gdk.ModifierType.CONTROL_MASK) &&
|
||||
|
|
|
|||
Loading…
Reference in a new issue