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";
|
||||
|
||||
"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 {
|
||||
switch status {
|
||||
case let .Fetching(_, progress):
|
||||
let progressString = String(format: "%d%%", Int(progress * 100.0))
|
||||
badgeContent = .text(inset: 12.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: progressString))
|
||||
mediaDownloadState = .compactFetching(progress: 0.0)
|
||||
case .Local:
|
||||
badgeContent = .text(inset: 0.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: durationString))
|
||||
case .Remote, .Paused:
|
||||
badgeContent = .text(inset: 12.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: durationString))
|
||||
mediaDownloadState = .compactRemote
|
||||
case let .Fetching(_, progress):
|
||||
let progressString = String(format: "%d%%", Int(progress * 100.0))
|
||||
badgeContent = .text(inset: 12.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: progressString), iconName: nil)
|
||||
mediaDownloadState = .compactFetching(progress: 0.0)
|
||||
case .Local:
|
||||
badgeContent = .text(inset: 0.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: durationString), iconName: nil)
|
||||
case .Remote, .Paused:
|
||||
badgeContent = .text(inset: 12.0, backgroundColor: mediaBadgeBackgroundColor, foregroundColor: mediaBadgeTextColor, text: NSAttributedString(string: durationString), iconName: nil)
|
||||
mediaDownloadState = .compactRemote
|
||||
}
|
||||
} 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)
|
||||
|
@ -18,13 +18,13 @@ public enum ChatMessageInteractiveMediaDownloadState: 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)
|
||||
|
||||
public static func ==(lhs: ChatMessageInteractiveMediaBadgeContent, rhs: ChatMessageInteractiveMediaBadgeContent) -> Bool {
|
||||
switch lhs {
|
||||
case let .text(lhsInset, lhsBackgroundColor, lhsForegroundColor, lhsText):
|
||||
if case let .text(rhsInset, rhsBackgroundColor, rhsForegroundColor, rhsText) = rhs, lhsInset.isEqual(to: rhsInset), lhsBackgroundColor.isEqual(rhsBackgroundColor), lhsForegroundColor.isEqual(rhsForegroundColor), lhsText.isEqual(to: rhsText) {
|
||||
case let .text(lhsInset, lhsBackgroundColor, lhsForegroundColor, lhsText, lhsIconName):
|
||||
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
|
||||
} else {
|
||||
return false
|
||||
@ -48,6 +48,7 @@ public final class ChatMessageInteractiveMediaBadge: ASDisplayNode {
|
||||
private var previousContentSize: CGSize?
|
||||
private var backgroundNodeColor: UIColor?
|
||||
private var foregroundColor: UIColor?
|
||||
private var iconName: String?
|
||||
|
||||
private let backgroundNode: ASImageNode
|
||||
private let durationNode: ASTextNode
|
||||
@ -107,14 +108,18 @@ public final class ChatMessageInteractiveMediaBadge: ASDisplayNode {
|
||||
}
|
||||
|
||||
switch content {
|
||||
case let .text(inset, backgroundColor, foregroundColor, text):
|
||||
case let .text(inset, backgroundColor, foregroundColor, text, iconName):
|
||||
transition = .immediate
|
||||
|
||||
if self.backgroundNodeColor != backgroundColor {
|
||||
self.backgroundNodeColor = 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
|
||||
if let _ = attributes[ChatTextInputAttributes.bold] {
|
||||
convertedText.addAttribute(.font, value: boldFont, range: range)
|
||||
@ -122,12 +127,33 @@ public final class ChatMessageInteractiveMediaBadge: ASDisplayNode {
|
||||
}
|
||||
self.durationNode.attributedText = convertedText
|
||||
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)
|
||||
|
||||
if let iconNode = self.iconNode {
|
||||
transition.updateTransformScale(node: iconNode, scale: 0.001)
|
||||
transition.updateAlpha(node: iconNode, alpha: 0.0)
|
||||
if let iconName {
|
||||
let iconNode: ASImageNode
|
||||
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):
|
||||
if self.backgroundNodeColor != backgroundColor {
|
||||
@ -209,7 +235,7 @@ public final class ChatMessageInteractiveMediaBadge: ASDisplayNode {
|
||||
|
||||
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))
|
||||
|
||||
|
||||
if muted {
|
||||
transition.updateAlpha(node: iconNode, alpha: 1.0)
|
||||
transition.updateTransformScale(node: iconNode, scale: 1.0)
|
||||
|
@ -14,6 +14,7 @@ swift_library(
|
||||
"//submodules/AsyncDisplayKit:AsyncDisplayKit",
|
||||
"//submodules/LegacyComponents:LegacyComponents",
|
||||
"//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit",
|
||||
"//submodules/ManagedAnimationNode:ManagedAnimationNode"
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
@ -5,6 +5,7 @@ import AsyncDisplayKit
|
||||
|
||||
enum RadialStatusIcon {
|
||||
case custom(UIImage)
|
||||
case timeout
|
||||
case play(UIColor)
|
||||
case pause(UIColor)
|
||||
}
|
||||
@ -22,14 +23,28 @@ private final class RadialStatusIconContentNodeParameters: NSObject {
|
||||
final class RadialStatusIconContentNode: RadialStatusContentNode {
|
||||
private let icon: RadialStatusIcon
|
||||
|
||||
private var animationNode: FireIconNode?
|
||||
|
||||
init(icon: RadialStatusIcon, synchronous: Bool) {
|
||||
self.icon = icon
|
||||
|
||||
super.init()
|
||||
|
||||
self.displaysAsynchronously = !synchronous
|
||||
self.isLayerBacked = true
|
||||
// self.isLayerBacked = true
|
||||
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? {
|
||||
@ -48,6 +63,8 @@ final class RadialStatusIconContentNode: RadialStatusContentNode {
|
||||
if let parameters = parameters as? RadialStatusIconContentNodeParameters {
|
||||
let diameter = min(bounds.size.width, bounds.size.height)
|
||||
switch parameters.icon {
|
||||
case .timeout:
|
||||
break
|
||||
case let .play(color):
|
||||
context.setFillColor(color.cgColor)
|
||||
|
||||
|
@ -12,6 +12,7 @@ public enum RadialStatusNodeState: Equatable {
|
||||
case cloudProgress(color: UIColor, strokeBackgroundColor: UIColor, lineWidth: CGFloat, value: CGFloat?)
|
||||
case check(UIColor)
|
||||
case customIcon(UIImage)
|
||||
case staticTimeout
|
||||
case secretTimeout(color: UIColor, icon: UIImage?, beginTime: Double, timeout: Double, sparks: Bool)
|
||||
|
||||
public static func ==(lhs: RadialStatusNodeState, rhs: RadialStatusNodeState) -> Bool {
|
||||
@ -64,6 +65,12 @@ public enum RadialStatusNodeState: Equatable {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case .staticTimeout:
|
||||
if case .staticTimeout = rhs {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
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 {
|
||||
return true
|
||||
@ -123,6 +130,12 @@ public enum RadialStatusNodeState: Equatable {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case .staticTimeout:
|
||||
if case .staticTimeout = rhs{
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
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 {
|
||||
return true
|
||||
@ -179,6 +192,8 @@ public enum RadialStatusNodeState: Equatable {
|
||||
node.progress = value
|
||||
return node
|
||||
}
|
||||
case .staticTimeout:
|
||||
return RadialStatusIconContentNode(icon: .timeout, synchronous: synchronous)
|
||||
case let .secretTimeout(color, icon, beginTime, timeout, 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 var backgroundNodeColor: UIColor {
|
||||
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 AsyncDisplayKit
|
||||
import LegacyComponents
|
||||
import ManagedAnimationNode
|
||||
|
||||
private struct ContentParticle {
|
||||
var position: CGPoint
|
||||
@ -53,6 +54,8 @@ final class RadialStatusSecretTimeoutContentNode: RadialStatusContentNode {
|
||||
private var progress: CGFloat = 0.0
|
||||
private var particles: [ContentParticle] = []
|
||||
|
||||
private let animationNode = FireIconNode()
|
||||
|
||||
private var displayLink: CADisplayLink?
|
||||
|
||||
init(color: UIColor, beginTime: Double, timeout: Double, icon: UIImage?, sparks: Bool) {
|
||||
@ -65,7 +68,7 @@ final class RadialStatusSecretTimeoutContentNode: RadialStatusContentNode {
|
||||
super.init()
|
||||
|
||||
self.isOpaque = false
|
||||
self.isLayerBacked = true
|
||||
// self.isLayerBacked = true
|
||||
|
||||
class DisplayLinkProxy: NSObject {
|
||||
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?.isPaused = true
|
||||
self.displayLink?.add(to: RunLoop.main, forMode: .common)
|
||||
|
||||
self.addSubnode(self.animationNode)
|
||||
}
|
||||
|
||||
deinit {
|
||||
@ -89,6 +94,8 @@ final class RadialStatusSecretTimeoutContentNode: RadialStatusContentNode {
|
||||
|
||||
override func 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) {
|
||||
@ -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
|
||||
for attribute in attributes {
|
||||
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
|
||||
}
|
||||
} 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
|
||||
}
|
||||
} else if let mentionAttribute = attribute as? ConsumablePersonalMentionMessageAttribute {
|
||||
|
@ -1,6 +1,8 @@
|
||||
import Foundation
|
||||
import Postbox
|
||||
|
||||
public let viewOnceTimeout: Int32 = 0x7fffffff
|
||||
|
||||
public class AutoremoveTimeoutMessageAttribute: MessageAttribute {
|
||||
public let timeout: Int32
|
||||
public let countdownBeginTime: Int32?
|
||||
@ -124,7 +126,7 @@ public extension Message {
|
||||
guard let timeout = self.minAutoremoveOrClearTimeout else {
|
||||
return false
|
||||
}
|
||||
if timeout > 1 * 60 {
|
||||
if timeout > 1 * 60 && timeout != viewOnceTimeout {
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -939,7 +939,6 @@ final class MediaEditorScreenComponent: Component {
|
||||
self.appliedAudioData = audioData
|
||||
|
||||
var timeoutValue: String
|
||||
let timeoutSelected: Bool
|
||||
switch component.privacy.timeout {
|
||||
case 21600:
|
||||
timeoutValue = "6"
|
||||
@ -952,7 +951,6 @@ final class MediaEditorScreenComponent: Component {
|
||||
default:
|
||||
timeoutValue = "24"
|
||||
}
|
||||
timeoutSelected = false
|
||||
|
||||
var inputPanelAvailableWidth = previewSize.width
|
||||
var inputPanelAvailableHeight = 103.0
|
||||
@ -1192,7 +1190,7 @@ final class MediaEditorScreenComponent: Component {
|
||||
hasRecordedVideoPreview: false,
|
||||
wasRecordingDismissed: false,
|
||||
timeoutValue: timeoutValue,
|
||||
timeoutSelected: timeoutSelected,
|
||||
timeoutSelected: false,
|
||||
displayGradient: false,
|
||||
bottomInset: 0.0,
|
||||
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 = {
|
||||
self.node.mediaEditor?.play()
|
||||
}
|
||||
@ -3845,6 +3849,12 @@ public final class MediaEditorScreen: ViewController, UIDropInteractionDelegate
|
||||
editCategory: { _, _, _ 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 = {
|
||||
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))
|
||||
}
|
||||
}
|
||||
self.cursorView.isHidden = component.audioOnly
|
||||
|
||||
let bounds = CGRect(origin: .zero, size: scrubberSize)
|
||||
|
||||
|
@ -135,7 +135,7 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
self.itemHeight = itemHeight
|
||||
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
|
||||
topOffsetFraction = max(0.0, min(1.0, topOffsetFraction))
|
||||
|
||||
//let transitionFactor: CGFloat = 1.0 - topOffsetFraction
|
||||
//controller.updateModalStyleOverlayTransitionFactor(transitionFactor, transition: transition.containedViewLayoutTransition)
|
||||
let transitionFactor: CGFloat = 1.0 - topOffsetFraction
|
||||
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
|
||||
visibleBounds.origin.y -= itemLayout.topInset
|
||||
@ -907,7 +915,7 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
|
||||
let sectionTitle: String
|
||||
if section.id == 0, case .stories = component.stateContext.subject {
|
||||
sectionTitle = "POST STORY AS"
|
||||
sectionTitle = environment.strings.Story_Privacy_PostStoryAsHeader
|
||||
} else if section.id == 2 {
|
||||
sectionTitle = environment.strings.Story_Privacy_WhoCanViewHeader
|
||||
} else if section.id == 1 {
|
||||
@ -1362,11 +1370,16 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
self.visibleItems[itemId] = visibleItem
|
||||
}
|
||||
|
||||
var title = item.title
|
||||
if item.id == .pin && !hasCategories {
|
||||
title = environment.strings.Story_Privacy_KeepOnChannelPage
|
||||
}
|
||||
|
||||
let _ = visibleItem.update(
|
||||
transition: itemTransition,
|
||||
component: AnyComponent(OptionListItemComponent(
|
||||
theme: environment.theme,
|
||||
title: item.title,
|
||||
title: title,
|
||||
hasNext: i != component.optionItems.count - 1,
|
||||
selected: self.selectedOptions.contains(item.id),
|
||||
selectionChanged: { [weak self] selected in
|
||||
@ -1414,7 +1427,7 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
var footerText = environment.strings.Story_Privacy_KeepOnMyPageInfo(footerValue).string
|
||||
|
||||
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(
|
||||
@ -1508,6 +1521,9 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
for id in removeSectionBackgroundIds {
|
||||
self.visibleSectionBackgrounds.removeValue(forKey: id)
|
||||
}
|
||||
for id in removeSectionFooterIds {
|
||||
self.visibleSectionFooters.removeValue(forKey: id)
|
||||
}
|
||||
|
||||
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 {
|
||||
@ -1932,11 +1948,16 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
)
|
||||
|
||||
var hasCategories = false
|
||||
var hasChannels = false
|
||||
if case .stories = component.stateContext.subject {
|
||||
if let peerId = self.sendAsPeerId, peerId.isGroupOrChannel {
|
||||
} else {
|
||||
hasCategories = true
|
||||
}
|
||||
let sendAsPeersCount = component.stateContext.stateValue?.sendAsPeers.count ?? 1
|
||||
if sendAsPeersCount > 1 {
|
||||
hasChannels = true
|
||||
}
|
||||
}
|
||||
|
||||
var footersTotalHeight: CGFloat = 0.0
|
||||
@ -2016,16 +2037,15 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
if case let .peers(peers, _) = component.stateContext.subject {
|
||||
sections.append(ItemLayout.Section(
|
||||
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,
|
||||
itemCount: peers.count
|
||||
))
|
||||
} else if case let .stories(editing) = component.stateContext.subject {
|
||||
let sendAsPeersCount = component.stateContext.stateValue?.sendAsPeers.count ?? 1
|
||||
if !editing && sendAsPeersCount > 1 {
|
||||
if !editing && hasChannels {
|
||||
sections.append(ItemLayout.Section(
|
||||
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,
|
||||
itemCount: 1
|
||||
))
|
||||
@ -2040,7 +2060,7 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
}
|
||||
sections.append(ItemLayout.Section(
|
||||
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,
|
||||
itemCount: component.optionItems.count
|
||||
))
|
||||
@ -2110,7 +2130,7 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
let title: String
|
||||
switch component.stateContext.subject {
|
||||
case .peers:
|
||||
title = "Post Story As"
|
||||
title = environment.strings.Story_Privacy_PostStoryAs
|
||||
case let .stories(editing):
|
||||
if editing {
|
||||
title = environment.strings.Story_Privacy_EditStory
|
||||
@ -2178,11 +2198,16 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
inset = 351.0
|
||||
inset += 10.0 + environment.safeInsets.bottom + 50.0 + footersTotalHeight
|
||||
} else {
|
||||
if hasCategories {
|
||||
inset = 1000.0
|
||||
} else {
|
||||
if !hasCategories {
|
||||
inset = 314.0
|
||||
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 {
|
||||
@ -2201,7 +2226,7 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
var bottomPanelHeight: CGFloat = 0.0
|
||||
var bottomPanelInset: CGFloat = 0.0
|
||||
if case .peers = component.stateContext.subject {
|
||||
|
||||
bottomPanelInset = environment.safeInsets.bottom
|
||||
} else {
|
||||
let badge: Int
|
||||
if case .stories = component.stateContext.subject {
|
||||
@ -2367,7 +2392,7 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
}
|
||||
return Array(filteredMentions)
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { mentions in
|
||||
|> deliverOnMainQueue).start(next: { mentions in
|
||||
if mentions.isEmpty {
|
||||
proceed()
|
||||
} else {
|
||||
@ -2377,7 +2402,7 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
}
|
||||
} else if case .contacts = base {
|
||||
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)
|
||||
let peers = contacts.peers
|
||||
for peer in peers {
|
||||
@ -2390,7 +2415,7 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
}
|
||||
return Array(filteredMentions)
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { mentions in
|
||||
|> deliverOnMainQueue).start(next: { mentions in
|
||||
if mentions.isEmpty {
|
||||
proceed()
|
||||
} else {
|
||||
@ -2399,7 +2424,7 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
})
|
||||
} else if case .closeFriends = base {
|
||||
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)
|
||||
let peers = contacts.peers
|
||||
for peer in peers {
|
||||
@ -2409,7 +2434,7 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
}
|
||||
return Array(filteredMentions)
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { mentions in
|
||||
|> deliverOnMainQueue).start(next: { mentions in
|
||||
if mentions.isEmpty {
|
||||
proceed()
|
||||
} else {
|
||||
@ -2452,7 +2477,7 @@ final class ShareWithPeersScreenComponent: Component {
|
||||
let previousItemLayout = self.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)
|
||||
|
||||
|
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 {
|
||||
case .linear(_, .None), .linear(_, .Neighbour(true, _, _)):
|
||||
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
|
||||
} 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 {
|
||||
skipStandardStatus = isFile
|
||||
}
|
||||
|
@ -860,7 +860,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
|
||||
let maxWidth: CGFloat
|
||||
if isSecretMedia {
|
||||
maxWidth = 180.0
|
||||
maxWidth = 200.0
|
||||
} else {
|
||||
maxWidth = maxDimensions.width
|
||||
}
|
||||
@ -898,7 +898,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
switch sizeCalculation {
|
||||
case .constrained:
|
||||
if isSecretMedia {
|
||||
boundingSize = CGSize(width: maxWidth, height: maxWidth)
|
||||
boundingSize = CGSize(width: maxWidth, height: maxWidth / 5.0 * 3.0)
|
||||
drawingSize = nativeSize.aspectFilled(boundingSize)
|
||||
} else {
|
||||
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 self.statusNode == nil {
|
||||
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 backgroundColor = messageTheme.mediaOverlayControlColors.fillColor
|
||||
var badgeContent: ChatMessageInteractiveMediaBadgeContent?
|
||||
var mediaDownloadState: ChatMessageInteractiveMediaDownloadState?
|
||||
let messageTheme = theme.chat.message
|
||||
|
||||
if let invoice = invoice {
|
||||
if let extendedMedia = invoice.extendedMedia {
|
||||
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 {
|
||||
let string = NSMutableAttributedString()
|
||||
@ -1808,7 +1816,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
}
|
||||
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
|
||||
@ -1944,7 +1952,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
}
|
||||
} else {
|
||||
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)
|
||||
}
|
||||
|
||||
@ -1980,8 +1988,10 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
}
|
||||
if isSecretMedia, let (maybeBeginTime, timeout) = secretBeginTimeAndTimeout, let beginTime = maybeBeginTime {
|
||||
state = .secretTimeout(color: messageTheme.mediaOverlayControlColors.foregroundColor, icon: secretProgressIcon, beginTime: beginTime, timeout: timeout, sparks: true)
|
||||
} else if isSecretMedia, let secretProgressIcon = secretProgressIcon {
|
||||
state = .customIcon(secretProgressIcon)
|
||||
backgroundColor = messageTheme.mediaDateAndStatusFillColor
|
||||
} else if isSecretMedia, let _ = secretProgressIcon {
|
||||
state = .staticTimeout
|
||||
backgroundColor = messageTheme.mediaDateAndStatusFillColor
|
||||
} else if let file = media as? TelegramMediaFile, !file.isVideoSticker {
|
||||
let isInlinePlayableVideo = file.isVideo && !isSecretMedia && (self.automaticPlayback ?? false)
|
||||
if (!isInlinePlayableVideo || isStory) && file.isVideo {
|
||||
@ -2017,11 +2027,11 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
} else {
|
||||
if isMediaStreamable(message: message, media: file) {
|
||||
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
|
||||
} else {
|
||||
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 {
|
||||
let remainingTime: Int32
|
||||
if let beginTime = maybeBeginTime {
|
||||
let elapsedTime = CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970 - beginTime
|
||||
remainingTime = Int32(max(0.0, timeout - elapsedTime))
|
||||
if isSecretMedia {
|
||||
let remainingTime: Int32?
|
||||
if let (maybeBeginTime, timeout) = secretBeginTimeAndTimeout {
|
||||
if let beginTime = maybeBeginTime {
|
||||
let elapsedTime = CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970 - beginTime
|
||||
remainingTime = Int32(max(0.0, timeout - elapsedTime))
|
||||
} else {
|
||||
remainingTime = Int32(timeout)
|
||||
}
|
||||
} 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 {
|
||||
@ -2062,6 +2088,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
statusNode?.removeFromSupernode()
|
||||
}
|
||||
})
|
||||
statusNode.backgroundNodeColor = backgroundColor
|
||||
}
|
||||
if let badgeContent = badgeContent {
|
||||
if self.badgeNode == nil {
|
||||
@ -2100,6 +2127,8 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
displaySpoiler = true
|
||||
} else if message.attributes.contains(where: { $0 is MediaSpoilerMessageAttribute }) {
|
||||
displaySpoiler = true
|
||||
} else if isSecretMedia {
|
||||
displaySpoiler = true
|
||||
}
|
||||
|
||||
if displaySpoiler {
|
||||
@ -2115,11 +2144,13 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
|
||||
self.extendedMediaOverlayNode?.frame = self.imageNode.frame
|
||||
|
||||
var tappable = false
|
||||
switch state {
|
||||
case .play, .pause, .download, .none:
|
||||
tappable = true
|
||||
default:
|
||||
break
|
||||
if !isSecretMedia {
|
||||
switch state {
|
||||
case .play, .pause, .download, .none:
|
||||
tappable = true
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
self.extendedMediaOverlayNode?.isUserInteractionEnabled = tappable
|
||||
|
@ -281,16 +281,16 @@ final class GridMessageItemNode: GridItemNode {
|
||||
switch status {
|
||||
case let .Fetching(_, progress):
|
||||
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)
|
||||
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:
|
||||
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
|
||||
}
|
||||
} 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)
|
||||
|
@ -385,16 +385,16 @@ private final class VisualMediaItemNode: ASDisplayNode {
|
||||
switch status {
|
||||
case let .Fetching(_, progress):
|
||||
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)
|
||||
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:
|
||||
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
|
||||
}
|
||||
} 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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user