From fb2edb3bd68b93185be84c3e97d729f07f3bceeb Mon Sep 17 00:00:00 2001 From: Oleg Date: Mon, 26 Feb 2024 14:03:21 +0700 Subject: [PATCH] Refactoring --- .../Messaging/Chat/ChatView/ChatView.swift | 51 ++++--------------- .../Chat/ChatView/ChatViewModel.swift | 46 ++++++++++++++++- 2 files changed, 54 insertions(+), 43 deletions(-) diff --git a/unstoppable-ios-app/domains-manager-ios/Modules/Messaging/Chat/ChatView/ChatView.swift b/unstoppable-ios-app/domains-manager-ios/Modules/Messaging/Chat/ChatView/ChatView.swift index dec8c04ee..18447d5ec 100644 --- a/unstoppable-ios-app/domains-manager-ios/Modules/Messaging/Chat/ChatView/ChatView.swift +++ b/unstoppable-ios-app/domains-manager-ios/Modules/Messaging/Chat/ChatView/ChatView.swift @@ -12,7 +12,6 @@ struct ChatView: View, ViewAnalyticsLogger { @EnvironmentObject var navigationState: NavigationStateManager @StateObject var viewModel: ChatViewModel @FocusState var focused: Bool - @State private var suggestingUsers: [MessagingChatUserDisplayInfo] = [] var analyticsName: Analytics.ViewName { .chatDialog } var additionalAppearAnalyticParameters: Analytics.EventParameters { [:] } @@ -38,9 +37,9 @@ struct ChatView: View, ViewAnalyticsLogger { focused = keyboardFocused } } - .onChange(of: viewModel.input) { newValue in + .onChange(of: viewModel.input) { _ in withAnimation { - showMentionSuggestionsIfNeeded(in: newValue) + viewModel.showMentionSuggestionsIfNeeded() } } .toolbar { @@ -82,34 +81,10 @@ private extension ChatView { } } } - - func showMentionSuggestionsIfNeeded(in text: String) { - let listOfGroupParticipants = viewModel.listOfGroupParticipants - if !listOfGroupParticipants.isEmpty { - let components = text.components(separatedBy: " ") - if let lastComponent = components.last, - let mention = MessageMentionString(string: lastComponent) { - showMentionSuggestions(using: listOfGroupParticipants, - mention: mention) - } - } - } - - func showMentionSuggestions(using listOfGroupParticipants: [MessagingChatUserDisplayInfo], - mention: MessageMentionString) { - let mentionUsername = mention.mentionWithoutPrefix.lowercased() - if mentionUsername.isEmpty { - suggestingUsers = listOfGroupParticipants - } else { - suggestingUsers = listOfGroupParticipants.filter { - let nameForMention = $0.nameForMention - let isMentionFullyTyped = nameForMention == mentionUsername - let isUsernameContainMention = nameForMention?.contains(mentionUsername) == true - return isUsernameContainMention && !isMentionFullyTyped - } - } - } - +} + +// MARK: - Views +private extension ChatView { @ViewBuilder func chatContentView() -> some View { ScrollViewReader { proxy in @@ -205,7 +180,7 @@ private extension ChatView { @ViewBuilder func chatInputView() -> some View { VStack { - if !suggestingUsers.isEmpty { + if !viewModel.suggestingUsers.isEmpty { mentionSuggestionsView() } messageInputView() @@ -224,16 +199,8 @@ private extension ChatView { @ViewBuilder func mentionSuggestionsView() -> some View { - ChatMentionSuggestionsView(suggestingUsers: suggestingUsers, - selectionCallback: { user in - if let nameForMention = user.nameForMention, - let mention = MessageMentionString.makeMentionFrom(string: nameForMention) { - var userInput = viewModel.input.components(separatedBy: " ").dropLast() - userInput.append(mention.mentionWithPrefix) - viewModel.input = userInput.joined(separator: " ") - suggestingUsers.removeAll() - } - }) + ChatMentionSuggestionsView(suggestingUsers: viewModel.suggestingUsers, + selectionCallback: viewModel.didSelectMentionSuggestion) .padding(.init(horizontal: 20)) } diff --git a/unstoppable-ios-app/domains-manager-ios/Modules/Messaging/Chat/ChatView/ChatViewModel.swift b/unstoppable-ios-app/domains-manager-ios/Modules/Messaging/Chat/ChatView/ChatViewModel.swift index aa3ac15e7..d06779845 100644 --- a/unstoppable-ios-app/domains-manager-ios/Modules/Messaging/Chat/ChatView/ChatViewModel.swift +++ b/unstoppable-ios-app/domains-manager-ios/Modules/Messaging/Chat/ChatView/ChatViewModel.swift @@ -30,6 +30,8 @@ final class ChatViewModel: ObservableObject, ViewAnalyticsLogger { @Published private(set) var placeholder: String = "" @Published private(set) var navActions: [ChatView.NavAction] = [] @Published private(set) var titleType: ChatNavTitleView.TitleType = .walletAddress("") + @Published private(set) var suggestingUsers: [MessagingChatUserDisplayInfo] = [] + @Published var input: String = "" @Published var keyboardFocused: Bool = false @Published var error: Error? @@ -104,7 +106,7 @@ extension ChatViewModel { Task { if case .existingChat(let chat) = conversationState, case .private(let details) = chat.type { - try? await setUser(details.otherUser, in: chat, blocked: true) + _ = (try? await setUser(details.otherUser, in: chat, blocked: true)) } } } @@ -171,10 +173,52 @@ extension ChatViewModel { func handleExternalLinkPressed(_ url: URL, by sender: MessagingChatSender) { verifyAndHandleExternalLink(url, by: sender) } + + func showMentionSuggestionsIfNeeded() { + let listOfGroupParticipants = listOfGroupParticipants + if !listOfGroupParticipants.isEmpty { + let components = input.components(separatedBy: " ") + if let lastComponent = components.last, + let mention = MessageMentionString(string: lastComponent) { + showMentionSuggestions(using: listOfGroupParticipants, + mention: mention) + } + } + } + + func didSelectMentionSuggestion(user: MessagingChatUserDisplayInfo) { + if let nameForMention = user.nameForMention, + let mention = MessageMentionString.makeMentionFrom(string: nameForMention) { + replaceCurrentInputWithSelectedMention(mention) + } + } } // MARK: - Private methods private extension ChatViewModel { + func showMentionSuggestions(using listOfGroupParticipants: [MessagingChatUserDisplayInfo], + mention: MessageMentionString) { + let mentionUsername = mention.mentionWithoutPrefix.lowercased() + if mentionUsername.isEmpty { + suggestingUsers = listOfGroupParticipants + } else { + suggestingUsers = listOfGroupParticipants.filter { + let nameForMention = $0.nameForMention + let isMentionFullyTyped = nameForMention == mentionUsername + let isUsernameContainMention = nameForMention?.contains(mentionUsername) == true + return isUsernameContainMention && !isMentionFullyTyped + } + } + } + + func replaceCurrentInputWithSelectedMention(_ mention: MessageMentionString) { + let separator = " " + var userInput = input.components(separatedBy: separator).dropLast() + userInput.append(mention.mentionWithPrefix) + input = userInput.joined(separator: separator) + suggestingUsers.removeAll() + } + func verifyAndHandleExternalLink(_ url: URL, by sender: MessagingChatSender) { if let domainName = parseMentionDomainNameFrom(url: url) { handleMentionPressedTo(domainName: domainName)