Skip to content
Snippets Groups Projects
Commit e144e690 authored by Bruno Muniz's avatar Bruno Muniz :apple:
Browse files

Merge branch 'continuing-search-ui' into 'development'

Search UI 2.0

See merge request elixxir/client-ios!50
parents bfc31b88 433999d7
No related branches found
No related tags found
2 merge requests!54Releasing 1.1.4,!50Search UI 2.0
Showing
with 171 additions and 83 deletions
...@@ -68,7 +68,7 @@ let package = Package( ...@@ -68,7 +68,7 @@ let package = Package(
.package(url: "https://github.com/pointfreeco/combine-schedulers", from: "0.5.0"), .package(url: "https://github.com/pointfreeco/combine-schedulers", from: "0.5.0"),
.package(url: "https://github.com/kishikawakatsumi/KeychainAccess", from: "4.2.1"), .package(url: "https://github.com/kishikawakatsumi/KeychainAccess", from: "4.2.1"),
.package(url: "https://github.com/google/google-api-objectivec-client-for-rest", from: "1.6.0"), .package(url: "https://github.com/google/google-api-objectivec-client-for-rest", from: "1.6.0"),
.package(url: "https://git.xx.network/elixxir/client-ios-db.git", .upToNextMajor(from: "1.0.5")), .package(url: "https://git.xx.network/elixxir/client-ios-db.git", .upToNextMajor(from: "1.0.8")),
.package(url: "https://github.com/firebase/firebase-ios-sdk.git", .upToNextMajor(from: "8.10.0")), .package(url: "https://github.com/firebase/firebase-ios-sdk.git", .upToNextMajor(from: "8.10.0")),
.package(url: "https://github.com/darrarski/Shout.git", revision: "df5a662293f0ac15eeb4f2fd3ffd0c07b73d0de0"), .package(url: "https://github.com/darrarski/Shout.git", revision: "df5a662293f0ac15eeb4f2fd3ffd0c07b73d0de0"),
.package(url: "https://github.com/pointfreeco/swift-composable-architecture.git",.upToNextMajor(from: "0.32.0")), .package(url: "https://github.com/pointfreeco/swift-composable-architecture.git",.upToNextMajor(from: "0.32.0")),
...@@ -220,9 +220,11 @@ let package = Package( ...@@ -220,9 +220,11 @@ let package = Package(
name: "SFTPFeature", name: "SFTPFeature",
dependencies: [ dependencies: [
"HUD", "HUD",
"Models",
"Shared", "Shared",
"Keychain", "Keychain",
"InputField", "InputField",
"Presentation",
"DependencyInjection", "DependencyInjection",
.product( .product(
name: "Shout", name: "Shout",
......
...@@ -104,7 +104,7 @@ struct DependencyRegistrator { ...@@ -104,7 +104,7 @@ struct DependencyRegistrator {
// MARK: Isolated // MARK: Isolated
container.register(HUD() as HUDType) container.register(HUD())
container.register(ThemeController() as ThemeControlling) container.register(ThemeController() as ThemeControlling)
container.register(ToastController()) container.register(ToastController())
container.register(StatusBarController() as StatusBarStyleControlling) container.register(StatusBarController() as StatusBarStyleControlling)
...@@ -137,6 +137,8 @@ struct DependencyRegistrator { ...@@ -137,6 +137,8 @@ struct DependencyRegistrator {
container.register( container.register(
SearchCoordinator( SearchCoordinator(
contactsFactory: ContactListController.init,
requestsFactory: RequestsContainerController.init,
contactFactory: ContactController.init(_:), contactFactory: ContactController.init(_:),
countriesFactory: CountryListController.init(_:) countriesFactory: CountryListController.init(_:)
) as SearchCoordinating) ) as SearchCoordinating)
......
...@@ -6,7 +6,7 @@ import Combine ...@@ -6,7 +6,7 @@ import Combine
import DependencyInjection import DependencyInjection
public final class BackupController: UIViewController { public final class BackupController: UIViewController {
@Dependency private var hud: HUDType @Dependency var hud: HUD
private let viewModel = BackupViewModel.live() private let viewModel = BackupViewModel.live()
private var cancellables = Set<AnyCancellable>() private var cancellables = Set<AnyCancellable>()
...@@ -14,7 +14,7 @@ public final class BackupController: UIViewController { ...@@ -14,7 +14,7 @@ public final class BackupController: UIViewController {
public override func viewDidLoad() { public override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
view.backgroundColor = Asset.neutralWhite.color view.backgroundColor = Asset.neutralWhite.color
hud.update(with: .on(nil)) hud.update(with: .on)
setupNavigationBar() setupNavigationBar()
setupBindings() setupBindings()
......
...@@ -30,7 +30,7 @@ struct BackupConfigViewModel { ...@@ -30,7 +30,7 @@ struct BackupConfigViewModel {
extension BackupConfigViewModel { extension BackupConfigViewModel {
static func live() -> Self { static func live() -> Self {
class Context { class Context {
@Dependency var hud: HUDType @Dependency var hud: HUD
@Dependency var service: BackupService @Dependency var service: BackupService
@Dependency var coordinator: BackupCoordinating @Dependency var coordinator: BackupCoordinating
} }
...@@ -40,7 +40,7 @@ extension BackupConfigViewModel { ...@@ -40,7 +40,7 @@ extension BackupConfigViewModel {
return .init( return .init(
didTapBackupNow: { didTapBackupNow: {
context.service.performBackup() context.service.performBackup()
context.hud.update(with: .on(nil)) context.hud.update(with: .on)
DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) { DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
context.hud.update(with: .none) context.hud.update(with: .none)
} }
...@@ -57,7 +57,7 @@ extension BackupConfigViewModel { ...@@ -57,7 +57,7 @@ extension BackupConfigViewModel {
context.service.toggle(service: service, enabling: false) context.service.toggle(service: service, enabling: false)
}, passphraseClosure: { passphrase in }, passphraseClosure: { passphrase in
context.service.passphrase = passphrase context.service.passphrase = passphrase
context.hud.update(with: .on("Initializing and securing your backup file will take few seconds, please keep the app open.")) context.hud.update(with: .onTitle("Initializing and securing your backup file will take few seconds, please keep the app open."))
DispatchQueue.global().async { DispatchQueue.global().async {
context.service.toggle(service: service, enabling: enabling) context.service.toggle(service: service, enabling: enabling)
......
...@@ -24,7 +24,7 @@ extension Message: Differentiable { ...@@ -24,7 +24,7 @@ extension Message: Differentiable {
} }
public final class SingleChatController: UIViewController { public final class SingleChatController: UIViewController {
@Dependency private var hud: HUDType @Dependency private var hud: HUD
@Dependency private var logger: XXLogger @Dependency private var logger: XXLogger
@Dependency private var voxophone: Voxophone @Dependency private var voxophone: Voxophone
@Dependency private var coordinator: ChatCoordinating @Dependency private var coordinator: ChatCoordinating
......
...@@ -107,7 +107,7 @@ final class SingleChatViewModel { ...@@ -107,7 +107,7 @@ final class SingleChatViewModel {
func didSend(image: UIImage) { func didSend(image: UIImage) {
guard let imageData = image.orientedUp().jpegData(compressionQuality: 1.0) else { return } guard let imageData = image.orientedUp().jpegData(compressionQuality: 1.0) else { return }
hudRelay.send(.on(nil)) hudRelay.send(.on)
session.send(imageData: imageData, to: contact) { [weak self] in session.send(imageData: imageData, to: contact) { [weak self] in
switch $0 { switch $0 {
......
...@@ -147,7 +147,7 @@ final class ChatListViewModel { ...@@ -147,7 +147,7 @@ final class ChatListViewModel {
} }
func leave(_ group: Group) { func leave(_ group: Group) {
hudSubject.send(.on(nil)) hudSubject.send(.on)
do { do {
try session.leave(group: group) try session.leave(group: group)
......
...@@ -14,7 +14,7 @@ final class ChatListView: UIView { ...@@ -14,7 +14,7 @@ final class ChatListView: UIView {
backgroundColor = Asset.neutralWhite.color backgroundColor = Asset.neutralWhite.color
listContainerView.backgroundColor = Asset.neutralWhite.color listContainerView.backgroundColor = Asset.neutralWhite.color
searchListContainerView.backgroundColor = Asset.neutralWhite.color searchListContainerView.backgroundColor = Asset.neutralWhite.color
searchView.update(placeholder: "Search chats") searchView.update(placeholder: Localized.ChatList.Search.title)
addSubview(snackBar) addSubview(snackBar)
addSubview(searchView) addSubview(searchView)
...@@ -22,6 +22,34 @@ final class ChatListView: UIView { ...@@ -22,6 +22,34 @@ final class ChatListView: UIView {
containerView.addSubview(searchListContainerView) containerView.addSubview(searchListContainerView)
containerView.addSubview(listContainerView) containerView.addSubview(listContainerView)
setupConstraints()
}
required init?(coder: NSCoder) { nil }
func showConnectingBanner(_ show: Bool) {
if show == true {
snackBar.alpha = 0.0
snackBar.snp.updateConstraints {
$0.bottom
.equalTo(snp.top)
.offset(snackBar.bounds.height)
}
} else {
snackBar.alpha = 1.0
snackBar.snp.updateConstraints {
$0.bottom.equalTo(snp.top)
}
}
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseInOut) {
self.setNeedsLayout()
self.layoutIfNeeded()
self.snackBar.alpha = show ? 1.0 : 0.0
}
}
private func setupConstraints() {
snackBar.snp.makeConstraints { snackBar.snp.makeConstraints {
$0.left.equalToSuperview() $0.left.equalToSuperview()
$0.right.equalToSuperview() $0.right.equalToSuperview()
...@@ -49,28 +77,4 @@ final class ChatListView: UIView { ...@@ -49,28 +77,4 @@ final class ChatListView: UIView {
$0.edges.equalToSuperview() $0.edges.equalToSuperview()
} }
} }
required init?(coder: NSCoder) { nil }
func showConnectingBanner(_ show: Bool) {
if show == true {
snackBar.alpha = 0.0
snackBar.snp.updateConstraints {
$0.bottom
.equalTo(snp.top)
.offset(snackBar.bounds.height)
}
} else {
snackBar.alpha = 1.0
snackBar.snp.updateConstraints {
$0.bottom.equalTo(snp.top)
}
}
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseInOut) {
self.setNeedsLayout()
self.layoutIfNeeded()
self.snackBar.alpha = show ? 1.0 : 0.0
}
}
} }
...@@ -10,7 +10,7 @@ import DependencyInjection ...@@ -10,7 +10,7 @@ import DependencyInjection
import ScrollViewController import ScrollViewController
public final class ContactController: UIViewController { public final class ContactController: UIViewController {
@Dependency private var hud: HUDType @Dependency private var hud: HUD
@Dependency private var coordinator: ContactCoordinating @Dependency private var coordinator: ContactCoordinating
@Dependency private var statusBarController: StatusBarStyleControlling @Dependency private var statusBarController: StatusBarStyleControlling
......
...@@ -62,7 +62,7 @@ final class ContactViewModel { ...@@ -62,7 +62,7 @@ final class ContactViewModel {
} }
func didTapDelete() { func didTapDelete() {
hudRelay.send(.on(nil)) hudRelay.send(.on)
do { do {
try session.deleteContact(contact) try session.deleteContact(contact)
...@@ -91,7 +91,7 @@ final class ContactViewModel { ...@@ -91,7 +91,7 @@ final class ContactViewModel {
} }
func didTapResend() { func didTapResend() {
hudRelay.send(.on(nil)) hudRelay.send(.on)
backgroundScheduler.schedule { [weak self] in backgroundScheduler.schedule { [weak self] in
guard let self = self else { return } guard let self = self else { return }
...@@ -107,7 +107,7 @@ final class ContactViewModel { ...@@ -107,7 +107,7 @@ final class ContactViewModel {
} }
func didTapRequest(with nickname: String) { func didTapRequest(with nickname: String) {
hudRelay.send(.on(nil)) hudRelay.send(.on)
contact.nickname = nickname contact.nickname = nickname
backgroundScheduler.schedule { [weak self] in backgroundScheduler.schedule { [weak self] in
...@@ -124,7 +124,7 @@ final class ContactViewModel { ...@@ -124,7 +124,7 @@ final class ContactViewModel {
} }
func didTapAccept(_ nickname: String) { func didTapAccept(_ nickname: String) {
hudRelay.send(.on(nil)) hudRelay.send(.on)
contact.nickname = nickname contact.nickname = nickname
backgroundScheduler.schedule { [weak self] in backgroundScheduler.schedule { [weak self] in
......
...@@ -30,7 +30,7 @@ final class ContactListTableController: UITableViewController { ...@@ -30,7 +30,7 @@ final class ContactListTableController: UITableViewController {
private func setupTableView() { private func setupTableView() {
tableView.separatorStyle = .none tableView.separatorStyle = .none
tableView.register(SmallAvatarAndTitleCell.self) tableView.register(AvatarCell.self)
tableView.backgroundColor = Asset.neutralWhite.color tableView.backgroundColor = Asset.neutralWhite.color
tableView.sectionIndexColor = Asset.neutralDark.color tableView.sectionIndexColor = Asset.neutralDark.color
tableView.contentInset = UIEdgeInsets(top: -20, left: 0, bottom: 0, right: 0) tableView.contentInset = UIEdgeInsets(top: -20, left: 0, bottom: 0, right: 0)
...@@ -45,11 +45,11 @@ final class ContactListTableController: UITableViewController { ...@@ -45,11 +45,11 @@ final class ContactListTableController: UITableViewController {
} }
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: SmallAvatarAndTitleCell = tableView.dequeueReusableCell(forIndexPath: indexPath) let cell: AvatarCell = tableView.dequeueReusableCell(forIndexPath: indexPath)
let contact = sections[indexPath.section][indexPath.row] let contact = sections[indexPath.section][indexPath.row]
let name = (contact.nickname ?? contact.username) ?? "Fetching username..." let name = (contact.nickname ?? contact.username) ?? "Fetching username..."
cell.titleLabel.text = name
cell.avatarView.setupProfile(title: name, image: contact.photo, size: .medium) cell.setup(title: name, image: contact.photo)
return cell return cell
} }
......
...@@ -7,7 +7,7 @@ import XXModels ...@@ -7,7 +7,7 @@ import XXModels
import DependencyInjection import DependencyInjection
public final class CreateGroupController: UIViewController { public final class CreateGroupController: UIViewController {
@Dependency private var hud: HUDType @Dependency private var hud: HUD
@Dependency private var coordinator: ContactListCoordinating @Dependency private var coordinator: ContactListCoordinating
lazy private var titleLabel = UILabel() lazy private var titleLabel = UILabel()
...@@ -66,7 +66,7 @@ public final class CreateGroupController: UIViewController { ...@@ -66,7 +66,7 @@ public final class CreateGroupController: UIViewController {
private func setupTableAndCollection() { private func setupTableAndCollection() {
screenView.tableView.rowHeight = 64.0 screenView.tableView.rowHeight = 64.0
screenView.tableView.register(SmallAvatarAndTitleCell.self) screenView.tableView.register(AvatarCell.self)
screenView.collectionView.register(CreateGroupCollectionCell.self) screenView.collectionView.register(CreateGroupCollectionCell.self)
collectionDataSource = UICollectionViewDiffableDataSource<SectionId, Contact>( collectionDataSource = UICollectionViewDiffableDataSource<SectionId, Contact>(
...@@ -84,10 +84,10 @@ public final class CreateGroupController: UIViewController { ...@@ -84,10 +84,10 @@ public final class CreateGroupController: UIViewController {
tableDataSource = DiffEditableDataSource<SectionId, Contact>( tableDataSource = DiffEditableDataSource<SectionId, Contact>(
tableView: screenView.tableView tableView: screenView.tableView
) { [weak self] tableView, indexPath, contact in ) { [weak self] tableView, indexPath, contact in
let cell = tableView.dequeueReusableCell(forIndexPath: indexPath, ofType: SmallAvatarAndTitleCell.self) let cell = tableView.dequeueReusableCell(forIndexPath: indexPath, ofType: AvatarCell.self)
let title = (contact.nickname ?? contact.username) ?? "" let title = (contact.nickname ?? contact.username) ?? ""
cell.titleLabel.text = title
cell.avatarView.setupProfile(title: title, image: contact.photo, size: .medium) cell.setup(title: title, image: contact.photo)
if let selectedElements = self?.selectedElements, selectedElements.contains(contact) { if let selectedElements = self?.selectedElements, selectedElements.contains(contact) {
tableView.selectRow(at: indexPath, animated: true, scrollPosition: .none) tableView.selectRow(at: indexPath, animated: true, scrollPosition: .none)
......
...@@ -76,7 +76,7 @@ final class CreateGroupViewModel { ...@@ -76,7 +76,7 @@ final class CreateGroupViewModel {
} }
func create(name: String, welcome: String?, members: [Contact]) { func create(name: String, welcome: String?, members: [Contact]) {
hudRelay.send(.on(nil)) hudRelay.send(.on)
session.createGroup(name: name, welcome: welcome, members: members) { [weak self] in session.createGroup(name: name, welcome: welcome, members: members) { [weak self] in
guard let self = self else { return } guard let self = self else { return }
......
...@@ -10,15 +10,17 @@ private enum Constants { ...@@ -10,15 +10,17 @@ private enum Constants {
} }
public enum HUDStatus: Equatable { public enum HUDStatus: Equatable {
case on(String?)
case none case none
case on
case onTitle(String)
case onAction(String)
case error(HUDError) case error(HUDError)
var isPresented: Bool { var isPresented: Bool {
switch self { switch self {
case .none: case .none:
return false return false
case .on, .error: case .on, .error, .onTitle, .onAction:
return true return true
} }
} }
...@@ -50,15 +52,12 @@ public struct HUDError: Equatable { ...@@ -50,15 +52,12 @@ public struct HUDError: Equatable {
} }
} }
public protocol HUDType { public final class HUD {
func update(with status: HUDStatus)
}
public final class HUD: HUDType {
private(set) var window: UIWindow? private(set) var window: UIWindow?
private(set) var errorView: ErrorView? private(set) var errorView: ErrorView?
private(set) var titleLabel: UILabel? private(set) var titleLabel: UILabel?
private(set) var animation: DotAnimation? private(set) var animation: DotAnimation?
public var actionButton: CapsuleButton?
private var cancellables = Set<AnyCancellable>() private var cancellables = Set<AnyCancellable>()
private var status: HUDStatus = .none { private var status: HUDStatus = .none {
...@@ -67,16 +66,23 @@ public final class HUD: HUDType { ...@@ -67,16 +66,23 @@ public final class HUD: HUDType {
self.errorView = nil self.errorView = nil
self.animation = nil self.animation = nil
self.window = nil self.window = nil
self.actionButton = nil
self.titleLabel = nil self.titleLabel = nil
switch status { switch status {
case .on(let text): case .on:
animation = DotAnimation() animation = DotAnimation()
if let text = text { case .onTitle(let text):
animation = DotAnimation()
titleLabel = UILabel() titleLabel = UILabel()
titleLabel!.text = text titleLabel!.text = text
}
case .onAction(let title):
animation = DotAnimation()
actionButton = CapsuleButton()
actionButton!.set(style: .seeThroughWhite, title: title)
case .error(let error): case .error(let error):
errorView = ErrorView(with: error) errorView = ErrorView(with: error)
case .none: case .none:
...@@ -88,13 +94,19 @@ public final class HUD: HUDType { ...@@ -88,13 +94,19 @@ public final class HUD: HUDType {
if oldValue.isPresented == false && status.isPresented == true { if oldValue.isPresented == false && status.isPresented == true {
switch status { switch status {
case .on(let text): case .on:
animation = DotAnimation() animation = DotAnimation()
if let text = text { case .onTitle(let text):
animation = DotAnimation()
titleLabel = UILabel() titleLabel = UILabel()
titleLabel!.text = text titleLabel!.text = text
}
case .onAction(let title):
animation = DotAnimation()
actionButton = CapsuleButton()
actionButton!.set(style: .seeThroughWhite, title: title)
case .error(let error): case .error(let error):
errorView = ErrorView(with: error) errorView = ErrorView(with: error)
case .none: case .none:
...@@ -118,7 +130,7 @@ public final class HUD: HUDType { ...@@ -118,7 +130,7 @@ public final class HUD: HUDType {
private func showWindow() { private func showWindow() {
window = Window() window = Window()
window?.backgroundColor = UIColor.black.withAlphaComponent(0.5) window?.backgroundColor = UIColor.black.withAlphaComponent(0.8)
window?.rootViewController = StatusBarViewController(nil) window?.rootViewController = StatusBarViewController(nil)
if let animation = animation { if let animation = animation {
...@@ -138,6 +150,15 @@ public final class HUD: HUDType { ...@@ -138,6 +150,15 @@ public final class HUD: HUDType {
} }
} }
if let actionButton = actionButton {
window?.addSubview(actionButton)
actionButton.snp.makeConstraints {
$0.left.equalToSuperview().offset(18)
$0.right.equalToSuperview().offset(-18)
$0.bottom.equalToSuperview().offset(-50)
}
}
if let errorView = errorView { if let errorView = errorView {
window?.addSubview(errorView) window?.addSubview(errorView)
errorView.snp.makeConstraints { make in errorView.snp.makeConstraints { make in
...@@ -166,6 +187,7 @@ public final class HUD: HUDType { ...@@ -166,6 +187,7 @@ public final class HUD: HUDType {
self.cancellables.removeAll() self.cancellables.removeAll()
self.errorView = nil self.errorView = nil
self.animation = nil self.animation = nil
self.actionButton = nil
self.titleLabel = nil self.titleLabel = nil
self.window = nil self.window = nil
} }
......
...@@ -90,7 +90,7 @@ public class Client { ...@@ -90,7 +90,7 @@ public class Client {
public func addJson(_ string: String) { public func addJson(_ string: String) {
guard let backupManager = backupManager else { guard let backupManager = backupManager else {
fatalError() fatalError("Trying to add json parameters to backup but no backup manager created yet")
} }
print("^^^ Set params: \(string) to backup") print("^^^ Set params: \(string) to backup")
......
...@@ -154,17 +154,15 @@ extension BindingsClient: BindingsInterface { ...@@ -154,17 +154,15 @@ extension BindingsClient: BindingsInterface {
for env: NetworkEnvironment, for env: NetworkEnvironment,
_ completion: @escaping (Result<Data?, Error>) -> Void _ completion: @escaping (Result<Data?, Error>) -> Void
) { ) {
log(type: .crumbs)
var error: NSError? var error: NSError?
let ndf = BindingsDownloadAndVerifySignedNdfWithUrl(env.url, env.cert, &error) let ndf = BindingsDownloadAndVerifySignedNdfWithUrl(env.url, env.cert, &error)
if let error = error { guard error == nil else {
log(string: error.localizedDescription, type: .error) Self.updateNDF(for: env, completion)
completion(.failure(error)) return
} else {
completion(.success(ndf))
} }
completion(.success(ndf))
} }
/// Fetches a JSON with up-to-date error descriptions /// Fetches a JSON with up-to-date error descriptions
......
...@@ -94,7 +94,7 @@ extension Session { ...@@ -94,7 +94,7 @@ extension Session {
} }
public func retryRequest(_ contact: Contact) throws { public func retryRequest(_ contact: Contact) throws {
log(string: "Retrying to request a contact", type: .info) let name = (contact.nickname ?? contact.username) ?? ""
client.bindings.add(contact.marshaled!, from: myQR) { [weak self, contact] in client.bindings.add(contact.marshaled!, from: myQR) { [weak self, contact] in
var contact = contact var contact = contact
...@@ -103,11 +103,21 @@ extension Session { ...@@ -103,11 +103,21 @@ extension Session {
do { do {
switch $0 { switch $0 {
case .success: case .success:
log(string: "Retrying to request a contact -- Success", type: .info)
contact.authStatus = .requested contact.authStatus = .requested
case .failure(let error):
log(string: "Retrying to request a contact -- Failed: \(error.localizedDescription)", type: .error) self.toastController.enqueueToast(model: .init(
title: Localized.Requests.Sent.Toast.resent(name),
leftImage: Asset.sharedSuccess.image
))
case .failure:
contact.createdAt = Date() contact.createdAt = Date()
self.toastController.enqueueToast(model: .init(
title: Localized.Requests.Sent.Toast.resentFailed(name),
color: Asset.accentDanger.color,
leftImage: Asset.requestFailedToaster.image
))
} }
_ = try self.dbManager.saveContact(contact) _ = try self.dbManager.saveContact(contact)
...@@ -170,6 +180,13 @@ extension Session { ...@@ -170,6 +180,13 @@ extension Session {
contact.authStatus = success ? .requested : .requestFailed contact.authStatus = success ? .requested : .requestFailed
contact = try self.dbManager.saveContact(contact) contact = try self.dbManager.saveContact(contact)
let name = contact.nickname ?? contact.username
self.toastController.enqueueToast(model: .init(
title: Localized.Requests.Sent.Toast.sent(name ?? ""),
leftImage: Asset.sharedSuccess.image
))
case .failure: case .failure:
contact.createdAt = Date() contact.createdAt = Date()
contact.authStatus = .requestFailed contact.authStatus = .requestFailed
......
import Models import Models
import XXModels import XXModels
import Foundation import Foundation
import Combine
extension Session { extension Session {
public func search(fact: String) -> AnyPublisher<Contact, Error> {
Deferred {
Future { promise in
guard let ud = self.client.userDiscovery else {
let error = NSError(domain: "", code: 0)
promise(.failure(error))
return
}
do {
try self.client.bindings.nodeRegistrationStatus()
try ud.search(fact: fact) {
switch $0 {
case .success(let contact):
promise(.success(contact))
case .failure(let error):
promise(.failure(error))
}
}
} catch {
promise(.failure(error))
}
}
}.eraseToAnyPublisher()
}
public func search(fact: String, _ completion: @escaping (Result<Contact, Error>) -> Void) throws { public func search(fact: String, _ completion: @escaping (Result<Contact, Error>) -> Void) throws {
guard let ud = client.userDiscovery else { return } guard let ud = client.userDiscovery else { return }
try client.bindings.nodeRegistrationStatus() try client.bindings.nodeRegistrationStatus()
...@@ -69,6 +96,8 @@ extension Session { ...@@ -69,6 +96,8 @@ extension Session {
phone = confirmation.content phone = confirmation.content
} }
if let _ = client.backupManager {
updateFactsOnBackup() updateFactsOnBackup()
} }
} }
}
...@@ -130,8 +130,20 @@ public final class Session: SessionType { ...@@ -130,8 +130,20 @@ public final class Session: SessionType {
let params = try! JSONDecoder().decode(BackupParameters.self, from: Data(report.parameters.utf8)) let params = try! JSONDecoder().decode(BackupParameters.self, from: Data(report.parameters.utf8))
username = params.username username = params.username
phone = params.phone
email = params.email if let paramsPhone = params.phone, !paramsPhone.isEmpty {
phone = paramsPhone
}
if let paramsEmail = params.email, !paramsEmail.isEmpty {
email = paramsEmail
}
}
print("^^^ \(report.parameters)")
guard username!.isEmpty == false else {
fatalError("Trying to restore an account that has no username")
} }
try continueInitialization() try continueInitialization()
......
...@@ -66,4 +66,6 @@ public protocol SessionType { ...@@ -66,4 +66,6 @@ public protocol SessionType {
members: [Contact], members: [Contact],
_ completion: @escaping (Result<GroupInfo, Error>) -> Void _ completion: @escaping (Result<GroupInfo, Error>) -> Void
) )
func search(fact: String) -> AnyPublisher<Contact, Error>
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment