Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
ed55f41
nmc 2023 - privacy policy localization changes added
TSI-amrutwaghmare May 10, 2023
6960f43
NMC 2023 german translation update (+35 squashed commits)
TSI-amrutwaghmare May 10, 2023
880dca2
nmc 2023 - scan cluster localisation changes
TSI-amrutwaghmare May 19, 2023
70f885c
nmc 2023 - sharing feature localisation strings update
TSI-amrutwaghmare Jun 6, 2023
056d93f
nmc 2023 - localisation update for share text field
TSI-amrutwaghmare Jun 7, 2023
6534c57
NMC 2023 - update missing localised strings for german languages
TSI-amrutwaghmare Feb 27, 2024
f9d119d
nmc 2023 - privacy policy localization changes added
TSI-amrutwaghmare May 10, 2023
dd5362b
NMC 1990 Settings cluster Localization strings added
TSI-shwetawaikar May 11, 2023
0e0b0b1
nmc 2023 - sharing feature localisation strings update
TSI-amrutwaghmare Jun 6, 2023
7614890
nmc 2023 - localisation update for share text field
TSI-amrutwaghmare Jun 7, 2023
3eb4c4a
nmc 2023 - more tab localisation changes
TSI-amrutwaghmare Jun 9, 2023
eee74a4
nmc 2023 - image video upload localisation related changes
TSI-amrutwaghmare Jun 12, 2023
a1aaf2e
NMC 2023 "Details" string changed
TSI-shwetawaikar Jun 23, 2023
58f4586
NMC 2023 - share strings update
TSI-amrutwaghmare Jun 24, 2023
c0a01fd
NMC 2023 - Localisation changes for auto upload description
TSI-amrutwaghmare Dec 26, 2023
f4b2fbb
NMC 2023 - update missing localised strings for german languages
TSI-amrutwaghmare Feb 27, 2024
58490bb
NMC 2023 german translation update
TSI-amrutwaghmare Aug 26, 2024
b98c965
NMC 2023 - update missing localised strings for english and german la…
harshada-15-tsys Apr 7, 2025
e0bc2bc
NMC 2023 - Updated missing localised strings for English and DE language
harshada-15-tsys Apr 16, 2025
01eb708
NMC-2023 - Localizations for EN and DE updated for New sharing design…
harshada-15-tsys Sep 30, 2025
97471df
NMC 2023 german translation update (+35 squashed commits)
TSI-amrutwaghmare May 10, 2023
cefdeaf
nmc 2023 - sharing feature localisation strings update
TSI-amrutwaghmare Jun 6, 2023
75b6fd6
nmc 2023 - localisation update for share text field
TSI-amrutwaghmare Jun 7, 2023
4eb814a
NMC 2023 - update missing localised strings for german languages
TSI-amrutwaghmare Feb 27, 2024
d2eb780
nmc 2023 - privacy policy localization changes added
TSI-amrutwaghmare May 10, 2023
73a80e9
nmc 2023 - sharing feature localisation strings update
TSI-amrutwaghmare Jun 6, 2023
b75b71c
nmc 2023 - localisation update for share text field
TSI-amrutwaghmare Jun 7, 2023
4e35bef
nmc 2023 - more tab localisation changes
TSI-amrutwaghmare Jun 9, 2023
1beccd0
nmc 2023 - image video upload localisation related changes
TSI-amrutwaghmare Jun 12, 2023
4dfe8bd
NMC 2023 "Details" string changed
TSI-shwetawaikar Jun 23, 2023
a841546
NMC 2023 - share strings update
TSI-amrutwaghmare Jun 24, 2023
3c0b687
NMC 2023 - Localisation changes for auto upload description
TSI-amrutwaghmare Dec 26, 2023
1eae16e
NMC 2023 - update missing localised strings for german languages
TSI-amrutwaghmare Feb 27, 2024
5b1761b
NMC 2023 german translation update
TSI-amrutwaghmare Aug 26, 2024
2939802
NMC 2023 - update missing localised strings for english and german la…
harshada-15-tsys Apr 7, 2025
a7a6fa6
NMC 2023 - Updated missing localised strings for English and DE language
harshada-15-tsys Apr 16, 2025
cd6e136
NMC-2023 - Localizations for EN and DE updated for New sharing design…
harshada-15-tsys Sep 30, 2025
78b2d80
NMC 2023 - Localisation changes
harshada-15-tsys Dec 17, 2025
6f5af23
NMC 2023 - Localisation updated changes
harshada-15-tsys Jun 17, 2026
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
4 changes: 2 additions & 2 deletions File Provider Extension/FileProviderData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class FileProviderData: NSObject {
case workingSet
}

