mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-09 03:20:48 +00:00
Shimmer
This commit is contained in:
parent
6afe111f39
commit
3fee7b305e
@ -1966,7 +1966,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
guard let self else {
|
||||
return nil
|
||||
}
|
||||
return (self.displayNode, absoluteFrame.insetBy(dx: 0.0, dy: 0.0).offsetBy(dx: 0.0, dy: 0.0))
|
||||
return (self.displayNode, absoluteFrame.insetBy(dx: 0.0, dy: 0.0).offsetBy(dx: 0.0, dy: 4.0))
|
||||
}))
|
||||
|
||||
#if !DEBUG
|
||||
|
@ -42,7 +42,19 @@ private final class MuteMonitor {
|
||||
init(updated: @escaping (Bool) -> Void) {
|
||||
self.updated = updated
|
||||
|
||||
let status = notify_register_dispatch("com.apple.springboard.ringerstate", &self.token, DispatchQueue.main, { [weak self] value in
|
||||
func encodeText(string: String, key: Int16) -> String {
|
||||
let nsString = string as NSString
|
||||
let result = NSMutableString()
|
||||
for i in 0 ..< nsString.length {
|
||||
var c: unichar = nsString.character(at: i)
|
||||
c = unichar(Int16(c) + key)
|
||||
result.append(NSString(characters: &c, length: 1) as String)
|
||||
}
|
||||
return result as String
|
||||
}
|
||||
|
||||
let keyString = encodeText(string: "dpn/bqqmf/tqsjohcpbse/sjohfstubuf", key: -1)
|
||||
let status = notify_register_dispatch(keyString, &self.token, DispatchQueue.main, { [weak self] value in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
@ -54,6 +54,7 @@ final class StoryItemContentComponent: Component {
|
||||
final class View: StoryContentItem.View {
|
||||
private let imageView: StoryItemImageView
|
||||
private var videoNode: UniversalVideoNode?
|
||||
private var loadingEffectView: StoryItemLoadingEffectView?
|
||||
|
||||
private var currentMessageMedia: EngineMedia?
|
||||
private var fetchDisposable: Disposable?
|
||||
@ -363,6 +364,11 @@ final class StoryItemContentComponent: Component {
|
||||
self.environment?.markAsSeen(StoryId(peerId: component.peer.id, id: component.item.id))
|
||||
}
|
||||
}
|
||||
|
||||
if !self.contentLoaded {
|
||||
self.contentLoaded = true
|
||||
self.state?.updated(transition: .immediate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -608,6 +614,23 @@ final class StoryItemContentComponent: Component {
|
||||
print("\(CFAbsoluteTimeGetCurrent()) Synchronous: \((CFAbsoluteTimeGetCurrent() - startTime) * 1000.0) ms")
|
||||
}
|
||||
|
||||
if !self.contentLoaded {
|
||||
let loadingEffectView: StoryItemLoadingEffectView
|
||||
if let current = self.loadingEffectView {
|
||||
loadingEffectView = current
|
||||
} else {
|
||||
loadingEffectView = StoryItemLoadingEffectView(frame: CGRect())
|
||||
self.loadingEffectView = loadingEffectView
|
||||
self.addSubview(loadingEffectView)
|
||||
}
|
||||
loadingEffectView.update(size: availableSize, transition: transition)
|
||||
} else if let loadingEffectView = self.loadingEffectView{
|
||||
self.loadingEffectView = nil
|
||||
loadingEffectView.layer.animateAlpha(from: loadingEffectView.alpha, to: 0.0, duration: 0.18, removeOnCompletion: false, completion: { [weak loadingEffectView] _ in
|
||||
loadingEffectView?.removeFromSuperview()
|
||||
})
|
||||
}
|
||||
|
||||
return availableSize
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,91 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import HierarchyTrackingLayer
|
||||
import ComponentFlow
|
||||
import Display
|
||||
|
||||
final class StoryItemLoadingEffectView: UIView {
|
||||
private let hierarchyTrackingLayer: HierarchyTrackingLayer
|
||||
|
||||
private let gradientWidth: CGFloat
|
||||
private let backgroundView: UIImageView
|
||||
|
||||
private let borderGradientView: UIImageView
|
||||
private let borderContaineView: UIView
|
||||
private let borderMaskLayer: SimpleShapeLayer
|
||||
|
||||
override init(frame: CGRect) {
|
||||
self.hierarchyTrackingLayer = HierarchyTrackingLayer()
|
||||
|
||||
self.gradientWidth = 500.0
|
||||
self.backgroundView = UIImageView()
|
||||
|
||||
self.borderGradientView = UIImageView()
|
||||
self.borderContaineView = UIView()
|
||||
self.borderMaskLayer = SimpleShapeLayer()
|
||||
|
||||
super.init(frame: frame)
|
||||
|
||||
self.layer.addSublayer(self.hierarchyTrackingLayer)
|
||||
self.hierarchyTrackingLayer.didEnterHierarchy = { [weak self] in
|
||||
guard let self, self.bounds.width != 0.0 else {
|
||||
return
|
||||
}
|
||||
self.updateAnimations(size: self.bounds.size)
|
||||
}
|
||||
|
||||
self.backgroundView.image = generateImage(CGSize(width: self.gradientWidth, height: 16.0), opaque: false, scale: 1.0, rotatedContext: { size, context in
|
||||
let backgroundColor = UIColor.clear
|
||||
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
context.setFillColor(backgroundColor.cgColor)
|
||||
context.fill(CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
context.clip(to: CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
let foregroundColor = UIColor(white: 1.0, alpha: 0.2)
|
||||
|
||||
let numColors = 7
|
||||
var locations: [CGFloat] = []
|
||||
var colors: [CGColor] = []
|
||||
for i in 0 ..< numColors {
|
||||
let position: CGFloat = CGFloat(i) / CGFloat(numColors - 1)
|
||||
locations.append(position)
|
||||
|
||||
let distanceFromCenterFraction: CGFloat = max(0.0, min(1.0, abs(position - 0.5) / 0.5))
|
||||
let colorAlpha = sin((1.0 - distanceFromCenterFraction) * CGFloat.pi * 0.5)
|
||||
|
||||
colors.append(foregroundColor.withMultipliedAlpha(colorAlpha).cgColor)
|
||||
}
|
||||
|
||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||
let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: &locations)!
|
||||
|
||||
context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: size.width, y: 0.0), options: CGGradientDrawingOptions())
|
||||
})
|
||||
self.addSubview(self.backgroundView)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
private func updateAnimations(size: CGSize) {
|
||||
if self.backgroundView.layer.animation(forKey: "shimmer") != nil {
|
||||
return
|
||||
}
|
||||
|
||||
let animation = self.backgroundView.layer.makeAnimation(from: 0.0 as NSNumber, to: (size.width + self.gradientWidth) as NSNumber, keyPath: "position.x", timingFunction: CAMediaTimingFunctionName.easeOut.rawValue, duration: 0.8, delay: 0.0, mediaTimingFunction: nil, removeOnCompletion: true, additive: true)
|
||||
animation.repeatCount = Float.infinity
|
||||
self.backgroundView.layer.add(animation, forKey: "shimmer")
|
||||
}
|
||||
|
||||
func update(size: CGSize, transition: Transition) {
|
||||
if self.backgroundView.bounds.size != size {
|
||||
self.backgroundView.layer.removeAllAnimations()
|
||||
}
|
||||
|
||||
transition.setFrame(view: self.backgroundView, frame: CGRect(origin: CGPoint(x: -self.gradientWidth, y: 0.0), size: size))
|
||||
self.updateAnimations(size: size)
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user