diff --git a/App/client-ios.xcodeproj/project.pbxproj b/App/client-ios.xcodeproj/project.pbxproj index 3e09d58a41130302b5a9477bbef829531567752b..3bafd36f61bebee028596893aab877e7775c4a7a 100644 --- a/App/client-ios.xcodeproj/project.pbxproj +++ b/App/client-ios.xcodeproj/project.pbxproj @@ -448,7 +448,7 @@ CODE_SIGN_ENTITLEMENTS = "client-ios/Resources/client-ios.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 167; + CURRENT_PROJECT_VERSION = 232; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = S6JDM2WW29; ENABLE_BITCODE = NO; @@ -463,7 +463,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.1.2; + MARKETING_VERSION = 1.1.7; OTHER_SWIFT_FLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = xx.messenger.mock; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -487,7 +487,7 @@ CODE_SIGN_ENTITLEMENTS = "client-ios/Resources/client-ios.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 167; + CURRENT_PROJECT_VERSION = 232; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = S6JDM2WW29; ENABLE_BITCODE = NO; @@ -503,7 +503,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.1.2; + MARKETING_VERSION = 1.1.7; OTHER_SWIFT_FLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = xx.messenger; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -522,7 +522,7 @@ CODE_SIGN_ENTITLEMENTS = NotificationExtension/NotificationExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 167; + CURRENT_PROJECT_VERSION = 232; DEVELOPMENT_TEAM = S6JDM2WW29; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( @@ -536,7 +536,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.1.3; + MARKETING_VERSION = 1.1.7; PRODUCT_BUNDLE_IDENTIFIER = xx.messenger.mock.notifications; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -553,7 +553,7 @@ CODE_SIGN_ENTITLEMENTS = NotificationExtension/NotificationExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 167; + CURRENT_PROJECT_VERSION = 232; DEVELOPMENT_TEAM = S6JDM2WW29; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( @@ -567,7 +567,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.1.3; + MARKETING_VERSION = 1.1.7; PRODUCT_BUNDLE_IDENTIFIER = xx.messenger.notifications; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/Package.swift b/Package.swift index d07ef4c10f5de19de5e1382aa19049f473bf19cd..eb25b0ac28e0c38c136e315cc58a022a533ccf19 100644 --- a/Package.swift +++ b/Package.swift @@ -229,6 +229,8 @@ let package = Package( .target(name: "ReportingFeature"), .target(name: "DependencyInjection"), .product(name: "XXDatabase", package: "client-ios-db"), + .product(name: "XXClient", package: "elixxir-dapps-sdk-swift"), + .product(name: "XXMessengerClient", package: "elixxir-dapps-sdk-swift"), ] ), .target( @@ -560,6 +562,8 @@ let package = Package( .target(name: "DependencyInjection"), .product(name: "CombineSchedulers", package: "combine-schedulers"), .product(name: "ScrollViewController", package: "ScrollViewController"), + .product(name: "XXClient", package: "elixxir-dapps-sdk-swift"), + .product(name: "XXMessengerClient", package: "elixxir-dapps-sdk-swift"), ] ), .testTarget( diff --git a/Sources/ChatFeature/Controllers/SingleChatController.swift b/Sources/ChatFeature/Controllers/SingleChatController.swift index 5bded7c91dd9550d65fa300fbf7cc61b986cae9a..970539b33f9dc0ebf25c2fa1bad10ec97a6c20e4 100644 --- a/Sources/ChatFeature/Controllers/SingleChatController.swift +++ b/Sources/ChatFeature/Controllers/SingleChatController.swift @@ -603,8 +603,6 @@ extension SingleChatController: UICollectionViewDelegate { return UITargetedPreview(view: leftView, parameters: parameters) } - #warning("TODO: Refactor") - var rightView: UIView! if let cell = cell as? OutgoingTextCell { diff --git a/Sources/ChatFeature/ViewModels/GroupChatViewModel.swift b/Sources/ChatFeature/ViewModels/GroupChatViewModel.swift index b3bdbbf11b38c6ae9592bbebbaeef318baac3dda..a5f8e18dbc49fb6de2dd607bf2b1107416f478af 100644 --- a/Sources/ChatFeature/ViewModels/GroupChatViewModel.swift +++ b/Sources/ChatFeature/ViewModels/GroupChatViewModel.swift @@ -123,7 +123,7 @@ final class GroupChatViewModel { try messenger.cMix.get()!.waitForRoundResult( roundList: try report.encode(), - timeoutMS: 5_000, + timeoutMS: 15_000, callback: .init(handle: { switch $0 { case .delivered: @@ -176,7 +176,7 @@ final class GroupChatViewModel { try messenger.cMix.get()!.waitForRoundResult( roundList: try report.encode(), - timeoutMS: 5_000, + timeoutMS: 15_000, callback: .init(handle: { switch $0 { case .delivered: diff --git a/Sources/ChatFeature/ViewModels/SingleChatViewModel.swift b/Sources/ChatFeature/ViewModels/SingleChatViewModel.swift index 958634b6b678c86f021f66fad37c17784f46295d..2d7175c2c7f4f49f672793abf778d9fc70a5324b 100644 --- a/Sources/ChatFeature/ViewModels/SingleChatViewModel.swift +++ b/Sources/ChatFeature/ViewModels/SingleChatViewModel.swift @@ -143,7 +143,7 @@ final class SingleChatViewModel: NSObject { func didSendAudio(url: URL) { do { - let transferId = try transferManager.send( + let _ = try transferManager.send( params: .init( payload: .init( name: "", @@ -152,7 +152,6 @@ final class SingleChatViewModel: NSObject { contents: Data() ), recipientId: contact.id, - paramsJSON: Data(), retry: 1, period: "" ), @@ -177,16 +176,15 @@ final class SingleChatViewModel: NSObject { hudRelay.send(.on) do { - let transferId = try transferManager.send( + let _ = try transferManager.send( params: .init( payload: .init( name: "", type: "", preview: Data(), - contents: Data() + contents: imageData ), recipientId: Data(), - paramsJSON: Data(), retry: 1, period: "" ), @@ -200,7 +198,7 @@ final class SingleChatViewModel: NSObject { }) ) } catch { - // self?.hudRelay.send(.error(.init(with: error))) + hudRelay.send(.error(.init(with: error))) } } @@ -239,7 +237,7 @@ final class SingleChatViewModel: NSObject { try messenger.cMix.get()!.waitForRoundResult( roundList: try report.encode(), - timeoutMS: 5_000, + timeoutMS: 15_000, callback: .init(handle: { switch $0 { case .delivered: @@ -258,6 +256,7 @@ final class SingleChatViewModel: NSObject { }) ) + //message.roundURL = report.roundURL message.networkId = report.messageId if let timestamp = report.timestamp { message.date = Date.fromTimestamp(Int(timestamp)) @@ -344,7 +343,7 @@ final class SingleChatViewModel: NSObject { try self.messenger.cMix.get()!.waitForRoundResult( roundList: try report.encode(), - timeoutMS: 5_000, + timeoutMS: 15_000, callback: .init(handle: { switch $0 { case .delivered: @@ -363,6 +362,7 @@ final class SingleChatViewModel: NSObject { }) ) + message.roundURL = report.roundURL message.networkId = report.messageId if let timestamp = report.timestamp { message.date = Date.fromTimestamp(Int(timestamp)) diff --git a/Sources/ContactFeature/ViewModels/ContactViewModel.swift b/Sources/ContactFeature/ViewModels/ContactViewModel.swift index 9170c81ba32def8cbb77211768a9082378e4dc2b..c14131fe4c506128a33f5c087eecccc9595f1799 100644 --- a/Sources/ContactFeature/ViewModels/ContactViewModel.swift +++ b/Sources/ContactFeature/ViewModels/ContactViewModel.swift @@ -50,8 +50,8 @@ final class ContactViewModel { self.contact = contact let facts = try? getFactsFromContact(contact.marshaled!) - let email = facts?.first(where: { $0.type == FactType.email.rawValue })?.fact - let phone = facts?.first(where: { $0.type == FactType.phone.rawValue })?.fact + let email = facts?.first(where: { $0.type == .email })?.value + let phone = facts?.first(where: { $0.type == .phone })?.value stateRelay.value = .init( title: contact.nickname ?? contact.username, @@ -112,7 +112,7 @@ final class ContactViewModel { try self.database.saveContact(self.contact) var myFacts = try self.messenger.ud.get()!.getFacts() - myFacts.append(Fact(fact: self.username!, type: FactType.username.rawValue)) + myFacts.append(.init(type: .username, value: self.username!)) let _ = try self.messenger.e2e.get()!.requestAuthenticatedChannel( partner: XXClient.Contact.live(self.contact.marshaled!), @@ -144,7 +144,7 @@ final class ContactViewModel { try self.database.saveContact(self.contact) var myFacts = try self.messenger.ud.get()!.getFacts() - myFacts.append(Fact(fact: self.username!, type: FactType.username.rawValue)) + myFacts.append(.init(type: .username, value: self.username!)) let _ = try self.messenger.e2e.get()!.requestAuthenticatedChannel( partner: XXClient.Contact.live(self.contact.marshaled!), diff --git a/Sources/ContactListFeature/Controllers/CreateGroupController.swift b/Sources/ContactListFeature/Controllers/CreateGroupController.swift index e55860fc0a48220413dc33373c915e754351ebe5..a1b276859131ba26ff0bbafaf88aa5ac3c2a777f 100644 --- a/Sources/ContactListFeature/Controllers/CreateGroupController.swift +++ b/Sources/ContactListFeature/Controllers/CreateGroupController.swift @@ -164,7 +164,7 @@ public final class CreateGroupController: UIViewController { coordinator.toGroupDrawer( with: count + 1, from: self, { (name, welcome) in - viewModel.create(name: name, welcome: welcome, members: selectedElements) + self.viewModel.create(name: name, welcome: welcome, members: self.selectedElements) } ) }.store(in: &cancellables) diff --git a/Sources/LaunchFeature/LaunchViewModel.swift b/Sources/LaunchFeature/LaunchViewModel.swift index 8bf83a2f83dcf3796dcb75aa7fa2747286918906..f31d75740093836148184020fa5f0500e50c7b75 100644 --- a/Sources/LaunchFeature/LaunchViewModel.swift +++ b/Sources/LaunchFeature/LaunchViewModel.swift @@ -105,7 +105,7 @@ final class LaunchViewModel { do { try self.setupDatabase() - _ = try SetLogLevel.live(.trace) + _ = try SetLogLevel.live(.fatal) RegisterLogWriter.live(.init(handle: { XXLogger.live().debug($0) @@ -161,6 +161,7 @@ final class LaunchViewModel { senderId: nil, messageType: 2, callback: .init(handle: { + // let roundId = $0.roundId guard let payload = try? Payload(with: $0.payload) else { @@ -178,6 +179,7 @@ final class LaunchViewModel { text: payload.text, replyMessageId: payload.reply?.messageId, roundURL: "https://www.google.com.br", + //roundURL: $0.roundURL, fileTransferId: nil )) @@ -502,9 +504,9 @@ extension LaunchViewModel { } let facts = try? contact.getFacts() - let email = facts?.first(where: { $0.type == FactType.email.rawValue })?.fact - let phone = facts?.first(where: { $0.type == FactType.phone.rawValue })?.fact - let username = facts?.first(where: { $0.type == FactType.username.rawValue })?.fact + let email = facts?.first(where: { $0.type == .email })?.value + let phone = facts?.first(where: { $0.type == .phone })?.value + let username = facts?.first(where: { $0.type == .username })?.value var model = try! database.saveContact(.init( id: id, @@ -599,20 +601,49 @@ extension LaunchViewModel { serialized: group.serialize() )) - if let initialMessage = String(data: group.getInitMessage(), encoding: .utf8) { - try! database.saveMessage(.init( - senderId: leader.id, - recipientId: nil, - groupId: group.getId(), - date: Date.fromTimestamp(Int(group.getCreatedMS())), - status: .received, - isUnread: true, - text: initialMessage - )) +// if let initialMessage = String(data: group.getInitMessage(), encoding: .utf8) { +// try! database.saveMessage(.init( +// senderId: leader.id, +// recipientId: nil, +// groupId: group.getId(), +// date: Date.fromTimestamp(Int(group.getCreatedMS())), +// status: .received, +// isUnread: true, +// text: initialMessage +// )) +// } + + let friends = try! database.fetchContacts(.init(id: Set(members.map(\.id)))) + let strangers = members.filter { !friends.map(\.id).contains($0.id) } + + members.forEach { + if strangers.map(\.id).contains($0.id) { + try! database.saveContact(.init( + id: $0.id, + marshaled: nil, + username: "Fetching...", + email: nil, + phone: nil, + nickname: nil, + photo: nil, + authStatus: .stranger, + isRecent: false, + isBlocked: false, + isBanned: false, + createdAt: Date() + )) + } + } + + members.forEach { + let model = XXModels.GroupMember(groupId: group.getId(), contactId: $0.id) + _ = try? database.saveGroupMember(model) } - // TODO: - // All other members should be added to the database as GroupMembers +// DispatchQueue.global().async { [weak self] in +// guard let self = self else { return } +// // Multilookup on strangers +// } } private func performLookup( diff --git a/Sources/Models/FactType.swift b/Sources/Models/FactType.swift deleted file mode 100644 index 5dce1f05c2a327db9a09852dfc62384e3636546a..0000000000000000000000000000000000000000 --- a/Sources/Models/FactType.swift +++ /dev/null @@ -1,34 +0,0 @@ -import Foundation - -public enum FactType: Int { - case username = 0 - case email - case phone - case nickname - - public var description: String { - switch self { - case .email: - return "Email" - case .nickname: - return "Nickname" - case .phone: - return "Phone" - case .username: - return "Username" - } - } - - public var prefix: String { - switch self { - case .email: - return "E" - case .nickname: - return "N" - case .phone: - return "P" - case .username: - return "U" - } - } -} diff --git a/Sources/OnboardingFeature/Controllers/OnboardingEmailController.swift b/Sources/OnboardingFeature/Controllers/OnboardingEmailController.swift index 54fb8cf4efcf4cd29489729598ed22144b918f65..4ff185e789c7d3761e5be4d6aeabdcc8ef272b0b 100644 --- a/Sources/OnboardingFeature/Controllers/OnboardingEmailController.swift +++ b/Sources/OnboardingFeature/Controllers/OnboardingEmailController.swift @@ -73,10 +73,10 @@ public final class OnboardingEmailController: UIViewController { let successModel = OnboardingSuccessModel( title: Localized.Onboarding.Success.Email.title, subtitle: nil, - nextController: coordinator.toPhone(from:) + nextController: self.coordinator.toPhone(from:) ) - coordinator.toSuccess(with: successModel, from: controller) + self.coordinator.toSuccess(with: successModel, from: controller) } }.store(in: &cancellables) diff --git a/Sources/OnboardingFeature/Controllers/OnboardingPhoneController.swift b/Sources/OnboardingFeature/Controllers/OnboardingPhoneController.swift index 8793508fe6ec8d94e3ee00ff5f3052031c70ee53..4686825bbeba8c9e599602f7c62453c3f23cffee 100644 --- a/Sources/OnboardingFeature/Controllers/OnboardingPhoneController.swift +++ b/Sources/OnboardingFeature/Controllers/OnboardingPhoneController.swift @@ -81,7 +81,7 @@ public final class OnboardingPhoneController: UIViewController { screenView.inputField.codePublisher .receive(on: DispatchQueue.main) .sink { [unowned self] in - coordinator.toCountries(from: self) { viewModel.didChooseCountry($0) } + coordinator.toCountries(from: self) { self.viewModel.didChooseCountry($0) } }.store(in: &cancellables) viewModel.state.map(\.confirmation) @@ -93,10 +93,10 @@ public final class OnboardingPhoneController: UIViewController { let successModel = OnboardingSuccessModel( title: Localized.Onboarding.Success.Phone.title, subtitle: nil, - nextController: coordinator.toChats(from:) + nextController: self.coordinator.toChats(from:) ) - coordinator.toSuccess(with: successModel, from: controller) + self.coordinator.toSuccess(with: successModel, from: controller) } }.store(in: &cancellables) diff --git a/Sources/OnboardingFeature/ViewModels/OnboardingEmailViewModel.swift b/Sources/OnboardingFeature/ViewModels/OnboardingEmailViewModel.swift index cf21d93b4fd005bb991595e991b066c703bf48fe..8215204dd75749bf4ca4f6f243453d04d2eed1e5 100644 --- a/Sources/OnboardingFeature/ViewModels/OnboardingEmailViewModel.swift +++ b/Sources/OnboardingFeature/ViewModels/OnboardingEmailViewModel.swift @@ -46,7 +46,7 @@ final class OnboardingEmailViewModel { do { let confirmationId = try self.messenger.ud.get()!.sendRegisterFact( - .init(fact: self.stateRelay.value.input, type: FactType.email.rawValue) + .init(type: .email, value: self.stateRelay.value.input) ) self.hudRelay.send(.none) diff --git a/Sources/OnboardingFeature/ViewModels/OnboardingPhoneViewModel.swift b/Sources/OnboardingFeature/ViewModels/OnboardingPhoneViewModel.swift index f226397f4faa6d8afc4c9de36c505ffa5b6762fe..1644c795d0d3b23c5b17b0316daa2b39a7e9dfc9 100644 --- a/Sources/OnboardingFeature/ViewModels/OnboardingPhoneViewModel.swift +++ b/Sources/OnboardingFeature/ViewModels/OnboardingPhoneViewModel.swift @@ -58,7 +58,7 @@ final class OnboardingPhoneViewModel { do { let confirmationId = try self.messenger.ud.get()!.sendRegisterFact( - .init(fact: content, type: FactType.phone.rawValue) + .init(type: .phone, value: content) ) self.hudRelay.send(.none) diff --git a/Sources/ProfileFeature/Controllers/ProfileController.swift b/Sources/ProfileFeature/Controllers/ProfileController.swift index e3138f275dd967d73d58548649e4156409178e57..750c5342b31ddad18660f94aa784f3b22ef520b3 100644 --- a/Sources/ProfileFeature/Controllers/ProfileController.swift +++ b/Sources/ProfileFeature/Controllers/ProfileController.swift @@ -69,7 +69,7 @@ public final class ProfileController: UIViewController { actionTitle: Localized.Profile.Delete.action( Localized.Profile.Email.title )) { - viewModel.didTapDelete(isEmail: true) + self.viewModel.didTapDelete(isEmail: true) } } else { coordinator.toEmail(from: self) @@ -91,7 +91,7 @@ public final class ProfileController: UIViewController { actionTitle: Localized.Profile.Delete.action( Localized.Profile.Phone.title )) { - viewModel.didTapDelete(isEmail: false) + self.viewModel.didTapDelete(isEmail: false) } } else { coordinator.toPhone(from: self) @@ -114,7 +114,7 @@ public final class ProfileController: UIViewController { title: Localized.Profile.Photo.title, subtitle: Localized.Profile.Photo.subtitle, actionTitle: Localized.Profile.Photo.continue) { - coordinator.toPhotos(from: self) + self.coordinator.toPhotos(from: self) } case .libraryPermission: coordinator.toPermission(type: .library, from: self) diff --git a/Sources/ProfileFeature/Controllers/ProfileEmailController.swift b/Sources/ProfileFeature/Controllers/ProfileEmailController.swift index 3fb88d2b649ed6f9f20b8189467a021563188c13..799cbae557abf3808f8f297fadfff08ffb9d8bb3 100644 --- a/Sources/ProfileFeature/Controllers/ProfileEmailController.swift +++ b/Sources/ProfileFeature/Controllers/ProfileEmailController.swift @@ -61,8 +61,8 @@ public final class ProfileEmailController: UIViewController { .sink { [unowned self] in viewModel.clearUp() coordinator.toCode(with: $0, from: self) { _, _ in - if let viewControllers = navigationController?.viewControllers { - navigationController?.popToViewController( + if let viewControllers = self.navigationController?.viewControllers { + self.navigationController?.popToViewController( viewControllers[viewControllers.count - 3], animated: true ) diff --git a/Sources/ProfileFeature/Controllers/ProfilePhoneController.swift b/Sources/ProfileFeature/Controllers/ProfilePhoneController.swift index 01737802adc9611476892ca38675b5dd8ff6d743..34fbd10bf1cabcb14ae5b93474d0d3b8b835b369 100644 --- a/Sources/ProfileFeature/Controllers/ProfilePhoneController.swift +++ b/Sources/ProfileFeature/Controllers/ProfilePhoneController.swift @@ -6,8 +6,6 @@ import Theme import DependencyInjection import ScrollViewController -#warning("TODO: Merge ProfilePhoneController/ProfileEmailController") - public final class ProfilePhoneController: UIViewController { @Dependency private var hud: HUD @Dependency private var coordinator: ProfileCoordinating @@ -59,7 +57,7 @@ public final class ProfilePhoneController: UIViewController { screenView.inputField.codePublisher .receive(on: DispatchQueue.main) .sink { [unowned self] in - coordinator.toCountries(from: self) { viewModel.didChooseCountry($0) } + coordinator.toCountries(from: self) { self.viewModel.didChooseCountry($0) } }.store(in: &cancellables) viewModel.state @@ -69,8 +67,8 @@ public final class ProfilePhoneController: UIViewController { .sink { [unowned self] in viewModel.clearUp() coordinator.toCode(with: $0, from: self) { _, _ in - if let viewControllers = navigationController?.viewControllers { - navigationController?.popToViewController( + if let viewControllers = self.navigationController?.viewControllers { + self.navigationController?.popToViewController( viewControllers[viewControllers.count - 3], animated: true ) diff --git a/Sources/ProfileFeature/ViewModels/ProfileEmailViewModel.swift b/Sources/ProfileFeature/ViewModels/ProfileEmailViewModel.swift index 4a192c306e329bfadb92142ee0d453fc19c8de6c..4f7b61c3fdda42c084739cecc97fd048303f2d74 100644 --- a/Sources/ProfileFeature/ViewModels/ProfileEmailViewModel.swift +++ b/Sources/ProfileFeature/ViewModels/ProfileEmailViewModel.swift @@ -49,7 +49,7 @@ final class ProfileEmailViewModel { do { let confirmationId = try self.messenger.ud.get()!.sendRegisterFact( - .init(fact: self.stateRelay.value.input, type: FactType.email.rawValue) + .init(type: .email, value: self.stateRelay.value.input) ) self.hudRelay.send(.none) diff --git a/Sources/ProfileFeature/ViewModels/ProfilePhoneViewModel.swift b/Sources/ProfileFeature/ViewModels/ProfilePhoneViewModel.swift index bbf580a249e2da6e8041dce235e8a3769ea19952..560f78cc0b7b9a94e356872fedff46005acf54cf 100644 --- a/Sources/ProfileFeature/ViewModels/ProfilePhoneViewModel.swift +++ b/Sources/ProfileFeature/ViewModels/ProfilePhoneViewModel.swift @@ -58,7 +58,7 @@ final class ProfilePhoneViewModel { do { let confirmationId = try self.messenger.ud.get()!.sendRegisterFact( - .init(fact: content, type: FactType.phone.rawValue) + .init(type: .phone, value: content) ) self.hudRelay.send(.none) diff --git a/Sources/ProfileFeature/ViewModels/ProfileViewModel.swift b/Sources/ProfileFeature/ViewModels/ProfileViewModel.swift index 36006fa591b7841c762bfb429f1f67a1a5c9e07b..252acd4974aa48cefed3a71b390d14fc62208d9c 100644 --- a/Sources/ProfileFeature/ViewModels/ProfileViewModel.swift +++ b/Sources/ProfileFeature/ViewModels/ProfileViewModel.swift @@ -93,8 +93,8 @@ final class ProfileViewModel { do { try self.messenger.ud.get()!.removeFact( .init( - fact: isEmail ? self.emailStored! : self.phoneStored!, - type: isEmail ? FactType.email.rawValue : FactType.phone.rawValue + type: isEmail ? .email : .phone, + value: isEmail ? self.emailStored! : self.phoneStored! ) ) diff --git a/Sources/PushFeature/PushExtractor.swift b/Sources/PushFeature/PushExtractor.swift index 6141650b414965931487d56a51f285000857e474..6d080841ae0e87120bb57391d09cd41e73bf39d4 100644 --- a/Sources/PushFeature/PushExtractor.swift +++ b/Sources/PushFeature/PushExtractor.swift @@ -1,4 +1,6 @@ +import XXModels import Foundation +import DependencyInjection public struct PushExtractor { enum Constants { @@ -12,27 +14,44 @@ public struct PushExtractor { public extension PushExtractor { static let live = PushExtractor { dictionary in - fatalError(">>> Missing API for notifications") -// var error: NSError? -// -// guard let data = dictionary[Constants.notificationData] as? String, -// let defaults = UserDefaults(suiteName: Constants.appGroup), -// let preImage = defaults.value(forKey: Constants.preImage) as? String, -// let reports = evaluateNotification(data, preImage, &error) else { + NSLog("EXTRACTING PUSH A...") + + guard let database = try? DependencyInjection.Container.shared.resolve() as Database, + let anyone = try? database.fetchContacts(.init()).first else { + NSLog("EXTRACTING PUSH B...") + return .success(nil) + } + + NSLog("EXTRACTING PUSH C...") + + return .success([.init(type: PushType.request.rawValue, source: anyone.id)!]) + +// guard let messenger = try? DependencyInjection.Container.shared.resolve() as Messenger, +// let data = dictionary[Constants.notificationData] as? String else { // return .success(nil) // } // -// if let error = error { -// return .failure(error) -// } +// do { +// let reportFunctor = GetNotificationsReport.live() +// let report = try reportFunctor( +// e2eId: messenger.e2e.get()!.getId(), +// notificationCSV: data, +// marshaledServices: Data() // <--- ??? +// ) // -// let pushes = (0..<reports.len()) -// .compactMap { try? reports.get(index: $0) } -// .filter { $0.forMe() } -// .filter { $0.type() != PushType.silent.rawValue } -// .filter { $0.type() != PushType.default.rawValue } -// .compactMap { Push(type: $0.type(), source: $0.source()) } +// guard report.forMe, +// report.type != .silent, +// report.type != .default +// else { +// return .success(nil) +// } // -// return .success(pushes) +// return .success([Push( +// type: report.type.rawValue, +// source: report.source)! +// ]) +// } catch { +// return .failure(error) +// } } } diff --git a/Sources/PushFeature/PushHandler.swift b/Sources/PushFeature/PushHandler.swift index acee5de05830efd6a348a982523fbee405bba27f..e6407316c52c9fa5569dbc25396c7a40e16f5b63 100644 --- a/Sources/PushFeature/PushHandler.swift +++ b/Sources/PushFeature/PushHandler.swift @@ -1,8 +1,10 @@ import UIKit import Models import Defaults +import XXClient import XXModels import XXDatabase +import XXMessengerClient import ReportingFeature import DependencyInjection @@ -12,6 +14,7 @@ public final class PushHandler: PushHandling { static let usernamesSetting = "isShowingUsernames" } + @Dependency var messenger: Messenger @Dependency var reportingStatus: ReportingStatus @KeyObject(.pushNotifications, defaultValue: false) var isPushEnabled: Bool @@ -38,8 +41,12 @@ public final class PushHandler: PushHandling { public func registerToken(_ token: Data) { do { - fatalError(">>> Missing API for notifications") + try RegisterForNotifications.live( + e2eId: messenger.e2e.get()!.getId(), + token: token.map { String(format: "%02hhx", $0) }.joined() + ) } catch { + print(error.localizedDescription) isPushEnabled = false } } diff --git a/Sources/RequestsFeature/ViewModels/RequestsFailedViewModel.swift b/Sources/RequestsFeature/ViewModels/RequestsFailedViewModel.swift index 2963688360817f3b4215c6bac200e569206cca4b..676fefbff0d66416e8db59251b54d797ca0e56df 100644 --- a/Sources/RequestsFeature/ViewModels/RequestsFailedViewModel.swift +++ b/Sources/RequestsFeature/ViewModels/RequestsFailedViewModel.swift @@ -50,7 +50,7 @@ final class RequestsFailedViewModel { do { var myFacts = try self.messenger.ud.get()!.getFacts() - myFacts.append(Fact(fact: self.username!, type: FactType.username.rawValue)) + myFacts.append(.init(type: .username, value: self.username!)) let _ = try self.messenger.e2e.get()!.requestAuthenticatedChannel( partner: XXClient.Contact.live(contact.marshaled!), diff --git a/Sources/RequestsFeature/ViewModels/RequestsSentViewModel.swift b/Sources/RequestsFeature/ViewModels/RequestsSentViewModel.swift index 1522b9ecd70b7990de61cbcc921d3e6834cf1247..334a0eb21d9f01224f0d8f057b7331b819cf667e 100644 --- a/Sources/RequestsFeature/ViewModels/RequestsSentViewModel.swift +++ b/Sources/RequestsFeature/ViewModels/RequestsSentViewModel.swift @@ -71,7 +71,7 @@ final class RequestsSentViewModel { do { var myFacts = try self.messenger.ud.get()!.getFacts() - myFacts.append(Fact(fact: self.username!, type: FactType.username.rawValue)) + myFacts.append(.init(type: .username, value: self.username!)) let _ = try self.messenger.e2e.get()!.requestAuthenticatedChannel( partner: XXClient.Contact.live(contact.marshaled!), diff --git a/Sources/RestoreFeature/ViewModels/RestoreViewModel.swift b/Sources/RestoreFeature/ViewModels/RestoreViewModel.swift index 002ba409c12d0257c150f8539bf14183e11e4f7c..b3b275d633e98462f102c51eb41672e8686bff4c 100644 --- a/Sources/RestoreFeature/ViewModels/RestoreViewModel.swift +++ b/Sources/RestoreFeature/ViewModels/RestoreViewModel.swift @@ -182,15 +182,11 @@ final class RestoreViewModel { self.phone = facts.phone self.email = facts.email - var emailFact: Fact? = { - if let email = facts.email { return Fact(fact: email, type: FactType.email.rawValue) } - return nil - }() + var emailFact: Fact? + var phoneFact: Fact? - var phoneFact: Fact? = { - if let phone = facts.phone { return Fact(fact: phone, type: FactType.phone.rawValue) } - return nil - }() + if let email = self.email { emailFact = .init(type: .email, value: email) } + if let phone = self.phone { phoneFact = .init(type: .phone, value: phone) } let cMix = try self.cMixManager.load() @@ -236,7 +232,7 @@ final class RestoreViewModel { let userDiscovery = try NewUdManagerFromBackup.live( params: .init( e2eId: e2e.getId(), - username: Fact(fact: facts.username, type: 0), + username: .init(type: .username, value: facts.username), email: emailFact, phone: phoneFact, cert: Data(contentsOf: URL(fileURLWithPath: certPath)), diff --git a/Sources/SFTPFeature/ActionHandlers/SFTPAuthenticator.swift b/Sources/SFTPFeature/ActionHandlers/SFTPAuthenticator.swift index 389cdd46fc0c0136247e09f3dbd900ec265a7858..6693ac08eedb5f9ce86212614a8a2a0eb4eccfa0 100644 --- a/Sources/SFTPFeature/ActionHandlers/SFTPAuthenticator.swift +++ b/Sources/SFTPFeature/ActionHandlers/SFTPAuthenticator.swift @@ -42,7 +42,7 @@ extension SFTPAuthenticator { } else if let error = error as? Socket.Error { print(error.errorCode) print(error.description) - print(error.errorReason) + print(error.errorReason ?? "No error reason available") print(error.localizedDescription) } else { print(error.localizedDescription) diff --git a/Sources/SFTPFeature/ActionHandlers/SFTPFetcher.swift b/Sources/SFTPFeature/ActionHandlers/SFTPFetcher.swift index a27df80ffe8e9be6f41f09185e9962351c44cff9..0c30331bae777cd08cb255af0e8d3fc1f21f940a 100644 --- a/Sources/SFTPFeature/ActionHandlers/SFTPFetcher.swift +++ b/Sources/SFTPFeature/ActionHandlers/SFTPFetcher.swift @@ -55,7 +55,7 @@ extension SFTPFetcher { } else if let error = error as? Socket.Error { print(error.errorCode) print(error.description) - print(error.errorReason) + print(error.errorReason ?? "No error reason available") print(error.localizedDescription) } else { print(error.localizedDescription) diff --git a/Sources/SFTPFeature/ActionHandlers/SFTPUploader.swift b/Sources/SFTPFeature/ActionHandlers/SFTPUploader.swift index fee691d1b7e1669226fecfad6ecc37c97e64f9c5..0c39386eef0cc99703d00b0905d11221052b91aa 100644 --- a/Sources/SFTPFeature/ActionHandlers/SFTPUploader.swift +++ b/Sources/SFTPFeature/ActionHandlers/SFTPUploader.swift @@ -56,7 +56,7 @@ extension SFTPUploader { } else if let error = error as? Socket.Error { print(error.errorCode) print(error.description) - print(error.errorReason) + print(error.errorReason ?? "No error reason available") print(error.localizedDescription) } else { print(error.localizedDescription) diff --git a/Sources/ScanFeature/ViewModels/ScanDisplayViewModel.swift b/Sources/ScanFeature/ViewModels/ScanDisplayViewModel.swift index ad307df16619eea7fb9207bd2718198f3f314bf2..fb03482a4e6405f543aa310bf1c2d0661285a40d 100644 --- a/Sources/ScanFeature/ViewModels/ScanDisplayViewModel.swift +++ b/Sources/ScanFeature/ViewModels/ScanDisplayViewModel.swift @@ -61,14 +61,14 @@ final class ScanDisplayViewModel { func generateQR() { guard let filter = CIFilter(name: "CIQRCodeGenerator") else { return } - var facts: [Fact] = [Fact(fact: username!, type: FactType.username.rawValue)] + var facts: [Fact] = [.init(type: .username, value: username!)] if sharingPhone { - facts.append(Fact(fact: phone!, type: FactType.phone.rawValue)) + facts.append(.init(type: .phone, value: phone!)) } if sharingEmail { - facts.append(Fact(fact: email!, type: FactType.email.rawValue)) + facts.append(.init(type: .email, value: email!)) } let e2e = messenger.e2e.get()! diff --git a/Sources/ScanFeature/ViewModels/ScanViewModel.swift b/Sources/ScanFeature/ViewModels/ScanViewModel.swift index b58546fb542279cdef56390e1c0111c8c502ed5e..48e2ed2918b877233caea0b252525d6c45dfabe4 100644 --- a/Sources/ScanFeature/ViewModels/ScanViewModel.swift +++ b/Sources/ScanFeature/ViewModels/ScanViewModel.swift @@ -48,14 +48,14 @@ final class ScanViewModel { guard let uid = try? user.getId(), let facts = try? user.getFacts(), - let username = facts.first(where: { $0.type == FactType.username.rawValue })?.fact else { + let username = facts.first(where: { $0.type == .username })?.value else { let errorTitle = Localized.Scan.Error.invalid stateSubject.send(.failed(.unknown(errorTitle))) return } - let email = facts.first { $0.type == FactType.email.rawValue }?.fact - let phone = facts.first { $0.type == FactType.phone.rawValue }?.fact + let email = facts.first { $0.type == .email }?.value + let phone = facts.first { $0.type == .phone }?.value if let alreadyContact = try? database.fetchContacts(.init(id: [uid])).first { if alreadyContact.isBlocked, reportingStatus.isEnabled() { diff --git a/Sources/SearchFeature/ViewModels/SearchContainerViewModel.swift b/Sources/SearchFeature/ViewModels/SearchContainerViewModel.swift index c3f0f59efd5eb3b2400c8e4f959608f72ab01a75..b221c6fea0631a7d8cb6963b309adc3e75a865f3 100644 --- a/Sources/SearchFeature/ViewModels/SearchContainerViewModel.swift +++ b/Sources/SearchFeature/ViewModels/SearchContainerViewModel.swift @@ -26,7 +26,7 @@ final class SearchContainerViewModel { func didEnableCoverTraffic() { try! dummyTrafficManager.setStatus(true) - dummyTrafficOn = dummyTrafficManager.getStatus() + dummyTrafficOn = true } private func verifyCoverTraffic() { diff --git a/Sources/SearchFeature/ViewModels/SearchLeftViewModel.swift b/Sources/SearchFeature/ViewModels/SearchLeftViewModel.swift index a8f0135d85ec7c76ac332b1a5cfbdbd8ce850a94..2d8b7827aa63b56c98c76660d7dcd3487b0fd5f4 100644 --- a/Sources/SearchFeature/ViewModels/SearchLeftViewModel.swift +++ b/Sources/SearchFeature/ViewModels/SearchLeftViewModel.swift @@ -142,6 +142,12 @@ final class SearchLeftViewModel { return } + var factType: FactType = .email + + if stateSubject.value.item == .phone { + factType = .phone + } + backgroundScheduler.schedule { [weak self] in guard let self = self else { return } @@ -149,7 +155,7 @@ final class SearchLeftViewModel { let report = try SearchUD.live( e2eId: self.messenger.e2e.get()!.getId(), udContact: self.messenger.ud.get()!.getContact(), - facts: [Fact(fact: content, type: self.stateSubject.value.item.rawValue)], + facts: [.init(type: factType, value: content)], callback: .init(handle: { switch $0 { case .success(let results): @@ -158,9 +164,9 @@ final class SearchLeftViewModel { XXModels.Contact( id: try! results.first!.getId(), marshaled: results.first!.data, - username: try! results.first?.getFacts().first(where: { $0.type == FactType.username.rawValue })?.fact, - email: try? results.first?.getFacts().first(where: { $0.type == FactType.email.rawValue })?.fact, - phone: try? results.first?.getFacts().first(where: { $0.type == FactType.phone.rawValue })?.fact, + username: try! results.first?.getFacts().first(where: { $0.type == .username })?.value, + email: try? results.first?.getFacts().first(where: { $0.type == .email })?.value, + phone: try? results.first?.getFacts().first(where: { $0.type == .phone })?.value, nickname: nil, photo: nil, authStatus: .stranger, @@ -199,7 +205,7 @@ final class SearchLeftViewModel { try self.database.saveContact(contact) var myFacts = try self.messenger.ud.get()!.getFacts() - myFacts.append(Fact(fact: self.username!, type: FactType.username.rawValue)) + myFacts.append(.init(type: .username, value: self.username!)) let _ = try self.messenger.e2e.get()!.requestAuthenticatedChannel( partner: .live(contact.marshaled!), @@ -233,7 +239,7 @@ final class SearchLeftViewModel { try self.database.saveContact(contact) var myFacts = try self.messenger.ud.get()!.getFacts() - myFacts.append(Fact(fact: self.username!, type: FactType.username.rawValue)) + myFacts.append(.init(type: .username, value: self.username!)) let _ = try self.messenger.e2e.get()!.requestAuthenticatedChannel( partner: .live(contact.marshaled!), diff --git a/Sources/SearchFeature/ViewModels/SearchRightViewModel.swift b/Sources/SearchFeature/ViewModels/SearchRightViewModel.swift index b1b4020b4527e99f80d8eee5990b5f6aadc97844..c238960cb61657e98dcb7262965cdf87215e7302 100644 --- a/Sources/SearchFeature/ViewModels/SearchRightViewModel.swift +++ b/Sources/SearchFeature/ViewModels/SearchRightViewModel.swift @@ -77,15 +77,15 @@ final class SearchRightViewModel { guard let uid = try? user.getId(), let facts = try? user.getFacts(), - let username = facts.first(where: { $0.type == FactType.username.rawValue })?.fact + let username = facts.first(where: { $0.type == .username })?.value else { let errorTitle = Localized.Scan.Error.invalid statusSubject.send(.failed(.unknown(errorTitle))) return } - let email = facts.first { $0.type == FactType.email.rawValue }?.fact - let phone = facts.first { $0.type == FactType.phone.rawValue }?.fact + let email = facts.first { $0.type == .email }?.value + let phone = facts.first { $0.type == .phone }?.value /// Make sure we are not processing a contact /// that we already have diff --git a/Sources/SettingsFeature/ViewModels/AccountDeleteViewModel.swift b/Sources/SettingsFeature/ViewModels/AccountDeleteViewModel.swift index 851576795c1ad10bfea9980499591eb2613d5290..817c9311a50f3bbe4ac27fc42d20cee0259a9809 100644 --- a/Sources/SettingsFeature/ViewModels/AccountDeleteViewModel.swift +++ b/Sources/SettingsFeature/ViewModels/AccountDeleteViewModel.swift @@ -75,10 +75,8 @@ final class AccountDeleteViewModel { } private func cleanUD() throws { - let fact = Fact(fact: username!, type: FactType.username.rawValue) - - print(">>> Deleting my username (\(fact.fact)) from ud") - try messenger.ud.get()!.permanentDeleteAccount(username: fact) + print(">>> Deleting my username (\(username ?? "NO_USERNAME")) from ud") + try messenger.ud.get()!.permanentDeleteAccount(username: .init(type: .username, value: username!)) } private func deleteDatabase() throws { diff --git a/Sources/SettingsFeature/ViewModels/SettingsViewModel.swift b/Sources/SettingsFeature/ViewModels/SettingsViewModel.swift index bee9de2901e28b3b1f00750e6a92741e939313d0..e157bce23751995b42b915fd45e965fed835bf97 100644 --- a/Sources/SettingsFeature/ViewModels/SettingsViewModel.swift +++ b/Sources/SettingsFeature/ViewModels/SettingsViewModel.swift @@ -6,6 +6,7 @@ import Defaults import Permissions import PushFeature import XXClient +import XXMessengerClient import UserNotifications import CombineSchedulers import DependencyInjection @@ -21,6 +22,7 @@ struct SettingsViewState: Equatable { } final class SettingsViewModel { + @Dependency var messenger: Messenger @Dependency var pushHandler: PushHandling @Dependency var permissions: PermissionHandling @Dependency var dummyTrafficManager: DummyTraffic @@ -135,10 +137,14 @@ final class SettingsViewModel { guard let self = self else { return } do { - fatalError(">>> Missing API for notifications") + try UnregisterForNotifications.live( + e2eId: self.messenger.e2e.get()!.getId() + ) + self.hudRelay.send(.none) } catch { - self.hudRelay.send(.error(.init(with: error))) + let xxError = CreateUserFriendlyErrorMessage.live(error.localizedDescription) + self.hudRelay.send(.error(.init(content: xxError))) } self.pushNotifications = false diff --git a/Sources/VersionChecking/VersionChecking.swift b/Sources/VersionChecking/VersionChecking.swift index cc5a719cdc5bd28f08ca8aea34dd04a7bcf233de..bf50d90c877a65858940a4bdad70b1101e1dc1d0 100644 --- a/Sources/VersionChecking/VersionChecking.swift +++ b/Sources/VersionChecking/VersionChecking.swift @@ -1,8 +1,6 @@ import Combine import Foundation -#warning("TODO: Unit test this feature") - public enum VersionInfo { case upToDate case failure(Error) diff --git a/client-ios.xcworkspace/xcshareddata/swiftpm/Package.resolved b/client-ios.xcworkspace/xcshareddata/swiftpm/Package.resolved index 50525d0f451211b9644f60f113a59b006a55666c..23ec4727ce331bc2d829851a7466b7fe213a55c9 100644 --- a/client-ios.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/client-ios.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -68,8 +68,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/pointfreeco/combine-schedulers", "state" : { - "revision" : "9e42b4b0453da417a44daa17174103e7d1c5be07", - "version" : "0.7.3" + "revision" : "11973960af9c5426f22d337628cec4342c5e660d", + "version" : "0.7.4" } }, { @@ -105,7 +105,7 @@ "location" : "https://git.xx.network/elixxir/elixxir-dapps-sdk-swift", "state" : { "branch" : "development", - "revision" : "15a7ab035a7c0b9031cf0fa977563b3a1a254647" + "revision" : "f1ea0689bbd0e2faa978d5b478c9d594a9f96115" } }, { @@ -176,8 +176,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/groue/GRDB.swift", "state" : { - "revision" : "23f4254ae36fa19aecd73047c0577a9f49850d1c", - "version" : "5.26.0" + "revision" : "dd7e7f39e8e4d7a22d258d9809a882f914690b01", + "version" : "5.26.1" } }, { @@ -328,8 +328,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/pointfreeco/swift-composable-architecture.git", "state" : { - "revision" : "a518935116b2bada7234f47073159b433d432af1", - "version" : "0.39.1" + "revision" : "5b78fbcb0583568392762b15a262b3106cfb5185", + "version" : "0.40.0" } }, {