// MARK: -
// MARK: -

@discardableResult
func setupAccount(domain: NSFileProviderDomain? = nil,
Expand Down Expand Up @@ -173,7 +173,7 @@ class FileProviderData: NSObject {

if error == .success {
if let metadata = await NCManageDatabase.shared.getMetadataFromOcIdAsync(ocId) {
await NCManageDatabase.shared.addLocalFilesAsync(metadatas: [metadata])
await NCManageDatabase.shared.addLocalFileAsync(metadata: metadata)
}
}

Expand Down
61 changes: 23 additions & 38 deletions iOSClient/Data/NCManageDatabase+LocalFile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,50 +29,35 @@ extension NCManageDatabase {

// MARK: - Realm Write

/// Adds or updates multiple local file entries corresponding to the given metadata array.
/// Uses async Realm read + single write transaction. Assumes `tableLocalFile` has a primary key.
/// - Parameters:
/// - metadatas: Array of `tableMetadata` to map into `tableLocalFile`.
/// - offline: Optional override for the `offline` flag applied to all items.
func addLocalFilesAsync(metadatas: [tableMetadata], offline: Bool? = nil) async {
guard !metadatas.isEmpty else {
return
}

// Extract ocIds for efficient lookup
let ocIds = metadatas.compactMap { $0.ocId }
guard !ocIds.isEmpty else {
return
/// - metadata: The `tableMetadata` containing file details.
/// - offline: Optional flag to mark the file as available offline.
/// - Returns: Nothing. Realm write is performed asynchronously.
func addLocalFileAsync(metadata: tableMetadata, offline: Bool? = nil) async {
// Read (non-blocking): safely detach from Realm thread
let existing: tableLocalFile? = performRealmRead { realm in
realm.objects(tableLocalFile.self)
.filter(NSPredicate(format: "ocId == %@", metadata.ocId))
.first
.map { tableLocalFile(value: $0) }
}

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

await core.performRealmWriteAsync { realm in
for metadata in metadatas {
// Reuse existing object or create a new one
let local = existingMap[metadata.ocId] ?? tableLocalFile()

local.account = metadata.account
local.etag = metadata.etag
local.exifDate = NSDate()
local.exifLatitude = "-1"
local.exifLongitude = "-1"
local.ocId = metadata.ocId
local.fileName = metadata.fileName

if let offline {
local.offline = offline
}
addObject.account = metadata.account
addObject.etag = metadata.etag
addObject.exifDate = NSDate()
addObject.exifLatitude = "-1"
addObject.exifLongitude = "-1"
addObject.ocId = metadata.ocId
addObject.fileName = metadata.fileName

realm.add(local, update: .all)
if let offline {
addObject.offline = offline
}

realm.add(addObject, update: .all)
}
}

Expand Down
66 changes: 66 additions & 0 deletions iOSClient/Data/NCManageDatabase+Metadata.swift
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,37 @@ extension tableMetadata {
(fileNameView as NSString).deletingPathExtension
}

var isRenameable: Bool {
if !NCMetadataPermissions.canRename(self) {
return false
}
if lock {
return false
}
if !isDirectoryE2EE && e2eEncrypted {
return false
}
return true
}

var isPrintable: Bool {
if isDocumentViewableOnly {
return false
}
if ["application/pdf", "com.adobe.pdf"].contains(contentType) || contentType.hasPrefix("text/") || classFile == NKTypeClassFile.image.rawValue {
return true
}
return false
}

var isSavebleInCameraRoll: Bool {
return (classFile == NKTypeClassFile.image.rawValue && contentType != "image/svg+xml") || classFile == NKTypeClassFile.video.rawValue
}

var isDocumentViewableOnly: Bool {
sharePermissionsCollaborationServices == NCPermissions().permissionReadShare && classFile == NKTypeClassFile.document.rawValue
}

var isAudioOrVideo: Bool {
return classFile == NKTypeClassFile.audio.rawValue || classFile == NKTypeClassFile.video.rawValue
}
Expand Down Expand Up @@ -343,6 +370,17 @@ extension tableMetadata {
return !lock || (lockOwner == user && lockOwnerType == 0)
}

// Return if is sharable
func isSharable() -> Bool {
guard let capabilities = NCNetworking.shared.capabilities[account] else {
return false
}
if !capabilities.fileSharingApiEnabled || (capabilities.e2EEEnabled && isDirectoryE2EE), !e2eEncrypted {
return false
}
return !e2eEncrypted
}

/// Returns a detached (unmanaged) deep copy of the current `tableMetadata` object.
///
/// - Note: Primitive properties and lists of primitive values (for example `shareType`)
Expand Down Expand Up @@ -917,6 +955,34 @@ extension NCManageDatabase {
.map { $0.detachedCopy() }
} ?? []
}

func getMediaMetadatas(predicate: NSPredicate, sorted: String? = nil, ascending: Bool = false) -> ThreadSafeArray<tableMetadata>? {

do {
let realm = try Realm()
if let sorted {
var results: [tableMetadata] = []
switch sorted {//NCPreferences().mediaSortDate {
case "date":
results = realm.objects(tableMetadata.self).filter(predicate).sorted { ($0.date as Date) > ($1.date as Date) }
case "creationDate":
results = realm.objects(tableMetadata.self).filter(predicate).sorted { ($0.creationDate as Date) > ($1.creationDate as Date) }
case "uploadDate":
results = realm.objects(tableMetadata.self).filter(predicate).sorted { ($0.uploadDate as Date) > ($1.uploadDate as Date) }
default:
let results = realm.objects(tableMetadata.self).filter(predicate)
return ThreadSafeArray(results.map { tableMetadata.init(value: $0) })
}
return ThreadSafeArray(results.map { tableMetadata.init(value: $0) })
} else {
let results = realm.objects(tableMetadata.self).filter(predicate)
return ThreadSafeArray(results.map { tableMetadata.init(value: $0) })
}
} catch let error as NSError {
// NextcloudKit.shared.nkCommonInstance.writeLog("Could not access database: \(error)")
}
return nil
}

func getMetadatas(predicate: NSPredicate,
sortedByKeyPath: String,
Expand Down
19 changes: 8 additions & 11 deletions iOSClient/NCBackgroundLocationUploadManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -102,22 +102,19 @@ class NCBackgroundLocationUploadManager: NSObject, CLLocationManagerDelegate {
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// Must work only in background
guard isAppInBackground else {
return
}

// Open Realm
guard NCManageDatabase.shared.openRealmBackground() else {
nkLog(tag: self.global.logTagLocation, emoji: .error, message: "Failed to open Realm in Location Manager")
return
}

let location = locations.last
nkLog(tag: self.global.logTagLocation, emoji: .start, message: "Triggered by location change: \(location?.coordinate.latitude ?? 0), \(location?.coordinate.longitude ?? 0)")

Task.detached {
await NCAutoUpload.shared.autoUploadBackgroundSync()
if database.openRealmBackground() {
let appDelegate = (UIApplication.shared.delegate as? AppDelegate)!
let location = locations.last
nkLog(tag: self.global.logTagLocation, emoji: .start, message: "Triggered by location change: \(location?.coordinate.latitude ?? 0), \(location?.coordinate.longitude ?? 0)")

Task.detached {
await NCAutoUpload.shared.autoUploadBackgroundSync()
}
}
}

Expand Down
56 changes: 53 additions & 3 deletions iOSClient/NCGlobal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,14 @@ final class NCGlobal: Sendable {
// Intro selector
//
let introLogin: Int = 0
let introSignup: Int = 1
let introSignUpWithProvider: Int = 1

// Avatar
//
let avatarSize: Int = 128 * Int(UIScreen.main.scale)
let avatarSizeRounded: Int = 128

// Preview size
//
let size1024: CGSize = CGSize(width: 1024, height: 1024)
Expand Down Expand Up @@ -113,7 +114,35 @@ final class NCGlobal: Sendable {
//
let buttonMoreMore = "more"
let buttonMoreLock = "moreLock"

let buttonMoreStop = "stop"

// Standard height sections header/footer
//
let heightButtonsView: CGFloat = 50
let heightHeaderTransfer: CGFloat = 50
let heightSection: CGFloat = 30
let heightFooter: CGFloat = 1
let heightFooterButton: CGFloat = 30
let endHeightFooter: CGFloat = 85


// Text - OnlyOffice - Collabora - QuickLook
//
let editorText = "text"
let editorOnlyoffice = "onlyoffice"
let editorCollabora = "collabora"
let editorQuickLook = "quicklook"

let onlyofficeDocx = "onlyoffice_docx"
let onlyofficeXlsx = "onlyoffice_xlsx"
let onlyofficePptx = "onlyoffice_pptx"

// Template
//
let templateDocument = "document"
let templateSpreadsheet = "spreadsheet"
let templatePresentation = "presentation"

// Rich Workspace
//
let fileNameRichWorkspace = "Readme.md"
Expand Down Expand Up @@ -198,6 +227,8 @@ final class NCGlobal: Sendable {
let selectorSaveAsScan = "saveAsScan"
let selectorOpenDetail = "openDetail"
let selectorSynchronizationOffline = "synchronizationOffline"
let selectorPrint = "print"
let selectorDeleteFile = "deleteFile"

// Metadata : Status
//
Expand Down Expand Up @@ -228,7 +259,6 @@ final class NCGlobal: Sendable {
let metadataStatusForScreenAwake = [-1, -2, 1, 2]
let metadataStatusHideInView = [1, 2, 3, 11]
let metadataStatusWaitWebDav = [10, 11, 12, 13, 14, 15]
let metadataStatusTransfers = [-2, -3, 2, 3, 10, 11, 12, 13, 14, 15]

let metadatasStatusInWaiting = [-1, 1, 10, 11, 12, 13, 14, 15]
let metadatasStatusInWaitingDownloadUpload = [-1, 1]
Expand All @@ -246,13 +276,17 @@ final class NCGlobal: Sendable {
let notificationCenterChangeTheming = "changeTheming" // userInfo: account
let notificationCenterRichdocumentGrabFocus = "richdocumentGrabFocus"
let notificationCenterReloadDataNCShare = "reloadDataNCShare"
let notificationCenterDidCreateShareLink = "didCreateShareLink"

let notificationCenterCloseRichWorkspaceWebView = "closeRichWorkspaceWebView"
let notificationCenterReloadAvatar = "reloadAvatar"
let notificationCenterClearCache = "clearCache"
let notificationCenterCheckUserDelaultErrorDone = "checkUserDelaultErrorDone" // userInfo: account, controller
let notificationCenterServerDidUpdate = "serverDidUpdate" // userInfo: account
let notificationCenterNetworkReachability = "networkReachability"

let notificationCenterRenameFile = "renameFile" // userInfo: serverUrl, account, error

let notificationCenterMenuSearchTextPDF = "menuSearchTextPDF"
let notificationCenterMenuGotToPageInPDF = "menuGotToPageInPDF"

Expand All @@ -270,6 +304,7 @@ final class NCGlobal: Sendable {

let notificationCenterNetworkingProcess = "networkingProcess"
let notificationCenterTransferCountChanged = "transferCountChanged"
let notificationCenterFavoriteStatusChanged = "favoriteStatusChanged"

// Networking Status
let networkingStatusCreateFolder = "statusCreateFolder"
Expand All @@ -286,6 +321,7 @@ final class NCGlobal: Sendable {
let networkingStatusUploaded = "statusUploaded"

let networkingStatusReloadAvatar = "statusReloadAvatar"
let notificationCenterUpdateIcons = "updateIcons"

// TIP
//
Expand Down Expand Up @@ -368,6 +404,20 @@ final class NCGlobal: Sendable {
//
let taskDescriptionRetrievesProperties = "retrievesProperties"
let taskDescriptionSynchronization = "synchronization"
let taskDescriptionDeleteFileOrFolder = "deleteFileOrFolder"

// MoEngage App Version
//
let moEngageAppVersion = 854

// Filename Mask and Type
//
let keyFileNameMask = "fileNameMask"
let keyFileNameType = "fileNameType"
let keyFileNameAutoUploadMask = "fileNameAutoUploadMask"
let keyFileNameAutoUploadType = "fileNameAutoUploadType"
let keyFileNameOriginal = "fileNameOriginal"
let keyFileNameOriginalAutoUpload = "fileNameOriginalAutoUpload"

// LOG TAG
//
Expand Down
1 change: 1 addition & 0 deletions iOSClient/Networking/E2EE/NCNetworkingE2EEUpload.swift
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ class NCNetworkingE2EEUpload: NSObject {

await self.database.addMetadataAsync(metadata)
await self.database.addLocalFilesAsync(metadatas: [metadata])
// await self.database.addLocalFileAsync(metadata: metadata)

utility.createImageFileFrom(metadata: metadata)

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

import Foundation
import UIKit
Expand Down
Loading
Loading