diff --git a/submodules/Display/Source/TransformImageNode.swift b/submodules/Display/Source/TransformImageNode.swift index 93285773a1..a8bd1a272f 100644 --- a/submodules/Display/Source/TransformImageNode.swift +++ b/submodules/Display/Source/TransformImageNode.swift @@ -22,7 +22,7 @@ open class TransformImageNode: ASDisplayNode { private var currentTransform: ((TransformImageArguments) -> DrawingContext?)? private var currentArguments: TransformImageArguments? - private var image: UIImage? + public private(set) var image: UIImage? private var argumentsPromise = ValuePromise(ignoreRepeated: true) private var overlayColor: UIColor? @@ -276,6 +276,7 @@ private final class NullActionClass: NSObject, CAAction { private let nullAction = NullActionClass() private class CaptureProtectedContentLayer: AVSampleBufferDisplayLayer { + override func action(forKey event: String) -> CAAction? { return nullAction } @@ -289,13 +290,13 @@ open class TransformImageView: UIView { private var currentTransform: ((TransformImageArguments) -> DrawingContext?)? private var currentArguments: TransformImageArguments? private var argumentsPromise = ValuePromise(ignoreRepeated: true) - private var image: UIImage? + public private(set) var image: UIImage? private var captureProtectedContentLayer: CaptureProtectedContentLayer? private var overlayColor: UIColor? private var overlayView: UIView? - + open override var bounds: CGRect { didSet { if let captureProtectedContentLayer = self.captureProtectedContentLayer, super.bounds.size != oldValue.size { diff --git a/submodules/Display/Source/UIKitUtils.swift b/submodules/Display/Source/UIKitUtils.swift index bb2f3d0333..2b6ee6a68e 100644 --- a/submodules/Display/Source/UIKitUtils.swift +++ b/submodules/Display/Source/UIKitUtils.swift @@ -1,5 +1,6 @@ import UIKit import UIKitRuntimeUtils +import AVFoundation public extension UIView { static func animationDurationFactor() -> Double { @@ -399,6 +400,9 @@ public extension UIImage { } private func makeSubtreeSnapshot(layer: CALayer, keepTransform: Bool = false) -> UIView? { + if layer is AVSampleBufferDisplayLayer { + return nil + } let view = UIView() view.layer.isHidden = layer.isHidden view.layer.opacity = layer.opacity @@ -441,7 +445,7 @@ private func makeSubtreeSnapshot(layer: CALayer, keepTransform: Bool = false) -> } view.addSubview(subtree) } else { - return nil + continue } } } @@ -449,6 +453,9 @@ private func makeSubtreeSnapshot(layer: CALayer, keepTransform: Bool = false) -> } private func makeLayerSubtreeSnapshot(layer: CALayer) -> CALayer? { + if layer is AVSampleBufferDisplayLayer { + return nil + } let view = CALayer() view.isHidden = layer.isHidden view.opacity = layer.opacity diff --git a/submodules/GalleryUI/Sources/Items/ChatImageGalleryItem.swift b/submodules/GalleryUI/Sources/Items/ChatImageGalleryItem.swift index c74a3a6c48..c6678d293b 100644 --- a/submodules/GalleryUI/Sources/Items/ChatImageGalleryItem.swift +++ b/submodules/GalleryUI/Sources/Items/ChatImageGalleryItem.swift @@ -122,6 +122,7 @@ class ChatImageGalleryItem: GalleryItem { func node(synchronous: Bool) -> GalleryItemNode { let node = ChatImageGalleryItemNode(context: self.context, presentationData: self.presentationData, performAction: self.performAction, openActionOptions: self.openActionOptions, present: self.present) + node.setMessage(self.message, displayInfo: !self.displayInfoOnTop) for media in self.message.media { if let image = media as? TelegramMediaImage { node.setImage(imageReference: .message(message: MessageReference(self.message), media: image)) @@ -147,7 +148,6 @@ class ChatImageGalleryItem: GalleryItem { if self.displayInfoOnTop { node.titleContentView?.setMessage(self.message, presentationData: self.presentationData, accountPeerId: self.context.account.peerId) } - node.setMessage(self.message, displayInfo: !self.displayInfoOnTop) return node } @@ -258,6 +258,8 @@ final class ChatImageGalleryItemNode: ZoomableContentGalleryItemNode { } fileprivate func setMessage(_ message: Message, displayInfo: Bool) { + self.message = message + self.imageNode.captureProtected = message.isCopyProtected() self.footerContentNode.setMessage(message, displayInfo: displayInfo) } diff --git a/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift b/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift index 19e682416f..cd175da649 100644 --- a/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelVisibilityController.swift @@ -839,7 +839,7 @@ private func channelVisibilityControllerEntries(presentationData: PresentationDa entries.append(.forwardingHeader(presentationData.theme, presentationData.strings.Group_Setup_ForwardingGroupTitle.uppercased())) entries.append(.forwardingEnabled(presentationData.theme, presentationData.strings.Group_Setup_ForwardingEnabled, forwardingEnabled)) - entries.append(.forwardingDisabled(presentationData.theme, presentationData.strings.Group_Setup_ForwardingEnabled, !forwardingEnabled)) + entries.append(.forwardingDisabled(presentationData.theme, presentationData.strings.Group_Setup_ForwardingDisabled, !forwardingEnabled)) entries.append(.forwardingInfo(presentationData.theme, presentationData.strings.Group_Setup_ForwardingGroupInfo)) } diff --git a/submodules/Postbox/Sources/Message.swift b/submodules/Postbox/Sources/Message.swift index 490712c543..8bf7ad9ed6 100644 --- a/submodules/Postbox/Sources/Message.swift +++ b/submodules/Postbox/Sources/Message.swift @@ -469,6 +469,10 @@ public struct MessageFlags: OptionSet { rawValue |= MessageFlags.CountedAsIncoming.rawValue } + if flags.contains(StoreMessageFlags.CopyProtected) { + rawValue |= MessageFlags.CopyProtected.rawValue + } + self.rawValue = rawValue } @@ -480,6 +484,7 @@ public struct MessageFlags: OptionSet { public static let CanBeGroupedIntoFeed = MessageFlags(rawValue: 64) public static let WasScheduled = MessageFlags(rawValue: 128) public static let CountedAsIncoming = MessageFlags(rawValue: 256) + public static let CopyProtected = MessageFlags(rawValue: 512) public static let IsIncomingMask = MessageFlags([.Incoming, .CountedAsIncoming]) } @@ -729,6 +734,10 @@ public struct StoreMessageFlags: OptionSet { rawValue |= StoreMessageFlags.CountedAsIncoming.rawValue } + if flags.contains(.CopyProtected) { + rawValue |= StoreMessageFlags.CopyProtected.rawValue + } + self.rawValue = rawValue } @@ -740,6 +749,7 @@ public struct StoreMessageFlags: OptionSet { public static let CanBeGroupedIntoFeed = StoreMessageFlags(rawValue: 64) public static let WasScheduled = StoreMessageFlags(rawValue: 128) public static let CountedAsIncoming = StoreMessageFlags(rawValue: 256) + public static let CopyProtected = StoreMessageFlags(rawValue: 512) public static let IsIncomingMask = StoreMessageFlags([.Incoming, .CountedAsIncoming]) } diff --git a/submodules/SettingsUI/Sources/Privacy and Security/Recent Sessions/RecentSessionsHeaderItem.swift b/submodules/SettingsUI/Sources/Privacy and Security/Recent Sessions/RecentSessionsHeaderItem.swift index 2b3fd5c41f..cf1aefa970 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/Recent Sessions/RecentSessionsHeaderItem.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/Recent Sessions/RecentSessionsHeaderItem.swift @@ -119,7 +119,7 @@ class RecentSessionsHeaderItemNode: ListViewItemNode { var updatedTheme: PresentationTheme? let leftInset: CGFloat = 32.0 + params.leftInset - let topInset: CGFloat = 92.0 + let topInset: CGFloat = 124.0 if currentItem?.theme !== item.theme { updatedTheme = item.theme @@ -139,8 +139,12 @@ class RecentSessionsHeaderItemNode: ListViewItemNode { return (layout, { [weak self] in if let strongSelf = self { if strongSelf.item == nil { - strongSelf.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: item.animationName), width: 192, height: 192, playbackMode: .once, mode: .direct(cachePathPrefix: nil)) + strongSelf.animationNode.autoplay = true + strongSelf.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(name: item.animationName), width: 256, height: 256, playbackMode: .still(.start), mode: .direct(cachePathPrefix: nil)) strongSelf.animationNode.visibility = true + Queue.mainQueue().after(0.3) { + strongSelf.animationNode.play() + } } strongSelf.item = item @@ -157,7 +161,7 @@ class RecentSessionsHeaderItemNode: ListViewItemNode { strongSelf.accessibilityLabel = attributedText.string - let iconSize = CGSize(width: 96.0, height: 96.0) + let iconSize = CGSize(width: 128.0, height: 128.0) strongSelf.animationNode.frame = CGRect(origin: CGPoint(x: floor((layout.size.width - iconSize.width) / 2.0), y: -10.0), size: iconSize) strongSelf.animationNode.updateLayout(size: iconSize) diff --git a/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift b/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift index 05890d4a7c..e26b60dd06 100644 --- a/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift +++ b/submodules/TelegramCore/Sources/ApiUtils/StoreMessage_Telegram.swift @@ -588,6 +588,10 @@ extension StoreMessage { storeFlags.insert(.WasScheduled) storeFlags.insert(.CountedAsIncoming) } + + if (flags & (1 << 26)) != 0 { + storeFlags.insert(.CopyProtected) + } if (flags & (1 << 4)) != 0 || (flags & (1 << 13)) != 0 { var notificationFlags: NotificationInfoMessageAttributeFlags = [] @@ -675,6 +679,10 @@ extension StoreMessage { if (flags & (1 << 18)) != 0 { storeFlags.insert(.WasScheduled) } + + if (flags & (1 << 26)) != 0 { + storeFlags.insert(.CopyProtected) + } self.init(id: MessageId(peerId: peerId, namespace: namespace, id: id), globallyUniqueId: nil, groupingKey: nil, threadId: threadId, timestamp: date, flags: storeFlags, tags: tags, globalTags: globalTags, localTags: [], forwardInfo: nil, authorId: authorId, text: "", attributes: attributes, media: media) } diff --git a/submodules/TelegramCore/Sources/Utils/MessageUtils.swift b/submodules/TelegramCore/Sources/Utils/MessageUtils.swift index cf49c11cb8..ea01b0e228 100644 --- a/submodules/TelegramCore/Sources/Utils/MessageUtils.swift +++ b/submodules/TelegramCore/Sources/Utils/MessageUtils.swift @@ -240,7 +240,9 @@ public extension Message { } func isCopyProtected() -> Bool { - if let group = self.peers[self.id.peerId] as? TelegramGroup, group.flags.contains(.copyProtectionEnabled) { + if self.flags.contains(.CopyProtected) { + return true + } else if let group = self.peers[self.id.peerId] as? TelegramGroup, group.flags.contains(.copyProtectionEnabled) { return true } else if let channel = self.peers[self.id.peerId] as? TelegramChannel, channel.flags.contains(.copyProtectionEnabled) { return true diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index f00074d3c4..2ed4e48336 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -990,12 +990,22 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G var tip: ContextController.Tip? if tip == nil { - if strongSelf.presentationInterfaceState.copyProtectionEnabled { - var isChannel = false - if let channel = strongSelf.presentationInterfaceState.renderedPeer?.peer as? TelegramChannel, case .broadcast = channel.info { - isChannel = true + var isAction = false + for media in message.media { + if media is TelegramMediaAction { + isAction = true + break + } + } + if strongSelf.presentationInterfaceState.copyProtectionEnabled && !isAction { + if case .scheduledMessages = strongSelf.subject { + } else { + var isChannel = false + if let channel = strongSelf.presentationInterfaceState.renderedPeer?.peer as? TelegramChannel, case .broadcast = channel.info { + isChannel = true + } + tip = .messageCopyProtection(isChannel: isChannel) } - tip = .messageCopyProtection(isChannel: isChannel) } else { let numberOfComponents = message.text.components(separatedBy: CharacterSet.whitespacesAndNewlines).count let displayTextSelectionTip = numberOfComponents >= 3 && !message.text.isEmpty && chatTextSelectionTips < 3 diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index e751b4a129..91a0de2bba 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -739,6 +739,8 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { additionalData.append(.peerNotificationSettings(peerId)) if peerId.namespace == Namespaces.Peer.CloudChannel { additionalData.append(.cacheEntry(cachedChannelAdminRanksEntryId(peerId: peerId))) + } + if [Namespaces.Peer.CloudChannel, Namespaces.Peer.CloudGroup].contains(peerId.namespace) { additionalData.append(.peer(peerId)) } if peerId.namespace == Namespaces.Peer.CloudUser || peerId.namespace == Namespaces.Peer.SecretChat { diff --git a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift index fa5fdfa92a..2c32f6c887 100644 --- a/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift +++ b/submodules/TelegramUI/Sources/ChatInterfaceStateContextMenus.swift @@ -1395,7 +1395,7 @@ func chatAvailableMessageActionsImpl(postbox: Postbox, accountPeerId: PeerId, me } } else if let group = peer as? TelegramGroup { if message.id.peerId.namespace != Namespaces.Peer.SecretChat && !message.containsSecretMedia { - if !isAction { + if !isAction && !message.isCopyProtected() { if !(message.flags.isSending || message.flags.contains(.Failed)) { optionsMap[id]!.insert(.forward) } diff --git a/submodules/TelegramUI/Sources/ChatSendAsPeerListContextItem.swift b/submodules/TelegramUI/Sources/ChatSendAsPeerListContextItem.swift index 8560bc9a1d..cd4293db3b 100644 --- a/submodules/TelegramUI/Sources/ChatSendAsPeerListContextItem.swift +++ b/submodules/TelegramUI/Sources/ChatSendAsPeerListContextItem.swift @@ -142,6 +142,8 @@ private final class ChatSendAsPeerListContextItemNode: ASDisplayNode, ContextMen func updateLayout(constrainedWidth: CGFloat, constrainedHeight: CGFloat) -> (CGSize, (CGSize, ContainedViewLayoutTransition) -> Void) { let minActionsWidth: CGFloat = 250.0 + let maxActionsWidth: CGFloat = 300.0 + let constrainedWidth = min(constrainedWidth, maxActionsWidth) var maxWidth: CGFloat = 0.0 var contentHeight: CGFloat = 0.0 var heightsAndCompletions: [(CGFloat, (CGSize, ContainedViewLayoutTransition) -> Void)?] = [] diff --git a/submodules/TelegramUI/Sources/DocumentPreviewController.swift b/submodules/TelegramUI/Sources/DocumentPreviewController.swift index 04ba8eff94..a44edeb8e0 100644 --- a/submodules/TelegramUI/Sources/DocumentPreviewController.swift +++ b/submodules/TelegramUI/Sources/DocumentPreviewController.swift @@ -178,6 +178,7 @@ final class CompactDocumentPreviewController: QLPreviewController, QLPreviewCont //self.cancelPressed() } + private var navigationBars: [UINavigationBar] = [] private var toolbars: [UIView] = [] private var observations : [NSKeyValueObservation] = [] @@ -197,28 +198,42 @@ final class CompactDocumentPreviewController: QLPreviewController, QLPreviewCont } private func tick() { - self.navigationItem.rightBarButtonItems?[0] = UIBarButtonItem() + self.navigationItem.rightBarButtonItems = [UIBarButtonItem()] self.navigationItem.setRightBarButton(UIBarButtonItem(), animated: false) self.navigationController?.toolbar.isHidden = true - self.toolbars = self.toolbarsInSubviews(forView: self.view) + let (navigationBars, toolbars) = navigationAndToolbarsInSubviews(forView: self.view) + self.navigationBars = navigationBars + self.toolbars = toolbars + for navigationBar in self.navigationBars { + navigationBar.topItem?.rightBarButtonItem = UIBarButtonItem() + navigationBar.topItem?.rightBarButtonItems = [UIBarButtonItem()] + } + for toolbar in self.toolbars { toolbar.isHidden = true } } - private func toolbarsInSubviews(forView view: UIView) -> [UIView] { + private func navigationAndToolbarsInSubviews(forView view: UIView) -> ([UINavigationBar], [UIView]) { + var navigationBars: [UINavigationBar] = [] var toolbars: [UIView] = [] for subview in view.subviews { - if subview is UIToolbar { + if let subview = subview as? UINavigationBar { + navigationBars.append(subview) + } else if let subview = subview as? UIToolbar { toolbars.append(subview) + } else { + let (subNavigationBars, subToolbars) = navigationAndToolbarsInSubviews(forView: subview) + navigationBars.append(contentsOf: subNavigationBars) + toolbars.append(contentsOf: subToolbars) } - toolbars.append(contentsOf: toolbarsInSubviews(forView: subview)) } - return toolbars + return (navigationBars, toolbars) } + } func presentDocumentPreviewController(rootController: UIViewController, theme: PresentationTheme, strings: PresentationStrings, postbox: Postbox, file: TelegramMediaFile, canShare: Bool) {