From a9d42fd5c82763273d1e40b29980380fbcc87df1 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Wed, 23 Dec 2020 21:11:56 +0400 Subject: [PATCH] Apply Voice Chat UI fixes --- .../Display/Source/ListViewItemNode.swift | 4 +-- .../LegacyComponents/TGMediaAsset.h | 1 + .../LegacyComponents/TGMediaPickerCell.h | 2 ++ .../LegacyComponents/Sources/TGMediaAsset.m | 5 ++++ .../Sources/TGMediaAssetsPhotoCell.m | 13 +++++++++ .../Sources/TGMediaAssetsVideoCell.m | 16 ++--------- .../Sources/TGMediaPickerCell.m | 6 +++++ .../Sources/TGViewController.mm | 2 +- .../Sources/VoiceChatActionItem.swift | 4 --- .../Sources/VoiceChatController.swift | 27 ++++++++++++------- .../Sources/VoiceChatParticipantItem.swift | 4 --- 11 files changed, 50 insertions(+), 34 deletions(-) diff --git a/submodules/Display/Source/ListViewItemNode.swift b/submodules/Display/Source/ListViewItemNode.swift index 3d055c9870..87e9fe34d0 100644 --- a/submodules/Display/Source/ListViewItemNode.swift +++ b/submodules/Display/Source/ListViewItemNode.swift @@ -422,7 +422,7 @@ open class ListViewItemNode: ASDisplayNode, AccessibilityFocusableNode { } public func addInsetsAnimationToValue(_ value: UIEdgeInsets, duration: Double, beginAt: Double) { - let animation = ListViewAnimation(from: self.insets, to: value, duration: duration, curve: listViewAnimationCurveSystem, beginAt: beginAt, update: { [weak self] _, currentValue in + let animation = ListViewAnimation(from: self.insets, to: value, duration: duration, curve: self.preferredAnimationCurve, beginAt: beginAt, update: { [weak self] _, currentValue in if let strongSelf = self { strongSelf.insets = currentValue } @@ -483,7 +483,7 @@ open class ListViewItemNode: ASDisplayNode, AccessibilityFocusableNode { duration = 0.0 } - let animation = ListViewAnimation(from: self.apparentHeight, to: value, duration: duration, curve: listViewAnimationCurveSystem, beginAt: beginAt, update: { [weak self] _, currentValue in + let animation = ListViewAnimation(from: self.apparentHeight, to: value, duration: duration, curve: self.preferredAnimationCurve, beginAt: beginAt, update: { [weak self] _, currentValue in if let strongSelf = self { strongSelf.apparentHeight = currentValue } diff --git a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGMediaAsset.h b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGMediaAsset.h index fc69fab2d0..8060ccb055 100644 --- a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGMediaAsset.h +++ b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGMediaAsset.h @@ -38,6 +38,7 @@ typedef enum @property (nonatomic, readonly) NSString *uniformTypeIdentifier; @property (nonatomic, readonly) NSString *fileName; @property (nonatomic, readonly) NSInteger fileSize; +@property (nonatomic, readonly) bool isFavorite; @property (nonatomic, readonly) TGMediaAssetType type; @property (nonatomic, readonly) TGMediaAssetSubtype subtypes; diff --git a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGMediaPickerCell.h b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGMediaPickerCell.h index 69953346f9..0fbd3a3d19 100644 --- a/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGMediaPickerCell.h +++ b/submodules/LegacyComponents/PublicHeaders/LegacyComponents/TGMediaPickerCell.h @@ -9,6 +9,8 @@ @property (nonatomic, readonly) TGImageView *imageView; @property (nonatomic, readonly) TGCheckButtonView *checkButton; +@property (nonatomic, readonly) UIImageView *typeIconView; + - (void)setHidden:(bool)hidden animated:(bool)animated; @property (nonatomic, strong) TGMediaSelectionContext *selectionContext; diff --git a/submodules/LegacyComponents/Sources/TGMediaAsset.m b/submodules/LegacyComponents/Sources/TGMediaAsset.m index ac9f4ca0b2..0b9ae58d4e 100644 --- a/submodules/LegacyComponents/Sources/TGMediaAsset.m +++ b/submodules/LegacyComponents/Sources/TGMediaAsset.m @@ -102,6 +102,11 @@ return [self.uniformTypeIdentifier isEqualToString:(NSString *)kUTTypeGIF]; } +- (bool)isFavorite +{ + return _backingAsset.isFavorite; +} + - (TGMediaAssetType)type { if (_cachedType == nil) diff --git a/submodules/LegacyComponents/Sources/TGMediaAssetsPhotoCell.m b/submodules/LegacyComponents/Sources/TGMediaAssetsPhotoCell.m index cdf00e53e1..775034781d 100644 --- a/submodules/LegacyComponents/Sources/TGMediaAssetsPhotoCell.m +++ b/submodules/LegacyComponents/Sources/TGMediaAssetsPhotoCell.m @@ -1,5 +1,7 @@ #import "TGMediaAssetsPhotoCell.h" +#import + #import "LegacyComponentsInternal.h" NSString *const TGMediaAssetsPhotoCellKind = @"TGMediaAssetsPhotoCellKind"; @@ -14,4 +16,15 @@ NSString *const TGMediaAssetsPhotoCellKind = @"TGMediaAssetsPhotoCellKind"; return self; } +- (void)setItem:(NSObject *)item signal:(SSignal *)signal +{ + [super setItem:item signal:signal]; + + TGMediaAsset *asset = (TGMediaAsset *)item; + if (![asset isKindOfClass:[TGMediaAsset class]]) + return; + + self.typeIconView.image = asset.isFavorite ? TGComponentsImageNamed(@"MediaGroupFavorites") : nil; +} + @end diff --git a/submodules/LegacyComponents/Sources/TGMediaAssetsVideoCell.m b/submodules/LegacyComponents/Sources/TGMediaAssetsVideoCell.m index 69a26f9b7b..2e1eab68a8 100644 --- a/submodules/LegacyComponents/Sources/TGMediaAssetsVideoCell.m +++ b/submodules/LegacyComponents/Sources/TGMediaAssetsVideoCell.m @@ -15,7 +15,6 @@ NSString *const TGMediaAssetsVideoCellKind = @"TGMediaAssetsVideoCellKind"; @interface TGMediaAssetsVideoCell () { UIImageView *_shadowView; - UIImageView *_iconView; UILabel *_durationLabel; SMetaDisposable *_adjustmentsDisposable; @@ -64,10 +63,7 @@ NSString *const TGMediaAssetsVideoCellKind = @"TGMediaAssetsVideoCellKind"; _shadowView = [[UIImageView alloc] initWithFrame:CGRectMake(0, frame.size.height - 20, frame.size.width, 20)]; _shadowView.image = shadowImage; [self addSubview:_shadowView]; - - _iconView = [[UIImageView alloc] init]; - _iconView.contentMode = UIViewContentModeCenter; - + _durationLabel = [[UILabel alloc] init]; _durationLabel.textColor = [UIColor whiteColor]; _durationLabel.backgroundColor = [UIColor clearColor]; @@ -81,7 +77,6 @@ NSString *const TGMediaAssetsVideoCellKind = @"TGMediaAssetsVideoCellKind"; if (iosMajorVersion() >= 11) { _shadowView.accessibilityIgnoresInvertColors = true; - _iconView.accessibilityIgnoresInvertColors = true; _durationLabel.accessibilityIgnoresInvertColors = true; } @@ -103,7 +98,6 @@ NSString *const TGMediaAssetsVideoCellKind = @"TGMediaAssetsVideoCellKind"; if (![asset isKindOfClass:[TGMediaAsset class]]) return; - NSString *durationString = nil; int duration = (int)ceil(asset.videoDuration); if (duration >= 3600) @@ -114,12 +108,7 @@ NSString *const TGMediaAssetsVideoCellKind = @"TGMediaAssetsVideoCellKind"; _durationLabel.text = durationString; [_durationLabel sizeToFit]; - if (asset.subtypes & TGMediaAssetSubtypeVideoTimelapse) - _iconView.image = TGComponentsImageNamed(@"ModernMediaItemTimelapseIcon"); - else if (asset.subtypes & TGMediaAssetSubtypeVideoHighFrameRate) - _iconView.image = TGComponentsImageNamed(@"ModernMediaItemSloMoIcon"); - else - _iconView.image = TGComponentsImageNamed(@"ModernMediaItemVideoIcon"); + self.typeIconView.image = asset.isFavorite ? TGComponentsImageNamed(@"MediaGroupFavorites") : nil; SSignal *adjustmentsSignal = [self.editingContext adjustmentsSignalForItem:(id)self.item]; @@ -234,7 +223,6 @@ NSString *const TGMediaAssetsVideoCellKind = @"TGMediaAssetsVideoCellKind"; { self.checkButton.frame = (CGRect){ { self.frame.size.width - self.checkButton.frame.size.width - 2, 2 }, self.checkButton.frame.size }; _shadowView.frame = (CGRect){ { 0, self.frame.size.height - _shadowView.frame.size.height }, {self.frame.size.width, _shadowView.frame.size.height } }; - _iconView.frame = CGRectMake(0, self.frame.size.height - 19, 19, 19); CGSize durationSize = _durationLabel.frame.size; _durationLabel.frame = CGRectMake(self.frame.size.width - floor(durationSize.width) - 5.0, self.frame.size.height - floor(durationSize.height) - 4.0, durationSize.width, durationSize.height); diff --git a/submodules/LegacyComponents/Sources/TGMediaPickerCell.m b/submodules/LegacyComponents/Sources/TGMediaPickerCell.m index 263eb2aa9c..6e4ae434c8 100644 --- a/submodules/LegacyComponents/Sources/TGMediaPickerCell.m +++ b/submodules/LegacyComponents/Sources/TGMediaPickerCell.m @@ -34,6 +34,10 @@ if (iosMajorVersion() >= 11) _imageView.accessibilityIgnoresInvertColors = true; + _typeIconView = [[UIImageView alloc] init]; + _typeIconView.contentMode = UIViewContentModeCenter; + [self addSubview:_typeIconView]; + self.isAccessibilityElement = true; } return self; @@ -212,6 +216,8 @@ _imageView.frame = self.bounds; _imageView.transform = transform; + _typeIconView.frame = CGRectMake(2.0, self.frame.size.height - 19 - 2, 19, 19); + _checkButton.frame = (CGRect){ { self.frame.size.width - _checkButton.frame.size.width - 2, 2 }, _checkButton.frame.size }; } diff --git a/submodules/LegacyComponents/Sources/TGViewController.mm b/submodules/LegacyComponents/Sources/TGViewController.mm index d8dd2aad62..4ec8d72d20 100644 --- a/submodules/LegacyComponents/Sources/TGViewController.mm +++ b/submodules/LegacyComponents/Sources/TGViewController.mm @@ -1072,7 +1072,7 @@ static id _defaultContext = nil; + (UIEdgeInsets)safeAreaInsetForOrientation:(UIInterfaceOrientation)orientation hasOnScreenNavigation:(bool)hasOnScreenNavigation { int height = (int)TGScreenSize().height; - if (!TGIsPad() && (height != 812 && height != 896 && height != 780 && height != 844 && height != 926)) + if (!TGIsPad() && (height != 812 && height != 896 && height != 780 && height != 844 && height != 926) && !hasOnScreenNavigation) return UIEdgeInsetsZero; if (TGIsPad()) { diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatActionItem.swift b/submodules/TelegramCallsUI/Sources/VoiceChatActionItem.swift index e7384f0e41..16638681c3 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatActionItem.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatActionItem.swift @@ -257,8 +257,4 @@ class VoiceChatActionItemNode: ListViewItemNode { override public func header() -> ListViewItemHeader? { return nil } - - override var preferredAnimationCurve: (CGFloat) -> CGFloat { - return listViewAnimationCurveEaseInOut - } } diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift index dd65f0e9fc..a85b3db46a 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift @@ -940,9 +940,9 @@ public final class VoiceChatController: ViewController { self.call.members, invitedPeers ) - |> mapToSignal { values in + |> mapToThrottled { values in return .single(values) - |> delay(0.0, queue: .mainQueue()) + |> then(.complete() |> delay(0.1, queue: Queue.mainQueue())) }).start(next: { [weak self] state, callMembers, invitedPeers in guard let strongSelf = self else { return @@ -1826,8 +1826,6 @@ public final class VoiceChatController: ViewController { } let topPanelFrame = self.topPanelNode.view.convert(self.topPanelNode.bounds, to: self.view) - let offset: CGFloat = self.contentContainer.bounds.minY - self.contentContainer.layer.animateBoundsOriginYAdditive(from: self.contentContainer.bounds.origin.y, to: -(layout.size.height - topPanelFrame.minY) - 44.0, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, completion: { _ in offsetCompleted = true internalCompletion() @@ -1861,7 +1859,7 @@ public final class VoiceChatController: ViewController { if transition.crossFade { options.insert(.AnimateCrossfade) } - if transition.animated { + if transition.animated && self.animation == nil { options.insert(.AnimateInsertion) } } @@ -1897,7 +1895,7 @@ public final class VoiceChatController: ViewController { self.listNode.frame = frame } else if !self.isExpanded { if self.listNode.frame.minY != targetY && !self.animatingExpansion && self.panGestureArguments == nil { - self.animation = ListViewAnimation(from: self.listNode.frame.minY, to: targetY, duration: 0.4, curve: listViewAnimationCurveEaseInOut, beginAt: CACurrentMediaTime(), update: { [weak self] _, currentValue in + self.animation = ListViewAnimation(from: self.listNode.frame.minY, to: targetY, duration: 0.4, curve: listViewAnimationCurveSystem, beginAt: CACurrentMediaTime(), update: { [weak self] _, currentValue in if let strongSelf = self { var frame = strongSelf.listNode.frame frame.origin.y = currentValue @@ -2055,6 +2053,7 @@ public final class VoiceChatController: ViewController { private var panGestureArguments: (topInset: CGFloat, offset: CGFloat)? @objc func panGesture(_ recognizer: UIPanGestureRecognizer) { + let contentOffset = self.listNode.visibleContentOffset() switch recognizer.state { case .began: let topInset: CGFloat @@ -2072,7 +2071,8 @@ public final class VoiceChatController: ViewController { if let (currentTopInset, currentPanOffset) = self.panGestureArguments { topInset = currentTopInset - if case let .known(value) = self.listNode.visibleContentOffset(), value > 0 { + if case let .known(value) = contentOffset, value <= 0.5 { + } else { translation = currentPanOffset if self.isExpanded { recognizer.setTranslation(CGPoint(), in: self.contentContainer.view) @@ -2090,7 +2090,6 @@ public final class VoiceChatController: ViewController { } if self.isExpanded { - } else { if currentOffset > 0.0 { self.listNode.scroller.panGestureRecognizer.setTranslation(CGPoint(), in: self.listNode.scroller) @@ -2112,7 +2111,9 @@ public final class VoiceChatController: ViewController { let translation = recognizer.translation(in: self.contentContainer.view) var velocity = recognizer.velocity(in: self.contentContainer.view) - if case let .known(value) = self.listNode.visibleContentOffset(), value > 0 { + if case let .known(value) = contentOffset, value > 0.0 { + velocity = CGPoint() + } else if case .unknown = contentOffset { velocity = CGPoint() } @@ -2140,6 +2141,7 @@ public final class VoiceChatController: ViewController { self.isExpanded = false self.updateIsFullscreen(false) self.animatingExpansion = true + self.listNode.scroller.setContentOffset(CGPoint(), animated: false) if let (layout, navigationHeight) = self.validLayout { self.containerLayoutUpdated(layout, navigationHeight: navigationHeight, transition: .animated(duration: 0.3, curve: .easeInOut)) @@ -2165,6 +2167,12 @@ public final class VoiceChatController: ViewController { self.controller?.dismiss(closing: false, manual: true) dismissing = true } else if velocity.y < -300.0 || offset < topInset / 2.0 { + if velocity.y > -1500.0 && !self.isFullscreen { + DispatchQueue.main.async { + self.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous, .LowLatency], scrollToItem: ListViewScrollToItem(index: 0, position: .top(0.0), animated: true, curve: .Default(duration: nil), directionHint: .Up), updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in }) + } + } + self.isExpanded = true self.updateIsFullscreen(true) self.animatingExpansion = true @@ -2178,6 +2186,7 @@ public final class VoiceChatController: ViewController { } else { self.updateIsFullscreen(false) self.animatingExpansion = true + self.listNode.scroller.setContentOffset(CGPoint(), animated: false) if let (layout, navigationHeight) = self.validLayout { self.containerLayoutUpdated(layout, navigationHeight: navigationHeight, transition: .animated(duration: 0.3, curve: .easeInOut)) diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatParticipantItem.swift b/submodules/TelegramCallsUI/Sources/VoiceChatParticipantItem.swift index 9ddd978bdb..b67b3af3db 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatParticipantItem.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatParticipantItem.swift @@ -787,8 +787,4 @@ class VoiceChatParticipantItemNode: ItemListRevealOptionsItemNode { self.setRevealOptionsOpened(false, animated: true) self.revealOptionsInteractivelyClosed() } - - override var preferredAnimationCurve: (CGFloat) -> CGFloat { - return listViewAnimationCurveEaseInOut - } }