mirror of
https://github.com/end-4/dots-hyprland.git
synced 2026-06-05 14:59:27 -05:00
waifu widget: added actions
This commit is contained in:
@@ -21,12 +21,11 @@
|
||||
}
|
||||
|
||||
.test {
|
||||
background-image: linear-gradient(45deg,
|
||||
#F4D609 0%, #F4D609 10%, #212121 10%, #212121 20%,
|
||||
#F4D609 20%, #F4D609 30%, #212121 30%, #212121 40%,
|
||||
#F4D609 40%, #F4D609 50%, #212121 50%, #212121 60%,
|
||||
#F4D609 60%, #F4D609 70%, #212121 70%, #212121 80%,
|
||||
#F4D609 80%, #F4D609 90%, #212121 90%, #212121 100%);
|
||||
background-image: linear-gradient(
|
||||
45deg, #f4d609 0%, #f4d609 10%, #212121 10%, #212121 20%, #f4d609 20%, #f4d609 30%, #212121 30%,
|
||||
#212121 40%, #f4d609 40%, #f4d609 50%, #212121 50%, #212121 60%, #f4d609 60%,
|
||||
#f4d609 70%, #212121 70%, #212121 80%, #f4d609 80%, #f4d609 90%, #212121 90%, #212121 100%
|
||||
);
|
||||
background-repeat: repeat;
|
||||
}
|
||||
|
||||
@@ -186,183 +185,190 @@
|
||||
min-height: 0.545rem;
|
||||
}
|
||||
|
||||
.spacing-h-3>* {
|
||||
.spacing-h-3 > * {
|
||||
margin-right: 0.205rem;
|
||||
}
|
||||
|
||||
.spacing-h-3>*:last-child {
|
||||
.spacing-h-3 > *:last-child {
|
||||
margin-right: 0rem;
|
||||
}
|
||||
|
||||
.spacing-v-15>* {
|
||||
.spacing-v-3 > * {
|
||||
margin-bottom: 0.205rem;
|
||||
}
|
||||
|
||||
.spacing-v-3 > *:last-child {
|
||||
margin-bottom: 0rem;
|
||||
}
|
||||
|
||||
.spacing-v-15 > * {
|
||||
margin-bottom: 1.023rem;
|
||||
}
|
||||
|
||||
.spacing-v-15>*:last-child {
|
||||
.spacing-v-15 > *:last-child {
|
||||
margin-bottom: 0rem;
|
||||
}
|
||||
|
||||
.spacing-h-15>* {
|
||||
.spacing-h-15 > * {
|
||||
margin-right: 1.023rem;
|
||||
}
|
||||
|
||||
.spacing-h-15>*:last-child {
|
||||
.spacing-h-15 > *:last-child {
|
||||
margin-right: 0rem;
|
||||
}
|
||||
|
||||
.spacing-h-15>revealer>* {
|
||||
.spacing-h-15 > revealer > * {
|
||||
margin-right: 1.023rem;
|
||||
}
|
||||
|
||||
.spacing-h-15>revealer:last-child>* {
|
||||
.spacing-h-15 > revealer:last-child > * {
|
||||
margin-right: 0rem;
|
||||
}
|
||||
|
||||
.spacing-h-15>scrolledwindow>* {
|
||||
.spacing-h-15 > scrolledwindow > * {
|
||||
margin-right: 1.023rem;
|
||||
}
|
||||
|
||||
.spacing-h-15>scrolledwindow:last-child>* {
|
||||
.spacing-h-15 > scrolledwindow:last-child > * {
|
||||
margin-right: 0rem;
|
||||
}
|
||||
|
||||
.spacing-v-5>box {
|
||||
.spacing-v-5 > box {
|
||||
margin-bottom: 0.341rem;
|
||||
}
|
||||
|
||||
.spacing-v-5>box:last-child {
|
||||
.spacing-v-5 > box:last-child {
|
||||
margin-bottom: 0rem;
|
||||
}
|
||||
|
||||
.spacing-v-5>* {
|
||||
.spacing-v-5 > * {
|
||||
margin-bottom: 0.341rem;
|
||||
}
|
||||
|
||||
.spacing-v-5>*:last-child {
|
||||
.spacing-v-5 > *:last-child {
|
||||
margin-bottom: 0rem;
|
||||
}
|
||||
|
||||
.spacing-v-5-revealer>revealer>* {
|
||||
.spacing-v-5-revealer > revealer > * {
|
||||
margin-bottom: 0.341rem;
|
||||
}
|
||||
|
||||
.spacing-v-5-revealer>revealer:last-child>* {
|
||||
.spacing-v-5-revealer > revealer:last-child > * {
|
||||
margin-bottom: 0rem;
|
||||
}
|
||||
|
||||
.spacing-v-5-revealer>scrolledwindow>* {
|
||||
.spacing-v-5-revealer > scrolledwindow > * {
|
||||
margin-bottom: 0.341rem;
|
||||
}
|
||||
|
||||
.spacing-v-5-revealer>scrolledwindow:last-child>* {
|
||||
.spacing-v-5-revealer > scrolledwindow:last-child > * {
|
||||
margin-bottom: 0rem;
|
||||
}
|
||||
|
||||
.spacing-h-4>* {
|
||||
.spacing-h-4 > * {
|
||||
margin-right: 0.273rem;
|
||||
}
|
||||
|
||||
.spacing-h-4>*:last-child {
|
||||
.spacing-h-4 > *:last-child {
|
||||
margin-right: 0rem;
|
||||
}
|
||||
|
||||
.spacing-h-5>* {
|
||||
.spacing-h-5 > * {
|
||||
margin-right: 0.341rem;
|
||||
}
|
||||
|
||||
.spacing-h-5>*:last-child {
|
||||
.spacing-h-5 > *:last-child {
|
||||
margin-right: 0rem;
|
||||
}
|
||||
|
||||
.spacing-h-5>widget>* {
|
||||
.spacing-h-5 > widget > * {
|
||||
margin-right: 0.341rem;
|
||||
}
|
||||
|
||||
.spacing-h-5>widget:last-child>* {
|
||||
.spacing-h-5 > widget:last-child > * {
|
||||
margin-right: 0rem;
|
||||
}
|
||||
|
||||
.spacing-h-5>revealer>* {
|
||||
.spacing-h-5 > revealer > * {
|
||||
margin-right: 0.341rem;
|
||||
}
|
||||
|
||||
.spacing-h-5>revealer:last-child>* {
|
||||
.spacing-h-5 > revealer:last-child > * {
|
||||
margin-right: 0rem;
|
||||
}
|
||||
|
||||
.spacing-h-5>scrolledwindow>* {
|
||||
.spacing-h-5 > scrolledwindow > * {
|
||||
margin-right: 0.341rem;
|
||||
}
|
||||
|
||||
.spacing-h-5>scrolledwindow:last-child>* {
|
||||
.spacing-h-5 > scrolledwindow:last-child > * {
|
||||
margin-right: 0rem;
|
||||
}
|
||||
|
||||
.spacing-v-minus5>* {
|
||||
.spacing-v-minus5 > * {
|
||||
margin-bottom: -0.341rem;
|
||||
}
|
||||
|
||||
.spacing-v-minus5>*:last-child {
|
||||
.spacing-v-minus5 > *:last-child {
|
||||
margin-bottom: 0rem;
|
||||
}
|
||||
|
||||
.spacing-h-10>* {
|
||||
.spacing-h-10 > * {
|
||||
margin-right: 0.682rem;
|
||||
}
|
||||
|
||||
.spacing-h-10>*:last-child {
|
||||
.spacing-h-10 > *:last-child {
|
||||
margin-right: 0rem;
|
||||
}
|
||||
|
||||
.spacing-h-10>revealer>* {
|
||||
.spacing-h-10 > revealer > * {
|
||||
margin-right: 0.682rem;
|
||||
}
|
||||
|
||||
.spacing-h-10>revealer:last-child>* {
|
||||
.spacing-h-10 > revealer:last-child > * {
|
||||
margin-right: 0rem;
|
||||
}
|
||||
|
||||
.spacing-h-10>scrolledwindow>* {
|
||||
.spacing-h-10 > scrolledwindow > * {
|
||||
margin-right: 0.682rem;
|
||||
}
|
||||
|
||||
.spacing-h-10>scrolledwindow:last-child>* {
|
||||
.spacing-h-10 > scrolledwindow:last-child > * {
|
||||
margin-right: 0rem;
|
||||
}
|
||||
|
||||
.spacing-h-10>flowboxchild>* {
|
||||
.spacing-h-10 > flowboxchild > * {
|
||||
margin-right: 0.682rem;
|
||||
}
|
||||
|
||||
.spacing-h-10>flowboxchild:last-child>* {
|
||||
.spacing-h-10 > flowboxchild:last-child > * {
|
||||
margin-right: 0rem;
|
||||
}
|
||||
|
||||
.spacing-v-10>* {
|
||||
.spacing-v-10 > * {
|
||||
margin-bottom: 0.682rem;
|
||||
}
|
||||
|
||||
.spacing-v-10>*:last-child {
|
||||
.spacing-v-10 > *:last-child {
|
||||
margin-bottom: 0rem;
|
||||
}
|
||||
|
||||
.spacing-h-20>* {
|
||||
.spacing-h-20 > * {
|
||||
margin-right: 1.364rem;
|
||||
}
|
||||
|
||||
.spacing-h-20>*:last-child {
|
||||
.spacing-h-20 > *:last-child {
|
||||
margin-right: 0rem;
|
||||
}
|
||||
|
||||
.spacing-v-20>* {
|
||||
.spacing-v-20 > * {
|
||||
margin-bottom: 1.364rem;
|
||||
}
|
||||
|
||||
.spacing-v-20>*:last-child {
|
||||
.spacing-v-20 > *:last-child {
|
||||
margin-bottom: 0rem;
|
||||
}
|
||||
|
||||
|
||||
.anim-enter {
|
||||
@include anim-enter;
|
||||
}
|
||||
@@ -429,51 +435,51 @@
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.spacing-h--5>box {
|
||||
.spacing-h--5 > box {
|
||||
margin-right: -0.341rem;
|
||||
}
|
||||
|
||||
.spacing-h--5>box:last-child {
|
||||
.spacing-h--5 > box:last-child {
|
||||
margin-right: 0rem;
|
||||
}
|
||||
|
||||
.spacing-v--5>* {
|
||||
.spacing-v--5 > * {
|
||||
margin-bottom: -0.341rem;
|
||||
}
|
||||
|
||||
.spacing-v--5>*:last-child {
|
||||
.spacing-v--5 > *:last-child {
|
||||
margin-bottom: 0rem;
|
||||
}
|
||||
|
||||
.spacing-h--10>* {
|
||||
.spacing-h--10 > * {
|
||||
margin-left: -1.364rem;
|
||||
}
|
||||
|
||||
.spacing-h--10>*:first-child {
|
||||
.spacing-h--10 > *:first-child {
|
||||
margin-left: 0rem;
|
||||
}
|
||||
|
||||
.spacing-v--10>* {
|
||||
.spacing-v--10 > * {
|
||||
margin-bottom: -0.682rem;
|
||||
}
|
||||
|
||||
.spacing-v--10>*:last-child {
|
||||
.spacing-v--10 > *:last-child {
|
||||
margin-bottom: 0rem;
|
||||
}
|
||||
|
||||
.spacing-v--10>* {
|
||||
.spacing-v--10 > * {
|
||||
margin-bottom: -0.682rem;
|
||||
}
|
||||
|
||||
.spacing-v--10>*:last-child {
|
||||
.spacing-v--10 > *:last-child {
|
||||
margin-bottom: 0rem;
|
||||
}
|
||||
|
||||
.spacing-h--20>* {
|
||||
.spacing-h--20 > * {
|
||||
margin-left: -1.364rem;
|
||||
}
|
||||
|
||||
.spacing-h--20>*:first-child {
|
||||
.spacing-h--20 > *:first-child {
|
||||
margin-left: 0rem;
|
||||
}
|
||||
|
||||
@@ -491,4 +497,12 @@
|
||||
|
||||
.element-hide {
|
||||
@include element_easeInOut;
|
||||
}
|
||||
}
|
||||
|
||||
.element-decel {
|
||||
@include element_decel;
|
||||
}
|
||||
|
||||
.element-accel {
|
||||
@include element_accel;
|
||||
}
|
||||
|
||||
@@ -759,16 +759,13 @@ $onChatgpt: $onPrimary;
|
||||
margin-left: -0.136rem;
|
||||
padding-left: 0.818rem;
|
||||
}
|
||||
|
||||
.sidebar-waifu-content {
|
||||
margin-left: 0.682rem;
|
||||
}
|
||||
|
||||
.sidebar-waifu-txt {
|
||||
@include readingfont;
|
||||
margin-left: 0.682rem;
|
||||
}
|
||||
|
||||
.sidebar-waifu-image {
|
||||
margin-left: 0.682rem;
|
||||
@include normal-rounding;
|
||||
@@ -776,3 +773,21 @@ $onChatgpt: $onPrimary;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
.sidebar-waifu-image-actions {
|
||||
padding: 0.313rem;
|
||||
}
|
||||
$waifu_image_overlay_transparency: 0.7;
|
||||
.sidebar-waifu-image-action {
|
||||
@include full-rounding;
|
||||
min-width: 1.875rem;
|
||||
min-height: 1.875rem;
|
||||
background-color: rgba(0, 0, 0, $waifu_image_overlay_transparency); // Fixed cuz on image
|
||||
color: rgba(255, 255, 255, $waifu_image_overlay_transparency);
|
||||
}
|
||||
.sidebar-waifu-image-action:hover,
|
||||
.sidebar-waifu-image-action:focus {
|
||||
background-color: rgba(30, 30, 30, $waifu_image_overlay_transparency);
|
||||
}
|
||||
.sidebar-waifu-image-action:active {
|
||||
background-color: rgba(60, 60, 60, $waifu_image_overlay_transparency);
|
||||
}
|
||||
|
||||
@@ -5,6 +5,20 @@ import GLib from 'gi://GLib';
|
||||
import Soup from 'gi://Soup?version=3.0';
|
||||
import { fileExists } from './messages.js';
|
||||
|
||||
// Usage from my python waifu fetcher, for reference
|
||||
// Usage: waifu-get.py [OPTION]... [TAG]...
|
||||
// Options:
|
||||
// --segs\tForce NSFW images
|
||||
// --im\tUse waifu.im API. You can use many tags
|
||||
// --pics\tUse waifu.pics API. Use 1 tag only.
|
||||
// --nekos\tUse nekos.life (old) API. No tags.
|
||||
|
||||
// Tags:
|
||||
// waifu.im (type):
|
||||
// maid waifu marin-kitagawa mori-calliope raiden-shogun oppai selfies uniform
|
||||
// waifu.im (nsfw tags):
|
||||
// ecchi hentai ero ass paizuri oral milf
|
||||
|
||||
function paramStringFromObj(params) {
|
||||
return Object.entries(params)
|
||||
.map(([key, value]) => {
|
||||
@@ -38,6 +52,7 @@ class WaifuService extends Service {
|
||||
_queries = [];
|
||||
_nsfw = false;
|
||||
_minHeight = 600;
|
||||
_status = 0;
|
||||
|
||||
static {
|
||||
Service.register(this, {
|
||||
@@ -81,17 +96,21 @@ class WaifuService extends Service {
|
||||
'nsfw': this._nsfw,
|
||||
};
|
||||
const paramString = paramStringFromObj(params);
|
||||
console.log(paramString);
|
||||
// Fetch
|
||||
const options = {
|
||||
method: 'GET',
|
||||
headers: this._headers[this._mode],
|
||||
};
|
||||
var status = 0;
|
||||
Utils.fetch(`${this._baseUrl}?${paramString}`, options)
|
||||
.then(result => result.text()) // Parse
|
||||
.then(result => {
|
||||
status = result.status;
|
||||
return result.text();
|
||||
})
|
||||
.then((dataString) => { // Store interesting stuff and emit
|
||||
const parsedData = JSON.parse(dataString);
|
||||
if (!parsedData.images) this._responses.push({
|
||||
status: status,
|
||||
signature: -1,
|
||||
url: '',
|
||||
source: '',
|
||||
@@ -104,6 +123,7 @@ class WaifuService extends Service {
|
||||
else {
|
||||
const imageData = parsedData.images[0];
|
||||
this._responses.push({
|
||||
status: status,
|
||||
signature: imageData?.signature || -1,
|
||||
url: imageData?.url || undefined,
|
||||
source: imageData?.source,
|
||||
|
||||
+31
-1
@@ -16,7 +16,7 @@
|
||||
margin-top: 0rem; } }
|
||||
|
||||
.test {
|
||||
background-image: linear-gradient(45deg, #F4D609 0%, #F4D609 10%, #212121 10%, #212121 20%, #F4D609 20%, #F4D609 30%, #212121 30%, #212121 40%, #F4D609 40%, #F4D609 50%, #212121 50%, #212121 60%, #F4D609 60%, #F4D609 70%, #212121 70%, #212121 80%, #F4D609 80%, #F4D609 90%, #212121 90%, #212121 100%);
|
||||
background-image: linear-gradient(45deg, #f4d609 0%, #f4d609 10%, #212121 10%, #212121 20%, #f4d609 20%, #f4d609 30%, #212121 30%, #212121 40%, #f4d609 40%, #f4d609 50%, #212121 50%, #212121 60%, #f4d609 60%, #f4d609 70%, #212121 70%, #212121 80%, #f4d609 80%, #f4d609 90%, #212121 90%, #212121 100%);
|
||||
background-repeat: repeat; }
|
||||
|
||||
.test-size {
|
||||
@@ -144,6 +144,12 @@
|
||||
.spacing-h-3 > *:last-child {
|
||||
margin-right: 0rem; }
|
||||
|
||||
.spacing-v-3 > * {
|
||||
margin-bottom: 0.205rem; }
|
||||
|
||||
.spacing-v-3 > *:last-child {
|
||||
margin-bottom: 0rem; }
|
||||
|
||||
.spacing-v-15 > * {
|
||||
margin-bottom: 1.023rem; }
|
||||
|
||||
@@ -369,6 +375,12 @@
|
||||
.element-hide {
|
||||
transition: 300ms cubic-bezier(0.85, 0, 0.15, 1); }
|
||||
|
||||
.element-decel {
|
||||
transition: 300ms cubic-bezier(0, 0.55, 0.45, 1); }
|
||||
|
||||
.element-accel {
|
||||
transition: 300ms cubic-bezier(0.55, 0, 1, 0.45); }
|
||||
|
||||
* {
|
||||
caret-color: #ffc4f5; }
|
||||
* selection {
|
||||
@@ -2001,6 +2013,24 @@ tooltip {
|
||||
background-repeat: no-repeat;
|
||||
background-position: center; }
|
||||
|
||||
.sidebar-waifu-image-actions {
|
||||
padding: 0.313rem; }
|
||||
|
||||
.sidebar-waifu-image-action {
|
||||
border-radius: 9999px;
|
||||
-gtk-outline-radius: 9999px;
|
||||
min-width: 1.875rem;
|
||||
min-height: 1.875rem;
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
color: rgba(255, 255, 255, 0.7); }
|
||||
|
||||
.sidebar-waifu-image-action:hover,
|
||||
.sidebar-waifu-image-action:focus {
|
||||
background-color: rgba(30, 30, 30, 0.7); }
|
||||
|
||||
.sidebar-waifu-image-action:active {
|
||||
background-color: rgba(60, 60, 60, 0.7); }
|
||||
|
||||
.session-bg {
|
||||
margin-top: -2.727rem;
|
||||
background-color: rgba(16, 13, 16, 0.64); }
|
||||
|
||||
@@ -201,6 +201,11 @@ export const chatGPTView = Scrollable({
|
||||
const viewport = scrolledWindow.child;
|
||||
viewport.set_focus_vadjustment(new Gtk.Adjustment(undefined));
|
||||
})
|
||||
// Always scroll to bottom with new content
|
||||
const adjustment = scrolledWindow.get_vadjustment();
|
||||
adjustment.connect("changed", () => {
|
||||
adjustment.set_value(adjustment.get_upper() - adjustment.get_page_size());
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ const CUSTOM_SOURCEVIEW_SCHEME_PATH = `${App.configDir}/data/sourceviewtheme.xml
|
||||
const CUSTOM_SCHEME_ID = 'custom';
|
||||
const USERNAME = GLib.get_user_name();
|
||||
const CHATGPT_CURSOR = ' (o) ';
|
||||
const MESSAGE_SCROLL_DELAY = 13; // In milliseconds, the time before an updated message scrolls to bottom
|
||||
|
||||
/////////////////////// Custom source view colorscheme /////////////////////////
|
||||
|
||||
@@ -125,7 +124,11 @@ const CodeBlock = (content = '', lang = 'txt') => {
|
||||
Box({
|
||||
className: 'sidebar-chat-codeblock-code',
|
||||
homogeneous: true,
|
||||
children: [sourceView,],
|
||||
children: [Scrollable({
|
||||
vscroll: 'never',
|
||||
hscroll: 'automatic',
|
||||
child: sourceView,
|
||||
})],
|
||||
})
|
||||
]
|
||||
})
|
||||
@@ -246,11 +249,6 @@ export const ChatMessage = (message, scrolledWindow) => {
|
||||
}, 'notify::thinking'],
|
||||
[message, (self) => { // Message update
|
||||
messageContentBox._fullUpdate(messageContentBox, message.content, message.role != 'user');
|
||||
Utils.timeout(MESSAGE_SCROLL_DELAY, () => {
|
||||
if (!scrolledWindow) return;
|
||||
var adjustment = scrolledWindow.get_vadjustment();
|
||||
adjustment.set_value(adjustment.get_upper() - adjustment.get_page_size());
|
||||
});
|
||||
}, 'notify::content'],
|
||||
[message, (label, isDone) => { // Remove the cursor
|
||||
messageContentBox._fullUpdate(messageContentBox, message.content, false);
|
||||
@@ -285,11 +283,6 @@ export const SystemMessage = (content, commandName, scrolledWindow) => {
|
||||
],
|
||||
})
|
||||
],
|
||||
setup: (self) => Utils.timeout(MESSAGE_SCROLL_DELAY, () => {
|
||||
if (!scrolledWindow) return;
|
||||
var adjustment = scrolledWindow.get_vadjustment();
|
||||
adjustment.set_value(adjustment.get_upper() - adjustment.get_page_size());
|
||||
})
|
||||
});
|
||||
return thisMessage;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
const { Gdk, GLib, Gtk, Pango } = imports.gi;
|
||||
const { Gdk, Gio, GLib, Gtk, Pango } = imports.gi;
|
||||
import { App, Utils, Widget } from '../../../imports.js';
|
||||
const { Box, Button, Entry, EventBox, Icon, Label, Revealer, Scrollable, Stack } = Widget;
|
||||
const { execAsync, exec } = Utils;
|
||||
import { MaterialIcon } from "../../../lib/materialicon.js";
|
||||
import { MarginRevealer } from '../../../lib/advancedrevealers.js';
|
||||
import { setupCursorHover, setupCursorHoverInfo } from "../../../lib/cursorhover.js";
|
||||
import WaifuService from '../../../services/waifus.js';
|
||||
|
||||
const MESSAGE_SCROLL_DELAY = 13; // In milliseconds, the time before an updated message scrolls to bottom
|
||||
|
||||
// Create cache folder and clear pics from previous session
|
||||
Utils.exec(`bash -c 'mkdir -p ${GLib.get_user_cache_dir()}/ags/media/waifus'`);
|
||||
Utils.exec(`bash -c 'rm ${GLib.get_user_cache_dir()}/ags/media/waifus/*'`);
|
||||
@@ -29,62 +28,146 @@ export const waifuTabIcon = Box({
|
||||
});
|
||||
|
||||
const WaifuImage = (taglist) => {
|
||||
var imagePath = '';
|
||||
var blockImageData = {};
|
||||
const ImageState = (icon, name) => Box({
|
||||
className: 'spacing-h-5',
|
||||
children: [
|
||||
Box({ hexpand: true }),
|
||||
Label({
|
||||
className: 'sidebar-waifu-txt txt-smallie txt',
|
||||
xalign: 0,
|
||||
label: name,
|
||||
}),
|
||||
MaterialIcon(icon, 'norm'),
|
||||
]
|
||||
})
|
||||
const ImageAction = ({ name, icon, action }) => Button({
|
||||
className: 'sidebar-waifu-image-action txt-norm icon-material',
|
||||
tooltipText: name,
|
||||
label: icon,
|
||||
onClicked: action,
|
||||
setup: setupCursorHover,
|
||||
})
|
||||
const colorIndicator = Box({
|
||||
className: `sidebar-chat-indicator`,
|
||||
});
|
||||
const downloadIndicator = Label({
|
||||
className: 'sidebar-waifu-txt txt-smallie txt',
|
||||
xalign: 0,
|
||||
label: 'Downloading image...',
|
||||
const downloadState = Stack({
|
||||
homogeneous: false,
|
||||
transition: 'slide_up_down',
|
||||
transitionDuration: 150,
|
||||
items: [
|
||||
['api', ImageState('api', 'Calling API')],
|
||||
['download', ImageState('downloading', 'Downloading image')],
|
||||
['done', ImageState('done', 'Finished!')],
|
||||
['error', ImageState('error', 'Error')],
|
||||
]
|
||||
});
|
||||
const downloadIndicator = MarginRevealer({
|
||||
vpack: 'center',
|
||||
transition: 'slide_left',
|
||||
revealChild: true,
|
||||
child: downloadState,
|
||||
});
|
||||
const blockHeading = Box({
|
||||
className: 'sidebar-waifu-content',
|
||||
vertical: true,
|
||||
hpack: 'fill',
|
||||
className: 'sidebar-waifu-content spacing-h-5',
|
||||
children: [
|
||||
Box({
|
||||
children: taglist.map((tag) => CommandButton(tag))
|
||||
}),
|
||||
...taglist.map((tag) => CommandButton(tag)),
|
||||
Box({ hexpand: true }),
|
||||
downloadIndicator,
|
||||
]
|
||||
});
|
||||
const blockImage = Box({
|
||||
hpack: 'start',
|
||||
className: 'sidebar-waifu-image',
|
||||
const blockImageActions = Box({
|
||||
className: 'sidebar-waifu-image-actions spacing-h-3',
|
||||
children: [
|
||||
Box({ hexpand: true }),
|
||||
ImageAction({
|
||||
name: 'Go to source',
|
||||
icon: 'link',
|
||||
action: () => execAsync(['xdg-open', `${blockImageData.source}`]).catch(print),
|
||||
}),
|
||||
ImageAction({
|
||||
name: 'Hoard',
|
||||
icon: 'save',
|
||||
action: () => execAsync(['bash', '-c', `mkdir -p ~/Pictures/waifus && cp ${imagePath} ~/Pictures/waifus`]).catch(print),
|
||||
}),
|
||||
ImageAction({
|
||||
name: 'Open externally',
|
||||
icon: 'open_in_new',
|
||||
action: () => execAsync(['xdg-open', `${imagePath}`]).catch(print),
|
||||
}),
|
||||
]
|
||||
})
|
||||
const blockImage = Box({
|
||||
className: 'test',
|
||||
hpack: 'start',
|
||||
vertical: true,
|
||||
className: 'sidebar-waifu-image',
|
||||
homogeneous: true,
|
||||
children: [
|
||||
Revealer({
|
||||
transition: 'crossfade',
|
||||
revealChild: false,
|
||||
child: Box({
|
||||
vertical: true,
|
||||
children: [blockImageActions],
|
||||
})
|
||||
})
|
||||
]
|
||||
})
|
||||
const blockImageRevealer = Revealer({
|
||||
transition: 'slide_down',
|
||||
transitionDuration: 150,
|
||||
revealChild: false,
|
||||
child: blockImage,
|
||||
});
|
||||
const thisBlock = Box({
|
||||
className: 'sidebar-chat-message',
|
||||
properties: [
|
||||
['update', (imageData) => {
|
||||
const { signature, url, source, dominant_color, is_nsfw, width, height, tags } = imageData;
|
||||
const imagePath = `${GLib.get_user_cache_dir()}/ags/media/waifus/${signature}`;
|
||||
blockImageData = imageData;
|
||||
const { status, signature, url, source, dominant_color, is_nsfw, width, height, tags } = blockImageData;
|
||||
if (status != 200) {
|
||||
downloadState.shown = 'error';
|
||||
return;
|
||||
}
|
||||
imagePath = `${GLib.get_user_cache_dir()}/ags/media/waifus/${signature}`;
|
||||
downloadState.shown = 'download';
|
||||
// Width allocation
|
||||
const widgetWidth = Math.min(Math.floor(waifuContent.get_allocated_width() * 0.75), width);
|
||||
blockImage.set_size_request(widgetWidth, Math.ceil(widgetWidth * height / width));
|
||||
// Start download
|
||||
Utils.execAsync(['bash', '-c', `wget -O '${imagePath}' '${url}'`])
|
||||
.then(() => {
|
||||
blockImage.css = `background-image:url('${imagePath}');`;
|
||||
downloadIndicator.destroy();
|
||||
})
|
||||
const showImage = () => {
|
||||
downloadState.shown = 'done';
|
||||
blockImage.css = `background-image:url('${imagePath}');`;
|
||||
blockImage.get_children()[0].revealChild = true;
|
||||
Utils.timeout(blockImageRevealer.transitionDuration,
|
||||
() => blockImageRevealer.revealChild = true
|
||||
);
|
||||
downloadIndicator._hide(downloadIndicator);
|
||||
}
|
||||
if (Gio.File.new_for_path(imagePath).query_exists(null)) showImage();
|
||||
else Utils.execAsync(['bash', '-c', `wget -O '${imagePath}' '${url}'`])
|
||||
.then(showImage)
|
||||
.catch(print);
|
||||
colorIndicator.css = `background-color: ${dominant_color};`;
|
||||
// Width allocation
|
||||
const widgetWidth = Math.floor(waifuContent.get_allocated_width() * 0.75); // idk tbh
|
||||
blockImage.set_size_request(widgetWidth, Math.ceil(widgetWidth * height / width));
|
||||
}],
|
||||
],
|
||||
children: [
|
||||
colorIndicator,
|
||||
Box({
|
||||
vertical: true,
|
||||
className: 'spacing-v-10',
|
||||
className: 'spacing-v-5',
|
||||
children: [
|
||||
blockHeading,
|
||||
blockImage,
|
||||
Box({
|
||||
vertical: true,
|
||||
children: [blockImageRevealer],
|
||||
})
|
||||
]
|
||||
})
|
||||
],
|
||||
setup: (self) => Utils.timeout(MESSAGE_SCROLL_DELAY, () => {
|
||||
var adjustment = waifuView.get_vadjustment();
|
||||
adjustment.set_value(adjustment.get_upper() - adjustment.get_page_size());
|
||||
})
|
||||
});
|
||||
return thisBlock;
|
||||
}
|
||||
@@ -99,7 +182,6 @@ const waifuContent = Box({
|
||||
connections: [
|
||||
[WaifuService, (box, id) => {
|
||||
if (id === undefined) return;
|
||||
console.log('new', WaifuService.queries[id]);
|
||||
const newImageBlock = WaifuImage(WaifuService.queries[id]);
|
||||
box.add(newImageBlock);
|
||||
box.show_all();
|
||||
@@ -134,9 +216,29 @@ export const waifuView = Scrollable({
|
||||
const viewport = scrolledWindow.child;
|
||||
viewport.set_focus_vadjustment(new Gtk.Adjustment(undefined));
|
||||
})
|
||||
// Always scroll to bottom with new content
|
||||
const adjustment = scrolledWindow.get_vadjustment();
|
||||
adjustment.connect("changed", () => {
|
||||
adjustment.set_value(adjustment.get_upper() - adjustment.get_page_size());
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
// const waifuTags = Box({
|
||||
// className: 'spacing-h-5',
|
||||
// children: [
|
||||
// Box({ hexpand: true }),
|
||||
// CommandButton('waifu'),
|
||||
// CommandButton('maid'),
|
||||
// CommandButton('uniform'),
|
||||
// CommandButton('oppai'),
|
||||
// CommandButton('selfies'),
|
||||
// CommandButton('marin-kitagawa'),
|
||||
// CommandButton('raiden-shogun'),
|
||||
// CommandButton('mori-calliope'),
|
||||
// ]
|
||||
// });
|
||||
|
||||
export const waifuCommands = Box({
|
||||
className: 'spacing-h-5',
|
||||
children: [
|
||||
@@ -156,6 +258,22 @@ export const sendMessage = (text) => {
|
||||
child.destroy();
|
||||
}
|
||||
}
|
||||
else if (text.startsWith('/test')) {
|
||||
const newImage = WaifuImage(['/test']);
|
||||
waifuContent.add(newImage);
|
||||
Utils.timeout(13, () => newImage._update({ // Needs timeout or inits won't make it
|
||||
// This is an image uploaded to my github repo
|
||||
status: 200,
|
||||
url: 'https://picsum.photos/400/600',
|
||||
signature: 0,
|
||||
source: 'https://picsum.photos/400/600',
|
||||
dominant_color: '#9392A6',
|
||||
is_nsfw: false,
|
||||
width: 300,
|
||||
height: 200,
|
||||
tags: ['/test'],
|
||||
}));
|
||||
}
|
||||
}
|
||||
else WaifuService.fetch(text);
|
||||
}
|
||||
Reference in New Issue
Block a user