Skip to content

Commit ee0d5b8

Browse files
Lucid Banner Views (#3898)
* test Signed-off-by: Marino Faggiana <[email protected]> * remove code Signed-off-by: Marino Faggiana <[email protected]> * mainAppWindow Signed-off-by: Marino Faggiana <[email protected]> * fix Signed-off-by: Marino Faggiana <[email protected]> * cod Signed-off-by: Marino Faggiana <[email protected]> * fix Signed-off-by: Marino Faggiana <[email protected]> * cod Signed-off-by: Marino Faggiana <[email protected]> * cod Signed-off-by: Marino Faggiana <[email protected]> * cod Signed-off-by: Marino Faggiana <[email protected]> * code Signed-off-by: Marino Faggiana <[email protected]> * Code refactoring Signed-off-by: Marino Faggiana <[email protected]> * clean Signed-off-by: Marino Faggiana <[email protected]> * cleaning Signed-off-by: Marino Faggiana <[email protected]> --------- Signed-off-by: Marino Faggiana <[email protected]>
1 parent 9120e37 commit ee0d5b8

40 files changed

+876
-929
lines changed

Nextcloud.xcodeproj/project.pbxproj

Lines changed: 18 additions & 18 deletions
Large diffs are not rendered by default.

iOSClient/Account/NCAccount.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,10 @@ class NCAccount: NSObject {
7474
controller.modalPresentationStyle = .fullScreen
7575
controller.view.alpha = 0
7676

77-
UIApplication.shared.firstWindow?.rootViewController = controller
78-
UIApplication.shared.firstWindow?.makeKeyAndVisible()
77+
UIApplication.shared.mainAppWindow?.rootViewController = controller
78+
UIApplication.shared.mainAppWindow?.makeKeyAndVisible()
7979

80-
if let scene = UIApplication.shared.firstWindow?.windowScene {
80+
if let scene = UIApplication.shared.mainAppWindow?.windowScene {
8181
SceneManager.shared.register(scene: scene, withRootViewController: controller)
8282
}
8383

iOSClient/Activity/NCActivityTableViewCell.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ extension NCActivityTableViewCell: UICollectionViewDelegate {
9797
return
9898
}
9999
Task {
100-
await NCDownloadAction.shared.viewerFile(account: account, fileId: activitySubjectRich.id, viewController: viewController)
100+
await NCNetworking.shared.viewerFile(account: account, fileId: activitySubjectRich.id, viewController: viewController)
101101
}
102102
}
103103
}

iOSClient/AppDelegate.swift

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
6060

6161
NCBrandColor.shared.createUserColors()
6262

63+
// Setup Networking
64+
//
6365
NextcloudKit.shared.setup(groupIdentifier: NCBrandOptions.shared.capabilitiesGroup,
6466
delegate: NCNetworking.shared)
67+
NCNetworking.shared.setupTransferDelegate()
6568

6669
NextcloudKit.configureLogger(logLevel: (NCBrandOptions.shared.disable_log ? .disabled : NCPreferences().log))
6770

@@ -421,7 +424,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
421424
if let controller = SceneManager.shared.getControllers().first(where: { $0.account == account }) {
422425
openNotification(controller: controller)
423426
} else if let tblAccount = NCManageDatabase.shared.getAllTableAccount().first(where: { $0.account == account }),
424-
let controller = UIApplication.shared.firstWindow?.rootViewController as? NCMainTabBarController {
427+
let controller = UIApplication.shared.mainAppWindow?.rootViewController as? NCMainTabBarController {
425428
Task { @MainActor in
426429
await NCAccount().changeAccount(tblAccount.account, userProfile: nil, controller: controller)
427430
openNotification(controller: controller)
@@ -430,7 +433,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
430433
let message = NSLocalizedString("_the_account_", comment: "") + " " + account + " " + NSLocalizedString("_does_not_exist_", comment: "")
431434
let alertController = UIAlertController(title: NSLocalizedString("_info_", comment: ""), message: message, preferredStyle: .alert)
432435
alertController.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default, handler: { _ in }))
433-
UIApplication.shared.firstWindow?.rootViewController?.present(alertController, animated: true, completion: { })
436+
UIApplication.shared.mainAppWindow?.rootViewController?.present(alertController, animated: true, completion: { })
434437
}
435438
}
436439

@@ -463,11 +466,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
463466
let viewController = navigationController.topViewController as? NCViewCertificateDetails {
464467
viewController.delegate = self
465468
viewController.host = host
466-
UIApplication.shared.firstWindow?.rootViewController?.present(navigationController, animated: true)
469+
UIApplication.shared.mainAppWindow?.rootViewController?.present(navigationController, animated: true)
467470
}
468471
}))
469472

