This commit is contained in:
Marino Faggiana 2024-07-30 12:17:44 +02:00 коммит произвёл GitHub
Родитель ca03c1d3a7
Коммит 9e4e7af280
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
18 изменённых файлов: 294 добавлений и 192 удалений

Просмотреть файл

@ -58,6 +58,14 @@ class fileProviderData: NSObject {
case workingSet
}
struct UploadMetadata {
var id: String
var metadata: tableMetadata
var task: URLSessionUploadTask?
}
var uploadMetadata: [UploadMetadata] = []
// MARK: -
func setupAccount(domain: NSFileProviderDomain?, providerExtension: NSFileProviderExtension) -> tableAccount? {
@ -140,4 +148,17 @@ class fileProviderData: NSObject {
fileProviderManager.signalEnumerator(for: .workingSet) { _ in }
return item
}
// MARK: -
func appendUploadMetadata(id: String, metadata: tableMetadata, task: URLSessionUploadTask?) {
if let index = uploadMetadata.firstIndex(where: { $0.id == id }) {
uploadMetadata.remove(at: index)
}
uploadMetadata.append(UploadMetadata(id: id, metadata: metadata, task: task))
}
func getUploadMetadata(id: String) -> UploadMetadata? {
return uploadMetadata.filter({ $0.id == id }).first
}
}

Просмотреть файл

@ -36,37 +36,45 @@ extension FileProviderExtension: NCNetworkingDelegate {
func uploadComplete(fileName: String, serverUrl: String, ocId: String?, etag: String?, date: Date?, size: Int64, task: URLSessionTask, error: NKError) {
guard let url = task.currentRequest?.url,
let metadata = NCManageDatabase.shared.getMetadata(from: url, sessionTaskIdentifier: task.taskIdentifier) else { return }
if error == .success, let ocId {
/// SIGNAL
fileProviderData.shared.signalEnumerator(ocId: metadata.ocIdTemp, type: .delete)
metadata.fileName = fileName
metadata.serverUrl = serverUrl
metadata.uploadDate = (date as? NSDate) ?? NSDate()
metadata.etag = etag ?? ""
metadata.ocId = ocId
metadata.size = size
if let fileId = NCUtility().ocIdToFileId(ocId: ocId) {
metadata.fileId = fileId
}
metadata.session = ""
metadata.sessionError = ""
metadata.status = NCGlobal.shared.metadataStatusNormal
NCManageDatabase.shared.addMetadata(metadata)
NCManageDatabase.shared.addLocalFile(metadata: metadata)
/// NEW File
if ocId != metadata.ocIdTemp {
let atPath = utilityFileSystem.getDirectoryProviderStorageOcId(metadata.ocIdTemp)
let toPath = utilityFileSystem.getDirectoryProviderStorageOcId(ocId)
utilityFileSystem.copyFile(atPath: atPath, toPath: toPath)
DispatchQueue.global(qos: .userInteractive).async {
if error == .success, let ocId {
/// SIGNAL
fileProviderData.shared.signalEnumerator(ocId: metadata.ocIdTemp, type: .delete)
metadata.fileName = fileName
metadata.serverUrl = serverUrl
metadata.uploadDate = (date as? NSDate) ?? NSDate()
metadata.etag = etag ?? ""
metadata.ocId = ocId
metadata.size = size
if let fileId = NCUtility().ocIdToFileId(ocId: ocId) {
metadata.fileId = fileId
}
metadata.sceneIdentifier = nil
metadata.session = ""
metadata.sessionError = ""
metadata.sessionSelector = ""
metadata.sessionDate = nil
metadata.sessionTaskIdentifier = 0
metadata.status = NCGlobal.shared.metadataStatusNormal
NCManageDatabase.shared.addMetadata(metadata)
NCManageDatabase.shared.addLocalFile(metadata: metadata)
/// NEW File
if !metadata.ocIdTemp.isEmpty, ocId != metadata.ocIdTemp {
let atPath = self.utilityFileSystem.getDirectoryProviderStorageOcId(metadata.ocIdTemp)
let toPath = self.utilityFileSystem.getDirectoryProviderStorageOcId(ocId)
self.utilityFileSystem.copyFile(atPath: atPath, toPath: toPath)
NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocIdTemp))
}
/// SIGNAL
fileProviderData.shared.signalEnumerator(ocId: metadata.ocId, type: .update)
} else {
NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocIdTemp))
/// SIGNAL
fileProviderData.shared.signalEnumerator(ocId: metadata.ocIdTemp, type: .delete)
}
/// SIGNAL
fileProviderData.shared.signalEnumerator(ocId: metadata.ocId, type: .update)
} else {
NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocIdTemp))
/// SIGNAL
fileProviderData.shared.signalEnumerator(ocId: metadata.ocIdTemp, type: .delete)
}
}
}

