Skip to content

Commit 0a15335

Browse files
GUI banner (#3901)
1 parent ae34d1a commit 0a15335

File tree

11 files changed

+111
-118
lines changed

11 files changed

+111
-118
lines changed

Nextcloud.xcodeproj/project.pbxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5754,7 +5754,7 @@
57545754
CLANG_WARN_UNREACHABLE_CODE = YES;
57555755
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
57565756
COPY_PHASE_STRIP = NO;
5757-
CURRENT_PROJECT_VERSION = 0;
5757+
CURRENT_PROJECT_VERSION = 1;
57585758
DEBUG_INFORMATION_FORMAT = dwarf;
57595759
DEVELOPMENT_TEAM = NKUJUXUJ3B;
57605760
ENABLE_STRICT_OBJC_MSGSEND = YES;
@@ -5820,7 +5820,7 @@
58205820
CLANG_WARN_UNREACHABLE_CODE = YES;
58215821
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
58225822
COPY_PHASE_STRIP = NO;
5823-
CURRENT_PROJECT_VERSION = 0;
5823+
CURRENT_PROJECT_VERSION = 1;
58245824
DEVELOPMENT_TEAM = NKUJUXUJ3B;
58255825
ENABLE_STRICT_OBJC_MSGSEND = YES;
58265826
ENABLE_TESTABILITY = YES;

Share/NCShareExtension.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -446,12 +446,11 @@ extension NCShareExtension {
446446
userId: metadata.userId,
447447
urlBase: metadata.urlBase)
448448

449-
let results = await NCNetworking.shared.uploadFile(fileNameLocalPath: fileNameLocalPath,
449+
let results = await NCNetworking.shared.uploadFile(account: metadata.account,
450+
fileNameLocalPath: fileNameLocalPath,
450451
serverUrlFileName: metadata.serverUrlFileName,
451452
creationDate: metadata.creationDate as Date,
452-
dateModificationFile: metadata.date as Date,
453-
account: metadata.account,
454-
metadata: metadata) { _ in
453+
dateModificationFile: metadata.date as Date) { _ in
455454
} progressHandler: { _, _, fractionCompleted in
456455
self.hud.progress(fractionCompleted)
457456
}

iOSClient/Data/NCManageDatabase+LivePhoto.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ extension NCManageDatabase {
102102
return results.map { tableLivePhoto(value: $0) } // detached copy
103103
}
104104
}
105-
// swiftlint:enable empty_string
106105

107106
/// Returns true if at least one valid Live Photo record exists for the given account.
108107
func hasLivePhotos() async -> Bool {
@@ -117,4 +116,5 @@ extension NCManageDatabase {
117116
return !results.isEmpty
118117
} ?? false
119118
}
119+
// swiftlint:enable empty_string
120120
}

iOSClient/Main/Collection Common/NCCollectionViewCommon.swift

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,7 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
713713
let scene = SceneManager.shared.getWindow(controller: controller)?.windowScene
714714
let token = showHudBanner(
715715
scene: scene,
716-
title: NSLocalizedString("_delete_in_progress_", comment: ""))
716+
title: NSLocalizedString("_upload_in_progress_", comment: ""))
717717

