190 lines
9.1 KiB
Swift
190 lines
9.1 KiB
Swift
//
|
|
// Copyright 2019 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
import Foundation
|
|
import LibSignalClient
|
|
|
|
extension TSInfoMessage {
|
|
|
|
// MARK: - Convenience initializers
|
|
|
|
public convenience init(
|
|
thread: TSThread,
|
|
messageType: TSInfoMessageType,
|
|
timestamp: UInt64 = MessageTimestampGenerator.sharedInstance.generateTimestamp(),
|
|
expireTimerVersion: UInt32? = nil,
|
|
expiresInSeconds: UInt32? = nil,
|
|
infoMessageUserInfo: [InfoMessageUserInfoKey: Any]? = nil,
|
|
) {
|
|
self.init(
|
|
thread: thread,
|
|
timestamp: timestamp,
|
|
serverGuid: nil,
|
|
messageType: messageType,
|
|
expireTimerVersion: expireTimerVersion as NSNumber?,
|
|
expiresInSeconds: expiresInSeconds ?? 0,
|
|
infoMessageUserInfo: infoMessageUserInfo,
|
|
)
|
|
}
|
|
|
|
@objc
|
|
func _infoMessagePreviewText(tx: DBReadTransaction) -> String {
|
|
switch messageType {
|
|
case .typeLocalUserEndedSession:
|
|
fallthrough
|
|
case .typeRemoteUserEndedSession:
|
|
return OWSLocalizedString("SECURE_SESSION_RESET", comment: "")
|
|
case .typeUnsupportedMessage:
|
|
return OWSLocalizedString("UNSUPPORTED_ATTACHMENT", comment: "")
|
|
case .userNotRegistered:
|
|
if let unregisteredAddress, unregisteredAddress.isValid {
|
|
let recipientName = SSKEnvironment.shared.contactManagerRef.displayNameString(for: unregisteredAddress, transaction: tx)
|
|
return String.nonPluralLocalizedStringWithFormat(
|
|
OWSLocalizedString(
|
|
"ERROR_UNREGISTERED_USER_FORMAT",
|
|
comment: "Format string for 'unregistered user' error. Embeds {{the unregistered user's name or signal id}}.",
|
|
),
|
|
recipientName,
|
|
)
|
|
} else {
|
|
return OWSLocalizedString("CONTACT_DETAIL_COMM_TYPE_INSECURE", comment: "")
|
|
}
|
|
case .typeGroupQuit:
|
|
return OWSLocalizedString("GROUP_YOU_LEFT", comment: "")
|
|
case .typeGroupUpdate:
|
|
return self.groupUpdateDescription(tx: tx).string
|
|
case .addToContactsOffer:
|
|
return OWSLocalizedString("ADD_TO_CONTACTS_OFFER", comment: "Message shown in conversation view that offers to add an unknown user to your phone's contacts.")
|
|
case .verificationStateChange:
|
|
return OWSLocalizedString("VERIFICATION_STATE_CHANGE_GENERIC", comment: "Generic message indicating that verification state changed for a given user.")
|
|
case .addUserToProfileWhitelistOffer:
|
|
return OWSLocalizedString("ADD_USER_TO_PROFILE_WHITELIST_OFFER", comment: "Message shown in conversation view that offers to share your profile with a user.")
|
|
case .addGroupToProfileWhitelistOffer:
|
|
return OWSLocalizedString("ADD_GROUP_TO_PROFILE_WHITELIST_OFFER", comment: "Message shown in conversation view that offers to share your profile with a group.")
|
|
case .typeDisappearingMessagesUpdate:
|
|
break
|
|
case .unknownProtocolVersion:
|
|
break
|
|
case .userJoinedSignal:
|
|
let address = TSContactThread.contactAddress(fromThreadId: self.uniqueThreadId, transaction: tx)
|
|
let recipientName = SSKEnvironment.shared.contactManagerRef.displayNameString(for: address!, transaction: tx)
|
|
let format = OWSLocalizedString("INFO_MESSAGE_USER_JOINED_SIGNAL_BODY_FORMAT", comment: "Shown in inbox and conversation when a user joins Signal, embeds the new user's {{contact name}}")
|
|
return String.nonPluralLocalizedStringWithFormat(format, recipientName)
|
|
case .syncedThread:
|
|
return ""
|
|
case .profileUpdate:
|
|
return self.profileChangeDescription(tx: tx)
|
|
case .phoneNumberChange:
|
|
guard let aci = self.phoneNumberChangeInfoAci() else {
|
|
owsFailDebug("Invalid info message")
|
|
return ""
|
|
}
|
|
let address = SignalServiceAddress(aci.wrappedAciValue)
|
|
let userName = SSKEnvironment.shared.contactManagerRef.displayNameString(for: address, transaction: tx)
|
|
let format = OWSLocalizedString(
|
|
"INFO_MESSAGE_USER_CHANGED_PHONE_NUMBER_FORMAT",
|
|
comment: "Indicates that another user has changed their phone number. Embeds: {{ the user's name}}",
|
|
)
|
|
return String.nonPluralLocalizedStringWithFormat(format, userName)
|
|
case .recipientHidden:
|
|
/// This does not control whether to show the info message in the chat
|
|
/// preview. To control that, see ``TSInteraction.shouldAppearInInbox``.
|
|
let address = TSContactThread.contactAddress(fromThreadId: self.uniqueThreadId, transaction: tx)
|
|
if DependenciesBridge.shared.recipientHidingManager.isHiddenAddress(address!, tx: tx) {
|
|
return OWSLocalizedString(
|
|
"INFO_MESSAGE_CONTACT_REMOVED",
|
|
comment: "Indicates that the recipient has been removed from the current user's contacts and that messaging them will re-add them.",
|
|
)
|
|
} else {
|
|
return OWSLocalizedString(
|
|
"INFO_MESSAGE_CONTACT_REINSTATED",
|
|
comment: "Indicates that a previously-removed recipient has been added back to the current user's contacts.",
|
|
)
|
|
}
|
|
case .paymentsActivationRequest:
|
|
return self.paymentsActivationRequestDescription(tx: tx) ?? ""
|
|
case .paymentsActivated:
|
|
return self.paymentsActivatedDescription(tx: tx) ?? ""
|
|
case .threadMerge:
|
|
return self.threadMergeDescription(tx: tx)
|
|
case .sessionSwitchover:
|
|
return self.sessionSwitchoverDescription(tx: tx)
|
|
case .reportedSpam:
|
|
return OWSLocalizedString(
|
|
"INFO_MESSAGE_REPORTED_SPAM",
|
|
comment: "Shown when a user reports a conversation as spam.",
|
|
)
|
|
case .learnedProfileName:
|
|
return self.learnedProfileNameDescription(tx: tx)
|
|
case .blockedOtherUser:
|
|
return OWSLocalizedString(
|
|
"INFO_MESSAGE_BLOCKED_OTHER_USER",
|
|
comment: "An info message inserted into a 1:1 chat when you block another user.",
|
|
)
|
|
case .blockedGroup:
|
|
return OWSLocalizedString(
|
|
"INFO_MESSAGE_BLOCKED_GROUP",
|
|
comment: "An info message inserted into a group chat when you block the group.",
|
|
)
|
|
case .unblockedOtherUser:
|
|
return OWSLocalizedString(
|
|
"INFO_MESSAGE_UNBLOCKED_OTHER_USER",
|
|
comment: "An info message inserted into a 1:1 chat when you unblock another user.",
|
|
)
|
|
case .unblockedGroup:
|
|
return OWSLocalizedString(
|
|
"INFO_MESSAGE_UNBLOCKED_GROUP",
|
|
comment: "An info message inserted into a group chat when you unblock the group.",
|
|
)
|
|
case .acceptedMessageRequest:
|
|
let thread = TSThread.fetchViaCache(uniqueId: self.uniqueThreadId, transaction: tx)
|
|
if let thread, thread.isGroupThread {
|
|
return OWSLocalizedString(
|
|
"INFO_MESSAGE_ACCEPTED_MESSAGE_REQUEST_GROUP",
|
|
comment: "An info message inserted into the chat when you accept a message request in a group chat.",
|
|
)
|
|
}
|
|
if let address = TSContactThread.contactAddress(fromThreadId: self.uniqueThreadId, transaction: tx) {
|
|
let recipientName = SSKEnvironment.shared.contactManagerRef.displayNameString(for: address, transaction: tx)
|
|
let format = OWSLocalizedString(
|
|
"INFO_MESSAGE_ACCEPTED_MESSAGE_REQUEST_ONE_ON_ONE",
|
|
comment: "An info message inserted into the chat when you accept a message request in a 1:1. {{ Embeds name of your chat partner }}.",
|
|
)
|
|
return String.nonPluralLocalizedStringWithFormat(format, recipientName)
|
|
}
|
|
owsFailDebug("No contact address for message request that is not in a group thread")
|
|
return OWSLocalizedString(
|
|
"INFO_MESSAGE_ACCEPTED_MESSAGE_REQUEST",
|
|
comment: "An info message inserted into the chat when you accept a message request, in a 1:1 or group chat.",
|
|
)
|
|
case .typeEndPoll:
|
|
return self.endPollDescription(transaction: tx) ?? ""
|
|
case .typePinnedMessage:
|
|
return self.pinnedMessageDescription(transaction: tx) ?? ""
|
|
}
|
|
|
|
owsFailDebug("Unknown info message type")
|
|
return ""
|
|
}
|
|
|
|
// MARK: - InfoMessageUserInfo
|
|
|
|
func infoMessageValue<T>(forKey key: InfoMessageUserInfoKey) -> T? {
|
|
guard let value = infoMessageUserInfo?[key] as? T else {
|
|
return nil
|
|
}
|
|
|
|
return value
|
|
}
|
|
|
|
func setInfoMessageValue(_ value: Any, forKey key: InfoMessageUserInfoKey) {
|
|
if self.infoMessageUserInfo != nil {
|
|
self.infoMessageUserInfo![key] = value
|
|
} else {
|
|
self.infoMessageUserInfo = [key: value]
|
|
}
|
|
}
|
|
}
|