eleven / messenger Public

ios+mac: sidebar preview shows a file chip for non-image attachments (#542)

previewText rendered any attachment on a text-less message as "📷 Photo",
so a Word doc or PDF showed up in the chat list as a photo. Mirror the
web (previewText in shell.js): all-image sets → "📷 Photo"/"📷 N photos",
anything else → "📎 <filename>"/"📎 N files".

Shared in LChatCore, so this fixes both the iOS thread list and the Mac
app (which also uses previewText for notification bodies). Adds
PreviewTextTests covering images, files, mixed/untyped sets, and the
group-name prefix.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Dermot Daly 91280c1fb9411ddf3d28d6a7bc8c6b85bbfe018a parent 72fc9a6
2 files changed, +71 −1
  • ios/LChatCore/Sources/LChatCore/Models.swift +10 −1
  • ios/LChatCore/Tests/LChatCoreTests/PreviewTextTests.swift +61 −0
diff --git a/ios/LChatCore/Sources/LChatCore/Models.swift b/ios/LChatCore/Sources/LChatCore/Models.swift
index dc7c834..a29b5df 100644
--- a/ios/LChatCore/Sources/LChatCore/Models.swift
+++ b/ios/LChatCore/Sources/LChatCore/Models.swift
@@ -277,7 +277,16 @@ public func previewText(kind: String, payload: MessagePayload) -> String {
var body = (payload.text ?? "")
.replacingOccurrences(of: "\\s+", with: " ", options: .regularExpression)
.trimmingCharacters(in: .whitespacesAndNewlines)
- if body.isEmpty, let a = payload.attachments, !a.isEmpty { body = "📷 Photo" }
+ if body.isEmpty, let a = payload.attachments, !a.isEmpty {
+ // Match the web (previewText in shell.js): all-image → "📷 Photo(s)",
+ // otherwise a file chip "📎 name" so a Word doc doesn't read as a photo.
+ let n = a.count
+ if a.allSatisfy({ $0.isImage }) {
+ body = n > 1 ? "📷 \(n) photos" : "📷 Photo"
+ } else {
+ body = n > 1 ? "📎 \(n) files" : "📎 " + (a.first?.name ?? "File")
+ }
+ }
if kind == "group", let n = payload.name, !n.isEmpty { return "\(n): \(body)" }
return body
}
diff --git a/ios/LChatCore/Tests/LChatCoreTests/PreviewTextTests.swift b/ios/LChatCore/Tests/LChatCoreTests/PreviewTextTests.swift
new file mode 100644
index 0000000..5ab4dbc
--- /dev/null
+++ b/ios/LChatCore/Tests/LChatCoreTests/PreviewTextTests.swift
@@ -0,0 +1,61 @@
+import XCTest
+@testable import LChatCore
+
+// 🤖 Sidebar snippet (previewText) must mirror the web (previewText in
+// shell.js): a non-image attachment reads as a file chip, not "📷 Photo".
+final class PreviewTextTests: XCTestCase {
+ private func att(_ name: String, _ type: String?) -> Attachment {
+ Attachment(id: "b", name: name, type: type)
+ }
+
+ func testTextTakesPrecedence() {
+ var p = MessagePayload()
+ p.text = " hello world \n"
+ p.attachments = [att("photo.jpg", "image/jpeg")]
+ XCTAssertEqual(previewText(kind: "dm", payload: p), "hello world")
+ }
+
+ func testSingleImage() {
+ var p = MessagePayload()
+ p.attachments = [att("photo.jpg", "image/jpeg")]
+ XCTAssertEqual(previewText(kind: "dm", payload: p), "📷 Photo")
+ }
+
+ func testMultipleImages() {
+ var p = MessagePayload()
+ p.attachments = [att("a.jpg", "image/jpeg"), att("b.png", "image/png")]
+ XCTAssertEqual(previewText(kind: "dm", payload: p), "📷 2 photos")
+ }
+
+ func testSingleFileIsNotAPhoto() {
+ var p = MessagePayload()
+ p.attachments = [att("report.docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document")]
+ XCTAssertEqual(previewText(kind: "dm", payload: p), "📎 report.docx")
+ }
+
+ func testMultipleFiles() {
+ var p = MessagePayload()
+ p.attachments = [att("a.docx", "application/msword"), att("b.pdf", "application/pdf")]
+ XCTAssertEqual(previewText(kind: "dm", payload: p), "📎 2 files")
+ }
+
+ func testMixedImageAndFileFallsToFiles() {
+ var p = MessagePayload()
+ p.attachments = [att("a.jpg", "image/jpeg"), att("b.pdf", "application/pdf")]
+ XCTAssertEqual(previewText(kind: "dm", payload: p), "📎 2 files")
+ }
+
+ // A typeless attachment (legacy) isn't an image → file chip with its name.
+ func testUntypedAttachment() {
+ var p = MessagePayload()
+ p.attachments = [att("mystery.bin", nil)]
+ XCTAssertEqual(previewText(kind: "dm", payload: p), "📎 mystery.bin")
+ }
+
+ func testGroupPrefix() {
+ var p = MessagePayload()
+ p.name = "Ada"
+ p.attachments = [att("report.docx", "application/msword")]
+ XCTAssertEqual(previewText(kind: "group", payload: p), "Ada: 📎 report.docx")
+ }
+}