forked from Shinonome/dots-hyprland
add waifu image fetch
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user