diff --git a/submodules/ChatListUI/Sources/ChatListController.swift b/submodules/ChatListUI/Sources/ChatListController.swift index ee97122b5d..5659012f7f 100644 --- a/submodules/ChatListUI/Sources/ChatListController.swift +++ b/submodules/ChatListUI/Sources/ChatListController.swift @@ -1126,6 +1126,26 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController self.chatListDisplayNode.containerNode.updateEnableAdjacentFilterLoading(true) + self.chatListDisplayNode.containerNode.didBeginSelectingChats = { [weak self] in + guard let strongSelf = self else { + return + } + if !strongSelf.chatListDisplayNode.didBeginSelectingChatsWhileEditing { + var isEditing = false + strongSelf.chatListDisplayNode.containerNode.updateState { state in + isEditing = state.editing + return state + } + if !isEditing { + strongSelf.editPressed() + } + strongSelf.chatListDisplayNode.didBeginSelectingChatsWhileEditing = true + if let layout = strongSelf.validLayout { + strongSelf.updateLayout(layout: layout, transition: .animated(duration: 0.2, curve: .easeInOut)) + } + } + } + guard case .root = self.groupId else { return } @@ -1265,27 +1285,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController return true }) } - - self.chatListDisplayNode.containerNode.didBeginSelectingChats = { [weak self] in - guard let strongSelf = self else { - return - } - if !strongSelf.chatListDisplayNode.didBeginSelectingChatsWhileEditing { - var isEditing = false - strongSelf.chatListDisplayNode.containerNode.updateState { state in - isEditing = state.editing - return state - } - if !isEditing { - strongSelf.editPressed() - } - strongSelf.chatListDisplayNode.didBeginSelectingChatsWhileEditing = true - if let layout = strongSelf.validLayout { - strongSelf.updateLayout(layout: layout, transition: .animated(duration: 0.2, curve: .easeInOut)) - } - } - } - + if !self.processedFeaturedFilters { let initializedFeatured = self.context.account.postbox.preferencesView(keys: [ PreferencesKeys.chatListFiltersFeaturedState diff --git a/submodules/ChatListUI/Sources/Node/ChatListNode.swift b/submodules/ChatListUI/Sources/Node/ChatListNode.swift index 2d96d5dbd0..226005a3cd 100644 --- a/submodules/ChatListUI/Sources/Node/ChatListNode.swift +++ b/submodules/ChatListUI/Sources/Node/ChatListNode.swift @@ -1997,6 +1997,13 @@ public final class ChatListNode: ListView { } private func handlePanSelection(location: CGPoint) { + var location = location + if location.y < self.insets.top { + location.y = self.insets.top + 5.0 + } else if location.y > self.frame.height - self.insets.bottom { + location.y = self.frame.height - self.insets.bottom - 5.0 + } + if let state = self.selectionPanState { if let peer = self.peerAtPoint(location) { if peer.id == state.initialPeerId { diff --git a/submodules/LegacyComponents/LegacyImages.xcassets/Camera/Flash.imageset/Contents.json b/submodules/LegacyComponents/LegacyImages.xcassets/Camera/Flash.imageset/Contents.json new file mode 100644 index 0000000000..2ddf28fc77 --- /dev/null +++ b/submodules/LegacyComponents/LegacyImages.xcassets/Camera/Flash.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "ic_cam_flashon (1).pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/submodules/LegacyComponents/LegacyImages.xcassets/Camera/Flash.imageset/ic_cam_flashon (1).pdf b/submodules/LegacyComponents/LegacyImages.xcassets/Camera/Flash.imageset/ic_cam_flashon (1).pdf new file mode 100644 index 0000000000..0cd45d0c0e Binary files /dev/null and b/submodules/LegacyComponents/LegacyImages.xcassets/Camera/Flash.imageset/ic_cam_flashon (1).pdf differ diff --git a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/PGCamera.h b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/PGCamera.h index f8e27bc0a7..16113759ff 100644 --- a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/PGCamera.h +++ b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/PGCamera.h @@ -60,7 +60,7 @@ typedef enum @property (nonatomic, copy) void(^finishedModeChange)(void); @property (nonatomic, copy) void(^beganPositionChange)(bool targetPositionHasFlash, bool targetPositionHasZoom, void(^commitBlock)(void)); -@property (nonatomic, copy) void(^finishedPositionChange)(void); +@property (nonatomic, copy) void(^finishedPositionChange)(bool targetPositionHasZoom); @property (nonatomic, copy) void(^beganAdjustingFocus)(void); @property (nonatomic, copy) void(^finishedAdjustingFocus)(void); diff --git a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGCameraFlashControl.h b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGCameraFlashControl.h index b914fd8eef..50b3dff6d0 100644 --- a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGCameraFlashControl.h +++ b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGCameraFlashControl.h @@ -6,15 +6,13 @@ @property (nonatomic, assign) PGCameraFlashMode mode; @property (nonatomic, assign) UIInterfaceOrientation interfaceOrientation; -@property (nonatomic, copy) void(^becameActive)(void); @property (nonatomic, copy) void(^modeChanged)(PGCameraFlashMode mode); - (void)setFlashUnavailable:(bool)unavailable; +- (void)setFlashActive:(bool)active; - (void)setHidden:(bool)hidden animated:(bool)animated; -- (void)dismissAnimated:(bool)animated; - @end extern const CGFloat TGCameraFlashControlHeight; diff --git a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGCameraMainView.h b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGCameraMainView.h index df2cfbbd03..c8cc7ecaf4 100644 --- a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGCameraMainView.h +++ b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGCameraMainView.h @@ -18,6 +18,10 @@ @class TGMediaPickerGallerySelectedItemsModel; @class TGMediaEditingContext; +@interface TGCameraCornersView : UIImageView + +@end + @interface TGCameraMainView : UIView { UIInterfaceOrientation _interfaceOrientation; diff --git a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGCameraZoomView.h b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGCameraZoomView.h index 6b7e585a18..4ee4776c82 100644 --- a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGCameraZoomView.h +++ b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGCameraZoomView.h @@ -27,7 +27,7 @@ - (void)setHidden:(bool)hidden animated:(bool)animated; -- (instancetype)initWithFrame:(CGRect)frame hasUltrawideCamera:(bool)hasUltrawideCamera hasTelephotoCamera:(bool)hasTelephotoCamera; +- (instancetype)initWithFrame:(CGRect)frame hasUltrawideCamera:(bool)hasUltrawideCamera hasTelephotoCamera:(bool)hasTelephotoCamera minZoomLevel:(CGFloat)minZoomLevel maxZoomLevel:(CGFloat)maxZoomLevel; @end @@ -38,4 +38,6 @@ - (void)setHidden:(bool)hidden animated:(bool)animated; +- (instancetype)initWithFrame:(CGRect)frame hasUltrawideCamera:(bool)hasUltrawideCamera hasTelephotoCamera:(bool)hasTelephotoCamera; + @end diff --git a/submodules/LegacyComponents/Sources/PGCamera.m b/submodules/LegacyComponents/Sources/PGCamera.m index 305cb2c76a..4ffeb5f002 100644 --- a/submodules/LegacyComponents/Sources/PGCamera.m +++ b/submodules/LegacyComponents/Sources/PGCamera.m @@ -690,7 +690,7 @@ NSString *const PGCameraAdjustingFocusKey = @"adjustingFocus"; [strongSelf.captureSession setCurrentCameraPosition:targetCameraPosition]; if (strongSelf.finishedPositionChange != nil) - strongSelf.finishedPositionChange(); + strongSelf.finishedPositionChange([PGCameraCaptureSession _isZoomAvailableForDevice:targetDevice]); [strongSelf _subscribeForCameraChanges]; }]; diff --git a/submodules/LegacyComponents/Sources/TGCameraController.m b/submodules/LegacyComponents/Sources/TGCameraController.m index dbd9ba9d0c..4b0beb4d9a 100644 --- a/submodules/LegacyComponents/Sources/TGCameraController.m +++ b/submodules/LegacyComponents/Sources/TGCameraController.m @@ -107,6 +107,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus UIView *_backgroundView; TGCameraPreviewView *_previewView; TGCameraMainView *_interfaceView; + TGCameraCornersView *_cornersView; UIView *_overlayView; TGCameraFocusCrosshairsControl *_focusControl; TGCameraRectangleView *_rectangleView; @@ -318,6 +319,9 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus _interfaceView.transform = CGAffineTransformMakeRotation(TGRotationForInterfaceOrientation(interfaceOrientation)); _interfaceView.frame = CGRectMake(0, 0, referenceSize.width, referenceSize.height); } + + _cornersView = [[TGCameraCornersView alloc] init]; + if (_intent == TGCameraControllerPassportIdIntent) [_interfaceView setDocumentFrameHidden:false]; _selectedItemsModel = [[TGMediaPickerGallerySelectedItemsModel alloc] initWithSelectionContext:nil items:[_items copy]]; @@ -451,7 +455,8 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus } [_autorotationCorrectionView addSubview:_interfaceView]; - + [_autorotationCorrectionView addSubview:_cornersView]; + _photoSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)]; _photoSwipeGestureRecognizer.delegate = self; [_autorotationCorrectionView addGestureRecognizer:_photoSwipeGestureRecognizer]; @@ -633,7 +638,9 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus [strongSelf->_focusControl reset]; [strongSelf->_interfaceView setHasFlash:targetPositionHasFlash]; - [strongSelf->_interfaceView setHasZoom:targetPositionHasZoom]; + if (!targetPositionHasZoom) { + [strongSelf->_interfaceView setHasZoom:targetPositionHasZoom]; + } strongSelf->_camera.zoomLevel = 0.0f; strongSelf.view.userInteractionEnabled = false; @@ -664,7 +671,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus } }; - _camera.finishedPositionChange = ^ + _camera.finishedPositionChange = ^(bool targetPositionHasZoom) { __strong TGCameraController *strongSelf = weakSelf; if (strongSelf == nil) @@ -675,6 +682,10 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus [strongSelf->_previewView endTransitionAnimated:true]; [strongSelf->_interfaceView setZoomLevel:1.0f displayNeeded:false]; + if (targetPositionHasZoom) { + [strongSelf->_interfaceView setHasZoom:targetPositionHasZoom]; + } + if (strongSelf->_camera.hasFlash && strongSelf->_camera.flashActive) [strongSelf->_interfaceView setFlashActive:true]; @@ -712,8 +723,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus TGDispatchOnMainThread(^ { - if (!strongSelf->_camera.isRecordingVideo) - [strongSelf->_interfaceView setFlashActive:active]; + [strongSelf->_interfaceView setFlashActive:active]; }); }; @@ -904,12 +914,22 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus animation.duration = 0.2f; [_interfaceView.layer addAnimation:animation forKey:@"opacity"]; + CABasicAnimation *cornersAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"]; + cornersAnimation.fromValue = @(_cornersView.alpha); + cornersAnimation.toValue = @(hidden ? 0.0f : 1.0f); + cornersAnimation.duration = 0.2f; + [_cornersView.layer addAnimation:cornersAnimation forKey:@"opacity"]; + _interfaceView.alpha = hidden ? 0.0f : 1.0f; + _cornersView.alpha = hidden ? 0.0 : 1.0; } else { [_interfaceView.layer removeAllAnimations]; - _interfaceView.alpha = 0.0f; + _interfaceView.alpha = hidden ? 0.0 : 1.0; + + [_cornersView.layer removeAllAnimations]; + _cornersView.alpha = hidden ? 0.0 : 1.0; } } @@ -2156,6 +2176,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus [UIView animateWithDuration:0.3f delay:0.1f options:UIViewAnimationOptionCurveLinear animations:^ { _interfaceView.alpha = 1.0f; + _cornersView.alpha = 1.0; } completion:nil]; _interfaceView.previewViewFrame = _previewView.frame; @@ -2173,11 +2194,13 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus _backgroundView.alpha = 0.0f; _interfaceView.alpha = 0.0f; + _cornersView.alpha = 0.0; [UIView animateWithDuration:0.3f animations:^ { _backgroundView.alpha = 1.0f; _interfaceView.alpha = 1.0f; + _cornersView.alpha = 1.0; }]; CGRect fromFrame = rect; @@ -2191,10 +2214,18 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus frameAnimation.springSpeed = 20; frameAnimation.springBounciness = 1; [_previewView pop_addAnimation:frameAnimation forKey:@"frame"]; + + POPSpringAnimation *cornersFrameAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewFrame]; + cornersFrameAnimation.fromValue = [NSValue valueWithCGRect:fromFrame]; + cornersFrameAnimation.toValue = [NSValue valueWithCGRect:toFrame]; + cornersFrameAnimation.springSpeed = 20; + cornersFrameAnimation.springBounciness = 1; + [_cornersView pop_addAnimation:cornersFrameAnimation forKey:@"frame"]; } else { _previewView.frame = toFrame; + _cornersView.frame = toFrame; } _interfaceView.previewViewFrame = toFrame; @@ -2208,16 +2239,12 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus _focusControl.active = false; _rectangleView.hidden = true; - [UIView animateWithDuration:0.3f animations:^ - { - //[_context setApplicationStatusBarAlpha:1.0f]; - }]; - [self setInterfaceHidden:true animated:true]; [UIView animateWithDuration:0.25f animations:^ { _backgroundView.alpha = 0.0f; + _cornersView.alpha = 0.0; }]; CGRect referenceFrame = CGRectZero; @@ -2272,6 +2299,13 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus [strongSelf dismiss]; }; [_previewView pop_addAnimation:frameAnimation forKey:@"frame"]; + + POPSpringAnimation *cornersAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPViewFrame]; + cornersAnimation.fromValue = [NSValue valueWithCGRect:_cornersView.frame]; + cornersAnimation.toValue = [NSValue valueWithCGRect:referenceFrame]; + cornersAnimation.springSpeed = 20; + cornersAnimation.springBounciness = 1; + [_cornersView pop_addAnimation:cornersAnimation forKey:@"frame"]; } else { @@ -2328,6 +2362,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus [UIView animateWithDuration:ABS(distance / velocity) animations:^ { _previewView.frame = targetFrame; + _cornersView.frame = targetFrame; } completion:^(__unused BOOL finished) { if (completion) @@ -2344,11 +2379,13 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus [UIView animateWithDuration:0.3 animations:^ { _previewView.frame = frame; + _cornersView.frame = frame; }]; } else { _previewView.frame = frame; + _cornersView.frame = frame; } } @@ -2390,6 +2427,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus [UIView animateWithDuration:0.3f delay:0.0f options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionLayoutSubviews animations:^ { _previewView.frame = frame; + _cornersView.frame = frame; _overlayView.frame = frame; } completion:nil]; } diff --git a/submodules/LegacyComponents/Sources/TGCameraFlashControl.m b/submodules/LegacyComponents/Sources/TGCameraFlashControl.m index 743e5db3be..4f7e1f2c96 100644 --- a/submodules/LegacyComponents/Sources/TGCameraFlashControl.m +++ b/submodules/LegacyComponents/Sources/TGCameraFlashControl.m @@ -2,21 +2,118 @@ #import "LegacyComponentsInternal.h" +#import "TGImageUtils.h" + #import "UIControl+HitTestEdgeInsets.h" #import "TGCameraInterfaceAssets.h" #import +#import "POPBasicAnimation.h" + const CGFloat TGCameraFlashControlHeight = 44.0f; +@interface TGCameraFlashIcon: UIView +{ + bool _active; + CGFloat _progress; + bool _on; +} +@end + +@implementation TGCameraFlashIcon + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self != nil) { + self.contentMode = UIViewContentModeRedraw; + } + return self; +} + +- (void)setOn:(bool)on animated:(bool)animated { + _on = on; + if (animated) { + POPBasicAnimation *animation = [POPBasicAnimation animation]; + animation.property = [POPAnimatableProperty propertyWithName:@"progress" initializer:^(POPMutableAnimatableProperty *prop) + { + prop.readBlock = ^(TGCameraFlashIcon *view, CGFloat values[]) + { + if (view != nil) { + values[0] = view->_progress; + } + }; + + prop.writeBlock = ^(TGCameraFlashIcon *view, const CGFloat values[]) + { + view->_progress = values[0]; + [view setNeedsDisplay]; + }; + + prop.threshold = 0.03f; + }]; + animation.fromValue = @(_progress); + animation.toValue = @(on ? 1.0 : 0.0); + animation.duration = 0.2; + animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; + [self pop_addAnimation:animation forKey:@"progress"]; + } else { + _progress = on ? 1.0 : 0.0; + [self setNeedsDisplay]; + } +} + +- (void)setActive:(bool)active { + _active = active; + [self setNeedsDisplay]; +} + +- (void)drawRect:(CGRect)__unused rect +{ + CGContextRef context = UIGraphicsGetCurrentContext(); + CGRect bounds = CGRectMake(0, 0, rect.size.width, rect.size.height); + + CGContextClearRect(context, bounds); + + UIImage *iconImage = [UIImage imageNamed:@"Camera/Flash"]; + + if (_active && _on) { + CGContextSetFillColorWithColor(context, [TGCameraInterfaceAssets accentColor].CGColor); + CGContextFillEllipseInRect(context, CGRectInset(bounds, 2.5, 2.5)); + + [TGTintedImage(iconImage, [UIColor blackColor]) drawInRect:CGRectMake(0, 0, 30, 30)]; + } else { + CGContextSetLineWidth(context, 1.0); + CGContextSetStrokeColorWithColor(context, [UIColor colorWithWhite:1.0 alpha:0.5].CGColor); + CGContextStrokeEllipseInRect(context, CGRectInset(bounds, 3.0, 3.0)); + + [TGTintedImage(iconImage, [UIColor whiteColor]) drawInRect:CGRectMake(0, 0, 30, 30)]; + } + + CGFloat lineProgress = 1.0 - _progress; + + if (lineProgress > 0.0) { + CGMutablePathRef path = CGPathCreateMutable(); + CGPathMoveToPoint(path, NULL, 5, 5); + CGPathAddLineToPoint(path, NULL, 5 + (bounds.size.width - 10.0) * lineProgress, 5 + (bounds.size.height - 10.0) * lineProgress); + + CGPathRef strokedPath = CGPathCreateCopyByStrokingPath(path, NULL, 2.0f, kCGLineCapRound, kCGLineJoinMiter, 10); + CGContextAddPath(context, strokedPath); + CGPathRelease(strokedPath); + CGPathRelease(path); + + CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor); + CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor); + CGContextDrawPath(context, kCGPathFillStroke); + } +} + +@end + @interface TGCameraFlashControl () { - UIButton *_flashIconView; - UIButton *_autoButton; - UIButton *_onButton; - UIButton *_offButton; - - bool _active; + TGCameraFlashIcon *_icon; + UIButton *_button; } @end @@ -27,23 +124,22 @@ const CGFloat TGCameraFlashControlHeight = 44.0f; self = [super initWithFrame:frame]; if (self != nil) { + self.mode = PGCameraFlashModeOff; + self.hitTestEdgeInsets = UIEdgeInsetsMake(-10, -10, -10, -10); - _flashIconView = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 44, 44)]; - _flashIconView.adjustsImageWhenHighlighted = false; - _flashIconView.contentMode = UIViewContentModeCenter; - _flashIconView.exclusiveTouch = true; - _flashIconView.hitTestEdgeInsets = UIEdgeInsetsMake(0, -10, 0, -10); - _flashIconView.tag = -1; - [_flashIconView setImage:[UIImage imageNamed:@"Camera/FlashOff"] forState:UIControlStateNormal]; - [_flashIconView addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside]; - [self addSubview:_flashIconView]; - - [UIView performWithoutAnimation:^ - { - self.mode = PGCameraFlashModeOff; - [self setActive:false animated:false]; - }]; + _icon = [[TGCameraFlashIcon alloc] initWithFrame:CGRectMake(7, 7, 30, 30)]; + _icon.userInteractionEnabled = false; + [self addSubview:_icon]; + + _button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 44, 44)]; + _button.adjustsImageWhenHighlighted = false; + _button.contentMode = UIViewContentModeCenter; + _button.exclusiveTouch = true; + _button.hitTestEdgeInsets = UIEdgeInsetsMake(0, -10, 0, -10); + _button.tag = -1; + [_button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside]; + [self addSubview:_button]; } return self; } @@ -61,11 +157,11 @@ const CGFloat TGCameraFlashControlHeight = 44.0f; - (void)buttonPressed:(UIButton *)sender { if (_mode == PGCameraFlashModeOff) { - self.mode = PGCameraFlashModeOn; - [_flashIconView setImage:[UIImage imageNamed:@"Camera/FlashOn"] forState:UIControlStateNormal]; + self.mode = PGCameraFlashModeAuto; + [_icon setOn:true animated:true]; } else { self.mode = PGCameraFlashModeOff; - [_flashIconView setImage:[UIImage imageNamed:@"Camera/FlashOff"] forState:UIControlStateNormal]; + [_icon setOn:false animated:true]; } if (self.modeChanged != nil) @@ -75,35 +171,24 @@ const CGFloat TGCameraFlashControlHeight = 44.0f; - (void)setFlashUnavailable:(bool)unavailable { self.userInteractionEnabled = !unavailable; - [self setActive:false animated:false]; + self.alpha = unavailable ? 0.4 : 1.0; } -- (void)setActive:(bool)active animated:(bool)animated +- (void)setFlashActive:(bool)active { - return; + [_icon setActive:active]; } - (void)setMode:(PGCameraFlashMode)mode { _mode = mode; - - [self setActive:false animated:_active]; -} - -- (void)dismissAnimated:(bool)animated -{ - if (animated && _active) - [self setActive:false animated:animated]; - else - [self setActive:false animated:false]; + [_icon setOn:mode == PGCameraFlashModeAuto animated:true]; } - (void)setHidden:(BOOL)hidden { self.alpha = hidden ? 0.0f : 1.0f; super.hidden = hidden; - - [self setActive:false animated:false]; } - (void)setHidden:(bool)hidden animated:(bool)animated @@ -123,16 +208,12 @@ const CGFloat TGCameraFlashControlHeight = 44.0f; if (finished) self.hidden = hidden; - - [self setActive:false animated:false]; }]; } else { self.alpha = hidden ? 0.0f : 1.0f; super.hidden = hidden; - - [self setActive:false animated:false]; } } diff --git a/submodules/LegacyComponents/Sources/TGCameraFlipButton.m b/submodules/LegacyComponents/Sources/TGCameraFlipButton.m index b4e05637cb..e1aecdc279 100644 --- a/submodules/LegacyComponents/Sources/TGCameraFlipButton.m +++ b/submodules/LegacyComponents/Sources/TGCameraFlipButton.m @@ -11,6 +11,8 @@ self = [super initWithFrame:frame]; if (self != nil) { + self.adjustsImageWhenHighlighted = false; + self.modernHighlight = false; self.exclusiveTouch = true; self.backgroundColor = [TGCameraInterfaceAssets buttonColor]; self.layer.cornerRadius = 24.0; @@ -19,6 +21,16 @@ return self; } +- (void)_setHighligtedAnimated:(bool)highlighted animated:(bool)animated { + if (animated) { + [UIView animateWithDuration:0.3 animations:^{ + self.layer.sublayerTransform = highlighted ? CATransform3DMakeScale(0.9, 0.9, 1.0) : CATransform3DIdentity; + }]; + } else { + self.layer.sublayerTransform = highlighted ? CATransform3DMakeScale(0.9, 0.9, 1.0) : CATransform3DIdentity; + } +} + - (void)setHidden:(BOOL)hidden { self.alpha = hidden ? 0.0f : 1.0f; @@ -60,6 +72,8 @@ self = [super initWithFrame:frame]; if (self != nil) { + self.adjustsImageWhenHighlighted = false; + self.modernHighlight = false; self.exclusiveTouch = true; self.backgroundColor = [TGCameraInterfaceAssets buttonColor]; self.layer.cornerRadius = 24.0; @@ -68,6 +82,16 @@ return self; } +- (void)_setHighligtedAnimated:(bool)highlighted animated:(bool)animated { + if (animated) { + [UIView animateWithDuration:0.3 animations:^{ + self.layer.sublayerTransform = highlighted ? CATransform3DMakeScale(0.9, 0.9, 1.0) : CATransform3DIdentity; + }]; + } else { + self.layer.sublayerTransform = highlighted ? CATransform3DMakeScale(0.9, 0.9, 1.0) : CATransform3DIdentity; + } +} + - (void)setHidden:(BOOL)hidden { self.alpha = hidden ? 0.0f : 1.0f; diff --git a/submodules/LegacyComponents/Sources/TGCameraMainPhoneView.m b/submodules/LegacyComponents/Sources/TGCameraMainPhoneView.m index df82cfcfd5..6ad2ddc825 100644 --- a/submodules/LegacyComponents/Sources/TGCameraMainPhoneView.m +++ b/submodules/LegacyComponents/Sources/TGCameraMainPhoneView.m @@ -82,6 +82,8 @@ bool _displayedTooltip; TGMenuContainerView *_tooltipContainerView; NSTimer *_tooltipTimer; + + bool _dismissingWheel; } @end @@ -261,21 +263,31 @@ _toastView.userInteractionEnabled = false; [self addSubview:_toastView]; - _zoomModeView = [[TGCameraZoomModeView alloc] initWithFrame:CGRectMake(floor((frame.size.width - 129.0) / 2.0), frame.size.height - _bottomPanelHeight - _bottomPanelOffset - 18 - 43, 129, 43) hasUltrawideCamera:hasUltrawideCamera hasTelephotoCamera:hasTelephotoCamera]; + _zoomModeView = [[TGCameraZoomModeView alloc] initWithFrame:CGRectMake(floor((frame.size.width - 129.0) / 2.0), frame.size.height - _bottomPanelHeight - _bottomPanelOffset - 18 - 43, 129, 43) hasUltrawideCamera:hasUltrawideCamera hasTelephotoCamera:hasTelephotoCamera minZoomLevel:hasUltrawideCamera ? 0.5 : 1.0 maxZoomLevel:8.0]; _zoomModeView.zoomChanged = ^(CGFloat zoomLevel, bool done, bool animated) { __strong TGCameraMainPhoneView *strongSelf = weakSelf; if (strongSelf == nil) return; - if (!done) { - [strongSelf->_zoomWheelView setZoomLevel:zoomLevel]; - [strongSelf->_zoomModeView setHidden:true animated:true]; - [strongSelf->_zoomWheelView setHidden:false animated:true]; - } else { + if (done) { [strongSelf->_zoomWheelView setZoomLevel:zoomLevel]; [strongSelf->_zoomModeView setZoomLevel:zoomLevel animated:false]; - [strongSelf->_zoomModeView setHidden:false animated:true]; - [strongSelf->_zoomWheelView setHidden:true animated:true]; + + if (!strongSelf->_zoomWheelView.isHidden) { + strongSelf->_dismissingWheel = true; + + TGDispatchAfter(0.6, dispatch_get_main_queue(), ^{ + if (strongSelf->_dismissingWheel) { + [strongSelf->_zoomModeView setHidden:false animated:true]; +// [strongSelf->_zoomWheelView setHidden:true animated:true]; + } + }); + } + } else { + strongSelf->_dismissingWheel = false; + [strongSelf->_zoomWheelView setZoomLevel:zoomLevel]; + [strongSelf->_zoomModeView setHidden:true animated:true]; +// [strongSelf->_zoomWheelView setHidden:false animated:true]; } if (strongSelf.zoomChanged != nil) @@ -284,7 +296,7 @@ [_zoomModeView setZoomLevel:1.0]; [self addSubview:_zoomModeView]; - _zoomWheelView = [[TGCameraZoomWheelView alloc] initWithFrame:CGRectMake(0.0, frame.size.height - _bottomPanelHeight - _bottomPanelOffset - 132, frame.size.width, 132)]; + _zoomWheelView = [[TGCameraZoomWheelView alloc] initWithFrame:CGRectMake(0.0, frame.size.height - _bottomPanelHeight - _bottomPanelOffset - 132, frame.size.width, 132) hasUltrawideCamera:hasUltrawideCamera hasTelephotoCamera:hasTelephotoCamera]; [_zoomWheelView setHidden:true animated:false]; [_zoomWheelView setZoomLevel:1.0]; _zoomWheelView.userInteractionEnabled = false; @@ -440,13 +452,6 @@ #pragma mark - Actions -- (void)shutterButtonReleased -{ - [super shutterButtonReleased]; - - [_flashControl dismissAnimated:true]; -} - - (void)updateForCameraModeChangeWithPreviousMode:(PGCameraMode)previousMode { [super updateForCameraModeChangeWithPreviousMode:previousMode]; @@ -490,7 +495,6 @@ [self _attachControlsToTopPanel]; [self _layoutTopPanelSubviewsForInterfaceOrientation:orientation]; - [_flashControl dismissAnimated:false]; [UIView animateWithDuration:0.2f delay:0.0f options:UIViewAnimationOptionCurveEaseInOut animations:^ { @@ -512,7 +516,7 @@ - (void)setFlashActive:(bool)active { - [_flashActiveView setActive:active animated:true]; + [_flashControl setFlashActive:active]; } - (void)setFlashUnavailable:(bool)unavailable @@ -522,9 +526,6 @@ - (void)setHasFlash:(bool)hasFlash { - if (!hasFlash) - [_flashActiveView setActive:false animated:true]; - [_flashControl setHidden:!hasFlash animated:true]; } @@ -676,8 +677,6 @@ } else { - [_flashControl dismissAnimated:false]; - _flipButton.transform = CGAffineTransformMakeRotation(TGRotationForInterfaceOrientation(orientation)); _flashControl.transform = CGAffineTransformMakeRotation(TGRotationForInterfaceOrientation(orientation)); _zoomModeView.interfaceOrientation = orientation; diff --git a/submodules/LegacyComponents/Sources/TGCameraMainView.m b/submodules/LegacyComponents/Sources/TGCameraMainView.m index a35684f061..39b7ac246f 100644 --- a/submodules/LegacyComponents/Sources/TGCameraMainView.m +++ b/submodules/LegacyComponents/Sources/TGCameraMainView.m @@ -14,6 +14,51 @@ #import "TGMediaPickerPhotoCounterButton.h" #import "TGMediaPickerPhotoStripView.h" +@implementation TGCameraCornersView + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self != nil) { + self.contentMode = UIViewContentModeScaleToFill; + + static UIImage *cornersImage = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^ + { + CGSize size = CGSizeMake(50.0, 50.0); + UIGraphicsBeginImageContextWithOptions(CGSizeMake(50.0, 50.0), false, 0.0f); + CGContextRef context = UIGraphicsGetCurrentContext(); + + CGContextSetAlpha(context, 0.5); + CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor); + CGContextSetBlendMode(context, kCGBlendModeCopy); + + CGFloat width = 1.0; + CGFloat length = 24.0; + CGContextFillRect(context, CGRectMake(0, 0, length, width)); + CGContextFillRect(context, CGRectMake(0, 0, width, length)); + + CGContextFillRect(context, CGRectMake(size.width - length, 0, length, width)); + CGContextFillRect(context, CGRectMake(size.width - width, 0, width, length)); + + CGContextFillRect(context, CGRectMake(0, size.height - width, length, width)); + CGContextFillRect(context, CGRectMake(0, size.height - length, width, length)); + + CGContextFillRect(context, CGRectMake(size.width - length, size.height - width, length, width)); + CGContextFillRect(context, CGRectMake(size.width - width, size.height - length, width, length)); + + cornersImage = [UIGraphicsGetImageFromCurrentImageContext() stretchableImageWithLeftCapWidth:25 topCapHeight:25]; + UIGraphicsEndImageContext(); + }); + + self.image = cornersImage; + self.userInteractionEnabled = false; + } + return self; +} + +@end + @interface TGCameraMainView () { diff --git a/submodules/LegacyComponents/Sources/TGCameraTimeCodeView.m b/submodules/LegacyComponents/Sources/TGCameraTimeCodeView.m index 1fbea1fea1..0f6878d13c 100644 --- a/submodules/LegacyComponents/Sources/TGCameraTimeCodeView.m +++ b/submodules/LegacyComponents/Sources/TGCameraTimeCodeView.m @@ -66,12 +66,20 @@ [self reset]; _recordingTimer = [TGTimerTarget scheduledMainThreadTimerWithTarget:self action:@selector(recordingTimerEvent) interval:1.0 repeat:false]; + + [UIView animateWithDuration:0.2 animations:^{ + _backgroundView.alpha = 1.0; + }]; } - (void)stopRecording { [_recordingTimer invalidate]; _recordingTimer = nil; + + [UIView animateWithDuration:0.2 animations:^{ + _backgroundView.alpha = 0.0; + }]; } - (void)reset diff --git a/submodules/LegacyComponents/Sources/TGCameraZoomView.m b/submodules/LegacyComponents/Sources/TGCameraZoomView.m index 65403755cc..1c0e22d43b 100644 --- a/submodules/LegacyComponents/Sources/TGCameraZoomView.m +++ b/submodules/LegacyComponents/Sources/TGCameraZoomView.m @@ -227,6 +227,9 @@ @interface TGCameraZoomModeView () { + CGFloat _minZoomLevel; + CGFloat _maxZoomLevel; + UIView *_backgroundView; bool _hasUltrawideCamera; @@ -240,13 +243,15 @@ @implementation TGCameraZoomModeView -- (instancetype)initWithFrame:(CGRect)frame hasUltrawideCamera:(bool)hasUltrawideCamera hasTelephotoCamera:(bool)hasTelephotoCamera +- (instancetype)initWithFrame:(CGRect)frame hasUltrawideCamera:(bool)hasUltrawideCamera hasTelephotoCamera:(bool)hasTelephotoCamera minZoomLevel:(CGFloat)minZoomLevel maxZoomLevel:(CGFloat)maxZoomLevel { self = [super initWithFrame:frame]; if (self != nil) { _hasUltrawideCamera = hasUltrawideCamera; _hasTelephotoCamera = hasTelephotoCamera; + _minZoomLevel = minZoomLevel; + _maxZoomLevel = maxZoomLevel; _backgroundView = [[UIView alloc] initWithFrame:self.bounds]; _backgroundView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.15]; @@ -270,34 +275,39 @@ [self addSubview:_rightItem]; } - UIPanGestureRecognizer *gestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)]; -// [self addGestureRecognizer:gestureRecognizer]; + UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)]; + [self addGestureRecognizer:panGestureRecognizer]; + + UILongPressGestureRecognizer *pressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(pressGesture:)]; + [self addGestureRecognizer:pressGestureRecognizer]; } return self; } +- (void)pressGesture:(UILongPressGestureRecognizer *)gestureRecognizer { + switch (gestureRecognizer.state) { + case UIGestureRecognizerStateBegan: + self.zoomChanged(_zoomLevel, false, false); + break; + case UIGestureRecognizerStateEnded: + self.zoomChanged(_zoomLevel, true, false); + break; + case UIGestureRecognizerStateCancelled: + self.zoomChanged(_zoomLevel, true, false); + break; + default: + break; + } +} - (void)panGesture:(UIPanGestureRecognizer *)gestureRecognizer { CGPoint translation = [gestureRecognizer translationInView:self]; switch (gestureRecognizer.state) { - case UIGestureRecognizerStateBegan: - self.zoomChanged(_zoomLevel, false, false); - break; - case UIGestureRecognizerStateChanged: _zoomLevel = MAX(0.5, MIN(10.0, _zoomLevel - translation.x / 100.0)); self.zoomChanged(_zoomLevel, false, false); break; - - case UIGestureRecognizerStateEnded: - self.zoomChanged(_zoomLevel, true, false); - break; - - case UIGestureRecognizerStateCancelled: - self.zoomChanged(_zoomLevel, true, false); - break; - default: break; } @@ -425,21 +435,85 @@ @interface TGCameraZoomWheelView () { + bool _hasUltrawideCamera; + bool _hasTelephotoCamera; UIImageView *_backgroundView; } @end @implementation TGCameraZoomWheelView -- (instancetype)initWithFrame:(CGRect)frame +- (void)_drawLineInContext:(CGContextRef)context side:(CGFloat)side atAngle:(CGFloat)angle lineLength:(CGFloat)lineLength lineWidth:(CGFloat)lineWidth opaque:(bool)opaque { + CGContextSaveGState(context); + + CGContextTranslateCTM(context, side / 2.0, side / 2.0); + CGContextRotateCTM(context, angle); + CGContextTranslateCTM(context, -side / 2.0, -side / 2.0); + + CGContextSetLineWidth(context, lineWidth); + CGContextSetStrokeColorWithColor(context, [UIColor colorWithWhite:1.0 alpha:opaque ? 1.0 : 0.5].CGColor); + CGContextMoveToPoint(context, side / 2.0, 4.0); + CGContextAddLineToPoint(context, side / 2.0, 4.0 + lineLength); + CGContextStrokePath(context); + + CGContextRestoreGState(context); +} + +- (instancetype)initWithFrame:(CGRect)frame hasUltrawideCamera:(bool)hasUltrawideCamera hasTelephotoCamera:(bool)hasTelephotoCamera { self = [super initWithFrame:frame]; if (self != nil) { - self.clipsToBounds = true; + _hasUltrawideCamera = true;// hasUltrawideCamera; + _hasTelephotoCamera = true;//hasTelephotoCamera; - _backgroundView = [[UIImageView alloc] initWithFrame:CGRectMake(-28.0, 0.0, 446.0, 446.0)]; - _backgroundView.alpha = 0.75; + self.clipsToBounds = true; + + CGFloat side = floor(frame.size.width * 1.1435); + CGFloat length = 17.0; + CGFloat smallWidth = MAX(0.5, 1.0 - TGScreenPixel); + CGFloat mediumWidth = 1.0; + CGFloat bigWidth = 1.0 + TGScreenPixel; + + CGFloat smallAngle = M_PI * 0.12; + CGFloat finalAngle = 1.08; + + UIGraphicsBeginImageContextWithOptions(CGSizeMake(side, side), false, 0.0f); + CGContextRef context = UIGraphicsGetCurrentContext(); + + CGContextSetFillColorWithColor(context, [UIColor colorWithWhite:0.0 alpha:0.75].CGColor); + CGContextFillEllipseInRect(context, CGRectMake(0, 0, side, side)); + + [self _drawLineInContext:context side:side atAngle:0.0 lineLength:length lineWidth:bigWidth opaque:true]; + + if (_hasUltrawideCamera) { + for (NSInteger i = 0; i < 4; i++) { + CGFloat angle = (smallAngle / 5.0) * (i + 1) + (0.007 * (i - 1)); + [self _drawLineInContext:context side:side atAngle:-angle lineLength:length lineWidth:smallWidth opaque:false]; + } + [self _drawLineInContext:context side:side atAngle:-smallAngle lineLength:length lineWidth:bigWidth opaque:true]; + } + if (_hasTelephotoCamera) { + [self _drawLineInContext:context side:side atAngle:smallAngle lineLength:length lineWidth:bigWidth opaque:true]; + + for (NSInteger i = 0; i < 4; i++) { + CGFloat angle = (smallAngle / 5.0) * (i + 1) + (0.01 * (i - 1)); + [self _drawLineInContext:context side:side atAngle:angle lineLength:length lineWidth:smallWidth opaque:false]; + } + + [self _drawLineInContext:context side:side atAngle:finalAngle lineLength:length lineWidth:bigWidth opaque:true]; + } else { + [self _drawLineInContext:context side:side atAngle:smallAngle lineLength:length lineWidth:mediumWidth opaque:true]; + + [self _drawLineInContext:context side:side atAngle:finalAngle lineLength:length lineWidth:bigWidth opaque:true]; + } + + + UIImage *image = [UIGraphicsGetImageFromCurrentImageContext() stretchableImageWithLeftCapWidth:25 topCapHeight:25]; + UIGraphicsEndImageContext(); + + _backgroundView = [[UIImageView alloc] initWithFrame:CGRectMake(TGScreenPixelFloor((frame.size.width - side) / 2.0), 0.0, side, side)]; + _backgroundView.image = image; [self addSubview:_backgroundView]; } diff --git a/submodules/LegacyComponents/Sources/TGPhotoPaintColorPicker.m b/submodules/LegacyComponents/Sources/TGPhotoPaintColorPicker.m index 1bceed2d44..71812d67a3 100644 --- a/submodules/LegacyComponents/Sources/TGPhotoPaintColorPicker.m +++ b/submodules/LegacyComponents/Sources/TGPhotoPaintColorPicker.m @@ -11,8 +11,8 @@ const CGFloat TGPhotoPaintColorWeightGestureRange = 320.0f; const CGFloat TGPhotoPaintVerticalThreshold = 5.0f; const CGFloat TGPhotoPaintPreviewOffset = -70.0f; const CGFloat TGPhotoPaintPreviewScale = 2.0f; -const CGFloat TGPhotoPaintDefaultBrushWeight = 0.22f; -const CGFloat TGPhotoPaintDefaultColorLocation = 1.0f; +const CGFloat TGPhotoPaintDefaultBrushWeight = 0.08f; +const CGFloat TGPhotoPaintDefaultColorLocation = 0.0f; @interface TGPhotoPaintColorPickerKnobCircleView : UIView { @@ -97,7 +97,7 @@ const CGFloat TGPhotoPaintDefaultColorLocation = 1.0f; [self addGestureRecognizer:_tapGestureRecognizer]; _location = [self restoreLastColorLocation]; - _weight = 0.08f; + _weight = TGPhotoPaintDefaultBrushWeight; } return self; } @@ -107,7 +107,7 @@ const CGFloat TGPhotoPaintDefaultColorLocation = 1.0f; NSNumber *lastColor = [[NSUserDefaults standardUserDefaults] objectForKey:@"TG_paintLastColorLocation_v0"]; if (lastColor != nil) return [lastColor floatValue]; - + return TGPhotoPaintDefaultColorLocation; } diff --git a/submodules/TelegramCore/Sources/State/SynchronizePeerReadState.swift b/submodules/TelegramCore/Sources/State/SynchronizePeerReadState.swift index 9f213ac37e..1cfa73aaa3 100644 --- a/submodules/TelegramCore/Sources/State/SynchronizePeerReadState.swift +++ b/submodules/TelegramCore/Sources/State/SynchronizePeerReadState.swift @@ -213,8 +213,10 @@ private func pushPeerReadState(network: Network, postbox: Postbox, stateManager: return .single(readState) case let .indexBased(maxIncomingReadIndex, _, _, _): return network.request(Api.functions.messages.readEncryptedHistory(peer: inputPeer, maxDate: maxIncomingReadIndex.timestamp)) - |> retryRequest - |> mapToSignalPromotingError { _ -> Signal in + |> mapError { _ in + return PeerReadStateValidationError.retry + } + |> mapToSignal { _ -> Signal in return .single(readState) } } diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index b1189bdf07..c3dad67922 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -2218,6 +2218,13 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { } private func handlePanSelection(location: CGPoint) { + var location = location + if location.y < self.insets.top { + location.y = self.insets.top + 5.0 + } else if location.y > self.frame.height - self.insets.bottom { + location.y = self.frame.height - self.insets.bottom - 5.0 + } + if let state = self.selectionPanState { if let messages = self.messagesAtPoint(location), let message = messages.first { if message.id == state.initialMessageId { diff --git a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift index e28ddf8f18..6cd464e424 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInstantVideoItemNode.swift @@ -70,6 +70,8 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD } } + private var wasPlaying = false + required init() { self.contextSourceNode = ContextExtractedContentContainingNode() self.containerNode = ContextControllerSourceNode() @@ -97,7 +99,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD return false } if strongSelf.appliedCurrentlyPlaying && !strongSelf.interactiveVideoNode.isPlaying { - return false + return strongSelf.interactiveVideoNode.frame.insetBy(dx: 0.15 * strongSelf.interactiveVideoNode.frame.width, dy: 0.15 * strongSelf.interactiveVideoNode.frame.height).contains(location) } if let action = strongSelf.gestureRecognized(gesture: .tap, location: location, recognizer: nil) { if case .action = action { @@ -126,10 +128,24 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD case let .openContextMenu(tapMessage, selectAll, subFrame): strongSelf.recognizer?.cancel() item.controllerInteraction.openMessageContextMenu(tapMessage, selectAll, strongSelf, subFrame, gesture) + if strongSelf.appliedCurrentlyPlaying && strongSelf.interactiveVideoNode.isPlaying { + strongSelf.wasPlaying = true + strongSelf.interactiveVideoNode.pause() + } } } } + self.contextSourceNode.willUpdateIsExtractedToContextPreview = { [weak self] extracted, _ in + guard let strongSelf = self, let _ = strongSelf.item else { + return + } + if !extracted && strongSelf.wasPlaying { + strongSelf.wasPlaying = false + strongSelf.interactiveVideoNode.play() + } + } + self.containerNode.addSubnode(self.contextSourceNode) self.containerNode.targetNodeForActivationProgress = self.contextSourceNode.contentNode self.addSubnode(self.containerNode) diff --git a/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift b/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift index 9f16e113e0..0ff7f5f6b9 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInteractiveInstantVideoNode.swift @@ -777,9 +777,9 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode { if !self.bounds.contains(point) { return nil } - if let playbackNode = self.playbackStatusNode, !self.isPlaying, !playbackNode.frame.insetBy(dx: 0.15 * playbackNode.frame.width, dy: 0.15 * playbackNode.frame.height).contains(point) { + if let playbackNode = self.playbackStatusNode, !self.isPlaying, !playbackNode.frame.insetBy(dx: 0.2 * playbackNode.frame.width, dy: 0.2 * playbackNode.frame.height).contains(point) { let distanceFromCenter = point.distanceTo(playbackNode.position) - if distanceFromCenter < 0.15 * playbackNode.frame.width { + if distanceFromCenter < 0.2 * playbackNode.frame.width { return self.view } else { return playbackNode.view diff --git a/submodules/TelegramUI/Sources/InstantVideoRadialStatusNode.swift b/submodules/TelegramUI/Sources/InstantVideoRadialStatusNode.swift index 4e1b625b2f..404531adbf 100644 --- a/submodules/TelegramUI/Sources/InstantVideoRadialStatusNode.swift +++ b/submodules/TelegramUI/Sources/InstantVideoRadialStatusNode.swift @@ -11,12 +11,14 @@ private final class InstantVideoRadialStatusNodeParameters: NSObject { let progress: CGFloat let dimProgress: CGFloat let playProgress: CGFloat + let hasSeek: Bool - init(color: UIColor, progress: CGFloat, dimProgress: CGFloat, playProgress: CGFloat) { + init(color: UIColor, progress: CGFloat, dimProgress: CGFloat, playProgress: CGFloat, hasSeek: Bool) { self.color = color self.progress = progress self.dimProgress = dimProgress self.playProgress = playProgress + self.hasSeek = hasSeek } } @@ -141,7 +143,7 @@ final class InstantVideoRadialStatusNode: ASDisplayNode, UIGestureRecognizerDele let center = CGPoint(x: self.bounds.width / 2.0, y: self.bounds.height / 2.0) let location = gestureRecognizer.location(in: self.view) let distanceFromCenter = location.distanceTo(center) - if distanceFromCenter < self.bounds.width * 0.15 { + if distanceFromCenter < self.bounds.width * 0.2 { return false } return true @@ -210,7 +212,7 @@ final class InstantVideoRadialStatusNode: ASDisplayNode, UIGestureRecognizerDele } override func drawParameters(forAsyncLayer layer: _ASDisplayLayer) -> NSObjectProtocol? { - return InstantVideoRadialStatusNodeParameters(color: self.color, progress: self.effectiveProgress, dimProgress: self.effectiveDimProgress, playProgress: self.effectivePlayProgress) + return InstantVideoRadialStatusNodeParameters(color: self.color, progress: self.effectiveProgress, dimProgress: self.effectiveDimProgress, playProgress: self.effectivePlayProgress, hasSeek: self.hasSeek) } @objc override class func draw(_ bounds: CGRect, withParameters parameters: Any?, isCancelled: () -> Bool, isRasterizing: Bool) { @@ -239,20 +241,30 @@ final class InstantVideoRadialStatusNode: ASDisplayNode, UIGestureRecognizerDele progress = min(1.0, progress) var lineWidth: CGFloat = 4.0 - lineWidth += 1.0 * parameters.dimProgress + if parameters.hasSeek { + lineWidth += 1.0 * parameters.dimProgress + } var pathDiameter = bounds.size.width - lineWidth - 8.0 - pathDiameter -= (18.0 * 2.0) * parameters.dimProgress - - if !parameters.dimProgress.isZero { - context.setStrokeColor(parameters.color.withAlphaComponent(0.2 * parameters.dimProgress).cgColor) - context.setLineWidth(lineWidth) - context.strokeEllipse(in: CGRect(x: (bounds.size.width - pathDiameter) / 2.0 , y: (bounds.size.height - pathDiameter) / 2.0, width: pathDiameter, height: pathDiameter)) + if parameters.hasSeek { + pathDiameter -= (18.0 * 2.0) * parameters.dimProgress + } + if !parameters.dimProgress.isZero { + if parameters.hasSeek { + context.setStrokeColor(parameters.color.withAlphaComponent(0.2 * parameters.dimProgress).cgColor) + context.setLineWidth(lineWidth) + context.strokeEllipse(in: CGRect(x: (bounds.size.width - pathDiameter) / 2.0 , y: (bounds.size.height - pathDiameter) / 2.0, width: pathDiameter, height: pathDiameter)) + } + if !parameters.playProgress.isZero { context.saveGState() context.translateBy(x: bounds.width / 2.0, y: bounds.height / 2.0) - context.scaleBy(x: 1.0 + 1.4 * parameters.playProgress, y: 1.0 + 1.4 * parameters.playProgress) + if parameters.hasSeek { + context.scaleBy(x: 1.0 + 1.4 * parameters.playProgress, y: 1.0 + 1.4 * parameters.playProgress) + } else { + context.scaleBy(x: 1.0 + 0.7 * parameters.playProgress, y: 1.0 + 0.7 * parameters.playProgress) + } context.translateBy(x: -bounds.width / 2.0, y: -bounds.height / 2.0) let iconSize = CGSize(width: 15.0, height: 18.0) @@ -272,12 +284,14 @@ final class InstantVideoRadialStatusNode: ASDisplayNode, UIGestureRecognizerDele path.lineCapStyle = .round path.stroke() - let handleSide = 16.0 * min(1.0, (parameters.dimProgress * 2.0)) - let handleSize = CGSize(width: handleSide, height: handleSide) - let handlePosition = CGPoint(x: 0.5 * pathDiameter * cos(endAngle), y: 0.5 * pathDiameter * sin(endAngle)).offsetBy(dx: bounds.size.width / 2.0, dy: bounds.size.height / 2.0) - let handleFrame = CGRect(origin: CGPoint(x: floorToScreenPixels(handlePosition.x - handleSize.width / 2.0), y: floorToScreenPixels(handlePosition.y - handleSize.height / 2.0)), size: handleSize) - context.setFillColor(UIColor.white.cgColor) - context.fillEllipse(in: handleFrame) + if parameters.hasSeek { + let handleSide = 16.0 * min(1.0, (parameters.dimProgress * 2.0)) + let handleSize = CGSize(width: handleSide, height: handleSide) + let handlePosition = CGPoint(x: 0.5 * pathDiameter * cos(endAngle), y: 0.5 * pathDiameter * sin(endAngle)).offsetBy(dx: bounds.size.width / 2.0, dy: bounds.size.height / 2.0) + let handleFrame = CGRect(origin: CGPoint(x: floorToScreenPixels(handlePosition.x - handleSize.width / 2.0), y: floorToScreenPixels(handlePosition.y - handleSize.height / 2.0)), size: handleSize) + context.setFillColor(UIColor.white.cgColor) + context.fillEllipse(in: handleFrame) + } } } @@ -296,11 +310,7 @@ final class InstantVideoRadialStatusNode: ASDisplayNode, UIGestureRecognizerDele if self.seeking { dimmed = true } - - if !self.hasSeek { - dimmed = false - } - + if dimmed != self.dimmed { self.dimmed = dimmed