diff --git a/src/equicordplugins/channelTabs/components/ChannelTabsContainer.tsx b/src/equicordplugins/channelTabs/components/ChannelTabsContainer.tsx
index 20ad46e5..8ee35fc3 100644
--- a/src/equicordplugins/channelTabs/components/ChannelTabsContainer.tsx
+++ b/src/equicordplugins/channelTabs/components/ChannelTabsContainer.tsx
@@ -52,16 +52,25 @@ export default function ChannelsTabsContainer(props: BasicChannelTabsProps) {
}, []);
useEffect(() => {
- (Vencord.Plugins.plugins.ChannelTabs as any).containerHeight = ref.current?.clientHeight;
+ if (ref.current) {
+ try {
+ (Vencord.Plugins.plugins.ChannelTabs as any).containerHeight = ref.current.clientHeight;
+ } catch { }
+ }
}, [userId, showBookmarkBar]);
useEffect(() => {
_update();
}, [widerTabsAndBookmarks]);
+ useEffect(() => {
+ if (userId) {
+ handleChannelSwitch(props);
+ saveTabs(userId);
+ }
+ }, [userId, props.channelId, props.guildId]);
+
if (!userId) return null;
- handleChannelSwitch(props);
- saveTabs(userId);
return (
>
);
-}
+}
\ No newline at end of file
diff --git a/src/equicordplugins/channelTabs/index.tsx b/src/equicordplugins/channelTabs/index.tsx
index 6c5aaf10..f0cc1b4f 100644
--- a/src/equicordplugins/channelTabs/index.tsx
+++ b/src/equicordplugins/channelTabs/index.tsx
@@ -15,7 +15,7 @@ import { Channel, Message } from "discord-types/general";
import { JSX } from "react";
import ChannelsTabsContainer from "./components/ChannelTabsContainer";
-import { BasicChannelTabsProps, createTab, settings } from "./util";
+import { BasicChannelTabsProps, createTab, handleChannelSwitch, settings } from "./util";
import * as ChannelTabsUtils from "./util";
const contextMenuPatch: NavContextMenuPatchCallback = (children, props: { channel: Channel, messageId?: string; }) =>
@@ -52,6 +52,14 @@ export default definePlugin({
replace: "$1$4$self.render,{currentChannel:$2,children:$3})$5"
}
},
+ // intercept channel navigation to switch/create tabs
+ {
+ find: "transitionToGuild",
+ replacement: {
+ match: /transitionToGuild\(([^,]+),([^)]+)\)/,
+ replace: "$&;$self.handleNavigation($1,$2)"
+ }
+ },
// ctrl click to open in new tab in inbox unread
{
find: ".messageContainer,onKeyDown",
@@ -113,5 +121,14 @@ export default definePlugin({
createTab(tab, false, message.id);
},
+ handleNavigation(guildId: string, channelId: string) {
+ if (!guildId || !channelId) return;
+
+ // wait for discord to update channel data
+ requestAnimationFrame(() => {
+ handleChannelSwitch({ guildId, channelId });
+ });
+ },
+
util: ChannelTabsUtils,
-});
+});
\ No newline at end of file
diff --git a/src/equicordplugins/channelTabs/style.css b/src/equicordplugins/channelTabs/style.css
index 2d4f187a..b99f4c2e 100644
--- a/src/equicordplugins/channelTabs/style.css
+++ b/src/equicordplugins/channelTabs/style.css
@@ -145,6 +145,9 @@
width: 12rem;
min-width: 0;
margin-right: 0.25rem;
+ background-color: var(--background-primary);
+ border: 1px solid var(--background-modifier-accent);
+ transition: background-color 0.15s ease;
}
.vc-channeltabs-tab.vc-channeltabs-wider:not(.vc-channeltabs-tab-compact) {
@@ -159,6 +162,7 @@
.vc-channeltabs-tab-selected {
background: var(--bg-overlay-selected);
background-color: var(--background-modifier-selected);
+ border-color: var(--brand-500);
}
/* channel type container */
diff --git a/src/equicordplugins/channelTabs/util/constants.tsx b/src/equicordplugins/channelTabs/util/constants.tsx
index 04e2b078..7d72f16c 100644
--- a/src/equicordplugins/channelTabs/util/constants.tsx
+++ b/src/equicordplugins/channelTabs/util/constants.tsx
@@ -71,7 +71,32 @@ export const settings = definePluginSettings({
type: OptionType.BOOLEAN,
default: false,
restartNeeded: false
+ },
+ switchToExistingTab: {
+ type: OptionType.BOOLEAN,
+ description: "Switch to tab if it already exists for the channel you're navigating to",
+ default: false,
+ restartNeeded: false
+ },
+ createNewTabIfNotExists: {
+ type: OptionType.BOOLEAN,
+ description: "Create a new tab if one doesn't exist for the channel you're navigating to",
+ default: false,
+ restartNeeded: false
+ },
+ enableRapidNavigation: {
+ type: OptionType.BOOLEAN,
+ description: "Enable rapid navigation behavior - quickly navigating between channels will replace the current tab instead of creating new ones",
+ default: false,
+ restartNeeded: false
+ },
+ rapidNavigationThreshold: {
+ type: OptionType.SLIDER,
+ description: "Time window (in milliseconds) for rapid navigation. Within this time, new channels replace the current tab instead of creating new ones.",
+ markers: [500, 1000, 1500, 2000, 3000, 5000, 10000],
+ default: 3000,
+ stickToMarkers: false,
}
});
-export const CircleQuestionIcon = findComponentByCodeLazy("10.58l-3.3-3.3a1");
+export const CircleQuestionIcon = findComponentByCodeLazy("10.58l-3.3-3.3a1");
\ No newline at end of file
diff --git a/src/equicordplugins/channelTabs/util/tabs.tsx b/src/equicordplugins/channelTabs/util/tabs.tsx
index 3deb257f..74773495 100644
--- a/src/equicordplugins/channelTabs/util/tabs.tsx
+++ b/src/equicordplugins/channelTabs/util/tabs.tsx
@@ -128,11 +128,46 @@ export function closeTabsToTheLeft(id: number) {
else update();
}
+let lastNavigationTime = 0;
+
export function handleChannelSwitch(ch: BasicChannelTabsProps) {
const tab = openTabs.find(c => c.id === currentlyOpenTab);
- if (tab === undefined) return logger.error("Couldn't find the currently open channel " + currentlyOpenTab, openTabs);
+ const existingTab = openTabs.find(tab => tab.channelId === ch.channelId && tab.guildId === ch.guildId);
- if (tab.channelId !== ch.channelId) openTabs[openTabs.indexOf(tab)] = { id: tab.id, compact: tab.compact, ...ch };
+ // First check: switch to existing tab if setting enabled and tab exists
+ if (settings.store.switchToExistingTab && existingTab) {
+ moveToTab(existingTab.id);
+ return;
+ }
+
+ // Second check: create new tab if setting enabled
+ if (settings.store.createNewTabIfNotExists) {
+ // Apply rapid navigation logic when creating new tabs
+ const now = Date.now();
+ const isRapidNavigation = now - lastNavigationTime < settings.store.rapidNavigationThreshold;
+ lastNavigationTime = now;
+
+ if (isRapidNavigation && settings.store.enableRapidNavigation) {
+ // Replace current tab content instead of creating new one
+ const currentTab = openTabs.find(t => t.id === currentlyOpenTab);
+ if (currentTab) {
+ currentTab.channelId = ch.channelId;
+ currentTab.guildId = ch.guildId;
+ update();
+ return;
+ }
+ }
+
+ // Create new tab (normal behavior)
+ createTab(ch, true);
+ return;
+ }
+
+ // Default behavior: replace current tab content
+ if (tab && tab.channelId !== ch.channelId) {
+ openTabs[openTabs.indexOf(tab)] = { id: tab.id, compact: tab.compact, ...ch };
+ update();
+ }
}
export function hasClosedTabs() {
@@ -271,4 +306,4 @@ export function useGhostTabs() {
setCount(0);
};
return new Array
(count).fill();
-}
+}
\ No newline at end of file