diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index c8d27b3e1..6a8815610 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -5279,7 +5279,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 277; + CURRENT_PROJECT_VERSION = 279; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -5348,7 +5348,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 277; + CURRENT_PROJECT_VERSION = 279; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -5409,7 +5409,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 277; + CURRENT_PROJECT_VERSION = 279; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -5479,7 +5479,7 @@ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 277; + CURRENT_PROJECT_VERSION = 279; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = SUQ8J2PCT7; ENABLE_NS_ASSERTIONS = NO; @@ -6364,7 +6364,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 277; + CURRENT_PROJECT_VERSION = 279; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -6433,7 +6433,7 @@ CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 277; + CURRENT_PROJECT_VERSION = 279; DEVELOPMENT_TEAM = SUQ8J2PCT7; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", diff --git a/Session/Conversations/ConversationVC+Interaction.swift b/Session/Conversations/ConversationVC+Interaction.swift index 61ac11d40..89ae4dc4e 100644 --- a/Session/Conversations/ConversationVC+Interaction.swift +++ b/Session/Conversations/ConversationVC+Interaction.swift @@ -22,6 +22,7 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc // so the result may be inaccurate before all the cells are loaded. Use this // to scroll to the last row instead. let indexPath = IndexPath(row: viewItems.count - 1, section: 0) + unreadViewItems.removeAll() messagesTableView.scrollToRow(at: indexPath, at: .top, animated: true) } diff --git a/Session/Conversations/ConversationVC.swift b/Session/Conversations/ConversationVC.swift index ab678dec6..439394502 100644 --- a/Session/Conversations/ConversationVC.swift +++ b/Session/Conversations/ConversationVC.swift @@ -150,7 +150,7 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat /// The button will be invisible until the user has scrolled at least this amount from the bottom of the table view. static let scrollButtonNoVisibilityThreshold: CGFloat = 20 /// Automatically scroll to the bottom of the conversation when sending a message if the scroll distance from the bottom is less than this number. - static let scrollToBottomMargin: CGFloat = 40 + static let scrollToBottomMargin: CGFloat = 60 // MARK: Lifecycle init(thread: TSThread, focusedMessageID: String? = nil) { diff --git a/Session/Conversations/Settings/OWSConversationSettingsViewController.m b/Session/Conversations/Settings/OWSConversationSettingsViewController.m index 62f475e15..3d303ca9d 100644 --- a/Session/Conversations/Settings/OWSConversationSettingsViewController.m +++ b/Session/Conversations/Settings/OWSConversationSettingsViewController.m @@ -515,6 +515,56 @@ CGFloat kIconViewLength = 24; [weakSelf.navigationController pushViewController:vc animated:YES]; }]]; + if (self.isOpenGroup) { + // Notification Settings + [section addItem:[OWSTableItem itemWithCustomCellBlock:^{ + UITableViewCell *cell = [OWSTableItem newCell]; + OWSConversationSettingsViewController *strongSelf = weakSelf; + OWSCAssertDebug(strongSelf); + cell.preservesSuperviewLayoutMargins = YES; + cell.contentView.preservesSuperviewLayoutMargins = YES; + cell.selectionStyle = UITableViewCellSelectionStyleNone; + + UIImageView *iconView = [strongSelf viewForIconWithName:@"NotifyMentions"]; + + UILabel *rowLabel = [UILabel new]; + rowLabel.text = NSLocalizedString(@"vc_conversation_settings_notify_for_mentions_only_title", @""); + rowLabel.textColor = LKColors.text; + rowLabel.font = [UIFont systemFontOfSize:LKValues.mediumFontSize]; + rowLabel.lineBreakMode = NSLineBreakByTruncatingTail; + + UISwitch *switchView = [UISwitch new]; + switchView.on = ((TSGroupThread *)strongSelf.thread).isOnlyNotifyingForMentions; + [switchView addTarget:strongSelf action:@selector(notifyForMentionsOnlySwitchValueDidChange:) + forControlEvents:UIControlEventValueChanged]; + + UIStackView *topRow = + [[UIStackView alloc] initWithArrangedSubviews:@[ iconView, rowLabel, switchView ]]; + topRow.spacing = strongSelf.iconSpacing; + topRow.alignment = UIStackViewAlignmentCenter; + [cell.contentView addSubview:topRow]; + [topRow autoPinEdgesToSuperviewMarginsExcludingEdge:ALEdgeBottom]; + + UILabel *subtitleLabel = [UILabel new]; + subtitleLabel.text = NSLocalizedString(@"vc_conversation_settings_notify_for_mentions_only_explanation", @""); + subtitleLabel.textColor = LKColors.text; + subtitleLabel.font = [UIFont systemFontOfSize:LKValues.smallFontSize]; + subtitleLabel.numberOfLines = 0; + subtitleLabel.lineBreakMode = NSLineBreakByWordWrapping; + [cell.contentView addSubview:subtitleLabel]; + [subtitleLabel autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:topRow withOffset:8]; + [subtitleLabel autoPinEdge:ALEdgeLeading toEdge:ALEdgeLeading ofView:rowLabel]; + [subtitleLabel autoPinTrailingToSuperviewMargin]; + [subtitleLabel autoPinBottomToSuperviewMargin]; + + cell.userInteractionEnabled = !strongSelf.hasLeftGroup; + + cell.accessibilityIdentifier = ACCESSIBILITY_IDENTIFIER_WITH_NAME(OWSConversationSettingsViewController, @"notify_for_mentions_only"); + + return cell; + } customRowHeight:UITableViewAutomaticDimension actionBlock:nil]]; + } + // Mute thread [section addItem:[OWSTableItem itemWithCustomCellBlock:^{ OWSConversationSettingsViewController *strongSelf = weakSelf; @@ -947,6 +997,15 @@ CGFloat kIconViewLength = 24; [self.conversationSettingsViewDelegate conversationSettingsDidRequestConversationSearch:self]; } +- (void)notifyForMentionsOnlySwitchValueDidChange:(id)sender +{ + UISwitch *uiSwitch = (UISwitch *)sender; + BOOL isEnabled = uiSwitch.isOn; + [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [(TSGroupThread *)self.thread setisOnlyNotifyingForMentions:isEnabled withTransaction:transaction]; + }]; +} + - (void)hideEditNameUI { self.isEditingDisplayName = NO; diff --git a/Session/Conversations/Views & Modals/ConversationTitleView.swift b/Session/Conversations/Views & Modals/ConversationTitleView.swift index 1604490ad..d80912b29 100644 --- a/Session/Conversations/Views & Modals/ConversationTitleView.swift +++ b/Session/Conversations/Views & Modals/ConversationTitleView.swift @@ -86,22 +86,33 @@ final class ConversationTitleView : UIView { } private func getSubtitle() -> NSAttributedString? { + let result = NSMutableAttributedString() if thread.isMuted { - let result = NSMutableAttributedString() result.append(NSAttributedString(string: "\u{e067} ", attributes: [ .font : UIFont.ows_elegantIconsFont(10), .foregroundColor : Colors.text ])) result.append(NSAttributedString(string: "Muted")) return result } else if let thread = self.thread as? TSGroupThread { - var userCount: UInt64? - switch thread.groupModel.groupType { - case .closedGroup: userCount = UInt64(thread.groupModel.groupMemberIds.count) - case .openGroup: - guard let openGroupV2 = Storage.shared.getV2OpenGroup(for: self.thread.uniqueId!) else { return nil } - userCount = Storage.shared.getUserCount(forV2OpenGroupWithID: openGroupV2.id) - default: break - } - if let userCount = userCount { - return NSAttributedString(string: "\(userCount) members") + if thread.isOnlyNotifyingForMentions { + let imageAttachment = NSTextAttachment() + let color: UIColor = isDarkMode ? .white : .black + imageAttachment.image = UIImage(named: "NotifyMentions.png")?.asTintedImage(color: color) + imageAttachment.bounds = CGRect(x: 0, y: -2, width: Values.smallFontSize, height: Values.smallFontSize) + let imageAsString = NSAttributedString(attachment: imageAttachment) + result.append(imageAsString) + result.append(NSAttributedString(string: " " + NSLocalizedString("view_conversation_title_notify_for_mentions_only", comment: ""))) + return result + } else { + var userCount: UInt64? + switch thread.groupModel.groupType { + case .closedGroup: userCount = UInt64(thread.groupModel.groupMemberIds.count) + case .openGroup: + guard let openGroupV2 = Storage.shared.getV2OpenGroup(for: self.thread.uniqueId!) else { return nil } + userCount = Storage.shared.getUserCount(forV2OpenGroupWithID: openGroupV2.id) + default: break + } + if let userCount = userCount { + return NSAttributedString(string: "\(userCount) members") + } } } return nil diff --git a/Session/Meta/Images.xcassets/Session/NotifyMentions.imageset/Contents.json b/Session/Meta/Images.xcassets/Session/NotifyMentions.imageset/Contents.json new file mode 100644 index 000000000..60527f39d --- /dev/null +++ b/Session/Meta/Images.xcassets/Session/NotifyMentions.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "ic_notification_mentions.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "ic_notification_mentions-1.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "ic_notification_mentions-2.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Session/Meta/Images.xcassets/Session/NotifyMentions.imageset/ic_notification_mentions-1.png b/Session/Meta/Images.xcassets/Session/NotifyMentions.imageset/ic_notification_mentions-1.png new file mode 100644 index 000000000..fe39a8b35 Binary files /dev/null and b/Session/Meta/Images.xcassets/Session/NotifyMentions.imageset/ic_notification_mentions-1.png differ diff --git a/Session/Meta/Images.xcassets/Session/NotifyMentions.imageset/ic_notification_mentions-2.png b/Session/Meta/Images.xcassets/Session/NotifyMentions.imageset/ic_notification_mentions-2.png new file mode 100644 index 000000000..fe39a8b35 Binary files /dev/null and b/Session/Meta/Images.xcassets/Session/NotifyMentions.imageset/ic_notification_mentions-2.png differ diff --git a/Session/Meta/Images.xcassets/Session/NotifyMentions.imageset/ic_notification_mentions.png b/Session/Meta/Images.xcassets/Session/NotifyMentions.imageset/ic_notification_mentions.png new file mode 100644 index 000000000..fe39a8b35 Binary files /dev/null and b/Session/Meta/Images.xcassets/Session/NotifyMentions.imageset/ic_notification_mentions.png differ diff --git a/Session/Meta/Translations/de.lproj/Localizable.strings b/Session/Meta/Translations/de.lproj/Localizable.strings index edbde38f7..6c0dca3f4 100644 --- a/Session/Meta/Translations/de.lproj/Localizable.strings +++ b/Session/Meta/Translations/de.lproj/Localizable.strings @@ -546,3 +546,6 @@ "modal_send_seed_title" = "Warning"; "modal_send_seed_explanation" = "This is your recovery phrase. If you send it to someone they'll have full access to your account."; "modal_send_seed_send_button_title" = "Send"; +"vc_conversation_settings_notify_for_mentions_only_title" = "Notify for Mentions Only"; +"vc_conversation_settings_notify_for_mentions_only_explanation" = "When enabled, you'll only be notified for messages mentioning you."; +"view_conversation_title_notify_for_mentions_only" = "Notifying for Mentions Only"; diff --git a/Session/Meta/Translations/en.lproj/Localizable.strings b/Session/Meta/Translations/en.lproj/Localizable.strings index c1f7a7f76..5ae81cb62 100644 --- a/Session/Meta/Translations/en.lproj/Localizable.strings +++ b/Session/Meta/Translations/en.lproj/Localizable.strings @@ -546,3 +546,6 @@ "modal_send_seed_title" = "Warning"; "modal_send_seed_explanation" = "This is your recovery phrase. If you send it to someone they'll have full access to your account."; "modal_send_seed_send_button_title" = "Send"; +"vc_conversation_settings_notify_for_mentions_only_title" = "Notify for Mentions Only"; +"vc_conversation_settings_notify_for_mentions_only_explanation" = "When enabled, you'll only be notified for messages mentioning you."; +"view_conversation_title_notify_for_mentions_only" = "Notifying for Mentions Only"; diff --git a/Session/Meta/Translations/es.lproj/Localizable.strings b/Session/Meta/Translations/es.lproj/Localizable.strings index 2c758a958..3c05898e9 100644 --- a/Session/Meta/Translations/es.lproj/Localizable.strings +++ b/Session/Meta/Translations/es.lproj/Localizable.strings @@ -546,3 +546,6 @@ "modal_send_seed_title" = "Warning"; "modal_send_seed_explanation" = "This is your recovery phrase. If you send it to someone they'll have full access to your account."; "modal_send_seed_send_button_title" = "Send"; +"vc_conversation_settings_notify_for_mentions_only_title" = "Notify for Mentions Only"; +"vc_conversation_settings_notify_for_mentions_only_explanation" = "When enabled, you'll only be notified for messages mentioning you."; +"view_conversation_title_notify_for_mentions_only" = "Notifying for Mentions Only"; diff --git a/Session/Meta/Translations/fa.lproj/Localizable.strings b/Session/Meta/Translations/fa.lproj/Localizable.strings index 8c7f27588..2f210126b 100644 --- a/Session/Meta/Translations/fa.lproj/Localizable.strings +++ b/Session/Meta/Translations/fa.lproj/Localizable.strings @@ -546,3 +546,6 @@ "modal_send_seed_title" = "Warning"; "modal_send_seed_explanation" = "This is your recovery phrase. If you send it to someone they'll have full access to your account."; "modal_send_seed_send_button_title" = "Send"; +"vc_conversation_settings_notify_for_mentions_only_title" = "Notify for Mentions Only"; +"vc_conversation_settings_notify_for_mentions_only_explanation" = "When enabled, you'll only be notified for messages mentioning you."; +"view_conversation_title_notify_for_mentions_only" = "Notifying for Mentions Only"; diff --git a/Session/Meta/Translations/fi.lproj/Localizable.strings b/Session/Meta/Translations/fi.lproj/Localizable.strings index 058f05a0d..ba0488b5c 100644 --- a/Session/Meta/Translations/fi.lproj/Localizable.strings +++ b/Session/Meta/Translations/fi.lproj/Localizable.strings @@ -546,3 +546,6 @@ "modal_send_seed_title" = "Warning"; "modal_send_seed_explanation" = "This is your recovery phrase. If you send it to someone they'll have full access to your account."; "modal_send_seed_send_button_title" = "Send"; +"vc_conversation_settings_notify_for_mentions_only_title" = "Notify for Mentions Only"; +"vc_conversation_settings_notify_for_mentions_only_explanation" = "When enabled, you'll only be notified for messages mentioning you."; +"view_conversation_title_notify_for_mentions_only" = "Notifying for Mentions Only"; diff --git a/Session/Meta/Translations/fr.lproj/Localizable.strings b/Session/Meta/Translations/fr.lproj/Localizable.strings index 116e66da9..3f3615722 100644 --- a/Session/Meta/Translations/fr.lproj/Localizable.strings +++ b/Session/Meta/Translations/fr.lproj/Localizable.strings @@ -546,3 +546,6 @@ "modal_send_seed_title" = "Warning"; "modal_send_seed_explanation" = "This is your recovery phrase. If you send it to someone they'll have full access to your account."; "modal_send_seed_send_button_title" = "Send"; +"vc_conversation_settings_notify_for_mentions_only_title" = "Notify for Mentions Only"; +"vc_conversation_settings_notify_for_mentions_only_explanation" = "When enabled, you'll only be notified for messages mentioning you."; +"view_conversation_title_notify_for_mentions_only" = "Notifying for Mentions Only"; diff --git a/Session/Meta/Translations/hi.lproj/Localizable.strings b/Session/Meta/Translations/hi.lproj/Localizable.strings index 62c69c9ab..4ac63066d 100644 --- a/Session/Meta/Translations/hi.lproj/Localizable.strings +++ b/Session/Meta/Translations/hi.lproj/Localizable.strings @@ -546,3 +546,6 @@ "modal_send_seed_title" = "Warning"; "modal_send_seed_explanation" = "This is your recovery phrase. If you send it to someone they'll have full access to your account."; "modal_send_seed_send_button_title" = "Send"; +"vc_conversation_settings_notify_for_mentions_only_title" = "Notify for Mentions Only"; +"vc_conversation_settings_notify_for_mentions_only_explanation" = "When enabled, you'll only be notified for messages mentioning you."; +"view_conversation_title_notify_for_mentions_only" = "Notifying for Mentions Only"; diff --git a/Session/Meta/Translations/hr.lproj/Localizable.strings b/Session/Meta/Translations/hr.lproj/Localizable.strings index a4f1ecec0..06175d3bd 100644 --- a/Session/Meta/Translations/hr.lproj/Localizable.strings +++ b/Session/Meta/Translations/hr.lproj/Localizable.strings @@ -546,3 +546,6 @@ "modal_send_seed_title" = "Warning"; "modal_send_seed_explanation" = "This is your recovery phrase. If you send it to someone they'll have full access to your account."; "modal_send_seed_send_button_title" = "Send"; +"vc_conversation_settings_notify_for_mentions_only_title" = "Notify for Mentions Only"; +"vc_conversation_settings_notify_for_mentions_only_explanation" = "When enabled, you'll only be notified for messages mentioning you."; +"view_conversation_title_notify_for_mentions_only" = "Notifying for Mentions Only"; diff --git a/Session/Meta/Translations/id-ID.lproj/Localizable.strings b/Session/Meta/Translations/id-ID.lproj/Localizable.strings index 4ea14eeb4..53f074e91 100644 --- a/Session/Meta/Translations/id-ID.lproj/Localizable.strings +++ b/Session/Meta/Translations/id-ID.lproj/Localizable.strings @@ -546,3 +546,6 @@ "modal_send_seed_title" = "Warning"; "modal_send_seed_explanation" = "This is your recovery phrase. If you send it to someone they'll have full access to your account."; "modal_send_seed_send_button_title" = "Send"; +"vc_conversation_settings_notify_for_mentions_only_title" = "Notify for Mentions Only"; +"vc_conversation_settings_notify_for_mentions_only_explanation" = "When enabled, you'll only be notified for messages mentioning you."; +"view_conversation_title_notify_for_mentions_only" = "Notifying for Mentions Only"; diff --git a/Session/Meta/Translations/it.lproj/Localizable.strings b/Session/Meta/Translations/it.lproj/Localizable.strings index d13c5ddb5..ba556afb2 100644 --- a/Session/Meta/Translations/it.lproj/Localizable.strings +++ b/Session/Meta/Translations/it.lproj/Localizable.strings @@ -546,3 +546,6 @@ "modal_send_seed_title" = "Warning"; "modal_send_seed_explanation" = "This is your recovery phrase. If you send it to someone they'll have full access to your account."; "modal_send_seed_send_button_title" = "Send"; +"vc_conversation_settings_notify_for_mentions_only_title" = "Notify for Mentions Only"; +"vc_conversation_settings_notify_for_mentions_only_explanation" = "When enabled, you'll only be notified for messages mentioning you."; +"view_conversation_title_notify_for_mentions_only" = "Notifying for Mentions Only"; diff --git a/Session/Meta/Translations/ja.lproj/Localizable.strings b/Session/Meta/Translations/ja.lproj/Localizable.strings index faf24bdc6..c7a4ddb46 100644 --- a/Session/Meta/Translations/ja.lproj/Localizable.strings +++ b/Session/Meta/Translations/ja.lproj/Localizable.strings @@ -546,3 +546,6 @@ "modal_send_seed_title" = "Warning"; "modal_send_seed_explanation" = "This is your recovery phrase. If you send it to someone they'll have full access to your account."; "modal_send_seed_send_button_title" = "Send"; +"vc_conversation_settings_notify_for_mentions_only_title" = "Notify for Mentions Only"; +"vc_conversation_settings_notify_for_mentions_only_explanation" = "When enabled, you'll only be notified for messages mentioning you."; +"view_conversation_title_notify_for_mentions_only" = "Notifying for Mentions Only"; diff --git a/Session/Meta/Translations/nl.lproj/Localizable.strings b/Session/Meta/Translations/nl.lproj/Localizable.strings index 8967ddfc9..f097fb431 100644 --- a/Session/Meta/Translations/nl.lproj/Localizable.strings +++ b/Session/Meta/Translations/nl.lproj/Localizable.strings @@ -546,3 +546,6 @@ "modal_send_seed_title" = "Warning"; "modal_send_seed_explanation" = "This is your recovery phrase. If you send it to someone they'll have full access to your account."; "modal_send_seed_send_button_title" = "Send"; +"vc_conversation_settings_notify_for_mentions_only_title" = "Notify for Mentions Only"; +"vc_conversation_settings_notify_for_mentions_only_explanation" = "When enabled, you'll only be notified for messages mentioning you."; +"view_conversation_title_notify_for_mentions_only" = "Notifying for Mentions Only"; diff --git a/Session/Meta/Translations/pl.lproj/Localizable.strings b/Session/Meta/Translations/pl.lproj/Localizable.strings index 59a6706ae..ebb5aa434 100644 --- a/Session/Meta/Translations/pl.lproj/Localizable.strings +++ b/Session/Meta/Translations/pl.lproj/Localizable.strings @@ -546,3 +546,6 @@ "modal_send_seed_title" = "Warning"; "modal_send_seed_explanation" = "This is your recovery phrase. If you send it to someone they'll have full access to your account."; "modal_send_seed_send_button_title" = "Send"; +"vc_conversation_settings_notify_for_mentions_only_title" = "Notify for Mentions Only"; +"vc_conversation_settings_notify_for_mentions_only_explanation" = "When enabled, you'll only be notified for messages mentioning you."; +"view_conversation_title_notify_for_mentions_only" = "Notifying for Mentions Only"; diff --git a/Session/Meta/Translations/pt_BR.lproj/Localizable.strings b/Session/Meta/Translations/pt_BR.lproj/Localizable.strings index 2555e945c..c5572ccc4 100644 --- a/Session/Meta/Translations/pt_BR.lproj/Localizable.strings +++ b/Session/Meta/Translations/pt_BR.lproj/Localizable.strings @@ -546,3 +546,6 @@ "modal_send_seed_title" = "Warning"; "modal_send_seed_explanation" = "This is your recovery phrase. If you send it to someone they'll have full access to your account."; "modal_send_seed_send_button_title" = "Send"; +"vc_conversation_settings_notify_for_mentions_only_title" = "Notify for Mentions Only"; +"vc_conversation_settings_notify_for_mentions_only_explanation" = "When enabled, you'll only be notified for messages mentioning you."; +"view_conversation_title_notify_for_mentions_only" = "Notifying for Mentions Only"; diff --git a/Session/Meta/Translations/ru.lproj/Localizable.strings b/Session/Meta/Translations/ru.lproj/Localizable.strings index 89119cb53..129b0b3d1 100644 --- a/Session/Meta/Translations/ru.lproj/Localizable.strings +++ b/Session/Meta/Translations/ru.lproj/Localizable.strings @@ -546,3 +546,6 @@ "modal_send_seed_title" = "Warning"; "modal_send_seed_explanation" = "This is your recovery phrase. If you send it to someone they'll have full access to your account."; "modal_send_seed_send_button_title" = "Send"; +"vc_conversation_settings_notify_for_mentions_only_title" = "Notify for Mentions Only"; +"vc_conversation_settings_notify_for_mentions_only_explanation" = "When enabled, you'll only be notified for messages mentioning you."; +"view_conversation_title_notify_for_mentions_only" = "Notifying for Mentions Only"; diff --git a/Session/Meta/Translations/sk.lproj/Localizable.strings b/Session/Meta/Translations/sk.lproj/Localizable.strings index 2ade1f164..495b874d0 100644 --- a/Session/Meta/Translations/sk.lproj/Localizable.strings +++ b/Session/Meta/Translations/sk.lproj/Localizable.strings @@ -546,3 +546,6 @@ "modal_send_seed_title" = "Warning"; "modal_send_seed_explanation" = "This is your recovery phrase. If you send it to someone they'll have full access to your account."; "modal_send_seed_send_button_title" = "Send"; +"vc_conversation_settings_notify_for_mentions_only_title" = "Notify for Mentions Only"; +"vc_conversation_settings_notify_for_mentions_only_explanation" = "When enabled, you'll only be notified for messages mentioning you."; +"view_conversation_title_notify_for_mentions_only" = "Notifying for Mentions Only"; diff --git a/Session/Meta/Translations/sv.lproj/Localizable.strings b/Session/Meta/Translations/sv.lproj/Localizable.strings index 81332a545..e6b1b4d59 100644 --- a/Session/Meta/Translations/sv.lproj/Localizable.strings +++ b/Session/Meta/Translations/sv.lproj/Localizable.strings @@ -546,3 +546,6 @@ "modal_send_seed_title" = "Warning"; "modal_send_seed_explanation" = "This is your recovery phrase. If you send it to someone they'll have full access to your account."; "modal_send_seed_send_button_title" = "Send"; +"vc_conversation_settings_notify_for_mentions_only_title" = "Notify for Mentions Only"; +"vc_conversation_settings_notify_for_mentions_only_explanation" = "When enabled, you'll only be notified for messages mentioning you."; +"view_conversation_title_notify_for_mentions_only" = "Notifying for Mentions Only"; diff --git a/Session/Meta/Translations/th.lproj/Localizable.strings b/Session/Meta/Translations/th.lproj/Localizable.strings index a92caaefa..5a99c82e0 100644 --- a/Session/Meta/Translations/th.lproj/Localizable.strings +++ b/Session/Meta/Translations/th.lproj/Localizable.strings @@ -546,3 +546,6 @@ "modal_send_seed_title" = "Warning"; "modal_send_seed_explanation" = "This is your recovery phrase. If you send it to someone they'll have full access to your account."; "modal_send_seed_send_button_title" = "Send"; +"vc_conversation_settings_notify_for_mentions_only_title" = "Notify for Mentions Only"; +"vc_conversation_settings_notify_for_mentions_only_explanation" = "When enabled, you'll only be notified for messages mentioning you."; +"view_conversation_title_notify_for_mentions_only" = "Notifying for Mentions Only"; diff --git a/Session/Meta/Translations/vi-VN.lproj/Localizable.strings b/Session/Meta/Translations/vi-VN.lproj/Localizable.strings index 9742ba586..0faba1ebe 100644 --- a/Session/Meta/Translations/vi-VN.lproj/Localizable.strings +++ b/Session/Meta/Translations/vi-VN.lproj/Localizable.strings @@ -546,3 +546,6 @@ "modal_send_seed_title" = "Warning"; "modal_send_seed_explanation" = "This is your recovery phrase. If you send it to someone they'll have full access to your account."; "modal_send_seed_send_button_title" = "Send"; +"vc_conversation_settings_notify_for_mentions_only_title" = "Notify for Mentions Only"; +"vc_conversation_settings_notify_for_mentions_only_explanation" = "When enabled, you'll only be notified for messages mentioning you."; +"view_conversation_title_notify_for_mentions_only" = "Notifying for Mentions Only"; diff --git a/Session/Meta/Translations/zh-Hant.lproj/Localizable.strings b/Session/Meta/Translations/zh-Hant.lproj/Localizable.strings index 0166c55c2..03fa38484 100644 --- a/Session/Meta/Translations/zh-Hant.lproj/Localizable.strings +++ b/Session/Meta/Translations/zh-Hant.lproj/Localizable.strings @@ -546,3 +546,6 @@ "modal_send_seed_title" = "Warning"; "modal_send_seed_explanation" = "This is your recovery phrase. If you send it to someone they'll have full access to your account."; "modal_send_seed_send_button_title" = "Send"; +"vc_conversation_settings_notify_for_mentions_only_title" = "Notify for Mentions Only"; +"vc_conversation_settings_notify_for_mentions_only_explanation" = "When enabled, you'll only be notified for messages mentioning you."; +"view_conversation_title_notify_for_mentions_only" = "Notifying for Mentions Only"; diff --git a/Session/Meta/Translations/zh_CN.lproj/Localizable.strings b/Session/Meta/Translations/zh_CN.lproj/Localizable.strings index 127219d84..764187588 100644 --- a/Session/Meta/Translations/zh_CN.lproj/Localizable.strings +++ b/Session/Meta/Translations/zh_CN.lproj/Localizable.strings @@ -546,3 +546,6 @@ "modal_send_seed_title" = "Warning"; "modal_send_seed_explanation" = "This is your recovery phrase. If you send it to someone they'll have full access to your account."; "modal_send_seed_send_button_title" = "Send"; +"vc_conversation_settings_notify_for_mentions_only_title" = "Notify for Mentions Only"; +"vc_conversation_settings_notify_for_mentions_only_explanation" = "When enabled, you'll only be notified for messages mentioning you."; +"view_conversation_title_notify_for_mentions_only" = "Notifying for Mentions Only"; diff --git a/Session/Notifications/AppNotifications.swift b/Session/Notifications/AppNotifications.swift index 3ba8d5e62..594430aeb 100644 --- a/Session/Notifications/AppNotifications.swift +++ b/Session/Notifications/AppNotifications.swift @@ -165,6 +165,13 @@ public class NotificationPresenter: NSObject, NotificationsProtocol { // see https://developer.apple.com/documentation/uikit/uilocalnotification/1616646-alertbody // for more details. let messageText = DisplayableText.filterNotificationText(rawMessageText) + + // Don't fire the notification if the current user isn't mentioned + // and isOnlyNotifyingForMentions is on. + let isUserMentioned = MentionUtilities.isUserMentioned(in: messageText ?? "") + if let groupThread = thread as? TSGroupThread, groupThread.isOnlyNotifyingForMentions && !isUserMentioned { + return + } let context = Contact.context(for: thread) let senderName = Storage.shared.getContact(with: incomingMessage.authorId)?.displayName(for: context) ?? incomingMessage.authorId diff --git a/Session/Shared/ConversationCell.swift b/Session/Shared/ConversationCell.swift index d2f827a3b..46074851b 100644 --- a/Session/Shared/ConversationCell.swift +++ b/Session/Shared/ConversationCell.swift @@ -230,6 +230,13 @@ final class ConversationCell : UITableViewCell { let result = NSMutableAttributedString() if threadViewModel.isMuted { result.append(NSAttributedString(string: "\u{e067} ", attributes: [ .font : UIFont.ows_elegantIconsFont(10), .foregroundColor : Colors.unimportant ])) + } else if threadViewModel.isOnlyNotifyingForMentions { + let imageAttachment = NSTextAttachment() + imageAttachment.image = UIImage(named: "NotifyMentions.png")?.asTintedImage(color: Colors.unimportant) + imageAttachment.bounds = CGRect(x: 0, y: -2, width: Values.smallFontSize, height: Values.smallFontSize) + let imageString = NSAttributedString(attachment: imageAttachment) + result.append(imageString) + result.append(NSAttributedString(string: " ", attributes: [ .font : UIFont.ows_elegantIconsFont(10), .foregroundColor : Colors.unimportant ])) } if let rawSnippet = threadViewModel.lastMessageText { let snippet = MentionUtilities.highlightMentions(in: rawSnippet, threadID: threadViewModel.threadRecord.uniqueId!) diff --git a/Session/Utilities/MentionUtilities.swift b/Session/Utilities/MentionUtilities.swift index 1a39cb1fa..5c888b09d 100644 --- a/Session/Utilities/MentionUtilities.swift +++ b/Session/Utilities/MentionUtilities.swift @@ -44,4 +44,9 @@ public final class MentionUtilities : NSObject { } return result } + + public static func isUserMentioned(in string: String) -> Bool { + let userPublicKey = getUserHexEncodedPublicKey() + return string.contains("@\(userPublicKey)") + } } diff --git a/SessionMessagingKit/Threads/TSGroupThread.h b/SessionMessagingKit/Threads/TSGroupThread.h index 659ddd897..0599d0461 100644 --- a/SessionMessagingKit/Threads/TSGroupThread.h +++ b/SessionMessagingKit/Threads/TSGroupThread.h @@ -18,6 +18,7 @@ extern NSString *const TSGroupThread_NotificationKey_UniqueId; @property (nonatomic, strong) TSGroupModel *groupModel; @property (nonatomic, readonly) BOOL isOpenGroup; @property (nonatomic, readonly) BOOL isClosedGroup; +@property (nonatomic) BOOL isOnlyNotifyingForMentions; + (instancetype)getOrCreateThreadWithGroupModel:(TSGroupModel *)groupModel; + (instancetype)getOrCreateThreadWithGroupModel:(TSGroupModel *)groupModel @@ -44,6 +45,7 @@ extern NSString *const TSGroupThread_NotificationKey_UniqueId; transaction:(YapDatabaseReadWriteTransaction *)transaction; - (void)setGroupModel:(TSGroupModel *)newGroupModel withTransaction:(YapDatabaseReadWriteTransaction *)transaction; +- (void)setisOnlyNotifyingForMentions:(BOOL)isOnlyNotifyingForMentions withTransaction:(YapDatabaseReadWriteTransaction *)transaction; - (void)leaveGroupWithSneakyTransaction; - (void)leaveGroupWithTransaction:(YapDatabaseReadWriteTransaction *)transaction; diff --git a/SessionMessagingKit/Threads/TSGroupThread.m b/SessionMessagingKit/Threads/TSGroupThread.m index 542a2bb4e..f05d42732 100644 --- a/SessionMessagingKit/Threads/TSGroupThread.m +++ b/SessionMessagingKit/Threads/TSGroupThread.m @@ -208,6 +208,17 @@ NSString *const TSGroupThread_NotificationKey_UniqueId = @"TSGroupThread_Notific }]; } +- (void)setisOnlyNotifyingForMentions:(BOOL)isOnlyNotifyingForMentions withTransaction:(YapDatabaseReadWriteTransaction *)transaction +{ + self.isOnlyNotifyingForMentions = isOnlyNotifyingForMentions; + + [self saveWithTransaction:transaction]; + + [transaction addCompletionQueue:dispatch_get_main_queue() completionBlock:^{ + [NSNotificationCenter.defaultCenter postNotificationName:NSNotification.groupThreadUpdated object:self.uniqueId]; + }]; +} + - (void)leaveGroupWithSneakyTransaction { [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { diff --git a/SessionSnodeKit/SnodeAPI.swift b/SessionSnodeKit/SnodeAPI.swift index 8c0a43d52..fe15bccf5 100644 --- a/SessionSnodeKit/SnodeAPI.swift +++ b/SessionSnodeKit/SnodeAPI.swift @@ -413,22 +413,27 @@ public final class SnodeAPI : NSObject { private static func getMessagesInternal(from snode: Snode, associatedWith publicKey: String) -> RawResponsePromise { let storage = SNSnodeKitConfiguration.shared.storage - guard let userED25519KeyPair = storage.getUserED25519KeyPair() else { return Promise(error: Error.noKeyPair) } + + // NOTE: All authentication logic is currently commented out, the reason being that we can't currently support + // it yet for closed groups. The Storage Server requires an ed25519 key pair, but we don't have that for our + // closed groups. + +// guard let userED25519KeyPair = storage.getUserED25519KeyPair() else { return Promise(error: Error.noKeyPair) } // Get last message hash storage.pruneLastMessageHashInfoIfExpired(for: snode, associatedWith: publicKey) let lastHash = storage.getLastMessageHash(for: snode, associatedWith: publicKey) ?? "" // Construct signature - let timestamp = UInt64(Int64(NSDate.millisecondTimestamp()) + SnodeAPI.clockOffset) - let ed25519PublicKey = userED25519KeyPair.publicKey.toHexString() - let verificationData = ("retrieve" + String(timestamp)).data(using: String.Encoding.utf8)! - let signature = sodium.sign.signature(message: Bytes(verificationData), secretKey: userED25519KeyPair.secretKey)! +// let timestamp = UInt64(Int64(NSDate.millisecondTimestamp()) + SnodeAPI.clockOffset) +// let ed25519PublicKey = userED25519KeyPair.publicKey.toHexString() +// let verificationData = ("retrieve" + String(timestamp)).data(using: String.Encoding.utf8)! +// let signature = sodium.sign.signature(message: Bytes(verificationData), secretKey: userED25519KeyPair.secretKey)! // Make the request let parameters: JSON = [ "pubKey" : Features.useTestnet ? publicKey.removing05PrefixIfNeeded() : publicKey, "lastHash" : lastHash, - "timestamp" : timestamp, - "pubkey_ed25519" : ed25519PublicKey, - "signature" : signature.toBase64()! +// "timestamp" : timestamp, +// "pubkey_ed25519" : ed25519PublicKey, +// "signature" : signature.toBase64()! ] return invoke(.getMessages, on: snode, associatedWith: publicKey, parameters: parameters) } diff --git a/SignalUtilitiesKit/Messaging/ThreadViewModel.swift b/SignalUtilitiesKit/Messaging/ThreadViewModel.swift index 98bbf91d5..30177ec11 100644 --- a/SignalUtilitiesKit/Messaging/ThreadViewModel.swift +++ b/SignalUtilitiesKit/Messaging/ThreadViewModel.swift @@ -14,6 +14,7 @@ public class ThreadViewModel: NSObject { @objc public let contactSessionID: String? @objc public let name: String @objc public let isMuted: Bool + @objc public let isOnlyNotifyingForMentions: Bool var isContactThread: Bool { return !isGroupThread @@ -39,6 +40,12 @@ public class ThreadViewModel: NSObject { } else { self.contactSessionID = nil } + + if let groupThread = thread as? TSGroupThread { + self.isOnlyNotifyingForMentions = groupThread.isOnlyNotifyingForMentions + } else { + self.isOnlyNotifyingForMentions = false + } self.unreadCount = thread.unreadMessageCount(transaction: transaction) self.hasUnreadMessages = unreadCount > 0