mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-08 19:10:53 +00:00
Background portal views
This commit is contained in:
parent
48cb7f25ec
commit
11409151df
@ -90,7 +90,6 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
||||
case experimentalCompatibility(Bool)
|
||||
case enableDebugDataDisplay(Bool)
|
||||
case acceleratedStickers(Bool)
|
||||
case experimentalBackground(Bool)
|
||||
case inlineForums(Bool)
|
||||
case localTranscription(Bool)
|
||||
case enableReactionOverrides(Bool)
|
||||
@ -117,7 +116,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
||||
return DebugControllerSection.logging.rawValue
|
||||
case .enableRaiseToSpeak, .keepChatNavigationStack, .skipReadHistory, .crashOnSlowQueries:
|
||||
return DebugControllerSection.experiments.rawValue
|
||||
case .clearTips, .resetTranslationStates, .resetNotifications, .crash, .resetData, .resetDatabase, .resetDatabaseAndCache, .resetHoles, .reindexUnread, .resetCacheIndex, .reindexCache, .resetBiometricsData, .resetWebViewCache, .optimizeDatabase, .photoPreview, .knockoutWallpaper, .playerEmbedding, .playlistPlayback, .enableQuickReactionSwitch, .voiceConference, .experimentalCompatibility, .enableDebugDataDisplay, .acceleratedStickers, .experimentalBackground, .inlineForums, .localTranscription, . enableReactionOverrides, .restorePurchases:
|
||||
case .clearTips, .resetTranslationStates, .resetNotifications, .crash, .resetData, .resetDatabase, .resetDatabaseAndCache, .resetHoles, .reindexUnread, .resetCacheIndex, .reindexCache, .resetBiometricsData, .resetWebViewCache, .optimizeDatabase, .photoPreview, .knockoutWallpaper, .playerEmbedding, .playlistPlayback, .enableQuickReactionSwitch, .voiceConference, .experimentalCompatibility, .enableDebugDataDisplay, .acceleratedStickers, .inlineForums, .localTranscription, . enableReactionOverrides, .restorePurchases:
|
||||
return DebugControllerSection.experiments.rawValue
|
||||
case .preferredVideoCodec:
|
||||
return DebugControllerSection.videoExperiments.rawValue
|
||||
@ -202,8 +201,6 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
||||
return 34
|
||||
case .acceleratedStickers:
|
||||
return 35
|
||||
case .experimentalBackground:
|
||||
return 36
|
||||
case .inlineForums:
|
||||
return 37
|
||||
case .localTranscription:
|
||||
@ -1181,16 +1178,6 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
||||
})
|
||||
}).start()
|
||||
})
|
||||
case let .experimentalBackground(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Background Experiment", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
let _ = arguments.sharedContext.accountManager.transaction ({ transaction in
|
||||
transaction.updateSharedData(ApplicationSpecificSharedDataKeys.experimentalUISettings, { settings in
|
||||
var settings = settings?.get(ExperimentalUISettings.self) ?? ExperimentalUISettings.defaultSettings
|
||||
settings.experimentalBackground = value
|
||||
return PreferencesEntry(settings)
|
||||
})
|
||||
}).start()
|
||||
})
|
||||
case let .inlineForums(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Inline Forums", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
let _ = arguments.sharedContext.accountManager.transaction ({ transaction in
|
||||
@ -1371,7 +1358,6 @@ private func debugControllerEntries(sharedContext: SharedAccountContext, present
|
||||
entries.append(.experimentalCompatibility(experimentalSettings.experimentalCompatibility))
|
||||
entries.append(.enableDebugDataDisplay(experimentalSettings.enableDebugDataDisplay))
|
||||
entries.append(.acceleratedStickers(experimentalSettings.acceleratedStickers))
|
||||
entries.append(.experimentalBackground(experimentalSettings.experimentalBackground))
|
||||
entries.append(.inlineForums(experimentalSettings.inlineForums))
|
||||
entries.append(.localTranscription(experimentalSettings.localTranscription))
|
||||
if case .internal = sharedContext.applicationBindings.appBuildType {
|
||||
|
@ -523,7 +523,7 @@ final class MediaPickerSelectedListNode: ASDisplayNode, UIScrollViewDelegate, UI
|
||||
self.context = context
|
||||
self.persistentItems = persistentItems
|
||||
|
||||
self.wallpaperBackgroundNode = createWallpaperBackgroundNode(context: context, forChatDisplay: true, useSharedAnimationPhase: false, useExperimentalImplementation: context.sharedContext.immediateExperimentalUISettings.experimentalBackground)
|
||||
self.wallpaperBackgroundNode = createWallpaperBackgroundNode(context: context, forChatDisplay: true, useSharedAnimationPhase: false)
|
||||
self.wallpaperBackgroundNode.backgroundColor = .black
|
||||
self.scrollNode = ASScrollNode()
|
||||
|
||||
|
@ -572,7 +572,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
default:
|
||||
break
|
||||
}
|
||||
self.chatBackgroundNode = createWallpaperBackgroundNode(context: context, forChatDisplay: true, useSharedAnimationPhase: useSharedAnimationPhase, useExperimentalImplementation: self.context.sharedContext.immediateExperimentalUISettings.experimentalBackground)
|
||||
self.chatBackgroundNode = createWallpaperBackgroundNode(context: context, forChatDisplay: true, useSharedAnimationPhase: useSharedAnimationPhase)
|
||||
self.wallpaperReady.set(self.chatBackgroundNode.isReady)
|
||||
|
||||
var locationBroadcastPanelSource: LocationBroadcastPanelSource
|
||||
|
@ -1531,7 +1531,7 @@ private class QrContentNode: ASDisplayNode, ContentNode {
|
||||
|
||||
self.containerNode = ASDisplayNode()
|
||||
|
||||
self.wallpaperBackgroundNode = createWallpaperBackgroundNode(context: context, forChatDisplay: true, useSharedAnimationPhase: false, useExperimentalImplementation: context.sharedContext.immediateExperimentalUISettings.experimentalBackground)
|
||||
self.wallpaperBackgroundNode = createWallpaperBackgroundNode(context: context, forChatDisplay: true, useSharedAnimationPhase: false)
|
||||
|
||||
self.codeBackgroundNode = ASDisplayNode()
|
||||
self.codeBackgroundNode.backgroundColor = .white
|
||||
@ -2022,7 +2022,7 @@ private class MessageContentNode: ASDisplayNode, ContentNode {
|
||||
|
||||
self.containerNode = ASDisplayNode()
|
||||
|
||||
self.wallpaperBackgroundNode = createWallpaperBackgroundNode(context: context, forChatDisplay: true, useSharedAnimationPhase: false, useExperimentalImplementation: context.sharedContext.immediateExperimentalUISettings.experimentalBackground)
|
||||
self.wallpaperBackgroundNode = createWallpaperBackgroundNode(context: context, forChatDisplay: true, useSharedAnimationPhase: false)
|
||||
|
||||
self.backgroundNode = ASDisplayNode()
|
||||
self.backgroundImageNode = ASImageNode()
|
||||
|
@ -40,7 +40,6 @@ public struct ExperimentalUISettings: Codable, Equatable {
|
||||
public var experimentalCompatibility: Bool
|
||||
public var enableDebugDataDisplay: Bool
|
||||
public var acceleratedStickers: Bool
|
||||
public var experimentalBackground: Bool
|
||||
public var inlineStickers: Bool
|
||||
public var localTranscription: Bool
|
||||
public var enableReactionOverrides: Bool
|
||||
@ -68,7 +67,6 @@ public struct ExperimentalUISettings: Codable, Equatable {
|
||||
experimentalCompatibility: false,
|
||||
enableDebugDataDisplay: false,
|
||||
acceleratedStickers: false,
|
||||
experimentalBackground: false,
|
||||
inlineStickers: false,
|
||||
localTranscription: false,
|
||||
enableReactionOverrides: false,
|
||||
@ -97,7 +95,6 @@ public struct ExperimentalUISettings: Codable, Equatable {
|
||||
experimentalCompatibility: Bool,
|
||||
enableDebugDataDisplay: Bool,
|
||||
acceleratedStickers: Bool,
|
||||
experimentalBackground: Bool,
|
||||
inlineStickers: Bool,
|
||||
localTranscription: Bool,
|
||||
enableReactionOverrides: Bool,
|
||||
@ -123,7 +120,6 @@ public struct ExperimentalUISettings: Codable, Equatable {
|
||||
self.experimentalCompatibility = experimentalCompatibility
|
||||
self.enableDebugDataDisplay = enableDebugDataDisplay
|
||||
self.acceleratedStickers = acceleratedStickers
|
||||
self.experimentalBackground = experimentalBackground
|
||||
self.inlineStickers = inlineStickers
|
||||
self.localTranscription = localTranscription
|
||||
self.enableReactionOverrides = enableReactionOverrides
|
||||
@ -153,7 +149,6 @@ public struct ExperimentalUISettings: Codable, Equatable {
|
||||
self.experimentalCompatibility = (try container.decodeIfPresent(Int32.self, forKey: "experimentalCompatibility") ?? 0) != 0
|
||||
self.enableDebugDataDisplay = (try container.decodeIfPresent(Int32.self, forKey: "enableDebugDataDisplay") ?? 0) != 0
|
||||
self.acceleratedStickers = (try container.decodeIfPresent(Int32.self, forKey: "acceleratedStickers") ?? 0) != 0
|
||||
self.experimentalBackground = (try container.decodeIfPresent(Int32.self, forKey: "experimentalBackground") ?? 0) != 0
|
||||
self.inlineStickers = (try container.decodeIfPresent(Int32.self, forKey: "inlineStickers") ?? 0) != 0
|
||||
self.localTranscription = (try container.decodeIfPresent(Int32.self, forKey: "localTranscription") ?? 0) != 0
|
||||
self.enableReactionOverrides = try container.decodeIfPresent(Bool.self, forKey: "enableReactionOverrides") ?? false
|
||||
@ -183,7 +178,6 @@ public struct ExperimentalUISettings: Codable, Equatable {
|
||||
try container.encode((self.experimentalCompatibility ? 1 : 0) as Int32, forKey: "experimentalCompatibility")
|
||||
try container.encode((self.enableDebugDataDisplay ? 1 : 0) as Int32, forKey: "enableDebugDataDisplay")
|
||||
try container.encode((self.acceleratedStickers ? 1 : 0) as Int32, forKey: "acceleratedStickers")
|
||||
try container.encode((self.experimentalBackground ? 1 : 0) as Int32, forKey: "experimentalBackground")
|
||||
try container.encode((self.inlineStickers ? 1 : 0) as Int32, forKey: "inlineStickers")
|
||||
try container.encode((self.localTranscription ? 1 : 0) as Int32, forKey: "localTranscription")
|
||||
try container.encode(self.enableReactionOverrides, forKey: "enableReactionOverrides")
|
||||
|
@ -1,313 +1 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import AsyncDisplayKit
|
||||
import Display
|
||||
import GradientBackground
|
||||
import TelegramPresentationData
|
||||
import TelegramCore
|
||||
import AccountContext
|
||||
import SwiftSignalKit
|
||||
import WallpaperResources
|
||||
import FastBlur
|
||||
import Svg
|
||||
import GZip
|
||||
import AppBundle
|
||||
import AnimatedStickerNode
|
||||
import TelegramAnimatedStickerNode
|
||||
import HierarchyTrackingLayer
|
||||
import MetalKit
|
||||
import HierarchyTrackingLayer
|
||||
import simd
|
||||
|
||||
private final class NullActionClass: NSObject, CAAction {
|
||||
static let shared = NullActionClass()
|
||||
|
||||
@objc public func run(forKey event: String, object anObject: Any, arguments dict: [AnyHashable : Any]?) {
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
open class SimpleMetalLayer: CAMetalLayer {
|
||||
override open func action(forKey event: String) -> CAAction? {
|
||||
return nullAction
|
||||
}
|
||||
|
||||
override public init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
override public init(layer: Any) {
|
||||
super.init(layer: layer)
|
||||
}
|
||||
|
||||
required public init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
}
|
||||
|
||||
private func makePipelineState(device: MTLDevice, library: MTLLibrary, vertexProgram: String, fragmentProgram: String) -> MTLRenderPipelineState? {
|
||||
guard let loadedVertexProgram = library.makeFunction(name: vertexProgram) else {
|
||||
return nil
|
||||
}
|
||||
guard let loadedFragmentProgram = library.makeFunction(name: fragmentProgram) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let pipelineStateDescriptor = MTLRenderPipelineDescriptor()
|
||||
pipelineStateDescriptor.vertexFunction = loadedVertexProgram
|
||||
pipelineStateDescriptor.fragmentFunction = loadedFragmentProgram
|
||||
pipelineStateDescriptor.colorAttachments[0].pixelFormat = .bgra8Unorm
|
||||
guard let pipelineState = try? device.makeRenderPipelineState(descriptor: pipelineStateDescriptor) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return pipelineState
|
||||
}
|
||||
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
final class MetalWallpaperBackgroundNode: ASDisplayNode, WallpaperBackgroundNode {
|
||||
private let device: MTLDevice
|
||||
private let metalLayer: SimpleMetalLayer
|
||||
private let commandQueue: MTLCommandQueue
|
||||
private let renderPipelineState: MTLRenderPipelineState
|
||||
|
||||
private let hierarchyTrackingLayer = HierarchyTrackingLayer()
|
||||
|
||||
var isReady: Signal<Bool, NoError> {
|
||||
return .single(true)
|
||||
}
|
||||
|
||||
var rotation: CGFloat = 0.0
|
||||
|
||||
private var animationPhase: Int = 0
|
||||
|
||||
private var animationThread: Thread?
|
||||
private var displayLink: CADisplayLink?
|
||||
|
||||
override init() {
|
||||
self.device = MTLCreateSystemDefaultDevice()!
|
||||
self.metalLayer = SimpleMetalLayer()
|
||||
self.metalLayer.maximumDrawableCount = 3
|
||||
self.metalLayer.presentsWithTransaction = true
|
||||
self.metalLayer.contentsScale = UIScreenScale
|
||||
self.commandQueue = self.device.makeCommandQueue()!
|
||||
|
||||
let mainBundle = Bundle(for: MetalWallpaperBackgroundNode.self)
|
||||
|
||||
guard let path = mainBundle.path(forResource: "WallpaperBackgroundNodeBundle", ofType: "bundle") else {
|
||||
preconditionFailure()
|
||||
}
|
||||
guard let bundle = Bundle(path: path) else {
|
||||
preconditionFailure()
|
||||
}
|
||||
guard let defaultLibrary = try? self.device.makeDefaultLibrary(bundle: bundle) else {
|
||||
preconditionFailure()
|
||||
}
|
||||
|
||||
guard let renderPipelineState = makePipelineState(device: self.device, library: defaultLibrary, vertexProgram: "wallpaperVertex", fragmentProgram: "wallpaperFragment") else {
|
||||
preconditionFailure()
|
||||
}
|
||||
self.renderPipelineState = renderPipelineState
|
||||
|
||||
super.init()
|
||||
|
||||
self.metalLayer.device = self.device
|
||||
self.metalLayer.pixelFormat = .bgra8Unorm
|
||||
self.metalLayer.framebufferOnly = true
|
||||
self.metalLayer.allowsNextDrawableTimeout = true
|
||||
self.metalLayer.isOpaque = true
|
||||
|
||||
self.layer.addSublayer(self.metalLayer)
|
||||
self.layer.addSublayer(self.hierarchyTrackingLayer)
|
||||
|
||||
self.hierarchyTrackingLayer.opacity = 0.0
|
||||
self.hierarchyTrackingLayer.didEnterHierarchy = { [weak self] in
|
||||
self?.updateIsVisible(true)
|
||||
}
|
||||
self.hierarchyTrackingLayer.didExitHierarchy = { [weak self] in
|
||||
self?.updateIsVisible(false)
|
||||
}
|
||||
}
|
||||
|
||||
func update(wallpaper: TelegramWallpaper) {
|
||||
|
||||
}
|
||||
|
||||
func _internalUpdateIsSettingUpWallpaper() {
|
||||
|
||||
}
|
||||
|
||||
func updateLayout(size: CGSize, displayMode: WallpaperDisplayMode, transition: ContainedViewLayoutTransition) {
|
||||
if self.metalLayer.drawableSize != size {
|
||||
self.metalLayer.drawableSize = size
|
||||
|
||||
transition.updateFrame(layer: self.metalLayer, frame: CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
self.redraw()
|
||||
}
|
||||
}
|
||||
|
||||
private func updateIsVisible(_ isVisible: Bool) {
|
||||
if isVisible {
|
||||
if self.displayLink == nil {
|
||||
let displayLink = CADisplayLink(target: DisplayLinkTarget { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.redraw()
|
||||
}, selector: #selector(DisplayLinkTarget.event))
|
||||
self.displayLink = displayLink
|
||||
if #available(iOS 15.0, iOSApplicationExtension 15.0, *) {
|
||||
if "".isEmpty {
|
||||
displayLink.preferredFrameRateRange = CAFrameRateRange(minimum: 60.0, maximum: 60.0, preferred: 60.0)
|
||||
} else {
|
||||
displayLink.preferredFrameRateRange = CAFrameRateRange(minimum: Float(UIScreen.main.maximumFramesPerSecond), maximum: Float(UIScreen.main.maximumFramesPerSecond), preferred: Float(UIScreen.main.maximumFramesPerSecond))
|
||||
}
|
||||
}
|
||||
displayLink.isPaused = false
|
||||
|
||||
if !"".isEmpty {
|
||||
self.animationThread = Thread(block: {
|
||||
displayLink.add(to: .current, forMode: .common)
|
||||
|
||||
while true {
|
||||
if Thread.current.isCancelled {
|
||||
break
|
||||
}
|
||||
RunLoop.current.run(until: .init(timeIntervalSinceNow: 1.0))
|
||||
}
|
||||
})
|
||||
self.animationThread?.name = "MetalWallpaperBackgroundNode"
|
||||
self.animationThread?.qualityOfService = .userInteractive
|
||||
self.animationThread?.start()
|
||||
} else {
|
||||
displayLink.add(to: .current, forMode: .common)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if let displayLink = self.displayLink {
|
||||
self.displayLink = nil
|
||||
|
||||
displayLink.invalidate()
|
||||
}
|
||||
if let animationThread = self.animationThread {
|
||||
self.animationThread = nil
|
||||
animationThread.cancel()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var previousDrawTime: Double?
|
||||
|
||||
private func redraw() {
|
||||
let timestamp = CACurrentMediaTime()
|
||||
if let previousDrawTime = self.previousDrawTime {
|
||||
let _ = previousDrawTime
|
||||
//print("frame time \((timestamp - previousDrawTime) * 1000.0)")
|
||||
}
|
||||
self.previousDrawTime = timestamp
|
||||
|
||||
self.animationPhase += 1
|
||||
let animationOffset = Float(self.animationPhase % 200) / 200.0
|
||||
let _ = animationOffset
|
||||
|
||||
guard let commandBuffer = self.commandQueue.makeCommandBuffer() else {
|
||||
return
|
||||
}
|
||||
guard let drawable = self.metalLayer.nextDrawable() else {
|
||||
return
|
||||
}
|
||||
|
||||
let drawTime = CACurrentMediaTime() - timestamp
|
||||
if drawTime > 9.0 / 1000.0 {
|
||||
print("get time \(drawTime * 1000.0)")
|
||||
}
|
||||
|
||||
let renderPassDescriptor = MTLRenderPassDescriptor()
|
||||
renderPassDescriptor.colorAttachments[0].texture = drawable.texture
|
||||
renderPassDescriptor.colorAttachments[0].loadAction = .clear
|
||||
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColor(
|
||||
red: 0.0,
|
||||
green: 0.0,
|
||||
blue: 0.0,
|
||||
alpha: 1.0
|
||||
)
|
||||
|
||||
guard let renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor) else {
|
||||
return
|
||||
}
|
||||
|
||||
var vertices: [Float] = [
|
||||
-1.0, -1.0,
|
||||
1.0, -1.0,
|
||||
-1.0, 1.0,
|
||||
1.0, 1.0
|
||||
]
|
||||
|
||||
renderEncoder.setRenderPipelineState(self.renderPipelineState)
|
||||
|
||||
renderEncoder.setVertexBytes(&vertices, length: 4 * vertices.count, index: 0)
|
||||
|
||||
var resolution = simd_uint2(UInt32(drawable.texture.width), UInt32(drawable.texture.height))
|
||||
renderEncoder.setFragmentBytes(&resolution, length: MemoryLayout<simd_uint2>.size * 2, index: 0)
|
||||
|
||||
var time = Float(timestamp) * 0.25
|
||||
renderEncoder.setFragmentBytes(&time, length: 4, index: 1)
|
||||
|
||||
renderEncoder.drawPrimitives(type: .triangleStrip, vertexStart: 0, vertexCount: 4, instanceCount: 1)
|
||||
|
||||
renderEncoder.endEncoding()
|
||||
|
||||
if self.metalLayer.presentsWithTransaction {
|
||||
if Thread.isMainThread {
|
||||
commandBuffer.commit()
|
||||
commandBuffer.waitUntilScheduled()
|
||||
drawable.present()
|
||||
} else {
|
||||
CATransaction.begin()
|
||||
commandBuffer.commit()
|
||||
commandBuffer.waitUntilScheduled()
|
||||
drawable.present()
|
||||
CATransaction.commit()
|
||||
}
|
||||
} else {
|
||||
commandBuffer.addScheduledHandler { _ in
|
||||
drawable.present()
|
||||
}
|
||||
commandBuffer.commit()
|
||||
}
|
||||
}
|
||||
|
||||
func animateEvent(transition: ContainedViewLayoutTransition, extendAnimation: Bool) {
|
||||
|
||||
}
|
||||
|
||||
func updateIsLooping(_ isLooping: Bool) {
|
||||
|
||||
}
|
||||
|
||||
func updateBubbleTheme(bubbleTheme: PresentationTheme, bubbleCorners: PresentationChatBubbleCorners) {
|
||||
|
||||
}
|
||||
|
||||
func hasBubbleBackground(for type: WallpaperBubbleType) -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func hasExtraBubbleBackground() -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func makeBubbleBackground(for type: WallpaperBubbleType) -> WallpaperBubbleBackgroundNode? {
|
||||
return nil
|
||||
}
|
||||
|
||||
func makeFreeBackground() -> PortalView? {
|
||||
return nil
|
||||
}
|
||||
|
||||
func makeDimmedNode() -> ASDisplayNode? {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user