diff --git a/Telegram/BUILD b/Telegram/BUILD index d1f58bd9f1..f5b00ade87 100644 --- a/Telegram/BUILD +++ b/Telegram/BUILD @@ -1820,7 +1820,8 @@ ios_application( ], ) -# a temporary target used to simplify webrtc build tests +# Temporary targets used to simplify webrtc build tests + ios_application( name = "webrtc_build_test", bundle_id = "{telegram_bundle_id}".format( @@ -1843,3 +1844,26 @@ ios_application( "//third-party/webrtc:webrtc_lib", ], ) + +ios_application( + name = "libvpx_build_test", + bundle_id = "{telegram_bundle_id}".format( + telegram_bundle_id = telegram_bundle_id, + ), + families = ["iphone", "ipad"], + minimum_os_version = "9.0", + provisioning_profile = select({ + ":disableProvisioningProfilesSetting": None, + "//conditions:default": "@build_configuration//provisioning:Telegram.mobileprovision", + }), + entitlements = ":TelegramEntitlements.entitlements", + infoplists = [ + ":TelegramInfoPlist", + ":BuildNumberInfoPlist", + ":VersionInfoPlist", + ":UrlTypesInfoPlist", + ], + deps = [ + "//third-party/libvpx:vpx", + ], +) diff --git a/submodules/AccountContext/Sources/AccountContext.swift b/submodules/AccountContext/Sources/AccountContext.swift index 7f2652cf5c..0650e11e07 100644 --- a/submodules/AccountContext/Sources/AccountContext.swift +++ b/submodules/AccountContext/Sources/AccountContext.swift @@ -154,9 +154,9 @@ public struct ChatAvailableMessageActions { } public enum WallpaperUrlParameter { - case slug(String, WallpaperPresentationOptions, UIColor?, UIColor?, Int32?, Int32?) + case slug(String, WallpaperPresentationOptions, [UInt32], Int32?, Int32?) case color(UIColor) - case gradient(UIColor, UIColor, Int32?) + case gradient([UInt32], Int32?) } public enum ResolvedUrlSettingsSection { diff --git a/submodules/AccountContext/Sources/PresentationCallManager.swift b/submodules/AccountContext/Sources/PresentationCallManager.swift index 11f058ac56..b7bf2b0dcf 100644 --- a/submodules/AccountContext/Sources/PresentationCallManager.swift +++ b/submodules/AccountContext/Sources/PresentationCallManager.swift @@ -109,6 +109,7 @@ public final class PresentationCallVideoView { public let getAspect: () -> CGFloat public let setOnOrientationUpdated: (((Orientation, CGFloat) -> Void)?) -> Void public let setOnIsMirroredUpdated: (((Bool) -> Void)?) -> Void + public let updateIsEnabled: (Bool) -> Void public init( holder: AnyObject, @@ -117,7 +118,8 @@ public final class PresentationCallVideoView { getOrientation: @escaping () -> Orientation, getAspect: @escaping () -> CGFloat, setOnOrientationUpdated: @escaping (((Orientation, CGFloat) -> Void)?) -> Void, - setOnIsMirroredUpdated: @escaping (((Bool) -> Void)?) -> Void + setOnIsMirroredUpdated: @escaping (((Bool) -> Void)?) -> Void, + updateIsEnabled: @escaping (Bool) -> Void ) { self.holder = holder self.view = view @@ -126,6 +128,7 @@ public final class PresentationCallVideoView { self.getAspect = getAspect self.setOnOrientationUpdated = setOnOrientationUpdated self.setOnIsMirroredUpdated = setOnIsMirroredUpdated + self.updateIsEnabled = updateIsEnabled } } diff --git a/submodules/Display/Source/NavigationBar.swift b/submodules/Display/Source/NavigationBar.swift index 1d9a359e8e..d6a788760c 100644 --- a/submodules/Display/Source/NavigationBar.swift +++ b/submodules/Display/Source/NavigationBar.swift @@ -1132,12 +1132,18 @@ open class NavigationBar: ASDisplayNode { if let titleView = self.titleView { let titleSize = CGSize(width: max(1.0, size.width - max(leftTitleInset, rightTitleInset) * 2.0), height: nominalHeight) let titleFrame = CGRect(origin: CGPoint(x: floor((size.width - titleSize.width) / 2.0), y: contentVerticalOrigin + floorToScreenPixels((nominalHeight - titleSize.height) / 2.0)), size: titleSize) - transition.updateFrame(view: titleView, frame: titleFrame) + var titleViewTransition = transition + if titleView.frame.isEmpty { + titleViewTransition = .immediate + titleView.frame = titleFrame + } + + titleViewTransition.updateFrame(view: titleView, frame: titleFrame) if let titleView = titleView as? NavigationBarTitleView { let titleWidth = size.width - (leftTitleInset > 0.0 ? leftTitleInset : rightTitleInset) - (rightTitleInset > 0.0 ? rightTitleInset : leftTitleInset) - titleView.updateLayout(size: titleFrame.size, clearBounds: CGRect(origin: CGPoint(x: leftTitleInset - titleFrame.minX, y: 0.0), size: CGSize(width: titleWidth, height: titleFrame.height)), transition: transition) + titleView.updateLayout(size: titleFrame.size, clearBounds: CGRect(origin: CGPoint(x: leftTitleInset - titleFrame.minX, y: 0.0), size: CGSize(width: titleWidth, height: titleFrame.height)), transition: titleViewTransition) } if let transitionState = self.transitionState, let otherNavigationBar = transitionState.navigationBar { diff --git a/submodules/GalleryUI/Sources/GalleryControllerNode.swift b/submodules/GalleryUI/Sources/GalleryControllerNode.swift index 314dbb9b5d..f5905c7910 100644 --- a/submodules/GalleryUI/Sources/GalleryControllerNode.swift +++ b/submodules/GalleryUI/Sources/GalleryControllerNode.swift @@ -275,6 +275,7 @@ open class GalleryControllerNode: ASDisplayNode, UIScrollViewDelegate, UIGesture } self.pager.frame = CGRect(origin: CGPoint(x: 0.0, y: layout.size.height), size: layout.size) + self.pager.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: transition) } diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryController.swift b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryController.swift index 18f78b4645..26964a166e 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryController.swift +++ b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryController.swift @@ -25,8 +25,8 @@ public enum WallpaperListType { public enum WallpaperListSource { case list(wallpapers: [TelegramWallpaper], central: TelegramWallpaper, type: WallpaperListType) - case wallpaper(TelegramWallpaper, WallpaperPresentationOptions?, UIColor?, UIColor?, Int32?, Int32?, Message?) - case slug(String, TelegramMediaFile?, WallpaperPresentationOptions?, UIColor?, UIColor?, Int32?, Int32?, Message?) + case wallpaper(TelegramWallpaper, WallpaperPresentationOptions?, [UInt32], Int32?, Int32?, Message?) + case slug(String, TelegramMediaFile?, WallpaperPresentationOptions?, [UInt32], Int32?, Int32?, Message?) case asset(PHAsset) case contextResult(ChatContextResult) case customColor(UInt32?) @@ -131,42 +131,30 @@ class WallpaperGalleryControllerNode: GalleryControllerNode { } } -private func updatedFileWallpaper(wallpaper: TelegramWallpaper, firstColor: UIColor?, secondColor: UIColor?, intensity: Int32?, rotation: Int32?) -> TelegramWallpaper { +private func updatedFileWallpaper(wallpaper: TelegramWallpaper, colors: [UInt32], intensity: Int32?, rotation: Int32?) -> TelegramWallpaper { if case let .file(file) = wallpaper { - return updatedFileWallpaper(id: file.id, accessHash: file.accessHash, slug: file.slug, file: file.file, firstColor: firstColor, secondColor: secondColor, intensity: intensity, rotation: rotation) + return updatedFileWallpaper(id: file.id, accessHash: file.accessHash, slug: file.slug, file: file.file, colors: colors, intensity: intensity, rotation: rotation) } else { return wallpaper } } -private func updatedFileWallpaper(id: Int64? = nil, accessHash: Int64? = nil, slug: String, file: TelegramMediaFile, firstColor: UIColor?, secondColor: UIColor?, intensity: Int32?, rotation: Int32?) -> TelegramWallpaper { +private func updatedFileWallpaper(id: Int64? = nil, accessHash: Int64? = nil, slug: String, file: TelegramMediaFile, colors: [UInt32], intensity: Int32?, rotation: Int32?) -> TelegramWallpaper { var isPattern = ["image/png", "image/svg+xml", "application/x-tgwallpattern"].contains(file.mimeType) if let fileName = file.fileName, fileName.hasSuffix(".svgbg") { isPattern = true } - var firstColorValue: UInt32? - var secondColorValue: UInt32? + var colorValues: [UInt32] = [] var intensityValue: Int32? - if let firstColor = firstColor { - firstColorValue = firstColor.argb - intensityValue = intensity - } else if isPattern { - firstColorValue = 0xd6e2ee + if !colors.isEmpty { + colorValues = colors + intensityValue = intensity ?? 50 + } else { + colorValues = [0xd6e2ee] intensityValue = 50 } - if let secondColor = secondColor { - secondColorValue = secondColor.argb - } - - var colors: [UInt32] = [] - if let firstColorValue = firstColorValue { - colors.append(firstColorValue) - } - if let secondColorValue = secondColorValue { - colors.append(secondColorValue) - } - return .file(id: id ?? 0, accessHash: accessHash ?? 0, isCreator: false, isDefault: false, isPattern: isPattern, isDark: false, slug: slug, file: file, settings: WallpaperSettings(colors: colors, intensity: intensityValue, rotation: rotation)) + return .file(id: id ?? 0, accessHash: accessHash ?? 0, isCreator: false, isDefault: false, isPattern: isPattern, isDark: false, slug: slug, file: file, settings: WallpaperSettings(colors: colorValues, intensity: intensityValue, rotation: rotation)) } public class WallpaperGalleryController: ViewController { @@ -234,15 +222,15 @@ public class WallpaperGalleryController: ViewController { if case let .wallpapers(wallpaperOptions) = type, let options = wallpaperOptions { self.initialOptions = options } - case let .slug(slug, file, options, firstColor, secondColor, intensity, rotation, message): + case let .slug(slug, file, options, colors, intensity, rotation, message): if let file = file { - let wallpaper = updatedFileWallpaper(slug: slug, file: file, firstColor: firstColor, secondColor: secondColor, intensity: intensity, rotation: rotation) + let wallpaper = updatedFileWallpaper(slug: slug, file: file, colors: colors, intensity: intensity, rotation: rotation) entries = [.wallpaper(wallpaper, message)] centralEntryIndex = 0 self.initialOptions = options } - case let .wallpaper(wallpaper, options, firstColor, secondColor, intensity, rotation, message): - let wallpaper = updatedFileWallpaper(wallpaper: wallpaper, firstColor: firstColor, secondColor: secondColor, intensity: intensity, rotation: rotation) + case let .wallpaper(wallpaper, options, colors, intensity, rotation, message): + let wallpaper = updatedFileWallpaper(wallpaper: wallpaper, colors: colors, intensity: intensity, rotation: rotation) entries = [.wallpaper(wallpaper, message)] centralEntryIndex = 0 self.initialOptions = options @@ -327,7 +315,7 @@ public class WallpaperGalleryController: ViewController { self.navigationBar?.updatePresentationData(NavigationBarPresentationData(presentationData: self.presentationData)) self.toolbarNode?.updateThemeAndStrings(theme: self.presentationData.theme, strings: self.presentationData.strings) self.patternPanelNode?.updateTheme(self.presentationData.theme) - self.patternPanelNode?.backgroundColors = self.presentationData.theme.overallDarkAppearance ? ([self.presentationData.theme.list.blocksBackgroundColor.rgb], nil) : nil + //self.patternPanelNode?.backgroundColors = self.presentationData.theme.overallDarkAppearance ? ([self.presentationData.theme.list.blocksBackgroundColor.rgb], nil) : nil self.colorsPanelNode?.updateTheme(self.presentationData.theme) } @@ -452,7 +440,7 @@ public class WallpaperGalleryController: ViewController { let completion: (TelegramWallpaper) -> Void = { wallpaper in let baseSettings = wallpaper.settings - let updatedSettings = WallpaperSettings(blur: options.contains(.blur), motion: options.contains(.motion), colors: baseSettings?.colors ?? [], intensity: baseSettings?.intensity) + let updatedSettings = WallpaperSettings(blur: options.contains(.blur), motion: options.contains(.motion), colors: baseSettings?.colors ?? [], intensity: baseSettings?.intensity, rotation: baseSettings?.rotation) let wallpaper = wallpaper.withUpdatedSettings(updatedSettings) let autoNightModeTriggered = strongSelf.presentationData.autoNightModeTriggered @@ -613,14 +601,34 @@ public class WallpaperGalleryController: ViewController { strongSelf.colorsPanelEnabled = false strongSelf.patternInitialWallpaper = enabled ? initialWallpaper : nil + switch initialWallpaper { + case let .color(color): + strongSelf.patternPanelNode?.backgroundColors = ([color], nil) + case let .gradient(colors, settings): + strongSelf.patternPanelNode?.backgroundColors = (colors, settings.rotation) + case let .file(file) where file.isPattern: + strongSelf.patternPanelNode?.backgroundColors = (file.settings.colors, file.settings.rotation) + default: + break + } + strongSelf.patternPanelNode?.serviceBackgroundColor = serviceColor(for: (initialWallpaper, nil)) strongSelf.patternPanelEnabled = enabled strongSelf.galleryNode.scrollView.isScrollEnabled = !enabled if enabled { + strongSelf.patternPanelNode?.updateWallpapers() strongSelf.patternPanelNode?.didAppear() } else { switch initialWallpaper { - case .color: - strongSelf.updateEntries(pattern: .color(0), preview: false) + case .color, .gradient: + strongSelf.updateEntries(wallpaper: initialWallpaper) + case let .file(file): + if !file.settings.colors.isEmpty { + if file.settings.colors.count >= 2 { + strongSelf.updateEntries(wallpaper: .gradient(file.settings.colors, WallpaperSettings(rotation: file.settings.rotation))) + } else { + strongSelf.updateEntries(wallpaper: .color(file.settings.colors[0])) + } + } default: break } @@ -652,6 +660,15 @@ public class WallpaperGalleryController: ViewController { strongSelf.containerLayoutUpdated(layout, transition: .animated(duration: 0.3, curve: .spring)) } } + + node.requestRotateGradient = { [weak self] angle in + guard let strongSelf = self, let _ = strongSelf.validLayout, let entry = strongSelf.currentEntry(), case let .wallpaper(wallpaper, _) = entry else { + return + } + var settings = wallpaper.settings ?? WallpaperSettings() + settings.rotation = angle + strongSelf.updateEntries(wallpaper: wallpaper.withUpdatedSettings(settings)) + } if let entry = self.currentEntry(), case let .wallpaper(wallpaper, _) = entry, case let .file(_, _, _, _, true, _, _, _ , settings) = wallpaper, !settings.colors.isEmpty { if self.patternPanelNode?.backgroundColors != nil, let snapshotView = self.patternPanelNode?.scrollNode.view.snapshotContentTree() { @@ -660,7 +677,7 @@ public class WallpaperGalleryController: ViewController { snapshotView?.removeFromSuperview() } } - self.patternPanelNode?.backgroundColors = ([settings.colors[0]], nil) + //self.patternPanelNode?.backgroundColors = ([settings.colors[0]], nil) } } } @@ -711,23 +728,30 @@ public class WallpaperGalleryController: ViewController { private func updateEntries(pattern: TelegramWallpaper?, intensity: Int32? = nil, preview: Bool = false) { var updatedEntries: [WallpaperGalleryEntry] = [] for entry in self.entries { - var entryColor: UInt32? + var entryColors: [UInt32] = [] if case let .wallpaper(wallpaper, _) = entry { if case let .color(color) = wallpaper { - entryColor = color - } else if case let .file(file) = wallpaper { - entryColor = file.settings.colors.first + entryColors = [color] + } else if case let .file(file) = wallpaper, file.isPattern { + entryColors = file.settings.colors + } else if case let .gradient(colors, _) = wallpaper { + entryColors = colors } } - if let entryColor = entryColor { + if !entryColors.isEmpty { if let pattern = pattern, case let .file(file) = pattern { - let newSettings = WallpaperSettings(blur: file.settings.blur, motion: file.settings.motion, colors: [entryColor], intensity: intensity) + let newSettings = WallpaperSettings(blur: file.settings.blur, motion: file.settings.motion, colors: entryColors, intensity: intensity) let newWallpaper = TelegramWallpaper.file(id: file.id, accessHash: file.accessHash, isCreator: file.isCreator, isDefault: file.isDefault, isPattern: pattern.isPattern, isDark: file.isDark, slug: file.slug, file: file.file, settings: newSettings) updatedEntries.append(.wallpaper(newWallpaper, nil)) } else { - let newWallpaper = TelegramWallpaper.color(entryColor) - updatedEntries.append(.wallpaper(newWallpaper, nil)) + if entryColors.count == 1 { + let newWallpaper = TelegramWallpaper.color(entryColors[0]) + updatedEntries.append(.wallpaper(newWallpaper, nil)) + } else { + let newWallpaper = TelegramWallpaper.gradient(entryColors, WallpaperSettings(rotation: nil)) + updatedEntries.append(.wallpaper(newWallpaper, nil)) + } } } } @@ -742,9 +766,17 @@ public class WallpaperGalleryController: ViewController { let hadLayout = self.validLayout != nil super.containerLayoutUpdated(layout, transition: transition) + + let panelHeight: CGFloat = 235.0 + + var pagerLayout = layout + if self.patternPanelEnabled || self.colorsPanelEnabled { + pagerLayout.intrinsicInsets.bottom += panelHeight + } + pagerLayout.intrinsicInsets.bottom = max(pagerLayout.intrinsicInsets.bottom, layout.inputHeight ?? 0.0) self.galleryNode.frame = CGRect(origin: CGPoint(), size: layout.size) - self.galleryNode.containerLayoutUpdated(layout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition) + self.galleryNode.containerLayoutUpdated(pagerLayout, navigationBarHeight: self.navigationLayout(layout: layout).navigationFrame.maxY, transition: transition) self.overlayNode?.frame = self.galleryNode.bounds transition.updateFrame(node: self.toolbarNode!, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - 49.0 - layout.intrinsicInsets.bottom), size: CGSize(width: layout.size.width, height: 49.0 + layout.intrinsicInsets.bottom))) @@ -760,7 +792,7 @@ public class WallpaperGalleryController: ViewController { patternPanelNode.patternChanged = { [weak self] pattern, intensity, preview in if let strongSelf = self, strongSelf.validLayout != nil, let patternInitialWallpaper = strongSelf.patternInitialWallpaper { switch patternInitialWallpaper { - case .color: + case .color, .file, .gradient: strongSelf.updateEntries(pattern: pattern, intensity: intensity, preview: preview) default: break @@ -799,12 +831,10 @@ public class WallpaperGalleryController: ViewController { strongSelf.updateEntries(wallpaper: wallpaper) } } - - let panelHeight: CGFloat = 235.0 var patternPanelFrame = CGRect(x: 0.0, y: layout.size.height, width: layout.size.width, height: panelHeight) if self.patternPanelEnabled { - patternPanelFrame.origin = CGPoint(x: 0.0, y: layout.size.height - bottomInset - panelHeight) + patternPanelFrame.origin = CGPoint(x: 0.0, y: layout.size.height - max((layout.inputHeight ?? 0.0) - panelHeight + 44.0, bottomInset) - panelHeight) bottomInset += panelHeight } @@ -813,7 +843,7 @@ public class WallpaperGalleryController: ViewController { var colorsPanelFrame = CGRect(x: 0.0, y: layout.size.height, width: layout.size.width, height: panelHeight) if self.colorsPanelEnabled { - colorsPanelFrame.origin = CGPoint(x: 0.0, y: layout.size.height - bottomInset - panelHeight) + colorsPanelFrame.origin = CGPoint(x: 0.0, y: layout.size.height - max((layout.inputHeight ?? 0.0) - panelHeight + 44.0, bottomInset) - panelHeight) bottomInset += panelHeight } @@ -879,8 +909,17 @@ public class WallpaperGalleryController: ViewController { case let .file(_, _, _, _, isPattern, _, slug, _, settings): if isPattern { if !settings.colors.isEmpty { - if settings.colors.count >= 2 { + if settings.colors.count == 2 { options.append("bg_color=\(UIColor(rgb: settings.colors[0]).hexString)-\(UIColor(rgb: settings.colors[1]).hexString)") + } else if settings.colors.count >= 3 { + var colorsString = "" + for color in settings.colors { + if !colorsString.isEmpty { + colorsString.append("~") + } + colorsString.append(UIColor(rgb: color).hexString) + } + options.append("bg_color=\(colorsString)") } else { options.append("bg_color=\(UIColor(rgb: settings.colors[0]).hexString)") } @@ -902,7 +941,20 @@ public class WallpaperGalleryController: ViewController { case let .color(color): controller = ShareController(context: context, subject: .url("https://t.me/bg/\(UIColor(rgb: color).hexString)")) case let .gradient(colors, _): - controller = ShareController(context: context, subject:. url("https://t.me/bg/\(UIColor(rgb: colors[0]).hexString)-\(UIColor(rgb: colors[1]).hexString)")) + var colorsString = "" + + for color in colors { + if !colorsString.isEmpty { + if colors.count >= 3 { + colorsString.append("~") + } else { + colorsString.append("-") + } + } + colorsString.append(UIColor(rgb: color).hexString) + } + + controller = ShareController(context: context, subject:. url("https://t.me/bg/\(colorsString)")) default: break } diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift index d14fdba6d6..754cdb3a36 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift +++ b/submodules/SettingsUI/Sources/Themes/WallpaperGalleryItem.swift @@ -116,11 +116,15 @@ final class WallpaperGalleryItemNode: GalleryItemNode { var action: (() -> Void)? var requestPatternPanel: ((Bool, TelegramWallpaper) -> Void)? var requestColorsPanel: (([UIColor]?) -> Void)? + var requestRotateGradient: ((Int32) -> Void)? private var validLayout: (ContainerViewLayout, CGFloat)? private var validOffset: CGFloat? private var initialWallpaper: TelegramWallpaper? + + private let playButtonPlayImage: UIImage? + private let playButtonRotateImage: UIImage? init(context: AccountContext) { self.context = context @@ -151,7 +155,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode { self.colorsButtonNode = WallpaperOptionButtonNode(title: self.presentationData.strings.WallpaperPreview_WallpaperColors, value: .colors(false, [.clear])) self.playButtonNode = HighlightableButtonNode() - self.playButtonNode.setImage(generateImage(CGSize(width: 48.0, height: 48.0), rotatedContext: { size, context in + self.playButtonPlayImage = generateImage(CGSize(width: 48.0, height: 48.0), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) context.setFillColor(UIColor.white.cgColor) @@ -174,7 +178,11 @@ final class WallpaperGalleryItemNode: GalleryItemNode { context.translateBy(x: -size.width / 2.0, y: -size.height / 2.0) } context.translateBy(x: -(diameter - size.width) / 2.0 - 1.5, y: -(diameter - size.height) / 2.0) - }), for: []) + }) + + self.playButtonRotateImage = generateTintedImage(image: UIImage(bundleImageName: "Settings/ThemeColorRotateIcon"), color: .white) + + self.playButtonNode.setImage(self.playButtonPlayImage, for: []) super.init() @@ -250,8 +258,8 @@ final class WallpaperGalleryItemNode: GalleryItemNode { if previousEntry != entry { self.preparePatternEditing() } - - self.patternButtonNode.isSelected = self.arguments.patternEnabled + + self.colorsButtonNode.colors = self.calculateGradientColors() ?? defaultBuiltinWallpaperGradientColors let imagePromise = Promise() @@ -274,14 +282,35 @@ final class WallpaperGalleryItemNode: GalleryItemNode { switch entry { case let .wallpaper(wallpaper, _): - if case let .file(_, _, _, _, isPattern, _, _, _, settings) = wallpaper, isPattern, settings.colors.count >= 3 { + if case let .file(_, _, _, _, isPattern, _, _, _, settings) = wallpaper, isPattern { self.nativeNode.isHidden = false self.nativeNode.update(wallpaper: wallpaper) + self.patternButtonNode.isSelected = isPattern + + if isPattern && settings.colors.count >= 3 { + self.playButtonNode.setImage(self.playButtonPlayImage, for: []) + } else { + self.playButtonNode.setImage(self.playButtonRotateImage, for: []) + } + } else if case let .gradient(colors, _) = wallpaper { + self.nativeNode.isHidden = false + self.nativeNode.update(wallpaper: wallpaper) + self.patternButtonNode.isSelected = false + + if colors.count >= 3 { + self.playButtonNode.setImage(self.playButtonPlayImage, for: []) + } else { + self.playButtonNode.setImage(self.playButtonRotateImage, for: []) + } } else { self.nativeNode.isHidden = true + self.patternButtonNode.isSelected = false + self.playButtonNode.setImage(self.playButtonRotateImage, for: []) } default: self.nativeNode.isHidden = true + self.patternButtonNode.isSelected = false + self.playButtonNode.setImage(self.playButtonRotateImage, for: []) } switch entry { @@ -311,7 +340,11 @@ final class WallpaperGalleryItemNode: GalleryItemNode { case let .gradient(colors, settings): displaySize = CGSize(width: 1.0, height: 1.0) contentSize = displaySize - signal = gradientImage([UIColor(rgb: colors[0]), UIColor(rgb: colors[1])], rotation: settings.rotation) + if colors.count >= 2 { + signal = gradientImage([UIColor(rgb: colors[0]), UIColor(rgb: colors[1])], rotation: settings.rotation) + } else { + signal = solidColorImage(UIColor(rgb: colors[0])) + } fetchSignal = .complete() statusSignal = .single(.Local) subtitleSignal = .single(nil) @@ -319,10 +352,6 @@ final class WallpaperGalleryItemNode: GalleryItemNode { colorSignal = chatServiceBackgroundColor(wallpaper: wallpaper, mediaBox: self.context.account.postbox.mediaBox) isBlurrable = false case let .file(file): - let gradientColors = self.calculateGradientColors() ?? defaultBuiltinWallpaperGradientColors - - self.colorsButtonNode.colors = gradientColors - let dimensions = file.file.dimensions ?? PixelDimensions(width: 2000, height: 4000) contentSize = dimensions.cgSize displaySize = dimensions.cgSize.dividedByScreenScale().integralFloor @@ -738,12 +767,20 @@ final class WallpaperGalleryItemNode: GalleryItemNode { switch entry { case let .wallpaper(wallpaper, _): switch wallpaper { - case let .file(_, _, _, _, _, _, _, _, settings): - if settings.colors.count >= 3 { - return settings.colors.map(UIColor.init(rgb:)) + case let .file(_, _, _, _, isPattern, _, _, _, settings): + if isPattern { + if settings.colors.isEmpty { + return nil + } else { + return settings.colors.map(UIColor.init(rgb:)) + } } else { return nil } + case let .gradient(colors, _): + return colors.map(UIColor.init(rgb:)) + case let .color(color): + return [UIColor(rgb: color)] default: return nil } @@ -763,7 +800,29 @@ final class WallpaperGalleryItemNode: GalleryItemNode { } @objc private func togglePlay() { - self.nativeNode.animateEvent(transition: .animated(duration: 0.5, curve: .spring)) + guard let entry = self.entry, case let .wallpaper(wallpaper, _) = entry else { + return + } + switch wallpaper { + case let .gradient(colors, settings): + if colors.count >= 3 { + self.nativeNode.animateEvent(transition: .animated(duration: 0.5, curve: .spring)) + } else { + let rotation = settings.rotation ?? 0 + self.requestRotateGradient?((rotation + 90) % 360) + } + case let .file(file): + if file.isPattern { + if file.settings.colors.count >= 3 { + self.nativeNode.animateEvent(transition: .animated(duration: 0.5, curve: .spring)) + } else { + let rotation = file.settings.rotation ?? 0 + self.requestRotateGradient?((rotation + 90) % 360) + } + } + default: + break + } } private func preparePatternEditing() { @@ -837,12 +896,12 @@ final class WallpaperGalleryItemNode: GalleryItemNode { let buttonSize = CGSize(width: maxButtonWidth, height: 30.0) let alpha = 1.0 - min(1.0, max(0.0, abs(offset.y) / 50.0)) - var additionalYOffset: CGFloat = 0.0 - if self.patternButtonNode.isSelected { + let additionalYOffset: CGFloat = 0.0 + /*if self.patternButtonNode.isSelected { additionalYOffset = -235.0 } else if self.colorsButtonNode.isSelected { additionalYOffset = -235.0 - } + }*/ let leftButtonFrame = CGRect(origin: CGPoint(x: floor(layout.size.width / 2.0 - buttonSize.width - 10.0) + offset.x, y: layout.size.height - 49.0 - layout.intrinsicInsets.bottom - 54.0 + offset.y + additionalYOffset), size: buttonSize) let centerButtonFrame = CGRect(origin: CGPoint(x: floor((layout.size.width - buttonSize.width) / 2.0) + offset.x, y: layout.size.height - 49.0 - layout.intrinsicInsets.bottom - 54.0 + offset.y + additionalYOffset), size: buttonSize) @@ -883,23 +942,30 @@ final class WallpaperGalleryItemNode: GalleryItemNode { motionAlpha = 1.0 motionFrame = centerButtonFrame case .color: + motionAlpha = 0.0 patternAlpha = 1.0 - if self.patternButtonNode.isSelected { - patternFrame = leftButtonFrame - motionAlpha = 1.0 - motionFrame = rightButtonFrame - } + + patternFrame = leftButtonFrame.offsetBy(dx: -centerOffset, dy: 0.0) + colorsFrame = colorsFrame.offsetBy(dx: centerOffset, dy: 0.0) + playAlpha = 1.0 + + colorsAlpha = 1.0 case .image: blurAlpha = 1.0 blurFrame = leftButtonFrame motionAlpha = 1.0 motionFrame = rightButtonFrame case .gradient: - motionAlpha = 1.0 - case let .file(file): - if file.settings.colors.count >= 3 { - self.colorsButtonNode.colors = self.calculateGradientColors() + motionAlpha = 0.0 + patternAlpha = 1.0 + patternFrame = leftButtonFrame.offsetBy(dx: -centerOffset, dy: 0.0) + colorsFrame = colorsFrame.offsetBy(dx: centerOffset, dy: 0.0) + playAlpha = 1.0 + + colorsAlpha = 1.0 + case let .file(file): + if file.isPattern { motionAlpha = 0.0 patternAlpha = 1.0 @@ -948,8 +1014,9 @@ final class WallpaperGalleryItemNode: GalleryItemNode { private func updateMessagesLayout(layout: ContainerViewLayout, offset: CGPoint, transition: ContainedViewLayoutTransition) { var bottomInset: CGFloat = 115.0 + if self.patternButtonNode.isSelected || self.colorsButtonNode.isSelected { - bottomInset = 350.0 + //bottomInset = 350.0 } var items: [ListViewItem] = [] @@ -1058,10 +1125,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode { self.blurredNode.frame = self.imageNode.bounds } - var additionalYOffset: CGFloat = 0.0 - if self.patternButtonNode.isSelected || self.colorsButtonNode.isSelected { - additionalYOffset = -190.0 - } + let additionalYOffset: CGFloat = 0.0 self.statusNode.frame = CGRect(x: layout.safeInsets.left + floorToScreenPixels((layout.size.width - layout.safeInsets.left - layout.safeInsets.right - progressDiameter) / 2.0), y: floorToScreenPixels((layout.size.height + additionalYOffset - progressDiameter) / 2.0), width: progressDiameter, height: progressDiameter) diff --git a/submodules/SettingsUI/Sources/Themes/WallpaperOptionButtonNode.swift b/submodules/SettingsUI/Sources/Themes/WallpaperOptionButtonNode.swift index 3ed6dbb6eb..d5bb3c168f 100644 --- a/submodules/SettingsUI/Sources/Themes/WallpaperOptionButtonNode.swift +++ b/submodules/SettingsUI/Sources/Themes/WallpaperOptionButtonNode.swift @@ -15,13 +15,21 @@ enum WallpaperOptionButtonValue { private func generateColorsImage(diameter: CGFloat, colors: [UIColor]) -> UIImage? { return generateImage(CGSize(width: diameter, height: diameter), rotatedContext: { size, context in context.clear(CGRect(origin: CGPoint(), size: size)) - context.addEllipse(in: CGRect(origin: CGPoint(), size: size)) - context.clip() - for i in 0 ..< min(colors.count, 4) { - let x = i % 2 - let y = i / 2 - context.setFillColor(colors[i].cgColor) - context.fill(CGRect(origin: CGPoint(x: CGFloat(x) * size.width / 2.0, y: CGFloat(y) * size.height / 2.0), size: CGSize(width: size.width / 2.0, height: size.height / 2.0))) + + if !colors.isEmpty { + let center = CGPoint(x: size.width / 2.0, y: size.height / 2.0) + var startAngle = -CGFloat.pi * 0.5 + for i in 0 ..< colors.count { + context.setFillColor(colors[i].cgColor) + + let endAngle = startAngle + 2.0 * CGFloat.pi * (1.0 / CGFloat(colors.count)) + + context.move(to: center) + context.addArc(center: center, radius: size.width / 2.0, startAngle: startAngle, endAngle: endAngle, clockwise: false) + context.fillPath() + + startAngle = endAngle + } } }) } diff --git a/submodules/TelegramCallsUI/Sources/GroupVideoNode.swift b/submodules/TelegramCallsUI/Sources/GroupVideoNode.swift index 6b9e877000..791676a9f6 100644 --- a/submodules/TelegramCallsUI/Sources/GroupVideoNode.swift +++ b/submodules/TelegramCallsUI/Sources/GroupVideoNode.swift @@ -100,6 +100,10 @@ final class GroupVideoNode: ASDisplayNode { self.containerNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:)))) } + + func updateIsEnabled(_ isEnabled: Bool) { + self.videoView.updateIsEnabled(isEnabled) + } func updateIsBlurred(isBlurred: Bool, light: Bool = false, animated: Bool = true) { if self.isBlurred == isBlurred { diff --git a/submodules/TelegramCallsUI/Sources/PresentationCall.swift b/submodules/TelegramCallsUI/Sources/PresentationCall.swift index 110a963ac2..4c4c170a9b 100644 --- a/submodules/TelegramCallsUI/Sources/PresentationCall.swift +++ b/submodules/TelegramCallsUI/Sources/PresentationCall.swift @@ -927,6 +927,7 @@ public final class PresentationCallImpl: PresentationCall { let setOnFirstFrameReceived = view.setOnFirstFrameReceived let setOnOrientationUpdated = view.setOnOrientationUpdated let setOnIsMirroredUpdated = view.setOnIsMirroredUpdated + let updateIsEnabled = view.updateIsEnabled completion(PresentationCallVideoView( holder: view, view: view.view, @@ -978,6 +979,9 @@ public final class PresentationCallImpl: PresentationCall { setOnIsMirroredUpdated { value in f?(value) } + }, + updateIsEnabled: { value in + updateIsEnabled(value) } )) } else { @@ -997,6 +1001,7 @@ public final class PresentationCallImpl: PresentationCall { let setOnFirstFrameReceived = view.setOnFirstFrameReceived let setOnOrientationUpdated = view.setOnOrientationUpdated let setOnIsMirroredUpdated = view.setOnIsMirroredUpdated + let updateIsEnabled = view.updateIsEnabled completion(PresentationCallVideoView( holder: view, view: view.view, @@ -1048,6 +1053,9 @@ public final class PresentationCallImpl: PresentationCall { setOnIsMirroredUpdated { value in f?(value) } + }, + updateIsEnabled: { value in + updateIsEnabled(value) } )) } else { diff --git a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift index b38155022e..05f98837b2 100644 --- a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift +++ b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift @@ -1942,9 +1942,6 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { } else if participant.muteState?.mutedByYou == true { strongSelf.genericCallContext?.setVolume(ssrc: ssrc, volume: 0.0) } - if participant.videoJsonDescription == nil { - strongSelf.genericCallContext?.removeIncomingVideoSource(ssrc) - } } } @@ -2426,6 +2423,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { let setOnFirstFrameReceived = view.setOnFirstFrameReceived let setOnOrientationUpdated = view.setOnOrientationUpdated let setOnIsMirroredUpdated = view.setOnIsMirroredUpdated + let updateIsEnabled = view.updateIsEnabled completion(PresentationCallVideoView( holder: view, view: view.view, @@ -2477,6 +2475,9 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { setOnIsMirroredUpdated { value in f?(value) } + }, + updateIsEnabled: { value in + updateIsEnabled(value) } )) } else { @@ -2915,6 +2916,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { let setOnFirstFrameReceived = view.setOnFirstFrameReceived let setOnOrientationUpdated = view.setOnOrientationUpdated let setOnIsMirroredUpdated = view.setOnIsMirroredUpdated + let updateIsEnabled = view.updateIsEnabled completion(PresentationCallVideoView( holder: view, view: view.view, @@ -2966,6 +2968,9 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { setOnIsMirroredUpdated { value in f?(value) } + }, + updateIsEnabled: { value in + updateIsEnabled(value) } )) } else { diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift index 3416521010..8939519157 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift @@ -3844,6 +3844,9 @@ public final class VoiceChatController: ViewController { self.actionButton.update(size: centralButtonSize, buttonSize: CGSize(width: 112.0, height: 112.0), state: actionButtonState, title: actionButtonTitle, subtitle: actionButtonSubtitle, dark: self.isFullscreen, small: smallButtons, animated: true) var hasCameraButton = self.callState?.isVideoEnabled ?? false + #if DEBUG + hasCameraButton = true + #endif switch actionButtonState { case let .active(state): switch state { diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatTileItemNode.swift b/submodules/TelegramCallsUI/Sources/VoiceChatTileItemNode.swift index 30e115b23f..6088644648 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatTileItemNode.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatTileItemNode.swift @@ -259,6 +259,8 @@ final class VoiceChatTileItemNode: ASDisplayNode { if let shimmerNode = self.shimmerNode { shimmerNode.updateAbsoluteRect(rect, within: containerSize) } + let isVisible = rect.maxY >= 0.0 && rect.minY <= containerSize.height + self.videoNode?.updateIsEnabled(isVisible) } func update(size: CGSize, availableWidth: CGFloat, item: VoiceChatTileItem, transition: ContainedViewLayoutTransition) { diff --git a/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift index e5ca7a3c71..b21acfdb19 100644 --- a/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift @@ -596,7 +596,7 @@ final class ChatMessageAttachedContentNode: ASDisplayNode { let (_, initialImageWidth, refineLayout) = contentImageLayout(context, presentationData, presentationData.dateTimeFormat, message, attributes, wallpaper, imageDateAndStatus, .full, associatedData.automaticDownloadPeerType, .constrained(CGSize(width: constrainedSize.width - horizontalInsets.left - horizontalInsets.right, height: constrainedSize.height)), layoutConstants, contentMode) initialWidth = initialImageWidth + horizontalInsets.left + horizontalInsets.right refineContentImageLayout = refineLayout - if case let .file(_, _, _, _, isTheme, _) = wallpaper.content, isTheme { + if case let .file(_, _, _, isTheme, _) = wallpaper.content, isTheme { skipStandardStatus = true } } diff --git a/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift b/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift index 2ec2cfbf08..51b91c9b70 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift @@ -419,7 +419,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio unboundSize = CGSize(width: floor(dimensions.cgSize.width * 0.5), height: floor(dimensions.cgSize.height * 0.5)) } else if let wallpaper = media as? WallpaperPreviewMedia { switch wallpaper.content { - case let .file(file, _, _, _, isTheme, isSupported): + case let .file(file, _, _, isTheme, isSupported): if let thumbnail = file.previewRepresentations.first, var dimensions = file.dimensions { let dimensionsVertical = dimensions.width < dimensions.height let thumbnailVertical = thumbnail.dimensions.width < thumbnail.dimensions.height @@ -570,11 +570,12 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio emptyColor = message.effectivelyIncoming(context.account.peerId) ? presentationData.theme.theme.chat.message.incoming.mediaPlaceholderColor : presentationData.theme.theme.chat.message.outgoing.mediaPlaceholderColor } if let wallpaper = media as? WallpaperPreviewMedia { - if case let .file(_, patternColor, patternBottomColor, rotation, _, _) = wallpaper.content { + if case let .file(_, patternColors, rotation, _, _) = wallpaper.content { var colors: [UIColor] = [] - colors.append(patternColor ?? UIColor(rgb: 0xd6e2ee, alpha: 0.5)) - if let patternBottomColor = patternBottomColor { - colors.append(patternBottomColor) + if patternColors.isEmpty { + colors.append(UIColor(rgb: 0xd6e2ee, alpha: 0.5)) + } else { + colors.append(contentsOf: patternColors.map(UIColor.init(rgb:))) } patternArguments = PatternWallpaperArguments(colors: colors, rotation: rotation) } @@ -714,7 +715,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio } else if let wallpaper = media as? WallpaperPreviewMedia { updateImageSignal = { synchronousLoad, _ in switch wallpaper.content { - case let .file(file, _, _, _, isTheme, _): + case let .file(file, _, _, isTheme, _): if isTheme { return themeImage(account: context.account, accountManager: context.sharedContext.accountManager, source: .file(FileMediaReference.message(message: MessageReference(message), media: file))) } else { @@ -732,12 +733,12 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio return themeImage(account: context.account, accountManager: context.sharedContext.accountManager, source: .settings(settings)) case let .color(color): return solidColorImage(color) - case let .gradient(topColor, bottomColor, rotation): - return gradientImage([topColor, bottomColor], rotation: rotation ?? 0) + case let .gradient(colors, rotation): + return gradientImage(colors.map(UIColor.init(rgb:)), rotation: rotation ?? 0) } } - if case let .file(file, _, _, _, _, _) = wallpaper.content { + if case let .file(file, _, _, _, _) = wallpaper.content { updatedFetchControls = FetchControls(fetch: { manual in if let strongSelf = self { strongSelf.fetchDisposable.set(messageMediaFileInteractiveFetched(context: context, message: message, file: file, userInitiated: manual).start()) @@ -782,7 +783,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio } } else if let wallpaper = media as? WallpaperPreviewMedia { switch wallpaper.content { - case let .file(file, _, _, _, _, _): + case let .file(file, _, _, _, _): updatedStatusSignal = messageMediaFileStatus(context: context, messageId: message.id, file: file) |> map { resourceStatus -> (MediaResourceStatus, MediaResourceStatus?) in return (resourceStatus, nil) diff --git a/submodules/TelegramUI/Sources/ChatMessageWebpageBubbleContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageWebpageBubbleContentNode.swift index 229a9f0d58..089ca0d5f4 100644 --- a/submodules/TelegramUI/Sources/ChatMessageWebpageBubbleContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageWebpageBubbleContentNode.swift @@ -171,15 +171,13 @@ final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContentNode { mediaAndFlags = (webpage.image ?? file, [.preferMediaBeforeText]) } } else if webpage.type == "telegram_background" { - var topColor: UIColor? - var bottomColor: UIColor? + var colors: [UInt32] = [] var rotation: Int32? - if let wallpaper = parseWallpaperUrl(webpage.url), case let .slug(_, _, firstColor, secondColor, intensity, rotationValue) = wallpaper { - topColor = firstColor?.withAlphaComponent(CGFloat(intensity ?? 50) / 100.0) - bottomColor = secondColor?.withAlphaComponent(CGFloat(intensity ?? 50) / 100.0) + if let wallpaper = parseWallpaperUrl(webpage.url), case let .slug(_, _, colorsValue, intensity, rotationValue) = wallpaper { + colors = colorsValue rotation = rotationValue } - let media = WallpaperPreviewMedia(content: .file(file, topColor, bottomColor, rotation, false, false)) + let media = WallpaperPreviewMedia(content: .file(file, colors, rotation, false, false)) mediaAndFlags = (media, [.preferMediaAspectFilled]) if let fileSize = file.size { badge = dataSizeString(fileSize, formatting: DataSizeStringFormatting(chatPresentationData: item.presentationData)) @@ -207,25 +205,24 @@ final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContentNode { } } else if let type = webpage.type { if type == "telegram_background" { - var topColor: UIColor? + var colors: [UInt32] = [] var bottomColor: UIColor? var rotation: Int32? if let wallpaper = parseWallpaperUrl(webpage.url) { if case let .color(color) = wallpaper { - topColor = color - } else if case let .gradient(topColorValue, bottomColorValue, rotationValue) = wallpaper { - topColor = topColorValue - bottomColor = bottomColorValue + colors = [color.rgb] + } else if case let .gradient(colorsValue, rotationValue) = wallpaper { + colors = colorsValue rotation = rotationValue } } var content: WallpaperPreviewMediaContent? - if let topColor = topColor { - if let bottomColor = bottomColor { - content = .gradient(topColor, bottomColor, rotation) + if !colors.isEmpty { + if colors.count >= 2 { + content = .gradient(colors, rotation) } else { - content = .color(topColor) + content = .color(UIColor(rgb: colors[0])) } } if let content = content { @@ -254,7 +251,7 @@ final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContentNode { file = contentFile } if let file = file { - let media = WallpaperPreviewMedia(content: .file(file, nil, nil, nil, true, isSupported)) + let media = WallpaperPreviewMedia(content: .file(file, [], nil, true, isSupported)) mediaAndFlags = (media, ChatMessageAttachedContentNodeMediaFlags()) } else if let settings = settings { let media = WallpaperPreviewMedia(content: .themeSettings(settings)) diff --git a/submodules/TelegramUI/Sources/OpenChatMessage.swift b/submodules/TelegramUI/Sources/OpenChatMessage.swift index ddf9a413ef..4377cf914b 100644 --- a/submodules/TelegramUI/Sources/OpenChatMessage.swift +++ b/submodules/TelegramUI/Sources/OpenChatMessage.swift @@ -258,12 +258,12 @@ func openChatWallpaper(context: AccountContext, message: Message, present: @esca if case let .wallpaper(parameter) = resolvedUrl { let source: WallpaperListSource switch parameter { - case let .slug(slug, options, firstColor, secondColor, intensity, rotation): - source = .slug(slug, content.file, options, firstColor, secondColor, intensity, rotation, message) + case let .slug(slug, options, colors, intensity, rotation): + source = .slug(slug, content.file, options, colors, intensity, rotation, message) case let .color(color): - source = .wallpaper(.color(color.argb), nil, nil, nil, nil, nil, message) - case let .gradient(topColor, bottomColor, rotation): - source = .wallpaper(.gradient([topColor.argb, bottomColor.argb], WallpaperSettings(rotation: rotation)), nil, nil, nil, nil, rotation, message) + source = .wallpaper(.color(color.argb), nil, [], nil, nil, message) + case let .gradient(colors, rotation): + source = .wallpaper(.gradient(colors, WallpaperSettings(rotation: rotation)), nil, [], nil, rotation, message) } let controller = WallpaperGalleryController(context: context, source: source) diff --git a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift index 9b5cea8e26..1dc61745de 100644 --- a/submodules/TelegramUI/Sources/OpenResolvedUrl.swift +++ b/submodules/TelegramUI/Sources/OpenResolvedUrl.swift @@ -294,30 +294,28 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur let signal: Signal var options: WallpaperPresentationOptions? - var topColor: UIColor? - var bottomColor: UIColor? + var colors: [UInt32] = [] var intensity: Int32? var rotation: Int32? switch parameter { - case let .slug(slug, wallpaperOptions, firstColor, secondColor, intensityValue, rotationValue): + case let .slug(slug, wallpaperOptions, colorsValue, intensityValue, rotationValue): signal = getWallpaper(network: context.account.network, slug: slug) options = wallpaperOptions - topColor = firstColor - bottomColor = secondColor + colors = colorsValue intensity = intensityValue rotation = rotationValue controller = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: nil)) present(controller!, nil) case let .color(color): signal = .single(.color(color.argb)) - case let .gradient(topColor, bottomColor, rotation): - signal = .single(.gradient([topColor.argb, bottomColor.argb], WallpaperSettings(rotation: rotation))) + case let .gradient(colors, rotation): + signal = .single(.gradient(colors, WallpaperSettings(rotation: rotation))) } let _ = (signal |> deliverOnMainQueue).start(next: { [weak controller] wallpaper in controller?.dismiss() - let galleryController = WallpaperGalleryController(context: context, source: .wallpaper(wallpaper, options, topColor, bottomColor, intensity, rotation, nil)) + let galleryController = WallpaperGalleryController(context: context, source: .wallpaper(wallpaper, options, colors, intensity, rotation, nil)) present(galleryController, nil) }, error: { [weak controller] error in controller?.dismiss() diff --git a/submodules/TelegramUI/Sources/WallpaperPreviewMedia.swift b/submodules/TelegramUI/Sources/WallpaperPreviewMedia.swift index 6d6433875d..6e42d83cbe 100644 --- a/submodules/TelegramUI/Sources/WallpaperPreviewMedia.swift +++ b/submodules/TelegramUI/Sources/WallpaperPreviewMedia.swift @@ -5,9 +5,9 @@ import TelegramCore import SyncCore enum WallpaperPreviewMediaContent: Equatable { - case file(TelegramMediaFile, UIColor?, UIColor?, Int32?, Bool, Bool) + case file(TelegramMediaFile, [UInt32], Int32?, Bool, Bool) case color(UIColor) - case gradient(UIColor, UIColor, Int32?) + case gradient([UInt32], Int32?) case themeSettings(TelegramThemeSettings) } diff --git a/submodules/TelegramVoip/Sources/GroupCallContext.swift b/submodules/TelegramVoip/Sources/GroupCallContext.swift index ffdd8185ee..34d61f56ec 100644 --- a/submodules/TelegramVoip/Sources/GroupCallContext.swift +++ b/submodules/TelegramVoip/Sources/GroupCallContext.swift @@ -499,6 +499,9 @@ public final class OngoingGroupCallContext { view?.setOnIsMirroredUpdated { value in f?(value) } + }, + updateIsEnabled: { [weak view] value in + view?.updateIsEnabled(value) } )) #else diff --git a/submodules/TelegramVoip/Sources/OngoingCallContext.swift b/submodules/TelegramVoip/Sources/OngoingCallContext.swift index 7606426e38..2e10125487 100644 --- a/submodules/TelegramVoip/Sources/OngoingCallContext.swift +++ b/submodules/TelegramVoip/Sources/OngoingCallContext.swift @@ -376,6 +376,9 @@ public final class OngoingCallVideoCapturer { }, setOnIsMirroredUpdated: { [weak view] f in view?.setOnIsMirroredUpdated(f) + }, + updateIsEnabled: { [weak view] value in + view?.updateIsEnabled(value) } )) } else { @@ -508,6 +511,7 @@ public final class OngoingCallContextPresentationCallVideoView { public let getAspect: () -> CGFloat public let setOnOrientationUpdated: (((OngoingCallVideoOrientation, CGFloat) -> Void)?) -> Void public let setOnIsMirroredUpdated: (((Bool) -> Void)?) -> Void + public let updateIsEnabled: (Bool) -> Void public init( view: UIView, @@ -515,7 +519,8 @@ public final class OngoingCallContextPresentationCallVideoView { getOrientation: @escaping () -> OngoingCallVideoOrientation, getAspect: @escaping () -> CGFloat, setOnOrientationUpdated: @escaping (((OngoingCallVideoOrientation, CGFloat) -> Void)?) -> Void, - setOnIsMirroredUpdated: @escaping (((Bool) -> Void)?) -> Void + setOnIsMirroredUpdated: @escaping (((Bool) -> Void)?) -> Void, + updateIsEnabled: @escaping (Bool) -> Void ) { self.view = view self.setOnFirstFrameReceived = setOnFirstFrameReceived @@ -523,6 +528,7 @@ public final class OngoingCallContextPresentationCallVideoView { self.getAspect = getAspect self.setOnOrientationUpdated = setOnOrientationUpdated self.setOnIsMirroredUpdated = setOnIsMirroredUpdated + self.updateIsEnabled = updateIsEnabled } } @@ -918,6 +924,9 @@ public final class OngoingCallContext { view?.setOnIsMirroredUpdated { value in f?(value) } + }, + updateIsEnabled: { [weak view] value in + view?.updateIsEnabled(value) } )) } else { diff --git a/submodules/TgVoipWebrtc/BUILD b/submodules/TgVoipWebrtc/BUILD index f9e58e0265..1d2d331a09 100644 --- a/submodules/TgVoipWebrtc/BUILD +++ b/submodules/TgVoipWebrtc/BUILD @@ -19,6 +19,7 @@ objc_library( "tgcalls/tgcalls/platform/uwp/**", "tgcalls/tgcalls/platform/darwin/VideoCameraCapturerMac.*", "tgcalls/tgcalls/platform/darwin/VideoMetalViewMac.*", + "tgcalls/tgcalls/platform/darwin/VideoSampleBufferViewMac.*", "tgcalls/tgcalls/platform/darwin/GLVideoViewMac.*", "tgcalls/tgcalls/platform/darwin/ScreenCapturer.*", "tgcalls/tgcalls/platform/darwin/DesktopSharingCapturer.*", diff --git a/submodules/TgVoipWebrtc/PublicHeaders/TgVoipWebrtc/OngoingCallThreadLocalContext.h b/submodules/TgVoipWebrtc/PublicHeaders/TgVoipWebrtc/OngoingCallThreadLocalContext.h index 407dc2fbd9..4618467c66 100644 --- a/submodules/TgVoipWebrtc/PublicHeaders/TgVoipWebrtc/OngoingCallThreadLocalContext.h +++ b/submodules/TgVoipWebrtc/PublicHeaders/TgVoipWebrtc/OngoingCallThreadLocalContext.h @@ -101,6 +101,7 @@ typedef NS_ENUM(int32_t, OngoingCallDataSavingWebrtc) { - (void)setOnFirstFrameReceived:(void (^ _Nullable)(float))onFirstFrameReceived; - (void)setOnOrientationUpdated:(void (^ _Nullable)(OngoingCallVideoOrientationWebrtc, CGFloat))onOrientationUpdated; - (void)setOnIsMirroredUpdated:(void (^ _Nullable)(bool))onIsMirroredUpdated; +- (void)updateIsEnabled:(bool)isEnabled; #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) - (void)setVideoContentMode:(CALayerContentsGravity _Nonnull )mode; - (void)setForceMirrored:(bool)forceMirrored; diff --git a/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm b/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm index b739e28fa2..41165d9ee9 100644 --- a/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm +++ b/submodules/TgVoipWebrtc/Sources/OngoingCallThreadLocalContext.mm @@ -101,6 +101,10 @@ } } +- (void)updateIsEnabled:(bool)isEnabled { + [self setEnabled:isEnabled]; +} + @end @interface GLVideoView (VideoViewImpl) @@ -144,6 +148,9 @@ } } +- (void)updateIsEnabled:(bool)__unused isEnabled { +} + @end @interface VideoSampleBufferView (VideoViewImpl) @@ -187,6 +194,10 @@ } } +- (void)updateIsEnabled:(bool)isEnabled { + [self setEnabled:isEnabled]; +} + @end @interface OngoingCallThreadLocalContextVideoCapturer () { @@ -1271,7 +1282,21 @@ private: __weak GroupCallThreadLocalContext *weakSelf = self; id queue = _queue; dispatch_async(dispatch_get_main_queue(), ^{ - if ([VideoMetalView isSupported]) { + if (true) { + VideoSampleBufferView *remoteRenderer = [[VideoSampleBufferView alloc] initWithFrame:CGRectZero]; + remoteRenderer.videoContentMode = UIViewContentModeScaleAspectFill; + + std::shared_ptr> sink = [remoteRenderer getSink]; + + [queue dispatch:^{ + __strong GroupCallThreadLocalContext *strongSelf = weakSelf; + if (strongSelf && strongSelf->_instance) { + strongSelf->_instance->addIncomingVideoOutput(endpointId.UTF8String, sink); + } + }]; + + completion(remoteRenderer); + } else if ([VideoMetalView isSupported]) { VideoMetalView *remoteRenderer = [[VideoMetalView alloc] initWithFrame:CGRectZero]; #if TARGET_OS_IPHONE remoteRenderer.videoContentMode = UIViewContentModeScaleToFill; diff --git a/submodules/TgVoipWebrtc/tgcalls b/submodules/TgVoipWebrtc/tgcalls index 66186febe0..197878f551 160000 --- a/submodules/TgVoipWebrtc/tgcalls +++ b/submodules/TgVoipWebrtc/tgcalls @@ -1 +1 @@ -Subproject commit 66186febe0e20d7bc39053e627f93fd95a5ecac9 +Subproject commit 197878f551449341bc3fa74e117d011a9d0e8120 diff --git a/submodules/UrlHandling/Sources/UrlHandling.swift b/submodules/UrlHandling/Sources/UrlHandling.swift index 671fedd79e..d50eaee876 100644 --- a/submodules/UrlHandling/Sources/UrlHandling.swift +++ b/submodules/UrlHandling/Sources/UrlHandling.swift @@ -186,7 +186,7 @@ public func parseInternalUrl(query: String) -> ParsedInternalUrl? { let parameter: WallpaperUrlParameter if [6, 8].contains(component.count), component.rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789abcdefABCDEF").inverted) == nil, let color = UIColor(hexString: component) { parameter = .color(color) - } else if [13, 15, 17].contains(component.count), component.rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789abcdefABCDEF-").inverted) == nil { + } else if [13, 15, 17].contains(component.count), component.rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789abcdefABCDEF-~").inverted) == nil { var rotation: Int32? if let queryItems = components.queryItems { for queryItem in queryItems { @@ -197,17 +197,33 @@ public func parseInternalUrl(query: String) -> ParsedInternalUrl? { } } } - let components = component.components(separatedBy: "-") - if components.count == 2, let topColor = UIColor(hexString: components[0]), let bottomColor = UIColor(hexString: components[1]) { - parameter = .gradient(topColor, bottomColor, rotation) + if component.contains("~") { + let components = component.components(separatedBy: "~") + + var colors: [UInt32] = [] + if components.count >= 2 && components.count <= 4 { + colors = components.compactMap { component in + return UIColor(hexString: component)?.rgb + } + } + + if !colors.isEmpty { + parameter = .gradient(colors, rotation) + } else { + return nil + } } else { - return nil + let components = component.components(separatedBy: "-") + if components.count == 2, let topColor = UIColor(hexString: components[0]), let bottomColor = UIColor(hexString: components[1]) { + parameter = .gradient([topColor.rgb, bottomColor.rgb], rotation) + } else { + return nil + } } } else { var options: WallpaperPresentationOptions = [] var intensity: Int32? - var topColor: UIColor? - var bottomColor: UIColor? + var colors: [UInt32] = [] var rotation: Int32? if let queryItems = components.queryItems { for queryItem in queryItems { @@ -225,12 +241,18 @@ public func parseInternalUrl(query: String) -> ParsedInternalUrl? { } } else if queryItem.name == "bg_color" { if [6, 8].contains(value.count), value.rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789abcdefABCDEF").inverted) == nil, let color = UIColor(hexString: value) { - topColor = color + colors = [color.rgb] } else if [13, 15, 17].contains(value.count), value.rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789abcdefABCDEF-").inverted) == nil { let components = value.components(separatedBy: "-") if components.count == 2, let topColorValue = UIColor(hexString: components[0]), let bottomColorValue = UIColor(hexString: components[1]) { - topColor = topColorValue - bottomColor = bottomColorValue + colors = [topColorValue.rgb, bottomColorValue.rgb] + } + } else if value.contains("~") { + let components = value.components(separatedBy: "~") + if components.count >= 2 && components.count <= 4 { + colors = components.compactMap { component in + return UIColor(hexString: component)?.rgb + } } } } else if queryItem.name == "intensity" { @@ -241,7 +263,7 @@ public func parseInternalUrl(query: String) -> ParsedInternalUrl? { } } } - parameter = .slug(component, options, topColor, bottomColor, intensity, rotation) + parameter = .slug(component, options, colors, intensity, rotation) } return .wallpaper(parameter) } else if pathComponents[0] == "addtheme" { diff --git a/submodules/WallpaperResources/Sources/WallpaperResources.swift b/submodules/WallpaperResources/Sources/WallpaperResources.swift index e60c0ef07d..c6b7d595e1 100644 --- a/submodules/WallpaperResources/Sources/WallpaperResources.swift +++ b/submodules/WallpaperResources/Sources/WallpaperResources.swift @@ -1136,7 +1136,20 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the outgoingColor = (bubbleColor, bubbleColor) } } else { - topBackgroundColor = UIColor(rgb: 0xd6e2ee) + if let wallpaper = wallpaper, case let .file(file) = wallpaper { + topBackgroundColor = file.settings.colors.first.flatMap { UIColor(rgb: $0) } ?? UIColor(rgb: 0xd6e2ee) + if file.settings.colors.count >= 2 { + bottomBackgroundColor = UIColor(rgb: file.settings.colors[1]) + } + } else if let wallpaper = wallpaper, case let .gradient(colors, _) = wallpaper { + topBackgroundColor = colors.first.flatMap { UIColor(rgb: $0) } ?? UIColor(rgb: 0xd6e2ee) + if colors.count >= 2 { + bottomBackgroundColor = UIColor(rgb: colors[1]) + } + } else { + topBackgroundColor = defaultBuiltinWallpaperGradientColors[0] + bottomBackgroundColor = defaultBuiltinWallpaperGradientColors[1] + } outgoingColor = (UIColor(rgb: 0xe1ffc7), UIColor(rgb: 0xe1ffc7)) } case .day: @@ -1190,6 +1203,8 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the colors = [0xd6e2ee] topBackgroundColor = UIColor(rgb: 0xd6e2ee) } + } else { + colors = defaultBuiltinWallpaperGradientColors.map(\.rgb) } colorsSignal = .single(((topBackgroundColor, bottomBackgroundColor, colors), (incomingColor, incomingColor), outgoingColor, nil, rotation)) diff --git a/third-party/rnnoise/BUILD b/third-party/rnnoise/BUILD index bd8f0b843a..e1066c862b 100644 --- a/third-party/rnnoise/BUILD +++ b/third-party/rnnoise/BUILD @@ -41,6 +41,8 @@ objc_library( ], copts = [ "-D{name}=rnnoise_{name}".format(name = name) for name in replace_symbol_list + ] + [ + "-Os", ], visibility = [ "//visibility:public", diff --git a/third-party/webrtc/BUILD b/third-party/webrtc/BUILD index 79fc561020..124b1afd6b 100644 --- a/third-party/webrtc/BUILD +++ b/third-party/webrtc/BUILD @@ -9,7 +9,7 @@ config_setting( ) optimization_flags = select({ - #":debug_build": ["-Os"], + ":debug_build": ["-Os"], "//conditions:default": [], })