From 29c4059049101a5386679b4f579f954d5eec233c Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 27 Sep 2017 21:42:58 -0400 Subject: [PATCH 1/4] Rework message metadata view. // FREEBIE --- .../MessageMetadataViewController.swift | 266 ++++++++++++------ Signal/src/util/DateUtil.m | 7 +- Signal/src/util/NSString+OWS.h | 4 + Signal/src/util/NSString+OWS.m | 4 + .../translations/en.lproj/Localizable.strings | 50 ++-- 5 files changed, 204 insertions(+), 127 deletions(-) diff --git a/Signal/src/ViewControllers/MessageMetadataViewController.swift b/Signal/src/ViewControllers/MessageMetadataViewController.swift index eeb204757..b48fb4e6e 100644 --- a/Signal/src/ViewControllers/MessageMetadataViewController.swift +++ b/Signal/src/ViewControllers/MessageMetadataViewController.swift @@ -9,10 +9,19 @@ class MessageMetadataViewController: OWSViewController { static let TAG = "[MessageMetadataViewController]" let TAG = "[MessageMetadataViewController]" + enum MessageRecipientState { + case uploading + case sending + case sent + case delivered + case read + case failed + } + // MARK: Properties let contactsManager: OWSContactsManager - + let databaseConnection: YapDatabaseConnection var message: TSMessage @@ -22,6 +31,7 @@ class MessageMetadataViewController: OWSViewController { var scrollView: UIScrollView? var contentView: UIView? + var attachment: TSAttachment? var dataSource: DataSource? var attachmentStream: TSAttachmentStream? var messageBody: String? @@ -135,6 +145,9 @@ class MessageMetadataViewController: OWSViewController { let contactsManager = Environment.getCurrent().contactsManager! let thread = message.thread + // Content + rows += addContentRows() + // Sender? if let incomingMessage = message as? TSIncomingMessage { let senderId = incomingMessage.authorId @@ -147,32 +160,65 @@ class MessageMetadataViewController: OWSViewController { // Recipient(s) if let outgoingMessage = message as? TSOutgoingMessage { - // TODO: It'd be nice to inset these dividers from the edge of the screen. - let addDivider = { - let divider = UIView() - divider.backgroundColor = UIColor(white:0.9, alpha:1.0) - divider.autoSetDimension(.height, toSize:0.5) - rows.append(divider) - } - - addDivider() - - for recipientId in thread.recipientIdentifiers { - let recipientStatus = self.recipientStatus(forOutgoingMessage: outgoingMessage, recipientId: recipientId) - - let cell = ContactTableViewCell() - cell.configure(withRecipientId: recipientId, contactsManager: self.contactsManager) - let statusLabel = UILabel() - statusLabel.text = recipientStatus - statusLabel.textColor = UIColor.ows_darkGray() - statusLabel.font = UIFont.ows_footnote() - statusLabel.sizeToFit() - cell.accessoryView = statusLabel - cell.autoSetDimension(.height, toSize:ContactTableViewCell.rowHeight()) - cell.setContentHuggingLow() - rows.append(cell) - - addDivider() + let recipientStatusGroups: [MessageRecipientState] = [ + .read, + .uploading, + .delivered, + .sent, + .sending, + .failed + ] + for recipientStatusGroup in recipientStatusGroups { + var groupRows = [UIView]() + + // TODO: It'd be nice to inset these dividers from the edge of the screen. + let addDivider = { + let divider = UIView() + divider.backgroundColor = UIColor(white:0.9, alpha:1.0) + divider.autoSetDimension(.height, toSize:0.5) + groupRows.append(divider) + } + + for recipientId in thread.recipientIdentifiers { + let (recipientStatus, statusMessage) = self.recipientStatus(forOutgoingMessage: outgoingMessage, recipientId: recipientId) + + guard recipientStatus == recipientStatusGroup else { + continue + } + + if groupRows.count < 1 { + groupRows.append(valueRow(name: MessageRecipientStateName(recipientStatusGroup), + value:"")) + + addDivider() + } + + let cell = ContactTableViewCell() + cell.configure(withRecipientId: recipientId, contactsManager: self.contactsManager) + let statusLabel = UILabel() + statusLabel.text = statusMessage + statusLabel.textColor = UIColor.ows_darkGray() + statusLabel.font = UIFont.ows_footnote() + statusLabel.sizeToFit() + cell.accessoryView = statusLabel + cell.autoSetDimension(.height, toSize:ContactTableViewCell.rowHeight()) + cell.setContentHuggingLow() + groupRows.append(cell) + } + + if groupRows.count > 0 { + addDivider() + + let spacer = UIView() + spacer.autoSetDimension(.height, toSize:10) + groupRows.append(spacer) + } + + Logger.verbose("\(groupRows.count) rows for \(recipientStatusGroup)") + guard groupRows.count > 0 else { + continue + } + rows += groupRows } } @@ -180,14 +226,42 @@ class MessageMetadataViewController: OWSViewController { comment: "Label for the 'sent date & time' field of the 'message metadata' view."), value:DateUtil.formatPastTimestampRelativeToNow(message.timestamp))) - if let _ = message as? TSIncomingMessage { + if message as? TSIncomingMessage != nil { rows.append(valueRow(name: NSLocalizedString("MESSAGE_METADATA_VIEW_RECEIVED_DATE_TIME", comment: "Label for the 'received date & time' field of the 'message metadata' view."), value:DateUtil.formatPastTimestampRelativeToNow(message.timestampForSorting()))) } + rows += addAttachmentMetadataRows() + // TODO: We could include the "disappearing messages" state here. + var lastRow: UIView? + for row in rows { + contentView.addSubview(row) + row.autoPinLeadingToSuperView() + row.autoPinTrailingToSuperView() + + if let lastRow = lastRow { + row.autoPinEdge(.top, to:.bottom, of:lastRow, withOffset:5) + } else { + row.autoPinEdge(toSuperviewEdge:.top, withInset:20) + } + + lastRow = row + } + if let lastRow = lastRow { + lastRow.autoPinEdge(toSuperviewEdge:.bottom, withInset:20) + } + + if let mediaMessageView = mediaMessageView { + mediaMessageView.autoPinToSquareAspectRatio() + } + } + + private func addContentRows() -> [UIView] { + var rows = [UIView]() + if message.attachmentIds.count > 0 { rows += addAttachmentRows() } else if let messageBody = message.body { @@ -196,10 +270,6 @@ class MessageMetadataViewController: OWSViewController { if messageBody.characters.count > 0 { self.messageBody = messageBody - rows.append(valueRow(name: NSLocalizedString("MESSAGE_METADATA_VIEW_BODY_LABEL", - comment: "Label for the message body in the 'message metadata' view."), - value:"")) - let bodyLabel = UILabel() bodyLabel.textColor = UIColor.black bodyLabel.font = UIFont.ows_regularFont(withSize:14) @@ -216,27 +286,11 @@ class MessageMetadataViewController: OWSViewController { } } - var lastRow: UIView? - for row in rows { - contentView.addSubview(row) - row.autoPinLeadingToSuperView() - row.autoPinTrailingToSuperView() + let spacer = UIView() + spacer.autoSetDimension(.height, toSize:15) + rows.append(spacer) - if let lastRow = lastRow { - row.autoPinEdge(.top, to:.bottom, of:lastRow, withOffset:5) - } else { - row.autoPinEdge(toSuperviewEdge:.top, withInset:20) - } - - lastRow = row - } - if let lastRow = lastRow { - lastRow.autoPinEdge(toSuperviewEdge:.bottom, withInset:20) - } - - if let mediaMessageView = mediaMessageView { - mediaMessageView.autoPinToSquareAspectRatio() - } + return rows } private func addAttachmentRows() -> [UIView] { @@ -251,17 +305,7 @@ class MessageMetadataViewController: OWSViewController { owsFail("Missing attachment") return rows } - - let contentType = attachment.contentType - rows.append(valueRow(name: NSLocalizedString("MESSAGE_METADATA_VIEW_ATTACHMENT_MIME_TYPE", - comment: "Label for the MIME type of attachments in the 'message metadata' view."), - value:contentType)) - - if let sourceFilename = attachment.sourceFilename { - rows.append(valueRow(name: NSLocalizedString("MESSAGE_METADATA_VIEW_SOURCE_FILENAME", - comment: "Label for the original filename of any attachment in the 'message metadata' view."), - value:sourceFilename)) - } + self.attachment = attachment guard let attachmentStream = attachment as? TSAttachmentStream else { rows.append(valueRow(name: NSLocalizedString("MESSAGE_METADATA_VIEW_ATTACHMENT_NOT_YET_DOWNLOADED", @@ -282,21 +326,8 @@ class MessageMetadataViewController: OWSViewController { return rows } - let fileSize = dataSource.dataLength() - rows.append(valueRow(name: NSLocalizedString("MESSAGE_METADATA_VIEW_ATTACHMENT_FILE_SIZE", - comment: "Label for file size of attachments in the 'message metadata' view."), - value:ViewControllerUtils.formatFileSize(UInt(fileSize)))) - + let contentType = attachment.contentType if let dataUTI = MIMETypeUtil.utiType(forMIMEType:contentType) { - if attachment.isVoiceMessage() { - rows.append(valueRow(name: NSLocalizedString("MESSAGE_METADATA_VIEW_VOICE_MESSAGE", - comment: "Label for voice messages of the 'message metadata' view."), - value:"")) - } else { - rows.append(valueRow(name: NSLocalizedString("MESSAGE_METADATA_VIEW_MEDIA", - comment: "Label for media messages of the 'message metadata' view."), - value:"")) - } let attachment = SignalAttachment(dataSource : dataSource, dataUTI: dataUTI) let mediaMessageView = MediaMessageView(attachment:attachment) self.mediaMessageView = mediaMessageView @@ -305,7 +336,33 @@ class MessageMetadataViewController: OWSViewController { return rows } - private func recipientStatus(forOutgoingMessage message: TSOutgoingMessage, recipientId: String) -> String { + private func addAttachmentMetadataRows() -> [UIView] { + var rows = [UIView]() + + if let attachment = self.attachment { + let contentType = attachment.contentType + rows.append(valueRow(name: NSLocalizedString("MESSAGE_METADATA_VIEW_ATTACHMENT_MIME_TYPE", + comment: "Label for the MIME type of attachments in the 'message metadata' view."), + value:contentType)) + + if let sourceFilename = attachment.sourceFilename { + rows.append(valueRow(name: NSLocalizedString("MESSAGE_METADATA_VIEW_SOURCE_FILENAME", + comment: "Label for the original filename of any attachment in the 'message metadata' view."), + value:sourceFilename)) + } + } + + if let dataSource = self.dataSource { + let fileSize = dataSource.dataLength() + rows.append(valueRow(name: NSLocalizedString("MESSAGE_METADATA_VIEW_ATTACHMENT_FILE_SIZE", + comment: "Label for file size of attachments in the 'message metadata' view."), + value:ViewControllerUtils.formatFileSize(UInt(fileSize)))) + } + + return rows + } + + private func recipientStatus(forOutgoingMessage message: TSOutgoingMessage, recipientId: String) -> (MessageRecipientState, String) { // Legacy messages don't have "recipient read" state or "per-recipient delivery" state, // so we fall back to `TSOutgoingMessageState` which is not per-recipient and therefore // might be misleading. @@ -313,42 +370,49 @@ class MessageMetadataViewController: OWSViewController { let recipientReadMap = message.recipientReadMap if let readTimestamp = recipientReadMap[recipientId] { assert(message.messageState == .sentToService) - return NSLocalizedString("MESSAGE_STATUS_READ", comment:"message footer for read messages").rtlSafeAppend(" ", referenceView:self.view) - .rtlSafeAppend( - DateUtil.formatPastTimestampRelativeToNow(readTimestamp.uint64Value), referenceView:self.view) + let statusMessage = NSLocalizedString("MESSAGE_STATUS_READ", comment:"message footer for read messages").rtlSafeAppend(" ", referenceView:self.view) + .rtlSafeAppend( + DateUtil.formatPastTimestampRelativeToNow(readTimestamp.uint64Value), referenceView:self.view) + return (.read, statusMessage) } let recipientDeliveryMap = message.recipientDeliveryMap if let deliveryTimestamp = recipientDeliveryMap[recipientId] { assert(message.messageState == .sentToService) - return NSLocalizedString("MESSAGE_STATUS_DELIVERED", + let statusMessage = NSLocalizedString("MESSAGE_STATUS_DELIVERED", comment:"message status for message delivered to their recipient.").rtlSafeAppend(" ", referenceView:self.view) .rtlSafeAppend( DateUtil.formatPastTimestampRelativeToNow(deliveryTimestamp.uint64Value), referenceView:self.view) + return (.delivered, statusMessage) } if message.wasDelivered { - return NSLocalizedString("MESSAGE_STATUS_DELIVERED", + let statusMessage = NSLocalizedString("MESSAGE_STATUS_DELIVERED", comment:"message status for message delivered to their recipient.") + return (.delivered, statusMessage) } if message.messageState == .unsent { - return NSLocalizedString("MESSAGE_STATUS_FAILED", comment:"message footer for failed messages") - } else if (message.messageState == .sentToService || - message.wasSent(toRecipient:recipientId)) { - return + let statusMessage = NSLocalizedString("MESSAGE_STATUS_FAILED", comment:"message footer for failed messages") + return (.failed, statusMessage) + } else if message.messageState == .sentToService || + message.wasSent(toRecipient:recipientId) { + let statusMessage = NSLocalizedString("MESSAGE_STATUS_SENT", comment:"message footer for sent messages") + return (.sent, statusMessage) } else if message.hasAttachments() { assert(message.messageState == .attemptingOut) - return NSLocalizedString("MESSAGE_STATUS_UPLOADING", + let statusMessage = NSLocalizedString("MESSAGE_STATUS_UPLOADING", comment:"message footer while attachment is uploading") + return (.uploading, statusMessage) } else { assert(message.messageState == .attemptingOut) - return NSLocalizedString("MESSAGE_STATUS_SENDING", + let statusMessage = NSLocalizedString("MESSAGE_STATUS_SENDING", comment:"message status while message is sending.") + return (.sending, statusMessage) } } @@ -453,7 +517,6 @@ class MessageMetadataViewController: OWSViewController { } internal func yapDatabaseModified(notification: NSNotification) { -// Logger.info("\(TAG) in \(#function)") AssertIsOnMainThread() let notifications = self.databaseConnection.beginLongLivedReadTransaction() @@ -469,4 +532,27 @@ class MessageMetadataViewController: OWSViewController { updateContent() } + + private func MessageRecipientStateName(_ value: MessageRecipientState) -> String { + switch value { + case .uploading: + return NSLocalizedString("MESSAGE_METADATA_VIEW_MESSAGE_STATUS_UPLOADING", + comment: "Status label for messages which are uploading.") + case .sending: + return NSLocalizedString("MESSAGE_METADATA_VIEW_MESSAGE_STATUS_SENDING", + comment: "Status label for messages which are sending.") + case .sent: + return NSLocalizedString("MESSAGE_METADATA_VIEW_MESSAGE_STATUS_SENT", + comment: "Status label for messages which are sent.") + case .delivered: + return NSLocalizedString("MESSAGE_METADATA_VIEW_MESSAGE_STATUS_DELIVERED", + comment: "Status label for messages which are delivered.") + case .read: + return NSLocalizedString("MESSAGE_METADATA_VIEW_MESSAGE_STATUS_READ", + comment: "Status label for messages which are read.") + case .failed: + return NSLocalizedString("MESSAGE_METADATA_VIEW_MESSAGE_STATUS_FAILED", + comment: "Status label for messages which are failed.") + } + } } diff --git a/Signal/src/util/DateUtil.m b/Signal/src/util/DateUtil.m index 802d417a5..31571f866 100644 --- a/Signal/src/util/DateUtil.m +++ b/Signal/src/util/DateUtil.m @@ -70,13 +70,10 @@ static NSString *const DATE_FORMAT_WEEKDAY = @"EEEE"; OWSCAssert(pastTimestamp > 0); uint64_t nowTimestamp = [NSDate ows_millisecondTimeStamp]; - if (pastTimestamp >= nowTimestamp) { - OWSFail(@"%@ Unexpected timestamp", self.tag); - return NSLocalizedString(@"TIME_NOW", @"Indicates that the event happened now."); - } + BOOL isFutureTimestamp = pastTimestamp >= nowTimestamp; NSDate *pastDate = [NSDate ows_dateWithMillisecondsSince1970:pastTimestamp]; - if ([self dateIsToday:pastDate]) { + if (isFutureTimestamp || [self dateIsToday:pastDate]) { return [[self timeFormatter] stringFromDate:pastDate]; } else if (![self dateIsOlderThanOneWeek:pastDate]) { return [[self weekdayFormatter] stringFromDate:pastDate]; diff --git a/Signal/src/util/NSString+OWS.h b/Signal/src/util/NSString+OWS.h index 63fa578fc..c9b938cbb 100644 --- a/Signal/src/util/NSString+OWS.h +++ b/Signal/src/util/NSString+OWS.h @@ -2,6 +2,8 @@ // Copyright (c) 2017 Open Whisper Systems. All rights reserved. // +NS_ASSUME_NONNULL_BEGIN + @interface NSString (OWS) - (NSString *)ows_stripped; @@ -9,3 +11,5 @@ - (NSString *)rtlSafeAppend:(NSString *)string referenceView:(UIView *)referenceView; @end + +NS_ASSUME_NONNULL_END diff --git a/Signal/src/util/NSString+OWS.m b/Signal/src/util/NSString+OWS.m index 50ac43e63..45ae7db25 100644 --- a/Signal/src/util/NSString+OWS.m +++ b/Signal/src/util/NSString+OWS.m @@ -5,6 +5,8 @@ #import "NSString+OWS.h" #import "UIView+OWS.h" +NS_ASSUME_NONNULL_BEGIN + @implementation NSString (OWS) - (NSString *)ows_stripped @@ -25,3 +27,5 @@ } @end + +NS_ASSUME_NONNULL_END diff --git a/Signal/translations/en.lproj/Localizable.strings b/Signal/translations/en.lproj/Localizable.strings index ad7a00a46..3e33c1b10 100644 --- a/Signal/translations/en.lproj/Localizable.strings +++ b/Signal/translations/en.lproj/Localizable.strings @@ -796,24 +796,33 @@ /* Label for 'not yet downloaded' attachments in the 'message metadata' view. */ "MESSAGE_METADATA_VIEW_ATTACHMENT_NOT_YET_DOWNLOADED" = "Not yet downloaded"; -/* Label for the message body in the 'message metadata' view. */ -"MESSAGE_METADATA_VIEW_BODY_LABEL" = "Message"; - -/* Label for the 'group name' field of the 'message metadata' view. */ -"MESSAGE_METADATA_VIEW_GROUP_NAME" = "Group"; - /* Label for media messages of the 'message metadata' view. */ "MESSAGE_METADATA_VIEW_MEDIA" = "Media"; +/* Delivered */ +"MESSAGE_METADATA_VIEW_MESSAGE_STATUS_DELIVERED" = "Delivered"; + +/* Failed */ +"MESSAGE_METADATA_VIEW_MESSAGE_STATUS_FAILED" = "Failed"; + +/* Read */ +"MESSAGE_METADATA_VIEW_MESSAGE_STATUS_READ" = "Read"; + +/* Sending */ +"MESSAGE_METADATA_VIEW_MESSAGE_STATUS_SENDING" = "Sending"; + +/* Sent */ +"MESSAGE_METADATA_VIEW_MESSAGE_STATUS_SENT" = "Sent"; + +/* Uploading */ +"MESSAGE_METADATA_VIEW_MESSAGE_STATUS_UPLOADING" = "Uploading"; + /* Label for messages without a body or attachment in the 'message metadata' view. */ "MESSAGE_METADATA_VIEW_NO_ATTACHMENT_OR_BODY" = "Message has no content or attachment."; /* Label for the 'received date & time' field of the 'message metadata' view. */ "MESSAGE_METADATA_VIEW_RECEIVED_DATE_TIME" = "Received"; -/* Label for the 'recipient' field of the 'message metadata' view. */ -"MESSAGE_METADATA_VIEW_RECIPIENT" = "Recipient"; - /* Label for the 'sender' field of the 'message metadata' view. */ "MESSAGE_METADATA_VIEW_SENDER" = "Sender"; @@ -1442,9 +1451,6 @@ /* An explanation of the 'read receipts' setting. */ "SETTINGS_READ_RECEIPTS_SECTION_FOOTER" = "Read receipts let you see when others have read your message - and let them see when you have read their messages."; -/* Title of the 'read receipts' settings section. */ -"SETTINGS_READ_RECEIPTS_SECTION_TITLE" = "Read Receipts"; - /* No comment provided by engineer. */ "SETTINGS_SCREEN_SECURITY" = "Enable Screen Security"; @@ -1517,9 +1523,6 @@ /* {{number of weeks}}, embedded in strings, e.g. 'Alice updated disappearing messages expiration to {{5 weeks}}'. See other *_TIME_AMOUNT strings */ "TIME_AMOUNT_WEEKS" = "%@ weeks"; -/* Indicates that the event happened now. */ -"TIME_NOW" = "Now"; - /* Label for the cancel button in an alert or action sheet. */ "TXT_CANCEL_TITLE" = "Cancel"; @@ -1663,20 +1666,3 @@ /* Info message embedding a {{time amount}}, see the *_TIME_AMOUNT strings for context. */ "YOU_UPDATED_DISAPPEARING_MESSAGES_CONFIGURATION" = "You set disappearing message time to %@."; - -// Strings Copied in from JSQMessagesViewController - - -"load_earlier_messages" = "Load Earlier Messages"; - -"send" = "Send"; - -"new_message" = "New Message"; - -"text_message_accessibility_label" = "%@: %@"; - -"media_message_accessibility_label" = "%@: media message"; - -"accessory_button_accessibility_label" = "Share media"; - -"new_message_received_accessibility_announcement" = "New message received"; From de29b5a6ee7a6f812b1eb810f42a7f71d4a4d731 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 27 Sep 2017 22:05:01 -0400 Subject: [PATCH 2/4] Rework message metadata view. // FREEBIE --- .../MessageMetadataViewController.swift | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/Signal/src/ViewControllers/MessageMetadataViewController.swift b/Signal/src/ViewControllers/MessageMetadataViewController.swift index b48fb4e6e..eed5b07a4 100644 --- a/Signal/src/ViewControllers/MessageMetadataViewController.swift +++ b/Signal/src/ViewControllers/MessageMetadataViewController.swift @@ -270,13 +270,29 @@ class MessageMetadataViewController: OWSViewController { if messageBody.characters.count > 0 { self.messageBody = messageBody + let isIncoming = self.message as? TSIncomingMessage != nil + let bodyLabel = UILabel() - bodyLabel.textColor = UIColor.black - bodyLabel.font = UIFont.ows_regularFont(withSize:14) + bodyLabel.textColor = isIncoming ? UIColor.black : UIColor.white + bodyLabel.font = UIFont.ows_regularFont(withSize:16) bodyLabel.text = messageBody - bodyLabel.numberOfLines = 0 + bodyLabel.numberOfLines = 10 bodyLabel.lineBreakMode = .byWordWrapping - rows.append(bodyLabel) + + let bubbleView = UIView() + bubbleView.backgroundColor = isIncoming ? UIColor.gray : UIColor.ows_materialBlue() + bubbleView.layer.cornerRadius = 10 + bubbleView.addSubview(bodyLabel) + bodyLabel.autoPinLeadingToSuperView(withMargin:10) + bodyLabel.autoPinTrailingToSuperView(withMargin:10) + bodyLabel.autoPinHeightToSuperview(withMargin:10) + + let row = UIView() + row.addSubview(bubbleView) + bubbleView.autoPinLeadingToSuperView(withMargin:10) + bubbleView.autoPinTrailingToSuperView(withMargin:10) + bubbleView.autoPinHeightToSuperview() + rows.append(row) } else { // Neither attachment nor body. owsFail("\(self.TAG) Message has neither attachment nor body.") From 26c8c4e1fac41025794272a37db1a8c409635a75 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 27 Sep 2017 22:25:50 -0400 Subject: [PATCH 3/4] Rework message metadata view. // FREEBIE --- .../MessageMetadataViewController.swift | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/Signal/src/ViewControllers/MessageMetadataViewController.swift b/Signal/src/ViewControllers/MessageMetadataViewController.swift index eed5b07a4..890e93fcf 100644 --- a/Signal/src/ViewControllers/MessageMetadataViewController.swift +++ b/Signal/src/ViewControllers/MessageMetadataViewController.swift @@ -276,22 +276,40 @@ class MessageMetadataViewController: OWSViewController { bodyLabel.textColor = isIncoming ? UIColor.black : UIColor.white bodyLabel.font = UIFont.ows_regularFont(withSize:16) bodyLabel.text = messageBody + // Only show the first N lines. bodyLabel.numberOfLines = 10 bodyLabel.lineBreakMode = .byWordWrapping let bubbleView = UIView() - bubbleView.backgroundColor = isIncoming ? UIColor.gray : UIColor.ows_materialBlue() + bubbleView.backgroundColor = isIncoming ? UIColor.jsq_messageBubbleLightGray() : UIColor.ows_materialBlue() bubbleView.layer.cornerRadius = 10 bubbleView.addSubview(bodyLabel) bodyLabel.autoPinLeadingToSuperView(withMargin:10) bodyLabel.autoPinTrailingToSuperView(withMargin:10) bodyLabel.autoPinHeightToSuperview(withMargin:10) + let bubbleSpacer = UIView() + let row = UIView() row.addSubview(bubbleView) - bubbleView.autoPinLeadingToSuperView(withMargin:10) - bubbleView.autoPinTrailingToSuperView(withMargin:10) + row.addSubview(bubbleSpacer) + bubbleView.autoPinHeightToSuperview() + bubbleView.setContentHuggingHorizontalHigh() + bubbleView.setCompressionResistanceHigh() + bubbleSpacer.autoPinHeightToSuperview() + bubbleSpacer.setContentHuggingLow() + + if isIncoming { + bubbleView.autoPinLeadingToSuperView(withMargin:10) + bubbleSpacer.autoPinLeading(toTrailingOf:bubbleView) + bubbleSpacer.autoPinTrailingToSuperView(withMargin:10) + } else { + bubbleSpacer.autoPinLeadingToSuperView(withMargin:10) + bubbleView.autoPinLeading(toTrailingOf:bubbleSpacer) + bubbleView.autoPinTrailingToSuperView(withMargin:10) + } + rows.append(row) } else { // Neither attachment nor body. From 2dce0e9b1b3c1302c14f1c59bec2f559ebf60250 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Thu, 28 Sep 2017 10:09:54 -0400 Subject: [PATCH 4/4] Respond to CR. // FREEBIE --- .../MessageMetadataViewController.swift | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Signal/src/ViewControllers/MessageMetadataViewController.swift b/Signal/src/ViewControllers/MessageMetadataViewController.swift index 890e93fcf..1281680f9 100644 --- a/Signal/src/ViewControllers/MessageMetadataViewController.swift +++ b/Signal/src/ViewControllers/MessageMetadataViewController.swift @@ -146,7 +146,7 @@ class MessageMetadataViewController: OWSViewController { let thread = message.thread // Content - rows += addContentRows() + rows += contentRows() // Sender? if let incomingMessage = message as? TSIncomingMessage { @@ -180,7 +180,7 @@ class MessageMetadataViewController: OWSViewController { } for recipientId in thread.recipientIdentifiers { - let (recipientStatus, statusMessage) = self.recipientStatus(forOutgoingMessage: outgoingMessage, recipientId: recipientId) + let (recipientStatus, statusMessage) = self.recipientStatus(outgoingMessage: outgoingMessage, recipientId: recipientId) guard recipientStatus == recipientStatusGroup else { continue @@ -259,7 +259,7 @@ class MessageMetadataViewController: OWSViewController { } } - private func addContentRows() -> [UIView] { + private func contentRows() -> [UIView] { var rows = [UIView]() if message.attachmentIds.count > 0 { @@ -396,23 +396,23 @@ class MessageMetadataViewController: OWSViewController { return rows } - private func recipientStatus(forOutgoingMessage message: TSOutgoingMessage, recipientId: String) -> (MessageRecipientState, String) { + private func recipientStatus(outgoingMessage: TSOutgoingMessage, recipientId: String) -> (MessageRecipientState, String) { // Legacy messages don't have "recipient read" state or "per-recipient delivery" state, // so we fall back to `TSOutgoingMessageState` which is not per-recipient and therefore // might be misleading. - let recipientReadMap = message.recipientReadMap + let recipientReadMap = outgoingMessage.recipientReadMap if let readTimestamp = recipientReadMap[recipientId] { - assert(message.messageState == .sentToService) + assert(outgoingMessage.messageState == .sentToService) let statusMessage = NSLocalizedString("MESSAGE_STATUS_READ", comment:"message footer for read messages").rtlSafeAppend(" ", referenceView:self.view) .rtlSafeAppend( DateUtil.formatPastTimestampRelativeToNow(readTimestamp.uint64Value), referenceView:self.view) return (.read, statusMessage) } - let recipientDeliveryMap = message.recipientDeliveryMap + let recipientDeliveryMap = outgoingMessage.recipientDeliveryMap if let deliveryTimestamp = recipientDeliveryMap[recipientId] { - assert(message.messageState == .sentToService) + assert(outgoingMessage.messageState == .sentToService) let statusMessage = NSLocalizedString("MESSAGE_STATUS_DELIVERED", comment:"message status for message delivered to their recipient.").rtlSafeAppend(" ", referenceView:self.view) .rtlSafeAppend( @@ -420,29 +420,29 @@ class MessageMetadataViewController: OWSViewController { return (.delivered, statusMessage) } - if message.wasDelivered { + if outgoingMessage.wasDelivered { let statusMessage = NSLocalizedString("MESSAGE_STATUS_DELIVERED", comment:"message status for message delivered to their recipient.") return (.delivered, statusMessage) } - if message.messageState == .unsent { + if outgoingMessage.messageState == .unsent { let statusMessage = NSLocalizedString("MESSAGE_STATUS_FAILED", comment:"message footer for failed messages") return (.failed, statusMessage) - } else if message.messageState == .sentToService || + } else if outgoingMessage.messageState == .sentToService || message.wasSent(toRecipient:recipientId) { let statusMessage = NSLocalizedString("MESSAGE_STATUS_SENT", comment:"message footer for sent messages") return (.sent, statusMessage) } else if message.hasAttachments() { - assert(message.messageState == .attemptingOut) + assert(outgoingMessage.messageState == .attemptingOut) let statusMessage = NSLocalizedString("MESSAGE_STATUS_UPLOADING", comment:"message footer while attachment is uploading") return (.uploading, statusMessage) } else { - assert(message.messageState == .attemptingOut) + assert(outgoingMessage.messageState == .attemptingOut) let statusMessage = NSLocalizedString("MESSAGE_STATUS_SENDING", comment:"message status while message is sending.")