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

107 lines
3.2 KiB
Swift

//
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import Foundation
public enum EditSendValidationError: Error {
case messageTypeNotSupported
case messageNotFound
case editWindowClosed
case tooManyEdits(UInt)
}
extension EditSendValidationError: LocalizedError {
public var errorDescription: String? {
localizedDescription
}
public var localizedDescription: String {
switch self {
case .editWindowClosed:
return OWSLocalizedString(
"EDIT_MESSAGE_SEND_MESSAGE_TOO_OLD_ERROR",
comment: "Error message to display to user when a message is too old to edit"
)
case .tooManyEdits(let numEdits):
return String.localizedStringWithFormat(
OWSLocalizedString(
"EDIT_MESSAGE_SEND_TOO_MANY_EDITS_ERROR",
tableName: "PluralAware",
comment: "Error message to display to user when edit limit reached"
),
numEdits
)
default:
return OWSLocalizedString(
"EDIT_MESSAGE_SEND_MESSAGE_UNKNOWN_ERROR",
comment: "Edit failed for an unexpected reason"
)
}
}
}
public protocol EditManager {
// MARK: - Incoming Edit Processing
/// Process an incoming data message.
///
/// Checks the external edit for valid field values, then calls shared code
/// to create new copies and records as appropriate.
func processIncomingEditMessage(
_ newDataMessage: SSKProtoDataMessage,
serverTimestamp: UInt64,
serverGuid: String?,
serverDeliveryTimestamp: UInt64,
thread: TSThread,
editTarget: EditMessageTarget,
tx: DBWriteTransaction
) throws -> TSMessage
// MARK: - Edit UI Validation
func canShowEditMenu(interaction: TSInteraction, thread: TSThread) -> Bool
func validateCanSendEdit(
targetMessageTimestamp: UInt64,
thread: TSThread,
tx: DBReadTransaction
) -> EditSendValidationError?
// MARK: - Outgoing Edit Send
/// Fetches a fresh version of the `targetMessage`, creates and inserts
/// copies into the database with edits applied as needed, and finally
/// constructs and returns an `OutgoingEditMessage` with the newest copy.
func createOutgoingEditMessage(
targetMessage: TSOutgoingMessage,
thread: TSThread,
edits: MessageEdits,
oversizeText: AttachmentDataSource?,
quotedReplyEdit: MessageEdits.Edit<Void>,
linkPreview: LinkPreviewDataSource?,
tx: DBWriteTransaction
) throws -> OutgoingEditMessage
// MARK: - Edit Revision Read State
func markEditRevisionsAsRead(
for edit: TSMessage,
thread: TSThread,
tx: DBWriteTransaction
) throws
}
public extension TSMessage {
/// Check if the message is an old edit revision.
///
/// Past edits will still technically be part of a conversation,
/// but they should be hidden from operations that are determining
/// latest messages for things like sorting conversations.
func isPastEditRevision() -> Bool {
return self.editState == .pastRevision
}
}