diff --git a/submodules/AvatarNode/Sources/AvatarNode.swift b/submodules/AvatarNode/Sources/AvatarNode.swift index 7b7ed71609..79369bc56c 100644 --- a/submodules/AvatarNode/Sources/AvatarNode.swift +++ b/submodules/AvatarNode/Sources/AvatarNode.swift @@ -867,15 +867,18 @@ public final class AvatarNode: ASDisplayNode { public var totalCount: Int public var unseenCount: Int public var hasUnseenCloseFriendsItems: Bool + public var progress: Float? public init( totalCount: Int, unseenCount: Int, - hasUnseenCloseFriendsItems: Bool + hasUnseenCloseFriendsItems: Bool, + progress: Float? = nil ) { self.totalCount = totalCount self.unseenCount = unseenCount self.hasUnseenCloseFriendsItems = hasUnseenCloseFriendsItems + self.progress = progress } } @@ -1135,6 +1138,12 @@ public final class AvatarNode: ASDisplayNode { storyIndicator = ComponentView() self.storyIndicator = storyIndicator } + var mappedProgress: AvatarStoryIndicatorComponent.Progress? + if let value = storyStats.progress { + mappedProgress = .definite(value) + } else if !self.loadingStatuses.isEmpty { + mappedProgress = .indefinite + } let _ = storyIndicator.update( transition: indicatorTransition, component: AnyComponent(AvatarStoryIndicatorComponent( @@ -1151,7 +1160,7 @@ public final class AvatarNode: ASDisplayNode { totalCount: storyStats.totalCount, unseenCount: storyStats.unseenCount ), - displayProgress: !self.loadingStatuses.isEmpty + progress: mappedProgress )), environment: {}, containerSize: indicatorSize diff --git a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift index 3dc311829f..bedf9ee254 100644 --- a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift +++ b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift @@ -2724,6 +2724,34 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate } destinationView.isHidden = true + if let destinationTransitionView { + destinationTransitionView.layer.anchorPoint = CGPoint(x: 0.0, y: 0.5) + let snapshotScale = self.previewContainerView.bounds.width / destinationTransitionView.frame.width + destinationTransitionView.center = CGPoint(x: 0.0, y: self.previewContainerView.bounds.height / 2.0) + destinationTransitionView.layer.transform = CATransform3DMakeScale(snapshotScale, snapshotScale, 1.0) + + destinationTransitionView.alpha = 0.0 + Queue.mainQueue().after(0.15) { + destinationTransitionView.alpha = 1.0 + destinationTransitionView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25) + } + + self.previewContainerView.addSubview(destinationTransitionView) + destinationSnapshotView = destinationTransitionView + } + } else if let destinationNode = destinationView.asyncdisplaykit_node as? AvatarNode.ContentNode { + let destinationTransitionView: UIView? + if let image = destinationNode.unroundedImage { + destinationTransitionView = UIImageView(image: image) + destinationTransitionView?.bounds = destinationNode.bounds + destinationTransitionView?.layer.cornerRadius = destinationNode.bounds.width / 2.0 + } else if let snapshotView = destinationView.snapshotView(afterScreenUpdates: false) { + destinationTransitionView = snapshotView + } else { + destinationTransitionView = nil + } + destinationView.isHidden = true + if let destinationTransitionView { destinationTransitionView.layer.anchorPoint = CGPoint(x: 0.0, y: 0.5) let snapshotScale = self.previewContainerView.bounds.width / destinationTransitionView.frame.width diff --git a/submodules/TelegramUI/Components/Stories/AvatarStoryIndicatorComponent/Sources/AvatarStoryIndicatorComponent.swift b/submodules/TelegramUI/Components/Stories/AvatarStoryIndicatorComponent/Sources/AvatarStoryIndicatorComponent.swift index 50578db467..2c86f95315 100644 --- a/submodules/TelegramUI/Components/Stories/AvatarStoryIndicatorComponent/Sources/AvatarStoryIndicatorComponent.swift +++ b/submodules/TelegramUI/Components/Stories/AvatarStoryIndicatorComponent/Sources/AvatarStoryIndicatorComponent.swift @@ -38,13 +38,18 @@ public final class AvatarStoryIndicatorComponent: Component { } } + public enum Progress: Equatable { + case indefinite + case definite(Float) + } + public let hasUnseen: Bool public let hasUnseenCloseFriendsItems: Bool public let colors: Colors public let activeLineWidth: CGFloat public let inactiveLineWidth: CGFloat public let counters: Counters? - public let displayProgress: Bool + public let progress: Progress? public init( hasUnseen: Bool, @@ -53,7 +58,7 @@ public final class AvatarStoryIndicatorComponent: Component { activeLineWidth: CGFloat, inactiveLineWidth: CGFloat, counters: Counters?, - displayProgress: Bool = false + progress: Progress? = nil ) { self.hasUnseen = hasUnseen self.hasUnseenCloseFriendsItems = hasUnseenCloseFriendsItems @@ -61,7 +66,7 @@ public final class AvatarStoryIndicatorComponent: Component { self.activeLineWidth = activeLineWidth self.inactiveLineWidth = inactiveLineWidth self.counters = counters - self.displayProgress = displayProgress + self.progress = progress } public static func ==(lhs: AvatarStoryIndicatorComponent, rhs: AvatarStoryIndicatorComponent) -> Bool { @@ -83,7 +88,7 @@ public final class AvatarStoryIndicatorComponent: Component { if lhs.counters != rhs.counters { return false } - if lhs.displayProgress != rhs.displayProgress { + if lhs.progress != rhs.progress { return false } return true @@ -364,7 +369,7 @@ public final class AvatarStoryIndicatorComponent: Component { transition.setFrame(view: self.indicatorView, frame: indicatorFrame) let progressTransition = Transition(animation: .curve(duration: 0.3, curve: .easeInOut)) - if component.displayProgress { + if let progress = component.progress { let colorLayer: SimpleGradientLayer if let current = self.colorLayer { colorLayer = current @@ -379,13 +384,12 @@ public final class AvatarStoryIndicatorComponent: Component { progressTransition.setAlpha(layer: colorLayer, alpha: 1.0) let colors: [CGColor] = activeColors - /*if component.hasUnseen { - colors = activeColors + let lineWidth: CGFloat + if case .definite = progress { + lineWidth = component.activeLineWidth } else { - colors = inactiveColors - }*/ - - let lineWidth: CGFloat = component.hasUnseen ? component.activeLineWidth : component.inactiveLineWidth + lineWidth = component.hasUnseen ? component.activeLineWidth : component.inactiveLineWidth + } colorLayer.colors = colors colorLayer.startPoint = CGPoint(x: 0.0, y: 0.0) @@ -402,7 +406,16 @@ public final class AvatarStoryIndicatorComponent: Component { colorLayer.frame = indicatorFrame progressLayer.frame = CGRect(origin: CGPoint(), size: indicatorFrame.size) - progressLayer.update(size: indicatorFrame.size, radius: radius, lineWidth: lineWidth, value: .indefinite, transition: .immediate) + + let mappedProgress: ProgressLayer.Value + switch progress { + case .indefinite: + mappedProgress = .indefinite + case let .definite(value): + mappedProgress = .progress(value) + } + + progressLayer.update(size: indicatorFrame.size, radius: radius, lineWidth: lineWidth, value: mappedProgress, transition: .immediate) } else { progressTransition.setAlpha(view: self.indicatorView, alpha: 1.0) diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift index a5255567a8..2789108ead 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift @@ -424,6 +424,7 @@ final class PeerInfoAvatarTransformContainerNode: ASDisplayNode { private let playbackStartDisposable = MetaDisposable() var storyData: (totalCount: Int, unseenCount: Int, hasUnseenCloseFriends: Bool)? + var storyProgress: Float? init(context: AccountContext) { self.context = context @@ -462,13 +463,23 @@ final class PeerInfoAvatarTransformContainerNode: ASDisplayNode { theme.list.controlSecondaryColor, theme.list.controlSecondaryColor ] - self.avatarNode.setStoryStats(storyStats: self.storyData.flatMap { storyData in - return AvatarNode.StoryStats( + var storyStats: AvatarNode.StoryStats? + if let storyData = self.storyData { + storyStats = AvatarNode.StoryStats( totalCount: storyData.totalCount, unseenCount: storyData.unseenCount, - hasUnseenCloseFriendsItems: storyData.hasUnseenCloseFriends + hasUnseenCloseFriendsItems: storyData.hasUnseenCloseFriends, + progress: self.storyProgress ) - }, presentationParams: AvatarNode.StoryPresentationParams( + } else if let storyProgress = self.storyProgress { + storyStats = AvatarNode.StoryStats( + totalCount: 1, + unseenCount: 1, + hasUnseenCloseFriendsItems: false, + progress: storyProgress + ) + } + self.avatarNode.setStoryStats(storyStats: storyStats, presentationParams: AvatarNode.StoryPresentationParams( colors: colors, lineWidth: 3.0, inactiveLineWidth: 1.5 diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index bb9ed3f17f..895a2e8c1b 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -2169,6 +2169,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro private var expiringStoryList: PeerExpiringStoryListContext? private var expiringStoryListState: PeerExpiringStoryListContext.State? private var expiringStoryListDisposable: Disposable? + private var storyUploadProgressDisposable: Disposable? private var postingAvailabilityDisposable: Disposable? private let storiesReady = ValuePromise(true, ignoreRepeated: true) @@ -3936,6 +3937,24 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro self.storiesReady.set(false) let expiringStoryList = PeerExpiringStoryListContext(account: context.account, peerId: peerId) self.expiringStoryList = expiringStoryList + self.storyUploadProgressDisposable = (context.engine.messages.allStoriesUploadProgress() + |> map { value -> Float? in + return value[peerId] + } + |> distinctUntilChanged).start(next: { [weak self] value in + guard let self else { + return + } + var mappedValue = value + if let value { + mappedValue = max(0.027, value) + } + + if self.headerNode.avatarListNode.avatarContainerNode.storyProgress != mappedValue { + self.headerNode.avatarListNode.avatarContainerNode.storyProgress = mappedValue + self.headerNode.avatarListNode.avatarContainerNode.updateStoryView(transition: .immediate, theme: self.presentationData.theme) + } + }) self.expiringStoryListDisposable = (combineLatest(queue: .mainQueue(), context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)), expiringStoryList.state @@ -8269,7 +8288,14 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro private func openPostStory() { self.postingAvailabilityDisposable?.dispose() - self.postingAvailabilityDisposable = (self.context.engine.messages.checkStoriesUploadAvailability(target: .peer(self.peerId)) + let canPostStatus: Signal + #if DEBUG + canPostStatus = .single(.available) + #else + canPostStatus = self.context.engine.messages.checkStoriesUploadAvailability(target: .peer(self.peerId)) + #endif + + self.postingAvailabilityDisposable = (canPostStatus |> deliverOnMainQueue).start(next: { [weak self] status in guard let self else { return @@ -8338,15 +8364,15 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro guard let self else { return nil } - let _ = self - /*if let transitionView = self.headerNode.navigationButtonContainer.rightButtonNodes[.postStory]?.view { + if !self.headerNode.isAvatarExpanded { + let transitionView = self.headerNode.avatarListNode.avatarContainerNode.avatarNode.contentNode.view return StoryCameraTransitionOut( destinationView: transitionView, destinationRect: transitionView.bounds, destinationCornerRadius: transitionView.bounds.height * 0.5 ) - }*/ + } return nil }