Skip to content

Commit

Permalink
Version 6.2.3 (#3274)
Browse files Browse the repository at this point in the history
  • Loading branch information
marinofaggiana authored Jan 17, 2025
1 parent 5142d4a commit fe920b4
Show file tree
Hide file tree
Showing 144 changed files with 1,075 additions and 482 deletions.
1 change: 1 addition & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ disabled_rules:
- type_name
- void_function_in_ternary
- switch_case_alignment
- unavailable_condition
excluded:
- Carthage
- Pods
Expand Down
2 changes: 1 addition & 1 deletion Brand/Database.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ import Foundation
// Database Realm
//
let databaseName = "nextcloud.realm"
let databaseSchemaVersion: UInt64 = 367
let databaseSchemaVersion: UInt64 = 370
1 change: 1 addition & 0 deletions Brand/NCBrand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ let userAgent: String = {
var doNotAskPasscodeAtStartup: Bool = false
var disable_source_code_in_settings: Bool = false
var enforce_passcode_lock = false
var use_in_app_browser_for_login = false

// (name: "Name 1", url: "https://cloud.nextcloud.com"),(name: "Name 2", url: "https://cloud.nextcloud.com")
var enforce_servers: [(name: String, url: String)] = []
Expand Down
68 changes: 56 additions & 12 deletions Nextcloud.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions iOSClient/Data/NCManageDatabase+Capabilities.swift
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ extension NCManageDatabase {
let groupfolders: GroupFolders?
let securityguard: SecurityGuard?
let assistant: Assistant?
let recommendations: Recommendations?

enum CodingKeys: String, CodingKey {
case filessharing = "files_sharing"
Expand All @@ -110,6 +111,7 @@ extension NCManageDatabase {
case external, groupfolders
case securityguard = "security_guard"
case assistant
case recommendations
}

struct FilesSharing: Codable {
Expand Down Expand Up @@ -280,6 +282,10 @@ extension NCManageDatabase {
let enabled: Bool?
let version: String?
}

struct Recommendations: Codable {
let enabled: Bool?
}
}
}
}
Expand Down Expand Up @@ -383,6 +389,9 @@ extension NCManageDatabase {
capabilities.capabilityForbiddenFileNameCharacters = data.capabilities.files?.forbiddenFileNameCharacters ?? []
capabilities.capabilityForbiddenFileNameExtensions = data.capabilities.files?.forbiddenFileNameExtensions ?? []

// TODO: not yet available (IN TEST)

Check warning on line 392 in iOSClient/Data/NCManageDatabase+Capabilities.swift

View workflow job for this annotation

GitHub Actions / Lint

Todo Violation: TODOs should be resolved (not yet available (IN TEST)) (todo)
// capabilities.capabilityRecommendations = data.capabilities.recommendations?.enabled ?? false

NCCapabilities.shared.appendCapabilities(account: account, capabilities: capabilities)

return capabilities
Expand Down
71 changes: 71 additions & 0 deletions iOSClient/Data/NCManageDatabase+RecommendedFiles.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// SPDX-FileCopyrightText: Nextcloud GmbH
// SPDX-FileCopyrightText: 2024 Marino Faggiana
// SPDX-License-Identifier: GPL-3.0-or-later

import Foundation
import RealmSwift
import NextcloudKit

class tableRecommendedFiles: Object {
@Persisted var account = ""
@Persisted var id = ""
@Persisted(primaryKey: true) var primaryKey = ""
@Persisted var timestamp: Date?
@Persisted var name: String = ""
@Persisted var directory: String = ""
@Persisted var extensionType: String = ""
@Persisted var mimeType: String = ""
@Persisted var hasPreview: Bool = false
@Persisted var reason: String = ""

convenience init(account: String, id: String, timestamp: Date?, name: String, directory: String, extensionType: String, mimeType: String, hasPreview: Bool, reason: String) {
self.init()

self.account = account
self.id = id
self.primaryKey = account + id
self.timestamp = timestamp
self.name = name
self.directory = directory
self.extensionType = extensionType
self.mimeType = mimeType
self.hasPreview = hasPreview
self.reason = reason
}
}

extension NCManageDatabase {
func createRecommendedFiles(account: String, recommendations: [NKRecommendation]) {
do {
let realm = try Realm()

try realm.write {
// Removed all objct for account
let results = realm.objects(tableRecommendedFiles.self).filter("account == %@", account)

realm.delete(results)

// Added the new recommendations
for recommendation in recommendations {
let recommendedFile = tableRecommendedFiles(account: account, id: recommendation.id, timestamp: recommendation.timestamp, name: recommendation.name, directory: recommendation.directory, extensionType: recommendation.extensionType, mimeType: recommendation.mimeType, hasPreview: recommendation.hasPreview, reason: recommendation.reason)
realm.add(recommendedFile)
}
}
} catch let error {
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Could not write to database: \(error)")
}
}

func getRecommendedFiles(account: String) -> [tableRecommendedFiles] {
do {
let realm = try Realm()
let results = realm.objects(tableRecommendedFiles.self).filter("account == %@", account)

return Array(results.map { tableRecommendedFiles.init(value: $0) })
} catch let error {
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Could not access database: \(error)")
}

return []
}
}
1 change: 1 addition & 0 deletions iOSClient/Data/NCManageDatabase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ class NCManageDatabase: NSObject {
self.clearTable(tableTrash.self, account: account)
self.clearTable(tableUserStatus.self, account: account)
self.clearTable(tableVideo.self, account: account)
self.clearTable(tableRecommendedFiles.self, account: account)
}

func clearTablesE2EE(account: String?) {
Expand Down
40 changes: 40 additions & 0 deletions iOSClient/Extensions/UIButton+Extension.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// UIButton+Extension.swift
// Nextcloud
//
// Created by Milen Pivchev on 17.12.24.
// Copyright © 2024 Marino Faggiana. All rights reserved.
//

extension UIButton {
func hideButtonAndShowSpinner(tint: UIColor = .white) {
self.isHidden = true

let spinnerTag = Int(bitPattern: Unmanaged.passUnretained(self).toOpaque())
if self.superview?.subviews.first(where: { view -> Bool in
return view.isKind(of: UIActivityIndicatorView.self) && view.tag == spinnerTag
}) != nil {
return
}

let spinner = UIActivityIndicatorView(style: .medium)
spinner.tag = spinnerTag
spinner.color = tint
spinner.startAnimating()
spinner.center = self.center
self.superview?.addSubview(spinner)
spinner.translatesAutoresizingMaskIntoConstraints = false
spinner.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
spinner.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
}

func hideSpinnerAndShowButton() {
let spinnerTag = Int(bitPattern: Unmanaged.passUnretained(self).toOpaque())
let spinner = self.superview?.subviews.first(where: { view -> Bool in
return view.isKind(of: UIActivityIndicatorView.self) && view.tag == spinnerTag
})

spinner?.removeFromSuperview()
self.isHidden = false
}
}
89 changes: 72 additions & 17 deletions iOSClient/Files/NCFiles.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,10 @@ import RealmSwift
import SwiftUI

class NCFiles: NCCollectionViewCommon {
internal var isRoot: Bool = true
internal var fileNameBlink: String?
internal var fileNameOpen: String?
internal var matadatasHash: String = ""
internal var reloadDataSourceInProgress: Bool = false
internal var semaphoreReloadDataSource = DispatchSemaphore(value: 1)

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
Expand All @@ -50,7 +49,14 @@ class NCFiles: NCCollectionViewCommon {
override func viewDidLoad() {
super.viewDidLoad()

if isRoot {
if self.serverUrl.isEmpty {

///
/// Set ServerURL when start (isEmpty)
///
self.serverUrl = utilityFileSystem.getHomeServer(session: session)
self.titleCurrentFolder = getNavigationTitle()

NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterChangeUser), object: nil, queue: nil) { notification in

if let userInfo = notification.userInfo, let account = userInfo["account"] as? String {
Expand Down Expand Up @@ -88,10 +94,6 @@ class NCFiles: NCCollectionViewCommon {
}

override func viewWillAppear(_ animated: Bool) {
if isRoot {
serverUrl = utilityFileSystem.getHomeServer(session: session)
titleCurrentFolder = getNavigationTitle()
}
super.viewWillAppear(animated)

reloadDataSource()
Expand Down Expand Up @@ -122,12 +124,16 @@ class NCFiles: NCCollectionViewCommon {
// MARK: - DataSource

override func reloadDataSource() {
guard !isSearchingMode,
!reloadDataSourceInProgress
guard !isSearchingMode
else {
return super.reloadDataSource()
}
reloadDataSourceInProgress = true

// Watchdog: this is only a fail safe "dead lock", I don't think the timeout will ever be called but at least nothing gets stuck, if after 5 sec. (which is a long time in this routine), the semaphore is still locked
//
if self.semaphoreReloadDataSource.wait(timeout: .now() + 5) == .timedOut {
self.semaphoreReloadDataSource.signal()
}

var predicate = self.defaultPredicate
let predicateDirectory = NSPredicate(format: "account == %@ AND serverUrl == %@", session.account, self.serverUrl)
Expand All @@ -145,14 +151,16 @@ class NCFiles: NCCollectionViewCommon {
self.dataSource = NCCollectionViewDataSource(metadatas: metadatas, layoutForView: layoutForView)

if metadatas.isEmpty {
reloadDataSourceInProgress = false
self.semaphoreReloadDataSource.signal()
return super.reloadDataSource()
}

self.dataSource.caching(metadatas: metadatas, dataSourceMetadatas: dataSourceMetadatas) { updated in
self.reloadDataSourceInProgress = false
if updated || self.isNumberOfItemsInAllSectionsNull || self.numberOfItemsInAllSections != metadatas.count {
super.reloadDataSource()
self.semaphoreReloadDataSource.signal()
DispatchQueue.main.async {
if updated || self.isNumberOfItemsInAllSectionsNull || self.numberOfItemsInAllSections != metadatas.count {
super.reloadDataSource()
}
}
}
}
Expand All @@ -178,6 +186,26 @@ class NCFiles: NCCollectionViewCommon {
return false
}

///
/// Recommended files
///
if self.serverUrl == self.utilityFileSystem.getHomeServer(session: self.session),
NCCapabilities.shared.getCapabilities(account: self.session.account).capabilityRecommendations {
let options = NKRequestOptions(queue: NextcloudKit.shared.nkCommonInstance.backgroundQueue)

NextcloudKit.shared.getRecommendedFiles(account: self.session.account, options: options) { _, recommendations, _, error in
if error == .success,
let recommendations,
!recommendations.isEmpty {
Task.detached {
await self.createRecommendations(recommendations)
}
} else {
NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterReloadRecommendedFiles, userInfo: nil)
}
}
}

DispatchQueue.global().async {
self.networkReadFolder { metadatas, isChanged, error in
DispatchQueue.main.async {
Expand Down Expand Up @@ -340,6 +368,33 @@ class NCFiles: NCCollectionViewCommon {
}
}

private func createRecommendations(_ recommendations: [NKRecommendation]) async {
let home = self.utilityFileSystem.getHomeServer(session: self.session)
var recommendationsToInsert: [NKRecommendation] = []

for recommendation in recommendations {
var metadata = database.getResultMetadataFromFileId(recommendation.id)
if metadata == nil || metadata?.fileName != recommendation.name {
let serverUrlFileName = home + recommendation.directory + recommendation.name
let results = await NCNetworking.shared.readFileOrFolder(serverUrlFileName: serverUrlFileName, depth: "0", showHiddenFiles: NCKeychain().showHiddenFiles, account: session.account)

if results.error == .success, let file = results.files?.first {
let isDirectoryE2EE = self.utilityFileSystem.isDirectoryE2EE(file: file)
let metadataConverted = self.database.convertFileToMetadata(file, isDirectoryE2EE: isDirectoryE2EE)
metadata = metadataConverted

self.database.addMetadata(metadataConverted)
recommendationsToInsert.append(recommendation)
}
} else {
recommendationsToInsert.append(recommendation)
}
}

self.database.createRecommendedFiles(account: session.account, recommendations: recommendationsToInsert)
NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterReloadRecommendedFiles, userInfo: nil)
}

// MARK: - NCAccountSettingsModelDelegate

override func accountSettingsDidDismiss(tableAccount: tableAccount?, controller: NCMainTabBarController?) {
Expand All @@ -349,9 +404,9 @@ class NCFiles: NCCollectionViewCommon {
appDelegate.openLogin(selector: NCGlobal.shared.introLogin)
} else if let account = tableAccount?.account, account != currentAccount {
NCAccount().changeAccount(account, userProfile: nil, controller: controller) { }
} else if isRoot {
titleCurrentFolder = getNavigationTitle()
navigationItem.title = titleCurrentFolder
} else if self.serverUrl == self.utilityFileSystem.getHomeServer(session: self.session) {
self.titleCurrentFolder = getNavigationTitle()
navigationItem.title = self.titleCurrentFolder
}

setNavigationLeftItems()
Expand Down
Loading

0 comments on commit fe920b4

Please sign in to comment.