swadhinbiswas Initial release v0.1.0 · 1/16/2026
ed7a4e4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
export type TabType = 'catalog' | 'thread';
export interface Tab {
id: string;
type: TabType;
title: string;
board?: string;
threadId?: number;
hasNewReplies?: boolean;
}
interface TabState {
tabs: Tab[];
activeTabId: string | null;
// Actions
openTab: (tab: Omit<Tab, 'id'>) => string;
closeTab: (id: string) => void;
setActiveTab: (id: string) => void;
reorderTabs: (fromIndex: number, toIndex: number) => void;
updateTab: (id: string, updates: Partial<Tab>) => void;
closeAllTabs: () => void;
closeOtherTabs: (id: string) => void;
}
export const useTabStore = create<TabState>()(
persist(
(set, get) => ({
tabs: [],
activeTabId: null,
openTab: (tabData) => {
const id = `tab-${Date.now()}-${Math.random()}`;
const newTab: Tab = { id, ...tabData };
set((state) => ({
tabs: [...state.tabs, newTab],
activeTabId: id,
}));
return id;
},
closeTab: (id) => {
set((state) => {
const newTabs = state.tabs.filter((tab) => tab.id !== id);
let newActiveTabId = state.activeTabId;
// If closing the active tab, switch to the last tab
if (state.activeTabId === id) {
newActiveTabId = newTabs.length > 0 ? newTabs[newTabs.length - 1].id : null;
}
return {
tabs: newTabs,
activeTabId: newActiveTabId,
};
});
},
setActiveTab: (id) => {
set({ activeTabId: id });
},
reorderTabs: (fromIndex, toIndex) => {
set((state) => {
const newTabs = [...state.tabs];
const [movedTab] = newTabs.splice(fromIndex, 1);
newTabs.splice(toIndex, 0, movedTab);
return { tabs: newTabs };
});
},
updateTab: (id, updates) => {
set((state) => ({
tabs: state.tabs.map((tab) =>
tab.id === id ? { ...tab, ...updates } : tab
),
}));
},
closeAllTabs: () => {
set({ tabs: [], activeTabId: null });
},
closeOtherTabs: (id) => {
set((state) => ({
tabs: state.tabs.filter((tab) => tab.id === id),
activeTabId: id,
}));
},
}),
{
name: 'tab-storage',
partialize: (state) => ({
tabs: state.tabs,
activeTabId: state.activeTabId,
}),
}
)
);