Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
63f2996
nmc 2023 - privacy policy localization changes added
TSI-amrutwaghmare May 10, 2023
23a1824
NMC 2023 german translation update (+35 squashed commits)
TSI-amrutwaghmare May 10, 2023
177e438
nmc 2023 - scan cluster localisation changes
TSI-amrutwaghmare May 19, 2023
12f677d
nmc 2023 - sharing feature localisation strings update
TSI-amrutwaghmare Jun 6, 2023
023090b
nmc 2023 - localisation update for share text field
TSI-amrutwaghmare Jun 7, 2023
51a0114
NMC 2023 - update missing localised strings for german languages
TSI-amrutwaghmare Feb 27, 2024
a77ce68
nmc 2023 - privacy policy localization changes added
TSI-amrutwaghmare May 10, 2023
2ed5019
NMC 1990 Settings cluster Localization strings added
TSI-shwetawaikar May 11, 2023
e9389e3
nmc 2023 - sharing feature localisation strings update
TSI-amrutwaghmare Jun 6, 2023
bb78b01
nmc 2023 - localisation update for share text field
TSI-amrutwaghmare Jun 7, 2023
0497742
nmc 2023 - more tab localisation changes
TSI-amrutwaghmare Jun 9, 2023
d1db539
nmc 2023 - image video upload localisation related changes
TSI-amrutwaghmare Jun 12, 2023
6e959ca
NMC 2023 "Details" string changed
TSI-shwetawaikar Jun 23, 2023
a610c2c
NMC 2023 - share strings update
TSI-amrutwaghmare Jun 24, 2023
0953aee
NMC 2023 - Localisation changes for auto upload description
TSI-amrutwaghmare Dec 26, 2023
2cbe06e
NMC 2023 - update missing localised strings for german languages
TSI-amrutwaghmare Feb 27, 2024
e071b81
NMC 2023 german translation update
TSI-amrutwaghmare Aug 26, 2024
90bde3b
NMC 2023 - update missing localised strings for english and german la…
harshada-15-tsys Apr 7, 2025
e14dbfb
NMC 2023 - Updated missing localised strings for English and DE language
harshada-15-tsys Apr 16, 2025
c16e7f2
NMC-2023 - Localizations for EN and DE updated for New sharing design…
harshada-15-tsys Sep 30, 2025
2b5957d
NMC 2023 german translation update (+35 squashed commits)
TSI-amrutwaghmare May 10, 2023
3276e69
nmc 2023 - sharing feature localisation strings update
TSI-amrutwaghmare Jun 6, 2023
0306c8d
nmc 2023 - localisation update for share text field
TSI-amrutwaghmare Jun 7, 2023
e91450d
NMC 2023 - update missing localised strings for german languages
TSI-amrutwaghmare Feb 27, 2024
c651fb3
nmc 2023 - privacy policy localization changes added
TSI-amrutwaghmare May 10, 2023
66fa9ac
nmc 2023 - sharing feature localisation strings update
TSI-amrutwaghmare Jun 6, 2023
4fda847
nmc 2023 - localisation update for share text field
TSI-amrutwaghmare Jun 7, 2023
281f9aa
nmc 2023 - more tab localisation changes
TSI-amrutwaghmare Jun 9, 2023
d09d392
nmc 2023 - image video upload localisation related changes
TSI-amrutwaghmare Jun 12, 2023
ff2c15e
NMC 2023 "Details" string changed
TSI-shwetawaikar Jun 23, 2023
5740119
NMC 2023 - share strings update
TSI-amrutwaghmare Jun 24, 2023
97e6ce7
NMC 2023 - Localisation changes for auto upload description
TSI-amrutwaghmare Dec 26, 2023
27f3e6a
NMC 2023 - update missing localised strings for german languages
TSI-amrutwaghmare Feb 27, 2024
a7c2bb9
NMC 2023 german translation update
TSI-amrutwaghmare Aug 26, 2024
5c51dbd
NMC 2023 - update missing localised strings for english and german la…
harshada-15-tsys Apr 7, 2025
b48ebc9
NMC 2023 - Updated missing localised strings for English and DE language
harshada-15-tsys Apr 16, 2025
b263f0b
NMC-2023 - Localizations for EN and DE updated for New sharing design…
harshada-15-tsys Sep 30, 2025
f347afd
NMC 2023 - Localisation changes
harshada-15-tsys Dec 17, 2025
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 @@ -344,6 +371,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 @@ -918,6 +956,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 @@ -269,6 +303,7 @@ final class NCGlobal: Sendable {
let notificationCenterUserInteractionMonitor = "serInteractionMonitor"

let notificationCenterNetworkingProcess = "networkingProcess"
let notificationCenterFavoriteStatusChanged = "favoriteStatusChanged"

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

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

// TIP
//
Expand Down Expand Up @@ -367,6 +403,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