forked from Shinonome/dots-hyprland
ags: sync
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
const { Gdk, Gtk } = imports.gi;
|
||||
import { App, Service, Utils, Variable, Widget } from '../imports.js';
|
||||
const { Box, Button, Entry, EventBox, Icon, Label, Revealer, Scrollable, Stack } = Widget;
|
||||
|
||||
export const MarginRevealer = ({
|
||||
transition = 'slide_down',
|
||||
child,
|
||||
revealChild,
|
||||
showClass = 'element-show', // These are for animation curve
|
||||
hideClass = 'element-hide', // Don't put margins in these classes!
|
||||
extraProperties = [],
|
||||
...rest
|
||||
}) => {
|
||||
child.toggleClassName(`${revealChild ? showClass : hideClass}`, true);
|
||||
if(!revealChild) child.css = 'min-height: 2px;';
|
||||
const widget = Scrollable({
|
||||
properties: [
|
||||
['revealChild', true], // It'll be set to false after init if it's supposed to hide
|
||||
['transition', transition],
|
||||
['show', (self) => {
|
||||
if (self._revealChild) return;
|
||||
child.toggleClassName(hideClass, false);
|
||||
child.toggleClassName(showClass, true);
|
||||
self._revealChild = true;
|
||||
child.css = 'margin: 0px;';
|
||||
}],
|
||||
['hide', (self) => {
|
||||
if (!self._revealChild) return;
|
||||
child.toggleClassName(hideClass, true);
|
||||
child.toggleClassName(showClass, false);
|
||||
self._revealChild = false;
|
||||
if (self._transition == 'slide_left')
|
||||
child.css = `margin-right: -${child.get_allocated_width()}px;`;
|
||||
else if (self._transition == 'slide_right')
|
||||
child.css = `margin-left: -${child.get_allocated_width()}px;`;
|
||||
else if (self._transition == 'slide_up')
|
||||
child.css = `margin-bottom: -${child.get_allocated_height()}px;`;
|
||||
else if (self._transition == 'slide_down')
|
||||
child.css = `margin-top: -${child.get_allocated_height()}px;`;
|
||||
}],
|
||||
['toggle', (self) => {
|
||||
if (self._revealChild) self._hide(self);
|
||||
else self._show(self);
|
||||
}],
|
||||
...extraProperties,
|
||||
],
|
||||
child: child,
|
||||
setup: (self) => {
|
||||
self.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.NEVER);
|
||||
},
|
||||
...rest,
|
||||
});
|
||||
return widget;
|
||||
}
|
||||
|
||||
// TODO: Allow reveal update. Currently this just helps at declaration
|
||||
export const DoubleRevealer = ({
|
||||
transition1 = 'slide_right',
|
||||
transition2 = 'slide_left',
|
||||
duration1 = 150,
|
||||
duration2 = 150,
|
||||
child,
|
||||
revealChild,
|
||||
}) => {
|
||||
return Revealer({
|
||||
transition: transition1,
|
||||
transitionDuration: duration1,
|
||||
revealChild: revealChild,
|
||||
child: Revealer({
|
||||
transition: transition2,
|
||||
transitionDuration: duration2,
|
||||
revealChild: revealChild,
|
||||
child: child,
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
const { Gdk, Gtk } = imports.gi;
|
||||
import { App, Service, Utils, Variable, Widget } from '../imports.js';
|
||||
|
||||
// TODO: Allow reveal update. Currently this just helps at declaration
|
||||
export const DoubleRevealer = ({
|
||||
transition1 = 'slide_right',
|
||||
transition2 = 'slide_left',
|
||||
duration1 = 150,
|
||||
duration2 = 150,
|
||||
child,
|
||||
revealChild,
|
||||
}) => {
|
||||
return Widget.Revealer({
|
||||
transition: transition1,
|
||||
transitionDuration: duration1,
|
||||
revealChild: revealChild,
|
||||
child: Widget.Revealer({
|
||||
transition: transition2,
|
||||
transitionDuration: duration2,
|
||||
revealChild: revealChild,
|
||||
child: child,
|
||||
})
|
||||
})
|
||||
}
|
||||
+124
-76
@@ -7,6 +7,7 @@ const { Box, EventBox, Icon, Overlay, Label, Button, Revealer } = Widget;
|
||||
import { MaterialIcon } from "./materialicon.js";
|
||||
import { setupCursorHover } from "./cursorhover.js";
|
||||
import { AnimatedCircProg } from "./animatedcircularprogress.js";
|
||||
import { MarginRevealer } from './advancedrevealers.js';
|
||||
|
||||
function guessMessageType(summary) {
|
||||
if (summary.includes('recording')) return 'screen_record';
|
||||
@@ -43,16 +44,15 @@ const NotificationIcon = (notifObject) => {
|
||||
icon = notifObject.appEntry;
|
||||
|
||||
return Box({
|
||||
valign: Gtk.Align.CENTER,
|
||||
vpack: 'center',
|
||||
hexpand: false,
|
||||
className: `notif-icon notif-icon-material-${notifObject.urgency}`,
|
||||
homogeneous: true,
|
||||
children: [
|
||||
(icon != 'NO_ICON' ?
|
||||
Icon({
|
||||
vpack: 'center',
|
||||
icon: icon,
|
||||
halign: Gtk.Align.CENTER, hexpand: true,
|
||||
valign: Gtk.Align.CENTER,
|
||||
setup: (self) => Utils.timeout(1, () => {
|
||||
const styleContext = self.get_parent().get_style_context();
|
||||
const width = styleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
|
||||
@@ -81,7 +81,7 @@ export default ({
|
||||
)
|
||||
const destroyWithAnims = () => {
|
||||
widget.sensitive = false;
|
||||
notificationBox.setCss(rightAnim1);
|
||||
notificationBox.setCss(middleClickClose);
|
||||
Utils.timeout(200, () => {
|
||||
wholeThing.revealChild = false;
|
||||
});
|
||||
@@ -125,82 +125,124 @@ export default ({
|
||||
});
|
||||
|
||||
const display = Gdk.Display.get_default();
|
||||
const notifTextPreview = Revealer({
|
||||
transition: 'slide_down',
|
||||
transitionDuration: 300,
|
||||
revealChild: true,
|
||||
child: Label({
|
||||
xalign: 0,
|
||||
className: `txt-smallie notif-body-${notifObject.urgency}`,
|
||||
useMarkup: true,
|
||||
xalign: 0,
|
||||
justify: Gtk.Justification.LEFT,
|
||||
maxWidthChars: 24,
|
||||
truncate: 'end',
|
||||
label: notifObject.body.split("\n")[0],
|
||||
}),
|
||||
});
|
||||
const notifTextExpanded = Revealer({
|
||||
transition: 'slide_up',
|
||||
transitionDuration: 300,
|
||||
revealChild: false,
|
||||
child: Label({
|
||||
xalign: 0,
|
||||
className: `txt-smallie notif-body-${notifObject.urgency}`,
|
||||
useMarkup: true,
|
||||
xalign: 0,
|
||||
justify: Gtk.Justification.LEFT,
|
||||
maxWidthChars: 24,
|
||||
wrap: true,
|
||||
label: notifObject.body,
|
||||
}),
|
||||
});
|
||||
const notifIcon = Box({
|
||||
vpack: 'start',
|
||||
homogeneous: true,
|
||||
children: [
|
||||
Overlay({
|
||||
child: NotificationIcon(notifObject),
|
||||
overlays: [
|
||||
AnimatedCircProg({
|
||||
className: `notif-circprog-${notifObject.urgency}`,
|
||||
valign: Gtk.Align.CENTER,
|
||||
initFrom: (isPopup ? 100 : 0),
|
||||
initTo: 0,
|
||||
initAnimTime: popupTimeout,
|
||||
})
|
||||
]
|
||||
}),
|
||||
]
|
||||
});
|
||||
const notifText = Box({
|
||||
valign: Gtk.Align.CENTER,
|
||||
vertical: true,
|
||||
hexpand: true,
|
||||
children: [
|
||||
Box({
|
||||
children: [
|
||||
Label({
|
||||
xalign: 0,
|
||||
className: 'txt-small txt-semibold titlefont',
|
||||
justify: Gtk.Justification.LEFT,
|
||||
hexpand: true,
|
||||
maxWidthChars: 24,
|
||||
truncate: 'end',
|
||||
ellipsize: 3,
|
||||
// wrap: true,
|
||||
useMarkup: notifObject.summary.startsWith('<'),
|
||||
label: notifObject.summary,
|
||||
}),
|
||||
Label({
|
||||
valign: Gtk.Align.CENTER,
|
||||
className: 'txt-smaller txt-semibold',
|
||||
justify: Gtk.Justification.RIGHT,
|
||||
setup: (label) => {
|
||||
// Let's ignore how it won't work for Jan1 cuz I'm lazy
|
||||
const messageTime = GLib.DateTime.new_from_unix_local(notifObject.time);
|
||||
if (messageTime.get_day_of_year() == GLib.DateTime.new_now_local().get_day_of_year()) {
|
||||
label.label = messageTime.format('%H:%M');
|
||||
}
|
||||
else if (messageTime.get_day_of_year() == GLib.DateTime.new_now_local().get_day_of_year() - 1) {
|
||||
label.label = messageTime.format('Yesterday');
|
||||
}
|
||||
else {
|
||||
label.label = messageTime.format('%d/%m');
|
||||
}
|
||||
}
|
||||
}),
|
||||
]
|
||||
}),
|
||||
notifTextPreview,
|
||||
notifTextExpanded,
|
||||
]
|
||||
});
|
||||
const notifExpandButton = Button({
|
||||
vpack: 'start',
|
||||
className: 'notif-expand-btn',
|
||||
onClicked: (self) => {
|
||||
if (notifTextPreview.revealChild) { // Expanding...
|
||||
notifTextPreview.revealChild = false;
|
||||
notifTextExpanded.revealChild = true;
|
||||
self.child.label = 'expand_less';
|
||||
}
|
||||
else {
|
||||
notifTextPreview.revealChild = true;
|
||||
notifTextExpanded.revealChild = false;
|
||||
self.child.label = 'expand_more';
|
||||
}
|
||||
},
|
||||
child: MaterialIcon('expand_more', 'norm', {
|
||||
vpack: 'center',
|
||||
}),
|
||||
setup: setupCursorHover,
|
||||
});
|
||||
const notificationContent = Box({
|
||||
...props,
|
||||
className: `${isPopup ? 'popup-' : ''}notif-${notifObject.urgency} spacing-h-10`,
|
||||
children: [
|
||||
NotificationIcon(notifObject),
|
||||
Box({
|
||||
valign: Gtk.Align.CENTER,
|
||||
vertical: true,
|
||||
hexpand: true,
|
||||
children: [
|
||||
Box({
|
||||
children: [
|
||||
Label({
|
||||
xalign: 0,
|
||||
className: 'txt-small txt-semibold titlefont',
|
||||
justify: Gtk.Justification.LEFT,
|
||||
hexpand: true,
|
||||
maxWidthChars: 24,
|
||||
truncate: 'end',
|
||||
ellipsize: 3,
|
||||
wrap: true,
|
||||
useMarkup: notifObject.summary.startsWith('<'),
|
||||
label: notifObject.summary,
|
||||
}),
|
||||
Label({
|
||||
valign: Gtk.Align.CENTER,
|
||||
className: 'txt-smaller txt-semibold',
|
||||
justify: Gtk.Justification.RIGHT,
|
||||
setup: (label) => {
|
||||
// Let's ignore how it won't work for Jan1 cuz I'm lazy
|
||||
const messageTime = GLib.DateTime.new_from_unix_local(notifObject.time);
|
||||
if (messageTime.get_day_of_year() == GLib.DateTime.new_now_local().get_day_of_year()) {
|
||||
label.label = messageTime.format('%H:%M');
|
||||
}
|
||||
else if (messageTime.get_day_of_year() == GLib.DateTime.new_now_local().get_day_of_year() - 1) {
|
||||
label.label = messageTime.format('Yesterday');
|
||||
}
|
||||
else {
|
||||
label.label = messageTime.format('%d/%m');
|
||||
}
|
||||
}
|
||||
}),
|
||||
]
|
||||
}),
|
||||
Label({
|
||||
xalign: 0,
|
||||
className: `txt-smallie notif-body-${notifObject.urgency}`,
|
||||
useMarkup: true,
|
||||
xalign: 0,
|
||||
justify: Gtk.Justification.LEFT,
|
||||
wrap: true,
|
||||
label: notifObject.body,
|
||||
}),
|
||||
]
|
||||
}),
|
||||
Overlay({
|
||||
child: AnimatedCircProg({
|
||||
className: `notif-circprog-${notifObject.urgency}`,
|
||||
valign: Gtk.Align.CENTER,
|
||||
initFrom: (isPopup ? 100 : 0),
|
||||
initTo: 0,
|
||||
initAnimTime: popupTimeout,
|
||||
}),
|
||||
overlays: [
|
||||
Button({
|
||||
className: 'notif-close-btn',
|
||||
onClicked: () => {
|
||||
destroyWithAnims()
|
||||
},
|
||||
child: MaterialIcon('close', 'large', {
|
||||
valign: Gtk.Align.CENTER,
|
||||
}),
|
||||
setup: setupCursorHover,
|
||||
}),
|
||||
]
|
||||
}),
|
||||
notifIcon,
|
||||
notifText,
|
||||
notifExpandButton,
|
||||
|
||||
// what is this? i think it should be at the bottom not on the right
|
||||
// Box({
|
||||
@@ -236,10 +278,16 @@ export default ({
|
||||
margin-right: -${Number(maxOffset + endMargin)}rem;
|
||||
opacity: 0;`;
|
||||
|
||||
const middleClickClose = `transition: 200ms cubic-bezier(0.85, 0, 0.15, 1);
|
||||
margin-left: ${Number(maxOffset + endMargin)}rem;
|
||||
margin-right: -${Number(maxOffset + endMargin)}rem;
|
||||
opacity: 0;`;
|
||||
|
||||
const notificationBox = Box({
|
||||
properties: [
|
||||
['leftAnim1', leftAnim1],
|
||||
['rightAnim1', rightAnim1],
|
||||
['middleClickClose', middleClickClose],
|
||||
['ready', false],
|
||||
],
|
||||
homogeneous: true,
|
||||
|
||||
@@ -145,7 +145,11 @@ export const NetworkIndicator = () => Widget.Stack({
|
||||
['wired', NetworkWiredIndicator()],
|
||||
],
|
||||
connections: [[Network, stack => {
|
||||
let primary = Network.primary || 'fallback';
|
||||
if(!Network.primary) {
|
||||
stack.shown = 'wifi';
|
||||
return;
|
||||
}
|
||||
const primary = Network.primary || 'fallback';
|
||||
if (primary == 'wifi' || primary == 'wired')
|
||||
stack.shown = primary;
|
||||
else
|
||||
|
||||
@@ -8,13 +8,13 @@ cd ~/Videos || exit
|
||||
if [[ "$(pidof wf-recorder)" == "" ]]; then
|
||||
notify-send "Starting recording" 'recording_'"$(getdate)"'.mp4' -a 'record-script.sh'
|
||||
if [[ "$1" == "--sound" ]]; then
|
||||
wf-recorder -f './recording_'"$(getdate)"'.mp4' -t --geometry "$(slurp)" --audio=alsa_output.pci-0000_08_00.6.analog-stereo.monitor
|
||||
wf-recorder --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --geometry "$(slurp)" --audio=alsa_output.pci-0000_08_00.6.analog-stereo.monitor
|
||||
elif [[ "$1" == "--fullscreen-sound" ]]; then
|
||||
wf-recorder -f './recording_'"$(getdate)"'.mp4' -t --audio=alsa_output.pci-0000_08_00.6.analog-stereo.monitor
|
||||
wf-recorder --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --audio=alsa_output.pci-0000_08_00.6.analog-stereo.monitor
|
||||
elif [[ "$1" == "--fullscreen" ]]; then
|
||||
wf-recorder -f './recording_'"$(getdate)"'.mp4' -t
|
||||
wf-recorder --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t
|
||||
else
|
||||
wf-recorder -f './recording_'"$(getdate)"'.mp4' -t --geometry "$(slurp)"
|
||||
wf-recorder --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --geometry "$(slurp)"
|
||||
fi
|
||||
else
|
||||
/usr/bin/kill --signal SIGINT wf-recorder
|
||||
|
||||
@@ -87,34 +87,34 @@
|
||||
"BLACK_500": "#393634",
|
||||
"BLACK_700": "#33302F",
|
||||
"BLACK_900": "#2B2928",
|
||||
"accent_bg_color": "#e2e2e2",
|
||||
"accent_fg_color": "#000000",
|
||||
"accent_color": "#e2e2e2",
|
||||
"destructive_bg_color": "#e2e2e2",
|
||||
"destructive_fg_color": "#000000",
|
||||
"destructive_color": "#e2e2e2",
|
||||
"accent_bg_color": "#d6baff",
|
||||
"accent_fg_color": "#3d1c70",
|
||||
"accent_color": "#d6baff",
|
||||
"destructive_bg_color": "#ffb4a9",
|
||||
"destructive_fg_color": "#680003",
|
||||
"destructive_color": "#ffb4a9",
|
||||
"success_bg_color": "#81C995",
|
||||
"success_fg_color": "rgba(0, 0, 0, 0.87)",
|
||||
"warning_bg_color": "#FDD633",
|
||||
"warning_fg_color": "rgba(0, 0, 0, 0.87)",
|
||||
"error_bg_color": "#e2e2e2",
|
||||
"error_fg_color": "#000000",
|
||||
"window_bg_color": "#000000",
|
||||
"window_fg_color": "#e2e2e2",
|
||||
"view_bg_color": "#000000",
|
||||
"view_fg_color": "#e2e2e2",
|
||||
"error_bg_color": "#ffb4a9",
|
||||
"error_fg_color": "#680003",
|
||||
"window_bg_color": "#111012",
|
||||
"window_fg_color": "#e7e1e6",
|
||||
"view_bg_color": "#1d1b1e",
|
||||
"view_fg_color": "#e7e1e6",
|
||||
"headerbar_bg_color": "mix(@dialog_bg_color, @window_bg_color, 0.5)",
|
||||
"headerbar_fg_color": "#e2e2e2",
|
||||
"headerbar_border_color": "#313131",
|
||||
"headerbar_fg_color": "#eadef7",
|
||||
"headerbar_border_color": "#4b4358",
|
||||
"headerbar_backdrop_color": "@headerbar_bg_color",
|
||||
"headerbar_shade_color": "rgba(0, 0, 0, 0.09)",
|
||||
"card_bg_color": "#000000",
|
||||
"card_fg_color": "#e2e2e2",
|
||||
"card_bg_color": "#111012",
|
||||
"card_fg_color": "#eadef7",
|
||||
"card_shade_color": "rgba(0, 0, 0, 0.09)",
|
||||
"dialog_bg_color": "#313131",
|
||||
"dialog_fg_color": "#e2e2e2",
|
||||
"popover_bg_color": "#313131",
|
||||
"popover_fg_color": "#e2e2e2",
|
||||
"dialog_bg_color": "#4b4358",
|
||||
"dialog_fg_color": "#eadef7",
|
||||
"popover_bg_color": "#4b4358",
|
||||
"popover_fg_color": "#eadef7",
|
||||
"thumbnail_bg_color": "#1a1b26",
|
||||
"thumbnail_fg_color": "#AEE5FA",
|
||||
"shade_color": "rgba(0, 0, 0, 0.36)",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Auto generated color theme for image at: [Local wallpaper]
|
||||
general {
|
||||
col.active_border = rgba({{ $primaryContainer }}FF)
|
||||
col.active_border = rgba({{ $onPrimary }}FF)
|
||||
col.inactive_border = rgba({{ $secondaryContainer }}CC)
|
||||
}
|
||||
|
||||
|
||||
@@ -464,13 +464,14 @@ $notchOnPrimary: $onPrimary;
|
||||
|
||||
.bar-systray {
|
||||
@include full-rounding;
|
||||
min-height: 1.909rem;
|
||||
min-width: 1.909rem;
|
||||
margin: 0.137rem 0rem;
|
||||
padding: 0rem 0.682rem;
|
||||
}
|
||||
|
||||
.bar-systray-item {
|
||||
@include full-rounding;
|
||||
min-width: 1.909rem;
|
||||
min-height: 1.032rem;
|
||||
min-width: 1.032rem;
|
||||
}
|
||||
|
||||
.bar-statusicons {
|
||||
|
||||
@@ -125,4 +125,4 @@ $term3: $onPrimaryContainer;
|
||||
$term4: $onPrimaryContainer;
|
||||
$term5: $onSecondaryContainer;
|
||||
$term6: $primary;
|
||||
$term7: $onSurfaceVariant;
|
||||
$term7: $onSurfaceVariant;
|
||||
|
||||
@@ -214,6 +214,14 @@
|
||||
margin-right: 0rem;
|
||||
}
|
||||
|
||||
.spacing-h-15>scrolledwindow>* {
|
||||
margin-right: 1.023rem;
|
||||
}
|
||||
|
||||
.spacing-h-15>scrolledwindow:last-child>* {
|
||||
margin-right: 0rem;
|
||||
}
|
||||
|
||||
.spacing-v-5>box {
|
||||
margin-bottom: 0.341rem;
|
||||
}
|
||||
@@ -238,6 +246,14 @@
|
||||
margin-bottom: 0rem;
|
||||
}
|
||||
|
||||
.spacing-v-5-revealer>scrolledwindow>* {
|
||||
margin-bottom: 0.341rem;
|
||||
}
|
||||
|
||||
.spacing-v-5-revealer>scrolledwindow:last-child>* {
|
||||
margin-bottom: 0rem;
|
||||
}
|
||||
|
||||
.spacing-h-5>* {
|
||||
margin-right: 0.341rem;
|
||||
}
|
||||
@@ -262,6 +278,14 @@
|
||||
margin-right: 0rem;
|
||||
}
|
||||
|
||||
.spacing-h-5>scrolledwindow>* {
|
||||
margin-right: 0.341rem;
|
||||
}
|
||||
|
||||
.spacing-h-5>scrolledwindow:last-child>* {
|
||||
margin-right: 0rem;
|
||||
}
|
||||
|
||||
.spacing-v-minus5>* {
|
||||
margin-bottom: -0.341rem;
|
||||
}
|
||||
@@ -286,6 +310,14 @@
|
||||
margin-right: 0rem;
|
||||
}
|
||||
|
||||
.spacing-h-10>scrolledwindow>* {
|
||||
margin-right: 0.682rem;
|
||||
}
|
||||
|
||||
.spacing-h-10>scrolledwindow:last-child>* {
|
||||
margin-right: 0rem;
|
||||
}
|
||||
|
||||
.spacing-h-10>flowboxchild>* {
|
||||
margin-right: 0.682rem;
|
||||
}
|
||||
@@ -439,4 +471,12 @@
|
||||
|
||||
.menu-decel {
|
||||
@include menu_decel;
|
||||
}
|
||||
|
||||
.element-show {
|
||||
@include element_easeInOut;
|
||||
}
|
||||
|
||||
.element-hide {
|
||||
@include element_easeInOut;
|
||||
}
|
||||
@@ -161,6 +161,18 @@ $elevation_margin: 0.476rem;
|
||||
transition: 150ms cubic-bezier(0.3, 0, 0.8, 0.15);
|
||||
}
|
||||
|
||||
@mixin element_decel {
|
||||
transition: 300ms cubic-bezier(0, 0.55, 0.45, 1);
|
||||
}
|
||||
|
||||
@mixin element_accel {
|
||||
transition: 300ms cubic-bezier(0.55, 0, 1, 0.45);
|
||||
}
|
||||
|
||||
@mixin element_easeInOut {
|
||||
transition: 300ms cubic-bezier(0.85, 0, 0.15, 1);
|
||||
}
|
||||
|
||||
@function tint($color, $percentage) {
|
||||
@return mix(rgb(245, 250, 255), $color, $percentage);
|
||||
}
|
||||
|
||||
@@ -93,17 +93,18 @@ $notif_surface: $t_background;
|
||||
color: $secondaryContainer;
|
||||
}
|
||||
|
||||
.notif-close-btn {
|
||||
.notif-expand-btn {
|
||||
@include notif-rounding;
|
||||
padding: 0rem 0.136rem;
|
||||
min-width: 1.841rem;
|
||||
min-height: 1.841rem;
|
||||
}
|
||||
|
||||
.notif-close-btn:hover,
|
||||
.notif-close-btn:focus {
|
||||
.notif-expand-btn:hover,
|
||||
.notif-expand-btn:focus {
|
||||
background: $hovercolor;
|
||||
}
|
||||
|
||||
.notif-close-btn:active {
|
||||
.notif-expand-btn:active {
|
||||
background: $activecolor;
|
||||
}
|
||||
|
||||
@@ -123,14 +124,17 @@ $notif_surface: $t_background;
|
||||
|
||||
.osd-notif {
|
||||
@include notif-rounding;
|
||||
background-color: transparentize($background, $transparentize_surface_amount_subtract_surface);
|
||||
background-color: transparentize(
|
||||
$background,
|
||||
$transparentize_surface_amount_subtract_surface
|
||||
);
|
||||
min-width: 30.682rem;
|
||||
}
|
||||
|
||||
.notif-circprog-low {
|
||||
transition: 0ms linear;
|
||||
min-width: 0.136rem; // line width
|
||||
min-height: 1.770rem;
|
||||
min-height: 3.409rem;
|
||||
padding: 0rem;
|
||||
color: $onSecondaryContainer;
|
||||
}
|
||||
@@ -138,7 +142,7 @@ $notif_surface: $t_background;
|
||||
.notif-circprog-normal {
|
||||
transition: 0ms linear;
|
||||
min-width: 0.136rem; // line width
|
||||
min-height: 1.770rem;
|
||||
min-height: 3.409rem;
|
||||
padding: 0rem;
|
||||
color: $onSecondaryContainer;
|
||||
}
|
||||
@@ -146,7 +150,7 @@ $notif_surface: $t_background;
|
||||
.notif-circprog-critical {
|
||||
transition: 0ms linear;
|
||||
min-width: 0.136rem; // line width
|
||||
min-height: 1.770rem;
|
||||
min-height: 3.409rem;
|
||||
padding: 0rem;
|
||||
color: $onSecondaryContainer;
|
||||
}
|
||||
color: $secondaryContainer;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
// .osd-window {
|
||||
// margin-top: 2.727rem;
|
||||
// }
|
||||
|
||||
.osd-bg {
|
||||
min-width: 8.864rem;
|
||||
min-height: 3.409rem;
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
import { Utils, Widget } from '../imports.js';
|
||||
import Service from 'resource:///com/github/Aylur/ags/service.js';
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
import Soup from 'gi://Soup?version=3.0';
|
||||
import { fileExists } from './messages.js';
|
||||
|
||||
class WaifuResponse extends Service {
|
||||
static {
|
||||
Service.register(this,
|
||||
{
|
||||
'delta': ['string'],
|
||||
},
|
||||
{
|
||||
'content': ['string'],
|
||||
'thinking': ['boolean'],
|
||||
'done': ['boolean'],
|
||||
});
|
||||
}
|
||||
|
||||
_role = '';
|
||||
_content = '';
|
||||
_thinking = false;
|
||||
_done = false;
|
||||
|
||||
constructor(role, content, thinking = false, done = false) {
|
||||
super();
|
||||
this._role = role;
|
||||
this._content = content;
|
||||
this._thinking = thinking;
|
||||
this._done = done;
|
||||
}
|
||||
|
||||
get done() { return this._done }
|
||||
set done(isDone) { this._done = isDone; this.notify('done') }
|
||||
|
||||
get role() { return this._role }
|
||||
set role(role) { this._role = role; this.emit('changed') }
|
||||
|
||||
get content() { return this._content }
|
||||
set content(content) {
|
||||
this._content = content;
|
||||
this.notify('content')
|
||||
this.emit('changed')
|
||||
}
|
||||
|
||||
get label() { return this._parserState.parsed + this._parserState.stack.join('') }
|
||||
|
||||
get thinking() { return this._thinking }
|
||||
set thinking(thinking) {
|
||||
this._thinking = thinking;
|
||||
this.notify('thinking')
|
||||
this.emit('changed')
|
||||
}
|
||||
|
||||
addDelta(delta) {
|
||||
if (this.thinking) {
|
||||
this.thinking = false;
|
||||
this.content = delta;
|
||||
}
|
||||
else {
|
||||
this.content += delta;
|
||||
}
|
||||
this.emit('delta', delta);
|
||||
}
|
||||
}
|
||||
|
||||
class WaifuService extends Service {
|
||||
_endpoints = {
|
||||
'im': 'https://api.waifu.im/search',
|
||||
'nekos': 'https://nekos.life/api/neko',
|
||||
'pics': 'https://api.waifu.pics/sfw/',
|
||||
}
|
||||
_headers = {
|
||||
'im': { 'Accept-Version': 'v5' },
|
||||
'nekos': {},
|
||||
'pics': {},
|
||||
}
|
||||
_url = 'https://api.waifu.im/search';
|
||||
_mode = 'im'; // Allowed: im
|
||||
_responses = [];
|
||||
_nsfw = false;
|
||||
_minHeight = 600;
|
||||
|
||||
static {
|
||||
Service.register(this, {
|
||||
'initialized': [],
|
||||
'clear': [],
|
||||
'newResponse': ['string'],
|
||||
});
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.emit('initialized');
|
||||
}
|
||||
|
||||
clear() {
|
||||
this._responses = [];
|
||||
this.emit('clear');
|
||||
}
|
||||
|
||||
get mode() { return this._mode }
|
||||
set mode(value) {
|
||||
this._mode = value;
|
||||
this._url = this._endpoints[this._mode];
|
||||
}
|
||||
get nsfw() { return this._nsfw }
|
||||
set nsfw(value) { this._nsfw = value }
|
||||
get responses() { return this._responses }
|
||||
|
||||
readResponseRecursive(stream, response) {
|
||||
stream.read_line_async(
|
||||
0, null,
|
||||
(stream, res) => {
|
||||
if (!stream) return;
|
||||
const [bytes] = stream.read_line_finish(res);
|
||||
const line = this._decoder.decode(bytes);
|
||||
if (line && line != '') {
|
||||
let data = line.substr(6);
|
||||
if (data == '[DONE]') return;
|
||||
try {
|
||||
const result = JSON.parse(data);
|
||||
if (result.choices[0].finish_reason === 'stop') {
|
||||
response.done = true;
|
||||
return;
|
||||
}
|
||||
response.addDelta(result.choices[0].delta.content);
|
||||
}
|
||||
catch {
|
||||
response.addDelta(line + '\n');
|
||||
}
|
||||
}
|
||||
this.readResponseRecursive(stream, response);
|
||||
});
|
||||
}
|
||||
|
||||
fetch(msg) {
|
||||
const taglist = msg.split(' ');
|
||||
this.emit('newResponse', msg);
|
||||
this._responses.push(msg);
|
||||
|
||||
const params = {
|
||||
'included_tags': taglist,
|
||||
'height': `>=${this._minHeight}`,
|
||||
'nsfw': this._nsfw,
|
||||
};
|
||||
|
||||
const session = new Soup.Session();
|
||||
const message = new Soup.Message({
|
||||
method: 'GET',
|
||||
uri: GLib.Uri.parse(this._url, GLib.UriFlags.NONE),
|
||||
});
|
||||
session.send_message(message, (session, message) => {
|
||||
if (message.status_code === 200) {
|
||||
const responseBody = message.response_body.data;
|
||||
const data = JSON.parse(responseBody);
|
||||
// Process the response data as needed
|
||||
console.log(data);
|
||||
log(data);
|
||||
} else {
|
||||
logError('Request failed with status code: ' + message.status_code);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export default new WaifuService();
|
||||
|
||||
+44
-12
@@ -159,6 +159,12 @@
|
||||
.spacing-h-15 > revealer:last-child > * {
|
||||
margin-right: 0rem; }
|
||||
|
||||
.spacing-h-15 > scrolledwindow > * {
|
||||
margin-right: 1.023rem; }
|
||||
|
||||
.spacing-h-15 > scrolledwindow:last-child > * {
|
||||
margin-right: 0rem; }
|
||||
|
||||
.spacing-v-5 > box {
|
||||
margin-bottom: 0.341rem; }
|
||||
|
||||
@@ -177,6 +183,12 @@
|
||||
.spacing-v-5-revealer > revealer:last-child > * {
|
||||
margin-bottom: 0rem; }
|
||||
|
||||
.spacing-v-5-revealer > scrolledwindow > * {
|
||||
margin-bottom: 0.341rem; }
|
||||
|
||||
.spacing-v-5-revealer > scrolledwindow:last-child > * {
|
||||
margin-bottom: 0rem; }
|
||||
|
||||
.spacing-h-5 > * {
|
||||
margin-right: 0.341rem; }
|
||||
|
||||
@@ -195,6 +207,12 @@
|
||||
.spacing-h-5 > revealer:last-child > * {
|
||||
margin-right: 0rem; }
|
||||
|
||||
.spacing-h-5 > scrolledwindow > * {
|
||||
margin-right: 0.341rem; }
|
||||
|
||||
.spacing-h-5 > scrolledwindow:last-child > * {
|
||||
margin-right: 0rem; }
|
||||
|
||||
.spacing-v-minus5 > * {
|
||||
margin-bottom: -0.341rem; }
|
||||
|
||||
@@ -213,6 +231,12 @@
|
||||
.spacing-h-10 > revealer:last-child > * {
|
||||
margin-right: 0rem; }
|
||||
|
||||
.spacing-h-10 > scrolledwindow > * {
|
||||
margin-right: 0.682rem; }
|
||||
|
||||
.spacing-h-10 > scrolledwindow:last-child > * {
|
||||
margin-right: 0rem; }
|
||||
|
||||
.spacing-h-10 > flowboxchild > * {
|
||||
margin-right: 0.682rem; }
|
||||
|
||||
@@ -330,6 +354,12 @@
|
||||
.menu-decel {
|
||||
transition: 300ms cubic-bezier(0.1, 1, 0, 1); }
|
||||
|
||||
.element-show {
|
||||
transition: 300ms cubic-bezier(0.85, 0, 0.15, 1); }
|
||||
|
||||
.element-hide {
|
||||
transition: 300ms cubic-bezier(0.85, 0, 0.15, 1); }
|
||||
|
||||
* {
|
||||
caret-color: #d6baff; }
|
||||
* selection {
|
||||
@@ -844,13 +874,14 @@ tooltip {
|
||||
.bar-systray {
|
||||
border-radius: 9999px;
|
||||
-gtk-outline-radius: 9999px;
|
||||
min-height: 1.909rem;
|
||||
min-width: 1.909rem; }
|
||||
margin: 0.137rem 0rem;
|
||||
padding: 0rem 0.682rem; }
|
||||
|
||||
.bar-systray-item {
|
||||
border-radius: 9999px;
|
||||
-gtk-outline-radius: 9999px;
|
||||
min-width: 1.909rem; }
|
||||
min-height: 1.032rem;
|
||||
min-width: 1.032rem; }
|
||||
|
||||
.bar-statusicons {
|
||||
border-radius: 9999px;
|
||||
@@ -2089,16 +2120,17 @@ tooltip {
|
||||
background-color: #eadef7;
|
||||
color: #4b4358; }
|
||||
|
||||
.notif-close-btn {
|
||||
.notif-expand-btn {
|
||||
border-radius: 1.159rem;
|
||||
-gtk-outline-radius: 1.159rem;
|
||||
padding: 0rem 0.136rem; }
|
||||
min-width: 1.841rem;
|
||||
min-height: 1.841rem; }
|
||||
|
||||
.notif-close-btn:hover,
|
||||
.notif-close-btn:focus {
|
||||
.notif-expand-btn:hover,
|
||||
.notif-expand-btn:focus {
|
||||
background: rgba(128, 128, 128, 0.3); }
|
||||
|
||||
.notif-close-btn:active {
|
||||
.notif-expand-btn:active {
|
||||
background: rgba(128, 128, 128, 0.7); }
|
||||
|
||||
.notif-closeall-btn {
|
||||
@@ -2122,23 +2154,23 @@ tooltip {
|
||||
.notif-circprog-low {
|
||||
transition: 0ms linear;
|
||||
min-width: 0.136rem;
|
||||
min-height: 1.770rem;
|
||||
min-height: 3.409rem;
|
||||
padding: 0rem;
|
||||
color: #eadef7; }
|
||||
|
||||
.notif-circprog-normal {
|
||||
transition: 0ms linear;
|
||||
min-width: 0.136rem;
|
||||
min-height: 1.770rem;
|
||||
min-height: 3.409rem;
|
||||
padding: 0rem;
|
||||
color: #eadef7; }
|
||||
|
||||
.notif-circprog-critical {
|
||||
transition: 0ms linear;
|
||||
min-width: 0.136rem;
|
||||
min-height: 1.770rem;
|
||||
min-height: 3.409rem;
|
||||
padding: 0rem;
|
||||
color: #eadef7; }
|
||||
color: #4b4358; }
|
||||
|
||||
.osd-music {
|
||||
transition: 300ms cubic-bezier(0.1, 1, 0, 1);
|
||||
|
||||
@@ -10,7 +10,13 @@ const SysTrayItem = item => Button({
|
||||
className: 'bar-systray-item',
|
||||
child: Icon({
|
||||
hpack: 'center',
|
||||
binds: [['icon', item, 'icon']]
|
||||
binds: [['icon', item, 'icon']],
|
||||
setup: (self) => Utils.timeout(1, () => {
|
||||
const styleContext = self.get_parent().get_style_context();
|
||||
const width = styleContext.get_property('min-width', Gtk.StateFlags.NORMAL);
|
||||
const height = styleContext.get_property('min-height', Gtk.StateFlags.NORMAL);
|
||||
self.size = Math.max(width, height, 1); // im too lazy to add another box lol
|
||||
}),
|
||||
}),
|
||||
binds: [['tooltipMarkup', item, 'tooltip-markup']],
|
||||
onClicked: btn => item.menu.popup_at_widget(btn, Gravity.SOUTH, Gravity.NORTH, null),
|
||||
@@ -19,8 +25,7 @@ const SysTrayItem = item => Button({
|
||||
|
||||
export const Tray = (props = {}) => {
|
||||
const trayContent = Box({
|
||||
vpack: 'center',
|
||||
className: 'bar-systray bar-group',
|
||||
className: 'bar-systray bar-group spacing-h-10',
|
||||
properties: [
|
||||
['items', new Map()],
|
||||
['onAdded', (box, id) => {
|
||||
@@ -31,7 +36,7 @@ export const Tray = (props = {}) => {
|
||||
return;
|
||||
const widget = SysTrayItem(item);
|
||||
box._items.set(id, widget);
|
||||
box.pack_start(widget, false, false, 0);
|
||||
box.add(widget);
|
||||
box.show_all();
|
||||
if (box._items.size === 1)
|
||||
trayRevealer.revealChild = true;
|
||||
|
||||
@@ -2,34 +2,32 @@
|
||||
const { GLib, Gtk } = imports.gi;
|
||||
import { App, Service, Utils, Widget } from '../../imports.js';
|
||||
import Audio from 'resource:///com/github/Aylur/ags/service/audio.js';
|
||||
import Notifications from 'resource:///com/github/Aylur/ags/service/notifications.js';
|
||||
const { Box, EventBox, Icon, Scrollable, Label, Button, Revealer } = Widget;
|
||||
const { Box, Label, ProgressBar, Revealer } = Widget;
|
||||
import Brightness from '../../services/brightness.js';
|
||||
import Indicator from '../../services/indicator.js';
|
||||
import Notification from '../../lib/notification.js';
|
||||
|
||||
const OsdValue = (name, labelConnections, progressConnections, props = {}) => Widget.Box({ // Volume
|
||||
const OsdValue = (name, labelConnections, progressConnections, props = {}) => Box({ // Volume
|
||||
...props,
|
||||
vertical: true,
|
||||
className: 'osd-bg osd-value',
|
||||
hexpand: true,
|
||||
children: [
|
||||
Widget.Box({
|
||||
Box({
|
||||
vexpand: true,
|
||||
children: [
|
||||
Widget.Label({
|
||||
Label({
|
||||
xalign: 0, yalign: 0, hexpand: true,
|
||||
className: 'osd-label',
|
||||
label: `${name}`,
|
||||
}),
|
||||
Widget.Label({
|
||||
Label({
|
||||
hexpand: false, className: 'osd-value-txt',
|
||||
label: '100',
|
||||
connections: labelConnections,
|
||||
}),
|
||||
]
|
||||
}),
|
||||
Widget.ProgressBar({
|
||||
ProgressBar({
|
||||
className: 'osd-progress',
|
||||
hexpand: true,
|
||||
vertical: false,
|
||||
@@ -58,14 +56,14 @@ const volumeIndicator = OsdValue('Volume',
|
||||
}]],
|
||||
);
|
||||
|
||||
export default () => Widget.Revealer({
|
||||
export default () => Revealer({
|
||||
transition: 'slide_down',
|
||||
connections: [
|
||||
[Indicator, (revealer, value) => {
|
||||
revealer.revealChild = (value > -1);
|
||||
}, 'popup'],
|
||||
],
|
||||
child: Widget.Box({
|
||||
child: Box({
|
||||
hpack: 'center',
|
||||
vertical: false,
|
||||
children: [
|
||||
|
||||
@@ -10,6 +10,7 @@ export default (monitor) => Widget.Window({
|
||||
monitor,
|
||||
className: 'indicator',
|
||||
layer: 'overlay',
|
||||
// exclusivity: 'ignore',
|
||||
visible: true,
|
||||
anchor: ['top'],
|
||||
child: Widget.EventBox({
|
||||
@@ -18,6 +19,7 @@ export default (monitor) => Widget.Window({
|
||||
},
|
||||
child: Widget.Box({
|
||||
vertical: true,
|
||||
className: 'osd-window',
|
||||
css: 'min-height: 2px;',
|
||||
children: [
|
||||
IndicatorValues(),
|
||||
@@ -28,3 +30,4 @@ export default (monitor) => Widget.Window({
|
||||
})
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import Applications from 'resource:///com/github/Aylur/ags/service/applications.
|
||||
import Hyprland from 'resource:///com/github/Aylur/ags/service/hyprland.js';
|
||||
const { execAsync, exec } = Utils;
|
||||
import { setupCursorHover, setupCursorHoverGrab } from "../../lib/cursorhover.js";
|
||||
import { DoubleRevealer } from "../../lib/doublerevealer.js";
|
||||
import { DoubleRevealer } from "../../lib/advancedrevealers.js";
|
||||
import { execAndClose, expandTilde, hasUnterminatedBackslash, startsWithNumber, launchCustomCommand, ls } from './miscfunctions.js';
|
||||
import {
|
||||
CalculationResultButton, CustomCommandButton, DirectoryButton,
|
||||
|
||||
@@ -8,6 +8,7 @@ import { setupCursorHover, setupCursorHoverInfo } from "../../../lib/cursorhover
|
||||
import { SystemMessage, ChatMessage } from "./chatgpt_chatmessage.js";
|
||||
import { ConfigToggle, ConfigSegmentedSelection, ConfigGap } from '../../../lib/configwidgets.js';
|
||||
import { markdownTest } from '../../../lib/md2pango.js';
|
||||
import { MarginRevealer } from '../../../lib/advancedrevealers.js';
|
||||
|
||||
export const chatGPTTabIcon = Box({
|
||||
hpack: 'center',
|
||||
@@ -60,16 +61,15 @@ const chatGPTInfo = Box({
|
||||
]
|
||||
})
|
||||
|
||||
export const chatGPTSettings = Revealer({
|
||||
export const chatGPTSettings = MarginRevealer({
|
||||
transition: 'slide_down',
|
||||
transitionDuration: 150,
|
||||
revealChild: true,
|
||||
connections: [
|
||||
[ChatGPT, (self) => Utils.timeout(200, () => {
|
||||
self.revealChild = false;
|
||||
self._hide(self);
|
||||
}), 'newMsg'],
|
||||
[ChatGPT, (self) => Utils.timeout(200, () => {
|
||||
self.revealChild = true;
|
||||
self._show(self);
|
||||
}), 'clear'],
|
||||
],
|
||||
child: Box({
|
||||
@@ -249,6 +249,16 @@ export const chatGPTSendMessage = (text) => {
|
||||
if (text.startsWith('/')) {
|
||||
if (text.startsWith('/clear')) clearChat();
|
||||
else if (text.startsWith('/model')) chatContent.add(SystemMessage(`Currently using \`${ChatGPT.modelName}\``, '/model', chatGPTView))
|
||||
else if (text.startsWith('/prompt')) {
|
||||
const firstSpaceIndex = text.indexOf(' ');
|
||||
const prompt = text.slice(firstSpaceIndex + 1);
|
||||
if (firstSpaceIndex == -1 || prompt.length < 1) {
|
||||
chatContent.add(SystemMessage(`Usage: \`/prompt MESSAGE\``, '/prompt', chatGPTView))
|
||||
}
|
||||
else {
|
||||
ChatGPT.addMessage('user', prompt)
|
||||
}
|
||||
}
|
||||
else if (text.startsWith('/key')) {
|
||||
const parts = text.split(' ');
|
||||
if (parts.length == 1) chatContent.add(SystemMessage(
|
||||
|
||||
@@ -9,7 +9,7 @@ import GtkSource from "gi://GtkSource?version=3.0";
|
||||
const CUSTOM_SOURCEVIEW_SCHEME_PATH = `${App.configDir}/data/sourceviewtheme.xml`;
|
||||
const CUSTOM_SCHEME_ID = 'custom';
|
||||
const USERNAME = GLib.get_user_name();
|
||||
const CHATGPT_CURSOR = ' >> ';
|
||||
const CHATGPT_CURSOR = ' (o) ';
|
||||
const MESSAGE_SCROLL_DELAY = 13; // In milliseconds, the time before an updated message scrolls to bottom
|
||||
|
||||
/////////////////////// Custom source view colorscheme /////////////////////////
|
||||
@@ -92,10 +92,6 @@ const CodeBlock = (content = '', lang = 'txt') => {
|
||||
}),
|
||||
Button({
|
||||
className: 'sidebar-chat-codeblock-topbar-btn',
|
||||
onClicked: (self) => {
|
||||
// execAsync(['bash', '-c', `wl-copy '${content}'`, `&`]).catch(print);
|
||||
execAsync([`wl-copy`, `${sourceView.label}`]).catch(print);
|
||||
},
|
||||
child: Box({
|
||||
className: 'spacing-h-5',
|
||||
children: [
|
||||
@@ -104,8 +100,13 @@ const CodeBlock = (content = '', lang = 'txt') => {
|
||||
label: 'Copy',
|
||||
})
|
||||
]
|
||||
})
|
||||
})
|
||||
}),
|
||||
onClicked: (self) => {
|
||||
const copyContent = sourceView.get_buffer().get_text(0, 0, 0); // TODO: fix this
|
||||
console.log(copyContent);
|
||||
execAsync([`wl-copy`, `${copyContent}`]).catch(print);
|
||||
},
|
||||
}),
|
||||
]
|
||||
})
|
||||
// Source view
|
||||
|
||||
@@ -4,6 +4,7 @@ const { Box, Button, Entry, EventBox, Icon, Label, Revealer, Scrollable, Stack }
|
||||
const { execAsync, exec } = Utils;
|
||||
import { MaterialIcon } from "../../../lib/materialicon.js";
|
||||
import { setupCursorHover, setupCursorHoverInfo } from "../../../lib/cursorhover.js";
|
||||
import WaifuService from '../../../services/waifus.js';
|
||||
|
||||
export const waifuTabIcon = Box({
|
||||
hpack: 'center',
|
||||
@@ -14,12 +15,27 @@ export const waifuTabIcon = Box({
|
||||
]
|
||||
});
|
||||
|
||||
const waifuContent = Box({
|
||||
className: 'spacing-v-15',
|
||||
vertical: true,
|
||||
connections: [
|
||||
[WaifuService, (box, id) => {
|
||||
const message = WaifuService.responses[id];
|
||||
if (!message) return;
|
||||
box.add(Label({
|
||||
label: message,
|
||||
}))
|
||||
}, 'newResponse'],
|
||||
]
|
||||
});
|
||||
|
||||
export const waifuView = Scrollable({
|
||||
className: 'sidebar-chat-viewport',
|
||||
vexpand: true,
|
||||
child: Box({
|
||||
vertical: true,
|
||||
children: [
|
||||
waifuContent,
|
||||
]
|
||||
}),
|
||||
setup: (scrolledWindow) => {
|
||||
@@ -45,11 +61,12 @@ export const waifuCommands = Box({
|
||||
// command do something
|
||||
},
|
||||
setup: setupCursorHover,
|
||||
label: '/A command button',
|
||||
label: '/call',
|
||||
}),
|
||||
]
|
||||
});
|
||||
|
||||
export const waifuCallAPI = (text) => {
|
||||
// Do something on send
|
||||
WaifuService.fetch(text);
|
||||
}
|
||||
@@ -15,6 +15,7 @@ const APIS = [
|
||||
contentWidget: chatGPTView,
|
||||
commandBar: chatGPTCommands,
|
||||
tabIcon: chatGPTTabIcon,
|
||||
placeholderText: 'Message ChatGPT',
|
||||
},
|
||||
{
|
||||
name: 'Waifus',
|
||||
@@ -22,6 +23,7 @@ const APIS = [
|
||||
contentWidget: waifuView,
|
||||
commandBar: waifuCommands,
|
||||
tabIcon: waifuTabIcon,
|
||||
placeholderText: 'Enter tags',
|
||||
},
|
||||
];
|
||||
let currentApiId = 0;
|
||||
@@ -80,6 +82,7 @@ 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;
|
||||
}
|
||||
const apiSwitcher = Box({
|
||||
|
||||
@@ -172,6 +172,8 @@ export default () => Box({
|
||||
if (event.get_keyval()[1] == Gdk.KEY_p)
|
||||
pinButton._toggle(pinButton);
|
||||
// Switch sidebar tab
|
||||
else if (event.get_keyval()[1] === Gdk.KEY_Tab)
|
||||
switchToTab((currentTabId + 1) % contents.length);
|
||||
else if (event.get_keyval()[1] === Gdk.KEY_Page_Up)
|
||||
switchToTab(Math.max(currentTabId - 1), 0);
|
||||
else if (event.get_keyval()[1] === Gdk.KEY_Page_Down)
|
||||
|
||||
Reference in New Issue
Block a user