Просмотреть файл

@ -166,7 +166,13 @@ class FileProviderExtension: NSFileProviderExtension {
override func startProvidingItem(at url: URL, completionHandler: @escaping ((_ error: Error?) -> Void)) {
let pathComponents = url.pathComponents
let itemIdentifier = NSFileProviderItemIdentifier(pathComponents[pathComponents.count - 2])
guard let metadata = providerUtility.getTableMetadataFromItemIdentifier(itemIdentifier) else {
var metadata: tableMetadata?
if let result = fileProviderData.shared.getUploadMetadata(id: itemIdentifier.rawValue) {
metadata = result.metadata
} else {
metadata = NCManageDatabase.shared.getMetadataFromOcIdAndOcIdTemp(itemIdentifier.rawValue)
}
guard let metadata else {
return completionHandler(NSFileProviderError(.noSuchItem))
}
if metadata.session == NCNetworking.shared.sessionUploadBackgroundExtension {
@ -200,6 +206,12 @@ class FileProviderExtension: NSFileProviderExtension {
return completionHandler(NSFileProviderError(.noSuchItem))
}
if error == .success {
metadata.sceneIdentifier = nil
metadata.session = ""
metadata.sessionError = ""
metadata.sessionSelector = ""
metadata.sessionDate = nil
metadata.sessionTaskIdentifier = 0
metadata.status = NCGlobal.shared.metadataStatusNormal
metadata.date = (date as? NSDate) ?? NSDate()
metadata.etag = etag ?? ""
@ -226,16 +238,23 @@ class FileProviderExtension: NSFileProviderExtension {
assert(pathComponents.count > 2)
let itemIdentifier = NSFileProviderItemIdentifier(pathComponents[pathComponents.count - 2])
let fileName = pathComponents[pathComponents.count - 1]
guard let metadata = NCManageDatabase.shared.getMetadataFromOcIdAndOcIdTemp(itemIdentifier.rawValue) else { return }
var metadata: tableMetadata?
if let result = fileProviderData.shared.getUploadMetadata(id: itemIdentifier.rawValue) {
metadata = result.metadata
} else {
metadata = NCManageDatabase.shared.getMetadataFromOcIdAndOcIdTemp(itemIdentifier.rawValue)
}
guard let metadata else {
return
}
let serverUrlFileName = metadata.serverUrl + "/" + fileName
let fileNameLocalPath = utilityFileSystem.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: fileName)
utilityFileSystem.copyFile(atPath: url.path, toPath: fileNameLocalPath)
NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId,
session: NCNetworking.shared.sessionUploadBackgroundExtension,
sessionError: "",
selector: "",
status: NCGlobal.shared.metadataStatusUploading)
if let task = NKBackground(nkCommonInstance: NextcloudKit.shared.nkCommonInstance).upload(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, dateCreationFile: nil, dateModificationFile: nil, session: NCNetworking.shared.sessionManagerUploadBackgroundExtension) {
if let task = NKBackground(nkCommonInstance: NextcloudKit.shared.nkCommonInstance).upload(serverUrlFileName: serverUrlFileName, fileNameLocalPath: url.path, dateCreationFile: nil, dateModificationFile: nil, session: NCNetworking.shared.sessionManagerUploadBackgroundExtension) {
NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId,
status: NCGlobal.shared.metadataStatusUploading,
taskIdentifier: task.taskIdentifier)
@ -304,6 +323,7 @@ class FileProviderExtension: NSFileProviderExtension {
status: NCGlobal.shared.metadataStatusUploading,
taskIdentifier: task.taskIdentifier)
fileProviderData.shared.fileProviderManager.register(task, forItemWithIdentifier: NSFileProviderItemIdentifier(ocIdTemp)) { _ in }
fileProviderData.shared.appendUploadMetadata(id: ocIdTemp, metadata: metadata, task: task)
}
let item = FileProviderItem(metadata: tableMetadata.init(value: metadata), parentItemIdentifier: parentItemIdentifier)

Просмотреть файл

@ -75,12 +75,12 @@ class fileProviderUtility: NSObject {
do {
try fileManager.removeItem(atPath: toPath)
} catch let error {
print("error: \(error)")
print("Error: \(error.localizedDescription)")
}
do {
try fileManager.copyItem(atPath: atPath, toPath: toPath)
} catch let error {
print("error: \(error)")
print("Error: \(error.localizedDescription)")
}
}
@ -90,12 +90,28 @@ class fileProviderUtility: NSObject {
do {
try fileManager.removeItem(atPath: toPath)
} catch let error {
print("error: \(error)")
print("Error: \(error.localizedDescription)")
}
do {
try fileManager.moveItem(atPath: atPath, toPath: toPath)
} catch let error {
print("error: \(error)")
print("Error: \(error.localizedDescription)")
}
}
func getFileSize(from url: URL) -> Int64? {
do {
let attributes = try fileManager.attributesOfItem(atPath: url.path)
if let fileSize = attributes[FileAttributeKey.size] as? Int64 {
return fileSize
} else {
print("Failed to retrieve file size.")
return nil
}
} catch {
print("Error: \(error.localizedDescription)")
return nil
}
}
}

Просмотреть файл

@ -5414,7 +5414,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 11;
CURRENT_PROJECT_VERSION = 2;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = NKUJUXUJ3B;
ENABLE_STRICT_OBJC_MSGSEND = YES;
@ -5441,7 +5441,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 5.5.0;
MARKETING_VERSION = 5.5.2;
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = "-v";
OTHER_LDFLAGS = "";
@ -5480,7 +5480,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 11;
CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_TEAM = NKUJUXUJ3B;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
@ -5504,7 +5504,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 5.5.0;
MARKETING_VERSION = 5.5.2;
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = "-v";
OTHER_LDFLAGS = "";

Просмотреть файл

@ -15,9 +15,9 @@
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F771E3CF20E2392D00AFB62D"
BuildableName = "File Provider Extension.appex"
BlueprintName = "File Provider Extension"
BlueprintIdentifier = "F77B0DEB1D118A16002130FE"
BuildableName = "Nextcloud.app"
BlueprintName = "Nextcloud"
ReferencedContainer = "container:Nextcloud.xcodeproj">
</BuildableReference>
</BuildActionEntry>
@ -29,9 +29,9 @@
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F77B0DEB1D118A16002130FE"
BuildableName = "Nextcloud.app"
BlueprintName = "Nextcloud"
BlueprintIdentifier = "F771E3CF20E2392D00AFB62D"
BuildableName = "File Provider Extension.appex"
BlueprintName = "File Provider Extension"
ReferencedContainer = "container:Nextcloud.xcodeproj">
</BuildableReference>
</BuildActionEntry>

Просмотреть файл

@ -140,6 +140,13 @@ class NCAccountSettingsModel: ObservableObject, ViewOnAppearHandling {
return (nil, "", "")
}
/// Is the user an Admin
func isAdminGroup() -> Bool {
guard let activeAccount else { return false }
let groups = NCManageDatabase.shared.getAccountGroups(account: activeAccount.account)
return groups.contains(NCGlobal.shared.groupAdmin)
}
/// Function to know the height of "account" data
func getTableViewHeight() -> CGFloat {
guard let activeAccount else { return 0 }

Просмотреть файл

@ -181,52 +181,54 @@ struct NCAccountSettingsView: View {
}
///
/// Certificate server
Button(action: {
showServerCertificate.toggle()
}, label: {
HStack {
Image(systemName: "lock")
.resizable()
.scaledToFit()
.font(Font.system(.body).weight(.light))
.frame(width: 20, height: 20)
.foregroundStyle(Color(NCBrandColor.shared.iconImageColor))
Text(NSLocalizedString("_certificate_details_", comment: ""))
.lineLimit(1)
.truncationMode(.middle)
.foregroundStyle(Color(NCBrandColor.shared.textColor))
.padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 20))
if model.isAdminGroup() {
Button(action: {
showServerCertificate.toggle()
}, label: {
HStack {
Image(systemName: "lock")
.resizable()
.scaledToFit()
.font(Font.system(.body).weight(.light))
.frame(width: 20, height: 20)
.foregroundStyle(Color(NCBrandColor.shared.iconImageColor))
Text(NSLocalizedString("_certificate_details_", comment: ""))
.lineLimit(1)
.truncationMode(.middle)
.foregroundStyle(Color(NCBrandColor.shared.textColor))
.padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 20))
}
.font(.system(size: 14))
})
.sheet(isPresented: $showServerCertificate) {
if let url = URL(string: model.activeAccount?.urlBase), let host = url.host {
certificateDetailsView(host: host, title: NSLocalizedString("_certificate_view_", comment: ""))
}
}
.font(.system(size: 14))
})
.sheet(isPresented: $showServerCertificate) {
if let url = URL(string: model.activeAccount?.urlBase), let host = url.host {
certificateDetailsView(host: host, title: NSLocalizedString("_certificate_view_", comment: ""))
}
}
///
/// Certificate push
Button(action: {
showPushCertificate.toggle()
}, label: {
HStack {
Image(systemName: "lock")
.resizable()
.scaledToFit()
.font(Font.system(.body).weight(.light))
.frame(width: 20, height: 20)
.foregroundStyle(Color(NCBrandColor.shared.iconImageColor))
Text(NSLocalizedString("_certificate_pn_details_", comment: ""))
.lineLimit(1)
.truncationMode(.middle)
.foregroundStyle(Color(NCBrandColor.shared.textColor))
.padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 20))
}
.font(.system(size: 14))
})
.sheet(isPresented: $showPushCertificate) {
if let url = URL(string: NCBrandOptions.shared.pushNotificationServerProxy), let host = url.host {
certificateDetailsView(host: host, title: NSLocalizedString("_certificate_pn_view_", comment: ""))
///
/// Certificate push
Button(action: {
showPushCertificate.toggle()
}, label: {
HStack {
Image(systemName: "lock")
.resizable()
.scaledToFit()
.font(Font.system(.body).weight(.light))
.frame(width: 20, height: 20)
.foregroundStyle(Color(NCBrandColor.shared.iconImageColor))
Text(NSLocalizedString("_certificate_pn_details_", comment: ""))
.lineLimit(1)
.truncationMode(.middle)
.foregroundStyle(Color(NCBrandColor.shared.textColor))
.padding(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 20))
}
.font(.system(size: 14))
})
.sheet(isPresented: $showPushCertificate) {
if let url = URL(string: NCBrandOptions.shared.pushNotificationServerProxy), let host = url.host {
certificateDetailsView(host: host, title: NSLocalizedString("_certificate_pn_view_", comment: ""))
}
}
}
})

Просмотреть файл

@ -458,7 +458,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
let account: String = "\(user) \(urlBase)"
NextcloudKit.shared.setup(account: account, user: user, userId: user, password: password, urlBase: urlBase, groupIdentifier: NCBrandOptions.shared.capabilitiesGroup)
NextcloudKit.shared.getUserProfile { _, userProfile, _, error in
NextcloudKit.shared.getUserProfile { account, userProfile, _, error in
if error == .success, let userProfile {
NCManageDatabase.shared.deleteAccount(account)
NCManageDatabase.shared.addAccount(account, urlBase: urlBase, user: user, userId: userProfile.userId, password: password)

Просмотреть файл

@ -407,4 +407,16 @@ extension NCManageDatabase {
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Could not write to database: \(error)")
}
}
func getAccountGroups(account: String) -> [String] {
do {
let realm = try Realm()
if let result = realm.objects(tableAccount.self).filter("account == %@", account).first {
return result.groups.components(separatedBy: ",")
}
} catch let error as NSError {
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Could not access database: \(error)")
}
return []
}
}

Просмотреть файл

@ -40,17 +40,47 @@ class NCManageDatabase: NSObject {
let utilityFileSystem = NCUtilityFileSystem()
override init() {
let dirGroup = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: NCBrandOptions.shared.capabilitiesGroup)
let databaseFileUrlPath = dirGroup?.appendingPathComponent(NCGlobal.shared.appDatabaseNextcloud + "/" + databaseName)
if let databaseFilePath = databaseFileUrlPath?.path {
if FileManager.default.fileExists(atPath: databaseFilePath) {
NextcloudKit.shared.nkCommonInstance.writeLog("[INFO] DATABASE FOUND in " + databaseFilePath)
} else {
NextcloudKit.shared.nkCommonInstance.writeLog("[INFO] DATABASE NOT FOUND in " + databaseFilePath)
func migrationSchema(_ migration: Migration, _ oldSchemaVersion: UInt64) {
if oldSchemaVersion < 354 {
migration.deleteData(forType: NCDBLayoutForView.className())
}
}
func compactDB(_ totalBytes: Int, _ usedBytes: Int) -> Bool {
// totalBytes refers to the size of the file on disk in bytes (data + free space)
// usedBytes refers to the number of bytes used by data in the file
// Compact if the file is over 100MB in size and less than 50% 'used'
let oneHundredMB = 100 * 1024 * 1024
return (totalBytes > oneHundredMB) && (Double(usedBytes) / Double(totalBytes)) < 0.5
}
var realm: Realm?
let dirGroup = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: NCBrandOptions.shared.capabilitiesGroup)
let databaseFileUrlPath = dirGroup?.appendingPathComponent(NCGlobal.shared.appDatabaseNextcloud + "/" + databaseName)
let bundleUrl: URL = Bundle.main.bundleURL
let bundlePathExtension: String = bundleUrl.pathExtension
let bundleFileName: String = (bundleUrl.path as NSString).lastPathComponent
let isAppex: Bool = bundlePathExtension == "appex"
var objectTypesAppex = [tableMetadata.self,
tableLocalFile.self,
tableDirectory.self,
tableTag.self,
tableAccount.self,
tableCapabilities.self,
tablePhotoLibrary.self,
tableE2eEncryption.self,
tableE2eEncryptionLock.self,
tableE2eMetadata12.self,
tableE2eMetadata.self,
tableE2eUsers.self,
tableE2eCounter.self,
tableShare.self,
tableChunk.self,
tableAvatar.self,
tableDashboardWidget.self,
tableDashboardWidgetButton.self,
NCDBLayoutForView.self,
TableSecurityGuardDiagnostics.self]
// Disable file protection for directory DB
// https://docs.mongodb.com/realm/sdk/ios/examples/configure-and-open-a-realm/#std-label-ios-open-a-local-realm
if let folderPathURL = dirGroup?.appendingPathComponent(NCGlobal.shared.appDatabaseNextcloud) {
@ -62,61 +92,49 @@ class NCManageDatabase: NSObject {
}
}
do {
_ = try Realm(configuration: Realm.Configuration(
fileURL: databaseFileUrlPath,
schemaVersion: databaseSchemaVersion,
migrationBlock: { migration, oldSchemaVersion in
if oldSchemaVersion < 354 {
migration.deleteData(forType: NCDBLayoutForView.className())
}
}, shouldCompactOnLaunch: { totalBytes, usedBytes in
// totalBytes refers to the size of the file on disk in bytes (data + free space)
// usedBytes refers to the number of bytes used by data in the file
// Compact if the file is over 100MB in size and less than 50% 'used'
let oneHundredMB = 100 * 1024 * 1024
return (totalBytes > oneHundredMB) && (Double(usedBytes) / Double(totalBytes)) < 0.5
if isAppex {
if bundleFileName == "File Provider Extension.appex" {
objectTypesAppex = [tableMetadata.self,
tableLocalFile.self,
tableDirectory.self,
tableTag.self,
tableAccount.self,
tableCapabilities.self]
}
do {
Realm.Configuration.defaultConfiguration =
Realm.Configuration(fileURL: databaseFileUrlPath,
schemaVersion: databaseSchemaVersion,
migrationBlock: { migration, oldSchemaVersion in
migrationSchema(migration, oldSchemaVersion)
}, shouldCompactOnLaunch: { totalBytes, usedBytes in
compactDB(totalBytes, usedBytes)
}, objectTypes: objectTypesAppex)
realm = try Realm()
if let realm, let url = realm.configuration.fileURL {
print("Realm is located at: \(url)")
}
))
} catch let error {
if let databaseFileUrlPath = databaseFileUrlPath {
do {
#if !EXTENSION
let nkError = NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: error.localizedDescription)
NCContentPresenter().showError(error: nkError, priority: .max)
#endif
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] DATABASE ERROR: \(error.localizedDescription)")
try FileManager.default.removeItem(at: databaseFileUrlPath)
} catch {}
} catch let error {
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] DATABASE ERROR: \(error.localizedDescription)")
}
}
Realm.Configuration.defaultConfiguration = Realm.Configuration(
fileURL: dirGroup?.appendingPathComponent(NCGlobal.shared.appDatabaseNextcloud + "/" + databaseName),
schemaVersion: databaseSchemaVersion
)
// Verify Database, if corrupt remove it
do {
_ = try Realm()
} catch let error {
if let databaseFileUrlPath = databaseFileUrlPath {
do {
#if !EXTENSION
let nkError = NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: error.localizedDescription)
NCContentPresenter().showError(error: nkError, priority: .max)
#endif
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] DATABASE ERROR: \(error.localizedDescription)")
try FileManager.default.removeItem(at: databaseFileUrlPath)
} catch { }
} else {
do {
Realm.Configuration.defaultConfiguration =
Realm.Configuration(fileURL: databaseFileUrlPath,
schemaVersion: databaseSchemaVersion,
migrationBlock: { migration, oldSchemaVersion in
migrationSchema(migration, oldSchemaVersion)
}, shouldCompactOnLaunch: { totalBytes, usedBytes in
compactDB(totalBytes, usedBytes)
})
realm = try Realm()
if let realm, let url = realm.configuration.fileURL {
print("Realm is located at: \(url)")
}
} catch let error {
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] DATABASE ERROR: \(error.localizedDescription)")
}
}
do {
_ = try Realm()
} catch let error as NSError {
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Could not open database: \(error)")
}
}
// MARK: -
@ -184,24 +202,6 @@ class NCManageDatabase: NSObject {
self.clearTable(tableE2eCounter.self, account: account)
}
@objc func removeDB() {
let realmURL = Realm.Configuration.defaultConfiguration.fileURL!
let realmURLs = [
realmURL,
realmURL.appendingPathExtension("lock"),
realmURL.appendingPathExtension("note"),
realmURL.appendingPathExtension("management")
]
for URL in realmURLs {
do {
try FileManager.default.removeItem(at: URL)
} catch let error {
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Could not write to database: \(error)")
}
}
}
func getThreadConfined(_ object: Object) -> Any {
return ThreadSafeReference(to: object)
}

