diff --git a/submodules/MediaPlayer/Sources/MediaPlayer.swift b/submodules/MediaPlayer/Sources/MediaPlayer.swift index 190a4bced3..cadb46bfa5 100644 --- a/submodules/MediaPlayer/Sources/MediaPlayer.swift +++ b/submodules/MediaPlayer/Sources/MediaPlayer.swift @@ -814,7 +814,7 @@ private final class MediaPlayerContext { } else if case let .buffering(progress) = worstStatus { bufferingProgress = Float(progress) rate = 0.0 - print("bufferingProgress = \(progress)") + //print("bufferingProgress = \(progress)") let tickTimer = SwiftSignalKit.Timer(timeout: 0.3, repeat: false, completion: { [weak self] in self?.tick() diff --git a/submodules/PeerAvatarGalleryUI/Sources/AvatarGalleryController.swift b/submodules/PeerAvatarGalleryUI/Sources/AvatarGalleryController.swift index 39fa7faa48..563ea8839f 100644 --- a/submodules/PeerAvatarGalleryUI/Sources/AvatarGalleryController.swift +++ b/submodules/PeerAvatarGalleryUI/Sources/AvatarGalleryController.swift @@ -24,7 +24,7 @@ public enum AvatarGalleryEntryId: Hashable { public enum AvatarGalleryEntry: Equatable { case topImage([ImageRepresentationWithReference], [VideoRepresentationWithReference], Peer?, GalleryItemIndexData?, Data?, String?) - case image(MediaId, TelegramMediaImageReference?, [ImageRepresentationWithReference], [VideoRepresentationWithReference], Peer?, Int32, GalleryItemIndexData?, MessageId?, Data?, String?) + case image(MediaId, TelegramMediaImageReference?, [ImageRepresentationWithReference], [VideoRepresentationWithReference], Peer?, Int32?, GalleryItemIndexData?, MessageId?, Data?, String?) public var id: AvatarGalleryEntryId { switch self { @@ -148,14 +148,10 @@ public func initialAvatarGalleryEntries(account: Account, peer: Peer) -> Signal< initialPhoto = photo } - if let photo = initialPhoto, !photo.videoRepresentations.isEmpty { - return [.topImage(photo.representations.map({ ImageRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatar(peer: peerReference, resource: $0.resource)) }), photo.videoRepresentations.map({ VideoRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatar(peer: peerReference, resource: $0.resource)) }), peer, nil, photo.immediateThumbnailData, nil)] + 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)] } else { - if !peer.profileImageRepresentations.isEmpty { - return [.topImage(peer.profileImageRepresentations.map({ ImageRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatar(peer: peerReference, resource: $0.resource)) }), [], peer, nil, initialPhoto?.immediateThumbnailData, nil)] - } else { - return [] - } + return [] } } } else { @@ -175,14 +171,42 @@ public func fetchedAvatarGalleryEntries(account: Account, peer: Peer) -> Signal< result = initialEntries } else if let peerReference = PeerReference(peer) { var index: Int32 = 0 - for photo in photos { - let indexData = GalleryItemIndexData(position: index, totalCount: Int32(photos.count)) - if result.isEmpty, let first = initialEntries.first { - result.append(.image(photo.image.imageId, photo.image.reference, first.representations, photo.image.videoRepresentations.map({ VideoRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatarList(peer: peerReference, resource: $0.resource)) }), peer, photo.date, indexData, photo.messageId, photo.image.immediateThumbnailData, nil)) - } else { - result.append(.image(photo.image.imageId, photo.image.reference, photo.image.representations.map({ ImageRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatarList(peer: peerReference, resource: $0.resource)) }), photo.image.videoRepresentations.map({ VideoRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatarList(peer: peerReference, resource: $0.resource)) }), peer, photo.date, indexData, photo.messageId, photo.image.immediateThumbnailData, nil)) + if [Namespaces.Peer.CloudGroup, Namespaces.Peer.CloudChannel].contains(peer.id.namespace) { + var initialMediaIds = Set() + for entry in initialEntries { + if case let .image(image) = entry { + initialMediaIds.insert(image.0) + } + } + + var photosCount = photos.count + for i in 0 ..< photos.count { + let photo = photos[i] + if i == 0 && !initialMediaIds.contains(photo.image.imageId) { + photosCount += 1 + for entry in initialEntries { + let indexData = GalleryItemIndexData(position: index, totalCount: Int32(photosCount)) + if case let .image(image) = entry { + result.append(.image(image.0, image.1, image.2, image.3, image.4, nil, indexData, nil, image.8, nil)) + index += 1 + } + } + } + + let indexData = GalleryItemIndexData(position: index, totalCount: Int32(photosCount)) + result.append(.image(photo.image.imageId, photo.image.reference, photo.image.representations.map({ ImageRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatarList(peer: peerReference, resource: $0.resource)) }), photo.image.videoRepresentations.map({ VideoRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatarList(peer: peerReference, resource: $0.resource)) }), peer, photo.date, indexData, photo.messageId, photo.image.immediateThumbnailData, nil)) + index += 1 + } + } else { + for photo in photos { + let indexData = GalleryItemIndexData(position: index, totalCount: Int32(photos.count)) + if result.isEmpty, let first = initialEntries.first { + result.append(.image(photo.image.imageId, photo.image.reference, first.representations, photo.image.videoRepresentations.map({ VideoRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatarList(peer: peerReference, resource: $0.resource)) }), peer, photo.date, indexData, photo.messageId, photo.image.immediateThumbnailData, nil)) + } else { + result.append(.image(photo.image.imageId, photo.image.reference, photo.image.representations.map({ ImageRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatarList(peer: peerReference, resource: $0.resource)) }), photo.image.videoRepresentations.map({ VideoRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatarList(peer: peerReference, resource: $0.resource)) }), peer, photo.date, indexData, photo.messageId, photo.image.immediateThumbnailData, nil)) + } + index += 1 } - index += 1 } } return result @@ -203,14 +227,43 @@ public func fetchedAvatarGalleryEntries(account: Account, peer: Peer, firstEntry result = initialEntries } else if let peerReference = PeerReference(peer) { var index: Int32 = 0 - for photo in photos { - let indexData = GalleryItemIndexData(position: index, totalCount: Int32(photos.count)) - if result.isEmpty, let first = initialEntries.first { - result.append(.image(photo.image.imageId, photo.image.reference, first.representations, photo.image.videoRepresentations.map({ VideoRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatarList(peer: peerReference, resource: $0.resource)) }), peer, photo.date, indexData, photo.messageId, photo.image.immediateThumbnailData, nil)) - } else { - result.append(.image(photo.image.imageId, photo.image.reference, photo.image.representations.map({ ImageRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatarList(peer: peerReference, resource: $0.resource)) }), photo.image.videoRepresentations.map({ VideoRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatarList(peer: peerReference, resource: $0.resource)) }), peer, photo.date, indexData, photo.messageId, photo.image.immediateThumbnailData, nil)) + + if [Namespaces.Peer.CloudGroup, Namespaces.Peer.CloudChannel].contains(peer.id.namespace) { + var initialMediaIds = Set() + for entry in initialEntries { + if case let .image(image) = entry { + initialMediaIds.insert(image.0) + } + } + + var photosCount = photos.count + for i in 0 ..< photos.count { + let photo = photos[i] + if i == 0 && !initialMediaIds.contains(photo.image.imageId) { + photosCount += 1 + for entry in initialEntries { + let indexData = GalleryItemIndexData(position: index, totalCount: Int32(photosCount)) + if case let .image(image) = entry { + result.append(.image(image.0, image.1, image.2, image.3, image.4, nil, indexData, nil, image.8, nil)) + index += 1 + } + } + } + + let indexData = GalleryItemIndexData(position: index, totalCount: Int32(photosCount)) + result.append(.image(photo.image.imageId, photo.image.reference, photo.image.representations.map({ ImageRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatarList(peer: peerReference, resource: $0.resource)) }), photo.image.videoRepresentations.map({ VideoRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatarList(peer: peerReference, resource: $0.resource)) }), peer, photo.date, indexData, photo.messageId, photo.image.immediateThumbnailData, nil)) + index += 1 + } + } else { + for photo in photos { + let indexData = GalleryItemIndexData(position: index, totalCount: Int32(photos.count)) + if result.isEmpty, let first = initialEntries.first { + result.append(.image(photo.image.imageId, photo.image.reference, first.representations, photo.image.videoRepresentations.map({ VideoRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatarList(peer: peerReference, resource: $0.resource)) }), peer, photo.date, indexData, photo.messageId, photo.image.immediateThumbnailData, nil)) + } else { + result.append(.image(photo.image.imageId, photo.image.reference, photo.image.representations.map({ ImageRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatarList(peer: peerReference, resource: $0.resource)) }), photo.image.videoRepresentations.map({ VideoRepresentationWithReference(representation: $0, reference: MediaResourceReference.avatarList(peer: peerReference, resource: $0.resource)) }), peer, photo.date, indexData, photo.messageId, photo.image.immediateThumbnailData, nil)) + } + index += 1 } - index += 1 } } return result diff --git a/submodules/PeerAvatarGalleryUI/Sources/AvatarGalleryItemFooterContentNode.swift b/submodules/PeerAvatarGalleryUI/Sources/AvatarGalleryItemFooterContentNode.swift index 75dbe97de5..280f1bca0a 100644 --- a/submodules/PeerAvatarGalleryUI/Sources/AvatarGalleryItemFooterContentNode.swift +++ b/submodules/PeerAvatarGalleryUI/Sources/AvatarGalleryItemFooterContentNode.swift @@ -109,8 +109,10 @@ final class AvatarGalleryItemFooterContentNode: GalleryFooterContentNode { switch entry { case let .image(_, _, _, videoRepresentations, peer, date, _, _, _, _): nameText = peer?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "" - dateText = humanReadableStringForTimestamp(strings: self.strings, dateTimeFormat: self.dateTimeFormat, timestamp: date) - + if let date = date { + dateText = humanReadableStringForTimestamp(strings: self.strings, dateTimeFormat: self.dateTimeFormat, timestamp: date) + } + if (!videoRepresentations.isEmpty) { typeText = self.strings.ProfilePhoto_MainVideo buttonText = self.strings.ProfilePhoto_SetMainVideo diff --git a/submodules/SettingsUI/Sources/Data and Storage/StorageUsageController.swift b/submodules/SettingsUI/Sources/Data and Storage/StorageUsageController.swift index 9b9882a2b2..e76d3bea1b 100644 --- a/submodules/SettingsUI/Sources/Data and Storage/StorageUsageController.swift +++ b/submodules/SettingsUI/Sources/Data and Storage/StorageUsageController.swift @@ -291,9 +291,9 @@ private func storageUsageControllerEntries(presentationData: PresentationData, c entries.append(.keepMedia(presentationData.theme, presentationData.strings, cacheSettings.defaultCacheStorageTimeout)) entries.append(.keepMediaInfo(presentationData.theme, presentationData.strings.Cache_KeepMediaHelp)) - entries.append(.maximumSizeHeader(presentationData.theme, presentationData.strings.Cache_MaximumCacheSize.uppercased())) + /*entries.append(.maximumSizeHeader(presentationData.theme, presentationData.strings.Cache_MaximumCacheSize.uppercased())) entries.append(.maximumSize(presentationData.theme, presentationData.strings, cacheSettings.defaultCacheStorageLimitGigabytes)) - entries.append(.maximumSizeInfo(presentationData.theme, presentationData.strings.Cache_MaximumCacheSizeHelp)) + entries.append(.maximumSizeInfo(presentationData.theme, presentationData.strings.Cache_MaximumCacheSizeHelp))*/ var addedHeader = false diff --git a/submodules/TelegramApi/Sources/Api3.swift b/submodules/TelegramApi/Sources/Api3.swift index d4e63b4654..c3c2f25f4a 100644 --- a/submodules/TelegramApi/Sources/Api3.swift +++ b/submodules/TelegramApi/Sources/Api3.swift @@ -6767,20 +6767,6 @@ public extension Api { } } public struct photos { - public static func updateProfilePhoto(id: Api.InputPhoto) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { - let buffer = Buffer() - buffer.appendInt32(-256159406) - id.serialize(buffer, true) - return (FunctionDescription(name: "photos.updateProfilePhoto", parameters: [("id", id)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.UserProfilePhoto? in - let reader = BufferReader(buffer) - var result: Api.UserProfilePhoto? - if let signature = reader.readInt32() { - result = Api.parse(reader, signature: signature) as? Api.UserProfilePhoto - } - return result - }) - } - public static func deletePhotos(id: [Api.InputPhoto]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<[Int64]>) { let buffer = Buffer() buffer.appendInt32(-2016444625) @@ -6832,6 +6818,20 @@ public extension Api { return result }) } + + public static func updateProfilePhoto(id: Api.InputPhoto) -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { + let buffer = Buffer() + buffer.appendInt32(1926525996) + id.serialize(buffer, true) + return (FunctionDescription(name: "photos.updateProfilePhoto", parameters: [("id", id)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.photos.Photo? in + let reader = BufferReader(buffer) + var result: Api.photos.Photo? + if let signature = reader.readInt32() { + result = Api.parse(reader, signature: signature) as? Api.photos.Photo + } + return result + }) + } } public struct phone { public static func getCallConfig() -> (FunctionDescription, Buffer, DeserializeFunctionResponse) { diff --git a/submodules/TelegramCore/Sources/AccountStateManagementUtils.swift b/submodules/TelegramCore/Sources/AccountStateManagementUtils.swift index 0cbadc4b43..76501f517a 100644 --- a/submodules/TelegramCore/Sources/AccountStateManagementUtils.swift +++ b/submodules/TelegramCore/Sources/AccountStateManagementUtils.swift @@ -2858,7 +2858,8 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP } } - for (peerIdAndNamespace, pts) in clearHolesFromPreviousStateForChannelMessagesWithPts { + // could be the reason for unbounded slowdown, needs investigation + /*for (peerIdAndNamespace, pts) in clearHolesFromPreviousStateForChannelMessagesWithPts { var upperMessageId: Int32? var lowerMessageId: Int32? transaction.scanMessageAttributes(peerId: peerIdAndNamespace.peerId, namespace: peerIdAndNamespace.namespace, { id, attributes in @@ -2886,7 +2887,7 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP transaction.removeHole(peerId: peerIdAndNamespace.peerId, namespace: peerIdAndNamespace.namespace, space: .everywhere, range: lowerMessageId ... upperMessageId) } } - } + }*/ if !peerActivityTimestamps.isEmpty { updatePeerPresenceLastActivities(transaction: transaction, accountPeerId: accountPeerId, activities: peerActivityTimestamps) diff --git a/submodules/TelegramCore/Sources/PeerPhotoUpdater.swift b/submodules/TelegramCore/Sources/PeerPhotoUpdater.swift index 9aac08971b..804707580f 100644 --- a/submodules/TelegramCore/Sources/PeerPhotoUpdater.swift +++ b/submodules/TelegramCore/Sources/PeerPhotoUpdater.swift @@ -294,10 +294,12 @@ public func updatePeerPhotoInternal(postbox: Postbox, network: Network, stateMan } } else { if let _ = peer as? TelegramUser { - return network.request(Api.functions.photos.updateProfilePhoto(id: Api.InputPhoto.inputPhotoEmpty)) - |> `catch` { _ -> Signal in - return .fail(.generic) + let signal: Signal = network.request(Api.functions.photos.updateProfilePhoto(id: Api.InputPhoto.inputPhotoEmpty)) + |> mapError { _ -> UploadPeerPhotoError in + return .generic } + + return signal |> mapToSignal { _ -> Signal in return .single(.complete([])) } @@ -341,7 +343,7 @@ public func updatePeerPhotoExisting(network: Network, reference: TelegramMediaIm switch reference { case let .cloud(imageId, accessHash, fileReference): return network.request(Api.functions.photos.updateProfilePhoto(id: .inputPhoto(id: imageId, accessHash: accessHash, fileReference: Buffer(data: fileReference)))) - |> `catch` { _ -> Signal in + |> `catch` { _ -> Signal in return .complete() } |> mapToSignal { _ -> Signal in diff --git a/submodules/TelegramUI/Sources/ChatMessageActionItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageActionItemNode.swift index e12c9fc369..c1424d1579 100644 --- a/submodules/TelegramUI/Sources/ChatMessageActionItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageActionItemNode.swift @@ -221,7 +221,7 @@ class ChatMessageActionBubbleContentNode: ChatMessageBubbleContentNode { strongSelf.mediaBackgroundNode.image = backgroundImage if let image = image, let video = image.videoRepresentations.last, let id = image.id?.id { - let videoFileReference = FileMediaReference.standalone(media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: video.resource, previewRepresentations: image.representations, videoThumbnails: [], immediateThumbnailData: image.immediateThumbnailData, mimeType: "video/mp4", size: nil, attributes: [.Animated, .Video(duration: 0, size: video.dimensions, flags: [])])) + let videoFileReference = FileMediaReference.message(message: MessageReference(item.message), media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: video.resource, previewRepresentations: image.representations, videoThumbnails: [], immediateThumbnailData: image.immediateThumbnailData, mimeType: "video/mp4", size: nil, attributes: [.Animated, .Video(duration: 0, size: video.dimensions, flags: [])])) let videoContent = NativeVideoContent(id: .profileVideo(id, "action"), fileReference: videoFileReference, streamVideo: isMediaStreamable(resource: video.resource) ? .conservative : .none, loopVideo: true, enableSound: false, fetchAutomatically: true, onlyFullSizeThumbnail: false, useLargeThumbnail: true, autoFetchFullSizeThumbnail: true, continuePlayingWithoutSoundOnLostAudioSession: false, placeholderColor: .clear) if videoContent.id != strongSelf.videoContent?.id { let mediaManager = item.context.sharedContext.mediaManager diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift index 70688ffb61..510d6a4e41 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift @@ -217,12 +217,7 @@ final class PeerInfoAvatarListItemNode: ASDisplayNode { private var statusPromise = Promise<(MediaPlayerStatus?, Double?)?>() var mediaStatus: Signal<(MediaPlayerStatus?, Double?)?, NoError> { get { - if let videoNode = self.videoNode { - let videoStartTimestamp = self.videoStartTimestamp - return videoNode.status |> map { ($0, videoStartTimestamp) } - } else { - return self.statusPromise.get() - } + return self.statusPromise.get() } } @@ -284,7 +279,7 @@ final class PeerInfoAvatarListItemNode: ASDisplayNode { return } if isLoading, let progress = progress { - strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: CGFloat(progress), cancelEnabled: false), completion: {}) + strongSelf.statusNode.transitionToState(.progress(color: .white, lineWidth: nil, value: CGFloat(max(0.027, progress)), cancelEnabled: false), completion: {}) } else { strongSelf.statusNode.transitionToState(.none, completion: {}) } @@ -307,7 +302,6 @@ final class PeerInfoAvatarListItemNode: ASDisplayNode { if let playerStatus = self.playerStatus { if case let .buffering(_, _, progress) = playerStatus.status { bufferingProgress = progress - print(progress) } else if case .playing = playerStatus.status { bufferingProgress = nil } diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index ade4e2e3d6..e6d73a5364 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -3847,18 +3847,6 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD } } } - - private func setMainAvatar(_ item: PeerInfoAvatarListItem) { - if self.data?.peer?.id == self.context.account.peerId { - if case let .image(reference, _, _, _) = item { - if let reference = reference { - let _ = updatePeerPhotoExisting(network: self.context.account.network, reference: reference).start() - self.headerNode.avatarListNode.listContainerNode.setMainItem(item) - - } - } - } - } private func deleteAvatar(_ item: PeerInfoAvatarListItem, remove: Bool = true) { if self.data?.peer?.id == self.context.account.peerId { @@ -3880,28 +3868,6 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD } } } -// if entry == self.entries.first { -// self.dismiss(forceAway: true) -// } else { -// if let index = self.entries.firstIndex(of: entry) { -// self.entries.remove(at: index) -// self.galleryNode.pager.transaction(GalleryPagerTransaction(deleteItems: [index], insertItems: [], updateItems: [], focusOnItem: index - 1, synchronous: false)) -// } -// } - } else { -// if let messageId = messageId { -// let _ = deleteMessagesInteractively(account: self.context.account, messageIds: [messageId], type: .forEveryone).start() -// } - -// if entry == self.entries.first { -// let _ = updatePeerPhoto(postbox: self.context.account.postbox, network: self.context.account.network, stateManager: self.context.account.stateManager, accountPeerId: self.context.account.peerId, peerId: self.peer.id, photo: nil, mapResourceToAvatarSizes: { _, _ in .single([:]) }).start() -// self.dismiss(forceAway: true) -// } else { -// if let index = self.entries.firstIndex(of: entry) { -// self.entries.remove(at: index) -// self.galleryNode.pager.transaction(GalleryPagerTransaction(deleteItems: [index], insertItems: [], updateItems: [], focusOnItem: index - 1, synchronous: false)) -// } -// } } } @@ -3949,18 +3915,6 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD } })) } - - fileprivate func resetHeaderExpansion() { - if self.headerNode.isAvatarExpanded { - self.headerNode.ignoreCollapse = true - self.headerNode.updateIsAvatarExpanded(false, transition: .immediate) - self.updateNavigationExpansionPresentation(isExpanded: false, animated: true) - if let (layout, navigationHeight) = self.validLayout { - self.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .immediate, additive: false) - } - self.headerNode.ignoreCollapse = false - } - } private func updateProfileVideo(_ image: UIImage, asset: Any?, adjustments: TGVideoEditAdjustments?) { guard let data = image.jpegData(compressionQuality: 0.6) else { @@ -4182,35 +4136,55 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD return } - if let item = item { - strongSelf.deleteAvatar(item, remove: false) - } - - let _ = strongSelf.currentAvatarMixin.swap(nil) - if let _ = peer.smallProfileImage { - strongSelf.state = strongSelf.state.withUpdatingAvatar(nil) - if let (layout, navigationHeight) = strongSelf.validLayout { - strongSelf.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .immediate, additive: false) + let proceed = { + if let item = item { + strongSelf.deleteAvatar(item, remove: false) } - } - let postbox = strongSelf.context.account.postbox - strongSelf.updateAvatarDisposable.set((updatePeerPhoto(postbox: strongSelf.context.account.postbox, network: strongSelf.context.account.network, stateManager: strongSelf.context.account.stateManager, accountPeerId: strongSelf.context.account.peerId, peerId: strongSelf.peerId, photo: nil, mapResourceToAvatarSizes: { resource, representations in - return mapResourceToAvatarSizes(postbox: postbox, resource: resource, representations: representations) - }) - |> deliverOnMainQueue).start(next: { result in - guard let strongSelf = self else { - return - } - switch result { - case .complete: + + let _ = strongSelf.currentAvatarMixin.swap(nil) + if let _ = peer.smallProfileImage { strongSelf.state = strongSelf.state.withUpdatingAvatar(nil) if let (layout, navigationHeight) = strongSelf.validLayout { strongSelf.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .immediate, additive: false) } - case .progress: - break } - })) + let postbox = strongSelf.context.account.postbox + strongSelf.updateAvatarDisposable.set((updatePeerPhoto(postbox: strongSelf.context.account.postbox, network: strongSelf.context.account.network, stateManager: strongSelf.context.account.stateManager, accountPeerId: strongSelf.context.account.peerId, peerId: strongSelf.peerId, photo: nil, mapResourceToAvatarSizes: { resource, representations in + return mapResourceToAvatarSizes(postbox: postbox, resource: resource, representations: representations) + }) + |> deliverOnMainQueue).start(next: { result in + guard let strongSelf = self else { + return + } + switch result { + case .complete: + strongSelf.state = strongSelf.state.withUpdatingAvatar(nil) + if let (layout, navigationHeight) = strongSelf.validLayout { + strongSelf.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .immediate, additive: false) + } + case .progress: + break + } + })) + } + + let actionSheet = ActionSheetController(presentationData: presentationData) + let items: [ActionSheetItem] = [ + ActionSheetButtonItem(title: presentationData.strings.Settings_RemoveConfirmation, color: .destructive, action: { [weak actionSheet] in + actionSheet?.dismissAnimated() + proceed() + }) + ] + + actionSheet.setItemGroups([ + ActionSheetItemGroup(items: items), + ActionSheetItemGroup(items: [ + ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in + actionSheet?.dismissAnimated() + }) + ]) + ]) + strongSelf.controller?.present(actionSheet, in: .window(.root)) } mixin.didDismiss = { [weak legacyController] in guard let strongSelf = self else { @@ -5373,6 +5347,18 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD } } + fileprivate func resetHeaderExpansion() { + if self.headerNode.isAvatarExpanded { + self.headerNode.ignoreCollapse = true + self.headerNode.updateIsAvatarExpanded(false, transition: .immediate) + self.updateNavigationExpansionPresentation(isExpanded: false, animated: true) + if let (layout, navigationHeight) = self.validLayout { + self.containerLayoutUpdated(layout: layout, navigationHeight: navigationHeight, transition: .immediate, additive: false) + } + self.headerNode.ignoreCollapse = false + } + } + private func updateNavigationExpansionPresentation(isExpanded: Bool, animated: Bool) { if let controller = self.controller { controller.setStatusBarStyle(isExpanded ? .White : self.presentationData.theme.rootController.statusBarStyle.style, animated: animated)