Skip to content

Commit

Permalink
feature: Show cloud saving state on sensor settings #1600
Browse files Browse the repository at this point in the history
  • Loading branch information
priyonto committed Dec 12, 2023
1 parent 0a51f49 commit 4625f1d
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ public extension ActivityPresenterRuuviLogo {
}

func update(with state: ActivityPresenterState) {
// Reset start time with state update since we want to show
// latest state message before dismissing the presenter.
startTime = CFAbsoluteTimeGetCurrent()
activityPresenterViewProvider.updateState(state)
}

Expand Down
18 changes: 18 additions & 0 deletions Packages/RuuviCloud/Sources/RuuviCloud/RuuviCloud.swift
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,21 @@ public enum MimeType: String, Codable {
case gif = "image/gif"
case jpg = "image/jpeg"
}

// MARK: State Observer
public extension Notification.Name {
static let RuuviCloudRequestStateDidChange =
Notification.Name("RuuviCloudRequestStateDidChange")
}

public enum RuuviCloudCallStateKey: String {
case state
case macId
}

public enum RuuviCloudCallStateType: String {
case loading
case success
case failed
case complete
}
30 changes: 28 additions & 2 deletions Packages/RuuviCloud/Sources/RuuviCloudPure/RuuviCloudPure.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,12 @@ public final class RuuviCloudPure: RuuviCloud {
description: String?,
for macId: MACIdentifier
) -> Future<Void, RuuviCloudError> {
notifyListener(state: .loading, macId: macId.mac)
let promise = Promise<Void, RuuviCloudError>()
guard let apiKey = user.apiKey
else {
promise.fail(error: .notAuthorized)
notifyListener(state: .failed, macId: macId.mac)
return promise.future
}
let request = RuuviCloudApiPostAlertRequest(
Expand All @@ -71,8 +73,9 @@ public final class RuuviCloudPure: RuuviCloud {
timestamp: Int(Date().timeIntervalSince1970)
)
api.postAlert(request, authorization: apiKey)
.on(success: { _ in
.on(success: { [weak self] _ in
promise.succeed(value: ())
self?.notifyListener(state: .success, macId: macId.mac)
}, failure: { [weak self] error in
let uniqueKey = macId.value + "-" + type.rawValue + "-" + settingType.rawValue
self?.createQueuedRequest(
Expand All @@ -82,6 +85,9 @@ public final class RuuviCloudPure: RuuviCloud {
)

promise.fail(error: .api(error))
self?.notifyListener(state: .failed, macId: macId.mac)
}, completion: { [weak self] in
self?.notifyListener(state: .complete, macId: macId.mac)
})
return promise.future
}
Expand Down Expand Up @@ -676,10 +682,12 @@ public final class RuuviCloudPure: RuuviCloud {
name: String,
for sensor: RuuviTagSensor
) -> Future<AnyRuuviTagSensor, RuuviCloudError> {
notifyListener(state: .loading, macId: sensor.id)
let promise = Promise<AnyRuuviTagSensor, RuuviCloudError>()
guard let apiKey = user.apiKey
else {
promise.fail(error: .notAuthorized)
notifyListener(state: .failed, macId: sensor.id)
return promise.future
}
let request = RuuviCloudApiSensorUpdateRequest(
Expand All @@ -691,8 +699,9 @@ public final class RuuviCloudPure: RuuviCloud {
timestamp: Int(Date().timeIntervalSince1970)
)
api.update(request, authorization: apiKey)
.on(success: { _ in
.on(success: { [weak self] _ in
promise.succeed(value: sensor.with(name: name).any)
self?.notifyListener(state: .success, macId: sensor.id)
}, failure: { [weak self] error in
let uniqueKey = sensor.id + "-name"
self?.createQueuedRequest(
Expand All @@ -701,6 +710,9 @@ public final class RuuviCloudPure: RuuviCloud {
uniqueKey: uniqueKey
)
promise.fail(error: .api(error))
self?.notifyListener(state: .failed, macId: sensor.id)
}, completion: { [weak self] in
self?.notifyListener(state: .complete, macId: sensor.id)
})
return promise.future
}
Expand Down Expand Up @@ -1362,6 +1374,20 @@ public final class RuuviCloudPure: RuuviCloud {
)
pool?.createQueuedRequest(request)
}

private func notifyListener(
state: RuuviCloudCallStateType,
macId: String
) {
NotificationCenter.default.post(
name: .RuuviCloudRequestStateDidChange,
object: nil,
userInfo: [
RuuviCloudCallStateKey.macId: macId,
RuuviCloudCallStateKey.state: state,
]
)
}
}

// swiftlint:enable file_length
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import RuuviNotifier
import RuuviPool
import RuuviPresenters
import RuuviUser
import RuuviCloud

class TagSettingsPresenter: NSObject, TagSettingsModuleInput {
weak var view: TagSettingsViewInput!
Expand Down Expand Up @@ -78,6 +79,7 @@ class TagSettingsPresenter: NSObject, TagSettingsModuleInput {
private var appDidBecomeActiveToken: NSObjectProtocol?
private var alertDidChangeToken: NSObjectProtocol?
private var backgroundToken: NSObjectProtocol?
private var cloudRequestStateToken: NSObjectProtocol?
private var mutedTillTimer: Timer?
private var exportFileUrl: URL?
private var previousAdvertisementSequence: Int?
Expand Down Expand Up @@ -109,6 +111,7 @@ class TagSettingsPresenter: NSObject, TagSettingsModuleInput {
appDidBecomeActiveToken?.invalidate()
alertDidChangeToken?.invalidate()
backgroundToken?.invalidate()
cloudRequestStateToken?.invalidate()
timer?.invalidate()
NotificationCenter.default.removeObserver(self)
}
Expand Down Expand Up @@ -143,6 +146,7 @@ class TagSettingsPresenter: NSObject, TagSettingsModuleInput {
startObservingConnectionStatus()
startObservingApplicationState()
startObservingAlertChanges()
startObservingCloudRequestState()
startMutedTillTimer()
startListeningToRuuviTagsAlertStatus()
processAlerts()
Expand Down Expand Up @@ -1139,6 +1143,30 @@ extension TagSettingsPresenter {
)
}

private func startObservingCloudRequestState() {
cloudRequestStateToken?.invalidate()
cloudRequestStateToken = nil

cloudRequestStateToken = NotificationCenter
.default
.addObserver(
forName: .RuuviCloudRequestStateDidChange,
object: nil,
queue: .main,
using: { [weak self] notification in
guard let sSelf = self,
let userInfo = notification.userInfo,
let macId = userInfo[RuuviCloudCallStateKey.macId] as? String,
macId == sSelf.ruuviTag.macId?.value,
let state = userInfo[RuuviCloudCallStateKey.state] as? RuuviCloudCallStateType
else {
return
}
sSelf.presentActivityIndicator(with: state)
}
)
}

private func reloadMutedTill() {
if let mutedTill = viewModel.temperatureAlertMutedTill.value,
mutedTill < Date() {
Expand Down Expand Up @@ -1768,6 +1796,31 @@ extension TagSettingsPresenter {
localSyncState.setGattSyncDate(nil, for: ruuviTag.macId)
settings.setOwnerCheckDate(for: ruuviTag.macId, value: nil)
}

private func presentActivityIndicator(with state: RuuviCloudCallStateType) {
switch state {
case .loading:
activityPresenter.show(
with: .loading(
message: RuuviLocalization.activitySavingToCloud
)
)
case .success:
activityPresenter.update(
with: .success(
message: RuuviLocalization.activitySavingSuccess
)
)
case .failed:
activityPresenter.update(
with: .success(
message: RuuviLocalization.activitySavingFail
)
)
case .complete:
activityPresenter.dismiss()
}
}
}

extension TagSettingsPresenter {
Expand Down

0 comments on commit 4625f1d

Please sign in to comment.