internal: sidebar: apis: cleaner tabs

This commit is contained in:
end-4 2024-03-23 23:37:25 +07:00
parent 59cb7c2b08
commit 842159da5a
9 changed files with 92 additions and 67 deletions

View file

@ -92,3 +92,71 @@ export const TabContainer = ({ icons, names, children, className = '', setup = (
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;
}

View file

@ -39,7 +39,6 @@ const CommandButton = (command) => Button({
export const booruTabIcon = Box({
hpack: 'center',
className: 'sidebar-chat-apiswitcher-icon',
homogeneous: true,
children: [
MaterialIcon('gallery_thumbnail', 'norm'),

View file

@ -15,7 +15,6 @@ import { chatEntry } from '../apiwidgets.js';
export const chatGPTTabIcon = Icon({
hpack: 'center',
className: 'sidebar-chat-apiswitcher-icon',
icon: `openai-symbolic`,
});

View file

@ -16,7 +16,6 @@ const MODEL_NAME = `Gemini`;
export const geminiTabIcon = Icon({
hpack: 'center',
className: 'sidebar-chat-apiswitcher-icon',
icon: `google-gemini-symbolic`,
})

View file

@ -39,8 +39,6 @@ const CommandButton = (command) => Button({
export const waifuTabIcon = Box({
hpack: 'center',
className: 'sidebar-chat-apiswitcher-icon',
homogeneous: true,
children: [
MaterialIcon('photo', 'norm'),
]

View file

@ -16,6 +16,7 @@ import { checkKeybind } from '../.widgetutils/keybind.js';
const TextView = Widget.subclass(Gtk.TextView, "AgsTextView");
import { widgetContent } from './sideleft.js';
import { IconTabContainer } from '../.commonwidgets/tabcontainer.js';
const EXPAND_INPUT_THRESHOLD = 30;
const APIS = [
@ -53,7 +54,6 @@ const APIS = [
},
];
let currentApiId = 0;
APIS[currentApiId].tabIcon.toggleClassName('sidebar-chat-apiswitcher-icon-enabled', true);
function apiSendMessage(textView) {
// 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({
transition: 'slide_up_down',
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) {
APIS[currentApiId].tabIcon.toggleClassName('sidebar-chat-apiswitcher-icon-enabled', false);
APIS[id].tabIcon.toggleClassName('sidebar-chat-apiswitcher-icon-enabled', true);
apiContentStack.shown = APIS[id].name;
apiContentStack.shown.value = id;
apiCommandStack.shown = APIS[id].name;
chatPlaceholder.label = APIS[id].placeholderText;
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({
attribute: {
'nextTab': () => switchToTab(Math.min(currentApiId + 1, APIS.length - 1)),
@ -233,7 +202,6 @@ const apiWidgets = Widget.Box({
className: 'spacing-v-10',
homogeneous: false,
children: [
apiSwitcher,
apiContentStack,
apiCommandStack,
textboxArea,

View file

@ -274,6 +274,20 @@ popover {
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 {
@include small-rounding;
}

View file

@ -492,26 +492,6 @@ $colorpicker_rounding: 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 {
@include small-rounding;
padding: 0.477rem 0.682rem;

View file

@ -202,7 +202,7 @@ class GeminiService extends Service {
try {
const [bytes] = stream.read_line_finish(res);
const line = this._decoder.decode(bytes);
console.log(line);
// console.log(line);
if (line == '[{') { // beginning of response
aiResponse._rawData += '{';
this.thinking = false;