Skip to content

Commit

Permalink
6.4.6-rc2 (#1289)
Browse files Browse the repository at this point in the history
Reverts #1287
  • Loading branch information
tmolitor-stud-tu authored Nov 9, 2024
2 parents 3256769 + 68d3029 commit 961bbc2
Show file tree
Hide file tree
Showing 10 changed files with 30 additions and 107 deletions.
2 changes: 1 addition & 1 deletion Monal/Classes/ActiveChatsViewController.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, weak) IBOutlet UIBarButtonItem* settingsButton;
@property (weak, nonatomic) IBOutlet UIBarButtonItem* spinnerButton;
@property (nonatomic, weak) IBOutlet UIBarButtonItem* composeButton;
@property (nonatomic, strong) chatViewController* currentChatViewController;
@property (nonatomic, strong) UIActivityIndicatorView* spinner;
@property (atomic, readonly) chatViewController* _Nullable currentChatView;

-(void) showCallContactNotFoundAlert:(NSString*) jid;
-(void) callContact:(MLContact*) contact withUIKitSender:(_Nullable id) sender;
Expand Down
19 changes: 4 additions & 15 deletions Monal/Classes/ActiveChatsViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -361,13 +361,13 @@ -(void) refreshDisplay

dispatch_async(dispatch_get_main_queue(), ^{
//make sure we don't display a chat view for a disabled account
if([MLNotificationManager sharedInstance].currentContact != nil)
if(self.currentChatViewController != nil && self.currentChatViewController.contact != nil)
{
BOOL found = NO;
for(NSDictionary* accountDict in [[DataLayer sharedInstance] enabledAccountList])
{
NSNumber* accountID = accountDict[kAccountID];
if([MLNotificationManager sharedInstance].currentContact.accountID.intValue == accountID.intValue)
NSNumber* accountNo = accountDict[kAccountID];
if(self.currentChatViewController.contact.accountId.intValue == accountNo.intValue)
found = YES;
}
if(!found)
Expand Down Expand Up @@ -879,7 +879,6 @@ -(void) presentSplitPlaceholder
UIViewController* detailsViewController = [[SwiftuiInterface new] makeViewWithName:@"ChatPlaceholder"];
[self showDetailViewController:detailsViewController sender:self];
}
[MLNotificationManager sharedInstance].currentContact = nil;
}

-(void) showNotificationSettings
Expand Down Expand Up @@ -1095,6 +1094,7 @@ -(void) prepareForSegue:(UIStoryboardSegue*) segue sender:(id) sender
UIBarButtonItem* barButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.backBarButtonItem = barButtonItem;
[chatVC setupWithContact:sender];
self.currentChatViewController = chatVC;
}
else if([segue.identifier isEqualToString:@"showDetails"])
{
Expand Down Expand Up @@ -1513,17 +1513,6 @@ -(void) dismissRecursorWithViewControllers:(NSMutableArray*) viewControllers ani
}
}

-(chatViewController* _Nullable) currentChatView
{
NSArray* controllers = ((UINavigationController*)self.splitViewController.viewControllers[0]).viewControllers;
chatViewController* chatView = nil;
if(controllers.count > 1)
chatView = [((UINavigationController*)controllers[1]).viewControllers firstObject];
if(![chatView isKindOfClass:NSClassFromString(@"chatViewController")])
chatView = nil;
return chatView;
}

-(void) scrollToContact:(MLContact*) contact
{
__block NSIndexPath* indexPath = nil;
Expand Down
4 changes: 0 additions & 4 deletions Monal/Classes/HelperTools.m
Original file line number Diff line number Diff line change
Expand Up @@ -2352,12 +2352,8 @@ +(NSString*) encodeRandomResource
u_int32_t i=arc4random();
#if TARGET_OS_MACCATALYST
NSString* resource = [NSString stringWithFormat:@"Monal-macOS.%@", [self hexadecimalString:[NSData dataWithBytes: &i length: sizeof(i)]]];
#else
#if IS_QUICKSY
NSString* resource = [NSString stringWithFormat:@"Quicksy-iOS.%@", [self hexadecimalString:[NSData dataWithBytes: &i length: sizeof(i)]]];
#else
NSString* resource = [NSString stringWithFormat:@"Monal-iOS.%@", [self hexadecimalString:[NSData dataWithBytes: &i length: sizeof(i)]]];
#endif
#endif
return resource;
}
Expand Down
27 changes: 2 additions & 25 deletions Monal/Classes/MLDelayableTimer.m
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,7 @@ -(void) start
return;
}
DDLogDebug(@"Starting timer: %@", self);
//scheduling and unscheduling of a timer must be done from the same thread --> use our runloop
[self scheduleBlockInRunLoop:^{
[[HelperTools getExtraRunloopWithIdentifier:MLRunLoopIdentifierTimer] addTimer:self->_wrappedTimer forMode:NSRunLoopCommonModes];
}];
[[HelperTools getExtraRunloopWithIdentifier:MLRunLoopIdentifierTimer] addTimer:_wrappedTimer forMode:NSRunLoopCommonModes];
}
}

