diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift index 46d22198fe..262955ad44 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift @@ -353,7 +353,7 @@ public final class VoiceChatController: ViewController { } else { let volumeValue = peerEntry.volume.flatMap { $0 / 100 } if let volume = volumeValue, volume != 100 { - text = .text("\(volume / 100)% \(presentationData.strings.VoiceChat_StatusSpeaking)", .constructive) + text = .text("\(volume)% \(presentationData.strings.VoiceChat_StatusSpeaking)", .constructive) } else { text = .text(presentationData.strings.VoiceChat_StatusSpeaking, .constructive) } diff --git a/submodules/TelegramUI/Sources/ChatControllerNode.swift b/submodules/TelegramUI/Sources/ChatControllerNode.swift index 19f6198ae7..b14a3fcf57 100644 --- a/submodules/TelegramUI/Sources/ChatControllerNode.swift +++ b/submodules/TelegramUI/Sources/ChatControllerNode.swift @@ -306,6 +306,8 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { let historyNodeContainer: ASDisplayNode let loadingNode: ChatLoadingNode private var emptyNode: ChatEmptyNode? + private var emptyType: ChatHistoryNodeLoadState.EmptyType? + private var didDisplayEmptyGreeting = false private var validEmptyNodeLayout: (CGSize, UIEdgeInsets)? var restrictedNode: ChatRecentActionsEmptyNode? @@ -535,11 +537,18 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { strongSelf.updateIsLoading(isLoading: false, animated: animated) } - var isEmpty = false - if case .empty = loadState { - isEmpty = true + var emptyType: ChatHistoryNodeLoadState.EmptyType? + if case let .empty(type) = loadState { + emptyType = type + if case .joined = type { + if strongSelf.didDisplayEmptyGreeting { + emptyType = .generic + } else { + strongSelf.didDisplayEmptyGreeting = true + } + } } - strongSelf.updateIsEmpty(isEmpty, animated: animated) + strongSelf.updateIsEmpty(emptyType, animated: animated) } } @@ -707,11 +716,12 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { }) } - private func updateIsEmpty(_ isEmpty: Bool, animated: Bool) { - if isEmpty && self.emptyNode == nil { + private func updateIsEmpty(_ emptyType: ChatHistoryNodeLoadState.EmptyType?, animated: Bool) { + self.emptyType = emptyType + if let emptyType = emptyType, self.emptyNode == nil { let emptyNode = ChatEmptyNode(account: self.context.account, interaction: self.interfaceInteraction) if let (size, insets) = self.validEmptyNodeLayout { - emptyNode.updateLayout(interfaceState: self.chatPresentationInterfaceState, size: size, insets: insets, transition: .immediate) + emptyNode.updateLayout(interfaceState: self.chatPresentationInterfaceState, emptyType: emptyType, size: size, insets: insets, transition: .immediate) } emptyNode.isHidden = self.restrictedNode != nil self.emptyNode = emptyNode @@ -1374,8 +1384,8 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate { var emptyNodeInsets = insets emptyNodeInsets.bottom += inputPanelsHeight self.validEmptyNodeLayout = (contentBounds.size, emptyNodeInsets) - if let emptyNode = self.emptyNode { - emptyNode.updateLayout(interfaceState: self.chatPresentationInterfaceState, size: contentBounds.size, insets: emptyNodeInsets, transition: transition) + if let emptyNode = self.emptyNode, let emptyType = self.emptyType { + emptyNode.updateLayout(interfaceState: self.chatPresentationInterfaceState, emptyType: emptyType, size: contentBounds.size, insets: emptyNodeInsets, transition: transition) transition.updateFrame(node: emptyNode, frame: contentBounds) } diff --git a/submodules/TelegramUI/Sources/ChatEmptyNode.swift b/submodules/TelegramUI/Sources/ChatEmptyNode.swift index 7be7123c6a..7bf9203539 100644 --- a/submodules/TelegramUI/Sources/ChatEmptyNode.swift +++ b/submodules/TelegramUI/Sources/ChatEmptyNode.swift @@ -809,7 +809,7 @@ final class ChatEmptyNode: ASDisplayNode { self.addSubnode(self.backgroundNode) } - func updateLayout(interfaceState: ChatPresentationInterfaceState, size: CGSize, insets: UIEdgeInsets, transition: ContainedViewLayoutTransition) { + func updateLayout(interfaceState: ChatPresentationInterfaceState, emptyType: ChatHistoryNodeLoadState.EmptyType, size: CGSize, insets: UIEdgeInsets, transition: ContainedViewLayoutTransition) { if self.currentTheme !== interfaceState.theme || self.currentStrings !== interfaceState.strings { self.currentTheme = interfaceState.theme self.currentStrings = interfaceState.strings @@ -838,7 +838,11 @@ final class ChatEmptyNode: ASDisplayNode { } else if let _ = interfaceState.peerNearbyData { contentType = .peerNearby } else if let _ = peer as? TelegramUser { - contentType = .greeting + if case .joined = emptyType { + contentType = .greeting + } else { + contentType = .regular + } } else { contentType = .regular } diff --git a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift index b80b10f2cc..50bd903835 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryListNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryListNode.swift @@ -1700,7 +1700,18 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { let loadState: ChatHistoryNodeLoadState if transition.historyView.filteredEntries.isEmpty { - loadState = .empty + if let firstEntry = transition.historyView.originalView.entries.first { + var isPeerJoined = false + for media in firstEntry.message.media { + if let action = media as? TelegramMediaAction, action.action == .peerJoined { + isPeerJoined = true + break + } + } + loadState = .empty(isPeerJoined ? .joined : .generic) + } else { + loadState = .empty(.generic) + } } else { loadState = .messages } @@ -1732,8 +1743,15 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode { let loadState: ChatHistoryNodeLoadState if let historyView = strongSelf.historyView { - if historyView.filteredEntries.isEmpty { - loadState = .empty + if let firstEntry = historyView.originalView.entries.first, historyView.filteredEntries.isEmpty { + var isPeerJoined = false + for media in firstEntry.message.media { + if let action = media as? TelegramMediaAction, action.action == .peerJoined { + isPeerJoined = true + break + } + } + loadState = .empty(isPeerJoined ? .joined : .generic) } else { loadState = .messages } diff --git a/submodules/TelegramUI/Sources/ChatHistoryNode.swift b/submodules/TelegramUI/Sources/ChatHistoryNode.swift index 6e4da2b2a6..8e7a7a8ba5 100644 --- a/submodules/TelegramUI/Sources/ChatHistoryNode.swift +++ b/submodules/TelegramUI/Sources/ChatHistoryNode.swift @@ -10,9 +10,14 @@ public enum ChatHistoryNodeHistoryState: Equatable { case loaded(isEmpty: Bool) } -public enum ChatHistoryNodeLoadState { +public enum ChatHistoryNodeLoadState: Equatable { + public enum EmptyType: Equatable { + case generic + case joined + } + case loading - case empty + case empty(EmptyType) case messages } diff --git a/submodules/TelegramUI/Sources/ContactMultiselectionController.swift b/submodules/TelegramUI/Sources/ContactMultiselectionController.swift index 0684eab5bc..d3f55ee3e1 100644 --- a/submodules/TelegramUI/Sources/ContactMultiselectionController.swift +++ b/submodules/TelegramUI/Sources/ContactMultiselectionController.swift @@ -484,6 +484,11 @@ class ContactMultiselectionControllerImpl: ViewController, ContactMultiselection strongSelf.requestLayout(transition: ContainedViewLayoutTransition.animated(duration: 0.4, curve: .spring)) } } + self.contactsNode.complete = { [weak self] in + if let strongSelf = self, let rightBarButtonItem = strongSelf.navigationItem.rightBarButtonItem, rightBarButtonItem.isEnabled { + strongSelf.rightNavigationButtonPressed() + } + } self.displayNodeDidLoad() } diff --git a/submodules/TelegramUI/Sources/ContactMultiselectionControllerNode.swift b/submodules/TelegramUI/Sources/ContactMultiselectionControllerNode.swift index a8ee2bc540..6623c13665 100644 --- a/submodules/TelegramUI/Sources/ContactMultiselectionControllerNode.swift +++ b/submodules/TelegramUI/Sources/ContactMultiselectionControllerNode.swift @@ -57,6 +57,7 @@ final class ContactMultiselectionControllerNode: ASDisplayNode { var removeSelectedPeer: ((ContactListPeerId) -> Void)? var removeSelectedCategory: ((Int) -> Void)? var additionalCategorySelected: ((Int) -> Void)? + var complete: (() -> Void)? var editableTokens: [EditableTokenListToken] = [] @@ -214,6 +215,9 @@ final class ContactMultiselectionControllerNode: ASDisplayNode { } } } + self.tokenListNode.textReturned = { [weak self] in + self?.complete?() + } self.presentationDataDisposable = (context.sharedContext.presentationData |> deliverOnMainQueue).start(next: { [weak self] presentationData in diff --git a/submodules/TelegramUI/Sources/EditableTokenListNode.swift b/submodules/TelegramUI/Sources/EditableTokenListNode.swift index 498661adb7..15ae33ed4b 100644 --- a/submodules/TelegramUI/Sources/EditableTokenListNode.swift +++ b/submodules/TelegramUI/Sources/EditableTokenListNode.swift @@ -123,6 +123,7 @@ final class EditableTokenListNode: ASDisplayNode, UITextFieldDelegate { var textUpdated: ((String) -> Void)? var deleteToken: ((AnyHashable) -> Void)? + var textReturned: (() -> Void)? init(theme: EditableTokenListNodeTheme, placeholder: String) { self.theme = theme @@ -335,6 +336,11 @@ final class EditableTokenListNode: ASDisplayNode, UITextFieldDelegate { } } + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + self.textReturned?() + return false + } + func textFieldDidBeginEditing(_ textField: UITextField) { /*if self.caretIndicatorNode.supernode == self { self.caretIndicatorNode.removeFromSupernode()