Skip to content

Commit

Permalink
Add file property to the ImageAttachmentPayload for exposing file siz…
Browse files Browse the repository at this point in the history
…e and mime type
  • Loading branch information
laevandus committed Jan 3, 2025
1 parent be21a9e commit 532fb66
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 11 deletions.
22 changes: 11 additions & 11 deletions DemoShare/DemoShareViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,32 +68,32 @@ class DemoShareViewModel: ObservableObject, ChatChannelControllerDelegate {
channelController.delegate = self
loading = true
try await channelController.synchronize()
let remoteUrls = await withThrowingTaskGroup(of: URL.self) { taskGroup in
let attachmentPayloads = await withThrowingTaskGroup(of: AnyAttachmentPayload.self) { taskGroup in
for url in imageURLs {
taskGroup.addTask {
let file = try AttachmentFile(url: url)
let uploaded = try await channelController.uploadAttachment(
localFileURL: url,
type: .image
)
return uploaded.remoteURL
let attachment = ImageAttachmentPayload(
title: nil,
imageRemoteURL: uploaded.remoteURL,
file: file
)
return AnyAttachmentPayload(payload: attachment)
}
}

var results = [URL]()
var results = [AnyAttachmentPayload]()
while let result = await taskGroup.nextResult() {
if let url = try? result.get() {
results.append(url)
if let attachment = try? result.get() {
results.append(attachment)
}
}
return results
}

var attachmentPayloads = [AnyAttachmentPayload]()
for remoteUrl in remoteUrls {
let attachment = ImageAttachmentPayload(title: nil, imageRemoteURL: remoteUrl)
attachmentPayloads.append(AnyAttachmentPayload(payload: attachment))
}

messageId = try await channelController.createNewMessage(
text: text,
attachments: attachmentPayloads
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ public extension AnyAttachmentPayload {
payload = ImageAttachmentPayload(
title: localFileURL.lastPathComponent,
imageRemoteURL: localFileURL,
file: file,
originalWidth: localMetadata?.originalResolution?.width,
originalHeight: localMetadata?.originalResolution?.height,
extraData: extraData
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ public struct ImageAttachmentPayload: AttachmentPayload {
public var originalWidth: Double?
/// The original height of the image in pixels.
public var originalHeight: Double?
/// The image file size information.
public var file: AttachmentFile
/// An extra data.
public var extraData: [String: RawJSON]?

Expand All @@ -35,10 +37,30 @@ public struct ImageAttachmentPayload: AttachmentPayload {
.flatMap { try? JSONEncoder.stream.encode($0) }
.flatMap { try? JSONDecoder.stream.decode(T.self, from: $0) }
}

/// Creates `ImageAttachmentPayload` instance.
///
/// Use this initializer if the attachment is already uploaded and you have the remote URLs.
public init(
title: String?,
imageRemoteURL: URL,
file: AttachmentFile,
originalWidth: Double? = nil,
originalHeight: Double? = nil,
extraData: [String: RawJSON]? = nil
) {
self.title = title
imageURL = imageRemoteURL
self.file = file
self.originalWidth = originalWidth
self.originalHeight = originalHeight
self.extraData = extraData
}

/// Creates `ImageAttachmentPayload` instance.
///
/// Use this initializer if the attachment is already uploaded and you have the remote URLs.
@available(*, deprecated, renamed: "init(title:imageRemoteURL:file:originalWidth:originalHeight:extraData:)")
public init(
title: String?,
imageRemoteURL: URL,
Expand All @@ -48,6 +70,8 @@ public struct ImageAttachmentPayload: AttachmentPayload {
) {
self.title = title
imageURL = imageRemoteURL
let fileType = AttachmentFileType(ext: imageRemoteURL.pathExtension)
file = AttachmentFile(type: fileType, size: 0, mimeType: nil)
self.originalWidth = originalWidth
self.originalHeight = originalHeight
self.extraData = extraData
Expand Down Expand Up @@ -78,6 +102,8 @@ public struct ImageAttachmentPayload: AttachmentPayload {
imageURL = imageRemoteURL
self.originalWidth = originalWidth
self.originalHeight = originalHeight
let fileType = AttachmentFileType(ext: imageRemoteURL.pathExtension)
file = AttachmentFile(type: fileType, size: 0, mimeType: nil)
self.extraData = extraData
}
}
Expand Down Expand Up @@ -108,6 +134,9 @@ extension ImageAttachmentPayload: Encodable {
values[AttachmentCodingKeys.originalWidth.rawValue] = .double(originalWidth)
values[AttachmentCodingKeys.originalHeight.rawValue] = .double(originalHeight)
}

values[AttachmentFile.CodingKeys.size.rawValue] = .number(Double(Int(file.size)))
values[AttachmentFile.CodingKeys.mimeType.rawValue] = file.mimeType.map { .string($0) }

try values.encode(to: encoder)
}
Expand All @@ -134,12 +163,14 @@ extension ImageAttachmentPayload: Decodable {
return try container.decodeIfPresent(String.self, forKey: .name)
}()

let file = try AttachmentFile(from: decoder)
let originalWidth = try container.decodeIfPresent(Double.self, forKey: .originalWidth)
let originalHeight = try container.decodeIfPresent(Double.self, forKey: .originalHeight)

self.init(
title: title?.trimmingCharacters(in: .whitespacesAndNewlines),
imageRemoteURL: imageURL,
file: file,
originalWidth: originalWidth,
originalHeight: originalHeight,
extraData: try Self.decodeExtraData(from: decoder)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ extension ChatMessageImageAttachment {
payload: .init(
title: title,
imageRemoteURL: imageURL,
file: try! AttachmentFile(url: imageURL),
extraData: extraData
),
downloadingState: localDownloadState.map {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ final class ImageAttachmentPayload_Tests: XCTestCase {
let thumbURL: URL = .unique()
let originalWidth: Double = 3200
let originalHeight: Double = 2600
let fileSize: Int64 = 1024

// Create JSON with the given values.
let json = """
{
"title": "\(title)",
"file_size": \(fileSize),
"image_url": "\(imageURL.absoluteString)",
"thumb_url": "\(thumbURL.absoluteString)",
"original_width": \(originalWidth),
Expand All @@ -32,6 +34,40 @@ final class ImageAttachmentPayload_Tests: XCTestCase {
// Assert values are decoded correctly.
XCTAssertEqual(payload.title, title)
XCTAssertEqual(payload.imageURL, imageURL)
XCTAssertEqual(payload.file.size, fileSize)
XCTAssertEqual(payload.file.mimeType, nil)
XCTAssertEqual(payload.originalWidth, originalWidth)
XCTAssertEqual(payload.originalHeight, originalHeight)
XCTAssertNil(payload.extraData)
}

func test_decodingDefaultValues_withoutFileSize() throws {
// Create attachment field values.
let title: String = .unique
let imageURL: URL = .unique()
let thumbURL: URL = .unique()
let originalWidth: Double = 3200
let originalHeight: Double = 2600

// Create JSON with the given values.
let json = """
{
"title": "\(title)",
"image_url": "\(imageURL.absoluteString)",
"thumb_url": "\(thumbURL.absoluteString)",
"original_width": \(originalWidth),
"original_height": \(originalHeight)
}
""".data(using: .utf8)!

// Decode attachment from JSON.
let payload = try JSONDecoder.stream.decode(ImageAttachmentPayload.self, from: json)

// Assert values are decoded correctly.
XCTAssertEqual(payload.title, title)
XCTAssertEqual(payload.imageURL, imageURL)
XCTAssertEqual(payload.file.size, 0)
XCTAssertEqual(payload.file.mimeType, nil)
XCTAssertEqual(payload.originalWidth, originalWidth)
XCTAssertEqual(payload.originalHeight, originalHeight)
XCTAssertNil(payload.extraData)
Expand Down Expand Up @@ -74,6 +110,7 @@ final class ImageAttachmentPayload_Tests: XCTestCase {
let payload = ImageAttachmentPayload(
title: "Image1.png",
imageRemoteURL: URL(string: "dummyURL")!,
file: AttachmentFile(type: .png, size: 75, mimeType: "image/png"),
originalWidth: 100,
originalHeight: 50,
extraData: ["isVerified": true]
Expand All @@ -83,6 +120,8 @@ final class ImageAttachmentPayload_Tests: XCTestCase {
let expectedJsonObject: [String: Any] = [
"title": "Image1.png",
"image_url": "dummyURL",
"file_size": 75,
"mime_type": "image/png",
"original_width": 100,
"original_height": 50,
"isVerified": true
Expand Down

0 comments on commit 532fb66

Please sign in to comment.