Skip to content

fix: stabilize the iOS conversation timeline - #140

Merged
torlando-tech merged 15 commits into
mainfrom
fix/ios-collection-timeline
Aug 4, 2026
Merged

fix: stabilize the iOS conversation timeline#140
torlando-tech merged 15 commits into
mainfrom
fix/ios-collection-timeline

Conversation

@torlando-tech

Copy link
Copy Markdown
Owner

Summary

  • replace the iOS SwiftUI stack timeline with a UIKit UICollectionView embedded through UIViewControllerRepresentable
  • keep existing SwiftUI message bubbles through UIHostingConfiguration, including adjustable message text sizing
  • trigger older-history loading from scroll offset and preserve the visible message position when prepending pages
  • serialize refresh and pagination state, discard stale offset pages, and preserve concurrent unpersisted outbound rows
  • keep outbound send, retry, delete, and delivery-proof identity transitions durable across persistence failures and relaunches
  • use an inline navigation-bar title to remove the empty large-title region above the conversation

Why

On physical iPhone hardware, the lazy SwiftUI timeline could discard every realized row during navigation, keyboard changes, typing, and repository updates while the message model remained populated. It could also fail to trigger or retain older-history pagination. The collection view gives the timeline one explicit owner for cell reuse, pagination, viewport continuity, and keyboard-driven viewport changes.

Verification

  • focused retry, pagination, and timeline policy tests: 23 passed
  • full native ColumbaAppTests suite: 190 passed
  • adjustable-text static regressions: 7 passed
  • full static suite: 223 passed, 1 skipped, 252 subtests passed
  • exact-head iPhone build, signature verification, install, launch, and running-process verification passed
  • physical iPhone: repeatedly navigated conversation without a black/blank timeline
  • physical iPhone: traversed stored history to the oldest available message
  • physical iPhone: compact conversation header verified
  • physical iPhone: adjustable message text size verified after rebase

No user data was wiped during device verification.

@greptile-apps

greptile-apps Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR replaces the iOS SwiftUI conversation stack with a UIKit collection-view timeline and strengthens pagination, viewport continuity, and outbound-message persistence.

  • Embeds existing SwiftUI message bubbles in reusable collection-view cells.
  • Tracks fetched-record offsets and serializes refreshes against pagination.
  • Preserves optimistic outbound rows and reconciles retry identities and delivery proofs.
  • Restricts replies and reactions to messages with safe canonical wire identities.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains; the previously reported unsafe reply-target path now validates target safety at admission and serializes the canonical wire hash when sending.

Important Files Changed

Filename Overview
Sources/ColumbaApp/Views/Messaging/MessageTimelineView.swift Adds the UIKit-backed timeline with hosted SwiftUI bubbles, viewport anchoring, pagination triggers, and safe reply admission.
Sources/ColumbaApp/ViewModels/MessagingViewModel.swift Serializes refresh and pagination while preserving optimistic outbound rows and reconciling canonical hashes, retries, and delivery proofs.
Sources/ColumbaApp/Services/MessageRepository.swift Adds durable markers and atomic recovery paths for optimistic and uncertain outbound identity transitions.
Sources/ColumbaApp/Views/Messaging/MessageBubble.swift Separates durable storage identity from canonical wire identity and derives whether a message is safe to target.
Sources/ColumbaApp/Views/Messaging/MessagingView.swift Integrates the collection-view timeline and consistently gates replies and reactions through canonical target-safety checks.

Sequence Diagram

sequenceDiagram
    participant UI as MessageTimelineView
    participant VM as MessagingViewModel
    participant Repo as MessageRepository
    participant Backend as LXMF Backend
    UI->>VM: Load or paginate messages
    VM->>Repo: Fetch records using record cursor
    Repo-->>VM: Persisted message page
    VM-->>UI: Reconciled visible messages
    UI->>VM: Send message
    VM->>UI: Add optimistic unsafe row
    VM->>Backend: Submit LXMF message
    Backend-->>VM: Canonical wire hash
    VM->>Repo: Persist or recover identity transition
    Repo-->>VM: Durable canonical or uncertain row
    VM-->>UI: Refresh timeline and targeting state
Loading

Reviews (2): Last reviewed commit: "fix: gate timeline replies by target saf..." | Re-trigger Greptile

Comment thread Sources/ColumbaApp/Views/Messaging/MessageTimelineView.swift
@torlando-tech
torlando-tech merged commit c5383ba into main Aug 4, 2026
4 checks passed
@torlando-tech
torlando-tech deleted the fix/ios-collection-timeline branch August 4, 2026 14:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant