Skip to content

Commit 9be8b8d

Browse files
author
Nextcloud GmbH
committed
Merge remote-tracking branch 'customization/nmc/2023-localization'
2 parents 71af36c + 328a16c commit 9be8b8d

119 files changed

Lines changed: 846 additions & 7999 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎File Provider Extension/FileProviderData.swift‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ class FileProviderData: NSObject {
176176

177177
if error == .success {
178178
if let metadata = await NCManageDatabase.shared.getMetadataFromOcIdAsync(ocId) {
179-
await NCManageDatabase.shared.addLocalFilesAsync(metadatas: [metadata])
179+
await NCManageDatabase.shared.addLocalFileAsync(metadata: metadata)
180180
}
181181
}
182182

‎iOSClient/Data/NCManageDatabase+LocalFile.swift‎

Lines changed: 23 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -29,50 +29,35 @@ extension NCManageDatabase {
2929

3030
// MARK: - Realm Write
3131

32-
/// Adds or updates multiple local file entries corresponding to the given metadata array.
33-
/// Uses async Realm read + single write transaction. Assumes `tableLocalFile` has a primary key.
3432
/// - Parameters:
35-
/// - metadatas: Array of `tableMetadata` to map into `tableLocalFile`.
36-
/// - offline: Optional override for the `offline` flag applied to all items.
37-
func addLocalFilesAsync(metadatas: [tableMetadata], offline: Bool? = nil) async {
38-
guard !metadatas.isEmpty else {
39-
return
40-
}
41-
42-
// Extract ocIds for efficient lookup
43-
let ocIds = metadatas.compactMap { $0.ocId }
44-
guard !ocIds.isEmpty else {
45-
return
33+
/// - metadata: The `tableMetadata` containing file details.
34+
/// - offline: Optional flag to mark the file as available offline.
35+
/// - Returns: Nothing. Realm write is performed asynchronously.
36+
func addLocalFileAsync(metadata: tableMetadata, offline: Bool? = nil) async {
37+
// Read (non-blocking): safely detach from Realm thread
38+
let existing: tableLocalFile? = performRealmRead { realm in
39+
realm.objects(tableLocalFile.self)
40+
.filter(NSPredicate(format: "ocId == %@", metadata.ocId))
41+
.first
42+
.map { tableLocalFile(value: $0) }
4643
}
4744

48-
// Preload existing entries to avoid creating duplicates
49-
let existingMap: [String: tableLocalFile] = await core.performRealmReadAsync { realm in
50-
let existing = realm.objects(tableLocalFile.self)
51-
.filter(NSPredicate(format: "ocId IN %@", ocIds))
52-
return Dictionary(uniqueKeysWithValues:
53-
existing.map { ($0.ocId, tableLocalFile(value: $0)) } // detached copy via value init
54-
)
55-
} ?? [:]
45+
await performRealmWriteAsync { realm in
46+
let addObject = existing ?? tableLocalFile()
5647

57-
await core.performRealmWriteAsync { realm in
58-
for metadata in metadatas {
59-
// Reuse existing object or create a new one
60-
let local = existingMap[metadata.ocId] ?? tableLocalFile()
61-
62-
local.account = metadata.account
63-
local.etag = metadata.etag
64-
local.exifDate = NSDate()
65-
local.exifLatitude = "-1"
66-
local.exifLongitude = "-1"
67-
local.ocId = metadata.ocId
68-
local.fileName = metadata.fileName
69-
70-
if let offline {
71-
local.offline = offline
72-
}
48+
addObject.account = metadata.account
49+
addObject.etag = metadata.etag
50+
addObject.exifDate = NSDate()
51+
addObject.exifLatitude = "-1"
52+
addObject.exifLongitude = "-1"
53+
addObject.ocId = metadata.ocId
54+
addObject.fileName = metadata.fileName
7355

74-
realm.add(local, update: .all)
56+
if let offline {
57+
addObject.offline = offline
7558
}
59+
60+
realm.add(addObject, update: .all)
7661
}
7762
}
7863

‎iOSClient/NCBackgroundLocationUploadManager.swift‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ class NCBackgroundLocationUploadManager: NSObject, CLLocationManagerDelegate {
102102
}
103103

104104
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
105-
// Must work only in background
106105
guard isAppInBackground else {
107106
return
108107
}
@@ -119,6 +118,14 @@ class NCBackgroundLocationUploadManager: NSObject, CLLocationManagerDelegate {
119118

120119
Task.detached {
121120
await NCAutoUpload.shared.autoUploadBackgroundSync()
121+
if database.openRealmBackground() {
122+
let appDelegate = (UIApplication.shared.delegate as? AppDelegate)!
123+
let location = locations.last
124+
nkLog(tag: self.global.logTagLocation, emoji: .start, message: "Triggered by location change: \(location?.coordinate.latitude ?? 0), \(location?.coordinate.longitude ?? 0)")
125+
126+
Task.detached {
127+
await NCAutoUpload.shared.autoUploadBackgroundSync()
128+
}
122129
}
123130
}
124131

‎iOSClient/NCGlobal.swift‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,8 @@ final class NCGlobal: Sendable {
538538

539539
let notificationCenterCreateFolder = "createFolder" // userInfo: ocId, serverUrl, account, withPush, sceneIdentifier
540540

541+
let notificationCenterRenameFile = "renameFile" // userInfo: serverUrl, account, error
542+
541543
let notificationCenterMenuSearchTextPDF = "menuSearchTextPDF"
542544
let notificationCenterMenuGotToPageInPDF = "menuGotToPageInPDF"
543545

‎iOSClient/Networking/E2EE/NCNetworkingE2EEUpload.swift‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@ class NCNetworkingE2EEUpload: NSObject {
238238
await self.database.addMetadataAsync(metadata)
239239
await self.database.addLocalFilesAsync(metadatas: [metadata])
240240
await self.database.addLocalFileAsync(metadata: metadata)
241+
// await self.database.addLocalFileAsync(metadata: metadata)
242+
241243
utility.createImageFileFrom(metadata: metadata)
242244

243245
await NCNetworking.shared.transferDispatcher.notifyAllDelegates { delegate in

‎iOSClient/Networking/NCConfigServer.swift‎

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,25 @@
1-
// SPDX-FileCopyrightText: Nextcloud GmbH
2-
// SPDX-FileCopyrightText: 2022 Marino Faggiana
3-
// SPDX-License-Identifier: GPL-3.0-or-later
1+
//
2+
// NCConfigServer.swift
3+
// Nextcloud
4+
//
5+
// Created by Marino Faggiana on 05/12/22.
6+
// Copyright © 2022 Marino Faggiana. All rights reserved.
7+
//
8+
// Author Marino Faggiana <marino.faggiana@nextcloud.com>
9+
//
10+
// This program is free software: you can redistribute it and/or modify
11+
// it under the terms of the GNU General Public License as published by
12+
// the Free Software Foundation, either version 3 of the License, or
13+
// (at your option) any later version.
14+
//
15+
// This program is distributed in the hope that it will be useful,
16+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+
// GNU General Public License for more details.
19+
//
20+
// You should have received a copy of the GNU General Public License
21+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
22+
//
423

524
import Foundation
625
import UIKit

‎iOSClient/Networking/NCNetworking+Download.swift‎

Lines changed: 140 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,25 @@
1-
// SPDX-FileCopyrightText: Nextcloud GmbH
2-
// SPDX-FileCopyrightText: 2024 Marino Faggiana
3-
// SPDX-License-Identifier: GPL-3.0-or-later
1+
//
2+
// NCNetworking+Download.swift
3+
// Nextcloud
4+
//
5+
// Created by Marino Faggiana on 07/02/24.
6+
// Copyright © 2024 Marino Faggiana. All rights reserved.
7+
//
8+
// Author Marino Faggiana <marino.faggiana@nextcloud.com>
9+
//
10+
// This program is free software: you can redistribute it and/or modify
11+
// it under the terms of the GNU General Public License as published by
12+
// the Free Software Foundation, either version 3 of the License, or
13+
// (at your option) any later version.
14+
//
15+
// This program is distributed in the hope that it will be useful,
16+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+
// GNU General Public License for more details.
19+
//
20+
// You should have received a copy of the GNU General Public License
21+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
22+
//
423

524
import UIKit
625
import NextcloudKit
@@ -319,23 +338,89 @@ extension NCNetworking {
319338
await NCManageDatabase.shared.clearMetadatasSessionAsync(metadatas: metadatas)
320339
}
321340
} else {
322-
await NCManageDatabase.shared.setOffLocalFileAsync(ocId: metadata.ocId)
341+
nkLog(error: "Downloaded file: " + metadata.serverUrlFileName + ", result: error \(error.errorCode)")
342+
343+
if error.errorCode == NCGlobal.shared.errorResourceNotFound {
344+
self.utilityFileSystem.removeFile(atPath: self.utilityFileSystem.getDirectoryProviderStorageOcId(metadata.ocId, userId: metadata.userId, urlBase: metadata.urlBase))
345+
346+
await NCManageDatabase.shared.deleteLocalFileAsync(id: metadata.ocId)
347+
await NCManageDatabase.shared.deleteMetadataAsync(id: metadata.ocId)
348+
} else if error.errorCode == NSURLErrorCancelled || error.errorCode == self.global.errorRequestExplicityCancelled {
349+
if let metadata = await NCManageDatabase.shared.setMetadataSessionAsync(ocId: metadata.ocId,
350+
session: "",
351+
sessionTaskIdentifier: 0,
352+
sessionError: "",
353+
selector: "",
354+
status: self.global.metadataStatusNormal) {
355+
await self.transferDispatcher.notifyAllDelegates { delegate in
356+
delegate.transferChange(status: self.global.networkingStatusDownloadCancel,
357+
metadata: metadata,
358+
error: .success)
359+
}
360+
}
361+
} else {
362+
if let metadata = await NCManageDatabase.shared.setMetadataSessionAsync(ocId: metadata.ocId,
363+
session: "",
364+
sessionTaskIdentifier: 0,
365+
sessionError: "",
366+
selector: "",
367+
status: self.global.metadataStatusNormal) {
368+
369+
await self.transferDispatcher.notifyAllDelegates { delegate in
370+
delegate.transferChange(status: NCGlobal.shared.networkingStatusDownloaded,
371+
metadata: metadata,
372+
error: error)
373+
}
374+
}
375+
}
376+
await NCManageDatabase.shared.updateBadge()
323377
}
324-
} else if metadata.directory {
325-
await NCManageDatabase.shared.cleanTablesOcIds(account: metadata.account, userId: metadata.userId, urlBase: metadata.urlBase)
326-
await NCManageDatabase.shared.setDirectoryAsync(serverUrl: metadata.serverUrlFileName, offline: true, metadata: metadata)
327-
await NCNetworking.shared.synchronizationDownload(account: metadata.account, serverUrl: metadata.serverUrlFileName, userId: metadata.userId, urlBase: metadata.urlBase, metadatasInDownload: nil)
328-
} else {
329-
var metadatasSynchronizationOffline: [tableMetadata] = []
330-
metadatasSynchronizationOffline.append(metadata)
331-
if let metadata = await NCManageDatabase.shared.getMetadataLivePhotoAsync(metadata: metadata) {
332-
metadatasSynchronizationOffline.append(metadata)
378+
}
379+
}
380+
381+
// MARK: - Download NextcloudKitDelegate
382+
383+
func downloadingFinish(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
384+
if let httpResponse = (downloadTask.response as? HTTPURLResponse) {
385+
if httpResponse.statusCode >= 200 && httpResponse.statusCode < 300,
386+
let url = downloadTask.currentRequest?.url,
387+
var serverUrl = url.deletingLastPathComponent().absoluteString.removingPercentEncoding {
388+
let fileName = url.lastPathComponent
389+
if serverUrl.hasSuffix("/") { serverUrl = String(serverUrl.dropLast()) }
390+
if let metadata = NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "serverUrl == %@ AND fileName == %@", serverUrl, fileName)) {
391+
let destinationFilePath = utilityFileSystem.getDirectoryProviderStorageOcId(metadata.ocId, fileName: metadata.fileName, userId: metadata.userId, urlBase: metadata.urlBase)
392+
do {
393+
if FileManager.default.fileExists(atPath: destinationFilePath) {
394+
try FileManager.default.removeItem(atPath: destinationFilePath)
395+
}
396+
try FileManager.default.copyItem(at: location, to: NSURL.fileURL(withPath: destinationFilePath))
397+
} catch {
398+
print(error)
399+
}
400+
}
333401
}
334-
await NCManageDatabase.shared.addLocalFilesAsync(metadatas: [metadata], offline: true)
335-
for metadata in metadatasSynchronizationOffline {
336-
await NCManageDatabase.shared.setMetadataSessionInWaitDownloadAsync(ocId: metadata.ocId,
337-
session: NCNetworking.shared.sessionDownloadBackground,
338-
selector: NCGlobal.shared.selectorSynchronizationOffline)
402+
}
403+
}
404+
405+
func downloadProgress(_ progress: Float,
406+
totalBytes: Int64,
407+
totalBytesExpected: Int64,
408+
fileName: String,
409+
serverUrl: String,
410+
session: URLSession,
411+
task: URLSessionTask) {
412+
413+
Task {
414+
guard await progressQuantizer.shouldEmit(serverUrlFileName: serverUrl + "/" + fileName, fraction: Double(progress)) else {
415+
return
416+
}
417+
await NCManageDatabase.shared.setMetadataProgress(fileName: fileName, serverUrl: serverUrl, taskIdentifier: task.taskIdentifier, progress: Double(progress))
418+
await self.transferDispatcher.notifyAllDelegates { delegate in
419+
delegate.transferProgressDidUpdate(progress: progress,
420+
totalBytes: totalBytes,
421+
totalBytesExpected: totalBytesExpected,
422+
fileName: fileName,
423+
serverUrl: serverUrl)
339424
}
340425
}
341426

@@ -345,3 +430,40 @@ extension NCNetworking {
345430
}
346431
}
347432
}
433+
434+
class NCOperationDownload: ConcurrentOperation, @unchecked Sendable {
435+
var metadata: tableMetadata
436+
var selector: String
437+
438+
init(metadata: tableMetadata, selector: String) {
439+
self.metadata = tableMetadata.init(value: metadata)
440+
self.selector = selector
441+
}
442+
443+
override func start() {
444+
guard !isCancelled else { return self.finish() }
445+
446+
metadata.session = NCNetworking.shared.sessionDownload
447+
metadata.sessionError = ""
448+
metadata.sessionSelector = selector
449+
metadata.sessionTaskIdentifier = 0
450+
metadata.status = NCGlobal.shared.metadataStatusWaitDownload
451+
452+
// let metadata = NCManageDatabase.shared.addMetadata(metadata)
453+
454+
// NCNetworking.shared.download(metadata: metadata, withNotificationProgressTask: true) {
455+
// } completion: { _, _ in
456+
// self.finish()
457+
// }
458+
Task {
459+
await download(withSelector: self.selector)
460+
}
461+
}
462+
463+
private func download(withSelector selector: String = "") async {
464+
await NCNetworking.shared.downloadFile(metadata: metadata) { _ in
465+
self.finish()
466+
} taskHandler: { _ in }
467+
468+
}
469+
}

‎iOSClient/Networking/NCNetworking+LivePhoto.swift‎

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,25 @@
1-
// SPDX-FileCopyrightText: Nextcloud GmbH
2-
// SPDX-FileCopyrightText: 2024 Marino Faggiana
3-
// SPDX-License-Identifier: GPL-3.0-or-later
1+
//
2+
// NCNetworking+LivePhoto.swift
3+
// Nextcloud
4+
//
5+
// Created by Marino Faggiana on 07/02/24.
6+
// Copyright © 2024 Marino Faggiana. All rights reserved.
7+
//
8+
// Author Marino Faggiana <marino.faggiana@nextcloud.com>
9+
//
10+
// This program is free software: you can redistribute it and/or modify
11+
// it under the terms of the GNU General Public License as published by
12+
// the Free Software Foundation, either version 3 of the License, or
13+
// (at your option) any later version.
14+
//
15+
// This program is distributed in the hope that it will be useful,
16+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+
// GNU General Public License for more details.
19+
//
20+
// You should have received a copy of the GNU General Public License
21+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
22+
//
423

524
import UIKit
625
import NextcloudKit

‎iOSClient/Networking/NCNetworking+Upload.swift‎

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
// SPDX-FileCopyrightText: Nextcloud GmbH
2-
// SPDX-FileCopyrightText: 2024 Marino Faggiana
3-
// SPDX-License-Identifier: GPL-3.0-or-later
4-
51
import UIKit
62
import NextcloudKit
73
import Alamofire
@@ -48,6 +44,22 @@ extension NCNetworking {
4844
} taskHandler: { task in
4945
taskHandler(task)
5046
} progressHandler: { progress in
47+
Task {
48+
guard await self.progressQuantizer.shouldEmit(serverUrlFileName: serverUrlFileName, fraction: progress.fractionCompleted) else {
49+
return
50+
}
51+
52+
if let metadata {
53+
await NCManageDatabase.shared.setMetadataProgress(ocId: metadata.ocId, progress: progress.fractionCompleted)
54+
await self.transferDispatcher.notifyAllDelegates { delegate in
55+
delegate.transferProgressDidUpdate(progress: Float(progress.fractionCompleted),
56+
totalBytes: progress.totalUnitCount,
57+
totalBytesExpected: progress.completedUnitCount,
58+
fileName: metadata.fileName,
59+
serverUrl: metadata.serverUrl)
60+
}
61+
}
62+
}
5163
progressHandler(progress.completedUnitCount, progress.totalUnitCount, progress.fractionCompleted)
5264
}
5365

@@ -446,6 +458,7 @@ extension NCNetworking {
446458
error: self.global.diagnosticProblemsUploadServerError)
447459
}
448460
}
461+
await NCManageDatabase.shared.updateBadge()
449462
}
450463

451464
// MARK: -

0 commit comments

Comments
 (0)