Skip to content
Merged
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
3 changes: 2 additions & 1 deletion iOSClient/GUI/Lucid Banner/UploadBannerView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,17 @@ struct UploadBannerView: View {
if state.isMinimized {
HStack(spacing: 5) {
Image(systemName: state.systemImage ?? "arrow.up.circle")
.applyBannerAnimation(state.imageAnimation)
.font(.body.weight(.medium))
.frame(width: 20, height: 20)
.foregroundStyle(Color(uiColor: NCBrandColor.shared.customer))

if let p = state.progress {
Text("\(Int(p * 100))%")
.font(.caption2.monospacedDigit())
.frame(height: 20)
.foregroundStyle(textColor)
}

}
.padding(.horizontal, 10)
.padding(.vertical, 10)
Expand Down
1 change: 0 additions & 1 deletion iOSClient/NCGlobal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,6 @@ final class NCGlobal: Sendable {
let notificationCenterOpenMediaDetail = "openMediaDetail" // userInfo: ocId

let notificationCenterDismissScanDocument = "dismissScanDocument"
let notificationCenterDismissUploadAssets = "dismissUploadAssets"

let notificationCenterEnableSwipeGesture = "enableSwipeGesture"
let notificationCenterDisableSwipeGesture = "disableSwipeGesture"
Expand Down
56 changes: 46 additions & 10 deletions iOSClient/Utility/NCDebouncer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,30 @@ import Foundation
public actor NCDebouncer {
private let delay: Duration
private let maxEventCount: Int
private var eventCount = 0
private var eventCount: Int = 0
private var pendingTask: Task<Void, Never>?
private var latestBlock: (@MainActor @Sendable () async -> Void)?
private var isPaused: Bool = false

// MARK: - Init

public init(delay: Duration = .seconds(2), maxEventCount: Int) {
self.delay = delay
self.maxEventCount = maxEventCount
}

// MARK: - Public API

public func call(_ block: @MainActor @Sendable @escaping () async -> Void, immediate: Bool = false) {
latestBlock = block

guard !isPaused else {
// We only store the latest block and count events,
// but we never schedule or commit while paused.
eventCount += 1
return
}

if immediate {
commit()
return
Expand All @@ -32,32 +44,56 @@ public actor NCDebouncer {
}
}

public func pause() {
guard !isPaused else { return }

isPaused = true
pendingTask?.cancel()
pendingTask = nil
}

public func resume() {
guard isPaused else { return }

isPaused = false

// If something accumulated while paused, commit immediately.
if latestBlock != nil {
commit()
}
}

public func cancel() {
pendingTask?.cancel()
pendingTask = nil
latestBlock = nil
eventCount = 0
}

// MARK: - Internal

private func scheduleIfNeeded() {
guard pendingTask == nil else { return }
guard pendingTask == nil, !isPaused else { return }

pendingTask = Task { [weak self] in
guard let delay = self?.delay else { return }
try? await Task.sleep(for: delay)
await self?.commit()
guard let self else { return }
try? await Task.sleep(for: self.delay)
await self.commit()
}
}

private func commit() {
guard !isPaused else { return }

pendingTask?.cancel()
pendingTask = nil
eventCount = 0

if let block = latestBlock {
latestBlock = nil
Task { @MainActor in
await block()
}
guard let block = latestBlock else { return }
latestBlock = nil

Task { @MainActor in
await block()
}
}
}
Loading