diff --git a/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift b/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift index 8d646bd36b..5e69293fca 100644 --- a/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift +++ b/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift @@ -489,26 +489,37 @@ private final class PictureInPictureContentImpl: NSObject, PictureInPictureConte private var statusDisposable: Disposable? private var status: MediaPlayerStatus? weak var pictureInPictureController: AVPictureInPictureController? - + + private var previousIsPlaying = false init(node: UniversalVideoNode) { self.node = node super.init() + var invalidatedStateOnce = false self.statusDisposable = (self.node.status |> deliverOnMainQueue).start(next: { [weak self] status in guard let strongSelf = self else { return } strongSelf.status = status - strongSelf.pictureInPictureController?.invalidatePlaybackState() + if let status { + let isPlaying = status.status == .playing + if !invalidatedStateOnce { + invalidatedStateOnce = true + strongSelf.pictureInPictureController?.invalidatePlaybackState() + } else if strongSelf.previousIsPlaying != isPlaying { + strongSelf.previousIsPlaying = isPlaying + strongSelf.pictureInPictureController?.invalidatePlaybackState() + } + } }) } deinit { self.statusDisposable?.dispose() } - + public func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, setPlaying playing: Bool) { self.node.togglePlayPause() } @@ -517,7 +528,7 @@ private final class PictureInPictureContentImpl: NSObject, PictureInPictureConte guard let status = self.status else { return CMTimeRange(start: CMTime(seconds: 0.0, preferredTimescale: CMTimeScale(30.0)), duration: CMTime(seconds: 0.0, preferredTimescale: CMTimeScale(30.0))) } - return CMTimeRange(start: CMTime(seconds: status.timestamp, preferredTimescale: CMTimeScale(30.0)), duration: CMTime(seconds: status.duration, preferredTimescale: CMTimeScale(30.0))) + return CMTimeRange(start: CMTime(seconds: 0.0, preferredTimescale: CMTimeScale(30.0)), duration: CMTime(seconds: status.duration - status.timestamp, preferredTimescale: CMTimeScale(30.0))) } public func pictureInPictureControllerIsPlaybackPaused(_ pictureInPictureController: AVPictureInPictureController) -> Bool { @@ -652,6 +663,11 @@ private final class PictureInPictureContentImpl: NSObject, PictureInPictureConte mediaManager.galleryHiddenMediaManager.removeSource(hiddenMediaManagerIndex) } } + + func invalidatePlaybackState() { + self.pictureInPictureController?.invalidatePlaybackState() + } + var videoNode: ASDisplayNode { return self.node @@ -675,6 +691,7 @@ private final class PictureInPictureContentImpl: NSObject, PictureInPictureConte } public func pictureInPictureController(_ pictureInPictureController: AVPictureInPictureController, failedToStartPictureInPictureWithError error: Error) { + print(error) } public func pictureInPictureControllerWillStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) { @@ -1444,7 +1461,14 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode { videoNode.playbackCompleted = { [weak self, weak videoNode] in Queue.mainQueue().async { item.playbackCompleted() + if let strongSelf = self, !isAnimated { + if #available(iOS 15.0, *) { + if let pictureInPictureContent = strongSelf.pictureInPictureContent as? PictureInPictureContentImpl { + pictureInPictureContent.invalidatePlaybackState() + } + } + if let snapshotView = videoNode?.view.snapshotView(afterScreenUpdates: false) { videoNode?.view.addSubview(snapshotView) snapshotView.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3, removeOnCompletion: false, completion: { [weak snapshotView] _ in diff --git a/submodules/Postbox/Package.swift b/submodules/Postbox/Package.swift index 049d141295..dd499b6a67 100644 --- a/submodules/Postbox/Package.swift +++ b/submodules/Postbox/Package.swift @@ -21,6 +21,7 @@ let package = Package( .package(name: "StringTransliteration", path: "../StringTransliteration"), .package(name: "ManagedFile", path: "../ManagedFile"), .package(name: "RangeSet", path: "../Utils/RangeSet"), + .package(name: "DarwinDirStat", path: "../Utils/DarwinDirStat"), .package(name: "SSignalKit", path: "../SSignalKit"), .package(name: "CryptoUtils", path: "../CryptoUtils") ], @@ -35,6 +36,7 @@ let package = Package( .product(name: "RangeSet", package: "RangeSet", condition: nil), .product(name: "sqlcipher", package: "sqlcipher", condition: nil), .product(name: "StringTransliteration", package: "StringTransliteration", condition: nil), + .product(name: "DarwinDirStat", package: "DarwinDirStat", condition: nil), .product(name: "CryptoUtils", package: "CryptoUtils", condition: nil), .product(name: "Crc32", package: "Crc32", condition: nil)], path: "Sources"), diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/AddPeerMember.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/AddPeerMember.swift index 06987d9d40..f0b5370172 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/AddPeerMember.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/AddPeerMember.swift @@ -229,3 +229,37 @@ func _internal_addChannelMembers(account: Account, peerId: PeerId, memberIds: [P return signal |> switchToLatest } + + +public enum SendBotRequestedPeerError { + case generic +} + +func _internal_sendBotRequestedPeer(account: Account, peerId: PeerId, messageId: MessageId, buttonId: Int32, requestedPeerId: PeerId) -> Signal { + let signal = account.postbox.transaction { transaction -> Signal in + + + if let peer = transaction.getPeer(peerId), let requestedPeer = transaction.getPeer(requestedPeerId) { + + let inputPeer = apiInputPeer(peer) + let inputRequestedPeer = apiInputPeer(requestedPeer) + + if let inputPeer = inputPeer, let inputRequestedPeer = inputRequestedPeer { + let signal = account.network.request(Api.functions.messages.sendBotRequestedPeer(peer: inputPeer, msgId: messageId.id, buttonId: buttonId, requestedPeer: inputRequestedPeer)) + |> mapError { error -> SendBotRequestedPeerError in + return .generic + } + |> map { result in + account.stateManager.addUpdates(result) + } + return signal + } + + } + return .single(Void()) + } + |> castError(SendBotRequestedPeerError.self) + + return signal + |> switchToLatest +} diff --git a/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift b/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift index 349756bfbf..347b9d86e2 100644 --- a/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift +++ b/submodules/TelegramCore/Sources/TelegramEngine/Peers/TelegramEnginePeers.swift @@ -439,6 +439,10 @@ public extension TelegramEngine { public func addChannelMember(peerId: PeerId, memberId: PeerId) -> Signal<(ChannelParticipant?, RenderedChannelParticipant), AddChannelMemberError> { return _internal_addChannelMember(account: self.account, peerId: peerId, memberId: memberId) } + + public func sendBotRequestedPeer(messageId: MessageId, buttonId: Int32, requestedPeerId: PeerId) -> Signal { + return _internal_sendBotRequestedPeer(account: self.account, peerId: messageId.peerId, messageId: messageId, buttonId: buttonId, requestedPeerId: requestedPeerId) + } public func addChannelMembers(peerId: PeerId, memberIds: [PeerId]) -> Signal { return _internal_addChannelMembers(account: self.account, peerId: peerId, memberIds: memberIds) diff --git a/submodules/TelegramUniversalVideoContent/Sources/OverlayUniversalVideoNode.swift b/submodules/TelegramUniversalVideoContent/Sources/OverlayUniversalVideoNode.swift index 7f1670691c..1d8cc7c36a 100644 --- a/submodules/TelegramUniversalVideoContent/Sources/OverlayUniversalVideoNode.swift +++ b/submodules/TelegramUniversalVideoContent/Sources/OverlayUniversalVideoNode.swift @@ -211,7 +211,7 @@ public final class OverlayUniversalVideoNode: OverlayMediaItemNode, AVPictureInP guard let status = self.status else { return CMTimeRange(start: CMTime(seconds: 0.0, preferredTimescale: CMTimeScale(30.0)), duration: CMTime(seconds: 0.0, preferredTimescale: CMTimeScale(30.0))) } - return CMTimeRange(start: CMTime(seconds: status.timestamp, preferredTimescale: CMTimeScale(30.0)), duration: CMTime(seconds: status.duration, preferredTimescale: CMTimeScale(30.0))) + return CMTimeRange(start: CMTime(seconds: 0.0, preferredTimescale: CMTimeScale(30.0)), duration: CMTime(seconds: status.duration, preferredTimescale: CMTimeScale(30.0))) } public func pictureInPictureControllerIsPlaybackPaused(_ pictureInPictureController: AVPictureInPictureController) -> Bool {