Просмотреть файл

@ -596,13 +596,14 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
let image = utility.loadUserImage(for: appDelegate.user, displayName: activeAccount?.displayName, userBaseUrl: appDelegate)
let accountButton = AccountSwitcherButton(type: .custom)
let accounts = NCManageDatabase.shared.getAllAccountOrderAlias()
var childrenAccountSubmenu: [UIMenuElement] = []
accountButton.setImage(image, for: .normal)
accountButton.setImage(image, for: .highlighted)
accountButton.semanticContentAttribute = .forceLeftToRight
accountButton.sizeToFit()
if !accounts.isEmpty, !NCBrandOptions.shared.disable_multiaccount {
if !accounts.isEmpty {
let accountActions: [UIAction] = accounts.map { account in
let image = utility.loadUserImage(for: account.user, displayName: account.displayName, userBaseUrl: account)
var name: String = ""
@ -637,8 +638,12 @@ class NCCollectionViewCommon: UIViewController, UIGestureRecognizerDelegate, UIS
self.present(accountSettingsController, animated: true, completion: nil)
}
let addAccountSubmenu = UIMenu(title: "", options: .displayInline, children: [addAccountAction, settingsAccountAction])
if !NCBrandOptions.shared.disable_multiaccount {
childrenAccountSubmenu.append(addAccountAction)
}
childrenAccountSubmenu.append(settingsAccountAction)
let addAccountSubmenu = UIMenu(title: "", options: .displayInline, children: childrenAccountSubmenu)
let menu = UIMenu(children: accountActions + [addAccountSubmenu])
accountButton.menu = menu

Просмотреть файл

@ -485,4 +485,8 @@ class NCGlobal: NSObject {
// DRAG & DROP
//
let metadataOcIdDataRepresentation = "text/com.nextcloud.ocId"
// GROUP AMIN
//
let groupAdmin = "admin"
}

Просмотреть файл

@ -33,6 +33,8 @@ class NCSettingsAdvancedModel: ObservableObject, ViewOnAppearHandling {
let appDelegate = (UIApplication.shared.delegate as? AppDelegate)!
/// Keychain access
var keychain = NCKeychain()
/// State variable for indicating if the user is in Admin group
@Published var isAdminGroup: Bool = false
/// State variable for indicating whether hidden files are shown.
@Published var showHiddenFiles: Bool = false
/// State variable for indicating the most compatible format.
@ -65,6 +67,8 @@ class NCSettingsAdvancedModel: ObservableObject, ViewOnAppearHandling {
/// Triggered when the view appears.
func onViewAppear() {
let groups = NCManageDatabase.shared.getAccountGroups(account: appDelegate.account)
isAdminGroup = groups.contains(NCGlobal.shared.groupAdmin)
showHiddenFiles = keychain.showHiddenFiles
mostCompatible = keychain.formatCompatibility
livePhoto = keychain.livePhoto
@ -73,6 +77,7 @@ class NCSettingsAdvancedModel: ObservableObject, ViewOnAppearHandling {
crashReporter = keychain.disableCrashservice
selectedLogLevel = LogLevel(rawValue: keychain.logLevel) ?? .standard
selectedInterval = CacheDeletionInterval(rawValue: keychain.cleanUpDay) ?? .never
DispatchQueue.global().async {
self.calculateSize()
}

Просмотреть файл

@ -182,26 +182,28 @@ struct NCSettingsAdvancedView: View {
Text(NSLocalizedString("_diagnostics_", comment: ""))
}, footer: { })
/// Set Log Level() & Capabilities
Section(content: {
NavigationLink(destination: LazyView {
NCCapabilitiesView(model: NCCapabilitiesModel())
}) {
HStack {
Image(systemName: "list.bullet")
.resizable()
.scaledToFit()
.font(Font.system(.body).weight(.light))
.frame(width: 25, height: 25)
.foregroundColor(Color(NCBrandColor.shared.iconImageColor))
Text(NSLocalizedString("_capabilities_", comment: ""))
if model.isAdminGroup {
Section(content: {
NavigationLink(destination: LazyView {
NCCapabilitiesView(model: NCCapabilitiesModel())
}) {
HStack {
Image(systemName: "list.bullet")
.resizable()
.scaledToFit()
.font(Font.system(.body).weight(.light))
.frame(width: 25, height: 25)
.foregroundColor(Color(NCBrandColor.shared.iconImageColor))
Text(NSLocalizedString("_capabilities_", comment: ""))
}
.font(.system(size: 16))
}
.font(.system(size: 16))
}
}, header: {
Text(NSLocalizedString("_capabilities_", comment: ""))
}, footer: {
Text(NSLocalizedString("_capabilities_footer_", comment: ""))
})
}, header: {
Text(NSLocalizedString("_capabilities_", comment: ""))
}, footer: {
Text(NSLocalizedString("_capabilities_footer_", comment: ""))
})
}
}
/// Delete in Cache & Clear Cache
Section(content: {

Двоичный файл не отображается.

Двоичный файл не отображается.

Просмотреть файл

@ -108,7 +108,7 @@ class NCContentPresenter: NSObject {
DispatchQueue.main.asyncAfter(deadline: .now() + afterDelay) {
switch error.errorCode {
case Int(CFNetworkErrors.cfurlErrorNotConnectedToInternet.rawValue):
let image = UIImage(named: "InfoNetwork")!.image(color: .white, size: 20)
let image = UIImage(named: "InfoNetwork")?.image(color: .white, size: 20)
self.noteTop(text: NSLocalizedString(title, comment: ""), image: image, color: .lightGray, delay: delay, priority: .max)
default:
var responseMessage = ""