mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-16 13:03:31 +08:00
fix(desktop): keep session refresh usable
Fixes #893. Reproduced the stuck session-list refresh by keeping the automatic fetch promise pending, then clicking the manual refresh button. Also covered the existing-sessions loading state so a background refresh does not leave the control disabled or spinning forever. Tested: cd desktop && bun run test -- src/components/layout/Sidebar.test.tsx --run Tested: bun run check:desktop Confidence: high Scope-risk: narrow
This commit is contained in:
parent
90cbe9f62c
commit
1f7b1e68c4
@ -293,6 +293,35 @@ describe('Sidebar', () => {
|
||||
expect(screen.getByRole('button', { name: 'Collapse display' })).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('lets a manual session refresh supersede a stuck automatic refresh', async () => {
|
||||
fetchSessions.mockReturnValue(new Promise(() => {}))
|
||||
|
||||
render(<Sidebar />)
|
||||
|
||||
await waitFor(() => expect(fetchSessions).toHaveBeenCalledTimes(1))
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Refresh sessions' }))
|
||||
|
||||
await waitFor(() => expect(fetchSessions).toHaveBeenCalledTimes(2))
|
||||
})
|
||||
|
||||
it('keeps the session refresh control usable when a background refresh is still loading existing sessions', async () => {
|
||||
useSessionStore.setState({
|
||||
sessions: [
|
||||
makeSession('session-loaded', 'Loaded session', '/workspace/alpha', '2026-05-15T10:00:00.000Z'),
|
||||
],
|
||||
isLoading: true,
|
||||
})
|
||||
|
||||
render(<Sidebar />)
|
||||
|
||||
const refreshButton = screen.getByRole('button', { name: 'Refresh sessions' })
|
||||
expect(refreshButton).not.toBeDisabled()
|
||||
expect(refreshButton.querySelector('svg')).not.toHaveClass('animate-spin')
|
||||
|
||||
fireEvent.click(refreshButton)
|
||||
await waitFor(() => expect(fetchSessions).toHaveBeenCalled())
|
||||
})
|
||||
|
||||
it('reorders project groups by dragging project headers while preserving expanded state', async () => {
|
||||
const base = new Date('2026-05-15T10:00:00.000Z').getTime()
|
||||
useSessionStore.setState({
|
||||
|
||||
@ -127,6 +127,7 @@ export function Sidebar({ isMobile = false, onRequestClose }: SidebarProps) {
|
||||
))
|
||||
}, [hiddenProjectKeys, orderedProjectGroups])
|
||||
const showInitialLoading = isLoading && sessions.length === 0
|
||||
const showRefreshLoading = showInitialLoading
|
||||
const filteredSessionIds = useMemo(() => filteredSessions.map((session) => session.id), [filteredSessions])
|
||||
const selectedCount = selectedSessionIds.size
|
||||
const sessionsById = useMemo(
|
||||
@ -709,12 +710,11 @@ export function Sidebar({ isMobile = false, onRequestClose }: SidebarProps) {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => void refreshSessionsNow()}
|
||||
disabled={isLoading}
|
||||
className="flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-[12px] border border-[var(--color-sidebar-search-border)] bg-[var(--color-sidebar-search-bg)] text-[var(--color-text-secondary)] transition-colors hover:bg-[var(--color-sidebar-item-hover)] hover:text-[var(--color-text-primary)] disabled:cursor-default disabled:opacity-65 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-border-focus)]"
|
||||
aria-label={t('sidebar.refreshSessions')}
|
||||
title={t('sidebar.refreshSessions')}
|
||||
>
|
||||
<RefreshCw className={`h-4 w-4 ${isLoading ? 'animate-spin' : ''}`} strokeWidth={1.9} aria-hidden="true" />
|
||||
<RefreshCw className={`h-4 w-4 ${showRefreshLoading ? 'animate-spin' : ''}`} strokeWidth={1.9} aria-hidden="true" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
@ -1213,7 +1213,7 @@ function useSessionListAutoRefresh(fetchSessions: () => Promise<void>): () => Pr
|
||||
const lastStartedAtRef = useRef(0)
|
||||
|
||||
const refreshSessions = useCallback((force = false) => {
|
||||
if (inFlightRef.current) return inFlightRef.current
|
||||
if (inFlightRef.current && !force) return inFlightRef.current
|
||||
|
||||
const now = Date.now()
|
||||
if (!force && now - lastStartedAtRef.current < SESSION_LIST_FOCUS_REFRESH_MIN_MS) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user