Expand Down Expand Up @@ -134,28 +131,8 @@ -(void) invalidate
return;
}
//DDLogVerbose(@"Invalidating timer: %@", self);
//scheduling and unscheduling of a timer must be done from the same thread --> use our runloop
[self scheduleBlockInRunLoop:^{
[self->_wrappedTimer invalidate];
}];
[_wrappedTimer invalidate];
}
}

-(void) scheduleBlockInRunLoop:(monal_void_block_t) block
{
NSRunLoop* runLoop = [HelperTools getExtraRunloopWithIdentifier:MLRunLoopIdentifierTimer];
// NSCondition* condition = [NSCondition new];
// [condition lock];
CFRunLoopPerformBlock([runLoop getCFRunLoop], (__bridge CFStringRef)NSDefaultRunLoopMode, ^{
block();
// [condition lock];
// [condition signal];
// [condition unlock];
});
CFRunLoopWakeUp([runLoop getCFRunLoop]); //trigger wakeup of runloop to execute the block as soon as possible
// //wait for our block to finish executing
// [condition wait];
// [condition unlock];
}

@end
46 changes: 10 additions & 36 deletions Monal/Classes/MLMessageProcessor.m
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ +(MLMessage* _Nullable) processMessage:(XMPPMessage*) messageNode andOuterMessag
}

//ignore messages from our own device, see this github issue: https://github.com/monal-im/Monal/issues/941
if(!isMLhistory && [messageNode.from isEqualToString:account.connectionProperties.identity.fullJid] && [messageNode.toUser isEqualToString:account.connectionProperties.identity.jid])
if(![messageNode check:@"/<type=groupchat>"] && !isMLhistory && [messageNode.from isEqualToString:account.connectionProperties.identity.fullJid] && [messageNode.toUser isEqualToString:account.connectionProperties.identity.jid])
return nil;

//handle incoming jmi calls (TODO: add entry to local history, once the UI for this is implemented)
Expand Down Expand Up @@ -207,10 +207,8 @@ +(MLMessage* _Nullable) processMessage:(XMPPMessage*) messageNode andOuterMessag

//ignore muc PMs (after discussion with holger we don't want to support that)
if(
![messageNode check:@"/<type=groupchat>"] &&
[messageNode check:@"{http://jabber.org/protocol/muc#user}x"] &&
![messageNode check:@"{http://jabber.org/protocol/muc#user}x/invite"] &&
[messageNode check:@"body#"]
![messageNode check:@"/<type=groupchat>"] && [messageNode check:@"{http://jabber.org/protocol/muc#user}x"] &&
![messageNode check:@"{http://jabber.org/protocol/muc#user}x/invite"] && [messageNode check:@"body#"]
)
{
DDLogWarn(@"Ignoring muc pm marked as such...");
Expand Down Expand Up @@ -244,7 +242,6 @@ +(MLMessage* _Nullable) processMessage:(XMPPMessage*) messageNode andOuterMessag
DDLogVerbose(@"Not a carbon copy of a muc pm for contact: %@", carbonTestContact);
}


