Files
session-ios/SessionMessagingKit/Messages/SNProtoContent+Utilities.swift
Morgan Pretty 1af2f75230 Refactored attachment handling and small bug fixes
• Updated display pictures and attachments to use a hash derived from the download url instead of a random UUID for the filename
• Renamed some database columns for consistency
• Dropped a bunch of unused database columns
• Removed old quoted attachment thumbnail logic
• Fixed an issue where updating the display picture wouldn't update the settings UI
• Fixed an issue where image thumbnails may not render correctly
• Fixed an issue where some text wouldn't be respect the theme
• Fixed a performance issue with one of our list components
• Fixed an issue where sharing files wasn't saving the attachment data correctly
2025-06-23 15:15:34 +10:00

85 lines
3.6 KiB
Swift

// Copyright © 2025 Rangeproof Pty Ltd. All rights reserved.
import Foundation
import SessionUtilitiesKit
public extension SNProtoContent {
/// Add attachment proto information if required
///
/// **Note:** This function expects the `attachments` array to be sorted in a way that matches the order of the
/// `InteractionAttachment` values
func addingAttachmentsIfNeeded(
_ message: Message,
_ attachments: [Attachment]? = nil
) throws -> SNProtoContent? {
guard
let message: VisibleMessage = message as? VisibleMessage, (
!message.attachmentIds.isEmpty ||
message.linkPreview?.attachmentId != nil
)
else { return self }
/// Calculate attachment information
let expectedAttachmentUploadCount: Int = (
message.attachmentIds.count +
(message.linkPreview?.attachmentId != nil ? 1 : 0)
)
let uniqueAttachmentIds: Set<String> = Set(message.attachmentIds)
.inserting(message.linkPreview?.attachmentId)
/// We need to ensure we don't send a message which should have uploaded files but hasn't, we do this by comparing the
/// `attachmentIds` on the `VisibleMessage` to the `attachments` value
guard expectedAttachmentUploadCount == (attachments?.count ?? 0) else {
throw MessageSenderError.attachmentsNotUploaded
}
/// Ensure we haven't incorrectly included the `linkPreview` or `quote` attachments in the main `attachmentIds`
guard uniqueAttachmentIds.count == expectedAttachmentUploadCount else {
throw MessageSenderError.attachmentsInvalid
}
do {
var processedAttachments: [Attachment] = (attachments ?? [])
/// Recreate the builder for the proto
guard let dataMessage = dataMessage?.asBuilder() else {
Log.warn(.messageSender, "Couldn't recreate dataMessage builder from: \(message).")
return nil
}
let builder = self.asBuilder()
var attachmentIds: [String] = message.attachmentIds
/// Link preview
if let attachmentId: String = message.linkPreview?.attachmentId {
if let index: Array<String>.Index = attachmentIds.firstIndex(of: attachmentId) {
attachmentIds.remove(at: index)
}
if
let linkPreviewBuilder = self.dataMessage?.preview.first?.asBuilder(),
let attachment: Attachment = processedAttachments.first(where: { $0.id == attachmentId }),
let attachmentProto = attachment.buildProto()
{
linkPreviewBuilder.setImage(attachmentProto)
try dataMessage.setPreview([ linkPreviewBuilder.build() ])
}
/// Remove the `linkPreview` attachment from the general attachments set
processedAttachments = processedAttachments.filter { $0.id != attachmentId }
}
/// Attachments
let attachmentProtos = processedAttachments.compactMap { $0.buildProto() }
dataMessage.setAttachments(attachmentProtos)
/// Build
builder.setDataMessage(try dataMessage.build())
return try builder.build()
} catch {
Log.warn(.messageSender, "Couldn't add attachments to proto from: \(message).")
return nil
}
}
}