closed-tabs.ts 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940
  1. import type { SessionTab, Tab } from "./tabs"
  2. export type ClosedTab = {
  3. tab: SessionTab
  4. index: number
  5. }
  6. const CLOSED_TAB_LIMIT = 25
  7. // Only session tabs are recorded; closing a draft tab deletes its persisted
  8. // state, so a reopened draft would come back empty anyway.
  9. export function pushClosedTab(stack: ClosedTab[], tab: Tab, index: number): ClosedTab[] {
  10. if (tab.type !== "session") return stack
  11. return [...stack, { tab: { ...tab }, index }].slice(-CLOSED_TAB_LIMIT)
  12. }
  13. // Pops the most recently closed tab that is not open again,
  14. // discarding stale entries along the way.
  15. export function takeClosedTab(stack: ClosedTab[], tabs: Tab[]): { entry?: ClosedTab; stack: ClosedTab[] } {
  16. const remaining = [...stack]
  17. while (remaining.length) {
  18. const entry = remaining.pop()
  19. if (entry && !isOpen(tabs, entry.tab)) return { entry, stack: remaining }
  20. }
  21. return { stack: remaining }
  22. }
  23. export function removeClosedTabs(stack: ClosedTab[], server: SessionTab["server"], sessionIDs: string[]) {
  24. const removed = new Set(sessionIDs)
  25. return stack.filter((entry) => entry.tab.server !== server || !removed.has(entry.tab.sessionId))
  26. }
  27. export function nextTabAfterClose(tabs: Tab[], index: number, active: boolean) {
  28. if (!active) return undefined
  29. return tabs[index + 1] ?? tabs[index - 1] ?? null
  30. }
  31. function isOpen(tabs: Tab[], tab: SessionTab) {
  32. return tabs.some((item) => item.type === "session" && item.server === tab.server && item.sessionId === tab.sessionId)
  33. }