Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[trello.com/c/F7EV0pKq] Feat: No active nodes popup #573

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Adamant.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
2657A0CD2C707D800021E7E6 /* short-success.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 4198D57E28C8B834009337F2 /* short-success.mp3 */; };
2657A0CE2C707D830021E7E6 /* default.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 4198D58028C8B8D1009337F2 /* default.mp3 */; };
265AA1622B74E6B900CF98B0 /* ChatPreservation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 265AA1612B74E6B900CF98B0 /* ChatPreservation.swift */; };
26843D6A2CDD29760010F047 /* NodeAvailabilityService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26843D692CDD29710010F047 /* NodeAvailabilityService.swift */; };
269B83102C74A2FF002AA1D7 /* note.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 269B830F2C74A2FF002AA1D7 /* note.mp3 */; };
269B83112C74A34F002AA1D7 /* note.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 269B830F2C74A2FF002AA1D7 /* note.mp3 */; };
269B831E2C74B4EC002AA1D7 /* handoff.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = 269B83122C74B4EA002AA1D7 /* handoff.mp3 */; };
Expand Down Expand Up @@ -706,6 +707,7 @@
2621AB382C60E7AE00046D7A /* NotificationsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsViewModel.swift; sourceTree = "<group>"; };
2621AB3A2C613C8100046D7A /* NotificationsFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsFactory.swift; sourceTree = "<group>"; };
265AA1612B74E6B900CF98B0 /* ChatPreservation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatPreservation.swift; sourceTree = "<group>"; };
26843D692CDD29710010F047 /* NodeAvailabilityService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NodeAvailabilityService.swift; sourceTree = "<group>"; };
269B830F2C74A2FF002AA1D7 /* note.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = note.mp3; sourceTree = "<group>"; };
269B83122C74B4EA002AA1D7 /* handoff.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = handoff.mp3; sourceTree = "<group>"; };
269B83132C74B4EA002AA1D7 /* portal.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = portal.mp3; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2297,6 +2299,7 @@
3AA2D5F8280EAF49000ED971 /* SocketService */,
E9B3D39F201FA2090019EB36 /* DataProviders */,
E9E7CD922002740500DFC4DB /* AdamantAccountService.swift */,
26843D692CDD29710010F047 /* NodeAvailabilityService.swift */,
6455E9F221075D8000B2E94C /* AdamantAddressBookService.swift */,
E90A494A204D9EB8009F6A65 /* AdamantAuthentication.swift */,
E9E7CDBF2003AF6D00DFC4DB /* AdamantCellFactory.swift */,
Expand Down Expand Up @@ -3302,6 +3305,7 @@
3A26D93D2C3C1CC3003AD832 /* KlyNodeApiService.swift in Sources */,
93A118512993167500E144CC /* ChatMessageBackgroundColor.swift in Sources */,
93760BD72C656CF8002507C3 /* DefaultNodesProvider.swift in Sources */,
26843D6A2CDD29760010F047 /* NodeAvailabilityService.swift in Sources */,
3A26D93B2C3C1C97003AD832 /* KlyApiCore.swift in Sources */,
2621AB372C60E74A00046D7A /* NotificationsView.swift in Sources */,
936658A32B0ADE4400BDB2D3 /* CoinsNodesListView+Row.swift in Sources */,
Expand Down
7 changes: 6 additions & 1 deletion Adamant/Modules/Account/AccountFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ struct AccountFactory {
currencyInfoService: assembler.resolve(InfoServiceProtocol.self)!,
languageService: assembler.resolve(LanguageStorageProtocol.self)!,
walletServiceCompose: assembler.resolve(WalletServiceCompose.self)!,
apiServiceCompose: assembler.resolve(ApiServiceComposeProtocol.self)!
apiServiceCompose: assembler.resolve(ApiServiceComposeProtocol.self)!, nodeAvailabilityService: NodeAvailabilityService(
dialogService: assembler.resolve(DialogService.self)!,
apiServiceCompose: assembler.resolve(ApiServiceComposeProtocol.self)!,
screensFactory: screensFactory
)

)
}
}
24 changes: 10 additions & 14 deletions Adamant/Modules/Account/AccountViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ final class AccountViewController: FormViewController {
private let languageService: LanguageStorageProtocol
private let walletServiceCompose: WalletServiceCompose
private let apiServiceCompose: ApiServiceComposeProtocol
private let nodeAvailabilityService: NodeAvailabilityProtocol

let accountService: AccountService
let dialogService: DialogService
Expand Down Expand Up @@ -219,7 +220,8 @@ final class AccountViewController: FormViewController {
currencyInfoService: InfoServiceProtocol,
languageService: LanguageStorageProtocol,
walletServiceCompose: WalletServiceCompose,
apiServiceCompose: ApiServiceComposeProtocol
apiServiceCompose: ApiServiceComposeProtocol,
nodeAvailabilityService: NodeAvailabilityProtocol
) {
self.visibleWalletsService = visibleWalletsService
self.accountService = accountService
Expand All @@ -233,6 +235,7 @@ final class AccountViewController: FormViewController {
self.languageService = languageService
self.walletServiceCompose = walletServiceCompose
self.apiServiceCompose = apiServiceCompose
self.nodeAvailabilityService = nodeAvailabilityService

super.init(style: .insetGrouped)
}
Expand Down Expand Up @@ -1111,19 +1114,12 @@ final class AccountViewController: FormViewController {
}

@objc private func handleRefresh(_ refreshControl: UIRefreshControl) {
let disabledGroup = NodeGroup.allCases.first {
apiServiceCompose.get($0)?.hasEnabledNode != true
}

if let disabledGroup {
dialogService.showWarning(
withMessage: ApiServiceError.noEndpointsAvailable(
nodeGroupName: disabledGroup.name
).localizedDescription
)
}

refreshControl.endRefreshing()
defer { refreshControl.endRefreshing() }
guard nodeAvailabilityService.checkNodeAvailability(
in: .adm,
vc: self
) else { return }

DispatchQueue.background.async { [accountService] in
accountService.reloadWallets()
}
Expand Down
14 changes: 14 additions & 0 deletions Adamant/Modules/Chat/View/ChatViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,20 @@ private extension ChatViewController {
self?.didTapSelectText(text: text)
}
.store(in: &subscriptions)

viewModel.presentNodeListVC
.sink { [weak self] node in
guard let self = self else { return }

let vc = node == .adm
? screensFactory.makeNodesList()
: screensFactory.makeCoinsNodesList(context: .menu)

let nav = UINavigationController(rootViewController: vc)
nav.modalPresentationStyle = .pageSheet
self.present(nav, animated: true, completion: nil)
}
.store(in: &subscriptions)
}
}

Expand Down
5 changes: 4 additions & 1 deletion Adamant/Modules/Chat/View/Managers/ChatDialogManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ final class ChatDialogManager {

typealias DidSelectEmojiAction = ((_ emoji: String, _ messageId: String) -> Void)?
typealias ContextMenuAction = ((_ messageId: String) -> Void)?

typealias NoActiveNodesAction = (() -> Void)

init(
viewModel: ChatViewModel,
dialogService: DialogService,
Expand Down Expand Up @@ -108,6 +109,8 @@ private extension ChatDialogManager {
showRenameAlert()
case .actionMenu:
showActionMenu()
case .noActiveNodesAlert(let name, let action):
dialogService.showNoActiveNodesAlert(nodeName: name, completion: action)
}
}

Expand Down
34 changes: 24 additions & 10 deletions Adamant/Modules/Chat/ViewModel/ChatViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ final class ChatViewModel: NSObject {
let presentDocumentPickerVC = ObservableSender<Void>()
let presentDocumentViewerVC = ObservableSender<([FileResult], Int)>()
let presentDropView = ObservableSender<Bool>()
let presentNodeListVC = ObservableSender<NodeGroup>()

@ObservableValue private(set) var isHeaderLoading = false
@ObservableValue private(set) var fullscreenLoading = false
Expand Down Expand Up @@ -295,9 +296,13 @@ final class ChatViewModel: NSObject {

Task {
guard apiServiceCompose.get(.adm)?.hasEnabledNode == true else {
dialog.send(.alert(ApiServiceError.noEndpointsAvailable(
nodeGroupName: NodeGroup.adm.name
).localizedDescription))
dialog.send(.noActiveNodesAlert(
nodeName: NodeGroup.adm.name,
action: { [weak self] in
guard let self = self else { return }
self.presentNodeListVC.send(.adm)
}
))
return
}

Expand Down Expand Up @@ -707,12 +712,15 @@ final class ChatViewModel: NSObject {
}

guard apiServiceCompose.get(.adm)?.hasEnabledNode == true else {
dialog.send(.alert(ApiServiceError.noEndpointsAvailable(
nodeGroupName: NodeGroup.adm.name
).localizedDescription))
dialog.send(.noActiveNodesAlert(
nodeName: NodeGroup.adm.name,
action: { [weak self] in
guard let self = self else { return }
self.presentNodeListVC.send(.adm)
}
))
return false
}

return true
}

Expand Down Expand Up @@ -1061,9 +1069,15 @@ extension ChatViewModel: NSFetchedResultsControllerDelegate {
private extension ChatViewModel {
func sendFiles(with text: String) async throws {
guard apiServiceCompose.get(.ipfs)?.hasEnabledNode == true else {
dialog.send(.alert(ApiServiceError.noEndpointsAvailable(
nodeGroupName: NodeGroup.ipfs.name
).localizedDescription))
dialog.send(
.noActiveNodesAlert(
nodeName: NodeGroup.adm.name,
action: { [weak self] in
guard let self = self else { return }
self.presentNodeListVC.send(.ipfs)
}
)
)
return
}

Expand Down
1 change: 1 addition & 0 deletions Adamant/Modules/Chat/ViewModel/Models/ChatDialog.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,5 @@ enum ChatDialog {
case dismissMenu
case renameAlert
case actionMenu
case noActiveNodesAlert(nodeName: String, action: ChatDialogManager.NoActiveNodesAction)
}
16 changes: 13 additions & 3 deletions Adamant/Modules/ChatsList/ChatListFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ struct ChatListFactory {
dialogService: assembler.resolve(DialogService.self)!,
addressBook: assembler.resolve(AddressBookService.self)!,
avatarService: assembler.resolve(AvatarService.self)!,
walletServiceCompose: assembler.resolve(WalletServiceCompose.self)!
walletServiceCompose: assembler.resolve(WalletServiceCompose.self)!, nodeAvailabilityService: NodeAvailabilityService(
dialogService: assembler.resolve(DialogService.self)!,
apiServiceCompose: assembler.resolve(ApiServiceComposeProtocol.self)!,
screensFactory: screensFactory
)
)
}

Expand All @@ -42,8 +46,14 @@ struct ChatListFactory {
visibleWalletsService: assembler.resolve(VisibleWalletsService.self)!,
addressBookService: assembler.resolve(AddressBookService.self)!,
screensFactory: screensFactory,
walletServiceCompose: assembler.resolve(WalletServiceCompose.self)!,
nodesStorage: assembler.resolve(NodesStorageProtocol.self)!
walletServiceCompose: assembler.resolve(WalletServiceCompose.self)!,
nodesStorage: assembler.resolve(NodesStorageProtocol.self)!,
dialogService: assembler.resolve(DialogService.self)!,
nodeAvailabilityService: NodeAvailabilityService(
dialogService: assembler.resolve(DialogService.self)!,
apiServiceCompose: assembler.resolve(ApiServiceComposeProtocol.self)!,
screensFactory: screensFactory
)
)
}

Expand Down
16 changes: 10 additions & 6 deletions Adamant/Modules/ChatsList/ChatListViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ final class ChatListViewController: KeyboardObservingViewController {
private let addressBook: AddressBookService
private let avatarService: AvatarService
private let walletServiceCompose: WalletServiceCompose
private let nodeAvailabilityService: NodeAvailabilityProtocol

// MARK: IBOutlet
@IBOutlet weak var tableView: UITableView!
Expand Down Expand Up @@ -149,7 +150,8 @@ final class ChatListViewController: KeyboardObservingViewController {
dialogService: DialogService,
addressBook: AddressBookService,
avatarService: AvatarService,
walletServiceCompose: WalletServiceCompose
walletServiceCompose: WalletServiceCompose,
nodeAvailabilityService: NodeAvailabilityProtocol
) {
self.accountService = accountService
self.chatsProvider = chatsProvider
Expand All @@ -160,6 +162,7 @@ final class ChatListViewController: KeyboardObservingViewController {
self.addressBook = addressBook
self.avatarService = avatarService
self.walletServiceCompose = walletServiceCompose
self.nodeAvailabilityService = nodeAvailabilityService

super.init(nibName: "ChatListViewController", bundle: nil)
}
Expand Down Expand Up @@ -467,21 +470,22 @@ final class ChatListViewController: KeyboardObservingViewController {
@objc private func handleRefresh(_ refreshControl: UIRefreshControl) {
Task {
let result = await chatsProvider.update(notifyState: true)
defer { refreshControl.endRefreshing() }

guard let result = result else {
refreshControl.endRefreshing()
return
}

switch result {
case .success:
tableView.reloadData()

case .failure(let error):
dialogService.showRichError(error: error)
case .failure:
guard nodeAvailabilityService.checkNodeAvailability(
in: .adm,
vc: self
) else { return }
}

refreshControl.endRefreshing()
}
}

Expand Down
21 changes: 11 additions & 10 deletions Adamant/Modules/ChatsList/ComplexTransferViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ final class ComplexTransferViewController: UIViewController {
private let screensFactory: ScreensFactory
private let walletServiceCompose: WalletServiceCompose
private let nodesStorage: NodesStorageProtocol
private let dialogService: DialogService
private let nodeAvailabilityService: NodeAvailabilityProtocol

// MARK: - Properties
var pagingViewController: PagingViewController!
Expand All @@ -44,13 +46,17 @@ final class ComplexTransferViewController: UIViewController {
addressBookService: AddressBookService,
screensFactory: ScreensFactory,
walletServiceCompose: WalletServiceCompose,
nodesStorage: NodesStorageProtocol
nodesStorage: NodesStorageProtocol,
dialogService: DialogService,
nodeAvailabilityService: NodeAvailabilityProtocol
) {
self.visibleWalletsService = visibleWalletsService
self.addressBookService = addressBookService
self.screensFactory = screensFactory
self.walletServiceCompose = walletServiceCompose
self.nodesStorage = nodesStorage
self.dialogService = dialogService
self.nodeAvailabilityService = nodeAvailabilityService

super.init(nibName: nil, bundle: nil)
}
Expand Down Expand Up @@ -144,15 +150,10 @@ extension ComplexTransferViewController: PagingViewControllerDataSource {
vc.showProgressView(animated: false)

Task {
guard service.core.hasEnabledNode else {
vc.showAlertView(
message: ApiServiceError.noEndpointsAvailable(
nodeGroupName: service.core.tokenName
).errorDescription ?? .adamant.sharedErrors.unknownError,
animated: true
)
return
}
guard nodeAvailabilityService.checkNodeAvailability(
in: .adm,
vc: self
) else { return }

guard admService?.core.hasEnabledNode ?? false else {
vc.showAlertView(
Expand Down
7 changes: 6 additions & 1 deletion Adamant/Modules/Login/LoginFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@ struct LoginFactory {
dialogService: assembler.resolve(DialogService.self)!,
localAuth: assembler.resolve(LocalAuthentication.self)!,
screensFactory: screenFactory,
apiService: assembler.resolve(AdamantApiServiceProtocol.self)!
apiService: assembler.resolve(AdamantApiServiceProtocol.self)!,
nodeAvailabilityService: NodeAvailabilityService(
dialogService: assembler.resolve(DialogService.self)!,
apiServiceCompose: assembler.resolve(ApiServiceComposeProtocol.self)!,
screensFactory: screenFactory
)
)
}
}
25 changes: 14 additions & 11 deletions Adamant/Modules/Login/LoginViewController+Pinpad.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,16 +67,8 @@ extension LoginViewController {
dialogService.showProgress(withMessage: String.adamant.login.loggingInProgressMessage, userInteractionEnable: false)

Task {
do {
let result = try await accountService.loginWithStoredAccount()
handleSavedAccountLoginResult(result)
} catch {
dialogService.showRichError(error: error)

if let pinpad = presentedViewController as? PinpadViewController {
pinpad.clearPin()
}
}
let result = await accountService.loginWithStoredAccount()
handleSavedAccountLoginResult(result)
}
}

Expand Down Expand Up @@ -104,13 +96,24 @@ extension LoginViewController {
}

case .failure(let error):
dialogService.showRichError(error: error)
handleError(error)

if let pinpad = presentedViewController as? PinpadViewController {
pinpad.clearPin()
}
}
}

func handleError(_ error: AccountServiceError) {
guard case .apiError(let error) = error else {
dialogService.showRichError(error: error)
return
}

dismiss(animated: true) { [weak self] in
self?.handleError(error)
}
}
}

// MARK: - PinpadViewControllerDelegate
Expand Down
Loading