Skip to content

fix: preview and export received attachments - #150

Merged
torlando-tech merged 22 commits into
mainfrom
fix/ios-issue-145-attachment-preview
Aug 6, 2026
Merged

fix: preview and export received attachments#150
torlando-tech merged 22 commits into
mainfrom
fix/ios-issue-145-attachment-preview

Conversation

@torlando-tech

Copy link
Copy Markdown
Owner

Summary

  • make received image and file attachments tappable without changing their existing bubble styling or gestures
  • present attachments with chat-owned SwiftUI Quick Look and preserve original bytes in isolated, safely named temporary items
  • route multi-file messages by stable attachment index and refresh callbacks across timeline controller reuse
  • add lifecycle, filename/type, accessibility, visual, static-contract, and Sideband-to-iOS regressions

Fixes #145

Verification

  • xcodebuild test on the shipping Columba scheme: 278 tests, 0 failures
  • focused attachment XTests: 9 tests, 0 failures
  • Columba-ModelB simulator build: succeeded
  • portable static suite: 244 tests passed, 1 skipped
  • attachment preview contract: 3 runs, 41 assertions, 0 failures
  • controlled Sideband interop: image, file, and second duplicate-name file flows all passed
    • tapped production attachment controls
    • opened native SwiftUI Quick Look
    • selected native Save Image / Save to Files
    • verified the active Quick Look export URL was byte-identical to the received attachment
  • physical iPhone: exact-head signed build, install, and launch succeeded

Notes

On the iOS 26.4 Simulator, selecting Save to Files returns directly to Quick Look rather than presenting a second picker-level Save control. The interop lane therefore verifies selection of the named native action and byte identity at Quick Look's active export URL; it does not claim destination Files-container readback.

Two unrelated project-graph contracts remain baseline failures on the merged PR #149 baseline and are unchanged by this branch.

Risk and rollback

The change is scoped to attachment presentation and temporary export files. It does not alter LXMF encoding, persistence, database schema, or the messaging backend. Reverting this PR restores the previous noninteractive attachment rendering.

@greptile-apps

greptile-apps Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR makes received image and file attachments interactive and presents their original bytes through native Quick Look.

  • Adds isolated, sanitized temporary preview items with scoped cleanup.
  • Routes image and indexed file-attachment actions through reusable timeline cells.
  • Adds unit, visual, static-contract, and Sideband interoperability coverage.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
Sources/ColumbaApp/Views/Messaging/MessageAttachmentPreviewItem.swift Adds byte-preserving temporary preview items with filename sanitization, type detection, isolated ownership, and idempotent cleanup.
Sources/ColumbaApp/Views/Messaging/MessageBubble.swift Converts rendered image and file attachments into accessible controls while retaining the bubble’s reaction gesture behavior.
Sources/ColumbaApp/Views/Messaging/MessageTimelineView.swift Propagates refreshed attachment callbacks through the reusable UIKit timeline and validates file indexes before routing.
Sources/ColumbaApp/Views/Messaging/MessagingView.swift Owns Quick Look presentation, prepares attachment URLs, reports preparation errors, and cleans preview resources on dismissal or conversation exit.
Tests/ColumbaAppTests/MessageAttachmentPreviewTests.swift Covers byte preservation, filename safety, item lifecycle, callback routing, controller reuse, accessibility sizing, and visual rendering.
Tests/interop/test_attachments.py Extends Sideband interoperability coverage through native preview and export flows for images and multiple files.
Columba.xcodeproj/project.pbxproj Adds the preview implementation to both app flavors and registers its shipping-target tests.

Sequence Diagram

sequenceDiagram
    participant User
    participant Bubble as MessageBubble
    participant Timeline as MessageTimelineViewController
    participant Chat as MessagingView
    participant Item as PreviewItem
    participant QL as Quick Look
    User->>Bubble: Tap image or file chip
    Bubble->>Timeline: Attachment callback + stable index
    Timeline->>Chat: Open attachment
    Chat->>Item: Write original bytes to isolated temp URL
    Item-->>Chat: Preview URL
    Chat->>QL: Present URL
    QL-->>User: Preview and native export actions
    User->>QL: Dismiss
    QL->>Chat: Clear URL binding
    Chat->>Item: Clean owned temporary directory
Loading

Reviews (2): Last reviewed commit: "fix: make attachment taps exclusive with..." | Re-trigger Greptile

@torlando-tech
torlando-tech merged commit 2da1f7f into main Aug 6, 2026
4 checks passed
@torlando-tech
torlando-tech deleted the fix/ios-issue-145-attachment-preview branch August 6, 2026 16:04
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.

android parity: no way to save/download image attachments

1 participant