if(([messageNode check:@"/<type=groupchat>"] || [messageNode check:@"{http://jabber.org/protocol/muc#user}x"]) && ![messageNode check:@"{http://jabber.org/protocol/muc#user}x/invite"])
{
// Ignore all group chat msgs from unkown groups
Expand Down Expand Up @@ -275,9 +272,9 @@ +(MLMessage* _Nullable) processMessage:(XMPPMessage*) messageNode andOuterMessag
//check stanza-id @by according to the rules outlined in XEP-0359
if(!stanzaid)
{
if(!possiblyUnknownContact.isMuc && [messageNode check:@"{urn:xmpp:sid:0}stanza-id<by=%@>", account.connectionProperties.identity.jid])
if(![messageNode check:@"/<type=groupchat>"] && [messageNode check:@"{urn:xmpp:sid:0}stanza-id<by=%@>", account.connectionProperties.identity.jid])
stanzaid = [messageNode findFirst:@"{urn:xmpp:sid:0}stanza-id<by=%@>@id", account.connectionProperties.identity.jid];
else if(possiblyUnknownContact.isMuc && [messageNode check:@"{urn:xmpp:sid:0}stanza-id<by=%@>", messageNode.fromUser] && [[account.mucProcessor getRoomFeaturesForMuc:messageNode.fromUser] containsObject:@"urn:xmpp:sid:0"])
else if([messageNode check:@"/<type=groupchat>"] && [messageNode check:@"{urn:xmpp:sid:0}stanza-id<by=%@>", messageNode.fromUser] && [[account.mucProcessor getRoomFeaturesForMuc:messageNode.fromUser] containsObject:@"urn:xmpp:sid:0"])
stanzaid = [messageNode findFirst:@"{urn:xmpp:sid:0}stanza-id<by=%@>@id", messageNode.fromUser];
}

Expand Down Expand Up @@ -316,35 +313,15 @@ +(MLMessage* _Nullable) processMessage:(XMPPMessage*) messageNode andOuterMessag
NSString* actualFrom = messageNode.fromUser;
NSString* participantJid = nil;
NSString* occupantId = nil;
if(possiblyUnknownContact.isMuc)
if([messageNode check:@"/<type=groupchat>"] && messageNode.fromResource)
{
actualFrom = messageNode.fromResource ?: @"";

ownNick = [[DataLayer sharedInstance] ownNickNameforMuc:messageNode.fromUser forAccount:account.accountID];
ownOccupantId = [[DataLayer sharedInstance] getOwnOccupantIdForMuc:messageNode.fromUser onAccountID:account.accountID];

//occupant ids are widely supported now and allow us to have a stable identifier of every muc participant,
//even if it is a semi-anonymous channel
if([[account.mucProcessor getRoomFeaturesForMuc:messageNode.fromUser] containsObject:@"urn:xmpp:occupant-id:0"] && [messageNode check:@"{urn:xmpp:occupant-id:0}occupant-id@id"])
{
occupantId = [messageNode findFirst:@"{urn:xmpp:occupant-id:0}occupant-id@id"];
NSDictionary* mucParticipant = [[DataLayer sharedInstance] getParticipantForOccupant:occupantId inRoom:messageNode.fromUser forAccountID:account.accountID];
//we will be able to get to know the real jid, if this is a group or we are the channel admin
participantJid = mucParticipant ? mucParticipant[@"participant_jid"] : nil;
}

ownNick = [[DataLayer sharedInstance] ownNickNameforMuc:messageNode.fromUser forAccount:account.accountNo];
actualFrom = messageNode.fromResource;
//mam catchups will contain a muc#user item listing the jid of the participant
//this can't be reconstructed from *current* participant lists because someone new could have taken the same nick
//we don't accept this in non-mam context to make sure this can't be spoofed somehow
//we also don't do that, if this was a message from the bare muc jid
//NOTE: this will override the participantJid extracted using the occupantId above,
//NOTE: but those should ALWAYS be the same (that's the exact purpose of occupant ids)
if([outerMessageNode check:@"{urn:xmpp:mam:2}result"] && ![@"" isEqualToString:actualFrom])
participantJid = [messageNode findFirst:@"{http://jabber.org/protocol/muc#user}x/item@jid"];

//try to get the jid of the current participant if the occupant-id based approach above did not work
//but don't do so, if this was a message from the bare muc jid
if(![outerMessageNode check:@"{urn:xmpp:mam:2}result"] && occupantId == nil && participantJid == nil && ![@"" isEqualToString:actualFrom])
participantJid = [messageNode findFirst:@"/<type=groupchat>/{http://jabber.org/protocol/muc#user}x/item@jid"];
if(![outerMessageNode check:@"{urn:xmpp:mam:2}result"] || participantJid == nil)
{
if([[account.mucProcessor getRoomFeaturesForMuc:messageNode.fromUser] containsObject:@"urn:xmpp:occupant-id:0"] && [messageNode check:@"{urn:xmpp:occupant-id:0}occupant-id@id"])
{
Expand Down Expand Up @@ -590,9 +567,6 @@ +(MLMessage* _Nullable) processMessage:(XMPPMessage*) messageNode andOuterMessag
else if([lowercaseBody hasPrefix:@"https://"])
messageType = kMessageTypeUrl;
}
//messages from the bare muc jid are classified as status messages
if(possiblyUnknownContact.isMuc && [@"" isEqualToString:actualFrom])
messageType = kMessageTypeStatus;
DDLogInfo(@"Got message of type: %@", messageType);

if(body)
Expand Down
12 changes: 7 additions & 5 deletions Monal/Classes/MLStream.m
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ @interface MLInputStream()
//(mutexes can not be unlocked in a thread different from the one it got locked in and NSLock internally uses mutext --> both can not be used)
dispatch_semaphore_t _read_sem;
}
@property (atomic, readonly) void (^incoming_data_handler)(NSData* _Nullable, BOOL, NSError* _Nullable);
@property (atomic, readonly) void (^incoming_data_handler)(NSData* _Nullable, BOOL, NSError* _Nullable, BOOL allow_next_read);
@end

@interface MLOutputStream()
Expand Down Expand Up @@ -89,7 +89,7 @@ -(instancetype) initWithSharedState:(MLSharedStreamState*) shared
//this handler will be called by the schedule_read method
//since the framer swallows all data, nw_connection_receive() and the framer cannot race against each other and deliver reordered data
weakify(self);
_incoming_data_handler = ^(NSData* _Nullable content, BOOL is_complete, NSError* _Nullable st_error) {
_incoming_data_handler = ^(NSData* _Nullable content, BOOL is_complete, NSError* _Nullable st_error, BOOL allow_next_read) {
strongify(self);
if(self == nil)
return;
Expand Down Expand Up @@ -142,7 +142,7 @@ -(instancetype) initWithSharedState:(MLSharedStreamState*) shared
[self generateEvent:NSStreamEventEndEncountered];

//try to read again
if(!is_complete && !generate_bytes_available_event)
if(!is_complete && !generate_bytes_available_event && allow_next_read)
[self schedule_read];
};
return self;
Expand Down Expand Up @@ -235,7 +235,8 @@ -(void) schedule_read
DDLogDebug(@"now calling nw_framer_parse_input inside framer queue");
nw_framer_parse_input(self.shared_state.framer, 1, BUFFER_SIZE, nil, ^size_t(uint8_t* buffer, size_t buffer_length, bool is_complete) {
DDLogDebug(@"nw_framer_parse_input got callback with is_complete:%@, length=%zu", bool2str(is_complete), (unsigned long)buffer_length);
self.incoming_data_handler([NSData dataWithBytes:buffer length:buffer_length], is_complete, nil);
//we only want to allow new calls to schedule_read if we received some data --> set last arg accordingly
self.incoming_data_handler([NSData dataWithBytes:buffer length:buffer_length], is_complete, nil, buffer_length > 0);
return buffer_length;
});
});
Expand All @@ -248,7 +249,8 @@ -(void) schedule_read
NSError* st_error = nil;
if(receive_error)
st_error = (NSError*)CFBridgingRelease(nw_error_copy_cf_error(receive_error));
self.incoming_data_handler((NSData*)content, is_complete, st_error);
//we always want to allow new calls to schedule_read --> set last arg to YES
self.incoming_data_handler((NSData*)content, is_complete, st_error, YES);
});
}
}
Expand Down
8 changes: 4 additions & 4 deletions Monal/Classes/MonalAppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -1972,10 +1972,10 @@ -(void) sendAllOutboxes
monal_id_block_t cleanup = ^(NSDictionary* payload) {
[[DataLayer sharedInstance] deleteShareSheetPayloadWithId:payload[@"id"]];
[[MLNotificationQueue currentQueue] postNotificationName:kMonalRefresh object:nil userInfo:nil];
if(self.activeChats.currentChatView != nil)
if(self.activeChats.currentChatViewController != nil)
{
[self.activeChats.currentChatView scrollToBottomAnimated:NO];
[self.activeChats.currentChatView hideUploadHUD];
[self.activeChats.currentChatViewController scrollToBottomAnimated:NO];
[self.activeChats.currentChatViewController hideUploadHUD];
}
//send next item (if there is one left)
[self sendAllOutboxes];
Expand Down Expand Up @@ -2007,7 +2007,7 @@ -(void) sendAllOutboxes
else if([payload[@"type"] isEqualToString:@"image"] || [payload[@"type"] isEqualToString:@"file"] || [payload[@"type"] isEqualToString:@"contact"] || [payload[@"type"] isEqualToString:@"audiovisual"])
{
DDLogInfo(@"Got %@ upload: %@", payload[@"type"], payload[@"data"]);
[self.activeChats.currentChatView showUploadHUD];
[self.activeChats.currentChatViewController showUploadHUD];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
$call(payload[@"data"], $ID(account), $BOOL(encrypted), $ID(completion, (^(NSString* url, NSString* mimeType, NSNumber* size, NSError* error) {
dispatch_async(dispatch_get_main_queue(), ^{
Expand Down
14 changes: 1 addition & 13 deletions Monal/Classes/NotificationDebugging.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@

import OrderedCollections

class NotificationDebuggingDefaultsDB: ObservableObject {
@defaultsDB("lastAppexStart")
var lastAppexStart: Date?
}

struct NotificationDebugging: View {
private let applePushEnabled: Bool
private let applePushToken: String
Expand All @@ -24,25 +19,18 @@ struct NotificationDebugging: View {
@State private var showPushToken = false

@State private var selectedPushServer: String

@ObservedObject var notificationDebuggingDefaultsDB = NotificationDebuggingDefaultsDB()

var body: some View {
Form {
Group {
Section(header: Text("Status").font(.title3)) {
VStack(alignment: .leading, spacing:10) {
VStack(alignment: .leading) {
buildNotificationStateLabel(Text("Apple Push Service"), isWorking: self.applePushEnabled);
Divider()
Text("Apple push service should always be on. If it is off, your device can not talk to Apple's server.").foregroundColor(Color(UIColor.secondaryLabel)).font(.footnote)
if !self.applePushEnabled, let apnsError = MLXMPPManager.sharedInstance().apnsError {
Text("Error: \(String(describing:apnsError))").foregroundColor(.red).font(.footnote)
}
if let lastAppexStart = notificationDebuggingDefaultsDB.lastAppexStart {
Text("Last incoming push: \(String(describing:lastAppexStart))").foregroundColor(.gray).font(.footnote)
} else {
Text("Last incoming push: unknown").foregroundColor(.gray).font(.footnote)
}
}.onTapGesture(count: 2, perform: {
showPushToken = true
}).alert(isPresented: $showPushToken) {
Expand Down
3 changes: 1 addition & 2 deletions Monal/Classes/chatViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -3560,8 +3560,7 @@ -(NSInteger)collectionView:(nonnull UICollectionView*) collectionView numberOfIt

-(void) notifyUploadQueueRemoval:(NSUInteger) index
{
if(index >= self.uploadQueue.count)
return;
MLAssert(index < self.uploadQueue.count, @"index is only allowed to be smaller than uploadQueue.count");
[self.uploadMenuView performBatchUpdates:^{
[self deleteQueueItemAtIndex:index];
} completion:^(BOOL finished) {
Expand Down
2 changes: 0 additions & 2 deletions Monal/NotificationService/NotificationService.m
Original file line number Diff line number Diff line change
Expand Up @@ -441,8 +441,6 @@ +(void) initialize
if(warnUnclean)
DDLogError(@"detected unclean appex shutdown!");

[[HelperTools defaultsDB] setObject:[NSDate now] forKey:@"lastAppexStart"];

//mark this appex as unclean (will be cleared directly before calling exit(0))
[NotificationService setAppexCleanShutdownStatus:NO];
}
Expand Down

0 comments on commit 961bbc2

Please sign in to comment.