Skip to content
This repository has been archived by the owner on Jan 24, 2022. It is now read-only.

Commit

Permalink
[global] i spent all day preventing this function from recursing
Browse files Browse the repository at this point in the history
  • Loading branch information
kirb committed Feb 11, 2017
1 parent 8f5d6e3 commit aee4a68
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 18 deletions.
16 changes: 16 additions & 0 deletions global/HBTSConversationPreferences.x
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#import <IMCore/IMChat.h>
#import <IMCore/IMHandle.h>
#import <version.h>
#include <notify.h>

@implementation HBTSConversationPreferences {
HBPreferences *_preferences;
Expand Down Expand Up @@ -65,6 +66,14 @@
[_preferences registerPreferenceChangeBlock:callback];
}

- (void)_postReadReceiptNotification {
// if we do this in imagent, the callback for this notification can cause an infinite loop, so
// don’t post it in that case
if (!self._isInIMAgent) {
notify_post("ws.hbang.typestatus/ReadReceiptSettingsChanged");
}
}

#pragma mark - Keys

- (NSString *)_keyForChat:(IMChat *)chat type:(NSString *)type {
Expand Down Expand Up @@ -101,6 +110,11 @@
return key ? [_preferences boolForKey:key default:self._readReceiptsEnabled] : self._readReceiptsEnabled;
}

- (NSNumber *)readReceiptsEnabledForHandleAsNumber:(NSString *)handle {
NSString *key = [self _keyForHandle:handle type:@"Read"];
return key ? [_preferences objectForKey:key] : nil;
}

#pragma mark - Setters

- (void)setTypingNotificationsEnabled:(BOOL)enabled forChat:(IMChat *)chat {
Expand All @@ -109,6 +123,7 @@

- (void)setReadReceiptsEnabled:(BOOL)enabled forChat:(IMChat *)chat {
[_preferences setBool:enabled forKey:[self _keyForChat:chat type:@"Read"]];
[self _postReadReceiptNotification];
}

- (void)setTypingNotificationsEnabled:(BOOL)enabled forHandle:(NSString *)handle {
Expand All @@ -117,6 +132,7 @@

- (void)setReadReceiptsEnabled:(BOOL)enabled forHandle:(NSString *)handle {
[_preferences setBool:enabled forKey:[self _keyForHandle:handle type:@"Read"]];
[self _postReadReceiptNotification];
}

#pragma mark - Add/Remove
Expand Down
2 changes: 1 addition & 1 deletion messages/DetailsController.x
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ NSBundle *bundle;
}

- (void)readReceiptsSwitchValueChanged:(UISwitch *)sender {
// update ours as well
// update our read receipt enabled state
[self._typeStatus_preferences setReadReceiptsEnabled:sender.on forChat:self.conversation.chat];
}

Expand Down
31 changes: 14 additions & 17 deletions relay/ReadReceiptMirror.x
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@

- (BOOL)_readReceiptsEnabled;

- (NSNumber *)readReceiptsEnabledForHandleAsNumber:(NSString *)handle;

@end

extern HBTSConversationPreferences *preferences;

// ugly workaround to avoid infinite loops
BOOL updating = YES;

void mirrorNativeReadReceiptPreferences() {
// grab the chats, and the global state
NSArray <IMDChat *> *chats = ((IMDChatRegistry *)[%c(IMDChatRegistry) sharedInstance]).chats;
Expand All @@ -31,18 +30,19 @@ void mirrorNativeReadReceiptPreferences() {

// get the native read receipt value, as well as our own
NSNumber *value = chat.properties[@"EnableReadReceiptForChat"];
BOOL ourValue = [preferences readReceiptsEnabledForHandle:handle];
NSNumber *ourValue = [preferences readReceiptsEnabledForHandleAsNumber:handle];

// if it’s been set at least once before and is different from the global state
if (value && value.boolValue != globalState) {
// mirror it over to our side
updating = YES;
[preferences setReadReceiptsEnabled:value.boolValue forHandle:handle];
} else if (!value && ourValue != globalState) {
// if the value is nil, but we have a value that is different from the global state
}

// if we have a value, and the system doesn’t or it differs from ours
if (ourValue && (!value || value.boolValue != ourValue.boolValue)) {
// mirror it over to the other side
[chat updateProperties:@{
@"EnableReadReceiptForChat": @(ourValue),
@"EnableReadReceiptForChat": ourValue,
@"EnableReadReceiptForChatVersionID": @1
}];
}
Expand All @@ -52,9 +52,11 @@ void mirrorNativeReadReceiptPreferences() {
%hook IMDChatRegistry

- (void)loadChatsWithCompletionBlock:(void(^)())completion {
// override the completion block so we can execute our mirror logic immediately
// override the completion block so we can execute our mirror logic afterwards
__block void (^oldCompletion)() = [completion copy];

void (^newCompletion)() = ^{
completion();
oldCompletion();
mirrorNativeReadReceiptPreferences();
};

Expand All @@ -64,11 +66,6 @@ void mirrorNativeReadReceiptPreferences() {
%end

%ctor {
[preferences registerPreferenceChangeBlock:^{
if (updating) {
updating = NO;
} else {
mirrorNativeReadReceiptPreferences();
}
}];
// register a preference change block so we can execute another mirror
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), NULL, (CFNotificationCallback)mirrorNativeReadReceiptPreferences, CFSTR("ws.hbang.typestatus/ReadReceiptSettingsChanged"), NULL, kNilOptions);
}

0 comments on commit aee4a68

Please sign in to comment.