Skip to content

Commit 2b28491

Browse files
LnamwMatthieu-dgl
authored andcommitted
feat: WIP
1 parent 5450dfc commit 2b28491

12 files changed

+141
-67
lines changed

Mail/Views/New Message/AutocompletionCell.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,21 @@ import MailResources
2323
import SwiftUI
2424

2525
struct AutocompletionCell: View {
26-
let addRecipient: @MainActor (Recipient) -> Void
27-
let recipient: Recipient
26+
let addRecipient: @MainActor (any ContactAutocompletable) -> Void
27+
let autocompletion: any ContactAutocompletable
2828
var highlight: String?
2929
let alreadyAppend: Bool
3030
let unknownRecipient: Bool
3131

3232
var body: some View {
3333
HStack(spacing: IKPadding.intermediate) {
3434
Button {
35-
addRecipient(recipient)
35+
addRecipient(autocompletion)
3636
} label: {
37-
if unknownRecipient {
38-
UnknownRecipientCell(recipient: recipient)
37+
if unknownRecipient, let email = autocompletion.email {
38+
UnknownRecipientCell(email: email)
3939
} else {
40-
RecipientCell(recipient: recipient, highlight: highlight)
40+
RecipientCell(contact: autocompletion, highlight: highlight)
4141
}
4242
}
4343
.allowsHitTesting(!alreadyAppend || unknownRecipient)
@@ -56,7 +56,7 @@ struct AutocompletionCell: View {
5656
#Preview {
5757
AutocompletionCell(
5858
addRecipient: { _ in /* Preview */ },
59-
recipient: PreviewHelper.sampleRecipient1,
59+
autocompletion: PreviewHelper.sampleMergedContact,
6060
alreadyAppend: false,
6161
unknownRecipient: false
6262
)

Mail/Views/New Message/AutocompletionView.swift

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,23 +32,26 @@ struct AutocompletionView: View {
3232

3333
@ObservedObject var textDebounce: TextDebounce
3434

35-
@Binding var autocompletion: [Recipient]
35+
@Binding var autocompletion: [any ContactAutocompletable]
3636
@Binding var addedRecipients: RealmSwift.List<Recipient>
3737

38-
let addRecipient: @MainActor (Recipient) -> Void
38+
let addRecipient: @MainActor (any ContactAutocompletable) -> Void
3939

4040
var body: some View {
4141
LazyVStack(spacing: IKPadding.small) {
42-
ForEach(autocompletion) { recipient in
43-
let isLastRecipient = autocompletion.last?.isSameCorrespondent(as: recipient) == true
42+
// TODO: Fix conformance Identifiable
43+
ForEach(autocompletion, id: \.stringId) { contact in
44+
let isLastRecipient =
45+
false // TODO: A implémenter -> autocompletion.last?.isSameCorrespondent(as: recipient) == true
4446
let isUserProposal = shouldAddUserProposal && isLastRecipient
4547

4648
VStack(alignment: .leading, spacing: IKPadding.small) {
4749
AutocompletionCell(
4850
addRecipient: addRecipient,
49-
recipient: recipient,
51+
autocompletion: contact,
5052
highlight: textDebounce.text,
51-
alreadyAppend: addedRecipients.contains { $0.isSameCorrespondent(as: recipient) },
53+
alreadyAppend: false,
54+
// TODO: A implémenter -> addedRecipients.contains { $0.isSameCorrespondent(as: recipient) },
5255
unknownRecipient: isUserProposal
5356
)
5457

@@ -77,25 +80,23 @@ struct AutocompletionView: View {
7780
fetchLimit: Self.maxAutocompleteCount,
7881
sorted: sortByRemoteAndName
7982
)
80-
var autocompleteRecipients = autocompleteContacts.map { Recipient(email: $0.email, name: $0.name) }
8183

82-
let autocompleteGroupContact = mailboxManager.contactManager.frozenGroupContacts(matching: trimmedSearch, fetchLimit: nil)
84+
let autocompleteGroupContacts = mailboxManager.contactManager.frozenGroupContacts(
85+
matching: trimmedSearch,
86+
fetchLimit: nil
87+
)
8388

84-
// TODO: Find group or organisation name
85-
var autocompleteGroupRecipients = autocompleteGroupContact.map { Recipient(
86-
email: "Afficher nom groupe ou organisation ?",
87-
name: "Groupe/carnet ? \($0.name)"
88-
) }
89+
let result: [any ContactAutocompletable] = Array(autocompleteContacts) + Array(autocompleteGroupContacts)
8990

90-
var result = autocompleteRecipients + autocompleteGroupRecipients
91+
// TODO: A implémenter
92+
// let realResults = autocompleteRecipients.filter { !addedRecipients.map(\.email).contains($0.email) }
93+
//
94+
// shouldAddUserProposal = !(realResults.count == 1 && realResults.first?.email == textDebounce.text)
95+
// if shouldAddUserProposal {
96+
// autocompleteRecipients.append(Recipient(email: textDebounce.text, name: ""))
97+
// }
9198

92-
let realResults = autocompleteRecipients.filter { !addedRecipients.map(\.email).contains($0.email) }
93-
94-
shouldAddUserProposal = !(realResults.count == 1 && realResults.first?.email == textDebounce.text)
95-
if shouldAddUserProposal {
96-
autocompleteRecipients.append(Recipient(email: textDebounce.text, name: ""))
97-
}
98-
autocompletion = autocompleteRecipients
99+
autocompletion = result
99100
}
100101
}
101102

Mail/Views/New Message/Header Cells/ComposeMessageCellRecipients.swift

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ class TextDebounce: ObservableObject {
4949
struct ComposeMessageCellRecipients: View {
5050
@StateObject private var textDebounce = TextDebounce()
5151

52-
@State private var autocompletion = [Recipient]()
52+
@EnvironmentObject private var mailboxManager: MailboxManager
53+
54+
@State private var autocompletion = [any ContactAutocompletable]()
5355

5456
@Binding var recipients: RealmSwift.List<Recipient>
5557
@Binding var showRecipientsFields: Bool
@@ -130,23 +132,35 @@ struct ComposeMessageCellRecipients: View {
130132
}
131133
}
132134

133-
@MainActor private func addNewRecipient(_ recipient: Recipient) {
135+
@MainActor private func addNewRecipient(_ contact: any ContactAutocompletable) {
134136
matomo.track(eventWithCategory: .newMessage, name: "addNewRecipient")
135137

136-
guard Constants.isEmailAddress(recipient.email) else {
137-
snackbarPresenter.show(message: MailResourcesStrings.Localizable.addUnknownRecipientInvalidEmail)
138-
return
139-
}
138+
if let mergedContact = contact as? MergedContact {
139+
$recipients.append(Recipient(email: mergedContact.email ?? "", name: mergedContact.name))
140+
} else if let groupeContact = contact as? GroupContact {
141+
let groupeContacts = mailboxManager.contactManager.getContacts(with: groupeContact.id)
140142

141-
guard !recipients.contains(where: { $0.isSameCorrespondent(as: recipient) }) else {
142-
snackbarPresenter.show(message: MailResourcesStrings.Localizable.addUnknownRecipientAlreadyUsed)
143-
return
143+
var groupContactRecipients = groupeContacts.map {
144+
$recipients.append(Recipient(email: $0.email ?? "", name: $0.name))
145+
}
144146
}
145147

146-
withAnimation {
147-
recipient.isAddedByMe = true
148-
$recipients.append(recipient)
149-
}
148+
// TODO: à implémenter
149+
// guard Constants.isEmailAddress(recipient.email) else {
150+
// snackbarPresenter.show(message: MailResourcesStrings.Localizable.addUnknownRecipientInvalidEmail)
151+
// return
152+
// }
153+
//
154+
// guard !recipients.contains(where: { $0.isSameCorrespondent(as: recipient) }) else {
155+
// snackbarPresenter.show(message: MailResourcesStrings.Localizable.addUnknownRecipientAlreadyUsed)
156+
// return
157+
// }
158+
//
159+
// withAnimation {
160+
// recipient.isAddedByMe = true
161+
// $recipients.append(recipient)
162+
// }
163+
150164
textDebounce.text = ""
151165
}
152166
}

Mail/Views/New Message/UnknownRecipientCell.swift

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,7 @@ import MailResources
2222
import SwiftUI
2323

2424
public struct UnknownRecipientCell: View {
25-
let recipient: Recipient
26-
27-
public init(recipient: Recipient) {
28-
self.recipient = recipient
29-
}
25+
let email: String
3026

3127
public var body: some View {
3228
HStack(spacing: 8) {
@@ -36,7 +32,7 @@ public struct UnknownRecipientCell: View {
3632
VStack(alignment: .leading) {
3733
Text(MailResourcesStrings.Localizable.addUnknownRecipientTitle)
3834
.textStyle(.bodyMedium)
39-
Text(recipient.email)
35+
Text(email)
4036
.textStyle(.bodySecondary)
4137
}
4238
}
@@ -45,5 +41,5 @@ public struct UnknownRecipientCell: View {
4541
}
4642

4743
#Preview {
48-
UnknownRecipientCell(recipient: PreviewHelper.sampleRecipient1)
44+
UnknownRecipientCell(email: PreviewHelper.sampleRecipient1.email)
4945
}

Mail/Views/Search/SearchViewModel.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ final class SearchViewModel: ObservableObject, ThreadListable {
148148
fetchLimit: nil,
149149
sorted: nil
150150
)
151-
var autocompleteRecipients = autocompleteContacts.map { Recipient(email: $0.email, name: $0.name).freezeIfNeeded() }
151+
// TODO: Handle optional email
152+
var autocompleteRecipients = autocompleteContacts.map { Recipient(email: $0.email ?? "", name: $0.name).freezeIfNeeded() }
152153

153154
// Append typed email
154155
if Constants.isEmailAddress(searchValue) && !frozenContacts

MailCore/Cache/ContactManager/ContactManager+DB.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ public protocol ContactFetchable {
4545
func getContact(for correspondent: any Correspondent) -> MergedContact?
4646
func addressBook(with id: Int) -> AddressBook?
4747
func addContact(recipient: Recipient) async throws
48+
49+
/// Get a contact from group contact (categories)
50+
func getContacts(with groupContactId: Int) -> [MergedContact]
4851
}
4952

5053
public extension ContactManager {
@@ -139,4 +142,16 @@ public extension ContactManager {
139142
writableRealm.add(mergedContact, update: .modified)
140143
}
141144
}
145+
146+
func getContacts(with groupContactId: Int) -> [MergedContact] {
147+
// TODO: To implement
148+
// let frozenContacts = fetchResults(ofType: MergedContact.self) { partial in
149+
// partial
150+
// .where { $0.groupContactId == groupContactId }
151+
// .freezeIfNeeded()
152+
// }
153+
//
154+
// return Array(frozenContacts)
155+
return []
156+
}
142157
}

MailCore/Cache/ContactManager/ContactManager+Merge.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,8 @@ extension ContactManager {
175175
continue
176176
}
177177

178-
let id = MergedContact.computeId(email: mergedContact.email, name: mergedContact.name)
178+
// TODO: Handle optional emai
179+
let id = MergedContact.computeId(email: mergedContact.email ?? "", name: mergedContact.name)
179180
if newMergedContacts[id] == nil {
180181
idsToDelete.append(id)
181182
}

MailCore/Models/Contact/CommonContactCache.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ public enum CommonContactCache {
7676
contact = wrappedContact
7777
case .emptyContact:
7878
contact = CommonContact.emptyContact
79+
case .groupContact:
80+
// TODO: To implement
81+
contact = CommonContact.emptyContact
7982
}
8083

8184
// Store the object in cache

MailCore/Models/Contact/ContactConfiguration.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ public enum ContactConfiguration: CustomDebugStringConvertible {
2828
return ".user:\(user.displayName) \(user.email)"
2929
case .contact(let contact):
3030
return ".contact:\(contact.fullName) \(contact.email)"
31+
case .groupContact:
32+
return ".groupContact"
3133
case .emptyContact:
3234
return ".emptyContact"
3335
}
@@ -41,6 +43,7 @@ public enum ContactConfiguration: CustomDebugStringConvertible {
4143
)
4244
case user(user: UserProfile)
4345
case contact(contact: CommonContact)
46+
case groupContact
4447
case emptyContact
4548

4649
public func freezeIfNeeded() -> Self {
@@ -82,6 +85,9 @@ extension ContactConfiguration: Identifiable {
8285
return wrappedContact.id
8386
case .emptyContact:
8487
return CommonContact.emptyContact.id
88+
case .groupContact:
89+
// TODO: To implement
90+
return CommonContact.emptyContact.id
8591
}
8692
}
8793
}

MailCore/Models/GroupContact.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,20 @@ import Foundation
2020
import RealmSwift
2121

2222
// AddressBook Categories
23-
public class GroupContact: Object, Codable {
23+
public class GroupContact: Object, Codable, ContactAutocompletable {
2424
@Persisted public var id: Int
2525
@Persisted public var name: String
26+
27+
public var stringId: String {
28+
return String(id)
29+
}
30+
31+
public var email: String?
32+
}
33+
34+
// TODO: A déplacer
35+
public protocol ContactAutocompletable: Identifiable {
36+
var stringId: String { get }
37+
var name: String { get }
38+
var email: String? { get }
2639
}

MailCore/Models/MergedContact.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,16 @@ extension CNContact {
4141
}
4242
}
4343

44-
public final class MergedContact: Object, Identifiable {
44+
public final class MergedContact: Object, Identifiable, ContactAutocompletable {
45+
public var stringId: String {
46+
return id
47+
}
48+
4549
private static let contactFormatter = CNContactFormatter()
4650

4751
/// Shared
4852
@Persisted(primaryKey: true) public var id: String
49-
@Persisted public var email: String
53+
@Persisted public var email: String?
5054
@Persisted public var name: String
5155

5256
/// Remote

0 commit comments

Comments
 (0)