mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge commit 'e5186bd7ae1b9f8bc8b1a0130b725a26ee5755f2'
This commit is contained in:
commit
4e6579d5b6
@ -1126,6 +1126,26 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
|
|
||||||
self.chatListDisplayNode.containerNode.updateEnableAdjacentFilterLoading(true)
|
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 {
|
guard case .root = self.groupId else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1266,26 +1286,6 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
if !self.processedFeaturedFilters {
|
||||||
let initializedFeatured = self.context.account.postbox.preferencesView(keys: [
|
let initializedFeatured = self.context.account.postbox.preferencesView(keys: [
|
||||||
PreferencesKeys.chatListFiltersFeaturedState
|
PreferencesKeys.chatListFiltersFeaturedState
|
||||||
|
@ -1997,6 +1997,13 @@ public final class ChatListNode: ListView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func handlePanSelection(location: CGPoint) {
|
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 state = self.selectionPanState {
|
||||||
if let peer = self.peerAtPoint(location) {
|
if let peer = self.peerAtPoint(location) {
|
||||||
if peer.id == state.initialPeerId {
|
if peer.id == state.initialPeerId {
|
||||||
|
12
submodules/LegacyComponents/LegacyImages.xcassets/Camera/Flash.imageset/Contents.json
vendored
Normal file
12
submodules/LegacyComponents/LegacyImages.xcassets/Camera/Flash.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "ic_cam_flashon (1).pdf",
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
BIN
submodules/LegacyComponents/LegacyImages.xcassets/Camera/Flash.imageset/ic_cam_flashon (1).pdf
vendored
Normal file
BIN
submodules/LegacyComponents/LegacyImages.xcassets/Camera/Flash.imageset/ic_cam_flashon (1).pdf
vendored
Normal file
Binary file not shown.
@ -60,7 +60,7 @@ typedef enum
|
|||||||
@property (nonatomic, copy) void(^finishedModeChange)(void);
|
@property (nonatomic, copy) void(^finishedModeChange)(void);
|
||||||
|
|
||||||
@property (nonatomic, copy) void(^beganPositionChange)(bool targetPositionHasFlash, bool targetPositionHasZoom, void(^commitBlock)(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(^beganAdjustingFocus)(void);
|
||||||
@property (nonatomic, copy) void(^finishedAdjustingFocus)(void);
|
@property (nonatomic, copy) void(^finishedAdjustingFocus)(void);
|
||||||
|
@ -6,15 +6,13 @@
|
|||||||
@property (nonatomic, assign) PGCameraFlashMode mode;
|
@property (nonatomic, assign) PGCameraFlashMode mode;
|
||||||
@property (nonatomic, assign) UIInterfaceOrientation interfaceOrientation;
|
@property (nonatomic, assign) UIInterfaceOrientation interfaceOrientation;
|
||||||
|
|
||||||
@property (nonatomic, copy) void(^becameActive)(void);
|
|
||||||
@property (nonatomic, copy) void(^modeChanged)(PGCameraFlashMode mode);
|
@property (nonatomic, copy) void(^modeChanged)(PGCameraFlashMode mode);
|
||||||
|
|
||||||
- (void)setFlashUnavailable:(bool)unavailable;
|
- (void)setFlashUnavailable:(bool)unavailable;
|
||||||
|
- (void)setFlashActive:(bool)active;
|
||||||
|
|
||||||
- (void)setHidden:(bool)hidden animated:(bool)animated;
|
- (void)setHidden:(bool)hidden animated:(bool)animated;
|
||||||
|
|
||||||
- (void)dismissAnimated:(bool)animated;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
extern const CGFloat TGCameraFlashControlHeight;
|
extern const CGFloat TGCameraFlashControlHeight;
|
||||||
|
@ -18,6 +18,10 @@
|
|||||||
@class TGMediaPickerGallerySelectedItemsModel;
|
@class TGMediaPickerGallerySelectedItemsModel;
|
||||||
@class TGMediaEditingContext;
|
@class TGMediaEditingContext;
|
||||||
|
|
||||||
|
@interface TGCameraCornersView : UIImageView
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
@interface TGCameraMainView : UIView
|
@interface TGCameraMainView : UIView
|
||||||
{
|
{
|
||||||
UIInterfaceOrientation _interfaceOrientation;
|
UIInterfaceOrientation _interfaceOrientation;
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
- (void)setHidden:(bool)hidden animated:(bool)animated;
|
- (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
|
@end
|
||||||
|
|
||||||
@ -38,4 +38,6 @@
|
|||||||
|
|
||||||
- (void)setHidden:(bool)hidden animated:(bool)animated;
|
- (void)setHidden:(bool)hidden animated:(bool)animated;
|
||||||
|
|
||||||
|
- (instancetype)initWithFrame:(CGRect)frame hasUltrawideCamera:(bool)hasUltrawideCamera hasTelephotoCamera:(bool)hasTelephotoCamera;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -690,7 +690,7 @@ NSString *const PGCameraAdjustingFocusKey = @"adjustingFocus";
|
|||||||
[strongSelf.captureSession setCurrentCameraPosition:targetCameraPosition];
|
[strongSelf.captureSession setCurrentCameraPosition:targetCameraPosition];
|
||||||
|
|
||||||
if (strongSelf.finishedPositionChange != nil)
|
if (strongSelf.finishedPositionChange != nil)
|
||||||
strongSelf.finishedPositionChange();
|
strongSelf.finishedPositionChange([PGCameraCaptureSession _isZoomAvailableForDevice:targetDevice]);
|
||||||
|
|
||||||
[strongSelf _subscribeForCameraChanges];
|
[strongSelf _subscribeForCameraChanges];
|
||||||
}];
|
}];
|
||||||
|
@ -107,6 +107,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
|||||||
UIView *_backgroundView;
|
UIView *_backgroundView;
|
||||||
TGCameraPreviewView *_previewView;
|
TGCameraPreviewView *_previewView;
|
||||||
TGCameraMainView *_interfaceView;
|
TGCameraMainView *_interfaceView;
|
||||||
|
TGCameraCornersView *_cornersView;
|
||||||
UIView *_overlayView;
|
UIView *_overlayView;
|
||||||
TGCameraFocusCrosshairsControl *_focusControl;
|
TGCameraFocusCrosshairsControl *_focusControl;
|
||||||
TGCameraRectangleView *_rectangleView;
|
TGCameraRectangleView *_rectangleView;
|
||||||
@ -318,6 +319,9 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
|||||||
_interfaceView.transform = CGAffineTransformMakeRotation(TGRotationForInterfaceOrientation(interfaceOrientation));
|
_interfaceView.transform = CGAffineTransformMakeRotation(TGRotationForInterfaceOrientation(interfaceOrientation));
|
||||||
_interfaceView.frame = CGRectMake(0, 0, referenceSize.width, referenceSize.height);
|
_interfaceView.frame = CGRectMake(0, 0, referenceSize.width, referenceSize.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_cornersView = [[TGCameraCornersView alloc] init];
|
||||||
|
|
||||||
if (_intent == TGCameraControllerPassportIdIntent)
|
if (_intent == TGCameraControllerPassportIdIntent)
|
||||||
[_interfaceView setDocumentFrameHidden:false];
|
[_interfaceView setDocumentFrameHidden:false];
|
||||||
_selectedItemsModel = [[TGMediaPickerGallerySelectedItemsModel alloc] initWithSelectionContext:nil items:[_items copy]];
|
_selectedItemsModel = [[TGMediaPickerGallerySelectedItemsModel alloc] initWithSelectionContext:nil items:[_items copy]];
|
||||||
@ -451,6 +455,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
|||||||
}
|
}
|
||||||
|
|
||||||
[_autorotationCorrectionView addSubview:_interfaceView];
|
[_autorotationCorrectionView addSubview:_interfaceView];
|
||||||
|
[_autorotationCorrectionView addSubview:_cornersView];
|
||||||
|
|
||||||
_photoSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)];
|
_photoSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)];
|
||||||
_photoSwipeGestureRecognizer.delegate = self;
|
_photoSwipeGestureRecognizer.delegate = self;
|
||||||
@ -633,7 +638,9 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
|||||||
[strongSelf->_focusControl reset];
|
[strongSelf->_focusControl reset];
|
||||||
|
|
||||||
[strongSelf->_interfaceView setHasFlash:targetPositionHasFlash];
|
[strongSelf->_interfaceView setHasFlash:targetPositionHasFlash];
|
||||||
|
if (!targetPositionHasZoom) {
|
||||||
[strongSelf->_interfaceView setHasZoom:targetPositionHasZoom];
|
[strongSelf->_interfaceView setHasZoom:targetPositionHasZoom];
|
||||||
|
}
|
||||||
strongSelf->_camera.zoomLevel = 0.0f;
|
strongSelf->_camera.zoomLevel = 0.0f;
|
||||||
|
|
||||||
strongSelf.view.userInteractionEnabled = false;
|
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;
|
__strong TGCameraController *strongSelf = weakSelf;
|
||||||
if (strongSelf == nil)
|
if (strongSelf == nil)
|
||||||
@ -675,6 +682,10 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
|||||||
[strongSelf->_previewView endTransitionAnimated:true];
|
[strongSelf->_previewView endTransitionAnimated:true];
|
||||||
[strongSelf->_interfaceView setZoomLevel:1.0f displayNeeded:false];
|
[strongSelf->_interfaceView setZoomLevel:1.0f displayNeeded:false];
|
||||||
|
|
||||||
|
if (targetPositionHasZoom) {
|
||||||
|
[strongSelf->_interfaceView setHasZoom:targetPositionHasZoom];
|
||||||
|
}
|
||||||
|
|
||||||
if (strongSelf->_camera.hasFlash && strongSelf->_camera.flashActive)
|
if (strongSelf->_camera.hasFlash && strongSelf->_camera.flashActive)
|
||||||
[strongSelf->_interfaceView setFlashActive:true];
|
[strongSelf->_interfaceView setFlashActive:true];
|
||||||
|
|
||||||
@ -712,7 +723,6 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
|||||||
|
|
||||||
TGDispatchOnMainThread(^
|
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;
|
animation.duration = 0.2f;
|
||||||
[_interfaceView.layer addAnimation:animation forKey:@"opacity"];
|
[_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;
|
_interfaceView.alpha = hidden ? 0.0f : 1.0f;
|
||||||
|
_cornersView.alpha = hidden ? 0.0 : 1.0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
[_interfaceView.layer removeAllAnimations];
|
[_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:^
|
[UIView animateWithDuration:0.3f delay:0.1f options:UIViewAnimationOptionCurveLinear animations:^
|
||||||
{
|
{
|
||||||
_interfaceView.alpha = 1.0f;
|
_interfaceView.alpha = 1.0f;
|
||||||
|
_cornersView.alpha = 1.0;
|
||||||
} completion:nil];
|
} completion:nil];
|
||||||
|
|
||||||
_interfaceView.previewViewFrame = _previewView.frame;
|
_interfaceView.previewViewFrame = _previewView.frame;
|
||||||
@ -2173,11 +2194,13 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
|||||||
|
|
||||||
_backgroundView.alpha = 0.0f;
|
_backgroundView.alpha = 0.0f;
|
||||||
_interfaceView.alpha = 0.0f;
|
_interfaceView.alpha = 0.0f;
|
||||||
|
_cornersView.alpha = 0.0;
|
||||||
|
|
||||||
[UIView animateWithDuration:0.3f animations:^
|
[UIView animateWithDuration:0.3f animations:^
|
||||||
{
|
{
|
||||||
_backgroundView.alpha = 1.0f;
|
_backgroundView.alpha = 1.0f;
|
||||||
_interfaceView.alpha = 1.0f;
|
_interfaceView.alpha = 1.0f;
|
||||||
|
_cornersView.alpha = 1.0;
|
||||||
}];
|
}];
|
||||||
|
|
||||||
CGRect fromFrame = rect;
|
CGRect fromFrame = rect;
|
||||||
@ -2191,10 +2214,18 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
|||||||
frameAnimation.springSpeed = 20;
|
frameAnimation.springSpeed = 20;
|
||||||
frameAnimation.springBounciness = 1;
|
frameAnimation.springBounciness = 1;
|
||||||
[_previewView pop_addAnimation:frameAnimation forKey:@"frame"];
|
[_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
|
else
|
||||||
{
|
{
|
||||||
_previewView.frame = toFrame;
|
_previewView.frame = toFrame;
|
||||||
|
_cornersView.frame = toFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
_interfaceView.previewViewFrame = toFrame;
|
_interfaceView.previewViewFrame = toFrame;
|
||||||
@ -2208,16 +2239,12 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
|||||||
_focusControl.active = false;
|
_focusControl.active = false;
|
||||||
_rectangleView.hidden = true;
|
_rectangleView.hidden = true;
|
||||||
|
|
||||||
[UIView animateWithDuration:0.3f animations:^
|
|
||||||
{
|
|
||||||
//[_context setApplicationStatusBarAlpha:1.0f];
|
|
||||||
}];
|
|
||||||
|
|
||||||
[self setInterfaceHidden:true animated:true];
|
[self setInterfaceHidden:true animated:true];
|
||||||
|
|
||||||
[UIView animateWithDuration:0.25f animations:^
|
[UIView animateWithDuration:0.25f animations:^
|
||||||
{
|
{
|
||||||
_backgroundView.alpha = 0.0f;
|
_backgroundView.alpha = 0.0f;
|
||||||
|
_cornersView.alpha = 0.0;
|
||||||
}];
|
}];
|
||||||
|
|
||||||
CGRect referenceFrame = CGRectZero;
|
CGRect referenceFrame = CGRectZero;
|
||||||
@ -2272,6 +2299,13 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
|||||||
[strongSelf dismiss];
|
[strongSelf dismiss];
|
||||||
};
|
};
|
||||||
[_previewView pop_addAnimation:frameAnimation forKey:@"frame"];
|
[_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
|
else
|
||||||
{
|
{
|
||||||
@ -2328,6 +2362,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
|||||||
[UIView animateWithDuration:ABS(distance / velocity) animations:^
|
[UIView animateWithDuration:ABS(distance / velocity) animations:^
|
||||||
{
|
{
|
||||||
_previewView.frame = targetFrame;
|
_previewView.frame = targetFrame;
|
||||||
|
_cornersView.frame = targetFrame;
|
||||||
} completion:^(__unused BOOL finished)
|
} completion:^(__unused BOOL finished)
|
||||||
{
|
{
|
||||||
if (completion)
|
if (completion)
|
||||||
@ -2344,11 +2379,13 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
|
|||||||
[UIView animateWithDuration:0.3 animations:^
|
[UIView animateWithDuration:0.3 animations:^
|
||||||
{
|
{
|
||||||
_previewView.frame = frame;
|
_previewView.frame = frame;
|
||||||
|
_cornersView.frame = frame;
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_previewView.frame = frame;
|
_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:^
|
[UIView animateWithDuration:0.3f delay:0.0f options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionLayoutSubviews animations:^
|
||||||
{
|
{
|
||||||
_previewView.frame = frame;
|
_previewView.frame = frame;
|
||||||
|
_cornersView.frame = frame;
|
||||||
_overlayView.frame = frame;
|
_overlayView.frame = frame;
|
||||||
} completion:nil];
|
} completion:nil];
|
||||||
}
|
}
|
||||||
|
@ -2,21 +2,118 @@
|
|||||||
|
|
||||||
#import "LegacyComponentsInternal.h"
|
#import "LegacyComponentsInternal.h"
|
||||||
|
|
||||||
|
#import "TGImageUtils.h"
|
||||||
|
|
||||||
#import "UIControl+HitTestEdgeInsets.h"
|
#import "UIControl+HitTestEdgeInsets.h"
|
||||||
|
|
||||||
#import "TGCameraInterfaceAssets.h"
|
#import "TGCameraInterfaceAssets.h"
|
||||||
#import <LegacyComponents/TGModernButton.h>
|
#import <LegacyComponents/TGModernButton.h>
|
||||||
|
|
||||||
|
#import "POPBasicAnimation.h"
|
||||||
|
|
||||||
const CGFloat TGCameraFlashControlHeight = 44.0f;
|
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 ()
|
@interface TGCameraFlashControl ()
|
||||||
{
|
{
|
||||||
UIButton *_flashIconView;
|
TGCameraFlashIcon *_icon;
|
||||||
UIButton *_autoButton;
|
UIButton *_button;
|
||||||
UIButton *_onButton;
|
|
||||||
UIButton *_offButton;
|
|
||||||
|
|
||||||
bool _active;
|
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@ -27,23 +124,22 @@ const CGFloat TGCameraFlashControlHeight = 44.0f;
|
|||||||
self = [super initWithFrame:frame];
|
self = [super initWithFrame:frame];
|
||||||
if (self != nil)
|
if (self != nil)
|
||||||
{
|
{
|
||||||
|
self.mode = PGCameraFlashModeOff;
|
||||||
|
|
||||||
self.hitTestEdgeInsets = UIEdgeInsetsMake(-10, -10, -10, -10);
|
self.hitTestEdgeInsets = UIEdgeInsetsMake(-10, -10, -10, -10);
|
||||||
|
|
||||||
_flashIconView = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 44, 44)];
|
_icon = [[TGCameraFlashIcon alloc] initWithFrame:CGRectMake(7, 7, 30, 30)];
|
||||||
_flashIconView.adjustsImageWhenHighlighted = false;
|
_icon.userInteractionEnabled = false;
|
||||||
_flashIconView.contentMode = UIViewContentModeCenter;
|
[self addSubview:_icon];
|
||||||
_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:^
|
_button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 44, 44)];
|
||||||
{
|
_button.adjustsImageWhenHighlighted = false;
|
||||||
self.mode = PGCameraFlashModeOff;
|
_button.contentMode = UIViewContentModeCenter;
|
||||||
[self setActive:false animated:false];
|
_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;
|
return self;
|
||||||
}
|
}
|
||||||
@ -61,11 +157,11 @@ const CGFloat TGCameraFlashControlHeight = 44.0f;
|
|||||||
- (void)buttonPressed:(UIButton *)sender
|
- (void)buttonPressed:(UIButton *)sender
|
||||||
{
|
{
|
||||||
if (_mode == PGCameraFlashModeOff) {
|
if (_mode == PGCameraFlashModeOff) {
|
||||||
self.mode = PGCameraFlashModeOn;
|
self.mode = PGCameraFlashModeAuto;
|
||||||
[_flashIconView setImage:[UIImage imageNamed:@"Camera/FlashOn"] forState:UIControlStateNormal];
|
[_icon setOn:true animated:true];
|
||||||
} else {
|
} else {
|
||||||
self.mode = PGCameraFlashModeOff;
|
self.mode = PGCameraFlashModeOff;
|
||||||
[_flashIconView setImage:[UIImage imageNamed:@"Camera/FlashOff"] forState:UIControlStateNormal];
|
[_icon setOn:false animated:true];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.modeChanged != nil)
|
if (self.modeChanged != nil)
|
||||||
@ -75,35 +171,24 @@ const CGFloat TGCameraFlashControlHeight = 44.0f;
|
|||||||
- (void)setFlashUnavailable:(bool)unavailable
|
- (void)setFlashUnavailable:(bool)unavailable
|
||||||
{
|
{
|
||||||
self.userInteractionEnabled = !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
|
- (void)setMode:(PGCameraFlashMode)mode
|
||||||
{
|
{
|
||||||
_mode = mode;
|
_mode = mode;
|
||||||
|
[_icon setOn:mode == PGCameraFlashModeAuto animated:true];
|
||||||
[self setActive:false animated:_active];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)dismissAnimated:(bool)animated
|
|
||||||
{
|
|
||||||
if (animated && _active)
|
|
||||||
[self setActive:false animated:animated];
|
|
||||||
else
|
|
||||||
[self setActive:false animated:false];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setHidden:(BOOL)hidden
|
- (void)setHidden:(BOOL)hidden
|
||||||
{
|
{
|
||||||
self.alpha = hidden ? 0.0f : 1.0f;
|
self.alpha = hidden ? 0.0f : 1.0f;
|
||||||
super.hidden = hidden;
|
super.hidden = hidden;
|
||||||
|
|
||||||
[self setActive:false animated:false];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setHidden:(bool)hidden animated:(bool)animated
|
- (void)setHidden:(bool)hidden animated:(bool)animated
|
||||||
@ -123,16 +208,12 @@ const CGFloat TGCameraFlashControlHeight = 44.0f;
|
|||||||
|
|
||||||
if (finished)
|
if (finished)
|
||||||
self.hidden = hidden;
|
self.hidden = hidden;
|
||||||
|
|
||||||
[self setActive:false animated:false];
|
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
self.alpha = hidden ? 0.0f : 1.0f;
|
self.alpha = hidden ? 0.0f : 1.0f;
|
||||||
super.hidden = hidden;
|
super.hidden = hidden;
|
||||||
|
|
||||||
[self setActive:false animated:false];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
self = [super initWithFrame:frame];
|
self = [super initWithFrame:frame];
|
||||||
if (self != nil)
|
if (self != nil)
|
||||||
{
|
{
|
||||||
|
self.adjustsImageWhenHighlighted = false;
|
||||||
|
self.modernHighlight = false;
|
||||||
self.exclusiveTouch = true;
|
self.exclusiveTouch = true;
|
||||||
self.backgroundColor = [TGCameraInterfaceAssets buttonColor];
|
self.backgroundColor = [TGCameraInterfaceAssets buttonColor];
|
||||||
self.layer.cornerRadius = 24.0;
|
self.layer.cornerRadius = 24.0;
|
||||||
@ -19,6 +21,16 @@
|
|||||||
return self;
|
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
|
- (void)setHidden:(BOOL)hidden
|
||||||
{
|
{
|
||||||
self.alpha = hidden ? 0.0f : 1.0f;
|
self.alpha = hidden ? 0.0f : 1.0f;
|
||||||
@ -60,6 +72,8 @@
|
|||||||
self = [super initWithFrame:frame];
|
self = [super initWithFrame:frame];
|
||||||
if (self != nil)
|
if (self != nil)
|
||||||
{
|
{
|
||||||
|
self.adjustsImageWhenHighlighted = false;
|
||||||
|
self.modernHighlight = false;
|
||||||
self.exclusiveTouch = true;
|
self.exclusiveTouch = true;
|
||||||
self.backgroundColor = [TGCameraInterfaceAssets buttonColor];
|
self.backgroundColor = [TGCameraInterfaceAssets buttonColor];
|
||||||
self.layer.cornerRadius = 24.0;
|
self.layer.cornerRadius = 24.0;
|
||||||
@ -68,6 +82,16 @@
|
|||||||
return self;
|
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
|
- (void)setHidden:(BOOL)hidden
|
||||||
{
|
{
|
||||||
self.alpha = hidden ? 0.0f : 1.0f;
|
self.alpha = hidden ? 0.0f : 1.0f;
|
||||||
|
@ -82,6 +82,8 @@
|
|||||||
bool _displayedTooltip;
|
bool _displayedTooltip;
|
||||||
TGMenuContainerView *_tooltipContainerView;
|
TGMenuContainerView *_tooltipContainerView;
|
||||||
NSTimer *_tooltipTimer;
|
NSTimer *_tooltipTimer;
|
||||||
|
|
||||||
|
bool _dismissingWheel;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@ -261,21 +263,31 @@
|
|||||||
_toastView.userInteractionEnabled = false;
|
_toastView.userInteractionEnabled = false;
|
||||||
[self addSubview:_toastView];
|
[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) {
|
_zoomModeView.zoomChanged = ^(CGFloat zoomLevel, bool done, bool animated) {
|
||||||
__strong TGCameraMainPhoneView *strongSelf = weakSelf;
|
__strong TGCameraMainPhoneView *strongSelf = weakSelf;
|
||||||
if (strongSelf == nil)
|
if (strongSelf == nil)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!done) {
|
if (done) {
|
||||||
[strongSelf->_zoomWheelView setZoomLevel:zoomLevel];
|
|
||||||
[strongSelf->_zoomModeView setHidden:true animated:true];
|
|
||||||
[strongSelf->_zoomWheelView setHidden:false animated:true];
|
|
||||||
} else {
|
|
||||||
[strongSelf->_zoomWheelView setZoomLevel:zoomLevel];
|
[strongSelf->_zoomWheelView setZoomLevel:zoomLevel];
|
||||||
[strongSelf->_zoomModeView setZoomLevel:zoomLevel animated:false];
|
[strongSelf->_zoomModeView setZoomLevel:zoomLevel animated:false];
|
||||||
|
|
||||||
|
if (!strongSelf->_zoomWheelView.isHidden) {
|
||||||
|
strongSelf->_dismissingWheel = true;
|
||||||
|
|
||||||
|
TGDispatchAfter(0.6, dispatch_get_main_queue(), ^{
|
||||||
|
if (strongSelf->_dismissingWheel) {
|
||||||
[strongSelf->_zoomModeView setHidden:false animated:true];
|
[strongSelf->_zoomModeView setHidden:false animated:true];
|
||||||
[strongSelf->_zoomWheelView setHidden:true 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)
|
if (strongSelf.zoomChanged != nil)
|
||||||
@ -284,7 +296,7 @@
|
|||||||
[_zoomModeView setZoomLevel:1.0];
|
[_zoomModeView setZoomLevel:1.0];
|
||||||
[self addSubview:_zoomModeView];
|
[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 setHidden:true animated:false];
|
||||||
[_zoomWheelView setZoomLevel:1.0];
|
[_zoomWheelView setZoomLevel:1.0];
|
||||||
_zoomWheelView.userInteractionEnabled = false;
|
_zoomWheelView.userInteractionEnabled = false;
|
||||||
@ -440,13 +452,6 @@
|
|||||||
|
|
||||||
#pragma mark - Actions
|
#pragma mark - Actions
|
||||||
|
|
||||||
- (void)shutterButtonReleased
|
|
||||||
{
|
|
||||||
[super shutterButtonReleased];
|
|
||||||
|
|
||||||
[_flashControl dismissAnimated:true];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)updateForCameraModeChangeWithPreviousMode:(PGCameraMode)previousMode
|
- (void)updateForCameraModeChangeWithPreviousMode:(PGCameraMode)previousMode
|
||||||
{
|
{
|
||||||
[super updateForCameraModeChangeWithPreviousMode:previousMode];
|
[super updateForCameraModeChangeWithPreviousMode:previousMode];
|
||||||
@ -490,7 +495,6 @@
|
|||||||
[self _attachControlsToTopPanel];
|
[self _attachControlsToTopPanel];
|
||||||
|
|
||||||
[self _layoutTopPanelSubviewsForInterfaceOrientation:orientation];
|
[self _layoutTopPanelSubviewsForInterfaceOrientation:orientation];
|
||||||
[_flashControl dismissAnimated:false];
|
|
||||||
|
|
||||||
[UIView animateWithDuration:0.2f delay:0.0f options:UIViewAnimationOptionCurveEaseInOut animations:^
|
[UIView animateWithDuration:0.2f delay:0.0f options:UIViewAnimationOptionCurveEaseInOut animations:^
|
||||||
{
|
{
|
||||||
@ -512,7 +516,7 @@
|
|||||||
|
|
||||||
- (void)setFlashActive:(bool)active
|
- (void)setFlashActive:(bool)active
|
||||||
{
|
{
|
||||||
[_flashActiveView setActive:active animated:true];
|
[_flashControl setFlashActive:active];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setFlashUnavailable:(bool)unavailable
|
- (void)setFlashUnavailable:(bool)unavailable
|
||||||
@ -522,9 +526,6 @@
|
|||||||
|
|
||||||
- (void)setHasFlash:(bool)hasFlash
|
- (void)setHasFlash:(bool)hasFlash
|
||||||
{
|
{
|
||||||
if (!hasFlash)
|
|
||||||
[_flashActiveView setActive:false animated:true];
|
|
||||||
|
|
||||||
[_flashControl setHidden:!hasFlash animated:true];
|
[_flashControl setHidden:!hasFlash animated:true];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -676,8 +677,6 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
[_flashControl dismissAnimated:false];
|
|
||||||
|
|
||||||
_flipButton.transform = CGAffineTransformMakeRotation(TGRotationForInterfaceOrientation(orientation));
|
_flipButton.transform = CGAffineTransformMakeRotation(TGRotationForInterfaceOrientation(orientation));
|
||||||
_flashControl.transform = CGAffineTransformMakeRotation(TGRotationForInterfaceOrientation(orientation));
|
_flashControl.transform = CGAffineTransformMakeRotation(TGRotationForInterfaceOrientation(orientation));
|
||||||
_zoomModeView.interfaceOrientation = orientation;
|
_zoomModeView.interfaceOrientation = orientation;
|
||||||
|
@ -14,6 +14,51 @@
|
|||||||
#import "TGMediaPickerPhotoCounterButton.h"
|
#import "TGMediaPickerPhotoCounterButton.h"
|
||||||
#import "TGMediaPickerPhotoStripView.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 ()
|
@interface TGCameraMainView ()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -66,12 +66,20 @@
|
|||||||
[self reset];
|
[self reset];
|
||||||
|
|
||||||
_recordingTimer = [TGTimerTarget scheduledMainThreadTimerWithTarget:self action:@selector(recordingTimerEvent) interval:1.0 repeat:false];
|
_recordingTimer = [TGTimerTarget scheduledMainThreadTimerWithTarget:self action:@selector(recordingTimerEvent) interval:1.0 repeat:false];
|
||||||
|
|
||||||
|
[UIView animateWithDuration:0.2 animations:^{
|
||||||
|
_backgroundView.alpha = 1.0;
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)stopRecording
|
- (void)stopRecording
|
||||||
{
|
{
|
||||||
[_recordingTimer invalidate];
|
[_recordingTimer invalidate];
|
||||||
_recordingTimer = nil;
|
_recordingTimer = nil;
|
||||||
|
|
||||||
|
[UIView animateWithDuration:0.2 animations:^{
|
||||||
|
_backgroundView.alpha = 0.0;
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)reset
|
- (void)reset
|
||||||
|
@ -227,6 +227,9 @@
|
|||||||
|
|
||||||
@interface TGCameraZoomModeView ()
|
@interface TGCameraZoomModeView ()
|
||||||
{
|
{
|
||||||
|
CGFloat _minZoomLevel;
|
||||||
|
CGFloat _maxZoomLevel;
|
||||||
|
|
||||||
UIView *_backgroundView;
|
UIView *_backgroundView;
|
||||||
|
|
||||||
bool _hasUltrawideCamera;
|
bool _hasUltrawideCamera;
|
||||||
@ -240,13 +243,15 @@
|
|||||||
|
|
||||||
@implementation TGCameraZoomModeView
|
@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];
|
self = [super initWithFrame:frame];
|
||||||
if (self != nil)
|
if (self != nil)
|
||||||
{
|
{
|
||||||
_hasUltrawideCamera = hasUltrawideCamera;
|
_hasUltrawideCamera = hasUltrawideCamera;
|
||||||
_hasTelephotoCamera = hasTelephotoCamera;
|
_hasTelephotoCamera = hasTelephotoCamera;
|
||||||
|
_minZoomLevel = minZoomLevel;
|
||||||
|
_maxZoomLevel = maxZoomLevel;
|
||||||
|
|
||||||
_backgroundView = [[UIView alloc] initWithFrame:self.bounds];
|
_backgroundView = [[UIView alloc] initWithFrame:self.bounds];
|
||||||
_backgroundView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.15];
|
_backgroundView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.15];
|
||||||
@ -270,34 +275,39 @@
|
|||||||
[self addSubview:_rightItem];
|
[self addSubview:_rightItem];
|
||||||
}
|
}
|
||||||
|
|
||||||
UIPanGestureRecognizer *gestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)];
|
UIPanGestureRecognizer *panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)];
|
||||||
// [self addGestureRecognizer:gestureRecognizer];
|
[self addGestureRecognizer:panGestureRecognizer];
|
||||||
|
|
||||||
|
UILongPressGestureRecognizer *pressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(pressGesture:)];
|
||||||
|
[self addGestureRecognizer:pressGestureRecognizer];
|
||||||
}
|
}
|
||||||
return self;
|
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 {
|
- (void)panGesture:(UIPanGestureRecognizer *)gestureRecognizer {
|
||||||
CGPoint translation = [gestureRecognizer translationInView:self];
|
CGPoint translation = [gestureRecognizer translationInView:self];
|
||||||
|
|
||||||
switch (gestureRecognizer.state) {
|
switch (gestureRecognizer.state) {
|
||||||
case UIGestureRecognizerStateBegan:
|
|
||||||
self.zoomChanged(_zoomLevel, false, false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UIGestureRecognizerStateChanged:
|
case UIGestureRecognizerStateChanged:
|
||||||
_zoomLevel = MAX(0.5, MIN(10.0, _zoomLevel - translation.x / 100.0));
|
_zoomLevel = MAX(0.5, MIN(10.0, _zoomLevel - translation.x / 100.0));
|
||||||
self.zoomChanged(_zoomLevel, false, false);
|
self.zoomChanged(_zoomLevel, false, false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UIGestureRecognizerStateEnded:
|
|
||||||
self.zoomChanged(_zoomLevel, true, false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UIGestureRecognizerStateCancelled:
|
|
||||||
self.zoomChanged(_zoomLevel, true, false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -425,21 +435,85 @@
|
|||||||
|
|
||||||
@interface TGCameraZoomWheelView ()
|
@interface TGCameraZoomWheelView ()
|
||||||
{
|
{
|
||||||
|
bool _hasUltrawideCamera;
|
||||||
|
bool _hasTelephotoCamera;
|
||||||
UIImageView *_backgroundView;
|
UIImageView *_backgroundView;
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation TGCameraZoomWheelView
|
@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];
|
self = [super initWithFrame:frame];
|
||||||
if (self != nil)
|
if (self != nil)
|
||||||
{
|
{
|
||||||
|
_hasUltrawideCamera = true;// hasUltrawideCamera;
|
||||||
|
_hasTelephotoCamera = true;//hasTelephotoCamera;
|
||||||
|
|
||||||
self.clipsToBounds = true;
|
self.clipsToBounds = true;
|
||||||
|
|
||||||
_backgroundView = [[UIImageView alloc] initWithFrame:CGRectMake(-28.0, 0.0, 446.0, 446.0)];
|
CGFloat side = floor(frame.size.width * 1.1435);
|
||||||
_backgroundView.alpha = 0.75;
|
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];
|
[self addSubview:_backgroundView];
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,8 @@ const CGFloat TGPhotoPaintColorWeightGestureRange = 320.0f;
|
|||||||
const CGFloat TGPhotoPaintVerticalThreshold = 5.0f;
|
const CGFloat TGPhotoPaintVerticalThreshold = 5.0f;
|
||||||
const CGFloat TGPhotoPaintPreviewOffset = -70.0f;
|
const CGFloat TGPhotoPaintPreviewOffset = -70.0f;
|
||||||
const CGFloat TGPhotoPaintPreviewScale = 2.0f;
|
const CGFloat TGPhotoPaintPreviewScale = 2.0f;
|
||||||
const CGFloat TGPhotoPaintDefaultBrushWeight = 0.22f;
|
const CGFloat TGPhotoPaintDefaultBrushWeight = 0.08f;
|
||||||
const CGFloat TGPhotoPaintDefaultColorLocation = 1.0f;
|
const CGFloat TGPhotoPaintDefaultColorLocation = 0.0f;
|
||||||
|
|
||||||
@interface TGPhotoPaintColorPickerKnobCircleView : UIView
|
@interface TGPhotoPaintColorPickerKnobCircleView : UIView
|
||||||
{
|
{
|
||||||
@ -97,7 +97,7 @@ const CGFloat TGPhotoPaintDefaultColorLocation = 1.0f;
|
|||||||
[self addGestureRecognizer:_tapGestureRecognizer];
|
[self addGestureRecognizer:_tapGestureRecognizer];
|
||||||
|
|
||||||
_location = [self restoreLastColorLocation];
|
_location = [self restoreLastColorLocation];
|
||||||
_weight = 0.08f;
|
_weight = TGPhotoPaintDefaultBrushWeight;
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -213,8 +213,10 @@ private func pushPeerReadState(network: Network, postbox: Postbox, stateManager:
|
|||||||
return .single(readState)
|
return .single(readState)
|
||||||
case let .indexBased(maxIncomingReadIndex, _, _, _):
|
case let .indexBased(maxIncomingReadIndex, _, _, _):
|
||||||
return network.request(Api.functions.messages.readEncryptedHistory(peer: inputPeer, maxDate: maxIncomingReadIndex.timestamp))
|
return network.request(Api.functions.messages.readEncryptedHistory(peer: inputPeer, maxDate: maxIncomingReadIndex.timestamp))
|
||||||
|> retryRequest
|
|> mapError { _ in
|
||||||
|> mapToSignalPromotingError { _ -> Signal<PeerReadState, PeerReadStateValidationError> in
|
return PeerReadStateValidationError.retry
|
||||||
|
}
|
||||||
|
|> mapToSignal { _ -> Signal<PeerReadState, PeerReadStateValidationError> in
|
||||||
return .single(readState)
|
return .single(readState)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2218,6 +2218,13 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func handlePanSelection(location: CGPoint) {
|
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 state = self.selectionPanState {
|
||||||
if let messages = self.messagesAtPoint(location), let message = messages.first {
|
if let messages = self.messagesAtPoint(location), let message = messages.first {
|
||||||
if message.id == state.initialMessageId {
|
if message.id == state.initialMessageId {
|
||||||
|
@ -70,6 +70,8 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var wasPlaying = false
|
||||||
|
|
||||||
required init() {
|
required init() {
|
||||||
self.contextSourceNode = ContextExtractedContentContainingNode()
|
self.contextSourceNode = ContextExtractedContentContainingNode()
|
||||||
self.containerNode = ContextControllerSourceNode()
|
self.containerNode = ContextControllerSourceNode()
|
||||||
@ -97,7 +99,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if strongSelf.appliedCurrentlyPlaying && !strongSelf.interactiveVideoNode.isPlaying {
|
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 let action = strongSelf.gestureRecognized(gesture: .tap, location: location, recognizer: nil) {
|
||||||
if case .action = action {
|
if case .action = action {
|
||||||
@ -126,9 +128,23 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD
|
|||||||
case let .openContextMenu(tapMessage, selectAll, subFrame):
|
case let .openContextMenu(tapMessage, selectAll, subFrame):
|
||||||
strongSelf.recognizer?.cancel()
|
strongSelf.recognizer?.cancel()
|
||||||
item.controllerInteraction.openMessageContextMenu(tapMessage, selectAll, strongSelf, subFrame, gesture)
|
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.addSubnode(self.contextSourceNode)
|
||||||
self.containerNode.targetNodeForActivationProgress = self.contextSourceNode.contentNode
|
self.containerNode.targetNodeForActivationProgress = self.contextSourceNode.contentNode
|
||||||
|
@ -777,9 +777,9 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
|||||||
if !self.bounds.contains(point) {
|
if !self.bounds.contains(point) {
|
||||||
return nil
|
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)
|
let distanceFromCenter = point.distanceTo(playbackNode.position)
|
||||||
if distanceFromCenter < 0.15 * playbackNode.frame.width {
|
if distanceFromCenter < 0.2 * playbackNode.frame.width {
|
||||||
return self.view
|
return self.view
|
||||||
} else {
|
} else {
|
||||||
return playbackNode.view
|
return playbackNode.view
|
||||||
|
@ -11,12 +11,14 @@ private final class InstantVideoRadialStatusNodeParameters: NSObject {
|
|||||||
let progress: CGFloat
|
let progress: CGFloat
|
||||||
let dimProgress: CGFloat
|
let dimProgress: CGFloat
|
||||||
let playProgress: 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.color = color
|
||||||
self.progress = progress
|
self.progress = progress
|
||||||
self.dimProgress = dimProgress
|
self.dimProgress = dimProgress
|
||||||
self.playProgress = playProgress
|
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 center = CGPoint(x: self.bounds.width / 2.0, y: self.bounds.height / 2.0)
|
||||||
let location = gestureRecognizer.location(in: self.view)
|
let location = gestureRecognizer.location(in: self.view)
|
||||||
let distanceFromCenter = location.distanceTo(center)
|
let distanceFromCenter = location.distanceTo(center)
|
||||||
if distanceFromCenter < self.bounds.width * 0.15 {
|
if distanceFromCenter < self.bounds.width * 0.2 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@ -210,7 +212,7 @@ final class InstantVideoRadialStatusNode: ASDisplayNode, UIGestureRecognizerDele
|
|||||||
}
|
}
|
||||||
|
|
||||||
override func drawParameters(forAsyncLayer layer: _ASDisplayLayer) -> NSObjectProtocol? {
|
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) {
|
@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)
|
progress = min(1.0, progress)
|
||||||
|
|
||||||
var lineWidth: CGFloat = 4.0
|
var lineWidth: CGFloat = 4.0
|
||||||
|
if parameters.hasSeek {
|
||||||
lineWidth += 1.0 * parameters.dimProgress
|
lineWidth += 1.0 * parameters.dimProgress
|
||||||
|
}
|
||||||
|
|
||||||
var pathDiameter = bounds.size.width - lineWidth - 8.0
|
var pathDiameter = bounds.size.width - lineWidth - 8.0
|
||||||
|
if parameters.hasSeek {
|
||||||
pathDiameter -= (18.0 * 2.0) * parameters.dimProgress
|
pathDiameter -= (18.0 * 2.0) * parameters.dimProgress
|
||||||
|
}
|
||||||
|
|
||||||
if !parameters.dimProgress.isZero {
|
if !parameters.dimProgress.isZero {
|
||||||
|
if parameters.hasSeek {
|
||||||
context.setStrokeColor(parameters.color.withAlphaComponent(0.2 * parameters.dimProgress).cgColor)
|
context.setStrokeColor(parameters.color.withAlphaComponent(0.2 * parameters.dimProgress).cgColor)
|
||||||
context.setLineWidth(lineWidth)
|
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))
|
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 {
|
if !parameters.playProgress.isZero {
|
||||||
context.saveGState()
|
context.saveGState()
|
||||||
context.translateBy(x: bounds.width / 2.0, y: bounds.height / 2.0)
|
context.translateBy(x: bounds.width / 2.0, y: bounds.height / 2.0)
|
||||||
|
if parameters.hasSeek {
|
||||||
context.scaleBy(x: 1.0 + 1.4 * parameters.playProgress, y: 1.0 + 1.4 * parameters.playProgress)
|
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)
|
context.translateBy(x: -bounds.width / 2.0, y: -bounds.height / 2.0)
|
||||||
|
|
||||||
let iconSize = CGSize(width: 15.0, height: 18.0)
|
let iconSize = CGSize(width: 15.0, height: 18.0)
|
||||||
@ -272,6 +284,7 @@ final class InstantVideoRadialStatusNode: ASDisplayNode, UIGestureRecognizerDele
|
|||||||
path.lineCapStyle = .round
|
path.lineCapStyle = .round
|
||||||
path.stroke()
|
path.stroke()
|
||||||
|
|
||||||
|
if parameters.hasSeek {
|
||||||
let handleSide = 16.0 * min(1.0, (parameters.dimProgress * 2.0))
|
let handleSide = 16.0 * min(1.0, (parameters.dimProgress * 2.0))
|
||||||
let handleSize = CGSize(width: handleSide, height: handleSide)
|
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 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)
|
||||||
@ -280,6 +293,7 @@ final class InstantVideoRadialStatusNode: ASDisplayNode, UIGestureRecognizerDele
|
|||||||
context.fillEllipse(in: handleFrame)
|
context.fillEllipse(in: handleFrame)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func updateProgress() {
|
private func updateProgress() {
|
||||||
let timestampAndDuration: (timestamp: Double, duration: Double, baseRate: Double)?
|
let timestampAndDuration: (timestamp: Double, duration: Double, baseRate: Double)?
|
||||||
@ -297,10 +311,6 @@ final class InstantVideoRadialStatusNode: ASDisplayNode, UIGestureRecognizerDele
|
|||||||
dimmed = true
|
dimmed = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.hasSeek {
|
|
||||||
dimmed = false
|
|
||||||
}
|
|
||||||
|
|
||||||
if dimmed != self.dimmed {
|
if dimmed != self.dimmed {
|
||||||
self.dimmed = dimmed
|
self.dimmed = dimmed
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user