Merge pull request #769 from mpretty-cyro/feature/read-status-updates

Added the updated delivery status UI
pull/772/head
RyanZhao 2 years ago committed by GitHub
commit a5cc813dd5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -9,15 +9,17 @@ import SessionMessagingKit
import SignalUtilitiesKit
private protocol TableViewTouchDelegate {
func tableViewWasTouched(_ tableView: TableView)
func tableViewWasTouched(_ tableView: TableView, withView hitView: UIView?)
}
private final class TableView: UITableView {
var touchDelegate: TableViewTouchDelegate?
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
touchDelegate?.tableViewWasTouched(self)
return super.hitTest(point, with: event)
let resultingView: UIView? = super.hitTest(point, with: event)
touchDelegate?.tableViewWasTouched(self, withView: resultingView)
return resultingView
}
}
@ -275,10 +277,23 @@ final class NewClosedGroupVC: BaseVC, UITableViewDataSource, UITableViewDelegate
)
}
fileprivate func tableViewWasTouched(_ tableView: TableView) {
fileprivate func tableViewWasTouched(_ tableView: TableView, withView hitView: UIView?) {
if nameTextField.isFirstResponder {
nameTextField.resignFirstResponder()
}
else if searchBar.isFirstResponder {
var hitSuperview: UIView? = hitView?.superview
while hitSuperview != nil && hitSuperview != searchBar {
hitSuperview = hitSuperview?.superview
}
// If the user hit the cancel button then do nothing (we want to let the cancel
// button remove the focus or it will instantly refocus)
if hitSuperview == searchBar { return }
searchBar.resignFirstResponder()
}
}
@objc private func close() {

@ -142,18 +142,33 @@ final class VisibleMessageCell: MessageCell, TappableLabelDelegate {
private lazy var reactionContainerView = ReactionContainerView()
internal lazy var messageStatusContainerView: UIView = {
let result = UIView()
return result
}()
internal lazy var messageStatusLabel: UILabel = {
let result = UILabel()
result.accessibilityLabel = "Message sent status"
result.font = .systemFont(ofSize: Values.verySmallFontSize)
result.themeTextColor = .messageBubble_deliveryStatus
return result
}()
internal lazy var messageStatusImageView: UIImageView = {
let result = UIImageView()
result.accessibilityLabel = "Message sent status tick"
result.contentMode = .scaleAspectFit
result.layer.cornerRadius = VisibleMessageCell.messageStatusImageViewSize / 2
result.layer.masksToBounds = true
result.themeTintColor = .messageBubble_deliveryStatus
return result
}()
// MARK: - Settings
private static let messageStatusImageViewSize: CGFloat = 16
private static let messageStatusImageViewSize: CGFloat = 12
private static let authorLabelBottomSpacing: CGFloat = 4
private static let groupThreadHSpacing: CGFloat = 12
private static let profilePictureSize = Values.verySmallProfilePictureSize
@ -236,13 +251,22 @@ final class VisibleMessageCell: MessageCell, TappableLabelDelegate {
underBubbleStackView.pin(.bottom, to: .bottom, of: self)
underBubbleStackView.addArrangedSubview(reactionContainerView)
underBubbleStackView.addArrangedSubview(messageStatusImageView)
underBubbleStackView.addArrangedSubview(messageStatusContainerView)
messageStatusContainerView.addSubview(messageStatusLabel)
messageStatusContainerView.addSubview(messageStatusImageView)
reactionContainerView.widthAnchor
.constraint(lessThanOrEqualTo: underBubbleStackView.widthAnchor)
.isActive = true
messageStatusImageView.pin(.top, to: .top, of: messageStatusContainerView)
messageStatusImageView.pin(.bottom, to: .bottom, of: messageStatusContainerView)
messageStatusImageView.pin(.trailing, to: .trailing, of: messageStatusContainerView)
messageStatusImageView.set(.width, to: VisibleMessageCell.messageStatusImageViewSize)
messageStatusImageView.set(.height, to: VisibleMessageCell.messageStatusImageViewSize)
messageStatusLabel.center(.vertical, in: messageStatusContainerView)
messageStatusLabel.pin(.leading, to: .leading, of: messageStatusContainerView)
messageStatusLabel.pin(.trailing, to: .leading, of: messageStatusImageView, withInset: -2)
}
override func setUpGestureRecognizers() {
@ -389,13 +413,15 @@ final class VisibleMessageCell: MessageCell, TappableLabelDelegate {
)
// Message status image view
let (image, tintColor) = cellViewModel.state.statusIconInfo(
let (image, statusText, tintColor) = cellViewModel.state.statusIconInfo(
variant: cellViewModel.variant,
hasAtLeastOneReadReceipt: cellViewModel.hasAtLeastOneReadReceipt
)
messageStatusLabel.text = statusText
messageStatusLabel.themeTextColor = tintColor
messageStatusImageView.image = image
messageStatusImageView.themeTintColor = tintColor
messageStatusImageView.isHidden = (
messageStatusContainerView.isHidden = (
cellViewModel.variant != .standardOutgoing ||
cellViewModel.variant == .infoCall ||
(

@ -596,3 +596,7 @@
"MESSAGE_STATE_READ" = "Read";
"MESSAGE_STATE_SENT" = "Sent";
"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request";
"MESSAGE_DELIVERY_STATUS_SENDING" = "Sending";
"MESSAGE_DELIVERY_STATUS_SENT" = "Sent";
"MESSAGE_DELIVERY_STATUS_READ" = "Read";
"MESSAGE_DELIVERY_STATUS_FAILED" = "Failed to send";

@ -596,3 +596,7 @@
"MESSAGE_STATE_READ" = "Read";
"MESSAGE_STATE_SENT" = "Sent";
"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request";
"MESSAGE_DELIVERY_STATUS_SENDING" = "Sending";
"MESSAGE_DELIVERY_STATUS_SENT" = "Sent";
"MESSAGE_DELIVERY_STATUS_READ" = "Read";
"MESSAGE_DELIVERY_STATUS_FAILED" = "Failed to send";

@ -596,3 +596,7 @@
"MESSAGE_STATE_READ" = "Read";
"MESSAGE_STATE_SENT" = "Sent";
"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request";
"MESSAGE_DELIVERY_STATUS_SENDING" = "Sending";
"MESSAGE_DELIVERY_STATUS_SENT" = "Sent";
"MESSAGE_DELIVERY_STATUS_READ" = "Read";
"MESSAGE_DELIVERY_STATUS_FAILED" = "Failed to send";

@ -596,3 +596,7 @@
"MESSAGE_STATE_READ" = "خوانده شد";
"MESSAGE_STATE_SENT" = "ارسال شد";
"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request";
"MESSAGE_DELIVERY_STATUS_SENDING" = "Sending";
"MESSAGE_DELIVERY_STATUS_SENT" = "Sent";
"MESSAGE_DELIVERY_STATUS_READ" = "Read";
"MESSAGE_DELIVERY_STATUS_FAILED" = "Failed to send";

@ -596,3 +596,7 @@
"MESSAGE_STATE_READ" = "Read";
"MESSAGE_STATE_SENT" = "Sent";
"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request";
"MESSAGE_DELIVERY_STATUS_SENDING" = "Sending";
"MESSAGE_DELIVERY_STATUS_SENT" = "Sent";
"MESSAGE_DELIVERY_STATUS_READ" = "Read";
"MESSAGE_DELIVERY_STATUS_FAILED" = "Failed to send";

@ -596,3 +596,7 @@
"MESSAGE_STATE_READ" = "Read";
"MESSAGE_STATE_SENT" = "Sent";
"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request";
"MESSAGE_DELIVERY_STATUS_SENDING" = "Sending";
"MESSAGE_DELIVERY_STATUS_SENT" = "Sent";
"MESSAGE_DELIVERY_STATUS_READ" = "Read";
"MESSAGE_DELIVERY_STATUS_FAILED" = "Failed to send";

@ -596,3 +596,7 @@
"MESSAGE_STATE_READ" = "Read";
"MESSAGE_STATE_SENT" = "Sent";
"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request";
"MESSAGE_DELIVERY_STATUS_SENDING" = "Sending";
"MESSAGE_DELIVERY_STATUS_SENT" = "Sent";
"MESSAGE_DELIVERY_STATUS_READ" = "Read";
"MESSAGE_DELIVERY_STATUS_FAILED" = "Failed to send";

@ -596,3 +596,7 @@
"MESSAGE_STATE_READ" = "Read";
"MESSAGE_STATE_SENT" = "Sent";
"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request";
"MESSAGE_DELIVERY_STATUS_SENDING" = "Sending";
"MESSAGE_DELIVERY_STATUS_SENT" = "Sent";
"MESSAGE_DELIVERY_STATUS_READ" = "Read";
"MESSAGE_DELIVERY_STATUS_FAILED" = "Failed to send";

@ -596,3 +596,7 @@
"MESSAGE_STATE_READ" = "Read";
"MESSAGE_STATE_SENT" = "Sent";
"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request";
"MESSAGE_DELIVERY_STATUS_SENDING" = "Sending";
"MESSAGE_DELIVERY_STATUS_SENT" = "Sent";
"MESSAGE_DELIVERY_STATUS_READ" = "Read";
"MESSAGE_DELIVERY_STATUS_FAILED" = "Failed to send";

@ -596,3 +596,7 @@
"MESSAGE_STATE_READ" = "Read";
"MESSAGE_STATE_SENT" = "Sent";
"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request";
"MESSAGE_DELIVERY_STATUS_SENDING" = "Sending";
"MESSAGE_DELIVERY_STATUS_SENT" = "Sent";
"MESSAGE_DELIVERY_STATUS_READ" = "Read";
"MESSAGE_DELIVERY_STATUS_FAILED" = "Failed to send";

@ -596,3 +596,7 @@
"MESSAGE_STATE_READ" = "Read";
"MESSAGE_STATE_SENT" = "Sent";
"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request";
"MESSAGE_DELIVERY_STATUS_SENDING" = "Sending";
"MESSAGE_DELIVERY_STATUS_SENT" = "Sent";
"MESSAGE_DELIVERY_STATUS_READ" = "Read";
"MESSAGE_DELIVERY_STATUS_FAILED" = "Failed to send";

@ -596,3 +596,7 @@
"MESSAGE_STATE_READ" = "Read";
"MESSAGE_STATE_SENT" = "Sent";
"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request";
"MESSAGE_DELIVERY_STATUS_SENDING" = "Sending";
"MESSAGE_DELIVERY_STATUS_SENT" = "Sent";
"MESSAGE_DELIVERY_STATUS_READ" = "Read";
"MESSAGE_DELIVERY_STATUS_FAILED" = "Failed to send";

@ -596,3 +596,7 @@
"MESSAGE_STATE_READ" = "Read";
"MESSAGE_STATE_SENT" = "Sent";
"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request";
"MESSAGE_DELIVERY_STATUS_SENDING" = "Sending";
"MESSAGE_DELIVERY_STATUS_SENT" = "Sent";
"MESSAGE_DELIVERY_STATUS_READ" = "Read";
"MESSAGE_DELIVERY_STATUS_FAILED" = "Failed to send";

@ -596,3 +596,7 @@
"MESSAGE_STATE_READ" = "Read";
"MESSAGE_STATE_SENT" = "Sent";
"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request";
"MESSAGE_DELIVERY_STATUS_SENDING" = "Sending";
"MESSAGE_DELIVERY_STATUS_SENT" = "Sent";
"MESSAGE_DELIVERY_STATUS_READ" = "Read";
"MESSAGE_DELIVERY_STATUS_FAILED" = "Failed to send";

@ -596,3 +596,7 @@
"MESSAGE_STATE_READ" = "Read";
"MESSAGE_STATE_SENT" = "Sent";
"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request";
"MESSAGE_DELIVERY_STATUS_SENDING" = "Sending";
"MESSAGE_DELIVERY_STATUS_SENT" = "Sent";
"MESSAGE_DELIVERY_STATUS_READ" = "Read";
"MESSAGE_DELIVERY_STATUS_FAILED" = "Failed to send";

@ -596,3 +596,7 @@
"MESSAGE_STATE_READ" = "Read";
"MESSAGE_STATE_SENT" = "Sent";
"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request";
"MESSAGE_DELIVERY_STATUS_SENDING" = "Sending";
"MESSAGE_DELIVERY_STATUS_SENT" = "Sent";
"MESSAGE_DELIVERY_STATUS_READ" = "Read";
"MESSAGE_DELIVERY_STATUS_FAILED" = "Failed to send";

@ -596,3 +596,7 @@
"MESSAGE_STATE_READ" = "Read";
"MESSAGE_STATE_SENT" = "Sent";
"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request";
"MESSAGE_DELIVERY_STATUS_SENDING" = "Sending";
"MESSAGE_DELIVERY_STATUS_SENT" = "Sent";
"MESSAGE_DELIVERY_STATUS_READ" = "Read";
"MESSAGE_DELIVERY_STATUS_FAILED" = "Failed to send";

@ -596,3 +596,7 @@
"MESSAGE_STATE_READ" = "Read";
"MESSAGE_STATE_SENT" = "Sent";
"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request";
"MESSAGE_DELIVERY_STATUS_SENDING" = "Sending";
"MESSAGE_DELIVERY_STATUS_SENT" = "Sent";
"MESSAGE_DELIVERY_STATUS_READ" = "Read";
"MESSAGE_DELIVERY_STATUS_FAILED" = "Failed to send";

@ -596,3 +596,7 @@
"MESSAGE_STATE_READ" = "Read";
"MESSAGE_STATE_SENT" = "Sent";
"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request";
"MESSAGE_DELIVERY_STATUS_SENDING" = "Sending";
"MESSAGE_DELIVERY_STATUS_SENT" = "Sent";
"MESSAGE_DELIVERY_STATUS_READ" = "Read";
"MESSAGE_DELIVERY_STATUS_FAILED" = "Failed to send";

@ -596,3 +596,7 @@
"MESSAGE_STATE_READ" = "Read";
"MESSAGE_STATE_SENT" = "Sent";
"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request";
"MESSAGE_DELIVERY_STATUS_SENDING" = "Sending";
"MESSAGE_DELIVERY_STATUS_SENT" = "Sent";
"MESSAGE_DELIVERY_STATUS_READ" = "Read";
"MESSAGE_DELIVERY_STATUS_FAILED" = "Failed to send";

@ -596,3 +596,7 @@
"MESSAGE_STATE_READ" = "Read";
"MESSAGE_STATE_SENT" = "Sent";
"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request";
"MESSAGE_DELIVERY_STATUS_SENDING" = "Sending";
"MESSAGE_DELIVERY_STATUS_SENT" = "Sent";
"MESSAGE_DELIVERY_STATUS_READ" = "Read";
"MESSAGE_DELIVERY_STATUS_FAILED" = "Failed to send";

@ -596,3 +596,7 @@
"MESSAGE_STATE_READ" = "Read";
"MESSAGE_STATE_SENT" = "Sent";
"MESSAGE_REQUEST_PENDING_APPROVAL_INFO" = "You will be able to send voice messages and attachments once the recipient has approved this message request";
"MESSAGE_DELIVERY_STATUS_SENDING" = "Sending";
"MESSAGE_DELIVERY_STATUS_SENT" = "Sent";
"MESSAGE_DELIVERY_STATUS_READ" = "Read";
"MESSAGE_DELIVERY_STATUS_FAILED" = "Failed to send";

@ -104,7 +104,6 @@ public final class FullConversationCell: UITableViewCell {
let result: UIImageView = UIImageView()
result.clipsToBounds = true
result.contentMode = .scaleAspectFit
result.layer.cornerRadius = (FullConversationCell.statusIndicatorSize / 2)
return result
}()

@ -65,16 +65,37 @@ public struct RecipientState: Codable, Equatable, FetchableRecord, PersistableRe
}
}
public func statusIconInfo(variant: Interaction.Variant, hasAtLeastOneReadReceipt: Bool) -> (image: UIImage?, themeTintColor: ThemeValue) {
guard variant == .standardOutgoing else { return (nil, .textPrimary) }
public func statusIconInfo(variant: Interaction.Variant, hasAtLeastOneReadReceipt: Bool) -> (image: UIImage?, text: String?, themeTintColor: ThemeValue) {
guard variant == .standardOutgoing else { return (nil, nil, .textPrimary) }
switch (self, hasAtLeastOneReadReceipt) {
case (.sending, _): return (UIImage(systemName: "ellipsis.circle"), .textPrimary)
case (.sending, _):
return (
UIImage(systemName: "ellipsis.circle"),
"MESSAGE_DELIVERY_STATUS_SENDING".localized(),
.messageBubble_deliveryStatus
)
case (.sent, false), (.skipped, _):
return (UIImage(systemName: "checkmark.circle"), .textPrimary)
return (
UIImage(systemName: "checkmark.circle"),
"MESSAGE_DELIVERY_STATUS_SENT".localized(),
.messageBubble_deliveryStatus
)
case (.sent, true):
return (
UIImage(systemName: "eye.fill"),
"MESSAGE_DELIVERY_STATUS_READ".localized(),
.messageBubble_deliveryStatus
)
case (.sent, true): return (UIImage(systemName: "checkmark.circle.fill"), .textPrimary)
case (.failed, _): return (UIImage(systemName: "exclamationmark.circle"), .danger)
case (.failed, _):
return (
UIImage(systemName: "exclamationmark.triangle"),
"MESSAGE_DELIVERY_STATUS_FAILED".localized(),
.danger
)
}
}
}

@ -34,6 +34,7 @@ internal enum Theme_ClassicDark: ThemeColors {
.messageBubble_outgoingText: .classicDark0,
.messageBubble_incomingText: .classicDark6,
.messageBubble_overlay: .black_06,
.messageBubble_deliveryStatus: .classicDark5,
// MenuButton
.menuButton_background: .primary,

@ -34,6 +34,7 @@ internal enum Theme_ClassicLight: ThemeColors {
.messageBubble_outgoingText: .classicLight0,
.messageBubble_incomingText: .classicLight0,
.messageBubble_overlay: .black_06,
.messageBubble_deliveryStatus: .classicLight1,
// MenuButton
.menuButton_background: .primary,

@ -34,6 +34,7 @@ internal enum Theme_OceanDark: ThemeColors {
.messageBubble_outgoingText: .oceanDark0,
.messageBubble_incomingText: .oceanDark7,
.messageBubble_overlay: .black_06,
.messageBubble_deliveryStatus: .oceanDark5,
// MenuButton
.menuButton_background: .primary,

@ -34,6 +34,7 @@ internal enum Theme_OceanLight: ThemeColors {
.messageBubble_outgoingText: .oceanLight1,
.messageBubble_incomingText: .oceanLight1,
.messageBubble_overlay: .black_06,
.messageBubble_deliveryStatus: .oceanLight2,
// MenuButton
.menuButton_background: .primary,

@ -122,6 +122,7 @@ public indirect enum ThemeValue: Hashable {
case messageBubble_outgoingText
case messageBubble_incomingText
case messageBubble_overlay
case messageBubble_deliveryStatus
// MenuButton
case menuButton_background

Loading…
Cancel
Save