// // Copyright 2020 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only // import LibSignalClient import SignalServiceKit import SignalUI public enum CVAttachmentTapAction: Int { case handledByDelegate case `default` } public protocol AudioMessageViewDelegate: AnyObject { func enqueueReloadWithoutCaches() typealias EndCellAnimation = () -> Void func beginCellAnimation(maximumDuration: TimeInterval) -> EndCellAnimation } public protocol CVComponentDelegate: AnyObject, AudioMessageViewDelegate { func enqueueReload() // MARK: - Body Text Items func didTapBodyTextItem(_ item: CVTextLabel.Item) func didLongPressBodyTextItem(_ item: CVTextLabel.Item) // MARK: - System Message Items func didTapSystemMessageItem(_ item: CVTextLabel.Item) // MARK: - Double-Tap func didDoubleTapTextViewItem(_ itemViewModel: CVItemViewModelImpl) // MARK: - Long Press func didLongPressTextViewItem(_ cell: CVCell, itemViewModel: CVItemViewModelImpl, shouldAllowReply: Bool) func didLongPressMediaViewItem(_ cell: CVCell, itemViewModel: CVItemViewModelImpl, shouldAllowReply: Bool) func didLongPressQuote(_ cell: CVCell, itemViewModel: CVItemViewModelImpl, shouldAllowReply: Bool) func didLongPressSystemMessage(_ cell: CVCell, itemViewModel: CVItemViewModelImpl) func didLongPressSticker(_ cell: CVCell, itemViewModel: CVItemViewModelImpl, shouldAllowReply: Bool) func didLongPressPaymentMessage( _ cell: CVCell, itemViewModel: CVItemViewModelImpl, shouldAllowReply: Bool ) func didChangeLongPress(_ itemViewModel: CVItemViewModelImpl) func didEndLongPress(_ itemViewModel: CVItemViewModelImpl) func didCancelLongPress(_ itemViewModel: CVItemViewModelImpl) // MARK: - func didTapReplyToItem(_ itemViewModel: CVItemViewModelImpl) func didTapSenderAvatar(_ interaction: TSInteraction) func shouldAllowReplyForItem(_ itemViewModel: CVItemViewModelImpl) -> Bool func didTapReactions(reactionState: InteractionReactionState, message: TSMessage) var hasPendingMessageRequest: Bool { get } func didTapTruncatedTextMessage(_ itemViewModel: CVItemViewModelImpl) func didTapFailedOrPendingDownloads(_ message: TSMessage) func didTapBrokenVideo() // MARK: - Messages func didTapBodyMedia( itemViewModel: CVItemViewModelImpl, attachmentStream: ReferencedTSResourceStream, imageView: UIView ) func didTapGenericAttachment(_ attachment: CVComponentGenericAttachment) -> CVAttachmentTapAction func didTapQuotedReply(_ quotedReply: QuotedReplyModel) func didTapLinkPreview(_ linkPreview: OWSLinkPreview) func didTapContactShare(_ contactShare: ContactShareViewModel) func didTapSendMessage(to phoneNumbers: [String]) func didTapSendInvite(toContactShare contactShare: ContactShareViewModel) func didTapAddToContacts(contactShare: ContactShareViewModel) func didTapStickerPack(_ stickerPackInfo: StickerPackInfo) func didTapPayment(_ paymentModel: TSPaymentModel, displayName: String) func didTapGroupInviteLink(url: URL) func didTapProxyLink(url: URL) func didTapShowMessageDetail(_ itemViewModel: CVItemViewModelImpl) func didTapShowEditHistory(_ itemViewModel: CVItemViewModelImpl) func prepareMessageDetailForInteractivePresentation(_ itemViewModel: CVItemViewModelImpl) var view: UIView! { get } var isConversationPreview: Bool { get } var wallpaperBlurProvider: WallpaperBlurProvider? { get } var spoilerState: SpoilerRenderState { get } // MARK: - Gift Badges /// Invoked just before a gift is wrapped. /// /// This allows the view controller to indicate that a particular gift /// shouldn't be wrapped (or that *no* gifts should be wrapped, by always /// returning false). /// /// This may not be invoked if the gift has already been redeemed. /// /// - Parameter messageUniqueId: The gift's TSMessage's uniqueId. /// - Returns: Whether or not the gift should be wrapped. func willWrapGift(_ messageUniqueId: String) -> Bool /// Invoked just before a gift is shaken. /// /// This allows the view controller to indicate that a particular gift /// shouldn't be shaken (or that it shouldn’t be shaken again). /// /// - Parameter messageUniqueId: The gift's TSMessage's uniqueId. /// - Returns: Whether or not the gift should be shaken. func willShakeGift(_ messageUniqueId: String) -> Bool /// Invoked just before a gift is unwrapped. func willUnwrapGift(_ itemViewModel: CVItemViewModelImpl) /// Invoked when the button on a gift is tapped. func didTapGiftBadge(_ itemViewModel: CVItemViewModelImpl, profileBadge: ProfileBadge, isExpired: Bool, isRedeemed: Bool) // MARK: - Selection var selectionState: CVSelectionState { get } // MARK: - System Cell func didTapPreviouslyVerifiedIdentityChange(_ address: SignalServiceAddress) func didTapUnverifiedIdentityChange(_ address: SignalServiceAddress) func didTapInvalidIdentityKeyErrorMessage(_ message: TSInvalidIdentityKeyErrorMessage) func didTapCorruptedMessage(_ message: TSErrorMessage) func didTapSessionRefreshMessage(_ message: TSErrorMessage) // See: resendGroupUpdate func didTapResendGroupUpdateForErrorMessage(_ errorMessage: TSErrorMessage) func didTapShowFingerprint(_ address: SignalServiceAddress) func didTapIndividualCall(_ call: TSCall) func didTapLearnMoreMissedCallFromBlockedContact(_ call: TSCall) func didTapGroupCall() func didTapPendingOutgoingMessage(_ message: TSOutgoingMessage) func didTapFailedOutgoingMessage(_ message: TSOutgoingMessage) func didTapGroupMigrationLearnMore() func didTapGroupInviteLinkPromotion(groupModel: TSGroupModel) func didTapViewGroupDescription(newGroupDescription: String) func didTapShowConversationSettings() func didTapShowConversationSettingsAndShowMemberRequests() func didTapBlockRequest(groupModel: TSGroupModelV2, requesterName: String, requesterAci: Aci) func didTapShowUpgradeAppUI() func didTapUpdateSystemContact(_ address: SignalServiceAddress, newNameComponents: PersonNameComponents) func didTapPhoneNumberChange(aci: Aci, phoneNumberOld: String, phoneNumberNew: String) func didTapViewOnceAttachment(_ interaction: TSInteraction) func didTapViewOnceExpired(_ interaction: TSInteraction) func didTapContactName(thread: TSContactThread) func didTapUnknownThreadWarningGroup() func didTapUnknownThreadWarningContact() func didTapDeliveryIssueWarning(_ message: TSErrorMessage) func didTapActivatePayments() func didTapSendPayment() func didTapThreadMergeLearnMore(phoneNumber: String) func didTapReportSpamLearnMore() } // MARK: - struct CVMessageAction: Equatable { let title: String let accessibilityIdentifier: String let action: Action func perform(delegate: CVComponentDelegate) { action.perform(delegate: delegate) } enum Action: Equatable { case none case didTapPreviouslyVerifiedIdentityChange(address: SignalServiceAddress) case didTapUnverifiedIdentityChange(address: SignalServiceAddress) case didTapInvalidIdentityKeyErrorMessage(errorMessage: TSInvalidIdentityKeyErrorMessage) case didTapCorruptedMessage(errorMessage: TSErrorMessage) case didTapSessionRefreshMessage(errorMessage: TSErrorMessage) case didTapResendGroupUpdate(errorMessage: TSErrorMessage) case didTapGroupMigrationLearnMore case didTapViewGroupDescription(newGroupDescription: String) case didTapGroupInviteLinkPromotion(groupModel: TSGroupModel) case didTapShowConversationSettingsAndShowMemberRequests case didTapBlockRequest(groupModel: TSGroupModelV2, requesterName: String, requesterAci: Aci) case didTapShowUpgradeAppUI case didTapUpdateSystemContact(address: SignalServiceAddress, newNameComponents: PersonNameComponents) case didTapPhoneNumberChange(aci: Aci, phoneNumberOld: String, phoneNumberNew: String) case didTapIndividualCall(call: TSCall) case didTapLearnMoreMissedCallFromBlockedContact(call: TSCall) case didTapGroupCall case didTapSendMessage(phoneNumbers: [String]) case didTapSendInvite(contactShare: ContactShareViewModel) case didTapAddToContacts(contactShare: ContactShareViewModel) case didTapUnknownThreadWarningGroup case didTapUnknownThreadWarningContact case didTapDeliveryIssueWarning(errorMessage: TSErrorMessage) case didTapActivatePayments case didTapSendPayment case didTapThreadMergeLearnMore(phoneNumber: String) case didTapReportSpamLearnMore func perform(delegate: CVComponentDelegate) { switch self { case .none: break case .didTapPreviouslyVerifiedIdentityChange(let address): delegate.didTapPreviouslyVerifiedIdentityChange(address) case .didTapUnverifiedIdentityChange(let address): delegate.didTapUnverifiedIdentityChange(address) case .didTapInvalidIdentityKeyErrorMessage(let errorMessage): delegate.didTapInvalidIdentityKeyErrorMessage(errorMessage) case .didTapCorruptedMessage(let errorMessage): delegate.didTapCorruptedMessage(errorMessage) case .didTapSessionRefreshMessage(let errorMessage): delegate.didTapSessionRefreshMessage(errorMessage) case .didTapResendGroupUpdate(let errorMessage): delegate.didTapResendGroupUpdateForErrorMessage(errorMessage) case .didTapGroupMigrationLearnMore: delegate.didTapGroupMigrationLearnMore() case .didTapViewGroupDescription(let newGroupDescription): delegate.didTapViewGroupDescription(newGroupDescription: newGroupDescription) case .didTapGroupInviteLinkPromotion(let groupModel): delegate.didTapGroupInviteLinkPromotion(groupModel: groupModel) case .didTapShowConversationSettingsAndShowMemberRequests: delegate.didTapShowConversationSettingsAndShowMemberRequests() case .didTapBlockRequest(let groupModel, let requesterName, let requesterAci): delegate.didTapBlockRequest(groupModel: groupModel, requesterName: requesterName, requesterAci: requesterAci) case .didTapShowUpgradeAppUI: delegate.didTapShowUpgradeAppUI() case .didTapUpdateSystemContact(let address, let newNameComponents): delegate.didTapUpdateSystemContact(address, newNameComponents: newNameComponents) case .didTapPhoneNumberChange(let aci, let phoneNumberOld, let phoneNumberNew): delegate.didTapPhoneNumberChange(aci: aci, phoneNumberOld: phoneNumberOld, phoneNumberNew: phoneNumberNew) case .didTapIndividualCall(let call): delegate.didTapIndividualCall(call) case .didTapLearnMoreMissedCallFromBlockedContact(let call): delegate.didTapLearnMoreMissedCallFromBlockedContact(call) case .didTapGroupCall: delegate.didTapGroupCall() case .didTapSendMessage(let phoneNumbers): delegate.didTapSendMessage(to: phoneNumbers) case .didTapSendInvite(let contactShare): delegate.didTapSendInvite(toContactShare: contactShare) case .didTapAddToContacts(let contactShare): delegate.didTapAddToContacts(contactShare: contactShare) case .didTapUnknownThreadWarningGroup: delegate.didTapUnknownThreadWarningGroup() case .didTapUnknownThreadWarningContact: delegate.didTapUnknownThreadWarningContact() case .didTapDeliveryIssueWarning(let errorMessage): delegate.didTapDeliveryIssueWarning(errorMessage) case .didTapActivatePayments: delegate.didTapActivatePayments() case .didTapSendPayment: delegate.didTapSendPayment() case .didTapThreadMergeLearnMore(let phoneNumber): delegate.didTapThreadMergeLearnMore(phoneNumber: phoneNumber) case .didTapReportSpamLearnMore: delegate.didTapReportSpamLearnMore() } } } }