Combo update

This commit is contained in:
Ali 2021-05-25 19:00:50 +04:00
parent af59d15412
commit ef99bb604f
29 changed files with 408 additions and 154 deletions

View File

@ -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( ios_application(
name = "webrtc_build_test", name = "webrtc_build_test",
bundle_id = "{telegram_bundle_id}".format( bundle_id = "{telegram_bundle_id}".format(
@ -1843,3 +1844,26 @@ ios_application(
"//third-party/webrtc:webrtc_lib", "//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",
],
)

View File

@ -154,9 +154,9 @@ public struct ChatAvailableMessageActions {
} }
public enum WallpaperUrlParameter { public enum WallpaperUrlParameter {
case slug(String, WallpaperPresentationOptions, UIColor?, UIColor?, Int32?, Int32?) case slug(String, WallpaperPresentationOptions, [UInt32], Int32?, Int32?)
case color(UIColor) case color(UIColor)
case gradient(UIColor, UIColor, Int32?) case gradient([UInt32], Int32?)
} }
public enum ResolvedUrlSettingsSection { public enum ResolvedUrlSettingsSection {

View File

@ -109,6 +109,7 @@ public final class PresentationCallVideoView {
public let getAspect: () -> CGFloat public let getAspect: () -> CGFloat
public let setOnOrientationUpdated: (((Orientation, CGFloat) -> Void)?) -> Void public let setOnOrientationUpdated: (((Orientation, CGFloat) -> Void)?) -> Void
public let setOnIsMirroredUpdated: (((Bool) -> Void)?) -> Void public let setOnIsMirroredUpdated: (((Bool) -> Void)?) -> Void
public let updateIsEnabled: (Bool) -> Void
public init( public init(
holder: AnyObject, holder: AnyObject,
@ -117,7 +118,8 @@ public final class PresentationCallVideoView {
getOrientation: @escaping () -> Orientation, getOrientation: @escaping () -> Orientation,
getAspect: @escaping () -> CGFloat, getAspect: @escaping () -> CGFloat,
setOnOrientationUpdated: @escaping (((Orientation, CGFloat) -> Void)?) -> Void, setOnOrientationUpdated: @escaping (((Orientation, CGFloat) -> Void)?) -> Void,
setOnIsMirroredUpdated: @escaping (((Bool) -> Void)?) -> Void setOnIsMirroredUpdated: @escaping (((Bool) -> Void)?) -> Void,
updateIsEnabled: @escaping (Bool) -> Void
) { ) {
self.holder = holder self.holder = holder
self.view = view self.view = view
@ -126,6 +128,7 @@ public final class PresentationCallVideoView {
self.getAspect = getAspect self.getAspect = getAspect
self.setOnOrientationUpdated = setOnOrientationUpdated self.setOnOrientationUpdated = setOnOrientationUpdated
self.setOnIsMirroredUpdated = setOnIsMirroredUpdated self.setOnIsMirroredUpdated = setOnIsMirroredUpdated
self.updateIsEnabled = updateIsEnabled
} }
} }

View File

@ -1132,12 +1132,18 @@ open class NavigationBar: ASDisplayNode {
if let titleView = self.titleView { if let titleView = self.titleView {
let titleSize = CGSize(width: max(1.0, size.width - max(leftTitleInset, rightTitleInset) * 2.0), height: nominalHeight) 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) 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 { if let titleView = titleView as? NavigationBarTitleView {
let titleWidth = size.width - (leftTitleInset > 0.0 ? leftTitleInset : rightTitleInset) - (rightTitleInset > 0.0 ? rightTitleInset : leftTitleInset) 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 { if let transitionState = self.transitionState, let otherNavigationBar = transitionState.navigationBar {

View File

@ -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.frame = CGRect(origin: CGPoint(x: 0.0, y: layout.size.height), size: layout.size)
self.pager.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: transition) self.pager.containerLayoutUpdated(layout, navigationBarHeight: navigationBarHeight, transition: transition)
} }

View File

@ -25,8 +25,8 @@ public enum WallpaperListType {
public enum WallpaperListSource { public enum WallpaperListSource {
case list(wallpapers: [TelegramWallpaper], central: TelegramWallpaper, type: WallpaperListType) case list(wallpapers: [TelegramWallpaper], central: TelegramWallpaper, type: WallpaperListType)
case wallpaper(TelegramWallpaper, WallpaperPresentationOptions?, UIColor?, UIColor?, Int32?, Int32?, Message?) case wallpaper(TelegramWallpaper, WallpaperPresentationOptions?, [UInt32], Int32?, Int32?, Message?)
case slug(String, TelegramMediaFile?, WallpaperPresentationOptions?, UIColor?, UIColor?, Int32?, Int32?, Message?) case slug(String, TelegramMediaFile?, WallpaperPresentationOptions?, [UInt32], Int32?, Int32?, Message?)
case asset(PHAsset) case asset(PHAsset)
case contextResult(ChatContextResult) case contextResult(ChatContextResult)
case customColor(UInt32?) 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 { 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 { } else {
return wallpaper 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) var isPattern = ["image/png", "image/svg+xml", "application/x-tgwallpattern"].contains(file.mimeType)
if let fileName = file.fileName, fileName.hasSuffix(".svgbg") { if let fileName = file.fileName, fileName.hasSuffix(".svgbg") {
isPattern = true isPattern = true
} }
var firstColorValue: UInt32? var colorValues: [UInt32] = []
var secondColorValue: UInt32?
var intensityValue: Int32? var intensityValue: Int32?
if let firstColor = firstColor { if !colors.isEmpty {
firstColorValue = firstColor.argb colorValues = colors
intensityValue = intensity intensityValue = intensity ?? 50
} else if isPattern { } else {
firstColorValue = 0xd6e2ee colorValues = [0xd6e2ee]
intensityValue = 50 intensityValue = 50
} }
if let secondColor = secondColor {
secondColorValue = secondColor.argb
}
var colors: [UInt32] = [] 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))
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))
} }
public class WallpaperGalleryController: ViewController { public class WallpaperGalleryController: ViewController {
@ -234,15 +222,15 @@ public class WallpaperGalleryController: ViewController {
if case let .wallpapers(wallpaperOptions) = type, let options = wallpaperOptions { if case let .wallpapers(wallpaperOptions) = type, let options = wallpaperOptions {
self.initialOptions = options 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 { 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)] entries = [.wallpaper(wallpaper, message)]
centralEntryIndex = 0 centralEntryIndex = 0
self.initialOptions = options self.initialOptions = options
} }
case let .wallpaper(wallpaper, options, firstColor, secondColor, intensity, rotation, message): case let .wallpaper(wallpaper, options, colors, intensity, rotation, message):
let wallpaper = updatedFileWallpaper(wallpaper: wallpaper, firstColor: firstColor, secondColor: secondColor, intensity: intensity, rotation: rotation) let wallpaper = updatedFileWallpaper(wallpaper: wallpaper, colors: colors, intensity: intensity, rotation: rotation)
entries = [.wallpaper(wallpaper, message)] entries = [.wallpaper(wallpaper, message)]
centralEntryIndex = 0 centralEntryIndex = 0
self.initialOptions = options self.initialOptions = options
@ -327,7 +315,7 @@ public class WallpaperGalleryController: ViewController {
self.navigationBar?.updatePresentationData(NavigationBarPresentationData(presentationData: self.presentationData)) self.navigationBar?.updatePresentationData(NavigationBarPresentationData(presentationData: self.presentationData))
self.toolbarNode?.updateThemeAndStrings(theme: self.presentationData.theme, strings: self.presentationData.strings) self.toolbarNode?.updateThemeAndStrings(theme: self.presentationData.theme, strings: self.presentationData.strings)
self.patternPanelNode?.updateTheme(self.presentationData.theme) 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) self.colorsPanelNode?.updateTheme(self.presentationData.theme)
} }
@ -452,7 +440,7 @@ public class WallpaperGalleryController: ViewController {
let completion: (TelegramWallpaper) -> Void = { wallpaper in let completion: (TelegramWallpaper) -> Void = { wallpaper in
let baseSettings = wallpaper.settings 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 wallpaper = wallpaper.withUpdatedSettings(updatedSettings)
let autoNightModeTriggered = strongSelf.presentationData.autoNightModeTriggered let autoNightModeTriggered = strongSelf.presentationData.autoNightModeTriggered
@ -613,14 +601,34 @@ public class WallpaperGalleryController: ViewController {
strongSelf.colorsPanelEnabled = false strongSelf.colorsPanelEnabled = false
strongSelf.patternInitialWallpaper = enabled ? initialWallpaper : nil 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.patternPanelEnabled = enabled
strongSelf.galleryNode.scrollView.isScrollEnabled = !enabled strongSelf.galleryNode.scrollView.isScrollEnabled = !enabled
if enabled { if enabled {
strongSelf.patternPanelNode?.updateWallpapers()
strongSelf.patternPanelNode?.didAppear() strongSelf.patternPanelNode?.didAppear()
} else { } else {
switch initialWallpaper { switch initialWallpaper {
case .color: case .color, .gradient:
strongSelf.updateEntries(pattern: .color(0), preview: false) 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: default:
break break
} }
@ -653,6 +661,15 @@ public class WallpaperGalleryController: ViewController {
} }
} }
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 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() { if self.patternPanelNode?.backgroundColors != nil, let snapshotView = self.patternPanelNode?.scrollNode.view.snapshotContentTree() {
self.patternPanelNode?.view.addSubview(snapshotView) self.patternPanelNode?.view.addSubview(snapshotView)
@ -660,7 +677,7 @@ public class WallpaperGalleryController: ViewController {
snapshotView?.removeFromSuperview() 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) { private func updateEntries(pattern: TelegramWallpaper?, intensity: Int32? = nil, preview: Bool = false) {
var updatedEntries: [WallpaperGalleryEntry] = [] var updatedEntries: [WallpaperGalleryEntry] = []
for entry in self.entries { for entry in self.entries {
var entryColor: UInt32? var entryColors: [UInt32] = []
if case let .wallpaper(wallpaper, _) = entry { if case let .wallpaper(wallpaper, _) = entry {
if case let .color(color) = wallpaper { if case let .color(color) = wallpaper {
entryColor = color entryColors = [color]
} else if case let .file(file) = wallpaper { } else if case let .file(file) = wallpaper, file.isPattern {
entryColor = file.settings.colors.first 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 { 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) 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)) updatedEntries.append(.wallpaper(newWallpaper, nil))
} else { } else {
let newWallpaper = TelegramWallpaper.color(entryColor) if entryColors.count == 1 {
let newWallpaper = TelegramWallpaper.color(entryColors[0])
updatedEntries.append(.wallpaper(newWallpaper, nil)) updatedEntries.append(.wallpaper(newWallpaper, nil))
} else {
let newWallpaper = TelegramWallpaper.gradient(entryColors, WallpaperSettings(rotation: nil))
updatedEntries.append(.wallpaper(newWallpaper, nil))
}
} }
} }
} }
@ -743,8 +767,16 @@ public class WallpaperGalleryController: ViewController {
super.containerLayoutUpdated(layout, transition: transition) 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.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 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))) 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 patternPanelNode.patternChanged = { [weak self] pattern, intensity, preview in
if let strongSelf = self, strongSelf.validLayout != nil, let patternInitialWallpaper = strongSelf.patternInitialWallpaper { if let strongSelf = self, strongSelf.validLayout != nil, let patternInitialWallpaper = strongSelf.patternInitialWallpaper {
switch patternInitialWallpaper { switch patternInitialWallpaper {
case .color: case .color, .file, .gradient:
strongSelf.updateEntries(pattern: pattern, intensity: intensity, preview: preview) strongSelf.updateEntries(pattern: pattern, intensity: intensity, preview: preview)
default: default:
break break
@ -800,11 +832,9 @@ public class WallpaperGalleryController: ViewController {
} }
} }
let panelHeight: CGFloat = 235.0
var patternPanelFrame = CGRect(x: 0.0, y: layout.size.height, width: layout.size.width, height: panelHeight) var patternPanelFrame = CGRect(x: 0.0, y: layout.size.height, width: layout.size.width, height: panelHeight)
if self.patternPanelEnabled { 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 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) var colorsPanelFrame = CGRect(x: 0.0, y: layout.size.height, width: layout.size.width, height: panelHeight)
if self.colorsPanelEnabled { 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 bottomInset += panelHeight
} }
@ -879,8 +909,17 @@ public class WallpaperGalleryController: ViewController {
case let .file(_, _, _, _, isPattern, _, slug, _, settings): case let .file(_, _, _, _, isPattern, _, slug, _, settings):
if isPattern { if isPattern {
if !settings.colors.isEmpty { 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)") 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 { } else {
options.append("bg_color=\(UIColor(rgb: settings.colors[0]).hexString)") options.append("bg_color=\(UIColor(rgb: settings.colors[0]).hexString)")
} }
@ -902,7 +941,20 @@ public class WallpaperGalleryController: ViewController {
case let .color(color): case let .color(color):
controller = ShareController(context: context, subject: .url("https://t.me/bg/\(UIColor(rgb: color).hexString)")) controller = ShareController(context: context, subject: .url("https://t.me/bg/\(UIColor(rgb: color).hexString)"))
case let .gradient(colors, _): 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: default:
break break
} }

View File

@ -116,12 +116,16 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
var action: (() -> Void)? var action: (() -> Void)?
var requestPatternPanel: ((Bool, TelegramWallpaper) -> Void)? var requestPatternPanel: ((Bool, TelegramWallpaper) -> Void)?
var requestColorsPanel: (([UIColor]?) -> Void)? var requestColorsPanel: (([UIColor]?) -> Void)?
var requestRotateGradient: ((Int32) -> Void)?
private var validLayout: (ContainerViewLayout, CGFloat)? private var validLayout: (ContainerViewLayout, CGFloat)?
private var validOffset: CGFloat? private var validOffset: CGFloat?
private var initialWallpaper: TelegramWallpaper? private var initialWallpaper: TelegramWallpaper?
private let playButtonPlayImage: UIImage?
private let playButtonRotateImage: UIImage?
init(context: AccountContext) { init(context: AccountContext) {
self.context = context self.context = context
self.presentationData = context.sharedContext.currentPresentationData.with { $0 } self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
@ -151,7 +155,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
self.colorsButtonNode = WallpaperOptionButtonNode(title: self.presentationData.strings.WallpaperPreview_WallpaperColors, value: .colors(false, [.clear])) self.colorsButtonNode = WallpaperOptionButtonNode(title: self.presentationData.strings.WallpaperPreview_WallpaperColors, value: .colors(false, [.clear]))
self.playButtonNode = HighlightableButtonNode() 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.clear(CGRect(origin: CGPoint(), size: size))
context.setFillColor(UIColor.white.cgColor) 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: -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) 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() super.init()
@ -251,7 +259,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
self.preparePatternEditing() self.preparePatternEditing()
} }
self.patternButtonNode.isSelected = self.arguments.patternEnabled self.colorsButtonNode.colors = self.calculateGradientColors() ?? defaultBuiltinWallpaperGradientColors
let imagePromise = Promise<UIImage?>() let imagePromise = Promise<UIImage?>()
@ -274,14 +282,35 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
switch entry { switch entry {
case let .wallpaper(wallpaper, _): 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.isHidden = false
self.nativeNode.update(wallpaper: wallpaper) 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 { } else {
self.nativeNode.isHidden = true self.nativeNode.isHidden = true
self.patternButtonNode.isSelected = false
self.playButtonNode.setImage(self.playButtonRotateImage, for: [])
} }
default: default:
self.nativeNode.isHidden = true self.nativeNode.isHidden = true
self.patternButtonNode.isSelected = false
self.playButtonNode.setImage(self.playButtonRotateImage, for: [])
} }
switch entry { switch entry {
@ -311,7 +340,11 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
case let .gradient(colors, settings): case let .gradient(colors, settings):
displaySize = CGSize(width: 1.0, height: 1.0) displaySize = CGSize(width: 1.0, height: 1.0)
contentSize = displaySize contentSize = displaySize
if colors.count >= 2 {
signal = gradientImage([UIColor(rgb: colors[0]), UIColor(rgb: colors[1])], rotation: settings.rotation) signal = gradientImage([UIColor(rgb: colors[0]), UIColor(rgb: colors[1])], rotation: settings.rotation)
} else {
signal = solidColorImage(UIColor(rgb: colors[0]))
}
fetchSignal = .complete() fetchSignal = .complete()
statusSignal = .single(.Local) statusSignal = .single(.Local)
subtitleSignal = .single(nil) subtitleSignal = .single(nil)
@ -319,10 +352,6 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
colorSignal = chatServiceBackgroundColor(wallpaper: wallpaper, mediaBox: self.context.account.postbox.mediaBox) colorSignal = chatServiceBackgroundColor(wallpaper: wallpaper, mediaBox: self.context.account.postbox.mediaBox)
isBlurrable = false isBlurrable = false
case let .file(file): case let .file(file):
let gradientColors = self.calculateGradientColors() ?? defaultBuiltinWallpaperGradientColors
self.colorsButtonNode.colors = gradientColors
let dimensions = file.file.dimensions ?? PixelDimensions(width: 2000, height: 4000) let dimensions = file.file.dimensions ?? PixelDimensions(width: 2000, height: 4000)
contentSize = dimensions.cgSize contentSize = dimensions.cgSize
displaySize = dimensions.cgSize.dividedByScreenScale().integralFloor displaySize = dimensions.cgSize.dividedByScreenScale().integralFloor
@ -738,12 +767,20 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
switch entry { switch entry {
case let .wallpaper(wallpaper, _): case let .wallpaper(wallpaper, _):
switch wallpaper { switch wallpaper {
case let .file(_, _, _, _, _, _, _, _, settings): case let .file(_, _, _, _, isPattern, _, _, _, settings):
if settings.colors.count >= 3 { if isPattern {
if settings.colors.isEmpty {
return nil
} else {
return settings.colors.map(UIColor.init(rgb:)) return settings.colors.map(UIColor.init(rgb:))
}
} else { } else {
return nil return nil
} }
case let .gradient(colors, _):
return colors.map(UIColor.init(rgb:))
case let .color(color):
return [UIColor(rgb: color)]
default: default:
return nil return nil
} }
@ -763,7 +800,29 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
} }
@objc private func togglePlay() { @objc private func togglePlay() {
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)) 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() { private func preparePatternEditing() {
@ -837,12 +896,12 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
let buttonSize = CGSize(width: maxButtonWidth, height: 30.0) let buttonSize = CGSize(width: maxButtonWidth, height: 30.0)
let alpha = 1.0 - min(1.0, max(0.0, abs(offset.y) / 50.0)) let alpha = 1.0 - min(1.0, max(0.0, abs(offset.y) / 50.0))
var additionalYOffset: CGFloat = 0.0 let additionalYOffset: CGFloat = 0.0
if self.patternButtonNode.isSelected { /*if self.patternButtonNode.isSelected {
additionalYOffset = -235.0 additionalYOffset = -235.0
} else if self.colorsButtonNode.isSelected { } else if self.colorsButtonNode.isSelected {
additionalYOffset = -235.0 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 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) 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 motionAlpha = 1.0
motionFrame = centerButtonFrame motionFrame = centerButtonFrame
case .color: case .color:
motionAlpha = 0.0
patternAlpha = 1.0 patternAlpha = 1.0
if self.patternButtonNode.isSelected {
patternFrame = leftButtonFrame patternFrame = leftButtonFrame.offsetBy(dx: -centerOffset, dy: 0.0)
motionAlpha = 1.0 colorsFrame = colorsFrame.offsetBy(dx: centerOffset, dy: 0.0)
motionFrame = rightButtonFrame playAlpha = 1.0
}
colorsAlpha = 1.0
case .image: case .image:
blurAlpha = 1.0 blurAlpha = 1.0
blurFrame = leftButtonFrame blurFrame = leftButtonFrame
motionAlpha = 1.0 motionAlpha = 1.0
motionFrame = rightButtonFrame motionFrame = rightButtonFrame
case .gradient: case .gradient:
motionAlpha = 1.0 motionAlpha = 0.0
case let .file(file): patternAlpha = 1.0
if file.settings.colors.count >= 3 {
self.colorsButtonNode.colors = self.calculateGradientColors()
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 motionAlpha = 0.0
patternAlpha = 1.0 patternAlpha = 1.0
@ -948,8 +1014,9 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
private func updateMessagesLayout(layout: ContainerViewLayout, offset: CGPoint, transition: ContainedViewLayoutTransition) { private func updateMessagesLayout(layout: ContainerViewLayout, offset: CGPoint, transition: ContainedViewLayoutTransition) {
var bottomInset: CGFloat = 115.0 var bottomInset: CGFloat = 115.0
if self.patternButtonNode.isSelected || self.colorsButtonNode.isSelected { if self.patternButtonNode.isSelected || self.colorsButtonNode.isSelected {
bottomInset = 350.0 //bottomInset = 350.0
} }
var items: [ListViewItem] = [] var items: [ListViewItem] = []
@ -1058,10 +1125,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
self.blurredNode.frame = self.imageNode.bounds self.blurredNode.frame = self.imageNode.bounds
} }
var additionalYOffset: CGFloat = 0.0 let additionalYOffset: CGFloat = 0.0
if self.patternButtonNode.isSelected || self.colorsButtonNode.isSelected {
additionalYOffset = -190.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) 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)

View File

@ -15,13 +15,21 @@ enum WallpaperOptionButtonValue {
private func generateColorsImage(diameter: CGFloat, colors: [UIColor]) -> UIImage? { private func generateColorsImage(diameter: CGFloat, colors: [UIColor]) -> UIImage? {
return generateImage(CGSize(width: diameter, height: diameter), rotatedContext: { size, context in return generateImage(CGSize(width: diameter, height: diameter), rotatedContext: { size, context in
context.clear(CGRect(origin: CGPoint(), size: size)) context.clear(CGRect(origin: CGPoint(), size: size))
context.addEllipse(in: CGRect(origin: CGPoint(), size: size))
context.clip() if !colors.isEmpty {
for i in 0 ..< min(colors.count, 4) { let center = CGPoint(x: size.width / 2.0, y: size.height / 2.0)
let x = i % 2 var startAngle = -CGFloat.pi * 0.5
let y = i / 2 for i in 0 ..< colors.count {
context.setFillColor(colors[i].cgColor) 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)))
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
}
} }
}) })
} }

View File

@ -101,6 +101,10 @@ final class GroupVideoNode: ASDisplayNode {
self.containerNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:)))) 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) { func updateIsBlurred(isBlurred: Bool, light: Bool = false, animated: Bool = true) {
if self.isBlurred == isBlurred { if self.isBlurred == isBlurred {
return return

View File

@ -927,6 +927,7 @@ public final class PresentationCallImpl: PresentationCall {
let setOnFirstFrameReceived = view.setOnFirstFrameReceived let setOnFirstFrameReceived = view.setOnFirstFrameReceived
let setOnOrientationUpdated = view.setOnOrientationUpdated let setOnOrientationUpdated = view.setOnOrientationUpdated
let setOnIsMirroredUpdated = view.setOnIsMirroredUpdated let setOnIsMirroredUpdated = view.setOnIsMirroredUpdated
let updateIsEnabled = view.updateIsEnabled
completion(PresentationCallVideoView( completion(PresentationCallVideoView(
holder: view, holder: view,
view: view.view, view: view.view,
@ -978,6 +979,9 @@ public final class PresentationCallImpl: PresentationCall {
setOnIsMirroredUpdated { value in setOnIsMirroredUpdated { value in
f?(value) f?(value)
} }
},
updateIsEnabled: { value in
updateIsEnabled(value)
} }
)) ))
} else { } else {
@ -997,6 +1001,7 @@ public final class PresentationCallImpl: PresentationCall {
let setOnFirstFrameReceived = view.setOnFirstFrameReceived let setOnFirstFrameReceived = view.setOnFirstFrameReceived
let setOnOrientationUpdated = view.setOnOrientationUpdated let setOnOrientationUpdated = view.setOnOrientationUpdated
let setOnIsMirroredUpdated = view.setOnIsMirroredUpdated let setOnIsMirroredUpdated = view.setOnIsMirroredUpdated
let updateIsEnabled = view.updateIsEnabled
completion(PresentationCallVideoView( completion(PresentationCallVideoView(
holder: view, holder: view,
view: view.view, view: view.view,
@ -1048,6 +1053,9 @@ public final class PresentationCallImpl: PresentationCall {
setOnIsMirroredUpdated { value in setOnIsMirroredUpdated { value in
f?(value) f?(value)
} }
},
updateIsEnabled: { value in
updateIsEnabled(value)
} }
)) ))
} else { } else {

View File

@ -1942,9 +1942,6 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
} else if participant.muteState?.mutedByYou == true { } else if participant.muteState?.mutedByYou == true {
strongSelf.genericCallContext?.setVolume(ssrc: ssrc, volume: 0.0) 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 setOnFirstFrameReceived = view.setOnFirstFrameReceived
let setOnOrientationUpdated = view.setOnOrientationUpdated let setOnOrientationUpdated = view.setOnOrientationUpdated
let setOnIsMirroredUpdated = view.setOnIsMirroredUpdated let setOnIsMirroredUpdated = view.setOnIsMirroredUpdated
let updateIsEnabled = view.updateIsEnabled
completion(PresentationCallVideoView( completion(PresentationCallVideoView(
holder: view, holder: view,
view: view.view, view: view.view,
@ -2477,6 +2475,9 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
setOnIsMirroredUpdated { value in setOnIsMirroredUpdated { value in
f?(value) f?(value)
} }
},
updateIsEnabled: { value in
updateIsEnabled(value)
} }
)) ))
} else { } else {
@ -2915,6 +2916,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
let setOnFirstFrameReceived = view.setOnFirstFrameReceived let setOnFirstFrameReceived = view.setOnFirstFrameReceived
let setOnOrientationUpdated = view.setOnOrientationUpdated let setOnOrientationUpdated = view.setOnOrientationUpdated
let setOnIsMirroredUpdated = view.setOnIsMirroredUpdated let setOnIsMirroredUpdated = view.setOnIsMirroredUpdated
let updateIsEnabled = view.updateIsEnabled
completion(PresentationCallVideoView( completion(PresentationCallVideoView(
holder: view, holder: view,
view: view.view, view: view.view,
@ -2966,6 +2968,9 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
setOnIsMirroredUpdated { value in setOnIsMirroredUpdated { value in
f?(value) f?(value)
} }
},
updateIsEnabled: { value in
updateIsEnabled(value)
} }
)) ))
} else { } else {

View File

@ -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) 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 var hasCameraButton = self.callState?.isVideoEnabled ?? false
#if DEBUG
hasCameraButton = true
#endif
switch actionButtonState { switch actionButtonState {
case let .active(state): case let .active(state):
switch state { switch state {

View File

@ -259,6 +259,8 @@ final class VoiceChatTileItemNode: ASDisplayNode {
if let shimmerNode = self.shimmerNode { if let shimmerNode = self.shimmerNode {
shimmerNode.updateAbsoluteRect(rect, within: containerSize) 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) { func update(size: CGSize, availableWidth: CGFloat, item: VoiceChatTileItem, transition: ContainedViewLayoutTransition) {

View File

@ -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) 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 initialWidth = initialImageWidth + horizontalInsets.left + horizontalInsets.right
refineContentImageLayout = refineLayout refineContentImageLayout = refineLayout
if case let .file(_, _, _, _, isTheme, _) = wallpaper.content, isTheme { if case let .file(_, _, _, isTheme, _) = wallpaper.content, isTheme {
skipStandardStatus = true skipStandardStatus = true
} }
} }

View File

@ -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)) unboundSize = CGSize(width: floor(dimensions.cgSize.width * 0.5), height: floor(dimensions.cgSize.height * 0.5))
} else if let wallpaper = media as? WallpaperPreviewMedia { } else if let wallpaper = media as? WallpaperPreviewMedia {
switch wallpaper.content { 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 { if let thumbnail = file.previewRepresentations.first, var dimensions = file.dimensions {
let dimensionsVertical = dimensions.width < dimensions.height let dimensionsVertical = dimensions.width < dimensions.height
let thumbnailVertical = thumbnail.dimensions.width < thumbnail.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 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 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] = [] var colors: [UIColor] = []
colors.append(patternColor ?? UIColor(rgb: 0xd6e2ee, alpha: 0.5)) if patternColors.isEmpty {
if let patternBottomColor = patternBottomColor { colors.append(UIColor(rgb: 0xd6e2ee, alpha: 0.5))
colors.append(patternBottomColor) } else {
colors.append(contentsOf: patternColors.map(UIColor.init(rgb:)))
} }
patternArguments = PatternWallpaperArguments(colors: colors, rotation: rotation) patternArguments = PatternWallpaperArguments(colors: colors, rotation: rotation)
} }
@ -714,7 +715,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
} else if let wallpaper = media as? WallpaperPreviewMedia { } else if let wallpaper = media as? WallpaperPreviewMedia {
updateImageSignal = { synchronousLoad, _ in updateImageSignal = { synchronousLoad, _ in
switch wallpaper.content { switch wallpaper.content {
case let .file(file, _, _, _, isTheme, _): case let .file(file, _, _, isTheme, _):
if isTheme { if isTheme {
return themeImage(account: context.account, accountManager: context.sharedContext.accountManager, source: .file(FileMediaReference.message(message: MessageReference(message), media: file))) return themeImage(account: context.account, accountManager: context.sharedContext.accountManager, source: .file(FileMediaReference.message(message: MessageReference(message), media: file)))
} else { } else {
@ -732,12 +733,12 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
return themeImage(account: context.account, accountManager: context.sharedContext.accountManager, source: .settings(settings)) return themeImage(account: context.account, accountManager: context.sharedContext.accountManager, source: .settings(settings))
case let .color(color): case let .color(color):
return solidColorImage(color) return solidColorImage(color)
case let .gradient(topColor, bottomColor, rotation): case let .gradient(colors, rotation):
return gradientImage([topColor, bottomColor], rotation: rotation ?? 0) 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 updatedFetchControls = FetchControls(fetch: { manual in
if let strongSelf = self { if let strongSelf = self {
strongSelf.fetchDisposable.set(messageMediaFileInteractiveFetched(context: context, message: message, file: file, userInitiated: manual).start()) 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 { } else if let wallpaper = media as? WallpaperPreviewMedia {
switch wallpaper.content { switch wallpaper.content {
case let .file(file, _, _, _, _, _): case let .file(file, _, _, _, _):
updatedStatusSignal = messageMediaFileStatus(context: context, messageId: message.id, file: file) updatedStatusSignal = messageMediaFileStatus(context: context, messageId: message.id, file: file)
|> map { resourceStatus -> (MediaResourceStatus, MediaResourceStatus?) in |> map { resourceStatus -> (MediaResourceStatus, MediaResourceStatus?) in
return (resourceStatus, nil) return (resourceStatus, nil)

View File

@ -171,15 +171,13 @@ final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContentNode {
mediaAndFlags = (webpage.image ?? file, [.preferMediaBeforeText]) mediaAndFlags = (webpage.image ?? file, [.preferMediaBeforeText])
} }
} else if webpage.type == "telegram_background" { } else if webpage.type == "telegram_background" {
var topColor: UIColor? var colors: [UInt32] = []
var bottomColor: UIColor?
var rotation: Int32? var rotation: Int32?
if let wallpaper = parseWallpaperUrl(webpage.url), case let .slug(_, _, firstColor, secondColor, intensity, rotationValue) = wallpaper { if let wallpaper = parseWallpaperUrl(webpage.url), case let .slug(_, _, colorsValue, intensity, rotationValue) = wallpaper {
topColor = firstColor?.withAlphaComponent(CGFloat(intensity ?? 50) / 100.0) colors = colorsValue
bottomColor = secondColor?.withAlphaComponent(CGFloat(intensity ?? 50) / 100.0)
rotation = rotationValue 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]) mediaAndFlags = (media, [.preferMediaAspectFilled])
if let fileSize = file.size { if let fileSize = file.size {
badge = dataSizeString(fileSize, formatting: DataSizeStringFormatting(chatPresentationData: item.presentationData)) badge = dataSizeString(fileSize, formatting: DataSizeStringFormatting(chatPresentationData: item.presentationData))
@ -207,25 +205,24 @@ final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContentNode {
} }
} else if let type = webpage.type { } else if let type = webpage.type {
if type == "telegram_background" { if type == "telegram_background" {
var topColor: UIColor? var colors: [UInt32] = []
var bottomColor: UIColor? var bottomColor: UIColor?
var rotation: Int32? var rotation: Int32?
if let wallpaper = parseWallpaperUrl(webpage.url) { if let wallpaper = parseWallpaperUrl(webpage.url) {
if case let .color(color) = wallpaper { if case let .color(color) = wallpaper {
topColor = color colors = [color.rgb]
} else if case let .gradient(topColorValue, bottomColorValue, rotationValue) = wallpaper { } else if case let .gradient(colorsValue, rotationValue) = wallpaper {
topColor = topColorValue colors = colorsValue
bottomColor = bottomColorValue
rotation = rotationValue rotation = rotationValue
} }
} }
var content: WallpaperPreviewMediaContent? var content: WallpaperPreviewMediaContent?
if let topColor = topColor { if !colors.isEmpty {
if let bottomColor = bottomColor { if colors.count >= 2 {
content = .gradient(topColor, bottomColor, rotation) content = .gradient(colors, rotation)
} else { } else {
content = .color(topColor) content = .color(UIColor(rgb: colors[0]))
} }
} }
if let content = content { if let content = content {
@ -254,7 +251,7 @@ final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContentNode {
file = contentFile file = contentFile
} }
if let file = file { 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()) mediaAndFlags = (media, ChatMessageAttachedContentNodeMediaFlags())
} else if let settings = settings { } else if let settings = settings {
let media = WallpaperPreviewMedia(content: .themeSettings(settings)) let media = WallpaperPreviewMedia(content: .themeSettings(settings))

View File

@ -258,12 +258,12 @@ func openChatWallpaper(context: AccountContext, message: Message, present: @esca
if case let .wallpaper(parameter) = resolvedUrl { if case let .wallpaper(parameter) = resolvedUrl {
let source: WallpaperListSource let source: WallpaperListSource
switch parameter { switch parameter {
case let .slug(slug, options, firstColor, secondColor, intensity, rotation): case let .slug(slug, options, colors, intensity, rotation):
source = .slug(slug, content.file, options, firstColor, secondColor, intensity, rotation, message) source = .slug(slug, content.file, options, colors, intensity, rotation, message)
case let .color(color): case let .color(color):
source = .wallpaper(.color(color.argb), nil, nil, nil, nil, nil, message) source = .wallpaper(.color(color.argb), nil, [], nil, nil, message)
case let .gradient(topColor, bottomColor, rotation): case let .gradient(colors, rotation):
source = .wallpaper(.gradient([topColor.argb, bottomColor.argb], WallpaperSettings(rotation: rotation)), nil, nil, nil, nil, rotation, message) source = .wallpaper(.gradient(colors, WallpaperSettings(rotation: rotation)), nil, [], nil, rotation, message)
} }
let controller = WallpaperGalleryController(context: context, source: source) let controller = WallpaperGalleryController(context: context, source: source)

View File

@ -294,30 +294,28 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
let signal: Signal<TelegramWallpaper, GetWallpaperError> let signal: Signal<TelegramWallpaper, GetWallpaperError>
var options: WallpaperPresentationOptions? var options: WallpaperPresentationOptions?
var topColor: UIColor? var colors: [UInt32] = []
var bottomColor: UIColor?
var intensity: Int32? var intensity: Int32?
var rotation: Int32? var rotation: Int32?
switch parameter { 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) signal = getWallpaper(network: context.account.network, slug: slug)
options = wallpaperOptions options = wallpaperOptions
topColor = firstColor colors = colorsValue
bottomColor = secondColor
intensity = intensityValue intensity = intensityValue
rotation = rotationValue rotation = rotationValue
controller = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: nil)) controller = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: nil))
present(controller!, nil) present(controller!, nil)
case let .color(color): case let .color(color):
signal = .single(.color(color.argb)) signal = .single(.color(color.argb))
case let .gradient(topColor, bottomColor, rotation): case let .gradient(colors, rotation):
signal = .single(.gradient([topColor.argb, bottomColor.argb], WallpaperSettings(rotation: rotation))) signal = .single(.gradient(colors, WallpaperSettings(rotation: rotation)))
} }
let _ = (signal let _ = (signal
|> deliverOnMainQueue).start(next: { [weak controller] wallpaper in |> deliverOnMainQueue).start(next: { [weak controller] wallpaper in
controller?.dismiss() 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) present(galleryController, nil)
}, error: { [weak controller] error in }, error: { [weak controller] error in
controller?.dismiss() controller?.dismiss()

View File

@ -5,9 +5,9 @@ import TelegramCore
import SyncCore import SyncCore
enum WallpaperPreviewMediaContent: Equatable { enum WallpaperPreviewMediaContent: Equatable {
case file(TelegramMediaFile, UIColor?, UIColor?, Int32?, Bool, Bool) case file(TelegramMediaFile, [UInt32], Int32?, Bool, Bool)
case color(UIColor) case color(UIColor)
case gradient(UIColor, UIColor, Int32?) case gradient([UInt32], Int32?)
case themeSettings(TelegramThemeSettings) case themeSettings(TelegramThemeSettings)
} }

View File

@ -499,6 +499,9 @@ public final class OngoingGroupCallContext {
view?.setOnIsMirroredUpdated { value in view?.setOnIsMirroredUpdated { value in
f?(value) f?(value)
} }
},
updateIsEnabled: { [weak view] value in
view?.updateIsEnabled(value)
} }
)) ))
#else #else

View File

@ -376,6 +376,9 @@ public final class OngoingCallVideoCapturer {
}, },
setOnIsMirroredUpdated: { [weak view] f in setOnIsMirroredUpdated: { [weak view] f in
view?.setOnIsMirroredUpdated(f) view?.setOnIsMirroredUpdated(f)
},
updateIsEnabled: { [weak view] value in
view?.updateIsEnabled(value)
} }
)) ))
} else { } else {
@ -508,6 +511,7 @@ public final class OngoingCallContextPresentationCallVideoView {
public let getAspect: () -> CGFloat public let getAspect: () -> CGFloat
public let setOnOrientationUpdated: (((OngoingCallVideoOrientation, CGFloat) -> Void)?) -> Void public let setOnOrientationUpdated: (((OngoingCallVideoOrientation, CGFloat) -> Void)?) -> Void
public let setOnIsMirroredUpdated: (((Bool) -> Void)?) -> Void public let setOnIsMirroredUpdated: (((Bool) -> Void)?) -> Void
public let updateIsEnabled: (Bool) -> Void
public init( public init(
view: UIView, view: UIView,
@ -515,7 +519,8 @@ public final class OngoingCallContextPresentationCallVideoView {
getOrientation: @escaping () -> OngoingCallVideoOrientation, getOrientation: @escaping () -> OngoingCallVideoOrientation,
getAspect: @escaping () -> CGFloat, getAspect: @escaping () -> CGFloat,
setOnOrientationUpdated: @escaping (((OngoingCallVideoOrientation, CGFloat) -> Void)?) -> Void, setOnOrientationUpdated: @escaping (((OngoingCallVideoOrientation, CGFloat) -> Void)?) -> Void,
setOnIsMirroredUpdated: @escaping (((Bool) -> Void)?) -> Void setOnIsMirroredUpdated: @escaping (((Bool) -> Void)?) -> Void,
updateIsEnabled: @escaping (Bool) -> Void
) { ) {
self.view = view self.view = view
self.setOnFirstFrameReceived = setOnFirstFrameReceived self.setOnFirstFrameReceived = setOnFirstFrameReceived
@ -523,6 +528,7 @@ public final class OngoingCallContextPresentationCallVideoView {
self.getAspect = getAspect self.getAspect = getAspect
self.setOnOrientationUpdated = setOnOrientationUpdated self.setOnOrientationUpdated = setOnOrientationUpdated
self.setOnIsMirroredUpdated = setOnIsMirroredUpdated self.setOnIsMirroredUpdated = setOnIsMirroredUpdated
self.updateIsEnabled = updateIsEnabled
} }
} }
@ -918,6 +924,9 @@ public final class OngoingCallContext {
view?.setOnIsMirroredUpdated { value in view?.setOnIsMirroredUpdated { value in
f?(value) f?(value)
} }
},
updateIsEnabled: { [weak view] value in
view?.updateIsEnabled(value)
} }
)) ))
} else { } else {

View File

@ -19,6 +19,7 @@ objc_library(
"tgcalls/tgcalls/platform/uwp/**", "tgcalls/tgcalls/platform/uwp/**",
"tgcalls/tgcalls/platform/darwin/VideoCameraCapturerMac.*", "tgcalls/tgcalls/platform/darwin/VideoCameraCapturerMac.*",
"tgcalls/tgcalls/platform/darwin/VideoMetalViewMac.*", "tgcalls/tgcalls/platform/darwin/VideoMetalViewMac.*",
"tgcalls/tgcalls/platform/darwin/VideoSampleBufferViewMac.*",
"tgcalls/tgcalls/platform/darwin/GLVideoViewMac.*", "tgcalls/tgcalls/platform/darwin/GLVideoViewMac.*",
"tgcalls/tgcalls/platform/darwin/ScreenCapturer.*", "tgcalls/tgcalls/platform/darwin/ScreenCapturer.*",
"tgcalls/tgcalls/platform/darwin/DesktopSharingCapturer.*", "tgcalls/tgcalls/platform/darwin/DesktopSharingCapturer.*",

View File

@ -101,6 +101,7 @@ typedef NS_ENUM(int32_t, OngoingCallDataSavingWebrtc) {
- (void)setOnFirstFrameReceived:(void (^ _Nullable)(float))onFirstFrameReceived; - (void)setOnFirstFrameReceived:(void (^ _Nullable)(float))onFirstFrameReceived;
- (void)setOnOrientationUpdated:(void (^ _Nullable)(OngoingCallVideoOrientationWebrtc, CGFloat))onOrientationUpdated; - (void)setOnOrientationUpdated:(void (^ _Nullable)(OngoingCallVideoOrientationWebrtc, CGFloat))onOrientationUpdated;
- (void)setOnIsMirroredUpdated:(void (^ _Nullable)(bool))onIsMirroredUpdated; - (void)setOnIsMirroredUpdated:(void (^ _Nullable)(bool))onIsMirroredUpdated;
- (void)updateIsEnabled:(bool)isEnabled;
#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
- (void)setVideoContentMode:(CALayerContentsGravity _Nonnull )mode; - (void)setVideoContentMode:(CALayerContentsGravity _Nonnull )mode;
- (void)setForceMirrored:(bool)forceMirrored; - (void)setForceMirrored:(bool)forceMirrored;

View File

@ -101,6 +101,10 @@
} }
} }
- (void)updateIsEnabled:(bool)isEnabled {
[self setEnabled:isEnabled];
}
@end @end
@interface GLVideoView (VideoViewImpl) <OngoingCallThreadLocalContextWebrtcVideoView, OngoingCallThreadLocalContextWebrtcVideoViewImpl> @interface GLVideoView (VideoViewImpl) <OngoingCallThreadLocalContextWebrtcVideoView, OngoingCallThreadLocalContextWebrtcVideoViewImpl>
@ -144,6 +148,9 @@
} }
} }
- (void)updateIsEnabled:(bool)__unused isEnabled {
}
@end @end
@interface VideoSampleBufferView (VideoViewImpl) <OngoingCallThreadLocalContextWebrtcVideoView, OngoingCallThreadLocalContextWebrtcVideoViewImpl> @interface VideoSampleBufferView (VideoViewImpl) <OngoingCallThreadLocalContextWebrtcVideoView, OngoingCallThreadLocalContextWebrtcVideoViewImpl>
@ -187,6 +194,10 @@
} }
} }
- (void)updateIsEnabled:(bool)isEnabled {
[self setEnabled:isEnabled];
}
@end @end
@interface OngoingCallThreadLocalContextVideoCapturer () { @interface OngoingCallThreadLocalContextVideoCapturer () {
@ -1271,7 +1282,21 @@ private:
__weak GroupCallThreadLocalContext *weakSelf = self; __weak GroupCallThreadLocalContext *weakSelf = self;
id<OngoingCallThreadLocalContextQueueWebrtc> queue = _queue; id<OngoingCallThreadLocalContextQueueWebrtc> queue = _queue;
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
if ([VideoMetalView isSupported]) { if (true) {
VideoSampleBufferView *remoteRenderer = [[VideoSampleBufferView alloc] initWithFrame:CGRectZero];
remoteRenderer.videoContentMode = UIViewContentModeScaleAspectFill;
std::shared_ptr<rtc::VideoSinkInterface<webrtc::VideoFrame>> 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]; VideoMetalView *remoteRenderer = [[VideoMetalView alloc] initWithFrame:CGRectZero];
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
remoteRenderer.videoContentMode = UIViewContentModeScaleToFill; remoteRenderer.videoContentMode = UIViewContentModeScaleToFill;

@ -1 +1 @@
Subproject commit 66186febe0e20d7bc39053e627f93fd95a5ecac9 Subproject commit 197878f551449341bc3fa74e117d011a9d0e8120

View File

@ -186,7 +186,7 @@ public func parseInternalUrl(query: String) -> ParsedInternalUrl? {
let parameter: WallpaperUrlParameter let parameter: WallpaperUrlParameter
if [6, 8].contains(component.count), component.rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789abcdefABCDEF").inverted) == nil, let color = UIColor(hexString: component) { if [6, 8].contains(component.count), component.rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789abcdefABCDEF").inverted) == nil, let color = UIColor(hexString: component) {
parameter = .color(color) 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? var rotation: Int32?
if let queryItems = components.queryItems { if let queryItems = components.queryItems {
for queryItem in queryItems { for queryItem in queryItems {
@ -197,17 +197,33 @@ public func parseInternalUrl(query: String) -> ParsedInternalUrl? {
} }
} }
} }
let components = component.components(separatedBy: "-") if component.contains("~") {
if components.count == 2, let topColor = UIColor(hexString: components[0]), let bottomColor = UIColor(hexString: components[1]) { let components = component.components(separatedBy: "~")
parameter = .gradient(topColor, bottomColor, rotation)
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 { } else {
return nil return nil
} }
} else {
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 { } else {
var options: WallpaperPresentationOptions = [] var options: WallpaperPresentationOptions = []
var intensity: Int32? var intensity: Int32?
var topColor: UIColor? var colors: [UInt32] = []
var bottomColor: UIColor?
var rotation: Int32? var rotation: Int32?
if let queryItems = components.queryItems { if let queryItems = components.queryItems {
for queryItem in queryItems { for queryItem in queryItems {
@ -225,12 +241,18 @@ public func parseInternalUrl(query: String) -> ParsedInternalUrl? {
} }
} else if queryItem.name == "bg_color" { } 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) { 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 { } else if [13, 15, 17].contains(value.count), value.rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789abcdefABCDEF-").inverted) == nil {
let components = value.components(separatedBy: "-") let components = value.components(separatedBy: "-")
if components.count == 2, let topColorValue = UIColor(hexString: components[0]), let bottomColorValue = UIColor(hexString: components[1]) { if components.count == 2, let topColorValue = UIColor(hexString: components[0]), let bottomColorValue = UIColor(hexString: components[1]) {
topColor = topColorValue colors = [topColorValue.rgb, bottomColorValue.rgb]
bottomColor = bottomColorValue }
} 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" { } 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) return .wallpaper(parameter)
} else if pathComponents[0] == "addtheme" { } else if pathComponents[0] == "addtheme" {

View File

@ -1136,7 +1136,20 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
outgoingColor = (bubbleColor, bubbleColor) outgoingColor = (bubbleColor, bubbleColor)
} }
} else { } 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)) outgoingColor = (UIColor(rgb: 0xe1ffc7), UIColor(rgb: 0xe1ffc7))
} }
case .day: case .day:
@ -1190,6 +1203,8 @@ public func themeIconImage(account: Account, accountManager: AccountManager, the
colors = [0xd6e2ee] colors = [0xd6e2ee]
topBackgroundColor = UIColor(rgb: 0xd6e2ee) topBackgroundColor = UIColor(rgb: 0xd6e2ee)
} }
} else {
colors = defaultBuiltinWallpaperGradientColors.map(\.rgb)
} }
colorsSignal = .single(((topBackgroundColor, bottomBackgroundColor, colors), (incomingColor, incomingColor), outgoingColor, nil, rotation)) colorsSignal = .single(((topBackgroundColor, bottomBackgroundColor, colors), (incomingColor, incomingColor), outgoingColor, nil, rotation))

View File

@ -41,6 +41,8 @@ objc_library(
], ],
copts = [ copts = [
"-D{name}=rnnoise_{name}".format(name = name) for name in replace_symbol_list "-D{name}=rnnoise_{name}".format(name = name) for name in replace_symbol_list
] + [
"-Os",
], ],
visibility = [ visibility = [
"//visibility:public", "//visibility:public",

View File

@ -9,7 +9,7 @@ config_setting(
) )
optimization_flags = select({ optimization_flags = select({
#":debug_build": ["-Os"], ":debug_build": ["-Os"],
"//conditions:default": [], "//conditions:default": [],
}) })