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
8 changes: 4 additions & 4 deletions Nextcloud.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -5826,7 +5826,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 5;
CURRENT_PROJECT_VERSION = 0;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = NKUJUXUJ3B;
Expand All @@ -5853,7 +5853,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 33.0.7;
MARKETING_VERSION = 33.0.8;
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = "-v";
OTHER_LDFLAGS = "";
Expand Down Expand Up @@ -5893,7 +5893,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 5;
CURRENT_PROJECT_VERSION = 0;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = NKUJUXUJ3B;
Expand All @@ -5918,7 +5918,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 33.0.7;
MARKETING_VERSION = 33.0.8;
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = "-v";
OTHER_LDFLAGS = "";
Expand Down
7 changes: 5 additions & 2 deletions iOSClient/GUI/Lucid Banner/ErrorBannerView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@ func showErrorBanner(windowScene: UIWindowScene?,
}

#if !EXTENSION
guard !bannerContainsError(errorCode: errorCode, afError: afError) else {
return
if let errorCode,
let controller = SceneManager.shared.getController(scene: windowScene) {
if await !ErrorBannerGate.shared.shouldShow(errorCode: errorCode, account: controller.account) {
Comment on lines +32 to +34
return
}
}
#endif
Comment on lines 31 to 38
Comment on lines +32 to 38

Expand Down
86 changes: 56 additions & 30 deletions iOSClient/GUI/Lucid Banner/HelperBanner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -124,41 +124,67 @@ func horizontalLayoutBanner(bounds: CGRect,
}
}

