Merge commit 'e5186bd7ae1b9f8bc8b1a0130b725a26ee5755f2'

This commit is contained in:
Ali 2021-07-27 00:49:20 +02:00
commit 4e6579d5b6
22 changed files with 482 additions and 155 deletions

View File

@ -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
}
@ -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 {
let initializedFeatured = self.context.account.postbox.preferencesView(keys: [
PreferencesKeys.chatListFiltersFeaturedState

View File

@ -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 {

View File

@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "ic_cam_flashon (1).pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -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);

View File

@ -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;

View File

@ -18,6 +18,10 @@
@class TGMediaPickerGallerySelectedItemsModel;
@class TGMediaEditingContext;
@interface TGCameraCornersView : UIImageView
@end
@interface TGCameraMainView : UIView
{
UIInterfaceOrientation _interfaceOrientation;

View File

@ -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

View File

@ -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];
}];

View File

@ -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,6 +455,7 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
}
[_autorotationCorrectionView addSubview:_interfaceView];
[_autorotationCorrectionView addSubview:_cornersView];
_photoSwipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)];
_photoSwipeGestureRecognizer.delegate = self;
@ -633,7 +638,9 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
[strongSelf->_focusControl reset];
[strongSelf->_interfaceView setHasFlash:targetPositionHasFlash];
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,7 +723,6 @@ static CGPoint TGCameraControllerClampPointToScreenSize(__unused id self, __unus
TGDispatchOnMainThread(^
{
if (!strongSelf->_camera.isRecordingVideo)
[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];
}

View File

@ -2,21 +2,118 @@
#import "LegacyComponentsInternal.h"
#import "TGImageUtils.h"
#import "UIControl+HitTestEdgeInsets.h"
#import "TGCameraInterfaceAssets.h"
#import <LegacyComponents/TGModernButton.h>
#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];
_icon = [[TGCameraFlashIcon alloc] initWithFrame:CGRectMake(7, 7, 30, 30)];
_icon.userInteractionEnabled = false;
[self addSubview:_icon];
[UIView performWithoutAnimation:^
{
self.mode = PGCameraFlashModeOff;
[self setActive:false animated:false];
}];
_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];
}
}

View File

@ -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;

View File

@ -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];
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];
// [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;

View File

@ -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 ()
{

View File

@ -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

View File

@ -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)
{
_hasUltrawideCamera = true;// hasUltrawideCamera;
_hasTelephotoCamera = true;//hasTelephotoCamera;
self.clipsToBounds = true;
_backgroundView = [[UIImageView alloc] initWithFrame:CGRectMake(-28.0, 0.0, 446.0, 446.0)];
_backgroundView.alpha = 0.75;
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];
}

View File

@ -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;
}

View File

@ -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<PeerReadState, PeerReadStateValidationError> in
|> mapError { _ in
return PeerReadStateValidationError.retry
}
|> mapToSignal { _ -> Signal<PeerReadState, PeerReadStateValidationError> in
return .single(readState)
}
}

View File

@ -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 {

View File

@ -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,9 +128,23 @@ 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

View File

@ -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

View File

@ -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
if parameters.hasSeek {
lineWidth += 1.0 * parameters.dimProgress
}
var pathDiameter = bounds.size.width - lineWidth - 8.0
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)
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,6 +284,7 @@ final class InstantVideoRadialStatusNode: ASDisplayNode, UIGestureRecognizerDele
path.lineCapStyle = .round
path.stroke()
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)
@ -280,6 +293,7 @@ final class InstantVideoRadialStatusNode: ASDisplayNode, UIGestureRecognizerDele
context.fillEllipse(in: handleFrame)
}
}
}
private func updateProgress() {
let timestampAndDuration: (timestamp: Double, duration: Double, baseRate: Double)?
@ -297,10 +311,6 @@ final class InstantVideoRadialStatusNode: ASDisplayNode, UIGestureRecognizerDele
dimmed = true
}
if !self.hasSeek {
dimmed = false
}
if dimmed != self.dimmed {
self.dimmed = dimmed