fix(desktop): polish compaction indicator and preserve scrollback
Show a shimmering "Summarizing thread" label during auto-compaction, skip the post-turn hydrate when compaction fired so the live transcript does not collapse to the stored summary-only session.
This commit is contained in:
@@ -96,7 +96,7 @@ import { extractPreviewTargets } from '@/lib/preview-targets'
|
||||
import { useEnterAnimation } from '@/lib/use-enter-animation'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { playSpeechText, stopVoicePlayback } from '@/lib/voice-playback'
|
||||
import { $compactionStatus } from '@/store/compaction'
|
||||
import { $compactionActive } from '@/store/compaction'
|
||||
import type { ComposerAttachment } from '@/store/composer'
|
||||
import { notifyError } from '@/store/notifications'
|
||||
import { $connection } from '@/store/session'
|
||||
@@ -337,15 +337,25 @@ const StatusRow: FC<{ children: ReactNode; label: string } & React.ComponentProp
|
||||
</div>
|
||||
)
|
||||
|
||||
// Fixed label while auto-compaction runs — decoupled from backend status text.
|
||||
const COMPACTION_LABEL = 'Summarizing thread'
|
||||
|
||||
const CompactionHint: FC = () => (
|
||||
<span className="shimmer min-w-0 truncate text-muted-foreground/55">{COMPACTION_LABEL}</span>
|
||||
)
|
||||
|
||||
const ResponseLoadingIndicator: FC = () => {
|
||||
const { t } = useI18n()
|
||||
const elapsed = useElapsedSeconds()
|
||||
const compaction = useStore($compactionStatus)
|
||||
const compacting = useStore($compactionActive)
|
||||
|
||||
return (
|
||||
<StatusRow data-slot="aui_response-loading" label={compaction ?? t.assistant.thread.loadingResponse}>
|
||||
<StatusRow
|
||||
data-slot="aui_response-loading"
|
||||
label={compacting ? COMPACTION_LABEL : t.assistant.thread.loadingResponse}
|
||||
>
|
||||
<span aria-hidden="true" className="dither inline-block size-3 rounded-[2px] text-midground/80 animate-pulse" />
|
||||
{compaction && <span className="min-w-0 truncate">{compaction}</span>}
|
||||
{compacting && <CompactionHint />}
|
||||
<ActivityTimerText seconds={elapsed} />
|
||||
</StatusRow>
|
||||
)
|
||||
@@ -380,7 +390,7 @@ const StreamStallIndicator: FC = () => {
|
||||
})
|
||||
|
||||
const [stalled, setStalled] = useState(false)
|
||||
const compaction = useStore($compactionStatus)
|
||||
const compacting = useStore($compactionActive)
|
||||
|
||||
useEffect(() => {
|
||||
setStalled(false)
|
||||
@@ -389,8 +399,7 @@ const StreamStallIndicator: FC = () => {
|
||||
return () => window.clearTimeout(id)
|
||||
}, [activity])
|
||||
|
||||
// Compaction surfaces immediately; an ordinary stall waits out STREAM_STALL_S.
|
||||
const active = stalled || Boolean(compaction)
|
||||
const active = stalled || compacting
|
||||
const elapsed = useElapsedSeconds(active)
|
||||
|
||||
if (!active) {
|
||||
@@ -398,9 +407,13 @@ const StreamStallIndicator: FC = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<StatusRow className="mt-1.5" data-slot="aui_stream-stall" label={compaction ?? 'Hermes is thinking'}>
|
||||
<StatusRow
|
||||
className="mt-1.5"
|
||||
data-slot="aui_stream-stall"
|
||||
label={compacting ? COMPACTION_LABEL : 'Hermes is thinking'}
|
||||
>
|
||||
<span aria-hidden="true" className="dither inline-block size-3 rounded-[2px] text-midground/80 animate-pulse" />
|
||||
{compaction && <span className="min-w-0 truncate">{compaction}</span>}
|
||||
{compacting && <CompactionHint />}
|
||||
<ActivityTimerText seconds={elapsed} />
|
||||
</StatusRow>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user