diff --git a/src/equicordplugins/channelTabs/components/ChannelTabsContainer.tsx b/src/equicordplugins/channelTabs/components/ChannelTabsContainer.tsx index 3210785d1..7f6444a24 100644 --- a/src/equicordplugins/channelTabs/components/ChannelTabsContainer.tsx +++ b/src/equicordplugins/channelTabs/components/ChannelTabsContainer.tsx @@ -27,6 +27,7 @@ const cl = classNameFactory("vc-channeltabs-"); export default function ChannelsTabsContainer(props: BasicChannelTabsProps) { const [userId, setUserId] = useState(""); + const [tabsOverflow, setTabsOverflow] = useState(false); const { showBookmarkBar, widerTabsAndBookmarks, @@ -57,7 +58,8 @@ export default function ChannelsTabsContainer(props: BasicChannelTabsProps) { animationResizeHandle, animationQuestsActive, compactAutoExpandSelected, - compactAutoExpandOnHover + compactAutoExpandOnHover, + newTabButtonBehavior } = settings.use([ "showBookmarkBar", "widerTabsAndBookmarks", @@ -88,7 +90,8 @@ export default function ChannelsTabsContainer(props: BasicChannelTabsProps) { "animationResizeHandle", "animationQuestsActive", "compactAutoExpandSelected", - "compactAutoExpandOnHover" + "compactAutoExpandOnHover", + "newTabButtonBehavior" ]); const GhostTabs = useGhostTabs(); const isFullscreen = useStateFromStores([ChannelRTCStore], () => ChannelRTCStore.isFullscreenInContext() ?? false); @@ -100,6 +103,7 @@ export default function ChannelsTabsContainer(props: BasicChannelTabsProps) { }, [userId]); const ref = useRef(null); + const scrollerRef = useRef(null); useEffect(() => { setUpdaterFunction(update); @@ -128,6 +132,27 @@ export default function ChannelsTabsContainer(props: BasicChannelTabsProps) { useEffect(() => { _update(); }, [widerTabsAndBookmarks]); + useEffect(() => { + const scroller = scrollerRef.current; + if (!scroller) return; + + const checkOverflow = () => { + if (!newTabButtonBehavior) { + setTabsOverflow(true); + return; + } + const overflow = scroller.scrollWidth > scroller.clientWidth; + setTabsOverflow(overflow); + }; + + checkOverflow(); + + const observer = new ResizeObserver(checkOverflow); + observer.observe(scroller); + + return () => observer.disconnect(); + }, [openedTabs.length, newTabButtonBehavior]); + useEffect(() => { const matchesKeybind = (event: KeyboardEvent, keybindString: string): boolean => { const parts = keybindString.split("+"); @@ -295,7 +320,10 @@ export default function ChannelsTabsContainer(props: BasicChannelTabsProps) {
}
- + { scrollerRef.current = node; }} + className={cl("tab-scroller", newTabButtonBehavior && !tabsOverflow && "tab-scroller-following")} + > {openedTabs.filter(tab => tab != null).map((tab, i) => )} diff --git a/src/equicordplugins/channelTabs/style.css b/src/equicordplugins/channelTabs/style.css index f8eb43145..c5fef99d7 100644 --- a/src/equicordplugins/channelTabs/style.css +++ b/src/equicordplugins/channelTabs/style.css @@ -107,6 +107,11 @@ padding-top: 1px; } +.vc-channeltabs-tab-scroller-following { + width: fit-content; + flex: unset; +} + .vc-channeltabs-tab-scroller::-webkit-scrollbar { display: none; } diff --git a/src/equicordplugins/channelTabs/util/constants.tsx b/src/equicordplugins/channelTabs/util/constants.tsx index 90528df33..fdc7b40ae 100644 --- a/src/equicordplugins/channelTabs/util/constants.tsx +++ b/src/equicordplugins/channelTabs/util/constants.tsx @@ -420,6 +420,12 @@ export const settings = definePluginSettings({ default: false, restartNeeded: false }, + newTabButtonBehavior: { + type: OptionType.BOOLEAN, + description: "New tab (+) button follows tabs instead of staying pinned to the right", + default: true, + restartNeeded: false + }, oneTabPerServer: { type: OptionType.BOOLEAN, description: "Limit to one tab per server, so opening a new channel in that server will use the existing tab.",