diff --git a/Package.swift b/Package.swift index 45958a19c19a494cb6979c9dac8b55ca1905e56f..2c6601fb955ac822efb8dcfd0bf129af5052b47d 100644 --- a/Package.swift +++ b/Package.swift @@ -116,7 +116,7 @@ let package = Package( ), .package( url: "https://git.xx.network/elixxir/client-ios-db.git", - .upToNextMajor(from: "1.0.8") + branch: "feature/blocked-and-banned-contacts" ), .package( url: "https://github.com/firebase/firebase-ios-sdk.git", @@ -134,6 +134,10 @@ let package = Package( url: "https://github.com/pointfreeco/swift-custom-dump.git", .upToNextMajor(from: "0.5.0") ), + .package( + url: "https://github.com/swiftcsv/SwiftCSV.git", + from: "0.8.0" + ), .package( url: "https://github.com/pointfreeco/xctest-dynamic-overlay.git", .upToNextMajor(from: "0.3.3") @@ -507,6 +511,7 @@ let package = Package( .target(name: "DropboxFeature"), .target(name: "VersionChecking"), .target(name: "DependencyInjection"), + .product(name: "SwiftCSV", package: "SwiftCSV"), ] ), .target( diff --git a/Sources/LaunchFeature/LaunchController.swift b/Sources/LaunchFeature/LaunchController.swift index 9d904232f4f1900e8ea1880a83717a4b9eadafd6..cf8b093b2131d2becbb7d5e6bb55a3b02fb73c0e 100644 --- a/Sources/LaunchFeature/LaunchController.swift +++ b/Sources/LaunchFeature/LaunchController.swift @@ -2,6 +2,7 @@ import HUD import UIKit import Shared import Combine +import Defaults import PushFeature import DependencyInjection @@ -9,6 +10,8 @@ public final class LaunchController: UIViewController { @Dependency private var hud: HUD @Dependency private var coordinator: LaunchCoordinating + @KeyObject(.acceptedTerms, defaultValue: false) var didAcceptTerms: Bool + lazy private var screenView = LaunchView() private let blocker = UpdateBlocker() @@ -50,6 +53,11 @@ public final class LaunchController: UIViewController { .sink { [unowned self] in switch $0 { case .chats: + guard didAcceptTerms == true else { + coordinator.toTerms(from: self) + return + } + if let pushRoute = pendingPushRoute { switch pushRoute { case .requests: diff --git a/Sources/LaunchFeature/LaunchViewModel.swift b/Sources/LaunchFeature/LaunchViewModel.swift index 0b8354dacde4b0a364b2f7d2b4a3b7701a66093e..9dea87edf7217a2c0077187d1b71ffc12bf427d2 100644 --- a/Sources/LaunchFeature/LaunchViewModel.swift +++ b/Sources/LaunchFeature/LaunchViewModel.swift @@ -1,6 +1,7 @@ import HUD import Shared import Models +import SwiftCSV import Combine import Defaults @@ -46,6 +47,10 @@ final class LaunchViewModel { routeSubject.eraseToAnyPublisher() } + var mainScheduler: AnySchedulerOf<DispatchQueue> = { + DispatchQueue.main.eraseToAnyScheduler() + }() + var backgroundScheduler: AnySchedulerOf<DispatchQueue> = { DispatchQueue.global().eraseToAnyScheduler() }() @@ -57,67 +62,74 @@ final class LaunchViewModel { private let hudSubject = CurrentValueSubject<HUDStatus, Never>(.none) func viewDidAppear() { - DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in - self?.hudSubject.send(.on) - self?.checkVersion() - } - } - - private func checkVersion() { - versionChecker().sink { [unowned self] in - switch $0 { - case .upToDate: - versionApproved() - case .failure(let error): - versionFailed(error: error) - case .updateRequired(let info): - versionUpdateRequired(info) - case .updateRecommended(let info): - versionUpdateRecommended(info) - } - }.store(in: &cancellables) - } - - func versionApproved() { - network.writeLogs() - - network.updateNDF { [weak self] in + mainScheduler.schedule(after: .init(.now() + 1)) { [weak self] in guard let self = self else { return } - switch $0 { - case .success(let ndf): - self.network.updateErrors() + self.hudSubject.send(.on) - guard self.network.hasClient else { - self.hudSubject.send(.none) - self.routeSubject.send(.onboarding(ndf)) - self.dropboxService.unlink() - try? self.keychainHandler.clear() - return + self.versionChecker().sink { [unowned self] in + switch $0 { + case .upToDate: + self.versionApproved() + case .failure(let error): + self.versionFailed(error: error) + case .updateRequired(let info): + self.versionUpdateRequired(info) + case .updateRecommended(let info): + self.versionUpdateRecommended(info) } + }.store(in: &self.cancellables) + } + } - guard self.username != nil else { - self.network.purgeFiles() - self.hudSubject.send(.none) - self.routeSubject.send(.onboarding(ndf)) - self.dropboxService.unlink() - try? self.keychainHandler.clear() - return - } + func versionApproved() { + Task { + do { + network.writeLogs() + let bannedList = try await fetchBannedList() + process(bannedList: bannedList) - self.backgroundScheduler.schedule { [weak self] in + network.updateNDF { [weak self] in guard let self = self else { return } - do { - let session = try self.getSession(ndf) - DependencyInjection.Container.shared.register(session as SessionType) - self.hudSubject.send(.none) - self.checkBiometrics() - } catch { + switch $0 { + case .success(let ndf): + self.network.updateErrors() + + guard self.network.hasClient else { + self.hudSubject.send(.none) + self.routeSubject.send(.onboarding(ndf)) + self.dropboxService.unlink() + try? self.keychainHandler.clear() + return + } + + guard self.username != nil else { + self.network.purgeFiles() + self.hudSubject.send(.none) + self.routeSubject.send(.onboarding(ndf)) + self.dropboxService.unlink() + try? self.keychainHandler.clear() + return + } + + self.backgroundScheduler.schedule { [weak self] in + guard let self = self else { return } + + do { + let session = try self.getSession(ndf) + DependencyInjection.Container.shared.register(session as SessionType) + self.hudSubject.send(.none) + self.checkBiometrics() + } catch { + self.hudSubject.send(.error(HUDError(with: error))) + } + } + case .failure(let error): self.hudSubject.send(.error(HUDError(with: error))) } } - case .failure(let error): + } catch { self.hudSubject.send(.error(HUDError(with: error))) } } @@ -195,4 +207,34 @@ final class LaunchViewModel { self.routeSubject.send(.chats) } } + + private func fetchBannedList() async throws -> Data { + let request = URLRequest( + url: URL(string: "https://elixxir-bins.s3.us-west-1.amazonaws.com/client/bannedUsers/banned.csv")!, + cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, + timeoutInterval: 5 + ) + + return try await withCheckedThrowingContinuation { continuation in + URLSession.shared.dataTask(with: request) { data, _, error in + if let error = error { + return continuation.resume(throwing: error) + } + + guard let data = data else { fatalError("?") } + return continuation.resume(returning: data) + }.resume() + } + } + + private func process(bannedList: Data) { + if let csv: CSV = try? CSV<Enumerated>( + string: String(data: bannedList, encoding: .utf8)!, + loadColumns: false + ) { + /// csv.rows[0][0] == userId + /// csv.rows[0][1] == username + csv.rows.forEach { print("^^^ Banned row: \($0)") } + } + } } diff --git a/client-ios.xcworkspace/xcshareddata/swiftpm/Package.resolved b/client-ios.xcworkspace/xcshareddata/swiftpm/Package.resolved index 2932261c8cc3c80fb2730138af5c8ff904e9334f..453f1d5d557a06e08739d65208b67e6ff2d655c0 100644 --- a/client-ios.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/client-ios.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -59,8 +59,8 @@ "kind" : "remoteSourceControl", "location" : "https://git.xx.network/elixxir/client-ios-db.git", "state" : { - "revision" : "785e1f653ee5eaaaf58a82c8abbcda2174fbc27a", - "version" : "1.0.8" + "branch" : "feature/blocked-and-banned-contacts", + "revision" : "b35a3779c276471aa6e79f047e1c843e49b0dea8" } }, { @@ -350,6 +350,15 @@ "version" : "1.18.0" } }, + { + "identity" : "swiftcsv", + "kind" : "remoteSourceControl", + "location" : "https://github.com/swiftcsv/SwiftCSV.git", + "state" : { + "revision" : "048a1d3c2950b9c151ef9364b36f91baadc2c28c", + "version" : "0.8.0" + } + }, { "identity" : "swiftybeaver", "kind" : "remoteSourceControl",