diff --git a/submodules/DrawingUI/Sources/DrawingStickerEntityView.swift b/submodules/DrawingUI/Sources/DrawingStickerEntityView.swift index dfe7aec55c..5e21b7c124 100644 --- a/submodules/DrawingUI/Sources/DrawingStickerEntityView.swift +++ b/submodules/DrawingUI/Sources/DrawingStickerEntityView.swift @@ -363,6 +363,7 @@ public class DrawingStickerEntityView: DrawingEntityView { self.addSubview(cameraPreviewView) self.cameraPreviewView = cameraPreviewView + self.progressLayer.opacity = 1.0 self.progressLayer.transform = CATransform3DMakeRotation(-.pi / 2.0, 0.0, 0.0, 1.0) self.progressLayer.fillColor = UIColor.clear.cgColor self.progressLayer.strokeColor = UIColor(rgb: 0xffffff, alpha: 0.5).cgColor @@ -385,17 +386,38 @@ public class DrawingStickerEntityView: DrawingEntityView { guard let cameraPreviewView = self.cameraPreviewView else { return } - Queue.mainQueue().after(0.3, { + Queue.mainQueue().after(0.1, { self.cameraPreviewView = nil - cameraPreviewView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, removeOnCompletion: false, completion: { _ in - cameraPreviewView.removeFromSuperview() - }) + cameraPreviewView.removeFromSuperview() + + if let cameraSnapshotView = self.cameraSnapshotView { + self.cameraSnapshotView = nil + UIView.animate(withDuration: 0.25, animations: { + cameraSnapshotView.alpha = 0.0 + }, completion: { _ in + cameraSnapshotView.removeFromSuperview() + }) + } + }) + self.progressLayer.opacity = 0.0 + self.progressLayer.animateAlpha(from: 1.0, to: 0.0, duration: 0.2, completion: { _ in + self.progressLayer.removeFromSuperlayer() + self.progressLayer.path = nil }) - self.progressLayer.removeFromSuperlayer() - self.progressLayer.path = nil self.progressDisposable.set(nil) } + public func snapshotCameraPreviewView() { + guard let cameraPreviewView = self.cameraPreviewView else { + return + } + if let snapshot = cameraPreviewView.snapshotView(afterScreenUpdates: false) { + self.cameraSnapshotView = snapshot + self.addSubview(snapshot) + } + self.layer.addSublayer(self.progressLayer) + } + private var cameraBlurView: BlurView? private var cameraSnapshotView: UIView? public func beginCameraSwitch() { diff --git a/submodules/DrawingUI/Sources/VideoRecorder.swift b/submodules/DrawingUI/Sources/VideoRecorder.swift index 8c78d1cd03..6b24d5ec38 100644 --- a/submodules/DrawingUI/Sources/VideoRecorder.swift +++ b/submodules/DrawingUI/Sources/VideoRecorder.swift @@ -178,8 +178,12 @@ public final class EntityVideoRecorder { } if let entityView = entitiesView.getView(for: self.entity.uuid) as? DrawingStickerEntityView { - mediaEditor.onFirstAdditionalDisplay = { [weak entityView] in - entityView?.invalidateCameraPreviewView() + entityView.snapshotCameraPreviewView() + + mediaEditor.setOnNextAdditionalDisplay { [weak entityView] in + Queue.mainQueue().async { + entityView?.invalidateCameraPreviewView() + } } let entity = self.entity diff --git a/submodules/PremiumUI/Sources/PremiumIntroScreen.swift b/submodules/PremiumUI/Sources/PremiumIntroScreen.swift index ac8bbf1061..7e69004140 100644 --- a/submodules/PremiumUI/Sources/PremiumIntroScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumIntroScreen.swift @@ -630,6 +630,14 @@ struct PremiumIntroConfiguration { if perks.count < 4 { perks = PremiumIntroConfiguration.defaultValue.perks } + #if DEBUG + if !perks.contains(.wallpapers) { + perks.append(.wallpapers) + } + if !perks.contains(.colors) { + perks.append(.colors) + } + #endif return PremiumIntroConfiguration(perks: perks) } else { return .defaultValue @@ -1355,7 +1363,7 @@ final class PerkComponent: CombinedComponent { let badgeWidth = badgeText.size.width + 7.0 let badgeBackground = badgeBackground.update( component: RoundedRectangle( - colors: [component.accentColor], + colors: component.iconBackgroundColors, cornerRadius: 5.0, gradientDirection: .vertical), availableSize: CGSize(width: badgeWidth, height: 16.0), @@ -1566,12 +1574,21 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent { }) - self.newPerksDisposable = (ApplicationSpecificNotice.dismissedPremiumAppIconsBadge(accountManager: context.sharedContext.accountManager) - |> deliverOnMainQueue).startStrict(next: { [weak self] dismissedPremiumAppIconsBadge in + self.newPerksDisposable = combineLatest(queue: Queue.mainQueue(), + ApplicationSpecificNotice.dismissedPremiumAppIconsBadge(accountManager: context.sharedContext.accountManager), + ApplicationSpecificNotice.dismissedPremiumWallpapersBadge(accountManager: context.sharedContext.accountManager), + ApplicationSpecificNotice.dismissedPremiumColorsBadge(accountManager: context.sharedContext.accountManager) + ).startStrict(next: { [weak self] dismissedPremiumAppIconsBadge, dismissedPremiumWallpapersBadge, dismissedPremiumColorsBadge in guard let self else { return } - let newPerks: [String] = [] + var newPerks: [String] = [] + if !dismissedPremiumWallpapersBadge { + newPerks.append(PremiumPerk.wallpapers.identifier) + } + if !dismissedPremiumColorsBadge { + newPerks.append(PremiumPerk.colors.identifier) + } self.newPerks = newPerks self.updated() }) @@ -1915,8 +1932,10 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent { demoSubject = .stories case .colors: demoSubject = .colors + let _ = ApplicationSpecificNotice.setDismissedPremiumColorsBadge(accountManager: accountContext.sharedContext.accountManager).startStandalone() case .wallpapers: demoSubject = .wallpapers + let _ = ApplicationSpecificNotice.setDismissedPremiumWallpapersBadge(accountManager: accountContext.sharedContext.accountManager).startStandalone() } let isPremium = state?.isPremium == true diff --git a/submodules/PremiumUI/Sources/PremiumLimitsListScreen.swift b/submodules/PremiumUI/Sources/PremiumLimitsListScreen.swift index 9e6ffe1660..cdf8b1294e 100644 --- a/submodules/PremiumUI/Sources/PremiumLimitsListScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumLimitsListScreen.swift @@ -668,7 +668,6 @@ public class PremiumLimitsListScreen: ViewController { ) ) ) - availableItems[.animatedEmoji] = DemoPagerComponent.Item( AnyComponentWithIdentity( id: PremiumDemoScreen.Subject.animatedEmoji, @@ -687,7 +686,6 @@ public class PremiumLimitsListScreen: ViewController { ) ) ) - availableItems[.translation] = DemoPagerComponent.Item( AnyComponentWithIdentity( id: PremiumDemoScreen.Subject.translation, @@ -707,6 +705,42 @@ public class PremiumLimitsListScreen: ViewController { ) ) ) + availableItems[.colors] = DemoPagerComponent.Item( + AnyComponentWithIdentity( + id: PremiumDemoScreen.Subject.colors, + component: AnyComponent( + PageComponent( + content: AnyComponent(PhoneDemoComponent( + context: context, + position: .top, + videoFile: configuration.videos["colors"], + decoration: .badgeStars + )), + title: strings.Premium_Colors, + text: strings.Premium_ColorsInfo, + textColor: textColor + ) + ) + ) + ) + availableItems[.wallpapers] = DemoPagerComponent.Item( + AnyComponentWithIdentity( + id: PremiumDemoScreen.Subject.wallpapers, + component: AnyComponent( + PageComponent( + content: AnyComponent(PhoneDemoComponent( + context: context, + position: .top, + videoFile: configuration.videos["wallpapers"], + decoration: .swirlStars + )), + title: strings.Premium_Wallpapers, + text: strings.Premium_WallpapersInfo, + textColor: textColor + ) + ) + ) + ) if let order = controller.order { var items: [DemoPagerComponent.Item] = order.compactMap { availableItems[$0] } diff --git a/submodules/TelegramNotices/Sources/Notices.swift b/submodules/TelegramNotices/Sources/Notices.swift index 812bae542c..800d91231e 100644 --- a/submodules/TelegramNotices/Sources/Notices.swift +++ b/submodules/TelegramNotices/Sources/Notices.swift @@ -185,6 +185,8 @@ private enum ApplicationSpecificGlobalNotice: Int32 { case displayStoryInteractionGuide = 51 case dismissedPremiumAppIconsBadge = 52 case replyQuoteTextSelectionTip = 53 + case dismissedPremiumWallpapersBadge = 54 + case dismissedPremiumColorsBadge = 55 var key: ValueBoxKey { let v = ValueBoxKey(length: 4) @@ -450,10 +452,15 @@ private struct ApplicationSpecificNoticeKeys { static func dismissedPremiumAppIconsBadge() -> NoticeEntryKey { return NoticeEntryKey(namespace: noticeNamespace(namespace: globalNamespace), key: ApplicationSpecificGlobalNotice.dismissedPremiumAppIconsBadge.key) } - static func replyQuoteTextSelectionTip() -> NoticeEntryKey { return NoticeEntryKey(namespace: noticeNamespace(namespace: globalNamespace), key: ApplicationSpecificGlobalNotice.replyQuoteTextSelectionTip.key) } + static func dismissedPremiumWallpapersBadge() -> NoticeEntryKey { + return NoticeEntryKey(namespace: noticeNamespace(namespace: globalNamespace), key: ApplicationSpecificGlobalNotice.dismissedPremiumWallpapersBadge.key) + } + static func dismissedPremiumColorsBadge() -> NoticeEntryKey { + return NoticeEntryKey(namespace: noticeNamespace(namespace: globalNamespace), key: ApplicationSpecificGlobalNotice.dismissedPremiumColorsBadge.key) + } } public struct ApplicationSpecificNotice { @@ -1772,4 +1779,46 @@ public struct ApplicationSpecificNotice { } |> take(1) } + + public static func setDismissedPremiumWallpapersBadge(accountManager: AccountManager) -> Signal { + return accountManager.transaction { transaction -> Void in + if let entry = CodableEntry(ApplicationSpecificBoolNotice()) { + transaction.setNotice(ApplicationSpecificNoticeKeys.dismissedPremiumWallpapersBadge(), entry) + } + } + |> ignoreValues + } + + public static func dismissedPremiumWallpapersBadge(accountManager: AccountManager) -> Signal { + return accountManager.noticeEntry(key: ApplicationSpecificNoticeKeys.dismissedPremiumWallpapersBadge()) + |> map { view -> Bool in + if let _ = view.value?.get(ApplicationSpecificBoolNotice.self) { + return true + } else { + return false + } + } + |> take(1) + } + + public static func setDismissedPremiumColorsBadge(accountManager: AccountManager) -> Signal { + return accountManager.transaction { transaction -> Void in + if let entry = CodableEntry(ApplicationSpecificBoolNotice()) { + transaction.setNotice(ApplicationSpecificNoticeKeys.dismissedPremiumColorsBadge(), entry) + } + } + |> ignoreValues + } + + public static func dismissedPremiumColorsBadge(accountManager: AccountManager) -> Signal { + return accountManager.noticeEntry(key: ApplicationSpecificNoticeKeys.dismissedPremiumColorsBadge()) + |> map { view -> Bool in + if let _ = view.value?.get(ApplicationSpecificBoolNotice.self) { + return true + } else { + return false + } + } + |> take(1) + } } diff --git a/submodules/TelegramUI/Components/MediaEditor/Sources/MediaEditor.swift b/submodules/TelegramUI/Components/MediaEditor/Sources/MediaEditor.swift index badc0010c4..f8d94d5e59 100644 --- a/submodules/TelegramUI/Components/MediaEditor/Sources/MediaEditor.swift +++ b/submodules/TelegramUI/Components/MediaEditor/Sources/MediaEditor.swift @@ -261,7 +261,6 @@ public final class MediaEditor { } public var onFirstDisplay: () -> Void = {} - public var onFirstAdditionalDisplay: () -> Void = {} public func playerState(framesCount: Int) -> Signal { func artistAndTitleForTrack(_ audioTrack: MediaAudioTrack) -> (artist: String?, title: String?) {