diff --git a/submodules/PeerAvatarGalleryUI/Sources/AvatarGalleryController.swift b/submodules/PeerAvatarGalleryUI/Sources/AvatarGalleryController.swift index e2e02eea2d..720e8d6bec 100644 --- a/submodules/PeerAvatarGalleryUI/Sources/AvatarGalleryController.swift +++ b/submodules/PeerAvatarGalleryUI/Sources/AvatarGalleryController.swift @@ -149,7 +149,11 @@ public func initialAvatarGalleryEntries(account: Account, peer: Peer) -> Signal< } if let photo = initialPhoto { - return [.image(photo.imageId, photo.reference, photo.representations.map({ ImageRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatar(peer: peerReference, resource: $0.resource)) }), photo.videoRepresentations.map({ VideoRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatarList(peer: peerReference, resource: $0.resource)) }), peer, nil, nil, nil, photo.immediateThumbnailData, nil)] + if photo.immediateThumbnailData == nil { + return initialEntries + } else { + return [.image(photo.imageId, photo.reference, photo.representations.map({ ImageRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatar(peer: peerReference, resource: $0.resource)) }), photo.videoRepresentations.map({ VideoRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatarList(peer: peerReference, resource: $0.resource)) }), peer, nil, nil, nil, photo.immediateThumbnailData, nil)] + } } else { return [] } @@ -215,12 +219,12 @@ public func fetchedAvatarGalleryEntries(account: Account, peer: Peer) -> Signal< } } -public func fetchedAvatarGalleryEntries(account: Account, peer: Peer, firstEntry: AvatarGalleryEntry) -> Signal<[AvatarGalleryEntry], NoError> { +public func fetchedAvatarGalleryEntries(account: Account, peer: Peer, firstEntry: AvatarGalleryEntry) -> Signal<(Bool, [AvatarGalleryEntry]), NoError> { let initialEntries = [firstEntry] - return Signal<[AvatarGalleryEntry], NoError>.single(initialEntries) + return Signal<(Bool, [AvatarGalleryEntry]), NoError>.single((false, initialEntries)) |> then( requestPeerPhotos(postbox: account.postbox, network: account.network, peerId: peer.id) - |> map { photos -> [AvatarGalleryEntry] in + |> map { photos -> (Bool, [AvatarGalleryEntry]) in var result: [AvatarGalleryEntry] = [] let initialEntries = [firstEntry] if photos.isEmpty { @@ -266,7 +270,7 @@ public func fetchedAvatarGalleryEntries(account: Account, peer: Peer, firstEntry } } } - return result + return (true, result) } ) } diff --git a/submodules/Postbox/Sources/MediaBox.swift b/submodules/Postbox/Sources/MediaBox.swift index 014f45c1fd..3a3ff6f109 100644 --- a/submodules/Postbox/Sources/MediaBox.swift +++ b/submodules/Postbox/Sources/MediaBox.swift @@ -1105,4 +1105,22 @@ public final class MediaBox { return EmptyDisposable } } + + + + public func allFileContexts() -> Signal<[(partial: String, complete: String)], NoError> { + return Signal { subscriber in + self.dataQueue.async { + var result: [(partial: String, complete: String)] = [] + for (id, _) in self.fileContexts { + let paths = self.storePathsForId(id.id) + result.append((partial: paths.partial, complete: paths.complete)) + } + subscriber.putNext(result) + subscriber.putCompletion() + } + return EmptyDisposable + } + } + } diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 0d33bd2097..9a1d426759 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -5124,7 +5124,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G if peerId.namespace == Namespaces.Peer.CloudUser { self.preloadAvatarDisposable.set((peerInfoProfilePhotosWithCache(context: context, peerId: peerId) - |> mapToSignal { result -> Signal in + |> mapToSignal { (complete, result) -> Signal in var signals: [Signal] = [.complete()] for i in 0 ..< min(1, result.count) { if let video = result[i].videoRepresentations.first { diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoData.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoData.swift index f4024e2621..d4c6e967fc 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoData.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoData.swift @@ -328,14 +328,14 @@ private func peerInfoProfilePhotos(context: AccountContext, peerId: PeerId) -> S } } |> distinctUntilChanged - |> mapToSignal { firstEntry -> Signal<[AvatarGalleryEntry], NoError> in + |> mapToSignal { firstEntry -> Signal<(Bool, [AvatarGalleryEntry]), NoError> in if let firstEntry = firstEntry { return context.account.postbox.loadedPeerWithId(peerId) - |> mapToSignal { peer -> Signal<[AvatarGalleryEntry], NoError>in + |> mapToSignal { peer -> Signal<(Bool, [AvatarGalleryEntry]), NoError>in return fetchedAvatarGalleryEntries(account: context.account, peer: peer, firstEntry: firstEntry) } } else { - return .single([]) + return .single((true, [])) } } |> map { items -> Any in @@ -343,10 +343,10 @@ private func peerInfoProfilePhotos(context: AccountContext, peerId: PeerId) -> S } } -func peerInfoProfilePhotosWithCache(context: AccountContext, peerId: PeerId) -> Signal<[AvatarGalleryEntry], NoError> { +func peerInfoProfilePhotosWithCache(context: AccountContext, peerId: PeerId) -> Signal<(Bool, [AvatarGalleryEntry]), NoError> { return context.peerChannelMemberCategoriesContextsManager.profilePhotos(postbox: context.account.postbox, network: context.account.network, peerId: peerId, fetch: peerInfoProfilePhotos(context: context, peerId: peerId)) - |> map { items -> [AvatarGalleryEntry] in - return items as? [AvatarGalleryEntry] ?? [] + |> map { items -> (Bool, [AvatarGalleryEntry]) in + return items as? (Bool, [AvatarGalleryEntry]) ?? (true, []) } } diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift index 7c0f94300f..06c2bbd731 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift @@ -203,11 +203,11 @@ final class PeerInfoAvatarListItemNode: ASDisplayNode { private let preloadDisposable = MetaDisposable() private let statusNode: RadialStatusNode - private var playerStatus: MediaPlayerStatus? private var isLoading = ValuePromise(false) private var loadingProgress = ValuePromise(nil) private var loadingProgressDisposable = MetaDisposable() + private var hasProgress = false let isReady = Promise() private var didSetReady: Bool = false @@ -274,14 +274,25 @@ final class PeerInfoAvatarListItemNode: ASDisplayNode { } else { return .single(value) } - }, self.loadingProgress.get())).start(next: { [weak self] isLoading, progress in + } |> distinctUntilChanged, self.loadingProgress.get() |> distinctUntilChanged)).start(next: { [weak self] isLoading, progress in guard let strongSelf = self else { return } if isLoading, let progress = progress { + strongSelf.hasProgress = true strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: CGFloat(max(0.027, progress)), cancelEnabled: false), completion: {}) - } else { - strongSelf.statusNode.transitionToState(.none, completion: {}) + } else if strongSelf.hasProgress { + strongSelf.hasProgress = false + strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: 1.0, cancelEnabled: false), completion: { [weak self] in + guard let strongSelf = self else { + return + } + if !strongSelf.hasProgress { + Queue.mainQueue().after(0.3) { + strongSelf.statusNode.transitionToState(.none, completion: {}) + } + } + }) } })) } @@ -309,7 +320,6 @@ final class PeerInfoAvatarListItemNode: ASDisplayNode { bufferingProgress = nil } } - self.loadingProgress.set(bufferingProgress) self.isLoading.set(bufferingProgress != nil) } @@ -1043,12 +1053,12 @@ final class PeerInfoAvatarListContainerNode: ASDisplayNode { if let peer = peer, !self.initializedList { self.initializedList = true self.disposable.set((peerInfoProfilePhotosWithCache(context: self.context, peerId: peer.id) - |> deliverOnMainQueue).start(next: { [weak self] entries in + |> deliverOnMainQueue).start(next: { [weak self] (complete, entries) in guard let strongSelf = self else { return } - if strongSelf.galleryEntries.count > 1, entries.count == 1, let first = entries.first, case .topImage = first { + if strongSelf.galleryEntries.count > 1, entries.count == 1 && !complete { return } diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index e6d73a5364..76b09166f5 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -5389,12 +5389,14 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD guard let (_, navigationHeight) = self.validLayout else { return } - if self.state.isEditing && self.isSettings { - if targetContentOffset.pointee.y < navigationHeight { - if targetContentOffset.pointee.y < navigationHeight / 2.0 { - targetContentOffset.pointee.y = 0.0 - } else { - targetContentOffset.pointee.y = navigationHeight + if self.state.isEditing { + if self.isSettings { + if targetContentOffset.pointee.y < navigationHeight { + if targetContentOffset.pointee.y < navigationHeight / 2.0 { + targetContentOffset.pointee.y = 0.0 + } else { + targetContentOffset.pointee.y = navigationHeight + } } } } else {