diff --git a/Telegram/Telegram-iOS/en.lproj/Localizable.strings b/Telegram/Telegram-iOS/en.lproj/Localizable.strings index 9ee3fe6e40..9690eab09b 100644 --- a/Telegram/Telegram-iOS/en.lproj/Localizable.strings +++ b/Telegram/Telegram-iOS/en.lproj/Localizable.strings @@ -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 %@."; diff --git a/submodules/ChatListUI/Sources/ChatListSearchMediaNode.swift b/submodules/ChatListUI/Sources/ChatListSearchMediaNode.swift index 0923c3c18f..d8b21b9fd6 100644 --- a/submodules/ChatListUI/Sources/ChatListSearchMediaNode.swift +++ b/submodules/ChatListUI/Sources/ChatListSearchMediaNode.swift @@ -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) diff --git a/submodules/ChatMessageInteractiveMediaBadge/Sources/ChatMessageInteractiveMediaBadge.swift b/submodules/ChatMessageInteractiveMediaBadge/Sources/ChatMessageInteractiveMediaBadge.swift index c97b5b013b..611a6966d5 100644 --- a/submodules/ChatMessageInteractiveMediaBadge/Sources/ChatMessageInteractiveMediaBadge.swift +++ b/submodules/ChatMessageInteractiveMediaBadge/Sources/ChatMessageInteractiveMediaBadge.swift @@ -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) diff --git a/submodules/RadialStatusNode/BUILD b/submodules/RadialStatusNode/BUILD index 264f6f4f6d..5fb0386325 100644 --- a/submodules/RadialStatusNode/BUILD +++ b/submodules/RadialStatusNode/BUILD @@ -14,6 +14,7 @@ swift_library( "//submodules/AsyncDisplayKit:AsyncDisplayKit", "//submodules/LegacyComponents:LegacyComponents", "//submodules/SSignalKit/SwiftSignalKit:SwiftSignalKit", + "//submodules/ManagedAnimationNode:ManagedAnimationNode" ], visibility = [ "//visibility:public", diff --git a/submodules/RadialStatusNode/Sources/RadialStatusIconContentNode.swift b/submodules/RadialStatusNode/Sources/RadialStatusIconContentNode.swift index d0b5f9e2af..0d1510195a 100644 --- a/submodules/RadialStatusNode/Sources/RadialStatusIconContentNode.swift +++ b/submodules/RadialStatusNode/Sources/RadialStatusIconContentNode.swift @@ -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) diff --git a/submodules/RadialStatusNode/Sources/RadialStatusNode.swift b/submodules/RadialStatusNode/Sources/RadialStatusNode.swift index 28670b84b2..3c1a78394d 100644 --- a/submodules/RadialStatusNode/Sources/RadialStatusNode.swift +++ b/submodules/RadialStatusNode/Sources/RadialStatusNode.swift @@ -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: {}) + } } } diff --git a/submodules/RadialStatusNode/Sources/RadialStatusSecretTimeoutContentNode.swift b/submodules/RadialStatusNode/Sources/RadialStatusSecretTimeoutContentNode.swift index ac5fcf9e02..f790cf06d9 100644 --- a/submodules/RadialStatusNode/Sources/RadialStatusSecretTimeoutContentNode.swift +++ b/submodules/RadialStatusNode/Sources/RadialStatusSecretTimeoutContentNode.swift @@ -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)) + } +} diff --git a/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift b/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift index c7534923c5..3e798cbdd9 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift @@ -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 { diff --git a/submodules/TelegramCore/Sources/SyncCore/SyncCore_AutoremoveTimeoutMessageAttribute.swift b/submodules/TelegramCore/Sources/SyncCore/SyncCore_AutoremoveTimeoutMessageAttribute.swift index 77e1eec8dc..2ec5399c1e 100644 --- a/submodules/TelegramCore/Sources/SyncCore/SyncCore_AutoremoveTimeoutMessageAttribute.swift +++ b/submodules/TelegramCore/Sources/SyncCore/SyncCore_AutoremoveTimeoutMessageAttribute.swift @@ -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 } diff --git a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift index 95c06fd31f..32c166157a 100644 --- a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift +++ b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/MediaEditorScreen.swift @@ -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() } diff --git a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/VideoScrubberComponent.swift b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/VideoScrubberComponent.swift index 79a2e2ac22..a4c46e7f31 100644 --- a/submodules/TelegramUI/Components/MediaEditorScreen/Sources/VideoScrubberComponent.swift +++ b/submodules/TelegramUI/Components/MediaEditorScreen/Sources/VideoScrubberComponent.swift @@ -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) diff --git a/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift b/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift index fc8af9c569..56dbc068be 100644 --- a/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift +++ b/submodules/TelegramUI/Components/ShareWithPeersScreen/Sources/ShareWithPeersScreen.swift @@ -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) diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Message/SecretMediaOnce.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat/Message/SecretMediaOnce.imageset/Contents.json new file mode 100644 index 0000000000..ba266bf499 --- /dev/null +++ b/submodules/TelegramUI/Images.xcassets/Chat/Message/SecretMediaOnce.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "miniplayonce.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Message/SecretMediaOnce.imageset/miniplayonce.pdf b/submodules/TelegramUI/Images.xcassets/Chat/Message/SecretMediaOnce.imageset/miniplayonce.pdf new file mode 100644 index 0000000000..7ec1ebc79c --- /dev/null +++ b/submodules/TelegramUI/Images.xcassets/Chat/Message/SecretMediaOnce.imageset/miniplayonce.pdf @@ -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 \ No newline at end of file diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Message/SecretMediaPlay.imageset/Contents.json b/submodules/TelegramUI/Images.xcassets/Chat/Message/SecretMediaPlay.imageset/Contents.json new file mode 100644 index 0000000000..865478dba9 --- /dev/null +++ b/submodules/TelegramUI/Images.xcassets/Chat/Message/SecretMediaPlay.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "miniplay.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/submodules/TelegramUI/Images.xcassets/Chat/Message/SecretMediaPlay.imageset/miniplay.pdf b/submodules/TelegramUI/Images.xcassets/Chat/Message/SecretMediaPlay.imageset/miniplay.pdf new file mode 100644 index 0000000000..62377ab473 --- /dev/null +++ b/submodules/TelegramUI/Images.xcassets/Chat/Message/SecretMediaPlay.imageset/miniplay.pdf @@ -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 \ No newline at end of file diff --git a/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift b/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift index 9ab5f25b15..cfbd1db7e2 100644 --- a/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageAttachedContentNode.swift @@ -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 } diff --git a/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift b/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift index f48f5dcaf8..f73d32a596 100644 --- a/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageInteractiveMediaNode.swift @@ -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 diff --git a/submodules/TelegramUI/Sources/GridMessageItem.swift b/submodules/TelegramUI/Sources/GridMessageItem.swift index 5d6c0903fb..20db9157d1 100644 --- a/submodules/TelegramUI/Sources/GridMessageItem.swift +++ b/submodules/TelegramUI/Sources/GridMessageItem.swift @@ -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) diff --git a/submodules/TelegramUI/Sources/PeerInfoGifPaneNode.swift b/submodules/TelegramUI/Sources/PeerInfoGifPaneNode.swift index 0f606a494e..974594da51 100644 --- a/submodules/TelegramUI/Sources/PeerInfoGifPaneNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfoGifPaneNode.swift @@ -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)