diff --git a/.config/ags/modules/.commonwidgets/tabcontainer.js b/.config/ags/modules/.commonwidgets/tabcontainer.js index 706f7dec9..135875fb6 100644 --- a/.config/ags/modules/.commonwidgets/tabcontainer.js +++ b/.config/ags/modules/.commonwidgets/tabcontainer.js @@ -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; +} diff --git a/.config/ags/modules/sideleft/apis/booru.js b/.config/ags/modules/sideleft/apis/booru.js index b4612e24a..c00ec24c5 100644 --- a/.config/ags/modules/sideleft/apis/booru.js +++ b/.config/ags/modules/sideleft/apis/booru.js @@ -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'), diff --git a/.config/ags/modules/sideleft/apis/chatgpt.js b/.config/ags/modules/sideleft/apis/chatgpt.js index 37c27dabd..3c15983a9 100644 --- a/.config/ags/modules/sideleft/apis/chatgpt.js +++ b/.config/ags/modules/sideleft/apis/chatgpt.js @@ -15,7 +15,6 @@ import { chatEntry } from '../apiwidgets.js'; export const chatGPTTabIcon = Icon({ hpack: 'center', - className: 'sidebar-chat-apiswitcher-icon', icon: `openai-symbolic`, }); diff --git a/.config/ags/modules/sideleft/apis/gemini.js b/.config/ags/modules/sideleft/apis/gemini.js index 06a888dab..6c9c89d97 100644 --- a/.config/ags/modules/sideleft/apis/gemini.js +++ b/.config/ags/modules/sideleft/apis/gemini.js @@ -16,7 +16,6 @@ const MODEL_NAME = `Gemini`; export const geminiTabIcon = Icon({ hpack: 'center', - className: 'sidebar-chat-apiswitcher-icon', icon: `google-gemini-symbolic`, }) diff --git a/.config/ags/modules/sideleft/apis/waifu.js b/.config/ags/modules/sideleft/apis/waifu.js index 367b16dff..733b79559 100644 --- a/.config/ags/modules/sideleft/apis/waifu.js +++ b/.config/ags/modules/sideleft/apis/waifu.js @@ -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'), ] diff --git a/.config/ags/modules/sideleft/apiwidgets.js b/.config/ags/modules/sideleft/apiwidgets.js index e90d867b4..6595c32d3 100644 --- a/.config/ags/modules/sideleft/apiwidgets.js +++ b/.config/ags/modules/sideleft/apiwidgets.js @@ -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, diff --git a/.config/ags/scss/_common.scss b/.config/ags/scss/_common.scss index d84009eb6..435837e52 100644 --- a/.config/ags/scss/_common.scss +++ b/.config/ags/scss/_common.scss @@ -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; } diff --git a/.config/ags/scss/_sidebars.scss b/.config/ags/scss/_sidebars.scss index e92714fd5..f2b0cf608 100644 --- a/.config/ags/scss/_sidebars.scss +++ b/.config/ags/scss/_sidebars.scss @@ -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; diff --git a/.config/ags/services/gemini.js b/.config/ags/services/gemini.js index 4457749f0..3722d0eea 100644 --- a/.config/ags/services/gemini.js +++ b/.config/ags/services/gemini.js @@ -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;