import React, { createContext, useContext, useState, useRef, type ReactNode, } from "react"; import { useTranslation } from "react-i18next"; import type { TabContextTab } from "../../../types/index.js"; export type Tab = TabContextTab; interface TabContextType { tabs: Tab[]; currentTab: number | null; addTab: (tab: Omit) => number; removeTab: (tabId: number) => void; setCurrentTab: (tabId: number) => void; getTab: (tabId: number) => Tab | undefined; } const TabContext = createContext(undefined); export function useTabs() { const context = useContext(TabContext); if (context === undefined) { throw new Error("useTabs must be used within a TabProvider"); } return context; } interface TabProviderProps { children: ReactNode; } export function TabProvider({ children }: TabProviderProps) { const { t } = useTranslation(); const [tabs, setTabs] = useState([]); const [currentTab, setCurrentTab] = useState(null); const nextTabId = useRef(1); function computeUniqueTitle(desiredTitle: string | undefined): string { const baseTitle = (desiredTitle || "Terminal").trim(); const existingTitles = tabs.map((t) => t.title); if (!existingTitles.includes(baseTitle)) { return baseTitle; } let i = 2; while (existingTitles.includes(`${baseTitle} (${i})`)) { i++; } return `${baseTitle} (${i})`; } const addTab = (tabData: Omit): number => { const id = nextTabId.current++; const newTab: Tab = { ...tabData, id, title: computeUniqueTitle(tabData.title), terminalRef: React.createRef(), }; setTabs((prev) => [...prev, newTab]); setCurrentTab(id); return id; }; const removeTab = (tabId: number) => { const tab = tabs.find((t) => t.id === tabId); if ( tab && tab.terminalRef?.current && typeof tab.terminalRef.current.disconnect === "function" ) { tab.terminalRef.current.disconnect(); } setTabs((prev) => { const newTabs = prev.filter((tab) => tab.id !== tabId); if (currentTab === tabId) { setCurrentTab( newTabs.length > 0 ? newTabs[newTabs.length - 1].id : null, ); } return newTabs; }); }; const getTab = (tabId: number) => { return tabs.find((tab) => tab.id === tabId); }; const value: TabContextType = { tabs, currentTab, addTab, removeTab, setCurrentTab, getTab, }; return {children}; }