Files
raspberry/iOS/Wallet/Sources/Account/Service/AccountServiceUpdate.swift
2022-12-21 16:48:44 +03:00

94 lines
2.9 KiB
Swift

//
// AccountServiceUpdate.swift
// Malinka
//
// Created by NUT.Tech on 29.09.2022.
// Copyright © 2022 NUT.Tech. All rights reserved.
//
import Foundation
import Combine
import WalletFoundation
import WalletKit
import WalletNetwork
extension Account.Service {
final class Update {
// MARK: - Constants
private enum Constants {
static let timerInterval = 3
static let maximumRefreshCount = 5
}
static let shared = Update()
// MARK: - Properties
var selected: WalletKit.Wallet? { Accounts().current }
var accounts: [WalletKit.Wallet] { Account.Service.shared.collection }
private let updateSubject = CurrentValueSubject<Void, Never>(())
var updatePublisher: AnyPublisher<Void, Never> { self.updateSubject.eraseToAnyPublisher() }
private let accountService: AccountService?
private var timerPublisher: DispatchTimer?
private var refreshSubscription: AnyCancellable?
// MARK: - Init
private init() {
let record = ApplicationEnvironment.shared().current
if let environment = try? record.networkEnvironment() {
self.accountService = AccountService(environment: environment)
} else {
self.accountService = nil
}
}
// MARK: - Methods
func updateAccountsStates(times: Int? = nil) {
guard !self.refreshSubscription.isExist else { return }
let publisher = Publishers.timer(queue: DispatchQueue.global(qos: .background),
interval: .seconds(Constants.timerInterval),
times: .max(times ?? Constants.maximumRefreshCount))
self.timerPublisher = publisher
self.refreshSubscription = publisher.sink(receiveCompletion: { [weak self] _ in
self?.timerPublisher = nil
self?.refreshSubscription = nil
}, receiveValue: { [weak self] _ in
self?.refresh()
})
}
// MARK: - Private
private func refresh() {
Task {
let wallets = Account.Service.shared.collection
guard wallets.first(where: { $0.state != .accepted && $0.state != .declined }).isExist else {
self.refreshSubscription?.cancel()
self.refreshSubscription = nil
self.timerPublisher = nil
self.updateSubject.send()
return
}
let bank = Account.Service.shared.bank
try? await bank.refreshStatus(wallet: nil)
self.updateSubject.send()
}
}
}
}