From 091f313b01860852d414487658265d0744828e8c Mon Sep 17 00:00:00 2001 From: Valentin Perignon Date: Tue, 20 Jun 2023 11:25:37 +0200 Subject: [PATCH] feat: Add debounce --- .../New Message/AutocompletionView.swift | 19 +++++++++++------- .../ComposeMessageCellRecipients.swift | 20 ++++++++++++++----- Mail/Views/New Message/RecipientField.swift | 2 +- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/Mail/Views/New Message/AutocompletionView.swift b/Mail/Views/New Message/AutocompletionView.swift index 37abdf3883..cc074e6cff 100644 --- a/Mail/Views/New Message/AutocompletionView.swift +++ b/Mail/Views/New Message/AutocompletionView.swift @@ -16,6 +16,7 @@ along with this program. If not, see . */ +import Combine import MailCore import MailResources import RealmSwift @@ -24,8 +25,9 @@ import SwiftUI struct AutocompletionView: View { @State private var shouldAddUserProposal = false + @ObservedObject var cellRecipientsModel: CellRecipientsModel + @Binding var autocompletion: [Recipient] - @Binding var currentSearch: String @Binding var addedRecipients: RealmSwift.List let addRecipient: @MainActor (Recipient) -> Void @@ -40,7 +42,7 @@ struct AutocompletionView: View { AutocompletionCell( addRecipient: addRecipient, recipient: recipient, - highlight: currentSearch, + highlight: cellRecipientsModel.currentText, alreadyAppend: addedRecipients.contains { $0.isSameRecipient(as: recipient) }, unknownRecipient: isUserProposal ) @@ -52,9 +54,12 @@ struct AutocompletionView: View { } } .onAppear { - updateAutocompletion(currentSearch) + updateAutocompletion(cellRecipientsModel.currentText) + } + // .onChange(of: currentSearch, perform: updateAutocompletion) + .onReceive(cellRecipientsModel.$currentText.debounce(for: .milliseconds(150), scheduler: DispatchQueue.main)) { currentValue in + updateAutocompletion("\(currentValue)") } - .onChange(of: currentSearch, perform: updateAutocompletion) } private func updateAutocompletion(_ search: String) { @@ -73,10 +78,10 @@ struct AutocompletionView: View { let realResults = autocompleteRecipients.filter { !addedRecipients.map(\.email).contains($0.email) } withAnimation { - shouldAddUserProposal = !(realResults.count == 1 && realResults.first?.email == currentSearch) + shouldAddUserProposal = !(realResults.count == 1 && realResults.first?.email == cellRecipientsModel.currentText) if shouldAddUserProposal { autocompleteRecipients - .append(Recipient(email: currentSearch, name: "")) + .append(Recipient(email: cellRecipientsModel.currentText, name: "")) } autocompletion = autocompleteRecipients @@ -87,8 +92,8 @@ struct AutocompletionView: View { struct AutocompletionView_Previews: PreviewProvider { static var previews: some View { AutocompletionView( + cellRecipientsModel: CellRecipientsModel(), autocompletion: .constant([]), - currentSearch: .constant(""), addedRecipients: .constant([PreviewHelper.sampleRecipient1].toRealmList()) ) { _ in /* Preview */ } } diff --git a/Mail/Views/New Message/Header Cells/ComposeMessageCellRecipients.swift b/Mail/Views/New Message/Header Cells/ComposeMessageCellRecipients.swift index 500c3b4d4f..515b1af8fc 100644 --- a/Mail/Views/New Message/Header Cells/ComposeMessageCellRecipients.swift +++ b/Mail/Views/New Message/Header Cells/ComposeMessageCellRecipients.swift @@ -33,8 +33,13 @@ extension VerticalAlignment { static let newMessageCellAlignment = VerticalAlignment(NewMessageCellAlignment.self) } +class CellRecipientsModel: ObservableObject { + @Published var currentText = "" +} + struct ComposeMessageCellRecipients: View { - @State private var currentText = "" + @StateObject private var cellRecipientsModel = CellRecipientsModel() + @State private var autocompletion = [Recipient]() @Binding var recipients: RealmSwift.List @@ -52,7 +57,12 @@ struct ComposeMessageCellRecipients: View { Text(type.title) .textStyle(.bodySecondary) - RecipientField(currentText: $currentText, recipients: $recipients, focusedField: _focusedField, type: type) { + RecipientField( + currentText: $cellRecipientsModel.currentText, + recipients: $recipients, + focusedField: _focusedField, + type: type + ) { if let bestMatch = autocompletion.first { addNewRecipient(bestMatch) } @@ -70,8 +80,8 @@ struct ComposeMessageCellRecipients: View { if autocompletionType == type { AutocompletionView( + cellRecipientsModel: cellRecipientsModel, autocompletion: $autocompletion, - currentSearch: $currentText, addedRecipients: $recipients, addRecipient: addNewRecipient ) @@ -81,7 +91,7 @@ struct ComposeMessageCellRecipients: View { .onTapGesture { focusedField = type } - .onChange(of: currentText) { newValue in + .onChange(of: cellRecipientsModel.currentText) { newValue in withAnimation { if newValue.isEmpty { autocompletionType = nil @@ -109,7 +119,7 @@ struct ComposeMessageCellRecipients: View { withAnimation { $recipients.append(recipient) } - currentText = "" + cellRecipientsModel.currentText = "" } } diff --git a/Mail/Views/New Message/RecipientField.swift b/Mail/Views/New Message/RecipientField.swift index ce0cde8fe0..d230e619d5 100644 --- a/Mail/Views/New Message/RecipientField.swift +++ b/Mail/Views/New Message/RecipientField.swift @@ -82,7 +82,7 @@ struct RecipientField: View { } private func switchFocus() { - guard case .chip(let hash, let recipient) = focusedField else { return } + guard case let .chip(hash, recipient) = focusedField else { return } if recipient == recipients.last { focusedField = type