diff --git a/submodules/PremiumUI/Sources/PremiumDemoScreen.swift b/submodules/PremiumUI/Sources/PremiumDemoScreen.swift index e9a2701fb4..616697c8c4 100644 --- a/submodules/PremiumUI/Sources/PremiumDemoScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumDemoScreen.swift @@ -952,7 +952,7 @@ private final class DemoSheetContent: CombinedComponent { content: AnyComponent(PhoneDemoComponent( context: component.context, position: .top, - videoFile: configuration.videos["colors"], + videoFile: configuration.videos["peer_colors"], decoration: .badgeStars )), title: strings.Premium_Colors, diff --git a/submodules/PremiumUI/Sources/PremiumIntroScreen.swift b/submodules/PremiumUI/Sources/PremiumIntroScreen.swift index 7e69004140..0b56e5e20a 100644 --- a/submodules/PremiumUI/Sources/PremiumIntroScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumIntroScreen.swift @@ -458,7 +458,7 @@ public enum PremiumPerk: CaseIterable { case .stories: return "stories" case .colors: - return "colors" + return "peer_colors" case .wallpapers: return "wallpapers" } diff --git a/submodules/PremiumUI/Sources/PremiumLimitsListScreen.swift b/submodules/PremiumUI/Sources/PremiumLimitsListScreen.swift index cdf8b1294e..8b839296f7 100644 --- a/submodules/PremiumUI/Sources/PremiumLimitsListScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumLimitsListScreen.swift @@ -713,7 +713,7 @@ public class PremiumLimitsListScreen: ViewController { content: AnyComponent(PhoneDemoComponent( context: context, position: .top, - videoFile: configuration.videos["colors"], + videoFile: configuration.videos["peer_colors"], decoration: .badgeStars )), title: strings.Premium_Colors, diff --git a/submodules/TelegramUI/Components/MediaEditor/Sources/VideoFinishPass.swift b/submodules/TelegramUI/Components/MediaEditor/Sources/VideoFinishPass.swift index 1c83237ba9..665931793b 100644 --- a/submodules/TelegramUI/Components/MediaEditor/Sources/VideoFinishPass.swift +++ b/submodules/TelegramUI/Components/MediaEditor/Sources/VideoFinishPass.swift @@ -420,57 +420,56 @@ final class VideoFinishPass: RenderPass { } var isVisible = true - if let additionalVideoRemovalStartTimestamp { + var trimRangeLowerBound: Double? + var trimRangeUpperBound: Double? + if let additionalVideoRange = self.additionalVideoRange { + if let additionalVideoOffset = self.additionalVideoOffset { + trimRangeLowerBound = additionalVideoRange.lowerBound - additionalVideoOffset + trimRangeUpperBound = additionalVideoRange.upperBound - additionalVideoOffset + } else { + trimRangeLowerBound = additionalVideoRange.lowerBound + trimRangeUpperBound = additionalVideoRange.upperBound + } + } else if let additionalVideoOffset = self.additionalVideoOffset { + trimRangeLowerBound = -additionalVideoOffset + if let additionalVideoDuration = self.additionalVideoDuration { + trimRangeUpperBound = -additionalVideoOffset + additionalVideoDuration + } + } + + if (trimRangeLowerBound != nil || trimRangeUpperBound != nil), let _ = self.videoDuration { let disappearingPosition = VideoPosition(position: foregroundPosition.position, size: foregroundPosition.size, scale: 0.01, rotation: foregroundPosition.rotation, baseScale: foregroundPosition.baseScale) - let visibilityFraction = max(0.0, min(1.0, 1.0 - (CACurrentMediaTime() - additionalVideoRemovalStartTimestamp) / videoRemovalDuration)) - if visibilityFraction.isZero { - isVisible = false - } - foregroundAlpha = Float(visibilityFraction) - foregroundPosition = disappearingPosition.mixed(with: foregroundPosition, fraction: visibilityFraction) - } else { - var trimRangeLowerBound: Double? - var trimRangeUpperBound: Double? - if let additionalVideoRange = self.additionalVideoRange { - if let additionalVideoOffset = self.additionalVideoOffset { - trimRangeLowerBound = additionalVideoRange.lowerBound - additionalVideoOffset - trimRangeUpperBound = additionalVideoRange.upperBound - additionalVideoOffset - } else { - trimRangeLowerBound = additionalVideoRange.lowerBound - trimRangeUpperBound = additionalVideoRange.upperBound - } - } else if let additionalVideoOffset = self.additionalVideoOffset { - trimRangeLowerBound = -additionalVideoOffset - if let additionalVideoDuration = self.additionalVideoDuration { - trimRangeUpperBound = -additionalVideoOffset + additionalVideoDuration - } - } + let mainLowerBound = self.videoRange?.lowerBound ?? 0.0 - if (trimRangeLowerBound != nil || trimRangeUpperBound != nil), let _ = self.videoDuration { - let disappearingPosition = VideoPosition(position: foregroundPosition.position, size: foregroundPosition.size, scale: 0.01, rotation: foregroundPosition.rotation, baseScale: foregroundPosition.baseScale) - - let mainLowerBound = self.videoRange?.lowerBound ?? 0.0 - - if let trimRangeLowerBound, trimRangeLowerBound > mainLowerBound + 0.1, timestamp < trimRangeLowerBound + apperanceDuration { - let visibilityFraction = max(0.0, min(1.0, (timestamp - trimRangeLowerBound) / apperanceDuration)) - if visibilityFraction.isZero { - isVisible = false - } - foregroundAlpha = Float(visibilityFraction) - foregroundPosition = disappearingPosition.mixed(with: foregroundPosition, fraction: visibilityFraction) - } else if let trimRangeUpperBound, timestamp > trimRangeUpperBound - apperanceDuration { - let visibilityFraction = 1.0 - max(0.0, min(1.0, (timestamp - trimRangeUpperBound) / apperanceDuration)) - if visibilityFraction.isZero { - isVisible = false - } - foregroundAlpha = Float(visibilityFraction) - foregroundPosition = disappearingPosition.mixed(with: foregroundPosition, fraction: visibilityFraction) + if let trimRangeLowerBound, trimRangeLowerBound > mainLowerBound + 0.1, timestamp < trimRangeLowerBound + apperanceDuration { + let visibilityFraction = max(0.0, min(1.0, (timestamp - trimRangeLowerBound) / apperanceDuration)) + if visibilityFraction.isZero { + isVisible = false } + foregroundAlpha = Float(visibilityFraction) + foregroundPosition = disappearingPosition.mixed(with: foregroundPosition, fraction: visibilityFraction) + } else if let trimRangeUpperBound, timestamp > trimRangeUpperBound - apperanceDuration { + let visibilityFraction = 1.0 - max(0.0, min(1.0, (timestamp - trimRangeUpperBound) / apperanceDuration)) + if visibilityFraction.isZero { + isVisible = false + } + foregroundAlpha = Float(visibilityFraction) + foregroundPosition = disappearingPosition.mixed(with: foregroundPosition, fraction: visibilityFraction) } } if isVisible { + if let additionalVideoRemovalStartTimestamp { + let disappearingPosition = VideoPosition(position: foregroundPosition.position, size: foregroundPosition.size, scale: 0.01, rotation: foregroundPosition.rotation, baseScale: foregroundPosition.baseScale) + + let visibilityFraction = max(0.0, min(1.0, 1.0 - (CACurrentMediaTime() - additionalVideoRemovalStartTimestamp) / videoRemovalDuration)) + if visibilityFraction.isZero { + isVisible = false + } + foregroundAlpha = Float(visibilityFraction) + foregroundPosition = disappearingPosition.mixed(with: foregroundPosition, fraction: visibilityFraction) + } foregroundVideoState = VideoState(texture: foregroundTexture, textureRotation: foregroundTextureRotation, position: foregroundPosition, roundness: 1.0, alpha: foregroundAlpha) } } diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContainerScreen.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContainerScreen.swift index 96c0b8a7a0..694e57159d 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContainerScreen.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryContainerScreen.swift @@ -502,7 +502,7 @@ private final class StoryContainerScreenComponent: Component { } } longPressRecognizer.updatePanMove = { [weak self] initialLocation, translation in - guard let self else { + guard let self, self.itemSetPanState?.didBegin == false else { return } guard let stateValue = self.stateValue, let slice = stateValue.slice, let itemSetView = self.visibleItemSetViews[slice.peer.id], let itemSetComponentView = itemSetView.view.view as? StoryItemSetContainerComponent.View else { @@ -538,11 +538,7 @@ private final class StoryContainerScreenComponent: Component { let fraction = translation.x / (self.bounds.width / 2.0) timestamp = initialSeekTimestamp + duration * fraction } - if translation.y < 64.0 { - visibleItemView.seekTo(max(0.0, min(duration, timestamp)), apply: apply) - } else { - visibleItemView.seekTo(initialSeekTimestamp, apply: apply) - } + visibleItemView.seekTo(max(0.0, min(duration, timestamp)), apply: apply) } longPressRecognizer.updatePanEnded = { [weak self] in guard let self else { @@ -1124,15 +1120,16 @@ private final class StoryContainerScreenComponent: Component { } } + private var previousBackNavigationTime: Double? private func navigate(direction: StoryItemSetContainerComponent.NavigationDirection) { - guard let component = self.component, let environment = self.environment else { + guard let component = self.component, let environment = self.environment, let controller = environment.controller() as? StoryContainerScreen else { return } if let stateValue = self.stateValue, let slice = stateValue.slice { if case .next = direction, slice.nextItemId == nil, (slice.item.position == nil || slice.item.position == slice.totalCount - 1) { if stateValue.nextSlice == nil { - environment.controller()?.dismiss() + controller.dismiss() } else { self.beginHorizontalPan(translation: CGPoint()) self.updateHorizontalPan(translation: CGPoint()) @@ -1142,7 +1139,17 @@ private final class StoryContainerScreenComponent: Component { if stateValue.previousSlice == nil { if let itemSetView = self.visibleItemSetViews[slice.peer.id] { if let componentView = itemSetView.view.view as? StoryItemSetContainerComponent.View { - componentView.rewindCurrentItem() + if let customBackAction = controller.customBackAction { + let currentTime = CACurrentMediaTime() + if let previousBackNavigationTime = self.previousBackNavigationTime, currentTime - previousBackNavigationTime < 1.0 { + customBackAction() + } else { + self.previousBackNavigationTime = CACurrentMediaTime() + componentView.rewindCurrentItem() + } + } else { + componentView.rewindCurrentItem() + } } } } else { @@ -1943,6 +1950,8 @@ public class StoryContainerScreen: ViewControllerComponentContainer { return self.focusedItemPromise.get() } + public var customBackAction: (() -> Void)? + public init( context: AccountContext, content: StoryContentContext, diff --git a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift index 70b98a2b21..9bcf6235c7 100644 --- a/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift +++ b/submodules/TelegramUI/Components/Stories/StoryContainerScreen/Sources/StoryItemSetContainerComponent.swift @@ -1220,10 +1220,13 @@ public final class StoryItemSetContainerComponent: Component { self.state?.updated(transition: Transition(animation: .curve(duration: 0.4, curve: .spring))) } } else { + if let visibleItemView = self.visibleItems[component.slice.item.storyItem.id]?.view.view as? StoryItemContentComponent.View { + visibleItemView.seekEnded() + } if translation.y > 200.0 || (translation.y > 5.0 && velocity.y > 200.0) { self.state?.updated(transition: Transition(animation: .curve(duration: 0.3, curve: .spring))) self.component?.controller()?.dismiss() - } else if translation.y < -200.0 || (translation.y < -100.0 && velocity.y < -100.0) { + } else if translation.y < -200.0 || (translation.y < -100.0 && velocity.y < -100.0) { var displayViewLists = false if component.slice.peer.id == component.context.account.peerId { displayViewLists = true @@ -4218,13 +4221,45 @@ public final class StoryItemSetContainerComponent: Component { return component.controller() }, openStory: { [weak self] peer, story in - guard let self else { + guard let self, let component = self.component else { return } + let context = component.context + let peerId = component.slice.peer.id + let currentResult: ResolvedUrl = .story(peerId: peerId, id: component.slice.item.storyItem.id) + self.sendMessageContext.openResolved(view: self, result: .story(peerId: peer.id, id: story.id), completion: { [weak self] in guard let self, let controller = self.component?.controller() as? StoryContainerScreen else { return } + if let nextController = controller.navigationController?.viewControllers.last as? StoryContainerScreen { + nextController.customBackAction = { [weak nextController] in + context.sharedContext.openResolvedUrl( + currentResult, + context: context, + urlContext: .generic, + navigationController: nextController?.navigationController as? NavigationController, + forceExternal: false, + openPeer: { _, _ in + }, + sendFile: nil, + sendSticker: nil, + requestMessageActionUrlAuth: nil, + joinVoiceChat: nil, + present: { _, _ in + }, + dismissInput: { + }, + contentContext: nil, + progress: nil, + completion: { [weak nextController] in + Queue.mainQueue().after(0.5) { + nextController?.dismissWithoutTransitionOut() + } + } + ) + } + } Queue.mainQueue().after(0.5) { controller.dismissWithoutTransitionOut() }