Session View Animation

Nucleic-Session: A8FFA1A6-443F-444A-A735-C53958D7E570
Co-authored-by: Nucleic <[email protected]>
This commit is contained in:
2026-07-06 18:01:27 -07:00
co-authored by Nucleic
parent 12893fdc2d
commit f69f3456b4
@@ -258,4 +258,35 @@ struct MarkdownText: View {
inlineCache.setObject(InlineBox(parsed), forKey: key)
return parsed
}
// MARK: - Pre-warming
/// Populate the block and inline caches for `markdown` ahead of layout. `AttributedString(markdown:)`
/// is the dominant per-row cost when a long transcript first lays out, and the eager `VStack`
/// runs it for every prose line synchronously — right as the session is pushed and the tab bar
/// is sliding away, which is what makes the load-in jitter. Calling this off the main thread
/// (see `TranscriptList`) does that parsing in the background so the first layout hits ready
/// results instead.
///
/// Safe to call from any thread and redundantly: the caches are `NSCache` (thread-safe) and
/// keyed only by the source string (independent of `bodySize`), so a warm value equals what
/// the main thread would compute, and a repeat call is a cheap cache hit. Cooperatively
/// cancellable — a huge transcript's warm loop bails the moment its owning task is cancelled.
static func prewarm(_ markdown: String) {
for block in parse(markdown) { // also warms the block cache
if Task.isCancelled { return }
switch block {
case .code:
break // a code block renders via `Text(code)` — no inline parse to warm
case .text(let text):
for raw in text.components(separatedBy: "\n") {
if let content = classify(raw).inlineContent { _ = attributedInline(content) }
}
case .table(let rows):
for row in rows where !Task.isCancelled {
for cell in row { _ = attributedInline(cell) }
}
}
}
}
}