470-
UIApplication.shared.firstWindow?.rootViewController?.present(alertController, animated: true)
473+
UIApplication.shared.mainAppWindow?.rootViewController?.present(alertController, animated: true)
471474
}
472475

473476
// MARK: - Reset Application

iOSClient/Extensions/UIApplication+Extension.swift

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,45 @@ import Foundation
1010
import UIKit
1111

1212
extension UIApplication {
13-
var firstWindow: UIWindow? {
14-
let windowScenes = UIApplication.shared.connectedScenes.compactMap { $0 as? UIWindowScene }
15-
let firstActiveScene = windowScenes.first
16-
let keyWindow = firstActiveScene?.keyWindow
17-
return keyWindow
13+
/// Returns the main application window, excluding overlay windows
14+
/// like LucidBanner, keyboard or debug windows.
15+
var mainAppWindow: UIWindow? {
16+
let activeScenes = connectedScenes
17+
.compactMap { $0 as? UIWindowScene }
18+
.filter { $0.activationState == .foregroundActive }
19+
let allWindows = activeScenes.flatMap { $0.windows }
20+
21+
return allWindows.first { window in
22+
guard window.isHidden == false else { return false }
23+
24+
// Filter by normal level to ignore overlays with higher levels
25+
guard window.windowLevel == .normal else { return false }
26+
27+
// Optionally exclude LucidBanner windows by rootViewController type name
28+
if let root = window.rootViewController {
29+
let typeName = String(describing: type(of: root))
30+
if typeName.contains("LucidBanner") {
31+
return false
32+
}
33+
}
34+
35+
return true
36+
}
1837
}
38+
1939
func allSceneSessionDestructionExceptFirst() {
20-
let windowScenes = UIApplication.shared.connectedScenes.compactMap { $0 as? UIWindowScene }
21-
let firstActiveScene = windowScenes.first
40+
let windowScenes = connectedScenes.compactMap { $0 as? UIWindowScene }
41+
42+
// Keep the first foregroundActive scene if possible,
43+
// otherwise fall back to the very first one.
44+
let primaryScene = windowScenes
45+
.first { $0.activationState == .foregroundActive } ?? windowScenes.first
46+
2247
let options = UIWindowSceneDestructionRequestOptions()
2348
options.windowDismissalAnimation = .standard
49+
2450
for windowScene in windowScenes {
25-
if windowScene == firstActiveScene { continue }
51+
if windowScene == primaryScene { continue }
2652
requestSceneSessionDestruction(windowScene.session, options: options, errorHandler: nil)
2753
}
2854
}

iOSClient/Files/NCFiles.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ class NCFiles: NCCollectionViewCommon {
401401
navigationController = UIStoryboard(name: "NCIntro", bundle: nil).instantiateInitialViewController() as? UINavigationController
402402
}
403403

404-
UIApplication.shared.firstWindow?.rootViewController = navigationController
404+
UIApplication.shared.mainAppWindow?.rootViewController = navigationController
405405
} else if let account = tblAccount?.account, account != currentAccount {
406406
Task {
407407
await NCAccount().changeAccount(account, userProfile: nil, controller: controller)

iOSClient/GUI/Lucid Banner/ErrorBannerView.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,20 @@ struct ErrorBannerView: View {
2323
Text("_error_")
2424
.font(.subheadline.weight(.bold))
2525
.multilineTextAlignment(.leading)
26-
.lineLimit(1)
2726
.truncationMode(.tail)
2827
.foregroundStyle(.white)
2928

3029
if showSubtitle, let subtitle = state.subtitle {
3130
Text(subtitle)
3231
.font(.subheadline)
3332
.multilineTextAlignment(.leading)
34-
.lineLimit(4)
3533
.truncationMode(.tail)
3634
.foregroundStyle(.white)
3735
}
3836
if showFootnote, let footnote = state.footnote {
3937
Text(footnote)
4038
.font(.caption)
4139
.multilineTextAlignment(.leading)
42-
.lineLimit(1)
4340
.truncationMode(.tail)
4441
.foregroundStyle(.white)
4542
}

iOSClient/GUI/Lucid Banner/HudBannerView.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ struct HudBannerView: View {
2323
.font(.headline.weight(.semibold))
2424
.foregroundStyle(.primary)
2525
.multilineTextAlignment(.center)
26-
.lineLimit(2)
2726
}
2827

2928
// SUBTITLE
@@ -32,7 +31,6 @@ struct HudBannerView: View {
3231
.font(.subheadline)
3332
.foregroundStyle(.primary.opacity(0.95))
3433
.multilineTextAlignment(.center)
35-
.lineLimit(3)
3634
}
3735

3836
// PROGRESS CIRCLE
@@ -97,7 +95,6 @@ func showHudBanner(
9795
scene: scene,
9896
title: title,
9997
subtitle: subtitle,
100-
maxWidth: 300,
10198
vPosition: .center,
10299
swipeToDismiss: false,
103100
blocksTouches: true,

iOSClient/GUI/Lucid Banner/ToastBannerView.swift renamed to iOSClient/GUI/Lucid Banner/UploadBannerView.swift

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,13 @@
55
import SwiftUI
66
import LucidBanner
77

8-
struct ToastBannerView: View {
8+
struct UploadBannerView: View {
99
@ObservedObject var state: LucidBannerState
1010

1111
var body: some View {
1212
let showTitle = !(state.title?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ?? true)
1313
let showSubtitle = !(state.subtitle?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ?? true)
1414
let showFootnote = !(state.footnote?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ?? true)
15-
let showProgress = (state.progress ?? 0) > 0
16-
let measuring = (state.flags["measuring"] as? Bool) ?? false
1715

1816
containerView {
1917
VStack(spacing: 15) {
@@ -30,7 +28,6 @@ struct ToastBannerView: View {
3028
Text(title)
3129
.font(.subheadline.weight(.bold))
3230
.multilineTextAlignment(.leading)
33-
.lineLimit(2)
3431
.truncationMode(.tail)
3532
.minimumScaleFactor(0.9)
3633
.foregroundStyle(.primary)
@@ -39,28 +36,24 @@ struct ToastBannerView: View {
3936
Text(subtitle)
4037
.font(.subheadline)
4138
.multilineTextAlignment(.leading)
42-
.lineLimit(4)
4339
.truncationMode(.tail)
4440
.foregroundStyle(.primary)
4541
}
4642
if showFootnote, let footnote = state.footnote {
4743
Text(footnote)
4844
.font(.caption)
4945
.multilineTextAlignment(.leading)
50-
.lineLimit(2)
5146
.truncationMode(.tail)
5247
.foregroundStyle(.primary)
5348
}
5449
}
5550
}
5651

57-
if showProgress && !measuring {
58-
ProgressView(value: min(state.progress ?? 0, 1))
59-
.progressViewStyle(.linear)
60-
.tint(Color(uiColor: NCBrandColor.shared.customer))
61-
.scaleEffect(x: 1, y: 0.8, anchor: .center)
62-
.transition(.opacity.combined(with: .move(edge: .top)))
63-
}
52+
ProgressView(value: state.progress ?? 0)
53+
.tint(.accentColor)
54+
.opacity(state.progress == nil ? 0 : 1)
55+
.animation(.easeInOut(duration: 0.2), value: state.progress == nil)
56+
6457
}
6558
.padding(.horizontal, 12)
6659
.padding(.vertical, 12)
@@ -120,7 +113,7 @@ public extension View {
120113
// MARK: - Helper
121114

122115
@MainActor
123-
func showToastBanner(
116+
func showUploadBanner(
124117
scene: UIWindowScene?,
125118
title: String? = nil,
126119
subtitle: String? = nil,
@@ -136,15 +129,15 @@ func showToastBanner(
136129
footnote: footnote,
137130
systemImage: systemImage,
138131
imageAnimation: imageAnimation,
139-
maxWidth: 0,
140132
vPosition: .bottom,
141133
hAlignment: .center,
142134
verticalMargin: 55,
135+
swipeToDismiss: false,
143136
onTap: { token, stage in
144137
onTap?(token, stage)
145138
}
146139
) { state in
147-
ToastBannerView(state: state)
140+
UploadBannerView(state: state)
148141
}
149142
}
150143

@@ -158,7 +151,7 @@ func showToastBanner(
158151
endPoint: .bottom
159152
)
160153

161-
ToastBannerView(
154+
UploadBannerView(
162155
state: LucidBannerState(
163156
title: "Downloading …",
164157
subtitle: "Keep application active until the transfers are completed …",

iOSClient/Login/NCLogin.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate {
412412

413413
private func createAccount(urlBase: String, user: String, password: String) {
414414
if self.controller == nil {
415-
self.controller = UIApplication.shared.firstWindow?.rootViewController as? NCMainTabBarController
415+
self.controller = UIApplication.shared.mainAppWindow?.rootViewController as? NCMainTabBarController
416416
}
417417

418418
if let host = URL(string: urlBase)?.host {

0 commit comments

Comments
 (0)