refactor(tabs): remove close-folder-tabs and reveal-in-sidebar menu items
This commit is contained in:
@@ -114,7 +114,6 @@ const FolderHeader = memo(function FolderHeader({
|
|||||||
onFocus,
|
onFocus,
|
||||||
onCloseFolderTabs,
|
onCloseFolderTabs,
|
||||||
onRemoveFromWorkspace,
|
onRemoveFromWorkspace,
|
||||||
highlighted,
|
|
||||||
t,
|
t,
|
||||||
}: {
|
}: {
|
||||||
folderId: number
|
folderId: number
|
||||||
@@ -126,7 +125,6 @@ const FolderHeader = memo(function FolderHeader({
|
|||||||
onFocus: (folderId: number) => void
|
onFocus: (folderId: number) => void
|
||||||
onCloseFolderTabs: (folderId: number) => void
|
onCloseFolderTabs: (folderId: number) => void
|
||||||
onRemoveFromWorkspace: (folderId: number) => void
|
onRemoveFromWorkspace: (folderId: number) => void
|
||||||
highlighted: boolean
|
|
||||||
t: ReturnType<typeof useTranslations>
|
t: ReturnType<typeof useTranslations>
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
@@ -140,8 +138,7 @@ const FolderHeader = memo(function FolderHeader({
|
|||||||
"flex h-[1.9375rem] w-full items-center gap-[0.5rem] cursor-pointer outline-none",
|
"flex h-[1.9375rem] w-full items-center gap-[0.5rem] cursor-pointer outline-none",
|
||||||
"rounded-[0.4375rem] px-2",
|
"rounded-[0.4375rem] px-2",
|
||||||
"text-sidebar-foreground hover:bg-[color-mix(in_oklab,var(--sidebar-accent),var(--sidebar-foreground)_2%)]",
|
"text-sidebar-foreground hover:bg-[color-mix(in_oklab,var(--sidebar-accent),var(--sidebar-foreground)_2%)]",
|
||||||
"transition-[background-color,color] duration-150",
|
"transition-[background-color,color] duration-150"
|
||||||
highlighted && "ring-2 ring-sidebar-primary ring-offset-1"
|
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
@@ -200,7 +197,6 @@ export interface SidebarConversationListHandle {
|
|||||||
scrollToActive: () => void
|
scrollToActive: () => void
|
||||||
expandAll: () => void
|
expandAll: () => void
|
||||||
collapseAll: () => void
|
collapseAll: () => void
|
||||||
revealFolder: (folderId: number) => void
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SidebarConversationListProps {
|
export interface SidebarConversationListProps {
|
||||||
@@ -266,9 +262,6 @@ export function SidebarConversationList({
|
|||||||
const [folderExpanded, setFolderExpanded] = useState<Record<number, boolean>>(
|
const [folderExpanded, setFolderExpanded] = useState<Record<number, boolean>>(
|
||||||
{}
|
{}
|
||||||
)
|
)
|
||||||
const [highlightedFolder, setHighlightedFolder] = useState<number | null>(
|
|
||||||
null
|
|
||||||
)
|
|
||||||
const [scrollOffset, setScrollOffset] = useState(0)
|
const [scrollOffset, setScrollOffset] = useState(0)
|
||||||
const [removeConfirm, setRemoveConfirm] = useState<{
|
const [removeConfirm, setRemoveConfirm] = useState<{
|
||||||
folderId: number
|
folderId: number
|
||||||
@@ -284,7 +277,6 @@ export function SidebarConversationList({
|
|||||||
const scrollToActiveRef = useRef<() => void>(() => {})
|
const scrollToActiveRef = useRef<() => void>(() => {})
|
||||||
const pendingScrollRef = useRef(false)
|
const pendingScrollRef = useRef(false)
|
||||||
const virtualizerRef = useRef<VirtualizerHandle>(null)
|
const virtualizerRef = useRef<VirtualizerHandle>(null)
|
||||||
const highlightTimerRef = useRef<number | null>(null)
|
|
||||||
|
|
||||||
const filteredConversations = useMemo(() => {
|
const filteredConversations = useMemo(() => {
|
||||||
if (showCompleted) return conversations
|
if (showCompleted) return conversations
|
||||||
@@ -403,43 +395,8 @@ export function SidebarConversationList({
|
|||||||
return next
|
return next
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
revealFolder(folderId: number) {
|
|
||||||
setFolderExpanded((prev) => {
|
|
||||||
if (prev[folderId] === true) return prev
|
|
||||||
const next = { ...prev, [folderId]: true }
|
|
||||||
saveFolderExpanded(next)
|
|
||||||
return next
|
|
||||||
})
|
|
||||||
setHighlightedFolder(folderId)
|
|
||||||
if (highlightTimerRef.current) {
|
|
||||||
window.clearTimeout(highlightTimerRef.current)
|
|
||||||
}
|
|
||||||
highlightTimerRef.current = window.setTimeout(() => {
|
|
||||||
setHighlightedFolder(null)
|
|
||||||
highlightTimerRef.current = null
|
|
||||||
}, 1200)
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
const idx = flatItems.findIndex(
|
|
||||||
(item) => item.type === "folder_header" && item.folderId === folderId
|
|
||||||
)
|
|
||||||
if (idx >= 0) {
|
|
||||||
virtualizerRef.current?.scrollToIndex(idx, {
|
|
||||||
align: "start",
|
|
||||||
smooth: true,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
}))
|
}))
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
return () => {
|
|
||||||
if (highlightTimerRef.current) {
|
|
||||||
window.clearTimeout(highlightTimerRef.current)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
scrollToActiveRef.current = () => {
|
scrollToActiveRef.current = () => {
|
||||||
if (!selectedConversation) return
|
if (!selectedConversation) return
|
||||||
@@ -728,9 +685,6 @@ export function SidebarConversationList({
|
|||||||
onFocus={focusFolder}
|
onFocus={focusFolder}
|
||||||
onCloseFolderTabs={handleCloseFolderTabs}
|
onCloseFolderTabs={handleCloseFolderTabs}
|
||||||
onRemoveFromWorkspace={handleRemoveFolder}
|
onRemoveFromWorkspace={handleRemoveFolder}
|
||||||
highlighted={
|
|
||||||
highlightedFolder === stickyFolderItem.folderId
|
|
||||||
}
|
|
||||||
t={t}
|
t={t}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -761,7 +715,6 @@ export function SidebarConversationList({
|
|||||||
onFocus={focusFolder}
|
onFocus={focusFolder}
|
||||||
onCloseFolderTabs={handleCloseFolderTabs}
|
onCloseFolderTabs={handleCloseFolderTabs}
|
||||||
onRemoveFromWorkspace={handleRemoveFolder}
|
onRemoveFromWorkspace={handleRemoveFolder}
|
||||||
highlighted={highlightedFolder === item.folderId}
|
|
||||||
t={t}
|
t={t}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -71,18 +71,6 @@ export function Sidebar() {
|
|||||||
}
|
}
|
||||||
}, [allExpanded])
|
}, [allExpanded])
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const onReveal = (e: Event) => {
|
|
||||||
const detail = (e as CustomEvent<{ folderId: number }>).detail
|
|
||||||
if (!detail) return
|
|
||||||
listRef.current?.revealFolder(detail.folderId)
|
|
||||||
}
|
|
||||||
window.addEventListener("sidebar:reveal-folder", onReveal)
|
|
||||||
return () => {
|
|
||||||
window.removeEventListener("sidebar:reveal-folder", onReveal)
|
|
||||||
}
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
if (!isOpen) return null
|
if (!isOpen) return null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ export function TabBar() {
|
|||||||
closeTab,
|
closeTab,
|
||||||
closeOtherTabs,
|
closeOtherTabs,
|
||||||
closeAllTabs,
|
closeAllTabs,
|
||||||
closeTabsByFolder,
|
|
||||||
pinTab,
|
pinTab,
|
||||||
toggleTileMode,
|
toggleTileMode,
|
||||||
reorderTabs,
|
reorderTabs,
|
||||||
@@ -33,11 +32,6 @@ export function TabBar() {
|
|||||||
return map
|
return map
|
||||||
}, [allFolders])
|
}, [allFolders])
|
||||||
|
|
||||||
const handleRevealInSidebar = useCallback((folderId: number) => {
|
|
||||||
window.dispatchEvent(
|
|
||||||
new CustomEvent("sidebar:reveal-folder", { detail: { folderId } })
|
|
||||||
)
|
|
||||||
}, [])
|
|
||||||
const { shortcuts } = useShortcutSettings()
|
const { shortcuts } = useShortcutSettings()
|
||||||
const scrollRef = useRef<HTMLDivElement>(null)
|
const scrollRef = useRef<HTMLDivElement>(null)
|
||||||
const [isHovered, setIsHovered] = useState(false)
|
const [isHovered, setIsHovered] = useState(false)
|
||||||
@@ -115,8 +109,6 @@ export function TabBar() {
|
|||||||
onClose={closeTab}
|
onClose={closeTab}
|
||||||
onCloseOthers={closeOtherTabs}
|
onCloseOthers={closeOtherTabs}
|
||||||
onCloseAll={closeAllTabs}
|
onCloseAll={closeAllTabs}
|
||||||
onCloseFolderTabs={closeTabsByFolder}
|
|
||||||
onRevealInSidebar={handleRevealInSidebar}
|
|
||||||
onPin={pinTab}
|
onPin={pinTab}
|
||||||
onToggleTile={toggleTileMode}
|
onToggleTile={toggleTileMode}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -26,8 +26,6 @@ interface TabItemProps {
|
|||||||
onClose: (tabId: string) => void
|
onClose: (tabId: string) => void
|
||||||
onCloseOthers: (tabId: string) => void
|
onCloseOthers: (tabId: string) => void
|
||||||
onCloseAll: () => void
|
onCloseAll: () => void
|
||||||
onCloseFolderTabs: (folderId: number) => void
|
|
||||||
onRevealInSidebar: (folderId: number) => void
|
|
||||||
onPin: (tabId: string) => void
|
onPin: (tabId: string) => void
|
||||||
onToggleTile: () => void
|
onToggleTile: () => void
|
||||||
}
|
}
|
||||||
@@ -42,8 +40,6 @@ export const TabItem = memo(function TabItem({
|
|||||||
onClose,
|
onClose,
|
||||||
onCloseOthers,
|
onCloseOthers,
|
||||||
onCloseAll,
|
onCloseAll,
|
||||||
onCloseFolderTabs,
|
|
||||||
onRevealInSidebar,
|
|
||||||
onPin,
|
onPin,
|
||||||
onToggleTile,
|
onToggleTile,
|
||||||
}: TabItemProps) {
|
}: TabItemProps) {
|
||||||
@@ -56,14 +52,6 @@ export const TabItem = memo(function TabItem({
|
|||||||
? `${resolvedFolderName} · ${folderBranch} — ${tab.title}`
|
? `${resolvedFolderName} · ${folderBranch} — ${tab.title}`
|
||||||
: `${resolvedFolderName} — ${tab.title}`
|
: `${resolvedFolderName} — ${tab.title}`
|
||||||
|
|
||||||
const handleCloseFolderTabs = useCallback(() => {
|
|
||||||
onCloseFolderTabs(tab.folderId)
|
|
||||||
}, [onCloseFolderTabs, tab.folderId])
|
|
||||||
|
|
||||||
const handleRevealInSidebar = useCallback(() => {
|
|
||||||
onRevealInSidebar(tab.folderId)
|
|
||||||
}, [onRevealInSidebar, tab.folderId])
|
|
||||||
|
|
||||||
const clearResidualStyles = useCallback(() => {
|
const clearResidualStyles = useCallback(() => {
|
||||||
const el = itemRef.current
|
const el = itemRef.current
|
||||||
if (!el) return
|
if (!el) return
|
||||||
@@ -167,13 +155,7 @@ export const TabItem = memo(function TabItem({
|
|||||||
<ContextMenuItem onSelect={handleCloseOthers}>
|
<ContextMenuItem onSelect={handleCloseOthers}>
|
||||||
{t("closeOthers")}
|
{t("closeOthers")}
|
||||||
</ContextMenuItem>
|
</ContextMenuItem>
|
||||||
<ContextMenuItem onSelect={handleCloseFolderTabs}>
|
|
||||||
{t("closeFolderTabs", { folder: resolvedFolderName })}
|
|
||||||
</ContextMenuItem>
|
|
||||||
<ContextMenuSeparator />
|
<ContextMenuSeparator />
|
||||||
<ContextMenuItem onSelect={handleRevealInSidebar}>
|
|
||||||
{t("revealInSidebar")}
|
|
||||||
</ContextMenuItem>
|
|
||||||
<ContextMenuItem onSelect={onToggleTile}>
|
<ContextMenuItem onSelect={onToggleTile}>
|
||||||
{isTileMode ? t("untileDisplay") : t("tileDisplay")}
|
{isTileMode ? t("untileDisplay") : t("tileDisplay")}
|
||||||
</ContextMenuItem>
|
</ContextMenuItem>
|
||||||
|
|||||||
@@ -981,9 +981,7 @@
|
|||||||
"closeOthers": "إغلاق البقية",
|
"closeOthers": "إغلاق البقية",
|
||||||
"closeAll": "إغلاق الكل",
|
"closeAll": "إغلاق الكل",
|
||||||
"tileDisplay": "عرض متجانب",
|
"tileDisplay": "عرض متجانب",
|
||||||
"untileDisplay": "إلغاء التجانب",
|
"untileDisplay": "إلغاء التجانب"
|
||||||
"closeFolderTabs": "إغلاق جميع علامات التبويب لـ {folder}",
|
|
||||||
"revealInSidebar": "إظهار في الشريط الجانبي"
|
|
||||||
},
|
},
|
||||||
"fileWorkspace": {
|
"fileWorkspace": {
|
||||||
"files": "الملفات",
|
"files": "الملفات",
|
||||||
|
|||||||
@@ -981,9 +981,7 @@
|
|||||||
"closeOthers": "Andere schließen",
|
"closeOthers": "Andere schließen",
|
||||||
"closeAll": "Alle schließen",
|
"closeAll": "Alle schließen",
|
||||||
"tileDisplay": "Kachelansicht",
|
"tileDisplay": "Kachelansicht",
|
||||||
"untileDisplay": "Kachel beenden",
|
"untileDisplay": "Kachel beenden"
|
||||||
"closeFolderTabs": "Alle Tabs von {folder} schließen",
|
|
||||||
"revealInSidebar": "In Seitenleiste anzeigen"
|
|
||||||
},
|
},
|
||||||
"fileWorkspace": {
|
"fileWorkspace": {
|
||||||
"files": "Dateien",
|
"files": "Dateien",
|
||||||
|
|||||||
@@ -981,9 +981,7 @@
|
|||||||
"closeOthers": "Close Others",
|
"closeOthers": "Close Others",
|
||||||
"closeAll": "Close All",
|
"closeAll": "Close All",
|
||||||
"tileDisplay": "Tile Display",
|
"tileDisplay": "Tile Display",
|
||||||
"untileDisplay": "Exit Tile",
|
"untileDisplay": "Exit Tile"
|
||||||
"closeFolderTabs": "Close all tabs of {folder}",
|
|
||||||
"revealInSidebar": "Reveal in sidebar"
|
|
||||||
},
|
},
|
||||||
"fileWorkspace": {
|
"fileWorkspace": {
|
||||||
"files": "Files",
|
"files": "Files",
|
||||||
|
|||||||
@@ -981,9 +981,7 @@
|
|||||||
"closeOthers": "Cerrar otros",
|
"closeOthers": "Cerrar otros",
|
||||||
"closeAll": "Cerrar todo",
|
"closeAll": "Cerrar todo",
|
||||||
"tileDisplay": "Vista en mosaico",
|
"tileDisplay": "Vista en mosaico",
|
||||||
"untileDisplay": "Salir de mosaico",
|
"untileDisplay": "Salir de mosaico"
|
||||||
"closeFolderTabs": "Cerrar todas las pestañas de {folder}",
|
|
||||||
"revealInSidebar": "Mostrar en la barra lateral"
|
|
||||||
},
|
},
|
||||||
"fileWorkspace": {
|
"fileWorkspace": {
|
||||||
"files": "Archivos",
|
"files": "Archivos",
|
||||||
|
|||||||
@@ -981,9 +981,7 @@
|
|||||||
"closeOthers": "Fermer les autres",
|
"closeOthers": "Fermer les autres",
|
||||||
"closeAll": "Tout fermer",
|
"closeAll": "Tout fermer",
|
||||||
"tileDisplay": "Affichage en mosaïque",
|
"tileDisplay": "Affichage en mosaïque",
|
||||||
"untileDisplay": "Quitter la mosaïque",
|
"untileDisplay": "Quitter la mosaïque"
|
||||||
"closeFolderTabs": "Fermer tous les onglets de {folder}",
|
|
||||||
"revealInSidebar": "Afficher dans la barre latérale"
|
|
||||||
},
|
},
|
||||||
"fileWorkspace": {
|
"fileWorkspace": {
|
||||||
"files": "Fichiers",
|
"files": "Fichiers",
|
||||||
|
|||||||
@@ -981,9 +981,7 @@
|
|||||||
"closeOthers": "他を閉じる",
|
"closeOthers": "他を閉じる",
|
||||||
"closeAll": "すべて閉じる",
|
"closeAll": "すべて閉じる",
|
||||||
"tileDisplay": "タイル表示",
|
"tileDisplay": "タイル表示",
|
||||||
"untileDisplay": "タイル解除",
|
"untileDisplay": "タイル解除"
|
||||||
"closeFolderTabs": "{folder} のすべてのタブを閉じる",
|
|
||||||
"revealInSidebar": "サイドバーで表示"
|
|
||||||
},
|
},
|
||||||
"fileWorkspace": {
|
"fileWorkspace": {
|
||||||
"files": "ファイル",
|
"files": "ファイル",
|
||||||
|
|||||||
@@ -981,9 +981,7 @@
|
|||||||
"closeOthers": "다른 항목 닫기",
|
"closeOthers": "다른 항목 닫기",
|
||||||
"closeAll": "모두 닫기",
|
"closeAll": "모두 닫기",
|
||||||
"tileDisplay": "타일 표시",
|
"tileDisplay": "타일 표시",
|
||||||
"untileDisplay": "타일 해제",
|
"untileDisplay": "타일 해제"
|
||||||
"closeFolderTabs": "{folder}의 모든 탭 닫기",
|
|
||||||
"revealInSidebar": "사이드바에서 표시"
|
|
||||||
},
|
},
|
||||||
"fileWorkspace": {
|
"fileWorkspace": {
|
||||||
"files": "파일",
|
"files": "파일",
|
||||||
|
|||||||
@@ -981,9 +981,7 @@
|
|||||||
"closeOthers": "Fechar outros",
|
"closeOthers": "Fechar outros",
|
||||||
"closeAll": "Fechar tudo",
|
"closeAll": "Fechar tudo",
|
||||||
"tileDisplay": "Exibição em mosaico",
|
"tileDisplay": "Exibição em mosaico",
|
||||||
"untileDisplay": "Sair do mosaico",
|
"untileDisplay": "Sair do mosaico"
|
||||||
"closeFolderTabs": "Fechar todas as abas de {folder}",
|
|
||||||
"revealInSidebar": "Mostrar na barra lateral"
|
|
||||||
},
|
},
|
||||||
"fileWorkspace": {
|
"fileWorkspace": {
|
||||||
"files": "Arquivos",
|
"files": "Arquivos",
|
||||||
|
|||||||
@@ -981,9 +981,7 @@
|
|||||||
"closeOthers": "关闭其它",
|
"closeOthers": "关闭其它",
|
||||||
"closeAll": "关闭所有",
|
"closeAll": "关闭所有",
|
||||||
"tileDisplay": "平铺显示",
|
"tileDisplay": "平铺显示",
|
||||||
"untileDisplay": "取消平铺",
|
"untileDisplay": "取消平铺"
|
||||||
"closeFolderTabs": "关闭 {folder} 的所有标签",
|
|
||||||
"revealInSidebar": "在侧边栏中定位"
|
|
||||||
},
|
},
|
||||||
"fileWorkspace": {
|
"fileWorkspace": {
|
||||||
"files": "文件",
|
"files": "文件",
|
||||||
|
|||||||
@@ -981,9 +981,7 @@
|
|||||||
"closeOthers": "關閉其它",
|
"closeOthers": "關閉其它",
|
||||||
"closeAll": "關閉所有",
|
"closeAll": "關閉所有",
|
||||||
"tileDisplay": "平鋪顯示",
|
"tileDisplay": "平鋪顯示",
|
||||||
"untileDisplay": "取消平鋪",
|
"untileDisplay": "取消平鋪"
|
||||||
"closeFolderTabs": "關閉 {folder} 的所有標籤",
|
|
||||||
"revealInSidebar": "在側邊欄中定位"
|
|
||||||
},
|
},
|
||||||
"fileWorkspace": {
|
"fileWorkspace": {
|
||||||
"files": "檔案",
|
"files": "檔案",
|
||||||
|
|||||||
Reference in New Issue
Block a user