mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-15 13:35:19 +00:00
[WIP] Chat Import
This commit is contained in:
parent
8eaf939a92
commit
22b04a7ffb
@ -757,6 +757,8 @@ public final class AnimatedStickerNode: ASDisplayNode {
|
||||
private var canDisplayFirstFrame: Bool = false
|
||||
private var playbackMode: AnimatedStickerPlaybackMode = .loop
|
||||
|
||||
public var stopAtNearestLoop: Bool = false
|
||||
|
||||
private let playbackStatus = Promise<AnimatedStickerStatus>()
|
||||
public var status: Signal<AnimatedStickerStatus, NoError> {
|
||||
return self.playbackStatus.get()
|
||||
@ -966,7 +968,13 @@ public final class AnimatedStickerNode: ASDisplayNode {
|
||||
|
||||
if frame.isLastFrame {
|
||||
var stopped = false
|
||||
var stopNow = false
|
||||
if case .once = strongSelf.playbackMode {
|
||||
stopNow = true
|
||||
} else if strongSelf.stopAtNearestLoop {
|
||||
stopNow = true
|
||||
}
|
||||
if stopNow {
|
||||
strongSelf.stop()
|
||||
strongSelf.isPlaying = false
|
||||
stopped = true
|
||||
@ -1043,7 +1051,13 @@ public final class AnimatedStickerNode: ASDisplayNode {
|
||||
|
||||
if frame.isLastFrame {
|
||||
var stopped = false
|
||||
var stopNow = false
|
||||
if case .once = strongSelf.playbackMode {
|
||||
stopNow = true
|
||||
} else if strongSelf.stopAtNearestLoop {
|
||||
stopNow = true
|
||||
}
|
||||
if stopNow {
|
||||
strongSelf.stop()
|
||||
strongSelf.isPlaying = false
|
||||
stopped = true
|
||||
|
@ -22,6 +22,7 @@ swift_library(
|
||||
"//submodules/AnimatedStickerNode:AnimatedStickerNode",
|
||||
"//submodules/ChatHistoryImportTasks:ChatHistoryImportTasks",
|
||||
"//submodules/MimeTypes:MimeTypes",
|
||||
"//submodules/ConfettiEffect:ConfettiEffect",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
@ -13,6 +13,7 @@ import AnimatedStickerNode
|
||||
import AppBundle
|
||||
import ZIPFoundation
|
||||
import MimeTypes
|
||||
import ConfettiEffect
|
||||
|
||||
public final class ChatImportActivityScreen: ViewController {
|
||||
private final class Node: ViewControllerTracingNode {
|
||||
@ -22,6 +23,7 @@ public final class ChatImportActivityScreen: ViewController {
|
||||
private var presentationData: PresentationData
|
||||
|
||||
private let animationNode: AnimatedStickerNode
|
||||
private let doneAnimationNode: AnimatedStickerNode
|
||||
private let radialStatus: RadialStatusNode
|
||||
private let radialCheck: RadialStatusNode
|
||||
private let radialStatusBackground: ASImageNode
|
||||
@ -38,6 +40,8 @@ public final class ChatImportActivityScreen: ViewController {
|
||||
private let totalBytes: Int
|
||||
private var isDone: Bool = false
|
||||
|
||||
private var feedback: HapticFeedback?
|
||||
|
||||
init(controller: ChatImportActivityScreen, context: AccountContext, totalBytes: Int) {
|
||||
self.controller = controller
|
||||
self.context = context
|
||||
@ -46,6 +50,8 @@ public final class ChatImportActivityScreen: ViewController {
|
||||
self.presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
self.animationNode = AnimatedStickerNode()
|
||||
self.doneAnimationNode = AnimatedStickerNode()
|
||||
self.doneAnimationNode.isHidden = true
|
||||
|
||||
self.radialStatus = RadialStatusNode(backgroundNodeColor: .clear)
|
||||
self.radialCheck = RadialStatusNode(backgroundNodeColor: .clear)
|
||||
@ -89,8 +95,19 @@ public final class ChatImportActivityScreen: ViewController {
|
||||
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 170 * 2, height: 170 * 2, playbackMode: .loop, mode: .direct(cachePathPrefix: nil))
|
||||
self.animationNode.visibility = true
|
||||
}
|
||||
if let path = getAppBundle().path(forResource: "HistoryImportDone", ofType: "tgs") {
|
||||
self.doneAnimationNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 170 * 2, height: 170 * 2, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
|
||||
self.doneAnimationNode.started = { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.animationNode.isHidden = true
|
||||
}
|
||||
self.doneAnimationNode.visibility = false
|
||||
}
|
||||
|
||||
self.addSubnode(self.animationNode)
|
||||
self.addSubnode(self.doneAnimationNode)
|
||||
self.addSubnode(self.radialStatusBackground)
|
||||
self.addSubnode(self.radialStatus)
|
||||
self.addSubnode(self.radialCheck)
|
||||
@ -112,6 +129,15 @@ public final class ChatImportActivityScreen: ViewController {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.animationNode.completed = { [weak self] stopped in
|
||||
guard let strongSelf = self, stopped else {
|
||||
return
|
||||
}
|
||||
strongSelf.animationNode.visibility = false
|
||||
strongSelf.doneAnimationNode.visibility = true
|
||||
strongSelf.doneAnimationNode.isHidden = false
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func statusButtonPressed() {
|
||||
@ -119,6 +145,7 @@ public final class ChatImportActivityScreen: ViewController {
|
||||
}
|
||||
|
||||
func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationHeight: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||
let isFirstLayout = self.validLayout == nil
|
||||
self.validLayout = (layout, navigationHeight)
|
||||
|
||||
//TODO:localize
|
||||
@ -156,11 +183,14 @@ public final class ChatImportActivityScreen: ViewController {
|
||||
}
|
||||
|
||||
transition.updateAlpha(node: self.animationNode, alpha: hideIcon ? 0.0 : 1.0)
|
||||
transition.updateAlpha(node: self.doneAnimationNode, alpha: hideIcon ? 0.0 : 1.0)
|
||||
|
||||
let contentOriginY = navigationHeight + floor((layout.size.height - contentHeight) / 2.0)
|
||||
|
||||
self.animationNode.frame = CGRect(origin: CGPoint(x: floor((layout.size.width - iconSize.width) / 2.0), y: contentOriginY), size: iconSize)
|
||||
self.animationNode.updateLayout(size: iconSize)
|
||||
self.doneAnimationNode.frame = CGRect(origin: CGPoint(x: floor((layout.size.width - iconSize.width) / 2.0), y: contentOriginY), size: iconSize)
|
||||
self.doneAnimationNode.updateLayout(size: iconSize)
|
||||
|
||||
self.radialStatus.frame = CGRect(origin: CGPoint(x: floor((layout.size.width - radialStatusSize.width) / 2.0), y: hideIcon ? contentOriginY : (contentOriginY + iconSize.height + maxIconStatusSpacing)), size: radialStatusSize)
|
||||
let checkSize: CGFloat = 130.0
|
||||
@ -184,17 +214,22 @@ public final class ChatImportActivityScreen: ViewController {
|
||||
self.statusButtonText.isHidden = !self.isDone
|
||||
self.statusButton.isHidden = !self.isDone
|
||||
self.progressText.isHidden = self.isDone
|
||||
|
||||
if isFirstLayout {
|
||||
self.updateProgress(totalProgress: self.totalProgress, isDone: self.isDone, animated: false)
|
||||
}
|
||||
}
|
||||
|
||||
func updateProgress(totalProgress: CGFloat, isDone: Bool, animated: Bool) {
|
||||
self.totalProgress = totalProgress
|
||||
let wasDone = self.isDone
|
||||
self.isDone = isDone
|
||||
|
||||
if let (layout, navigationHeight) = self.validLayout {
|
||||
self.containerLayoutUpdated(layout, navigationHeight: navigationHeight, transition: .immediate)
|
||||
self.radialStatus.transitionToState(.progress(color: self.presentationData.theme.list.itemAccentColor, lineWidth: 6.0, value: max(0.02, self.totalProgress), cancelEnabled: false), animated: animated, synchronous: true, completion: {})
|
||||
self.radialStatus.transitionToState(.progress(color: self.presentationData.theme.list.itemAccentColor, lineWidth: 6.0, value: max(0.02, self.totalProgress), cancelEnabled: false, animateRotation: false), animated: animated, synchronous: true, completion: {})
|
||||
if isDone {
|
||||
self.radialCheck.transitionToState(.progress(color: .clear, lineWidth: 6.0, value: self.totalProgress, cancelEnabled: false), animated: false, synchronous: true, completion: {})
|
||||
self.radialCheck.transitionToState(.progress(color: .clear, lineWidth: 6.0, value: self.totalProgress, cancelEnabled: false, animateRotation: false), animated: false, synchronous: true, completion: {})
|
||||
self.radialCheck.transitionToState(.check(self.presentationData.theme.list.itemAccentColor), animated: animated, synchronous: true, completion: {})
|
||||
self.radialStatus.layer.animateScale(from: 1.0, to: 1.05, duration: 0.07, delay: 0.0, timingFunction: CAMediaTimingFunctionName.linear.rawValue, removeOnCompletion: false, additive: false, completion: { [weak self] _ in
|
||||
guard let strongSelf = self else {
|
||||
@ -216,6 +251,17 @@ public final class ChatImportActivityScreen: ViewController {
|
||||
transition = .immediate
|
||||
}
|
||||
transition.updateAlpha(node: self.radialStatusText, alpha: 0.0)
|
||||
|
||||
if !wasDone {
|
||||
self.view.addSubview(ConfettiView(frame: self.view.bounds))
|
||||
|
||||
if self.feedback == nil {
|
||||
self.feedback = HapticFeedback()
|
||||
}
|
||||
self.feedback?.success()
|
||||
|
||||
self.animationNode.stopAtNearestLoop = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ private final class VisualMediaItemNode: ASDisplayNode {
|
||||
switch status {
|
||||
case let .Fetching(_, progress):
|
||||
let adjustedProgress = max(progress, 0.027)
|
||||
statusState = .progress(color: .white, lineWidth: nil, value: CGFloat(adjustedProgress), cancelEnabled: true)
|
||||
statusState = .progress(color: .white, lineWidth: nil, value: CGFloat(adjustedProgress), cancelEnabled: true, animateRotation: true)
|
||||
case .Local:
|
||||
statusState = .none
|
||||
case .Remote:
|
||||
|
@ -459,14 +459,14 @@ private class ChatListStatusProgressNode: ChatListStatusContentNode {
|
||||
|
||||
super.init()
|
||||
|
||||
self.statusNode.transitionToState(.progress(color: color, lineWidth: 1.0, value: progress, cancelEnabled: false))
|
||||
self.statusNode.transitionToState(.progress(color: color, lineWidth: 1.0, value: progress, cancelEnabled: false, animateRotation: true))
|
||||
|
||||
self.addSubnode(self.statusNode)
|
||||
}
|
||||
|
||||
override func updateWithState(_ state: ChatListStatusNodeState, animated: Bool) {
|
||||
if case let .progress(color, progress) = state {
|
||||
self.statusNode.transitionToState(.progress(color: color, lineWidth: 1.0, value: progress, cancelEnabled: false), animated: animated, completion: {})
|
||||
self.statusNode.transitionToState(.progress(color: color, lineWidth: 1.0, value: progress, cancelEnabled: false, animateRotation: true), animated: animated, completion: {})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -279,7 +279,7 @@ public final class ChatMessageInteractiveMediaBadge: ASDisplayNode {
|
||||
isCompact = true
|
||||
originY = -1.0 - UIScreenPixel
|
||||
case .compactFetching:
|
||||
state = .progress(color: .white, lineWidth: nil, value: 0.0, cancelEnabled: true)
|
||||
state = .progress(color: .white, lineWidth: nil, value: 0.0, cancelEnabled: true, animateRotation: true)
|
||||
isCompact = true
|
||||
originY = -1.0
|
||||
}
|
||||
|
16
submodules/ConfettiEffect/BUILD
Normal file
16
submodules/ConfettiEffect/BUILD
Normal file
@ -0,0 +1,16 @@
|
||||
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
|
||||
|
||||
swift_library(
|
||||
name = "ConfettiEffect",
|
||||
module_name = "ConfettiEffect",
|
||||
srcs = glob([
|
||||
"Sources/**/*.swift",
|
||||
]),
|
||||
deps = [
|
||||
"//submodules/AsyncDisplayKit:AsyncDisplayKit",
|
||||
"//submodules/Display:Display",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
],
|
||||
)
|
@ -44,13 +44,13 @@ private final class ParticleLayer: CALayer {
|
||||
}
|
||||
}
|
||||
|
||||
final class ConfettiView: UIView {
|
||||
public final class ConfettiView: UIView {
|
||||
private var particles: [ParticleLayer] = []
|
||||
private var displayLink: ConstantDisplayLinkAnimator?
|
||||
|
||||
private var localTime: Float = 0.0
|
||||
|
||||
override init(frame: CGRect) {
|
||||
override public init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
self.isUserInteractionEnabled = false
|
||||
@ -142,7 +142,7 @@ final class ConfettiView: UIView {
|
||||
self.displayLink?.isPaused = false
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
required public init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
@ -214,10 +214,10 @@ final class ChatAnimationGalleryItemNode: ZoomableContentGalleryItemNode {
|
||||
strongSelf.statusNode.alpha = 1.0
|
||||
strongSelf.statusNodeContainer.isUserInteractionEnabled = true
|
||||
let adjustedProgress = max(progress, 0.027)
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: CGFloat(adjustedProgress), cancelEnabled: true), completion: {})
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: CGFloat(adjustedProgress), cancelEnabled: true, animateRotation: true), completion: {})
|
||||
case .Local:
|
||||
if let previousStatus = previousStatus, case .Fetching = previousStatus {
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: 1.0, cancelEnabled: true), completion: {
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: 1.0, cancelEnabled: true, animateRotation: true), completion: {
|
||||
if let strongSelf = self {
|
||||
strongSelf.statusNode.alpha = 0.0
|
||||
strongSelf.statusNodeContainer.isUserInteractionEnabled = false
|
||||
|
@ -203,10 +203,10 @@ class ChatDocumentGalleryItemNode: ZoomableContentGalleryItemNode, WKNavigationD
|
||||
strongSelf.statusNode.alpha = 1.0
|
||||
strongSelf.statusNodeContainer.isUserInteractionEnabled = true
|
||||
let adjustedProgress = max(progress, 0.027)
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: CGFloat(adjustedProgress), cancelEnabled: true), completion: {})
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: CGFloat(adjustedProgress), cancelEnabled: true, animateRotation: true), completion: {})
|
||||
case .Local:
|
||||
if let previousStatus = previousStatus, case .Fetching = previousStatus {
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: 1.0, cancelEnabled: true), completion: {
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: 1.0, cancelEnabled: true, animateRotation: true), completion: {
|
||||
if let strongSelf = self {
|
||||
strongSelf.statusNode.alpha = 0.0
|
||||
strongSelf.statusNodeContainer.isUserInteractionEnabled = false
|
||||
|
@ -201,10 +201,10 @@ class ChatExternalFileGalleryItemNode: GalleryItemNode {
|
||||
strongSelf.statusNode.alpha = 1.0
|
||||
strongSelf.statusNodeContainer.isUserInteractionEnabled = true
|
||||
let adjustedProgress = max(progress, 0.027)
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: CGFloat(adjustedProgress), cancelEnabled: true), completion: {})
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: CGFloat(adjustedProgress), cancelEnabled: true, animateRotation: true), completion: {})
|
||||
case .Local:
|
||||
if let previousStatus = previousStatus, case .Fetching = previousStatus {
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: 1.0, cancelEnabled: true), completion: {
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: 1.0, cancelEnabled: true, animateRotation: true), completion: {
|
||||
if let strongSelf = self {
|
||||
strongSelf.statusNode.alpha = 0.0
|
||||
strongSelf.statusNodeContainer.isUserInteractionEnabled = false
|
||||
|
@ -426,10 +426,10 @@ final class ChatImageGalleryItemNode: ZoomableContentGalleryItemNode {
|
||||
strongSelf.statusNode.alpha = 1.0
|
||||
strongSelf.statusNodeContainer.isUserInteractionEnabled = true
|
||||
let adjustedProgress = max(progress, 0.027)
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: CGFloat(adjustedProgress), cancelEnabled: true), completion: {})
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: CGFloat(adjustedProgress), cancelEnabled: true, animateRotation: true), completion: {})
|
||||
case .Local:
|
||||
if let previousStatus = previousStatus, case .Fetching = previousStatus {
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: 1.0, cancelEnabled: true), completion: {
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: 1.0, cancelEnabled: true, animateRotation: true), completion: {
|
||||
if let strongSelf = self {
|
||||
strongSelf.statusNode.alpha = 0.0
|
||||
strongSelf.statusNodeContainer.isUserInteractionEnabled = false
|
||||
|
@ -723,7 +723,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
||||
var fetching = false
|
||||
if initialBuffering {
|
||||
if displayProgress {
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: nil, cancelEnabled: false), animated: false, completion: {})
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: nil, cancelEnabled: false, animateRotation: true), animated: false, completion: {})
|
||||
} else {
|
||||
strongSelf.statusNode.transitionToState(.none, animated: false, completion: {})
|
||||
}
|
||||
@ -740,7 +740,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
||||
fetching = true
|
||||
isPaused = true
|
||||
}
|
||||
state = .progress(color: .white, lineWidth: nil, value: CGFloat(progress), cancelEnabled: true)
|
||||
state = .progress(color: .white, lineWidth: nil, value: CGFloat(progress), cancelEnabled: true, animateRotation: true)
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ final class InstantPageImageNode: ASDisplayNode, InstantPageNode {
|
||||
switch fetchStatus {
|
||||
case let .Fetching(_, progress):
|
||||
let adjustedProgress = max(progress, 0.027)
|
||||
state = .progress(color: .white, lineWidth: nil, value: CGFloat(adjustedProgress), cancelEnabled: true)
|
||||
state = .progress(color: .white, lineWidth: nil, value: CGFloat(adjustedProgress), cancelEnabled: true, animateRotation: true)
|
||||
case .Remote:
|
||||
state = .download(.white)
|
||||
default:
|
||||
|
@ -119,7 +119,7 @@ final class InstantPagePlayableVideoNode: ASDisplayNode, InstantPageNode, Galler
|
||||
switch fetchStatus {
|
||||
case let .Fetching(_, progress):
|
||||
let adjustedProgress = max(progress, 0.027)
|
||||
state = .progress(color: .white, lineWidth: nil, value: CGFloat(adjustedProgress), cancelEnabled: true)
|
||||
state = .progress(color: .white, lineWidth: nil, value: CGFloat(adjustedProgress), cancelEnabled: true, animateRotation: true)
|
||||
case .Remote:
|
||||
state = .download(.white)
|
||||
default:
|
||||
|
@ -28,7 +28,7 @@ private final class LegacyDataImportSplashImpl: WindowCoveringView, LegacyDataIm
|
||||
self.updateLayout(size)
|
||||
}
|
||||
}
|
||||
self.progressNode.transitionToState(.progress(color: self.theme?.list.itemAccentColor ?? UIColor(rgb: 0x007ee5), lineWidth: 2.0, value: CGFloat(max(0.025, self.progress.1)), cancelEnabled: false), animated: false, completion: {})
|
||||
self.progressNode.transitionToState(.progress(color: self.theme?.list.itemAccentColor ?? UIColor(rgb: 0x007ee5), lineWidth: 2.0, value: CGFloat(max(0.025, self.progress.1)), cancelEnabled: false, animateRotation: true), animated: false, completion: {})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,7 +138,7 @@ final class SecureIdValueFormFileItemNode: FormEditableBlockItemNode<SecureIdVal
|
||||
|
||||
let progressState: RadialStatusNodeState
|
||||
if let progress = progress {
|
||||
progressState = .progress(color: .white, lineWidth: nil, value: progress, cancelEnabled: false)
|
||||
progressState = .progress(color: .white, lineWidth: nil, value: progress, cancelEnabled: false, animateRotation: true)
|
||||
} else {
|
||||
progressState = .none
|
||||
}
|
||||
|
@ -99,9 +99,12 @@ private final class RadialProgressContentSpinnerNode: ASDisplayNode {
|
||||
|
||||
let lineWidth: CGFloat?
|
||||
|
||||
init(color: UIColor, lineWidth: CGFloat?) {
|
||||
private let animateRotation: Bool
|
||||
|
||||
init(color: UIColor, lineWidth: CGFloat?, animateRotation: Bool) {
|
||||
self.color = color
|
||||
self.lineWidth = lineWidth
|
||||
self.animateRotation = animateRotation
|
||||
|
||||
super.init()
|
||||
|
||||
@ -159,25 +162,29 @@ private final class RadialProgressContentSpinnerNode: ASDisplayNode {
|
||||
override func willEnterHierarchy() {
|
||||
super.willEnterHierarchy()
|
||||
|
||||
let basicAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
|
||||
basicAnimation.duration = 1.5
|
||||
var fromValue = Float.pi + 0.58
|
||||
if let presentation = self.layer.presentation(), let value = (presentation.value(forKeyPath: "transform.rotation.z") as? NSNumber)?.floatValue {
|
||||
fromValue = value
|
||||
if self.animateRotation {
|
||||
let basicAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
|
||||
basicAnimation.duration = 1.5
|
||||
var fromValue = Float.pi + 0.58
|
||||
if let presentation = self.layer.presentation(), let value = (presentation.value(forKeyPath: "transform.rotation.z") as? NSNumber)?.floatValue {
|
||||
fromValue = value
|
||||
}
|
||||
basicAnimation.fromValue = NSNumber(value: fromValue)
|
||||
basicAnimation.toValue = NSNumber(value: fromValue + Float.pi * 2.0)
|
||||
basicAnimation.repeatCount = Float.infinity
|
||||
basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
|
||||
basicAnimation.beginTime = 0.0
|
||||
|
||||
self.layer.add(basicAnimation, forKey: "progressRotation")
|
||||
}
|
||||
basicAnimation.fromValue = NSNumber(value: fromValue)
|
||||
basicAnimation.toValue = NSNumber(value: fromValue + Float.pi * 2.0)
|
||||
basicAnimation.repeatCount = Float.infinity
|
||||
basicAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
|
||||
basicAnimation.beginTime = 0.0
|
||||
|
||||
self.layer.add(basicAnimation, forKey: "progressRotation")
|
||||
}
|
||||
|
||||
override func didExitHierarchy() {
|
||||
super.didExitHierarchy()
|
||||
|
||||
self.layer.removeAnimation(forKey: "progressRotation")
|
||||
if self.animateRotation {
|
||||
self.layer.removeAnimation(forKey: "progressRotation")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -258,13 +265,16 @@ final class RadialProgressContentNode: RadialStatusContentNode {
|
||||
let displayCancel: Bool
|
||||
var ready: Bool = false
|
||||
|
||||
let animateRotation: Bool
|
||||
|
||||
private var enqueuedReadyForTransition: (() -> Void)?
|
||||
|
||||
init(color: UIColor, lineWidth: CGFloat?, displayCancel: Bool) {
|
||||
init(color: UIColor, lineWidth: CGFloat?, displayCancel: Bool, animateRotation: Bool) {
|
||||
self.color = color
|
||||
self.displayCancel = displayCancel
|
||||
self.animateRotation = animateRotation
|
||||
|
||||
self.spinnerNode = RadialProgressContentSpinnerNode(color: color, lineWidth: lineWidth)
|
||||
self.spinnerNode = RadialProgressContentSpinnerNode(color: color, lineWidth: lineWidth, animateRotation: animateRotation)
|
||||
self.cancelNode = RadialProgressContentCancelNode(color: color, displayCancel: displayCancel)
|
||||
|
||||
super.init()
|
||||
|
@ -7,7 +7,7 @@ public enum RadialStatusNodeState: Equatable {
|
||||
case download(UIColor)
|
||||
case play(UIColor)
|
||||
case pause(UIColor)
|
||||
case progress(color: UIColor, lineWidth: CGFloat?, value: CGFloat?, cancelEnabled: Bool)
|
||||
case progress(color: UIColor, lineWidth: CGFloat?, value: CGFloat?, cancelEnabled: Bool, animateRotation: Bool)
|
||||
case cloudProgress(color: UIColor, strokeBackgroundColor: UIColor, lineWidth: CGFloat, value: CGFloat?)
|
||||
case check(UIColor)
|
||||
case customIcon(UIImage)
|
||||
@ -39,8 +39,8 @@ public enum RadialStatusNodeState: Equatable {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .progress(lhsColor, lhsLineWidth, lhsValue, lhsCancelEnabled):
|
||||
if case let .progress(rhsColor, rhsLineWidth, rhsValue, rhsCancelEnabled) = rhs, lhsColor.isEqual(rhsColor), lhsValue == rhsValue, lhsLineWidth == rhsLineWidth, lhsCancelEnabled == rhsCancelEnabled {
|
||||
case let .progress(lhsColor, lhsLineWidth, lhsValue, lhsCancelEnabled, lhsAnimateRotation):
|
||||
if case let .progress(rhsColor, rhsLineWidth, rhsValue, rhsCancelEnabled, rhsAnimateRotation) = rhs, lhsColor.isEqual(rhsColor), lhsValue == rhsValue, lhsLineWidth == rhsLineWidth, lhsCancelEnabled == rhsCancelEnabled, lhsAnimateRotation == rhsAnimateRotation {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
@ -98,8 +98,8 @@ public enum RadialStatusNodeState: Equatable {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .progress(lhsColor, lhsLineWidth, lhsValue, lhsCancelEnabled):
|
||||
if case let .progress(rhsColor, rhsLineWidth, rhsValue, rhsCancelEnabled) = rhs, lhsColor.isEqual(rhsColor), lhsValue == rhsValue, lhsLineWidth == rhsLineWidth, lhsCancelEnabled == rhsCancelEnabled {
|
||||
case let .progress(lhsColor, lhsLineWidth, lhsValue, lhsCancelEnabled, lhsAnimateRotation):
|
||||
if case let .progress(rhsColor, rhsLineWidth, rhsValue, rhsCancelEnabled, rhsAnimateRotation) = rhs, lhsColor.isEqual(rhsColor), lhsValue == rhsValue, lhsLineWidth == rhsLineWidth, lhsCancelEnabled == rhsCancelEnabled, lhsAnimateRotation == rhsAnimateRotation {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
@ -154,15 +154,15 @@ public enum RadialStatusNodeState: Equatable {
|
||||
return RadialStatusIconContentNode(icon: .custom(image), synchronous: synchronous)
|
||||
case let .check(color):
|
||||
return RadialCheckContentNode(color: color)
|
||||
case let .progress(color, lineWidth, value, cancelEnabled):
|
||||
if let current = current as? RadialProgressContentNode, current.displayCancel == cancelEnabled {
|
||||
case let .progress(color, lineWidth, value, cancelEnabled, animateRotation):
|
||||
if let current = current as? RadialProgressContentNode, current.displayCancel == cancelEnabled, current.animateRotation == animateRotation {
|
||||
if !current.color.isEqual(color) {
|
||||
current.color = color
|
||||
}
|
||||
current.progress = value
|
||||
return current
|
||||
} else {
|
||||
let node = RadialProgressContentNode(color: color, lineWidth: lineWidth, displayCancel: cancelEnabled)
|
||||
let node = RadialProgressContentNode(color: color, lineWidth: lineWidth, displayCancel: cancelEnabled, animateRotation: animateRotation)
|
||||
node.progress = value
|
||||
return node
|
||||
}
|
||||
|
@ -501,12 +501,12 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
||||
switch status {
|
||||
case let .Fetching(_, progress):
|
||||
let adjustedProgress = max(progress, 0.027)
|
||||
state = .progress(color: statusForegroundColor, lineWidth: nil, value: CGFloat(adjustedProgress), cancelEnabled: false)
|
||||
state = .progress(color: statusForegroundColor, lineWidth: nil, value: CGFloat(adjustedProgress), cancelEnabled: false, animateRotation: true)
|
||||
case .Local:
|
||||
state = .none
|
||||
local = true
|
||||
case .Remote:
|
||||
state = .progress(color: statusForegroundColor, lineWidth: nil, value: 0.027, cancelEnabled: false)
|
||||
state = .progress(color: statusForegroundColor, lineWidth: nil, value: 0.027, cancelEnabled: false, animateRotation: true)
|
||||
}
|
||||
strongSelf.statusNode.transitionToState(state, completion: {})
|
||||
|
||||
|
@ -31,11 +31,11 @@ public final class ShareLoadingContainerNode: ASDisplayNode, ShareContentContain
|
||||
case let .progress(value):
|
||||
self.activityIndicator.isHidden = true
|
||||
self.statusNode.isHidden = false
|
||||
self.statusNode.transitionToState(.progress(color: self.theme.actionSheet.controlAccentColor, lineWidth: 2.0, value: max(0.12, CGFloat(value)), cancelEnabled: false), completion: {})
|
||||
self.statusNode.transitionToState(.progress(color: self.theme.actionSheet.controlAccentColor, lineWidth: 2.0, value: max(0.12, CGFloat(value)), cancelEnabled: false, animateRotation: true), completion: {})
|
||||
case .done:
|
||||
self.activityIndicator.isHidden = true
|
||||
self.statusNode.isHidden = false
|
||||
self.statusNode.transitionToState(.progress(color: self.theme.actionSheet.controlAccentColor, lineWidth: 2.0, value: 1.0, cancelEnabled: false), completion: {})
|
||||
self.statusNode.transitionToState(.progress(color: self.theme.actionSheet.controlAccentColor, lineWidth: 2.0, value: 1.0, cancelEnabled: false, animateRotation: true), completion: {})
|
||||
self.doneStatusNode.transitionToState(.check(self.theme.actionSheet.controlAccentColor), completion: {})
|
||||
}
|
||||
}
|
||||
@ -52,7 +52,7 @@ public final class ShareLoadingContainerNode: ASDisplayNode, ShareContentContain
|
||||
self.addSubnode(self.activityIndicator)
|
||||
self.addSubnode(self.statusNode)
|
||||
self.addSubnode(self.doneStatusNode)
|
||||
self.doneStatusNode.transitionToState(.progress(color: self.theme.actionSheet.controlAccentColor, lineWidth: 2.0, value: 0.0, cancelEnabled: false), completion: {})
|
||||
self.doneStatusNode.transitionToState(.progress(color: self.theme.actionSheet.controlAccentColor, lineWidth: 2.0, value: 0.0, cancelEnabled: false, animateRotation: true), completion: {})
|
||||
}
|
||||
|
||||
public func activate() {
|
||||
|
@ -217,6 +217,7 @@ swift_library(
|
||||
"//submodules/ChatImportUI:ChatImportUI",
|
||||
"//submodules/ChatHistoryImportTasks:ChatHistoryImportTasks",
|
||||
"//submodules/DatePickerNode:DatePickerNode",
|
||||
"//submodules/ConfettiEffect:ConfettiEffect",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
Binary file not shown.
@ -15,6 +15,7 @@ import ReactionSelectionNode
|
||||
import TelegramUniversalVideoContent
|
||||
import ChatInterfaceState
|
||||
import FastBlur
|
||||
import ConfettiEffect
|
||||
|
||||
final class VideoNavigationControllerDropContentItem: NavigationControllerDropContentItem {
|
||||
let itemNode: OverlayMediaItemNode
|
||||
|
@ -335,7 +335,7 @@ final class ChatMessageCommentFooterContentNode: ChatMessageBubbleContentNode {
|
||||
transition.updateFrameAdditive(node: statusNode, frame: statusFrame)
|
||||
}
|
||||
|
||||
statusNode.transitionToState(.progress(color: messageTheme.accentTextColor, lineWidth: 1.5, value: nil, cancelEnabled: false), animated: false, synchronous: false, completion: {})
|
||||
statusNode.transitionToState(.progress(color: messageTheme.accentTextColor, lineWidth: 1.5, value: nil, cancelEnabled: false, animateRotation: true), animated: false, synchronous: false, completion: {})
|
||||
} else {
|
||||
strongSelf.arrowNode.isHidden = false
|
||||
if let statusNode = strongSelf.statusNode {
|
||||
|
@ -593,13 +593,13 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
||||
case let .Fetching(_, progress):
|
||||
if let isBuffering = isBuffering {
|
||||
if isBuffering {
|
||||
state = .progress(color: messageTheme.mediaOverlayControlColors.foregroundColor, lineWidth: nil, value: nil, cancelEnabled: true)
|
||||
state = .progress(color: messageTheme.mediaOverlayControlColors.foregroundColor, lineWidth: nil, value: nil, cancelEnabled: true, animateRotation: true)
|
||||
} else {
|
||||
state = .none
|
||||
}
|
||||
} else {
|
||||
let adjustedProgress = max(progress, 0.027)
|
||||
state = .progress(color: messageTheme.mediaOverlayControlColors.foregroundColor, lineWidth: nil, value: CGFloat(adjustedProgress), cancelEnabled: true)
|
||||
state = .progress(color: messageTheme.mediaOverlayControlColors.foregroundColor, lineWidth: nil, value: CGFloat(adjustedProgress), cancelEnabled: true, animateRotation: true)
|
||||
}
|
||||
case .Local:
|
||||
if isSecretMedia && self.secretProgressIcon != nil {
|
||||
@ -620,7 +620,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
||||
isLocal = true
|
||||
}
|
||||
if (isBuffering ?? false) && !isLocal {
|
||||
state = .progress(color: messageTheme.mediaOverlayControlColors.foregroundColor, lineWidth: nil, value: nil, cancelEnabled: true)
|
||||
state = .progress(color: messageTheme.mediaOverlayControlColors.foregroundColor, lineWidth: nil, value: nil, cancelEnabled: true, animateRotation: true)
|
||||
} else {
|
||||
state = .none
|
||||
}
|
||||
|
@ -1036,7 +1036,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
}
|
||||
var animated: Bool = animated
|
||||
if let updatingMedia = attributes.updatingMedia, case .update = updatingMedia.media {
|
||||
state = .progress(color: messageTheme.mediaOverlayControlColors.foregroundColor, lineWidth: nil, value: CGFloat(updatingMedia.progress), cancelEnabled: true)
|
||||
state = .progress(color: messageTheme.mediaOverlayControlColors.foregroundColor, lineWidth: nil, value: CGFloat(updatingMedia.progress), cancelEnabled: true, animateRotation: true)
|
||||
} else if var fetchStatus = self.fetchStatus {
|
||||
var playerPosition: Int32?
|
||||
var playerDuration: Int32 = 0
|
||||
@ -1087,7 +1087,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
if adjustedProgress.isEqual(to: 1.0), case .unconstrained = sizeCalculation, (message.flags.contains(.Unsent) || wasCheck) {
|
||||
state = .check(messageTheme.mediaOverlayControlColors.foregroundColor)
|
||||
} else {
|
||||
state = .progress(color: messageTheme.mediaOverlayControlColors.foregroundColor, lineWidth: nil, value: CGFloat(adjustedProgress), cancelEnabled: true)
|
||||
state = .progress(color: messageTheme.mediaOverlayControlColors.foregroundColor, lineWidth: nil, value: CGFloat(adjustedProgress), cancelEnabled: true, animateRotation: true)
|
||||
}
|
||||
|
||||
if let file = self.media as? TelegramMediaFile {
|
||||
|
@ -216,7 +216,7 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode {
|
||||
transition.updateSublayerTransformScale(node: strongSelf.buttonsContainer, scale: 0.1)
|
||||
|
||||
if let theme = strongSelf.theme {
|
||||
strongSelf.activityIndicator.transitionToState(.progress(color: theme.chat.inputPanel.panelControlAccentColor, lineWidth: nil, value: nil, cancelEnabled: false), animated: false, completion: {
|
||||
strongSelf.activityIndicator.transitionToState(.progress(color: theme.chat.inputPanel.panelControlAccentColor, lineWidth: nil, value: nil, cancelEnabled: false, animateRotation: true), animated: false, completion: {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ final class EditAccessoryPanelNode: AccessoryPanelNode {
|
||||
strongSelf.statusNode.transitionToState(.none, completion: {})
|
||||
} else {
|
||||
strongSelf.activityIndicator.isHidden = true
|
||||
strongSelf.statusNode.transitionToState(.progress(color: strongSelf.theme.chat.inputPanel.panelControlAccentColor, lineWidth: nil, value: CGFloat(value), cancelEnabled: false), completion: {})
|
||||
strongSelf.statusNode.transitionToState(.progress(color: strongSelf.theme.chat.inputPanel.panelControlAccentColor, lineWidth: nil, value: CGFloat(value), cancelEnabled: false, animateRotation: true), completion: {})
|
||||
}
|
||||
} else {
|
||||
strongSelf.activityIndicator.isHidden = true
|
||||
|
@ -248,7 +248,7 @@ final class GridMessageItemNode: GridItemNode {
|
||||
switch status {
|
||||
case let .Fetching(_, progress):
|
||||
let adjustedProgress = max(progress, 0.027)
|
||||
statusState = .progress(color: .white, lineWidth: nil, value: CGFloat(adjustedProgress), cancelEnabled: true)
|
||||
statusState = .progress(color: .white, lineWidth: nil, value: CGFloat(adjustedProgress), cancelEnabled: true, animateRotation: true)
|
||||
case .Local:
|
||||
statusState = .none
|
||||
case .Remote:
|
||||
|
@ -460,7 +460,7 @@ final class HorizontalListContextResultsChatInputPanelItemNode: ListViewItemNode
|
||||
|
||||
switch status {
|
||||
case let .Fetching(_, progress):
|
||||
state = .progress(color: statusForegroundColor, lineWidth: nil, value: CGFloat(max(progress, 0.2)), cancelEnabled: false)
|
||||
state = .progress(color: statusForegroundColor, lineWidth: nil, value: CGFloat(max(progress, 0.2)), cancelEnabled: false, animateRotation: true)
|
||||
case .Remote:
|
||||
//state = .download(statusForegroundColor)
|
||||
state = .none
|
||||
|
@ -345,7 +345,7 @@ private final class VisualMediaItemNode: ASDisplayNode {
|
||||
switch status {
|
||||
case let .Fetching(_, progress):
|
||||
let adjustedProgress = max(progress, 0.027)
|
||||
statusState = .progress(color: .white, lineWidth: nil, value: CGFloat(adjustedProgress), cancelEnabled: true)
|
||||
statusState = .progress(color: .white, lineWidth: nil, value: CGFloat(adjustedProgress), cancelEnabled: true, animateRotation: true)
|
||||
case .Local:
|
||||
statusState = .none
|
||||
case .Remote:
|
||||
|
@ -287,10 +287,10 @@ final class PeerInfoAvatarListItemNode: ASDisplayNode {
|
||||
}
|
||||
if isLoading, let progress = progress {
|
||||
strongSelf.hasProgress = true
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: CGFloat(max(0.027, progress)), cancelEnabled: false), completion: {})
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: CGFloat(max(0.027, progress)), cancelEnabled: false, animateRotation: true), completion: {})
|
||||
} else if strongSelf.hasProgress {
|
||||
strongSelf.hasProgress = false
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: 1.0, cancelEnabled: false), completion: { [weak self] in
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: 1.0, cancelEnabled: false, animateRotation: true), completion: { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -1517,7 +1517,7 @@ final class PeerInfoEditingAvatarOverlayNode: ASDisplayNode {
|
||||
if let updatingAvatar = updatingAvatar {
|
||||
overlayHidden = false
|
||||
|
||||
self.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: max(0.027, uploadProgress ?? 0.0), cancelEnabled: true))
|
||||
self.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: max(0.027, uploadProgress ?? 0.0), cancelEnabled: true, animateRotation: true))
|
||||
|
||||
if case let .image(representation) = updatingAvatar {
|
||||
if representation != self.currentRepresentation {
|
||||
|
@ -22,6 +22,7 @@ import OverlayStatusController
|
||||
import PresentationDataUtils
|
||||
import ChatImportUI
|
||||
import ZIPFoundation
|
||||
import ActivityIndicator
|
||||
|
||||
private let inForeground = ValuePromise<Bool>(false, ignoreRepeated: true)
|
||||
|
||||
@ -462,10 +463,10 @@ public class ShareRootControllerImpl {
|
||||
|
||||
if let mainFile = mainFile, let mainFileText = try? String(contentsOf: URL(fileURLWithPath: mainFile.path)) {
|
||||
let mainFileHeader: String
|
||||
if mainFileText.count < 1000 {
|
||||
if mainFileText.count < 2000 {
|
||||
mainFileHeader = mainFileText
|
||||
} else {
|
||||
mainFileHeader = String(mainFileText[mainFileText.startIndex ..< mainFileText.index(mainFileText.startIndex, offsetBy: 1000)])
|
||||
mainFileHeader = String(mainFileText[mainFileText.startIndex ..< mainFileText.index(mainFileText.startIndex, offsetBy: 2000)])
|
||||
}
|
||||
|
||||
final class TempController: ViewController {
|
||||
@ -476,11 +477,16 @@ public class ShareRootControllerImpl {
|
||||
}
|
||||
}
|
||||
|
||||
private let activityIndicator: ActivityIndicator
|
||||
|
||||
init(context: AccountContext) {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
self.activityIndicator = ActivityIndicator(type: .custom(presentationData.theme.list.itemAccentColor, 22.0, 1.0, false))
|
||||
|
||||
super.init(navigationBarPresentationData: NavigationBarPresentationData(presentationData: presentationData))
|
||||
|
||||
//TODO:localize
|
||||
self.title = "Import Chat"
|
||||
self.navigationItem.setLeftBarButton(UIBarButtonItem(title: presentationData.strings.Common_Cancel, style: .plain, target: self, action: #selector(self.cancelPressed)), animated: false)
|
||||
}
|
||||
@ -492,6 +498,19 @@ public class ShareRootControllerImpl {
|
||||
@objc private func cancelPressed() {
|
||||
//self?.getExtensionContext()?.completeRequest(returningItems: nil, completionHandler: nil)
|
||||
}
|
||||
|
||||
override func displayNodeDidLoad() {
|
||||
super.displayNodeDidLoad()
|
||||
|
||||
self.displayNode.addSubnode(self.activityIndicator)
|
||||
}
|
||||
|
||||
override func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
|
||||
super.containerLayoutUpdated(layout, transition: transition)
|
||||
|
||||
let indicatorSize = self.activityIndicator.measure(CGSize(width: 100.0, height: 100.0))
|
||||
transition.updateFrame(node: self.activityIndicator, frame: CGRect(origin: CGPoint(x: floor((layout.size.width - indicatorSize.width) / 2.0), y: floor((layout.size.height - indicatorSize.height - 50.0) / 2.0)), size: indicatorSize))
|
||||
}
|
||||
}
|
||||
|
||||
let presentationData = internalContext.sharedContext.currentPresentationData.with { $0 }
|
||||
@ -620,10 +639,8 @@ public class ShareRootControllerImpl {
|
||||
}
|
||||
|
||||
navigationController.viewControllers = [controller]
|
||||
strongSelf.mainWindow?.present(navigationController, on: .root)
|
||||
case let .privateChat(title):
|
||||
let presentationData = internalContext.sharedContext.currentPresentationData.with { $0 }
|
||||
let navigationController = NavigationController(mode: .single, theme: NavigationControllerTheme(presentationTheme: presentationData.theme))
|
||||
|
||||
//TODO:localize
|
||||
var attemptSelectionImpl: ((Peer) -> Void)?
|
||||
@ -684,7 +701,6 @@ public class ShareRootControllerImpl {
|
||||
}
|
||||
|
||||
navigationController.viewControllers = [controller]
|
||||
strongSelf.mainWindow?.present(navigationController, on: .root)
|
||||
case let .unknown(peerTitle):
|
||||
//TODO:localize
|
||||
var attemptSelectionImpl: ((Peer) -> Void)?
|
||||
@ -839,7 +855,6 @@ public class ShareRootControllerImpl {
|
||||
}
|
||||
|
||||
navigationController.viewControllers = [controller]
|
||||
strongSelf.mainWindow?.present(navigationController, on: .root)
|
||||
}
|
||||
}, error: { _ in
|
||||
beginShare()
|
||||
|
@ -364,7 +364,7 @@ final class VerticalListContextResultsChatInputPanelItemNode: ListViewItemNode {
|
||||
|
||||
switch status {
|
||||
case let .Fetching(_, progress):
|
||||
state = RadialStatusNodeState.progress(color: statusForegroundColor, lineWidth: nil, value: CGFloat(max(progress, 0.2)), cancelEnabled: false)
|
||||
state = RadialStatusNodeState.progress(color: statusForegroundColor, lineWidth: nil, value: CGFloat(max(progress, 0.2)), cancelEnabled: false, animateRotation: true)
|
||||
case .Remote:
|
||||
state = .download(statusForegroundColor)
|
||||
case .Local:
|
||||
|
@ -188,7 +188,7 @@ final class OverlayVideoDecoration: UniversalVideoDecoration {
|
||||
return
|
||||
}
|
||||
if let status = status, case .buffering = status.status {
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: nil, cancelEnabled: false))
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: nil, cancelEnabled: false, animateRotation: true))
|
||||
} else {
|
||||
strongSelf.statusNode.transitionToState(.none)
|
||||
}
|
||||
|
@ -227,7 +227,7 @@ final class WebSearchVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
||||
|
||||
var fetching = false
|
||||
if initialBuffering {
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: nil, cancelEnabled: false), animated: false, completion: {})
|
||||
strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: nil, cancelEnabled: false, animateRotation: true), animated: false, completion: {})
|
||||
} else {
|
||||
var state: RadialStatusNodeState = .none
|
||||
|
||||
@ -237,7 +237,7 @@ final class WebSearchVideoGalleryItemNode: ZoomableContentGalleryItemNode {
|
||||
case let .Fetching(_, progress):
|
||||
fetching = true
|
||||
isPaused = true
|
||||
state = .progress(color: .white, lineWidth: nil, value: CGFloat(max(0.027, progress)), cancelEnabled: false)
|
||||
state = .progress(color: .white, lineWidth: nil, value: CGFloat(max(0.027, progress)), cancelEnabled: false, animateRotation: true)
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user