mirror of
https://github.com/danbulant/dots-hyprland
synced 2026-05-19 04:08:48 +00:00
add waifu image fetch
This commit is contained in:
parent
5a7efaa139
commit
ff377a5826
14 changed files with 269 additions and 211 deletions
|
|
@ -1,5 +1,6 @@
|
|||
"strict mode";
|
||||
"use strict";
|
||||
// Import
|
||||
const { GLib } = imports.gi;
|
||||
import { App, Utils } from './imports.js';
|
||||
// Widgets
|
||||
import Bar from './widgets/bar/main.js';
|
||||
|
|
@ -16,8 +17,6 @@ import SideRight from './widgets/sideright/main.js';
|
|||
|
||||
const CLOSE_ANIM_TIME = 210; // Longer than actual anim time (see styles) to make sure widgets animate fully
|
||||
|
||||
// Init cache
|
||||
Utils.exec(`bash -c 'mkdir -p ~/.cache/ags/user/colorschemes'`);
|
||||
// SCSS compilation
|
||||
Utils.exec(`bash -c 'echo "" > ${App.configDir}/scss/_musicwal.scss'`); // reset music styles
|
||||
Utils.exec(`bash -c 'echo "" > ${App.configDir}/scss/_musicmaterial.scss'`); // reset music styles
|
||||
|
|
@ -43,8 +42,8 @@ export default {
|
|||
CornerTopright(),
|
||||
CornerBottomleft(),
|
||||
CornerBottomright(),
|
||||
// DesktopBackground(),
|
||||
// Dock(), // Buggy
|
||||
// DesktopBackground(), // If you're going to uncomment these,
|
||||
// Dock(), // Buggy // uncomment the import statement too.
|
||||
Overview(),
|
||||
Indicator(),
|
||||
Cheatsheet(),
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ const pad = (lines, start = 1, end = 1) => {
|
|||
return lines.map((l) => l.padEnd(len + end, ' ').padStart(len + end + start, ' '))
|
||||
}
|
||||
|
||||
export function convert(text) {
|
||||
export default (text) => {
|
||||
let lines = text.split('\n')
|
||||
|
||||
// Indicates if the current line is within a code block
|
||||
|
|
@ -205,33 +205,6 @@ export function convert(text) {
|
|||
return output.join('\n')
|
||||
}
|
||||
|
||||
const readFile = (f) => {
|
||||
// node.js only and when running from the command line
|
||||
const fs = require('fs')
|
||||
return fs.readFileSync(f, 'utf8')
|
||||
}
|
||||
|
||||
let __is_nodejs_main = false
|
||||
try {
|
||||
// node.js specific checks and exports
|
||||
__is_nodejs_main = (require.main === module)
|
||||
exports.convert = convert
|
||||
} catch (e) { }
|
||||
|
||||
if (__is_nodejs_main) {
|
||||
// running in node.js called from the CLI
|
||||
let args = process.argv.slice(2)
|
||||
if (args.length == 0 || args.find((a) => a == '-h')) {
|
||||
console.log(`Usage: ${process.argv[1]} FILE [FILE...]`)
|
||||
process.exit(0)
|
||||
}
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const f = args[i];
|
||||
process.stdout.write(convert(readFile(f)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const markdownTest = `# Heading 1
|
||||
## Heading 2
|
||||
### Heading 3
|
||||
|
|
|
|||
|
|
@ -166,27 +166,27 @@ $onChatgpt: $onPrimary;
|
|||
padding: 0rem $rounding_medium;
|
||||
}
|
||||
|
||||
.sidebar-navrail-btn>box>label {
|
||||
.sidebar-navrail-btn > box > label {
|
||||
@include full-rounding;
|
||||
@include menu_decel;
|
||||
}
|
||||
|
||||
.sidebar-navrail-btn:hover>box>label:first-child,
|
||||
.sidebar-navrail-btn:focus>box>label:first-child {
|
||||
.sidebar-navrail-btn:hover > box > label:first-child,
|
||||
.sidebar-navrail-btn:focus > box > label:first-child {
|
||||
background-color: mix($t_surfaceVariant, $onSurfaceVariant, 90%);
|
||||
}
|
||||
|
||||
.sidebar-navrail-btn:active>box>label:first-child {
|
||||
.sidebar-navrail-btn:active > box > label:first-child {
|
||||
background-color: mix($surfaceVariant, $onSurfaceVariant, 75%);
|
||||
}
|
||||
|
||||
.sidebar-navrail-btn-active>box>label:first-child {
|
||||
.sidebar-navrail-btn-active > box > label:first-child {
|
||||
background-color: $secondaryContainer;
|
||||
color: $onSecondaryContainer;
|
||||
}
|
||||
|
||||
.sidebar-navrail-btn-active:hover>box>label:first-child,
|
||||
.sidebar-navrail-btn-active:focus>box>label:first-child {
|
||||
.sidebar-navrail-btn-active:hover > box > label:first-child,
|
||||
.sidebar-navrail-btn-active:focus > box > label:first-child {
|
||||
background-color: mix($secondaryContainer, $hovercolor, 90%);
|
||||
color: mix($onSecondaryContainer, $hovercolor, 90%);
|
||||
}
|
||||
|
|
@ -346,7 +346,7 @@ $onChatgpt: $onPrimary;
|
|||
background-color: mix($surfaceVariant, $onSurfaceVariant, 75%);
|
||||
}
|
||||
|
||||
.sidebar-selector-tab-active>box>label {
|
||||
.sidebar-selector-tab-active > box > label {
|
||||
color: $primary;
|
||||
}
|
||||
|
||||
|
|
@ -509,7 +509,7 @@ $onChatgpt: $onPrimary;
|
|||
.sidebar-chat-apiswitcher-icon {
|
||||
@include menu_decel;
|
||||
@include full-rounding;
|
||||
min-width: 2.182rem;
|
||||
min-width: 2.182rem;
|
||||
min-height: 2.182rem;
|
||||
color: $onSurface;
|
||||
}
|
||||
|
|
@ -548,11 +548,19 @@ $onChatgpt: $onPrimary;
|
|||
|
||||
.sidebar-chat-send:hover,
|
||||
.sidebar-chat-send:focus {
|
||||
background-color: mix($sidebar_chat_textboxareaColor, $t_onSecondaryContainer, 97%);
|
||||
background-color: mix(
|
||||
$sidebar_chat_textboxareaColor,
|
||||
$t_onSecondaryContainer,
|
||||
97%
|
||||
);
|
||||
}
|
||||
|
||||
.sidebar-chat-send:active {
|
||||
background-color: mix($sidebar_chat_textboxareaColor, $t_onSecondaryContainer, 80%);
|
||||
background-color: mix(
|
||||
$sidebar_chat_textboxareaColor,
|
||||
$t_onSecondaryContainer,
|
||||
80%
|
||||
);
|
||||
}
|
||||
|
||||
.sidebar-chat-send-available {
|
||||
|
|
@ -576,6 +584,7 @@ $onChatgpt: $onPrimary;
|
|||
.sidebar-chat-indicator {
|
||||
@include full-rounding;
|
||||
min-width: 0.136rem;
|
||||
background-color: $onBackground;
|
||||
}
|
||||
|
||||
.sidebar-chat-indicator-user {
|
||||
|
|
@ -594,7 +603,6 @@ $onChatgpt: $onPrimary;
|
|||
@include titlefont;
|
||||
padding: 0.341rem;
|
||||
margin-left: -0.136rem;
|
||||
padding: 0.341rem;
|
||||
padding-left: 0.818rem;
|
||||
}
|
||||
|
||||
|
|
@ -699,7 +707,11 @@ $onChatgpt: $onPrimary;
|
|||
}
|
||||
|
||||
.sidebar-chat-chip-action:active {
|
||||
background-color: mix($sidebar_chat_textboxareaColor, $onSurfaceVariant, 70%);
|
||||
background-color: mix(
|
||||
$sidebar_chat_textboxareaColor,
|
||||
$onSurfaceVariant,
|
||||
70%
|
||||
);
|
||||
color: mix($sidebar_chat_textboxareaColor, $surfaceVariant, 70%);
|
||||
}
|
||||
|
||||
|
|
@ -741,3 +753,26 @@ $onChatgpt: $onPrimary;
|
|||
background-color: mix($primary, $onPrimary, 80%);
|
||||
}
|
||||
|
||||
.sidebar-waifu-heading {
|
||||
@include titlefont;
|
||||
padding: 0.341rem;
|
||||
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;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ function expandTilde(path) {
|
|||
|
||||
// We're using many models to not be restricted to 3 messages per minute.
|
||||
// The whole chat will be sent every request anyway.
|
||||
const KEY_FILE_LOCATION = `~/.cache/ags/user/openai_api_key.txt`;
|
||||
const KEY_FILE_LOCATION = `${GLib.get_user_cache_dir()}/ags/user/openai_api_key.txt`;
|
||||
const CHAT_MODELS = ["gpt-3.5-turbo-1106", "gpt-3.5-turbo", "gpt-3.5-turbo-16k", "gpt-3.5-turbo-0613"]
|
||||
const ONE_CYCLE_COUNT = 3;
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ class TodoService extends Service {
|
|||
super();
|
||||
this._todoPath = `${GLib.get_user_cache_dir()}/ags/user/todo.json`;
|
||||
if (!fileExists(this._todoPath)) { // No? create file with empty array
|
||||
Utils.exec(`bash -c 'mkdir -p ~/.cache/ags/user'`);
|
||||
Utils.exec(`bash -c 'mkdir -p ${GLib.get_user_cache_dir()}/ags/user'`);
|
||||
Utils.exec(`touch ${this._todoPath}`);
|
||||
Utils.writeFile("[]", this._todoPath).then(() => {
|
||||
this._todoJson = JSON.parse(Utils.readFile(this._todoPath))
|
||||
|
|
|
|||
|
|
@ -5,64 +5,20 @@ 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);
|
||||
}
|
||||
function paramStringFromObj(params) {
|
||||
return Object.entries(params)
|
||||
.map(([key, value]) => {
|
||||
if (Array.isArray(value)) { // If it's an array, repeat
|
||||
if (value.length == 0) return '';
|
||||
let thisKey = `${encodeURIComponent(key)}=${encodeURIComponent(value[0])}`
|
||||
for (let i = 1; i < value.length; i++) {
|
||||
thisKey += `&${encodeURIComponent(key)}=${encodeURIComponent(value[i])}`;
|
||||
}
|
||||
return thisKey;
|
||||
}
|
||||
return `${key}=${value}`;
|
||||
})
|
||||
.join('&');
|
||||
}
|
||||
|
||||
class WaifuService extends Service {
|
||||
|
|
@ -76,9 +32,10 @@ class WaifuService extends Service {
|
|||
'nekos': {},
|
||||
'pics': {},
|
||||
}
|
||||
_url = 'https://api.waifu.im/search';
|
||||
_baseUrl = 'https://api.waifu.im/search';
|
||||
_mode = 'im'; // Allowed: im
|
||||
_responses = [];
|
||||
_queries = [];
|
||||
_nsfw = false;
|
||||
_minHeight = 600;
|
||||
|
||||
|
|
@ -86,7 +43,8 @@ class WaifuService extends Service {
|
|||
Service.register(this, {
|
||||
'initialized': [],
|
||||
'clear': [],
|
||||
'newResponse': ['string'],
|
||||
'newResponse': ['int'],
|
||||
'updateResponse': ['int'],
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -97,71 +55,68 @@ class WaifuService extends Service {
|
|||
|
||||
clear() {
|
||||
this._responses = [];
|
||||
this._queries = [];
|
||||
this.emit('clear');
|
||||
}
|
||||
|
||||
get mode() { return this._mode }
|
||||
set mode(value) {
|
||||
this._mode = value;
|
||||
this._url = this._endpoints[this._mode];
|
||||
this._baseUrl = this._endpoints[this._mode];
|
||||
}
|
||||
get nsfw() { return this._nsfw }
|
||||
set nsfw(value) { this._nsfw = value }
|
||||
get queries() { return this._queries }
|
||||
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 newMessageId = this._responses.length;
|
||||
const taglist = msg.split(' ');
|
||||
this.emit('newResponse', msg);
|
||||
this._responses.push(msg);
|
||||
|
||||
this._queries.push(taglist);
|
||||
this.emit('newResponse', newMessageId);
|
||||
// Construct body/headers
|
||||
const params = {
|
||||
'included_tags': taglist,
|
||||
'height': `>=${this._minHeight}`,
|
||||
'nsfw': this._nsfw,
|
||||
};
|
||||
|
||||
const session = new Soup.Session();
|
||||
const message = new Soup.Message({
|
||||
const paramString = paramStringFromObj(params);
|
||||
console.log(paramString);
|
||||
// Fetch
|
||||
const options = {
|
||||
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);
|
||||
}
|
||||
});
|
||||
headers: this._headers[this._mode],
|
||||
};
|
||||
Utils.fetch(`${this._baseUrl}?${paramString}`, options)
|
||||
.then(result => result.text()) // Parse
|
||||
.then((dataString) => { // Store interesting stuff and emit
|
||||
const parsedData = JSON.parse(dataString);
|
||||
if (!parsedData.images) this._responses.push({
|
||||
signature: -1,
|
||||
url: '',
|
||||
source: '',
|
||||
dominant_color: '#383A40',
|
||||
is_nsfw: false,
|
||||
width: 0,
|
||||
height: 0,
|
||||
tags: [],
|
||||
});
|
||||
else {
|
||||
const imageData = parsedData.images[0];
|
||||
this._responses.push({
|
||||
signature: imageData?.signature || -1,
|
||||
url: imageData?.url || undefined,
|
||||
source: imageData?.source,
|
||||
dominant_color: imageData?.dominant_color || '#000000',
|
||||
is_nsfw: imageData?.is_nsfw || false,
|
||||
width: imageData?.width || 0,
|
||||
height: imageData?.height || 0,
|
||||
tags: imageData?.tags.map(obj => obj["name"]) || [],
|
||||
});
|
||||
}
|
||||
this.emit('updateResponse', newMessageId);
|
||||
})
|
||||
.catch(console.error)
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1839,7 +1839,8 @@ tooltip {
|
|||
.sidebar-chat-indicator {
|
||||
border-radius: 9999px;
|
||||
-gtk-outline-radius: 9999px;
|
||||
min-width: 0.136rem; }
|
||||
min-width: 0.136rem;
|
||||
background-color: #eae0e4; }
|
||||
|
||||
.sidebar-chat-indicator-user {
|
||||
background-color: #eae0e4; }
|
||||
|
|
@ -1854,7 +1855,6 @@ tooltip {
|
|||
font-family: 'Gabarito', 'Poppins', 'Lexend', sans-serif;
|
||||
padding: 0.341rem;
|
||||
margin-left: -0.136rem;
|
||||
padding: 0.341rem;
|
||||
padding-left: 0.818rem; }
|
||||
|
||||
.sidebar-chat-txtblock {
|
||||
|
|
@ -1980,6 +1980,27 @@ tooltip {
|
|||
.sidebar-pin-enabled:active {
|
||||
background-color: #dda0d4; }
|
||||
|
||||
.sidebar-waifu-heading {
|
||||
font-family: 'Gabarito', 'Poppins', 'Lexend', sans-serif;
|
||||
padding: 0.341rem;
|
||||
margin-left: -0.136rem;
|
||||
padding-left: 0.818rem; }
|
||||
|
||||
.sidebar-waifu-content {
|
||||
margin-left: 0.682rem; }
|
||||
|
||||
.sidebar-waifu-txt {
|
||||
font-family: 'Lexend', 'Noto Sans', sans-serif;
|
||||
margin-left: 0.682rem; }
|
||||
|
||||
.sidebar-waifu-image {
|
||||
margin-left: 0.682rem;
|
||||
border-radius: 1.159rem;
|
||||
-gtk-outline-radius: 1.159rem;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center; }
|
||||
|
||||
.session-bg {
|
||||
margin-top: -2.727rem;
|
||||
background-color: rgba(16, 13, 16, 0.64); }
|
||||
|
|
|
|||
|
|
@ -129,6 +129,7 @@ const Taskbar = () => Widget.Box({
|
|||
if (!address) return;
|
||||
|
||||
const removedButton = box._map.get(address);
|
||||
if (!removedButton) return;
|
||||
removedButton.revealChild = false;
|
||||
|
||||
Utils.timeout(ANIMATION_TIME, () => {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ function expandTilde(path) {
|
|||
}
|
||||
}
|
||||
|
||||
const LIGHTDARK_FILE_LOCATION = '~/.cache/ags/user/colormode.txt'
|
||||
const LIGHTDARK_FILE_LOCATION = `${GLib.get_user_cache_dir()}/ags/user/colormode.txt`;
|
||||
const lightDark = Utils.readFile(expandTilde(LIGHTDARK_FILE_LOCATION)).trim();
|
||||
const COVER_COLORSCHEME_SUFFIX = '_colorscheme.css';
|
||||
const PREFERRED_PLAYER = 'plasma-browser-integration';
|
||||
|
|
@ -165,7 +165,7 @@ const CoverArt = ({ player, ...rest }) => Box({
|
|||
`${App.configDir}/scripts/color_generation/generate_colors_material.py --path '${coverPath}' > ${App.configDir}/scss/_musicmaterial.scss ${lightDark}`])
|
||||
.then(() => {
|
||||
exec(`wal -i "${player.coverPath}" -n -t -s -e -q ${lightDark}`)
|
||||
exec(`bash -c "cp ~/.cache/wal/colors.scss ${App.configDir}/scss/_musicwal.scss"`)
|
||||
exec(`cp ${GLib.get_user_cache_dir()}/wal/colors.scss ${App.configDir}/scss/_musicwal.scss`);
|
||||
exec(`sassc ${App.configDir}/scss/_music.scss ${stylePath}`);
|
||||
self.css = `background-image: url('${coverPath}');`;
|
||||
App.applyCss(`${stylePath}`);
|
||||
|
|
|
|||
|
|
@ -21,12 +21,12 @@ export function launchCustomCommand(command) {
|
|||
execAsync([`bash`, `-c`, `${App.configDir}/scripts/color_generation/switchcolor.sh`, `&`]).catch(print);
|
||||
}
|
||||
else if (args[0] == '>light') { // Light mode
|
||||
execAsync([`bash`, `-c`, `mkdir -p ~/.cache/ags/user && echo "-l" > ~/.cache/ags/user/colormode.txt`])
|
||||
execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_cache_dir()}/ags/user && echo "-l" > ${GLib.get_user_cache_dir()}/ags/user/colormode.txt`])
|
||||
.then(execAsync(['bash', '-c', `${App.configDir}/scripts/color_generation/switchwall.sh --noswitch`]).catch(print))
|
||||
.catch(print);
|
||||
}
|
||||
else if (args[0] == '>dark') { // Dark mode
|
||||
execAsync([`bash`, `-c`, `mkdir -p ~/.cache/ags/user && echo "" > ~/.cache/ags/user/colormode.txt`])
|
||||
execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_cache_dir()}/ags/user && echo "" > ${GLib.get_user_cache_dir()}/ags/user/colormode.txt`])
|
||||
.then(execAsync(['bash', '-c', `${App.configDir}/scripts/color_generation/switchwall.sh --noswitch`]).catch(print))
|
||||
.catch(print);
|
||||
}
|
||||
|
|
@ -34,10 +34,10 @@ export function launchCustomCommand(command) {
|
|||
execAsync([`bash`, `-c`, `${App.configDir}/scripts/color_generation/applycolor.sh --bad-apple`]).catch(print);
|
||||
}
|
||||
else if (args[0] == '>material') { // Light mode
|
||||
execAsync([`bash`, `-c`, `mkdir -p ~/.cache/ags/user && echo "material" > ~/.cache/ags/user/colorbackend.txt`]).catch(print);
|
||||
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);
|
||||
}
|
||||
else if (args[0] == '>pywal') { // Dark mode
|
||||
execAsync([`bash`, `-c`, `mkdir -p ~/.cache/ags/user && echo "pywal" > ~/.cache/ags/user/colorbackend.txt`]).catch(print);
|
||||
execAsync([`bash`, `-c`, `mkdir -p ${GLib.get_user_cache_dir()}/ags/user && echo "pywal" > ${GLib.get_user_cache_dir()}/ags/user/colorbackend.txt`]).catch(print);
|
||||
}
|
||||
else if (args[0] == '>todo') { // Todo
|
||||
Todo.add(args.slice(1).join(' '));
|
||||
|
|
|
|||
|
|
@ -204,39 +204,24 @@ export const chatGPTView = Scrollable({
|
|||
}
|
||||
});
|
||||
|
||||
const CommandButton = (command) => Button({
|
||||
className: 'sidebar-chat-chip sidebar-chat-chip-action txt txt-small',
|
||||
onClicked: () => sendMessage(command),
|
||||
setup: setupCursorHover,
|
||||
label: command,
|
||||
});
|
||||
|
||||
export const chatGPTCommands = Box({
|
||||
className: 'spacing-h-5',
|
||||
children: [
|
||||
Box({ hexpand: true }),
|
||||
Button({
|
||||
className: 'sidebar-chat-chip sidebar-chat-chip-action txt txt-small',
|
||||
onClicked: () => chatContent.add(SystemMessage(
|
||||
`Key stored in:\n\`${ChatGPT.keyPath}\`\nTo update this key, type \`/key YOUR_API_KEY\``,
|
||||
'/key',
|
||||
chatGPTView)),
|
||||
setup: setupCursorHover,
|
||||
label: '/key',
|
||||
}),
|
||||
Button({
|
||||
className: 'sidebar-chat-chip sidebar-chat-chip-action txt txt-small',
|
||||
onClicked: () => chatContent.add(SystemMessage(
|
||||
`Currently using \`${ChatGPT.modelName}\``,
|
||||
'/model',
|
||||
chatGPTView
|
||||
)),
|
||||
setup: setupCursorHover,
|
||||
label: '/model',
|
||||
}),
|
||||
Button({
|
||||
className: 'sidebar-chat-chip sidebar-chat-chip-action txt txt-small',
|
||||
onClicked: () => clearChat(),
|
||||
setup: setupCursorHover,
|
||||
label: '/clear',
|
||||
}),
|
||||
CommandButton('/key'),
|
||||
CommandButton('/model'),
|
||||
CommandButton('/clear'),
|
||||
]
|
||||
});
|
||||
|
||||
export const chatGPTSendMessage = (text) => {
|
||||
export const sendMessage = (text) => {
|
||||
// Check if text or API key is empty
|
||||
if (text.length == 0) return;
|
||||
if (ChatGPT.key.length == 0) {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ 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 { convert } from "../../../lib/md2pango.js";
|
||||
import md2pango from "../../../lib/md2pango.js";
|
||||
import GtkSource from "gi://GtkSource?version=3.0";
|
||||
|
||||
const CUSTOM_SOURCEVIEW_SCHEME_PATH = `${App.configDir}/data/sourceviewtheme.xml`;
|
||||
|
|
@ -168,7 +168,7 @@ const MessageContent = (content) => {
|
|||
const lastLabel = kids[kids.length - 1];
|
||||
const blockContent = lines.slice(lastProcessed, index).join('\n');
|
||||
if (!inCode) {
|
||||
lastLabel.label = convert(blockContent);
|
||||
lastLabel.label = md2pango(blockContent);
|
||||
contentBox.add(CodeBlock('', codeBlockRegex.exec(line)[1]));
|
||||
}
|
||||
else {
|
||||
|
|
@ -185,7 +185,7 @@ const MessageContent = (content) => {
|
|||
const kids = self.get_children();
|
||||
const lastLabel = kids[kids.length - 1];
|
||||
const blockContent = lines.slice(lastProcessed, index).join('\n');
|
||||
lastLabel.label = convert(blockContent);
|
||||
lastLabel.label = md2pango(blockContent);
|
||||
contentBox.add(Divider());
|
||||
contentBox.add(TextBlock());
|
||||
lastProcessed = index + 1;
|
||||
|
|
@ -196,7 +196,7 @@ const MessageContent = (content) => {
|
|||
const lastLabel = kids[kids.length - 1];
|
||||
let blockContent = lines.slice(lastProcessed, lines.length).join('\n');
|
||||
if (!inCode)
|
||||
lastLabel.label = `${convert(blockContent)}${useCursor ? CHATGPT_CURSOR : ''}`;
|
||||
lastLabel.label = `${md2pango(blockContent)}${useCursor ? CHATGPT_CURSOR : ''}`;
|
||||
else
|
||||
lastLabel._updateText(blockContent);
|
||||
}
|
||||
|
|
@ -208,7 +208,7 @@ const MessageContent = (content) => {
|
|||
// xalign: 0,
|
||||
// wrap: true,
|
||||
// selectable: true,
|
||||
// label: '------------------------------\n' + convert(content),
|
||||
// label: '------------------------------\n' + md2pango(content),
|
||||
// }))
|
||||
contentBox.show_all();
|
||||
}]
|
||||
|
|
|
|||
|
|
@ -6,6 +6,19 @@ import { MaterialIcon } from "../../../lib/materialicon.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/*'`);
|
||||
|
||||
const CommandButton = (command) => Button({
|
||||
className: 'sidebar-chat-chip sidebar-chat-chip-action txt txt-small',
|
||||
onClicked: () => sendMessage(command),
|
||||
setup: setupCursorHover,
|
||||
label: command,
|
||||
});
|
||||
|
||||
export const waifuTabIcon = Box({
|
||||
hpack: 'center',
|
||||
className: 'sidebar-chat-apiswitcher-icon',
|
||||
|
|
@ -15,17 +28,90 @@ export const waifuTabIcon = Box({
|
|||
]
|
||||
});
|
||||
|
||||
const WaifuImage = (taglist) => {
|
||||
const colorIndicator = Box({
|
||||
className: `sidebar-chat-indicator`,
|
||||
});
|
||||
const downloadIndicator = Label({
|
||||
className: 'sidebar-waifu-txt txt-smallie txt',
|
||||
xalign: 0,
|
||||
label: 'Downloading image...',
|
||||
});
|
||||
const blockHeading = Box({
|
||||
className: 'sidebar-waifu-content',
|
||||
vertical: true,
|
||||
children: [
|
||||
Box({
|
||||
children: taglist.map((tag) => CommandButton(tag))
|
||||
}),
|
||||
downloadIndicator,
|
||||
]
|
||||
});
|
||||
const blockImage = Box({
|
||||
hpack: 'start',
|
||||
className: 'sidebar-waifu-image',
|
||||
})
|
||||
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}`;
|
||||
// Start download
|
||||
Utils.execAsync(['bash', '-c', `wget -O '${imagePath}' '${url}'`])
|
||||
.then(() => {
|
||||
blockImage.css = `background-image:url('${imagePath}');`;
|
||||
downloadIndicator.destroy();
|
||||
})
|
||||
.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',
|
||||
children: [
|
||||
blockHeading,
|
||||
blockImage,
|
||||
]
|
||||
})
|
||||
],
|
||||
setup: (self) => Utils.timeout(MESSAGE_SCROLL_DELAY, () => {
|
||||
var adjustment = waifuView.get_vadjustment();
|
||||
adjustment.set_value(adjustment.get_upper() - adjustment.get_page_size());
|
||||
})
|
||||
});
|
||||
return thisBlock;
|
||||
}
|
||||
|
||||
const waifuContent = Box({
|
||||
className: 'spacing-v-15',
|
||||
vertical: true,
|
||||
vexpand: true,
|
||||
properties: [
|
||||
['map', new Map()],
|
||||
],
|
||||
connections: [
|
||||
[WaifuService, (box, id) => {
|
||||
const message = WaifuService.responses[id];
|
||||
if (!message) return;
|
||||
box.add(Label({
|
||||
label: message,
|
||||
}))
|
||||
if (id === undefined) return;
|
||||
console.log('new', WaifuService.queries[id]);
|
||||
const newImageBlock = WaifuImage(WaifuService.queries[id]);
|
||||
box.add(newImageBlock);
|
||||
box.show_all();
|
||||
box._map.set(id, newImageBlock);
|
||||
}, 'newResponse'],
|
||||
[WaifuService, (box, id) => {
|
||||
if (id === undefined) return;
|
||||
const data = WaifuService.responses[id];
|
||||
if (!data) return;
|
||||
const imageBlock = box._map.get(id);
|
||||
imageBlock._update(data);
|
||||
}, 'updateResponse'],
|
||||
]
|
||||
});
|
||||
|
||||
|
|
@ -55,18 +141,21 @@ export const waifuCommands = Box({
|
|||
className: 'spacing-h-5',
|
||||
children: [
|
||||
Box({ hexpand: true }),
|
||||
Button({
|
||||
className: 'sidebar-chat-chip sidebar-chat-chip-action txt txt-small',
|
||||
onClicked: () => {
|
||||
// command do something
|
||||
},
|
||||
setup: setupCursorHover,
|
||||
label: '/call',
|
||||
}),
|
||||
CommandButton('/clear'),
|
||||
]
|
||||
});
|
||||
|
||||
export const waifuCallAPI = (text) => {
|
||||
export const sendMessage = (text) => {
|
||||
// Do something on send
|
||||
WaifuService.fetch(text);
|
||||
// Commands
|
||||
if (text.startsWith('/')) {
|
||||
if (text.startsWith('/clear')) {
|
||||
const kids = waifuContent.get_children();
|
||||
for (let i = 0; i < kids.length; i++) {
|
||||
const child = kids[i];
|
||||
child.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
else WaifuService.fetch(text);
|
||||
}
|
||||
|
|
@ -5,8 +5,8 @@ const { execAsync, exec } = Utils;
|
|||
import { setupCursorHover, setupCursorHoverInfo } from "../../lib/cursorhover.js";
|
||||
// APIs
|
||||
import ChatGPT from '../../services/chatgpt.js';
|
||||
import { chatGPTView, chatGPTCommands, chatGPTSendMessage, chatGPTTabIcon } from './apis/chatgpt.js';
|
||||
import { waifuView, waifuCommands, waifuCallAPI, waifuTabIcon } from './apis/waifu.js';
|
||||
import { chatGPTView, chatGPTCommands, sendMessage as chatGPTSendMessage, chatGPTTabIcon } from './apis/chatgpt.js';
|
||||
import { waifuView, waifuCommands, sendMessage as waifuSendMessage, waifuTabIcon } from './apis/waifu.js';
|
||||
|
||||
const APIS = [
|
||||
{
|
||||
|
|
@ -19,7 +19,7 @@ const APIS = [
|
|||
},
|
||||
{
|
||||
name: 'Waifus',
|
||||
sendCommand: waifuCallAPI,
|
||||
sendCommand: waifuSendMessage,
|
||||
contentWidget: waifuView,
|
||||
commandBar: waifuCommands,
|
||||
tabIcon: waifuTabIcon,
|
||||
|
|
|
|||
Loading…
Reference in a new issue