Various UI Fixes

This commit is contained in:
Peter
2018-11-21 20:21:40 +03:00
parent 60d6b4c9ba
commit 43d05b877b
24 changed files with 163 additions and 107 deletions

View File

@@ -192,7 +192,7 @@ public final class AvatarNode: ASDisplayNode {
} }
} }
public func setPeer(account: Account, peer: Peer, authorOfMessage: MessageReference? = nil, overrideImage: AvatarNodeImageOverride? = nil) { public func setPeer(account: Account, peer: Peer, authorOfMessage: MessageReference? = nil, overrideImage: AvatarNodeImageOverride? = nil, emptyColor: UIColor? = nil) {
var representation: TelegramMediaImageRepresentation? var representation: TelegramMediaImageRepresentation?
var icon = AvatarNodeIcon.none var icon = AvatarNodeIcon.none
if let overrideImage = overrideImage { if let overrideImage = overrideImage {
@@ -222,7 +222,7 @@ public final class AvatarNode: ASDisplayNode {
let theme = account.telegramApplicationContext.currentPresentationData.with { $0 }.theme let theme = account.telegramApplicationContext.currentPresentationData.with { $0 }.theme
if let signal = peerAvatarImage(account: account, peer: peer, authorOfMessage: authorOfMessage, representation: representation) { if let signal = peerAvatarImage(account: account, peer: peer, authorOfMessage: authorOfMessage, representation: representation, emptyColor: emptyColor) {
self.imageReady.set(self.imageNode.ready) self.imageReady.set(self.imageNode.ready)
self.imageNode.setSignal(signal) self.imageNode.setSignal(signal)

View File

@@ -430,7 +430,7 @@ class CallListCallItemNode: ItemListRevealOptionsItemNode {
return (nodeLayout, { [weak self] in return (nodeLayout, { [weak self] in
if let strongSelf = self { if let strongSelf = self {
if let peer = item.topMessage.peers[item.topMessage.id.peerId] { if let peer = item.topMessage.peers[item.topMessage.id.peerId] {
strongSelf.avatarNode.setPeer(account: item.account, peer: peer) strongSelf.avatarNode.setPeer(account: item.account, peer: peer, emptyColor: item.theme.list.mediaPlaceholderColor)
} }
return (strongSelf.avatarNode.ready, { [weak strongSelf] animated in return (strongSelf.avatarNode.ready, { [weak strongSelf] animated in

View File

@@ -377,6 +377,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
if let (size, insets) = self.validEmptyNodeLayout { if let (size, insets) = self.validEmptyNodeLayout {
emptyNode.updateLayout(interfaceState: self.chatPresentationInterfaceState, size: size, insets: insets, transition: .immediate) emptyNode.updateLayout(interfaceState: self.chatPresentationInterfaceState, size: size, insets: insets, transition: .immediate)
} }
emptyNode.isHidden = self.restrictedNode != nil
self.emptyNode = emptyNode self.emptyNode = emptyNode
self.historyNodeContainer.supernode?.insertSubnode(emptyNode, aboveSubnode: self.historyNodeContainer) self.historyNodeContainer.supernode?.insertSubnode(emptyNode, aboveSubnode: self.historyNodeContainer)
if animated { if animated {
@@ -1330,12 +1331,14 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
self.historyNodeContainer.isHidden = true self.historyNodeContainer.isHidden = true
self.navigateButtons.isHidden = true self.navigateButtons.isHidden = true
self.loadingNode.isHidden = true self.loadingNode.isHidden = true
self.emptyNode?.isHidden = true
} else if let restrictedNode = self.restrictedNode { } else if let restrictedNode = self.restrictedNode {
self.restrictedNode = nil self.restrictedNode = nil
restrictedNode.removeFromSupernode() restrictedNode.removeFromSupernode()
self.historyNodeContainer.isHidden = false self.historyNodeContainer.isHidden = false
self.navigateButtons.isHidden = false self.navigateButtons.isHidden = false
self.loadingNode.isHidden = false self.loadingNode.isHidden = false
self.emptyNode?.isHidden = false
} }
let layoutTransition: ContainedViewLayoutTransition = transition let layoutTransition: ContainedViewLayoutTransition = transition

View File

@@ -132,38 +132,41 @@ private func updatedContextQueryResultStateForQuery(account: Account, peer: Peer
let inlineBots: Signal<[(Peer, Double)], NoError> = types.contains(.contextBots) ? recentlyUsedInlineBots(postbox: account.postbox) : .single([]) let inlineBots: Signal<[(Peer, Double)], NoError> = types.contains(.contextBots) ? recentlyUsedInlineBots(postbox: account.postbox) : .single([])
let participants = combineLatest(inlineBots, searchPeerMembers(account: account, peerId: peer.id, query: query)) let participants = combineLatest(inlineBots, searchPeerMembers(account: account, peerId: peer.id, query: query))
|> map { inlineBots, peers -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in |> map { inlineBots, peers -> (ChatPresentationInputQueryResult?) -> ChatPresentationInputQueryResult? in
let filteredInlineBots = inlineBots.sorted(by: { $0.1 > $1.1 }).filter { peer, rating in let filteredInlineBots = inlineBots.sorted(by: { $0.1 > $1.1 }).filter { peer, rating in
if rating < 0.14 { if rating < 0.14 {
return false
}
if peer.indexName.matchesByTokens(normalizedQuery) {
return true
}
if let addressName = peer.addressName, addressName.lowercased().hasPrefix(normalizedQuery) {
return true
}
return false return false
}.map { $0.0 } }
if peer.indexName.matchesByTokens(normalizedQuery) {
let inlineBotPeerIds = Set(filteredInlineBots.map { $0.id })
let filteredPeers = peers.filter { peer in
if inlineBotPeerIds.contains(peer.id) {
return false
}
if !types.contains(.accountPeer) && peer.id == account.peerId {
return false
}
return true return true
} }
var sortedPeers = filteredInlineBots if let addressName = peer.addressName, addressName.lowercased().hasPrefix(normalizedQuery) {
sortedPeers.append(contentsOf: filteredPeers.sorted(by: { lhs, rhs in return true
let result = lhs.indexName.indexName(.lastNameFirst).compare(rhs.indexName.indexName(.lastNameFirst)) }
return result == .orderedAscending return false
})) }.map { $0.0 }
return { _ in return .mentions(sortedPeers) }
let inlineBotPeerIds = Set(filteredInlineBots.map { $0.id })
let filteredPeers = peers.filter { peer in
if inlineBotPeerIds.contains(peer.id) {
return false
}
if !types.contains(.accountPeer) && peer.id == account.peerId {
return false
}
return true
} }
var sortedPeers = filteredInlineBots
sortedPeers.append(contentsOf: filteredPeers.sorted(by: { lhs, rhs in
let result = lhs.indexName.indexName(.lastNameFirst).compare(rhs.indexName.indexName(.lastNameFirst))
return result == .orderedAscending
}))
sortedPeers = sortedPeers.filter { peer in
return !peer.displayTitle.isEmpty
}
return { _ in return .mentions(sortedPeers) }
}
return signal |> then(participants) return signal |> then(participants)
case let .command(query): case let .command(query):

View File

@@ -339,7 +339,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
if peer.id == item.account.peerId { if peer.id == item.account.peerId {
overrideImage = .savedMessagesIcon overrideImage = .savedMessagesIcon
} }
self.avatarNode.setPeer(account: item.account, peer: peer, overrideImage: overrideImage) self.avatarNode.setPeer(account: item.account, peer: peer, overrideImage: overrideImage, emptyColor: item.presentationData.theme.list.mediaPlaceholderColor)
} }
} }

View File

@@ -11,13 +11,15 @@ final class ChatMessageAvatarAccessoryItem: ListViewAccessoryItem {
private let peer: Peer? private let peer: Peer?
private let messageReference: MessageReference? private let messageReference: MessageReference?
private let messageTimestamp: Int32 private let messageTimestamp: Int32
private let emptyColor: UIColor
init(account: Account, peerId: PeerId, peer: Peer?, messageReference: MessageReference?, messageTimestamp: Int32) { init(account: Account, peerId: PeerId, peer: Peer?, messageReference: MessageReference?, messageTimestamp: Int32, emptyColor: UIColor) {
self.account = account self.account = account
self.peerId = peerId self.peerId = peerId
self.peer = peer self.peer = peer
self.messageReference = messageReference self.messageReference = messageReference
self.messageTimestamp = messageTimestamp self.messageTimestamp = messageTimestamp
self.emptyColor = emptyColor
} }
func isEqualToItem(_ other: ListViewAccessoryItem) -> Bool { func isEqualToItem(_ other: ListViewAccessoryItem) -> Bool {
@@ -32,7 +34,7 @@ final class ChatMessageAvatarAccessoryItem: ListViewAccessoryItem {
let node = ChatMessageAvatarAccessoryItemNode() let node = ChatMessageAvatarAccessoryItemNode()
node.frame = CGRect(origin: CGPoint(), size: CGSize(width: 38.0, height: 38.0)) node.frame = CGRect(origin: CGPoint(), size: CGSize(width: 38.0, height: 38.0))
if let peer = self.peer { if let peer = self.peer {
node.setPeer(account: account, peer: peer, authorOfMessage: self.messageReference) node.setPeer(account: account, peer: peer, authorOfMessage: self.messageReference, emptyColor: self.emptyColor)
} }
return node return node
} }
@@ -52,7 +54,7 @@ final class ChatMessageAvatarAccessoryItemNode: ListViewAccessoryItemNode {
self.addSubnode(self.avatarNode) self.addSubnode(self.avatarNode)
} }
func setPeer(account: Account, peer: Peer, authorOfMessage: MessageReference?) { func setPeer(account: Account, peer: Peer, authorOfMessage: MessageReference?, emptyColor: UIColor) {
self.avatarNode.setPeer(account: account, peer: peer, authorOfMessage: authorOfMessage) self.avatarNode.setPeer(account: account, peer: peer, authorOfMessage: authorOfMessage, emptyColor: emptyColor)
} }
} }

View File

@@ -184,6 +184,7 @@ class ChatMessageContactBubbleContentNode: ChatMessageBubbleContentNode {
let buttonHighlightedImage: UIImage let buttonHighlightedImage: UIImage
let titleColor: UIColor let titleColor: UIColor
let titleHighlightedColor: UIColor let titleHighlightedColor: UIColor
let avatarPlaceholderColor: UIColor
if item.message.effectivelyIncoming(item.account.peerId) { if item.message.effectivelyIncoming(item.account.peerId) {
buttonImage = PresentationResourcesChat.chatMessageAttachedContentButtonIncoming(item.presentationData.theme.theme)! buttonImage = PresentationResourcesChat.chatMessageAttachedContentButtonIncoming(item.presentationData.theme.theme)!
buttonHighlightedImage = PresentationResourcesChat.chatMessageAttachedContentHighlightedButtonIncoming(item.presentationData.theme.theme)! buttonHighlightedImage = PresentationResourcesChat.chatMessageAttachedContentHighlightedButtonIncoming(item.presentationData.theme.theme)!
@@ -191,6 +192,7 @@ class ChatMessageContactBubbleContentNode: ChatMessageBubbleContentNode {
let bubbleColors = bubbleColorComponents(theme: item.presentationData.theme.theme, incoming: true, wallpaper: !item.presentationData.theme.wallpaper.isEmpty) let bubbleColors = bubbleColorComponents(theme: item.presentationData.theme.theme, incoming: true, wallpaper: !item.presentationData.theme.wallpaper.isEmpty)
titleHighlightedColor = bubbleColors.fill titleHighlightedColor = bubbleColors.fill
avatarPlaceholderColor = item.presentationData.theme.theme.chat.bubble.incomingMediaPlaceholderColor
} else { } else {
buttonImage = PresentationResourcesChat.chatMessageAttachedContentButtonOutgoing(item.presentationData.theme.theme)! buttonImage = PresentationResourcesChat.chatMessageAttachedContentButtonOutgoing(item.presentationData.theme.theme)!
buttonHighlightedImage = PresentationResourcesChat.chatMessageAttachedContentHighlightedButtonOutgoing(item.presentationData.theme.theme)! buttonHighlightedImage = PresentationResourcesChat.chatMessageAttachedContentHighlightedButtonOutgoing(item.presentationData.theme.theme)!
@@ -198,6 +200,7 @@ class ChatMessageContactBubbleContentNode: ChatMessageBubbleContentNode {
let bubbleColors = bubbleColorComponents(theme: item.presentationData.theme.theme, incoming: false, wallpaper: !item.presentationData.theme.wallpaper.isEmpty) let bubbleColors = bubbleColorComponents(theme: item.presentationData.theme.theme, incoming: false, wallpaper: !item.presentationData.theme.wallpaper.isEmpty)
titleHighlightedColor = bubbleColors.fill titleHighlightedColor = bubbleColors.fill
avatarPlaceholderColor = item.presentationData.theme.theme.chat.bubble.outgoingMediaPlaceholderColor
} }
let (buttonWidth, continueLayout) = makeButtonLayout(constrainedSize.width, buttonImage, buttonHighlightedImage, nil, nil, item.presentationData.strings.Conversation_ViewContactDetails, titleColor, titleHighlightedColor) let (buttonWidth, continueLayout) = makeButtonLayout(constrainedSize.width, buttonImage, buttonHighlightedImage, nil, nil, item.presentationData.strings.Conversation_ViewContactDetails, titleColor, titleHighlightedColor)
@@ -286,7 +289,7 @@ class ChatMessageContactBubbleContentNode: ChatMessageBubbleContentNode {
} }
if let peerId = selectedContact?.peerId, let peer = item.message.peers[peerId] { if let peerId = selectedContact?.peerId, let peer = item.message.peers[peerId] {
strongSelf.avatarNode.setPeer(account: item.account, peer: peer) strongSelf.avatarNode.setPeer(account: item.account, peer: peer, emptyColor: avatarPlaceholderColor)
} else { } else {
strongSelf.avatarNode.setCustomLetters(customLetters) strongSelf.avatarNode.setCustomLetters(customLetters)
} }

View File

@@ -475,7 +475,9 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode {
} else if let image = media as? TelegramMediaWebFile { } else if let image = media as? TelegramMediaWebFile {
strongSelf.fetchDisposable.set(chatMessageWebFileInteractiveFetched(account: account, image: image).start()) strongSelf.fetchDisposable.set(chatMessageWebFileInteractiveFetched(account: account, image: image).start())
} else if let file = media as? TelegramMediaFile { } else if let file = media as? TelegramMediaFile {
strongSelf.fetchDisposable.set(messageMediaFileInteractiveFetched(account: account, message: message, file: file, userInitiated: false).start()) if automaticPlayback || !file.isAnimated {
strongSelf.fetchDisposable.set(messageMediaFileInteractiveFetched(account: account, message: message, file: file, userInitiated: false).start())
}
} }
} }
} else if previousAutomaticDownload != automaticDownload, automaticDownload { } else if previousAutomaticDownload != automaticDownload, automaticDownload {

View File

@@ -307,7 +307,7 @@ public final class ChatMessageItem: ListViewItem, CustomStringConvertible {
} }
if !hasActionMedia && !isBroadcastChannel { if !hasActionMedia && !isBroadcastChannel {
if let effectiveAuthor = effectiveAuthor { if let effectiveAuthor = effectiveAuthor {
accessoryItem = ChatMessageAvatarAccessoryItem(account: account, peerId: effectiveAuthor.id, peer: effectiveAuthor, messageReference: MessageReference(message), messageTimestamp: content.index.timestamp) accessoryItem = ChatMessageAvatarAccessoryItem(account: account, peerId: effectiveAuthor.id, peer: effectiveAuthor, messageReference: MessageReference(message), messageTimestamp: content.index.timestamp, emptyColor: presentationData.theme.theme.chat.bubble.incoming.withoutWallpaper.fill)
} }
} }
} }

View File

@@ -92,7 +92,7 @@ final class ChatMessageNotificationItemNode: NotificationItemNode {
var title: String? var title: String?
if let firstMessage = item.messages.first, let peer = messageMainPeer(firstMessage) { if let firstMessage = item.messages.first, let peer = messageMainPeer(firstMessage) {
self.avatarNode.setPeer(account: item.account, peer: peer) self.avatarNode.setPeer(account: item.account, peer: peer, emptyColor: presentationData.theme.list.mediaPlaceholderColor)
if let channel = peer as? TelegramChannel, case .broadcast = channel.info { if let channel = peer as? TelegramChannel, case .broadcast = channel.info {
title = peer.displayTitle title = peer.displayTitle

View File

@@ -383,26 +383,39 @@ final class ChatTitleView: UIView, NavigationBarTitleView {
} }
} else if let channel = peer as? TelegramChannel { } else if let channel = peer as? TelegramChannel {
if let cachedChannelData = peerView.cachedData as? CachedChannelData, let memberCount = cachedChannelData.participantsSummary.memberCount { if let cachedChannelData = peerView.cachedData as? CachedChannelData, let memberCount = cachedChannelData.participantsSummary.memberCount {
if case .group = channel.info, let onlineMemberCount = onlineMemberCount, onlineMemberCount > 1 { if memberCount == 0 {
let string = NSMutableAttributedString() let string: NSAttributedString
if case .group = channel.info {
string.append(NSAttributedString(string: "\(strings.Conversation_StatusMembers(Int32(memberCount))), ", font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor)) string = NSAttributedString(string: strings.Group_Status, font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor)
string.append(NSAttributedString(string: strings.Conversation_StatusOnline(Int32(onlineMemberCount)), font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor)) } else {
string = NSAttributedString(string: strings.Channel_Status, font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor)
}
if self.infoNode.attributedText == nil || !self.infoNode.attributedText!.isEqual(to: string) { if self.infoNode.attributedText == nil || !self.infoNode.attributedText!.isEqual(to: string) {
self.infoNode.attributedText = string self.infoNode.attributedText = string
shouldUpdateLayout = true shouldUpdateLayout = true
} }
} else { } else {
let membersString: String if case .group = channel.info, let onlineMemberCount = onlineMemberCount, onlineMemberCount > 1 {
if case .group = channel.info { let string = NSMutableAttributedString()
membersString = strings.Conversation_StatusMembers(memberCount)
string.append(NSAttributedString(string: "\(strings.Conversation_StatusMembers(Int32(memberCount))), ", font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor))
string.append(NSAttributedString(string: strings.Conversation_StatusOnline(Int32(onlineMemberCount)), font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor))
if self.infoNode.attributedText == nil || !self.infoNode.attributedText!.isEqual(to: string) {
self.infoNode.attributedText = string
shouldUpdateLayout = true
}
} else { } else {
membersString = strings.Conversation_StatusSubscribers(memberCount) let membersString: String
} if case .group = channel.info {
let string = NSAttributedString(string: membersString, font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor) membersString = strings.Conversation_StatusMembers(memberCount)
if self.infoNode.attributedText == nil || !self.infoNode.attributedText!.isEqual(to: string) { } else {
self.infoNode.attributedText = string membersString = strings.Conversation_StatusSubscribers(memberCount)
shouldUpdateLayout = true }
let string = NSAttributedString(string: membersString, font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor)
if self.infoNode.attributedText == nil || !self.infoNode.attributedText!.isEqual(to: string) {
self.infoNode.attributedText = string
shouldUpdateLayout = true
}
} }
} }
} else { } else {

View File

@@ -156,7 +156,7 @@ final class CommandChatInputPanelItemNode: ListViewItemNode {
strongSelf.arrowNode.setImage(iconImage, for: []) strongSelf.arrowNode.setImage(iconImage, for: [])
strongSelf.avatarNode.setPeer(account: item.account, peer: item.command.peer) strongSelf.avatarNode.setPeer(account: item.account, peer: item.command.peer, emptyColor: item.theme.list.mediaPlaceholderColor)
let _ = textApply() let _ = textApply()

View File

@@ -567,7 +567,7 @@ class ContactsPeerItemNode: ItemListRevealOptionsItemNode {
if peer.id == item.account.peerId, case .generalSearch = item.peerMode { if peer.id == item.account.peerId, case .generalSearch = item.peerMode {
overrideImage = .savedMessagesIcon overrideImage = .savedMessagesIcon
} }
strongSelf.avatarNode.setPeer(account: item.account, peer: peer, overrideImage: overrideImage) strongSelf.avatarNode.setPeer(account: item.account, peer: peer, overrideImage: overrideImage, emptyColor: item.theme.list.mediaPlaceholderColor)
} }
case let .deviceContact(_, contact): case let .deviceContact(_, contact):
let letters: [String] let letters: [String]

View File

@@ -124,9 +124,9 @@ final class HorizontalPeerItemNode: ListViewItemNode {
let itemTheme: SelectablePeerNodeTheme let itemTheme: SelectablePeerNodeTheme
switch item.mode { switch item.mode {
case .list: case .list:
itemTheme = SelectablePeerNodeTheme(textColor: item.theme.list.itemPrimaryTextColor, secretTextColor: item.theme.chatList.secretTitleColor, selectedTextColor: item.theme.list.itemAccentColor, checkBackgroundColor: item.theme.list.plainBackgroundColor, checkFillColor: item.theme.list.itemAccentColor, checkColor: item.theme.list.plainBackgroundColor) itemTheme = SelectablePeerNodeTheme(textColor: item.theme.list.itemPrimaryTextColor, secretTextColor: item.theme.chatList.secretTitleColor, selectedTextColor: item.theme.list.itemAccentColor, checkBackgroundColor: item.theme.list.plainBackgroundColor, checkFillColor: item.theme.list.itemAccentColor, checkColor: item.theme.list.plainBackgroundColor, avatarPlaceholderColor: item.theme.list.mediaPlaceholderColor)
case .actionSheet: case .actionSheet:
itemTheme = SelectablePeerNodeTheme(textColor: item.theme.actionSheet.primaryTextColor, secretTextColor: item.theme.chatList.secretTitleColor, selectedTextColor: item.theme.actionSheet.controlAccentColor, checkBackgroundColor: item.theme.actionSheet.opaqueItemBackgroundColor, checkFillColor: item.theme.actionSheet.controlAccentColor, checkColor: item.theme.actionSheet.opaqueItemBackgroundColor) itemTheme = SelectablePeerNodeTheme(textColor: item.theme.actionSheet.primaryTextColor, secretTextColor: item.theme.chatList.secretTitleColor, selectedTextColor: item.theme.actionSheet.controlAccentColor, checkBackgroundColor: item.theme.actionSheet.opaqueItemBackgroundColor, checkFillColor: item.theme.actionSheet.controlAccentColor, checkColor: item.theme.actionSheet.opaqueItemBackgroundColor, avatarPlaceholderColor: item.theme.list.mediaPlaceholderColor)
} }
let currentBadgeBackgroundImage: UIImage? let currentBadgeBackgroundImage: UIImage?
let badgeAttributedString: NSAttributedString let badgeAttributedString: NSAttributedString

View File

@@ -622,7 +622,7 @@ class ItemListAvatarAndNameInfoItemNode: ListViewItemNode, ItemListItemNode, Ite
} else if case .editSettings = item.mode { } else if case .editSettings = item.mode {
overrideImage = AvatarNodeImageOverride.editAvatarIcon overrideImage = AvatarNodeImageOverride.editAvatarIcon
} }
strongSelf.avatarNode.setPeer(account: item.account, peer: peer, overrideImage: overrideImage) strongSelf.avatarNode.setPeer(account: item.account, peer: peer, overrideImage: overrideImage, emptyColor: item.theme.list.mediaPlaceholderColor)
} }
let avatarFrame = CGRect(origin: CGPoint(x: params.leftInset + 15.0, y: avatarOriginY), size: CGSize(width: 66.0, height: 66.0)) let avatarFrame = CGRect(origin: CGPoint(x: params.leftInset + 15.0, y: avatarOriginY), size: CGSize(width: 66.0, height: 66.0))

View File

@@ -601,9 +601,9 @@ class ItemListPeerItemNode: ItemListRevealOptionsItemNode {
transition.updateFrame(node: strongSelf.avatarNode, frame: CGRect(origin: CGPoint(x: params.leftInset + revealOffset + editingOffset + 12.0, y: 4.0), size: CGSize(width: 40.0, height: 40.0))) transition.updateFrame(node: strongSelf.avatarNode, frame: CGRect(origin: CGPoint(x: params.leftInset + revealOffset + editingOffset + 12.0, y: 4.0), size: CGSize(width: 40.0, height: 40.0)))
if item.peer.id == item.account.peerId, case .threatSelfAsSaved = item.aliasHandling { if item.peer.id == item.account.peerId, case .threatSelfAsSaved = item.aliasHandling {
strongSelf.avatarNode.setPeer(account: item.account, peer: item.peer, overrideImage: .savedMessagesIcon) strongSelf.avatarNode.setPeer(account: item.account, peer: item.peer, overrideImage: .savedMessagesIcon, emptyColor: item.theme.list.mediaPlaceholderColor)
} else { } else {
strongSelf.avatarNode.setPeer(account: item.account, peer: item.peer) strongSelf.avatarNode.setPeer(account: item.account, peer: item.peer, emptyColor: item.theme.list.mediaPlaceholderColor)
} }
strongSelf.highlightedBackgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -UIScreenPixel), size: CGSize(width: params.width, height: 48.0 + UIScreenPixel + UIScreenPixel)) strongSelf.highlightedBackgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -UIScreenPixel), size: CGSize(width: params.width, height: 48.0 + UIScreenPixel + UIScreenPixel))

View File

@@ -39,7 +39,7 @@ final class JoinLinkPreviewPeerContentNode: ASDisplayNode, ShareContentContainer
self.peersScrollNode = ASScrollNode() self.peersScrollNode = ASScrollNode()
self.peersScrollNode.view.showsHorizontalScrollIndicator = false self.peersScrollNode.view.showsHorizontalScrollIndicator = false
let itemTheme = SelectablePeerNodeTheme(textColor: theme.actionSheet.primaryTextColor, secretTextColor: .green, selectedTextColor: theme.actionSheet.controlAccentColor, checkBackgroundColor: theme.actionSheet.opaqueItemBackgroundColor, checkFillColor: theme.actionSheet.controlAccentColor, checkColor: theme.actionSheet.opaqueItemBackgroundColor) let itemTheme = SelectablePeerNodeTheme(textColor: theme.actionSheet.primaryTextColor, secretTextColor: .green, selectedTextColor: theme.actionSheet.controlAccentColor, checkBackgroundColor: theme.actionSheet.opaqueItemBackgroundColor, checkFillColor: theme.actionSheet.controlAccentColor, checkColor: theme.actionSheet.opaqueItemBackgroundColor, avatarPlaceholderColor: theme.list.mediaPlaceholderColor)
self.peerNodes = members.map { peer in self.peerNodes = members.map { peer in
let node = SelectablePeerNode() let node = SelectablePeerNode()
@@ -59,7 +59,7 @@ final class JoinLinkPreviewPeerContentNode: ASDisplayNode, ShareContentContainer
let peer = TelegramGroup(id: PeerId(namespace: 0, id: 0), title: title, photo: image.flatMap { [$0] } ?? [], participantCount: Int(memberCount), role: .member, membership: .Left, flags: [], migrationReference: nil, creationDate: 0, version: 0) let peer = TelegramGroup(id: PeerId(namespace: 0, id: 0), title: title, photo: image.flatMap { [$0] } ?? [], participantCount: Int(memberCount), role: .member, membership: .Left, flags: [], migrationReference: nil, creationDate: 0, version: 0)
self.addSubnode(self.avatarNode) self.addSubnode(self.avatarNode)
self.avatarNode.setPeer(account: account, peer: peer) self.avatarNode.setPeer(account: account, peer: peer, emptyColor: theme.list.mediaPlaceholderColor)
self.addSubnode(self.titleNode) self.addSubnode(self.titleNode)
self.titleNode.attributedText = NSAttributedString(string: title, font: Font.semibold(16.0), textColor: theme.actionSheet.primaryTextColor) self.titleNode.attributedText = NSAttributedString(string: title, font: Font.semibold(16.0), textColor: theme.actionSheet.primaryTextColor)

View File

@@ -29,9 +29,13 @@ private final class MediaPlayerLoadedState {
} }
} }
private struct MediaPlayerSeekState {
let duration: Double
}
private enum MediaPlayerState { private enum MediaPlayerState {
case empty case empty
case seeking(frameSource: MediaFrameSource, timestamp: Double, disposable: Disposable, action: MediaPlayerPlaybackAction, enableSound: Bool) case seeking(frameSource: MediaFrameSource, timestamp: Double, seekState: MediaPlayerSeekState?, disposable: Disposable, action: MediaPlayerPlaybackAction, enableSound: Bool)
case paused(MediaPlayerLoadedState) case paused(MediaPlayerLoadedState)
case playing(MediaPlayerLoadedState) case playing(MediaPlayerLoadedState)
} }
@@ -119,7 +123,7 @@ private final class MediaPlayerContext {
if !value { if !value {
strongSelf.pause(lostAudioSession: false) strongSelf.pause(lostAudioSession: false)
} }
case let .seeking(_, _, _, action, _): case let .seeking(_, _, _, _, action, _):
switch action { switch action {
case .pause: case .pause:
if value { if value {
@@ -167,7 +171,7 @@ private final class MediaPlayerContext {
self.tickTimer?.invalidate() self.tickTimer?.invalidate()
if case let .seeking(_, _, disposable, _, _) = self.state { if case let .seeking(_, _, _, disposable, _, _) = self.state {
disposable.dispose() disposable.dispose()
} }
} }
@@ -181,7 +185,7 @@ private final class MediaPlayerContext {
action = .pause action = .pause
case .playing: case .playing:
action = .play action = .play
case let .seeking(_, _, _, currentAction, _): case let .seeking(_, _, _, _, currentAction, _):
action = currentAction action = currentAction
} }
self.seek(timestamp: timestamp, action: action) self.seek(timestamp: timestamp, action: action)
@@ -191,6 +195,7 @@ private final class MediaPlayerContext {
assert(self.queue.isCurrent()) assert(self.queue.isCurrent())
var loadedState: MediaPlayerLoadedState? var loadedState: MediaPlayerLoadedState?
var seekState: MediaPlayerSeekState?
switch self.state { switch self.state {
case .empty: case .empty:
break break
@@ -198,16 +203,18 @@ private final class MediaPlayerContext {
loadedState = currentLoadedState loadedState = currentLoadedState
case let .paused(currentLoadedState): case let .paused(currentLoadedState):
loadedState = currentLoadedState loadedState = currentLoadedState
case let .seeking(previousFrameSource, previousTimestamp, previousDisposable, _, previousEnableSound): case let .seeking(previousFrameSource, previousTimestamp, seekStateValue, previousDisposable, _, previousEnableSound):
if previousTimestamp.isEqual(to: timestamp) && self.enableSound == previousEnableSound { if previousTimestamp.isEqual(to: timestamp) && self.enableSound == previousEnableSound {
self.state = .seeking(frameSource: previousFrameSource, timestamp: previousTimestamp, disposable: previousDisposable, action: action, enableSound: self.enableSound) self.state = .seeking(frameSource: previousFrameSource, timestamp: previousTimestamp, seekState: seekStateValue, disposable: previousDisposable, action: action, enableSound: self.enableSound)
return return
} else { } else {
seekState = seekStateValue
previousDisposable.dispose() previousDisposable.dispose()
} }
} }
self.tickTimer?.invalidate() self.tickTimer?.invalidate()
var loadedDuration: Double?
if let loadedState = loadedState { if let loadedState = loadedState {
self.seekId += 1 self.seekId += 1
@@ -231,16 +238,24 @@ private final class MediaPlayerContext {
audioStatus = audioTrackFrameBuffer.status(at: currentTimestamp) audioStatus = audioTrackFrameBuffer.status(at: currentTimestamp)
duration = max(duration, CMTimeGetSeconds(audioTrackFrameBuffer.duration)) duration = max(duration, CMTimeGetSeconds(audioTrackFrameBuffer.duration))
} }
loadedDuration = duration
let status = MediaPlayerStatus(generationTimestamp: CACurrentMediaTime(), duration: duration, dimensions: CGSize(), timestamp: min(max(timestamp, 0.0), duration), baseRate: self.baseRate, seekId: self.seekId, status: .buffering(initial: false, whilePlaying: action == .play)) let status = MediaPlayerStatus(generationTimestamp: CACurrentMediaTime(), duration: duration, dimensions: CGSize(), timestamp: min(max(timestamp, 0.0), duration), baseRate: self.baseRate, seekId: self.seekId, status: .buffering(initial: false, whilePlaying: action == .play))
self.playerStatus.set(.single(status)) self.playerStatus.set(.single(status))
} else { } else {
let status = MediaPlayerStatus(generationTimestamp: CACurrentMediaTime(), duration: 0.0, dimensions: CGSize(), timestamp: 0.0, baseRate: self.baseRate, seekId: self.seekId, status: .buffering(initial: false, whilePlaying: action == .play)) let duration = seekState?.duration ?? 0.0
let status = MediaPlayerStatus(generationTimestamp: CACurrentMediaTime(), duration: duration, dimensions: CGSize(), timestamp: min(max(timestamp, 0.0), duration), baseRate: self.baseRate, seekId: self.seekId, status: .buffering(initial: false, whilePlaying: action == .play))
self.playerStatus.set(.single(status)) self.playerStatus.set(.single(status))
} }
let frameSource = FFMpegMediaFrameSource(queue: self.queue, postbox: self.postbox, resourceReference: self.resourceReference, streamable: self.streamable, video: self.video, preferSoftwareDecoding: self.preferSoftwareDecoding, fetchAutomatically: self.fetchAutomatically) let frameSource = FFMpegMediaFrameSource(queue: self.queue, postbox: self.postbox, resourceReference: self.resourceReference, streamable: self.streamable, video: self.video, preferSoftwareDecoding: self.preferSoftwareDecoding, fetchAutomatically: self.fetchAutomatically)
let disposable = MetaDisposable() let disposable = MetaDisposable()
self.state = .seeking(frameSource: frameSource, timestamp: timestamp, disposable: disposable, action: action, enableSound: self.enableSound) let updatedSeekState: MediaPlayerSeekState?
if let loadedDuration = loadedDuration {
updatedSeekState = MediaPlayerSeekState(duration: loadedDuration)
} else {
updatedSeekState = seekState
}
self.state = .seeking(frameSource: frameSource, timestamp: timestamp, seekState: updatedSeekState, disposable: disposable, action: action, enableSound: self.enableSound)
self.lastStatusUpdateTimestamp = nil self.lastStatusUpdateTimestamp = nil
@@ -270,7 +285,7 @@ private final class MediaPlayerContext {
assert(self.queue.isCurrent()) assert(self.queue.isCurrent())
guard case let .seeking(frameSource, _, _, action, _) = self.state else { guard case let .seeking(frameSource, _, _, _, action, _) = self.state else {
assertionFailure() assertionFailure()
return return
} }
@@ -391,8 +406,8 @@ private final class MediaPlayerContext {
renderer.start() renderer.start()
} }
self.seek(timestamp: 0.0, action: .play) self.seek(timestamp: 0.0, action: .play)
case let .seeking(frameSource, timestamp, disposable, _, enableSound): case let .seeking(frameSource, timestamp, seekState, disposable, _, enableSound):
self.state = .seeking(frameSource: frameSource, timestamp: timestamp, disposable: disposable, action: .play, enableSound: enableSound) self.state = .seeking(frameSource: frameSource, timestamp: timestamp, seekState: seekState, disposable: disposable, action: .play, enableSound: enableSound)
self.lastStatusUpdateTimestamp = nil self.lastStatusUpdateTimestamp = nil
case let .paused(loadedState): case let .paused(loadedState):
if loadedState.lostAudioSession { if loadedState.lostAudioSession {
@@ -435,7 +450,7 @@ private final class MediaPlayerContext {
loadedState = currentLoadedState loadedState = currentLoadedState
case let .paused(currentLoadedState): case let .paused(currentLoadedState):
loadedState = currentLoadedState loadedState = currentLoadedState
case let .seeking(_, timestamp, disposable, action, _): case let .seeking(_, timestamp, _, disposable, action, _):
if self.enableSound { if self.enableSound {
self.state = .empty self.state = .empty
disposable.dispose() disposable.dispose()
@@ -476,7 +491,7 @@ private final class MediaPlayerContext {
switch self.state { switch self.state {
case .playing: case .playing:
isPlaying = true isPlaying = true
case let .seeking(_, _, _, action, _): case let .seeking(_, _, _, _, action, _):
switch action { switch action {
case .play: case .play:
isPlaying = true isPlaying = true
@@ -500,8 +515,8 @@ private final class MediaPlayerContext {
switch self.state { switch self.state {
case .empty: case .empty:
break break
case let .seeking(frameSource, timestamp, disposable, _, enableSound): case let .seeking(frameSource, timestamp, seekState, disposable, _, enableSound):
self.state = .seeking(frameSource: frameSource, timestamp: timestamp, disposable: disposable, action: .pause, enableSound: enableSound) self.state = .seeking(frameSource: frameSource, timestamp: timestamp, seekState: seekState, disposable: disposable, action: .pause, enableSound: enableSound)
self.lastStatusUpdateTimestamp = nil self.lastStatusUpdateTimestamp = nil
case let .paused(loadedState): case let .paused(loadedState):
if lostAudioSession { if lostAudioSession {
@@ -523,7 +538,7 @@ private final class MediaPlayerContext {
switch self.state { switch self.state {
case .empty: case .empty:
self.play() self.play()
case let .seeking(_, _, _, action, _): case let .seeking(_, _, _, _, action, _):
switch action { switch action {
case .play: case .play:
self.pause(lostAudioSession: false) self.pause(lostAudioSession: false)
@@ -712,7 +727,7 @@ private final class MediaPlayerContext {
if self.lastStatusUpdateTimestamp == nil || self.lastStatusUpdateTimestamp! < statusTimestamp + 500 { if self.lastStatusUpdateTimestamp == nil || self.lastStatusUpdateTimestamp! < statusTimestamp + 500 {
lastStatusUpdateTimestamp = statusTimestamp lastStatusUpdateTimestamp = statusTimestamp
var reportTimestamp = timestamp var reportTimestamp = timestamp
if case .seeking(_, timestamp, _, _, _) = self.state { if case .seeking(_, timestamp, _, _, _, _) = self.state {
reportTimestamp = timestamp reportTimestamp = timestamp
} }
let status = MediaPlayerStatus(generationTimestamp: statusTimestamp, duration: duration, dimensions: CGSize(), timestamp: min(max(reportTimestamp, 0.0), duration), baseRate: self.baseRate, seekId: self.seekId, status: playbackStatus) let status = MediaPlayerStatus(generationTimestamp: statusTimestamp, duration: duration, dimensions: CGSize(), timestamp: min(max(reportTimestamp, 0.0), duration), baseRate: self.baseRate, seekId: self.seekId, status: playbackStatus)

View File

@@ -389,7 +389,12 @@ final class MediaPlayerScrubbingNode: ASDisplayNode {
strongSelf._scrubbingTimestamp.set(.single(nil)) strongSelf._scrubbingTimestamp.set(.single(nil))
if let scrubbingTimestampValue = scrubbingTimestampValue, apply { if let scrubbingTimestampValue = scrubbingTimestampValue, apply {
if let statusValue = strongSelf.statusValue { if let statusValue = strongSelf.statusValue {
strongSelf.ignoreSeekId = statusValue.seekId switch statusValue.status {
case .buffering:
break
default:
strongSelf.ignoreSeekId = statusValue.seekId
}
} }
strongSelf.seek?(scrubbingTimestampValue) strongSelf.seek?(scrubbingTimestampValue)
} }

View File

@@ -165,7 +165,7 @@ final class MentionChatInputPanelItemNode: ListViewItemNode {
strongSelf.backgroundColor = item.theme.list.plainBackgroundColor strongSelf.backgroundColor = item.theme.list.plainBackgroundColor
strongSelf.highlightedBackgroundNode.backgroundColor = item.theme.list.itemHighlightedBackgroundColor strongSelf.highlightedBackgroundNode.backgroundColor = item.theme.list.itemHighlightedBackgroundColor
strongSelf.avatarNode.setPeer(account: item.account, peer: item.peer) strongSelf.avatarNode.setPeer(account: item.account, peer: item.peer, emptyColor: item.theme.list.mediaPlaceholderColor)
let _ = textApply() let _ = textApply()

View File

@@ -62,22 +62,24 @@ public func peerAvatarImageData(account: Account, peer: Peer, authorOfMessage: M
} }
} }
func peerAvatarImage(account: Account, peer: Peer, authorOfMessage: MessageReference?, representation: TelegramMediaImageRepresentation?, displayDimensions: CGSize = CGSize(width: 60.0, height: 60.0)) -> Signal<UIImage?, NoError>? { func peerAvatarImage(account: Account, peer: Peer, authorOfMessage: MessageReference?, representation: TelegramMediaImageRepresentation?, displayDimensions: CGSize = CGSize(width: 60.0, height: 60.0), emptyColor: UIColor? = nil) -> Signal<UIImage?, NoError>? {
if let imageData = peerAvatarImageData(account: account, peer: peer, authorOfMessage: authorOfMessage, representation: representation) { if let imageData = peerAvatarImageData(account: account, peer: peer, authorOfMessage: authorOfMessage, representation: representation) {
return imageData |> deliverOn(account.graphicsThreadPool) return imageData |> deliverOn(account.graphicsThreadPool)
|> map { data -> UIImage? in |> map { data -> UIImage? in
if let data = data, let image = generateImage(displayDimensions, contextGenerator: { size, context -> Void in return generateImage(displayDimensions, contextGenerator: { size, context -> Void in
if let imageSource = CGImageSourceCreateWithData(data as CFData, nil), let dataImage = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) { if let data = data {
context.setBlendMode(.copy) if let imageSource = CGImageSourceCreateWithData(data as CFData, nil), let dataImage = CGImageSourceCreateImageAtIndex(imageSource, 0, nil) {
context.draw(dataImage, in: CGRect(origin: CGPoint(), size: displayDimensions)) context.setBlendMode(.copy)
context.setBlendMode(.destinationOut) context.draw(dataImage, in: CGRect(origin: CGPoint(), size: displayDimensions))
context.draw(roundCorners.cgImage!, in: CGRect(origin: CGPoint(), size: displayDimensions)) context.setBlendMode(.destinationOut)
context.draw(roundCorners.cgImage!, in: CGRect(origin: CGPoint(), size: displayDimensions))
}
} else if let emptyColor = emptyColor {
context.clear(CGRect(origin: CGPoint(), size: displayDimensions))
context.setFillColor(emptyColor.cgColor)
context.fillEllipse(in: CGRect(origin: CGPoint(), size: displayDimensions))
} }
}) { })
return image
} else {
return nil
}
} }
} else { } else {
return nil return nil

View File

@@ -4,7 +4,7 @@ import TelegramCore
import SwiftSignalKit import SwiftSignalKit
func searchPeerMembers(account: Account, peerId: PeerId, query: String) -> Signal<[Peer], NoError> { func searchPeerMembers(account: Account, peerId: PeerId, query: String) -> Signal<[Peer], NoError> {
if peerId.namespace == Namespaces.Peer.CloudChannel && !query.isEmpty { if peerId.namespace == Namespaces.Peer.CloudChannel {
return account.postbox.transaction { transaction -> CachedChannelData? in return account.postbox.transaction { transaction -> CachedChannelData? in
return transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData return transaction.getPeerCachedData(peerId: peerId) as? CachedChannelData
} }
@@ -18,15 +18,18 @@ func searchPeerMembers(account: Account, peerId: PeerId, query: String) -> Signa
if normalizedQuery.isEmpty { if normalizedQuery.isEmpty {
return participant.peer return participant.peer
} }
if normalizedQuery.isEmpty {
if participant.peer.indexName.matchesByTokens(normalizedQuery) {
return participant.peer return participant.peer
} else {
if participant.peer.indexName.matchesByTokens(normalizedQuery) {
return participant.peer
}
if let addressName = participant.peer.addressName, addressName.lowercased().hasPrefix(normalizedQuery) {
return participant.peer
}
return nil
} }
if let addressName = participant.peer.addressName, addressName.lowercased().hasPrefix(normalizedQuery) {
return participant.peer
}
return nil
}) })
} }
}) })
@@ -38,7 +41,7 @@ func searchPeerMembers(account: Account, peerId: PeerId, query: String) -> Signa
} }
return Signal { subscriber in return Signal { subscriber in
let (disposable, _) = account.telegramApplicationContext.peerChannelMemberCategoriesContextsManager.recent(postbox: account.postbox, network: account.network, accountPeerId: account.peerId, peerId: peerId, searchQuery: query, updated: { state in let (disposable, _) = account.telegramApplicationContext.peerChannelMemberCategoriesContextsManager.recent(postbox: account.postbox, network: account.network, accountPeerId: account.peerId, peerId: peerId, searchQuery: query.isEmpty ? nil : query, updated: { state in
if case .ready = state.loadingState { if case .ready = state.loadingState {
subscriber.putNext(state.list.map { $0.peer }) subscriber.putNext(state.list.map { $0.peer })
} }

View File

@@ -17,14 +17,16 @@ final class SelectablePeerNodeTheme {
let checkBackgroundColor: UIColor let checkBackgroundColor: UIColor
let checkFillColor: UIColor let checkFillColor: UIColor
let checkColor: UIColor let checkColor: UIColor
let avatarPlaceholderColor: UIColor
init(textColor: UIColor, secretTextColor: UIColor, selectedTextColor: UIColor, checkBackgroundColor: UIColor, checkFillColor: UIColor, checkColor: UIColor) { init(textColor: UIColor, secretTextColor: UIColor, selectedTextColor: UIColor, checkBackgroundColor: UIColor, checkFillColor: UIColor, checkColor: UIColor, avatarPlaceholderColor: UIColor) {
self.textColor = textColor self.textColor = textColor
self.secretTextColor = secretTextColor self.secretTextColor = secretTextColor
self.selectedTextColor = selectedTextColor self.selectedTextColor = selectedTextColor
self.checkBackgroundColor = checkBackgroundColor self.checkBackgroundColor = checkBackgroundColor
self.checkFillColor = checkFillColor self.checkFillColor = checkFillColor
self.checkColor = checkColor self.checkColor = checkColor
self.avatarPlaceholderColor = avatarPlaceholderColor
} }
func isEqual(to: SelectablePeerNodeTheme) -> Bool { func isEqual(to: SelectablePeerNodeTheme) -> Bool {
@@ -49,6 +51,9 @@ final class SelectablePeerNodeTheme {
if !self.checkColor.isEqual(to.checkColor) { if !self.checkColor.isEqual(to.checkColor) {
return false return false
} }
if !self.avatarPlaceholderColor.isEqual(to.avatarPlaceholderColor) {
return false
}
return true return true
} }
} }
@@ -67,7 +72,7 @@ final class SelectablePeerNode: ASDisplayNode {
private var peer: RenderedPeer? private var peer: RenderedPeer?
var theme: SelectablePeerNodeTheme = SelectablePeerNodeTheme(textColor: .black, secretTextColor: .green, selectedTextColor: .blue, checkBackgroundColor: .white, checkFillColor: .blue, checkColor: .white) { var theme: SelectablePeerNodeTheme = SelectablePeerNodeTheme(textColor: .black, secretTextColor: .green, selectedTextColor: .blue, checkBackgroundColor: .white, checkFillColor: .blue, checkColor: .white, avatarPlaceholderColor: .white) {
didSet { didSet {
if !self.theme.isEqual(to: oldValue) { if !self.theme.isEqual(to: oldValue) {
if let peer = self.peer, let mainPeer = peer.chatMainPeer { if let peer = self.peer, let mainPeer = peer.chatMainPeer {
@@ -124,7 +129,7 @@ final class SelectablePeerNode: ASDisplayNode {
} }
self.textNode.maximumNumberOfLines = UInt(numberOfLines) self.textNode.maximumNumberOfLines = UInt(numberOfLines)
self.textNode.attributedText = NSAttributedString(string: text, font: textFont, textColor: self.currentSelected ? self.theme.selectedTextColor : defaultColor, paragraphAlignment: .center) self.textNode.attributedText = NSAttributedString(string: text, font: textFont, textColor: self.currentSelected ? self.theme.selectedTextColor : defaultColor, paragraphAlignment: .center)
self.avatarNode.setPeer(account: account, peer: mainPeer, overrideImage: overrideImage) self.avatarNode.setPeer(account: account, peer: mainPeer, overrideImage: overrideImage, emptyColor: self.theme.avatarPlaceholderColor)
self.setNeedsLayout() self.setNeedsLayout()
} }

View File

@@ -146,7 +146,7 @@ final class ShareControllerPeerGridItemNode: GridItemNode {
func setup(account: Account, theme: PresentationTheme, strings: PresentationStrings, peer: RenderedPeer, search: Bool) { func setup(account: Account, theme: PresentationTheme, strings: PresentationStrings, peer: RenderedPeer, search: Bool) {
if self.currentState == nil || self.currentState!.0 !== account || self.currentState!.1 != peer { if self.currentState == nil || self.currentState!.0 !== account || self.currentState!.1 != peer {
let itemTheme = SelectablePeerNodeTheme(textColor: theme.actionSheet.primaryTextColor, secretTextColor: theme.chatList.secretTitleColor, selectedTextColor: theme.actionSheet.controlAccentColor, checkBackgroundColor: theme.actionSheet.opaqueItemBackgroundColor, checkFillColor: theme.actionSheet.controlAccentColor, checkColor: theme.actionSheet.checkContentColor) let itemTheme = SelectablePeerNodeTheme(textColor: theme.actionSheet.primaryTextColor, secretTextColor: theme.chatList.secretTitleColor, selectedTextColor: theme.actionSheet.controlAccentColor, checkBackgroundColor: theme.actionSheet.opaqueItemBackgroundColor, checkFillColor: theme.actionSheet.controlAccentColor, checkColor: theme.actionSheet.checkContentColor, avatarPlaceholderColor: theme.list.mediaPlaceholderColor)
self.peerNode.theme = itemTheme self.peerNode.theme = itemTheme
self.peerNode.setup(account: account, strings: strings, peer: peer) self.peerNode.setup(account: account, strings: strings, peer: peer)
self.currentState = (account, peer, search) self.currentState = (account, peer, search)