mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various improvements
This commit is contained in:
parent
d0e9953d28
commit
167b9b3eac
@ -9863,3 +9863,8 @@ Sorry for the inconvenience.";
|
|||||||
"Story.ViewList.ViewerCount_any" = "%d Viewers";
|
"Story.ViewList.ViewerCount_any" = "%d Viewers";
|
||||||
|
|
||||||
"AuthSessions.MessageApp" = "You allowed this bot to message you when you opened %@.";
|
"AuthSessions.MessageApp" = "You allowed this bot to message you when you opened %@.";
|
||||||
|
|
||||||
|
"Story.Privacy.PostStoryAs" = "Post Story As";
|
||||||
|
"Story.Privacy.PostStoryAsHeader" = "POST STORY AS";
|
||||||
|
"Story.Privacy.KeepOnChannelPage" = "Post to Channel Profile";
|
||||||
|
"Story.Privacy.KeepOnChannelPageInfo" = "Keep this story on channel profile even after it expires in %@.";
|
||||||
|
@ -264,18 +264,18 @@ private final class VisualMediaItemNode: ASDisplayNode {
|
|||||||
|
|
||||||
if isStreamable {
|
if isStreamable {
|
||||||
switch status {
|
switch status {
|
||||||
case let .Fetching(_, progress):
|
case let .Fetching(_, progress):
|
||||||
let progressString = String(format: "%d%%", Int(progress * 100.0))
|
let progressString = String(format: "%d%%", Int(progress * 100.0))
|
||||||
badgeContent = .text(inset: 12.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: progressString))
|
badgeContent = .text(inset: 12.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: progressString), iconName: nil)
|
||||||
mediaDownloadState = .compactFetching(progress: 0.0)
|
mediaDownloadState = .compactFetching(progress: 0.0)
|
||||||
case .Local:
|
case .Local:
|
||||||
badgeContent = .text(inset: 0.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: durationString))
|
badgeContent = .text(inset: 0.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: durationString), iconName: nil)
|
||||||
case .Remote, .Paused:
|
case .Remote, .Paused:
|
||||||
badgeContent = .text(inset: 12.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: durationString))
|
badgeContent = .text(inset: 12.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: durationString), iconName: nil)
|
||||||
mediaDownloadState = .compactRemote
|
mediaDownloadState = .compactRemote
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
badgeContent = .text(inset: 0.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: durationString))
|
badgeContent = .text(inset: 0.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: durationString), iconName: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
strongSelf.mediaBadgeNode.update(theme: nil, content: badgeContent, mediaDownloadState: mediaDownloadState, alignment: .right, animated: false, badgeAnimated: false)
|
strongSelf.mediaBadgeNode.update(theme: nil, content: badgeContent, mediaDownloadState: mediaDownloadState, alignment: .right, animated: false, badgeAnimated: false)
|
||||||
|
@ -18,13 +18,13 @@ public enum ChatMessageInteractiveMediaDownloadState: Equatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public enum ChatMessageInteractiveMediaBadgeContent: Equatable {
|
public enum ChatMessageInteractiveMediaBadgeContent: Equatable {
|
||||||
case text(inset: CGFloat, backgroundColor: UIColor, foregroundColor: UIColor, text: NSAttributedString)
|
case text(inset: CGFloat, backgroundColor: UIColor, foregroundColor: UIColor, text: NSAttributedString, iconName: String?)
|
||||||
case mediaDownload(backgroundColor: UIColor, foregroundColor: UIColor, duration: String, size: String?, muted: Bool, active: Bool)
|
case mediaDownload(backgroundColor: UIColor, foregroundColor: UIColor, duration: String, size: String?, muted: Bool, active: Bool)
|
||||||
|
|
||||||
public static func ==(lhs: ChatMessageInteractiveMediaBadgeContent, rhs: ChatMessageInteractiveMediaBadgeContent) -> Bool {
|
public static func ==(lhs: ChatMessageInteractiveMediaBadgeContent, rhs: ChatMessageInteractiveMediaBadgeContent) -> Bool {
|
||||||
switch lhs {
|
switch lhs {
|
||||||
case let .text(lhsInset, lhsBackgroundColor, lhsForegroundColor, lhsText):
|
case let .text(lhsInset, lhsBackgroundColor, lhsForegroundColor, lhsText, lhsIconName):
|
||||||
if case let .text(rhsInset, rhsBackgroundColor, rhsForegroundColor, rhsText) = rhs, lhsInset.isEqual(to: rhsInset), lhsBackgroundColor.isEqual(rhsBackgroundColor), lhsForegroundColor.isEqual(rhsForegroundColor), lhsText.isEqual(to: rhsText) {
|
if case let .text(rhsInset, rhsBackgroundColor, rhsForegroundColor, rhsText, rhsIconName) = rhs, lhsInset.isEqual(to: rhsInset), lhsBackgroundColor.isEqual(rhsBackgroundColor), lhsForegroundColor.isEqual(rhsForegroundColor), lhsText.isEqual(to: rhsText), lhsIconName == rhsIconName {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
@ -48,6 +48,7 @@ public final class ChatMessageInteractiveMediaBadge: ASDisplayNode {
|
|||||||
private var previousContentSize: CGSize?
|
private var previousContentSize: CGSize?
|
||||||
private var backgroundNodeColor: UIColor?
|
private var backgroundNodeColor: UIColor?
|
||||||
private var foregroundColor: UIColor?
|
private var foregroundColor: UIColor?
|
||||||
|
private var iconName: String?
|
||||||
|
|
||||||
private let backgroundNode: ASImageNode
|
private let backgroundNode: ASImageNode
|
||||||
private let durationNode: ASTextNode
|
private let durationNode: ASTextNode
|
||||||
@ -107,14 +108,18 @@ public final class ChatMessageInteractiveMediaBadge: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch content {
|
switch content {
|
||||||
case let .text(inset, backgroundColor, foregroundColor, text):
|
case let .text(inset, backgroundColor, foregroundColor, text, iconName):
|
||||||
transition = .immediate
|
transition = .immediate
|
||||||
|
|
||||||
if self.backgroundNodeColor != backgroundColor {
|
if self.backgroundNodeColor != backgroundColor {
|
||||||
self.backgroundNodeColor = backgroundColor
|
self.backgroundNodeColor = backgroundColor
|
||||||
self.backgroundNode.image = generateStretchableFilledCircleImage(radius: 9.0, color: backgroundColor)
|
self.backgroundNode.image = generateStretchableFilledCircleImage(radius: 9.0, color: backgroundColor)
|
||||||
}
|
}
|
||||||
let convertedText = NSMutableAttributedString(string: text.string, attributes: [.font: font, .foregroundColor: foregroundColor])
|
var textFont = font
|
||||||
|
if iconName != nil {
|
||||||
|
textFont = boldFont
|
||||||
|
}
|
||||||
|
let convertedText = NSMutableAttributedString(string: text.string, attributes: [.font: textFont, .foregroundColor: foregroundColor])
|
||||||
text.enumerateAttributes(in: NSRange(location: 0, length: text.length), options: []) { attributes, range, _ in
|
text.enumerateAttributes(in: NSRange(location: 0, length: text.length), options: []) { attributes, range, _ in
|
||||||
if let _ = attributes[ChatTextInputAttributes.bold] {
|
if let _ = attributes[ChatTextInputAttributes.bold] {
|
||||||
convertedText.addAttribute(.font, value: boldFont, range: range)
|
convertedText.addAttribute(.font, value: boldFont, range: range)
|
||||||
@ -122,12 +127,33 @@ public final class ChatMessageInteractiveMediaBadge: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
self.durationNode.attributedText = convertedText
|
self.durationNode.attributedText = convertedText
|
||||||
let durationSize = self.durationNode.measure(CGSize(width: 160.0, height: 160.0))
|
let durationSize = self.durationNode.measure(CGSize(width: 160.0, height: 160.0))
|
||||||
self.durationNode.frame = CGRect(x: 7.0 + inset, y: 3.0, width: durationSize.width, height: durationSize.height)
|
self.durationNode.frame = CGRect(x: 7.0 + inset, y: 2.0 + UIScreenPixel, width: durationSize.width, height: durationSize.height)
|
||||||
currentContentSize = CGSize(width: widthForString(text.string) + 14.0 + inset, height: 18.0)
|
currentContentSize = CGSize(width: widthForString(text.string) + 14.0 + inset, height: 18.0)
|
||||||
|
|
||||||
if let iconNode = self.iconNode {
|
if let iconName {
|
||||||
transition.updateTransformScale(node: iconNode, scale: 0.001)
|
let iconNode: ASImageNode
|
||||||
transition.updateAlpha(node: iconNode, alpha: 0.0)
|
if let current = self.iconNode {
|
||||||
|
iconNode = current
|
||||||
|
} else {
|
||||||
|
iconNode = ASImageNode()
|
||||||
|
self.iconNode = iconNode
|
||||||
|
self.backgroundNode.addSubnode(iconNode)
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.foregroundColor != foregroundColor || self.iconName != iconName {
|
||||||
|
self.foregroundColor = foregroundColor
|
||||||
|
self.iconName = iconName
|
||||||
|
iconNode.image = generateTintedImage(image: UIImage(bundleImageName: iconName), color: foregroundColor)
|
||||||
|
}
|
||||||
|
transition.updateAlpha(node: iconNode, alpha: 1.0)
|
||||||
|
transition.updateTransformScale(node: iconNode, scale: 1.0)
|
||||||
|
|
||||||
|
iconNode.frame = CGRect(x: 3.0, y: 2.0, width: 12.0, height: 14.0)
|
||||||
|
} else {
|
||||||
|
if let iconNode = self.iconNode {
|
||||||
|
transition.updateTransformScale(node: iconNode, scale: 0.001)
|
||||||
|
transition.updateAlpha(node: iconNode, alpha: 0.0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case let .mediaDownload(backgroundColor, foregroundColor, duration, size, muted, active):
|
case let .mediaDownload(backgroundColor, foregroundColor, duration, size, muted, active):
|
||||||
if self.backgroundNodeColor != backgroundColor {
|
if self.backgroundNodeColor != backgroundColor {
|
||||||
@ -209,7 +235,7 @@ public final class ChatMessageInteractiveMediaBadge: ASDisplayNode {
|
|||||||
|
|
||||||
let durationWidth = widthForString(duration)
|
let durationWidth = widthForString(duration)
|
||||||
transition.updatePosition(node: iconNode, position: CGPoint(x: (active ? 42.0 : 7.0) + durationWidth + 4.0 + 7.0, y: (active ? 8.0 : 4.0) + 5.0))
|
transition.updatePosition(node: iconNode, position: CGPoint(x: (active ? 42.0 : 7.0) + durationWidth + 4.0 + 7.0, y: (active ? 8.0 : 4.0) + 5.0))
|
||||||
|
|
||||||
if muted {
|
if muted {
|
||||||
transition.updateAlpha(node: iconNode, alpha: 1.0)
|
transition.updateAlpha(node: iconNode, alpha: 1.0)
|
||||||
transition.updateTransformScale(node: iconNode, scale: 1.0)
|
transition.updateTransformScale(node: iconNode, scale: 1.0)
|
||||||
|
@ -14,6 +14,7 @@ swift_library(
|
|||||||
"//submodules/AsyncDisplayKit:AsyncDisplayKit",
|
"//submodules/AsyncDisplayKit:AsyncDisplayKit",
|
||||||
"//submodules/LegacyComponents:LegacyComponents",
|
"//submodules/LegacyComponents:LegacyComponents",
|
||||||
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
|
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
|
||||||
|
"//submodules/ManagedAnimationNode:ManagedAnimationNode"
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
@ -5,6 +5,7 @@ import AsyncDisplayKit
|
|||||||
|
|
||||||
enum RadialStatusIcon {
|
enum RadialStatusIcon {
|
||||||
case custom(UIImage)
|
case custom(UIImage)
|
||||||
|
case timeout
|
||||||
case play(UIColor)
|
case play(UIColor)
|
||||||
case pause(UIColor)
|
case pause(UIColor)
|
||||||
}
|
}
|
||||||
@ -22,14 +23,28 @@ private final class RadialStatusIconContentNodeParameters: NSObject {
|
|||||||
final class RadialStatusIconContentNode: RadialStatusContentNode {
|
final class RadialStatusIconContentNode: RadialStatusContentNode {
|
||||||
private let icon: RadialStatusIcon
|
private let icon: RadialStatusIcon
|
||||||
|
|
||||||
|
private var animationNode: FireIconNode?
|
||||||
|
|
||||||
init(icon: RadialStatusIcon, synchronous: Bool) {
|
init(icon: RadialStatusIcon, synchronous: Bool) {
|
||||||
self.icon = icon
|
self.icon = icon
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
self.displaysAsynchronously = !synchronous
|
self.displaysAsynchronously = !synchronous
|
||||||
self.isLayerBacked = true
|
// self.isLayerBacked = true
|
||||||
self.isOpaque = false
|
self.isOpaque = false
|
||||||
|
|
||||||
|
if case .timeout = icon {
|
||||||
|
let animationNode = FireIconNode()
|
||||||
|
self.animationNode = animationNode
|
||||||
|
self.addSubnode(animationNode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override func layout() {
|
||||||
|
super.layout()
|
||||||
|
|
||||||
|
self.animationNode?.frame = CGRect(x: 6.0, y: 2.0, width: 36.0, height: 36.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func drawParameters(forAsyncLayer layer: _ASDisplayLayer) -> NSObjectProtocol? {
|
override func drawParameters(forAsyncLayer layer: _ASDisplayLayer) -> NSObjectProtocol? {
|
||||||
@ -48,6 +63,8 @@ final class RadialStatusIconContentNode: RadialStatusContentNode {
|
|||||||
if let parameters = parameters as? RadialStatusIconContentNodeParameters {
|
if let parameters = parameters as? RadialStatusIconContentNodeParameters {
|
||||||
let diameter = min(bounds.size.width, bounds.size.height)
|
let diameter = min(bounds.size.width, bounds.size.height)
|
||||||
switch parameters.icon {
|
switch parameters.icon {
|
||||||
|
case .timeout:
|
||||||
|
break
|
||||||
case let .play(color):
|
case let .play(color):
|
||||||
context.setFillColor(color.cgColor)
|
context.setFillColor(color.cgColor)
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ public enum RadialStatusNodeState: Equatable {
|
|||||||
case cloudProgress(color: UIColor, strokeBackgroundColor: UIColor, lineWidth: CGFloat, value: CGFloat?)
|
case cloudProgress(color: UIColor, strokeBackgroundColor: UIColor, lineWidth: CGFloat, value: CGFloat?)
|
||||||
case check(UIColor)
|
case check(UIColor)
|
||||||
case customIcon(UIImage)
|
case customIcon(UIImage)
|
||||||
|
case staticTimeout
|
||||||
case secretTimeout(color: UIColor, icon: UIImage?, beginTime: Double, timeout: Double, sparks: Bool)
|
case secretTimeout(color: UIColor, icon: UIImage?, beginTime: Double, timeout: Double, sparks: Bool)
|
||||||
|
|
||||||
public static func ==(lhs: RadialStatusNodeState, rhs: RadialStatusNodeState) -> Bool {
|
public static func ==(lhs: RadialStatusNodeState, rhs: RadialStatusNodeState) -> Bool {
|
||||||
@ -64,6 +65,12 @@ public enum RadialStatusNodeState: Equatable {
|
|||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
case .staticTimeout:
|
||||||
|
if case .staticTimeout = rhs {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
case let .secretTimeout(lhsColor, lhsIcon, lhsBeginTime, lhsTimeout, lhsSparks):
|
case let .secretTimeout(lhsColor, lhsIcon, lhsBeginTime, lhsTimeout, lhsSparks):
|
||||||
if case let .secretTimeout(rhsColor, rhsIcon, rhsBeginTime, rhsTimeout, rhsSparks) = rhs, lhsColor.isEqual(rhsColor), lhsIcon === rhsIcon, lhsBeginTime.isEqual(to: rhsBeginTime), lhsTimeout.isEqual(to: rhsTimeout), lhsSparks == rhsSparks {
|
if case let .secretTimeout(rhsColor, rhsIcon, rhsBeginTime, rhsTimeout, rhsSparks) = rhs, lhsColor.isEqual(rhsColor), lhsIcon === rhsIcon, lhsBeginTime.isEqual(to: rhsBeginTime), lhsTimeout.isEqual(to: rhsTimeout), lhsSparks == rhsSparks {
|
||||||
return true
|
return true
|
||||||
@ -123,6 +130,12 @@ public enum RadialStatusNodeState: Equatable {
|
|||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
case .staticTimeout:
|
||||||
|
if case .staticTimeout = rhs{
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
case let .secretTimeout(lhsColor, lhsIcon, lhsBeginTime, lhsTimeout, lhsSparks):
|
case let .secretTimeout(lhsColor, lhsIcon, lhsBeginTime, lhsTimeout, lhsSparks):
|
||||||
if case let .secretTimeout(rhsColor, rhsIcon, rhsBeginTime, rhsTimeout, rhsSparks) = rhs, lhsColor.isEqual(rhsColor), lhsIcon === rhsIcon, lhsBeginTime.isEqual(to: rhsBeginTime), lhsTimeout.isEqual(to: rhsTimeout), lhsSparks == rhsSparks {
|
if case let .secretTimeout(rhsColor, rhsIcon, rhsBeginTime, rhsTimeout, rhsSparks) = rhs, lhsColor.isEqual(rhsColor), lhsIcon === rhsIcon, lhsBeginTime.isEqual(to: rhsBeginTime), lhsTimeout.isEqual(to: rhsTimeout), lhsSparks == rhsSparks {
|
||||||
return true
|
return true
|
||||||
@ -179,6 +192,8 @@ public enum RadialStatusNodeState: Equatable {
|
|||||||
node.progress = value
|
node.progress = value
|
||||||
return node
|
return node
|
||||||
}
|
}
|
||||||
|
case .staticTimeout:
|
||||||
|
return RadialStatusIconContentNode(icon: .timeout, synchronous: synchronous)
|
||||||
case let .secretTimeout(color, icon, beginTime, timeout, sparks):
|
case let .secretTimeout(color, icon, beginTime, timeout, sparks):
|
||||||
return RadialStatusSecretTimeoutContentNode(color: color, beginTime: beginTime, timeout: timeout, icon: icon, sparks: sparks)
|
return RadialStatusSecretTimeoutContentNode(color: color, beginTime: beginTime, timeout: timeout, icon: icon, sparks: sparks)
|
||||||
}
|
}
|
||||||
@ -188,7 +203,9 @@ public enum RadialStatusNodeState: Equatable {
|
|||||||
public final class RadialStatusNode: ASControlNode {
|
public final class RadialStatusNode: ASControlNode {
|
||||||
public var backgroundNodeColor: UIColor {
|
public var backgroundNodeColor: UIColor {
|
||||||
didSet {
|
didSet {
|
||||||
self.transitionToBackgroundColor(self.state.backgroundColor(color: self.backgroundNodeColor), previousContentNode: nil, animated: false, synchronous: false, completion: {})
|
if self.backgroundNodeColor != oldValue {
|
||||||
|
self.transitionToBackgroundColor(self.state.backgroundColor(color: self.backgroundNodeColor), previousContentNode: nil, animated: false, synchronous: false, completion: {})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ import UIKit
|
|||||||
import Display
|
import Display
|
||||||
import AsyncDisplayKit
|
import AsyncDisplayKit
|
||||||
import LegacyComponents
|
import LegacyComponents
|
||||||
|
import ManagedAnimationNode
|
||||||
|
|
||||||
private struct ContentParticle {
|
private struct ContentParticle {
|
||||||
var position: CGPoint
|
var position: CGPoint
|
||||||
@ -53,6 +54,8 @@ final class RadialStatusSecretTimeoutContentNode: RadialStatusContentNode {
|
|||||||
private var progress: CGFloat = 0.0
|
private var progress: CGFloat = 0.0
|
||||||
private var particles: [ContentParticle] = []
|
private var particles: [ContentParticle] = []
|
||||||
|
|
||||||
|
private let animationNode = FireIconNode()
|
||||||
|
|
||||||
private var displayLink: CADisplayLink?
|
private var displayLink: CADisplayLink?
|
||||||
|
|
||||||
init(color: UIColor, beginTime: Double, timeout: Double, icon: UIImage?, sparks: Bool) {
|
init(color: UIColor, beginTime: Double, timeout: Double, icon: UIImage?, sparks: Bool) {
|
||||||
@ -65,7 +68,7 @@ final class RadialStatusSecretTimeoutContentNode: RadialStatusContentNode {
|
|||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
self.isOpaque = false
|
self.isOpaque = false
|
||||||
self.isLayerBacked = true
|
// self.isLayerBacked = true
|
||||||
|
|
||||||
class DisplayLinkProxy: NSObject {
|
class DisplayLinkProxy: NSObject {
|
||||||
weak var target: RadialStatusSecretTimeoutContentNode?
|
weak var target: RadialStatusSecretTimeoutContentNode?
|
||||||
@ -81,6 +84,8 @@ final class RadialStatusSecretTimeoutContentNode: RadialStatusContentNode {
|
|||||||
self.displayLink = CADisplayLink(target: DisplayLinkProxy(target: self), selector: #selector(DisplayLinkProxy.displayLinkEvent))
|
self.displayLink = CADisplayLink(target: DisplayLinkProxy(target: self), selector: #selector(DisplayLinkProxy.displayLinkEvent))
|
||||||
self.displayLink?.isPaused = true
|
self.displayLink?.isPaused = true
|
||||||
self.displayLink?.add(to: RunLoop.main, forMode: .common)
|
self.displayLink?.add(to: RunLoop.main, forMode: .common)
|
||||||
|
|
||||||
|
self.addSubnode(self.animationNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
@ -89,6 +94,8 @@ final class RadialStatusSecretTimeoutContentNode: RadialStatusContentNode {
|
|||||||
|
|
||||||
override func layout() {
|
override func layout() {
|
||||||
super.layout()
|
super.layout()
|
||||||
|
|
||||||
|
self.animationNode.frame = CGRect(x: 6.0, y: 2.0, width: 36.0, height: 36.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func animateOut(to: RadialStatusNodeState, completion: @escaping () -> Void) {
|
override func animateOut(to: RadialStatusNodeState, completion: @escaping () -> Void) {
|
||||||
@ -231,3 +238,10 @@ final class RadialStatusSecretTimeoutContentNode: RadialStatusContentNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final class FireIconNode: ManagedAnimationNode {
|
||||||
|
init() {
|
||||||
|
super.init(size: CGSize(width: 100.0, height: 100.0))
|
||||||
|
|
||||||
|
self.trackTo(item: ManagedAnimationItem(source: .local("anim_autoremove_on"), frames: .range(startFrame: 0, endFrame: 120), duration: 2.0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -9,11 +9,11 @@ public func tagsForStoreMessage(incoming: Bool, attributes: [MessageAttribute],
|
|||||||
var hasUnseenReactions = false
|
var hasUnseenReactions = false
|
||||||
for attribute in attributes {
|
for attribute in attributes {
|
||||||
if let timerAttribute = attribute as? AutoclearTimeoutMessageAttribute {
|
if let timerAttribute = attribute as? AutoclearTimeoutMessageAttribute {
|
||||||
if timerAttribute.timeout > 0 && timerAttribute.timeout <= 60 {
|
if timerAttribute.timeout > 0 && (timerAttribute.timeout <= 60 || timerAttribute.timeout == viewOnceTimeout) {
|
||||||
isSecret = true
|
isSecret = true
|
||||||
}
|
}
|
||||||
} else if let timerAttribute = attribute as? AutoremoveTimeoutMessageAttribute {
|
} else if let timerAttribute = attribute as? AutoremoveTimeoutMessageAttribute {
|
||||||
if timerAttribute.timeout > 0 && timerAttribute.timeout <= 60 {
|
if timerAttribute.timeout > 0 && (timerAttribute.timeout <= 60 || timerAttribute.timeout == viewOnceTimeout) {
|
||||||
isSecret = true
|
isSecret = true
|
||||||
}
|
}
|
||||||
} else if let mentionAttribute = attribute as? ConsumablePersonalMentionMessageAttribute {
|
} else if let mentionAttribute = attribute as? ConsumablePersonalMentionMessageAttribute {
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import Postbox
|
import Postbox
|
||||||
|
|
||||||
|
public let viewOnceTimeout: Int32 = 0x7fffffff
|
||||||
|
|
||||||
public class AutoremoveTimeoutMessageAttribute: MessageAttribute {
|
public class AutoremoveTimeoutMessageAttribute: MessageAttribute {
|
||||||
public let timeout: Int32
|
public let timeout: Int32
|
||||||
public let countdownBeginTime: Int32?
|
public let countdownBeginTime: Int32?
|
||||||
@ -124,7 +126,7 @@ public extension Message {
|
|||||||
guard let timeout = self.minAutoremoveOrClearTimeout else {
|
guard let timeout = self.minAutoremoveOrClearTimeout else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if timeout > 1 * 60 {
|
if timeout > 1 * 60 && timeout != viewOnceTimeout {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -939,7 +939,6 @@ final class MediaEditorScreenComponent: Component {
|
|||||||
self.appliedAudioData = audioData
|
self.appliedAudioData = audioData
|
||||||
|
|
||||||
var timeoutValue: String
|
var timeoutValue: String
|
||||||
let timeoutSelected: Bool
|
|
||||||
switch component.privacy.timeout {
|
switch component.privacy.timeout {
|
||||||
case 21600:
|
case 21600:
|
||||||
timeoutValue = "6"
|
timeoutValue = "6"
|
||||||
@ -952,7 +951,6 @@ final class MediaEditorScreenComponent: Component {
|
|||||||
default:
|
default:
|
||||||
timeoutValue = "24"
|
timeoutValue = "24"
|
||||||
}
|
}
|
||||||
timeoutSelected = false
|
|
||||||
|
|
||||||
var inputPanelAvailableWidth = previewSize.width
|
var inputPanelAvailableWidth = previewSize.width
|
||||||
var inputPanelAvailableHeight = 103.0
|
var inputPanelAvailableHeight = 103.0
|
||||||
@ -1192,7 +1190,7 @@ final class MediaEditorScreenComponent: Component {
|
|||||||
hasRecordedVideoPreview: false,
|
hasRecordedVideoPreview: false,
|
||||||
wasRecordingDismissed: false,
|
wasRecordingDismissed: false,
|
||||||
timeoutValue: timeoutValue,
|
timeoutValue: timeoutValue,
|
||||||
timeoutSelected: timeoutSelected,
|
timeoutSelected: false,
|
||||||
displayGradient: false,
|
displayGradient: false,
|
||||||
bottomInset: 0.0,
|
bottomInset: 0.0,
|
||||||
isFormattingLocked: !state.isPremium,
|
isFormattingLocked: !state.isPremium,
|
||||||
@ -3794,6 +3792,12 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
controller.customModalStyleOverlayTransitionFactorUpdated = { [weak self, weak controller] transition in
|
||||||
|
if let self, let controller {
|
||||||
|
let transitionFactor = controller.modalStyleOverlayTransitionFactor
|
||||||
|
self.node.updateModalTransitionFactor(transitionFactor, transition: transition)
|
||||||
|
}
|
||||||
|
}
|
||||||
controller.dismissed = {
|
controller.dismissed = {
|
||||||
self.node.mediaEditor?.play()
|
self.node.mediaEditor?.play()
|
||||||
}
|
}
|
||||||
@ -3845,6 +3849,12 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
|||||||
editCategory: { _, _, _ in },
|
editCategory: { _, _, _ in },
|
||||||
editBlockedPeers: { _, _, _ in }
|
editBlockedPeers: { _, _, _ in }
|
||||||
)
|
)
|
||||||
|
controller.customModalStyleOverlayTransitionFactorUpdated = { [weak self, weak controller] transition in
|
||||||
|
if let self, let controller {
|
||||||
|
let transitionFactor = controller.modalStyleOverlayTransitionFactor
|
||||||
|
self.node.updateModalTransitionFactor(transitionFactor, transition: transition)
|
||||||
|
}
|
||||||
|
}
|
||||||
controller.dismissed = {
|
controller.dismissed = {
|
||||||
self.node.mediaEditor?.play()
|
self.node.mediaEditor?.play()
|
||||||
}
|
}
|
||||||
|
@ -581,6 +581,7 @@ final class VideoScrubberComponent: Component {
|
|||||||
audioTransition.setFrame(view: view, frame: CGRect(origin: CGPoint(x: 0.0, y: self.isAudioSelected || component.audioOnly ? 0.0 : 6.0), size: audioWaveformSize))
|
audioTransition.setFrame(view: view, frame: CGRect(origin: CGPoint(x: 0.0, y: self.isAudioSelected || component.audioOnly ? 0.0 : 6.0), size: audioWaveformSize))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.cursorView.isHidden = component.audioOnly
|
||||||
|
|
||||||
let bounds = CGRect(origin: .zero, size: scrubberSize)
|
let bounds = CGRect(origin: .zero, size: scrubberSize)
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ final class ShareWithPeersScreenComponent: Component {
|
|||||||
self.itemHeight = itemHeight
|
self.itemHeight = itemHeight
|
||||||
self.itemCount = itemCount
|
self.itemCount = itemCount
|
||||||
|
|
||||||
self.totalHeight = insets.top + itemHeight * CGFloat(itemCount)
|
self.totalHeight = insets.top + itemHeight * CGFloat(itemCount) + insets.bottom
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -818,8 +818,16 @@ final class ShareWithPeersScreenComponent: Component {
|
|||||||
var topOffsetFraction = topOffset / topOffsetDistance
|
var topOffsetFraction = topOffset / topOffsetDistance
|
||||||
topOffsetFraction = max(0.0, min(1.0, topOffsetFraction))
|
topOffsetFraction = max(0.0, min(1.0, topOffsetFraction))
|
||||||
|
|
||||||
//let transitionFactor: CGFloat = 1.0 - topOffsetFraction
|
let transitionFactor: CGFloat = 1.0 - topOffsetFraction
|
||||||
//controller.updateModalStyleOverlayTransitionFactor(transitionFactor, transition: transition.containedViewLayoutTransition)
|
if let controller = environment.controller() {
|
||||||
|
Queue.mainQueue().justDispatch {
|
||||||
|
var transition = transition
|
||||||
|
if controller.modalStyleOverlayTransitionFactor.isZero && transitionFactor > 0.0, transition.animation.isImmediate {
|
||||||
|
transition = .spring(duration: 0.4)
|
||||||
|
}
|
||||||
|
controller.updateModalStyleOverlayTransitionFactor(transitionFactor, transition: transition.containedViewLayoutTransition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var visibleBounds = self.scrollView.bounds
|
var visibleBounds = self.scrollView.bounds
|
||||||
visibleBounds.origin.y -= itemLayout.topInset
|
visibleBounds.origin.y -= itemLayout.topInset
|
||||||
@ -907,7 +915,7 @@ final class ShareWithPeersScreenComponent: Component {
|
|||||||
|
|
||||||
let sectionTitle: String
|
let sectionTitle: String
|
||||||
if section.id == 0, case .stories = component.stateContext.subject {
|
if section.id == 0, case .stories = component.stateContext.subject {
|
||||||
sectionTitle = "POST STORY AS"
|
sectionTitle = environment.strings.Story_Privacy_PostStoryAsHeader
|
||||||
} else if section.id == 2 {
|
} else if section.id == 2 {
|
||||||
sectionTitle = environment.strings.Story_Privacy_WhoCanViewHeader
|
sectionTitle = environment.strings.Story_Privacy_WhoCanViewHeader
|
||||||
} else if section.id == 1 {
|
} else if section.id == 1 {
|
||||||
@ -1362,11 +1370,16 @@ final class ShareWithPeersScreenComponent: Component {
|
|||||||
self.visibleItems[itemId] = visibleItem
|
self.visibleItems[itemId] = visibleItem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var title = item.title
|
||||||
|
if item.id == .pin && !hasCategories {
|
||||||
|
title = environment.strings.Story_Privacy_KeepOnChannelPage
|
||||||
|
}
|
||||||
|
|
||||||
let _ = visibleItem.update(
|
let _ = visibleItem.update(
|
||||||
transition: itemTransition,
|
transition: itemTransition,
|
||||||
component: AnyComponent(OptionListItemComponent(
|
component: AnyComponent(OptionListItemComponent(
|
||||||
theme: environment.theme,
|
theme: environment.theme,
|
||||||
title: item.title,
|
title: title,
|
||||||
hasNext: i != component.optionItems.count - 1,
|
hasNext: i != component.optionItems.count - 1,
|
||||||
selected: self.selectedOptions.contains(item.id),
|
selected: self.selectedOptions.contains(item.id),
|
||||||
selectionChanged: { [weak self] selected in
|
selectionChanged: { [weak self] selected in
|
||||||
@ -1414,7 +1427,7 @@ final class ShareWithPeersScreenComponent: Component {
|
|||||||
var footerText = environment.strings.Story_Privacy_KeepOnMyPageInfo(footerValue).string
|
var footerText = environment.strings.Story_Privacy_KeepOnMyPageInfo(footerValue).string
|
||||||
|
|
||||||
if self.sendAsPeerId?.isGroupOrChannel == true {
|
if self.sendAsPeerId?.isGroupOrChannel == true {
|
||||||
footerText = "Keep this story on channel profile even after it expires in 24 hours."
|
footerText = environment.strings.Story_Privacy_KeepOnChannelPageInfo(footerValue).string
|
||||||
}
|
}
|
||||||
|
|
||||||
let footerSize = sectionFooter.update(
|
let footerSize = sectionFooter.update(
|
||||||
@ -1508,6 +1521,9 @@ final class ShareWithPeersScreenComponent: Component {
|
|||||||
for id in removeSectionBackgroundIds {
|
for id in removeSectionBackgroundIds {
|
||||||
self.visibleSectionBackgrounds.removeValue(forKey: id)
|
self.visibleSectionBackgrounds.removeValue(forKey: id)
|
||||||
}
|
}
|
||||||
|
for id in removeSectionFooterIds {
|
||||||
|
self.visibleSectionFooters.removeValue(forKey: id)
|
||||||
|
}
|
||||||
|
|
||||||
let fadeTransition = Transition.easeInOut(duration: 0.25)
|
let fadeTransition = Transition.easeInOut(duration: 0.25)
|
||||||
if let searchStateContext = self.searchStateContext, case let .search(query, _) = searchStateContext.subject, let value = searchStateContext.stateValue, value.peers.isEmpty {
|
if let searchStateContext = self.searchStateContext, case let .search(query, _) = searchStateContext.subject, let value = searchStateContext.stateValue, value.peers.isEmpty {
|
||||||
@ -1932,11 +1948,16 @@ final class ShareWithPeersScreenComponent: Component {
|
|||||||
)
|
)
|
||||||
|
|
||||||
var hasCategories = false
|
var hasCategories = false
|
||||||
|
var hasChannels = false
|
||||||
if case .stories = component.stateContext.subject {
|
if case .stories = component.stateContext.subject {
|
||||||
if let peerId = self.sendAsPeerId, peerId.isGroupOrChannel {
|
if let peerId = self.sendAsPeerId, peerId.isGroupOrChannel {
|
||||||
} else {
|
} else {
|
||||||
hasCategories = true
|
hasCategories = true
|
||||||
}
|
}
|
||||||
|
let sendAsPeersCount = component.stateContext.stateValue?.sendAsPeers.count ?? 1
|
||||||
|
if sendAsPeersCount > 1 {
|
||||||
|
hasChannels = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var footersTotalHeight: CGFloat = 0.0
|
var footersTotalHeight: CGFloat = 0.0
|
||||||
@ -2016,16 +2037,15 @@ final class ShareWithPeersScreenComponent: Component {
|
|||||||
if case let .peers(peers, _) = component.stateContext.subject {
|
if case let .peers(peers, _) = component.stateContext.subject {
|
||||||
sections.append(ItemLayout.Section(
|
sections.append(ItemLayout.Section(
|
||||||
id: 0,
|
id: 0,
|
||||||
insets: UIEdgeInsets(top: 12.0, left: 0.0, bottom: 24.0, right: 0.0),
|
insets: UIEdgeInsets(top: 12.0, left: 0.0, bottom: 0.0, right: 0.0),
|
||||||
itemHeight: peerItemSize.height,
|
itemHeight: peerItemSize.height,
|
||||||
itemCount: peers.count
|
itemCount: peers.count
|
||||||
))
|
))
|
||||||
} else if case let .stories(editing) = component.stateContext.subject {
|
} else if case let .stories(editing) = component.stateContext.subject {
|
||||||
let sendAsPeersCount = component.stateContext.stateValue?.sendAsPeers.count ?? 1
|
if !editing && hasChannels {
|
||||||
if !editing && sendAsPeersCount > 1 {
|
|
||||||
sections.append(ItemLayout.Section(
|
sections.append(ItemLayout.Section(
|
||||||
id: 0,
|
id: 0,
|
||||||
insets: UIEdgeInsets(top: 28.0, left: 0.0, bottom: 24.0, right: 0.0),
|
insets: UIEdgeInsets(top: 28.0, left: 0.0, bottom: 0.0, right: 0.0),
|
||||||
itemHeight: peerItemSize.height,
|
itemHeight: peerItemSize.height,
|
||||||
itemCount: 1
|
itemCount: 1
|
||||||
))
|
))
|
||||||
@ -2040,7 +2060,7 @@ final class ShareWithPeersScreenComponent: Component {
|
|||||||
}
|
}
|
||||||
sections.append(ItemLayout.Section(
|
sections.append(ItemLayout.Section(
|
||||||
id: 3,
|
id: 3,
|
||||||
insets: UIEdgeInsets(top: 28.0, left: 0.0, bottom: 24.0, right: 0.0),
|
insets: UIEdgeInsets(top: 28.0, left: 0.0, bottom: 0.0, right: 0.0),
|
||||||
itemHeight: optionItemSize.height,
|
itemHeight: optionItemSize.height,
|
||||||
itemCount: component.optionItems.count
|
itemCount: component.optionItems.count
|
||||||
))
|
))
|
||||||
@ -2110,7 +2130,7 @@ final class ShareWithPeersScreenComponent: Component {
|
|||||||
let title: String
|
let title: String
|
||||||
switch component.stateContext.subject {
|
switch component.stateContext.subject {
|
||||||
case .peers:
|
case .peers:
|
||||||
title = "Post Story As"
|
title = environment.strings.Story_Privacy_PostStoryAs
|
||||||
case let .stories(editing):
|
case let .stories(editing):
|
||||||
if editing {
|
if editing {
|
||||||
title = environment.strings.Story_Privacy_EditStory
|
title = environment.strings.Story_Privacy_EditStory
|
||||||
@ -2178,11 +2198,16 @@ final class ShareWithPeersScreenComponent: Component {
|
|||||||
inset = 351.0
|
inset = 351.0
|
||||||
inset += 10.0 + environment.safeInsets.bottom + 50.0 + footersTotalHeight
|
inset += 10.0 + environment.safeInsets.bottom + 50.0 + footersTotalHeight
|
||||||
} else {
|
} else {
|
||||||
if hasCategories {
|
if !hasCategories {
|
||||||
inset = 1000.0
|
|
||||||
} else {
|
|
||||||
inset = 314.0
|
inset = 314.0
|
||||||
inset += 10.0 + environment.safeInsets.bottom + 50.0 + footersTotalHeight
|
inset += 10.0 + environment.safeInsets.bottom + 50.0 + footersTotalHeight
|
||||||
|
} else {
|
||||||
|
if hasChannels {
|
||||||
|
inset = 1000.0
|
||||||
|
} else {
|
||||||
|
inset = 464.0
|
||||||
|
inset += 10.0 + environment.safeInsets.bottom + 50.0 + footersTotalHeight
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if case .peers = component.stateContext.subject {
|
} else if case .peers = component.stateContext.subject {
|
||||||
@ -2201,7 +2226,7 @@ final class ShareWithPeersScreenComponent: Component {
|
|||||||
var bottomPanelHeight: CGFloat = 0.0
|
var bottomPanelHeight: CGFloat = 0.0
|
||||||
var bottomPanelInset: CGFloat = 0.0
|
var bottomPanelInset: CGFloat = 0.0
|
||||||
if case .peers = component.stateContext.subject {
|
if case .peers = component.stateContext.subject {
|
||||||
|
bottomPanelInset = environment.safeInsets.bottom
|
||||||
} else {
|
} else {
|
||||||
let badge: Int
|
let badge: Int
|
||||||
if case .stories = component.stateContext.subject {
|
if case .stories = component.stateContext.subject {
|
||||||
@ -2367,7 +2392,7 @@ final class ShareWithPeersScreenComponent: Component {
|
|||||||
}
|
}
|
||||||
return Array(filteredMentions)
|
return Array(filteredMentions)
|
||||||
}
|
}
|
||||||
|> deliverOnMainQueue).start(next: { mentions in
|
|> deliverOnMainQueue).start(next: { mentions in
|
||||||
if mentions.isEmpty {
|
if mentions.isEmpty {
|
||||||
proceed()
|
proceed()
|
||||||
} else {
|
} else {
|
||||||
@ -2377,7 +2402,7 @@ final class ShareWithPeersScreenComponent: Component {
|
|||||||
}
|
}
|
||||||
} else if case .contacts = base {
|
} else if case .contacts = base {
|
||||||
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Contacts.List(includePresences: false))
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Contacts.List(includePresences: false))
|
||||||
|> map { contacts -> [String] in
|
|> map { contacts -> [String] in
|
||||||
var filteredMentions = Set(component.mentions)
|
var filteredMentions = Set(component.mentions)
|
||||||
let peers = contacts.peers
|
let peers = contacts.peers
|
||||||
for peer in peers {
|
for peer in peers {
|
||||||
@ -2390,7 +2415,7 @@ final class ShareWithPeersScreenComponent: Component {
|
|||||||
}
|
}
|
||||||
return Array(filteredMentions)
|
return Array(filteredMentions)
|
||||||
}
|
}
|
||||||
|> deliverOnMainQueue).start(next: { mentions in
|
|> deliverOnMainQueue).start(next: { mentions in
|
||||||
if mentions.isEmpty {
|
if mentions.isEmpty {
|
||||||
proceed()
|
proceed()
|
||||||
} else {
|
} else {
|
||||||
@ -2399,7 +2424,7 @@ final class ShareWithPeersScreenComponent: Component {
|
|||||||
})
|
})
|
||||||
} else if case .closeFriends = base {
|
} else if case .closeFriends = base {
|
||||||
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Contacts.List(includePresences: false))
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Contacts.List(includePresences: false))
|
||||||
|> map { contacts -> [String] in
|
|> map { contacts -> [String] in
|
||||||
var filteredMentions = Set(component.mentions)
|
var filteredMentions = Set(component.mentions)
|
||||||
let peers = contacts.peers
|
let peers = contacts.peers
|
||||||
for peer in peers {
|
for peer in peers {
|
||||||
@ -2409,7 +2434,7 @@ final class ShareWithPeersScreenComponent: Component {
|
|||||||
}
|
}
|
||||||
return Array(filteredMentions)
|
return Array(filteredMentions)
|
||||||
}
|
}
|
||||||
|> deliverOnMainQueue).start(next: { mentions in
|
|> deliverOnMainQueue).start(next: { mentions in
|
||||||
if mentions.isEmpty {
|
if mentions.isEmpty {
|
||||||
proceed()
|
proceed()
|
||||||
} else {
|
} else {
|
||||||
@ -2452,7 +2477,7 @@ final class ShareWithPeersScreenComponent: Component {
|
|||||||
let previousItemLayout = self.itemLayout
|
let previousItemLayout = self.itemLayout
|
||||||
self.itemLayout = itemLayout
|
self.itemLayout = itemLayout
|
||||||
|
|
||||||
contentTransition.setFrame(view: self.itemContainerView, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: containerWidth, height: itemLayout.contentHeight)))
|
contentTransition.setFrame(view: self.itemContainerView, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: containerWidth, height: itemLayout.contentHeight + footersTotalHeight)))
|
||||||
|
|
||||||
let scrollContentHeight = max(topInset + itemLayout.contentHeight + containerInset, availableSize.height - containerInset)
|
let scrollContentHeight = max(topInset + itemLayout.contentHeight + containerInset, availableSize.height - containerInset)
|
||||||
|
|
||||||
|
12
submodules/TelegramUI/Images.xcassets/Chat/Message/SecretMediaOnce.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Chat/Message/SecretMediaOnce.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "miniplayonce.pdf",
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
107
submodules/TelegramUI/Images.xcassets/Chat/Message/SecretMediaOnce.imageset/miniplayonce.pdf
vendored
Normal file
107
submodules/TelegramUI/Images.xcassets/Chat/Message/SecretMediaOnce.imageset/miniplayonce.pdf
vendored
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
%PDF-1.7
|
||||||
|
|
||||||
|
1 0 obj
|
||||||
|
<< >>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
2 0 obj
|
||||||
|
<< /Length 3 0 R >>
|
||||||
|
stream
|
||||||
|
/DeviceRGB CS
|
||||||
|
/DeviceRGB cs
|
||||||
|
q
|
||||||
|
1.000000 0.000000 -0.000000 1.000000 2.000000 1.669922 cm
|
||||||
|
0.000000 0.000000 0.000000 scn
|
||||||
|
4.000000 8.665078 m
|
||||||
|
4.367270 8.665078 4.665000 8.962809 4.665000 9.330078 c
|
||||||
|
4.665000 9.697348 4.367270 9.995078 4.000000 9.995078 c
|
||||||
|
4.000000 8.665078 l
|
||||||
|
h
|
||||||
|
8.665000 5.330078 m
|
||||||
|
8.665000 5.697348 8.367270 5.995078 8.000000 5.995078 c
|
||||||
|
7.632730 5.995078 7.335000 5.697348 7.335000 5.330078 c
|
||||||
|
8.665000 5.330078 l
|
||||||
|
h
|
||||||
|
4.000000 9.995078 m
|
||||||
|
1.423591 9.995078 -0.665000 7.906487 -0.665000 5.330078 c
|
||||||
|
0.665000 5.330078 l
|
||||||
|
0.665000 7.171948 2.158130 8.665078 4.000000 8.665078 c
|
||||||
|
4.000000 9.995078 l
|
||||||
|
h
|
||||||
|
-0.665000 5.330078 m
|
||||||
|
-0.665000 2.753670 1.423591 0.665078 4.000000 0.665078 c
|
||||||
|
4.000000 1.995078 l
|
||||||
|
2.158130 1.995078 0.665000 3.488208 0.665000 5.330078 c
|
||||||
|
-0.665000 5.330078 l
|
||||||
|
h
|
||||||
|
4.000000 0.665078 m
|
||||||
|
6.576408 0.665078 8.665000 2.753670 8.665000 5.330078 c
|
||||||
|
7.335000 5.330078 l
|
||||||
|
7.335000 3.488208 5.841870 1.995078 4.000000 1.995078 c
|
||||||
|
4.000000 0.665078 l
|
||||||
|
h
|
||||||
|
f
|
||||||
|
n
|
||||||
|
Q
|
||||||
|
q
|
||||||
|
1.000000 0.000000 -0.000000 1.000000 6.000000 8.705566 cm
|
||||||
|
0.000000 0.000000 0.000000 scn
|
||||||
|
0.800000 4.694434 m
|
||||||
|
0.470382 4.941647 0.000000 4.706456 0.000000 4.294434 c
|
||||||
|
0.000000 0.294434 l
|
||||||
|
0.000000 -0.117589 0.470382 -0.352780 0.800000 -0.105567 c
|
||||||
|
3.466667 1.894433 l
|
||||||
|
3.733333 2.094434 3.733333 2.494434 3.466667 2.694434 c
|
||||||
|
0.800000 4.694434 l
|
||||||
|
h
|
||||||
|
f*
|
||||||
|
n
|
||||||
|
Q
|
||||||
|
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
|
||||||
|
3 0 obj
|
||||||
|
1311
|
||||||
|
endobj
|
||||||
|
|
||||||
|
4 0 obj
|
||||||
|
<< /Annots []
|
||||||
|
/Type /Page
|
||||||
|
/MediaBox [ 0.000000 0.000000 12.000000 14.000000 ]
|
||||||
|
/Resources 1 0 R
|
||||||
|
/Contents 2 0 R
|
||||||
|
/Parent 5 0 R
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
5 0 obj
|
||||||
|
<< /Kids [ 4 0 R ]
|
||||||
|
/Count 1
|
||||||
|
/Type /Pages
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
6 0 obj
|
||||||
|
<< /Pages 5 0 R
|
||||||
|
/Type /Catalog
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
xref
|
||||||
|
0 7
|
||||||
|
0000000000 65535 f
|
||||||
|
0000000010 00000 n
|
||||||
|
0000000034 00000 n
|
||||||
|
0000001401 00000 n
|
||||||
|
0000001424 00000 n
|
||||||
|
0000001597 00000 n
|
||||||
|
0000001671 00000 n
|
||||||
|
trailer
|
||||||
|
<< /ID [ (some) (id) ]
|
||||||
|
/Root 6 0 R
|
||||||
|
/Size 7
|
||||||
|
>>
|
||||||
|
startxref
|
||||||
|
1730
|
||||||
|
%%EOF
|
12
submodules/TelegramUI/Images.xcassets/Chat/Message/SecretMediaPlay.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Chat/Message/SecretMediaPlay.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "miniplay.pdf",
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
73
submodules/TelegramUI/Images.xcassets/Chat/Message/SecretMediaPlay.imageset/miniplay.pdf
vendored
Normal file
73
submodules/TelegramUI/Images.xcassets/Chat/Message/SecretMediaPlay.imageset/miniplay.pdf
vendored
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
%PDF-1.7
|
||||||
|
|
||||||
|
1 0 obj
|
||||||
|
<< >>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
2 0 obj
|
||||||
|
<< /Length 3 0 R >>
|
||||||
|
stream
|
||||||
|
/DeviceRGB CS
|
||||||
|
/DeviceRGB cs
|
||||||
|
q
|
||||||
|
1.000000 0.000000 -0.000000 1.000000 3.000000 2.780273 cm
|
||||||
|
0.000000 0.000000 0.000000 scn
|
||||||
|
2.332051 -0.225573 m
|
||||||
|
7.127887 2.971651 l
|
||||||
|
8.018486 3.565384 8.018486 4.874069 7.127886 5.467803 c
|
||||||
|
2.332050 8.665027 l
|
||||||
|
1.335218 9.329581 0.000000 8.614994 0.000000 7.416951 c
|
||||||
|
0.000000 1.022502 l
|
||||||
|
0.000000 -0.175541 1.335219 -0.890127 2.332051 -0.225573 c
|
||||||
|
h
|
||||||
|
f
|
||||||
|
n
|
||||||
|
Q
|
||||||
|
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
|
||||||
|
3 0 obj
|
||||||
|
379
|
||||||
|
endobj
|
||||||
|
|
||||||
|
4 0 obj
|
||||||
|
<< /Annots []
|
||||||
|
/Type /Page
|
||||||
|
/MediaBox [ 0.000000 0.000000 12.000000 14.000000 ]
|
||||||
|
/Resources 1 0 R
|
||||||
|
/Contents 2 0 R
|
||||||
|
/Parent 5 0 R
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
5 0 obj
|
||||||
|
<< /Kids [ 4 0 R ]
|
||||||
|
/Count 1
|
||||||
|
/Type /Pages
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
6 0 obj
|
||||||
|
<< /Pages 5 0 R
|
||||||
|
/Type /Catalog
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
xref
|
||||||
|
0 7
|
||||||
|
0000000000 65535 f
|
||||||
|
0000000010 00000 n
|
||||||
|
0000000034 00000 n
|
||||||
|
0000000469 00000 n
|
||||||
|
0000000491 00000 n
|
||||||
|
0000000664 00000 n
|
||||||
|
0000000738 00000 n
|
||||||
|
trailer
|
||||||
|
<< /ID [ (some) (id) ]
|
||||||
|
/Root 6 0 R
|
||||||
|
/Size 7
|
||||||
|
>>
|
||||||
|
startxref
|
||||||
|
797
|
||||||
|
%%EOF
|
@ -542,10 +542,10 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
|
|||||||
switch preparePosition {
|
switch preparePosition {
|
||||||
case .linear(_, .None), .linear(_, .Neighbour(true, _, _)):
|
case .linear(_, .None), .linear(_, .Neighbour(true, _, _)):
|
||||||
if let count = webpageGalleryMediaCount {
|
if let count = webpageGalleryMediaCount {
|
||||||
additionalImageBadgeContent = .text(inset: 0.0, backgroundColor: presentationData.theme.theme.chat.message.mediaDateAndStatusFillColor, foregroundColor: presentationData.theme.theme.chat.message.mediaDateAndStatusTextColor, text: NSAttributedString(string: presentationData.strings.Items_NOfM("1", "\(count)").string))
|
additionalImageBadgeContent = .text(inset: 0.0, backgroundColor: presentationData.theme.theme.chat.message.mediaDateAndStatusFillColor, foregroundColor: presentationData.theme.theme.chat.message.mediaDateAndStatusTextColor, text: NSAttributedString(string: presentationData.strings.Items_NOfM("1", "\(count)").string), iconName: nil)
|
||||||
skipStandardStatus = isImage
|
skipStandardStatus = isImage
|
||||||
} else if let mediaBadge = mediaBadge {
|
} else if let mediaBadge = mediaBadge {
|
||||||
additionalImageBadgeContent = .text(inset: 0.0, backgroundColor: presentationData.theme.theme.chat.message.mediaDateAndStatusFillColor, foregroundColor: presentationData.theme.theme.chat.message.mediaDateAndStatusTextColor, text: NSAttributedString(string: mediaBadge))
|
additionalImageBadgeContent = .text(inset: 0.0, backgroundColor: presentationData.theme.theme.chat.message.mediaDateAndStatusFillColor, foregroundColor: presentationData.theme.theme.chat.message.mediaDateAndStatusTextColor, text: NSAttributedString(string: mediaBadge), iconName: nil)
|
||||||
} else {
|
} else {
|
||||||
skipStandardStatus = isFile
|
skipStandardStatus = isFile
|
||||||
}
|
}
|
||||||
|
@ -860,7 +860,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
|||||||
|
|
||||||
let maxWidth: CGFloat
|
let maxWidth: CGFloat
|
||||||
if isSecretMedia {
|
if isSecretMedia {
|
||||||
maxWidth = 180.0
|
maxWidth = 200.0
|
||||||
} else {
|
} else {
|
||||||
maxWidth = maxDimensions.width
|
maxWidth = maxDimensions.width
|
||||||
}
|
}
|
||||||
@ -898,7 +898,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
|||||||
switch sizeCalculation {
|
switch sizeCalculation {
|
||||||
case .constrained:
|
case .constrained:
|
||||||
if isSecretMedia {
|
if isSecretMedia {
|
||||||
boundingSize = CGSize(width: maxWidth, height: maxWidth)
|
boundingSize = CGSize(width: maxWidth, height: maxWidth / 5.0 * 3.0)
|
||||||
drawingSize = nativeSize.aspectFilled(boundingSize)
|
drawingSize = nativeSize.aspectFilled(boundingSize)
|
||||||
} else {
|
} else {
|
||||||
let fittedSize = nativeSize.fittedToWidthOrSmaller(boundingWidth)
|
let fittedSize = nativeSize.fittedToWidthOrSmaller(boundingWidth)
|
||||||
@ -1764,7 +1764,12 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let radialStatusSize: CGFloat = wideLayout ? 50.0 : 32.0
|
var radialStatusSize: CGFloat
|
||||||
|
if isSecretMedia {
|
||||||
|
radialStatusSize = 48.0
|
||||||
|
} else {
|
||||||
|
radialStatusSize = wideLayout ? 50.0 : 32.0
|
||||||
|
}
|
||||||
if progressRequired {
|
if progressRequired {
|
||||||
if self.statusNode == nil {
|
if self.statusNode == nil {
|
||||||
let statusNode = RadialStatusNode(backgroundNodeColor: theme.chat.message.mediaOverlayControlColors.fillColor)
|
let statusNode = RadialStatusNode(backgroundNodeColor: theme.chat.message.mediaOverlayControlColors.fillColor)
|
||||||
@ -1782,14 +1787,17 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let messageTheme = theme.chat.message
|
||||||
|
|
||||||
var state: RadialStatusNodeState = .none
|
var state: RadialStatusNodeState = .none
|
||||||
|
var backgroundColor = messageTheme.mediaOverlayControlColors.fillColor
|
||||||
var badgeContent: ChatMessageInteractiveMediaBadgeContent?
|
var badgeContent: ChatMessageInteractiveMediaBadgeContent?
|
||||||
var mediaDownloadState: ChatMessageInteractiveMediaDownloadState?
|
var mediaDownloadState: ChatMessageInteractiveMediaDownloadState?
|
||||||
let messageTheme = theme.chat.message
|
|
||||||
if let invoice = invoice {
|
if let invoice = invoice {
|
||||||
if let extendedMedia = invoice.extendedMedia {
|
if let extendedMedia = invoice.extendedMedia {
|
||||||
if case let .preview(_, _, maybeVideoDuration) = extendedMedia, let videoDuration = maybeVideoDuration {
|
if case let .preview(_, _, maybeVideoDuration) = extendedMedia, let videoDuration = maybeVideoDuration {
|
||||||
badgeContent = .text(inset: 0.0, backgroundColor: messageTheme.mediaDateAndStatusFillColor, foregroundColor: messageTheme.mediaDateAndStatusTextColor, text: NSAttributedString(string: stringForDuration(videoDuration, position: nil)))
|
badgeContent = .text(inset: 0.0, backgroundColor: messageTheme.mediaDateAndStatusFillColor, foregroundColor: messageTheme.mediaDateAndStatusTextColor, text: NSAttributedString(string: stringForDuration(videoDuration, position: nil)), iconName: nil)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let string = NSMutableAttributedString()
|
let string = NSMutableAttributedString()
|
||||||
@ -1808,7 +1816,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
|||||||
}
|
}
|
||||||
string.append(NSAttributedString(string: title))
|
string.append(NSAttributedString(string: title))
|
||||||
}
|
}
|
||||||
badgeContent = .text(inset: 0.0, backgroundColor: messageTheme.mediaDateAndStatusFillColor, foregroundColor: messageTheme.mediaDateAndStatusTextColor, text: string)
|
badgeContent = .text(inset: 0.0, backgroundColor: messageTheme.mediaDateAndStatusFillColor, foregroundColor: messageTheme.mediaDateAndStatusTextColor, text: string, iconName: nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var animated = animated
|
var animated = animated
|
||||||
@ -1944,7 +1952,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let progressString = String(format: "%d%%", Int(progress * 100.0))
|
let progressString = String(format: "%d%%", Int(progress * 100.0))
|
||||||
badgeContent = .text(inset: message.flags.contains(.Unsent) ? 0.0 : 12.0, backgroundColor: messageTheme.mediaDateAndStatusFillColor, foregroundColor: messageTheme.mediaDateAndStatusTextColor, text: NSAttributedString(string: progressString))
|
badgeContent = .text(inset: message.flags.contains(.Unsent) ? 0.0 : 12.0, backgroundColor: messageTheme.mediaDateAndStatusFillColor, foregroundColor: messageTheme.mediaDateAndStatusTextColor, text: NSAttributedString(string: progressString), iconName: nil)
|
||||||
mediaDownloadState = automaticPlayback ? .none : .compactFetching(progress: 0.0)
|
mediaDownloadState = automaticPlayback ? .none : .compactFetching(progress: 0.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1980,8 +1988,10 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
|||||||
}
|
}
|
||||||
if isSecretMedia, let (maybeBeginTime, timeout) = secretBeginTimeAndTimeout, let beginTime = maybeBeginTime {
|
if isSecretMedia, let (maybeBeginTime, timeout) = secretBeginTimeAndTimeout, let beginTime = maybeBeginTime {
|
||||||
state = .secretTimeout(color: messageTheme.mediaOverlayControlColors.foregroundColor, icon: secretProgressIcon, beginTime: beginTime, timeout: timeout, sparks: true)
|
state = .secretTimeout(color: messageTheme.mediaOverlayControlColors.foregroundColor, icon: secretProgressIcon, beginTime: beginTime, timeout: timeout, sparks: true)
|
||||||
} else if isSecretMedia, let secretProgressIcon = secretProgressIcon {
|
backgroundColor = messageTheme.mediaDateAndStatusFillColor
|
||||||
state = .customIcon(secretProgressIcon)
|
} else if isSecretMedia, let _ = secretProgressIcon {
|
||||||
|
state = .staticTimeout
|
||||||
|
backgroundColor = messageTheme.mediaDateAndStatusFillColor
|
||||||
} else if let file = media as? TelegramMediaFile, !file.isVideoSticker {
|
} else if let file = media as? TelegramMediaFile, !file.isVideoSticker {
|
||||||
let isInlinePlayableVideo = file.isVideo && !isSecretMedia && (self.automaticPlayback ?? false)
|
let isInlinePlayableVideo = file.isVideo && !isSecretMedia && (self.automaticPlayback ?? false)
|
||||||
if (!isInlinePlayableVideo || isStory) && file.isVideo {
|
if (!isInlinePlayableVideo || isStory) && file.isVideo {
|
||||||
@ -2017,11 +2027,11 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
|||||||
} else {
|
} else {
|
||||||
if isMediaStreamable(message: message, media: file) {
|
if isMediaStreamable(message: message, media: file) {
|
||||||
state = automaticPlayback ? .none : .play(messageTheme.mediaOverlayControlColors.foregroundColor)
|
state = automaticPlayback ? .none : .play(messageTheme.mediaOverlayControlColors.foregroundColor)
|
||||||
badgeContent = .text(inset: 12.0, backgroundColor: messageTheme.mediaDateAndStatusFillColor, foregroundColor: messageTheme.mediaDateAndStatusTextColor, text: NSAttributedString(string: durationString))
|
badgeContent = .text(inset: 12.0, backgroundColor: messageTheme.mediaDateAndStatusFillColor, foregroundColor: messageTheme.mediaDateAndStatusTextColor, text: NSAttributedString(string: durationString), iconName: nil)
|
||||||
mediaDownloadState = .compactRemote
|
mediaDownloadState = .compactRemote
|
||||||
} else {
|
} else {
|
||||||
state = automaticPlayback ? .none : state
|
state = automaticPlayback ? .none : state
|
||||||
badgeContent = .text(inset: 0.0, backgroundColor: messageTheme.mediaDateAndStatusFillColor, foregroundColor: messageTheme.mediaDateAndStatusTextColor, text: NSAttributedString(string: durationString))
|
badgeContent = .text(inset: 0.0, backgroundColor: messageTheme.mediaDateAndStatusFillColor, foregroundColor: messageTheme.mediaDateAndStatusTextColor, text: NSAttributedString(string: durationString), iconName: nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2031,16 +2041,32 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if isSecretMedia, let (maybeBeginTime, timeout) = secretBeginTimeAndTimeout {
|
if isSecretMedia {
|
||||||
let remainingTime: Int32
|
let remainingTime: Int32?
|
||||||
if let beginTime = maybeBeginTime {
|
if let (maybeBeginTime, timeout) = secretBeginTimeAndTimeout {
|
||||||
let elapsedTime = CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970 - beginTime
|
if let beginTime = maybeBeginTime {
|
||||||
remainingTime = Int32(max(0.0, timeout - elapsedTime))
|
let elapsedTime = CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970 - beginTime
|
||||||
|
remainingTime = Int32(max(0.0, timeout - elapsedTime))
|
||||||
|
} else {
|
||||||
|
remainingTime = Int32(timeout)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
remainingTime = Int32(timeout)
|
if let attribute = message.autoclearAttribute {
|
||||||
|
remainingTime = attribute.timeout
|
||||||
|
} else if let attribute = message.autoremoveAttribute {
|
||||||
|
remainingTime = attribute.timeout
|
||||||
|
} else {
|
||||||
|
remainingTime = nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
badgeContent = .text(inset: 0.0, backgroundColor: messageTheme.mediaDateAndStatusFillColor, foregroundColor: messageTheme.mediaDateAndStatusTextColor, text: NSAttributedString(string: strings.MessageTimer_ShortSeconds(Int32(remainingTime))))
|
if let remainingTime {
|
||||||
|
if remainingTime == viewOnceTimeout {
|
||||||
|
badgeContent = .text(inset: 10.0, backgroundColor: messageTheme.mediaDateAndStatusFillColor, foregroundColor: messageTheme.mediaDateAndStatusTextColor, text: NSAttributedString(string: "1"), iconName: "Chat/Message/SecretMediaOnce")
|
||||||
|
} else {
|
||||||
|
badgeContent = .text(inset: 10.0, backgroundColor: messageTheme.mediaDateAndStatusFillColor, foregroundColor: messageTheme.mediaDateAndStatusTextColor, text: NSAttributedString(string: strings.MessageTimer_ShortSeconds(Int32(remainingTime))), iconName: "Chat/Message/SecretMediaPlay")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let statusNode = self.statusNode {
|
if let statusNode = self.statusNode {
|
||||||
@ -2062,6 +2088,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
|||||||
statusNode?.removeFromSupernode()
|
statusNode?.removeFromSupernode()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
statusNode.backgroundNodeColor = backgroundColor
|
||||||
}
|
}
|
||||||
if let badgeContent = badgeContent {
|
if let badgeContent = badgeContent {
|
||||||
if self.badgeNode == nil {
|
if self.badgeNode == nil {
|
||||||
@ -2100,6 +2127,8 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
|||||||
displaySpoiler = true
|
displaySpoiler = true
|
||||||
} else if message.attributes.contains(where: { $0 is MediaSpoilerMessageAttribute }) {
|
} else if message.attributes.contains(where: { $0 is MediaSpoilerMessageAttribute }) {
|
||||||
displaySpoiler = true
|
displaySpoiler = true
|
||||||
|
} else if isSecretMedia {
|
||||||
|
displaySpoiler = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if displaySpoiler {
|
if displaySpoiler {
|
||||||
@ -2115,11 +2144,13 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
|||||||
self.extendedMediaOverlayNode?.frame = self.imageNode.frame
|
self.extendedMediaOverlayNode?.frame = self.imageNode.frame
|
||||||
|
|
||||||
var tappable = false
|
var tappable = false
|
||||||
switch state {
|
if !isSecretMedia {
|
||||||
case .play, .pause, .download, .none:
|
switch state {
|
||||||
tappable = true
|
case .play, .pause, .download, .none:
|
||||||
default:
|
tappable = true
|
||||||
break
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.extendedMediaOverlayNode?.isUserInteractionEnabled = tappable
|
self.extendedMediaOverlayNode?.isUserInteractionEnabled = tappable
|
||||||
|
@ -281,16 +281,16 @@ final class GridMessageItemNode: GridItemNode {
|
|||||||
switch status {
|
switch status {
|
||||||
case let .Fetching(_, progress):
|
case let .Fetching(_, progress):
|
||||||
let progressString = String(format: "%d%%", Int(progress * 100.0))
|
let progressString = String(format: "%d%%", Int(progress * 100.0))
|
||||||
badgeContent = .text(inset: 12.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: progressString))
|
badgeContent = .text(inset: 12.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: progressString), iconName: nil)
|
||||||
mediaDownloadState = .compactFetching(progress: 0.0)
|
mediaDownloadState = .compactFetching(progress: 0.0)
|
||||||
case .Local:
|
case .Local:
|
||||||
badgeContent = .text(inset: 0.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: durationString))
|
badgeContent = .text(inset: 0.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: durationString), iconName: nil)
|
||||||
case .Remote, .Paused:
|
case .Remote, .Paused:
|
||||||
badgeContent = .text(inset: 12.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: durationString))
|
badgeContent = .text(inset: 12.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: durationString), iconName: nil)
|
||||||
mediaDownloadState = .compactRemote
|
mediaDownloadState = .compactRemote
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
badgeContent = .text(inset: 0.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: durationString))
|
badgeContent = .text(inset: 0.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: durationString), iconName: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
strongSelf.mediaBadgeNode.update(theme: item.theme, content: badgeContent, mediaDownloadState: mediaDownloadState, alignment: .right, animated: false, badgeAnimated: false)
|
strongSelf.mediaBadgeNode.update(theme: item.theme, content: badgeContent, mediaDownloadState: mediaDownloadState, alignment: .right, animated: false, badgeAnimated: false)
|
||||||
|
@ -385,16 +385,16 @@ private final class VisualMediaItemNode: ASDisplayNode {
|
|||||||
switch status {
|
switch status {
|
||||||
case let .Fetching(_, progress):
|
case let .Fetching(_, progress):
|
||||||
let progressString = String(format: "%d%%", Int(progress * 100.0))
|
let progressString = String(format: "%d%%", Int(progress * 100.0))
|
||||||
badgeContent = .text(inset: 12.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: progressString))
|
badgeContent = .text(inset: 12.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: progressString), iconName: nil)
|
||||||
mediaDownloadState = .compactFetching(progress: 0.0)
|
mediaDownloadState = .compactFetching(progress: 0.0)
|
||||||
case .Local:
|
case .Local:
|
||||||
badgeContent = .text(inset: 0.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: durationString))
|
badgeContent = .text(inset: 0.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: durationString), iconName: nil)
|
||||||
case .Remote, .Paused:
|
case .Remote, .Paused:
|
||||||
badgeContent = .text(inset: 12.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: durationString))
|
badgeContent = .text(inset: 12.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: durationString), iconName: nil)
|
||||||
mediaDownloadState = .compactRemote
|
mediaDownloadState = .compactRemote
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
badgeContent = .text(inset: 0.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: durationString))
|
badgeContent = .text(inset: 0.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: durationString), iconName: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
strongSelf.mediaBadgeNode.update(theme: nil, content: badgeContent, mediaDownloadState: mediaDownloadState, alignment: .right, animated: false, badgeAnimated: false)
|
strongSelf.mediaBadgeNode.update(theme: nil, content: badgeContent, mediaDownloadState: mediaDownloadState, alignment: .right, animated: false, badgeAnimated: false)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user