#if !EXTENSION
/// Prevents the same error banner from being shown repeatedly in a short time.
/// Uses a per-error (and optional account) cooldown to avoid UI spam.
/// Call `shouldShow(...)` before presenting a banner.
actor ErrorBannerGate {
static let shared = ErrorBannerGate()

// Error 401 (maintenance mode)
// Error 423 (locked)
// Error 507 (insufficient storage)
// Error -1009 (NSURLErrorNotConnectedToInternet)
// Error -1003 (NSURLError​Cannot​Find​Host)
private var lastShownByKey: [String: Date] = [:]
private let maxEntryAge: TimeInterval = 120

func bannerContainsError(errorCode: Int?, afError: AFError? = nil) -> Bool {
guard let errorCode else {
return false
}
// List of errors not to be displayed
if errorCode == -999 || errorCode == 423 {
private init() {}

func shouldShow(errorCode: Int, account: String? = nil) -> Bool {
cleanupOldEntries()

let key = makeKey(errorCode: errorCode, account: account)
let now = Date()
let cooldown = cooldownInterval(for: errorCode)

if let lastShown = lastShownByKey[key],
now.timeIntervalSince(lastShown) < cooldown {
return false
}

lastShownByKey[key] = now
return true
}
if let afError, case .explicitlyCancelled = afError {
return true

// MARK: - Private

private func makeKey(errorCode: Int, account: String?) -> String {
"\(errorCode)|\(account ?? "-")"
}
// Prevent repeated display of the same user-facing error during the current foreground session.
// If this error code has already been shown, do nothing.
// Otherwise, record it and allow the UX notification to be displayed once.
if shownErrors.contains(errorCode) {
return true
} else {
// Coalesce user-facing errors across the current foreground session.
// The same error code is shown to the user only once.
if errorCode == 401 ||
errorCode == 423 ||
errorCode == 507 ||
errorCode == NSURLErrorNotConnectedToInternet ||
errorCode == NSURLErrorCannotFindHost {
shownErrors.insert(errorCode)

private func cooldownInterval(for errorCode: Int) -> TimeInterval {
switch errorCode {

case NSURLErrorNotConnectedToInternet:
return 30 // No internet connection (persistent until network changes)

case NSURLErrorCannotFindHost:
return 30 // Host/DNS not reachable (likely server down or misconfigured URL)

case 401:
return 30 // Unauthorized (server maintenance)

case 423:
return 20 // Resource locked (temporary server-side condition)

case 507:
return 30 // Insufficient storage (server quota exceeded, persistent)

default:
return 5 // Transient or unknown error
}
Comment on lines +160 to +180
}

private func cleanupOldEntries() {
let now = Date()

lastShownByKey = lastShownByKey.filter { _, lastShown in
now.timeIntervalSince(lastShown) < maxEntryAge
}
return false
}
}
#endif
7 changes: 5 additions & 2 deletions iOSClient/GUI/Lucid Banner/InfoBannerView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ func showInfoBanner(windowScene: UIWindowScene?,
}

#if !EXTENSION
guard !bannerContainsError(errorCode: errorCode) else {
return
if let errorCode,
let controller = SceneManager.shared.getController(scene: windowScene) {
if await !ErrorBannerGate.shared.shouldShow(errorCode: errorCode, account: controller.account) {
Comment on lines +22 to +24
return
}
}
#endif
Comment on lines +22 to 28

Expand Down
7 changes: 5 additions & 2 deletions iOSClient/GUI/Lucid Banner/ShowBanner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ func showBanner(windowScene: UIWindowScene?,
}

#if !EXTENSION
guard !bannerContainsError(errorCode: errorCode) else {
return (nil, nil)
if let errorCode,
let controller = SceneManager.shared.getController(scene: windowScene) {
if await !ErrorBannerGate.shared.shouldShow(errorCode: errorCode, account: controller.account) {
Comment on lines +35 to +37
return(nil, nil)
}
}
#endif
Comment on lines +35 to 41

Expand Down
7 changes: 5 additions & 2 deletions iOSClient/GUI/Lucid Banner/WarningBannerView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ func showWarningBanner(windowScene: UIWindowScene?,
}

#if !EXTENSION
guard !bannerContainsError(errorCode: errorCode) else {
return
if let errorCode,
let controller = SceneManager.shared.getController(scene: windowScene) {
if await !ErrorBannerGate.shared.shouldShow(errorCode: errorCode, account: controller.account) {
Comment on lines +24 to +26
return
}
}
#endif
Comment on lines +24 to 30

Expand Down
8 changes: 0 additions & 8 deletions iOSClient/NCAppStateManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ var isAppInBackground: Bool = true
// Global flag indicating whether the app is in maintenanceMode.
var maintenanceMode: Bool = false

// Global error code
var shownErrors: Set<Int> = []

/// Singleton responsible for monitoring and managing app state transitions.
///
/// This class observes system notifications related to app lifecycle events and updates global flags accordingly:
Expand Down Expand Up @@ -53,11 +50,6 @@ final class NCAppStateManager {
appDelegate?.pushSubscriptionTask?.cancel()
appDelegate?.pushSubscriptionTask = nil

//
// Clear the errors
//
shownErrors.removeAll()

nkLog(debug: "Application did enter in background")
}
}
Expand Down
3 changes: 0 additions & 3 deletions iOSClient/Networking/NCNetworkingProcess.swift
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@

await runMetadataPipelineAsync(metadatas: metadatas)

// TODO: Check temperature

Check warning on line 270 in iOSClient/Networking/NCNetworkingProcess.swift

View workflow job for this annotation

GitHub Actions / Lint

Todo Violation: TODOs should be resolved (Check temperature) (todo)

Check warning on line 270 in iOSClient/Networking/NCNetworkingProcess.swift

View workflow job for this annotation

GitHub Actions / Lint

Todo Violation: TODOs should be resolved (Check temperature) (todo)

if networking.isOffline {
await startTimer(interval: offlineInterval)
Expand All @@ -281,9 +281,6 @@
// Set Live Photo
await NCNetworking.shared.setLivePhoto(account: currentAccount)

// Clear the errors
shownErrors.removeAll()

if lastUsedInterval != maxInterval {
await startTimer(interval: maxInterval)
}
Expand Down
Loading