Merge branch 'dev' of https://github.com/oxen-io/session-ios into filtered-push-notification
This commit is contained in:
commit
369034d790
|
@ -5063,7 +5063,7 @@
|
|||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 279;
|
||||
CURRENT_PROJECT_VERSION = 284;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = SUQ8J2PCT7;
|
||||
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
|
||||
|
@ -5132,7 +5132,7 @@
|
|||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 279;
|
||||
CURRENT_PROJECT_VERSION = 284;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = SUQ8J2PCT7;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
|
@ -5193,7 +5193,7 @@
|
|||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 279;
|
||||
CURRENT_PROJECT_VERSION = 284;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
DEVELOPMENT_TEAM = SUQ8J2PCT7;
|
||||
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
|
||||
|
@ -5263,7 +5263,7 @@
|
|||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 279;
|
||||
CURRENT_PROJECT_VERSION = 284;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
DEVELOPMENT_TEAM = SUQ8J2PCT7;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
|
@ -6148,7 +6148,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 279;
|
||||
CURRENT_PROJECT_VERSION = 284;
|
||||
DEVELOPMENT_TEAM = SUQ8J2PCT7;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
|
@ -6216,7 +6216,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements;
|
||||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
CURRENT_PROJECT_VERSION = 279;
|
||||
CURRENT_PROJECT_VERSION = 284;
|
||||
DEVELOPMENT_TEAM = SUQ8J2PCT7;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
|
|
|
@ -689,7 +689,7 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc
|
|||
return cancelVoiceMessageRecording()
|
||||
}
|
||||
// Limit voice messages to a minute
|
||||
audioTimer = Timer.scheduledTimer(withTimeInterval: 60, repeats: false, block: { [weak self] _ in
|
||||
audioTimer = Timer.scheduledTimer(withTimeInterval: 180, repeats: false, block: { [weak self] _ in
|
||||
self?.snInputView.hideVoiceMessageUI()
|
||||
self?.endVoiceMessageRecording()
|
||||
})
|
||||
|
|
|
@ -55,6 +55,11 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat
|
|||
return messagesTableView.contentSize.height - tableViewUnobscuredHeight
|
||||
}
|
||||
|
||||
var isCloseToBottom: Bool {
|
||||
let margin = (self.lastPageTop - self.messagesTableView.contentOffset.y)
|
||||
return margin <= ConversationVC.scrollToBottomMargin
|
||||
}
|
||||
|
||||
lazy var mnemonic: String = {
|
||||
let identityManager = OWSIdentityManager.shared()
|
||||
let databaseConnection = identityManager.value(forKey: "dbConnection") as! YapDatabaseConnection
|
||||
|
@ -150,7 +155,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) {
|
||||
|
@ -314,6 +319,13 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat
|
|||
baselineKeyboardHeight = newHeight
|
||||
self.messagesTableView.keyboardHeight = newHeight
|
||||
}
|
||||
let margin = (self.lastPageTop - self.messagesTableView.contentOffset.y)
|
||||
// HACK: If the keyboard is coming up and we're very close to the bottom, scroll to the
|
||||
// bottom. This "fixes" an issue where the conversation would randomly scroll up sometimes
|
||||
// when bringing up the keyboard.
|
||||
if newHeight > 200 && margin <= 2 {
|
||||
scrollToBottom(isAnimated: false)
|
||||
}
|
||||
scrollButtonConstraint?.constant = -(newHeight + 16)
|
||||
let newContentOffsetY = max(self.messagesTableView.contentOffset.y + min(lastPageTop, 0) + newHeight - self.messagesTableView.keyboardHeight, 0.0)
|
||||
self.messagesTableView.contentOffset.y = newContentOffsetY
|
||||
|
@ -353,13 +365,11 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat
|
|||
if update.viewItem?.interaction is TSOutgoingMessage {
|
||||
shouldScrollToBottom = true
|
||||
} else {
|
||||
let margin = (self.lastPageTop - self.messagesTableView.contentOffset.y)
|
||||
shouldScrollToBottom = margin <= ConversationVC.scrollToBottomMargin
|
||||
shouldScrollToBottom = self.isCloseToBottom
|
||||
}
|
||||
case .update:
|
||||
self.messagesTableView.reloadRows(at: [ IndexPath(row: Int(update.oldIndex), section: 0) ], with: .fade)
|
||||
let margin = (self.lastPageTop - self.messagesTableView.contentOffset.y)
|
||||
shouldScrollToBottom = margin <= ConversationVC.scrollToBottomMargin
|
||||
shouldScrollToBottom = self.isCloseToBottom
|
||||
default: preconditionFailure()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -546,7 +546,7 @@ CGFloat kIconViewLength = 24;
|
|||
[topRow autoPinEdgesToSuperviewMarginsExcludingEdge:ALEdgeBottom];
|
||||
|
||||
UILabel *subtitleLabel = [UILabel new];
|
||||
subtitleLabel.text = NSLocalizedString(@"When enabled, only messages mentioned you will be notified.", @"");
|
||||
subtitleLabel.text = NSLocalizedString(@"vc_conversation_settings_notify_for_mentions_only_explanation", @"");
|
||||
subtitleLabel.textColor = LKColors.text;
|
||||
subtitleLabel.font = [UIFont systemFontOfSize:LKValues.smallFontSize];
|
||||
subtitleLabel.numberOfLines = 0;
|
||||
|
|
|
@ -168,8 +168,7 @@ public class NotificationPresenter: NSObject, NotificationsProtocol {
|
|||
|
||||
// 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 {
|
||||
if let groupThread = thread as? TSGroupThread, groupThread.isOnlyNotifyingForMentions && !incomingMessage.isUserMentioned {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -157,8 +157,7 @@ final class ConversationCell : UITableViewCell {
|
|||
// MARK: Updating
|
||||
private func update() {
|
||||
AssertIsOnMainThread()
|
||||
guard let thread = threadViewModel?.threadRecord, let threadID = thread.uniqueId else { return }
|
||||
MentionsManager.populateUserPublicKeyCacheIfNeeded(for: threadID) // FIXME: This is a terrible place to do this
|
||||
guard let thread = threadViewModel?.threadRecord else { return }
|
||||
let isBlocked: Bool
|
||||
if let thread = thread as? TSContactThread {
|
||||
isBlocked = SSKEnvironment.shared.blockingManager.isRecipientIdBlocked(thread.contactSessionID())
|
||||
|
|
|
@ -16,6 +16,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
@property (nonatomic, readonly) BOOL wasReceivedByUD;
|
||||
|
||||
@property (nonatomic, readonly) BOOL isUserMentioned;
|
||||
|
||||
- (instancetype)initMessageWithTimestamp:(uint64_t)timestamp
|
||||
inThread:(nullable TSThread *)thread
|
||||
messageBody:(nullable NSString *)body
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#import "TSGroupThread.h"
|
||||
#import <YapDatabase/YapDatabaseConnection.h>
|
||||
#import <SessionUtilitiesKit/SessionUtilitiesKit.h>
|
||||
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
@ -121,6 +122,12 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
return self.isExpiringMessage;
|
||||
}
|
||||
|
||||
- (BOOL)isUserMentioned
|
||||
{
|
||||
NSString *userPublicKey = [SNGeneralUtilities getUserPublicKey];
|
||||
return (self.body != nil && [self.body containsString:[NSString stringWithFormat:@"@%@", userPublicKey]]) || (self.quotedMessage != nil && [self.quotedMessage.authorId isEqualToString:userPublicKey]);
|
||||
}
|
||||
|
||||
#pragma mark - OWSReadTracking
|
||||
|
||||
- (BOOL)shouldAffectUnreadCounts
|
||||
|
|
|
@ -288,7 +288,11 @@ extension MessageReceiver {
|
|||
// Notify the user if needed
|
||||
guard (isMainAppAndActive || isBackgroundPoll), let tsIncomingMessage = TSMessage.fetch(uniqueId: tsMessageID, transaction: transaction) as? TSIncomingMessage,
|
||||
let thread = TSThread.fetch(uniqueId: threadID, transaction: transaction) else { return tsMessageID }
|
||||
SSKEnvironment.shared.notificationsManager!.notifyUser(for: tsIncomingMessage, in: thread, transaction: transaction)
|
||||
DispatchQueue.main.async {
|
||||
Storage.read { transaction in
|
||||
SSKEnvironment.shared.notificationsManager!.notifyUser(for: tsIncomingMessage, in: thread, transaction: transaction)
|
||||
}
|
||||
}
|
||||
return tsMessageID
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ public final class ClosedGroupPoller : NSObject {
|
|||
private var timers: [String:Timer] = [:]
|
||||
|
||||
// MARK: Settings
|
||||
private static let minPollInterval: Double = 4
|
||||
private static let maxPollInterval: Double = 2 * 60
|
||||
private static let minPollInterval: Double = 2
|
||||
private static let maxPollInterval: Double = 30
|
||||
|
||||
// MARK: Error
|
||||
private enum Error : LocalizedError {
|
||||
|
|
|
@ -72,11 +72,13 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
[LKStorage readWithBlock:^(YapDatabaseReadTransaction *transaction) {
|
||||
YapDatabaseViewTransaction *unreadMessages = [transaction ext:TSUnreadDatabaseViewExtensionName];
|
||||
NSArray<NSString *> *allGroups = [unreadMessages allGroups];
|
||||
// FIXME: Confusingly, `allGroups` includes contact threads as well
|
||||
for (NSString *groupID in allGroups) {
|
||||
TSThread *thread = [TSThread fetchObjectWithUniqueID:groupID transaction:transaction];
|
||||
if (thread.isMuted) continue;
|
||||
if (thread.isMuted) { continue; }
|
||||
BOOL isGroupThread = thread.isGroupThread;
|
||||
[unreadMessages enumerateKeysAndObjectsInGroup:groupID
|
||||
usingBlock:^(NSString *collection, NSString *key, id object, NSUInteger index, BOOL *stop) {
|
||||
usingBlock:^(NSString *collection, NSString *key, id object, NSUInteger index, BOOL *stop) {
|
||||
if (![object conformsToProtocol:@protocol(OWSReadTracking)]) {
|
||||
return;
|
||||
}
|
||||
|
@ -85,6 +87,12 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
NSLog(@"Found an already read message in the * unread * messages list.");
|
||||
return;
|
||||
}
|
||||
if ([object isKindOfClass:TSIncomingMessage.class] && isGroupThread) {
|
||||
TSIncomingMessage *incomingMessage = (TSIncomingMessage *)object;
|
||||
if (((TSGroupThread *)thread).isOnlyNotifyingForMentions && !incomingMessage.isUserMentioned) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
count += 1;
|
||||
}];
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ public final class ProfilePictureView : UIView {
|
|||
publicKey = ""
|
||||
useFallbackPicture = true
|
||||
} else { // A closed group
|
||||
var users = MentionsManager.userPublicKeyCache[thread.uniqueId!] ?? []
|
||||
var users = Set(thread.groupModel.groupMemberIds)
|
||||
users.remove(getUserHexEncodedPublicKey())
|
||||
var randomUsers = users.sorted() // Sort to provide a level of stability
|
||||
if users.count == 1 {
|
||||
|
|
Loading…
Reference in New Issue