diff --git a/submodules/GalleryUI/Sources/GalleryController.swift b/submodules/GalleryUI/Sources/GalleryController.swift index 9f07705918..ab2d04e0f5 100644 --- a/submodules/GalleryUI/Sources/GalleryController.swift +++ b/submodules/GalleryUI/Sources/GalleryController.swift @@ -463,7 +463,6 @@ public class GalleryController: ViewController, StandalonePresentableController } } } - |> take(1) let semaphore: DispatchSemaphore? if synchronousLoad { @@ -487,6 +486,23 @@ public class GalleryController: ViewController, StandalonePresentableController strongSelf.configuration = configuration let entries = view.entries + + if let centralEntryStableId = strongSelf.centralEntryStableId { + var found = false + for i in 0 ..< entries.count { + let message = entries[i].message + if message.stableId == centralEntryStableId { + found = true + break + } + } + + if !found { + strongSelf.dismiss(forceAway: true) + return + } + } + var centralEntryStableId: UInt32? loop: for i in 0 ..< entries.count { let message = entries[i].message @@ -515,14 +531,16 @@ public class GalleryController: ViewController, StandalonePresentableController strongSelf.entries = entries.reversed() strongSelf.hasLeftEntries = view.hasLater strongSelf.hasRightEntries = view.hasEarlier - if let centralEntryStableId = centralEntryStableId { + if strongSelf.centralEntryStableId == nil, let centralEntryStableId = centralEntryStableId { strongSelf.centralEntryStableId = centralEntryStableId } } else { strongSelf.entries = entries strongSelf.hasLeftEntries = view.hasEarlier strongSelf.hasRightEntries = view.hasLater - strongSelf.centralEntryStableId = centralEntryStableId + if strongSelf.centralEntryStableId == nil { + strongSelf.centralEntryStableId = centralEntryStableId + } } if strongSelf.isViewLoaded { var items: [GalleryItem] = [] @@ -547,13 +565,17 @@ public class GalleryController: ViewController, StandalonePresentableController strongSelf.galleryNode.pager.replaceItems(items, centralItemIndex: centralItemIndex) if strongSelf.temporaryDoNotWaitForReady { - strongSelf.didSetReady = true - strongSelf._ready.set(.single(true)) - } else { - let ready = strongSelf.galleryNode.pager.ready() |> timeout(2.0, queue: Queue.mainQueue(), alternate: .single(Void())) |> afterNext { [weak strongSelf] _ in - strongSelf?.didSetReady = true + if !strongSelf.didSetReady { + strongSelf.didSetReady = true + strongSelf._ready.set(.single(true)) + } + } else { + if !strongSelf.didSetReady { + let ready = strongSelf.galleryNode.pager.ready() |> timeout(2.0, queue: Queue.mainQueue(), alternate: .single(Void())) |> afterNext { [weak strongSelf] _ in + strongSelf?.didSetReady = true + } + strongSelf._ready.set(ready |> map { true }) } - strongSelf._ready.set(ready |> map { true }) } } } @@ -568,7 +590,7 @@ public class GalleryController: ViewController, StandalonePresentableController return (true, nil) } semaphore?.signal() - if process { + if process || true { Queue.mainQueue().async { f() } diff --git a/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift b/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift index 310b5bcb7f..ecd6cbea61 100644 --- a/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift +++ b/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift @@ -1482,7 +1482,27 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode { let baseNavigationController = self.baseNavigationController() let mediaManager = self.context.sharedContext.mediaManager var expandImpl: (() -> Void)? - let overlayNode = OverlayUniversalVideoNode(postbox: self.context.account.postbox, audioSession: context.sharedContext.mediaManager.audioSession, manager: context.sharedContext.mediaManager.universalVideoManager, content: item.content, expand: { + + let shouldBeDismissed: Signal + if let contentInfo = item.contentInfo, case let .message(message) = contentInfo { + let viewKey = PostboxViewKey.messages(Set([message.id])) + shouldBeDismissed = context.account.postbox.combinedView(keys: [viewKey]) + |> map { views -> Bool in + guard let view = views.views[viewKey] as? MessagesView else { + return false + } + if view.messages.isEmpty { + return true + } else { + return false + } + } + |> distinctUntilChanged + } else { + shouldBeDismissed = .single(false) + } + + let overlayNode = OverlayUniversalVideoNode(postbox: self.context.account.postbox, audioSession: context.sharedContext.mediaManager.audioSession, manager: context.sharedContext.mediaManager.universalVideoManager, content: item.content, shouldBeDismissed: shouldBeDismissed, expand: { expandImpl?() }, close: { [weak mediaManager] in mediaManager?.setOverlayVideoNode(nil) diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index c79282227c..f1252a5dfd 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -128,6 +128,7 @@ struct ChatHistoryView { let associatedData: ChatMessageItemAssociatedData let lastHeaderId: Int64 let id: Int32 + let locationInput: ChatHistoryLocationInput? } enum ChatHistoryViewTransitionReason { @@ -705,7 +706,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { let currentViewVersion = Atomic(value: nil) - let historyViewUpdate: Signal<(ChatHistoryViewUpdate, Int), NoError> + let historyViewUpdate: Signal<(ChatHistoryViewUpdate, Int, ChatHistoryLocationInput?), NoError> var isFirstTime = true if case let .custom(messages, at, _) = source { historyViewUpdate = messages @@ -726,7 +727,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { scrollPosition = nil } - return (ChatHistoryViewUpdate.HistoryView(view: MessageHistoryView(tagMask: nil, namespaces: .all, entries: messages.reversed().map { MessageHistoryEntry(message: $0, isRead: false, location: nil, monthLocation: nil, attributes: MutableMessageHistoryEntryAttributes(authorIsContact: false)) }, holeEarlier: hasMore), type: .Generic(type: ViewUpdateType.Initial), scrollPosition: scrollPosition, flashIndicators: false, originalScrollPosition: nil, initialData: ChatHistoryCombinedInitialData(initialData: nil, buttonKeyboardMessage: nil, cachedData: nil, cachedDataMessages: nil, readStateData: nil), id: 0), version) + return (ChatHistoryViewUpdate.HistoryView(view: MessageHistoryView(tagMask: nil, namespaces: .all, entries: messages.reversed().map { MessageHistoryEntry(message: $0, isRead: false, location: nil, monthLocation: nil, attributes: MutableMessageHistoryEntryAttributes(authorIsContact: false)) }, holeEarlier: hasMore), type: .Generic(type: ViewUpdateType.Initial), scrollPosition: scrollPosition, flashIndicators: false, originalScrollPosition: nil, initialData: ChatHistoryCombinedInitialData(initialData: nil, buttonKeyboardMessage: nil, cachedData: nil, cachedDataMessages: nil, readStateData: nil), id: 0), version, nil) } } else { historyViewUpdate = self.chatHistoryLocationPromise.get() @@ -741,16 +742,16 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { break } } - } - |> map { view -> (ChatHistoryViewUpdate, Int) in - let version = currentViewVersion.modify({ value in - if let value = value { - return value + 1 - } else { - return 0 - } - })! - return (view, version) + |> map { view -> (ChatHistoryViewUpdate, Int, ChatHistoryLocationInput?) in + let version = currentViewVersion.modify({ value in + if let value = value { + return value + 1 + } else { + return 0 + } + })! + return (view, version, location) + } } } @@ -875,6 +876,10 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { func applyHole() { Queue.mainQueue().async { if let strongSelf = self { + if update.2 != strongSelf.chatHistoryLocationValue { + return + } + let historyView = (strongSelf.opaqueTransactionState as? ChatHistoryTransactionOpaqueState)?.historyView let displayRange = strongSelf.displayedItemRange if let filteredEntries = historyView?.filteredEntries, let visibleRange = displayRange.visibleRange { @@ -954,7 +959,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { let filteredEntries = chatHistoryEntriesForView(location: chatLocation, view: view, includeUnreadEntry: mode == .bubbles, includeEmptyEntry: mode == .bubbles && tagMask == nil, includeChatInfoEntry: mode == .bubbles, includeSearchEntry: includeSearchEntry && tagMask != nil, reverse: reverse, groupMessages: mode == .bubbles, selectedMessages: selectedMessages, presentationData: chatPresentationData, historyAppearsCleared: historyAppearsCleared, pendingUnpinnedAllMessages: pendingUnpinnedAllMessages, pendingRemovedMessages: pendingRemovedMessages, associatedData: associatedData, updatingMedia: updatingMedia, customChannelDiscussionReadState: customChannelDiscussionReadState, customThreadOutgoingReadState: customThreadOutgoingReadState) let lastHeaderId = filteredEntries.last.flatMap { listMessageDateHeaderId(timestamp: $0.index.timestamp) } ?? 0 - let processedView = ChatHistoryView(originalView: view, filteredEntries: filteredEntries, associatedData: associatedData, lastHeaderId: lastHeaderId, id: id) + let processedView = ChatHistoryView(originalView: view, filteredEntries: filteredEntries, associatedData: associatedData, lastHeaderId: lastHeaderId, id: id, locationInput: update.2) let previousValueAndVersion = previousView.swap((processedView, update.1, selectedMessages)) let previous = previousValueAndVersion?.0 let previousSelectedMessages = previousValueAndVersion?.2 @@ -1476,7 +1481,9 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { self.chatHistoryLocationValue = ChatHistoryLocationInput(content: locationInput, id: self.takeNextHistoryLocationId()) } } else if loaded.firstIndex < 5, historyView.originalView.laterId == nil, !historyView.originalView.holeLater, let chatHistoryLocationValue = self.chatHistoryLocationValue, !chatHistoryLocationValue.isAtUpperBound, historyView.originalView.anchorIndex != .upperBound { - self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Navigation(index: .upperBound, anchorIndex: .upperBound, count: historyMessageCount, highlight: false), id: self.takeNextHistoryLocationId()) + if self.chatHistoryLocationValue == historyView.locationInput { + self.chatHistoryLocationValue = ChatHistoryLocationInput(content: .Navigation(index: .upperBound, anchorIndex: .upperBound, count: historyMessageCount, highlight: false), id: self.takeNextHistoryLocationId()) + } } else if loaded.lastIndex >= historyView.filteredEntries.count - 5 && historyView.originalView.earlierId != nil { let locationInput: ChatHistoryLocation = .Navigation(index: .message(firstEntry.index), anchorIndex: .message(firstEntry.index), count: historyMessageCount, highlight: false) if self.chatHistoryLocationValue?.content != locationInput { diff --git a/submodules/TelegramUniversalVideoContent/Sources/OverlayUniversalVideoNode.swift b/submodules/TelegramUniversalVideoContent/Sources/OverlayUniversalVideoNode.swift index 2068dadf88..da44ebe879 100644 --- a/submodules/TelegramUniversalVideoContent/Sources/OverlayUniversalVideoNode.swift +++ b/submodules/TelegramUniversalVideoContent/Sources/OverlayUniversalVideoNode.swift @@ -16,6 +16,8 @@ public final class OverlayUniversalVideoNode: OverlayMediaItemNode { private var validLayoutSize: CGSize? + private var shouldBeDismissedDisposable: Disposable? + override public var group: OverlayMediaItemNodeGroup? { return OverlayMediaItemNodeGroup(rawValue: 0) } @@ -35,7 +37,7 @@ public final class OverlayUniversalVideoNode: OverlayMediaItemNode { public var customClose: (() -> Void)? public var controlsAreShowingUpdated: ((Bool) -> Void)? - public init(postbox: Postbox, audioSession: ManagedAudioSession, manager: UniversalVideoManager, content: UniversalVideoContent, expand: @escaping () -> Void, close: @escaping () -> Void) { + public init(postbox: Postbox, audioSession: ManagedAudioSession, manager: UniversalVideoManager, content: UniversalVideoContent, shouldBeDismissed: Signal = .single(false), expand: @escaping () -> Void, close: @escaping () -> Void) { self.content = content self.defaultExpand = expand @@ -112,6 +114,16 @@ public final class OverlayUniversalVideoNode: OverlayMediaItemNode { } self.videoNode.canAttachContent = true + + self.shouldBeDismissedDisposable = (shouldBeDismissed + |> filter { $0 } + |> deliverOnMainQueue).start(next: { [weak self] _ in + guard let strongSelf = self else { + return + } + strongSelf.dismiss() + closeImpl?() + }) } override public func didLoad() {