diff --git a/submodules/AvatarNode/Sources/AvatarNode.swift b/submodules/AvatarNode/Sources/AvatarNode.swift index 79369bc56c..d9b2958c69 100644 --- a/submodules/AvatarNode/Sources/AvatarNode.swift +++ b/submodules/AvatarNode/Sources/AvatarNode.swift @@ -63,7 +63,7 @@ private class AvatarNodeParameters: NSObject { } } -private func calculateColors(explicitColorIndex: Int?, peerId: EnginePeer.Id?, icon: AvatarNodeIcon, theme: PresentationTheme?) -> [UIColor] { +private func calculateColors(explicitColorIndex: Int?, peerId: EnginePeer.Id?, nameColor: PeerNameColor?, icon: AvatarNodeIcon, theme: PresentationTheme?) -> [UIColor] { let colorIndex: Int if let explicitColorIndex = explicitColorIndex { colorIndex = explicitColorIndex @@ -110,7 +110,11 @@ private func calculateColors(explicitColorIndex: Int?, peerId: EnginePeer.Id?, i colors = AvatarNode.grayscaleColors } } else { - colors = AvatarNode.gradientColors[colorIndex % AvatarNode.gradientColors.count] + if let nameColor { + colors = AvatarNode.gradientColors[Int(nameColor.rawValue) % AvatarNode.gradientColors.count] + } else { + colors = AvatarNode.gradientColors[colorIndex % AvatarNode.gradientColors.count] + } } return colors @@ -122,7 +126,7 @@ public enum AvatarNodeExplicitIcon { private enum AvatarNodeState: Equatable { case empty - case peerAvatar(EnginePeer.Id, [String], TelegramMediaImageRepresentation?, AvatarNodeClipStyle) + case peerAvatar(EnginePeer.Id, PeerNameColor?, [String], TelegramMediaImageRepresentation?, AvatarNodeClipStyle) case custom(letter: [String], explicitColorIndex: Int?, explicitIcon: AvatarNodeExplicitIcon?) } @@ -130,8 +134,8 @@ private func ==(lhs: AvatarNodeState, rhs: AvatarNodeState) -> Bool { switch (lhs, rhs) { case (.empty, .empty): return true - case let (.peerAvatar(lhsPeerId, lhsLetters, lhsPhotoRepresentations, lhsClipStyle), .peerAvatar(rhsPeerId, rhsLetters, rhsPhotoRepresentations, rhsClipStyle)): - return lhsPeerId == rhsPeerId && lhsLetters == rhsLetters && lhsPhotoRepresentations == rhsPhotoRepresentations && lhsClipStyle == rhsClipStyle + case let (.peerAvatar(lhsPeerId, lhsPeerNameColor, lhsLetters, lhsPhotoRepresentations, lhsClipStyle), .peerAvatar(rhsPeerId, rhsPeerNameColor, rhsLetters, rhsPhotoRepresentations, rhsClipStyle)): + return lhsPeerId == rhsPeerId && lhsPeerNameColor == rhsPeerNameColor && lhsLetters == rhsLetters && lhsPhotoRepresentations == rhsPhotoRepresentations && lhsClipStyle == rhsClipStyle case let (.custom(lhsLetters, lhsIndex, lhsIcon), .custom(rhsLetters, rhsIndex, rhsIcon)): return lhsLetters == rhsLetters && lhsIndex == rhsIndex && lhsIcon == rhsIcon default: @@ -450,7 +454,7 @@ public final class AvatarNode: ASDisplayNode { } else if peer?.restrictionText(platform: "ios", contentSettings: contentSettings) == nil { representation = peer?.smallProfileImage } - let updatedState: AvatarNodeState = .peerAvatar(peer?.id ?? EnginePeer.Id(0), peer?.displayLetters ?? [], representation, clipStyle) + let updatedState: AvatarNodeState = .peerAvatar(peer?.id ?? EnginePeer.Id(0), peer?.nameColor, peer?.displayLetters ?? [], representation, clipStyle) if updatedState != self.state || overrideImage != self.overrideImage || theme !== self.theme { self.state = updatedState self.overrideImage = overrideImage @@ -485,7 +489,7 @@ public final class AvatarNode: ASDisplayNode { self.editOverlayNode?.isHidden = true } - parameters = AvatarNodeParameters(theme: theme, accountPeerId: accountPeerId, peerId: peer.id, colors: calculateColors(explicitColorIndex: nil, peerId: peer.id, icon: icon, theme: theme), letters: peer.displayLetters, font: self.font, icon: icon, explicitColorIndex: nil, hasImage: true, clipStyle: clipStyle) + parameters = AvatarNodeParameters(theme: theme, accountPeerId: accountPeerId, peerId: peer.id, colors: calculateColors(explicitColorIndex: nil, peerId: peer.id, nameColor: peer.nameColor, icon: icon, theme: theme), letters: peer.displayLetters, font: self.font, icon: icon, explicitColorIndex: nil, hasImage: true, clipStyle: clipStyle) } else { self.imageReady.set(.single(true)) self.displaySuspended = false @@ -494,7 +498,7 @@ public final class AvatarNode: ASDisplayNode { } self.editOverlayNode?.isHidden = true - let colors = calculateColors(explicitColorIndex: nil, peerId: peer?.id ?? EnginePeer.Id(0), icon: icon, theme: theme) + let colors = calculateColors(explicitColorIndex: nil, peerId: peer?.id ?? EnginePeer.Id(0), nameColor: peer?.nameColor, icon: icon, theme: theme) parameters = AvatarNodeParameters(theme: theme, accountPeerId: accountPeerId, peerId: peer?.id ?? EnginePeer.Id(0), colors: colors, letters: peer?.displayLetters ?? [], font: self.font, icon: icon, explicitColorIndex: nil, hasImage: false, clipStyle: clipStyle) if let badgeView = self.badgeView { @@ -614,7 +618,7 @@ public final class AvatarNode: ASDisplayNode { } else if peer?.restrictionText(platform: "ios", contentSettings: genericContext.currentContentSettings.with { $0 }) == nil { representation = peer?.smallProfileImage } - let updatedState: AvatarNodeState = .peerAvatar(peer?.id ?? EnginePeer.Id(0), peer?.displayLetters ?? [], representation, clipStyle) + let updatedState: AvatarNodeState = .peerAvatar(peer?.id ?? EnginePeer.Id(0), peer?.nameColor, peer?.displayLetters ?? [], representation, clipStyle) if updatedState != self.state || overrideImage != self.overrideImage || theme !== self.theme { self.state = updatedState self.overrideImage = overrideImage @@ -651,7 +655,7 @@ public final class AvatarNode: ASDisplayNode { self.editOverlayNode?.isHidden = true } - parameters = AvatarNodeParameters(theme: theme, accountPeerId: account.peerId, peerId: peer.id, colors: calculateColors(explicitColorIndex: nil, peerId: peer.id, icon: icon, theme: theme), letters: peer.displayLetters, font: self.font, icon: icon, explicitColorIndex: nil, hasImage: true, clipStyle: clipStyle) + parameters = AvatarNodeParameters(theme: theme, accountPeerId: account.peerId, peerId: peer.id, colors: calculateColors(explicitColorIndex: nil, peerId: peer.id, nameColor: peer.nameColor, icon: icon, theme: theme), letters: peer.displayLetters, font: self.font, icon: icon, explicitColorIndex: nil, hasImage: true, clipStyle: clipStyle) } else { self.imageReady.set(.single(true)) self.displaySuspended = false @@ -660,7 +664,7 @@ public final class AvatarNode: ASDisplayNode { } self.editOverlayNode?.isHidden = true - let colors = calculateColors(explicitColorIndex: nil, peerId: peer?.id ?? EnginePeer.Id(0), icon: icon, theme: theme) + let colors = calculateColors(explicitColorIndex: nil, peerId: peer?.id ?? EnginePeer.Id(0), nameColor: peer?.nameColor, icon: icon, theme: theme) parameters = AvatarNodeParameters(theme: theme, accountPeerId: account.peerId, peerId: peer?.id ?? EnginePeer.Id(0), colors: colors, letters: peer?.displayLetters ?? [], font: self.font, icon: icon, explicitColorIndex: nil, hasImage: false, clipStyle: clipStyle) if let badgeView = self.badgeView { @@ -697,9 +701,9 @@ public final class AvatarNode: ASDisplayNode { let parameters: AvatarNodeParameters if let icon = icon, case .phone = icon { - parameters = AvatarNodeParameters(theme: nil, accountPeerId: nil, peerId: nil, colors: calculateColors(explicitColorIndex: explicitIndex, peerId: nil, icon: .phoneIcon, theme: nil), letters: [], font: self.font, icon: .phoneIcon, explicitColorIndex: explicitIndex, hasImage: false, clipStyle: .round) + parameters = AvatarNodeParameters(theme: nil, accountPeerId: nil, peerId: nil, colors: calculateColors(explicitColorIndex: explicitIndex, peerId: nil, nameColor: nil, icon: .phoneIcon, theme: nil), letters: [], font: self.font, icon: .phoneIcon, explicitColorIndex: explicitIndex, hasImage: false, clipStyle: .round) } else { - parameters = AvatarNodeParameters(theme: nil, accountPeerId: nil, peerId: nil, colors: calculateColors(explicitColorIndex: explicitIndex, peerId: nil, icon: .none, theme: nil), letters: letters, font: self.font, icon: .none, explicitColorIndex: explicitIndex, hasImage: false, clipStyle: .round) + parameters = AvatarNodeParameters(theme: nil, accountPeerId: nil, peerId: nil, colors: calculateColors(explicitColorIndex: explicitIndex, peerId: nil, nameColor: nil, icon: .none, theme: nil), letters: letters, font: self.font, icon: .none, explicitColorIndex: explicitIndex, hasImage: false, clipStyle: .round) } self.displaySuspended = true diff --git a/submodules/AvatarVideoNode/Sources/AvatarVideoNode.swift b/submodules/AvatarVideoNode/Sources/AvatarVideoNode.swift index b603ca5173..6b17989a2e 100644 --- a/submodules/AvatarVideoNode/Sources/AvatarVideoNode.swift +++ b/submodules/AvatarVideoNode/Sources/AvatarVideoNode.swift @@ -25,7 +25,7 @@ public final class AvatarVideoNode: ASDisplayNode { private var emojiMarkup: TelegramMediaImage.EmojiMarkup? - private var fileDisposable: Disposable? + private var fileDisposable = MetaDisposable() private var animationFile: TelegramMediaFile? private var itemLayer: EmojiPagerContentComponent.View.ItemLayer? private var useAnimationNode = false @@ -55,7 +55,7 @@ public final class AvatarVideoNode: ASDisplayNode { } deinit { - self.fileDisposable?.dispose() + self.fileDisposable.dispose() self.stickerFetchedDisposable.dispose() self.playbackStartDisposable.dispose() } @@ -174,15 +174,15 @@ public final class AvatarVideoNode: ASDisplayNode { switch markup.content { case let .emoji(fileId): - self.fileDisposable = (self.context.engine.stickers.resolveInlineStickers(fileIds: [fileId]) + self.fileDisposable.set((self.context.engine.stickers.resolveInlineStickers(fileIds: [fileId]) |> deliverOnMainQueue).startStrict(next: { [weak self] files in if let strongSelf = self, let file = files.values.first { strongSelf.animationFile = file strongSelf.setupAnimation() } - }).strict() + })) case let .sticker(packReference, fileId): - self.fileDisposable = (self.context.engine.stickers.loadedStickerPack(reference: packReference, forceActualized: false) + self.fileDisposable.set((self.context.engine.stickers.loadedStickerPack(reference: packReference, forceActualized: false) |> map { pack -> TelegramMediaFile? in if case let .result(_, items, _) = pack, let item = items.first(where: { $0.file.fileId.id == fileId }) { return item.file @@ -194,7 +194,7 @@ public final class AvatarVideoNode: ASDisplayNode { strongSelf.animationFile = file strongSelf.setupAnimation() } - }).strict() + })) } } diff --git a/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageDateHeader.swift b/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageDateHeader.swift index 9253684a1f..17821e75d8 100644 --- a/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageDateHeader.swift +++ b/submodules/TelegramUI/Components/Chat/ChatMessageItemImpl/Sources/ChatMessageDateHeader.swift @@ -425,6 +425,9 @@ public final class ChatMessageAvatarHeader: ListViewItemHeader { return } node.updatePresentationData(self.presentationData, context: self.context) + if let peer = self.peer { + node.updatePeer(peer: peer) + } node.updateStoryStats(storyStats: self.storyStats, theme: self.presentationData.theme.theme, force: false) } } @@ -441,7 +444,7 @@ public final class ChatMessageAvatarHeaderNodeImpl: ListViewItemHeaderNode { private let peerId: PeerId private let messageReference: MessageReference? - private let peer: Peer? + private var peer: Peer? private let adMessageId: EngineMessage.Id? private let containerNode: ContextControllerSourceNode @@ -518,6 +521,13 @@ public final class ChatMessageAvatarHeaderNodeImpl: ListViewItemHeaderNode { self.avatarNode.setCustomLetters(letters, icon: !letters.isEmpty ? nil : .phone) } + + public func updatePeer(peer: Peer) { + if let previousPeer = self.peer, previousPeer.nameColor != peer.nameColor { + self.peer = peer + self.avatarNode.setPeer(context: self.context, theme: self.presentationData.theme.theme, peer: EnginePeer(peer), authorOfMessage: self.messageReference, overrideImage: nil, emptyColor: .black, synchronousLoad: false, displayDimensions: CGSize(width: 38.0, height: 38.0)) + } + } public func setPeer(context: AccountContext, theme: PresentationTheme, synchronousLoad: Bool, peer: Peer, authorOfMessage: MessageReference?, emptyColor: UIColor) { self.containerNode.isGestureEnabled = peer.smallProfileImage != nil