718718
for (index, items) in UIPasteboard.general.items.enumerated() {
719719
for item in items {
@@ -739,26 +739,15 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
739739
continue
740740
}
741741

742-
let resultsUpload = await NextcloudKit.shared.uploadAsync(
743-
serverUrlFileName: serverUrlFileName,
744-
fileNameLocalPath: fileNameLocalPath,
745-
account: session.account) { _ in
746-
} taskHandler: { task in
747-
Task {
748-
let identifier = await NCNetworking.shared.networkingTasks.createIdentifier(
749-
account: self.session.account,
750-
path: serverUrlFileName,
751-
name: "upload")
752-
await NCNetworking.shared.networkingTasks.track(identifier: identifier, task: task)
753-
}
754-
} progressHandler: { progress in
755-
Task {@MainActor in
756-
LucidBanner.shared.update(
757-
title: "",
758-
progress: progress.fractionCompleted,
759-
for: token)
760-
}
742+
let resultsUpload = await NCNetworking.shared.uploadFile(account: session.account,
743+
fileNameLocalPath: fileNameLocalPath,
744+
serverUrlFileName: serverUrlFileName) { _ in
745+
} progressHandler: { _, _, fractionCompleted in
746+
Task {@MainActor in
747+
LucidBanner.shared.update(progress: fractionCompleted, for: token)
761748
}
749+
}
750+
762751
if resultsUpload.error == .success,
763752
let etag = resultsUpload.etag,
764753
let ocId = resultsUpload.ocId {

iOSClient/Main/Create cloud/NCCreate.swift

Lines changed: 85 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -228,84 +228,137 @@ class NCCreate: NSObject {
228228
}
229229
}
230230

231+
/// Creates and presents a UIActivityViewController for the given metadata list.
232+
/// - Parameters:
233+
/// - selectedMetadata: List of tableMetadata items selected by the user.
234+
/// - controller: Main tab bar controller used to present the activity view.
235+
/// - sender: The UI element that triggered the action (for iPad popover anchoring).
231236
@MainActor
232-
func createActivityViewController(selectedMetadata: [tableMetadata],
233-
controller: NCMainTabBarController?,
234-
sender: Any?) async {
237+
func createActivityViewController(selectedMetadata: [tableMetadata], controller: NCMainTabBarController?, sender: Any?) async {
235238
guard let controller else { return }
236-
let metadatas = selectedMetadata.filter({ !$0.directory })
237-
var urls: [URL] = []
239+
240+
let metadatas = selectedMetadata.filter { !$0.directory }
241+
var exportURLs: [URL] = []
238242
var downloadMetadata: [(tableMetadata, URL)] = []
243+
239244
let scene = SceneManager.shared.getWindow(controller: controller)?.windowScene
240245
let token = showHudBanner(
241246
scene: scene,
242-
title: NSLocalizedString("_download_in_progress_", comment: ""))
247+
title: NSLocalizedString("_download_in_progress_", comment: "")
248+
)
243249

244250
for metadata in metadatas {
245-
let fileURL = URL(fileURLWithPath: utilityFileSystem.getDirectoryProviderStorageOcId(
251+
let localPath = utilityFileSystem.getDirectoryProviderStorageOcId(
246252
metadata.ocId,
247253
fileName: metadata.fileNameView,
248254
userId: metadata.userId,
249-
urlBase: metadata.urlBase)
255+
urlBase: metadata.urlBase
250256
)
257+
let fileURL = URL(fileURLWithPath: localPath)
258+
251259
if utilityFileSystem.fileProviderStorageExists(metadata) {
252-
urls.append(fileURL)
260+
downloadMetadata.append((metadata, fileURL))
253261
} else {
254262
downloadMetadata.append((metadata, fileURL))
255263
}
256264
}
257265

258-
for (metadata, url) in downloadMetadata {
266+
// Download missing files
267+
for (originalMetadata, localFileURL) in downloadMetadata {
259268
guard let metadata = await NCManageDatabase.shared.setMetadataSessionInWaitDownloadAsync(
260-
ocId: metadata.ocId,
269+
ocId: originalMetadata.ocId,
261270
session: NCNetworking.shared.sessionDownload,
262271
selector: "",
263-
sceneIdentifier: controller.sceneIdentifier)
264-
else {
272+
sceneIdentifier: controller.sceneIdentifier
273+
) else {
274+
LucidBanner.shared.dismiss(for: token)
265275
return
266276
}
267277

268278
let results = await NCNetworking.shared.downloadFile(
269-
metadata: metadata) { _ in
270-
} progressHandler: { progress in
271-
Task {@MainActor in
272-
LucidBanner.shared.update(progress: progress.fractionCompleted, for: token)
273-
}
279+
metadata: metadata
280+
) { _ in
281+
// downloadStartHandler not used here
282+
} progressHandler: { progress in
283+
Task { @MainActor in
284+
LucidBanner.shared.update(
285+
progress: progress.fractionCompleted,
286+
for: token
287+
)
274288
}
289+
}
290+
275291
if results.nkError == .success {
276-
urls.append(url)
292+
if let exportedURL = exportFileForSharing(from: localFileURL) {
293+
exportURLs.append(exportedURL)
294+
}
277295
} else {
278-
Task {@MainActor in
279-
showErrorBanner(scene: scene,
280-
errorDescription: results.nkError.errorDescription,
281-
errorCode: results.nkError.errorCode)
296+
Task { @MainActor in
297+
showErrorBanner(
298+
scene: scene,
299+
errorDescription: results.nkError.errorDescription,
300+
errorCode: results.nkError.errorCode
301+
)
282302
}
283303
}
284304
}
285305

286306
LucidBanner.shared.dismiss(for: token)
287307

288-
guard !urls.isEmpty else {
289-
return
290-
}
308+
guard !exportURLs.isEmpty else { return }
291309

292-
let activityViewController = UIActivityViewController(activityItems: urls, applicationActivities: nil)
310+
let activityViewController = UIActivityViewController(activityItems: exportURLs, applicationActivities: nil)
293311

294-
// iPad
312+
// iPad popover configuration
295313
if let popover = activityViewController.popoverPresentationController {
296314
if let view = sender as? UIView {
297315
popover.sourceView = view
298316
popover.sourceRect = view.bounds
299317
} else {
300318
popover.sourceView = controller.view
301-
popover.sourceRect = CGRect(x: controller.view.bounds.midX,
302-
y: controller.view.bounds.midY,
303-
width: 0,
304-
height: 0)
319+
popover.sourceRect = CGRect(
320+
x: controller.view.bounds.midX,
321+
y: controller.view.bounds.midY,
322+
width: 0,
323+
height: 0
324+
)
305325
popover.permittedArrowDirections = []
306326
}
307327
}
308328

309329
controller.present(activityViewController, animated: true)
310330
}
331+
332+
// MARK: - Private helper
333+
334+
/// Copies a file from internal/provider storage to a shareable temporary location.
335+
/// This makes the URL safe to pass to UIActivityViewController, "Copy", etc.
336+
private func exportFileForSharing(from sourceURL: URL) -> URL? {
337+
let fileManager = FileManager.default
338+
let exportBaseURL = fileManager.temporaryDirectory.appendingPathComponent("ShareExports", isDirectory: true)
339+
340+
do {
341+
if !fileManager.fileExists(atPath: exportBaseURL.path) {
342+
try fileManager.createDirectory(
343+
at: exportBaseURL,
344+
withIntermediateDirectories: true,
345+
attributes: nil
346+
)
347+
}
348+
349+
// Destination file path (we can just reuse lastPathComponent)
350+
let destinationURL = exportBaseURL.appendingPathComponent(sourceURL.lastPathComponent, isDirectory: false)
351+
352+
// Remove previous copy if it exists
353+
if fileManager.fileExists(atPath: destinationURL.path) {
354+
try fileManager.removeItem(at: destinationURL)
355+
}
356+
357+
try fileManager.copyItem(at: sourceURL, to: destinationURL)
358+
359+
return destinationURL
360+
} catch {
361+
return nil
362+
}
363+
}
311364
}

iOSClient/Main/NCDragDrop.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -233,12 +233,11 @@ class NCDragDrop: NSObject {
233233
let fileName = await NCNetworking.shared.createFileName(fileNameBase: metadata.fileName, account: session.account, serverUrl: destination)
234234
let serverUrlFileName = utilityFileSystem.createServerUrl(serverUrl: destination, fileName: fileName)
235235

236-
let results = await NCNetworking.shared.uploadFile(fileNameLocalPath: fileNameLocalPath,
236+
let results = await NCNetworking.shared.uploadFile(account: session.account,
237+
fileNameLocalPath: fileNameLocalPath,
237238
serverUrlFileName: serverUrlFileName,
238239
creationDate: metadata.creationDate as Date,
239-
dateModificationFile: metadata.date as Date,
240-
account: session.account,
241-
performPostProcessing: false) { request in
240+
dateModificationFile: metadata.date as Date) { request in
242241
uploadRequest = request
243242
} progressHandler: { _, _, fractionCompleted in
244243
let status = NSLocalizedString("_status_uploading_", comment: "").lowercased()

iOSClient/Networking/E2EE/NCNetworkingE2EEUpload.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -279,13 +279,11 @@ class NCNetworkingE2EEUpload: NSObject {
279279
userId: metadata.userId,
280280
urlBase: metadata.urlBase)
281281

282-
let results = await NCNetworking.shared.uploadFile(fileNameLocalPath: fileNameLocalPath,
282+
let results = await NCNetworking.shared.uploadFile(account: metadata.account,
283+
fileNameLocalPath: fileNameLocalPath,
283284
serverUrlFileName: metadata.serverUrlFileName,
284285
creationDate: metadata.creationDate as Date,
285286
dateModificationFile: metadata.date as Date,
286-
account: metadata.account,
287-
metadata: metadata,
288-
performPostProcessing: false,
289287
customHeaders: ["e2e-token": e2eToken]) { request in
290288
self.request = request
291289
} progressHandler: { _, _, fractionCompleted in

iOSClient/Networking/NCNetworking+Upload.swift

Lines changed: 4 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,11 @@ extension NCNetworking {
1111
// MARK: - Upload file in foreground
1212

1313
@discardableResult
14-
func uploadFile(fileNameLocalPath: String,
14+
func uploadFile(account: String,
15+
fileNameLocalPath: String,
1516
serverUrlFileName: String,
16-
creationDate: Date,
17-
dateModificationFile: Date,
18-
account: String,
19-
metadata: tableMetadata? = nil,
20-
performPostProcessing: Bool = true,
17+
creationDate: Date? = nil,
18+
dateModificationFile: Date? = nil,
2119
customHeaders: [String: String]? = nil,
2220
requestHandler: @escaping (_ request: UploadRequest) -> Void = { _ in },
2321
taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in },
@@ -38,54 +36,12 @@ extension NCNetworking {
3836
path: serverUrlFileName,
3937
name: "upload")
4038
await NCNetworking.shared.networkingTasks.track(identifier: identifier, task: task)
41-
42-
if let metadata {
43-
await NCManageDatabase.shared.setMetadataSessionAsync(ocId: metadata.ocId,
44-
sessionTaskIdentifier: task.taskIdentifier,
45-
status: self.global.metadataStatusUploading)
46-
47-
await self.transferDispatcher.notifyAllDelegates { delegate in
48-
delegate.transferChange(status: self.global.networkingStatusUploading,
49-
account: metadata.account,
50-
fileName: metadata.fileName,
51-
serverUrl: metadata.serverUrl,
52-
selector: metadata.sessionSelector,
53-
ocId: metadata.ocId,
54-
destination: nil,
55-
error: .success)
56-
}
57-
}
5839
}
5940
taskHandler(task)
6041
} progressHandler: { progress in
61-
Task {
62-
guard let metadata,
63-
await self.progressQuantizer.shouldEmit(serverUrlFileName: serverUrlFileName, fraction: progress.fractionCompleted) else {
64-
return
65-
}
66-
await self.transferDispatcher.notifyAllDelegates { delegate in
67-
delegate.transferProgressDidUpdate(progress: Float(progress.fractionCompleted),
68-
totalBytes: progress.totalUnitCount,
69-
totalBytesExpected: progress.completedUnitCount,
70-
fileName: metadata.fileName,
71-
serverUrl: metadata.serverUrl)
72-
}
73-
}
7442
progressHandler(progress.completedUnitCount, progress.totalUnitCount, progress.fractionCompleted)
7543
}
7644

77-
Task {
78-
await progressQuantizer.clear(serverUrlFileName: serverUrlFileName)
79-
}
80-
81-
if performPostProcessing, let metadata {
82-
if results.error == .success, let ocId = results.ocId {
83-
await uploadSuccess(withMetadata: metadata, ocId: ocId, etag: results.etag, date: results.date)
84-
} else {
85-
await uploadError(withMetadata: metadata, error: results.error)
86-
}
87-
}
88-
8945
return results
9046
}
9147

iOSClient/StatusMessage/NCStatusMessageModel.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,5 +227,3 @@ import NextcloudKit
227227
return [meeting, commuting]
228228
}
229229
}
230-
231-

iOSClient/Supporting Files/en.lproj/Localizable.strings

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,7 @@
662662
"_update_in_progress_" = "Update in progress …";
663663
"_delete_in_progress_" = "Delete in progress …";
664664
"_download_in_progress_" = "Download in progress …";
665+
"_upload_in_progress_" = "Upload in progress …";
665666
"_in_waiting_" = "In waiting";
666667
"_in_progress_" = "In progress";
667668
"_in_error_" = "In error";

0 commit comments

Comments
 (0)