session-ios/Signal/src/ViewControllers/Utils/MessageRecipientStatusUtils.swift

163 lines
8.7 KiB
Swift
Raw Normal View History

//
2018-02-13 19:06:08 +01:00
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
import Foundation
import SignalServiceKit
import SignalMessaging
2018-05-25 23:17:15 +02:00
@objc public enum MessageReceiptStatus: Int {
case uploading
case sending
case sent
case delivered
case read
case failed
2018-04-23 16:30:51 +02:00
case skipped
}
2018-04-24 22:18:25 +02:00
@objc
public class MessageRecipientStatusUtils: NSObject {
// MARK: Initializers
@available(*, unavailable, message:"do not instantiate this class.")
private override init() {
}
2018-04-24 22:38:35 +02:00
// This method is per-recipient.
2018-05-25 23:17:15 +02:00
@objc
public class func recipientStatus(outgoingMessage: TSOutgoingMessage,
2018-04-24 22:18:25 +02:00
recipientState: TSOutgoingMessageRecipientState,
2018-04-24 22:38:35 +02:00
referenceView: UIView) -> MessageReceiptStatus {
let (messageReceiptStatus, _, _) = recipientStatusAndStatusMessage(outgoingMessage: outgoingMessage,
2018-04-24 22:18:25 +02:00
recipientState: recipientState,
referenceView: referenceView)
2018-04-24 22:38:35 +02:00
return messageReceiptStatus
}
2018-04-24 22:38:35 +02:00
// This method is per-recipient.
2018-04-24 22:18:25 +02:00
@objc
2018-02-13 19:06:08 +01:00
public class func shortStatusMessage(outgoingMessage: TSOutgoingMessage,
2018-04-24 22:18:25 +02:00
recipientState: TSOutgoingMessageRecipientState,
2018-02-13 19:06:08 +01:00
referenceView: UIView) -> String {
let (_, shortStatusMessage, _) = recipientStatusAndStatusMessage(outgoingMessage: outgoingMessage,
2018-04-24 22:18:25 +02:00
recipientState: recipientState,
2018-02-13 19:06:08 +01:00
referenceView: referenceView)
return shortStatusMessage
}
2018-04-24 22:38:35 +02:00
// This method is per-recipient.
2018-04-24 22:18:25 +02:00
@objc
2018-02-13 19:06:08 +01:00
public class func longStatusMessage(outgoingMessage: TSOutgoingMessage,
2018-04-24 22:18:25 +02:00
recipientState: TSOutgoingMessageRecipientState,
2018-02-13 19:06:08 +01:00
referenceView: UIView) -> String {
let (_, _, longStatusMessage) = recipientStatusAndStatusMessage(outgoingMessage: outgoingMessage,
2018-04-24 22:18:25 +02:00
recipientState: recipientState,
2018-02-13 19:06:08 +01:00
referenceView: referenceView)
return longStatusMessage
}
2018-04-24 22:38:35 +02:00
// This method is per-recipient.
2018-04-24 22:18:25 +02:00
class func recipientStatusAndStatusMessage(outgoingMessage: TSOutgoingMessage,
recipientState: TSOutgoingMessageRecipientState,
2018-04-24 22:38:35 +02:00
referenceView: UIView) -> (status: MessageReceiptStatus, shortStatusMessage: String, longStatusMessage: String) {
2018-04-23 16:30:51 +02:00
switch recipientState.state {
case .failed:
let shortStatusMessage = NSLocalizedString("MESSAGE_STATUS_FAILED_SHORT", comment: "status message for failed messages")
let longStatusMessage = NSLocalizedString("MESSAGE_STATUS_FAILED", comment: "message footer for failed messages")
return (status:.failed, shortStatusMessage:shortStatusMessage, longStatusMessage:longStatusMessage)
case .sending:
if outgoingMessage.hasAttachments() {
assert(outgoingMessage.messageState == .sending)
2018-04-23 16:30:51 +02:00
let statusMessage = NSLocalizedString("MESSAGE_STATUS_UPLOADING",
comment: "message footer while attachment is uploading")
return (status:.uploading, shortStatusMessage:statusMessage, longStatusMessage:statusMessage)
} else {
assert(outgoingMessage.messageState == .sending)
2018-04-23 16:30:51 +02:00
let statusMessage = NSLocalizedString("MESSAGE_STATUS_SENDING",
comment: "message status while message is sending.")
return (status:.sending, shortStatusMessage:statusMessage, longStatusMessage:statusMessage)
}
case .sent:
if let readTimestamp = recipientState.readTimestamp {
let timestampString = DateUtil.formatPastTimestampRelativeToNow(readTimestamp.uint64Value,
isRTL: referenceView.isRTL())
let shortStatusMessage = timestampString
let longStatusMessage = NSLocalizedString("MESSAGE_STATUS_READ", comment: "message footer for read messages").rtlSafeAppend(" ", referenceView: referenceView)
.rtlSafeAppend(timestampString, referenceView: referenceView)
return (status:.read, shortStatusMessage:shortStatusMessage, longStatusMessage:longStatusMessage)
}
if let deliveryTimestamp = recipientState.deliveryTimestamp {
let timestampString = DateUtil.formatPastTimestampRelativeToNow(deliveryTimestamp.uint64Value,
isRTL: referenceView.isRTL())
let shortStatusMessage = timestampString
let longStatusMessage = NSLocalizedString("MESSAGE_STATUS_DELIVERED",
comment: "message status for message delivered to their recipient.").rtlSafeAppend(" ", referenceView: referenceView)
.rtlSafeAppend(timestampString, referenceView: referenceView)
return (status:.delivered, shortStatusMessage:shortStatusMessage, longStatusMessage:longStatusMessage)
}
let statusMessage =
NSLocalizedString("MESSAGE_STATUS_SENT",
2018-04-23 16:30:51 +02:00
comment: "message footer for sent messages")
2018-02-13 19:06:08 +01:00
return (status:.sent, shortStatusMessage:statusMessage, longStatusMessage:statusMessage)
2018-04-23 16:30:51 +02:00
case .skipped:
let statusMessage = NSLocalizedString("MESSAGE_STATUS_RECIPIENT_SKIPPED",
2018-06-21 19:24:36 +02:00
comment: "message status if message delivery to a recipient is skipped. We skip delivering group messages to users who have left the group or unregistered their Signal account.")
2018-04-23 16:30:51 +02:00
return (status:.skipped, shortStatusMessage:statusMessage, longStatusMessage:statusMessage)
}
}
2018-04-24 22:38:35 +02:00
// This method is per-message.
internal class func receiptStatusAndMessage(outgoingMessage: TSOutgoingMessage,
referenceView: UIView) -> (status: MessageReceiptStatus, message: String) {
2017-11-03 19:40:47 +01:00
switch outgoingMessage.messageState {
2018-04-23 16:30:51 +02:00
case .failed:
// Use the "long" version of this message here.
2018-04-24 22:38:35 +02:00
return (.failed, NSLocalizedString("MESSAGE_STATUS_FAILED", comment: "message footer for failed messages"))
2018-04-23 16:30:51 +02:00
case .sending:
if outgoingMessage.hasAttachments() {
2018-04-24 22:38:35 +02:00
return (.uploading, NSLocalizedString("MESSAGE_STATUS_UPLOADING",
comment: "message footer while attachment is uploading"))
} else {
2018-04-24 22:38:35 +02:00
return (.sending, NSLocalizedString("MESSAGE_STATUS_SENDING",
comment: "message status while message is sending."))
}
2018-04-23 16:30:51 +02:00
case .sent:
if outgoingMessage.readRecipientIds().count > 0 {
2018-04-24 22:38:35 +02:00
return (.read, NSLocalizedString("MESSAGE_STATUS_READ", comment: "message footer for read messages"))
2017-11-03 19:40:47 +01:00
}
if outgoingMessage.wasDeliveredToAnyRecipient {
2018-04-24 22:38:35 +02:00
return (.delivered, NSLocalizedString("MESSAGE_STATUS_DELIVERED",
comment: "message status for message delivered to their recipient."))
2017-11-03 19:40:47 +01:00
}
2018-04-24 22:38:35 +02:00
return (.sent, NSLocalizedString("MESSAGE_STATUS_SENT",
comment: "message footer for sent messages"))
2017-11-03 19:40:47 +01:00
default:
2018-04-24 21:49:08 +02:00
owsFail("\(self.logTag) Message has unexpected status: \(outgoingMessage.messageState).")
2018-04-24 22:38:35 +02:00
return (.sent, NSLocalizedString("MESSAGE_STATUS_SENT",
comment: "message footer for sent messages"))
}
}
2018-04-24 22:38:35 +02:00
// This method is per-message.
2018-05-25 23:17:15 +02:00
@objc
2018-04-24 22:38:35 +02:00
public class func receiptMessage(outgoingMessage: TSOutgoingMessage,
referenceView: UIView) -> String {
let (_, message ) = receiptStatusAndMessage(outgoingMessage: outgoingMessage,
referenceView: referenceView)
return message
}
2018-04-24 22:38:35 +02:00
// This method is per-message.
2018-05-25 23:17:15 +02:00
@objc
public class func recipientStatus(outgoingMessage: TSOutgoingMessage, referenceView: UIView) -> MessageReceiptStatus {
2018-04-24 22:38:35 +02:00
let (status, _ ) = receiptStatusAndMessage(outgoingMessage: outgoingMessage,
referenceView: referenceView)
return status
}
}