110 lines
3.4 KiB
Swift
110 lines
3.4 KiB
Swift
//
|
|
// Copyright 2020 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
public import SignalServiceKit
|
|
public import SignalUI
|
|
|
|
public enum CVMessageCellType: Int, CustomStringConvertible, Equatable {
|
|
case unknown
|
|
|
|
// These message cell types all use the default root component.
|
|
case textOnlyMessage
|
|
case audio
|
|
case genericAttachment
|
|
case paymentAttachment
|
|
case archivedPaymentAttachment
|
|
case contactShare
|
|
case bodyMedia
|
|
case viewOnce
|
|
case stickerMessage
|
|
case quoteOnlyMessage
|
|
case giftBadge
|
|
|
|
// Most of these other message cell types use a special root view.
|
|
case dateHeader
|
|
case unreadIndicator
|
|
case typingIndicator
|
|
case threadDetails
|
|
case systemMessage
|
|
case unknownThreadWarning
|
|
case defaultDisappearingMessageTimer
|
|
|
|
// MARK: - CustomStringConvertible
|
|
|
|
public var description: String {
|
|
switch self {
|
|
case .unknown: return "unknown"
|
|
case .textOnlyMessage: return "textOnlyMessage"
|
|
case .quoteOnlyMessage: return "quoteOnlyMessage"
|
|
case .audio: return "audio"
|
|
case .genericAttachment: return "genericAttachment"
|
|
case .paymentAttachment: return "paymentAttachment"
|
|
case .archivedPaymentAttachment: return "archivedPaymentAttachment"
|
|
case .contactShare: return "contactShare"
|
|
case .bodyMedia: return "bodyMedia"
|
|
case .viewOnce: return "viewOnce"
|
|
case .stickerMessage: return "stickerMessage"
|
|
case .giftBadge: return "giftBadge"
|
|
case .dateHeader: return "dateHeader"
|
|
case .unreadIndicator: return "unreadIndicator"
|
|
case .typingIndicator: return "typingIndicator"
|
|
case .threadDetails: return "threadDetails"
|
|
case .systemMessage: return "systemMessage"
|
|
case .unknownThreadWarning: return "unknownThreadWarning"
|
|
case .defaultDisappearingMessageTimer: return "defaultDisappearingMessageTimer"
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: -
|
|
|
|
// Represents some _renderable_ portion of an Conversation View item.
|
|
// It could be the entire item or some part thereof.
|
|
public protocol CVNode {
|
|
var thread: TSThread { get }
|
|
var interaction: TSInteraction { get }
|
|
var messageCellType: CVMessageCellType { get }
|
|
var conversationStyle: ConversationStyle { get }
|
|
var mediaCache: CVMediaCache { get }
|
|
}
|
|
|
|
// MARK: -
|
|
|
|
// Represents some _renderable_ portion of an Conversation View item.
|
|
// It could be the entire item or some part thereof.
|
|
extension CVNode {
|
|
var interactionType: OWSInteractionType { interaction.interactionType }
|
|
|
|
var isIncoming: Bool {
|
|
interaction is TSIncomingMessage
|
|
}
|
|
|
|
var isOutgoing: Bool {
|
|
interaction is TSOutgoingMessage
|
|
}
|
|
|
|
var wasNotCreatedLocally: Bool {
|
|
(interaction as? TSOutgoingMessage)?.wasNotCreatedLocally == true
|
|
}
|
|
|
|
var wasRemotelyDeleted: Bool {
|
|
guard let message = interaction as? TSMessage else {
|
|
return false
|
|
}
|
|
return message.wasRemotelyDeleted
|
|
}
|
|
|
|
var hasPerConversationExpiration: Bool {
|
|
guard interaction.interactionType == .incomingMessage ||
|
|
interaction.interactionType == .outgoingMessage else {
|
|
return false
|
|
}
|
|
guard let message = interaction as? TSMessage else {
|
|
owsFailDebug("Invalid interaction.")
|
|
return false
|
|
}
|
|
return message.hasPerConversationExpiration
|
|
}
|
|
}
|