fix(sidebar): show loading state during batch export

Export button shows 'Exporting N sessions…' text and becomes disabled
while fetching blobs and building the zip. An info toast also fires
immediately so the user knows work is in progress.
This commit is contained in:
你的姓名 2026-06-19 19:42:10 +08:00
parent a6a2f6612a
commit 06156b445f
6 changed files with 12 additions and 2 deletions

View File

@ -103,6 +103,7 @@ export function Sidebar({ isMobile = false, onRequestClose }: SidebarProps) {
const [pendingDeleteSessionId, setPendingDeleteSessionId] = useState<string | null>(null)
const [pendingBatchDeleteSessionIds, setPendingBatchDeleteSessionIds] = useState<string[] | null>(null)
const [isBatchDeleting, setIsBatchDeleting] = useState(false)
const [isBatchExporting, setIsBatchExporting] = useState(false)
const [pendingClearProjectKey, setPendingClearProjectKey] = useState<string | null>(null)
const [isClearingProject, setIsClearingProject] = useState(false)
const [renamingId, setRenamingId] = useState<string | null>(null)
@ -642,6 +643,8 @@ export function Sidebar({ isMobile = false, onRequestClose }: SidebarProps) {
}
// Multiple sessions: collect blobs, pack into zip
setIsBatchExporting(true)
addToast({ type: 'info', message: t('sidebar.batchExporting', { count: ids.length }) })
try {
const { zipSync } = await import('fflate')
const entries: Record<string, Uint8Array> = {}
@ -687,6 +690,8 @@ export function Sidebar({ isMobile = false, onRequestClose }: SidebarProps) {
error: error instanceof Error ? error.message : String(error),
}),
})
} finally {
setIsBatchExporting(false)
}
}, [addToast, handleExitBatchMode, handleExportSession, selectedSessionIds, sessions, t])
@ -999,10 +1004,10 @@ export function Sidebar({ isMobile = false, onRequestClose }: SidebarProps) {
<button
type="button"
onClick={() => void handleBatchExport()}
disabled={selectedCount === 0}
disabled={selectedCount === 0 || isBatchExporting}
className="rounded-md border border-[var(--color-border)] px-2 py-1.5 text-xs font-medium text-[var(--color-text-secondary)] transition-colors hover:bg-[var(--color-surface-hover)] disabled:opacity-50"
>
{t('sidebar.batchExportSelected', { count: selectedCount })}
{isBatchExporting ? t('sidebar.batchExporting', { count: selectedCount }) : t('sidebar.batchExportSelected', { count: selectedCount })}
</button>
<button
type="button"

View File

@ -93,6 +93,7 @@ export const en = {
'sidebar.batchSelectGroup': 'Select {group}',
'sidebar.batchDeleteSelected': 'Delete selected ({count})',
'sidebar.batchExportSelected': 'Export selected ({count})',
'sidebar.batchExporting': 'Exporting {count} sessions…',
'sidebar.exportProjectSessions': 'Export sessions…',
'sidebar.batchDeleteConfirm': 'Delete {count} sessions? This cannot be undone.',
'sidebar.batchDeleteConfirmBody': 'The following sessions will be deleted:',

View File

@ -95,6 +95,7 @@ export const jp: Record<TranslationKey, string> = {
'sidebar.batchSelectGroup': '{group} を選択',
'sidebar.batchDeleteSelected': '選択項目を削除 ({count})',
'sidebar.batchExportSelected': '選択項目をエクスポート ({count})',
'sidebar.batchExporting': '{count} 件のセッションをエクスポート中…',
'sidebar.exportProjectSessions': 'セッションをエクスポート…',
'sidebar.batchDeleteConfirm': '{count} 件のセッションを削除しますか?この操作は取り消せません。',
'sidebar.batchDeleteConfirmBody': '以下のセッションが削除されます:',

View File

@ -95,6 +95,7 @@ export const kr: Record<TranslationKey, string> = {
'sidebar.batchSelectGroup': '{group} 선택',
'sidebar.batchDeleteSelected': '선택 항목 삭제 ({count})',
'sidebar.batchExportSelected': '선택 항목 내보내기 ({count})',
'sidebar.batchExporting': '{count}개 세션 내보내는 중…',
'sidebar.exportProjectSessions': '세션 내보내기…',
'sidebar.batchDeleteConfirm': '{count}개의 세션을 삭제하시겠습니까? 이 작업은 취소할 수 없습니다.',
'sidebar.batchDeleteConfirmBody': '다음 세션이 삭제됩니다:',

View File

@ -95,6 +95,7 @@ export const zh: Record<TranslationKey, string> = {
'sidebar.batchSelectGroup': '選擇{group}',
'sidebar.batchDeleteSelected': '刪除已選 ({count})',
'sidebar.batchExportSelected': '匯出已選 ({count})',
'sidebar.batchExporting': '正在匯出 {count} 個會話…',
'sidebar.exportProjectSessions': '匯出會話…',
'sidebar.batchDeleteConfirm': '確定要刪除 {count} 個會話嗎?此操作不可撤銷。',
'sidebar.batchDeleteConfirmBody': '以下會話將被刪除:',

View File

@ -95,6 +95,7 @@ export const zh: Record<TranslationKey, string> = {
'sidebar.batchSelectGroup': '选择{group}',
'sidebar.batchDeleteSelected': '删除已选 ({count})',
'sidebar.batchExportSelected': '导出已选 ({count})',
'sidebar.batchExporting': '正在导出 {count} 个会话…',
'sidebar.exportProjectSessions': '导出会话…',
'sidebar.batchDeleteConfirm': '确定要删除 {count} 个会话吗?此操作不可撤销。',
'sidebar.batchDeleteConfirmBody': '以下会话将被删除:',