mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various fixes
This commit is contained in:
parent
1203c589bf
commit
98f30de9fb
BIN
Telegram/Telegram-iOS/Resources/ShareDone.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/ShareDone.tgs
Normal file
Binary file not shown.
BIN
Telegram/Telegram-iOS/Resources/ShareProgress.tgs
Normal file
BIN
Telegram/Telegram-iOS/Resources/ShareProgress.tgs
Normal file
Binary file not shown.
@ -7520,3 +7520,6 @@ Sorry for the inconvenience.";
|
||||
"Group.RequestToJoinSentDescriptionGroup" = "You will be able to send messages once the admins approve your request.";
|
||||
|
||||
"Channel.AdminLog.JoinedViaPublicRequest" = "%1$@ joined via public request, approved by %2$@";
|
||||
|
||||
"Share.UploadProgress" = "Uploading • %d%";
|
||||
"Share.UploadDone" = "Done";
|
||||
|
@ -583,7 +583,9 @@ public final class MediaPlayerScrubbingNode: ASDisplayNode {
|
||||
let scrubbingTimestampValue = strongSelf.scrubbingTimestampValue
|
||||
strongSelf.scrubbingTimestampValue = nil
|
||||
strongSelf._scrubbingTimestamp.set(.single(nil))
|
||||
strongSelf._scrubbingPosition.set(.single(nil))
|
||||
Queue.mainQueue().after(0.01, {
|
||||
strongSelf._scrubbingPosition.set(.single(nil))
|
||||
})
|
||||
if let scrubbingTimestampValue = scrubbingTimestampValue, apply {
|
||||
if let statusValue = strongSelf.statusValue {
|
||||
switch statusValue.status {
|
||||
|
@ -1085,7 +1085,7 @@ private class StorageUsageClearProgressOverlayNode: ASDisplayNode, ActionSheetGr
|
||||
let descriptionTextSize = self.descriptionTextNode.updateLayout(CGSize(width: size.width - inset * 3.0, height: size.height))
|
||||
var descriptionTextFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - descriptionTextSize.width) / 2.0), y: progressFrame.minY - spacing - 9.0 - descriptionTextSize.height), size: descriptionTextSize)
|
||||
|
||||
self.progressTextNode.attributedText = NSAttributedString(string: self.presentationData.strings.ClearCache_Progress(Int(progress * 100.0)).string, font: Font.with(size: 17.0, design: .regular, weight: .bold, traits: [.monospacedNumbers]), textColor: self.presentationData.theme.actionSheet.primaryTextColor)
|
||||
self.progressTextNode.attributedText = NSAttributedString(string: self.presentationData.strings.ClearCache_Progress(Int(progress * 100.0)).string, font: Font.with(size: 17.0, design: .regular, weight: .semibold, traits: [.monospacedNumbers]), textColor: self.presentationData.theme.actionSheet.primaryTextColor)
|
||||
let progressTextSize = self.progressTextNode.updateLayout(size)
|
||||
var progressTextFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - progressTextSize.width) / 2.0), y: descriptionTextFrame.minY - spacing - progressTextSize.height), size: progressTextSize)
|
||||
|
||||
|
@ -32,6 +32,8 @@ swift_library(
|
||||
"//submodules/WallpaperBackgroundNode:WallpaperBackgroundNode",
|
||||
"//submodules/ShimmerEffect:ShimmerEffect",
|
||||
"//submodules/ContextUI:ContextUI",
|
||||
"//submodules/AnimatedStickerNode:AnimatedStickerNode",
|
||||
"//submodules/TelegramAnimatedStickerNode:TelegramAnimatedStickerNode",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
@ -457,7 +457,7 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
|
||||
if contentNode is ShareSearchContainerNode {
|
||||
self.setActionNodesHidden(true, inputField: true, actions: true)
|
||||
} else if !(contentNode is ShareLoadingContainerNode) {
|
||||
} else if !(contentNode is ShareLoadingContainer) {
|
||||
self.setActionNodesHidden(false, inputField: !self.controllerInteraction!.selectedPeers.isEmpty || self.presetText != nil, actions: true)
|
||||
}
|
||||
} else {
|
||||
@ -649,7 +649,12 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
let timestamp = CACurrentMediaTime()
|
||||
let doneImpl: (Bool) -> Void = { [weak self] shouldDelay in
|
||||
let minDelay: Double = shouldDelay ? 0.9 : 0.6
|
||||
let delay = max(minDelay, (timestamp + minDelay) - CACurrentMediaTime())
|
||||
let delay: Double
|
||||
if let strongSelf = self, let contentNode = strongSelf.contentNode as? ShareProlongedLoadingContainerNode {
|
||||
delay = contentNode.completionDuration
|
||||
} else {
|
||||
delay = max(minDelay, (timestamp + minDelay) - CACurrentMediaTime())
|
||||
}
|
||||
Queue.mainQueue().after(delay, {
|
||||
self?.animateOut(shared: true, completion: {
|
||||
self?.dismiss?(true)
|
||||
@ -658,7 +663,7 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
})
|
||||
}
|
||||
if self.fromForeignApp {
|
||||
self.transitionToContentNode(ShareLoadingContainerNode(theme: self.presentationData.theme, forceNativeAppearance: true), fastOut: true)
|
||||
self.transitionToContentNode(ShareProlongedLoadingContainerNode(theme: self.presentationData.theme, strings: self.presentationData.strings, forceNativeAppearance: true), fastOut: true)
|
||||
} else {
|
||||
self.animateOut(shared: true, completion: {
|
||||
})
|
||||
@ -683,7 +688,7 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
return
|
||||
}
|
||||
|
||||
guard let contentNode = strongSelf.contentNode as? ShareLoadingContainerNode else {
|
||||
guard let contentNode = strongSelf.contentNode as? ShareLoadingContainer else {
|
||||
return
|
||||
}
|
||||
|
||||
@ -988,7 +993,7 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
transition.updateAlpha(node: self.actionSeparatorNode, alpha: 0.0)
|
||||
transition.updateAlpha(node: self.actionsBackgroundNode, alpha: 0.0)
|
||||
|
||||
self.transitionToContentNode(ShareLoadingContainerNode(theme: self.presentationData.theme, forceNativeAppearance: true), fastOut: true)
|
||||
self.transitionToContentNode(ShareProlongedLoadingContainerNode(theme: self.presentationData.theme, strings: self.presentationData.strings, forceNativeAppearance: true), fastOut: true)
|
||||
let timestamp = CACurrentMediaTime()
|
||||
self.shareDisposable.set(signal.start(completed: { [weak self] in
|
||||
let minDelay = 0.6
|
||||
@ -1041,14 +1046,14 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
}
|
||||
self.shareDisposable.set((signal
|
||||
|> deliverOnMainQueue).start(next: { [weak self] status in
|
||||
guard let strongSelf = self, let contentNode = strongSelf.contentNode as? ShareLoadingContainerNode else {
|
||||
guard let strongSelf = self, let contentNode = strongSelf.contentNode as? ShareLoadingContainer else {
|
||||
return
|
||||
}
|
||||
if let status = status {
|
||||
contentNode.state = .progress(status)
|
||||
}
|
||||
}, completed: { [weak self] in
|
||||
guard let strongSelf = self, let contentNode = strongSelf.contentNode as? ShareLoadingContainerNode else {
|
||||
guard let strongSelf = self, let contentNode = strongSelf.contentNode as? ShareLoadingContainer else {
|
||||
return
|
||||
}
|
||||
contentNode.state = .done
|
||||
|
@ -1,11 +1,14 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import AsyncDisplayKit
|
||||
import SwiftSignalKit
|
||||
import Display
|
||||
import Postbox
|
||||
import TelegramPresentationData
|
||||
import ActivityIndicator
|
||||
import RadialStatusNode
|
||||
import AnimatedStickerNode
|
||||
import TelegramAnimatedStickerNode
|
||||
|
||||
public enum ShareLoadingState {
|
||||
case preparing
|
||||
@ -13,7 +16,11 @@ public enum ShareLoadingState {
|
||||
case done
|
||||
}
|
||||
|
||||
public final class ShareLoadingContainerNode: ASDisplayNode, ShareContentContainerNode {
|
||||
protocol ShareLoadingContainer: ASDisplayNode {
|
||||
var state: ShareLoadingState { get set }
|
||||
}
|
||||
|
||||
public final class ShareLoadingContainerNode: ASDisplayNode, ShareContentContainerNode, ShareLoadingContainer {
|
||||
private var contentOffsetUpdated: ((CGFloat, ContainedViewLayoutTransition) -> Void)?
|
||||
|
||||
private let theme: PresentationTheme
|
||||
@ -83,3 +90,229 @@ public final class ShareLoadingContainerNode: ASDisplayNode, ShareContentContain
|
||||
public func updateSelectedPeers() {
|
||||
}
|
||||
}
|
||||
|
||||
public final class ShareProlongedLoadingContainerNode: ASDisplayNode, ShareContentContainerNode, ShareLoadingContainer {
|
||||
private var contentOffsetUpdated: ((CGFloat, ContainedViewLayoutTransition) -> Void)?
|
||||
|
||||
private let theme: PresentationTheme
|
||||
private let strings: PresentationStrings
|
||||
|
||||
private let animationNode: AnimatedStickerNode
|
||||
private let doneAnimationNode: AnimatedStickerNode
|
||||
private let progressTextNode: ImmediateTextNode
|
||||
|
||||
private let progressBackgroundNode: ASDisplayNode
|
||||
private let progressForegroundNode: ASDisplayNode
|
||||
|
||||
private let animationStatusDisposable = MetaDisposable()
|
||||
|
||||
private var progressValue: CGFloat = 0.0
|
||||
|
||||
private var randomCompletionStart: CGFloat = .random(in: 0.94...0.97)
|
||||
private var completionProgress: Double = 0.0
|
||||
private var isDone: Bool = false
|
||||
|
||||
private var startTimestamp: Double?
|
||||
|
||||
public var state: ShareLoadingState = .preparing {
|
||||
didSet {
|
||||
switch self.state {
|
||||
case .preparing:
|
||||
break
|
||||
case let .progress(value):
|
||||
let currentTimestamp = CACurrentMediaTime()
|
||||
if self.startTimestamp == nil {
|
||||
self.startTimestamp = currentTimestamp
|
||||
} else if let startTimestamp = self.startTimestamp, currentTimestamp - startTimestamp < 1.0, value > 0.5 && value < 0.9 {
|
||||
self.randomCompletionStart = 0.8
|
||||
}
|
||||
|
||||
if let (size, isLandscape, bottomInset) = self.validLayout {
|
||||
self.updateLayout(size: size, isLandscape: isLandscape, bottomInset: bottomInset, transition: .animated(duration: 0.3, curve: .easeInOut))
|
||||
}
|
||||
case .done:
|
||||
if let (size, isLandscape, bottomInset) = self.validLayout {
|
||||
self.updateLayout(size: size, isLandscape: isLandscape, bottomInset: bottomInset, transition: .animated(duration: 0.2, curve: .easeInOut))
|
||||
}
|
||||
self.animationNode.stopAtNearestLoop = true
|
||||
self.animationNode.completed = { [weak self] _ in
|
||||
if let strongSelf = self {
|
||||
strongSelf.animationNode.visibility = false
|
||||
strongSelf.doneAnimationNode.visibility = true
|
||||
strongSelf.doneAnimationNode.isHidden = false
|
||||
}
|
||||
}
|
||||
self.animationNode.frameUpdated = { [weak self] index, total in
|
||||
if let strongSelf = self {
|
||||
let progress = min(1.0, CGFloat(index) / CGFloat(total))
|
||||
if abs(progress - strongSelf.completionProgress) >= 0.05 || progress == 1.0 {
|
||||
strongSelf.completionProgress = 0.5 * progress
|
||||
|
||||
if let (size, isLandscape, bottomInset) = strongSelf.validLayout {
|
||||
strongSelf.updateLayout(size: size, isLandscape: isLandscape, bottomInset: bottomInset, transition: .animated(duration: 0.2, curve: .easeInOut))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.doneAnimationNode.frameUpdated = { [weak self] index, total in
|
||||
if let strongSelf = self {
|
||||
let progress = 0.5 + min(1.0, CGFloat(index) / CGFloat(total) * 2.1) * 0.5
|
||||
if abs(progress - strongSelf.completionProgress) >= 0.05 || progress == 1.0 {
|
||||
strongSelf.completionProgress = progress
|
||||
|
||||
if progress == 1.0, !strongSelf.isDone {
|
||||
strongSelf.isDone = true
|
||||
|
||||
if let snapshotView = strongSelf.progressTextNode.view.snapshotContentTree() {
|
||||
snapshotView.frame = strongSelf.progressTextNode.frame
|
||||
strongSelf.view.addSubview(snapshotView)
|
||||
|
||||
snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { [weak snapshotView] _ in
|
||||
snapshotView?.removeFromSuperview()
|
||||
})
|
||||
snapshotView.layer.animatePosition(from: CGPoint(), to: CGPoint(x: 0.0, y: -20.0), duration: 0.25, removeOnCompletion: false, additive: true)
|
||||
|
||||
strongSelf.progressTextNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3)
|
||||
strongSelf.progressTextNode.layer.animatePosition(from: CGPoint(x: 0.0, y: 20.0), to: CGPoint(), duration: 0.25, additive: true)
|
||||
}
|
||||
}
|
||||
|
||||
if let (size, isLandscape, bottomInset) = strongSelf.validLayout {
|
||||
strongSelf.updateLayout(size: size, isLandscape: isLandscape, bottomInset: bottomInset, transition: .animated(duration: 0.2, curve: .easeInOut))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.doneAnimationNode.started = { [weak self] in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.animationNode.isHidden = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var elapsedTime: Double = 0.0
|
||||
public var completionDuration: Double {
|
||||
return self.elapsedTime + 3.0 + 0.15
|
||||
}
|
||||
|
||||
public init(theme: PresentationTheme, strings: PresentationStrings, forceNativeAppearance: Bool) {
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
|
||||
self.animationNode = AnimatedStickerNode()
|
||||
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "ShareProgress"), width: 256, height: 256, playbackMode: .loop, mode: .direct(cachePathPrefix: nil))
|
||||
self.animationNode.visibility = true
|
||||
|
||||
self.doneAnimationNode = AnimatedStickerNode()
|
||||
self.doneAnimationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: "ShareDone"), width: 256, height: 256, playbackMode: .once, mode: .direct(cachePathPrefix: nil))
|
||||
self.doneAnimationNode.visibility = false
|
||||
self.doneAnimationNode.isHidden = true
|
||||
|
||||
self.progressTextNode = ImmediateTextNode()
|
||||
self.progressTextNode.textAlignment = .center
|
||||
|
||||
self.progressBackgroundNode = ASDisplayNode()
|
||||
self.progressBackgroundNode.backgroundColor = theme.actionSheet.controlAccentColor.withMultipliedAlpha(0.2)
|
||||
self.progressBackgroundNode.cornerRadius = 3.0
|
||||
|
||||
self.progressForegroundNode = ASDisplayNode()
|
||||
self.progressForegroundNode.backgroundColor = theme.actionSheet.controlAccentColor
|
||||
self.progressForegroundNode.cornerRadius = 3.0
|
||||
|
||||
super.init()
|
||||
|
||||
self.addSubnode(self.animationNode)
|
||||
self.addSubnode(self.doneAnimationNode)
|
||||
|
||||
self.addSubnode(self.progressTextNode)
|
||||
|
||||
self.addSubnode(self.progressBackgroundNode)
|
||||
self.addSubnode(self.progressForegroundNode)
|
||||
|
||||
self.animationStatusDisposable.set((self.animationNode.status
|
||||
|> deliverOnMainQueue).start(next: { [weak self] status in
|
||||
if let strongSelf = self {
|
||||
strongSelf.elapsedTime = status.duration - status.timestamp
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.animationStatusDisposable.dispose()
|
||||
}
|
||||
|
||||
public func activate() {
|
||||
}
|
||||
|
||||
public func deactivate() {
|
||||
}
|
||||
|
||||
public func setEnsurePeerVisibleOnLayout(_ peerId: PeerId?) {
|
||||
}
|
||||
|
||||
public func setContentOffsetUpdated(_ f: ((CGFloat, ContainedViewLayoutTransition) -> Void)?) {
|
||||
self.contentOffsetUpdated = f
|
||||
}
|
||||
|
||||
private var validLayout: (CGSize, Bool, CGFloat)?
|
||||
public func updateLayout(size: CGSize, isLandscape: Bool, bottomInset: CGFloat, transition: ContainedViewLayoutTransition) {
|
||||
self.validLayout = (size, isLandscape, bottomInset)
|
||||
|
||||
let nodeHeight: CGFloat = 400.0
|
||||
|
||||
let inset: CGFloat = 24.0
|
||||
let progressHeight: CGFloat = 6.0
|
||||
let spacing: CGFloat = 16.0
|
||||
|
||||
var progress: CGFloat
|
||||
switch self.state {
|
||||
case .preparing:
|
||||
progress = 0.0
|
||||
case let .progress(value):
|
||||
progress = CGFloat(value) * self.randomCompletionStart
|
||||
case .done:
|
||||
progress = self.randomCompletionStart + (1.0 - self.randomCompletionStart) * self.completionProgress
|
||||
}
|
||||
self.progressValue = max(self.progressValue, progress)
|
||||
progress = self.progressValue
|
||||
|
||||
let progressFrame = CGRect(x: inset, y: size.height - inset - progressHeight, width: size.width - inset * 2.0, height: progressHeight)
|
||||
self.progressBackgroundNode.frame = progressFrame
|
||||
let progressForegroundFrame = CGRect(x: progressFrame.minX, y: progressFrame.minY, width: floorToScreenPixels(progressFrame.width * progress), height: progressHeight)
|
||||
if !self.progressForegroundNode.frame.width.isZero {
|
||||
transition.updateFrame(node: self.progressForegroundNode, frame: progressForegroundFrame)
|
||||
} else {
|
||||
self.progressForegroundNode.frame = progressForegroundFrame
|
||||
}
|
||||
|
||||
let progressText: String
|
||||
if self.isDone {
|
||||
progressText = self.strings.Share_UploadDone
|
||||
} else {
|
||||
progressText = self.strings.Share_UploadProgress(Int(progress * 100.0)).string
|
||||
}
|
||||
|
||||
self.progressTextNode.attributedText = NSAttributedString(string: progressText, font: Font.with(size: 17.0, design: .regular, weight: .semibold, traits: [.monospacedNumbers]), textColor: self.theme.actionSheet.primaryTextColor)
|
||||
let progressTextSize = self.progressTextNode.updateLayout(size)
|
||||
let progressTextFrame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - progressTextSize.width) / 2.0), y: progressFrame.minY - spacing - 9.0 - progressTextSize.height), size: progressTextSize)
|
||||
self.progressTextNode.frame = progressTextFrame
|
||||
|
||||
let imageSide: CGFloat = 160.0
|
||||
let imageSize = CGSize(width: imageSide, height: imageSide)
|
||||
|
||||
let animationFrame = CGRect(origin: CGPoint(x: floor((size.width - imageSize.width) / 2.0), y: (progressTextFrame.minY - imageSize.height - 20.0)), size: imageSize)
|
||||
self.animationNode.frame = animationFrame
|
||||
self.animationNode.updateLayout(size: imageSize)
|
||||
|
||||
self.doneAnimationNode.frame = animationFrame
|
||||
self.doneAnimationNode.updateLayout(size: imageSize)
|
||||
|
||||
self.contentOffsetUpdated?(-size.height + nodeHeight * 0.5, transition)
|
||||
}
|
||||
|
||||
public func updateSelectedPeers() {
|
||||
}
|
||||
}
|
||||
|
@ -146,7 +146,7 @@ public func canTranslateText(context: AccountContext, text: String, showTranslat
|
||||
return (false, nil)
|
||||
}
|
||||
|
||||
if #available(iOS 15.0, *) {
|
||||
if #available(iOS 12.0, *) {
|
||||
var dontTranslateLanguages: [String] = []
|
||||
if let ignoredLanguages = ignoredLanguages {
|
||||
dontTranslateLanguages = ignoredLanguages
|
||||
|
Loading…
x
Reference in New Issue
Block a user