forked from Shinonome/dots-hyprland
internal: sidebar: apis: cleaner tabs
This commit is contained in:
@@ -92,3 +92,71 @@ export const TabContainer = ({ icons, names, children, className = '', setup = (
|
|||||||
|
|
||||||
return mainBox;
|
return mainBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const IconTabContainer = ({ iconWidgets, names, children, className = '', setup = () => { }, tabsHpack = 'center', ...rest }) => {
|
||||||
|
const shownIndex = Variable(0);
|
||||||
|
let previousShownIndex = 0;
|
||||||
|
const count = Math.min(iconWidgets.length, names.length, children.length);
|
||||||
|
const tabs = Box({
|
||||||
|
homogeneous: true,
|
||||||
|
hpack: tabsHpack,
|
||||||
|
className: 'spacing-h-5',
|
||||||
|
children: iconWidgets.map((icon, i) => Button({
|
||||||
|
className: 'tab-icon',
|
||||||
|
child: icon,
|
||||||
|
setup: setupCursorHover,
|
||||||
|
onClicked: () => shownIndex.value = i,
|
||||||
|
})),
|
||||||
|
setup: (self) => self.hook(shownIndex, (self) => {
|
||||||
|
self.children[previousShownIndex].toggleClassName('tab-icon-active', false);
|
||||||
|
self.children[shownIndex.value].toggleClassName('tab-icon-active', true);
|
||||||
|
previousShownIndex = shownIndex.value;
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
const tabSection = Box({
|
||||||
|
homogeneous: true,
|
||||||
|
children: [EventBox({
|
||||||
|
onScrollUp: () => mainBox.prevTab(),
|
||||||
|
onScrollDown: () => mainBox.nextTab(),
|
||||||
|
child: Box({
|
||||||
|
vertical: true,
|
||||||
|
hexpand: true,
|
||||||
|
children: [
|
||||||
|
tabs,
|
||||||
|
]
|
||||||
|
})
|
||||||
|
})]
|
||||||
|
});
|
||||||
|
const contentStack = Stack({
|
||||||
|
transition: 'slide_left_right',
|
||||||
|
children: children.reduce((acc, currentValue, index) => {
|
||||||
|
acc[index] = currentValue;
|
||||||
|
return acc;
|
||||||
|
}, {}),
|
||||||
|
setup: (self) => self.hook(shownIndex, (self) => {
|
||||||
|
self.shown = `${shownIndex.value}`;
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
const mainBox = Box({
|
||||||
|
attribute: {
|
||||||
|
children: children,
|
||||||
|
shown: shownIndex,
|
||||||
|
names: names,
|
||||||
|
},
|
||||||
|
vertical: true,
|
||||||
|
className: `spacing-v-5 ${className}`,
|
||||||
|
setup: (self) => {
|
||||||
|
self.pack_start(tabSection, false, false, 0);
|
||||||
|
self.pack_end(contentStack, true, true, 0);
|
||||||
|
setup(self);
|
||||||
|
},
|
||||||
|
...rest,
|
||||||
|
});
|
||||||
|
mainBox.nextTab = () => shownIndex.value = Math.min(shownIndex.value + 1, count - 1);
|
||||||
|
mainBox.prevTab = () => shownIndex.value = Math.max(shownIndex.value - 1, 0);
|
||||||
|
mainBox.cycleTab = () => shownIndex.value = (shownIndex.value + 1) % count;
|
||||||
|
mainBox.shown = shownIndex;
|
||||||
|
|
||||||
|
return mainBox;
|
||||||
|
}
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ const CommandButton = (command) => Button({
|
|||||||
|
|
||||||
export const booruTabIcon = Box({
|
export const booruTabIcon = Box({
|
||||||
hpack: 'center',
|
hpack: 'center',
|
||||||
className: 'sidebar-chat-apiswitcher-icon',
|
|
||||||
homogeneous: true,
|
homogeneous: true,
|
||||||
children: [
|
children: [
|
||||||
MaterialIcon('gallery_thumbnail', 'norm'),
|
MaterialIcon('gallery_thumbnail', 'norm'),
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import { chatEntry } from '../apiwidgets.js';
|
|||||||
|
|
||||||
export const chatGPTTabIcon = Icon({
|
export const chatGPTTabIcon = Icon({
|
||||||
hpack: 'center',
|
hpack: 'center',
|
||||||
className: 'sidebar-chat-apiswitcher-icon',
|
|
||||||
icon: `openai-symbolic`,
|
icon: `openai-symbolic`,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ const MODEL_NAME = `Gemini`;
|
|||||||
|
|
||||||
export const geminiTabIcon = Icon({
|
export const geminiTabIcon = Icon({
|
||||||
hpack: 'center',
|
hpack: 'center',
|
||||||
className: 'sidebar-chat-apiswitcher-icon',
|
|
||||||
icon: `google-gemini-symbolic`,
|
icon: `google-gemini-symbolic`,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -39,8 +39,6 @@ const CommandButton = (command) => Button({
|
|||||||
|
|
||||||
export const waifuTabIcon = Box({
|
export const waifuTabIcon = Box({
|
||||||
hpack: 'center',
|
hpack: 'center',
|
||||||
className: 'sidebar-chat-apiswitcher-icon',
|
|
||||||
homogeneous: true,
|
|
||||||
children: [
|
children: [
|
||||||
MaterialIcon('photo', 'norm'),
|
MaterialIcon('photo', 'norm'),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { checkKeybind } from '../.widgetutils/keybind.js';
|
|||||||
const TextView = Widget.subclass(Gtk.TextView, "AgsTextView");
|
const TextView = Widget.subclass(Gtk.TextView, "AgsTextView");
|
||||||
|
|
||||||
import { widgetContent } from './sideleft.js';
|
import { widgetContent } from './sideleft.js';
|
||||||
|
import { IconTabContainer } from '../.commonwidgets/tabcontainer.js';
|
||||||
|
|
||||||
const EXPAND_INPUT_THRESHOLD = 30;
|
const EXPAND_INPUT_THRESHOLD = 30;
|
||||||
const APIS = [
|
const APIS = [
|
||||||
@@ -53,7 +54,6 @@ const APIS = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
let currentApiId = 0;
|
let currentApiId = 0;
|
||||||
APIS[currentApiId].tabIcon.toggleClassName('sidebar-chat-apiswitcher-icon-enabled', true);
|
|
||||||
|
|
||||||
function apiSendMessage(textView) {
|
function apiSendMessage(textView) {
|
||||||
// Get text
|
// Get text
|
||||||
@@ -170,16 +170,6 @@ const textboxArea = Box({ // Entry area
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
const apiContentStack = Stack({
|
|
||||||
vexpand: true,
|
|
||||||
transition: 'slide_left_right',
|
|
||||||
transitionDuration: userOptions.animations.durationLarge,
|
|
||||||
children: APIS.reduce((acc, api) => {
|
|
||||||
acc[api.name] = api.contentWidget;
|
|
||||||
return acc;
|
|
||||||
}, {}),
|
|
||||||
})
|
|
||||||
|
|
||||||
const apiCommandStack = Stack({
|
const apiCommandStack = Stack({
|
||||||
transition: 'slide_up_down',
|
transition: 'slide_up_down',
|
||||||
transitionDuration: userOptions.animations.durationLarge,
|
transitionDuration: userOptions.animations.durationLarge,
|
||||||
@@ -189,41 +179,20 @@ const apiCommandStack = Stack({
|
|||||||
}, {}),
|
}, {}),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const apiContentStack = IconTabContainer({
|
||||||
|
className: 'margin-top-5',
|
||||||
|
iconWidgets: APIS.map((api, id) => api.tabIcon),
|
||||||
|
names: APIS.map((api) => api.name),
|
||||||
|
children: APIS.map((api) => api.contentWidget),
|
||||||
|
});
|
||||||
|
|
||||||
function switchToTab(id) {
|
function switchToTab(id) {
|
||||||
APIS[currentApiId].tabIcon.toggleClassName('sidebar-chat-apiswitcher-icon-enabled', false);
|
apiContentStack.shown.value = id;
|
||||||
APIS[id].tabIcon.toggleClassName('sidebar-chat-apiswitcher-icon-enabled', true);
|
|
||||||
apiContentStack.shown = APIS[id].name;
|
|
||||||
apiCommandStack.shown = APIS[id].name;
|
apiCommandStack.shown = APIS[id].name;
|
||||||
chatPlaceholder.label = APIS[id].placeholderText;
|
chatPlaceholder.label = APIS[id].placeholderText;
|
||||||
currentApiId = id;
|
currentApiId = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
const apiSwitcher = EventBox({
|
|
||||||
onScrollUp: () => apiWidgets.attribute.prevTab(),
|
|
||||||
onScrollDown: () => apiWidgets.attribute.nextTab(),
|
|
||||||
child: CenterBox({
|
|
||||||
centerWidget: Box({
|
|
||||||
className: 'sidebar-chat-apiswitcher spacing-h-5',
|
|
||||||
hpack: 'center',
|
|
||||||
children: APIS.map((api, id) => Button({
|
|
||||||
child: api.tabIcon,
|
|
||||||
tooltipText: api.name,
|
|
||||||
setup: setupCursorHover,
|
|
||||||
onClicked: () => {
|
|
||||||
switchToTab(id);
|
|
||||||
}
|
|
||||||
})),
|
|
||||||
}),
|
|
||||||
endWidget: Button({
|
|
||||||
hpack: 'end',
|
|
||||||
className: 'txt-subtext txt-norm icon-material',
|
|
||||||
label: 'lightbulb',
|
|
||||||
tooltipText: 'Use PageUp/PageDown to switch between API pages',
|
|
||||||
setup: setupCursorHoverInfo,
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
const apiWidgets = Widget.Box({
|
const apiWidgets = Widget.Box({
|
||||||
attribute: {
|
attribute: {
|
||||||
'nextTab': () => switchToTab(Math.min(currentApiId + 1, APIS.length - 1)),
|
'nextTab': () => switchToTab(Math.min(currentApiId + 1, APIS.length - 1)),
|
||||||
@@ -233,7 +202,6 @@ const apiWidgets = Widget.Box({
|
|||||||
className: 'spacing-v-10',
|
className: 'spacing-v-10',
|
||||||
homogeneous: false,
|
homogeneous: false,
|
||||||
children: [
|
children: [
|
||||||
apiSwitcher,
|
|
||||||
apiContentStack,
|
apiContentStack,
|
||||||
apiCommandStack,
|
apiCommandStack,
|
||||||
textboxArea,
|
textboxArea,
|
||||||
|
|||||||
@@ -274,6 +274,20 @@ popover {
|
|||||||
color: $primary;
|
color: $primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tab-icon {
|
||||||
|
@include element_decel;
|
||||||
|
@include full-rounding;
|
||||||
|
min-width: 2.182rem;
|
||||||
|
min-height: 2.182rem;
|
||||||
|
font-size: 1.406rem;
|
||||||
|
color: $onSurface;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-icon-active {
|
||||||
|
background-color: $secondaryContainer;
|
||||||
|
color: $onSecondaryContainer;
|
||||||
|
}
|
||||||
|
|
||||||
widget {
|
widget {
|
||||||
@include small-rounding;
|
@include small-rounding;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -492,26 +492,6 @@ $colorpicker_rounding: 0.341rem;
|
|||||||
padding: 0.341rem;
|
padding: 0.341rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-chat-apiswitcher {
|
|
||||||
@include full-rounding;
|
|
||||||
@include group-padding;
|
|
||||||
background-color: $layer1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-chat-apiswitcher-icon {
|
|
||||||
@include element_decel;
|
|
||||||
@include full-rounding;
|
|
||||||
min-width: 2.182rem;
|
|
||||||
min-height: 2.182rem;
|
|
||||||
font-size: 1.406rem;
|
|
||||||
color: $onSurface;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-chat-apiswitcher-icon-enabled {
|
|
||||||
background-color: $secondaryContainer;
|
|
||||||
color: $onSecondaryContainer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-chat-providerswitcher {
|
.sidebar-chat-providerswitcher {
|
||||||
@include small-rounding;
|
@include small-rounding;
|
||||||
padding: 0.477rem 0.682rem;
|
padding: 0.477rem 0.682rem;
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ class GeminiService extends Service {
|
|||||||
try {
|
try {
|
||||||
const [bytes] = stream.read_line_finish(res);
|
const [bytes] = stream.read_line_finish(res);
|
||||||
const line = this._decoder.decode(bytes);
|
const line = this._decoder.decode(bytes);
|
||||||
console.log(line);
|
// console.log(line);
|
||||||
if (line == '[{') { // beginning of response
|
if (line == '[{') { // beginning of response
|
||||||
aiResponse._rawData += '{';
|
aiResponse._rawData += '{';
|
||||||
this.thinking = false;
|
this.thinking = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user