From d34e53a163a8b15c1ff5476631ff366a90f0657a Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 26 Jun 2018 11:51:01 -0400 Subject: [PATCH 1/5] Breaks: unread indicators and date headers. --- .../ConversationView/Cells/OWSMessageCell.m | 48 +++++++++++++------ .../Cells/OWSUnreadIndicatorCell.m | 6 +-- .../translations/en.lproj/Localizable.strings | 2 +- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m index 0abe0763f..daf145a6d 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m @@ -22,6 +22,8 @@ NS_ASSUME_NONNULL_BEGIN // * footerView (below message) @property (nonatomic) OWSMessageBubbleView *messageBubbleView; +@property (nonatomic) UIView *dateHeaderView; +@property (nonatomic) UIView *dateStrokeView; @property (nonatomic) UILabel *dateHeaderLabel; @property (nonatomic) AvatarImageView *avatarView; @@ -55,11 +57,24 @@ NS_ASSUME_NONNULL_BEGIN self.messageBubbleView = [OWSMessageBubbleView new]; [self.contentView addSubview:self.messageBubbleView]; + self.dateHeaderView = [UIView new]; + + self.dateStrokeView = [UIView new]; + self.dateStrokeView.backgroundColor = [UIColor lightGrayColor]; + [self.dateHeaderView addSubview:self.dateStrokeView]; + self.dateHeaderLabel = [UILabel new]; self.dateHeaderLabel.font = self.dateHeaderDateFont; self.dateHeaderLabel.textAlignment = NSTextAlignmentCenter; self.dateHeaderLabel.textColor = [UIColor lightGrayColor]; - [self.contentView addSubview:self.dateHeaderLabel]; + [self.dateHeaderView addSubview:self.dateHeaderLabel]; + + [self.dateStrokeView autoPinWidthToSuperview]; + [self.dateStrokeView autoSetDimension:ALDimensionHeight toSize:1.f]; + [self.dateHeaderLabel autoPinWidthToSuperview]; + [self.dateHeaderLabel autoVCenterInSuperview]; + // TODO: offset. + [self.dateStrokeView autoPinEdge:ALEdgeBottom toEdge:ALEdgeTop ofView:self.dateHeaderLabel withOffset:0.f]; self.avatarView = [[AvatarImageView alloc] init]; [self.contentView addSubview:self.avatarView]; @@ -67,10 +82,8 @@ NS_ASSUME_NONNULL_BEGIN [self.avatarView autoSetDimension:ALDimensionHeight toSize:self.avatarSize]; // Hide these views by default. - self.dateHeaderLabel.hidden = YES; self.avatarView.hidden = YES; - [self.messageBubbleView autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:self.dateHeaderLabel]; [self.messageBubbleView autoPinBottomToSuperviewMarginWithInset:0]; self.contentView.userInteractionEnabled = YES; @@ -244,20 +257,19 @@ NS_ASSUME_NONNULL_BEGIN referenceView:self]; self.dateHeaderLabel.attributedText = attributedText; - self.dateHeaderLabel.hidden = NO; + [self.contentView addSubview:self.dateHeaderView]; [self.viewConstraints addObjectsFromArray:@[ - // TODO: Are data headers symmetric or are they asymmetric? gutters are asymmetric? - [self.dateHeaderLabel autoPinLeadingToSuperviewMarginWithInset:self.conversationStyle.gutterLeading], - [self.dateHeaderLabel autoPinTrailingToSuperviewMarginWithInset:self.conversationStyle.gutterTrailing], - [self.dateHeaderLabel autoPinEdgeToSuperviewEdge:ALEdgeTop], - [self.dateHeaderLabel autoSetDimension:ALDimensionHeight toSize:self.dateHeaderHeight], + [self.dateHeaderView autoPinLeadingToSuperviewMarginWithInset:self.conversationStyle.gutterLeading], + [self.dateHeaderView autoPinTrailingToSuperviewMarginWithInset:self.conversationStyle.gutterTrailing], + [self.dateHeaderView autoPinEdgeToSuperviewEdge:ALEdgeTop], + [self.dateHeaderView autoSetDimension:ALDimensionHeight toSize:self.dateHeaderHeight], + + [self.messageBubbleView autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:self.dateHeaderView], ]]; } else { - self.dateHeaderLabel.hidden = YES; [self.viewConstraints addObjectsFromArray:@[ - [self.dateHeaderLabel autoSetDimension:ALDimensionHeight toSize:0], - [self.dateHeaderLabel autoPinEdgeToSuperviewEdge:ALEdgeTop], + [self.messageBubbleView autoPinEdgeToSuperviewEdge:ALEdgeTop], ]]; } } @@ -365,11 +377,17 @@ NS_ASSUME_NONNULL_BEGIN return cellSize; } +- (CGFloat)dateHeaderVSpacing +{ + return 24.f; +} + - (CGFloat)dateHeaderHeight { if (self.viewItem.shouldShowDate) { // Add 5pt spacing above and below the date header. - return (CGFloat)ceil(MAX(self.dateHeaderDateFont.lineHeight, self.dateHeaderTimeFont.lineHeight) + 10.f); + CGFloat textHeight = MAX(self.dateHeaderDateFont.capHeight, self.dateHeaderTimeFont.capHeight); + return (CGFloat)ceil(textHeight + self.dateHeaderVSpacing * 2); } else { return 0.f; } @@ -387,8 +405,8 @@ NS_ASSUME_NONNULL_BEGIN [self.messageBubbleView prepareForReuse]; [self.messageBubbleView unloadContent]; - self.dateHeaderLabel.text = nil; - self.dateHeaderLabel.hidden = YES; + [self.dateHeaderView removeFromSuperview]; + self.avatarView.image = nil; self.avatarView.hidden = YES; diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSUnreadIndicatorCell.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSUnreadIndicatorCell.m index c8d5918b1..eed8a6ee5 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSUnreadIndicatorCell.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSUnreadIndicatorCell.m @@ -45,12 +45,12 @@ NS_ASSUME_NONNULL_BEGIN self.strokeView = [UIView new]; // TODO: color. - self.strokeView.backgroundColor = [UIColor colorWithRGBHex:0xf6eee3]; + self.strokeView.backgroundColor = [UIColor blackColor]; [self.contentView addSubview:self.strokeView]; self.titleLabel = [UILabel new]; // TODO: color. - self.titleLabel.textColor = [UIColor colorWithRGBHex:0x403e3b]; + self.titleLabel.textColor = [UIColor blackColor]; self.titleLabel.textAlignment = NSTextAlignmentCenter; [self.contentView addSubview:self.titleLabel]; @@ -62,7 +62,7 @@ NS_ASSUME_NONNULL_BEGIN // Update cell to reflect changes in dynamic text. // // TODO: Font size. - self.titleLabel.font = UIFont.ows_dynamicTypeSubheadlineFont; + self.titleLabel.font = UIFont.ows_dynamicTypeCaption1Font.ows_bold; } + (NSString *)cellReuseIdentifier diff --git a/Signal/translations/en.lproj/Localizable.strings b/Signal/translations/en.lproj/Localizable.strings index 20d1ace60..1fe891a60 100644 --- a/Signal/translations/en.lproj/Localizable.strings +++ b/Signal/translations/en.lproj/Localizable.strings @@ -1257,7 +1257,7 @@ "MESSAGES_VIEW_TITLE_SUBTITLE" = "Tap here for settings"; /* Indicator that separates read from unread messages. */ -"MESSAGES_VIEW_UNREAD_INDICATOR" = "Unread Messages"; +"MESSAGES_VIEW_UNREAD_INDICATOR" = "New Messages"; /* Messages that indicates that there are more unseen messages including safety number changes that be revealed by tapping the 'load earlier messages' button. Embeds {{the name of the 'load earlier messages' button}}. */ "MESSAGES_VIEW_UNREAD_INDICATOR_HAS_MORE_UNSEEN_MESSAGES_AND_SAFETY_NUMBER_CHANGES_FORMAT" = "There are more unread messages (including safety number changes) above. Tap \"%@\" to see them."; From 4b60037e3537830fa75d5f1eedada0a3a80cc6c2 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 26 Jun 2018 13:20:43 -0400 Subject: [PATCH 2/5] Breaks: unread indicators and date headers. --- .../ConversationView/Cells/OWSMessageCell.m | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m index daf145a6d..0875e5ecf 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m @@ -77,13 +77,9 @@ NS_ASSUME_NONNULL_BEGIN [self.dateStrokeView autoPinEdge:ALEdgeBottom toEdge:ALEdgeTop ofView:self.dateHeaderLabel withOffset:0.f]; self.avatarView = [[AvatarImageView alloc] init]; - [self.contentView addSubview:self.avatarView]; [self.avatarView autoSetDimension:ALDimensionWidth toSize:self.avatarSize]; [self.avatarView autoSetDimension:ALDimensionHeight toSize:self.avatarSize]; - // Hide these views by default. - self.avatarView.hidden = YES; - [self.messageBubbleView autoPinBottomToSuperviewMarginWithInset:0]; self.contentView.userInteractionEnabled = YES; @@ -193,8 +189,6 @@ NS_ASSUME_NONNULL_BEGIN ofView:self.avatarView withOffset:avatarBottomMargin], ]]; - [self.messageBubbleView logFrameLaterWithLabel:@"messageBubbleView"]; - [self.avatarView logFrameLaterWithLabel:@"avatarView"]; } } @@ -310,7 +304,7 @@ NS_ASSUME_NONNULL_BEGIN diameter:self.avatarSize contactsManager:contactsManager]; self.avatarView.image = [avatarBuilder build]; - self.avatarView.hidden = NO; + [self.contentView addSubview:self.avatarView]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(otherUsersProfileDidChange:) @@ -408,7 +402,7 @@ NS_ASSUME_NONNULL_BEGIN [self.dateHeaderView removeFromSuperview]; self.avatarView.image = nil; - self.avatarView.hidden = YES; + [self.avatarView removeFromSuperview]; [self hideMenuControllerIfNecessary]; From a4703cec76b8322c07a5a54015c8a8f4e9c66b5d Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 26 Jun 2018 13:53:35 -0400 Subject: [PATCH 3/5] Breaks: unread indicators and date headers. --- .../ConversationView/Cells/OWSMessageCell.m | 5 +- .../Cells/OWSUnreadIndicatorCell.m | 55 ++++++++++++++++++- .../translations/en.lproj/Localizable.strings | 4 +- 3 files changed, 56 insertions(+), 8 deletions(-) diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m index 0875e5ecf..82d2e0983 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m @@ -73,8 +73,7 @@ NS_ASSUME_NONNULL_BEGIN [self.dateStrokeView autoSetDimension:ALDimensionHeight toSize:1.f]; [self.dateHeaderLabel autoPinWidthToSuperview]; [self.dateHeaderLabel autoVCenterInSuperview]; - // TODO: offset. - [self.dateStrokeView autoPinEdge:ALEdgeBottom toEdge:ALEdgeTop ofView:self.dateHeaderLabel withOffset:0.f]; + [self.dateStrokeView autoPinEdge:ALEdgeBottom toEdge:ALEdgeTop ofView:self.dateHeaderLabel]; self.avatarView = [[AvatarImageView alloc] init]; [self.avatarView autoSetDimension:ALDimensionWidth toSize:self.avatarSize]; @@ -232,7 +231,7 @@ NS_ASSUME_NONNULL_BEGIN NSString *timeString = [dateHeaderTimeFormatter stringFromDate:date]; NSAttributedString *attributedText = [NSAttributedString new]; - attributedText = [attributedText rtlSafeAppend:dateString + attributedText = [attributedText rtlSafeAppend:dateString.uppercaseString attributes:@{ NSFontAttributeName : self.dateHeaderDateFont, NSForegroundColorAttributeName : [UIColor lightGrayColor], diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSUnreadIndicatorCell.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSUnreadIndicatorCell.m index eed8a6ee5..a10569713 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSUnreadIndicatorCell.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSUnreadIndicatorCell.m @@ -17,6 +17,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, nullable) TSUnreadIndicatorInteraction *interaction; @property (nonatomic) UILabel *titleLabel; +@property (nonatomic) UILabel *subtitleLabel; @property (nonatomic) UIView *strokeView; @property (nonatomic) NSArray *layoutConstraints; @@ -54,6 +55,15 @@ NS_ASSUME_NONNULL_BEGIN self.titleLabel.textAlignment = NSTextAlignmentCenter; [self.contentView addSubview:self.titleLabel]; + self.subtitleLabel = [UILabel new]; + // TODO: color. + self.subtitleLabel.textColor = [UIColor lightGrayColor]; + // The subtitle may wrap to a second line. + self.subtitleLabel.numberOfLines = 0; + self.subtitleLabel.lineBreakMode = NSLineBreakByWordWrapping; + self.subtitleLabel.textAlignment = NSTextAlignmentCenter; + [self.contentView addSubview:self.subtitleLabel]; + [self configureFonts]; } @@ -62,7 +72,8 @@ NS_ASSUME_NONNULL_BEGIN // Update cell to reflect changes in dynamic text. // // TODO: Font size. - self.titleLabel.font = UIFont.ows_dynamicTypeCaption1Font.ows_bold; + self.titleLabel.font = UIFont.ows_dynamicTypeCaption1Font.ows_mediumWeight; + self.subtitleLabel.font = UIFont.ows_dynamicTypeCaption1Font; } + (NSString *)cellReuseIdentifier @@ -81,6 +92,7 @@ NS_ASSUME_NONNULL_BEGIN TSUnreadIndicatorInteraction *interaction = (TSUnreadIndicatorInteraction *)self.viewItem.interaction; self.titleLabel.text = [self titleForInteraction:interaction]; + self.subtitleLabel.text = [self subtitleForInteraction:interaction]; self.backgroundColor = [UIColor whiteColor]; @@ -90,11 +102,17 @@ NS_ASSUME_NONNULL_BEGIN [self.titleLabel autoPinLeadingToSuperviewMarginWithInset:self.conversationStyle.fullWidthGutterLeading], [self.titleLabel autoPinTrailingToSuperviewMarginWithInset:self.conversationStyle.fullWidthGutterTrailing], - // TODO: offset. - [self.strokeView autoPinEdge:ALEdgeBottom toEdge:ALEdgeTop ofView:self.titleLabel withOffset:0.f], + [self.strokeView autoPinEdge:ALEdgeBottom toEdge:ALEdgeTop ofView:self.titleLabel], [self.strokeView autoPinLeadingToSuperviewMarginWithInset:self.conversationStyle.fullWidthGutterLeading], [self.strokeView autoPinTrailingToSuperviewMarginWithInset:self.conversationStyle.fullWidthGutterTrailing], [self.strokeView autoSetDimension:ALDimensionHeight toSize:1.f], + + [self.subtitleLabel autoPinEdge:ALEdgeTop + toEdge:ALEdgeBottom + ofView:self.titleLabel + withOffset:self.subtitleVSpacing], + [self.subtitleLabel autoPinLeadingToSuperviewMarginWithInset:self.conversationStyle.fullWidthGutterLeading], + [self.subtitleLabel autoPinTrailingToSuperviewMarginWithInset:self.conversationStyle.fullWidthGutterTrailing], ]; } @@ -104,6 +122,28 @@ NS_ASSUME_NONNULL_BEGIN .uppercaseString; } +- (NSString *)subtitleForInteraction:(TSUnreadIndicatorInteraction *)interaction +{ + if (!interaction.hasMoreUnseenMessages) { + return nil; + } + return (interaction.missingUnseenSafetyNumberChangeCount > 0 + ? NSLocalizedString(@"MESSAGES_VIEW_UNREAD_INDICATOR_HAS_MORE_UNSEEN_MESSAGES", + @"Messages that indicates that there are more unseen messages.") + : NSLocalizedString(@"MESSAGES_VIEW_UNREAD_INDICATOR_HAS_MORE_UNSEEN_MESSAGES_AND_SAFETY_NUMBER_CHANGES", + @"Messages that indicates that there are more unseen messages including safety number changes.")); +} + +- (CGFloat)subtitleHMargin +{ + return 20.f; +} + +- (CGFloat)subtitleVSpacing +{ + return 3.f; +} + - (CGSize)cellSizeWithTransaction:(YapDatabaseReadTransaction *)transaction { OWSAssert(self.conversationStyle); @@ -117,6 +157,15 @@ NS_ASSUME_NONNULL_BEGIN CGSize result = CGSizeMake(self.conversationStyle.fullWidthContentWidth, self.titleLabel.font.lineHeight + vOffset * 2); + TSUnreadIndicatorInteraction *interaction = (TSUnreadIndicatorInteraction *)self.viewItem.interaction; + self.subtitleLabel.text = [self subtitleForInteraction:interaction]; + if (self.subtitleLabel.text.length > 0) { + result.height += self.subtitleVSpacing; + result.height += ceil( + [self.subtitleLabel sizeThatFits:CGSizeMake(self.conversationStyle.fullWidthContentWidth, CGFLOAT_MAX)] + .height); + } + return CGSizeCeil(result); } diff --git a/Signal/translations/en.lproj/Localizable.strings b/Signal/translations/en.lproj/Localizable.strings index 1fe891a60..c7c73a7c5 100644 --- a/Signal/translations/en.lproj/Localizable.strings +++ b/Signal/translations/en.lproj/Localizable.strings @@ -1260,10 +1260,10 @@ "MESSAGES_VIEW_UNREAD_INDICATOR" = "New Messages"; /* Messages that indicates that there are more unseen messages including safety number changes that be revealed by tapping the 'load earlier messages' button. Embeds {{the name of the 'load earlier messages' button}}. */ -"MESSAGES_VIEW_UNREAD_INDICATOR_HAS_MORE_UNSEEN_MESSAGES_AND_SAFETY_NUMBER_CHANGES_FORMAT" = "There are more unread messages (including safety number changes) above. Tap \"%@\" to see them."; +"MESSAGES_VIEW_UNREAD_INDICATOR_HAS_MORE_UNSEEN_MESSAGES_AND_SAFETY_NUMBER_CHANGES" = "There are more unread messages (including safety number changes)."; /* Messages that indicates that there are more unseen messages that be revealed by tapping the 'load earlier messages' button. Embeds {{the name of the 'load earlier messages' button}} */ -"MESSAGES_VIEW_UNREAD_INDICATOR_HAS_MORE_UNSEEN_MESSAGES_FORMAT" = "There are more unread messages above. Tap \"%@\" to see them."; +"MESSAGES_VIEW_UNREAD_INDICATOR_HAS_MORE_UNSEEN_MESSAGES" = "There are more unread messages."; /* notification title */ "MISSED_CALL" = "Missed call"; From 4fc24540dcc748cdc06fdc16d7aaac99c35eb22f Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 26 Jun 2018 13:54:26 -0400 Subject: [PATCH 4/5] Breaks: unread indicators and date headers. --- .../ConversationView/Cells/OWSUnreadIndicatorCell.m | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSUnreadIndicatorCell.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSUnreadIndicatorCell.m index a10569713..46ec6d38f 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSUnreadIndicatorCell.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSUnreadIndicatorCell.m @@ -134,11 +134,6 @@ NS_ASSUME_NONNULL_BEGIN @"Messages that indicates that there are more unseen messages including safety number changes.")); } -- (CGFloat)subtitleHMargin -{ - return 20.f; -} - - (CGFloat)subtitleVSpacing { return 3.f; From d04ee35216d48819b440e6dad635d6c48c8d7694 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 27 Jun 2018 09:27:09 -0400 Subject: [PATCH 5/5] Respond to CR. --- .../ConversationView/Cells/OWSMessageCell.m | 1 - Signal/translations/en.lproj/Localizable.strings | 11 ++++------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m index 82d2e0983..d815afea6 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m @@ -378,7 +378,6 @@ NS_ASSUME_NONNULL_BEGIN - (CGFloat)dateHeaderHeight { if (self.viewItem.shouldShowDate) { - // Add 5pt spacing above and below the date header. CGFloat textHeight = MAX(self.dateHeaderDateFont.capHeight, self.dateHeaderTimeFont.capHeight); return (CGFloat)ceil(textHeight + self.dateHeaderVSpacing * 2); } else { diff --git a/Signal/translations/en.lproj/Localizable.strings b/Signal/translations/en.lproj/Localizable.strings index c7c73a7c5..674cc0466 100644 --- a/Signal/translations/en.lproj/Localizable.strings +++ b/Signal/translations/en.lproj/Localizable.strings @@ -1112,9 +1112,6 @@ /* table cell label in conversation settings */ "LIST_GROUP_MEMBERS_ACTION" = "Group Members"; -/* Label for button that loads more messages in conversation view. */ -"load_earlier_messages" = "Load Earlier Messages"; - /* No comment provided by engineer. */ "LOGGING_SECTION" = "Logging"; @@ -1259,12 +1256,12 @@ /* Indicator that separates read from unread messages. */ "MESSAGES_VIEW_UNREAD_INDICATOR" = "New Messages"; -/* Messages that indicates that there are more unseen messages including safety number changes that be revealed by tapping the 'load earlier messages' button. Embeds {{the name of the 'load earlier messages' button}}. */ -"MESSAGES_VIEW_UNREAD_INDICATOR_HAS_MORE_UNSEEN_MESSAGES_AND_SAFETY_NUMBER_CHANGES" = "There are more unread messages (including safety number changes)."; - -/* Messages that indicates that there are more unseen messages that be revealed by tapping the 'load earlier messages' button. Embeds {{the name of the 'load earlier messages' button}} */ +/* Messages that indicates that there are more unseen messages. */ "MESSAGES_VIEW_UNREAD_INDICATOR_HAS_MORE_UNSEEN_MESSAGES" = "There are more unread messages."; +/* Messages that indicates that there are more unseen messages including safety number changes. */ +"MESSAGES_VIEW_UNREAD_INDICATOR_HAS_MORE_UNSEEN_MESSAGES_AND_SAFETY_NUMBER_CHANGES" = "There are more unread messages (including safety number changes)."; + /* notification title */ "MISSED_CALL" = "Missed call";