mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00

ChatController: fixed visual glitches ChatController: fixed reverse mention format propagation
210 lines
5.7 KiB
Objective-C
210 lines
5.7 KiB
Objective-C
#import "RaiseToListenActivator.h"
|
|
|
|
#import <UIKit/UIKit.h>
|
|
#import <SSignalKit/SSignalKit.h>
|
|
|
|
#import "DeviceProximityManager.h"
|
|
|
|
static NSString *TGEncodeText(NSString *string, int key)
|
|
{
|
|
NSMutableString *result = [[NSMutableString alloc] init];
|
|
|
|
for (int i = 0; i < (int)[string length]; i++)
|
|
{
|
|
unichar c = [string characterAtIndex:i];
|
|
c += key;
|
|
[result appendString:[NSString stringWithCharacters:&c length:1]];
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
static void TGDispatchOnMainThread(dispatch_block_t block)
|
|
{
|
|
if ([NSThread isMainThread])
|
|
block();
|
|
else
|
|
dispatch_async(dispatch_get_main_queue(), block);
|
|
}
|
|
|
|
@protocol RaiseManager <NSObject>
|
|
|
|
- (id)initWithPriority:(int)priority;
|
|
- (void)setGestureHandler:(void (^)(int, int))handler;
|
|
|
|
@end
|
|
|
|
@interface RaiseToListenActivator () {
|
|
NSInteger _proximityStateIndex;
|
|
|
|
bool (^_shouldActivate)(void);
|
|
void (^_activate)(void);
|
|
void (^_deactivate)(void);
|
|
|
|
bool _proximityState;
|
|
STimer *_timer;
|
|
|
|
id _manager;
|
|
CFTimeInterval _activationTimestamp;
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation RaiseToListenActivator
|
|
|
|
- (instancetype)initWithShouldActivate:(bool (^)(void))shouldActivate activate:(void (^)(void))activate deactivate:(void (^)(void))deactivate {
|
|
self = [super init];
|
|
if (self != nil) {
|
|
_shouldActivate = [shouldActivate copy];
|
|
_activate = [activate copy];
|
|
_deactivate = [deactivate copy];
|
|
|
|
_enabled = false;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc {
|
|
[_timer invalidate];
|
|
_timer = nil;
|
|
|
|
[self setEnabled:false];
|
|
}
|
|
|
|
- (void)setEnabled:(bool)enabled {
|
|
if (_enabled != enabled) {
|
|
_enabled = enabled;
|
|
|
|
if (enabled) {
|
|
Class c = NSClassFromString(TGEncodeText(@"DNHftuvsfNbobhfs", -1));
|
|
if (c != nil) {
|
|
_manager = [(id<RaiseManager>)[c alloc] initWithPriority:0x2];
|
|
__weak RaiseToListenActivator *weakSelf = self;
|
|
[_manager setGestureHandler:^(int arg0, int arg1) {
|
|
__strong RaiseToListenActivator *strongSelf = weakSelf;
|
|
if (strongSelf != nil) {
|
|
if (arg0 == 0) {
|
|
[strongSelf startCheckingProximity:0.0];
|
|
}
|
|
}
|
|
}];
|
|
}
|
|
} else {
|
|
[_manager setGestureHandler:nil];
|
|
_manager = nil;
|
|
[self stopCheckingProximity];
|
|
if (_activated) {
|
|
_activated = false;
|
|
if (_deactivate) {
|
|
_deactivate();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)stopCheckingProximity {
|
|
if (_proximityStateIndex != -1) {
|
|
[[DeviceProximityManager shared] remove:_proximityStateIndex];
|
|
_proximityStateIndex = -1;
|
|
}
|
|
}
|
|
|
|
- (bool)shouldActivate {
|
|
if (_shouldActivate) {
|
|
return _shouldActivate();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
- (void)startCheckingProximity:(double)__unused delay {
|
|
if (_enabled && [self shouldActivate]) {
|
|
NSInteger previousIndex = _proximityStateIndex;
|
|
__weak RaiseToListenActivator *weakSelf = self;
|
|
_proximityStateIndex = [[DeviceProximityManager shared] add:^(bool value) {
|
|
__strong RaiseToListenActivator *strongSelf = weakSelf;
|
|
if (strongSelf != nil) {
|
|
[strongSelf proximityChanged:value];
|
|
}
|
|
}];
|
|
if (previousIndex != -1) {
|
|
[[DeviceProximityManager shared] remove:previousIndex];
|
|
}
|
|
|
|
if (_proximityState) {
|
|
_activated = true;
|
|
_activationTimestamp = CACurrentMediaTime();
|
|
if (_activate) {
|
|
_activate();
|
|
}
|
|
|
|
[_timer invalidate];
|
|
_timer = nil;
|
|
} else if (_timer == nil) {
|
|
__weak RaiseToListenActivator *weakSelf = self;
|
|
_timer = [[STimer alloc] initWithTimeout:1.0 repeat:false completion:^{
|
|
__strong RaiseToListenActivator *strongSelf = weakSelf;
|
|
if (strongSelf != nil) {
|
|
strongSelf->_timer = nil;
|
|
[strongSelf stopCheckingProximity];
|
|
}
|
|
} queue:[SQueue mainQueue]];
|
|
[_timer start];
|
|
}
|
|
}
|
|
}
|
|
|
|
- (void)proximityChanged:(bool)proximityState {
|
|
TGDispatchOnMainThread(^{
|
|
if (_proximityState != proximityState) {
|
|
_proximityState = proximityState;
|
|
|
|
if (proximityState && _timer != nil) {
|
|
[_timer invalidate];
|
|
_timer = nil;
|
|
_activated = true;
|
|
_activationTimestamp = CACurrentMediaTime();
|
|
|
|
if (_activate) {
|
|
_activate();
|
|
}
|
|
} else if (!proximityState) {
|
|
[_timer invalidate];
|
|
_timer = nil;
|
|
[self stopCheckingProximity];
|
|
|
|
_activated = false;
|
|
if (_deactivate) {
|
|
_deactivate();
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
- (void)activateBasedOnProximityWithDelay:(double)delay {
|
|
if ([[DeviceProximityManager shared] currentValue]) {
|
|
[self startCheckingProximity:delay];
|
|
}
|
|
}
|
|
|
|
- (void)applicationResignedActive {
|
|
if (_activated) {
|
|
CFTimeInterval duration = CACurrentMediaTime() - _activationTimestamp;
|
|
if (duration > 0.0 && duration < 1.0) {
|
|
[_timer invalidate];
|
|
_timer = nil;
|
|
[self stopCheckingProximity];
|
|
|
|
_activated = false;
|
|
if (_deactivate) {
|
|
_deactivate();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@end
|
|
|