123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666 |
- // _____ _
- // |_ _| |_ _ _ ___ ___ _ __ __ _
- // | | | ' \| '_/ -_) -_) ' \/ _` |_
- // |_| |_||_|_| \___\___|_|_|_\__,_(_)
- //
- // Threema iOS Client
- // Copyright (c) 2012-2020 Threema GmbH
- //
- // This program is free software: you can redistribute it and/or modify
- // it under the terms of the GNU Affero General Public License, version 3,
- // as published by the Free Software Foundation.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU Affero General Public License for more details.
- //
- // You should have received a copy of the GNU Affero General Public License
- // along with this program. If not, see <https://www.gnu.org/licenses/>.
- #import <QuartzCore/QuartzCore.h>
- #import "ConversationCell.h"
- #import "Conversation.h"
- #import "Contact.h"
- #import "SystemMessage.h"
- #import "Utils.h"
- #import "AvatarMaker.h"
- #import "UIImage+ColoredImage.h"
- #import "BaseMessage+Accessibility.h"
- #import "BundleUtil.h"
- #import "UILabel+Markup.h"
- #import "MessageDraftStore.h"
- #import "ConversationUtils.h"
- #import "ChatCallMessageCell.h"
- #import "UserSettings.h"
- #import "LicenseStore.h"
- #import "TextStyleUtils.h"
- #import "PushSetting.h"
- #import "GroupProxy.h"
- @interface ConversationCell ()
- @property BOOL showStatusIcon;
- @property PushSetting *pushSetting;
- @end
- @implementation ConversationCell
- @synthesize conversation;
- - (void)dealloc {
- [self removeObservers];
-
- [[NSNotificationCenter defaultCenter] removeObserver: self];
- }
- - (void)awakeFromNib {
- [super awakeFromNib];
-
- /* very minor adjustment to make base lines of name, date and draft align on Retina displays */
- if ([UIScreen mainScreen].scale == 2.0) {
- self.dateLabel.frame = CGRectOffset(self.dateLabel.frame, 0, -0.5);
- self.draftLabel.frame = CGRectOffset(self.draftLabel.frame, 0, -0.5);
- }
-
- self.draftLabel.text = self.draftLabel.text.uppercaseString;
-
- _threemaTypeIcon.image = [Utils threemaTypeIcon];
-
- self.messagePreviewLabel.userInteractionEnabled = NO;
-
- self.statusIcon.contentMode = UIViewContentModeScaleAspectFit;
-
- [self setupColors];
- }
- - (void)setupColors {
- [Colors updateTableViewCellBackground:self];
-
- if (conversation.groupId == nil && (conversation.contact.state.intValue == kStateInactive || conversation.contact.state.intValue == kStateInvalid)) {
- self.nameLabel.textColor = [Colors fontLight];
- self.nameLabel.highlightedTextColor = [Colors fontLight];
- } else {
- self.nameLabel.textColor = [Colors fontNormal];
- self.nameLabel.highlightedTextColor = [Colors fontNormal];
- }
-
- [self.messagePreviewLabel setTextColor:[Colors fontLight]];
- self.messagePreviewLabel.highlightedTextColor = [Colors fontLight];
- [self.dateLabel setTextColor:[Colors fontLight]];
- self.dateLabel.highlightedTextColor = [Colors fontLight];
-
- self.markedView.backgroundColor = [Colors markTag];
-
- if (@available(iOS 11.0, *)) {
- _contactImage.accessibilityIgnoresInvertColors = true;
- _threemaTypeIcon.image = [Utils threemaTypeIcon];
- }
-
- _typingIndicator.image = [UIImage imageNamed:@"Typing" inColor:[Colors fontLight]];
- }
- - (void)removeObservers {
- [conversation removeObserver:self forKeyPath:@"typing"];
- [conversation removeObserver:self forKeyPath:@"lastMessage"];
- [conversation removeObserver:self forKeyPath:@"unreadMessageCount"];
- [conversation removeObserver:self forKeyPath:@"lastMessage.reverseGeocodingResult"];
- [conversation removeObserver:self forKeyPath:@"lastMessage.userack"];
- [conversation removeObserver:self forKeyPath:@"lastMessage.read"];
- [conversation removeObserver:self forKeyPath:@"lastMessage.delivered"];
- [conversation removeObserver:self forKeyPath:@"lastMessage.sendfailed"];
- [conversation removeObserver:self forKeyPath:@"lastMessage.sent"];
- [conversation removeObserver:self forKeyPath:@"groupName"];
- [conversation removeObserver:self forKeyPath:@"members"];
- [conversation removeObserver:self forKeyPath:@"contact.displayName"];
- [conversation removeObserver:self forKeyPath:@"contact.imageData"];
- [conversation removeObserver:self forKeyPath:@"groupImage"];
- [conversation removeObserver:self forKeyPath:@"contact.contactImage"];
- [conversation removeObserver:self forKeyPath:@"tags"];
- [[NSNotificationCenter defaultCenter] removeObserver: self];
- }
- - (void)setConversation:(Conversation *)newConversation {
-
- if (conversation == newConversation) {
- [self setupColors];
- [self updateDateLabel];
- [self updateContactImage];
- [self updateLastMessagePreview];
- [self updateThreemaTypeIcon];
- [self updateName];
- [self updateTagsView];
- [self updateNotificationIcon];
-
- return;
- }
-
- [self removeObservers];
-
- conversation = newConversation;
-
- /* observe this conversation as the last message text could change */
- [conversation addObserver:self forKeyPath:@"typing" options:0 context:nil];
- [conversation addObserver:self forKeyPath:@"lastMessage" options:0 context:nil];
- [conversation addObserver:self forKeyPath:@"unreadMessageCount" options:0 context:nil];
- [conversation addObserver:self forKeyPath:@"lastMessage.reverseGeocodingResult" options:0 context:nil];
- [conversation addObserver:self forKeyPath:@"lastMessage.userack" options:0 context:nil];
- [conversation addObserver:self forKeyPath:@"lastMessage.read" options:0 context:nil];
- [conversation addObserver:self forKeyPath:@"lastMessage.delivered" options:0 context:nil];
- [conversation addObserver:self forKeyPath:@"lastMessage.sendfailed" options:0 context:nil];
- [conversation addObserver:self forKeyPath:@"lastMessage.sent" options:0 context:nil];
- [conversation addObserver:self forKeyPath:@"groupName" options:0 context:nil];
- [conversation addObserver:self forKeyPath:@"members" options:0 context:nil];
- [conversation addObserver:self forKeyPath:@"contact.displayName" options:0 context:nil];
- [conversation addObserver:self forKeyPath:@"contact.imageData" options:0 context:nil];
- [conversation addObserver:self forKeyPath:@"groupImage" options:0 context:nil];
- [conversation addObserver:self forKeyPath:@"contact.contactImage" options:0 context:nil];
- [conversation addObserver:self forKeyPath:@"tags" options:0 context:nil];
-
-
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(avatarChanged:) name:kNotificationIdentityAvatarChanged object:nil];
-
- [self updateName];
-
- [self updateLastMessagePreview];
- [self updateDateLabel];
-
- [self updateBadgeView];
- [self updateContactImage];
- [self updateTypingIndicator];
-
- [self setupColors];
-
- [self updateThreemaTypeIcon];
-
- [self updateTagsView];
-
- [self updateNotificationIcon];
- }
- - (void)updateLastMessagePreview {
- BaseMessage *lastMessage = conversation.lastMessage;
-
- NSString *messageTextForPreview = [lastMessage previewText];
- if (messageTextForPreview == nil) {
- messageTextForPreview = @"";
- }
-
- if (conversation.groupId != nil) {
- self.statusIcon.image = [UIImage imageNamed:@"MessageStatus_group" inColor:[Colors fontLight]];
- self.statusIcon.highlightedImage = self.statusIcon.image;
- self.statusIcon.alpha = 1.0;
- self.statusIcon.hidden = NO;
- } else {
- NSString *iconName;
- UIColor *color = [Colors fontLight];
-
- if ([self isSystemCallMessage:lastMessage]) {
- iconName = @"call";
- }
- else {
- if (lastMessage.isOwn.boolValue && conversation.contact.isGatewayId == NO) {
- if (lastMessage.userackDate) {
- if (lastMessage.userack.boolValue) {
- iconName = @"thumb_up";
- color = [Colors green];
- } else if (lastMessage.userack.boolValue == NO) {
- iconName = @"thumb_down";
- color = [Colors orange];
- }
- } else if (lastMessage.read.boolValue) {
- iconName = @"read";
- } else if (lastMessage.delivered.boolValue) {
- iconName = @"delivered";
- } else if (lastMessage.sendFailed.boolValue) {
- iconName = @"sendfailed";
- color = [Colors red];
- } else {
- if (lastMessage.sent.boolValue) {
- iconName = @"sent";
- } else {
- iconName = @"sending";
- }
- }
- }
- else if (lastMessage == nil) {
- iconName = nil;
- }
- else if (!lastMessage.isOwn.boolValue && conversation.contact.isGatewayId == NO) {
- iconName = @"reply";
- if (lastMessage.userackDate) {
- if (lastMessage.userack.boolValue) {
- color = [Colors green];
- } else if (lastMessage.userack.boolValue == NO) {
- color = [Colors orange];
- }
- }
- }
- }
-
- if ((iconName && [self isSystemCallMessage:lastMessage]) || (iconName && ![lastMessage isKindOfClass:[SystemMessage class]])) {
- if ([iconName isEqualToString:@"sendfailed"]) {
- self.statusIcon.image = [UIImage imageNamed:[NSString stringWithFormat:@"MessageStatus_%@", iconName]];
- }
- else if ([iconName isEqualToString:@"call"]) {
- self.statusIcon.image = [UIImage imageNamed:@"ThreemaPhone" inColor:color];
- }
- else {
- self.statusIcon.image = [UIImage imageNamed:[NSString stringWithFormat:@"MessageStatus_%@", iconName] inColor:color];
- }
- self.statusIcon.highlightedImage = self.statusIcon.image;
- self.statusIcon.alpha = 1.0;
- self.statusIcon.hidden = NO;
- } else {
- self.statusIcon.hidden = YES;
- }
- }
-
- NSString *draftMessage = [MessageDraftStore loadDraftForConversation:self.conversation];
- NSAttributedString *attributedString;
- if (draftMessage) {
- self.dateLabel.hidden = YES;
- self.draftLabel.hidden = NO;
-
- NSAttributedString *draftAttributed = [TextStyleUtils makeAttributedStringFromString:draftMessage withFont:self.messagePreviewLabel.font textColor:[Colors fontLight] isOwn:true application:[UIApplication sharedApplication]];
- NSMutableAttributedString *formattedAttributeString = [[NSMutableAttributedString alloc] initWithAttributedString:[self.messagePreviewLabel applyMarkupFor:draftAttributed]];
- attributedString = [TextStyleUtils makeMentionsAttributedStringForAttributedString:formattedAttributeString textFont:self.messagePreviewLabel.font atColor:[[Colors fontLight] colorWithAlphaComponent:0.6] messageInfo:TextStyleUtilsMessageInfoOverview application:[UIApplication sharedApplication]];
- self.messagePreviewLabel.attributedText = attributedString;
- if (conversation.groupId == nil) {
- self.statusIcon.hidden = YES;
- }
- } else {
- self.dateLabel.hidden = NO;
- self.draftLabel.hidden = YES;
- NSString *editedString;
- if ([self isSystemCallMessage:lastMessage]) {
- NSString *spaces = @"";
- for (int i = 0; i < (self.messagePreviewLabel.font.pointSize / 2.2); i++) {
- spaces = [NSString stringWithFormat:@"%@ ", spaces];
- }
- editedString = [NSString stringWithFormat:@"%@%@",spaces, messageTextForPreview];
- } else {
- editedString = messageTextForPreview;
- }
-
- NSMutableAttributedString *formattedAttributeString;
- NSString *contactString;
- NSMutableAttributedString *messageAttributeString;
- if (conversation.groupId != nil) {
- if (lastMessage != nil && ![lastMessage isKindOfClass:[SystemMessage class]]) {
- if (lastMessage.sender == nil) {
- contactString = [[NSString alloc] initWithFormat:@"%@: ", [BundleUtil localizedStringForKey:@"me"]];
- } else {
- contactString = [[NSString alloc] initWithFormat:@"%@: ", lastMessage.sender.displayName];
- }
- }
-
- NSAttributedString *attributed = [TextStyleUtils makeAttributedStringFromString:editedString withFont:self.messagePreviewLabel.font textColor:[Colors fontLight] isOwn:true application:[UIApplication sharedApplication]];
- messageAttributeString = [[NSMutableAttributedString alloc] initWithAttributedString:[self.messagePreviewLabel applyMarkupFor:attributed]];
- NSAttributedString *attributedContact = [TextStyleUtils makeAttributedStringFromString:contactString withFont:self.messagePreviewLabel.font textColor:[Colors fontLight] isOwn:true application:[UIApplication sharedApplication]];
- formattedAttributeString = [[NSMutableAttributedString alloc] initWithAttributedString:attributedContact];
- [formattedAttributeString appendAttributedString:messageAttributeString];
- } else {
- NSAttributedString *attributed = [TextStyleUtils makeAttributedStringFromString:editedString withFont:self.messagePreviewLabel.font textColor:[Colors fontLight] isOwn:true application:[UIApplication sharedApplication]];
- formattedAttributeString = [[NSMutableAttributedString alloc] initWithAttributedString:[self.messagePreviewLabel applyMarkupFor:attributed]];
- }
-
- self.messagePreviewLabel.attributedText = [TextStyleUtils makeMentionsAttributedStringForAttributedString:formattedAttributeString textFont:self.messagePreviewLabel.font atColor:[[Colors fontLight] colorWithAlphaComponent:0.6] messageInfo:TextStyleUtilsMessageInfoOverview application:[UIApplication sharedApplication]];
- }
-
-
- if ([self isSystemCallMessage:lastMessage] && !draftMessage) {
- switch ([((SystemMessage *)lastMessage).type integerValue]) {
- case kSystemMessageCallEnded:
- if (((SystemMessage *)lastMessage).haveCallTime) {
- if (!((SystemMessage *)lastMessage).isOwn.boolValue) {
- _callImageView.image = [UIImage imageNamed:@"CallDownGreen" inColor:[Colors green]];
- } else {
- _callImageView.image = [UIImage imageNamed:@"CallUpGreen" inColor:[Colors green]];
- }
- } else {
- if (!((SystemMessage *)lastMessage).isOwn.boolValue) {
- _callImageView.image = [UIImage imageNamed:@"CallLeftRed"];
- } else {
- _callImageView.image = [UIImage imageNamed:@"CallUpRed"];
- }
- }
- break;
- case kSystemMessageCallRejected:
- if (!((SystemMessage *)lastMessage).isOwn.boolValue) {
- _callImageView.image = [UIImage imageNamed:@"CallLeftOrange"];
- } else {
- _callImageView.image = [UIImage imageNamed:@"CallRightRed"];
- }
- break;
- case kSystemMessageCallRejectedBusy:
- if (!((SystemMessage *)lastMessage).isOwn.boolValue) {
- _callImageView.image = [UIImage imageNamed:@"CallLeftRed"];
- } else {
- _callImageView.image = [UIImage imageNamed:@"CallRightRed"];
- }
- break;
- case kSystemMessageCallRejectedTimeout:
- if (!((SystemMessage *)lastMessage).isOwn.boolValue) {
- _callImageView.image = [UIImage imageNamed:@"CallLeftRed"];
- } else {
- _callImageView.image = [UIImage imageNamed:@"CallRightRed"];
- }
- break;
- case kSystemMessageCallRejectedDisabled:
- _callImageView.image = [UIImage imageNamed:@"CallRightRed"];
- break;
- case kSystemMessageCallMissed:
- _callImageView.image = [UIImage imageNamed:@"CallLeftRed"];
- break;
- default:
- _callImageView.image = [UIImage imageNamed:@"CallUpGreen" inColor:[Colors green]];
- break;
- }
-
- _callImageHeight.constant = self.messagePreviewLabel.font.pointSize * 1.2;
- _callImageView.hidden = NO;
- } else {
- _callImageView.hidden = YES;
- }
-
- _showStatusIcon = self.statusIcon.hidden == NO;
-
- // make sure typing indicator is in sync
- [self updateTypingIndicator];
- }
- - (void)updateDateLabel {
- BaseMessage *lastMessage = conversation.lastMessage;
- if (lastMessage.userackDate && lastMessage.isOwn.boolValue) {
- self.dateLabel.text = [Utils formatShortLastMessageDate:conversation.lastMessage.userackDate];
- } else if (lastMessage.read.boolValue && lastMessage.isOwn.boolValue) {
- self.dateLabel.text = [Utils formatShortLastMessageDate:conversation.lastMessage.readDate];
- } else if (lastMessage.delivered.boolValue && lastMessage.isOwn.boolValue) {
- self.dateLabel.text = [Utils formatShortLastMessageDate:conversation.lastMessage.deliveryDate];
- } else {
- self.dateLabel.text = [Utils formatShortLastMessageDate:conversation.lastMessage.remoteSentDate];
- }
- }
- - (void)updateContactImage {
- dispatch_async(dispatch_get_main_queue(), ^{
- self.contactImage.image = [BundleUtil imageNamed:@"Unknown"];
- });
-
- [[AvatarMaker sharedAvatarMaker] avatarForConversation:conversation size:56.0f masked:YES onCompletion:^(UIImage *avatarImage) {
- dispatch_async(dispatch_get_main_queue(), ^{
- self.contactImage.image = avatarImage;
- });
- }];
- }
- - (void)updateBadgeView {
- if (conversation.unreadMessageCount.intValue > 0) {
- self.badgeView.alignment = NSTextAlignmentCenter;
- self.badgeView.font = [UIFont systemFontOfSize:13];
- self.badgeView.shadowOffset = CGSizeMake(1,1);
- self.badgeView.value = conversation.unreadMessageCount.intValue;
- self.badgeView.alpha = 1.0;
- self.badgeView.hidden = NO;
- } else {
- self.badgeView.alpha = 0.0;
- self.badgeView.hidden = YES;
- }
- }
- - (void)updateTypingIndicator {
-
- if (conversation.typing.boolValue) {
- self.typingIndicator.alpha = 0.0;
- self.typingIndicator.hidden = NO;
-
- self.typingIndicator.alpha = 1.0;
- self.statusIcon.alpha = 0.0;
- self.statusIcon.hidden = YES;
- } else {
- if (_showStatusIcon) {
- self.statusIcon.hidden = NO;
- }
-
- self.typingIndicator.alpha = 0.0;
- self.statusIcon.alpha = 1.0;
- self.typingIndicator.hidden = YES;
- }
- }
- - (void)updateName {
- if (conversation.displayName) {
- if (conversation.groupId == nil && conversation.contact.state.intValue == kStateInvalid) {
- NSDictionary *strikethroughDict = @{NSStrikethroughStyleAttributeName: @(NSUnderlineStyleThick)};
- NSAttributedString *str = [[NSAttributedString alloc] initWithString:conversation.displayName attributes:strikethroughDict];
- if ([NSThread isMainThread]) {
- self.nameLabel.attributedText = str;
- } else {
- dispatch_async(dispatch_get_main_queue(), ^{
- self.nameLabel.attributedText = str;
- });
- }
- } else {
- NSMutableAttributedString *str = [[NSMutableAttributedString alloc] init];
- if ([[UserSettings sharedUserSettings].blacklist containsObject:conversation.contact.identity]) {
- [str appendAttributedString:[[NSAttributedString alloc] initWithString:@"🚫 " attributes:nil]];
- }
- [str appendAttributedString:[[NSAttributedString alloc] initWithString:conversation.displayName attributes:nil]];
- if ([NSThread isMainThread]) {
- self.nameLabel.attributedText = str;
- } else {
- dispatch_async(dispatch_get_main_queue(), ^{
- self.nameLabel.attributedText = str;
- });
- }
- }
- }
-
- UIFontDescriptor *fontDescriptor = [UIFontDescriptor preferredFontDescriptorWithTextStyle:UIFontTextStyleHeadline];
- CGFloat size = fontDescriptor.pointSize;
- dispatch_async(dispatch_get_main_queue(), ^{
- self.nameLabel.font = [UIFont boldSystemFontOfSize:size];
- });
- }
- - (void)updateThreemaTypeIcon {
- if (self.conversation.isGroup) {
- _threemaTypeIcon.hidden = YES;
- } else {
- _threemaTypeIcon.hidden = [Utils hideThreemaTypeIconForContact:self.conversation.contact];
- }
- }
- - (void)updateTagsView {
- self.markedView.alpha = [conversation.marked isEqualToNumber:[NSNumber numberWithBool:YES]] ? 1.0 : 0.0;
- }
- - (void)updateNotificationIcon {
- _pushSetting = [PushSetting findPushSettingForConversation:conversation];
- UIImage *pushSettingIcon = nil;
- if (_pushSetting) {
- pushSettingIcon = [_pushSetting imageForEditedPushSetting];
- }
- if (pushSettingIcon != nil) {
- _notificationIcon.image = [pushSettingIcon imageWithTint:[Colors fontLight]];
- _notificationIcon.hidden = false;
- } else {
- _notificationIcon.image = nil;
- _notificationIcon.hidden = true;
- }
- }
- - (NSString *)accessibilityLabel {
- NSMutableString *text = [NSMutableString stringWithFormat:@"%@. ", self.nameLabel.text];
-
- if (_pushSetting) {
- if (_pushSetting.type == kPushSettingTypeOn && _pushSetting.silent) {
- [text appendFormat:@"%@ %@. ", NSLocalizedString(@"notification_sound_header", nil), NSLocalizedString(@"doNotDisturb_off", nil)];
- }
- else if (_pushSetting.type == kPushSettingTypeOff && !_pushSetting.mentions) {
- [text appendFormat:@"%@ %@. ", NSLocalizedString(@"doNotDisturb_title", nil), NSLocalizedString(@"doNotDisturb_on", nil)];
- }
- else if (_pushSetting.type == kPushSettingTypeOff && _pushSetting.mentions) {
- [text appendFormat:@"%@ %@, %@. ", NSLocalizedString(@"doNotDisturb_title", nil), NSLocalizedString(@"doNotDisturb_on", nil), NSLocalizedString(@"doNotDisturb_mention", @"")];
- }
- else if (_pushSetting.type == kPushSettingTypeOffPeriod && !_pushSetting.mentions) {
- [text appendFormat:@"%@ %@ %@. ", NSLocalizedString(@"doNotDisturb_title", nil), NSLocalizedString(@"doNotDisturb_onPeriod_time", nil), [DateFormatter getFullDateFor:_pushSetting.periodOffTillDate]];
- }
- else if (_pushSetting.type == kPushSettingTypeOffPeriod && _pushSetting.mentions) {
- [text appendFormat:@"%@ %@ %@, %@. ", NSLocalizedString(@"doNotDisturb_title", nil), NSLocalizedString(@"doNotDisturb_onPeriod_time", nil), [DateFormatter getFullDateFor:_pushSetting.periodOffTillDate], NSLocalizedString(@"doNotDisturb_mention", @"")];
- }
- }
-
- NSString *messagePreview = [conversation.lastMessage previewText];
- NSString *draftPreview = [MessageDraftStore loadDraftForConversation:self.conversation];
- if (draftPreview.length > 0) {
- [text appendFormat:@"%@. ", [BundleUtil localizedStringForKey:@"draft"]];
- if (conversation.unreadMessageCount.intValue > 0) {
- [text appendFormat:@"%@. ", NSLocalizedString(@"unread", nil)];
- }
- [text appendFormat:@"%@ ", [BundleUtil localizedStringForKey:@"from"]];
- [text appendFormat:@"%@. ", [BundleUtil localizedStringForKey:@"me"]];
- [text appendFormat:@"%@. ", draftPreview];
- [text appendFormat:@"%@. ", [conversation.lastMessage accessibilityMessageShortStatus]];
- return text;
- }
-
- [text appendFormat:@"%@. ", [conversation.lastMessage accessibilityMessageDate]];
- if (messagePreview.length > 0) {
- if (conversation.unreadMessageCount.intValue > 0) {
- [text appendFormat:@"%@. ", NSLocalizedString(@"unread", nil)];
- }
- [text appendFormat:@"%@ ", [BundleUtil localizedStringForKey:@"from"]];
- [text appendFormat:@"%@. ", [conversation.lastMessage accessibilityMessageSender]];
- [text appendFormat:@"%@. ", messagePreview];
- [text appendFormat:@"%@. ", [conversation.lastMessage accessibilityMessageShortStatus]];
- }
-
- if ([conversation.marked isEqualToNumber:[NSNumber numberWithBool:YES]]) {
- [text appendFormat:@"%@. ", NSLocalizedString(@"pinned_conversation", nil)];
- }
-
- return text;
- }
- - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
- dispatch_async(dispatch_get_main_queue(), ^{
- if (object == conversation) {
- if ([keyPath isEqualToString:@"lastMessage"]) {
- [self updateLastMessagePreview];
- [self updateDateLabel];
- } else if ([keyPath isEqualToString:@"contact.displayName"] || [keyPath isEqualToString:@"groupName"] || [keyPath isEqualToString:@"members"]) {
- [self updateName];
- } else if ([keyPath isEqualToString:@"contact.imageData"] || [keyPath isEqualToString:@"groupImage"] || [keyPath isEqualToString:@"contact.contactImage"]) {
- [self updateContactImage];
- } else if ([keyPath isEqualToString:@"typing"]) {
- [self updateTypingIndicator];
- } else if ([keyPath isEqualToString:@"unreadMessageCount"]) {
- [self updateBadgeView];
- } else if ([keyPath hasPrefix:@"lastMessage."]) {
- [self updateLastMessagePreview];
- [self updateDateLabel];
- } else if ([keyPath hasPrefix:@"tags"]) {
- [self updateTagsView];
- }
- }
- });
- }
- - (BOOL)isSystemCallMessage:(BaseMessage *)message {
- if ([message isKindOfClass:[SystemMessage class]]) {
- switch ([((SystemMessage *)message).type integerValue]) {
- case kSystemMessageCallEnded:
- return YES;
- case kSystemMessageCallRejected:
- return YES;
- case kSystemMessageCallRejectedBusy:
- return YES;
- case kSystemMessageCallRejectedTimeout:
- return YES;
- case kSystemMessageCallRejectedDisabled:
- return YES;
- case kSystemMessageCallMissed:
- return YES;
- case kSystemMessageCallRejectedUnknown:
- return YES;
- default:
- return NO;
- }
- }
- return NO;
- }
- - (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated {
- [super setHighlighted:highlighted animated:animated];
- [_messagePreviewLabel setHighlighted:NO];
- }
- - (void)voiceOverDeleteConversation {
- if ([_conversationCellDelegate respondsToSelector:@selector(voiceOverDeleteConversation:)]) {
- [_conversationCellDelegate voiceOverDeleteConversation:self];
- }
- }
- - (void)voiceOverLeaveGroup {
- if ([_conversationCellDelegate respondsToSelector:@selector(voiceOverLeaveGroup:)]) {
- [_conversationCellDelegate voiceOverLeaveGroup:self];
- }
- }
- - (void)voiceOverMarkConversation:(id)sender {
- [ConversationUtils markConversation:conversation];
- }
- - (void)voiceOverUnmarkConversation:(id)sender {
- [ConversationUtils unmarkConversation:conversation];
- }
- - (void)voiceOverReadMessage:(id)sender {
- [ConversationUtils unreadConversation:conversation];
- }
- #pragma mark - Accessibility
- - (NSArray *)accessibilityCustomActions {
- UIAccessibilityCustomAction *readAction;
- UIAccessibilityCustomAction *markAction;
- NSMutableArray *actionArray = [NSMutableArray new];
- if (conversation.unreadMessageCount.intValue > 0) {
- readAction = [[UIAccessibilityCustomAction alloc] initWithName:NSLocalizedString(@"read", @"") target:self selector:@selector(voiceOverReadMessage:)];
- [actionArray addObject:readAction];
- }
- if (conversation.marked.boolValue) {
- markAction = [[UIAccessibilityCustomAction alloc] initWithName:NSLocalizedString(@"unpin", @"") target:self selector:@selector(voiceOverUnmarkConversation:)];
- } else {
- markAction = [[UIAccessibilityCustomAction alloc] initWithName:NSLocalizedString(@"pin", @"") target:self selector:@selector(voiceOverMarkConversation:)];
- }
- [actionArray addObject:markAction];
-
- if (conversation.isGroup) {
- GroupProxy *group = [GroupProxy groupProxyForConversation:conversation];
- if ([group isSelfMember]) {
- UIAccessibilityCustomAction *leaveAction = [[UIAccessibilityCustomAction alloc] initWithName:[BundleUtil localizedStringForKey:@"leave_group"] target:self selector:@selector(voiceOverLeaveGroup)];
- [actionArray addObject:leaveAction];
- }
- }
-
- UIAccessibilityCustomAction *deleteAction = [[UIAccessibilityCustomAction alloc] initWithName:NSLocalizedString(@"delete", @"") target:self selector:@selector(voiceOverDeleteConversation)];
- [actionArray addObject:deleteAction];
- return actionArray;
- }
- #pragma mark - Notification
- - (void)avatarChanged:(NSNotification*)notification
- {
- if (notification.object && [conversation.contact.identity isEqualToString:notification.object] ) {
- [self updateContactImage];
- }
- }
- @end
|