diff --git a/Lock.json b/Lock.json new file mode 100644 index 0000000000..f56c2c101f --- /dev/null +++ b/Lock.json @@ -0,0 +1 @@ +{"v":"5.5.9","fr":60,"ip":0,"op":30,"w":240,"h":360,"nm":"Lock2","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Path","parent":2,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[100]},{"t":25,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":15,"s":[100,100,100]},{"t":25,"s":[0,0,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.29,0],[0,0],[0,-1.29],[0,0],[1.28,0],[0,0],[0,1.28],[0,0]],"o":[[0,0],[1.28,0],[0,0],[0,1.28],[0,0],[-1.29,0],[0,0],[0,-1.29]],"v":[[-4.995,-6.335],[5.005,-6.335],[7.335,-3.995],[7.335,4.005],[5.005,6.335],[-4.995,6.335],[-7.335,4.005],[-7.335,-3.995]],"c":true},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.968627510819,0.968627510819,0.968627510819,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Path","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Rectangle","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[0]},{"t":25,"s":[90]}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[120]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[120]},{"t":25,"s":[120]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[150]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[200]},{"t":25,"s":[180]}],"ix":4}},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":15,"s":[{"i":[[-1.66,0],[0,0],[0,-1.66],[0,0],[1.66,0],[0,0],[0,1.66],[0,0]],"o":[[0,0],[1.66,0],[0,0],[0,1.66],[0,0],[-1.66,0],[0,0],[0,-1.66]],"v":[[-5,-7],[5,-7],[8,-4],[8,4],[5,7],[-5,7],[-8,4],[-8,-4]],"c":true}]},{"t":25,"s":[{"i":[[-1.66,0],[0,0],[0,-1.66],[0,0],[1.66,0],[0,0],[0,1.66],[0,0]],"o":[[0,0],[1.66,0],[0,0],[0,1.66],[0,0],[-1.66,0],[0,0],[0,-1.66]],"v":[[-5,-8],[5,-8],[8,-5],[8,5],[5,8],[-5,8],[-8,5],[-8,-5]],"c":true}]}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.592000007629,0.592000007629,0.592000007629,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.33,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Rectangle","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.592156862745,0.592156862745,0.592156862745,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":30,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Path","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[10]},{"t":15,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":0,"s":[30,-32,0],"to":[0,2.5,0],"ti":[0,-11.667,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":15,"s":[30,-17,0],"to":[0,11.667,0],"ti":[0,-9.167,0]},{"t":25,"s":[30,38,0]}],"ix":2},"a":{"a":0,"k":[30,36,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-2.76,0],[0,-2.76],[0,0]],"o":[[0,0],[0,-2.76],[2.76,0],[0,0],[0,0]],"v":[[-5,2],[-5,-1],[0,-6],[5,-1],[5,6]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.592000007629,0.592000007629,0.592000007629,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.33,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Path","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Path 4","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":0,"s":[0,132,0],"to":[0,-19.667,0],"ti":[0,19.667,0]},{"t":15,"s":[0,14,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":0,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-8,3],[0,-3],[8,3]],"c":false}]},{"t":12,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-0.753,3],[0,-3],[0.753,3]],"c":false}]}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.592000007629,0.592000007629,0.592000007629,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.33,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Path 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/LockWait.json b/LockWait.json new file mode 100644 index 0000000000..c46209d092 --- /dev/null +++ b/LockWait.json @@ -0,0 +1 @@ +{"v":"5.5.9","fr":60,"ip":0,"op":120,"w":240,"h":360,"nm":"Lock1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Path 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[120,282,0],"to":[0,-1.667,0],"ti":[0,0.833,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":45,"s":[120,272,0],"to":[0,-0.833,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":59,"s":[120,277,0],"to":[0,0,0],"ti":[0,-0.833,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":75,"s":[120,272,0],"to":[0,0.833,0],"ti":[0,-1.667,0]},{"t":120,"s":[120,282,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-8,3],[0,-3],[8,3]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.592000007629,0.592000007629,0.592000007629,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.33,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Path 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Rectangle","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[120,150,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.66,0],[0,0],[0,-1.66],[0,0],[1.66,0],[0,0],[0,1.66],[0,0]],"o":[[0,0],[1.66,0],[0,0],[0,1.66],[0,0],[-1.66,0],[0,0],[0,-1.66]],"v":[[-5,-7],[5,-7],[8,-4],[8,4],[5,7],[-5,7],[-8,4],[-8,-4]],"c":true},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.592000007629,0.592000007629,0.592000007629,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.33,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Rectangle","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.96862745098,0.96862745098,0.96862745098,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[10]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":45,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":60,"s":[5]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":75,"s":[0]},{"t":120,"s":[10]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[150,118,0],"to":[0,1.667,0],"ti":[0,-0.833,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":45,"s":[150,128,0],"to":[0,0.833,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":60,"s":[150,123,0],"to":[0,0,0],"ti":[0,0.833,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":75,"s":[150,128,0],"to":[0,-0.833,0],"ti":[0,1.667,0]},{"t":120,"s":[150,118,0]}],"ix":2},"a":{"a":0,"k":[30,36,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-2.76,0],[0,-2.76],[0,0]],"o":[[0,0],[0,-2.76],[2.76,0],[0,0],[0,0]],"v":[[-5,2],[-5,-1],[0,-6],[5,-1],[5,6]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.592000007629,0.592000007629,0.592000007629,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.33,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Path","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGModernConversationInputMicButton.h b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGModernConversationInputMicButton.h index 6b83406e04..51de64059c 100644 --- a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGModernConversationInputMicButton.h +++ b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGModernConversationInputMicButton.h @@ -2,6 +2,12 @@ @class TGModernConversationInputMicButton; +@protocol TGModernConversationInputMicButtonLock + +- (void)updateLockness:(CGFloat)lockness; + +@end + @protocol TGModernConversationInputMicButtonDecoration - (void)updateLevel:(CGFloat)level; @@ -29,11 +35,13 @@ - (void)micButtonInteractionLocked; - (void)micButtonInteractionRequestedLockedAction; - (void)micButtonInteractionStopped; +- (void)micButtonInteractionUpdateCancelTranslation:(CGFloat)translation; - (bool)micButtonShouldLock; - (id)micButtonPresenter; - (UIView *)micButtonDecoration; +- (UIView *)micButtonLock; @end diff --git a/submodules/LegacyComponents/Sources/TGModernConversationInputMicButton.m b/submodules/LegacyComponents/Sources/TGModernConversationInputMicButton.m index cf50004ae4..76869c132f 100644 --- a/submodules/LegacyComponents/Sources/TGModernConversationInputMicButton.m +++ b/submodules/LegacyComponents/Sources/TGModernConversationInputMicButton.m @@ -124,6 +124,7 @@ static const CGFloat outerCircleMinScale = innerCircleRadius / outerCircleRadius CGFloat _currentScale; CGFloat _currentTranslation; CGFloat _targetTranslation; + CGFloat _cancelTranslation; CFAbsoluteTime _animationStartTime; @@ -136,6 +137,10 @@ static const CGFloat outerCircleMinScale = innerCircleRadius / outerCircleRadius id _presentation; UIView *_decoration; + UIView *_lock; + + BOOL _xFeedbackOccured; + BOOL _yFeedbackOccured; } @end @@ -267,11 +272,11 @@ static const CGFloat outerCircleMinScale = innerCircleRadius / outerCircleRadius - (UIImage *)panelBackgroundImage { - UIGraphicsBeginImageContextWithOptions(CGSizeMake(38.0f, 38.0f), false, 0.0f); + UIGraphicsBeginImageContextWithOptions(CGSizeMake(40.0f, 40.0f), false, 0.0f); CGContextRef context = UIGraphicsGetCurrentContext(); - CGRect rect = CGRectMake(TGScreenPixel / 2.0f, TGScreenPixel / 2.0f, 38.0f - TGScreenPixel, 38.0 - TGScreenPixel); - CGFloat radius = 38.0f / 2.0f; + CGRect rect = CGRectMake(TGScreenPixel / 2.0f, TGScreenPixel / 2.0f, 40.0f - TGScreenPixel, 40.0 - TGScreenPixel); + CGFloat radius = 40.0f / 2.0f; CGFloat minx = CGRectGetMinX(rect), midx = CGRectGetMidX(rect), maxx = CGRectGetMaxX(rect); CGFloat miny = CGRectGetMinY(rect), midy = CGRectGetMidY(rect), maxy = CGRectGetMaxY(rect); @@ -298,14 +303,14 @@ static const CGFloat outerCircleMinScale = innerCircleRadius / outerCircleRadius - (UIImage *)stopButtonImage { - UIGraphicsBeginImageContextWithOptions(CGSizeMake(38.0f, 38.0f), false, 0.0f); + UIGraphicsBeginImageContextWithOptions(CGSizeMake(40.0f, 40.0f), false, 0.0f); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetFillColorWithColor(context, (self.pallete != nil ? self.pallete.backgroundColor : UIColorRGB(0xf7f7f7)).CGColor); CGContextSetStrokeColorWithColor(context, (self.pallete != nil ? self.pallete.borderColor : UIColorRGB(0xb2b2b2)).CGColor); CGContextSetLineWidth(context, TGScreenPixel); - CGRect rect1 = CGRectMake(TGScreenPixel / 2.0f, TGScreenPixel / 2.0f, 38.0f - TGScreenPixel, 38.0 - TGScreenPixel); + CGRect rect1 = CGRectMake(TGScreenPixel / 2.0f, TGScreenPixel / 2.0f, 40.0f - TGScreenPixel, 40.0 - TGScreenPixel); CGContextFillEllipseInRect(context, rect1); CGContextStrokeEllipseInRect(context, rect1); @@ -333,8 +338,10 @@ static const CGFloat outerCircleMinScale = innerCircleRadius / outerCircleRadius } - (void)animateIn { - if (!_locked) + if (!_locked) { _lockView.lockness = 0.0f; + [_lock updateLockness:0.0]; + } _animatedIn = true; _animationStartTime = CACurrentMediaTime(); @@ -358,39 +365,48 @@ static const CGFloat outerCircleMinScale = innerCircleRadius / outerCircleRadius }; } - _lockPanelWrapperView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 38.0f, 77.0f)]; - _lockPanelWrapperView.userInteractionEnabled = false; + _lockPanelWrapperView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 40.0f, 72.0f)]; [[_presentation view] addSubview:_lockPanelWrapperView]; - _lockPanelView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 38.0f, 77.0f)]; + _lockPanelView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 40.0f, 72.0f)]; + _lockPanelView.userInteractionEnabled = true; _lockPanelView.image = [self panelBackgroundImage]; + [_lockPanelWrapperView addSubview:_lockPanelView]; - _lockArrowView = [[UIImageView alloc] initWithImage:TGTintedImage(TGComponentsImageNamed(@"VideoRecordArrow"), self.pallete != nil ? self.pallete.lockColor : UIColorRGB(0x9597a0))]; - _lockArrowView.frame = CGRectMake(floor((_lockPanelView.frame.size.width - _lockArrowView.frame.size.width) / 2.0f), 54.0f, _lockArrowView.frame.size.width, _lockArrowView.frame.size.height); - [_lockPanelView addSubview:_lockArrowView]; - - _lockView = [[TGModernConversationInputLockView alloc] init]; - _lockView.color = self.pallete.lockColor; - _lockView.frame = CGRectMake(floor((_lockPanelView.frame.size.width - _lockView.frame.size.width) / 2.0f), 6.0f, _lockView.frame.size.width, _lockView.frame.size.height); - [_lockPanelView addSubview:_lockView]; + if ([_delegate respondsToSelector:@selector(micButtonLock)]) { + _lock = [_delegate micButtonLock]; + _lock.center = CGPointMake(CGRectGetMidX(_lockPanelView.bounds), CGRectGetMidY(_lockPanelView.bounds)); + [_lockPanelView addSubview:_lock]; + } else { + _lockArrowView = [[UIImageView alloc] initWithImage:TGTintedImage(TGComponentsImageNamed(@"VideoRecordArrow"), self.pallete != nil ? self.pallete.lockColor : UIColorRGB(0x9597a0))]; + _lockArrowView.frame = CGRectMake(floor((_lockPanelView.frame.size.width - _lockArrowView.frame.size.width) / 2.0f), 54.0f, _lockArrowView.frame.size.width, _lockArrowView.frame.size.height); + [_lockPanelView addSubview:_lockArrowView]; + + _lockView = [[TGModernConversationInputLockView alloc] init]; + _lockView.color = self.pallete.lockColor; + _lockView.frame = CGRectMake(floor((_lockPanelView.frame.size.width - _lockView.frame.size.width) / 2.0f), 6.0f, _lockView.frame.size.width, _lockView.frame.size.height); + [_lockPanelView addSubview:_lockView]; + } _innerCircleView = [[UIImageView alloc] initWithImage:[self innerCircleImage:self.pallete != nil ? self.pallete.buttonColor : TGAccentColor()]]; _innerCircleView.alpha = 0.0f; [[_presentation view] addSubview:_innerCircleView]; -// if ([_delegate respondsToSelector:@selector(micButtonDecoration)]) { -// UIView *decoration = [_delegate micButtonDecoration]; -// _decoration = decoration; -// [[_presentation view] addSubview:_decoration]; -// } + if ([_delegate respondsToSelector:@selector(micButtonDecoration)]) { + UIView *decoration = [_delegate micButtonDecoration]; + _decoration = decoration; + [[_presentation view] addSubview:_decoration]; + } - _outerCircleView = [[UIImageView alloc] initWithImage:[self outerCircleImage:self.pallete != nil ? self.pallete.buttonColor : TGAccentColor()]]; - _outerCircleView.alpha = 0.0f; - _outerCircleView.tag = 0x01f2bca; - [[_presentation view] addSubview:_outerCircleView]; - - [_outerCircleView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(outerCircleTapGesture:)]]; + if (_decoration == nil) { + _outerCircleView = [[UIImageView alloc] initWithImage:[self outerCircleImage:self.pallete != nil ? self.pallete.buttonColor : TGAccentColor()]]; + _outerCircleView.alpha = 0.0f; + _outerCircleView.tag = 0x01f2bca; + [[_presentation view] addSubview:_outerCircleView]; + + [_outerCircleView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(outerCircleTapGesture:)]]; + } _innerIconView = [[UIImageView alloc] initWithImage:_icon]; @@ -401,15 +417,17 @@ static const CGFloat outerCircleMinScale = innerCircleRadius / outerCircleRadius [[_presentation view] addSubview:_innerIconWrapperView]; - _stopButton = [[TGModernButton alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 38.0f, 38.0f)]; - _stopButton.accessibilityLabel = TGLocalized(@"VoiceOver.Recording.StopAndPreview"); - _stopButton.adjustsImageWhenHighlighted = false; - _stopButton.exclusiveTouch = true; - [_stopButton setImage:[self stopButtonImage] forState:UIControlStateNormal]; - _stopButton.userInteractionEnabled = false; - _stopButton.alpha = 0.0f; - [_stopButton addTarget:self action:@selector(stopPressed) forControlEvents:UIControlEventTouchUpInside]; - [[_presentation view] addSubview:_stopButton]; + if (_lock == nil) { + _stopButton = [[TGModernButton alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 40.0f, 40.0f)]; + _stopButton.accessibilityLabel = TGLocalized(@"VoiceOver.Recording.StopAndPreview"); + _stopButton.adjustsImageWhenHighlighted = false; + _stopButton.exclusiveTouch = true; + [_stopButton setImage:[self stopButtonImage] forState:UIControlStateNormal]; + _stopButton.userInteractionEnabled = false; + _stopButton.alpha = 0.0f; + [_stopButton addTarget:self action:@selector(stopPressed) forControlEvents:UIControlEventTouchUpInside]; + [[_presentation view] addSubview:_stopButton]; + } } [_presentation setUserInteractionEnabled:_blocking]; @@ -505,6 +523,11 @@ static const CGFloat outerCircleMinScale = innerCircleRadius / outerCircleRadius if (finished || [[[LegacyComponentsGlobals provider] applicationInstance] applicationState] == UIApplicationStateBackground) { [_presentation dismiss]; _presentation = nil; + + _cancelTranslation = 0; + id delegate = _delegate; + if ([delegate respondsToSelector:@selector(micButtonInteractionUpdateCancelTranslation:)]) + [delegate micButtonInteractionUpdateCancelTranslation:-_cancelTranslation]; } if (_previousIcon != nil) @@ -521,6 +544,7 @@ static const CGFloat outerCircleMinScale = innerCircleRadius / outerCircleRadius - (void)animateLock { _lockView.lockness = 1.0f; + [_lock updateLockness:1.0]; UIView *snapshotView = [_innerIconView snapshotViewAfterScreenUpdates:false]; snapshotView.frame = _innerIconView.frame; @@ -544,26 +568,29 @@ static const CGFloat outerCircleMinScale = innerCircleRadius / outerCircleRadius snapshotView.alpha = 0.0f; _innerIconView.alpha = 1.0f; - _lockPanelView.frame = CGRectMake(_lockPanelView.frame.origin.x, 39.0f, _lockPanelView.frame.size.width, 77.0f - 39.0f); + _lockPanelView.frame = CGRectMake(_lockPanelView.frame.origin.x, 40.0f, _lockPanelView.frame.size.width, 72.0f - 32.0f); _lockView.transform = CGAffineTransformMakeTranslation(0.0f, -11.0f); + _lock.transform = CGAffineTransformMakeTranslation(0.0f, -16.0f); _lockArrowView.transform = CGAffineTransformMakeTranslation(0.0f, -39.0f); _lockArrowView.alpha = 0.0f; }]; - - TGDispatchAfter(0.45, dispatch_get_main_queue(), ^ - { - [UIView animateWithDuration:0.2 delay:0.0 options:7 << 16 animations:^ + + if (_lock == nil) { + TGDispatchAfter(0.45, dispatch_get_main_queue(), ^ { - _lockPanelWrapperView.transform = CGAffineTransformMakeTranslation(0.0f, 120.0f); - } completion:^(__unused BOOL finished) - { - _lockPanelWrapperView.alpha = 0.0f; - _lockPanelView.frame = CGRectMake(_lockPanelView.frame.origin.x, 0.0f, _lockPanelView.frame.size.width, 77.0f); - _lockView.transform = CGAffineTransformIdentity; - _lockArrowView.transform = CGAffineTransformIdentity; - _lockArrowView.alpha = 1.0f; - }]; - }); + [UIView animateWithDuration:0.2 delay:0.0 options:7 << 16 animations:^ + { + _lockPanelWrapperView.transform = CGAffineTransformMakeTranslation(0.0f, 120.0f); + } completion:^(__unused BOOL finished) + { + _lockPanelWrapperView.alpha = 0.0f; + _lockPanelView.frame = CGRectMake(_lockPanelView.frame.origin.x, 0.0f, _lockPanelView.frame.size.width, 72.0f); + _lockView.transform = CGAffineTransformIdentity; + _lockArrowView.transform = CGAffineTransformIdentity; + _lockArrowView.alpha = 1.0f; + }]; + }); + } _stopButton.userInteractionEnabled = true; [UIView animateWithDuration:0.25 delay:0.56 options:kNilOptions animations:^ @@ -661,27 +688,31 @@ static const CGFloat outerCircleMinScale = innerCircleRadius / outerCircleRadius if (CACurrentMediaTime() > _animationStartTime + 0.50) { CGFloat scale = MAX(0.4f, MIN(1.0f, 1.0f - value.x)); - if (scale > 0.8f) { - scale = 1.0f; - } else { - scale /= 0.8f; - } _currentScale = scale; _targetTranslation = distanceY; + _cancelTranslation = distanceX; CGFloat targetLockness = _locked ? 1.0f : MIN(1.0f, fabs(_targetTranslation) / 105.0f); + [_lock updateLockness:targetLockness]; _lockView.lockness = targetLockness; _lockView.transform = CGAffineTransformMakeTranslation(0.0f, -11.0f * targetLockness); + _lock.transform = CGAffineTransformMakeTranslation(0.0f, -16.0f * targetLockness); - _lockPanelView.frame = CGRectMake(_lockPanelView.frame.origin.x, 39.0f * targetLockness, _lockPanelView.frame.size.width, 77.0f - 39.0f * targetLockness); + _lockPanelView.frame = CGRectMake(_lockPanelView.frame.origin.x, + 40.0f * targetLockness, + _lockPanelView.frame.size.width, + 72.0f - 32.0f * targetLockness); _lockArrowView.alpha = MAX(0.0f, 1.0f - targetLockness * 1.6f); _lockArrowView.transform = CGAffineTransformMakeTranslation(0.0f, -39.0f * targetLockness); } - if (distanceX < -100.0f) - { + id delegate = _delegate; + if ([delegate respondsToSelector:@selector(micButtonInteractionUpdateCancelTranslation:)]) + [delegate micButtonInteractionUpdateCancelTranslation:-_cancelTranslation]; + + if (distanceX < -150.0f) { id delegate = _delegate; if ([delegate respondsToSelector:@selector(micButtonInteractionCancelled:)]) [delegate micButtonInteractionCancelled:velocity]; @@ -689,16 +720,30 @@ static const CGFloat outerCircleMinScale = innerCircleRadius / outerCircleRadius _targetTranslation = 0.0f; return false; + } else if (distanceX < -100.0 && !_xFeedbackOccured) { + if (iosMajorVersion() >= 10) { + UIImpactFeedbackGenerator *generator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleMedium]; + [generator impactOccurred]; + } + _xFeedbackOccured = true; + } else if (distanceX > -100.0) { + _xFeedbackOccured = false; } - if (distanceY < -110.0f) - { + if (distanceY < -110.0f) { [self _commitLocked]; - + return false; + } else if (distanceY < -60.0 && !_yFeedbackOccured) { + if (iosMajorVersion() >= 10) { + UIImpactFeedbackGenerator *generator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleMedium]; + [generator impactOccurred]; + } + _yFeedbackOccured = true; + } else if (distanceY > -60.0) { + _yFeedbackOccured = false; } - id delegate = _delegate; if ([delegate respondsToSelector:@selector(micButtonInteractionUpdate:)]) [delegate micButtonInteractionUpdate:value]; @@ -722,6 +767,9 @@ static const CGFloat outerCircleMinScale = innerCircleRadius / outerCircleRadius } [super cancelTrackingWithEvent:event]; + + _yFeedbackOccured = false; + _xFeedbackOccured = false; } - (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event @@ -730,14 +778,22 @@ static const CGFloat outerCircleMinScale = innerCircleRadius / outerCircleRadius { _targetTranslation = 0.0f; + CGFloat distanceX = MIN(0.0f, [touch locationInView:self].x - _touchLocation.x); + CGFloat distanceY = MIN(0.0f, [touch locationInView:self].y - _touchLocation.y); + + if (fabs(distanceX) > fabs(distanceY)) + distanceY = 0.0f; + else + distanceX = 0.0f; + CGPoint velocity = _lastVelocity; id delegate = _delegate; - if (velocity.x < -400.0f) + if (velocity.x < -400.0f || distanceX < -100.0) { if ([delegate respondsToSelector:@selector(micButtonInteractionCancelled:)]) [delegate micButtonInteractionCancelled:_lastVelocity]; } - else if (velocity.y < -400.0f) + else if (velocity.y < -400.0f || distanceY < -60) { [self _commitLocked]; } @@ -748,6 +804,9 @@ static const CGFloat outerCircleMinScale = innerCircleRadius / outerCircleRadius } [super endTrackingWithTouch:touch withEvent:event]; + + _yFeedbackOccured = false; + _yFeedbackOccured = false; } - (void)_commitLocked @@ -788,18 +847,20 @@ static const CGFloat outerCircleMinScale = innerCircleRadius / outerCircleRadius _currentTranslation = MIN(0.0, _currentTranslation * 0.7f + _targetTranslation * 0.3f); CGFloat outerScale = outerCircleMinScale + _currentLevel * (1.0f - outerCircleMinScale); - CGAffineTransform translation = CGAffineTransformMakeTranslation(0.0f, _currentTranslation); + CGAffineTransform translation = CGAffineTransformMakeTranslation(0, _currentTranslation); CGAffineTransform transform = CGAffineTransformScale(translation, outerScale, outerScale); _outerCircleView.transform = transform; - - _innerIconWrapperView.transform = translation; if (_lockPanelWrapperView.layer.animationKeys.count == 0) _lockPanelWrapperView.transform = translation; transform = CGAffineTransformScale(translation, _currentScale, _currentScale); + transform = CGAffineTransformTranslate(transform, _cancelTranslation, 0); + _innerCircleView.transform = transform; + _innerIconWrapperView.transform = transform; + _decoration.transform = transform; [_decoration tick:_currentLevel]; } @@ -825,7 +886,7 @@ static const CGFloat outerCircleMinScale = innerCircleRadius / outerCircleRadius - (instancetype)initWithFrame:(CGRect)frame { - self = [super initWithFrame:CGRectMake(frame.origin.x, frame.origin.y, 38.0f, 38.0f)]; + self = [super initWithFrame:CGRectMake(frame.origin.x, frame.origin.y, 40.0f, 40.0f)]; if (self != nil) { self.backgroundColor = [UIColor clearColor]; diff --git a/submodules/TelegramUI/Resources/Animations/Lock.json b/submodules/TelegramUI/Resources/Animations/Lock.json new file mode 100644 index 0000000000..f56c2c101f --- /dev/null +++ b/submodules/TelegramUI/Resources/Animations/Lock.json @@ -0,0 +1 @@ +{"v":"5.5.9","fr":60,"ip":0,"op":30,"w":240,"h":360,"nm":"Lock2","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Path","parent":2,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[100]},{"t":25,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":15,"s":[100,100,100]},{"t":25,"s":[0,0,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.29,0],[0,0],[0,-1.29],[0,0],[1.28,0],[0,0],[0,1.28],[0,0]],"o":[[0,0],[1.28,0],[0,0],[0,1.28],[0,0],[-1.29,0],[0,0],[0,-1.29]],"v":[[-4.995,-6.335],[5.005,-6.335],[7.335,-3.995],[7.335,4.005],[5.005,6.335],[-4.995,6.335],[-7.335,4.005],[-7.335,-3.995]],"c":true},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.968627510819,0.968627510819,0.968627510819,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Path","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Rectangle","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[0]},{"t":25,"s":[90]}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[120]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[120]},{"t":25,"s":[120]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[150]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":15,"s":[200]},{"t":25,"s":[180]}],"ix":4}},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":15,"s":[{"i":[[-1.66,0],[0,0],[0,-1.66],[0,0],[1.66,0],[0,0],[0,1.66],[0,0]],"o":[[0,0],[1.66,0],[0,0],[0,1.66],[0,0],[-1.66,0],[0,0],[0,-1.66]],"v":[[-5,-7],[5,-7],[8,-4],[8,4],[5,7],[-5,7],[-8,4],[-8,-4]],"c":true}]},{"t":25,"s":[{"i":[[-1.66,0],[0,0],[0,-1.66],[0,0],[1.66,0],[0,0],[0,1.66],[0,0]],"o":[[0,0],[1.66,0],[0,0],[0,1.66],[0,0],[-1.66,0],[0,0],[0,-1.66]],"v":[[-5,-8],[5,-8],[8,-5],[8,5],[5,8],[-5,8],[-8,5],[-8,-5]],"c":true}]}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.592000007629,0.592000007629,0.592000007629,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.33,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Rectangle","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.592156862745,0.592156862745,0.592156862745,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":30,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Path","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[10]},{"t":15,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":0,"s":[30,-32,0],"to":[0,2.5,0],"ti":[0,-11.667,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":15,"s":[30,-17,0],"to":[0,11.667,0],"ti":[0,-9.167,0]},{"t":25,"s":[30,38,0]}],"ix":2},"a":{"a":0,"k":[30,36,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-2.76,0],[0,-2.76],[0,0]],"o":[[0,0],[0,-2.76],[2.76,0],[0,0],[0,0]],"v":[[-5,2],[-5,-1],[0,-6],[5,-1],[5,6]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.592000007629,0.592000007629,0.592000007629,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.33,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Path","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Path 4","parent":2,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":0,"s":[0,132,0],"to":[0,-19.667,0],"ti":[0,19.667,0]},{"t":15,"s":[0,14,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":0,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-8,3],[0,-3],[8,3]],"c":false}]},{"t":12,"s":[{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-0.753,3],[0,-3],[0.753,3]],"c":false}]}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.592000007629,0.592000007629,0.592000007629,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.33,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Path 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":30,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/submodules/TelegramUI/Resources/Animations/LockWait.json b/submodules/TelegramUI/Resources/Animations/LockWait.json new file mode 100644 index 0000000000..c46209d092 --- /dev/null +++ b/submodules/TelegramUI/Resources/Animations/LockWait.json @@ -0,0 +1 @@ +{"v":"5.5.9","fr":60,"ip":0,"op":120,"w":240,"h":360,"nm":"Lock1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Path 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[120,282,0],"to":[0,-1.667,0],"ti":[0,0.833,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":45,"s":[120,272,0],"to":[0,-0.833,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":59,"s":[120,277,0],"to":[0,0,0],"ti":[0,-0.833,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":75,"s":[120,272,0],"to":[0,0.833,0],"ti":[0,-1.667,0]},{"t":120,"s":[120,282,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0]],"v":[[-8,3],[0,-3],[8,3]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.592000007629,0.592000007629,0.592000007629,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.33,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Path 4","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Rectangle","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[120,150,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.66,0],[0,0],[0,-1.66],[0,0],[1.66,0],[0,0],[0,1.66],[0,0]],"o":[[0,0],[1.66,0],[0,0],[0,1.66],[0,0],[-1.66,0],[0,0],[0,-1.66]],"v":[[-5,-7],[5,-7],[8,-4],[8,4],[5,7],[-5,7],[-8,4],[-8,-4]],"c":true},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.592000007629,0.592000007629,0.592000007629,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.33,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Rectangle","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.96862745098,0.96862745098,0.96862745098,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[10]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":45,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":60,"s":[5]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":75,"s":[0]},{"t":120,"s":[10]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[150,118,0],"to":[0,1.667,0],"ti":[0,-0.833,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":45,"s":[150,128,0],"to":[0,0.833,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":60,"s":[150,123,0],"to":[0,0,0],"ti":[0,0.833,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":75,"s":[150,128,0],"to":[0,-0.833,0],"ti":[0,1.667,0]},{"t":120,"s":[150,118,0]}],"ix":2},"a":{"a":0,"k":[30,36,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-2.76,0],[0,-2.76],[0,0]],"o":[[0,0],[0,-2.76],[2.76,0],[0,0],[0,0]],"v":[[-5,2],[-5,-1],[0,-6],[5,-1],[5,6]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.592000007629,0.592000007629,0.592000007629,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.33,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Path","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/submodules/TelegramUI/Resources/Animations/voicebin.json b/submodules/TelegramUI/Resources/Animations/voicebin.json new file mode 100644 index 0000000000..baf0e38c66 --- /dev/null +++ b/submodules/TelegramUI/Resources/Animations/voicebin.json @@ -0,0 +1 @@ +{"v":"5.5.9","fr":60,"ip":0,"op":78,"w":240,"h":240,"nm":"RedBin 2","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Cap1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0],"y":[0]},"o":{"x":[0.333],"y":[0]},"t":42,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[1],"y":[1]},"t":52,"s":[10]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":62,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[1],"y":[0]},"t":68,"s":[-5]},{"t":77,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":22,"s":[120,18,0],"to":[0,11.667,0],"ti":[0,-6.667,0]},{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":42,"s":[120,88,0],"to":[0,6.667,0],"ti":[0,0.833,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":52,"s":[120,58,0],"to":[0,-0.833,0],"ti":[0,-1.667,0]},{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":62,"s":[120,83,0],"to":[0,1.667,0],"ti":[0,0.833,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":68,"s":[120,68,0],"to":[0,-0.833,0],"ti":[0,-1.667,0]},{"t":77,"s":[120,78,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-8.5,0],[8.5,0]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.231372563979,0.188235309077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.33,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Cap1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":27,"s":[50]},{"t":32,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":27,"s":[50]},{"t":32,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Обрезать контуры 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":78,"st":-188,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Cap2","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,-12,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.83,0],[0,0],[0,-0.83],[0,0],[0,0]],"o":[[0,0],[0,-0.83],[0,0],[0.83,0],[0,0],[0,0],[0,0]],"v":[[-3.5,1.5],[-3.5,0],[-2,-1.5],[2,-1.5],[3.5,0],[3.5,1.5],[3.5,1.5]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.231372563979,0.188235309077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.33,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Cap2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":27,"s":[50]},{"t":32,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":27,"s":[50]},{"t":32,"s":[0]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Обрезать контуры 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":78,"st":-188,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Line3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[139.5,129,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":32,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0.25,-5.5],[-0.25,5.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":42,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0.667,-3.833],[0.167,5.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":52,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0.25,-5.5],[-0.25,5.5]],"c":false}]},{"i":{"x":0.833,"y":1},"o":{"x":0.333,"y":0},"t":59,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0.25,-5.5],[-0.25,5.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"t":62,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0.458,-5.083],[-0.042,5.5]],"c":false}]},{"t":68,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0.25,-5.5],[-0.25,5.5]],"c":false}]}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.231372563979,0.188235309077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.2,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Line3","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":26,"s":[0]},{"t":29,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Обрезать контуры 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.231372563979,0.188235309077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":78,"st":-188,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Line2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[120,129,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":32,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,-5.5],[0,5.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":42,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,-3.833],[0,5.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":52,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,-5.5],[0,5.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":59,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,-5.5],[0,5.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":62,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,-5.083],[0,5.5]],"c":false}]},{"t":68,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,-5.5],[0,5.5]],"c":false}]}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.231372563979,0.188235309077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.2,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Line2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Обрезать контуры 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":26,"s":[0]},{"t":29,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Обрезать контуры 2","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":78,"st":-188,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Line1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[100.5,129,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":32,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.25,-5.5],[0.25,5.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":42,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.667,-3.833],[-0.167,5.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":52,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.25,-5.5],[0.25,5.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":59,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.25,-5.5],[0.25,5.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":62,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.458,-5.083],[0.042,5.5]],"c":false}]},{"t":68,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.25,-5.5],[0.25,5.5]],"c":false}]}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.231372563979,0.188235309077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.2,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Line1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":26,"s":[0]},{"t":29,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Обрезать контуры 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":78,"st":-188,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Bin","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[120,120,0],"ix":2},"a":{"a":0,"k":[0,-9,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":32,"s":[{"i":[[0,0],[0,0],[-1.06,0],[0,0],[-0.06,1.05],[0,0]],"o":[[0,0],[0.06,1.05],[0,0],[1.06,0],[0,0],[0,0]],"v":[[-7,-8.5],[-6.11,6.62],[-4.11,8.5],[4.11,8.5],[6.11,6.62],[7,-8.5]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":42,"s":[{"i":[[0,0],[0,0],[-1.06,0],[0,0],[-0.06,1.05],[0,0]],"o":[[0,0],[0.06,1.05],[0,0],[1.06,0],[0,0],[0,0]],"v":[[-7.833,-6.833],[-6.943,6.62],[-4.943,8.5],[4.943,8.5],[6.943,6.62],[7.833,-6.833]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":52,"s":[{"i":[[0,0],[0,0],[-1.06,0],[0,0],[-0.06,1.05],[0,0]],"o":[[0,0],[0.06,1.05],[0,0],[1.06,0],[0,0],[0,0]],"v":[[-7,-8.5],[-6.11,6.62],[-4.11,8.5],[4.11,8.5],[6.11,6.62],[7,-8.5]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":59,"s":[{"i":[[0,0],[0,0],[-1.06,0],[0,0],[-0.06,1.05],[0,0]],"o":[[0,0],[0.06,1.05],[0,0],[1.06,0],[0,0],[0,0]],"v":[[-7,-8.5],[-6.11,6.62],[-4.11,8.5],[4.11,8.5],[6.11,6.62],[7,-8.5]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":62,"s":[{"i":[[0,0],[0,0],[-1.06,0],[0,0],[-0.06,1.05],[0,0]],"o":[[0,0],[0.06,1.05],[0,0],[1.06,0],[0,0],[0,0]],"v":[[-7.417,-7.667],[-6.527,6.62],[-4.527,8.5],[4.527,8.5],[6.527,6.62],[7.417,-7.667]],"c":true}]},{"t":68,"s":[{"i":[[0,0],[0,0],[-1.06,0],[0,0],[-0.06,1.05],[0,0]],"o":[[0,0],[0.06,1.05],[0,0],[1.06,0],[0,0],[0,0]],"v":[[-7,-8.5],[-6.11,6.62],[-4.11,8.5],[4.11,8.5],[6.11,6.62],[7,-8.5]],"c":true}]}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.231372563979,0.188235309077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.33,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Bin","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":22,"s":[50]},{"t":42,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":22,"s":[50]},{"t":42,"s":[100]}],"ix":2},"o":{"a":0,"k":137,"ix":3},"m":1,"ix":2,"nm":"Обрезать контуры 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":78,"st":-188,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"RecMask 2","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[120,120,0],"to":[0,-15,0],"ti":[0,13.667,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":15,"s":[120,30,0],"to":[0,-13.667,0],"ti":[0,-1.333,0]},{"t":24,"s":[120,38,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,84.375,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[8.5,-8],[8.5,8],[-8.5,8],[-8.5,-8]],"c":true},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.96862745098,0.96862745098,0.96862745098,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Mask","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":78,"st":-190,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Recording","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[120,120,0],"to":[0,-15,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":15,"s":[120,30,0],"to":[0,0,0],"ti":[0,-15,0]},{"t":30,"s":[120,120,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.76,0],[0,2.76],[2.76,0],[0,-2.76]],"o":[[2.76,0],[0,-2.76],[-2.76,0],[0,2.76]],"v":[[0,5],[5,0],[0,-5],[-5,0]],"c":true},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.231372997165,0.188234999776,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Recording","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":40,"st":-180,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 8511d3895f..9060908960 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -7231,6 +7231,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G switch updatedAction { case .dismiss: + self.chatDisplayNode.updateRecordedMediaDeleted(true) break case .preview: let _ = (audioRecorderValue.takenRecordedData() |> deliverOnMainQueue).start(next: { [weak self] data in @@ -7251,6 +7252,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } }) case .send: + self.chatDisplayNode.updateRecordedMediaDeleted(false) let _ = (audioRecorderValue.takenRecordedData() |> deliverOnMainQueue).start(next: { [weak self] data in if let strongSelf = self, let data = data { diff --git a/submodules/TelegramUI/Sources/ChatControllerNode.swift b/submodules/TelegramUI/Sources/ChatControllerNode.swift index b52d8e1828..79185247c8 100644 --- a/submodules/TelegramUI/Sources/ChatControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatControllerNode.swift @@ -1772,6 +1772,10 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { return self.textInputPanelNode?.textInputNode } + func updateRecordedMediaDeleted(_ isDeleted: Bool) { + self.textInputPanelNode?.isMediaDeleted = isDeleted + } + func frameForVisibleArea() -> CGRect { let rect = CGRect(origin: CGPoint(x: self.visibleAreaInset.left, y: self.visibleAreaInset.top), size: CGSize(width: self.bounds.size.width - self.visibleAreaInset.left - self.visibleAreaInset.right, height: self.bounds.size.height - self.visibleAreaInset.top - self.visibleAreaInset.bottom)) if let containerNode = self.containerNode { diff --git a/submodules/TelegramUI/Sources/ChatTextInputMediaRecordingButton.swift b/submodules/TelegramUI/Sources/ChatTextInputMediaRecordingButton.swift index a56f0291a4..354a2ad6d3 100644 --- a/submodules/TelegramUI/Sources/ChatTextInputMediaRecordingButton.swift +++ b/submodules/TelegramUI/Sources/ChatTextInputMediaRecordingButton.swift @@ -166,6 +166,7 @@ final class ChatTextInputMediaRecordingButton: TGModernConversationInputMicButto var offsetRecordingControls: () -> Void = { } var switchMode: () -> Void = { } var updateLocked: (Bool) -> Void = { _ in } + var updateCancelTranslation: () -> Void = { } private var modeTimeoutTimer: SwiftSignalKit.Timer? @@ -174,6 +175,7 @@ final class ChatTextInputMediaRecordingButton: TGModernConversationInputMicButto private var recordingOverlay: ChatTextInputAudioRecordingOverlay? private var startTouchLocation: CGPoint? private(set) var controlsOffset: CGFloat = 0.0 + private(set) var cancelTranslation: CGFloat = 0.0 private var micLevelDisposable: MetaDisposable? @@ -368,6 +370,11 @@ final class ChatTextInputMediaRecordingButton: TGModernConversationInputMicButto self.offsetRecordingControls() } + func micButtonInteractionUpdateCancelTranslation(_ translation: CGFloat) { + self.cancelTranslation = translation + self.updateCancelTranslation() + } + func micButtonInteractionLocked() { self.updateLocked(true) } @@ -391,6 +398,30 @@ final class ChatTextInputMediaRecordingButton: TGModernConversationInputMicButto return CombinedWaveView(frame: CGRect(origin: CGPoint(), size: CGSize(width: 640.0, height: 640.0)), color: self.theme.chat.inputPanel.actionControlFillColor) } + func micButtonLock() -> (UIView & TGModernConversationInputMicButtonLock)! { + let lockView = LockView(frame: CGRect(origin: CGPoint(), size: CGSize(width: 40.0, height: 60.0)), theme: self.theme) + lockView.addTarget(self, action: #selector(handleStopTap), for: .touchUpInside) + return lockView + } + + @objc private func handleStopTap() { + micButtonInteractionStopped() + } + + override func animateIn() { + super.animateIn() + + innerIconView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, removeOnCompletion: false) + innerIconView.layer.animateScale(from: 1.0, to: 0.3, duration: 0.15, removeOnCompletion: false) + } + + override func animateOut() { + super.animateOut() + + innerIconView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15, removeOnCompletion: false) + innerIconView.layer.animateScale(from: 0.3, to: 1.0, duration: 0.15, removeOnCompletion: false) + } + private var previousSize = CGSize() func layoutItems() { let size = self.bounds.size diff --git a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift index 90e8b9993b..0373abee7a 100644 --- a/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/ChatTextInputPanelNode.swift @@ -13,6 +13,7 @@ import AccountContext import TouchDownGesture import ImageTransparency import ActivityIndicator +import AnimationUI private let accessoryButtonFont = Font.medium(14.0) @@ -210,7 +211,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { private let searchLayoutClearImageNode: ASImageNode private var searchActivityIndicator: ActivityIndicator? var audioRecordingInfoContainerNode: ASDisplayNode? - var audioRecordingDotNode: ASImageNode? + var audioRecordingDotNode: AnimationNode? var audioRecordingTimeNode: ChatTextInputAudioRecordingTimeNode? var audioRecordingCancelIndicator: ChatTextInputAudioRecordingCancelIndicator? @@ -235,6 +236,8 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { private var keepSendButtonEnabled = false private var extendedSearchLayout = false + var isMediaDeleted: Bool = false + private let inputMenu = ChatTextInputMenu() private var theme: PresentationTheme? @@ -445,6 +448,13 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { } } } + self.actionButtons.micButton.updateCancelTranslation = { [weak self] in + if let strongSelf = self, let presentationInterfaceState = strongSelf.presentationInterfaceState { + if let (width, leftInset, rightInset, maxHeight, metrics, isSecondary) = strongSelf.validLayout { + let _ = strongSelf.updateLayout(width: width, leftInset: leftInset, rightInset: rightInset, maxHeight: maxHeight, isSecondary: isSecondary, transition: .immediate, interfaceState: presentationInterfaceState, metrics: metrics) + } + } + } self.actionButtons.micButton.stopRecording = { [weak self] in if let strongSelf = self, let interfaceInteraction = strongSelf.interfaceInteraction { interfaceInteraction.stopMediaRecording() @@ -744,10 +754,6 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { self.searchLayoutClearImageNode.image = PresentationResourcesChat.chatInputTextFieldClearImage(interfaceState.theme) - if let audioRecordingDotNode = self.audioRecordingDotNode { - audioRecordingDotNode.image = PresentationResourcesChat.chatInputPanelMediaRecordingDotImage(interfaceState.theme) - } - self.audioRecordingTimeNode?.updateTheme(theme: interfaceState.theme) self.audioRecordingCancelIndicator?.updateTheme(theme: interfaceState.theme) @@ -899,9 +905,9 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { self.actionButtons.micButton.updateMode(mode: interfaceState.interfaceState.mediaRecordingMode, animated: transition.isAnimated) var hideMicButton = false - var audioRecordingItemsVerticalOffset: CGFloat = 0.0 + var audioRecordingItemsAlpha: CGFloat = 1 if let mediaRecordingState = interfaceState.inputTextPanelState.mediaRecordingState { - audioRecordingItemsVerticalOffset = panelHeight * 2.0 + audioRecordingItemsAlpha = 0 transition.updateAlpha(layer: self.textInputBackgroundNode.layer, alpha: 0.0) if let textInputNode = self.textInputNode { transition.updateAlpha(node: textInputNode, alpha: 0.0) @@ -936,7 +942,19 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { self.insertSubnode(audioRecordingCancelIndicator, at: 0) } - audioRecordingCancelIndicator.frame = CGRect(origin: CGPoint(x: leftInset + floor((baseWidth - audioRecordingCancelIndicator.bounds.size.width) / 2.0) - self.actionButtons.micButton.controlsOffset, y: panelHeight - minimalHeight + floor((minimalHeight - audioRecordingCancelIndicator.bounds.size.height) / 2.0)), size: audioRecordingCancelIndicator.bounds.size) + let cancelTransformThreshold: CGFloat = 8.0 + + let indicatorTranslation = max(0.0, self.actionButtons.micButton.cancelTranslation - cancelTransformThreshold) + + audioRecordingCancelIndicator.frame = CGRect( + origin: CGPoint( + x: leftInset + floor((baseWidth - audioRecordingCancelIndicator.bounds.size.width - indicatorTranslation) / 2.0), + y: panelHeight - minimalHeight + floor((minimalHeight - audioRecordingCancelIndicator.bounds.size.height) / 2.0)), + size: audioRecordingCancelIndicator.bounds.size) + if self.actionButtons.micButton.cancelTranslation > cancelTransformThreshold { + let progress = 1 - (self.actionButtons.micButton.cancelTranslation - cancelTransformThreshold) / 80 + audioRecordingCancelIndicator.alpha = progress + } if animateCancelSlideIn { let position = audioRecordingCancelIndicator.layer.position @@ -945,6 +963,18 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { audioRecordingCancelIndicator.updateIsDisplayingCancel(isLocked, animated: !animateCancelSlideIn) + if isLocked || self.actionButtons.micButton.cancelTranslation > cancelTransformThreshold { + audioRecordingCancelIndicator.layer.removeAnimation(forKey: "slide_juggle") + } else if audioRecordingCancelIndicator.layer.animation(forKey: "slide_juggle") == nil { + let slideJuggleAnimation = CABasicAnimation(keyPath: "transform") + slideJuggleAnimation.toValue = CATransform3DMakeTranslation(-6, 0, 0) + slideJuggleAnimation.duration = 1 + slideJuggleAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) + slideJuggleAnimation.autoreverses = true + slideJuggleAnimation.repeatCount = Float.infinity + audioRecordingCancelIndicator.layer.add(slideJuggleAnimation, forKey: "slide_juggle") + } + var animateTimeSlideIn = false let audioRecordingTimeNode: ChatTextInputAudioRecordingTimeNode if let currentAudioRecordingTimeNode = self.audioRecordingTimeNode { @@ -961,32 +991,41 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { let audioRecordingTimeSize = audioRecordingTimeNode.measure(CGSize(width: 200.0, height: 100.0)) - audioRecordingInfoContainerNode.frame = CGRect(origin: CGPoint(x: min(leftInset, audioRecordingCancelIndicator.frame.minX - audioRecordingTimeSize.width - 8.0 - 28.0), y: 0.0), size: CGSize(width: baseWidth, height: panelHeight)) + let cancelMinX = audioRecordingCancelIndicator.alpha > 0.5 ? audioRecordingCancelIndicator.frame.minX : width - audioRecordingTimeNode.frame = CGRect(origin: CGPoint(x: 28.0, y: panelHeight - minimalHeight + floor((minimalHeight - audioRecordingTimeSize.height) / 2.0)), size: audioRecordingTimeSize) + audioRecordingInfoContainerNode.frame = CGRect( + origin: CGPoint( + x: min(leftInset, cancelMinX - audioRecordingTimeSize.width - 8.0 - 28.0), + y: 0.0 + ), + size: CGSize(width: baseWidth, height: panelHeight) + ) + + audioRecordingTimeNode.frame = CGRect(origin: CGPoint(x: 40.0, y: panelHeight - minimalHeight + floor((minimalHeight - audioRecordingTimeSize.height) / 2.0)), size: audioRecordingTimeSize) if animateTimeSlideIn { let position = audioRecordingTimeNode.layer.position - audioRecordingTimeNode.layer.animatePosition(from: CGPoint(x: position.x - 28.0 - audioRecordingTimeSize.width, y: position.y), to: position, duration: 0.5, timingFunction: kCAMediaTimingFunctionSpring) + audioRecordingTimeNode.layer.animatePosition(from: CGPoint(x: position.x - 10.0, y: position.y), to: position, duration: 0.5, timingFunction: kCAMediaTimingFunctionSpring) + audioRecordingTimeNode.layer.animateAlpha(from: 0, to: 1, duration: 0.5, timingFunction: kCAMediaTimingFunctionSpring) } audioRecordingTimeNode.audioRecorder = recorder - var animateDotSlideIn = false - let audioRecordingDotNode: ASImageNode + var animateDotAppearing = false + let audioRecordingDotNode: AnimationNode if let currentAudioRecordingDotNode = self.audioRecordingDotNode { audioRecordingDotNode = currentAudioRecordingDotNode } else { - animateDotSlideIn = transition.isAnimated - - audioRecordingDotNode = ASImageNode() - audioRecordingDotNode.image = PresentationResourcesChat.chatInputPanelMediaRecordingDotImage(interfaceState.theme) + audioRecordingDotNode = AnimationNode(animation: "voicebin") + audioRecordingDotNode.speed = 2.0 self.audioRecordingDotNode = audioRecordingDotNode - audioRecordingInfoContainerNode.addSubnode(audioRecordingDotNode) + self.addSubnode(audioRecordingDotNode) } - audioRecordingDotNode.frame = CGRect(origin: CGPoint(x: audioRecordingTimeNode.frame.minX - 17.0, y: panelHeight - minimalHeight + floor((minimalHeight - 9.0) / 2.0)), size: CGSize(width: 9.0, height: 9.0)) - if animateDotSlideIn { - let position = audioRecordingDotNode.layer.position - audioRecordingDotNode.layer.animatePosition(from: CGPoint(x: position.x - 9.0 - 51.0, y: position.y), to: position, duration: 0.7, timingFunction: kCAMediaTimingFunctionSpring, completion: { [weak audioRecordingDotNode] finished in + + animateDotAppearing = transition.isAnimated + + audioRecordingDotNode.frame = CGRect(origin: CGPoint(x: leftInset + 2.0 - UIScreenPixel, y: panelHeight - 44), size: CGSize(width: 40.0, height: 40)) + if animateDotAppearing { + audioRecordingDotNode.layer.animateAlpha(from: 0, to: 1, duration: 0.25, delay: 0, timingFunction: kCAMediaTimingFunctionSpring, completion: { [weak audioRecordingDotNode] finished in if finished { let animation = CAKeyframeAnimation(keyPath: "opacity") animation.values = [1.0 as NSNumber, 1.0 as NSNumber, 0.0 as NSNumber] @@ -998,6 +1037,9 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { audioRecordingDotNode?.layer.add(animation, forKey: "recording") } }) + + self.attachmentButton.layer.animateAlpha(from: 1, to: 0, duration: 0.15, delay: 0, removeOnCompletion: false) + self.attachmentButton.layer.animateScale(from: 1, to: 0.3, duration: 0.15, delay: 0, removeOnCompletion: false) } case let .video(status, _): switch status { @@ -1021,13 +1063,38 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { if let audioRecordingInfoContainerNode = self.audioRecordingInfoContainerNode { self.audioRecordingInfoContainerNode = nil - transition.updateFrame(node: audioRecordingInfoContainerNode, frame: CGRect(origin: CGPoint(x: -width, y: 0.0), size: audioRecordingInfoContainerNode.bounds.size), completion: { [weak audioRecordingInfoContainerNode] _ in + transition.updateTransformScale(node: audioRecordingInfoContainerNode, scale: 0) + transition.updatePosition(node: audioRecordingInfoContainerNode, position: CGPoint(x: audioRecordingInfoContainerNode.position.x - 10, y: audioRecordingInfoContainerNode.position.y)) + transition.updateAlpha(node: audioRecordingInfoContainerNode, alpha: 0) { [weak audioRecordingInfoContainerNode] _ in audioRecordingInfoContainerNode?.removeFromSupernode() - }) + } } - if let _ = self.audioRecordingDotNode { - self.audioRecordingDotNode = nil + if let audioRecordingDotNode = self.audioRecordingDotNode { + let dismissDotNode = { [weak audioRecordingDotNode, weak attachmentButton, weak self] in + guard let audioRecordingDotNode = audioRecordingDotNode else { return } + + if audioRecordingDotNode === self?.audioRecordingDotNode { + self?.audioRecordingDotNode = nil + } + + audioRecordingDotNode.layer.animateScale(from: 1.0, to: 0.3, duration: 0.15, delay: 0, removeOnCompletion: false) + audioRecordingDotNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.15, delay: 0, removeOnCompletion: false) { [weak audioRecordingDotNode] _ in + audioRecordingDotNode?.removeFromSupernode() + } + + attachmentButton?.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.15, delay: 0, removeOnCompletion: false) + attachmentButton?.layer.animateScale(from: 0.3, to: 1.0, duration: 0.15, delay: 0, removeOnCompletion: false) + } + + audioRecordingDotNode.layer.removeAllAnimations() + + if self.isMediaDeleted { + audioRecordingDotNode.completion = dismissDotNode + audioRecordingDotNode.play() + } else { + dismissDotNode() + } } if let _ = self.audioRecordingTimeNode { @@ -1037,24 +1104,16 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { if let audioRecordingCancelIndicator = self.audioRecordingCancelIndicator { self.audioRecordingCancelIndicator = nil if transition.isAnimated { - if audioRecordingCancelIndicator.isDisplayingCancel { - audioRecordingCancelIndicator.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, removeOnCompletion: false) - audioRecordingCancelIndicator.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: -22.0), duration: 0.25, removeOnCompletion: false, additive: true, completion: { [weak audioRecordingCancelIndicator] _ in - audioRecordingCancelIndicator?.removeFromSupernode() - }) - } else { - let position = audioRecordingCancelIndicator.layer.position - audioRecordingCancelIndicator.layer.animatePosition(from: position, to: CGPoint(x: 0.0 - audioRecordingCancelIndicator.bounds.size.width, y: position.y), duration: 0.3, removeOnCompletion: false, completion: { [weak audioRecordingCancelIndicator] _ in - audioRecordingCancelIndicator?.removeFromSupernode() - }) - } + audioRecordingCancelIndicator.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, completion: { [weak audioRecordingCancelIndicator] _ in + audioRecordingCancelIndicator?.removeFromSupernode() + }) } else { audioRecordingCancelIndicator.removeFromSupernode() } } } - transition.updateFrame(layer: self.attachmentButton.layer, frame: CGRect(origin: CGPoint(x: leftInset + 2.0 - UIScreenPixel, y: panelHeight - minimalHeight + audioRecordingItemsVerticalOffset), size: CGSize(width: 40.0, height: minimalHeight))) + transition.updateFrame(layer: self.attachmentButton.layer, frame: CGRect(origin: CGPoint(x: leftInset + 2.0 - UIScreenPixel, y: panelHeight - minimalHeight), size: CGSize(width: 40.0, height: minimalHeight))) transition.updateFrame(node: self.attachmentButtonDisabledNode, frame: self.attachmentButton.frame) var composeButtonsOffset: CGFloat = 0.0 @@ -1113,8 +1172,9 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { self.searchLayoutClearImageNode.frame = CGRect(origin: CGPoint(x: floor((searchLayoutClearButtonSize.width - image.size.width) / 2.0), y: floor((searchLayoutClearButtonSize.height - image.size.height) / 2.0)), size: image.size) } - let textInputFrame = CGRect(x: leftInset + textFieldInsets.left, y: textFieldInsets.top + audioRecordingItemsVerticalOffset, width: baseWidth - textFieldInsets.left - textFieldInsets.right + textInputBackgroundWidthOffset, height: panelHeight - textFieldInsets.top - textFieldInsets.bottom) + let textInputFrame = CGRect(x: leftInset + textFieldInsets.left, y: textFieldInsets.top, width: baseWidth - textFieldInsets.left - textFieldInsets.right + textInputBackgroundWidthOffset, height: panelHeight - textFieldInsets.top - textFieldInsets.bottom) transition.updateFrame(node: self.textInputContainer, frame: textInputFrame) + transition.updateAlpha(node: self.textInputContainer, alpha: audioRecordingItemsAlpha) if let textInputNode = self.textInputNode { let textFieldFrame = CGRect(origin: CGPoint(x: self.textInputViewInternalInsets.left, y: self.textInputViewInternalInsets.top), size: CGSize(width: textInputFrame.size.width - (self.textInputViewInternalInsets.left + self.textInputViewInternalInsets.right + accessoryButtonsWidth), height: textInputFrame.size.height - self.textInputViewInternalInsets.top - textInputViewInternalInsets.bottom)) @@ -1143,7 +1203,8 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { let _ = placeholderApply() - contextPlaceholderNode.frame = CGRect(origin: CGPoint(x: leftInset + textFieldInsets.left + self.textInputViewInternalInsets.left, y: textFieldInsets.top + self.textInputViewInternalInsets.top + self.textInputViewRealInsets.top + audioRecordingItemsVerticalOffset + UIScreenPixel), size: placeholderSize.size) + contextPlaceholderNode.frame = CGRect(origin: CGPoint(x: leftInset + textFieldInsets.left + self.textInputViewInternalInsets.left, y: textFieldInsets.top + self.textInputViewInternalInsets.top + self.textInputViewRealInsets.top + UIScreenPixel), size: placeholderSize.size) + contextPlaceholderNode.alpha = audioRecordingItemsAlpha } else if let contextPlaceholderNode = self.contextPlaceholderNode { self.contextPlaceholderNode = nil contextPlaceholderNode.removeFromSupernode() @@ -1159,9 +1220,10 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { self.slowmodePlaceholderNode = slowmodePlaceholderNode self.insertSubnode(slowmodePlaceholderNode, aboveSubnode: self.textPlaceholderNode) } - let placeholderFrame = CGRect(origin: CGPoint(x: leftInset + textFieldInsets.left + self.textInputViewInternalInsets.left, y: textFieldInsets.top + self.textInputViewInternalInsets.top + self.textInputViewRealInsets.top + audioRecordingItemsVerticalOffset + UIScreenPixel), size: CGSize(width: width - leftInset - rightInset - textFieldInsets.left - textFieldInsets.right - self.textInputViewInternalInsets.left - self.textInputViewInternalInsets.right - accessoryButtonsWidth, height: 30.0)) + let placeholderFrame = CGRect(origin: CGPoint(x: leftInset + textFieldInsets.left + self.textInputViewInternalInsets.left, y: textFieldInsets.top + self.textInputViewInternalInsets.top + self.textInputViewRealInsets.top + UIScreenPixel), size: CGSize(width: width - leftInset - rightInset - textFieldInsets.left - textFieldInsets.right - self.textInputViewInternalInsets.left - self.textInputViewInternalInsets.right - accessoryButtonsWidth, height: 30.0)) slowmodePlaceholderNode.updateState(slowmodeState) slowmodePlaceholderNode.frame = placeholderFrame + slowmodePlaceholderNode.alpha = audioRecordingItemsAlpha slowmodePlaceholderNode.updateLayout(size: placeholderFrame.size) } else if let slowmodePlaceholderNode = self.slowmodePlaceholderNode { self.slowmodePlaceholderNode = nil @@ -1181,11 +1243,13 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate { self.slowmodePlaceholderNode?.isHidden = true } - transition.updateFrame(node: self.textPlaceholderNode, frame: CGRect(origin: CGPoint(x: leftInset + textFieldInsets.left + self.textInputViewInternalInsets.left, y: textFieldInsets.top + self.textInputViewInternalInsets.top + self.textInputViewRealInsets.top + audioRecordingItemsVerticalOffset + UIScreenPixel), size: self.textPlaceholderNode.frame.size)) + transition.updateFrame(node: self.textPlaceholderNode, frame: CGRect(origin: CGPoint(x: leftInset + textFieldInsets.left + self.textInputViewInternalInsets.left, y: textFieldInsets.top + self.textInputViewInternalInsets.top + self.textInputViewRealInsets.top + UIScreenPixel), size: self.textPlaceholderNode.frame.size)) + transition.updateAlpha(node: self.textPlaceholderNode, alpha: audioRecordingItemsAlpha) - transition.updateFrame(layer: self.textInputBackgroundNode.layer, frame: CGRect(x: leftInset + textFieldInsets.left, y: textFieldInsets.top + audioRecordingItemsVerticalOffset, width: baseWidth - textFieldInsets.left - textFieldInsets.right + textInputBackgroundWidthOffset, height: panelHeight - textFieldInsets.top - textFieldInsets.bottom)) + transition.updateFrame(layer: self.textInputBackgroundNode.layer, frame: CGRect(x: leftInset + textFieldInsets.left, y: textFieldInsets.top, width: baseWidth - textFieldInsets.left - textFieldInsets.right + textInputBackgroundWidthOffset, height: panelHeight - textFieldInsets.top - textFieldInsets.bottom)) + transition.updateAlpha(node: self.textInputBackgroundNode, alpha: audioRecordingItemsAlpha) - var nextButtonTopRight = CGPoint(x: width - rightInset - textFieldInsets.right - accessoryButtonInset, y: panelHeight - textFieldInsets.bottom - minimalInputHeight + audioRecordingItemsVerticalOffset) + var nextButtonTopRight = CGPoint(x: width - rightInset - textFieldInsets.right - accessoryButtonInset, y: panelHeight - textFieldInsets.bottom - minimalInputHeight) for (_, button) in self.accessoryItemButtons.reversed() { let buttonSize = CGSize(width: button.buttonWidth, height: minimalInputHeight) button.updateLayout(size: buttonSize) diff --git a/submodules/TelegramUI/Sources/LockView.swift b/submodules/TelegramUI/Sources/LockView.swift new file mode 100644 index 0000000000..3f8a3132ee --- /dev/null +++ b/submodules/TelegramUI/Sources/LockView.swift @@ -0,0 +1,93 @@ +import UIKit +import LegacyComponents +import AppBundle +import Lottie +import TelegramPresentationData + +final class LockView: UIButton, TGModernConversationInputMicButtonLock { + + private var colorCallbacks = [LOTValueDelegate]() + + private let idleView: LOTAnimationView = { + guard let url = getAppBundle().url(forResource: "LockWait", withExtension: "json"), + let composition = LOTComposition(filePath: url.path) + else { return LOTAnimationView() } + + let view = LOTAnimationView(model: composition, in: getAppBundle()) + view.autoReverseAnimation = true + view.loopAnimation = true + view.backgroundColor = .clear + view.isOpaque = false + return view + }() + + private let lockingView: LOTAnimationView = { + guard let url = getAppBundle().url(forResource: "Lock", withExtension: "json"), + let composition = LOTComposition(filePath: url.path) + else { return LOTAnimationView() } + + let view = LOTAnimationView(model: composition, in: getAppBundle()) + view.backgroundColor = .clear + view.isOpaque = false + return view + }() + + init(frame: CGRect, theme: PresentationTheme) { + super.init(frame: frame) + + addSubview(idleView) + idleView.frame = bounds + + addSubview(lockingView) + lockingView.frame = bounds + + [ + "Rectangle.Заливка 1": theme.chat.inputPanel.panelBackgroundColor, + "Rectangle.Rectangle.Обводка 1": theme.chat.inputPanel.panelControlAccentColor, + "Path.Path.Обводка 1": theme.chat.inputPanel.panelControlAccentColor, + "Path 4.Path 4.Обводка 1": theme.chat.inputPanel.panelControlAccentColor + ].forEach { key, value in + let colorCallback = LOTColorValueCallback(color: value.cgColor) + self.colorCallbacks.append(colorCallback) + idleView.setValueDelegate(colorCallback, for: LOTKeypath(string: "\(key).Color")) + } + + [ + "Path.Path.Обводка 1": theme.chat.inputPanel.panelControlAccentColor, + "Path.Path.Заливка 1": theme.chat.inputPanel.panelBackgroundColor, + "Rectangle.Rectangle.Обводка 1": theme.chat.inputPanel.panelControlAccentColor, + "Rectangle.Заливка 1": theme.chat.inputPanel.panelControlAccentColor, + "Path 4.Path 4.Обводка 1": theme.chat.inputPanel.panelControlAccentColor + ].forEach { key, value in + let colorCallback = LOTColorValueCallback(color: value.cgColor) + self.colorCallbacks.append(colorCallback) + lockingView.setValueDelegate(colorCallback, for: LOTKeypath(string: "\(key).Color")) + } + + updateLockness(0) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func updateLockness(_ lockness: CGFloat) { + idleView.isHidden = lockness > 0 + if lockness > 0 && idleView.isAnimationPlaying { + idleView.stop() + } else if lockness == 0 && !idleView.isAnimationPlaying { + idleView.play() + } + lockingView.isHidden = !idleView.isHidden + + lockingView.animationProgress = lockness + } + + override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + let superTest = super.hitTest(point, with: event) + if superTest === lockingView { + return self + } + return superTest + } +} diff --git a/submodules/TelegramUI/Sources/WaveButtonNode.swift b/submodules/TelegramUI/Sources/WaveButtonNode.swift index 6af4225cd3..cba1dbeb45 100644 --- a/submodules/TelegramUI/Sources/WaveButtonNode.swift +++ b/submodules/TelegramUI/Sources/WaveButtonNode.swift @@ -35,7 +35,7 @@ class CombinedWaveView: UIView, TGModernConversationInputMicButtonDecoration { init(frame: CGRect, color: UIColor) { let n = 12 let bounds = CGRect(origin: CGPoint(), size: frame.size) - self.bigWaveView = WaveView(frame: bounds, n: n, amplitudeRadius: 40.0, isBig: true, color: color.withAlphaComponent(0.3)) + self.bigWaveView = WaveView(frame: bounds, n: n, amplitudeRadius: 30.0, isBig: true, color: color.withAlphaComponent(0.3)) self.smallWaveView = WaveView(frame: bounds, n: n, amplitudeRadius: 35.0, isBig: false, color: color.withAlphaComponent(0.15)) super.init(frame: frame) @@ -46,7 +46,7 @@ class CombinedWaveView: UIView, TGModernConversationInputMicButtonDecoration { self.bigWaveView.amplitudeWaveDif = 0.02 * Constants.sineWaveSpeed * CGFloat.pi / 180.0 self.smallWaveView.amplitudeWaveDif = 0.026 * Constants.sineWaveSpeed - self.smallWaveView.amplitudeRadius = 20.0 + 20.0 * Constants.smallWaveRadius + self.smallWaveView.amplitudeRadius = 10.0 + 20.0 * Constants.smallWaveRadius self.smallWaveView.maxScale = 0.3 * Constants.smallWaveScale self.smallWaveView.scaleSpeed = 0.001 * Constants.smallWaveScaleSpeed self.smallWaveView.fling = Constants.flingDistance @@ -60,14 +60,14 @@ class CombinedWaveView: UIView, TGModernConversationInputMicButtonDecoration { } func updateLevel(_ level: CGFloat) { - let level = level * 0.45 + let level = level * 0.2 self.level = level self.bigWaveView.setLevel(level) self.smallWaveView.setLevel(level) } func tick(_ level: CGFloat) { - let radius = 56.0 + 30.0 * level * 0.45 + let radius = 56.0 + 30.0 * level * 0.2 self.bigWaveView.tick(circleRadius: radius) self.smallWaveView.tick(circleRadius: radius) } diff --git a/voicebin.json b/voicebin.json new file mode 100644 index 0000000000..baf0e38c66 --- /dev/null +++ b/voicebin.json @@ -0,0 +1 @@ +{"v":"5.5.9","fr":60,"ip":0,"op":78,"w":240,"h":240,"nm":"RedBin 2","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Cap1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0],"y":[0]},"o":{"x":[0.333],"y":[0]},"t":42,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[1],"y":[1]},"t":52,"s":[10]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":62,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[1],"y":[0]},"t":68,"s":[-5]},{"t":77,"s":[0]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":22,"s":[120,18,0],"to":[0,11.667,0],"ti":[0,-6.667,0]},{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":42,"s":[120,88,0],"to":[0,6.667,0],"ti":[0,0.833,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":52,"s":[120,58,0],"to":[0,-0.833,0],"ti":[0,-1.667,0]},{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":62,"s":[120,83,0],"to":[0,1.667,0],"ti":[0,0.833,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":68,"s":[120,68,0],"to":[0,-0.833,0],"ti":[0,-1.667,0]},{"t":77,"s":[120,78,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-8.5,0],[8.5,0]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.231372563979,0.188235309077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.33,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Cap1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":27,"s":[50]},{"t":32,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":27,"s":[50]},{"t":32,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Обрезать контуры 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":78,"st":-188,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Cap2","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,-12,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-0.83,0],[0,0],[0,-0.83],[0,0],[0,0]],"o":[[0,0],[0,-0.83],[0,0],[0.83,0],[0,0],[0,0],[0,0]],"v":[[-3.5,1.5],[-3.5,0],[-2,-1.5],[2,-1.5],[3.5,0],[3.5,1.5],[3.5,1.5]],"c":false},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.231372563979,0.188235309077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.33,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Cap2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":27,"s":[50]},{"t":32,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":27,"s":[50]},{"t":32,"s":[0]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Обрезать контуры 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":78,"st":-188,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Line3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[139.5,129,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":32,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0.25,-5.5],[-0.25,5.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":42,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0.667,-3.833],[0.167,5.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":52,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0.25,-5.5],[-0.25,5.5]],"c":false}]},{"i":{"x":0.833,"y":1},"o":{"x":0.333,"y":0},"t":59,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0.25,-5.5],[-0.25,5.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"t":62,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0.458,-5.083],[-0.042,5.5]],"c":false}]},{"t":68,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0.25,-5.5],[-0.25,5.5]],"c":false}]}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.231372563979,0.188235309077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.2,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Line3","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":26,"s":[0]},{"t":29,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Обрезать контуры 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.231372563979,0.188235309077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.2,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":78,"st":-188,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Line2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[120,129,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":32,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,-5.5],[0,5.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":42,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,-3.833],[0,5.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":52,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,-5.5],[0,5.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":59,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,-5.5],[0,5.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":62,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,-5.083],[0,5.5]],"c":false}]},{"t":68,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[0,-5.5],[0,5.5]],"c":false}]}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.231372563979,0.188235309077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.2,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Line2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Обрезать контуры 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":26,"s":[0]},{"t":29,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":3,"nm":"Обрезать контуры 2","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":78,"st":-188,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Line1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[100.5,129,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":32,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.25,-5.5],[0.25,5.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":42,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.667,-3.833],[-0.167,5.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":52,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.25,-5.5],[0.25,5.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":59,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.25,-5.5],[0.25,5.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":62,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.458,-5.083],[0.042,5.5]],"c":false}]},{"t":68,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-0.25,-5.5],[0.25,5.5]],"c":false}]}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.231372563979,0.188235309077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.2,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Line1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":26,"s":[0]},{"t":29,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Обрезать контуры 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":78,"st":-188,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Bin","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[120,120,0],"ix":2},"a":{"a":0,"k":[0,-9,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":32,"s":[{"i":[[0,0],[0,0],[-1.06,0],[0,0],[-0.06,1.05],[0,0]],"o":[[0,0],[0.06,1.05],[0,0],[1.06,0],[0,0],[0,0]],"v":[[-7,-8.5],[-6.11,6.62],[-4.11,8.5],[4.11,8.5],[6.11,6.62],[7,-8.5]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":42,"s":[{"i":[[0,0],[0,0],[-1.06,0],[0,0],[-0.06,1.05],[0,0]],"o":[[0,0],[0.06,1.05],[0,0],[1.06,0],[0,0],[0,0]],"v":[[-7.833,-6.833],[-6.943,6.62],[-4.943,8.5],[4.943,8.5],[6.943,6.62],[7.833,-6.833]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":52,"s":[{"i":[[0,0],[0,0],[-1.06,0],[0,0],[-0.06,1.05],[0,0]],"o":[[0,0],[0.06,1.05],[0,0],[1.06,0],[0,0],[0,0]],"v":[[-7,-8.5],[-6.11,6.62],[-4.11,8.5],[4.11,8.5],[6.11,6.62],[7,-8.5]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":59,"s":[{"i":[[0,0],[0,0],[-1.06,0],[0,0],[-0.06,1.05],[0,0]],"o":[[0,0],[0.06,1.05],[0,0],[1.06,0],[0,0],[0,0]],"v":[[-7,-8.5],[-6.11,6.62],[-4.11,8.5],[4.11,8.5],[6.11,6.62],[7,-8.5]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":62,"s":[{"i":[[0,0],[0,0],[-1.06,0],[0,0],[-0.06,1.05],[0,0]],"o":[[0,0],[0.06,1.05],[0,0],[1.06,0],[0,0],[0,0]],"v":[[-7.417,-7.667],[-6.527,6.62],[-4.527,8.5],[4.527,8.5],[6.527,6.62],[7.417,-7.667]],"c":true}]},{"t":68,"s":[{"i":[[0,0],[0,0],[-1.06,0],[0,0],[-0.06,1.05],[0,0]],"o":[[0,0],[0.06,1.05],[0,0],[1.06,0],[0,0],[0,0]],"v":[[-7,-8.5],[-6.11,6.62],[-4.11,8.5],[4.11,8.5],[6.11,6.62],[7,-8.5]],"c":true}]}],"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.231372563979,0.188235309077,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.33,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"Обводка 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Bin","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":22,"s":[50]},{"t":42,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":22,"s":[50]},{"t":42,"s":[100]}],"ix":2},"o":{"a":0,"k":137,"ix":3},"m":1,"ix":2,"nm":"Обрезать контуры 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":78,"st":-188,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"RecMask 2","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[120,120,0],"to":[0,-15,0],"ti":[0,13.667,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":15,"s":[120,30,0],"to":[0,-13.667,0],"ti":[0,-1.333,0]},{"t":24,"s":[120,38,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,84.375,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[8.5,-8],[8.5,8],[-8.5,8],[-8.5,-8]],"c":true},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.96862745098,0.96862745098,0.96862745098,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Mask","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":78,"st":-190,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Recording","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[120,120,0],"to":[0,-15,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":15,"s":[120,30,0],"to":[0,0,0],"ti":[0,-15,0]},{"t":30,"s":[120,120,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-2.76,0],[0,2.76],[2.76,0],[0,-2.76]],"o":[[2.76,0],[0,-2.76],[-2.76,0],[0,2.76]],"v":[[0,5],[5,0],[0,-5],[-5,0]],"c":true},"ix":2},"nm":"Контур 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.231372997165,0.188234999776,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Заливка 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[600,600],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Преобразовать"}],"nm":"Recording","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":40,"st":-180,"bm":0}],"markers":[]} \ No newline at end of file