TM-SGNL-iOS/SignalServiceKit/Messages/Attachments/V2/AttachmentManager/AttachmentManager.swift
TeleMessage developers dde0620daf initial commit
2025-05-03 12:28:28 -07:00

154 lines
5.5 KiB
Swift

//
// Copyright 2024 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import Foundation
public protocol AttachmentManager {
// MARK: - Creating Attachments from source
/// Create attachment pointers from protos.
/// Does no deduplication; once we download the contents of the attachment
/// we may deduplicate and update the owner reference accordingly.
/// Creates a reference from the owner to the attachment.
///
/// Throws an error if any of the provided protos are invalid.
func createAttachmentPointers(
from protos: [OwnedAttachmentPointerProto],
tx: DBWriteTransaction
) throws
/// Create attachment pointers from backup protos.
/// Does no deduplication; once we download the contents of the attachment
/// we may deduplicate and update the owner reference accordingly.
/// Creates a reference from the owner to the attachment.
///
/// - parameter uploadEra: see ``Attachment/uploadEra(backupSubscriptionId:)``.
/// Defines the valid lifetime of the backup upload. Derived from the subscription id.
///
/// - returns errors for any of the provided protos that are invalid. Callers _must_ cancel
/// the transaction if any error is returned; not doing so could result in writing partial invalid state.
/// Returns an empty array on success.
func createAttachmentPointers(
from backupProtos: [OwnedAttachmentBackupPointerProto],
uploadEra: String,
tx: DBWriteTransaction
) -> [OwnedAttachmentBackupPointerProto.CreationError]
/// Create attachment streams from the data sources, consuming those data sources.
/// May reuse an existing attachment stream if matched by content, and discard
/// the data source.
/// Creates a reference from the owner to the attachments.
func createAttachmentStreams(
consuming dataSources: [OwnedAttachmentDataSource],
tx: DBWriteTransaction
) throws
// MARK: - Quoted Replies
/// Given an original message available locally, returns metadata
/// supplied to a TSQuotedReply, which distinguishes "stubs"
/// (attachments that cannot be thumbnail-ed) from thumbnails.
///
/// If the original lacks an attachment, returns nil. If the original has an
/// attachment that can't be thumbnailed, returns stub metadata.
///
/// Callers should call ``createQuotedReplyMessageThumbnail`` to
/// actually construct the attachment once the owning message exists.
func quotedReplyAttachmentInfo(
originalMessage: TSMessage,
tx: DBReadTransaction
) -> QuotedAttachmentInfo?
/// Given a quote thumbnail source, creates a builder for a thumbnail
/// attachment (if necessary) and an owner reference to it.
func createQuotedReplyMessageThumbnailBuilder(
from dataSource: QuotedReplyAttachmentDataSource,
tx: DBWriteTransaction
) -> OwnedAttachmentBuilder<QuotedAttachmentInfo>
// MARK: - Removing Attachments
/// Remove an attachment from an owner.
/// Will only delete the attachment if this is the last owner.
/// Typically because the owner has been deleted.
func removeAttachment(
reference: AttachmentReference,
tx: DBWriteTransaction
) throws
/// Removed all attachments of the provided types from the provided owners.
/// Will only delete attachments if they are left without any owners.
func removeAllAttachments(
from owners: [AttachmentReference.OwnerId],
tx: DBWriteTransaction
) throws
}
// MARK: - Array<->Single object convenience methods
extension AttachmentManager {
/// Given an attachment proto from its sender and an owner,
/// creates a local attachment and an owner reference to it.
///
/// Throws an error if the provided proto is invalid.
public func createAttachmentPointer(
from proto: OwnedAttachmentPointerProto,
tx: DBWriteTransaction
) throws {
try createAttachmentPointers(
from: [proto],
tx: tx
)
}
/// Create an attachment stream from a data source, consuming that data source.
/// May reuse an existing attachment stream if matched by content, and discard
/// the data source.
/// Creates a reference from the owner to the attachment.
public func createAttachmentStream(
consuming dataSource: OwnedAttachmentDataSource,
tx: DBWriteTransaction
) throws {
try createAttachmentStreams(
consuming: [dataSource],
tx: tx
)
}
}
// MARK: - OwnedAttachmentBuilder convenience
extension AttachmentManager {
public func createAttachmentPointerBuilder(
from proto: SSKProtoAttachmentPointer,
tx: DBWriteTransaction
) throws -> OwnedAttachmentBuilder<Void> {
return OwnedAttachmentBuilder<Void>(
finalize: { [self] owner, innerTx in
return try self.createAttachmentPointer(
from: .init(proto: proto, owner: owner),
tx: innerTx
)
}
)
}
public func createAttachmentStreamBuilder(
from dataSource: AttachmentDataSource,
tx: DBWriteTransaction
) throws -> OwnedAttachmentBuilder<Void> {
return OwnedAttachmentBuilder<Void>(
finalize: { [self] owner, innerTx in
return try self.createAttachmentStream(
consuming: .init(dataSource: dataSource, owner: owner),
tx: innerTx
)
}
)
}
}