зеркало из https://github.com/nextcloud/ios.git
Version 6.0.0 (#3122)
Signed-off-by: Nextcloud bot <bot@nextcloud.com> Signed-off-by: Marino Faggiana <marino@marinofaggiana.com> Signed-off-by: Milen Pivchev <milen.pivchev@gmail.com> Signed-off-by: rakekniven <2069590+rakekniven@users.noreply.github.com>
This commit is contained in:
Родитель
64ab8f4891
Коммит
574ab7e3a2
|
@ -26,4 +26,4 @@ import Foundation
|
|||
// Database Realm
|
||||
//
|
||||
let databaseName = "nextcloud.realm"
|
||||
let databaseSchemaVersion: UInt64 = 354
|
||||
let databaseSchemaVersion: UInt64 = 365
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
<string>group.it.twsweb.Crypto-Cloud</string>
|
||||
<key>NSExtensionFileProviderSupportsEnumeration</key>
|
||||
<true/>
|
||||
<key>NSExtensionFileProviderSupportsPickingFolders</key>
|
||||
<true/>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.fileprovider-nonui</string>
|
||||
<key>NSExtensionPrincipalClass</key>
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
import UIKit
|
||||
|
||||
class NCIntroViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
|
||||
|
||||
@IBOutlet weak var buttonLogin: UIButton!
|
||||
@IBOutlet weak var buttonSignUp: UIButton!
|
||||
@IBOutlet weak var buttonHost: UIButton!
|
||||
|
@ -99,18 +98,23 @@ class NCIntroViewController: UIViewController, UICollectionViewDataSource, UICol
|
|||
view.backgroundColor = NCBrandColor.shared.customer
|
||||
timerAutoScroll = Timer.scheduledTimer(timeInterval: 5, target: self, selector: (#selector(NCIntroViewController.autoScroll)), userInfo: nil, repeats: true)
|
||||
|
||||
NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterChangeUser), object: nil, queue: nil) { _ in
|
||||
let window = UIApplication.shared.firstWindow
|
||||
if window?.rootViewController is NCMainTabBarController {
|
||||
self.dismiss(animated: true)
|
||||
} else {
|
||||
if let mainTabBarController = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController() as? NCMainTabBarController {
|
||||
mainTabBarController.modalPresentationStyle = .fullScreen
|
||||
mainTabBarController.view.alpha = 0
|
||||
window?.rootViewController = mainTabBarController
|
||||
window?.makeKeyAndVisible()
|
||||
UIView.animate(withDuration: 0.5) {
|
||||
mainTabBarController.view.alpha = 1
|
||||
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 {
|
||||
let window = UIApplication.shared.firstWindow
|
||||
if let controller = window?.rootViewController as? NCMainTabBarController {
|
||||
controller.account = account
|
||||
self.dismiss(animated: true)
|
||||
} else {
|
||||
if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController() as? NCMainTabBarController {
|
||||
controller.account = account
|
||||
controller.modalPresentationStyle = .fullScreen
|
||||
controller.view.alpha = 0
|
||||
window?.rootViewController = controller
|
||||
window?.makeKeyAndVisible()
|
||||
UIView.animate(withDuration: 0.5) {
|
||||
controller.view.alpha = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -179,11 +183,11 @@ class NCIntroViewController: UIViewController, UICollectionViewDataSource, UICol
|
|||
}
|
||||
|
||||
@IBAction func login(_ sender: Any) {
|
||||
appDelegate.openLogin(selector: NCGlobal.shared.introLogin, openLoginWeb: false)
|
||||
appDelegate.openLogin(selector: NCGlobal.shared.introLogin)
|
||||
}
|
||||
|
||||
@IBAction func signup(_ sender: Any) {
|
||||
appDelegate.openLogin(selector: NCGlobal.shared.introSignup, openLoginWeb: false)
|
||||
appDelegate.openLogin(selector: NCGlobal.shared.introSignup)
|
||||
}
|
||||
|
||||
@IBAction func host(_ sender: Any) {
|
||||
|
|
|
@ -58,7 +58,7 @@ let userAgent: String = {
|
|||
// BRAND ONLY
|
||||
@objc public var use_AppConfig: Bool = false // Don't touch me !!
|
||||
|
||||
// Options
|
||||
// Use server theming color
|
||||
@objc public var use_themingColor: Bool = true
|
||||
|
||||
var disable_intro: Bool = false
|
||||
|
@ -71,6 +71,10 @@ let userAgent: String = {
|
|||
var disable_mobileconfig: Bool = false
|
||||
var disable_show_more_nextcloud_apps_in_settings: Bool = false
|
||||
var doNotAskPasscodeAtStartup: Bool = false
|
||||
var disable_source_code_in_settings: Bool = false
|
||||
|
||||
// (name: "Name 1", url: "https://cloud.nextcloud.com"),(name: "Name 2", url: "https://cloud.nextcloud.com")
|
||||
var enforce_servers: [(name: String, url: String)] = []
|
||||
|
||||
// Internal option behaviour
|
||||
var cleanUpDay: Int = 0 // Set default "Delete, in the cache, all files older than" possible days value are: 0, 1, 7, 30, 90, 180, 365
|
||||
|
@ -127,26 +131,22 @@ class NCBrandColor: NSObject {
|
|||
return instance
|
||||
}()
|
||||
|
||||
// Color
|
||||
/// This is rewrited from customet theme, default is Nextcloud color
|
||||
///
|
||||
let customer: UIColor = UIColor(red: 0.0 / 255.0, green: 130.0 / 255.0, blue: 201.0 / 255.0, alpha: 1.0) // BLU NC : #0082c9
|
||||
var customerText: UIColor = .white
|
||||
|
||||
var brand: UIColor // don't touch me
|
||||
var brandElement: UIColor // don't touch me
|
||||
var brandText: UIColor // don't touch me
|
||||
|
||||
let nextcloud: UIColor = UIColor(red: 0.0 / 255.0, green: 130.0 / 255.0, blue: 201.0 / 255.0, alpha: 1.0)
|
||||
let yellowFavorite: UIColor = UIColor(red: 248.0 / 255.0, green: 205.0 / 255.0, blue: 70.0 / 255.0, alpha: 1.0)
|
||||
// INTERNAL DEFINE COLORS
|
||||
private var themingColor = ThreadSafeDictionary<String, UIColor>()
|
||||
private var themingColorElement = ThreadSafeDictionary<String, UIColor>()
|
||||
private var themingColorText = ThreadSafeDictionary<String, UIColor>()
|
||||
|
||||
var userColors: [CGColor] = []
|
||||
var themingColor: String = ""
|
||||
var themingColorElement: String = ""
|
||||
var themingColorText: String = ""
|
||||
|
||||
let nextcloud: UIColor = UIColor(red: 0.0 / 255.0, green: 130.0 / 255.0, blue: 201.0 / 255.0, alpha: 1.0)
|
||||
let yellowFavorite: UIColor = UIColor(red: 248.0 / 255.0, green: 205.0 / 255.0, blue: 70.0 / 255.0, alpha: 1.0)
|
||||
let iconImageColor: UIColor = .label
|
||||
let iconImageColor2: UIColor = .secondaryLabel
|
||||
let iconImageMultiColors: [UIColor] = [.secondaryLabel, .label]
|
||||
|
||||
let textColor: UIColor = .label
|
||||
let textColor2: UIColor = .secondaryLabel
|
||||
|
||||
|
@ -174,110 +174,7 @@ class NCBrandColor: NSObject {
|
|||
}
|
||||
}
|
||||
|
||||
override init() {
|
||||
brand = customer
|
||||
brandElement = customer
|
||||
brandText = customerText
|
||||
}
|
||||
|
||||
func createUserColors() {
|
||||
userColors = generateColors()
|
||||
}
|
||||
|
||||
func settingThemingColor(account: String) {
|
||||
let darker: CGFloat = 30 // %
|
||||
let lighter: CGFloat = 30 // %
|
||||
|
||||
if NCBrandOptions.shared.use_themingColor {
|
||||
self.themingColor = NCGlobal.shared.capabilityThemingColor
|
||||
self.themingColorElement = NCGlobal.shared.capabilityThemingColorElement
|
||||
self.themingColorText = NCGlobal.shared.capabilityThemingColorText
|
||||
|
||||
// COLOR
|
||||
if themingColor.first == "#" {
|
||||
if let color = UIColor(hex: themingColor) {
|
||||
brand = color
|
||||
} else {
|
||||
brand = customer
|
||||
}
|
||||
} else {
|
||||
brand = customer
|
||||
}
|
||||
|
||||
// COLOR TEXT
|
||||
if themingColorText.first == "#" {
|
||||
if let color = UIColor(hex: themingColorText) {
|
||||
brandText = color
|
||||
} else {
|
||||
brandText = customerText
|
||||
}
|
||||
} else {
|
||||
brandText = customerText
|
||||
}
|
||||
|
||||
// COLOR ELEMENT
|
||||
if themingColorElement.first == "#" {
|
||||
if let color = UIColor(hex: themingColorElement) {
|
||||
brandElement = color
|
||||
} else {
|
||||
brandElement = brand
|
||||
}
|
||||
} else {
|
||||
brandElement = brand
|
||||
}
|
||||
|
||||
if brandElement.isTooLight() {
|
||||
if let color = brandElement.darker(by: darker) {
|
||||
brandElement = color
|
||||
}
|
||||
} else if brandElement.isTooDark() {
|
||||
if let color = brandElement.lighter(by: lighter) {
|
||||
brandElement = color
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if self.customer.isTooLight() {
|
||||
if let color = customer.darker(by: darker) {
|
||||
brandElement = color
|
||||
}
|
||||
} else if customer.isTooDark() {
|
||||
if let color = customer.lighter(by: lighter) {
|
||||
brandElement = color
|
||||
}
|
||||
} else {
|
||||
brandElement = customer
|
||||
}
|
||||
|
||||
brand = customer
|
||||
brandText = customerText
|
||||
}
|
||||
}
|
||||
|
||||
private func stepCalc(steps: Int, color1: CGColor, color2: CGColor) -> [CGFloat] {
|
||||
var step = [CGFloat](repeating: 0, count: 3)
|
||||
|
||||
step[0] = (color2.components![0] - color1.components![0]) / CGFloat(steps)
|
||||
step[1] = (color2.components![1] - color1.components![1]) / CGFloat(steps)
|
||||
step[2] = (color2.components![2] - color1.components![2]) / CGFloat(steps)
|
||||
return step
|
||||
}
|
||||
|
||||
private func mixPalette(steps: Int, color1: CGColor, color2: CGColor) -> [CGColor] {
|
||||
var palette = [color1]
|
||||
let step = stepCalc(steps: steps, color1: color1, color2: color2)
|
||||
let c1Components = color1.components!
|
||||
|
||||
for i in 1 ..< steps {
|
||||
let r = c1Components[0] + step[0] * CGFloat(i)
|
||||
let g = c1Components[1] + step[1] * CGFloat(i)
|
||||
let b = c1Components[2] + step[2] * CGFloat(i)
|
||||
|
||||
palette.append(UIColor(red: r, green: g, blue: b, alpha: 1).cgColor)
|
||||
}
|
||||
return palette
|
||||
}
|
||||
override init() { }
|
||||
|
||||
/**
|
||||
Generate colors from the official nextcloud color.
|
||||
|
@ -285,15 +182,154 @@ class NCBrandColor: NSObject {
|
|||
if `step` = 6,
|
||||
3 colors \* 6 will result in 18 generated colors
|
||||
*/
|
||||
func generateColors(steps: Int = 6) -> [CGColor] {
|
||||
let red = UIColor(red: 182 / 255, green: 70 / 255, blue: 157 / 255, alpha: 1).cgColor
|
||||
let yellow = UIColor(red: 221 / 255, green: 203 / 255, blue: 85 / 255, alpha: 1).cgColor
|
||||
let blue = UIColor(red: 0 / 255, green: 130 / 255, blue: 201 / 255, alpha: 1).cgColor
|
||||
func createUserColors() {
|
||||
func generateColors(steps: Int = 6) -> [CGColor] {
|
||||
func stepCalc(steps: Int, color1: CGColor, color2: CGColor) -> [CGFloat] {
|
||||
var step = [CGFloat](repeating: 0, count: 3)
|
||||
|
||||
let palette1 = mixPalette(steps: steps, color1: red, color2: yellow)
|
||||
let palette2 = mixPalette(steps: steps, color1: yellow, color2: blue)
|
||||
let palette3 = mixPalette(steps: steps, color1: blue, color2: red)
|
||||
step[0] = (color2.components![0] - color1.components![0]) / CGFloat(steps)
|
||||
step[1] = (color2.components![1] - color1.components![1]) / CGFloat(steps)
|
||||
step[2] = (color2.components![2] - color1.components![2]) / CGFloat(steps)
|
||||
return step
|
||||
}
|
||||
|
||||
return palette1 + palette2 + palette3
|
||||
func mixPalette(steps: Int, color1: CGColor, color2: CGColor) -> [CGColor] {
|
||||
var palette = [color1]
|
||||
let step = stepCalc(steps: steps, color1: color1, color2: color2)
|
||||
let c1Components = color1.components!
|
||||
|
||||
for i in 1 ..< steps {
|
||||
let r = c1Components[0] + step[0] * CGFloat(i)
|
||||
let g = c1Components[1] + step[1] * CGFloat(i)
|
||||
let b = c1Components[2] + step[2] * CGFloat(i)
|
||||
|
||||
palette.append(UIColor(red: r, green: g, blue: b, alpha: 1).cgColor)
|
||||
}
|
||||
return palette
|
||||
}
|
||||
|
||||
let red = UIColor(red: 182 / 255, green: 70 / 255, blue: 157 / 255, alpha: 1).cgColor
|
||||
let yellow = UIColor(red: 221 / 255, green: 203 / 255, blue: 85 / 255, alpha: 1).cgColor
|
||||
let blue = UIColor(red: 0 / 255, green: 130 / 255, blue: 201 / 255, alpha: 1).cgColor
|
||||
|
||||
let palette1 = mixPalette(steps: steps, color1: red, color2: yellow)
|
||||
let palette2 = mixPalette(steps: steps, color1: yellow, color2: blue)
|
||||
let palette3 = mixPalette(steps: steps, color1: blue, color2: red)
|
||||
|
||||
return palette1 + palette2 + palette3
|
||||
}
|
||||
|
||||
userColors = generateColors()
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
func settingThemingColor(account: String) -> Bool {
|
||||
let darker: CGFloat = 30 // %
|
||||
let lighter: CGFloat = 30 // %
|
||||
var colorThemingColor: UIColor?
|
||||
var colorThemingColorElement: UIColor?
|
||||
var colorThemingColorText: UIColor?
|
||||
|
||||
if NCBrandOptions.shared.use_themingColor {
|
||||
let themingColor = NCCapabilities.shared.getCapabilities(account: account).capabilityThemingColor
|
||||
let themingColorElement = NCCapabilities.shared.getCapabilities(account: account).capabilityThemingColorElement
|
||||
let themingColorText = NCCapabilities.shared.getCapabilities(account: account).capabilityThemingColorText
|
||||
|
||||
// THEMING COLOR
|
||||
if themingColor.first == "#" {
|
||||
if let color = UIColor(hex: themingColor) {
|
||||
colorThemingColor = color
|
||||
} else {
|
||||
colorThemingColor = customer
|
||||
}
|
||||
} else {
|
||||
colorThemingColor = customer
|
||||
}
|
||||
|
||||
// THEMING COLOR ELEMENT (control isTooLight / isTooDark)
|
||||
if themingColorElement.first == "#" {
|
||||
if let color = UIColor(hex: themingColorElement) {
|
||||
if color.isTooLight() {
|
||||
if let color = color.darker(by: darker) {
|
||||
colorThemingColorElement = color
|
||||
}
|
||||
} else if color.isTooDark() {
|
||||
if let color = color.lighter(by: lighter) {
|
||||
colorThemingColorElement = color
|
||||
}
|
||||
} else {
|
||||
colorThemingColorElement = color
|
||||
}
|
||||
} else {
|
||||
colorThemingColorElement = customer
|
||||
}
|
||||
} else {
|
||||
colorThemingColorElement = customer
|
||||
}
|
||||
|
||||
// THEMING COLOR TEXT
|
||||
if themingColorText.first == "#" {
|
||||
if let color = UIColor(hex: themingColorText) {
|
||||
colorThemingColorText = color
|
||||
} else {
|
||||
colorThemingColorText = .white
|
||||
}
|
||||
} else {
|
||||
colorThemingColorText = .white
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// THEMING COLOR
|
||||
colorThemingColor = customer
|
||||
|
||||
// THEMING COLOR ELEMENT (control isTooLight / isTooDark)
|
||||
if self.customer.isTooLight() {
|
||||
if let color = customer.darker(by: darker) {
|
||||
colorThemingColorElement = color
|
||||
}
|
||||
} else if customer.isTooDark() {
|
||||
if let color = customer.lighter(by: lighter) {
|
||||
colorThemingColorElement = color
|
||||
}
|
||||
} else {
|
||||
colorThemingColorElement = customer
|
||||
}
|
||||
|
||||
// THEMING COLOR TEXT
|
||||
colorThemingColorText = customerText
|
||||
}
|
||||
|
||||
if self.themingColor[account] != colorThemingColor || self.themingColorElement[account] != colorThemingColorElement || self.themingColorText[account] != colorThemingColorText {
|
||||
|
||||
self.themingColor[account] = colorThemingColor
|
||||
self.themingColorElement[account] = colorThemingColorElement
|
||||
self.themingColorText[account] = colorThemingColorText
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
public func getTheming(account: String?) -> UIColor {
|
||||
if let account, let color = self.themingColor[account] {
|
||||
return color
|
||||
}
|
||||
return customer
|
||||
}
|
||||
|
||||
public func getElement(account: String?) -> UIColor {
|
||||
if let account, let color = self.themingColorElement[account] {
|
||||
return color
|
||||
}
|
||||
return customer
|
||||
}
|
||||
|
||||
public func getText(account: String?) -> UIColor {
|
||||
if let account, let color = self.themingColorText[account] {
|
||||
return color
|
||||
}
|
||||
return .white
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
</array>
|
||||
<key>CFBundleAllowMixedLocalizations</key>
|
||||
<true/>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>12.3</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
|
|
2
Cartfile
2
Cartfile
|
@ -1,2 +0,0 @@
|
|||
github "https://github.com/marinofaggiana/TOPasscodeViewController" "master"
|
||||
binary "https://code.videolan.org/videolan/VLCKit/raw/master/Packaging/MobileVLCKit.json" ~> 3.5.1
|
|
@ -1,2 +0,0 @@
|
|||
binary "https://code.videolan.org/videolan/VLCKit/raw/master/Packaging/MobileVLCKit.json" "3.6.0"
|
||||
github "marinofaggiana/TOPasscodeViewController" "ed795637acd2b1ef154e011a04ebab4686d0523c"
|
|
@ -53,7 +53,7 @@ class NCApplicationHandle: NSObject {
|
|||
|
||||
// class: NCCollectionViewCommon (+Menu)
|
||||
// func: toggleMenu(metadata: tableMetadata, imageIcon: UIImage?)
|
||||
func addCollectionViewCommonMenu(metadata: tableMetadata, imageIcon: UIImage?, actions: inout [NCMenuAction]) {
|
||||
func addCollectionViewCommonMenu(metadata: tableMetadata, image: UIImage?, actions: inout [NCMenuAction]) {
|
||||
}
|
||||
|
||||
// class: NCMore
|
||||
|
|
|
@ -32,9 +32,9 @@ class DocumentActionViewController: FPUIActionExtensionViewController {
|
|||
override func loadView() {
|
||||
super.loadView()
|
||||
|
||||
view.backgroundColor = NCBrandColor.shared.brandElement
|
||||
titleError.textColor = NCBrandColor.shared.brandText
|
||||
cancelButton.setTitleColor(NCBrandColor.shared.brandText, for: .normal)
|
||||
view.backgroundColor = NCBrandColor.shared.customer
|
||||
titleError.textColor = NCBrandColor.shared.customerText
|
||||
cancelButton.setTitleColor(NCBrandColor.shared.customerText, for: .normal)
|
||||
|
||||
titleError.text = ""
|
||||
}
|
||||
|
|
|
@ -33,19 +33,24 @@ class fileProviderData: NSObject {
|
|||
var domain: NSFileProviderDomain?
|
||||
var fileProviderManager: NSFileProviderManager = NSFileProviderManager.default
|
||||
let utilityFileSystem = NCUtilityFileSystem()
|
||||
|
||||
var account = ""
|
||||
var user = ""
|
||||
var userId = ""
|
||||
var accountUrlBase = ""
|
||||
var homeServerUrl = ""
|
||||
|
||||
let database = NCManageDatabase.shared
|
||||
var listFavoriteIdentifierRank: [String: NSNumber] = [:]
|
||||
|
||||
var fileProviderSignalDeleteContainerItemIdentifier: [NSFileProviderItemIdentifier: NSFileProviderItemIdentifier] = [:]
|
||||
var fileProviderSignalUpdateContainerItem: [NSFileProviderItemIdentifier: FileProviderItem] = [:]
|
||||
var fileProviderSignalDeleteWorkingSetItemIdentifier: [NSFileProviderItemIdentifier: NSFileProviderItemIdentifier] = [:]
|
||||
var fileProviderSignalUpdateWorkingSetItem: [NSFileProviderItemIdentifier: FileProviderItem] = [:]
|
||||
private var account: String = ""
|
||||
var session: NCSession.Session {
|
||||
if !account.isEmpty,
|
||||
let tableAccount = self.database.getTableAccount(account: account) {
|
||||
return NCSession.Session(account: tableAccount.account, urlBase: tableAccount.urlBase, user: tableAccount.user, userId: tableAccount.userId)
|
||||
} else if let activeTableAccount = self.database.getActiveTableAccount() {
|
||||
self.account = activeTableAccount.account
|
||||
return NCSession.Session(account: activeTableAccount.account, urlBase: activeTableAccount.urlBase, user: activeTableAccount.user, userId: activeTableAccount.userId)
|
||||
} else {
|
||||
return NCSession.Session(account: "", urlBase: "", user: "", userId: "")
|
||||
}
|
||||
}
|
||||
|
||||
enum FileProviderError: Error {
|
||||
case downloadError
|
||||
|
@ -81,54 +86,45 @@ class fileProviderData: NSObject {
|
|||
let version = NSString(format: NCBrandOptions.shared.textCopyrightNextcloudiOS as NSString, NCUtility().getVersionApp()) as String
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[INFO] Start File Provider session with level \(levelLog) " + version + " (File Provider Extension)")
|
||||
|
||||
// NO DOMAIN -> Set default account
|
||||
if domain == nil {
|
||||
guard let activeAccount = NCManageDatabase.shared.getActiveAccount() else { return nil }
|
||||
account = activeAccount.account
|
||||
user = activeAccount.user
|
||||
userId = activeAccount.userId
|
||||
accountUrlBase = activeAccount.urlBase
|
||||
homeServerUrl = utilityFileSystem.getHomeServer(urlBase: activeAccount.urlBase, userId: activeAccount.userId)
|
||||
|
||||
NCManageDatabase.shared.setCapabilities(account: account)
|
||||
NextcloudKit.shared.setup(account: activeAccount.account, user: activeAccount.user, userId: activeAccount.userId, password: NCKeychain().getPassword(account: activeAccount.account), urlBase: activeAccount.urlBase, userAgent: userAgent, nextcloudVersion: NCGlobal.shared.capabilityServerVersionMajor, delegate: NCNetworking.shared)
|
||||
NCNetworking.shared.delegate = providerExtension as? NCNetworkingDelegate
|
||||
|
||||
return tableAccount.init(value: activeAccount)
|
||||
}
|
||||
|
||||
// DOMAIN
|
||||
let accounts = NCManageDatabase.shared.getAllAccount()
|
||||
if accounts.isEmpty { return nil }
|
||||
|
||||
for activeAccount in accounts {
|
||||
guard let url = NSURL(string: activeAccount.urlBase) else { continue }
|
||||
guard let host = url.host else { continue }
|
||||
let accountDomain = activeAccount.userId + " (" + host + ")"
|
||||
if accountDomain == domain!.identifier.rawValue {
|
||||
account = activeAccount.account
|
||||
user = activeAccount.user
|
||||
userId = activeAccount.userId
|
||||
accountUrlBase = activeAccount.urlBase
|
||||
homeServerUrl = utilityFileSystem.getHomeServer(urlBase: activeAccount.urlBase, userId: activeAccount.userId)
|
||||
|
||||
NCManageDatabase.shared.setCapabilities(account: account)
|
||||
|
||||
NextcloudKit.shared.setup(account: activeAccount.account, user: activeAccount.user, userId: activeAccount.userId, password: NCKeychain().getPassword(account: activeAccount.account), urlBase: activeAccount.urlBase, userAgent: userAgent, nextcloudVersion: NCGlobal.shared.capabilityServerVersionMajor, delegate: NCNetworking.shared)
|
||||
NCNetworking.shared.delegate = providerExtension as? NCNetworkingDelegate
|
||||
|
||||
return tableAccount.init(value: activeAccount)
|
||||
var tblAccount = self.database.getActiveTableAccount()
|
||||
if let domain {
|
||||
for tableAccount in self.database.getAllTableAccount() {
|
||||
guard let urlBase = NSURL(string: tableAccount.urlBase) else { continue }
|
||||
guard let host = urlBase.host else { continue }
|
||||
let accountDomain = tableAccount.userId + " (" + host + ")"
|
||||
if accountDomain == domain.identifier.rawValue {
|
||||
let account = "\(tableAccount.user) \(tableAccount.urlBase)"
|
||||
tblAccount = self.database.getTableAccount(account: account)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
guard let tblAccount else { return nil }
|
||||
|
||||
self.account = tblAccount.account
|
||||
/// NextcloudKit Session
|
||||
NextcloudKit.shared.setup(delegate: NCNetworking.shared)
|
||||
NextcloudKit.shared.appendSession(account: tblAccount.account,
|
||||
urlBase: tblAccount.urlBase,
|
||||
user: tblAccount.user,
|
||||
userId: tblAccount.userId,
|
||||
password: NCKeychain().getPassword(account: tblAccount.account),
|
||||
userAgent: userAgent,
|
||||
nextcloudVersion: NCCapabilities.shared.getCapabilities(account: tblAccount.account).capabilityServerVersionMajor,
|
||||
groupIdentifier: NCBrandOptions.shared.capabilitiesGroup)
|
||||
NCNetworking.shared.delegate = providerExtension as? NCNetworkingDelegate
|
||||
|
||||
return tableAccount(value: tblAccount)
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
|
||||
@discardableResult
|
||||
func signalEnumerator(ocId: String, type: TypeSignal) -> FileProviderItem? {
|
||||
guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId),
|
||||
let parentItemIdentifier = fileProviderUtility().getParentItemIdentifier(metadata: metadata) else { return nil }
|
||||
guard let metadata = self.database.getMetadataFromOcId(ocId),
|
||||
let parentItemIdentifier = fileProviderUtility().getParentItemIdentifier(metadata: metadata) else {
|
||||
return nil
|
||||
}
|
||||
let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier)
|
||||
|
||||
if type == .delete {
|
||||
|
|
|
@ -28,7 +28,7 @@ class FileProviderDomain: NSObject {
|
|||
NSFileProviderManager.getDomainsWithCompletionHandler { fileProviderDomain, error in
|
||||
var domains: [String] = []
|
||||
let pathRelativeToDocumentStorage = NSFileProviderManager.default.documentStorageURL.absoluteString
|
||||
let accounts = NCManageDatabase.shared.getAllAccount()
|
||||
let tableAccounts = NCManageDatabase.shared.getAllTableAccount()
|
||||
|
||||
for domain in fileProviderDomain {
|
||||
domains.append(domain.identifier.rawValue)
|
||||
|
@ -37,10 +37,10 @@ class FileProviderDomain: NSObject {
|
|||
// Delete
|
||||
for domain in domains {
|
||||
var domainFound = false
|
||||
for account in accounts {
|
||||
guard let urlBase = NSURL(string: account.urlBase) else { continue }
|
||||
for tableAccount in tableAccounts {
|
||||
guard let urlBase = NSURL(string: tableAccount.urlBase) else { continue }
|
||||
guard let host = urlBase.host else { continue }
|
||||
let accountDomain = account.userId + " (" + host + ")"
|
||||
let accountDomain = tableAccount.userId + " (" + host + ")"
|
||||
if domain == accountDomain {
|
||||
domainFound = true
|
||||
break
|
||||
|
@ -57,11 +57,11 @@ class FileProviderDomain: NSObject {
|
|||
}
|
||||
|
||||
// Add
|
||||
for account in accounts {
|
||||
for tableAccount in tableAccounts {
|
||||
var domainFound = false
|
||||
guard let urlBase = NSURL(string: account.urlBase) else { continue }
|
||||
guard let urlBase = NSURL(string: tableAccount.urlBase) else { continue }
|
||||
guard let host = urlBase.host else { continue }
|
||||
let accountDomain = account.userId + " (" + host + ")"
|
||||
let accountDomain = tableAccount.userId + " (" + host + ")"
|
||||
for domain in domains {
|
||||
if domain == accountDomain {
|
||||
domainFound = true
|
||||
|
|
|
@ -30,16 +30,17 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
|
|||
var enumeratedItemIdentifier: NSFileProviderItemIdentifier
|
||||
var serverUrl: String?
|
||||
let providerUtility = fileProviderUtility()
|
||||
let database = NCManageDatabase.shared
|
||||
var recordsPerPage: Int = 20
|
||||
var anchor: UInt64 = 0
|
||||
|
||||
init(enumeratedItemIdentifier: NSFileProviderItemIdentifier) {
|
||||
self.enumeratedItemIdentifier = enumeratedItemIdentifier
|
||||
if enumeratedItemIdentifier == .rootContainer {
|
||||
serverUrl = fileProviderData.shared.homeServerUrl
|
||||
serverUrl = NCUtilityFileSystem().getHomeServer(session: fileProviderData.shared.session)
|
||||
} else {
|
||||
if let metadata = providerUtility.getTableMetadataFromItemIdentifier(enumeratedItemIdentifier),
|
||||
let directorySource = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", metadata.account, metadata.serverUrl)) {
|
||||
let directorySource = self.database.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", metadata.account, metadata.serverUrl)) {
|
||||
serverUrl = directorySource.serverUrl + "/" + metadata.fileName
|
||||
|
||||
}
|
||||
|
@ -55,15 +56,15 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
|
|||
if enumeratedItemIdentifier == .workingSet {
|
||||
var itemIdentifierMetadata: [NSFileProviderItemIdentifier: tableMetadata] = [:]
|
||||
/// Tags
|
||||
let tags = NCManageDatabase.shared.getTags(predicate: NSPredicate(format: "account == %@", fileProviderData.shared.account))
|
||||
let tags = self.database.getTags(predicate: NSPredicate(format: "account == %@", fileProviderData.shared.session.account))
|
||||
for tag in tags {
|
||||
guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(tag.ocId) else { continue }
|
||||
guard let metadata = self.database.getMetadataFromOcId(tag.ocId) else { continue }
|
||||
itemIdentifierMetadata[providerUtility.getItemIdentifier(metadata: metadata)] = metadata
|
||||
}
|
||||
/// Favorite
|
||||
fileProviderData.shared.listFavoriteIdentifierRank = NCManageDatabase.shared.getTableMetadatasDirectoryFavoriteIdentifierRank(account: fileProviderData.shared.account)
|
||||
fileProviderData.shared.listFavoriteIdentifierRank = self.database.getTableMetadatasDirectoryFavoriteIdentifierRank(account: fileProviderData.shared.session.account)
|
||||
for (identifier, _) in fileProviderData.shared.listFavoriteIdentifierRank {
|
||||
guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(identifier) else { continue }
|
||||
guard let metadata = self.database.getMetadataFromOcId(identifier) else { continue }
|
||||
itemIdentifierMetadata[providerUtility.getItemIdentifier(metadata: metadata)] = metadata
|
||||
}
|
||||
/// Create items
|
||||
|
@ -90,7 +91,7 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
|
|||
self.fetchItemsForPage(serverUrl: serverUrl, pageNumber: pageNumber) { metadatas in
|
||||
if let metadatas {
|
||||
for metadata in metadatas {
|
||||
if metadata.e2eEncrypted || (!metadata.session.isEmpty && metadata.session != NCNetworking.shared.sessionUploadBackgroundExtension) {
|
||||
if metadata.e2eEncrypted || (!metadata.session.isEmpty && metadata.session != NCNetworking.shared.sessionUploadBackgroundExt) {
|
||||
continue
|
||||
}
|
||||
if let parentItemIdentifier = self.providerUtility.getParentItemIdentifier(metadata: metadata) {
|
||||
|
@ -157,25 +158,25 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
|
|||
}
|
||||
|
||||
func fetchItemsForPage(serverUrl: String, pageNumber: Int, completionHandler: @escaping (_ metadatas: Results<tableMetadata>?) -> Void) {
|
||||
let predicate = NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.shared.account, serverUrl)
|
||||
let predicate = NSPredicate(format: "account == %@ AND serverUrl == %@", fileProviderData.shared.session.account, serverUrl)
|
||||
|
||||
if pageNumber == 1 {
|
||||
NextcloudKit.shared.readFileOrFolder(serverUrlFileName: serverUrl, depth: "1", showHiddenFiles: NCKeychain().showHiddenFiles, account: fileProviderData.shared.account) { _, files, _, error in
|
||||
if error == .success {
|
||||
NCManageDatabase.shared.convertFilesToMetadatas(files, useFirstAsMetadataFolder: true) { metadataFolder, metadatas in
|
||||
NextcloudKit.shared.readFileOrFolder(serverUrlFileName: serverUrl, depth: "1", showHiddenFiles: NCKeychain().showHiddenFiles, account: fileProviderData.shared.session.account) { _, files, _, error in
|
||||
if error == .success, let files {
|
||||
self.database.convertFilesToMetadatas(files, useFirstAsMetadataFolder: true) { metadataFolder, metadatas in
|
||||
/// FOLDER
|
||||
NCManageDatabase.shared.addMetadata(metadataFolder)
|
||||
NCManageDatabase.shared.addDirectory(e2eEncrypted: metadataFolder.e2eEncrypted, favorite: metadataFolder.favorite, ocId: metadataFolder.ocId, fileId: metadataFolder.fileId, etag: metadataFolder.etag, permissions: metadataFolder.permissions, richWorkspace: metadataFolder.richWorkspace, serverUrl: serverUrl, account: metadataFolder.account)
|
||||
self.database.addMetadata(metadataFolder)
|
||||
self.database.addDirectory(e2eEncrypted: metadataFolder.e2eEncrypted, favorite: metadataFolder.favorite, ocId: metadataFolder.ocId, fileId: metadataFolder.fileId, etag: metadataFolder.etag, permissions: metadataFolder.permissions, richWorkspace: metadataFolder.richWorkspace, serverUrl: serverUrl, account: metadataFolder.account)
|
||||
/// FILES
|
||||
NCManageDatabase.shared.deleteMetadata(predicate: predicate)
|
||||
NCManageDatabase.shared.addMetadatas(metadatas)
|
||||
self.database.deleteMetadata(predicate: predicate)
|
||||
self.database.addMetadatas(metadatas)
|
||||
}
|
||||
}
|
||||
let resultsMetadata = NCManageDatabase.shared.fetchPagedResults(ofType: tableMetadata.self, primaryKey: "ocId", recordsPerPage: self.recordsPerPage, pageNumber: pageNumber, filter: predicate, sortedByKeyPath: "fileName")
|
||||
let resultsMetadata = self.database.fetchPagedResults(ofType: tableMetadata.self, primaryKey: "ocId", recordsPerPage: self.recordsPerPage, pageNumber: pageNumber, filter: predicate, sortedByKeyPath: "fileName")
|
||||
completionHandler(resultsMetadata)
|
||||
}
|
||||
} else {
|
||||
let resultsMetadata = NCManageDatabase.shared.fetchPagedResults(ofType: tableMetadata.self, primaryKey: "ocId", recordsPerPage: recordsPerPage, pageNumber: pageNumber, filter: predicate, sortedByKeyPath: "fileName")
|
||||
let resultsMetadata = self.database.fetchPagedResults(ofType: tableMetadata.self, primaryKey: "ocId", recordsPerPage: recordsPerPage, pageNumber: pageNumber, filter: predicate, sortedByKeyPath: "fileName")
|
||||
completionHandler(resultsMetadata)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,23 +27,23 @@ import NextcloudKit
|
|||
|
||||
extension FileProviderExtension {
|
||||
override func createDirectory(withName directoryName: String, inParentItemIdentifier parentItemIdentifier: NSFileProviderItemIdentifier, completionHandler: @escaping (NSFileProviderItem?, Error?) -> Void) {
|
||||
guard let tableDirectory = providerUtility.getTableDirectoryFromParentItemIdentifier(parentItemIdentifier, account: fileProviderData.shared.account, homeServerUrl: fileProviderData.shared.homeServerUrl) else {
|
||||
guard let tableDirectory = providerUtility.getTableDirectoryFromParentItemIdentifier(parentItemIdentifier, account: fileProviderData.shared.session.account, homeServerUrl: utilityFileSystem.getHomeServer(session: fileProviderData.shared.session)) else {
|
||||
return completionHandler(nil, NSFileProviderError(.noSuchItem))
|
||||
}
|
||||
let directoryName = utilityFileSystem.createFileName(directoryName, serverUrl: tableDirectory.serverUrl, account: fileProviderData.shared.account)
|
||||
let directoryName = utilityFileSystem.createFileName(directoryName, serverUrl: tableDirectory.serverUrl, account: fileProviderData.shared.session.account)
|
||||
let serverUrlFileName = tableDirectory.serverUrl + "/" + directoryName
|
||||
|
||||
NextcloudKit.shared.createFolder(serverUrlFileName: serverUrlFileName, account: fileProviderData.shared.account) { _, ocId, _, error in
|
||||
NextcloudKit.shared.createFolder(serverUrlFileName: serverUrlFileName, account: fileProviderData.shared.session.account) { _, ocId, _, _, error in
|
||||
if error == .success {
|
||||
NextcloudKit.shared.readFileOrFolder(serverUrlFileName: serverUrlFileName, depth: "0", showHiddenFiles: NCKeychain().showHiddenFiles, account: fileProviderData.shared.account) { _, files, _, error in
|
||||
if error == .success, let file = files.first {
|
||||
NextcloudKit.shared.readFileOrFolder(serverUrlFileName: serverUrlFileName, depth: "0", showHiddenFiles: NCKeychain().showHiddenFiles, account: fileProviderData.shared.session.account) { _, files, _, error in
|
||||
if error == .success, let file = files?.first {
|
||||
let isDirectoryEncrypted = self.utilityFileSystem.isDirectoryE2EE(file: file)
|
||||
let metadata = NCManageDatabase.shared.convertFileToMetadata(file, isDirectoryE2EE: isDirectoryEncrypted)
|
||||
let metadata = self.database.convertFileToMetadata(file, isDirectoryE2EE: isDirectoryEncrypted)
|
||||
|
||||
NCManageDatabase.shared.addDirectory(e2eEncrypted: false, favorite: false, ocId: ocId!, fileId: metadata.fileId, etag: metadata.etag, permissions: metadata.permissions, serverUrl: serverUrlFileName, account: metadata.account)
|
||||
NCManageDatabase.shared.addMetadata(metadata)
|
||||
self.database.addDirectory(e2eEncrypted: false, favorite: false, ocId: ocId!, fileId: metadata.fileId, etag: metadata.etag, permissions: metadata.permissions, serverUrl: serverUrlFileName, account: metadata.account)
|
||||
self.database.addMetadata(metadata)
|
||||
|
||||
guard let metadataInsert = NCManageDatabase.shared.getMetadataFromOcId(ocId!),
|
||||
guard let metadataInsert = self.database.getMetadataFromOcId(ocId!),
|
||||
let parentItemIdentifier = self.providerUtility.getParentItemIdentifier(metadata: metadataInsert) else {
|
||||
return completionHandler(nil, NSFileProviderError(.noSuchItem))
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ extension FileProviderExtension {
|
|||
let serverUrl = metadata.serverUrl
|
||||
let fileName = metadata.fileName
|
||||
|
||||
NextcloudKit.shared.deleteFileOrFolder(serverUrlFileName: serverUrlFileName, account: metadata.account) { account, error in
|
||||
NextcloudKit.shared.deleteFileOrFolder(serverUrlFileName: serverUrlFileName, account: metadata.account) { account, _, error in
|
||||
if error == .success {
|
||||
let fileNamePath = self.utilityFileSystem.getDirectoryProviderStorageOcId(itemIdentifier.rawValue)
|
||||
|
||||
|
@ -81,11 +81,11 @@ extension FileProviderExtension {
|
|||
|
||||
if isDirectory {
|
||||
let dirForDelete = self.utilityFileSystem.stringAppendServerUrl(serverUrl, addFileName: fileName)
|
||||
NCManageDatabase.shared.deleteDirectoryAndSubDirectory(serverUrl: dirForDelete, account: account)
|
||||
self.database.deleteDirectoryAndSubDirectory(serverUrl: dirForDelete, account: account)
|
||||
}
|
||||
|
||||
NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", ocId))
|
||||
NCManageDatabase.shared.deleteLocalFile(predicate: NSPredicate(format: "ocId == %@", ocId))
|
||||
self.database.deleteMetadataOcId(ocId)
|
||||
self.database.deleteLocalFileOcId(ocId)
|
||||
completionHandler(nil)
|
||||
} else {
|
||||
completionHandler(NSFileProviderError(.serverUnreachable))
|
||||
|
@ -101,38 +101,41 @@ extension FileProviderExtension {
|
|||
let ocIdFrom = metadataFrom.ocId
|
||||
let serverUrlFrom = metadataFrom.serverUrl
|
||||
let fileNameFrom = serverUrlFrom + "/" + itemFrom.filename
|
||||
guard let tableDirectoryTo = providerUtility.getTableDirectoryFromParentItemIdentifier(parentItemIdentifier, account: fileProviderData.shared.account, homeServerUrl: fileProviderData.shared.homeServerUrl) else {
|
||||
|
||||
guard let tableDirectoryTo = providerUtility.getTableDirectoryFromParentItemIdentifier(parentItemIdentifier, account: fileProviderData.shared.session.account, homeServerUrl: utilityFileSystem.getHomeServer(session: fileProviderData.shared.session)) else {
|
||||
return completionHandler(nil, NSFileProviderError(.noSuchItem))
|
||||
}
|
||||
let serverUrlTo = tableDirectoryTo.serverUrl
|
||||
let fileNameTo = serverUrlTo + "/" + itemFrom.filename
|
||||
var fileNameTo = serverUrlTo + "/" + itemFrom.filename
|
||||
if let newName {
|
||||
fileNameTo = serverUrlTo + "/" + newName
|
||||
}
|
||||
|
||||
NextcloudKit.shared.moveFileOrFolder(serverUrlFileNameSource: fileNameFrom, serverUrlFileNameDestination: fileNameTo, overwrite: false, account: metadataFrom.account) { account, error in
|
||||
if error == .success {
|
||||
if metadataFrom.directory {
|
||||
NCManageDatabase.shared.deleteDirectoryAndSubDirectory(serverUrl: serverUrlFrom, account: account)
|
||||
NCManageDatabase.shared.renameDirectory(ocId: ocIdFrom, serverUrl: serverUrlTo)
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
NextcloudKit.shared.moveFileOrFolder(serverUrlFileNameSource: fileNameFrom, serverUrlFileNameDestination: fileNameTo, overwrite: true, account: metadataFrom.account) { account, _, error in
|
||||
if error == .success {
|
||||
if metadataFrom.directory {
|
||||
self.database.deleteDirectoryAndSubDirectory(serverUrl: serverUrlFrom, account: account)
|
||||
self.database.renameDirectory(ocId: ocIdFrom, serverUrl: serverUrlTo)
|
||||
}
|
||||
self.database.moveMetadata(ocId: ocIdFrom, serverUrlTo: serverUrlTo)
|
||||
|
||||
guard let metadata = self.database.getMetadataFromOcId(ocIdFrom) else {
|
||||
return completionHandler(nil, NSFileProviderError(.noSuchItem))
|
||||
|
||||
}
|
||||
let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier)
|
||||
|
||||
completionHandler(item, nil)
|
||||
} else {
|
||||
completionHandler(nil, NSFileProviderError(.noSuchItem, userInfo: [NSLocalizedDescriptionKey: error.errorDescription, NSLocalizedFailureReasonErrorKey: ""]))
|
||||
}
|
||||
NCManageDatabase.shared.moveMetadata(ocId: ocIdFrom, serverUrlTo: serverUrlTo)
|
||||
|
||||
guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocIdFrom) else {
|
||||
return completionHandler(nil, NSFileProviderError(.noSuchItem))
|
||||
|
||||
}
|
||||
let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier)
|
||||
|
||||
completionHandler(item, nil)
|
||||
} else if error.errorCode == NCGlobal.shared.errorBadRequest {
|
||||
completionHandler(nil, NSFileProviderError(.noSuchItem, userInfo: [NSLocalizedDescriptionKey: error.errorDescription, NSLocalizedFailureReasonErrorKey: ""]))
|
||||
} else {
|
||||
completionHandler(nil, NSFileProviderError(.serverUnreachable))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override func renameItem(withIdentifier itemIdentifier: NSFileProviderItemIdentifier, toName itemName: String, completionHandler: @escaping (NSFileProviderItem?, Error?) -> Void) {
|
||||
guard let metadata = providerUtility.getTableMetadataFromItemIdentifier(itemIdentifier),
|
||||
let directoryTable = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", metadata.account, metadata.serverUrl)) else {
|
||||
guard let metadata = providerUtility.getTableMetadataFromItemIdentifier(itemIdentifier) else {
|
||||
return completionHandler(nil, NSFileProviderError(.noSuchItem))
|
||||
}
|
||||
let fileNameFrom = metadata.fileNameView
|
||||
|
@ -140,30 +143,22 @@ extension FileProviderExtension {
|
|||
let fileNamePathTo = metadata.serverUrl + "/" + itemName
|
||||
let ocId = metadata.ocId
|
||||
|
||||
NextcloudKit.shared.moveFileOrFolder(serverUrlFileNameSource: fileNamePathFrom, serverUrlFileNameDestination: fileNamePathTo, overwrite: false, account: metadata.account) { account, error in
|
||||
NextcloudKit.shared.moveFileOrFolder(serverUrlFileNameSource: fileNamePathFrom, serverUrlFileNameDestination: fileNamePathTo, overwrite: false, account: metadata.account) { _, _, error in
|
||||
if error == .success {
|
||||
// Rename metadata
|
||||
NCManageDatabase.shared.renameMetadata(fileNameTo: itemName, ocId: ocId)
|
||||
|
||||
guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) else {
|
||||
self.database.renameMetadata(fileNameNew: itemName, ocId: ocId)
|
||||
self.database.setMetadataServeUrlFileNameStatusNormal(ocId: ocId)
|
||||
|
||||
guard let metadata = self.database.getMetadataFromOcId(ocId) else {
|
||||
return completionHandler(nil, NSFileProviderError(.noSuchItem))
|
||||
}
|
||||
if metadata.directory {
|
||||
NCManageDatabase.shared.setDirectory(serverUrl: fileNamePathFrom, serverUrlTo: fileNamePathTo, encrypted: directoryTable.e2eEncrypted, account: account)
|
||||
} else {
|
||||
let itemIdentifier = self.providerUtility.getItemIdentifier(metadata: metadata)
|
||||
self.providerUtility.moveFile(self.utilityFileSystem.getDirectoryProviderStorageOcId(itemIdentifier.rawValue, fileNameView: fileNameFrom), toPath: self.utilityFileSystem.getDirectoryProviderStorageOcId(itemIdentifier.rawValue, fileNameView: itemName))
|
||||
self.providerUtility.moveFile(self.utilityFileSystem.getDirectoryProviderStoragePreviewOcId(itemIdentifier.rawValue, etag: metadata.etag), toPath: self.utilityFileSystem.getDirectoryProviderStoragePreviewOcId(itemIdentifier.rawValue, etag: metadata.etag))
|
||||
self.providerUtility.moveFile(self.utilityFileSystem.getDirectoryProviderStorageIconOcId(itemIdentifier.rawValue, etag: metadata.etag), toPath: self.utilityFileSystem.getDirectoryProviderStorageIconOcId(itemIdentifier.rawValue, etag: metadata.etag))
|
||||
NCManageDatabase.shared.setLocalFile(ocId: ocId, fileName: itemName)
|
||||
}
|
||||
|
||||
guard let parentItemIdentifier = self.providerUtility.getParentItemIdentifier(metadata: metadata) else {
|
||||
return completionHandler(nil, NSFileProviderError(.noSuchItem))
|
||||
}
|
||||
let item = FileProviderItem(metadata: tableMetadata.init(value: metadata), parentItemIdentifier: parentItemIdentifier)
|
||||
completionHandler(item, nil)
|
||||
} else if error.errorCode == NCGlobal.shared.errorBadRequest {
|
||||
} else if error.errorCode == NCGlobal.shared.errorBadRequest {
|
||||
completionHandler(nil, NSFileProviderError(.noSuchItem, userInfo: [NSLocalizedDescriptionKey: error.errorDescription, NSLocalizedFailureReasonErrorKey: ""]))
|
||||
} else {
|
||||
completionHandler(nil, NSFileProviderError(.serverUnreachable))
|
||||
|
@ -188,20 +183,20 @@ extension FileProviderExtension {
|
|||
}
|
||||
|
||||
if (favorite == true && metadata.favorite == false) || (favorite == false && metadata.favorite == true) {
|
||||
let fileNamePath = utilityFileSystem.getFileNamePath(metadata.fileName, serverUrl: metadata.serverUrl, urlBase: metadata.urlBase, userId: metadata.userId)
|
||||
NextcloudKit.shared.setFavorite(fileName: fileNamePath, favorite: favorite, account: metadata.account) { _, error in
|
||||
let fileNamePath = utilityFileSystem.getFileNamePath(metadata.fileName, serverUrl: metadata.serverUrl, session: fileProviderData.shared.session)
|
||||
NextcloudKit.shared.setFavorite(fileName: fileNamePath, favorite: favorite, account: metadata.account) { _, _, error in
|
||||
if error == .success {
|
||||
guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) else {
|
||||
guard let metadata = self.database.getMetadataFromOcId(ocId) else {
|
||||
return completionHandler(nil, NSFileProviderError(.noSuchItem))
|
||||
}
|
||||
// Change DB
|
||||
metadata.favorite = favorite
|
||||
NCManageDatabase.shared.addMetadata(metadata)
|
||||
self.database.addMetadata(metadata)
|
||||
/// SIGNAL
|
||||
let item = fileProviderData.shared.signalEnumerator(ocId: metadata.ocId, type: .workingSet)
|
||||
completionHandler(item, nil)
|
||||
} else {
|
||||
guard let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId) else {
|
||||
guard let metadata = self.database.getMetadataFromOcId(ocId) else {
|
||||
return completionHandler(nil, NSFileProviderError(.noSuchItem))
|
||||
}
|
||||
// Errore, remove from listFavoriteIdentifierRank
|
||||
|
@ -221,7 +216,7 @@ extension FileProviderExtension {
|
|||
let ocId = metadataForTag.ocId
|
||||
let account = metadataForTag.account
|
||||
|
||||
NCManageDatabase.shared.addTag(ocId, tagIOS: tagData, account: account)
|
||||
self.database.addTag(ocId, tagIOS: tagData, account: account)
|
||||
/// SIGNAL WORKINGSET
|
||||
let item = fileProviderData.shared.signalEnumerator(ocId: ocId, type: .workingSet)
|
||||
completionHandler(item, nil)
|
||||
|
|
|
@ -37,10 +37,19 @@ extension FileProviderExtension: NCNetworkingDelegate {
|
|||
guard let url = task.currentRequest?.url,
|
||||
let metadata = NCManageDatabase.shared.getMetadata(from: url, sessionTaskIdentifier: task.taskIdentifier) else { return }
|
||||
|
||||
DispatchQueue.global(qos: .userInteractive).async {
|
||||
if let ocId, !metadata.ocIdTransfer.isEmpty {
|
||||
let atPath = self.utilityFileSystem.getDirectoryProviderStorageOcId(metadata.ocIdTransfer)
|
||||
let toPath = self.utilityFileSystem.getDirectoryProviderStorageOcId(ocId)
|
||||
self.utilityFileSystem.copyFile(atPath: atPath, toPath: toPath)
|
||||
}
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
|
||||
if error == .success, let ocId {
|
||||
/// SIGNAL
|
||||
fileProviderData.shared.signalEnumerator(ocId: metadata.ocIdTemp, type: .delete)
|
||||
fileProviderData.shared.signalEnumerator(ocId: metadata.ocIdTransfer, type: .delete)
|
||||
if !metadata.ocIdTransfer.isEmpty, ocId != metadata.ocIdTransfer {
|
||||
NCManageDatabase.shared.deleteMetadataOcId(metadata.ocIdTransfer)
|
||||
}
|
||||
metadata.fileName = fileName
|
||||
metadata.serverUrl = serverUrl
|
||||
metadata.uploadDate = (date as? NSDate) ?? NSDate()
|
||||
|
@ -61,19 +70,13 @@ extension FileProviderExtension: NCNetworkingDelegate {
|
|||
|
||||
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))
|
||||
NCManageDatabase.shared.deleteMetadataOcId(metadata.ocIdTransfer)
|
||||
/// SIGNAL
|
||||
fileProviderData.shared.signalEnumerator(ocId: metadata.ocIdTemp, type: .delete)
|
||||
fileProviderData.shared.signalEnumerator(ocId: metadata.ocIdTransfer, type: .delete)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
import UIKit
|
||||
import FileProvider
|
||||
import NextcloudKit
|
||||
import Alamofire
|
||||
|
||||
extension FileProviderExtension {
|
||||
override func fetchThumbnails(for itemIdentifiers: [NSFileProviderItemIdentifier], requestedSize size: CGSize, perThumbnailCompletionHandler: @escaping (NSFileProviderItemIdentifier, Data?, Error?) -> Void, completionHandler: @escaping (Error?) -> Void) -> Progress {
|
||||
|
@ -36,14 +37,14 @@ extension FileProviderExtension {
|
|||
if counterProgress == progress.totalUnitCount { completionHandler(nil) }
|
||||
continue
|
||||
}
|
||||
let fileNameIconLocalPath = utilityFileSystem.getDirectoryProviderStorageIconOcId(metadata.ocId, etag: metadata.etag)
|
||||
|
||||
NextcloudKit.shared.downloadPreview(fileId: metadata.fileId, widthPreview: Int(size.width), heightPreview: Int(size.height), etag: metadata.etag, account: metadata.account) { _ in
|
||||
} completion: { _, data, error in
|
||||
if error == .success, let data {
|
||||
do {
|
||||
try data.write(to: URL(fileURLWithPath: fileNameIconLocalPath), options: .atomic)
|
||||
} catch { }
|
||||
NextcloudKit.shared.downloadPreview(fileId: metadata.fileId,
|
||||
width: Int(size.width),
|
||||
height: Int(size.height),
|
||||
etag: metadata.etag,
|
||||
account: metadata.account) { _ in
|
||||
} completion: { _, _, _, _, responseData, error in
|
||||
if error == .success, let data = responseData?.data {
|
||||
perThumbnailCompletionHandler(itemIdentifier, data, nil)
|
||||
} else {
|
||||
perThumbnailCompletionHandler(itemIdentifier, nil, NSFileProviderError(.serverUnreachable))
|
||||
|
|
|
@ -55,16 +55,13 @@ import Alamofire
|
|||
class FileProviderExtension: NSFileProviderExtension {
|
||||
let providerUtility = fileProviderUtility()
|
||||
let utilityFileSystem = NCUtilityFileSystem()
|
||||
let database = NCManageDatabase.shared
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
|
||||
// Create directory File Provider Storage
|
||||
_ = utilityFileSystem.directoryProviderStorage
|
||||
// Configure URLSession
|
||||
_ = NCNetworking.shared.sessionManagerUploadBackgroundExtension
|
||||
// Domains
|
||||
// FileProviderDomain().registerDomains()
|
||||
_ = fileProviderData.shared.setupAccount(domain: domain, providerExtension: self)
|
||||
}
|
||||
|
||||
deinit {
|
||||
|
@ -114,12 +111,12 @@ class FileProviderExtension: NSFileProviderExtension {
|
|||
override func item(for identifier: NSFileProviderItemIdentifier) throws -> NSFileProviderItem {
|
||||
if identifier == .rootContainer {
|
||||
let metadata = tableMetadata()
|
||||
metadata.account = fileProviderData.shared.account
|
||||
metadata.account = fileProviderData.shared.session.account
|
||||
metadata.directory = true
|
||||
metadata.ocId = NSFileProviderItemIdentifier.rootContainer.rawValue
|
||||
metadata.fileName = "root"
|
||||
metadata.fileNameView = "root"
|
||||
metadata.serverUrl = fileProviderData.shared.homeServerUrl
|
||||
metadata.serverUrl = utilityFileSystem.getHomeServer(session: fileProviderData.shared.session)
|
||||
metadata.classFile = NKCommon.TypeClassFile.directory.rawValue
|
||||
return FileProviderItem(metadata: metadata, parentItemIdentifier: NSFileProviderItemIdentifier(NSFileProviderItemIdentifier.rootContainer.rawValue))
|
||||
} else {
|
||||
|
@ -170,35 +167,36 @@ class FileProviderExtension: NSFileProviderExtension {
|
|||
if let result = fileProviderData.shared.getUploadMetadata(id: itemIdentifier.rawValue) {
|
||||
metadata = result.metadata
|
||||
} else {
|
||||
metadata = NCManageDatabase.shared.getMetadataFromOcIdAndOcIdTemp(itemIdentifier.rawValue)
|
||||
metadata = self.database.getMetadataFromOcIdAndocIdTransfer(itemIdentifier.rawValue)
|
||||
}
|
||||
guard let metadata else {
|
||||
return completionHandler(NSFileProviderError(.noSuchItem))
|
||||
}
|
||||
if metadata.session == NCNetworking.shared.sessionUploadBackgroundExtension {
|
||||
if metadata.session == NCNetworking.shared.sessionUploadBackgroundExt {
|
||||
return completionHandler(nil)
|
||||
}
|
||||
let serverUrlFileName = metadata.serverUrl + "/" + metadata.fileName
|
||||
let fileNameLocalPath = utilityFileSystem.getDirectoryProviderStorageOcId(metadata.ocId, fileNameView: metadata.fileName)
|
||||
// Exists ? return
|
||||
if let tableLocalFile = NCManageDatabase.shared.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)),
|
||||
if let tableLocalFile = self.database.getTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId)),
|
||||
utilityFileSystem.fileProviderStorageExists(metadata),
|
||||
tableLocalFile.etag == metadata.etag {
|
||||
return completionHandler(nil)
|
||||
} else {
|
||||
NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId,
|
||||
session: NextcloudKit.shared.nkCommonInstance.sessionIdentifierDownload,
|
||||
sessionError: "",
|
||||
selector: "",
|
||||
status: NCGlobal.shared.metadataStatusDownloading)
|
||||
self.database.setMetadataSession(ocId: metadata.ocId,
|
||||
session: NCNetworking.shared.sessionDownload,
|
||||
sessionTaskIdentifier: 0,
|
||||
sessionError: "",
|
||||
selector: "",
|
||||
status: NCGlobal.shared.metadataStatusDownloading)
|
||||
}
|
||||
/// SIGNAL
|
||||
fileProviderData.shared.signalEnumerator(ocId: metadata.ocId, type: .update)
|
||||
|
||||
NextcloudKit.shared.download(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, account: metadata.account, requestHandler: { _ in
|
||||
}, taskHandler: { task in
|
||||
NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId,
|
||||
taskIdentifier: task.taskIdentifier)
|
||||
self.database.setMetadataSession(ocId: metadata.ocId,
|
||||
sessionTaskIdentifier: task.taskIdentifier)
|
||||
fileProviderData.shared.fileProviderManager.register(task, forItemWithIdentifier: NSFileProviderItemIdentifier(itemIdentifier.rawValue)) { _ in }
|
||||
}, progressHandler: { _ in
|
||||
}) { _, etag, date, _, _, _, error in
|
||||
|
@ -215,16 +213,16 @@ class FileProviderExtension: NSFileProviderExtension {
|
|||
metadata.status = NCGlobal.shared.metadataStatusNormal
|
||||
metadata.date = (date as? NSDate) ?? NSDate()
|
||||
metadata.etag = etag ?? ""
|
||||
NCManageDatabase.shared.addLocalFile(metadata: metadata)
|
||||
NCManageDatabase.shared.addMetadata(metadata)
|
||||
self.database.addLocalFile(metadata: metadata)
|
||||
self.database.addMetadata(metadata)
|
||||
completionHandler(nil)
|
||||
} else if error.errorCode == 200 {
|
||||
NCManageDatabase.shared.setMetadataStatus(ocId: metadata.ocId, status: NCGlobal.shared.metadataStatusNormal)
|
||||
self.database.setMetadataStatus(ocId: metadata.ocId, status: NCGlobal.shared.metadataStatusNormal)
|
||||
completionHandler(nil)
|
||||
} else {
|
||||
metadata.status = NCGlobal.shared.metadataStatusDownloadError
|
||||
metadata.sessionError = error.errorDescription
|
||||
NCManageDatabase.shared.addMetadata(metadata)
|
||||
self.database.addMetadata(metadata)
|
||||
completionHandler(NSFileProviderError(.noSuchItem))
|
||||
}
|
||||
/// SIGNAL
|
||||
|
@ -242,23 +240,33 @@ class FileProviderExtension: NSFileProviderExtension {
|
|||
if let result = fileProviderData.shared.getUploadMetadata(id: itemIdentifier.rawValue) {
|
||||
metadata = result.metadata
|
||||
} else {
|
||||
metadata = NCManageDatabase.shared.getMetadataFromOcIdAndOcIdTemp(itemIdentifier.rawValue)
|
||||
metadata = self.database.getMetadataFromOcIdAndocIdTransfer(itemIdentifier.rawValue)
|
||||
}
|
||||
guard let metadata else {
|
||||
return
|
||||
}
|
||||
let serverUrlFileName = metadata.serverUrl + "/" + fileName
|
||||
|
||||
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: url.path, dateCreationFile: nil, dateModificationFile: nil, account: metadata.account, session: NCNetworking.shared.sessionManagerUploadBackgroundExtension) {
|
||||
NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId,
|
||||
status: NCGlobal.shared.metadataStatusUploading,
|
||||
taskIdentifier: task.taskIdentifier)
|
||||
fileProviderData.shared.fileProviderManager.register(task, forItemWithIdentifier: NSFileProviderItemIdentifier(metadata.fileId)) { _ in }
|
||||
self.database.setMetadataSession(ocId: metadata.ocId,
|
||||
session: NCNetworking.shared.sessionUploadBackgroundExt,
|
||||
sessionTaskIdentifier: 0,
|
||||
sessionError: "",
|
||||
selector: "",
|
||||
status: NCGlobal.shared.metadataStatusUploading)
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
if let task = NKBackground(nkCommonInstance: NextcloudKit.shared.nkCommonInstance).upload(serverUrlFileName: serverUrlFileName,
|
||||
fileNameLocalPath: url.path,
|
||||
dateCreationFile: nil,
|
||||
dateModificationFile: nil,
|
||||
overwrite: true,
|
||||
account: metadata.account,
|
||||
sessionIdentifier: metadata.session) {
|
||||
self.database.setMetadataSession(ocId: metadata.ocId,
|
||||
sessionTaskIdentifier: task.taskIdentifier,
|
||||
status: NCGlobal.shared.metadataStatusUploading)
|
||||
fileProviderData.shared.fileProviderManager.register(task, forItemWithIdentifier: NSFileProviderItemIdentifier(metadata.fileId)) { _ in }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -266,9 +274,10 @@ class FileProviderExtension: NSFileProviderExtension {
|
|||
let pathComponents = url.pathComponents
|
||||
assert(pathComponents.count > 2)
|
||||
let itemIdentifier = NSFileProviderItemIdentifier(pathComponents[pathComponents.count - 2])
|
||||
guard let metadata = NCManageDatabase.shared.getMetadataFromOcIdAndOcIdTemp(itemIdentifier.rawValue) else { return }
|
||||
if metadata.session == NextcloudKit.shared.nkCommonInstance.sessionIdentifierDownload {
|
||||
NextcloudKit.shared.sessionManager.session.getTasksWithCompletionHandler { _, _, downloadTasks in
|
||||
guard let metadata = self.database.getMetadataFromOcIdAndocIdTransfer(itemIdentifier.rawValue) else { return }
|
||||
if metadata.session == NCNetworking.shared.sessionDownload {
|
||||
let session = NextcloudKit.shared.nkCommonInstance.getSession(account: metadata.session)?.sessionData.session
|
||||
session?.getTasksWithCompletionHandler { _, _, downloadTasks in
|
||||
downloadTasks.forEach { task in
|
||||
if metadata.sessionTaskIdentifier == task.taskIdentifier {
|
||||
task.cancel()
|
||||
|
@ -281,7 +290,7 @@ class FileProviderExtension: NSFileProviderExtension {
|
|||
override func importDocument(at fileURL: URL, toParentItemIdentifier parentItemIdentifier: NSFileProviderItemIdentifier, completionHandler: @escaping (NSFileProviderItem?, Error?) -> Void) {
|
||||
DispatchQueue.main.async {
|
||||
autoreleasepool {
|
||||
guard let tableDirectory = self.providerUtility.getTableDirectoryFromParentItemIdentifier(parentItemIdentifier, account: fileProviderData.shared.account, homeServerUrl: fileProviderData.shared.homeServerUrl) else {
|
||||
guard let tableDirectory = self.providerUtility.getTableDirectoryFromParentItemIdentifier(parentItemIdentifier, account: fileProviderData.shared.session.account, homeServerUrl: self.utilityFileSystem.getHomeServer(session: fileProviderData.shared.session)) else {
|
||||
return completionHandler(nil, NSFileProviderError(.noSuchItem))
|
||||
}
|
||||
var size = 0 as Int64
|
||||
|
@ -299,34 +308,48 @@ class FileProviderExtension: NSFileProviderExtension {
|
|||
return completionHandler(nil, NSFileProviderError(.noSuchItem))
|
||||
}
|
||||
|
||||
let fileName = self.utilityFileSystem.createFileName(fileURL.lastPathComponent, serverUrl: tableDirectory.serverUrl, account: fileProviderData.shared.account)
|
||||
let ocIdTemp = NSUUID().uuidString.lowercased()
|
||||
let fileName = self.utilityFileSystem.createFileName(fileURL.lastPathComponent, serverUrl: tableDirectory.serverUrl, account: fileProviderData.shared.session.account)
|
||||
let ocIdTransfer = NSUUID().uuidString.lowercased()
|
||||
|
||||
NSFileCoordinator().coordinate(readingItemAt: fileURL, options: .withoutChanges, error: &error) { url in
|
||||
self.providerUtility.copyFile(url.path, toPath: self.utilityFileSystem.getDirectoryProviderStorageOcId(ocIdTemp, fileNameView: fileName))
|
||||
self.providerUtility.copyFile(url.path, toPath: self.utilityFileSystem.getDirectoryProviderStorageOcId(ocIdTransfer, fileNameView: fileName))
|
||||
}
|
||||
|
||||
fileURL.stopAccessingSecurityScopedResource()
|
||||
|
||||
let metadata = NCManageDatabase.shared.createMetadata(account: fileProviderData.shared.account, user: fileProviderData.shared.user, userId: fileProviderData.shared.userId, fileName: fileName, fileNameView: fileName, ocId: ocIdTemp, serverUrl: tableDirectory.serverUrl, urlBase: fileProviderData.shared.accountUrlBase, url: "", contentType: "")
|
||||
metadata.session = NCNetworking.shared.sessionUploadBackgroundExtension
|
||||
metadata.size = size
|
||||
metadata.status = NCGlobal.shared.metadataStatusUploading
|
||||
let metadataForUpload = self.database.createMetadata(fileName: fileName,
|
||||
fileNameView: fileName,
|
||||
ocId: ocIdTransfer,
|
||||
serverUrl: tableDirectory.serverUrl,
|
||||
url: "",
|
||||
contentType: "",
|
||||
session: fileProviderData.shared.session,
|
||||
sceneIdentifier: nil)
|
||||
|
||||
NCManageDatabase.shared.addMetadata(metadata)
|
||||
metadataForUpload.session = NCNetworking.shared.sessionUploadBackgroundExt
|
||||
metadataForUpload.size = size
|
||||
metadataForUpload.status = NCGlobal.shared.metadataStatusUploading
|
||||
|
||||
self.database.addMetadata(metadataForUpload)
|
||||
|
||||
let serverUrlFileName = tableDirectory.serverUrl + "/" + fileName
|
||||
let fileNameLocalPath = self.utilityFileSystem.getDirectoryProviderStorageOcId(ocIdTemp, fileNameView: fileName)
|
||||
let fileNameLocalPath = self.utilityFileSystem.getDirectoryProviderStorageOcId(ocIdTransfer, fileNameView: fileName)
|
||||
|
||||
if let task = NKBackground(nkCommonInstance: NextcloudKit.shared.nkCommonInstance).upload(serverUrlFileName: serverUrlFileName, fileNameLocalPath: fileNameLocalPath, dateCreationFile: nil, dateModificationFile: nil, account: metadata.account, session: NCNetworking.shared.sessionManagerUploadBackgroundExtension) {
|
||||
NCManageDatabase.shared.setMetadataSession(ocId: metadata.ocId,
|
||||
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)
|
||||
if let task = NKBackground(nkCommonInstance: NextcloudKit.shared.nkCommonInstance).upload(serverUrlFileName: serverUrlFileName,
|
||||
fileNameLocalPath: fileNameLocalPath,
|
||||
dateCreationFile: nil,
|
||||
dateModificationFile: nil,
|
||||
overwrite: true,
|
||||
account: metadataForUpload.account,
|
||||
sessionIdentifier: metadataForUpload.session) {
|
||||
self.database.setMetadataSession(ocId: metadataForUpload.ocId,
|
||||
sessionTaskIdentifier: task.taskIdentifier,
|
||||
status: NCGlobal.shared.metadataStatusUploading)
|
||||
fileProviderData.shared.fileProviderManager.register(task, forItemWithIdentifier: NSFileProviderItemIdentifier(ocIdTransfer)) { _ in }
|
||||
fileProviderData.shared.appendUploadMetadata(id: ocIdTransfer, metadata: metadataForUpload, task: task)
|
||||
}
|
||||
|
||||
let item = FileProviderItem(metadata: tableMetadata.init(value: metadata), parentItemIdentifier: parentItemIdentifier)
|
||||
let item = FileProviderItem(metadata: tableMetadata.init(value: metadataForUpload), parentItemIdentifier: parentItemIdentifier)
|
||||
completionHandler(item, nil)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ class FileProviderItem: NSObject, NSFileProviderItem {
|
|||
return metadata.fileNameView
|
||||
}
|
||||
var typeIdentifier: String {
|
||||
let results = NextcloudKit.shared.nkCommonInstance.getInternalType(fileName: metadata.fileNameView, mimeType: "", directory: metadata.directory)
|
||||
let results = NextcloudKit.shared.nkCommonInstance.getInternalType(fileName: metadata.fileNameView, mimeType: "", directory: metadata.directory, account: metadata.account)
|
||||
return results.typeIdentifier
|
||||
}
|
||||
var capabilities: NSFileProviderItemCapabilities {
|
||||
|
|
|
@ -26,15 +26,16 @@ import UIKit
|
|||
class fileProviderUtility: NSObject {
|
||||
let fileManager = FileManager()
|
||||
let utilityFileSystem = NCUtilityFileSystem()
|
||||
let database = NCManageDatabase.shared
|
||||
|
||||
func getAccountFromItemIdentifier(_ itemIdentifier: NSFileProviderItemIdentifier) -> String? {
|
||||
let ocId = itemIdentifier.rawValue
|
||||
return NCManageDatabase.shared.getMetadataFromOcId(ocId)?.account
|
||||
return self.database.getMetadataFromOcId(ocId)?.account
|
||||
}
|
||||
|
||||
func getTableMetadataFromItemIdentifier(_ itemIdentifier: NSFileProviderItemIdentifier) -> tableMetadata? {
|
||||
let ocId = itemIdentifier.rawValue
|
||||
return NCManageDatabase.shared.getMetadataFromOcId(ocId)
|
||||
return self.database.getMetadataFromOcId(ocId)
|
||||
}
|
||||
|
||||
func getItemIdentifier(metadata: tableMetadata) -> NSFileProviderItemIdentifier {
|
||||
|
@ -42,13 +43,13 @@ class fileProviderUtility: NSObject {
|
|||
}
|
||||
|
||||
func getParentItemIdentifier(metadata: tableMetadata) -> NSFileProviderItemIdentifier? {
|
||||
let homeServerUrl = utilityFileSystem.getHomeServer(urlBase: metadata.urlBase, userId: metadata.userId)
|
||||
if let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", metadata.account, metadata.serverUrl)) {
|
||||
let homeServerUrl = utilityFileSystem.getHomeServer(session: fileProviderData.shared.session)
|
||||
if let directory = self.database.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", metadata.account, metadata.serverUrl)) {
|
||||
if directory.serverUrl == homeServerUrl {
|
||||
return NSFileProviderItemIdentifier(NSFileProviderItemIdentifier.rootContainer.rawValue)
|
||||
} else {
|
||||
// get the metadata.ocId of parent Directory
|
||||
if let metadata = NCManageDatabase.shared.getMetadataFromOcId(directory.ocId) {
|
||||
if let metadata = self.database.getMetadataFromOcId(directory.ocId) {
|
||||
let identifier = getItemIdentifier(metadata: metadata)
|
||||
return identifier
|
||||
}
|
||||
|
@ -65,7 +66,7 @@ class fileProviderUtility: NSObject {
|
|||
guard let metadata = getTableMetadataFromItemIdentifier(parentItemIdentifier) else { return nil }
|
||||
predicate = NSPredicate(format: "ocId == %@", metadata.ocId)
|
||||
}
|
||||
guard let directory = NCManageDatabase.shared.getTableDirectory(predicate: predicate) else { return nil }
|
||||
guard let directory = self.database.getTableDirectory(predicate: predicate) else { return nil }
|
||||
return directory
|
||||
}
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -120,8 +120,12 @@
|
|||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES"
|
||||
launchAutomaticallySubstyle = "2">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<RemoteRunnable
|
||||
runnableDebuggingMode = "0"
|
||||
BundleIdentifier = "it.twsweb.Nextcloud"
|
||||
RemotePath = "/var/containers/Bundle/Application/92F13FE8-7056-4509-8468-5856675AB1CA/Nextcloud.app">
|
||||
</RemoteRunnable>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "F77B0DEB1D118A16002130FE"
|
||||
|
@ -129,7 +133,7 @@
|
|||
BlueprintName = "Nextcloud"
|
||||
ReferencedContainer = "container:Nextcloud.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</MacroExpansion>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
|
|
|
@ -121,9 +121,9 @@
|
|||
allowLocationSimulation = "YES"
|
||||
launchAutomaticallySubstyle = "2">
|
||||
<RemoteRunnable
|
||||
runnableDebuggingMode = "1"
|
||||
runnableDebuggingMode = "0"
|
||||
BundleIdentifier = "it.twsweb.Nextcloud"
|
||||
RemotePath = "/Users/marinofaggiana/Library/Developer/CoreSimulator/Devices/4DBB1715-4E24-4CE7-B67C-CA327B95130C/data/Containers/Bundle/Application/F427D7FF-1632-4BB9-ADEA-A094898BB6C7/Nextcloud.app">
|
||||
RemotePath = "/var/containers/Bundle/Application/92F13FE8-7056-4509-8468-5856675AB1CA/Nextcloud.app">
|
||||
</RemoteRunnable>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
|
|
|
@ -36,8 +36,7 @@ class NotificationService: UNNotificationServiceExtension {
|
|||
bestAttemptContent.body = "Nextcloud notification"
|
||||
do {
|
||||
if let message = bestAttemptContent.userInfo["subject"] as? String {
|
||||
let tableAccounts = NCManageDatabase.shared.getAllAccount()
|
||||
for tableAccount in tableAccounts {
|
||||
for tableAccount in NCManageDatabase.shared.getAllTableAccount() {
|
||||
guard let privateKey = NCKeychain().getPushNotificationPrivateKey(account: tableAccount.account),
|
||||
let decryptedMessage = NCPushNotificationEncryption.shared().decryptPushNotification(message, withDevicePrivateKey: privateKey),
|
||||
let data = decryptedMessage.data(using: .utf8) else {
|
||||
|
|
10
README.md
10
README.md
|
@ -38,18 +38,10 @@ branch. Maybe start working on [starter issues](https://github.com/nextcloud/ios
|
|||
|
||||
Easy starting points are also reviewing [pull requests](https://github.com/nextcloud/ios/pulls)
|
||||
|
||||
### Xcode 15 Project Setup
|
||||
### Xcode 16 Project Setup
|
||||
|
||||
#### Dependencies
|
||||
|
||||
After forking a repository you have to build the dependencies. Dependencies are managed with Carthage version 0.38.0 or later.
|
||||
Run
|
||||
|
||||
```
|
||||
carthage update --use-xcframeworks --platform iOS
|
||||
```
|
||||
to fetch and compile the dependencies.
|
||||
|
||||
In order to build the project in Xcode you will also need a file `GoogleService-Info.plist` at the root of the repository which contains the Firebase configuration. For development work you can use a mock version found [here](https://github.com/firebase/quickstart-ios/blob/master/mock-GoogleService-Info.plist).
|
||||
|
||||
### Creating Pull requests
|
||||
|
|
|
@ -27,7 +27,7 @@ import NextcloudKit
|
|||
protocol NCShareCellDelegate: AnyObject {
|
||||
var uploadStarted: Bool { get }
|
||||
func removeFile(named fileName: String)
|
||||
func renameFile(named fileName: String)
|
||||
func renameFile(named fileName: String, account: String)
|
||||
}
|
||||
|
||||
class NCShareCell: UITableViewCell {
|
||||
|
@ -36,13 +36,15 @@ class NCShareCell: UITableViewCell {
|
|||
@IBOutlet weak var moreButton: UIButton!
|
||||
@IBOutlet weak var sizeCell: UILabel!
|
||||
weak var delegate: (NCShareCellDelegate & UIViewController)?
|
||||
var fileName = ""
|
||||
var fileName: String = ""
|
||||
var account: String = ""
|
||||
let utilityFileSystem = NCUtilityFileSystem()
|
||||
let utility = NCUtility()
|
||||
|
||||
func setup(fileName: String) {
|
||||
func setup(fileName: String, account: String) {
|
||||
self.fileName = fileName
|
||||
let resultInternalType = NextcloudKit.shared.nkCommonInstance.getInternalType(fileName: fileName, mimeType: "", directory: false)
|
||||
self.account = account
|
||||
let resultInternalType = NextcloudKit.shared.nkCommonInstance.getInternalType(fileName: fileName, mimeType: "", directory: false, account: account)
|
||||
|
||||
backgroundColor = .systemBackground
|
||||
imageCell?.layer.cornerRadius = 6
|
||||
|
@ -52,7 +54,7 @@ class NCShareCell: UITableViewCell {
|
|||
imageCell.image = image
|
||||
imageCell.contentMode = .scaleAspectFill
|
||||
} else {
|
||||
imageCell.image = utility.loadImage(named: resultInternalType.iconName, useTypeIconFile: true)
|
||||
imageCell.image = utility.loadImage(named: resultInternalType.iconName, useTypeIconFile: true, account: account)
|
||||
imageCell.contentMode = .scaleAspectFit
|
||||
}
|
||||
|
||||
|
@ -61,7 +63,7 @@ class NCShareCell: UITableViewCell {
|
|||
let fileSize = utilityFileSystem.getFileSize(filePath: (NSTemporaryDirectory() + fileName))
|
||||
sizeCell?.text = utilityFileSystem.transformedSize(fileSize)
|
||||
|
||||
moreButton?.setImage(NCImageCache.images.buttonMore, for: .normal)
|
||||
moreButton?.setImage(NCImageCache.shared.getImageButtonMore(), for: .normal)
|
||||
}
|
||||
|
||||
@IBAction func buttonTapped(_ sender: Any) {
|
||||
|
@ -69,7 +71,7 @@ class NCShareCell: UITableViewCell {
|
|||
let alertController = UIAlertController(title: "", message: fileName, preferredStyle: .alert)
|
||||
|
||||
alertController.addAction(UIAlertAction(title: NSLocalizedString("_rename_file_", comment: ""), style: .default) { _ in
|
||||
self.delegate?.renameFile(named: self.fileName)
|
||||
self.delegate?.renameFile(named: self.fileName, account: self.account)
|
||||
})
|
||||
|
||||
alertController.addAction(UIAlertAction(title: NSLocalizedString("_remove_file_", comment: ""), style: .default) { _ in
|
||||
|
|
|
@ -27,15 +27,14 @@ import NextcloudKit
|
|||
// MARK: - Collection View (target folder)
|
||||
|
||||
extension NCShareExtension: UICollectionViewDelegate {
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||
guard let metadata = dataSource.cellForItemAt(indexPath: indexPath) else { return showAlert(description: "_invalid_url_") }
|
||||
guard let metadata = self.dataSource.getMetadata(indexPath: indexPath) else { return showAlert(description: "_invalid_url_") }
|
||||
let serverUrl = utilityFileSystem.stringAppendServerUrl(metadata.serverUrl, addFileName: metadata.fileName)
|
||||
if metadata.e2eEncrypted && !NCKeychain().isEndToEndEnabled(account: activeAccount.account) {
|
||||
if metadata.e2eEncrypted && !NCKeychain().isEndToEndEnabled(account: session.account) {
|
||||
showAlert(title: "_info_", description: "_e2e_goto_settings_for_enable_")
|
||||
}
|
||||
|
||||
if let fileNameError = FileNameValidator.shared.checkFileName(metadata.fileNameView) {
|
||||
if let fileNameError = FileNameValidator.shared.checkFileName(metadata.fileNameView, account: session.account) {
|
||||
present(UIAlertController.warning(message: "\(fileNameError.errorDescription) \(NSLocalizedString("_please_rename_file_", comment: ""))"), animated: true)
|
||||
return
|
||||
}
|
||||
|
@ -49,11 +48,11 @@ extension NCShareExtension: UICollectionViewDelegate {
|
|||
if kind == UICollectionView.elementKindSectionHeader {
|
||||
guard let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "sectionFirstHeaderEmptyData", for: indexPath) as? NCSectionFirstHeaderEmptyData else { return NCSectionFirstHeaderEmptyData() }
|
||||
if self.dataSourceTask?.state == .running {
|
||||
header.emptyImage.image = utility.loadImage(named: "wifi", colors: [NCBrandColor.shared.brandElement])
|
||||
header.emptyImage.image = utility.loadImage(named: "wifi", colors: [NCBrandColor.shared.getElement(account: session.account)])
|
||||
header.emptyTitle.text = NSLocalizedString("_request_in_progress_", comment: "")
|
||||
header.emptyDescription.text = ""
|
||||
} else {
|
||||
header.emptyImage.image = NCImageCache.images.folder
|
||||
header.emptyImage.image = NCImageCache.shared.getFolder(account: self.session.account)
|
||||
header.emptyTitle.text = NSLocalizedString("_files_no_folders_", comment: "")
|
||||
header.emptyDescription.text = ""
|
||||
}
|
||||
|
@ -67,30 +66,30 @@ extension NCShareExtension: UICollectionViewDelegate {
|
|||
extension NCShareExtension: UICollectionViewDelegateFlowLayout {
|
||||
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
|
||||
var height: CGFloat = 0
|
||||
if dataSource.getMetadataSourceForAllSections().isEmpty {
|
||||
height = NCGlobal.shared.getHeightHeaderEmptyData(view: view, portraitOffset: 0, landscapeOffset: -50)
|
||||
if self.dataSource.isEmpty() {
|
||||
height = NCUtility().getHeightHeaderEmptyData(view: view, portraitOffset: 0, landscapeOffset: -50)
|
||||
}
|
||||
return CGSize(width: collectionView.frame.width, height: height)
|
||||
}
|
||||
}
|
||||
|
||||
extension NCShareExtension: UICollectionViewDataSource {
|
||||
|
||||
func numberOfSections(in collectionView: UICollectionView) -> Int {
|
||||
return dataSource.numberOfSections()
|
||||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||
return dataSource.numberOfItemsInSection(section)
|
||||
return self.dataSource.numberOfItemsInSection(section)
|
||||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||
guard let metadata = dataSource.cellForItemAt(indexPath: indexPath), let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "listCell", for: indexPath) as? NCListCell else {
|
||||
return UICollectionViewCell()
|
||||
let cell = (collectionView.dequeueReusableCell(withReuseIdentifier: "listCell", for: indexPath) as? NCListCell)!
|
||||
guard let metadata = self.dataSource.getMetadata(indexPath: indexPath) else {
|
||||
return cell
|
||||
}
|
||||
|
||||
cell.fileObjectId = metadata.ocId
|
||||
cell.indexPath = indexPath
|
||||
cell.fileOcId = metadata.ocId
|
||||
cell.fileOcIdTransfer = metadata.ocIdTransfer
|
||||
cell.fileUser = metadata.ownerId
|
||||
cell.labelTitle.text = metadata.fileNameView
|
||||
cell.labelTitle.textColor = NCBrandColor.shared.textColor
|
||||
|
@ -102,14 +101,13 @@ extension NCShareExtension: UICollectionViewDataSource {
|
|||
cell.imageMore.image = nil
|
||||
cell.imageItem.image = nil
|
||||
cell.imageItem.backgroundColor = nil
|
||||
cell.progressView.progress = 0.0
|
||||
|
||||
if metadata.directory {
|
||||
setupDirectoryCell(cell, indexPath: indexPath, with: metadata)
|
||||
}
|
||||
|
||||
if metadata.favorite {
|
||||
cell.imageFavorite.image = NCImageCache.images.favorite
|
||||
cell.imageFavorite.image = NCImageCache.shared.getImageFavorite()
|
||||
}
|
||||
|
||||
cell.imageSelect.isHidden = true
|
||||
|
@ -119,7 +117,7 @@ extension NCShareExtension: UICollectionViewDataSource {
|
|||
cell.selected(false, isEditMode: false)
|
||||
|
||||
if metadata.isLivePhoto {
|
||||
cell.imageStatus.image = NCImageCache.images.livePhoto
|
||||
cell.imageStatus.image = utility.loadImage(named: "livephoto", colors: [NCBrandColor.shared.iconImageColor2])
|
||||
}
|
||||
|
||||
cell.setTags(tags: Array(metadata.tags))
|
||||
|
@ -139,31 +137,31 @@ extension NCShareExtension: UICollectionViewDataSource {
|
|||
}
|
||||
|
||||
if metadata.e2eEncrypted {
|
||||
cell.imageItem.image = NCImageCache.images.folderEncrypted
|
||||
cell.imageItem.image = NCImageCache.shared.getFolderEncrypted(account: metadata.account)
|
||||
} else if isShare {
|
||||
cell.imageItem.image = NCImageCache.images.folderSharedWithMe
|
||||
cell.imageItem.image = NCImageCache.shared.getFolderSharedWithMe(account: metadata.account)
|
||||
} else if !metadata.shareType.isEmpty {
|
||||
metadata.shareType.contains(3) ?
|
||||
(cell.imageItem.image = NCImageCache.images.folderPublic) :
|
||||
(cell.imageItem.image = NCImageCache.images.folderSharedWithMe)
|
||||
(cell.imageItem.image = NCImageCache.shared.getFolderPublic(account: metadata.account)) :
|
||||
(cell.imageItem.image = NCImageCache.shared.getFolderSharedWithMe(account: metadata.account))
|
||||
} else if metadata.mountType == "group" {
|
||||
cell.imageItem.image = NCImageCache.images.folderGroup
|
||||
cell.imageItem.image = NCImageCache.shared.getFolderGroup(account: metadata.account)
|
||||
} else if isMounted {
|
||||
cell.imageItem.image = NCImageCache.images.folderExternal
|
||||
cell.imageItem.image = NCImageCache.shared.getFolderExternal(account: metadata.account)
|
||||
} else if metadata.fileName == autoUploadFileName && metadata.serverUrl == autoUploadDirectory {
|
||||
cell.imageItem.image = NCImageCache.images.folderAutomaticUpload
|
||||
cell.imageItem.image = NCImageCache.shared.getFolderAutomaticUpload(account: metadata.account)
|
||||
} else {
|
||||
cell.imageItem.image = NCImageCache.images.folder
|
||||
cell.imageItem.image = NCImageCache.shared.getFolder(account: metadata.account)
|
||||
}
|
||||
|
||||
cell.labelInfo.text = utility.dateDiff(metadata.date as Date)
|
||||
|
||||
let lockServerUrl = utilityFileSystem.stringAppendServerUrl(metadata.serverUrl, addFileName: metadata.fileName)
|
||||
let tableDirectory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", activeAccount.account, lockServerUrl))
|
||||
let tableDirectory = self.database.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", session.account, lockServerUrl))
|
||||
|
||||
// Local image: offline
|
||||
if tableDirectory != nil && tableDirectory!.offline {
|
||||
cell.imageLocal.image = NCImageCache.images.offlineFlag
|
||||
cell.imageLocal.image = NCImageCache.shared.getImageOfflineFlag()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -171,7 +169,6 @@ extension NCShareExtension: UICollectionViewDataSource {
|
|||
// MARK: - Table View (uploading files)
|
||||
|
||||
extension NCShareExtension: UITableViewDelegate {
|
||||
|
||||
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
|
||||
return heightRowTableView
|
||||
}
|
||||
|
@ -179,12 +176,11 @@ extension NCShareExtension: UITableViewDelegate {
|
|||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
guard !uploadStarted else { return }
|
||||
let fileName = filesName[indexPath.row]
|
||||
renameFile(named: fileName)
|
||||
renameFile(named: fileName, account: session.account)
|
||||
}
|
||||
}
|
||||
|
||||
extension NCShareExtension: UITableViewDataSource {
|
||||
|
||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
filesName.count
|
||||
}
|
||||
|
@ -192,7 +188,7 @@ extension NCShareExtension: UITableViewDataSource {
|
|||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as? NCShareCell else { return UITableViewCell() }
|
||||
let fileName = filesName[indexPath.row]
|
||||
cell.setup(fileName: fileName)
|
||||
cell.setup(fileName: fileName, account: session.account)
|
||||
cell.delegate = self
|
||||
return cell
|
||||
}
|
||||
|
|
|
@ -22,14 +22,16 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import UniformTypeIdentifiers
|
||||
import NextcloudKit
|
||||
|
||||
extension NCShareExtension {
|
||||
@objc func reloadDatasource(withLoadFolder: Bool) {
|
||||
layoutForView = NCManageDatabase.shared.setLayoutForView(account: activeAccount.account, key: keyLayout, serverUrl: serverUrl)
|
||||
let metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND directory == true", activeAccount.account, serverUrl))
|
||||
self.dataSource = NCDataSource(metadatas: metadatas, account: activeAccount.account, layoutForView: layoutForView)
|
||||
let predicate = NSPredicate(format: "account == %@ AND serverUrl == %@ AND directory == true", session.account, serverUrl)
|
||||
let results = self.database.getResultsMetadatasPredicate(predicate, layoutForView: NCDBLayoutForView())
|
||||
|
||||
self.dataSource = NCCollectionViewDataSource(results: results)
|
||||
|
||||
if withLoadFolder {
|
||||
loadFolder()
|
||||
|
@ -42,7 +44,7 @@ extension NCShareExtension {
|
|||
@objc func didCreateFolder(_ notification: NSNotification) {
|
||||
guard let userInfo = notification.userInfo as NSDictionary?,
|
||||
let ocId = userInfo["ocId"] as? String,
|
||||
let metadata = NCManageDatabase.shared.getMetadataFromOcId(ocId)
|
||||
let metadata = self.database.getMetadataFromOcId(ocId)
|
||||
else { return }
|
||||
|
||||
self.serverUrl += "/" + metadata.fileName
|
||||
|
@ -51,10 +53,13 @@ extension NCShareExtension {
|
|||
}
|
||||
|
||||
func loadFolder() {
|
||||
NCNetworking.shared.readFolder(serverUrl: serverUrl, account: activeAccount.account) { task in
|
||||
NCNetworking.shared.readFolder(serverUrl: serverUrl,
|
||||
account: session.account,
|
||||
checkResponseDataChanged: false,
|
||||
queue: .main) { task in
|
||||
self.dataSourceTask = task
|
||||
self.collectionView.reloadData()
|
||||
} completion: { _, metadataFolder, _, _, _, error in
|
||||
} completion: { _, metadataFolder, _, _, error in
|
||||
DispatchQueue.main.async {
|
||||
if error != .success {
|
||||
self.showAlert(description: error.errorDescription)
|
||||
|
|
|
@ -29,16 +29,16 @@ extension NCShareExtension: NCAccountRequestDelegate {
|
|||
// MARK: - Account
|
||||
|
||||
func showAccountPicker() {
|
||||
let accounts = NCManageDatabase.shared.getAllAccountOrderAlias()
|
||||
let accounts = self.database.getAllAccountOrderAlias()
|
||||
guard accounts.count > 1,
|
||||
let vcAccountRequest = UIStoryboard(name: "NCAccountRequest", bundle: nil).instantiateInitialViewController() as? NCAccountRequest else { return }
|
||||
|
||||
// Only here change the active account
|
||||
for account in accounts {
|
||||
account.active = account.account == self.activeAccount.account
|
||||
account.active = account.account == session.account
|
||||
}
|
||||
|
||||
vcAccountRequest.activeAccount = self.activeAccount
|
||||
vcAccountRequest.activeAccount = self.session.account
|
||||
vcAccountRequest.accounts = accounts.sorted { sorg, dest -> Bool in
|
||||
return sorg.active && !dest.active
|
||||
}
|
||||
|
@ -57,49 +57,37 @@ extension NCShareExtension: NCAccountRequestDelegate {
|
|||
|
||||
func accountRequestAddAccount() { }
|
||||
|
||||
func accountRequestChangeAccount(account: String) {
|
||||
guard let activeAccount = NCManageDatabase.shared.getAccount(predicate: NSPredicate(format: "account == %@", account)) else {
|
||||
func accountRequestChangeAccount(account: String, controller: UIViewController?) {
|
||||
guard let tableAccount = self.database.getTableAccount(predicate: NSPredicate(format: "account == %@", account)),
|
||||
let capabilities = self.database.setCapabilities(account: account) else {
|
||||
cancel(with: NCShareExtensionError.noAccount)
|
||||
return
|
||||
}
|
||||
self.activeAccount = activeAccount
|
||||
|
||||
// CAPABILITIES
|
||||
NCManageDatabase.shared.setCapabilities(account: account)
|
||||
self.account = account
|
||||
|
||||
// COLORS
|
||||
NCBrandColor.shared.settingThemingColor(account: activeAccount.account)
|
||||
NCBrandColor.shared.createUserColors()
|
||||
NCImageCache.shared.createImagesBrandCache()
|
||||
NCBrandColor.shared.settingThemingColor(account: account)
|
||||
NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterChangeTheming, userInfo: ["account": account])
|
||||
|
||||
// NETWORKING
|
||||
NextcloudKit.shared.setup(
|
||||
account: activeAccount.account,
|
||||
user: activeAccount.user,
|
||||
userId: activeAccount.userId,
|
||||
password: NCKeychain().getPassword(account: activeAccount.account),
|
||||
urlBase: activeAccount.urlBase,
|
||||
userAgent: userAgent,
|
||||
nextcloudVersion: 0,
|
||||
delegate: NCNetworking.shared)
|
||||
NextcloudKit.shared.setup(delegate: NCNetworking.shared)
|
||||
NextcloudKit.shared.appendSession(account: tableAccount.account,
|
||||
urlBase: tableAccount.urlBase,
|
||||
user: tableAccount.user,
|
||||
userId: tableAccount.userId,
|
||||
password: NCKeychain().getPassword(account: tableAccount.account),
|
||||
userAgent: userAgent,
|
||||
nextcloudVersion: capabilities.capabilityServerVersionMajor,
|
||||
groupIdentifier: NCBrandOptions.shared.capabilitiesGroup)
|
||||
|
||||
// get auto upload folder
|
||||
autoUploadFileName = NCManageDatabase.shared.getAccountAutoUploadFileName()
|
||||
autoUploadDirectory = NCManageDatabase.shared.getAccountAutoUploadDirectory(urlBase: activeAccount.urlBase, userId: activeAccount.userId, account: activeAccount.account)
|
||||
autoUploadFileName = self.database.getAccountAutoUploadFileName()
|
||||
autoUploadDirectory = self.database.getAccountAutoUploadDirectory(session: session)
|
||||
|
||||
serverUrl = utilityFileSystem.getHomeServer(urlBase: activeAccount.urlBase, userId: activeAccount.userId)
|
||||
|
||||
layoutForView = NCManageDatabase.shared.getLayoutForView(account: activeAccount.account, key: keyLayout, serverUrl: serverUrl)
|
||||
serverUrl = utilityFileSystem.getHomeServer(session: session)
|
||||
|
||||
reloadDatasource(withLoadFolder: true)
|
||||
setNavigationBar(navigationTitle: NCBrandOptions.shared.brand)
|
||||
|
||||
FileNameValidator.shared.setup(
|
||||
forbiddenFileNames: NCGlobal.shared.capabilityForbiddenFileNames,
|
||||
forbiddenFileNameBasenames: NCGlobal.shared.capabilityForbiddenFileNameBasenames,
|
||||
forbiddenFileNameCharacters: NCGlobal.shared.capabilityForbiddenFileNameCharacters,
|
||||
forbiddenFileNameExtensions: NCGlobal.shared.capabilityForbiddenFileNameExtensions
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,20 +105,8 @@ extension NCShareExtension: NCCreateFormUploadConflictDelegate {
|
|||
}
|
||||
|
||||
extension NCShareExtension: NCShareCellDelegate {
|
||||
func removeFile(named fileName: String) {
|
||||
guard let index = self.filesName.firstIndex(of: fileName) else {
|
||||
return showAlert(title: "_file_not_found_", description: fileName)
|
||||
}
|
||||
self.filesName.remove(at: index)
|
||||
if self.filesName.isEmpty {
|
||||
cancel(with: NCShareExtensionError.noFiles)
|
||||
} else {
|
||||
self.setCommandView()
|
||||
}
|
||||
}
|
||||
|
||||
func renameFile(named fileName: String) {
|
||||
let alert = UIAlertController.renameFile(fileName: fileName) { [self] newFileName in
|
||||
func renameFile(named fileName: String, account: String) {
|
||||
let alert = UIAlertController.renameFile(fileName: fileName, account: account) { [self] newFileName in
|
||||
guard let fileIx = self.filesName.firstIndex(of: fileName),
|
||||
!self.filesName.contains(newFileName),
|
||||
utilityFileSystem.moveFile(atPath: (NSTemporaryDirectory() + fileName), toPath: (NSTemporaryDirectory() + newFileName)) else {
|
||||
|
@ -143,4 +119,16 @@ extension NCShareExtension: NCShareCellDelegate {
|
|||
|
||||
present(alert, animated: true)
|
||||
}
|
||||
|
||||
func removeFile(named fileName: String) {
|
||||
guard let index = self.filesName.firstIndex(of: fileName) else {
|
||||
return showAlert(title: "_file_not_found_", description: fileName)
|
||||
}
|
||||
self.filesName.remove(at: index)
|
||||
if self.filesName.isEmpty {
|
||||
cancel(with: NCShareExtensionError.noFiles)
|
||||
} else {
|
||||
self.setCommandView()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -25,15 +25,12 @@
|
|||
|
||||
import UIKit
|
||||
import NextcloudKit
|
||||
import JGProgressHUD
|
||||
import TOPasscodeViewController
|
||||
|
||||
enum NCShareExtensionError: Error {
|
||||
case cancel, fileUpload, noAccount, noFiles
|
||||
}
|
||||
|
||||
class NCShareExtension: UIViewController {
|
||||
|
||||
@IBOutlet weak var collectionView: UICollectionView!
|
||||
@IBOutlet weak var tableView: UITableView!
|
||||
@IBOutlet weak var cancelButton: UIBarButtonItem!
|
||||
|
@ -57,22 +54,33 @@ class NCShareExtension: UIViewController {
|
|||
let keyLayout = NCGlobal.shared.layoutViewShareExtension
|
||||
var metadataFolder: tableMetadata?
|
||||
var dataSourceTask: URLSessionTask?
|
||||
var dataSource = NCDataSource()
|
||||
var layoutForView: NCDBLayoutForView?
|
||||
var dataSource = NCCollectionViewDataSource()
|
||||
let heightRowTableView: CGFloat = 50
|
||||
let heightCommandView: CGFloat = 170
|
||||
var autoUploadFileName = ""
|
||||
var autoUploadDirectory = ""
|
||||
let refreshControl = UIRefreshControl()
|
||||
var activeAccount: tableAccount!
|
||||
var progress: CGFloat = 0
|
||||
var counterUploaded: Int = 0
|
||||
var uploadErrors: [tableMetadata] = []
|
||||
var uploadMetadata: [tableMetadata] = []
|
||||
var uploadStarted = false
|
||||
let hud = JGProgressHUD()
|
||||
let hud = NCHud()
|
||||
let utilityFileSystem = NCUtilityFileSystem()
|
||||
let utility = NCUtility()
|
||||
let database = NCManageDatabase.shared
|
||||
var account: String = ""
|
||||
var session: NCSession.Session {
|
||||
if !account.isEmpty,
|
||||
let tableAccount = self.database.getTableAccount(account: account) {
|
||||
return NCSession.Session(account: tableAccount.account, urlBase: tableAccount.urlBase, user: tableAccount.user, userId: tableAccount.userId)
|
||||
} else if let activeTableAccount = self.database.getActiveTableAccount() {
|
||||
self.account = activeTableAccount.account
|
||||
return NCSession.Session(account: activeTableAccount.account, urlBase: activeTableAccount.urlBase, user: activeTableAccount.user, userId: activeTableAccount.userId)
|
||||
} else {
|
||||
return NCSession.Session(account: "", urlBase: "", user: "", userId: "")
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - View Life Cycle
|
||||
|
||||
|
@ -86,7 +94,7 @@ class NCShareExtension: UIViewController {
|
|||
collectionView.collectionViewLayout = NCListLayout()
|
||||
|
||||
collectionView.refreshControl = refreshControl
|
||||
refreshControl.tintColor = NCBrandColor.shared.brandText
|
||||
refreshControl.tintColor = NCBrandColor.shared.iconImageColor
|
||||
refreshControl.backgroundColor = .systemBackground
|
||||
refreshControl.addTarget(self, action: #selector(reloadDatasource), for: .valueChanged)
|
||||
|
||||
|
@ -125,33 +133,20 @@ class NCShareExtension: UIViewController {
|
|||
NextcloudKit.shared.nkCommonInstance.writeLog("[INFO] Start Share session with level \(levelLog) " + versionNextcloudiOS)
|
||||
}
|
||||
|
||||
// Colors
|
||||
if let activeAccount = NCManageDatabase.shared.getActiveAccount() {
|
||||
NCBrandColor.shared.settingThemingColor(account: activeAccount.account)
|
||||
}
|
||||
NCBrandColor.shared.createUserColors()
|
||||
NCImageCache.shared.createImagesCache()
|
||||
NCImageCache.shared.createImagesBrandCache()
|
||||
|
||||
hud.indicatorView = JGProgressHUDRingIndicatorView()
|
||||
if let indicatorView = hud.indicatorView as? JGProgressHUDRingIndicatorView {
|
||||
indicatorView.ringWidth = 1.5
|
||||
indicatorView.ringColor = NCBrandColor.shared.brandElement
|
||||
}
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(didCreateFolder(_:)), name: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterCreateFolder), object: nil)
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
guard serverUrl.isEmpty else { return }
|
||||
guard let activeAccount = NCManageDatabase.shared.getActiveAccount(),
|
||||
guard !session.account.isEmpty,
|
||||
!NCPasscode.shared.isPasscodeReset else {
|
||||
return showAlert(description: "_no_active_account_") {
|
||||
self.cancel(with: .noAccount)
|
||||
}
|
||||
}
|
||||
accountRequestChangeAccount(account: activeAccount.account)
|
||||
accountRequestChangeAccount(account: account, controller: nil)
|
||||
guard let inputItems = extensionContext?.inputItems as? [NSExtensionItem] else {
|
||||
cancel(with: .noFiles)
|
||||
return
|
||||
|
@ -197,7 +192,6 @@ class NCShareExtension: UIViewController {
|
|||
}
|
||||
|
||||
func setNavigationBar(navigationTitle: String) {
|
||||
|
||||
navigationItem.title = navigationTitle
|
||||
cancelButton.title = NSLocalizedString("_cancel_", comment: "")
|
||||
|
||||
|
@ -212,28 +206,26 @@ class NCShareExtension: UIViewController {
|
|||
if !self.uploadStarted {
|
||||
while self.serverUrl.last != "/" { self.serverUrl.removeLast() }
|
||||
self.serverUrl.removeLast()
|
||||
|
||||
self.reloadDatasource(withLoadFolder: true)
|
||||
|
||||
var navigationTitle = (self.serverUrl as NSString).lastPathComponent
|
||||
if self.utilityFileSystem.getHomeServer(urlBase: self.activeAccount.urlBase, userId: self.activeAccount.userId) == self.serverUrl {
|
||||
if self.utilityFileSystem.getHomeServer(session: self.session) == self.serverUrl {
|
||||
navigationTitle = NCBrandOptions.shared.brand
|
||||
}
|
||||
self.setNavigationBar(navigationTitle: navigationTitle)
|
||||
}
|
||||
}
|
||||
|
||||
let image = utility.loadUserImage(for: activeAccount.user, displayName: activeAccount.displayName, userBaseUrl: activeAccount)
|
||||
let tableAccount = self.database.getTableAccount(account: session.account)
|
||||
let image = utility.loadUserImage(for: session.user, displayName: tableAccount?.displayName, urlBase: session.urlBase)
|
||||
let profileButton = UIButton(type: .custom)
|
||||
profileButton.setImage(image, for: .normal)
|
||||
|
||||
if serverUrl == utilityFileSystem.getHomeServer(urlBase: activeAccount.urlBase, userId: activeAccount.userId) {
|
||||
|
||||
if serverUrl == utilityFileSystem.getHomeServer(session: self.session) {
|
||||
var title = " "
|
||||
if let userAlias = activeAccount?.alias, !userAlias.isEmpty {
|
||||
if let userAlias = tableAccount?.alias, !userAlias.isEmpty {
|
||||
title += userAlias
|
||||
} else {
|
||||
title += activeAccount?.displayName ?? ""
|
||||
title += tableAccount?.displayName ?? ""
|
||||
}
|
||||
|
||||
profileButton.setTitle(title, for: .normal)
|
||||
|
@ -248,7 +240,7 @@ class NCShareExtension: UIViewController {
|
|||
}
|
||||
}
|
||||
var navItems = [UIBarButtonItem(customView: profileButton)]
|
||||
if serverUrl != utilityFileSystem.getHomeServer(urlBase: activeAccount.urlBase, userId: activeAccount.userId) {
|
||||
if serverUrl != utilityFileSystem.getHomeServer(session: self.session) {
|
||||
let space = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil)
|
||||
space.width = 20
|
||||
navItems.append(contentsOf: [UIBarButtonItem(customView: backButton), space])
|
||||
|
@ -278,7 +270,7 @@ class NCShareExtension: UIViewController {
|
|||
}
|
||||
|
||||
@objc func actionCreateFolder() {
|
||||
let alertController = UIAlertController.createFolder(serverUrl: serverUrl, userBaseUrl: activeAccount) { error in
|
||||
let alertController = UIAlertController.createFolder(serverUrl: serverUrl, account: session.account) { error in
|
||||
guard error != .success else { return }
|
||||
self.showAlert(title: "_error_createsubfolders_upload_", description: error.errorDescription)
|
||||
}
|
||||
|
@ -298,7 +290,7 @@ extension NCShareExtension {
|
|||
|
||||
var conflicts: [tableMetadata] = []
|
||||
for fileName in filesName {
|
||||
if let fileNameError = FileNameValidator.shared.checkFileName(fileName) {
|
||||
if let fileNameError = FileNameValidator.shared.checkFileName(fileName, account: session.account) {
|
||||
present(UIAlertController.warning(message: "\(fileNameError.errorDescription) \(NSLocalizedString("_please_rename_file_", comment: ""))"), animated: true)
|
||||
|
||||
continue
|
||||
|
@ -307,27 +299,32 @@ extension NCShareExtension {
|
|||
let ocId = NSUUID().uuidString
|
||||
let toPath = utilityFileSystem.getDirectoryProviderStorageOcId(ocId, fileNameView: fileName)
|
||||
guard utilityFileSystem.copyFile(atPath: (NSTemporaryDirectory() + fileName), toPath: toPath) else { continue }
|
||||
let metadata = NCManageDatabase.shared.createMetadata(
|
||||
account: activeAccount.account, user: activeAccount.user, userId: activeAccount.userId,
|
||||
fileName: fileName, fileNameView: fileName,
|
||||
ocId: ocId,
|
||||
serverUrl: serverUrl, urlBase: activeAccount.urlBase, url: "",
|
||||
contentType: "")
|
||||
metadata.session = NextcloudKit.shared.nkCommonInstance.sessionIdentifierUpload
|
||||
metadata.sessionSelector = NCGlobal.shared.selectorUploadFileShareExtension
|
||||
metadata.size = utilityFileSystem.getFileSize(filePath: toPath)
|
||||
metadata.status = NCGlobal.shared.metadataStatusWaitUpload
|
||||
metadata.sessionDate = Date()
|
||||
if NCManageDatabase.shared.getMetadataConflict(account: activeAccount.account, serverUrl: serverUrl, fileNameView: fileName) != nil {
|
||||
conflicts.append(metadata)
|
||||
let metadataForUpload = self.database.createMetadata(fileName: fileName,
|
||||
fileNameView: fileName,
|
||||
ocId: ocId,
|
||||
serverUrl: serverUrl,
|
||||
url: "",
|
||||
contentType: "",
|
||||
session: session,
|
||||
sceneIdentifier: nil)
|
||||
|
||||
metadataForUpload.session = NCNetworking.shared.sessionUpload
|
||||
metadataForUpload.sessionSelector = NCGlobal.shared.selectorUploadFileShareExtension
|
||||
metadataForUpload.size = utilityFileSystem.getFileSize(filePath: toPath)
|
||||
metadataForUpload.status = NCGlobal.shared.metadataStatusWaitUpload
|
||||
metadataForUpload.sessionDate = Date()
|
||||
if self.database.getMetadataConflict(account: session.account, serverUrl: serverUrl, fileNameView: fileName) != nil {
|
||||
conflicts.append(metadataForUpload)
|
||||
} else {
|
||||
uploadMetadata.append(metadata)
|
||||
uploadMetadata.append(metadataForUpload)
|
||||
}
|
||||
}
|
||||
|
||||
if !conflicts.isEmpty {
|
||||
guard let conflict = UIStoryboard(name: "NCCreateFormUploadConflict", bundle: nil).instantiateInitialViewController() as? NCCreateFormUploadConflict
|
||||
else { return }
|
||||
|
||||
conflict.account = session.account
|
||||
conflict.serverUrl = self.serverUrl
|
||||
conflict.metadatasUploadInConflict = conflicts
|
||||
conflict.delegate = self
|
||||
|
@ -341,8 +338,8 @@ extension NCShareExtension {
|
|||
guard uploadStarted else { return }
|
||||
guard uploadMetadata.count > counterUploaded else { return DispatchQueue.main.async { self.finishedUploading() } }
|
||||
let metadata = uploadMetadata[counterUploaded]
|
||||
let results = NextcloudKit.shared.nkCommonInstance.getInternalType(fileName: metadata.fileNameView, mimeType: metadata.contentType, directory: false, account: session.account)
|
||||
|
||||
let results = NextcloudKit.shared.nkCommonInstance.getInternalType(fileName: metadata.fileNameView, mimeType: metadata.contentType, directory: false)
|
||||
metadata.contentType = results.mimeType
|
||||
metadata.iconName = results.iconName
|
||||
metadata.classFile = results.classFile
|
||||
|
@ -359,22 +356,16 @@ extension NCShareExtension {
|
|||
// E2EE
|
||||
metadata.e2eEncrypted = metadata.isDirectoryE2EE
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.hud.show(in: self.view)
|
||||
self.hud.textLabel.text = NSLocalizedString("_upload_file_", comment: "") + " \(self.counterUploaded + 1) " + NSLocalizedString("_of_", comment: "") + " \(self.filesName.count)"
|
||||
}
|
||||
hud.initHudRing(view: self.view,
|
||||
text: NSLocalizedString("_upload_file_", comment: "") + " \(self.counterUploaded + 1) " + NSLocalizedString("_of_", comment: "") + " \(self.filesName.count)")
|
||||
|
||||
NCNetworking.shared.upload(metadata: metadata, uploadE2EEDelegate: self, hudView: self.view, hud: JGProgressHUD()) {
|
||||
DispatchQueue.main.async {
|
||||
self.hud.progress = 0
|
||||
}
|
||||
NCNetworking.shared.upload(metadata: metadata, uploadE2EEDelegate: self, controller: self) {
|
||||
self.hud.progress(0)
|
||||
} progressHandler: { _, _, fractionCompleted in
|
||||
DispatchQueue.main.async {
|
||||
self.hud.progress = Float(fractionCompleted)
|
||||
}
|
||||
self.hud.progress(fractionCompleted)
|
||||
} completion: { _, error in
|
||||
if error != .success {
|
||||
NCManageDatabase.shared.deleteMetadata(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))
|
||||
self.database.deleteMetadataOcId(metadata.ocId)
|
||||
self.utilityFileSystem.removeFile(atPath: self.utilityFileSystem.getDirectoryProviderStorageOcId(metadata.ocId))
|
||||
self.uploadErrors.append(metadata)
|
||||
}
|
||||
|
@ -391,9 +382,7 @@ extension NCShareExtension {
|
|||
self.extensionContext?.cancelRequest(withError: NCShareExtensionError.fileUpload)
|
||||
}
|
||||
} else {
|
||||
hud.indicatorView = JGProgressHUDSuccessIndicatorView()
|
||||
hud.indicatorView?.tintColor = NCBrandColor.shared.brandElement
|
||||
hud.textLabel.text = NSLocalizedString("_success_", comment: "")
|
||||
hud.success()
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
self.extensionContext?.completeRequest(returningItems: self.extensionContext?.inputItems, completionHandler: nil)
|
||||
}
|
||||
|
@ -403,11 +392,11 @@ extension NCShareExtension {
|
|||
|
||||
extension NCShareExtension: uploadE2EEDelegate {
|
||||
func start() {
|
||||
self.hud.progress = 0
|
||||
self.hud.progress(0)
|
||||
}
|
||||
|
||||
func uploadE2EEProgress(_ totalBytesExpected: Int64, _ totalBytes: Int64, _ fractionCompleted: Double) {
|
||||
self.hud.progress = Float(fractionCompleted)
|
||||
self.hud.progress(fractionCompleted)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,3 +4,4 @@
|
|||
|
||||
#import "NCEndToEndEncryption.h"
|
||||
#import "UIImage+animatedGIF.h"
|
||||
#import "TOPasscodeViewController.h"
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
import XCTest
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Alamofire
|
||||
import NextcloudKit
|
||||
@testable import Nextcloud
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
public class TestConstants {
|
||||
static let timeoutLong: Double = 600
|
||||
|
|
|
@ -24,10 +24,9 @@ import NextcloudKit
|
|||
@testable import Nextcloud
|
||||
|
||||
final class FilesIntegrationTests: BaseIntegrationXCTestCase {
|
||||
private let appDelegate = (UIApplication.shared.delegate as? AppDelegate)!
|
||||
|
||||
override func setUp() {
|
||||
appDelegate.deleteAllAccounts()
|
||||
NCAccount().deleteAllAccounts()
|
||||
}
|
||||
|
||||
func test_createReadDeleteFolder_withProperParams_shouldCreateReadDeleteFolder() throws {
|
||||
|
@ -36,11 +35,14 @@ final class FilesIntegrationTests: BaseIntegrationXCTestCase {
|
|||
let folderName = "TestFolder\(randomInt)"
|
||||
let serverUrl = "\(TestConstants.server)/remote.php/dav/files/\(TestConstants.username)"
|
||||
let serverUrlFileName = "\(serverUrl)/\(folderName)"
|
||||
let domain = NCDomain.Domain(account: TestConstants.account, urlBase: TestConstants.server, user: TestConstants.username, userId: TestConstants.username, sceneIdentifier: "")
|
||||
|
||||
NextcloudKit.shared.setup(account: TestConstants.account, user: TestConstants.username, userId: TestConstants.username, password: appToken, urlBase: TestConstants.server, groupIdentifier: NCBrandOptions.shared.capabilitiesGroup)
|
||||
NextcloudKit.shared.setup(delegate: NCNetworking.shared)
|
||||
NextcloudKit.shared.appendAccount(TestConstants.account, urlBase: TestConstants.server, user: TestConstants.username, userId: TestConstants.username, password: appToken, userAgent: userAgent, nextcloudVersion: 0, groupIdentifier: NCBrandOptions.shared.capabilitiesGroup)
|
||||
|
||||
// Test creating folder
|
||||
NCNetworking.shared.createFolder(fileName: folderName, serverUrl: serverUrl, account: TestConstants.account, urlBase: TestConstants.server, userId: TestConstants.username, withPush: true, sceneIdentifier: nil) { error in
|
||||
NCNetworking.shared.createFolder(fileName: folderName, serverUrl: serverUrl, overwrite: true, withPush: true, sceneIdentifier: nil, domain: domain) { error in
|
||||
|
||||
XCTAssertEqual(NKError.success.errorCode, error.errorCode)
|
||||
XCTAssertEqual(NKError.success.errorDescription, error.errorDescription)
|
||||
|
||||
|
@ -61,7 +63,7 @@ final class FilesIntegrationTests: BaseIntegrationXCTestCase {
|
|||
|
||||
Task {
|
||||
// Test deleting folder
|
||||
await _ = NCNetworking.shared.deleteMetadata(metadataFolder!, onlyLocalCache: false)
|
||||
await _ = NCNetworking.shared.deleteMetadata(metadataFolder!)
|
||||
|
||||
XCTAssertEqual(NKError.success.errorCode, error.errorCode)
|
||||
XCTAssertEqual(NKError.success.errorDescription, error.errorDescription)
|
||||
|
|
|
@ -39,6 +39,7 @@ struct DashboardDataEntry: TimelineEntry {
|
|||
let title: String
|
||||
let footerImage: String
|
||||
let footerText: String
|
||||
let account: String
|
||||
}
|
||||
|
||||
struct DashboardData: Identifiable, Hashable {
|
||||
|
@ -101,45 +102,44 @@ func getDashboardDataEntry(configuration: DashboardIntent?, isPreview: Bool, dis
|
|||
let utility = NCUtility()
|
||||
let dashboardItems = getDashboardItems(displaySize: displaySize, withButton: false)
|
||||
let datasPlaceholder = Array(dashboardDatasTest[0...dashboardItems - 1])
|
||||
var account: tableAccount?
|
||||
var activeTableAccount: tableAccount?
|
||||
|
||||
if isPreview {
|
||||
return completion(DashboardDataEntry(date: Date(), datas: datasPlaceholder, dashboard: nil, buttons: nil, isPlaceholder: true, isEmpty: false, titleImage: UIImage(named: "widget")!, title: "Dashboard", footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " dashboard"))
|
||||
return completion(DashboardDataEntry(date: Date(), datas: datasPlaceholder, dashboard: nil, buttons: nil, isPlaceholder: true, isEmpty: false, titleImage: UIImage(named: "widget")!, title: "Dashboard", footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " dashboard", account: ""))
|
||||
}
|
||||
|
||||
let accountIdentifier: String = configuration?.accounts?.identifier ?? "active"
|
||||
if accountIdentifier == "active" {
|
||||
account = NCManageDatabase.shared.getActiveAccount()
|
||||
activeTableAccount = NCManageDatabase.shared.getActiveTableAccount()
|
||||
} else {
|
||||
account = NCManageDatabase.shared.getAccount(predicate: NSPredicate(format: "account == %@", accountIdentifier))
|
||||
activeTableAccount = NCManageDatabase.shared.getTableAccount(predicate: NSPredicate(format: "account == %@", accountIdentifier))
|
||||
}
|
||||
|
||||
guard let account = account else {
|
||||
return completion(DashboardDataEntry(date: Date(), datas: datasPlaceholder, dashboard: nil, buttons: nil, isPlaceholder: true, isEmpty: false, titleImage: UIImage(named: "widget")!, title: "Dashboard", footerImage: "xmark.icloud", footerText: NSLocalizedString("_no_active_account_", comment: "")))
|
||||
guard let activeTableAccount,
|
||||
let capabilities = NCManageDatabase.shared.setCapabilities(account: activeTableAccount.account) else {
|
||||
return completion(DashboardDataEntry(date: Date(), datas: datasPlaceholder, dashboard: nil, buttons: nil, isPlaceholder: true, isEmpty: false, titleImage: UIImage(named: "widget")!, title: "Dashboard", footerImage: "xmark.icloud", footerText: NSLocalizedString("_no_active_account_", comment: ""), account: ""))
|
||||
}
|
||||
|
||||
// Default widget
|
||||
let result = NCManageDatabase.shared.getDashboardWidgetApplications(account: account.account).first
|
||||
let result = NCManageDatabase.shared.getDashboardWidgetApplications(account: activeTableAccount.account).first
|
||||
let id: String = configuration?.applications?.identifier ?? (result?.id ?? "recommendations")
|
||||
|
||||
// Capabilities
|
||||
NCManageDatabase.shared.setCapabilities(account: account.account)
|
||||
|
||||
guard NCGlobal.shared.capabilityServerVersionMajor >= NCGlobal.shared.nextcloudVersion25 else {
|
||||
return completion(DashboardDataEntry(date: Date(), datas: datasPlaceholder, dashboard: nil, buttons: nil, isPlaceholder: true, isEmpty: false, titleImage: UIImage(named: "widget")!, title: "Dashboard", footerImage: "xmark.icloud", footerText: NSLocalizedString("_widget_available_nc25_", comment: "")))
|
||||
guard capabilities.capabilityServerVersionMajor >= NCGlobal.shared.nextcloudVersion25 else {
|
||||
return completion(DashboardDataEntry(date: Date(), datas: datasPlaceholder, dashboard: nil, buttons: nil, isPlaceholder: true, isEmpty: false, titleImage: UIImage(named: "widget")!, title: "Dashboard", footerImage: "xmark.icloud", footerText: NSLocalizedString("_widget_available_nc25_", comment: ""), account: activeTableAccount.account))
|
||||
}
|
||||
|
||||
// NETWORKING
|
||||
let password = NCKeychain().getPassword(account: account.account)
|
||||
NextcloudKit.shared.setup(
|
||||
account: account.account,
|
||||
user: account.user,
|
||||
userId: account.userId,
|
||||
password: password,
|
||||
urlBase: account.urlBase,
|
||||
userAgent: userAgent,
|
||||
nextcloudVersion: 0,
|
||||
delegate: NCNetworking.shared)
|
||||
let password = NCKeychain().getPassword(account: activeTableAccount.account)
|
||||
|
||||
NextcloudKit.shared.setup(delegate: NCNetworking.shared)
|
||||
NextcloudKit.shared.appendSession(account: activeTableAccount.account,
|
||||
urlBase: activeTableAccount.urlBase,
|
||||
user: activeTableAccount.user,
|
||||
userId: activeTableAccount.userId,
|
||||
password: password,
|
||||
userAgent: userAgent,
|
||||
nextcloudVersion: capabilities.capabilityServerVersionMajor,
|
||||
groupIdentifier: NCBrandOptions.shared.capabilitiesGroup)
|
||||
|
||||
// LOG
|
||||
let levelLog = NCKeychain().logLevel
|
||||
|
@ -154,7 +154,7 @@ func getDashboardDataEntry(configuration: DashboardIntent?, isPreview: Bool, dis
|
|||
NextcloudKit.shared.nkCommonInstance.writeLog("[INFO] Start \(NCBrandOptions.shared.brand) dashboard widget session with level \(levelLog) " + versionNextcloudiOS)
|
||||
}
|
||||
|
||||
let (tableDashboard, tableButton) = NCManageDatabase.shared.getDashboardWidget(account: account.account, id: id)
|
||||
let (tableDashboard, tableButton) = NCManageDatabase.shared.getDashboardWidget(account: activeTableAccount.account, id: id)
|
||||
let existsButton = (tableButton?.isEmpty ?? true) ? false : true
|
||||
let title = tableDashboard?.title ?? id
|
||||
|
||||
|
@ -168,7 +168,7 @@ func getDashboardDataEntry(configuration: DashboardIntent?, isPreview: Bool, dis
|
|||
let titleImage = imagetmp
|
||||
|
||||
let options = NKRequestOptions(timeout: 90, queue: NextcloudKit.shared.nkCommonInstance.backgroundQueue)
|
||||
NextcloudKit.shared.getDashboardWidgetsApplication(id, account: account.account, options: options) { _, results, data, error in
|
||||
NextcloudKit.shared.getDashboardWidgetsApplication(id, account: activeTableAccount.account, options: options) { account, results, responseData, error in
|
||||
Task {
|
||||
var datas = [DashboardData]()
|
||||
var numberItems = 0
|
||||
|
@ -225,9 +225,10 @@ func getDashboardDataEntry(configuration: DashboardIntent?, isPreview: Bool, dis
|
|||
if FileManager().fileExists(atPath: fileNamePath), let image = UIImage(contentsOfFile: fileNamePath) {
|
||||
icon = image
|
||||
} else {
|
||||
let (_, data, error) = await NCNetworking.shared.downloadPreview(url: url, account: account.account)
|
||||
let (_, data, error) = await NCNetworking.shared.downloadPreview(url: url, account: activeTableAccount.account)
|
||||
if error == .success,
|
||||
let image = convertDataToImage(data: data, size: CGSize(width: 256, height: 256), fileNameToWrite: fileName) {
|
||||
let data = responseData?.data,
|
||||
let image = convertDataToImage(data: data, size: NCGlobal.shared.size256, fileNameToWrite: fileName) {
|
||||
icon = image
|
||||
}
|
||||
}
|
||||
|
@ -248,13 +249,13 @@ func getDashboardDataEntry(configuration: DashboardIntent?, isPreview: Bool, dis
|
|||
buttons = tableButton.filter(({ $0.type != "more" }))
|
||||
}
|
||||
|
||||
let alias = (account.alias.isEmpty) ? "" : (" (" + account.alias + ")")
|
||||
let footerText = "Dashboard " + NSLocalizedString("_of_", comment: "") + " " + account.displayName + alias
|
||||
let alias = (activeTableAccount.alias.isEmpty) ? "" : (" (" + activeTableAccount.alias + ")")
|
||||
let footerText = "Dashboard " + NSLocalizedString("_of_", comment: "") + " " + activeTableAccount.displayName + alias
|
||||
|
||||
if error != .success {
|
||||
completion(DashboardDataEntry(date: Date(), datas: datasPlaceholder, dashboard: tableDashboard, buttons: buttons, isPlaceholder: true, isEmpty: false, titleImage: titleImage, title: title, footerImage: "xmark.icloud", footerText: error.errorDescription))
|
||||
completion(DashboardDataEntry(date: Date(), datas: datasPlaceholder, dashboard: tableDashboard, buttons: buttons, isPlaceholder: true, isEmpty: false, titleImage: titleImage, title: title, footerImage: "xmark.icloud", footerText: error.errorDescription, account: account))
|
||||
} else {
|
||||
completion(DashboardDataEntry(date: Date(), datas: datas, dashboard: tableDashboard, buttons: buttons, isPlaceholder: false, isEmpty: datas.isEmpty, titleImage: titleImage, title: title, footerImage: "checkmark.icloud", footerText: footerText))
|
||||
completion(DashboardDataEntry(date: Date(), datas: datas, dashboard: tableDashboard, buttons: buttons, isPlaceholder: false, isEmpty: datas.isEmpty, titleImage: titleImage, title: title, footerImage: "checkmark.icloud", footerText: footerText, account: account))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ struct DashboardWidgetProvider: IntentTimelineProvider {
|
|||
let datasPlaceholder = Array(dashboardDatasTest[0...dashboardItems])
|
||||
let title = "Dashboard"
|
||||
let titleImage = UIImage(named: "widget")!
|
||||
return Entry(date: Date(), datas: datasPlaceholder, dashboard: nil, buttons: nil, isPlaceholder: true, isEmpty: false, titleImage: titleImage, title: title, footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " widget")
|
||||
return Entry(date: Date(), datas: datasPlaceholder, dashboard: nil, buttons: nil, isPlaceholder: true, isEmpty: false, titleImage: titleImage, title: title, footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " widget", account: "")
|
||||
}
|
||||
|
||||
func getSnapshot(for configuration: DashboardIntent, in context: Context, completion: @escaping (DashboardDataEntry) -> Void) {
|
||||
|
|
|
@ -25,13 +25,9 @@ import SwiftUI
|
|||
import WidgetKit
|
||||
|
||||
struct DashboardWidgetView: View {
|
||||
|
||||
var entry: DashboardDataEntry
|
||||
|
||||
var body: some View {
|
||||
|
||||
GeometryReader { geo in
|
||||
|
||||
if entry.isEmpty {
|
||||
VStack(alignment: .center) {
|
||||
Image(systemName: "checkmark")
|
||||
|
@ -156,9 +152,8 @@ struct DashboardWidgetView: View {
|
|||
if let buttons = entry.buttons, !buttons.isEmpty, !entry.isPlaceholder {
|
||||
|
||||
HStack(spacing: 10) {
|
||||
|
||||
let brandColor = Color(NCBrandColor.shared.brandElement)
|
||||
let brandTextColor = Color(NCBrandColor.shared.brandText)
|
||||
let brandColor = Color(NCBrandColor.shared.getElement(account: entry.account))
|
||||
let brandTextColor = Color(NCBrandColor.shared.getText(account: entry.account))
|
||||
|
||||
ForEach(buttons, id: \.index) { element in
|
||||
Link(destination: URL(string: element.link)!, label: {
|
||||
|
@ -183,12 +178,12 @@ struct DashboardWidgetView: View {
|
|||
.scaledToFit()
|
||||
.frame(width: 15, height: 15)
|
||||
.font(Font.system(.body).weight(.light))
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandElement))
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account)))
|
||||
|
||||
Text(entry.footerText)
|
||||
.font(.caption2)
|
||||
.lineLimit(1)
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandElement))
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account)))
|
||||
}
|
||||
.padding(.horizontal, 15.0)
|
||||
.frame(maxWidth: geo.size.width, maxHeight: geo.size.height - 2, alignment: .bottomTrailing)
|
||||
|
@ -203,7 +198,7 @@ struct DashboardWidget_Previews: PreviewProvider {
|
|||
let datas = Array(dashboardDatasTest[0...4])
|
||||
let title = "Dashboard"
|
||||
let titleImage = UIImage(named: "widget")!
|
||||
let entry = DashboardDataEntry(date: Date(), datas: datas, dashboard: nil, buttons: nil, isPlaceholder: false, isEmpty: true, titleImage: titleImage, title: title, footerImage: "checkmark.icloud", footerText: "Nextcloud widget")
|
||||
let entry = DashboardDataEntry(date: Date(), datas: datas, dashboard: nil, buttons: nil, isPlaceholder: false, isEmpty: true, titleImage: titleImage, title: title, footerImage: "checkmark.icloud", footerText: "Nextcloud widget", account: "")
|
||||
DashboardWidgetView(entry: entry).previewContext(WidgetPreviewContext(family: .systemLarge))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ struct FilesDataEntry: TimelineEntry {
|
|||
let isEmpty: Bool
|
||||
let userId: String
|
||||
let url: String
|
||||
let account: String
|
||||
let tile: String
|
||||
let footerImage: String
|
||||
let footerText: String
|
||||
|
@ -60,7 +61,7 @@ let filesDatasTest: [FilesData] = [
|
|||
.init(id: "9", image: UIImage(named: "widget")!, title: "title4", subTitle: "subTitle-description4", url: URL(string: "https://nextcloud.com/")!)
|
||||
]
|
||||
|
||||
func getTitleFilesWidget(account: tableAccount?) -> String {
|
||||
func getTitleFilesWidget(tableAccount: tableAccount?) -> String {
|
||||
let hour = Calendar.current.component(.hour, from: Date())
|
||||
var good = ""
|
||||
|
||||
|
@ -72,8 +73,8 @@ func getTitleFilesWidget(account: tableAccount?) -> String {
|
|||
default: good = NSLocalizedString("_good_night_", value: "Good night", comment: "")
|
||||
}
|
||||
|
||||
if let account = account {
|
||||
return good + ", " + account.displayName
|
||||
if let tableAccount {
|
||||
return good + ", " + tableAccount.displayName
|
||||
} else {
|
||||
return good
|
||||
}
|
||||
|
@ -89,34 +90,35 @@ func getFilesDataEntry(configuration: AccountIntent?, isPreview: Bool, displaySi
|
|||
let utility = NCUtility()
|
||||
let filesItems = getFilesItems(displaySize: displaySize)
|
||||
let datasPlaceholder = Array(filesDatasTest[0...filesItems - 1])
|
||||
var account: tableAccount?
|
||||
var activeTableAccount: tableAccount?
|
||||
|
||||
if isPreview {
|
||||
return completion(FilesDataEntry(date: Date(), datas: datasPlaceholder, isPlaceholder: true, isEmpty: false, userId: "", url: "", tile: getTitleFilesWidget(account: nil), footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " files"))
|
||||
return completion(FilesDataEntry(date: Date(), datas: datasPlaceholder, isPlaceholder: true, isEmpty: false, userId: "", url: "", account: "", tile: getTitleFilesWidget(tableAccount: nil), footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " files"))
|
||||
}
|
||||
|
||||
let accountIdentifier: String = configuration?.accounts?.identifier ?? "active"
|
||||
if accountIdentifier == "active" {
|
||||
account = NCManageDatabase.shared.getActiveAccount()
|
||||
activeTableAccount = NCManageDatabase.shared.getActiveTableAccount()
|
||||
} else {
|
||||
account = NCManageDatabase.shared.getAccount(predicate: NSPredicate(format: "account == %@", accountIdentifier))
|
||||
activeTableAccount = NCManageDatabase.shared.getTableAccount(predicate: NSPredicate(format: "account == %@", accountIdentifier))
|
||||
}
|
||||
|
||||
guard let account = account else {
|
||||
return completion(FilesDataEntry(date: Date(), datas: datasPlaceholder, isPlaceholder: true, isEmpty: false, userId: "", url: "", tile: getTitleFilesWidget(account: nil), footerImage: "xmark.icloud", footerText: NSLocalizedString("_no_active_account_", value: "No account found", comment: "")))
|
||||
guard let activeTableAccount else {
|
||||
return completion(FilesDataEntry(date: Date(), datas: datasPlaceholder, isPlaceholder: true, isEmpty: false, userId: "", url: "", account: "", tile: getTitleFilesWidget(tableAccount: nil), footerImage: "xmark.icloud", footerText: NSLocalizedString("_no_active_account_", value: "No account found", comment: "")))
|
||||
}
|
||||
|
||||
// NETWORKING
|
||||
let password = NCKeychain().getPassword(account: account.account)
|
||||
NextcloudKit.shared.setup(
|
||||
account: account.account,
|
||||
user: account.user,
|
||||
userId: account.userId,
|
||||
password: password,
|
||||
urlBase: account.urlBase,
|
||||
userAgent: userAgent,
|
||||
nextcloudVersion: 0,
|
||||
delegate: NCNetworking.shared)
|
||||
let password = NCKeychain().getPassword(account: activeTableAccount.account)
|
||||
|
||||
NextcloudKit.shared.setup(delegate: NCNetworking.shared)
|
||||
NextcloudKit.shared.appendSession(account: activeTableAccount.account,
|
||||
urlBase: activeTableAccount.urlBase,
|
||||
user: activeTableAccount.user,
|
||||
userId: activeTableAccount.userId,
|
||||
password: password,
|
||||
userAgent: userAgent,
|
||||
nextcloudVersion: NCCapabilities.shared.getCapabilities(account: activeTableAccount.account).capabilityServerVersionMajor,
|
||||
groupIdentifier: NCBrandOptions.shared.capabilitiesGroup)
|
||||
|
||||
let requestBodyRecent =
|
||||
"""
|
||||
|
@ -173,7 +175,7 @@ func getFilesDataEntry(configuration: AccountIntent?, isPreview: Bool, displaySi
|
|||
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
|
||||
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
|
||||
let lessDateString = dateFormatter.string(from: Date())
|
||||
let requestBody = String(format: requestBodyRecent, "/files/" + account.userId, lessDateString)
|
||||
let requestBody = String(format: requestBodyRecent, "/files/" + activeTableAccount.userId, lessDateString)
|
||||
|
||||
// LOG
|
||||
let levelLog = NCKeychain().logLevel
|
||||
|
@ -190,11 +192,11 @@ func getFilesDataEntry(configuration: AccountIntent?, isPreview: Bool, displaySi
|
|||
}
|
||||
|
||||
let options = NKRequestOptions(timeout: 30, queue: NextcloudKit.shared.nkCommonInstance.backgroundQueue)
|
||||
NextcloudKit.shared.searchBodyRequest(serverUrl: account.urlBase, requestBody: requestBody, showHiddenFiles: NCKeychain().showHiddenFiles, account: account.account, options: options) { _, files, data, error in
|
||||
NextcloudKit.shared.searchBodyRequest(serverUrl: activeTableAccount.urlBase, requestBody: requestBody, showHiddenFiles: NCKeychain().showHiddenFiles, account: activeTableAccount.account, options: options) { _, files, data, error in
|
||||
Task {
|
||||
var datas: [FilesData] = []
|
||||
let title = getTitleFilesWidget(account: account)
|
||||
let files = files.sorted(by: { ($0.date as Date) > ($1.date as Date) })
|
||||
let title = getTitleFilesWidget(tableAccount: activeTableAccount)
|
||||
let files = files?.sorted(by: { ($0.date as Date) > ($1.date as Date) }) ?? []
|
||||
|
||||
for file in files {
|
||||
var useTypeIconFile = false
|
||||
|
@ -216,18 +218,18 @@ func getFilesDataEntry(configuration: AccountIntent?, isPreview: Bool, displaySi
|
|||
guard let url = URL(string: urlString) else { continue }
|
||||
|
||||
// IMAGE
|
||||
let fileNamePreviewLocalPath = utilityFileSystem.getDirectoryProviderStoragePreviewOcId(file.ocId, etag: file.etag)
|
||||
let fileNameIconLocalPath = utilityFileSystem.getDirectoryProviderStorageIconOcId(file.ocId, etag: file.etag)
|
||||
if FileManager.default.fileExists(atPath: fileNameIconLocalPath) {
|
||||
image = UIImage(contentsOfFile: fileNameIconLocalPath)
|
||||
}
|
||||
image = utility.getImage(ocId: file.ocId, etag: file.etag, ext: NCGlobal.shared.previewExt512)
|
||||
if image == nil, file.hasPreview {
|
||||
let sizePreview = NCUtility().getSizePreview(width: Int(file.width), height: Int(file.height))
|
||||
let (_, _, imageIcon, _, _, _) = await NCNetworking.shared.downloadPreview(fileId: file.fileId, fileNamePreviewLocalPath: fileNamePreviewLocalPath, fileNameIconLocalPath: fileNameIconLocalPath, widthPreview: Int(sizePreview.width), heightPreview: Int(sizePreview.height), sizeIcon: NCGlobal.shared.sizeIcon, account: account.account, options: options)
|
||||
image = imageIcon
|
||||
let result = await NCNetworking.shared.downloadPreview(fileId: file.fileId,
|
||||
account: activeTableAccount.account,
|
||||
options: options)
|
||||
if result.error == .success, let data = result.responseData?.data {
|
||||
utility.createImageFileFrom(data: data, ocId: file.ocId, etag: file.etag)
|
||||
image = utility.getImage(ocId: file.ocId, etag: file.etag, ext: NCGlobal.shared.previewExt256)
|
||||
}
|
||||
}
|
||||
if image == nil {
|
||||
image = utility.loadImage(named: file.iconName, useTypeIconFile: true)
|
||||
image = utility.loadImage(named: file.iconName, useTypeIconFile: true, account: file.account)
|
||||
useTypeIconFile = true
|
||||
}
|
||||
|
||||
|
@ -240,13 +242,13 @@ func getFilesDataEntry(configuration: AccountIntent?, isPreview: Bool, displaySi
|
|||
if datas.count == filesItems { break}
|
||||
}
|
||||
|
||||
let alias = (account.alias.isEmpty) ? "" : (" (" + account.alias + ")")
|
||||
let footerText = "Files " + NSLocalizedString("_of_", comment: "") + " " + account.displayName + alias
|
||||
let alias = (activeTableAccount.alias.isEmpty) ? "" : (" (" + activeTableAccount.alias + ")")
|
||||
let footerText = "Files " + NSLocalizedString("_of_", comment: "") + " " + activeTableAccount.displayName + alias
|
||||
|
||||
if error != .success {
|
||||
completion(FilesDataEntry(date: Date(), datas: datasPlaceholder, isPlaceholder: true, isEmpty: false, userId: account.userId, url: account.urlBase, tile: title, footerImage: "xmark.icloud", footerText: error.errorDescription))
|
||||
completion(FilesDataEntry(date: Date(), datas: datasPlaceholder, isPlaceholder: true, isEmpty: false, userId: activeTableAccount.userId, url: activeTableAccount.urlBase, account: activeTableAccount.account, tile: title, footerImage: "xmark.icloud", footerText: error.errorDescription))
|
||||
} else {
|
||||
completion(FilesDataEntry(date: Date(), datas: datas, isPlaceholder: false, isEmpty: datas.isEmpty, userId: account.userId, url: account.urlBase, tile: title, footerImage: "checkmark.icloud", footerText: footerText))
|
||||
completion(FilesDataEntry(date: Date(), datas: datas, isPlaceholder: false, isEmpty: datas.isEmpty, userId: activeTableAccount.userId, url: activeTableAccount.urlBase, account: activeTableAccount.account, tile: title, footerImage: "checkmark.icloud", footerText: footerText))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,8 +33,8 @@ struct FilesWidgetProvider: IntentTimelineProvider {
|
|||
func placeholder(in context: Context) -> Entry {
|
||||
let filesItems = getFilesItems(displaySize: context.displaySize)
|
||||
let datasPlaceholder = Array(filesDatasTest[0...filesItems - 1])
|
||||
let title = getTitleFilesWidget(account: nil)
|
||||
return Entry(date: Date(), datas: datasPlaceholder, isPlaceholder: true, isEmpty: false, userId: "", url: "", tile: title, footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " files")
|
||||
let title = getTitleFilesWidget(tableAccount: nil)
|
||||
return Entry(date: Date(), datas: datasPlaceholder, isPlaceholder: true, isEmpty: false, userId: "", url: "", account: "", tile: title, footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " files")
|
||||
}
|
||||
|
||||
func getSnapshot(for configuration: AccountIntent, in context: Context, completion: @escaping (Entry) -> Void) {
|
||||
|
|
|
@ -120,9 +120,9 @@ struct FilesWidgetView: View {
|
|||
Image("addImage")
|
||||
.resizable()
|
||||
.renderingMode(.template)
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandText))
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getText(account: entry.account)))
|
||||
.padding(11)
|
||||
.background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandElement))
|
||||
.background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account)))
|
||||
.clipShape(Circle())
|
||||
.scaledToFit()
|
||||
.frame(width: geo.size.width / 4, height: sizeButton)
|
||||
|
@ -132,9 +132,9 @@ struct FilesWidgetView: View {
|
|||
Image(systemName: "doc.text.viewfinder")
|
||||
.resizable()
|
||||
.renderingMode(.template)
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandText))
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getText(account: entry.account)))
|
||||
.padding(11)
|
||||
.background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandElement))
|
||||
.background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account)))
|
||||
.clipShape(Circle())
|
||||
.scaledToFit()
|
||||
.font(Font.system(.body).weight(.light))
|
||||
|
@ -145,9 +145,9 @@ struct FilesWidgetView: View {
|
|||
Image("note.text")
|
||||
.resizable()
|
||||
.renderingMode(.template)
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandText))
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getText(account: entry.account)))
|
||||
.padding(11)
|
||||
.background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandElement))
|
||||
.background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account)))
|
||||
.clipShape(Circle())
|
||||
.scaledToFit()
|
||||
.frame(width: geo.size.width / 4, height: sizeButton)
|
||||
|
@ -157,9 +157,9 @@ struct FilesWidgetView: View {
|
|||
Image("microphone")
|
||||
.resizable()
|
||||
.renderingMode(.template)
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandText))
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getText(account: entry.account)))
|
||||
.padding(11)
|
||||
.background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandElement))
|
||||
.background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account)))
|
||||
.clipShape(Circle())
|
||||
.scaledToFit()
|
||||
.frame(width: geo.size.width / 4, height: sizeButton)
|
||||
|
@ -174,12 +174,12 @@ struct FilesWidgetView: View {
|
|||
.scaledToFit()
|
||||
.frame(width: 15, height: 15)
|
||||
.font(Font.system(.body).weight(.light))
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandElement))
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account)))
|
||||
|
||||
Text(entry.footerText)
|
||||
.font(.caption2)
|
||||
.lineLimit(1)
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandElement))
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account)))
|
||||
}
|
||||
.padding(.horizontal, 15.0)
|
||||
.frame(maxWidth: geo.size.width, maxHeight: geo.size.height - 2, alignment: .bottomTrailing)
|
||||
|
@ -192,7 +192,7 @@ struct FilesWidgetView: View {
|
|||
struct FilesWidget_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
let datas = Array(filesDatasTest[0...4])
|
||||
let entry = FilesDataEntry(date: Date(), datas: datas, isPlaceholder: false, isEmpty: true, userId: "", url: "", tile: "Good afternoon, Marino Faggiana", footerImage: "checkmark.icloud", footerText: "Nextcloud files")
|
||||
let entry = FilesDataEntry(date: Date(), datas: datas, isPlaceholder: false, isEmpty: true, userId: "", url: "", account: "", tile: "Good afternoon, Marino Faggiana", footerImage: "checkmark.icloud", footerText: "Nextcloud files")
|
||||
FilesWidgetView(entry: entry).previewContext(WidgetPreviewContext(family: .systemLarge))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ struct LockscreenData: TimelineEntry {
|
|||
|
||||
func getLockscreenDataEntry(configuration: AccountIntent?, isPreview: Bool, family: WidgetFamily, completion: @escaping (_ entry: LockscreenData) -> Void) {
|
||||
let utilityFileSystem = NCUtilityFileSystem()
|
||||
var account: tableAccount?
|
||||
var activeTableAccount: tableAccount?
|
||||
var quotaRelative: Float = 0
|
||||
|
||||
if isPreview {
|
||||
|
@ -47,38 +47,37 @@ func getLockscreenDataEntry(configuration: AccountIntent?, isPreview: Bool, fami
|
|||
|
||||
let accountIdentifier: String = configuration?.accounts?.identifier ?? "active"
|
||||
if accountIdentifier == "active" {
|
||||
account = NCManageDatabase.shared.getActiveAccount()
|
||||
activeTableAccount = NCManageDatabase.shared.getActiveTableAccount()
|
||||
} else {
|
||||
account = NCManageDatabase.shared.getAccount(predicate: NSPredicate(format: "account == %@", accountIdentifier))
|
||||
activeTableAccount = NCManageDatabase.shared.getTableAccount(predicate: NSPredicate(format: "account == %@", accountIdentifier))
|
||||
}
|
||||
|
||||
guard let account else {
|
||||
guard let activeTableAccount,
|
||||
let capabilities = NCManageDatabase.shared.setCapabilities(account: activeTableAccount.account) else {
|
||||
return completion(LockscreenData(date: Date(), isPlaceholder: true, activity: "", link: URL(string: "https://")!, quotaRelative: 0, quotaUsed: "", quotaTotal: "", error: false))
|
||||
}
|
||||
|
||||
// Capabilities
|
||||
NCManageDatabase.shared.setCapabilities(account: account.account)
|
||||
|
||||
if NCGlobal.shared.capabilityServerVersionMajor < NCGlobal.shared.nextcloudVersion25 {
|
||||
if capabilities.capabilityServerVersionMajor < NCGlobal.shared.nextcloudVersion25 {
|
||||
completion(LockscreenData(date: Date(), isPlaceholder: false, activity: NSLocalizedString("_widget_available_nc25_", comment: ""), link: URL(string: "https://")!, quotaRelative: 0, quotaUsed: "", quotaTotal: "", error: true))
|
||||
}
|
||||
|
||||
// NETWORKING
|
||||
let password = NCKeychain().getPassword(account: account.account)
|
||||
NextcloudKit.shared.setup(
|
||||
account: account.account,
|
||||
user: account.user,
|
||||
userId: account.userId,
|
||||
password: password,
|
||||
urlBase: account.urlBase,
|
||||
userAgent: userAgent,
|
||||
nextcloudVersion: 0,
|
||||
delegate: NCNetworking.shared)
|
||||
let password = NCKeychain().getPassword(account: activeTableAccount.account)
|
||||
|
||||
NextcloudKit.shared.setup(delegate: NCNetworking.shared)
|
||||
NextcloudKit.shared.appendSession(account: activeTableAccount.account,
|
||||
urlBase: activeTableAccount.urlBase,
|
||||
user: activeTableAccount.user,
|
||||
userId: activeTableAccount.userId,
|
||||
password: password,
|
||||
userAgent: userAgent,
|
||||
nextcloudVersion: capabilities.capabilityServerVersionMajor,
|
||||
groupIdentifier: NCBrandOptions.shared.capabilitiesGroup)
|
||||
|
||||
let options = NKRequestOptions(timeout: 90, queue: NextcloudKit.shared.nkCommonInstance.backgroundQueue)
|
||||
if #available(iOSApplicationExtension 16.0, *) {
|
||||
if family == .accessoryCircular {
|
||||
NextcloudKit.shared.getUserProfile(account: account.account, options: options) { _, userProfile, _, error in
|
||||
NextcloudKit.shared.getUserProfile(account: activeTableAccount.account, options: options) { _, userProfile, _, error in
|
||||
if error == .success, let userProfile = userProfile {
|
||||
if userProfile.quotaRelative > 0 {
|
||||
quotaRelative = Float(userProfile.quotaRelative) / 100
|
||||
|
@ -102,7 +101,7 @@ func getLockscreenDataEntry(configuration: AccountIntent?, isPreview: Bool, fami
|
|||
}
|
||||
}
|
||||
} else if family == .accessoryRectangular {
|
||||
NextcloudKit.shared.getDashboardWidgetsApplication("activity", account: account.account, options: options) { _, results, _, error in
|
||||
NextcloudKit.shared.getDashboardWidgetsApplication("activity", account: activeTableAccount.account, options: options) { _, results, _, error in
|
||||
var activity: String = NSLocalizedString("_no_data_available_", comment: "")
|
||||
var link = URL(string: "https://")!
|
||||
if error == .success, let result = results?.first {
|
||||
|
|
|
@ -29,6 +29,7 @@ struct ToolbarDataEntry: TimelineEntry {
|
|||
let isPlaceholder: Bool
|
||||
let userId: String
|
||||
let url: String
|
||||
let account: String
|
||||
let footerImage: String
|
||||
let footerText: String
|
||||
}
|
||||
|
@ -36,19 +37,21 @@ struct ToolbarDataEntry: TimelineEntry {
|
|||
func getToolbarDataEntry(isPreview: Bool, completion: @escaping (_ entry: ToolbarDataEntry) -> Void) {
|
||||
var userId = ""
|
||||
var url = ""
|
||||
var account = ""
|
||||
|
||||
if let account = NCManageDatabase.shared.getActiveAccount() {
|
||||
userId = account.userId
|
||||
url = account.urlBase
|
||||
if let activeTableAccount = NCManageDatabase.shared.getActiveTableAccount() {
|
||||
userId = activeTableAccount.userId
|
||||
url = activeTableAccount.urlBase
|
||||
account = activeTableAccount.account
|
||||
}
|
||||
|
||||
if isPreview {
|
||||
return completion(ToolbarDataEntry(date: Date(), isPlaceholder: true, userId: userId, url: url, footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " toolbar"))
|
||||
return completion(ToolbarDataEntry(date: Date(), isPlaceholder: true, userId: userId, url: url, account: account, footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " toolbar"))
|
||||
}
|
||||
|
||||
if NCManageDatabase.shared.getActiveAccount() == nil {
|
||||
return completion(ToolbarDataEntry(date: Date(), isPlaceholder: true, userId: userId, url: url, footerImage: "xmark.icloud", footerText: NSLocalizedString("_no_active_account_", value: "No account found", comment: "")))
|
||||
if NCManageDatabase.shared.getActiveTableAccount() == nil {
|
||||
return completion(ToolbarDataEntry(date: Date(), isPlaceholder: true, userId: userId, url: url, account: account, footerImage: "xmark.icloud", footerText: NSLocalizedString("_no_active_account_", value: "No account found", comment: "")))
|
||||
}
|
||||
|
||||
completion(ToolbarDataEntry(date: Date(), isPlaceholder: false, userId: userId, url: url, footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " toolbar"))
|
||||
completion(ToolbarDataEntry(date: Date(), isPlaceholder: false, userId: userId, url: url, account: account, footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " toolbar"))
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ struct ToolbarWidgetProvider: TimelineProvider {
|
|||
typealias Entry = ToolbarDataEntry
|
||||
|
||||
func placeholder(in context: Context) -> Entry {
|
||||
return Entry(date: Date(), isPlaceholder: true, userId: "", url: "", footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " toolbar")
|
||||
return Entry(date: Date(), isPlaceholder: true, userId: "", url: "", account: "", footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " toolbar")
|
||||
}
|
||||
|
||||
func getSnapshot(in context: Context, completion: @escaping (Entry) -> Void) {
|
||||
|
|
|
@ -49,9 +49,9 @@ struct ToolbarWidgetView: View {
|
|||
Image("addImage")
|
||||
.resizable()
|
||||
.renderingMode(.template)
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandText))
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getText(account: entry.account)))
|
||||
.padding()
|
||||
.background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandElement))
|
||||
.background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account)))
|
||||
.clipShape(Circle())
|
||||
.scaledToFit()
|
||||
.frame(width: geo.size.width / 4, height: sizeButton)
|
||||
|
@ -62,9 +62,9 @@ struct ToolbarWidgetView: View {
|
|||
.resizable()
|
||||
.renderingMode(.template)
|
||||
.font(Font.system(.body).weight(.light))
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandText))
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getText(account: entry.account)))
|
||||
.padding()
|
||||
.background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandElement))
|
||||
.background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account)))
|
||||
.clipShape(Circle())
|
||||
.scaledToFit()
|
||||
.frame(width: geo.size.width / 4, height: sizeButton)
|
||||
|
@ -74,9 +74,9 @@ struct ToolbarWidgetView: View {
|
|||
Image("note.text")
|
||||
.resizable()
|
||||
.renderingMode(.template)
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandText))
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getText(account: entry.account)))
|
||||
.padding()
|
||||
.background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandElement))
|
||||
.background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account)))
|
||||
.clipShape(Circle())
|
||||
.scaledToFit()
|
||||
.frame(width: geo.size.width / 4, height: sizeButton)
|
||||
|
@ -85,9 +85,9 @@ struct ToolbarWidgetView: View {
|
|||
Link(destination: entry.isPlaceholder ? linkNoAction : linkActionVoiceMemo, label: {
|
||||
Image("microphone")
|
||||
.resizable()
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandText))
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getText(account: entry.account)))
|
||||
.padding()
|
||||
.background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandElement))
|
||||
.background(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account)))
|
||||
.clipShape(Circle())
|
||||
.scaledToFit()
|
||||
.frame(width: geo.size.width / 4, height: sizeButton)
|
||||
|
@ -102,12 +102,12 @@ struct ToolbarWidgetView: View {
|
|||
.font(Font.system(.body).weight(.light))
|
||||
.scaledToFit()
|
||||
.frame(width: 15, height: 15)
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandElement))
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account)))
|
||||
|
||||
Text(entry.footerText)
|
||||
.font(.caption2)
|
||||
.padding(.trailing, 13.0)
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.brandElement))
|
||||
.foregroundColor(entry.isPlaceholder ? Color(.systemGray4) : Color(NCBrandColor.shared.getElement(account: entry.account)))
|
||||
}
|
||||
.frame(maxWidth: geo.size.width - 5, maxHeight: geo.size.height - 2, alignment: .bottomTrailing)
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ struct ToolbarWidgetView: View {
|
|||
|
||||
struct ToolbarWidget_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
let entry = ToolbarDataEntry(date: Date(), isPlaceholder: false, userId: "", url: "", footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " toolbar")
|
||||
let entry = ToolbarDataEntry(date: Date(), isPlaceholder: false, userId: "", url: "", account: "", footerImage: "checkmark.icloud", footerText: NCBrandOptions.shared.brand + " toolbar")
|
||||
ToolbarWidgetView(entry: entry).previewContext(WidgetPreviewContext(family: .systemMedium))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ class IntentHandler: INExtension, DashboardIntentHandling, AccountIntentHandling
|
|||
|
||||
func provideAccountsOptionsCollection(for intent: AccountIntent, with completion: @escaping (INObjectCollection<Accounts>?, Error?) -> Void) {
|
||||
var accounts: [Accounts] = []
|
||||
let results = NCManageDatabase.shared.getAllAccount()
|
||||
let results = NCManageDatabase.shared.getAllTableAccount()
|
||||
|
||||
accounts.append(Accounts(identifier: "active", display: "Active account"))
|
||||
|
||||
|
@ -49,7 +49,7 @@ class IntentHandler: INExtension, DashboardIntentHandling, AccountIntentHandling
|
|||
}
|
||||
|
||||
func defaultAccounts(for intent: AccountIntent) -> Accounts? {
|
||||
if NCManageDatabase.shared.getActiveAccount() == nil {
|
||||
if NCManageDatabase.shared.getActiveTableAccount() == nil {
|
||||
return nil
|
||||
} else {
|
||||
return Accounts(identifier: "active", display: "Active account")
|
||||
|
@ -61,20 +61,20 @@ class IntentHandler: INExtension, DashboardIntentHandling, AccountIntentHandling
|
|||
// Application
|
||||
func provideApplicationsOptionsCollection(for intent: DashboardIntent, with completion: @escaping (INObjectCollection<Applications>?, Error?) -> Void) {
|
||||
var applications: [Applications] = []
|
||||
var account: tableAccount?
|
||||
var activeTableAccount: tableAccount?
|
||||
|
||||
let accountIdentifier: String = intent.accounts?.identifier ?? "active"
|
||||
if accountIdentifier == "active" {
|
||||
account = NCManageDatabase.shared.getActiveAccount()
|
||||
activeTableAccount = NCManageDatabase.shared.getActiveTableAccount()
|
||||
} else {
|
||||
account = NCManageDatabase.shared.getAccount(predicate: NSPredicate(format: "account == %@", accountIdentifier))
|
||||
activeTableAccount = NCManageDatabase.shared.getTableAccount(predicate: NSPredicate(format: "account == %@", accountIdentifier))
|
||||
}
|
||||
|
||||
guard let account = account else {
|
||||
guard let activeTableAccount else {
|
||||
return completion(nil, nil)
|
||||
}
|
||||
|
||||
let results = NCManageDatabase.shared.getDashboardWidgetApplications(account: account.account)
|
||||
let results = NCManageDatabase.shared.getDashboardWidgetApplications(account: activeTableAccount.account)
|
||||
for result in results {
|
||||
let application = Applications(identifier: result.id, display: result.title)
|
||||
applications.append(application)
|
||||
|
@ -84,7 +84,7 @@ class IntentHandler: INExtension, DashboardIntentHandling, AccountIntentHandling
|
|||
}
|
||||
|
||||
func defaultApplications(for intent: DashboardIntent) -> Applications? {
|
||||
guard let account = NCManageDatabase.shared.getActiveAccount() else {
|
||||
guard let account = NCManageDatabase.shared.getActiveTableAccount() else {
|
||||
return nil
|
||||
}
|
||||
if let result = NCManageDatabase.shared.getDashboardWidgetApplications(account: account.account).first {
|
||||
|
@ -96,7 +96,7 @@ class IntentHandler: INExtension, DashboardIntentHandling, AccountIntentHandling
|
|||
// Account
|
||||
func provideAccountsOptionsCollection(for intent: DashboardIntent, with completion: @escaping (INObjectCollection<Accounts>?, Error?) -> Void) {
|
||||
var accounts: [Accounts] = []
|
||||
let results = NCManageDatabase.shared.getAllAccount()
|
||||
let results = NCManageDatabase.shared.getAllTableAccount()
|
||||
|
||||
accounts.append(Accounts(identifier: "active", display: "Active account"))
|
||||
|
||||
|
@ -115,7 +115,7 @@ class IntentHandler: INExtension, DashboardIntentHandling, AccountIntentHandling
|
|||
}
|
||||
|
||||
func defaultAccounts(for intent: DashboardIntent) -> Accounts? {
|
||||
if NCManageDatabase.shared.getActiveAccount() == nil {
|
||||
if NCManageDatabase.shared.getActiveTableAccount() == nil {
|
||||
return nil
|
||||
} else {
|
||||
return Accounts(identifier: "active", display: "Active account")
|
||||
|
|
|
@ -26,7 +26,7 @@ import NextcloudKit
|
|||
|
||||
public protocol NCAccountRequestDelegate: AnyObject {
|
||||
func accountRequestAddAccount()
|
||||
func accountRequestChangeAccount(account: String)
|
||||
func accountRequestChangeAccount(account: String, controller: UIViewController?)
|
||||
}
|
||||
|
||||
class NCAccountRequest: UIViewController {
|
||||
|
@ -35,11 +35,12 @@ class NCAccountRequest: UIViewController {
|
|||
@IBOutlet weak var progressView: UIProgressView!
|
||||
|
||||
public var accounts: [tableAccount] = []
|
||||
public var activeAccount: tableAccount?
|
||||
public var activeAccount: String?
|
||||
public let heightCell: CGFloat = 60
|
||||
public var enableTimerProgress: Bool = true
|
||||
public var enableAddAccount: Bool = false
|
||||
public var dismissDidEnterBackground: Bool = false
|
||||
public var controller: UIViewController?
|
||||
public weak var delegate: NCAccountRequestDelegate?
|
||||
let utility = NCUtility()
|
||||
private var timer: Timer?
|
||||
|
@ -134,9 +135,9 @@ extension NCAccountRequest: UITableViewDelegate {
|
|||
delegate?.accountRequestAddAccount()
|
||||
} else {
|
||||
let account = accounts[indexPath.row]
|
||||
if account.account != activeAccount?.account {
|
||||
if account.account != activeAccount {
|
||||
dismiss(animated: true) {
|
||||
self.delegate?.accountRequestChangeAccount(account: account.account)
|
||||
self.delegate?.accountRequestChangeAccount(account: account.account, controller: self.controller)
|
||||
}
|
||||
} else {
|
||||
dismiss(animated: true)
|
||||
|
@ -177,10 +178,7 @@ extension NCAccountRequest: UITableViewDataSource {
|
|||
|
||||
let account = accounts[indexPath.row]
|
||||
|
||||
avatarImage?.image = utility.loadUserImage(
|
||||
for: account.user,
|
||||
displayName: account.displayName,
|
||||
userBaseUrl: account)
|
||||
avatarImage?.image = utility.loadUserImage(for: account.user, displayName: account.displayName, urlBase: account.urlBase)
|
||||
|
||||
if account.alias.isEmpty {
|
||||
userLabel?.text = account.user.uppercased()
|
||||
|
|
|
@ -27,7 +27,7 @@ import RealmSwift
|
|||
|
||||
/// Protocol for know when the Account Settings has dimissed
|
||||
protocol NCAccountSettingsModelDelegate: AnyObject {
|
||||
func accountSettingsDidDismiss(tableAccount: tableAccount?)
|
||||
func accountSettingsDidDismiss(tableAccount: tableAccount?, controller: NCMainTabBarController?)
|
||||
}
|
||||
|
||||
/// A model that allows the user to configure the account
|
||||
|
@ -37,36 +37,34 @@ class NCAccountSettingsModel: ObservableObject, ViewOnAppearHandling {
|
|||
/// Root View Controller
|
||||
var controller: NCMainTabBarController?
|
||||
/// All account
|
||||
var accounts: [tableAccount] = []
|
||||
var tblAccounts: [tableAccount] = []
|
||||
/// Delegate
|
||||
weak var delegate: NCAccountSettingsModelDelegate?
|
||||
/// Timer change user
|
||||
var timerChangeAccount: Timer?
|
||||
/// Token observe tableAccount
|
||||
var notificationToken: NotificationToken?
|
||||
/// Account now active
|
||||
@Published var activeAccount: tableAccount?
|
||||
/// Account now
|
||||
@Published var tblAccount: tableAccount?
|
||||
/// Index
|
||||
@Published var indexActiveAccount: Int = 0
|
||||
/// Current alias
|
||||
@Published var alias: String = ""
|
||||
/// Set true for dismiss the view
|
||||
@Published var dismissView = false
|
||||
/// DB
|
||||
let database = NCManageDatabase.shared
|
||||
|
||||
/// Initialization code to set up the ViewModel with the active account
|
||||
init(controller: NCMainTabBarController?, delegate: NCAccountSettingsModelDelegate?) {
|
||||
self.controller = controller
|
||||
self.delegate = delegate
|
||||
if ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1" {
|
||||
NCManageDatabase.shared.previewCreateDB()
|
||||
database.previewCreateDB()
|
||||
}
|
||||
onViewAppear()
|
||||
observeTableAccount()
|
||||
}
|
||||
|
||||
deinit {
|
||||
timerChangeAccount?.invalidate()
|
||||
timerChangeAccount = nil
|
||||
notificationToken?.invalidate()
|
||||
notificationToken = nil
|
||||
}
|
||||
|
@ -96,45 +94,44 @@ class NCAccountSettingsModel: ObservableObject, ViewOnAppearHandling {
|
|||
/// Triggered when the view appears.
|
||||
func onViewAppear() {
|
||||
var indexActiveAccount = 0
|
||||
let accounts = NCManageDatabase.shared.getAllAccount()
|
||||
var activeAccount = NCManageDatabase.shared.getActiveAccount()
|
||||
let tableAccounts = database.getAllTableAccount()
|
||||
var alias = ""
|
||||
|
||||
for (index, account) in accounts.enumerated() {
|
||||
for (index, account) in tableAccounts.enumerated() {
|
||||
if account.active {
|
||||
activeAccount = account
|
||||
tblAccount = account
|
||||
indexActiveAccount = index
|
||||
alias = account.alias
|
||||
}
|
||||
}
|
||||
|
||||
self.indexActiveAccount = indexActiveAccount
|
||||
self.accounts = accounts
|
||||
self.activeAccount = activeAccount
|
||||
self.tblAccounts = tableAccounts
|
||||
self.tblAccount = tblAccount
|
||||
self.alias = alias
|
||||
}
|
||||
|
||||
/// Func to get the user display name + alias
|
||||
func getUserName() -> String {
|
||||
guard let activeAccount else { return "" }
|
||||
guard let tblAccount else { return "" }
|
||||
if alias.isEmpty {
|
||||
return activeAccount.displayName
|
||||
return tblAccount.displayName
|
||||
} else {
|
||||
return activeAccount.displayName + " (\(alias))"
|
||||
return tblAccount.displayName + " (\(alias))"
|
||||
}
|
||||
}
|
||||
|
||||
/// Func to set alias
|
||||
func setAlias(_ value: String) {
|
||||
guard let activeAccount else { return }
|
||||
NCManageDatabase.shared.setAccountAlias(activeAccount.account, alias: alias)
|
||||
guard let tblAccount else { return }
|
||||
database.setAccountAlias(tblAccount.account, alias: alias)
|
||||
}
|
||||
|
||||
/// Function to update the user data
|
||||
func getUserStatus() -> (statusImage: UIImage?, statusMessage: String, descriptionMessage: String) {
|
||||
guard let activeAccount else { return (UIImage(), "", "") }
|
||||
if NCGlobal.shared.capabilityUserStatusEnabled,
|
||||
let tableAccount = NCManageDatabase.shared.getAccount(predicate: NSPredicate(format: "account == %@", activeAccount.account)) {
|
||||
guard let tblAccount else { return (UIImage(), "", "") }
|
||||
if NCCapabilities.shared.getCapabilities(account: tblAccount.account).capabilityUserStatusEnabled,
|
||||
let tableAccount = database.getTableAccount(predicate: NSPredicate(format: "account == %@", tblAccount.account)) {
|
||||
return NCUtility().getUserStatus(userIcon: tableAccount.userStatusIcon, userStatus: tableAccount.userStatusStatus, userMessage: tableAccount.userStatusMessage)
|
||||
}
|
||||
return (nil, "", "")
|
||||
|
@ -142,17 +139,18 @@ class NCAccountSettingsModel: ObservableObject, ViewOnAppearHandling {
|
|||
|
||||
/// Is the user an Admin
|
||||
func isAdminGroup() -> Bool {
|
||||
guard let activeAccount else { return false }
|
||||
let groups = NCManageDatabase.shared.getAccountGroups(account: activeAccount.account)
|
||||
guard let tblAccount else { return false }
|
||||
let groups = database.getAccountGroups(account: tblAccount.account)
|
||||
return groups.contains(NCGlobal.shared.groupAdmin)
|
||||
}
|
||||
|
||||
/// Function to know the height of "account" data
|
||||
func getTableViewHeight() -> CGFloat {
|
||||
guard let activeAccount else { return 0 }
|
||||
var height: CGFloat = NCGlobal.shared.capabilityUserStatusEnabled ? 190 : 220
|
||||
if NCGlobal.shared.capabilityUserStatusEnabled,
|
||||
let tableAccount = NCManageDatabase.shared.getAccount(predicate: NSPredicate(format: "account == %@", activeAccount.account)) {
|
||||
guard let tblAccount else { return 0 }
|
||||
let capabilities = NCCapabilities.shared.getCapabilities(account: tblAccount.account)
|
||||
var height: CGFloat = capabilities.capabilityUserStatusEnabled ? 190 : 220
|
||||
if capabilities.capabilityUserStatusEnabled,
|
||||
let tableAccount = database.getTableAccount(predicate: NSPredicate(format: "account == %@", tblAccount.account)) {
|
||||
if !tableAccount.email.isEmpty { height += 30 }
|
||||
if !tableAccount.phone.isEmpty { height += 30 }
|
||||
if !tableAccount.address.isEmpty { height += 30 }
|
||||
|
@ -163,33 +161,23 @@ class NCAccountSettingsModel: ObservableObject, ViewOnAppearHandling {
|
|||
|
||||
/// Function to change account after 1.5 sec of change
|
||||
func setAccount(account: String) {
|
||||
if let tableAccount = NCManageDatabase.shared.getAccount(predicate: NSPredicate(format: "account == %@", account)), self.activeAccount?.account != tableAccount.account {
|
||||
self.activeAccount = tableAccount
|
||||
if let tableAccount = database.getTableAccount(predicate: NSPredicate(format: "account == %@", account)) {
|
||||
self.tblAccount = tableAccount
|
||||
self.alias = tableAccount.alias
|
||||
/// Change active account
|
||||
timerChangeAccount?.invalidate()
|
||||
timerChangeAccount = Timer.scheduledTimer(timeInterval: 1.5, target: self, selector: #selector(changeAccount), userInfo: nil, repeats: false)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@objc func changeAccount() {
|
||||
if let activeAccount {
|
||||
self.appDelegate.changeAccount(activeAccount.account, userProfile: nil) { }
|
||||
}
|
||||
}
|
||||
|
||||
/// Function to delete the current account
|
||||
func deleteAccount() {
|
||||
if let activeAccount {
|
||||
appDelegate.deleteAccount(activeAccount.account)
|
||||
if let account = NCManageDatabase.shared.getAllAccount().first?.account {
|
||||
appDelegate.changeAccount(account, userProfile: nil) {
|
||||
if let tblAccount {
|
||||
NCAccount().deleteAccount(tblAccount.account)
|
||||
if let account = database.getAllTableAccount().first?.account {
|
||||
NCAccount().changeAccount(account, userProfile: nil, controller: self.controller) {
|
||||
onViewAppear()
|
||||
}
|
||||
} else {
|
||||
dismissView = true
|
||||
appDelegate.openLogin(selector: NCGlobal.shared.introLogin, openLoginWeb: false)
|
||||
appDelegate.openLogin(selector: NCGlobal.shared.introLogin)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,9 +41,9 @@ struct NCAccountSettingsView: View {
|
|||
Form {
|
||||
Section(content: {
|
||||
TabView(selection: $model.indexActiveAccount) {
|
||||
ForEach(0..<model.accounts.count, id: \.self) { index in
|
||||
ForEach(0..<model.tblAccounts.count, id: \.self) { index in
|
||||
let status = model.getUserStatus()
|
||||
let avatar = NCUtility().loadUserImage(for: model.accounts[index].user, displayName: model.accounts[index].displayName, userBaseUrl: model.accounts[index])
|
||||
let avatar = NCUtility().loadUserImage(for: model.tblAccounts[index].user, displayName: model.tblAccounts[index].displayName, urlBase: model.tblAccounts[index].urlBase)
|
||||
///
|
||||
/// User
|
||||
VStack {
|
||||
|
@ -76,15 +76,15 @@ struct NCAccountSettingsView: View {
|
|||
.frame(height: 20)
|
||||
///
|
||||
/// Personal data
|
||||
if let activeAccount = model.activeAccount {
|
||||
if !activeAccount.email.isEmpty {
|
||||
if let tblAccount = model.tblAccount {
|
||||
if !tblAccount.email.isEmpty {
|
||||
HStack {
|
||||
Image(systemName: "mail")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.font(Font.system(.body).weight(.light))
|
||||
.frame(width: 20, height: 20)
|
||||
Text(activeAccount.email)
|
||||
Text(tblAccount.email)
|
||||
.lineLimit(1)
|
||||
.truncationMode(.middle)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
|
@ -92,28 +92,28 @@ struct NCAccountSettingsView: View {
|
|||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: 30)
|
||||
}
|
||||
if !activeAccount.phone.isEmpty {
|
||||
if !tblAccount.phone.isEmpty {
|
||||
HStack {
|
||||
Image(systemName: "phone")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.font(Font.system(.body).weight(.light))
|
||||
.frame(width: 20, height: 20)
|
||||
Text(activeAccount.phone)
|
||||
Text(tblAccount.phone)
|
||||
.lineLimit(1)
|
||||
.truncationMode(.middle)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: 30)
|
||||
}
|
||||
if !activeAccount.address.isEmpty {
|
||||
if !tblAccount.address.isEmpty {
|
||||
HStack {
|
||||
Image(systemName: "house")
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.font(Font.system(.body).weight(.light))
|
||||
.frame(width: 20, height: 20)
|
||||
Text(activeAccount.address)
|
||||
Text(tblAccount.address)
|
||||
.lineLimit(1)
|
||||
.truncationMode(.middle)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
|
@ -130,7 +130,7 @@ struct NCAccountSettingsView: View {
|
|||
.animation(.easeIn(duration: 0.3), value: animation)
|
||||
.onChange(of: model.indexActiveAccount) { index in
|
||||
animation.toggle()
|
||||
model.setAccount(account: model.accounts[index].account)
|
||||
model.setAccount(account: model.tblAccounts[index].account)
|
||||
}
|
||||
///
|
||||
/// Change alias
|
||||
|
@ -155,7 +155,7 @@ struct NCAccountSettingsView: View {
|
|||
}
|
||||
///
|
||||
/// User Status
|
||||
if NCGlobal.shared.capabilityUserStatusEnabled {
|
||||
if NCCapabilities.shared.getCapabilities(account: model.tblAccount?.account).capabilityUserStatusEnabled {
|
||||
Button(action: {
|
||||
showUserStatus = true
|
||||
}, label: {
|
||||
|
@ -175,7 +175,9 @@ struct NCAccountSettingsView: View {
|
|||
.font(.system(size: 14))
|
||||
})
|
||||
.sheet(isPresented: $showUserStatus) {
|
||||
UserStatusView(showUserStatus: $showUserStatus)
|
||||
if let account = model.tblAccount?.account {
|
||||
UserStatusView(showUserStatus: $showUserStatus, account: account)
|
||||
}
|
||||
}
|
||||
.onChange(of: showUserStatus) { _ in }
|
||||
}
|
||||
|
@ -201,7 +203,7 @@ struct NCAccountSettingsView: View {
|
|||
.font(.system(size: 14))
|
||||
})
|
||||
.sheet(isPresented: $showServerCertificate) {
|
||||
if let url = URL(string: model.activeAccount?.urlBase), let host = url.host {
|
||||
if let url = URL(string: model.tblAccount?.urlBase), let host = url.host {
|
||||
certificateDetailsView(host: host, title: NSLocalizedString("_certificate_view_", comment: ""))
|
||||
}
|
||||
}
|
||||
|
@ -279,7 +281,7 @@ struct NCAccountSettingsView: View {
|
|||
}
|
||||
}
|
||||
.onDisappear {
|
||||
model.delegate?.accountSettingsDidDismiss(tableAccount: model.activeAccount)
|
||||
model.delegate?.accountSettingsDidDismiss(tableAccount: model.tblAccount, controller: model.controller)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="22505" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="nhT-TJ-YvX">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23094" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="nhT-TJ-YvX">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22504"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23084"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
|
@ -20,28 +20,28 @@
|
|||
<rect key="frame" x="0.0" y="48" width="414" height="848"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<prototypes>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="tableCell" rowHeight="35" id="ggj-aE-fnh" customClass="NCActivityTableViewCell" customModule="Nextcloud" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="50" width="414" height="35"/>
|
||||
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="tableCell" rowHeight="50" id="ggj-aE-fnh" customClass="NCActivityTableViewCell" customModule="Nextcloud" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="50" width="414" height="50"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="ggj-aE-fnh" id="i35-U4-bEk">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="35"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="50"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="252" text="Label" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fcO-YL-MuT">
|
||||
<rect key="frame" x="100" y="0.0" width="304" height="18"/>
|
||||
<fontDescription key="fontDescription" name=".AppleSystemUIFont" family=".AppleSystemUIFont" pointSize="15"/>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="252" text="Label" lineBreakMode="tailTruncation" numberOfLines="4" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fcO-YL-MuT">
|
||||
<rect key="frame" x="90" y="3" width="314" height="44"/>
|
||||
<fontDescription key="fontDescription" name=".AppleSystemUIFont" family=".AppleSystemUIFont" pointSize="14"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<imageView contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="LQ8-cO-794" userLabel="avatar">
|
||||
<rect key="frame" x="50" y="0.0" width="35" height="35"/>
|
||||
<imageView contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="LQ8-cO-794" userLabel="avatar">
|
||||
<rect key="frame" x="50" y="12.5" width="25" height="25"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="35" id="OKz-e8-DzD"/>
|
||||
<constraint firstAttribute="height" constant="35" id="fwd-J4-5uY"/>
|
||||
<constraint firstAttribute="width" constant="25" id="OKz-e8-DzD" userLabel="25"/>
|
||||
<constraint firstAttribute="height" constant="25" id="fwd-J4-5uY"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<imageView userInteractionEnabled="NO" alpha="0.59999999999999998" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="xNG-sf-PnA">
|
||||
<rect key="frame" x="20" y="8" width="20" height="20"/>
|
||||
<rect key="frame" x="20" y="15" width="20" height="20"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="20" id="Lbv-yi-vAh"/>
|
||||
<constraint firstAttribute="height" constant="20" id="TML-VJ-2i3"/>
|
||||
|
@ -50,12 +50,13 @@
|
|||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="fcO-YL-MuT" secondAttribute="trailing" constant="10" id="1pG-qk-inI"/>
|
||||
<constraint firstItem="LQ8-cO-794" firstAttribute="top" secondItem="i35-U4-bEk" secondAttribute="top" id="3fU-rp-D7s"/>
|
||||
<constraint firstItem="xNG-sf-PnA" firstAttribute="top" secondItem="i35-U4-bEk" secondAttribute="top" constant="8" id="4EB-59-y1Y"/>
|
||||
<constraint firstAttribute="bottom" secondItem="fcO-YL-MuT" secondAttribute="bottom" constant="3" id="9Yo-kF-q3Y"/>
|
||||
<constraint firstItem="xNG-sf-PnA" firstAttribute="leading" secondItem="i35-U4-bEk" secondAttribute="leading" constant="20" id="CRN-18-SeU"/>
|
||||
<constraint firstItem="LQ8-cO-794" firstAttribute="centerY" secondItem="i35-U4-bEk" secondAttribute="centerY" id="Giz-bM-Jpm"/>
|
||||
<constraint firstItem="xNG-sf-PnA" firstAttribute="centerY" secondItem="i35-U4-bEk" secondAttribute="centerY" id="PDf-gj-Y2F"/>
|
||||
<constraint firstItem="fcO-YL-MuT" firstAttribute="leading" secondItem="LQ8-cO-794" secondAttribute="trailing" constant="15" id="am5-CT-0kZ" userLabel="Subject.leading = Icon.trailing + 50"/>
|
||||
<constraint firstItem="LQ8-cO-794" firstAttribute="leading" secondItem="xNG-sf-PnA" secondAttribute="trailing" constant="10" id="aqp-Wu-9Hk"/>
|
||||
<constraint firstItem="fcO-YL-MuT" firstAttribute="top" secondItem="i35-U4-bEk" secondAttribute="top" id="faC-by-km5"/>
|
||||
<constraint firstItem="fcO-YL-MuT" firstAttribute="top" secondItem="i35-U4-bEk" secondAttribute="top" constant="3" id="faC-by-km5"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<connections>
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
import UIKit
|
||||
import SwiftRichString
|
||||
import NextcloudKit
|
||||
import SVGKit
|
||||
|
||||
class NCActivity: UIViewController, NCSharePagingContent {
|
||||
@IBOutlet weak var viewContainerConstraint: NSLayoutConstraint!
|
||||
|
@ -36,9 +37,9 @@ class NCActivity: UIViewController, NCSharePagingContent {
|
|||
var metadata: tableMetadata?
|
||||
var showComments: Bool = false
|
||||
|
||||
let appDelegate = (UIApplication.shared.delegate as? AppDelegate)!
|
||||
let utilityFileSystem = NCUtilityFileSystem()
|
||||
let utility = NCUtility()
|
||||
let database = NCManageDatabase.shared
|
||||
var allItems: [DateCompareable] = []
|
||||
var sectionDates: [Date] = []
|
||||
var dataSourceTask: URLSessionTask?
|
||||
|
@ -46,6 +47,7 @@ class NCActivity: UIViewController, NCSharePagingContent {
|
|||
var insets = UIEdgeInsets(top: 8, left: 0, bottom: 0, right: 0)
|
||||
var didSelectItemEnable: Bool = true
|
||||
var objectType: String?
|
||||
var account: String = ""
|
||||
|
||||
var isFetchingActivity = false
|
||||
var hasActivityToLoad = true {
|
||||
|
@ -53,6 +55,14 @@ class NCActivity: UIViewController, NCSharePagingContent {
|
|||
}
|
||||
var dateAutomaticFetch: Date?
|
||||
|
||||
var session: NCSession.Session {
|
||||
if account.isEmpty {
|
||||
NCSession.shared.getSession(controller: tabBarController)
|
||||
} else {
|
||||
NCSession.shared.getSession(account: account)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - View Life Cycle
|
||||
|
||||
override func viewDidLoad() {
|
||||
|
@ -74,15 +84,12 @@ class NCActivity: UIViewController, NCSharePagingContent {
|
|||
|
||||
func setupComments() {
|
||||
// Display Name & Quota
|
||||
guard let activeAccount = NCManageDatabase.shared.getActiveAccount(), height > 0 else {
|
||||
return
|
||||
}
|
||||
|
||||
guard let metadata else { return }
|
||||
tableView.register(UINib(nibName: "NCShareCommentsCell", bundle: nil), forCellReuseIdentifier: "cell")
|
||||
commentView = Bundle.main.loadNibNamed("NCActivityCommentView", owner: self, options: nil)?.first as? NCActivityCommentView
|
||||
commentView?.setup(urlBase: appDelegate, account: activeAccount) { newComment in
|
||||
commentView?.setup(account: metadata.account) { newComment in
|
||||
guard let newComment = newComment, !newComment.isEmpty, let metadata = self.metadata else { return }
|
||||
NextcloudKit.shared.putComments(fileId: metadata.fileId, message: newComment, account: self.appDelegate.account) { _, error in
|
||||
NextcloudKit.shared.putComments(fileId: metadata.fileId, message: newComment, account: metadata.account) { _, _, error in
|
||||
if error == .success {
|
||||
self.commentView?.newCommentField.text?.removeAll()
|
||||
self.loadComments()
|
||||
|
@ -145,7 +152,7 @@ extension NCActivity: UITableViewDelegate {
|
|||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
|
||||
return 80
|
||||
return 80.0
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
|
||||
|
@ -209,34 +216,49 @@ extension NCActivity: UITableViewDataSource {
|
|||
}
|
||||
|
||||
func makeCommentCell(_ comment: tableComments, for indexPath: IndexPath) -> UITableViewCell {
|
||||
guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? NCShareCommentsCell else {
|
||||
guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? NCShareCommentsCell,
|
||||
let metadata else {
|
||||
return UITableViewCell()
|
||||
}
|
||||
|
||||
cell.indexPath = indexPath
|
||||
cell.tableComments = comment
|
||||
cell.delegate = self
|
||||
cell.sizeToFit()
|
||||
|
||||
// Image
|
||||
let fileName = appDelegate.userBaseUrl + "-" + comment.actorId + ".png"
|
||||
NCNetworking.shared.downloadAvatar(user: comment.actorId, dispalyName: comment.actorDisplayName, fileName: fileName, cell: cell, view: tableView)
|
||||
// Avatar
|
||||
let fileName = NCSession.shared.getFileName(urlBase: metadata.urlBase, user: comment.actorId)
|
||||
let results = NCManageDatabase.shared.getImageAvatarLoaded(fileName: fileName)
|
||||
|
||||
if results.image == nil {
|
||||
cell.fileAvatarImageView?.image = utility.loadUserImage(for: comment.actorId, displayName: comment.actorDisplayName, urlBase: NCSession.shared.getSession(account: account).urlBase)
|
||||
} else {
|
||||
cell.fileAvatarImageView?.image = results.image
|
||||
}
|
||||
|
||||
if let tableAvatar = results.tableAvatar,
|
||||
!tableAvatar.loaded,
|
||||
NCNetworking.shared.downloadAvatarQueue.operations.filter({ ($0 as? NCOperationDownloadAvatar)?.fileName == fileName }).isEmpty {
|
||||
NCNetworking.shared.downloadAvatarQueue.addOperation(NCOperationDownloadAvatar(user: comment.actorId, fileName: fileName, account: account, view: tableView))
|
||||
}
|
||||
|
||||
// Username
|
||||
cell.labelUser.text = comment.actorDisplayName
|
||||
cell.labelUser.textColor = NCBrandColor.shared.textColor
|
||||
// Date
|
||||
cell.labelDate.text = utility.dateDiff(comment.creationDateTime as Date)
|
||||
cell.labelDate.textColor = .systemGray4
|
||||
cell.labelDate.textColor = .lightGray
|
||||
// Message
|
||||
cell.labelMessage.text = comment.message
|
||||
cell.labelMessage.textColor = NCBrandColor.shared.textColor
|
||||
// Button Menu
|
||||
if comment.actorId == appDelegate.userId {
|
||||
if comment.actorId == metadata.userId {
|
||||
cell.buttonMenu.isHidden = false
|
||||
} else {
|
||||
cell.buttonMenu.isHidden = true
|
||||
}
|
||||
|
||||
cell.sizeToFit()
|
||||
|
||||
return cell
|
||||
}
|
||||
|
||||
|
@ -247,6 +269,7 @@ extension NCActivity: UITableViewDataSource {
|
|||
var orderKeysId: [String] = []
|
||||
|
||||
cell.idActivity = activity.idActivity
|
||||
cell.account = activity.account
|
||||
cell.indexPath = indexPath
|
||||
cell.avatar.image = nil
|
||||
cell.avatar.isHidden = true
|
||||
|
@ -256,18 +279,21 @@ extension NCActivity: UITableViewDataSource {
|
|||
|
||||
// icon
|
||||
if !activity.icon.isEmpty {
|
||||
activity.icon = activity.icon.replacingOccurrences(of: ".png", with: ".svg")
|
||||
let fileNameIcon = (activity.icon as NSString).lastPathComponent
|
||||
let fileNameLocalPath = utilityFileSystem.directoryUserData + "/" + fileNameIcon
|
||||
|
||||
if FileManager.default.fileExists(atPath: fileNameLocalPath) {
|
||||
if let image = UIImage(contentsOfFile: fileNameLocalPath) {
|
||||
let image = fileNameIcon.contains(".svg") ? SVGKImage(contentsOfFile: fileNameLocalPath)?.uiImage : UIImage(contentsOfFile: fileNameLocalPath)
|
||||
|
||||
if let image {
|
||||
cell.icon.image = image.withTintColor(NCBrandColor.shared.textColor, renderingMode: .alwaysOriginal)
|
||||
}
|
||||
} else {
|
||||
NextcloudKit.shared.downloadContent(serverUrl: activity.icon, account: appDelegate.account) { _, data, error in
|
||||
if error == .success {
|
||||
NextcloudKit.shared.downloadContent(serverUrl: activity.icon, account: activity.account) { _, responseData, error in
|
||||
if error == .success, let data = responseData?.data {
|
||||
do {
|
||||
try data!.write(to: NSURL(fileURLWithPath: fileNameLocalPath) as URL, options: .atomic)
|
||||
try data.write(to: NSURL(fileURLWithPath: fileNameLocalPath) as URL, options: .atomic)
|
||||
self.tableView.reloadData()
|
||||
} catch { return }
|
||||
}
|
||||
|
@ -276,12 +302,24 @@ extension NCActivity: UITableViewDataSource {
|
|||
}
|
||||
|
||||
// avatar
|
||||
if !activity.user.isEmpty && activity.user != appDelegate.userId {
|
||||
if !activity.user.isEmpty && activity.user != session.userId {
|
||||
cell.avatar.isHidden = false
|
||||
cell.fileUser = activity.user
|
||||
let fileName = appDelegate.userBaseUrl + "-" + activity.user + ".png"
|
||||
NCNetworking.shared.downloadAvatar(user: activity.user, dispalyName: nil, fileName: fileName, cell: cell, view: tableView)
|
||||
cell.subjectLeadingConstraint.constant = 15
|
||||
|
||||
let fileName = NCSession.shared.getFileName(urlBase: session.urlBase, user: activity.user)
|
||||
let results = NCManageDatabase.shared.getImageAvatarLoaded(fileName: fileName)
|
||||
|
||||
if results.image == nil {
|
||||
cell.fileAvatarImageView?.image = utility.loadUserImage(for: activity.user, displayName: nil, urlBase: session.urlBase)
|
||||
} else {
|
||||
cell.fileAvatarImageView?.image = results.image
|
||||
}
|
||||
|
||||
if !(results.tableAvatar?.loaded ?? false),
|
||||
NCNetworking.shared.downloadAvatarQueue.operations.filter({ ($0 as? NCOperationDownloadAvatar)?.fileName == fileName }).isEmpty {
|
||||
NCNetworking.shared.downloadAvatarQueue.addOperation(NCOperationDownloadAvatar(user: activity.user, fileName: fileName, account: session.account, view: tableView))
|
||||
}
|
||||
} else {
|
||||
cell.subjectLeadingConstraint.constant = -30
|
||||
}
|
||||
|
@ -300,7 +338,7 @@ extension NCActivity: UITableViewDataSource {
|
|||
}
|
||||
|
||||
for key in keys {
|
||||
if let result = NCManageDatabase.shared.getActivitySubjectRich(account: appDelegate.account, idActivity: activity.idActivity, key: key) {
|
||||
if let result = database.getActivitySubjectRich(account: session.account, idActivity: activity.idActivity, key: key) {
|
||||
orderKeysId.append(result.id)
|
||||
subject = subject.replacingOccurrences(of: "{\(key)}", with: "<bold>" + result.name + "</bold>")
|
||||
}
|
||||
|
@ -344,7 +382,7 @@ extension NCActivity {
|
|||
var bottom: CGFloat = 0
|
||||
|
||||
if let mainTabBar = self.tabBarController?.tabBar as? NCMainTabBar {
|
||||
bottom = -mainTabBar.getHeight()
|
||||
bottom = -mainTabBar.getHeight()
|
||||
}
|
||||
NCActivityIndicator.shared.start(backgroundView: self.view, bottom: bottom - 35, style: .medium)
|
||||
|
||||
|
@ -371,13 +409,13 @@ extension NCActivity {
|
|||
func loadDataSource() {
|
||||
var newItems = [DateCompareable]()
|
||||
|
||||
if showComments, let metadata = metadata, let account = NCManageDatabase.shared.getActiveAccount() {
|
||||
let comments = NCManageDatabase.shared.getComments(account: account.account, objectId: metadata.fileId)
|
||||
if showComments, let metadata {
|
||||
let comments = database.getComments(account: metadata.account, objectId: metadata.fileId)
|
||||
newItems += comments
|
||||
}
|
||||
|
||||
let activities = NCManageDatabase.shared.getActivity(
|
||||
predicate: NSPredicate(format: "account == %@", appDelegate.account),
|
||||
let activities = database.getActivity(
|
||||
predicate: NSPredicate(format: "account == %@", session.account),
|
||||
filterFileId: metadata?.fileId)
|
||||
newItems += activities.filter
|
||||
|
||||
|
@ -395,7 +433,7 @@ extension NCActivity {
|
|||
|
||||
NextcloudKit.shared.getComments(fileId: metadata.fileId, account: metadata.account) { _, comments, _, error in
|
||||
if error == .success, let comments = comments {
|
||||
NCManageDatabase.shared.addComments(comments, account: metadata.account, objectId: metadata.fileId)
|
||||
self.database.addComments(comments, account: metadata.account, objectId: metadata.fileId)
|
||||
} else if error.errorCode != NCGlobal.shared.errorResourceNotFound {
|
||||
NCContentPresenter().showError(error: error)
|
||||
}
|
||||
|
@ -410,7 +448,7 @@ extension NCActivity {
|
|||
|
||||
/// Check if most recent activivities are loaded, if not trigger reload
|
||||
func checkRecentActivity(disptachGroup: DispatchGroup) {
|
||||
guard let result = NCManageDatabase.shared.getLatestActivityId(account: appDelegate.account), metadata == nil, hasActivityToLoad else {
|
||||
guard let result = database.getLatestActivityId(account: session.account), metadata == nil, hasActivityToLoad else {
|
||||
return self.loadActivity(idActivity: 0, disptachGroup: disptachGroup)
|
||||
}
|
||||
let resultActivityId = max(result.activityFirstKnown, result.activityLastGiven)
|
||||
|
@ -423,14 +461,14 @@ extension NCActivity {
|
|||
objectId: nil,
|
||||
objectType: objectType,
|
||||
previews: true,
|
||||
account: appDelegate.account) { task in
|
||||
account: session.account) { task in
|
||||
self.dataSourceTask = task
|
||||
} completion: { account, _, activityFirstKnown, activityLastGiven, _, error in
|
||||
defer { disptachGroup.leave() }
|
||||
|
||||
let largestActivityId = max(activityFirstKnown, activityLastGiven)
|
||||
guard error == .success,
|
||||
account == self.appDelegate.account,
|
||||
account == self.session.account,
|
||||
largestActivityId > resultActivityId
|
||||
else {
|
||||
self.hasActivityToLoad = error.errorCode == NCGlobal.shared.errorNotModified ? false : self.hasActivityToLoad
|
||||
|
@ -452,26 +490,26 @@ extension NCActivity {
|
|||
objectId: metadata?.fileId,
|
||||
objectType: objectType,
|
||||
previews: true,
|
||||
account: appDelegate.account) { task in
|
||||
account: session.account) { task in
|
||||
self.dataSourceTask = task
|
||||
} completion: { account, activities, activityFirstKnown, activityLastGiven, _, error in
|
||||
defer { disptachGroup.leave() }
|
||||
guard error == .success,
|
||||
account == self.appDelegate.account,
|
||||
account == self.session.account,
|
||||
!activities.isEmpty
|
||||
else {
|
||||
self.hasActivityToLoad = error.errorCode == NCGlobal.shared.errorNotModified ? false : self.hasActivityToLoad
|
||||
return
|
||||
}
|
||||
NCManageDatabase.shared.addActivity(activities, account: account)
|
||||
self.database.addActivity(activities, account: account)
|
||||
|
||||
// update most recently loaded activity only when all activities are loaded (not filtered)
|
||||
let largestActivityId = max(activityFirstKnown, activityLastGiven)
|
||||
if let result = NCManageDatabase.shared.getLatestActivityId(account: self.appDelegate.account) {
|
||||
if let result = self.database.getLatestActivityId(account: self.session.account) {
|
||||
resultActivityId = max(result.activityFirstKnown, result.activityLastGiven)
|
||||
}
|
||||
if self.metadata == nil, largestActivityId > resultActivityId {
|
||||
NCManageDatabase.shared.updateLatestActivityId(activityFirstKnown: activityFirstKnown, activityLastGiven: activityLastGiven, account: account)
|
||||
self.database.updateLatestActivityId(activityFirstKnown: activityFirstKnown, activityLastGiven: activityLastGiven, account: account)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -482,7 +520,7 @@ extension NCActivity: NCShareCommentsCellDelegate {
|
|||
guard let tableComment = tableComment else {
|
||||
return
|
||||
}
|
||||
self.showProfileMenu(userId: tableComment.actorId)
|
||||
self.showProfileMenu(userId: tableComment.actorId, session: session)
|
||||
}
|
||||
|
||||
func tapMenu(with tableComments: tableComments?, sender: Any) {
|
||||
|
@ -509,7 +547,7 @@ extension NCActivity: NCShareCommentsCellDelegate {
|
|||
alert.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default, handler: { _ in
|
||||
guard let message = alert.textFields?.first?.text, !message.isEmpty else { return }
|
||||
|
||||
NextcloudKit.shared.updateComments(fileId: metadata.fileId, messageId: tableComments.messageId, message: message, account: self.appDelegate.account) { _, error in
|
||||
NextcloudKit.shared.updateComments(fileId: metadata.fileId, messageId: tableComments.messageId, message: message, account: metadata.account) { _, _, error in
|
||||
if error == .success {
|
||||
self.loadComments()
|
||||
} else {
|
||||
|
@ -531,7 +569,7 @@ extension NCActivity: NCShareCommentsCellDelegate {
|
|||
action: { _ in
|
||||
guard let metadata = self.metadata, let tableComments = tableComments else { return }
|
||||
|
||||
NextcloudKit.shared.deleteComments(fileId: metadata.fileId, messageId: tableComments.messageId, account: metadata.account) { _, error in
|
||||
NextcloudKit.shared.deleteComments(fileId: metadata.fileId, messageId: tableComments.messageId, account: metadata.account) { _, _, error in
|
||||
if error == .success {
|
||||
self.loadComments()
|
||||
} else {
|
||||
|
|
|
@ -29,12 +29,13 @@ class NCActivityCommentView: UIView, UITextFieldDelegate {
|
|||
|
||||
var completionHandler: ((String?) -> Void)?
|
||||
|
||||
func setup(urlBase: NCUserBaseUrl, account: tableAccount, completionHandler: @escaping (String?) -> Void) {
|
||||
func setup(account: String, completionHandler: @escaping (String?) -> Void) {
|
||||
let session = NCSession.shared.getSession(account: account)
|
||||
self.completionHandler = completionHandler
|
||||
newCommentField.placeholder = NSLocalizedString("_new_comment_", comment: "")
|
||||
newCommentField.delegate = self
|
||||
|
||||
let fileName = urlBase.userBaseUrl + "-" + urlBase.user + ".png"
|
||||
let fileName = NCSession.shared.getFileName(urlBase: session.urlBase, user: session.user)
|
||||
let fileNameLocalPath = NCUtilityFileSystem().directoryUserData + "/" + fileName
|
||||
if let image = UIImage(contentsOfFile: fileNameLocalPath) {
|
||||
imageItem.image = image
|
||||
|
|
|
@ -22,10 +22,11 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import NextcloudKit
|
||||
import FloatingPanel
|
||||
import JGProgressHUD
|
||||
import Queuer
|
||||
import Alamofire
|
||||
|
||||
class NCActivityCollectionViewCell: UICollectionViewCell {
|
||||
@IBOutlet weak var imageView: UIImageView!
|
||||
|
@ -44,14 +45,15 @@ class NCActivityTableViewCell: UITableViewCell, NCCellProtocol {
|
|||
@IBOutlet weak var subject: UILabel!
|
||||
@IBOutlet weak var subjectLeadingConstraint: NSLayoutConstraint!
|
||||
|
||||
private let appDelegate = (UIApplication.shared.delegate as? AppDelegate)!
|
||||
private var user: String = ""
|
||||
private var index = IndexPath()
|
||||
|
||||
var idActivity: Int = 0
|
||||
var activityPreviews: [tableActivityPreview] = []
|
||||
var didSelectItemEnable: Bool = true
|
||||
var viewController = UIViewController()
|
||||
var viewController = NCActivity()
|
||||
var account: String!
|
||||
|
||||
let utility = NCUtility()
|
||||
|
||||
var indexPath: IndexPath {
|
||||
|
@ -75,7 +77,7 @@ class NCActivityTableViewCell: UITableViewCell, NCCellProtocol {
|
|||
|
||||
@objc func tapAvatarImage() {
|
||||
guard let fileUser = fileUser else { return }
|
||||
viewController.showProfileMenu(userId: fileUser)
|
||||
viewController.showProfileMenu(userId: fileUser, session: NCSession.shared.getSession(account: account))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,9 +102,9 @@ extension NCActivityTableViewCell: UICollectionViewDelegate {
|
|||
}
|
||||
if (responder as? UIViewController)!.navigationController != nil {
|
||||
if let viewController = UIStoryboard(name: "NCTrash", bundle: nil).instantiateInitialViewController() as? NCTrash {
|
||||
if let result = NCManageDatabase.shared.getTrashItem(fileId: String(activityPreview.fileId), account: activityPreview.account) {
|
||||
viewController.blinkFileId = result.fileId
|
||||
viewController.filePath = result.filePath
|
||||
if let resultTableTrash = NCManageDatabase.shared.getResultTrashItem(fileId: String(activityPreview.fileId), account: activityPreview.account) {
|
||||
viewController.blinkFileId = resultTableTrash.fileId
|
||||
viewController.filePath = resultTableTrash.filePath
|
||||
(responder as? UIViewController)!.navigationController?.pushViewController(viewController, animated: true)
|
||||
} else {
|
||||
let error = NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: "_trash_file_not_found_")
|
||||
|
@ -117,7 +119,7 @@ extension NCActivityTableViewCell: UICollectionViewDelegate {
|
|||
guard let activitySubjectRich = NCManageDatabase.shared.getActivitySubjectRich(account: activityPreview.account, idActivity: activityPreview.idActivity, id: String(activityPreview.fileId)) else {
|
||||
return
|
||||
}
|
||||
NCActionCenter.shared.viewerFile(account: appDelegate.account, fileId: activitySubjectRich.id, viewController: viewController)
|
||||
NCActionCenter.shared.viewerFile(account: account, fileId: activitySubjectRich.id, viewController: viewController)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -133,9 +135,7 @@ extension NCActivityTableViewCell: UICollectionViewDataSource {
|
|||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||
guard let cell: NCActivityCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath) as? NCActivityCollectionViewCell else {
|
||||
return UICollectionViewCell()
|
||||
}
|
||||
let cell: NCActivityCollectionViewCell = (collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath) as? NCActivityCollectionViewCell)!
|
||||
|
||||
cell.imageView.image = nil
|
||||
cell.indexPath = indexPath
|
||||
|
@ -147,22 +147,22 @@ extension NCActivityTableViewCell: UICollectionViewDataSource {
|
|||
if activityPreview.view == "trashbin" {
|
||||
let source = activityPreview.source
|
||||
|
||||
utility.convertSVGtoPNGWriteToUserData(svgUrlString: source, width: 100, rewrite: false, account: appDelegate.account, id: idActivity) { imageNamePath, id in
|
||||
utility.convertSVGtoPNGWriteToUserData(svgUrlString: source, width: 100, rewrite: false, account: account, id: idActivity) { imageNamePath, id in
|
||||
if let imageNamePath = imageNamePath, id == self.idActivity, let image = UIImage(contentsOfFile: imageNamePath) {
|
||||
cell.imageView.image = image
|
||||
} else {
|
||||
cell.imageView.image = NCImageCache.images.file
|
||||
cell.imageView.image = NCImageCache.shared.getImageFile()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if activityPreview.isMimeTypeIcon {
|
||||
let source = activityPreview.source
|
||||
|
||||
utility.convertSVGtoPNGWriteToUserData(svgUrlString: source, width: 150, rewrite: false, account: appDelegate.account, id: idActivity) { imageNamePath, id in
|
||||
utility.convertSVGtoPNGWriteToUserData(svgUrlString: source, width: 150, rewrite: false, account: account, id: idActivity) { imageNamePath, id in
|
||||
if let imageNamePath = imageNamePath, id == self.idActivity, let image = UIImage(contentsOfFile: imageNamePath) {
|
||||
cell.imageView.image = image
|
||||
} else {
|
||||
cell.imageView.image = NCImageCache.images.file
|
||||
cell.imageView.image = NCImageCache.shared.getImageFile()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -178,7 +178,7 @@ extension NCActivityTableViewCell: UICollectionViewDataSource {
|
|||
cell.fileId = fileId
|
||||
if !FileManager.default.fileExists(atPath: fileNamePath) {
|
||||
if NCNetworking.shared.downloadThumbnailActivityQueue.operations.filter({ ($0 as? NCOperationDownloadThumbnailActivity)?.fileId == fileId }).isEmpty {
|
||||
NCNetworking.shared.downloadThumbnailActivityQueue.addOperation(NCOperationDownloadThumbnailActivity(fileId: fileId, fileNamePreviewLocalPath: fileNamePath, account: appDelegate.account, cell: cell, collectionView: collectionView))
|
||||
NCNetworking.shared.downloadThumbnailActivityQueue.addOperation(NCOperationDownloadThumbnailActivity(fileId: fileId, fileNamePreviewLocalPath: fileNamePath, account: account, collectionView: collectionView))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -203,18 +203,16 @@ extension NCActivityTableViewCell: UICollectionViewDelegateFlowLayout {
|
|||
}
|
||||
}
|
||||
|
||||
class NCOperationDownloadThumbnailActivity: ConcurrentOperation {
|
||||
var cell: NCActivityCollectionViewCell?
|
||||
class NCOperationDownloadThumbnailActivity: ConcurrentOperation, @unchecked Sendable {
|
||||
var collectionView: UICollectionView?
|
||||
var fileNamePreviewLocalPath: String
|
||||
var fileId: String
|
||||
var account: String
|
||||
|
||||
init(fileId: String, fileNamePreviewLocalPath: String, account: String, cell: NCActivityCollectionViewCell?, collectionView: UICollectionView?) {
|
||||
init(fileId: String, fileNamePreviewLocalPath: String, account: String, collectionView: UICollectionView?) {
|
||||
self.fileNamePreviewLocalPath = fileNamePreviewLocalPath
|
||||
self.fileId = fileId
|
||||
self.account = account
|
||||
self.cell = cell
|
||||
self.collectionView = collectionView
|
||||
}
|
||||
|
||||
|
@ -222,23 +220,19 @@ class NCOperationDownloadThumbnailActivity: ConcurrentOperation {
|
|||
guard !isCancelled else { return self.finish() }
|
||||
|
||||
NextcloudKit.shared.downloadPreview(fileId: fileId,
|
||||
fileNamePreviewLocalPath: fileNamePreviewLocalPath,
|
||||
account: account,
|
||||
options: NKRequestOptions(queue: NextcloudKit.shared.nkCommonInstance.backgroundQueue)) { _, imagePreview, _, _, _, error in
|
||||
if error == .success, let imagePreview = imagePreview {
|
||||
DispatchQueue.main.async {
|
||||
if self.fileId == self.cell?.fileId, let imageView = self.cell?.imageView {
|
||||
UIView.transition(with: imageView,
|
||||
account: account) { _, _, _, _, responseData, error in
|
||||
if error == .success, let data = responseData?.data, let collectionView = self.collectionView {
|
||||
for case let cell as NCActivityCollectionViewCell in collectionView.visibleCells {
|
||||
if self.fileId == cell.fileId {
|
||||
UIView.transition(with: cell.imageView,
|
||||
duration: 0.75,
|
||||
options: .transitionCrossDissolve,
|
||||
animations: { imageView.image = imagePreview },
|
||||
animations: { cell.imageView.image = UIImage(data: data) },
|
||||
completion: nil)
|
||||
} else {
|
||||
self.collectionView?.reloadData()
|
||||
}
|
||||
}
|
||||
}
|
||||
self.finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,20 +32,11 @@ import EasyTipView
|
|||
import SwiftUI
|
||||
|
||||
@UIApplicationMain
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, NCUserBaseUrl {
|
||||
|
||||
var account: String = ""
|
||||
var urlBase: String = ""
|
||||
var user: String = ""
|
||||
var userId: String = ""
|
||||
var password: String = ""
|
||||
|
||||
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
|
||||
var tipView: EasyTipView?
|
||||
var backgroundSessionCompletionHandler: (() -> Void)?
|
||||
var activeLogin: NCLogin?
|
||||
var activeLoginWeb: NCLoginProvider?
|
||||
var timerErrorNetworking: Timer?
|
||||
var timerErrorNetworkingDisabled: Bool = false
|
||||
var taskAutoUploadDate: Date = Date()
|
||||
var isUiTestingEnabled: Bool {
|
||||
return ProcessInfo.processInfo.arguments.contains("UI_TESTING")
|
||||
|
@ -58,15 +49,15 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|||
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||
if isUiTestingEnabled {
|
||||
deleteAllAccounts()
|
||||
NCAccount().deleteAllAccounts()
|
||||
}
|
||||
let utilityFileSystem = NCUtilityFileSystem()
|
||||
let utility = NCUtility()
|
||||
var levelLog = 0
|
||||
let versionNextcloudiOS = String(format: NCBrandOptions.shared.textCopyrightNextcloudiOS, utility.getVersionApp())
|
||||
|
||||
NCSettingsBundleHelper.checkAndExecuteSettings(delay: 0)
|
||||
|
||||
let versionNextcloudiOS = String(format: NCBrandOptions.shared.textCopyrightNextcloudiOS, utility.getVersionApp())
|
||||
|
||||
UserDefaults.standard.register(defaults: ["UserAgent": userAgent])
|
||||
if !NCKeychain().disableCrashservice, !NCBrandOptions.shared.disable_crash_service {
|
||||
FirebaseApp.configure()
|
||||
|
@ -76,14 +67,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|||
utilityFileSystem.emptyTemporaryDirectory()
|
||||
utilityFileSystem.clearCacheDirectory("com.limit-point.LivePhoto")
|
||||
|
||||
// Activated singleton
|
||||
_ = NCActionCenter.shared
|
||||
_ = NCNetworking.shared
|
||||
// Create users colors
|
||||
NCBrandColor.shared.createUserColors()
|
||||
|
||||
NextcloudKit.shared.setup(delegate: NCNetworking.shared)
|
||||
NextcloudKit.shared.setup(userAgent: userAgent)
|
||||
|
||||
var levelLog = 0
|
||||
NextcloudKit.shared.nkCommonInstance.pathLog = utilityFileSystem.directoryGroup
|
||||
|
||||
if NCBrandOptions.shared.disable_log {
|
||||
|
@ -96,37 +83,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|||
NextcloudKit.shared.nkCommonInstance.writeLog("[INFO] Start session with level \(levelLog) " + versionNextcloudiOS)
|
||||
}
|
||||
|
||||
if let activeAccount = NCManageDatabase.shared.getActiveAccount() {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[INFO] Account active \(activeAccount.account)")
|
||||
|
||||
if NCKeychain().getPassword(account: activeAccount.account).isEmpty {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] PASSWORD NOT FOUND for \(activeAccount.account)")
|
||||
}
|
||||
|
||||
account = activeAccount.account
|
||||
urlBase = activeAccount.urlBase
|
||||
user = activeAccount.user
|
||||
userId = activeAccount.userId
|
||||
password = NCKeychain().getPassword(account: account)
|
||||
|
||||
NextcloudKit.shared.setup(account: account, user: user, userId: userId, password: password, urlBase: urlBase)
|
||||
NCManageDatabase.shared.setCapabilities(account: account)
|
||||
|
||||
NCBrandColor.shared.settingThemingColor(account: activeAccount.account)
|
||||
DispatchQueue.global().async {
|
||||
NCImageCache.shared.createMediaCache(account: self.account, withCacheSize: true)
|
||||
}
|
||||
} else {
|
||||
NCKeychain().removeAll()
|
||||
if let bundleID = Bundle.main.bundleIdentifier {
|
||||
UserDefaults.standard.removePersistentDomain(forName: bundleID)
|
||||
}
|
||||
}
|
||||
|
||||
NCBrandColor.shared.createUserColors()
|
||||
NCImageCache.shared.createImagesCache()
|
||||
|
||||
// Push Notification & display notification
|
||||
/// Push Notification & display notification
|
||||
UNUserNotificationCenter.current().getNotificationSettings { settings in
|
||||
self.notificationSettings = settings
|
||||
}
|
||||
|
@ -140,7 +97,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|||
review.showStoreReview()
|
||||
}
|
||||
|
||||
// Background task register
|
||||
/// Background task register
|
||||
BGTaskScheduler.shared.register(forTaskWithIdentifier: NCGlobal.shared.refreshTask, using: nil) { task in
|
||||
self.handleAppRefresh(task)
|
||||
}
|
||||
|
@ -148,12 +105,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|||
self.handleProcessingTask(task)
|
||||
}
|
||||
|
||||
FileNameValidator.shared.setup(
|
||||
forbiddenFileNames: NCGlobal.shared.capabilityForbiddenFileNames,
|
||||
forbiddenFileNameBasenames: NCGlobal.shared.capabilityForbiddenFileNameBasenames,
|
||||
forbiddenFileNameCharacters: NCGlobal.shared.capabilityForbiddenFileNameCharacters,
|
||||
forbiddenFileNameExtensions: NCGlobal.shared.capabilityForbiddenFileNameExtensions
|
||||
)
|
||||
/// Activation singleton
|
||||
_ = NCActionCenter.shared
|
||||
_ = NCNetworkingProcess.shared
|
||||
|
||||
return true
|
||||
}
|
||||
|
@ -235,39 +189,46 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|||
|
||||
func handleAppRefreshProcessingTask(taskText: String, completion: @escaping () -> Void = {}) {
|
||||
Task {
|
||||
var itemsAutoUpload = 0
|
||||
var numAutoUpload = 0
|
||||
guard let account = NCManageDatabase.shared.getActiveTableAccount()?.account else {
|
||||
return
|
||||
}
|
||||
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[DEBUG] \(taskText) start handle")
|
||||
|
||||
// Test every > 1 min
|
||||
if Date() > self.taskAutoUploadDate.addingTimeInterval(60) {
|
||||
self.taskAutoUploadDate = Date()
|
||||
itemsAutoUpload = await NCAutoUpload.shared.initAutoUpload()
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[DEBUG] \(taskText) auto upload with \(itemsAutoUpload) uploads")
|
||||
numAutoUpload = await NCAutoUpload.shared.initAutoUpload(account: account)
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[DEBUG] \(taskText) auto upload with \(numAutoUpload) uploads")
|
||||
} else {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[DEBUG] \(taskText) disabled auto upload")
|
||||
}
|
||||
|
||||
let results = await NCNetworkingProcess.shared.start(scene: nil)
|
||||
let results = await NCNetworkingProcess.shared.refreshProcessingTask()
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[DEBUG] \(taskText) networking process with download: \(results.counterDownloading) upload: \(results.counterUploading)")
|
||||
|
||||
if taskText == "ProcessingTask",
|
||||
itemsAutoUpload == 0,
|
||||
numAutoUpload == 0,
|
||||
results.counterDownloading == 0,
|
||||
results.counterUploading == 0,
|
||||
let directories = NCManageDatabase.shared.getTablesDirectory(predicate: NSPredicate(format: "account == %@ AND offline == true", self.account), sorted: "offlineDate", ascending: true) {
|
||||
let directories = NCManageDatabase.shared.getTablesDirectory(predicate: NSPredicate(format: "account == %@ AND offline == true", account), sorted: "offlineDate", ascending: true) {
|
||||
for directory: tableDirectory in directories {
|
||||
// test only 3 time for day (every 8 h.)
|
||||
if let offlineDate = directory.offlineDate, offlineDate.addingTimeInterval(28800) > Date() {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[DEBUG] \(taskText) skip synchronization for \(directory.serverUrl) in date \(offlineDate)")
|
||||
continue
|
||||
}
|
||||
let results = await NCNetworking.shared.synchronization(account: self.account, serverUrl: directory.serverUrl, add: false)
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[DEBUG] \(taskText) end synchronization for \(directory.serverUrl), errorCode: \(results.errorCode), item: \(results.items)")
|
||||
let results = await NCNetworking.shared.synchronization(account: account, serverUrl: directory.serverUrl, add: false)
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[DEBUG] \(taskText) end synchronization for \(directory.serverUrl), errorCode: \(results.errorCode), item: \(results.num)")
|
||||
}
|
||||
}
|
||||
|
||||
let counter = NCManageDatabase.shared.getResultsMetadatas(predicate: NSPredicate(format: "account == %@ AND (session == %@ || session == %@) AND status != %d", self.account, NCNetworking.shared.sessionDownloadBackground, NCNetworking.shared.sessionUploadBackground, NCGlobal.shared.metadataStatusNormal))?.count ?? 0
|
||||
let counter = NCManageDatabase.shared.getResultsMetadatas(predicate: NSPredicate(format: "account == %@ AND (session == %@ || session == %@) AND status != %d",
|
||||
account,
|
||||
NCNetworking.shared.sessionDownloadBackground,
|
||||
NCNetworking.shared.sessionUploadBackground,
|
||||
NCGlobal.shared.metadataStatusNormal))?.count ?? 0
|
||||
UIApplication.shared.applicationIconBadgeNumber = counter
|
||||
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[DEBUG] \(taskText) completion handle")
|
||||
|
@ -315,28 +276,28 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|||
|
||||
func nextcloudPushNotificationAction(data: [String: AnyObject]) {
|
||||
guard let data = NCApplicationHandle().nextcloudPushNotificationAction(data: data) else { return }
|
||||
var findAccount: Bool = false
|
||||
var findAccount: String?
|
||||
|
||||
if let accountPush = data["account"] as? String {
|
||||
if accountPush == self.account {
|
||||
findAccount = true
|
||||
} else {
|
||||
let accounts = NCManageDatabase.shared.getAllAccount()
|
||||
for account in accounts {
|
||||
if account.account == accountPush {
|
||||
self.changeAccount(account.account, userProfile: nil) {
|
||||
findAccount = true
|
||||
for tableAccount in NCManageDatabase.shared.getAllTableAccount() {
|
||||
if tableAccount.account == accountPush {
|
||||
for controller in SceneManager.shared.getControllers() {
|
||||
if controller.account == accountPush {
|
||||
NCAccount().changeAccount(tableAccount.account, userProfile: nil, controller: controller) {
|
||||
findAccount = tableAccount.account
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if findAccount, let viewController = UIStoryboard(name: "NCNotification", bundle: nil).instantiateInitialViewController() as? NCNotification {
|
||||
if let account = findAccount, let viewController = UIStoryboard(name: "NCNotification", bundle: nil).instantiateInitialViewController() as? NCNotification {
|
||||
viewController.session = NCSession.shared.getSession(account: account)
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
||||
let navigationController = UINavigationController(rootViewController: viewController)
|
||||
navigationController.modalPresentationStyle = .fullScreen
|
||||
UIApplication.shared.firstWindow?.rootViewController?.present(navigationController, animated: true)
|
||||
}
|
||||
} else if !findAccount {
|
||||
} else {
|
||||
let message = NSLocalizedString("_the_account_", comment: "") + " " + accountPush + " " + NSLocalizedString("_does_not_exist_", comment: "")
|
||||
let alertController = UIAlertController(title: NSLocalizedString("_info_", comment: ""), message: message, preferredStyle: .alert)
|
||||
alertController.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default, handler: { _ in }))
|
||||
|
@ -347,7 +308,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|||
|
||||
// MARK: - Login
|
||||
|
||||
func openLogin(selector: Int, openLoginWeb: Bool, windowForRootViewController: UIWindow? = nil) {
|
||||
func openLogin(selector: Int) {
|
||||
UIApplication.shared.allSceneSessionDestructionExceptFirst()
|
||||
|
||||
func showLoginViewController(_ viewController: UIViewController?) {
|
||||
guard let viewController else { return }
|
||||
let navigationController = NCLoginNavigationController(rootViewController: viewController)
|
||||
|
@ -358,20 +321,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|||
navigationController.navigationBar.barTintColor = NCBrandColor.shared.customer
|
||||
navigationController.navigationBar.isTranslucent = false
|
||||
|
||||
if let window = windowForRootViewController {
|
||||
window.rootViewController = navigationController
|
||||
window.makeKeyAndVisible()
|
||||
} else {
|
||||
UIApplication.shared.allSceneSessionDestructionExceptFirst()
|
||||
|
||||
if let rootVC = UIApplication.shared.firstWindow?.rootViewController {
|
||||
if let presentedVC = rootVC.presentedViewController, !(presentedVC is NCLoginNavigationController) {
|
||||
presentedVC.dismiss(animated: false) {
|
||||
rootVC.present(navigationController, animated: true)
|
||||
}
|
||||
} else {
|
||||
rootVC.present(navigationController, animated: true)
|
||||
if let controller = UIApplication.shared.firstWindow?.rootViewController {
|
||||
if let presentedVC = controller.presentedViewController, !(presentedVC is NCLoginNavigationController) {
|
||||
presentedVC.dismiss(animated: false) {
|
||||
controller.present(navigationController, animated: true)
|
||||
}
|
||||
} else {
|
||||
controller.present(navigationController, animated: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -379,14 +335,16 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|||
// Nextcloud standard login
|
||||
if selector == NCGlobal.shared.introSignup {
|
||||
if activeLogin?.view.window == nil {
|
||||
activeLogin = UIStoryboard(name: "NCLogin", bundle: nil).instantiateViewController(withIdentifier: "NCLogin") as? NCLogin
|
||||
if selector == NCGlobal.shared.introSignup {
|
||||
activeLogin?.urlBase = NCBrandOptions.shared.linkloginPreferredProviders
|
||||
let web = UIStoryboard(name: "NCLogin", bundle: nil).instantiateViewController(withIdentifier: "NCLoginProvider") as? NCLoginProvider
|
||||
web?.urlBase = NCBrandOptions.shared.linkloginPreferredProviders
|
||||
showLoginViewController(web)
|
||||
} else {
|
||||
activeLogin?.urlBase = self.urlBase
|
||||
activeLogin = UIStoryboard(name: "NCLogin", bundle: nil).instantiateViewController(withIdentifier: "NCLogin") as? NCLogin
|
||||
if let controller = UIApplication.shared.firstWindow?.rootViewController as? NCMainTabBarController, !controller.account.isEmpty {
|
||||
let session = NCSession.shared.getSession(account: controller.account)
|
||||
activeLogin?.urlBase = session.urlBase
|
||||
}
|
||||
showLoginViewController(activeLogin)
|
||||
}
|
||||
}
|
||||
|
@ -399,35 +357,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|||
}
|
||||
}
|
||||
|
||||
// MARK: - Error Networking
|
||||
|
||||
func startTimerErrorNetworking(scene: UIScene) {
|
||||
timerErrorNetworkingDisabled = false
|
||||
timerErrorNetworking = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(checkErrorNetworking(_:)), userInfo: nil, repeats: true)
|
||||
}
|
||||
|
||||
@objc private func checkErrorNetworking(_ notification: NSNotification) {
|
||||
guard !self.timerErrorNetworkingDisabled,
|
||||
!account.isEmpty,
|
||||
NCKeychain().getPassword(account: account).isEmpty else { return }
|
||||
|
||||
let description = String.localizedStringWithFormat(NSLocalizedString("_error_check_remote_user_", comment: ""))
|
||||
let error = NKError(errorCode: NCKeychain().getPassword(account: account).isEmpty ? NCGlobal.shared.errorUnauthorized997 : NCGlobal.shared.errorInternalServerError, errorDescription: description)
|
||||
NCContentPresenter().showError(error: error, priority: .max)
|
||||
|
||||
deleteAccount(account)
|
||||
|
||||
let accounts = NCManageDatabase.shared.getAccounts()
|
||||
|
||||
if accounts?.count ?? 0 > 0, let newAccount = accounts?.first {
|
||||
changeAccount(newAccount, userProfile: nil) { }
|
||||
} else {
|
||||
openLogin(selector: NCGlobal.shared.introLogin, openLoginWeb: false)
|
||||
}
|
||||
}
|
||||
// MARK: -
|
||||
|
||||
func trustCertificateError(host: String) {
|
||||
guard let currentHost = URL(string: self.urlBase)?.host,
|
||||
guard let activeTableAccount = NCManageDatabase.shared.getActiveTableAccount(),
|
||||
let currentHost = URL(string: activeTableAccount.urlBase)?.host,
|
||||
let pushNotificationServerProxyHost = URL(string: NCBrandOptions.shared.pushNotificationServerProxy)?.host,
|
||||
host != pushNotificationServerProxyHost,
|
||||
host == currentHost
|
||||
|
@ -459,136 +393,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|||
UIApplication.shared.firstWindow?.rootViewController?.present(alertController, animated: true)
|
||||
}
|
||||
|
||||
// MARK: - Account
|
||||
|
||||
func createAccount(urlBase: String,
|
||||
user: String,
|
||||
password: String,
|
||||
completion: @escaping (_ error: NKError) -> Void) {
|
||||
var urlBase = urlBase
|
||||
if urlBase.last == "/" { urlBase = String(urlBase.dropLast()) }
|
||||
let account: String = "\(user) \(urlBase)"
|
||||
|
||||
NextcloudKit.shared.setup(account: account, user: user, userId: user, password: password, urlBase: urlBase)
|
||||
NextcloudKit.shared.getUserProfile(account: account) { 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)
|
||||
NCKeychain().setClientCertificate(account: account, p12Data: NCNetworking.shared.p12Data, p12Password: NCNetworking.shared.p12Password)
|
||||
self.changeAccount(account, userProfile: userProfile) {
|
||||
completion(error)
|
||||
}
|
||||
} else {
|
||||
NextcloudKit.shared.setup(account: self.account, user: self.user, userId: self.userId, password: self.password, urlBase: self.urlBase)
|
||||
let alertController = UIAlertController(title: NSLocalizedString("_error_", comment: ""), message: error.errorDescription, preferredStyle: .alert)
|
||||
alertController.addAction(UIAlertAction(title: NSLocalizedString("_ok_", comment: ""), style: .default, handler: { _ in }))
|
||||
UIApplication.shared.firstWindow?.rootViewController?.present(alertController, animated: true)
|
||||
completion(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func changeAccount(_ account: String,
|
||||
userProfile: NKUserProfile?,
|
||||
completion: () -> Void) {
|
||||
guard let tableAccount = NCManageDatabase.shared.setAccountActive(account) else {
|
||||
return completion()
|
||||
}
|
||||
|
||||
NCNetworking.shared.cancelAllQueue()
|
||||
NCNetworking.shared.cancelDataTask()
|
||||
NCNetworking.shared.cancelDownloadTasks()
|
||||
NCNetworking.shared.cancelUploadTasks()
|
||||
|
||||
if account != self.account {
|
||||
DispatchQueue.global().async {
|
||||
if NCManageDatabase.shared.getAccounts()?.count == 1 {
|
||||
NCImageCache.shared.createMediaCache(account: account, withCacheSize: true)
|
||||
} else {
|
||||
NCImageCache.shared.createMediaCache(account: account, withCacheSize: false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.account = tableAccount.account
|
||||
self.urlBase = tableAccount.urlBase
|
||||
self.user = tableAccount.user
|
||||
self.userId = tableAccount.userId
|
||||
self.password = NCKeychain().getPassword(account: tableAccount.account)
|
||||
|
||||
NextcloudKit.shared.setup(account: account, user: user, userId: userId, password: password, urlBase: urlBase)
|
||||
NCManageDatabase.shared.setCapabilities(account: account)
|
||||
|
||||
if let userProfile {
|
||||
NCManageDatabase.shared.setAccountUserProfile(account: account, userProfile: userProfile)
|
||||
}
|
||||
|
||||
NCPushNotification.shared.pushNotification()
|
||||
NCService().startRequestServicesServer(account: self.account, user: self.user, userId: self.userId)
|
||||
|
||||
NCAutoUpload.shared.initAutoUpload(viewController: nil) { items in
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[INFO] Initialize Auto upload with \(items) uploads")
|
||||
}
|
||||
|
||||
FileNameValidator.shared.setup(
|
||||
forbiddenFileNames: NCGlobal.shared.capabilityForbiddenFileNames,
|
||||
forbiddenFileNameBasenames: NCGlobal.shared.capabilityForbiddenFileNameBasenames,
|
||||
forbiddenFileNameCharacters: NCGlobal.shared.capabilityForbiddenFileNameCharacters,
|
||||
forbiddenFileNameExtensions: NCGlobal.shared.capabilityForbiddenFileNameExtensions
|
||||
)
|
||||
|
||||
NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterChangeUser)
|
||||
completion()
|
||||
}
|
||||
|
||||
func deleteAccount(_ account: String) {
|
||||
UIApplication.shared.allSceneSessionDestructionExceptFirst()
|
||||
|
||||
if let account = NCManageDatabase.shared.getAccount(predicate: NSPredicate(format: "account == %@", account)) {
|
||||
NCPushNotification.shared.unsubscribingNextcloudServerPushNotification(account: account.account, urlBase: account.urlBase, user: account.user, withSubscribing: false)
|
||||
}
|
||||
|
||||
let results = NCManageDatabase.shared.getTableLocalFiles(predicate: NSPredicate(format: "account == %@", account), sorted: "ocId", ascending: false)
|
||||
let utilityFileSystem = NCUtilityFileSystem()
|
||||
for result in results {
|
||||
utilityFileSystem.removeFile(atPath: utilityFileSystem.getDirectoryProviderStorageOcId(result.ocId))
|
||||
}
|
||||
NCManageDatabase.shared.clearDatabase(account: account, removeAccount: true)
|
||||
|
||||
NCKeychain().clearAllKeysEndToEnd(account: account)
|
||||
NCKeychain().clearAllKeysPushNotification(account: account)
|
||||
NCKeychain().setPassword(account: account, password: nil)
|
||||
|
||||
self.account = ""
|
||||
self.urlBase = ""
|
||||
self.user = ""
|
||||
self.userId = ""
|
||||
self.password = ""
|
||||
}
|
||||
|
||||
func deleteAllAccounts() {
|
||||
let accounts = NCManageDatabase.shared.getAccounts()
|
||||
accounts?.forEach({ account in
|
||||
deleteAccount(account)
|
||||
})
|
||||
}
|
||||
|
||||
func updateShareAccounts() -> Error? {
|
||||
guard let dirGroupApps = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: NCBrandOptions.shared.capabilitiesGroupApps) else { return nil }
|
||||
let tableAccount = NCManageDatabase.shared.getAllAccount()
|
||||
var accounts = [NKShareAccounts.DataAccounts]()
|
||||
|
||||
for account in tableAccount {
|
||||
let name = account.alias.isEmpty ? account.displayName : account.alias
|
||||
let userBaseUrl = account.user + "-" + (URL(string: account.urlBase)?.host ?? "")
|
||||
let avatarFileName = userBaseUrl + "-\(account.user).png"
|
||||
let pathAvatarFileName = NCUtilityFileSystem().directoryUserData + "/" + avatarFileName
|
||||
let image = UIImage(contentsOfFile: pathAvatarFileName)
|
||||
accounts.append(NKShareAccounts.DataAccounts(withUrl: account.urlBase, user: account.user, name: name, image: image))
|
||||
}
|
||||
return NKShareAccounts().putShareAccounts(at: dirGroupApps, app: NCGlobal.shared.appScheme, dataAccounts: accounts)
|
||||
}
|
||||
|
||||
// MARK: - Reset Application
|
||||
|
||||
func resetApplication() {
|
||||
|
@ -596,8 +400,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|||
|
||||
NCNetworking.shared.cancelAllTask()
|
||||
|
||||
URLCache.shared.memoryCapacity = 0
|
||||
URLCache.shared.diskCapacity = 0
|
||||
URLCache.shared.removeAllCachedResponses()
|
||||
|
||||
utilityFileSystem.removeGroupDirectoryProviderStorage()
|
||||
utilityFileSystem.removeGroupApplicationSupport()
|
||||
|
@ -605,6 +408,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|||
utilityFileSystem.removeTemporaryDirectory()
|
||||
|
||||
NCKeychain().removeAll()
|
||||
NCNetworking.shared.removeAllKeyUserDefaultsData(account: nil)
|
||||
|
||||
exit(0)
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ struct NCAssistantCreateNewTask: View {
|
|||
}
|
||||
|
||||
#Preview {
|
||||
let model = NCAssistantTask()
|
||||
let model = NCAssistantTask(controller: nil)
|
||||
|
||||
return NCAssistantCreateNewTask()
|
||||
.environmentObject(model)
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import NextcloudKit
|
||||
import SwiftUI
|
||||
|
||||
|
@ -17,12 +18,16 @@ class NCAssistantTask: ObservableObject {
|
|||
@Published var selectedTask: NKTextProcessingTask?
|
||||
@Published var hasError: Bool = false
|
||||
@Published var isLoading: Bool = false
|
||||
@Published var controller: NCMainTabBarController?
|
||||
|
||||
private var tasks: [NKTextProcessingTask] = []
|
||||
private let excludedTypeIds = ["OCA\\ContextChat\\TextProcessing\\ContextChatTaskType"]
|
||||
private let appDelegate = (UIApplication.shared.delegate as? AppDelegate)!
|
||||
private var session: NCSession.Session {
|
||||
NCSession.shared.getSession(controller: controller)
|
||||
}
|
||||
|
||||
init() {
|
||||
init(controller: NCMainTabBarController?) {
|
||||
self.controller = controller
|
||||
load()
|
||||
}
|
||||
|
||||
|
@ -50,7 +55,7 @@ class NCAssistantTask: ObservableObject {
|
|||
guard let id = task.id else { return }
|
||||
isLoading = true
|
||||
|
||||
NextcloudKit.shared.textProcessingGetTask(taskId: id, account: appDelegate.account) { _, task, _, error in
|
||||
NextcloudKit.shared.textProcessingGetTask(taskId: id, account: session.account) { _, task, _, error in
|
||||
self.isLoading = false
|
||||
|
||||
if error != .success {
|
||||
|
@ -65,7 +70,7 @@ class NCAssistantTask: ObservableObject {
|
|||
func scheduleTask(input: String) {
|
||||
isLoading = true
|
||||
|
||||
NextcloudKit.shared.textProcessingSchedule(input: input, typeId: selectedType?.id ?? "", identifier: "assistant", account: appDelegate.account) { _, task, _, error in
|
||||
NextcloudKit.shared.textProcessingSchedule(input: input, typeId: selectedType?.id ?? "", identifier: "assistant", account: session.account) { _, task, _, error in
|
||||
self.isLoading = false
|
||||
|
||||
if error != .success {
|
||||
|
@ -86,7 +91,7 @@ class NCAssistantTask: ObservableObject {
|
|||
guard let id = task.id else { return }
|
||||
isLoading = true
|
||||
|
||||
NextcloudKit.shared.textProcessingDeleteTask(taskId: id, account: appDelegate.account) { _, task, _, error in
|
||||
NextcloudKit.shared.textProcessingDeleteTask(taskId: id, account: session.account) { _, task, _, error in
|
||||
self.isLoading = false
|
||||
|
||||
if error != .success {
|
||||
|
@ -105,7 +110,7 @@ class NCAssistantTask: ObservableObject {
|
|||
private func loadAllTypes() {
|
||||
isLoading = true
|
||||
|
||||
NextcloudKit.shared.textProcessingGetTypes(account: appDelegate.account) { _, types, _, error in
|
||||
NextcloudKit.shared.textProcessingGetTypes(account: session.account) { _, types, _, error in
|
||||
self.isLoading = false
|
||||
|
||||
if error != .success {
|
||||
|
@ -130,7 +135,7 @@ class NCAssistantTask: ObservableObject {
|
|||
private func loadAllTasks(appId: String = "assistant") {
|
||||
isLoading = true
|
||||
|
||||
NextcloudKit.shared.textProcessingTaskList(appId: appId, account: appDelegate.account) { _, tasks, _, error in
|
||||
NextcloudKit.shared.textProcessingTaskList(appId: appId, account: session.account) { _, tasks, _, error in
|
||||
self.isLoading = false
|
||||
|
||||
if error != .success {
|
||||
|
|
|
@ -81,7 +81,7 @@ struct NCAssistant: View {
|
|||
}
|
||||
|
||||
#Preview {
|
||||
let model = NCAssistantTask()
|
||||
let model = NCAssistantTask(controller: nil)
|
||||
|
||||
return NCAssistant()
|
||||
.environmentObject(model)
|
||||
|
@ -125,7 +125,7 @@ struct TypeButton: View {
|
|||
.padding(.vertical, 7)
|
||||
.foregroundStyle(model.selectedType?.id == taskType?.id ? .white : .primary)
|
||||
.if(model.selectedType?.id == taskType?.id) { view in
|
||||
view.background(Color(NCBrandColor.shared.brandElement))
|
||||
view.background(Color(NCBrandColor.shared.getElement(account: model.controller?.account)))
|
||||
}
|
||||
.if(model.selectedType?.id != taskType?.id) { view in
|
||||
view.background(.ultraThinMaterial)
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
import SwiftUI
|
||||
|
||||
struct NCAssistantEmptyView: View {
|
||||
@EnvironmentObject var model: NCAssistantTask
|
||||
let titleKey, subtitleKey: String
|
||||
|
||||
var body: some View {
|
||||
|
@ -17,7 +18,7 @@ struct NCAssistantEmptyView: View {
|
|||
.renderingMode(.template)
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fit)
|
||||
.foregroundStyle(Color(NCBrandColor.shared.brandElement))
|
||||
.foregroundStyle(Color(NCBrandColor.shared.getElement(account: model.controller?.account)))
|
||||
.font(Font.system(.body).weight(.light))
|
||||
.frame(height: 100)
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ struct NCAssistantTaskDetail: View {
|
|||
}
|
||||
|
||||
#Preview {
|
||||
let model = NCAssistantTask()
|
||||
let model = NCAssistantTask(controller: nil)
|
||||
|
||||
return NCAssistantTaskDetail(task: NKTextProcessingTask(id: 1, type: "OCP\\TextProcessing\\FreePromptTaskType", status: 1, userId: "christine", appId: "assistant", input: "", output: "", identifier: "", completionExpectedAt: 1712666412))
|
||||
.environmentObject(model)
|
||||
|
|
|
@ -27,20 +27,22 @@
|
|||
import UIKit
|
||||
import AVFoundation
|
||||
import QuartzCore
|
||||
import NextcloudKit
|
||||
|
||||
class NCAudioRecorderViewController: UIViewController, NCAudioRecorderDelegate {
|
||||
|
||||
var recording: NCAudioRecorder!
|
||||
var startDate: Date = Date()
|
||||
var fileName: String = ""
|
||||
var serverUrl = ""
|
||||
let appDelegate = (UIApplication.shared.delegate as? AppDelegate)!
|
||||
|
||||
@IBOutlet weak var contentContainerView: UIView!
|
||||
@IBOutlet weak var durationLabel: UILabel!
|
||||
@IBOutlet weak var startStopLabel: UILabel!
|
||||
@IBOutlet weak var voiceRecordHUD: VoiceRecordHUD!
|
||||
|
||||
var recording: NCAudioRecorder!
|
||||
var startDate: Date = Date()
|
||||
var fileName: String = ""
|
||||
var controller: NCMainTabBarController!
|
||||
var session: NCSession.Session {
|
||||
NCSession.shared.getSession(controller: controller)
|
||||
}
|
||||
|
||||
// MARK: - View Life Cycle
|
||||
|
||||
override func viewDidLoad() {
|
||||
|
@ -55,7 +57,7 @@ class NCAudioRecorderViewController: UIViewController, NCAudioRecorderDelegate {
|
|||
voiceRecordHUD.fillColor = UIColor.green
|
||||
|
||||
Task {
|
||||
self.fileName = await NCNetworking.shared.createFileName(fileNameBase: NSLocalizedString("_untitled_", comment: "") + ".m4a", account: self.appDelegate.account, serverUrl: self.serverUrl)
|
||||
self.fileName = await NCNetworking.shared.createFileName(fileNameBase: NSLocalizedString("_untitled_", comment: "") + ".m4a", account: self.session.account, serverUrl: controller.currentServerUrl())
|
||||
recording = NCAudioRecorder(to: self.fileName)
|
||||
recording.delegate = self
|
||||
do {
|
||||
|
@ -97,7 +99,15 @@ class NCAudioRecorderViewController: UIViewController, NCAudioRecorderDelegate {
|
|||
|
||||
func uploadMetadata() {
|
||||
let fileNamePath = NSTemporaryDirectory() + self.fileName
|
||||
let metadata = NCManageDatabase.shared.createMetadata(account: appDelegate.account, user: appDelegate.user, userId: appDelegate.userId, fileName: fileName, fileNameView: fileName, ocId: UUID().uuidString, serverUrl: self.serverUrl, urlBase: appDelegate.urlBase, url: "", contentType: "")
|
||||
let metadata = NCManageDatabase.shared.createMetadata(fileName: fileName,
|
||||
fileNameView: fileName,
|
||||
ocId: UUID().uuidString,
|
||||
serverUrl: controller.currentServerUrl(),
|
||||
url: "",
|
||||
contentType: "",
|
||||
session: self.session,
|
||||
sceneIdentifier: self.controller?.sceneIdentifier)
|
||||
|
||||
metadata.session = NCNetworking.shared.sessionUploadBackground
|
||||
metadata.sessionSelector = NCGlobal.shared.selectorUploadFile
|
||||
metadata.status = NCGlobal.shared.metadataStatusWaitUpload
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
//
|
||||
|
||||
import UIKit
|
||||
import WebKit
|
||||
@preconcurrency import WebKit
|
||||
|
||||
@objc protocol NCBrowserWebDelegate: AnyObject {
|
||||
@objc optional func browserWebDismiss()
|
||||
|
|
|
@ -129,7 +129,7 @@ class NCColorPicker: UIViewController {
|
|||
systemIndigoButton.layer.cornerRadius = 5
|
||||
systemIndigoButton.layer.masksToBounds = true
|
||||
|
||||
defaultButton.backgroundColor = NCBrandColor.shared.brandElement
|
||||
defaultButton.backgroundColor = NCBrandColor.shared.customer
|
||||
defaultButton.layer.cornerRadius = 5
|
||||
defaultButton.layer.masksToBounds = true
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ class NCColorPicker: UIViewController {
|
|||
let serverUrl = metadata.serverUrl + "/" + metadata.fileName
|
||||
NCManageDatabase.shared.setDirectory(serverUrl: serverUrl, colorFolder: hexColor, metadata: metadata)
|
||||
self.dismiss(animated: true)
|
||||
NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterReloadDataSource)
|
||||
NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterReloadDataSource, userInfo: ["serverUrl": metadata.serverUrl, "clearDataSource": true])
|
||||
}
|
||||
self.dismiss(animated: true)
|
||||
}
|
||||
|
|
|
@ -22,10 +22,11 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import RealmSwift
|
||||
import NextcloudKit
|
||||
|
||||
class tableAccount: Object, NCUserBaseUrl {
|
||||
class tableAccount: Object {
|
||||
@objc dynamic var account = ""
|
||||
@objc dynamic var active: Bool = false
|
||||
@objc dynamic var address = ""
|
||||
|
@ -84,13 +85,16 @@ extension NCManageDatabase {
|
|||
do {
|
||||
let realm = try Realm()
|
||||
try realm.write {
|
||||
let addObject = tableAccount()
|
||||
addObject.account = account
|
||||
if let result = realm.objects(tableAccount.self).filter("account == %@", account).first {
|
||||
realm.delete(result)
|
||||
}
|
||||
let tableAccount = tableAccount()
|
||||
tableAccount.account = account
|
||||
NCKeychain().setPassword(account: account, password: password)
|
||||
addObject.urlBase = urlBase
|
||||
addObject.user = user
|
||||
addObject.userId = userId
|
||||
realm.add(addObject, update: .all)
|
||||
tableAccount.urlBase = urlBase
|
||||
tableAccount.user = user
|
||||
tableAccount.userId = userId
|
||||
realm.add(tableAccount, update: .all)
|
||||
}
|
||||
} catch let error {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Could not write to database: \(error)")
|
||||
|
@ -108,19 +112,7 @@ extension NCManageDatabase {
|
|||
}
|
||||
}
|
||||
|
||||
func deleteAccount(_ account: String) {
|
||||
do {
|
||||
let realm = try Realm()
|
||||
try realm.write {
|
||||
let result = realm.objects(tableAccount.self).filter("account == %@", account)
|
||||
realm.delete(result)
|
||||
}
|
||||
} catch let error {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Could not write to database: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
func getActiveAccount() -> tableAccount? {
|
||||
func getActiveTableAccount() -> tableAccount? {
|
||||
do {
|
||||
let realm = try Realm()
|
||||
guard let result = realm.objects(tableAccount.self).filter("active == true").first else { return nil }
|
||||
|
@ -131,6 +123,17 @@ extension NCManageDatabase {
|
|||
return nil
|
||||
}
|
||||
|
||||
func getTableAccount(account: String) -> tableAccount? {
|
||||
do {
|
||||
let realm = try Realm()
|
||||
guard let result = realm.objects(tableAccount.self).filter("account == %@", account).first else { return nil }
|
||||
return tableAccount.init(value: result)
|
||||
} catch let error as NSError {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Could not access database: \(error)")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getAccounts() -> [String]? {
|
||||
do {
|
||||
let realm = try Realm()
|
||||
|
@ -144,7 +147,7 @@ extension NCManageDatabase {
|
|||
return nil
|
||||
}
|
||||
|
||||
func getAccount(predicate: NSPredicate) -> tableAccount? {
|
||||
func getTableAccount(predicate: NSPredicate) -> tableAccount? {
|
||||
do {
|
||||
let realm = try Realm()
|
||||
guard let result = realm.objects(tableAccount.self).filter(predicate).first else { return nil }
|
||||
|
@ -155,7 +158,7 @@ extension NCManageDatabase {
|
|||
return nil
|
||||
}
|
||||
|
||||
func getAllAccount() -> [tableAccount] {
|
||||
func getAllTableAccount() -> [tableAccount] {
|
||||
do {
|
||||
let realm = try Realm()
|
||||
let sorted = [SortDescriptor(keyPath: "active", ascending: false), SortDescriptor(keyPath: "user", ascending: true)]
|
||||
|
@ -194,16 +197,16 @@ extension NCManageDatabase {
|
|||
return ""
|
||||
}
|
||||
|
||||
func getAccountAutoUploadDirectory(urlBase: String, userId: String, account: String) -> String {
|
||||
func getAccountAutoUploadDirectory(session: NCSession.Session) -> String {
|
||||
do {
|
||||
let realm = try Realm()
|
||||
guard let result = realm.objects(tableAccount.self).filter("active == true").first else { return "" }
|
||||
if result.autoUploadDirectory.isEmpty {
|
||||
return utilityFileSystem.getHomeServer(urlBase: urlBase, userId: userId)
|
||||
return utilityFileSystem.getHomeServer(session: session)
|
||||
} else {
|
||||
// FIX change webdav -> /dav/files/
|
||||
if result.autoUploadDirectory.contains("/webdav") {
|
||||
return utilityFileSystem.getHomeServer(urlBase: urlBase, userId: userId)
|
||||
return utilityFileSystem.getHomeServer(session: session)
|
||||
} else {
|
||||
return result.autoUploadDirectory
|
||||
}
|
||||
|
@ -214,9 +217,9 @@ extension NCManageDatabase {
|
|||
return ""
|
||||
}
|
||||
|
||||
func getAccountAutoUploadPath(urlBase: String, userId: String, account: String) -> String {
|
||||
func getAccountAutoUploadPath(session: NCSession.Session) -> String {
|
||||
let cameraFileName = self.getAccountAutoUploadFileName()
|
||||
let cameraDirectory = self.getAccountAutoUploadDirectory(urlBase: urlBase, userId: userId, account: account)
|
||||
let cameraDirectory = self.getAccountAutoUploadDirectory(session: session)
|
||||
let folderPhotos = utilityFileSystem.stringAppendServerUrl(cameraDirectory, addFileName: cameraFileName)
|
||||
return folderPhotos
|
||||
}
|
||||
|
@ -232,9 +235,7 @@ extension NCManageDatabase {
|
|||
return NCGlobal.shared.subfolderGranularityMonthly
|
||||
}
|
||||
|
||||
func setAccountActive(_ account: String) -> tableAccount? {
|
||||
var accountReturn = tableAccount()
|
||||
|
||||
func setAccountActive(_ account: String) {
|
||||
do {
|
||||
let realm = try Realm()
|
||||
try realm.write {
|
||||
|
@ -242,27 +243,11 @@ extension NCManageDatabase {
|
|||
for result in results {
|
||||
if result.account == account {
|
||||
result.active = true
|
||||
accountReturn = result
|
||||
} else {
|
||||
result.active = false
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch let error {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Could not write to database: \(error)")
|
||||
return nil
|
||||
}
|
||||
return tableAccount.init(value: accountReturn)
|
||||
}
|
||||
|
||||
func removePasswordAccount(_ account: String) {
|
||||
do {
|
||||
let realm = try Realm()
|
||||
try realm.write {
|
||||
if let result = realm.objects(tableAccount.self).filter("account == %@", account).first {
|
||||
result.password = "********"
|
||||
}
|
||||
}
|
||||
} catch let error {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Could not write to database: \(error)")
|
||||
}
|
||||
|
@ -309,7 +294,7 @@ extension NCManageDatabase {
|
|||
}
|
||||
}
|
||||
|
||||
func setAccountAutoUploadDirectory(_ serverUrl: String?, urlBase: String, userId: String, account: String) {
|
||||
func setAccountAutoUploadDirectory(_ serverUrl: String?, session: NCSession.Session) {
|
||||
do {
|
||||
let realm = try Realm()
|
||||
try realm.write {
|
||||
|
@ -317,7 +302,7 @@ extension NCManageDatabase {
|
|||
if let serverUrl = serverUrl {
|
||||
result.autoUploadDirectory = serverUrl
|
||||
} else {
|
||||
result.autoUploadDirectory = self.getAccountAutoUploadDirectory(urlBase: urlBase, userId: userId, account: account)
|
||||
result.autoUploadDirectory = self.getAccountAutoUploadDirectory(session: session)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import RealmSwift
|
||||
import NextcloudKit
|
||||
import SwiftyJSON
|
||||
|
|
|
@ -104,8 +104,9 @@ extension NCManageDatabase {
|
|||
return image
|
||||
}
|
||||
|
||||
func getImageAvatarLoaded(fileName: String) -> UIImage? {
|
||||
func getImageAvatarLoaded(fileName: String) -> (image: UIImage?, tableAvatar: tableAvatar?) {
|
||||
let fileNameLocalPath = utilityFileSystem.directoryUserData + "/" + fileName
|
||||
let image = UIImage(contentsOfFile: fileNameLocalPath)
|
||||
|
||||
do {
|
||||
let realm = try Realm()
|
||||
|
@ -113,16 +114,13 @@ extension NCManageDatabase {
|
|||
let result = realm.objects(tableAvatar.self).filter("fileName == %@", fileName).first
|
||||
if result == nil {
|
||||
utilityFileSystem.removeFile(atPath: fileNameLocalPath)
|
||||
return nil
|
||||
} else if result?.loaded == false {
|
||||
return nil
|
||||
}
|
||||
return UIImage(contentsOfFile: fileNameLocalPath)
|
||||
return (image, result)
|
||||
} catch let error as NSError {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Could not access database: \(error)")
|
||||
}
|
||||
|
||||
utilityFileSystem.removeFile(atPath: fileNameLocalPath)
|
||||
return nil
|
||||
return (nil, nil)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import RealmSwift
|
||||
import NextcloudKit
|
||||
|
||||
|
@ -62,7 +63,8 @@ extension NCManageDatabase {
|
|||
return nil
|
||||
}
|
||||
|
||||
func setCapabilities(account: String, data: Data? = nil) {
|
||||
@discardableResult
|
||||
func setCapabilities(account: String, data: Data? = nil) -> NCCapabilities.Capabilities? {
|
||||
let jsonData: Data?
|
||||
|
||||
struct CapabilityNextcloud: Codable {
|
||||
|
@ -285,97 +287,108 @@ extension NCManageDatabase {
|
|||
let ocs: Ocs
|
||||
}
|
||||
|
||||
if let data = data {
|
||||
if let data {
|
||||
jsonData = data
|
||||
} else {
|
||||
do {
|
||||
let realm = try Realm()
|
||||
guard let result = realm.objects(tableCapabilities.self).filter("account == %@", account).first,
|
||||
let data = result.jsondata else {
|
||||
return
|
||||
return nil
|
||||
}
|
||||
jsonData = data
|
||||
} catch let error as NSError {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Could not access database: \(error)")
|
||||
return
|
||||
return nil
|
||||
}
|
||||
}
|
||||
guard let jsonData = jsonData else { return }
|
||||
guard let jsonData = jsonData else {
|
||||
return nil
|
||||
}
|
||||
|
||||
do {
|
||||
let global = NCGlobal.shared
|
||||
let json = try JSONDecoder().decode(CapabilityNextcloud.self, from: jsonData)
|
||||
let data = json.ocs.data
|
||||
let capabilities = NCCapabilities.Capabilities()
|
||||
|
||||
global.capabilityServerVersion = data.version.string
|
||||
global.capabilityServerVersionMajor = data.version.major
|
||||
capabilities.capabilityServerVersion = data.version.string
|
||||
capabilities.capabilityServerVersionMajor = data.version.major
|
||||
|
||||
if global.capabilityServerVersionMajor > 0 {
|
||||
NextcloudKit.shared.setup(nextcloudVersion: global.capabilityServerVersionMajor)
|
||||
if capabilities.capabilityServerVersionMajor > 0 {
|
||||
NextcloudKit.shared.updateSession(account: account, nextcloudVersion: capabilities.capabilityServerVersionMajor)
|
||||
}
|
||||
|
||||
global.capabilityFileSharingApiEnabled = data.capabilities.filessharing?.apienabled ?? false
|
||||
global.capabilityFileSharingDefaultPermission = data.capabilities.filessharing?.defaultpermissions ?? 0
|
||||
global.capabilityFileSharingPubPasswdEnforced = data.capabilities.filessharing?.ncpublic?.password?.enforced ?? false
|
||||
global.capabilityFileSharingPubExpireDateEnforced = data.capabilities.filessharing?.ncpublic?.expiredate?.enforced ?? false
|
||||
global.capabilityFileSharingPubExpireDateDays = data.capabilities.filessharing?.ncpublic?.expiredate?.days ?? 0
|
||||
global.capabilityFileSharingInternalExpireDateEnforced = data.capabilities.filessharing?.ncpublic?.expiredateinternal?.enforced ?? false
|
||||
global.capabilityFileSharingInternalExpireDateDays = data.capabilities.filessharing?.ncpublic?.expiredateinternal?.days ?? 0
|
||||
global.capabilityFileSharingRemoteExpireDateEnforced = data.capabilities.filessharing?.ncpublic?.expiredateremote?.enforced ?? false
|
||||
global.capabilityFileSharingRemoteExpireDateDays = data.capabilities.filessharing?.ncpublic?.expiredateremote?.days ?? 0
|
||||
capabilities.capabilityFileSharingApiEnabled = data.capabilities.filessharing?.apienabled ?? false
|
||||
capabilities.capabilityFileSharingDefaultPermission = data.capabilities.filessharing?.defaultpermissions ?? 0
|
||||
capabilities.capabilityFileSharingPubPasswdEnforced = data.capabilities.filessharing?.ncpublic?.password?.enforced ?? false
|
||||
capabilities.capabilityFileSharingPubExpireDateEnforced = data.capabilities.filessharing?.ncpublic?.expiredate?.enforced ?? false
|
||||
capabilities.capabilityFileSharingPubExpireDateDays = data.capabilities.filessharing?.ncpublic?.expiredate?.days ?? 0
|
||||
capabilities.capabilityFileSharingInternalExpireDateEnforced = data.capabilities.filessharing?.ncpublic?.expiredateinternal?.enforced ?? false
|
||||
capabilities.capabilityFileSharingInternalExpireDateDays = data.capabilities.filessharing?.ncpublic?.expiredateinternal?.days ?? 0
|
||||
capabilities.capabilityFileSharingRemoteExpireDateEnforced = data.capabilities.filessharing?.ncpublic?.expiredateremote?.enforced ?? false
|
||||
capabilities.capabilityFileSharingRemoteExpireDateDays = data.capabilities.filessharing?.ncpublic?.expiredateremote?.days ?? 0
|
||||
|
||||
global.capabilityThemingColor = data.capabilities.theming?.color ?? ""
|
||||
global.capabilityThemingColorElement = data.capabilities.theming?.colorelement ?? ""
|
||||
global.capabilityThemingColorText = data.capabilities.theming?.colortext ?? ""
|
||||
global.capabilityThemingName = data.capabilities.theming?.name ?? ""
|
||||
global.capabilityThemingSlogan = data.capabilities.theming?.slogan ?? ""
|
||||
capabilities.capabilityThemingColor = data.capabilities.theming?.color ?? ""
|
||||
capabilities.capabilityThemingColorElement = data.capabilities.theming?.colorelement ?? ""
|
||||
capabilities.capabilityThemingColorText = data.capabilities.theming?.colortext ?? ""
|
||||
capabilities.capabilityThemingName = data.capabilities.theming?.name ?? ""
|
||||
capabilities.capabilityThemingSlogan = data.capabilities.theming?.slogan ?? ""
|
||||
|
||||
global.capabilityE2EEEnabled = data.capabilities.endtoendencryption?.enabled ?? false
|
||||
global.capabilityE2EEApiVersion = data.capabilities.endtoendencryption?.apiversion ?? ""
|
||||
capabilities.capabilityE2EEEnabled = data.capabilities.endtoendencryption?.enabled ?? false
|
||||
capabilities.capabilityE2EEApiVersion = data.capabilities.endtoendencryption?.apiversion ?? ""
|
||||
|
||||
global.capabilityRichDocumentsEnabled = json.ocs.data.capabilities.richdocuments?.directediting ?? false
|
||||
global.capabilityRichDocumentsMimetypes.removeAll()
|
||||
capabilities.capabilityRichDocumentsEnabled = json.ocs.data.capabilities.richdocuments?.directediting ?? false
|
||||
capabilities.capabilityRichDocumentsMimetypes.removeAll()
|
||||
if let mimetypes = data.capabilities.richdocuments?.mimetypes {
|
||||
for mimetype in mimetypes {
|
||||
global.capabilityRichDocumentsMimetypes.append(mimetype)
|
||||
capabilities.capabilityRichDocumentsMimetypes.append(mimetype)
|
||||
}
|
||||
}
|
||||
|
||||
global.capabilityAssistantEnabled = data.capabilities.assistant?.enabled ?? false
|
||||
capabilities.capabilityAssistantEnabled = data.capabilities.assistant?.enabled ?? false
|
||||
|
||||
global.capabilityActivity.removeAll()
|
||||
capabilities.capabilityActivity.removeAll()
|
||||
if let activities = data.capabilities.activity?.apiv2 {
|
||||
for activity in activities {
|
||||
global.capabilityActivity.append(activity)
|
||||
capabilities.capabilityActivity.append(activity)
|
||||
}
|
||||
}
|
||||
|
||||
global.capabilityNotification.removeAll()
|
||||
capabilities.capabilityNotification.removeAll()
|
||||
if let notifications = data.capabilities.notifications?.ocsendpoints {
|
||||
for notification in notifications {
|
||||
global.capabilityNotification.append(notification)
|
||||
capabilities.capabilityNotification.append(notification)
|
||||
}
|
||||
}
|
||||
|
||||
global.capabilityFilesUndelete = data.capabilities.files?.undelete ?? false
|
||||
global.capabilityFilesLockVersion = data.capabilities.files?.locking ?? ""
|
||||
global.capabilityFilesComments = data.capabilities.files?.comments ?? false
|
||||
global.capabilityFilesBigfilechunking = data.capabilities.files?.bigfilechunking ?? false
|
||||
capabilities.capabilityFilesUndelete = data.capabilities.files?.undelete ?? false
|
||||
capabilities.capabilityFilesLockVersion = data.capabilities.files?.locking ?? ""
|
||||
capabilities.capabilityFilesComments = data.capabilities.files?.comments ?? false
|
||||
capabilities.capabilityFilesBigfilechunking = data.capabilities.files?.bigfilechunking ?? false
|
||||
|
||||
global.capabilityUserStatusEnabled = data.capabilities.userstatus?.enabled ?? false
|
||||
capabilities.capabilityUserStatusEnabled = data.capabilities.userstatus?.enabled ?? false
|
||||
if data.capabilities.external != nil {
|
||||
global.capabilityExternalSites = true
|
||||
capabilities.capabilityExternalSites = true
|
||||
}
|
||||
global.capabilityGroupfoldersEnabled = data.capabilities.groupfolders?.hasGroupFolders ?? false
|
||||
global.capabilitySecurityGuardDiagnostics = data.capabilities.securityguard?.diagnostics ?? false
|
||||
capabilities.capabilityGroupfoldersEnabled = data.capabilities.groupfolders?.hasGroupFolders ?? false
|
||||
|
||||
global.capabilityForbiddenFileNames = data.capabilities.files?.forbiddenFileNames ?? []
|
||||
global.capabilityForbiddenFileNameBasenames = data.capabilities.files?.forbiddenFileNameBasenames ?? []
|
||||
global.capabilityForbiddenFileNameCharacters = data.capabilities.files?.forbiddenFileNameCharacters ?? []
|
||||
global.capabilityForbiddenFileNameExtensions = data.capabilities.files?.forbiddenFileNameExtensions ?? []
|
||||
if capabilities.capabilityServerVersionMajor >= NCGlobal.shared.nextcloudVersion28 {
|
||||
capabilities.isLivePhotoServerAvailable = true
|
||||
}
|
||||
|
||||
capabilities.capabilitySecurityGuardDiagnostics = data.capabilities.securityguard?.diagnostics ?? false
|
||||
|
||||
capabilities.capabilityForbiddenFileNames = data.capabilities.files?.forbiddenFileNames ?? []
|
||||
capabilities.capabilityForbiddenFileNameBasenames = data.capabilities.files?.forbiddenFileNameBasenames ?? []
|
||||
capabilities.capabilityForbiddenFileNameCharacters = data.capabilities.files?.forbiddenFileNameCharacters ?? []
|
||||
capabilities.capabilityForbiddenFileNameExtensions = data.capabilities.files?.forbiddenFileNameExtensions ?? []
|
||||
|
||||
NCCapabilities.shared.appendCapabilities(account: account, capabilities: capabilities)
|
||||
|
||||
return capabilities
|
||||
} catch let error as NSError {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Could not access database: \(error)")
|
||||
return
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import RealmSwift
|
||||
import NextcloudKit
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import RealmSwift
|
||||
import NextcloudKit
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import RealmSwift
|
||||
import NextcloudKit
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import RealmSwift
|
||||
import NextcloudKit
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import RealmSwift
|
||||
import NextcloudKit
|
||||
|
||||
|
@ -102,7 +103,7 @@ extension NCManageDatabase {
|
|||
let results = realm.objects(tableDirectory.self).filter("account == %@ AND serverUrl BEGINSWITH %@", account, serverUrl)
|
||||
for result in results {
|
||||
self.deleteMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", result.account, result.serverUrl))
|
||||
self.deleteLocalFile(predicate: NSPredicate(format: "ocId == %@", result.ocId))
|
||||
self.deleteLocalFileOcId(result.ocId)
|
||||
}
|
||||
try realm.write {
|
||||
realm.delete(results)
|
||||
|
@ -142,19 +143,6 @@ extension NCManageDatabase {
|
|||
}
|
||||
}
|
||||
|
||||
func cleanEtagDirectory(account: String, serverUrl: String) {
|
||||
do {
|
||||
let realm = try Realm()
|
||||
try realm.write {
|
||||
if let result = realm.objects(tableDirectory.self).filter("account == %@ AND serverUrl == %@", account, serverUrl).first {
|
||||
result.etag = ""
|
||||
}
|
||||
}
|
||||
} catch let error {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Could not write to database: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
func getTableDirectory(predicate: NSPredicate) -> tableDirectory? {
|
||||
do {
|
||||
let realm = try Realm()
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import RealmSwift
|
||||
import NextcloudKit
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import RealmSwift
|
||||
import NextcloudKit
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import RealmSwift
|
||||
import NextcloudKit
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import RealmSwift
|
||||
import NextcloudKit
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import RealmSwift
|
||||
import NextcloudKit
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import RealmSwift
|
||||
import NextcloudKit
|
||||
|
||||
|
@ -100,11 +101,13 @@ extension NCManageDatabase {
|
|||
}
|
||||
}
|
||||
|
||||
func deleteLocalFile(predicate: NSPredicate) {
|
||||
func deleteLocalFileOcId(_ ocId: String?) {
|
||||
guard let ocId else { return }
|
||||
|
||||
do {
|
||||
let realm = try Realm()
|
||||
try realm.write {
|
||||
let results = realm.objects(tableLocalFile.self).filter(predicate)
|
||||
let results = realm.objects(tableLocalFile.self).filter("ocId == %@", ocId)
|
||||
realm.delete(results)
|
||||
}
|
||||
} catch let error {
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import RealmSwift
|
||||
import NextcloudKit
|
||||
|
||||
|
@ -29,6 +30,7 @@ extension NCManageDatabase {
|
|||
func setMetadataSession(ocId: String,
|
||||
newFileName: String? = nil,
|
||||
session: String? = nil,
|
||||
sessionTaskIdentifier: Int? = nil,
|
||||
sessionError: String? = nil,
|
||||
selector: String? = nil,
|
||||
status: Int? = nil,
|
||||
|
@ -46,6 +48,9 @@ extension NCManageDatabase {
|
|||
if let session {
|
||||
result.session = session
|
||||
}
|
||||
if let sessionTaskIdentifier {
|
||||
result.sessionTaskIdentifier = sessionTaskIdentifier
|
||||
}
|
||||
if let sessionError {
|
||||
result.sessionError = sessionError
|
||||
if sessionError.isEmpty {
|
||||
|
@ -76,31 +81,6 @@ extension NCManageDatabase {
|
|||
}
|
||||
}
|
||||
|
||||
func setMetadataSession(ocId: String,
|
||||
status: Int? = nil,
|
||||
taskIdentifier: Int? = nil) {
|
||||
do {
|
||||
let realm = try Realm()
|
||||
try realm.write {
|
||||
if let result = realm.objects(tableMetadata.self).filter("ocId == %@", ocId).first {
|
||||
if let status {
|
||||
result.status = status
|
||||
if status == NCGlobal.shared.metadataStatusWaitDownload || status == NCGlobal.shared.metadataStatusWaitUpload {
|
||||
result.sessionDate = Date()
|
||||
} else if status == NCGlobal.shared.metadataStatusNormal {
|
||||
result.sessionDate = nil
|
||||
}
|
||||
}
|
||||
if let taskIdentifier {
|
||||
result.sessionTaskIdentifier = taskIdentifier
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch let error {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Could not write to database: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
func setMetadatasSessionInWaitDownload(metadatas: [tableMetadata], session: String, selector: String, sceneIdentifier: String? = nil) -> tableMetadata? {
|
||||
if metadatas.isEmpty { return nil }
|
||||
|
@ -113,6 +93,7 @@ extension NCManageDatabase {
|
|||
if let result = realm.objects(tableMetadata.self).filter("ocId == %@", metadata.ocId).first {
|
||||
result.sceneIdentifier = sceneIdentifier
|
||||
result.session = session
|
||||
result.sessionTaskIdentifier = 0
|
||||
result.sessionError = ""
|
||||
result.sessionSelector = selector
|
||||
result.status = NCGlobal.shared.metadataStatusWaitDownload
|
||||
|
@ -121,6 +102,7 @@ extension NCManageDatabase {
|
|||
} else {
|
||||
metadata.sceneIdentifier = sceneIdentifier
|
||||
metadata.session = session
|
||||
metadata.sessionTaskIdentifier = 0
|
||||
metadata.sessionError = ""
|
||||
metadata.sessionSelector = selector
|
||||
metadata.status = NCGlobal.shared.metadataStatusWaitDownload
|
||||
|
@ -137,17 +119,39 @@ extension NCManageDatabase {
|
|||
return metadataUpdated
|
||||
}
|
||||
|
||||
func clearMetadataSession(metadatas: Results<tableMetadata>) {
|
||||
func clearMetadataSession(metadatas: [tableMetadata]) {
|
||||
do {
|
||||
let realm = try Realm()
|
||||
try realm.write {
|
||||
for metadata in metadatas {
|
||||
metadata.sceneIdentifier = nil
|
||||
metadata.session = ""
|
||||
metadata.sessionError = ""
|
||||
metadata.sessionSelector = ""
|
||||
metadata.sessionDate = nil
|
||||
metadata.status = NCGlobal.shared.metadataStatusNormal
|
||||
if let result = realm.objects(tableMetadata.self).filter("ocId == %@", metadata.ocId).first {
|
||||
result.sceneIdentifier = nil
|
||||
result.session = ""
|
||||
result.sessionTaskIdentifier = 0
|
||||
result.sessionError = ""
|
||||
result.sessionSelector = ""
|
||||
result.sessionDate = nil
|
||||
result.status = NCGlobal.shared.metadataStatusNormal
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch let error {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Could not write to database: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
func clearMetadataSession(metadata: tableMetadata) {
|
||||
do {
|
||||
let realm = try Realm()
|
||||
try realm.write {
|
||||
if let result = realm.objects(tableMetadata.self).filter("ocId == %@", metadata.ocId).first {
|
||||
result.sceneIdentifier = nil
|
||||
result.session = ""
|
||||
result.sessionTaskIdentifier = 0
|
||||
result.sessionError = ""
|
||||
result.sessionSelector = ""
|
||||
result.sessionDate = nil
|
||||
result.status = NCGlobal.shared.metadataStatusNormal
|
||||
}
|
||||
}
|
||||
} catch let error {
|
||||
|
@ -164,6 +168,12 @@ extension NCManageDatabase {
|
|||
try realm.write {
|
||||
result = realm.objects(tableMetadata.self).filter("ocId == %@", ocId).first
|
||||
result?.status = status
|
||||
|
||||
if status == NCGlobal.shared.metadataStatusNormal {
|
||||
result?.sessionDate = nil
|
||||
} else {
|
||||
result?.sessionDate = Date()
|
||||
}
|
||||
}
|
||||
} catch let error {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Could not write to database: \(error)")
|
||||
|
@ -184,6 +194,9 @@ extension NCManageDatabase {
|
|||
if serverUrl.hasSuffix("/") {
|
||||
serverUrl = String(serverUrl.dropLast())
|
||||
}
|
||||
return NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "serverUrl == %@ AND fileName == %@ AND sessionTaskIdentifier == %d", serverUrl, fileName, sessionTaskIdentifier))
|
||||
return getMetadata(predicate: NSPredicate(format: "serverUrl == %@ AND fileName == %@ AND sessionTaskIdentifier == %d",
|
||||
serverUrl,
|
||||
fileName,
|
||||
sessionTaskIdentifier))
|
||||
}
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -22,6 +22,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import RealmSwift
|
||||
import NextcloudKit
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import RealmSwift
|
||||
import NextcloudKit
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import RealmSwift
|
||||
import NextcloudKit
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import RealmSwift
|
||||
import NextcloudKit
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import RealmSwift
|
||||
import NextcloudKit
|
||||
|
||||
|
@ -113,24 +114,22 @@ extension NCManageDatabase {
|
|||
}
|
||||
}
|
||||
|
||||
func getTrash(filePath: String, account: String) -> [tableTrash] {
|
||||
func getResultsTrash(filePath: String, account: String) -> Results<tableTrash>? {
|
||||
do {
|
||||
let realm = try Realm()
|
||||
realm.refresh()
|
||||
let results = realm.objects(tableTrash.self).filter("account == %@ AND filePath == %@", account, filePath).sorted(byKeyPath: "trashbinDeletionTime", ascending: false)
|
||||
return Array(results.map { tableTrash.init(value: $0) })
|
||||
return realm.objects(tableTrash.self).filter("account == %@ AND filePath == %@", account, filePath).sorted(byKeyPath: "trashbinDeletionTime", ascending: false)
|
||||
} catch let error as NSError {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Could not access to database: \(error)")
|
||||
}
|
||||
return []
|
||||
return nil
|
||||
}
|
||||
|
||||
func getTrashItem(fileId: String, account: String) -> tableTrash? {
|
||||
func getResultTrashItem(fileId: String, account: String) -> tableTrash? {
|
||||
do {
|
||||
let realm = try Realm()
|
||||
realm.refresh()
|
||||
guard let result = realm.objects(tableTrash.self).filter("account == %@ AND fileId == %@", account, fileId).first else { return nil }
|
||||
return tableTrash.init(value: result)
|
||||
return realm.objects(tableTrash.self).filter("account == %@ AND fileId == %@", account, fileId).first
|
||||
} catch let error as NSError {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Could not access to database: \(error)")
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import RealmSwift
|
||||
import NextcloudKit
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import RealmSwift
|
||||
import NextcloudKit
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ import RealmSwift
|
|||
import NextcloudKit
|
||||
import CoreMedia
|
||||
import Photos
|
||||
import CommonCrypto
|
||||
|
||||
protocol DateCompareable {
|
||||
var dateKey: Date { get }
|
||||
|
@ -41,17 +42,20 @@ class NCManageDatabase: NSObject {
|
|||
|
||||
override init() {
|
||||
func migrationSchema(_ migration: Migration, _ oldSchemaVersion: UInt64) {
|
||||
if oldSchemaVersion < 354 {
|
||||
migration.deleteData(forType: NCDBLayoutForView.className())
|
||||
if oldSchemaVersion < 365 {
|
||||
migration.deleteData(forType: tableMetadata.className())
|
||||
migration.enumerateObjects(ofType: tableDirectory.className()) { _, newObject in
|
||||
newObject?["etag"] = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
let usedPercentage = (Double(usedBytes) / Double(totalBytes)) * 100
|
||||
/// Compact the database if more than 25% of the space is free
|
||||
let shouldCompact = (usedPercentage < 75.0) && (totalBytes > 100 * 1024 * 1024)
|
||||
|
||||
return shouldCompact
|
||||
}
|
||||
var realm: Realm?
|
||||
let dirGroup = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: NCBrandOptions.shared.capabilitiesGroup)
|
||||
|
@ -60,7 +64,8 @@ class NCManageDatabase: NSObject {
|
|||
let bundlePathExtension: String = bundleUrl.pathExtension
|
||||
let bundleFileName: String = (bundleUrl.path as NSString).lastPathComponent
|
||||
let isAppex: Bool = bundlePathExtension == "appex"
|
||||
var objectTypesAppex = [tableMetadata.self,
|
||||
var objectTypesAppex = [NCKeyValue.self,
|
||||
tableMetadata.self,
|
||||
tableLocalFile.self,
|
||||
tableDirectory.self,
|
||||
tableTag.self,
|
||||
|
@ -94,12 +99,14 @@ class NCManageDatabase: NSObject {
|
|||
|
||||
if isAppex {
|
||||
if bundleFileName == "File Provider Extension.appex" {
|
||||
objectTypesAppex = [tableMetadata.self,
|
||||
objectTypesAppex = [NCKeyValue.self,
|
||||
tableMetadata.self,
|
||||
tableLocalFile.self,
|
||||
tableDirectory.self,
|
||||
tableTag.self,
|
||||
tableAccount.self,
|
||||
tableCapabilities.self]
|
||||
tableCapabilities.self,
|
||||
tableE2eEncryption.self]
|
||||
}
|
||||
do {
|
||||
Realm.Configuration.defaultConfiguration =
|
||||
|
@ -145,7 +152,6 @@ class NCManageDatabase: NSObject {
|
|||
let realm = try Realm()
|
||||
try realm.write {
|
||||
var results: Results<Object>
|
||||
|
||||
if let account = account {
|
||||
results = realm.objects(table).filter("account == %@", account)
|
||||
} else {
|
||||
|
@ -159,7 +165,7 @@ class NCManageDatabase: NSObject {
|
|||
}
|
||||
}
|
||||
|
||||
func clearDatabase(account: String?, removeAccount: Bool) {
|
||||
func clearDatabase(account: String? = nil, removeAccount: Bool = false) {
|
||||
if removeAccount {
|
||||
self.clearTable(tableAccount.self, account: account)
|
||||
}
|
||||
|
@ -216,6 +222,24 @@ class NCManageDatabase: NSObject {
|
|||
return nil
|
||||
}
|
||||
|
||||
func realmRefresh() {
|
||||
do {
|
||||
let realm = try Realm()
|
||||
realm.refresh()
|
||||
} catch let error as NSError {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Could not refresh database: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
func sha256Hash(_ input: String) -> String {
|
||||
let data = Data(input.utf8)
|
||||
var digest = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
|
||||
data.withUnsafeBytes {
|
||||
_ = CC_SHA256($0.baseAddress, CC_LONG(data.count), &digest)
|
||||
}
|
||||
return digest.map { String(format: "%02hhx", $0) }.joined()
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
// MARK: Func T
|
||||
|
||||
|
@ -250,17 +274,22 @@ class NCManageDatabase: NSObject {
|
|||
/// Account
|
||||
let account = "marinofaggiana https://cloudtest.nextcloud.com"
|
||||
let account2 = "mariorossi https://cloudtest.nextcloud.com"
|
||||
NCManageDatabase.shared.addAccount(account, urlBase: "https://cloudtest.nextcloud.com", user: "marinofaggiana", userId: "marinofaggiana", password: "password")
|
||||
NCManageDatabase.shared.addAccount(account2, urlBase: "https://cloudtest.nextcloud.com", user: "mariorossi", userId: "mariorossi", password: "password")
|
||||
addAccount(account, urlBase: "https://cloudtest.nextcloud.com", user: "marinofaggiana", userId: "marinofaggiana", password: "password")
|
||||
addAccount(account2, urlBase: "https://cloudtest.nextcloud.com", user: "mariorossi", userId: "mariorossi", password: "password")
|
||||
let userProfile = NKUserProfile()
|
||||
userProfile.displayName = "Marino Faggiana"
|
||||
userProfile.address = "Hirschstrasse 26, 70192 Stuttgart, Germany"
|
||||
userProfile.phone = "+49 (711) 252 428 - 90"
|
||||
userProfile.email = "cloudtest@nextcloud.com"
|
||||
NCManageDatabase.shared.setAccountUserProfile(account: account, userProfile: userProfile)
|
||||
setAccountUserProfile(account: account, userProfile: userProfile)
|
||||
let userProfile2 = NKUserProfile()
|
||||
userProfile2.displayName = "Mario Rossi"
|
||||
userProfile2.email = "cloudtest@nextcloud.com"
|
||||
NCManageDatabase.shared.setAccountUserProfile(account: account2, userProfile: userProfile2)
|
||||
setAccountUserProfile(account: account2, userProfile: userProfile2)
|
||||
}
|
||||
}
|
||||
|
||||
class NCKeyValue: Object {
|
||||
@Persisted var key: String = ""
|
||||
@Persisted var value: String?
|
||||
}
|
||||
|
|
|
@ -103,6 +103,7 @@ class NCDeepLinkHandler {
|
|||
controller.selectedIndex = ControllerConstants.filesIndex
|
||||
guard let navigationController = controller.viewControllers?[controller.selectedIndex] as? UINavigationController,
|
||||
let viewController = UIStoryboard(name: ControllerConstants.notification, bundle: nil).instantiateInitialViewController() as? NCNotification else { return }
|
||||
viewController.session = NCSession.shared.getSession(controller: controller)
|
||||
navigationController.pushViewController(viewController, animated: true)
|
||||
}
|
||||
|
||||
|
@ -111,10 +112,11 @@ class NCDeepLinkHandler {
|
|||
controller.selectedIndex = ControllerConstants.filesIndex
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 4) {
|
||||
let serverUrl = controller.currentServerUrl()
|
||||
let fileFolderPath = NCUtilityFileSystem().getFileNamePath("", serverUrl: serverUrl, urlBase: appDelegate.urlBase, userId: appDelegate.userId)
|
||||
let session = NCSession.shared.getSession(controller: controller)
|
||||
let fileFolderPath = NCUtilityFileSystem().getFileNamePath("", serverUrl: serverUrl, session: session)
|
||||
let fileFolderName = (serverUrl as NSString).lastPathComponent
|
||||
|
||||
if !FileNameValidator.shared.checkFolderPath(folderPath: fileFolderPath) {
|
||||
if !FileNameValidator.shared.checkFolderPath(fileFolderPath, account: controller.account) {
|
||||
controller.present(UIAlertController.warning(message: "\(String(format: NSLocalizedString("_file_name_validator_error_reserved_name_", comment: ""), fileFolderName)) \(NSLocalizedString("_please_rename_file_", comment: ""))"), animated: true)
|
||||
|
||||
return
|
||||
|
|
|
@ -25,7 +25,6 @@ import Foundation
|
|||
import UIKit
|
||||
|
||||
extension NotificationCenter {
|
||||
|
||||
func postOnMainThread(name: String, object anObject: Any? = nil, userInfo aUserInfo: [AnyHashable: Any]? = nil, second: Double = 0) {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + second) {
|
||||
NotificationCenter.default.post(name: Notification.Name(rawValue: name), object: anObject, userInfo: aUserInfo)
|
||||
|
|
|
@ -32,16 +32,21 @@ extension UIAlertController {
|
|||
/// - urlBase: UrlBase object
|
||||
/// - completion: If not` nil` it overrides the default behavior which shows an error using `NCContentPresenter`
|
||||
/// - Returns: The presentable alert controller
|
||||
static func createFolder(serverUrl: String, userBaseUrl: NCUserBaseUrl, markE2ee: Bool = false, sceneIdentifier: String? = nil, completion: ((_ error: NKError) -> Void)? = nil) -> UIAlertController {
|
||||
static func createFolder(serverUrl: String, account: String, markE2ee: Bool = false, sceneIdentifier: String? = nil, completion: ((_ error: NKError) -> Void)? = nil) -> UIAlertController {
|
||||
let alertController = UIAlertController(title: NSLocalizedString("_create_folder_", comment: ""), message: nil, preferredStyle: .alert)
|
||||
let session = NCSession.shared.getSession(account: account)
|
||||
let isDirectoryEncrypted = NCUtilityFileSystem().isDirectoryE2EE(session: session, serverUrl: serverUrl)
|
||||
|
||||
let okAction = UIAlertAction(title: NSLocalizedString("_save_", comment: ""), style: .default, handler: { _ in
|
||||
guard let fileNameFolder = alertController.textFields?.first?.text else { return }
|
||||
if markE2ee {
|
||||
if NCNetworking.shared.isOffline {
|
||||
return NCContentPresenter().showInfo(error: NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: "_offline_not_allowed_"))
|
||||
}
|
||||
Task {
|
||||
let createFolderResults = await NCNetworking.shared.createFolder(serverUrlFileName: serverUrl + "/" + fileNameFolder, account: userBaseUrl.account)
|
||||
let createFolderResults = await NCNetworking.shared.createFolder(serverUrlFileName: serverUrl + "/" + fileNameFolder, account: session.account)
|
||||
if createFolderResults.error == .success {
|
||||
let error = await NCNetworkingE2EEMarkFolder().markFolderE2ee(account: userBaseUrl.account, fileName: fileNameFolder, serverUrl: serverUrl, userId: userBaseUrl.userId)
|
||||
let error = await NCNetworkingE2EEMarkFolder().markFolderE2ee(account: session.account, fileName: fileNameFolder, serverUrl: serverUrl, userId: session.userId)
|
||||
if error != .success {
|
||||
NCContentPresenter().showError(error: error)
|
||||
}
|
||||
|
@ -49,14 +54,29 @@ extension UIAlertController {
|
|||
NCContentPresenter().showError(error: createFolderResults.error)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NCNetworking.shared.createFolder(fileName: fileNameFolder, serverUrl: serverUrl, account: userBaseUrl.account, urlBase: userBaseUrl.urlBase, userId: userBaseUrl.userId, overwrite: false, withPush: true, sceneIdentifier: sceneIdentifier) { error in
|
||||
if let completion = completion {
|
||||
completion(error)
|
||||
} else if error != .success {
|
||||
NCContentPresenter().showError(error: error)
|
||||
} // else: successful, no action
|
||||
} else if isDirectoryEncrypted {
|
||||
if NCNetworking.shared.isOffline {
|
||||
return NCContentPresenter().showInfo(error: NKError(errorCode: NCGlobal.shared.errorInternalError, errorDescription: "_offline_not_allowed_"))
|
||||
}
|
||||
#if !EXTENSION
|
||||
Task {
|
||||
await NCNetworkingE2EECreateFolder().createFolder(fileName: fileNameFolder, serverUrl: serverUrl, withPush: true, sceneIdentifier: sceneIdentifier, session: session)
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
let metadataForCreateFolder = NCManageDatabase.shared.createMetadata(fileName: fileNameFolder,
|
||||
fileNameView: fileNameFolder,
|
||||
ocId: NSUUID().uuidString,
|
||||
serverUrl: serverUrl,
|
||||
url: "",
|
||||
contentType: "httpd/unix-directory",
|
||||
directory: true,
|
||||
session: session,
|
||||
sceneIdentifier: sceneIdentifier)
|
||||
metadataForCreateFolder.status = NCGlobal.shared.metadataStatusWaitCreateFolder
|
||||
metadataForCreateFolder.sessionDate = Date()
|
||||
NCManageDatabase.shared.addMetadata(metadataForCreateFolder)
|
||||
NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterCreateFolder, userInfo: ["ocId": metadataForCreateFolder.ocId, "serverUrl": metadataForCreateFolder.serverUrl, "account": metadataForCreateFolder.account, "withPush": true, "sceneIdentifier": sceneIdentifier as Any])
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -76,7 +96,7 @@ extension UIAlertController {
|
|||
guard let text = alertController.textFields?.first?.text else { return }
|
||||
let folderName = text.trimmingCharacters(in: .whitespaces)
|
||||
|
||||
let textCheck = FileNameValidator.shared.checkFileName(folderName)
|
||||
let textCheck = FileNameValidator.shared.checkFileName(folderName, account: account)
|
||||
okAction.isEnabled = textCheck?.error == nil && !folderName.isEmpty
|
||||
alertController.message = textCheck?.error.localizedDescription
|
||||
}
|
||||
|
@ -107,24 +127,15 @@ extension UIAlertController {
|
|||
}, completion: completion)
|
||||
}
|
||||
|
||||
static func deleteFileOrFolder(titleString: String, message: String?, canDeleteServer: Bool, selectedMetadatas: [tableMetadata], completion: @escaping (_ cancelled: Bool) -> Void) -> UIAlertController {
|
||||
static func deleteFileOrFolder(titleString: String, message: String?, canDeleteServer: Bool, selectedMetadatas: [tableMetadata], sceneIdentifier: String?, completion: @escaping (_ cancelled: Bool) -> Void) -> UIAlertController {
|
||||
let alertController = UIAlertController(
|
||||
title: titleString,
|
||||
message: message,
|
||||
preferredStyle: .alert)
|
||||
if canDeleteServer {
|
||||
alertController.addAction(UIAlertAction(title: NSLocalizedString("_yes_", comment: ""), style: .destructive) { (_: UIAlertAction) in
|
||||
Task {
|
||||
var error = NKError()
|
||||
var ocId: [String] = []
|
||||
for metadata in selectedMetadatas where error == .success {
|
||||
error = await NCNetworking.shared.deleteMetadata(metadata, onlyLocalCache: false)
|
||||
if error == .success {
|
||||
ocId.append(metadata.ocId)
|
||||
}
|
||||
}
|
||||
NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterDeleteFile, userInfo: ["ocId": ocId, "onlyLocalCache": false, "error": error])
|
||||
}
|
||||
NCNetworking.shared.deleteMetadatas(selectedMetadatas, sceneIdentifier: sceneIdentifier)
|
||||
NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterReloadDataSource)
|
||||
completion(false)
|
||||
})
|
||||
}
|
||||
|
@ -134,15 +145,12 @@ extension UIAlertController {
|
|||
var error = NKError()
|
||||
var ocId: [String] = []
|
||||
for metadata in selectedMetadatas where error == .success {
|
||||
error = await NCNetworking.shared.deleteMetadata(metadata, onlyLocalCache: true)
|
||||
error = await NCNetworking.shared.deleteCache(metadata, sceneIdentifier: sceneIdentifier)
|
||||
if error == .success {
|
||||
ocId.append(metadata.ocId)
|
||||
}
|
||||
}
|
||||
if error != .success {
|
||||
NCContentPresenter().showError(error: error)
|
||||
}
|
||||
NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterDeleteFile, userInfo: ["ocId": ocId, "onlyLocalCache": true, "error": error])
|
||||
NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterDeleteFile, userInfo: ["ocId": ocId, "error": error])
|
||||
}
|
||||
completion(false)
|
||||
})
|
||||
|
@ -153,7 +161,7 @@ extension UIAlertController {
|
|||
return alertController
|
||||
}
|
||||
|
||||
static func renameFile(fileName: String, completion: @escaping (_ newFileName: String) -> Void) -> UIAlertController {
|
||||
static func renameFile(fileName: String, account: String, completion: @escaping (_ newFileName: String) -> Void) -> UIAlertController {
|
||||
let alertController = UIAlertController(title: NSLocalizedString("_rename_", comment: ""), message: nil, preferredStyle: .alert)
|
||||
|
||||
let okAction = UIAlertAction(title: NSLocalizedString("_save_", comment: ""), style: .default, handler: { _ in
|
||||
|
@ -190,7 +198,7 @@ extension UIAlertController {
|
|||
queue: .main) { _ in
|
||||
guard let text = alertController.textFields?.first?.text else { return }
|
||||
|
||||
let textCheck = FileNameValidator.shared.checkFileName(text)
|
||||
let textCheck = FileNameValidator.shared.checkFileName(text, account: account)
|
||||
okAction.isEnabled = textCheck?.error == nil && !text.isEmpty
|
||||
alertController.message = textCheck?.error.localizedDescription
|
||||
}
|
||||
|
@ -200,28 +208,21 @@ extension UIAlertController {
|
|||
return alertController
|
||||
}
|
||||
|
||||
static func renameFile(metadata: tableMetadata, indexPath: IndexPath) -> UIAlertController {
|
||||
static func renameFile(metadata: tableMetadata) -> UIAlertController {
|
||||
let alertController = UIAlertController(title: NSLocalizedString("_rename_", comment: ""), message: nil, preferredStyle: .alert)
|
||||
|
||||
let okAction = UIAlertAction(title: NSLocalizedString("_save_", comment: ""), style: .default, handler: { _ in
|
||||
guard let newFileName = alertController.textFields?.first?.text else { return }
|
||||
guard let fileNameNew = alertController.textFields?.first?.text else { return }
|
||||
|
||||
// verify if already exists
|
||||
if NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileName == %@", metadata.account, metadata.serverUrl, newFileName)) != nil {
|
||||
if NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileName == %@", metadata.account, metadata.serverUrl, fileNameNew)) != nil {
|
||||
NCContentPresenter().showError(error: NKError(errorCode: 0, errorDescription: "_rename_already_exists_"))
|
||||
return
|
||||
}
|
||||
|
||||
NCActivityIndicator.shared.start()
|
||||
NCNetworking.shared.renameMetadata(metadata, fileNameNew: fileNameNew)
|
||||
|
||||
NCNetworking.shared.renameMetadata(metadata, fileNameNew: newFileName, indexPath: indexPath) { error in
|
||||
|
||||
NCActivityIndicator.shared.stop()
|
||||
|
||||
if error != .success {
|
||||
NCContentPresenter().showError(error: error)
|
||||
}
|
||||
}
|
||||
NotificationCenter.default.postOnMainThread(name: NCGlobal.shared.notificationCenterReloadDataSource, userInfo: ["serverUrl": metadata.serverUrl])
|
||||
})
|
||||
|
||||
// text field is initially empty, no action
|
||||
|
@ -229,7 +230,7 @@ extension UIAlertController {
|
|||
let cancelAction = UIAlertAction(title: NSLocalizedString("_cancel_", comment: ""), style: .cancel)
|
||||
|
||||
alertController.addTextField { textField in
|
||||
textField.text = metadata.fileName
|
||||
textField.text = metadata.fileNameView
|
||||
textField.autocapitalizationType = .words
|
||||
}
|
||||
|
||||
|
@ -252,7 +253,7 @@ extension UIAlertController {
|
|||
queue: .main) { _ in
|
||||
guard let text = alertController.textFields?.first?.text else { return }
|
||||
|
||||
let textCheck = FileNameValidator.shared.checkFileName(text)
|
||||
let textCheck = FileNameValidator.shared.checkFileName(text, account: NCManageDatabase.shared.getActiveTableAccount()?.account)
|
||||
okAction.isEnabled = textCheck?.error == nil && !text.isEmpty
|
||||
alertController.message = textCheck?.error.localizedDescription
|
||||
}
|
||||
|
|
|
@ -26,9 +26,7 @@ import UIKit
|
|||
import Accelerate
|
||||
|
||||
extension UIImage {
|
||||
|
||||
@objc func resizeImage(size: CGSize, isAspectRation: Bool = true) -> UIImage? {
|
||||
|
||||
func resizeImage(size: CGSize, isAspectRation: Bool = true) -> UIImage? {
|
||||
let originRatio = self.size.width / self.size.height
|
||||
let newRatio = size.width / size.height
|
||||
var newSize = size
|
||||
|
@ -44,13 +42,9 @@ extension UIImage {
|
|||
}
|
||||
|
||||
UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
|
||||
self.draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
|
||||
let newImage = UIGraphicsGetImageFromCurrentImageContext()
|
||||
UIGraphicsEndImageContext()
|
||||
if let image = newImage {
|
||||
return image
|
||||
}
|
||||
return self
|
||||
self.draw(in: CGRect(origin: .zero, size: newSize))
|
||||
defer { UIGraphicsEndImageContext() }
|
||||
return UIGraphicsGetImageFromCurrentImageContext()
|
||||
}
|
||||
|
||||
func fixedOrientation() -> UIImage? {
|
||||
|
|
|
@ -33,7 +33,8 @@ class NCFavorite: NCCollectionViewCommon {
|
|||
layoutKey = NCGlobal.shared.layoutViewFavorite
|
||||
enableSearchBar = false
|
||||
headerRichWorkspaceDisable = true
|
||||
emptyImage = utility.loadImage(named: "star.fill", colors: [NCBrandColor.shared.yellowFavorite])
|
||||
emptyImageName = "star.fill"
|
||||
emptyImageColors = [NCBrandColor.shared.yellowFavorite]
|
||||
emptyTitle = "_favorite_no_files_"
|
||||
emptyDescription = "_tutorial_favorite_view_"
|
||||
}
|
||||
|
@ -43,43 +44,44 @@ class NCFavorite: NCCollectionViewCommon {
|
|||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
if dataSource.metadatas.isEmpty {
|
||||
reloadDataSource()
|
||||
}
|
||||
reloadDataSourceNetwork()
|
||||
reloadDataSource()
|
||||
}
|
||||
|
||||
// MARK: - DataSource + NC Endpoint
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
override func queryDB() {
|
||||
super.queryDB()
|
||||
getServerData()
|
||||
}
|
||||
|
||||
var metadatas: [tableMetadata] = []
|
||||
// MARK: - DataSource
|
||||
|
||||
override func reloadDataSource() {
|
||||
var predicate = self.defaultPredicate
|
||||
|
||||
if self.serverUrl.isEmpty {
|
||||
metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND favorite == true", self.appDelegate.account))
|
||||
} else {
|
||||
metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", self.appDelegate.account, self.serverUrl))
|
||||
predicate = NSPredicate(format: "account == %@ AND favorite == true", session.account)
|
||||
}
|
||||
|
||||
self.dataSource = NCDataSource(metadatas: metadatas, account: self.appDelegate.account, layoutForView: layoutForView, providers: self.providers, searchResults: self.searchResults)
|
||||
let results = self.database.getResultsMetadatasPredicate(predicate, layoutForView: layoutForView)
|
||||
self.dataSource = NCCollectionViewDataSource(results: results, layoutForView: layoutForView)
|
||||
|
||||
super.reloadDataSource()
|
||||
}
|
||||
|
||||
override func reloadDataSourceNetwork(withQueryDB: Bool = false) {
|
||||
super.reloadDataSourceNetwork()
|
||||
|
||||
NextcloudKit.shared.listingFavorites(showHiddenFiles: NCKeychain().showHiddenFiles, account: self.appDelegate.account, options: NKRequestOptions(queue: NextcloudKit.shared.nkCommonInstance.backgroundQueue)) { task in
|
||||
override func getServerData() {
|
||||
NextcloudKit.shared.listingFavorites(showHiddenFiles: NCKeychain().showHiddenFiles, account: session.account) { task in
|
||||
self.dataSourceTask = task
|
||||
self.collectionView.reloadData()
|
||||
} completion: { account, files, _, error in
|
||||
if error == .success {
|
||||
NCManageDatabase.shared.convertFilesToMetadatas(files, useFirstAsMetadataFolder: false) { _, metadatas in
|
||||
NCManageDatabase.shared.updateMetadatasFavorite(account: account, metadatas: metadatas)
|
||||
self.reloadDataSource()
|
||||
}
|
||||
} else {
|
||||
self.reloadDataSource(withQueryDB: withQueryDB)
|
||||
if self.dataSource.isEmpty() {
|
||||
self.collectionView.reloadData()
|
||||
}
|
||||
} completion: { account, files, _, error in
|
||||
if error == .success, let files {
|
||||
self.database.convertFilesToMetadatas(files, useFirstAsMetadataFolder: false) { _, metadatas in
|
||||
self.database.updateMetadatasFavorite(account: account, metadatas: metadatas)
|
||||
}
|
||||
self.reloadDataSource()
|
||||
}
|
||||
self.refreshControl.endRefreshing()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,11 +23,13 @@
|
|||
|
||||
import UIKit
|
||||
import NextcloudKit
|
||||
import RealmSwift
|
||||
|
||||
class NCFiles: NCCollectionViewCommon {
|
||||
internal var isRoot: Bool = true
|
||||
internal var fileNameBlink: String?
|
||||
internal var fileNameOpen: String?
|
||||
internal var matadatasHash: String = ""
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
|
@ -37,7 +39,6 @@ class NCFiles: NCCollectionViewCommon {
|
|||
enableSearchBar = true
|
||||
headerRichWorkspaceDisable = false
|
||||
headerMenuTransferView = true
|
||||
emptyImage = NCImageCache.images.folder
|
||||
emptyTitle = "_files_no_files_"
|
||||
emptyDescription = "_no_file_pull_down_"
|
||||
}
|
||||
|
@ -48,44 +49,65 @@ class NCFiles: NCCollectionViewCommon {
|
|||
super.viewDidLoad()
|
||||
|
||||
if isRoot {
|
||||
NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: NCGlobal.shared.notificationCenterChangeUser), object: nil, queue: nil) { _ in
|
||||
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 {
|
||||
if let controller = userInfo["controller"] as? NCMainTabBarController,
|
||||
controller == self.controller {
|
||||
controller.account = account
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
self.navigationController?.popToRootViewController(animated: false)
|
||||
|
||||
self.serverUrl = self.utilityFileSystem.getHomeServer(urlBase: self.appDelegate.urlBase, userId: self.appDelegate.userId)
|
||||
self.serverUrl = self.utilityFileSystem.getHomeServer(session: self.session)
|
||||
self.isSearchingMode = false
|
||||
self.isEditMode = false
|
||||
self.selectOcId.removeAll()
|
||||
self.fileSelect.removeAll()
|
||||
self.layoutForView = self.database.getLayoutForView(account: self.session.account, key: self.layoutKey, serverUrl: self.serverUrl)
|
||||
|
||||
self.layoutForView = NCManageDatabase.shared.getLayoutForView(account: self.appDelegate.account, key: self.layoutKey, serverUrl: self.serverUrl)
|
||||
if self.layoutForView?.layout == NCGlobal.shared.layoutList {
|
||||
if self.isLayoutList {
|
||||
self.collectionView?.collectionViewLayout = self.listLayout
|
||||
} else if self.layoutForView?.layout == NCGlobal.shared.layoutGrid {
|
||||
} else if self.isLayoutGrid {
|
||||
self.collectionView?.collectionViewLayout = self.gridLayout
|
||||
} else if self.layoutForView?.layout == NCGlobal.shared.layoutPhotoSquare || self.layoutForView?.layout == NCGlobal.shared.layoutPhotoRatio {
|
||||
} else if self.isLayoutPhoto {
|
||||
self.collectionView?.collectionViewLayout = self.mediaLayout
|
||||
}
|
||||
|
||||
self.titleCurrentFolder = self.getNavigationTitle()
|
||||
self.setNavigationLeftItems()
|
||||
|
||||
self.dataSource.removeAll()
|
||||
self.reloadDataSource()
|
||||
self.reloadDataSourceNetwork()
|
||||
self.getServerData()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
if isRoot {
|
||||
serverUrl = utilityFileSystem.getHomeServer(urlBase: appDelegate.urlBase, userId: appDelegate.userId)
|
||||
serverUrl = utilityFileSystem.getHomeServer(session: session)
|
||||
titleCurrentFolder = getNavigationTitle()
|
||||
}
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
if dataSource.metadatas.isEmpty {
|
||||
reloadDataSource(withQueryDB: true)
|
||||
reloadDataSource()
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
if !self.dataSource.isEmpty() {
|
||||
self.blinkCell(fileName: self.fileNameBlink)
|
||||
self.openFile(fileName: self.fileNameOpen)
|
||||
self.fileNameBlink = nil
|
||||
self.fileNameOpen = nil
|
||||
}
|
||||
|
||||
if !isSearchingMode {
|
||||
getServerData()
|
||||
}
|
||||
reloadDataSourceNetwork(withQueryDB: true)
|
||||
}
|
||||
|
||||
override func viewDidDisappear(_ animated: Bool) {
|
||||
|
@ -95,38 +117,36 @@ class NCFiles: NCCollectionViewCommon {
|
|||
fileNameOpen = nil
|
||||
}
|
||||
|
||||
// MARK: - DataSource + NC Endpoint
|
||||
// MARK: - DataSource
|
||||
|
||||
override func queryDB() {
|
||||
super.queryDB()
|
||||
override func reloadDataSource() {
|
||||
var predicate = self.defaultPredicate
|
||||
let predicateDirectory = NSPredicate(format: "account == %@ AND serverUrl == %@", session.account, self.serverUrl)
|
||||
let dataSourceMetadatas = self.dataSource.getMetadatas()
|
||||
|
||||
var metadatas: [tableMetadata] = []
|
||||
if NCKeychain().getPersonalFilesOnly(account: self.appDelegate.account) {
|
||||
metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND (ownerId == %@ || ownerId == '') AND mountType == ''", self.appDelegate.account, self.serverUrl, self.appDelegate.userId))
|
||||
} else {
|
||||
metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", self.appDelegate.account, self.serverUrl))
|
||||
}
|
||||
let directory = NCManageDatabase.shared.getTableDirectory(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", self.appDelegate.account, self.serverUrl))
|
||||
if self.metadataFolder == nil {
|
||||
self.metadataFolder = NCManageDatabase.shared.getMetadataFolder(account: self.appDelegate.account, urlBase: self.appDelegate.urlBase, userId: self.appDelegate.userId, serverUrl: self.serverUrl)
|
||||
if NCKeychain().getPersonalFilesOnly(account: session.account) {
|
||||
predicate = NSPredicate(format: "account == %@ AND serverUrl == %@ AND (ownerId == %@ || ownerId == '') AND mountType == '' AND NOT (status IN %@)", session.account, self.serverUrl, session.userId, global.metadataStatusHideInView)
|
||||
}
|
||||
|
||||
self.richWorkspaceText = directory?.richWorkspace
|
||||
self.dataSource = NCDataSource(metadatas: metadatas, account: self.appDelegate.account, layoutForView: layoutForView, providers: self.providers, searchResults: self.searchResults)
|
||||
}
|
||||
self.metadataFolder = database.getMetadataFolder(session: session, serverUrl: self.serverUrl)
|
||||
self.richWorkspaceText = database.getTableDirectory(predicate: predicateDirectory)?.richWorkspace
|
||||
|
||||
override func reloadDataSource(withQueryDB: Bool = true) {
|
||||
super.reloadDataSource(withQueryDB: withQueryDB)
|
||||
let results = self.database.getResultsMetadatasPredicate(predicate, layoutForView: layoutForView)
|
||||
self.dataSource = NCCollectionViewDataSource(results: results, layoutForView: layoutForView)
|
||||
|
||||
if !self.dataSource.metadatas.isEmpty {
|
||||
self.blinkCell(fileName: self.fileNameBlink)
|
||||
self.openFile(fileName: self.fileNameOpen)
|
||||
self.fileNameBlink = nil
|
||||
self.fileNameOpen = nil
|
||||
guard let results else {
|
||||
return super.reloadDataSource()
|
||||
}
|
||||
let metadatas = Array(results.freeze())
|
||||
|
||||
self.dataSource.caching(metadatas: metadatas, dataSourceMetadatas: dataSourceMetadatas) { updated in
|
||||
if updated || self.isNumberOfItemsInAllSectionsNull || self.numberOfItemsInAllSections != metadatas.count {
|
||||
super.reloadDataSource()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override func reloadDataSourceNetwork(withQueryDB: Bool = false) {
|
||||
override func getServerData() {
|
||||
if UIApplication.shared.applicationState == .background {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[DEBUG] Files not reload datasource network with the application in background")
|
||||
return
|
||||
|
@ -136,125 +156,137 @@ class NCFiles: NCCollectionViewCommon {
|
|||
}
|
||||
|
||||
func downloadMetadata(_ metadata: tableMetadata) -> Bool {
|
||||
|
||||
let fileSize = utilityFileSystem.fileProviderStorageSize(metadata.ocId, fileNameView: metadata.fileNameView)
|
||||
guard fileSize > 0 else { return false }
|
||||
|
||||
if let localFile = NCManageDatabase.shared.getResultsTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))?.first {
|
||||
if let localFile = database.getResultsTableLocalFile(predicate: NSPredicate(format: "ocId == %@", metadata.ocId))?.first {
|
||||
if localFile.etag != metadata.etag {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
super.reloadDataSourceNetwork()
|
||||
DispatchQueue.global().async {
|
||||
self.networkReadFolder { metadatas, isChanged, error in
|
||||
DispatchQueue.main.async {
|
||||
self.refreshControl.endRefreshing()
|
||||
|
||||
if isChanged || self.isNumberOfItemsInAllSectionsNull {
|
||||
self.reloadDataSource()
|
||||
}
|
||||
}
|
||||
|
||||
networkReadFolder { tableDirectory, metadatas, metadatasDifferentCount, metadatasModified, error in
|
||||
DispatchQueue.global(qos: .userInteractive).async {
|
||||
if error == .success {
|
||||
for metadata in metadatas ?? [] where !metadata.directory && downloadMetadata(metadata) {
|
||||
let metadatas: [tableMetadata] = metadatas ?? self.dataSource.getMetadatas()
|
||||
for metadata in metadatas where !metadata.directory && downloadMetadata(metadata) {
|
||||
if NCNetworking.shared.downloadQueue.operations.filter({ ($0 as? NCOperationDownload)?.metadata.ocId == metadata.ocId }).isEmpty {
|
||||
NCNetworking.shared.downloadQueue.addOperation(NCOperationDownload(metadata: metadata, selector: NCGlobal.shared.selectorDownloadFile))
|
||||
}
|
||||
}
|
||||
self.richWorkspaceText = tableDirectory?.richWorkspace
|
||||
if metadatasDifferentCount != 0 || metadatasModified != 0 {
|
||||
self.reloadDataSource()
|
||||
} else {
|
||||
self.reloadDataSource(withQueryDB: withQueryDB)
|
||||
}
|
||||
} else {
|
||||
self.reloadDataSource(withQueryDB: withQueryDB)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func networkReadFolder(completion: @escaping(_ tableDirectory: tableDirectory?, _ metadatas: [tableMetadata]?, _ metadatasDifferentCount: Int, _ metadatasModified: Int, _ error: NKError) -> Void) {
|
||||
var tableDirectory: tableDirectory?
|
||||
|
||||
NCNetworking.shared.readFile(serverUrlFileName: serverUrl, account: appDelegate.account) { task in
|
||||
private func networkReadFolder(completion: @escaping (_ metadatas: [tableMetadata]?, _ isDataChanged: Bool, _ error: NKError) -> Void) {
|
||||
NCNetworking.shared.readFile(serverUrlFileName: serverUrl, account: session.account) { task in
|
||||
self.dataSourceTask = task
|
||||
self.collectionView.reloadData()
|
||||
} completion: { account, metadata, error in
|
||||
guard error == .success, let metadata else {
|
||||
return completion(nil, nil, 0, 0, error)
|
||||
if self.dataSource.isEmpty() {
|
||||
self.collectionView.reloadData()
|
||||
}
|
||||
} completion: { account, metadata, error in
|
||||
let isDirectoryE2EE = NCUtilityFileSystem().isDirectoryE2EE(session: self.session, serverUrl: self.serverUrl)
|
||||
guard error == .success, let metadata else {
|
||||
return completion(nil, false, error)
|
||||
}
|
||||
/// Check change eTag or E2EE or DataSource empty
|
||||
let tableDirectory = self.database.setDirectory(serverUrl: self.serverUrl, richWorkspace: metadata.richWorkspace, account: account)
|
||||
guard tableDirectory?.etag != metadata.etag || metadata.e2eEncrypted || self.dataSource.isEmpty() else {
|
||||
return completion(nil, false, NKError())
|
||||
}
|
||||
/// Check Response DataC hanged
|
||||
var checkResponseDataChanged = true
|
||||
if tableDirectory?.etag.isEmpty ?? true || isDirectoryE2EE {
|
||||
checkResponseDataChanged = false
|
||||
}
|
||||
tableDirectory = NCManageDatabase.shared.setDirectory(serverUrl: self.serverUrl, richWorkspace: metadata.richWorkspace, account: account)
|
||||
// swiftlint:disable empty_string
|
||||
let forceReplaceMetadatas = tableDirectory?.etag == ""
|
||||
// swiftlint:enable empty_string
|
||||
|
||||
if tableDirectory?.etag != metadata.etag || metadata.e2eEncrypted {
|
||||
NCNetworking.shared.readFolder(serverUrl: self.serverUrl,
|
||||
account: self.appDelegate.account,
|
||||
forceReplaceMetadatas: forceReplaceMetadatas) { task in
|
||||
self.dataSourceTask = task
|
||||
NCNetworking.shared.readFolder(serverUrl: self.serverUrl,
|
||||
account: metadata.account,
|
||||
checkResponseDataChanged: checkResponseDataChanged,
|
||||
queue: NextcloudKit.shared.nkCommonInstance.backgroundQueue) { task in
|
||||
self.dataSourceTask = task
|
||||
if self.dataSource.isEmpty() {
|
||||
self.collectionView.reloadData()
|
||||
} completion: { account, metadataFolder, metadatas, metadatasDifferentCount, metadatasModified, error in
|
||||
guard account == self.appDelegate.account, error == .success else {
|
||||
return completion(tableDirectory, nil, 0, 0, error)
|
||||
}
|
||||
}
|
||||
} completion: { account, metadataFolder, metadatas, isDataChanged, error in
|
||||
/// Error
|
||||
guard error == .success else {
|
||||
return completion(nil, false, error)
|
||||
}
|
||||
/// Updata folder
|
||||
if let metadataFolder {
|
||||
self.metadataFolder = metadataFolder
|
||||
// E2EE
|
||||
if let metadataFolder = metadataFolder,
|
||||
metadataFolder.e2eEncrypted,
|
||||
NCKeychain().isEndToEndEnabled(account: account),
|
||||
!NCNetworkingE2EE().isInUpload(account: account, serverUrl: self.serverUrl) {
|
||||
let lock = NCManageDatabase.shared.getE2ETokenLock(account: account, serverUrl: self.serverUrl)
|
||||
NCNetworkingE2EE().getMetadata(fileId: metadataFolder.ocId, e2eToken: lock?.e2eToken, account: account) { account, version, e2eMetadata, signature, _, error in
|
||||
if account == self.appDelegate.account, error == .success, let e2eMetadata = e2eMetadata {
|
||||
let error = NCEndToEndMetadata().decodeMetadata(e2eMetadata, signature: signature, serverUrl: self.serverUrl, account: account, urlBase: self.appDelegate.urlBase, userId: self.appDelegate.userId)
|
||||
if error == .success {
|
||||
if version == "v1", NCGlobal.shared.capabilityE2EEApiVersion == NCGlobal.shared.e2eeVersionV20 {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[E2EE] Conversion v1 to v2")
|
||||
NCActivityIndicator.shared.start()
|
||||
Task {
|
||||
let serverUrl = metadataFolder.serverUrl + "/" + metadataFolder.fileName
|
||||
let error = await NCNetworkingE2EE().uploadMetadata(account: metadataFolder.account, serverUrl: serverUrl, userId: metadataFolder.userId, updateVersionV1V2: true)
|
||||
if error != .success {
|
||||
NCContentPresenter().showError(error: error)
|
||||
}
|
||||
NCActivityIndicator.shared.stop()
|
||||
self.reloadDataSource()
|
||||
}
|
||||
} else {
|
||||
self.reloadDataSource()
|
||||
}
|
||||
} else {
|
||||
// Client Diagnostic
|
||||
NCManageDatabase.shared.addDiagnostic(account: account, issue: NCGlobal.shared.diagnosticIssueE2eeErrors)
|
||||
NCContentPresenter().showError(error: error)
|
||||
}
|
||||
} else if error.errorCode == NCGlobal.shared.errorResourceNotFound {
|
||||
// no metadata found, send a new metadata
|
||||
self.richWorkspaceText = metadataFolder.richWorkspace
|
||||
}
|
||||
/// check Response Data Changed
|
||||
if !isDataChanged {
|
||||
return completion(nil, false, error)
|
||||
}
|
||||
|
||||
guard let metadataFolder,
|
||||
isDirectoryE2EE,
|
||||
NCKeychain().isEndToEndEnabled(account: account),
|
||||
!NCNetworkingE2EE().isInUpload(account: account, serverUrl: self.serverUrl) else {
|
||||
return completion(metadatas, true, error)
|
||||
}
|
||||
|
||||
/// E2EE
|
||||
let lock = self.database.getE2ETokenLock(account: account, serverUrl: self.serverUrl)
|
||||
NCNetworkingE2EE().getMetadata(fileId: metadataFolder.ocId, e2eToken: lock?.e2eToken, account: account) { account, version, e2eMetadata, signature, _, error in
|
||||
|
||||
if error == .success, let e2eMetadata = e2eMetadata {
|
||||
let error = NCEndToEndMetadata().decodeMetadata(e2eMetadata, signature: signature, serverUrl: self.serverUrl, session: self.session)
|
||||
|
||||
if error == .success {
|
||||
if version == "v1", NCCapabilities.shared.getCapabilities(account: account).capabilityE2EEApiVersion == NCGlobal.shared.e2eeVersionV20 {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[E2EE] Conversion v1 to v2")
|
||||
NCActivityIndicator.shared.start()
|
||||
Task {
|
||||
let serverUrl = metadataFolder.serverUrl + "/" + metadataFolder.fileName
|
||||
let error = await NCNetworkingE2EE().uploadMetadata(account: metadataFolder.account, serverUrl: serverUrl, userId: metadataFolder.userId)
|
||||
let error = await NCNetworkingE2EE().uploadMetadata(serverUrl: serverUrl, updateVersionV1V2: true, account: account)
|
||||
if error != .success {
|
||||
NCContentPresenter().showError(error: error)
|
||||
}
|
||||
NCActivityIndicator.shared.stop()
|
||||
}
|
||||
} else {
|
||||
NCContentPresenter().showError(error: NKError(errorCode: NCGlobal.shared.errorE2EEKeyDecodeMetadata, errorDescription: "_e2e_error_"))
|
||||
}
|
||||
completion(tableDirectory, metadatas, metadatasDifferentCount, metadatasModified, error)
|
||||
} else {
|
||||
// Client Diagnostic
|
||||
self.database.addDiagnostic(account: account, issue: NCGlobal.shared.diagnosticIssueE2eeErrors)
|
||||
NCContentPresenter().showError(error: error)
|
||||
}
|
||||
} else if error.errorCode == NCGlobal.shared.errorResourceNotFound {
|
||||
// no metadata found, send a new metadata
|
||||
Task {
|
||||
let serverUrl = metadataFolder.serverUrl + "/" + metadataFolder.fileName
|
||||
let error = await NCNetworkingE2EE().uploadMetadata(serverUrl: serverUrl, account: account)
|
||||
if error != .success {
|
||||
NCContentPresenter().showError(error: error)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
completion(tableDirectory, metadatas, metadatasDifferentCount, metadatasModified, error)
|
||||
NCContentPresenter().showError(error: NKError(errorCode: NCGlobal.shared.errorE2EEKeyDecodeMetadata, errorDescription: "_e2e_error_"))
|
||||
}
|
||||
completion(metadatas, true, error)
|
||||
}
|
||||
} else {
|
||||
completion(tableDirectory, nil, 0, 0, NKError())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func blinkCell(fileName: String?) {
|
||||
if let fileName = fileName, let metadata = NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileName == %@", self.appDelegate.account, self.serverUrl, fileName)) {
|
||||
let (indexPath, _) = self.dataSource.getIndexPathMetadata(ocId: metadata.ocId)
|
||||
if let fileName = fileName, let metadata = database.getMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileName == %@", session.account, self.serverUrl, fileName)) {
|
||||
let indexPath = self.dataSource.getIndexPathMetadata(ocId: metadata.ocId)
|
||||
if let indexPath = indexPath {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
UIView.animate(withDuration: 0.3) {
|
||||
|
@ -273,8 +305,8 @@ class NCFiles: NCCollectionViewCommon {
|
|||
}
|
||||
|
||||
func openFile(fileName: String?) {
|
||||
if let fileName = fileName, let metadata = NCManageDatabase.shared.getMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileName == %@", self.appDelegate.account, self.serverUrl, fileName)) {
|
||||
let (indexPath, _) = self.dataSource.getIndexPathMetadata(ocId: metadata.ocId)
|
||||
if let fileName = fileName, let metadata = database.getMetadata(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@ AND fileName == %@", session.account, self.serverUrl, fileName)) {
|
||||
let indexPath = self.dataSource.getIndexPathMetadata(ocId: metadata.ocId)
|
||||
if let indexPath = indexPath {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
self.collectionView(self.collectionView, didSelectItemAt: indexPath)
|
||||
|
@ -285,11 +317,12 @@ class NCFiles: NCCollectionViewCommon {
|
|||
|
||||
// MARK: - NCAccountSettingsModelDelegate
|
||||
|
||||
override func accountSettingsDidDismiss(tableAccount: tableAccount?) {
|
||||
if NCManageDatabase.shared.getAllAccount().isEmpty {
|
||||
appDelegate.openLogin(selector: NCGlobal.shared.introLogin, openLoginWeb: false)
|
||||
} else if let account = tableAccount?.account, account != appDelegate.account {
|
||||
appDelegate.changeAccount(account, userProfile: nil) { }
|
||||
override func accountSettingsDidDismiss(tableAccount: tableAccount?, controller: NCMainTabBarController?) {
|
||||
let currentAccount = session.account
|
||||
if database.getAllTableAccount().isEmpty {
|
||||
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
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
import SwiftUI
|
||||
|
||||
struct TextFieldClearButton: ViewModifier {
|
||||
|
||||
@Binding var text: String
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
|
@ -44,15 +43,15 @@ struct TextFieldClearButton: ViewModifier {
|
|||
}
|
||||
|
||||
struct ButtonRounded: ButtonStyle {
|
||||
|
||||
var disabled = false
|
||||
var account = ""
|
||||
|
||||
func makeBody(configuration: Configuration) -> some View {
|
||||
configuration.label
|
||||
.padding(.horizontal, 40)
|
||||
.padding(.vertical, 10)
|
||||
.background(disabled ? Color(UIColor.placeholderText) : Color(NCBrandColor.shared.brandElement))
|
||||
.foregroundColor(disabled ? Color(UIColor.placeholderText) : Color(NCBrandColor.shared.brandText))
|
||||
.background(disabled ? Color(UIColor.placeholderText) : Color(NCBrandColor.shared.getElement(account: account)))
|
||||
.foregroundColor(disabled ? Color(UIColor.placeholderText) : Color(NCBrandColor.shared.getText(account: account)))
|
||||
.clipShape(Capsule())
|
||||
.opacity(configuration.isPressed ? 0.5 : 1.0)
|
||||
}
|
||||
|
|
|
@ -23,11 +23,11 @@
|
|||
|
||||
import SwiftUI
|
||||
|
||||
struct HUDView: View {
|
||||
|
||||
struct NCHUDView: View {
|
||||
@Binding var showHUD: Bool
|
||||
@State var textLabel: String
|
||||
@State var image: String
|
||||
@State var color: UIColor
|
||||
|
||||
var body: some View {
|
||||
Button(action: {
|
||||
|
@ -40,7 +40,7 @@ struct HUDView: View {
|
|||
.padding(.horizontal, 10)
|
||||
.padding(14)
|
||||
.background(
|
||||
Blur(style: .regular)
|
||||
Blur(style: .regular, color: color)
|
||||
.clipShape(Capsule())
|
||||
.shadow(color: Color(.black).opacity(0.22), radius: 12, x: 0, y: 5)
|
||||
)
|
||||
|
@ -49,12 +49,12 @@ struct HUDView: View {
|
|||
}
|
||||
|
||||
struct Blur: UIViewRepresentable {
|
||||
|
||||
var style: UIBlurEffect.Style
|
||||
var color: UIColor
|
||||
|
||||
func makeUIView(context: Context) -> UIVisualEffectView {
|
||||
let effectView = UIVisualEffectView(effect: UIBlurEffect(style: style))
|
||||
effectView.backgroundColor = NCBrandColor.shared.brandElement
|
||||
effectView.backgroundColor = color
|
||||
return effectView
|
||||
}
|
||||
|
||||
|
@ -64,8 +64,8 @@ struct Blur: UIViewRepresentable {
|
|||
}
|
||||
|
||||
struct ContentView: View {
|
||||
|
||||
@State private var showHUD = false
|
||||
@State var color: UIColor
|
||||
@Namespace var hudAnimation
|
||||
|
||||
func dismissHUDAfterTime() {
|
||||
|
@ -83,14 +83,10 @@ struct ContentView: View {
|
|||
}
|
||||
.navigationTitle("Content View")
|
||||
}
|
||||
HUDView(showHUD: $showHUD, textLabel: NSLocalizedString("_wait_", comment: ""), image: "doc.badge.arrow.up")
|
||||
NCHUDView(showHUD: $showHUD, textLabel: NSLocalizedString("_wait_", comment: ""), image: "doc.badge.arrow.up", color: color)
|
||||
.offset(y: showHUD ? (geo.size.height / 2) : -200)
|
||||
.animation(.easeOut, value: showHUD)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
ContentView()
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
//
|
||||
// NCHud.swift
|
||||
// Nextcloud
|
||||
//
|
||||
// Created by Marino Faggiana on 04/09/24.
|
||||
// Copyright © 2024 Marino Faggiana. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import UIKit
|
||||
import JGProgressHUD
|
||||
|
||||
class NCHud: NSObject {
|
||||
private let hud = JGProgressHUD()
|
||||
private var view: UIView?
|
||||
|
||||
public init(_ view: UIView? = nil) {
|
||||
if let view {
|
||||
self.view = view
|
||||
}
|
||||
super.init()
|
||||
}
|
||||
|
||||
func initHud(view: UIView? = nil, text: String? = nil, detailText: String? = nil) {
|
||||
DispatchQueue.main.async {
|
||||
if let view {
|
||||
self.view = view
|
||||
}
|
||||
|
||||
self.hud.indicatorView = JGProgressHUDIndicatorView()
|
||||
|
||||
self.hud.textLabel.text = text
|
||||
self.hud.textLabel.textColor = NCBrandColor.shared.iconImageColor
|
||||
|
||||
self.hud.detailTextLabel.text = detailText
|
||||
self.hud.detailTextLabel.textColor = NCBrandColor.shared.iconImageColor2
|
||||
|
||||
if let view = self.view {
|
||||
self.hud.show(in: view)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func initHudRing(view: UIView? = nil, text: String? = nil, detailText: String? = nil, tapToCancelDetailText: Bool = false, tapOperation: (() -> Void)? = nil) {
|
||||
DispatchQueue.main.async {
|
||||
self.hud.tapOnHUDViewBlock = { hud in
|
||||
if let tapOperation {
|
||||
tapOperation()
|
||||
hud.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
if let view {
|
||||
self.view = view
|
||||
}
|
||||
|
||||
self.hud.indicatorView = JGProgressHUDRingIndicatorView()
|
||||
self.hud.progress = 0.0
|
||||
|
||||
let indicatorView = self.hud.indicatorView as? JGProgressHUDRingIndicatorView
|
||||
indicatorView?.ringWidth = 1.5
|
||||
indicatorView?.ringColor = NCBrandColor.shared.iconImageColor
|
||||
|
||||
self.hud.textLabel.text = text
|
||||
self.hud.textLabel.textColor = NCBrandColor.shared.iconImageColor
|
||||
|
||||
if tapToCancelDetailText {
|
||||
self.hud.detailTextLabel.text = NSLocalizedString("_tap_to_cancel_", comment: "")
|
||||
} else {
|
||||
self.hud.detailTextLabel.text = detailText
|
||||
}
|
||||
self.hud.detailTextLabel.textColor = NCBrandColor.shared.iconImageColor2
|
||||
|
||||
if let view = self.view {
|
||||
self.hud.show(in: view)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func dismiss() {
|
||||
DispatchQueue.main.async {
|
||||
self.hud.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
func show() {
|
||||
DispatchQueue.main.async {
|
||||
if let view = self.view {
|
||||
self.hud.show(in: view)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func progress(num: Float, total: Float) {
|
||||
DispatchQueue.main.async {
|
||||
self.hud.progress = num / total
|
||||
}
|
||||
}
|
||||
|
||||
func progress(_ progress: Double) {
|
||||
DispatchQueue.main.async {
|
||||
self.hud.progress = Float(progress)
|
||||
}
|
||||
}
|
||||
|
||||
func success() {
|
||||
DispatchQueue.main.async {
|
||||
self.hud.indicatorView = JGProgressHUDSuccessIndicatorView()
|
||||
self.hud.indicatorView?.tintColor = .green
|
||||
self.hud.textLabel.text = NSLocalizedString("_success_", comment: "")
|
||||
self.hud.detailTextLabel.text = nil
|
||||
self.hud.dismiss(afterDelay: 1.0)
|
||||
}
|
||||
}
|
||||
|
||||
func error(text: String?) {
|
||||
DispatchQueue.main.async {
|
||||
self.hud.indicatorView = JGProgressHUDErrorIndicatorView()
|
||||
self.hud.indicatorView?.tintColor = .red
|
||||
self.hud.textLabel.text = text
|
||||
self.hud.dismiss(afterDelay: 2.0)
|
||||
}
|
||||
}
|
||||
|
||||
func setText(text: String?, detailText: String? = nil) {
|
||||
DispatchQueue.main.async {
|
||||
self.hud.textLabel.text = text
|
||||
self.hud.detailTextLabel.text = detailText
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
import UIKit
|
||||
import NextcloudKit
|
||||
import RealmSwift
|
||||
|
||||
class NCGroupfolders: NCCollectionViewCommon {
|
||||
|
||||
|
@ -33,7 +34,7 @@ class NCGroupfolders: NCCollectionViewCommon {
|
|||
layoutKey = NCGlobal.shared.layoutViewGroupfolders
|
||||
enableSearchBar = false
|
||||
headerRichWorkspaceDisable = true
|
||||
emptyImage = utility.loadImage(named: "folder_group", colors: [NCBrandColor.shared.brandElement])
|
||||
emptyImageName = "folder_group"
|
||||
emptyTitle = "_files_no_files_"
|
||||
emptyDescription = "_tutorial_groupfolders_view_"
|
||||
}
|
||||
|
@ -43,58 +44,59 @@ class NCGroupfolders: NCCollectionViewCommon {
|
|||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
if dataSource.metadatas.isEmpty {
|
||||
reloadDataSource()
|
||||
}
|
||||
reloadDataSourceNetwork()
|
||||
reloadDataSource()
|
||||
}
|
||||
|
||||
// MARK: - DataSource + NC Endpoint
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
override func queryDB() {
|
||||
super.queryDB()
|
||||
getServerData()
|
||||
}
|
||||
|
||||
var metadatas: [tableMetadata] = []
|
||||
// MARK: - DataSource
|
||||
|
||||
override func reloadDataSource() {
|
||||
var results: Results<tableMetadata>?
|
||||
|
||||
if self.serverUrl.isEmpty {
|
||||
metadatas = NCManageDatabase.shared.getMetadatasFromGroupfolders(account: self.appDelegate.account, urlBase: self.appDelegate.urlBase, userId: self.appDelegate.userId)
|
||||
results = database.getResultsMetadatasFromGroupfolders(session: session)
|
||||
} else {
|
||||
metadatas = NCManageDatabase.shared.getMetadatas(predicate: NSPredicate(format: "account == %@ AND serverUrl == %@", self.appDelegate.account, self.serverUrl))
|
||||
results = self.database.getResultsMetadatasPredicate(self.defaultPredicate, layoutForView: layoutForView)
|
||||
}
|
||||
|
||||
self.dataSource = NCDataSource(metadatas: metadatas, account: self.appDelegate.account, layoutForView: layoutForView, providers: self.providers, searchResults: self.searchResults)
|
||||
self.dataSource = NCCollectionViewDataSource(results: results, layoutForView: layoutForView)
|
||||
|
||||
super.reloadDataSource()
|
||||
}
|
||||
|
||||
override func reloadDataSourceNetwork(withQueryDB: Bool = false) {
|
||||
super.reloadDataSourceNetwork()
|
||||
override func getServerData() {
|
||||
let homeServerUrl = utilityFileSystem.getHomeServer(session: session)
|
||||
|
||||
let homeServerUrl = utilityFileSystem.getHomeServer(urlBase: self.appDelegate.urlBase, userId: self.appDelegate.userId)
|
||||
|
||||
NextcloudKit.shared.getGroupfolders(account: self.appDelegate.account, options: NKRequestOptions(queue: NextcloudKit.shared.nkCommonInstance.backgroundQueue)) { task in
|
||||
NextcloudKit.shared.getGroupfolders(account: session.account) { task in
|
||||
self.dataSourceTask = task
|
||||
self.collectionView.reloadData()
|
||||
if self.dataSource.isEmpty() {
|
||||
self.collectionView.reloadData()
|
||||
}
|
||||
} completion: { account, results, _, error in
|
||||
if error == .success, let groupfolders = results {
|
||||
NCManageDatabase.shared.addGroupfolders(account: account, groupfolders: groupfolders)
|
||||
self.database.addGroupfolders(account: account, groupfolders: groupfolders)
|
||||
Task {
|
||||
for groupfolder in groupfolders {
|
||||
let mountPoint = groupfolder.mountPoint.hasPrefix("/") ? groupfolder.mountPoint : "/" + groupfolder.mountPoint
|
||||
let serverUrlFileName = homeServerUrl + mountPoint
|
||||
if NCManageDatabase.shared.getMetadataFromDirectory(account: self.appDelegate.account, serverUrl: serverUrlFileName) == nil {
|
||||
let results = await NCNetworking.shared.readFileOrFolder(serverUrlFileName: serverUrlFileName, depth: "0", showHiddenFiles: NCKeychain().showHiddenFiles, account: account)
|
||||
if results.error == .success, let file = results.files.first {
|
||||
let isDirectoryE2EE = self.utilityFileSystem.isDirectoryE2EE(file: file)
|
||||
let metadata = NCManageDatabase.shared.convertFileToMetadata(file, isDirectoryE2EE: isDirectoryE2EE)
|
||||
NCManageDatabase.shared.addMetadata(metadata)
|
||||
NCManageDatabase.shared.addDirectory(e2eEncrypted: isDirectoryE2EE, favorite: metadata.favorite, ocId: metadata.ocId, fileId: metadata.fileId, permissions: metadata.permissions, serverUrl: serverUrlFileName, account: metadata.account)
|
||||
}
|
||||
let results = await NCNetworking.shared.readFileOrFolder(serverUrlFileName: serverUrlFileName, depth: "0", showHiddenFiles: NCKeychain().showHiddenFiles, account: account)
|
||||
|
||||
if results.error == .success, let file = results.files?.first {
|
||||
let isDirectoryE2EE = self.utilityFileSystem.isDirectoryE2EE(file: file)
|
||||
let metadata = self.database.convertFileToMetadata(file, isDirectoryE2EE: isDirectoryE2EE)
|
||||
self.database.addMetadata(metadata)
|
||||
self.database.addDirectory(e2eEncrypted: isDirectoryE2EE, favorite: metadata.favorite, ocId: metadata.ocId, fileId: metadata.fileId, permissions: metadata.permissions, serverUrl: serverUrlFileName, account: metadata.account)
|
||||
}
|
||||
}
|
||||
self.reloadDataSource()
|
||||
}
|
||||
} else {
|
||||
self.reloadDataSource(withQueryDB: withQueryDB)
|
||||
}
|
||||
self.refreshControl.endRefreshing()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="23094" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina6_9" orientation="portrait" appearance="dark"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22685"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23084"/>
|
||||
<capability name="Image references" minToolsVersion="12.0"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
|
@ -13,18 +15,18 @@
|
|||
<objects>
|
||||
<viewController storyboardIdentifier="NCLogin" id="yj9-jo-WIn" customClass="NCLogin" customModule="Nextcloud" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="Bv6-g3-l0M">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="440" height="956"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="BpI-xK-1SU">
|
||||
<rect key="frame" x="87" y="226.5" width="240" height="120"/>
|
||||
<rect key="frame" x="100" y="241.66666666666663" width="240" height="120"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="120" id="E9d-5O-bto"/>
|
||||
<constraint firstAttribute="width" constant="240" id="xwH-mh-yDU"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<textField opaque="NO" clipsSubviews="YES" tag="1" contentMode="scaleToFill" layoutMarginsFollowReadableWidth="YES" insetsLayoutMarginsFromSafeArea="NO" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder=" Server address https://…" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="szn-G7-5sK">
|
||||
<rect key="frame" x="50" y="376.5" width="314" height="44"/>
|
||||
<rect key="frame" x="50" y="391.66666666666669" width="340" height="44"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="44" id="I2v-Zr-IWf"/>
|
||||
</constraints>
|
||||
|
@ -33,7 +35,7 @@
|
|||
<textInputTraits key="textInputTraits" autocorrectionType="no" keyboardType="URL" returnKeyType="done"/>
|
||||
</textField>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="HQd-pF-3cE">
|
||||
<rect key="frame" x="324" y="378.5" width="40" height="40"/>
|
||||
<rect key="frame" x="350" y="393.66666666666669" width="40" height="40"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="40" id="3yh-bo-Bzr"/>
|
||||
|
@ -42,36 +44,35 @@
|
|||
<color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<state key="normal">
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<imageReference key="image" image="arrow.right" catalog="system" symbolScale="large"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="actionButtonLogin:" destination="yj9-jo-WIn" eventType="touchUpInside" id="vFP-SJ-rFq"/>
|
||||
</connections>
|
||||
</button>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Al0-LA-Ndt">
|
||||
<rect key="frame" x="334" y="388.5" width="20" height="20"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="20" id="IQA-ga-jx5"/>
|
||||
<constraint firstAttribute="width" constant="20" id="hVA-N5-u88"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="The link to your Nextcloud web interface when you open it in the browser." textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="PJH-5i-Tkf">
|
||||
<rect key="frame" x="60" y="438.5" width="294" height="29"/>
|
||||
<rect key="frame" x="60" y="453.66666666666669" width="320" height="28.666666666666686"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="12"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6tp-bh-Z9k" userLabel="QRCode">
|
||||
<rect key="frame" x="182" y="567.5" width="50" height="50"/>
|
||||
<button contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6tp-bh-Z9k" userLabel="QRCode">
|
||||
<rect key="frame" x="192.66666666666663" y="582.33333333333337" width="55.000000000000028" height="50"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="50" id="3hb-Ez-hOz"/>
|
||||
<constraint firstAttribute="width" constant="55" id="3hb-Ez-hOz"/>
|
||||
<constraint firstAttribute="height" constant="50" id="OLT-tb-4Qb"/>
|
||||
</constraints>
|
||||
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal">
|
||||
<imageReference key="image" image="qrcode.viewfinder" catalog="system" symbolScale="default"/>
|
||||
<preferredSymbolConfiguration key="preferredSymbolConfiguration" configurationType="pointSize" pointSize="50" scale="large"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="actionQRCode:" destination="yj9-jo-WIn" eventType="touchUpInside" id="qwL-rG-ead"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="5lM-dt-8fM">
|
||||
<rect key="frame" x="182" y="667.5" width="50" height="50"/>
|
||||
<rect key="frame" x="195" y="682.33333333333337" width="50" height="50"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="50" id="0RD-Gi-CTv"/>
|
||||
<constraint firstAttribute="width" constant="50" id="NuK-Yo-LoT"/>
|
||||
|
@ -80,9 +81,29 @@
|
|||
<action selector="actionCertificate:" destination="yj9-jo-WIn" eventType="touchUpInside" id="Ibx-wC-iEY"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" buttonType="system" lineBreakMode="tailTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="IXM-eK-wKA" userLabel="Choose Server">
|
||||
<rect key="frame" x="50" y="391.66666666666669" width="290" height="44"/>
|
||||
<color key="backgroundColor" white="1" alpha="0.40478847789115646" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="44" id="k9B-my-RAo"/>
|
||||
</constraints>
|
||||
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<inset key="contentEdgeInsets" minX="0.0" minY="0.0" maxX="35" maxY="0.0"/>
|
||||
<inset key="titleEdgeInsets" minX="10" minY="0.0" maxX="0.0" maxY="0.0"/>
|
||||
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
|
||||
<state key="normal" title="Name 1"/>
|
||||
</button>
|
||||
<imageView hidden="YES" opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="arrowtriangle.down.circle" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="rza-UC-nsA">
|
||||
<rect key="frame" x="310" y="403.66666666666669" width="20" height="19.666666666666686"/>
|
||||
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="20" id="Y46-VP-7nh"/>
|
||||
<constraint firstAttribute="height" constant="21" id="boa-1i-a6E"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<viewLayoutGuide key="safeArea" id="8lf-3Y-f5R"/>
|
||||
<color key="backgroundColor" white="0.9023259132753424" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<color key="backgroundColor" systemColor="tintColor"/>
|
||||
<constraints>
|
||||
<constraint firstItem="8lf-3Y-f5R" firstAttribute="trailing" secondItem="szn-G7-5sK" secondAttribute="trailing" constant="50" id="24L-p4-zOF"/>
|
||||
<constraint firstItem="PJH-5i-Tkf" firstAttribute="leading" secondItem="8lf-3Y-f5R" secondAttribute="leading" constant="60" id="3aW-cF-rdF"/>
|
||||
|
@ -90,27 +111,33 @@
|
|||
<constraint firstItem="6tp-bh-Z9k" firstAttribute="centerX" secondItem="8lf-3Y-f5R" secondAttribute="centerX" id="Apc-1U-CwU"/>
|
||||
<constraint firstItem="BpI-xK-1SU" firstAttribute="top" secondItem="Bv6-g3-l0M" secondAttribute="centerY" multiplier="0.5" constant="2.5" id="Gkg-up-7eW"/>
|
||||
<constraint firstItem="8lf-3Y-f5R" firstAttribute="centerX" secondItem="BpI-xK-1SU" secondAttribute="centerX" id="IxG-UI-0vq"/>
|
||||
<constraint firstItem="rza-UC-nsA" firstAttribute="top" secondItem="BpI-xK-1SU" secondAttribute="bottom" constant="41.5" id="MS5-cH-8Ea"/>
|
||||
<constraint firstItem="6tp-bh-Z9k" firstAttribute="top" secondItem="PJH-5i-Tkf" secondAttribute="bottom" constant="100" id="MZQ-GT-XSM"/>
|
||||
<constraint firstItem="IXM-eK-wKA" firstAttribute="leading" secondItem="8lf-3Y-f5R" secondAttribute="leading" constant="50" id="SE6-52-VoG"/>
|
||||
<constraint firstItem="PJH-5i-Tkf" firstAttribute="top" secondItem="szn-G7-5sK" secondAttribute="bottom" constant="18" id="Vfj-lG-7wT"/>
|
||||
<constraint firstItem="Al0-LA-Ndt" firstAttribute="centerX" secondItem="HQd-pF-3cE" secondAttribute="centerX" id="Yll-3L-vuj"/>
|
||||
<constraint firstItem="HQd-pF-3cE" firstAttribute="centerY" secondItem="szn-G7-5sK" secondAttribute="centerY" id="cG8-kL-pdu"/>
|
||||
<constraint firstItem="Al0-LA-Ndt" firstAttribute="centerY" secondItem="HQd-pF-3cE" secondAttribute="centerY" id="eOF-06-PmZ"/>
|
||||
<constraint firstItem="5lM-dt-8fM" firstAttribute="top" secondItem="6tp-bh-Z9k" secondAttribute="bottom" constant="50" id="i5K-Jt-epF"/>
|
||||
<constraint firstItem="szn-G7-5sK" firstAttribute="top" secondItem="BpI-xK-1SU" secondAttribute="bottom" constant="30" id="lWz-Yy-NCO"/>
|
||||
<constraint firstItem="5lM-dt-8fM" firstAttribute="centerX" secondItem="8lf-3Y-f5R" secondAttribute="centerX" id="mKe-Nn-9dd"/>
|
||||
<constraint firstItem="HQd-pF-3cE" firstAttribute="leading" secondItem="IXM-eK-wKA" secondAttribute="trailing" constant="30" id="p5X-FY-AQg">
|
||||
<variation key="widthClass=compact" constant="10"/>
|
||||
</constraint>
|
||||
<constraint firstItem="IXM-eK-wKA" firstAttribute="top" secondItem="BpI-xK-1SU" secondAttribute="bottom" constant="30" id="sBQ-Q7-GKc"/>
|
||||
<constraint firstItem="szn-G7-5sK" firstAttribute="leading" secondItem="8lf-3Y-f5R" secondAttribute="leading" constant="50" id="uQw-dy-Ga4"/>
|
||||
<constraint firstItem="IXM-eK-wKA" firstAttribute="trailing" secondItem="rza-UC-nsA" secondAttribute="trailing" constant="10" id="zD5-gc-sHh"/>
|
||||
<constraint firstItem="8lf-3Y-f5R" firstAttribute="trailing" secondItem="PJH-5i-Tkf" secondAttribute="trailing" constant="60" id="zzV-UD-gRV"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<navigationItem key="navigationItem" id="6v9-Gy-jiv"/>
|
||||
<connections>
|
||||
<outlet property="baseUrl" destination="szn-G7-5sK" id="rpO-mh-09O"/>
|
||||
<outlet property="baseUrlTextField" destination="szn-G7-5sK" id="rpO-mh-09O"/>
|
||||
<outlet property="certificate" destination="5lM-dt-8fM" id="vw6-cH-njm"/>
|
||||
<outlet property="enforceServersButton" destination="IXM-eK-wKA" id="Ezu-3y-iDa"/>
|
||||
<outlet property="enforceServersDropdownImage" destination="rza-UC-nsA" id="eWk-Ww-vJM"/>
|
||||
<outlet property="imageBrand" destination="BpI-xK-1SU" id="0tB-69-RNs"/>
|
||||
<outlet property="imageBrandConstraintY" destination="Gkg-up-7eW" id="RKw-pM-dZr"/>
|
||||
<outlet property="loginAddressDetail" destination="PJH-5i-Tkf" id="wBQ-5P-HD4"/>
|
||||
<outlet property="loginButton" destination="HQd-pF-3cE" id="XOc-dS-QZ8"/>
|
||||
<outlet property="loginImage" destination="Al0-LA-Ndt" id="dT5-vu-5eD"/>
|
||||
<outlet property="qrCode" destination="6tp-bh-Z9k" id="Tw3-op-BgR"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
|
@ -123,7 +150,7 @@
|
|||
<objects>
|
||||
<viewController storyboardIdentifier="NCLoginProvider" id="yEb-Ky-35s" customClass="NCLoginProvider" customModule="Nextcloud" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="UX5-cJ-bY6">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="440" height="956"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<viewLayoutGuide key="safeArea" id="vqz-4v-cZu"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
|
@ -134,4 +161,12 @@
|
|||
<point key="canvasLocation" x="5421.739130434783" y="-1210.0446428571429"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="arrow.right" catalog="system" width="128" height="95"/>
|
||||
<image name="arrowtriangle.down.circle" catalog="system" width="128" height="123"/>
|
||||
<image name="qrcode.viewfinder" catalog="system" width="128" height="115"/>
|
||||
<systemColor name="tintColor">
|
||||
<color red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
||||
|
|
|
@ -30,12 +30,13 @@ import SwiftUI
|
|||
class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate {
|
||||
@IBOutlet weak var imageBrand: UIImageView!
|
||||
@IBOutlet weak var imageBrandConstraintY: NSLayoutConstraint!
|
||||
@IBOutlet weak var baseUrl: UITextField!
|
||||
@IBOutlet weak var baseUrlTextField: UITextField!
|
||||
@IBOutlet weak var loginAddressDetail: UILabel!
|
||||
@IBOutlet weak var loginButton: UIButton!
|
||||
@IBOutlet weak var loginImage: UIImageView!
|
||||
@IBOutlet weak var qrCode: UIButton!
|
||||
@IBOutlet weak var certificate: UIButton!
|
||||
@IBOutlet weak var enforceServersButton: UIButton!
|
||||
@IBOutlet weak var enforceServersDropdownImage: UIImageView!
|
||||
|
||||
private let appDelegate = (UIApplication.shared.delegate as? AppDelegate)!
|
||||
private var textColor: UIColor = .white
|
||||
|
@ -82,37 +83,31 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate {
|
|||
imageBrand.image = UIImage(named: "logo")
|
||||
|
||||
// Url
|
||||
baseUrl.textColor = textColor
|
||||
baseUrl.tintColor = textColor
|
||||
baseUrl.layer.cornerRadius = 10
|
||||
baseUrl.layer.borderWidth = 1
|
||||
baseUrl.layer.borderColor = textColor.cgColor
|
||||
baseUrl.leftView = UIView(frame: CGRect(x: 0, y: 0, width: 15, height: baseUrl.frame.height))
|
||||
baseUrl.leftViewMode = .always
|
||||
baseUrl.rightView = UIView(frame: CGRect(x: 0, y: 0, width: 35, height: baseUrl.frame.height))
|
||||
baseUrl.rightViewMode = .always
|
||||
baseUrl.attributedPlaceholder = NSAttributedString(string: NSLocalizedString("_login_url_", comment: ""), attributes: [NSAttributedString.Key.foregroundColor: textColor.withAlphaComponent(0.5)])
|
||||
baseUrl.delegate = self
|
||||
baseUrlTextField.textColor = textColor
|
||||
baseUrlTextField.tintColor = textColor
|
||||
baseUrlTextField.layer.cornerRadius = 10
|
||||
baseUrlTextField.layer.borderWidth = 1
|
||||
baseUrlTextField.layer.borderColor = textColor.cgColor
|
||||
baseUrlTextField.leftView = UIView(frame: CGRect(x: 0, y: 0, width: 15, height: baseUrlTextField.frame.height))
|
||||
baseUrlTextField.leftViewMode = .always
|
||||
baseUrlTextField.rightView = UIView(frame: CGRect(x: 0, y: 0, width: 35, height: baseUrlTextField.frame.height))
|
||||
baseUrlTextField.rightViewMode = .always
|
||||
baseUrlTextField.attributedPlaceholder = NSAttributedString(string: NSLocalizedString("_login_url_", comment: ""), attributes: [NSAttributedString.Key.foregroundColor: textColor.withAlphaComponent(0.5)])
|
||||
baseUrlTextField.delegate = self
|
||||
|
||||
baseUrl.isEnabled = !NCBrandOptions.shared.disable_request_login_url
|
||||
baseUrlTextField.isEnabled = !NCBrandOptions.shared.disable_request_login_url
|
||||
|
||||
// Login button
|
||||
loginAddressDetail.textColor = textColor
|
||||
loginAddressDetail.text = String.localizedStringWithFormat(NSLocalizedString("_login_address_detail_", comment: ""), NCBrandOptions.shared.brand)
|
||||
|
||||
// Login Image
|
||||
loginImage.image = UIImage(named: "arrow.right")?.image(color: textColor, size: 100)
|
||||
|
||||
// brand
|
||||
if NCBrandOptions.shared.disable_request_login_url {
|
||||
baseUrl.isEnabled = false
|
||||
baseUrl.isUserInteractionEnabled = false
|
||||
baseUrl.alpha = 0.5
|
||||
baseUrlTextField.isEnabled = false
|
||||
baseUrlTextField.isUserInteractionEnabled = false
|
||||
baseUrlTextField.alpha = 0.5
|
||||
}
|
||||
|
||||
// qrcode
|
||||
qrCode.setImage(UIImage(systemName: "qrcode.viewfinder")?.image(color: textColor, size: 100), for: .normal)
|
||||
|
||||
// certificate
|
||||
certificate.setImage(UIImage(named: "certificate")?.image(color: textColor, size: 100), for: .normal)
|
||||
certificate.isHidden = true
|
||||
|
@ -129,7 +124,7 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate {
|
|||
self.navigationController?.view.backgroundColor = NCBrandColor.shared.customer
|
||||
self.navigationController?.navigationBar.tintColor = textColor
|
||||
|
||||
if !NCManageDatabase.shared.getAllAccount().isEmpty {
|
||||
if !NCManageDatabase.shared.getAllTableAccount().isEmpty {
|
||||
let navigationItemCancel = UIBarButtonItem(barButtonSystemItem: .stop, target: self, action: #selector(self.actionCancel))
|
||||
navigationItemCancel.tintColor = textColor
|
||||
navigationItem.leftBarButtonItem = navigationItemCancel
|
||||
|
@ -137,14 +132,14 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate {
|
|||
|
||||
if let dirGroupApps = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: NCBrandOptions.shared.capabilitiesGroupApps) {
|
||||
// Nextcloud update share accounts
|
||||
if let error = appDelegate.updateShareAccounts() {
|
||||
if let error = NCAccount().updateAppsShareAccounts() {
|
||||
NextcloudKit.shared.nkCommonInstance.writeLog("[ERROR] Create share accounts \(error.localizedDescription)")
|
||||
}
|
||||
// Nextcloud get share accounts
|
||||
if let shareAccounts = NKShareAccounts().getShareAccount(at: dirGroupApps, application: UIApplication.shared) {
|
||||
var accountTemp = [NKShareAccounts.DataAccounts]()
|
||||
for shareAccount in shareAccounts {
|
||||
if NCManageDatabase.shared.getAccount(predicate: NSPredicate(format: "urlBase == %@ AND user == %@", shareAccount.url, shareAccount.user)) == nil {
|
||||
if NCManageDatabase.shared.getTableAccount(predicate: NSPredicate(format: "urlBase == %@ AND user == %@", shareAccount.url, shareAccount.user)) == nil {
|
||||
accountTemp.append(shareAccount)
|
||||
}
|
||||
}
|
||||
|
@ -165,14 +160,40 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate {
|
|||
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
|
||||
|
||||
handleLoginWithAppConfig()
|
||||
baseUrl.text = urlBase
|
||||
baseUrlTextField.text = urlBase
|
||||
|
||||
enforceServersButton.setTitle(NSLocalizedString("_select_server_", comment: ""), for: .normal)
|
||||
|
||||
let enforceServers = NCBrandOptions.shared.enforce_servers
|
||||
|
||||
if !enforceServers.isEmpty {
|
||||
baseUrlTextField.isHidden = true
|
||||
enforceServersDropdownImage.isHidden = false
|
||||
enforceServersButton.isHidden = false
|
||||
|
||||
let actions = enforceServers.map { server in
|
||||
UIAction(title: server.name, handler: { [self] _ in
|
||||
enforceServersButton.setTitle(server.name, for: .normal)
|
||||
baseUrlTextField.text = server.url
|
||||
})
|
||||
}
|
||||
|
||||
enforceServersButton.layer.cornerRadius = 10
|
||||
enforceServersButton.menu = .init(title: NSLocalizedString("_servers_", comment: ""), children: actions)
|
||||
enforceServersButton.showsMenuAsPrimaryAction = true
|
||||
enforceServersButton.configuration?.titleTextAttributesTransformer =
|
||||
UIConfigurationTextAttributesTransformer { incoming in
|
||||
var outgoing = incoming
|
||||
outgoing.font = UIFont.systemFont(ofSize: 13)
|
||||
return outgoing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
appDelegate.timerErrorNetworkingDisabled = true
|
||||
|
||||
if self.shareAccounts != nil, let image = UIImage(systemName: "person.badge.plus")?.withTintColor(.white, renderingMode: .alwaysOriginal), let backgroundColor = NCBrandColor.shared.brandElement.lighter(by: 10) {
|
||||
if self.shareAccounts != nil, let image = UIImage(systemName: "person.badge.plus")?.withTintColor(.white, renderingMode: .alwaysOriginal), let backgroundColor = NCBrandColor.shared.customer.lighter(by: 10) {
|
||||
let title = String(format: NSLocalizedString("_apps_nextcloud_detect_", comment: ""), NCBrandOptions.shared.brand)
|
||||
let description = String(format: NSLocalizedString("_add_existing_account_", comment: ""), NCBrandOptions.shared.brand)
|
||||
NCContentPresenter().alertAction(image: image, contentModeImage: .scaleAspectFit, sizeImage: CGSize(width: 45, height: 45), backgroundColor: backgroundColor, textColor: textColor, title: title, description: description, textCancelButton: "_cancel_", textOkButton: "_ok_", attributes: EKAttributes.topFloat) { identifier in
|
||||
|
@ -183,11 +204,6 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
override func viewDidDisappear(_ animated: Bool) {
|
||||
super.viewDidDisappear(animated)
|
||||
appDelegate.timerErrorNetworkingDisabled = false
|
||||
}
|
||||
|
||||
private func handleLoginWithAppConfig() {
|
||||
let accountCount = NCManageDatabase.shared.getAccounts()?.count ?? 0
|
||||
|
||||
|
@ -297,20 +313,20 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate {
|
|||
// MARK: - Login
|
||||
|
||||
private func login() {
|
||||
guard var url = baseUrl.text?.trimmingCharacters(in: .whitespacesAndNewlines) else { return }
|
||||
guard var url = baseUrlTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) else { return }
|
||||
if url.hasSuffix("/") { url = String(url.dropLast()) }
|
||||
if url.isEmpty { return }
|
||||
// Check whether baseUrl contain protocol. If not add https:// by default.
|
||||
if url.hasPrefix("https") == false && url.hasPrefix("http") == false {
|
||||
url = "https://" + url
|
||||
}
|
||||
self.baseUrl.text = url
|
||||
self.baseUrlTextField.text = url
|
||||
isUrlValid(url: url)
|
||||
}
|
||||
|
||||
func isUrlValid(url: String, user: String? = nil) {
|
||||
loginButton.isEnabled = false
|
||||
NextcloudKit.shared.getServerStatus(serverUrl: url) { serverInfoResult in
|
||||
NextcloudKit.shared.getServerStatus(serverUrl: url) { _, serverInfoResult in
|
||||
switch serverInfoResult {
|
||||
case .success(let serverInfo):
|
||||
if let host = URL(string: url)?.host {
|
||||
|
@ -369,9 +385,9 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate {
|
|||
let user = valueArray[0].replacingOccurrences(of: "user:", with: "")
|
||||
let password = valueArray[1].replacingOccurrences(of: "password:", with: "")
|
||||
let urlBase = valueArray[2].replacingOccurrences(of: "server:", with: "")
|
||||
let serverUrl = urlBase + "/" + NextcloudKit.shared.nkCommonInstance.dav
|
||||
let serverUrl = urlBase + "/remote.php/dav"
|
||||
loginButton.isEnabled = false
|
||||
NextcloudKit.shared.checkServer(serverUrl: serverUrl) { error in
|
||||
NextcloudKit.shared.checkServer(serverUrl: serverUrl) { _, error in
|
||||
self.loginButton.isEnabled = true
|
||||
if error == .success {
|
||||
self.createAccount(urlBase: urlBase, user: user, password: password)
|
||||
|
@ -397,16 +413,19 @@ class NCLogin: UIViewController, UITextFieldDelegate, NCLoginQRCodeDelegate {
|
|||
}
|
||||
|
||||
private func createAccount(urlBase: String, user: String, password: String) {
|
||||
let controller = UIApplication.shared.firstWindow?.rootViewController as? NCMainTabBarController
|
||||
if let host = URL(string: urlBase)?.host {
|
||||
NCNetworking.shared.writeCertificate(host: host)
|
||||
}
|
||||
self.appDelegate.createAccount(urlBase: urlBase, user: user, password: password) { error in
|
||||
NCAccount().createAccount(urlBase: urlBase, user: user, password: password, controller: controller) { account, error in
|
||||
if error == .success {
|
||||
let window = UIApplication.shared.firstWindow
|
||||
if window?.rootViewController is NCMainTabBarController {
|
||||
if let controller = window?.rootViewController as? NCMainTabBarController {
|
||||
controller.account = account
|
||||
self.dismiss(animated: true)
|
||||
} else {
|
||||
if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController() as? NCMainTabBarController {
|
||||
controller.account = account
|
||||
controller.modalPresentationStyle = .fullScreen
|
||||
controller.view.alpha = 0
|
||||
window?.rootViewController = controller
|
||||
|
|
|
@ -67,17 +67,18 @@ struct NCLoginPoll: View {
|
|||
.onChange(of: loginManager.pollFinished) { value in
|
||||
if value {
|
||||
let window = UIApplication.shared.firstWindow
|
||||
|
||||
if window?.rootViewController is NCMainTabBarController {
|
||||
window?.rootViewController?.dismiss(animated: true, completion: nil)
|
||||
if let controller = window?.rootViewController as? NCMainTabBarController {
|
||||
controller.account = loginManager.account
|
||||
controller.dismiss(animated: true, completion: nil)
|
||||
} else {
|
||||
if let mainTabBarController = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController() as? NCMainTabBarController {
|
||||
mainTabBarController.modalPresentationStyle = .fullScreen
|
||||
mainTabBarController.view.alpha = 0
|
||||
window?.rootViewController = mainTabBarController
|
||||
if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController() as? NCMainTabBarController {
|
||||
controller.account = loginManager.account
|
||||
controller.modalPresentationStyle = .fullScreen
|
||||
controller.view.alpha = 0
|
||||
window?.rootViewController = controller
|
||||
window?.makeKeyAndVisible()
|
||||
UIView.animate(withDuration: 0.5) {
|
||||
mainTabBarController.view.alpha = 1
|
||||
controller.view.alpha = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -91,6 +92,9 @@ struct NCLoginPoll: View {
|
|||
loginManager.openLoginInBrowser()
|
||||
}
|
||||
}
|
||||
.onDisappear {
|
||||
loginManager.onDisappear()
|
||||
}
|
||||
.interactiveDismissDisabled()
|
||||
}
|
||||
}
|
||||
|
@ -100,40 +104,53 @@ struct NCLoginPoll: View {
|
|||
}
|
||||
|
||||
private class LoginManager: ObservableObject {
|
||||
private let appDelegate = (UIApplication.shared.delegate as? AppDelegate)!
|
||||
|
||||
var loginFlowV2Token = ""
|
||||
var loginFlowV2Endpoint = ""
|
||||
var loginFlowV2Login = ""
|
||||
|
||||
@Published var pollFinished = false
|
||||
@Published var isLoading = false
|
||||
@Published var account = ""
|
||||
|
||||
init() {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(applicationDidBecomeActive(_:)), name: UIApplication.didBecomeActiveNotification, object: nil)
|
||||
}
|
||||
|
||||
@objc func applicationDidBecomeActive(_ notification: NSNotification) {
|
||||
poll()
|
||||
}
|
||||
var timer: DispatchSourceTimer?
|
||||
|
||||
func configure(loginFlowV2Token: String, loginFlowV2Endpoint: String, loginFlowV2Login: String) {
|
||||
self.loginFlowV2Token = loginFlowV2Token
|
||||
self.loginFlowV2Endpoint = loginFlowV2Endpoint
|
||||
self.loginFlowV2Login = loginFlowV2Login
|
||||
|
||||
poll()
|
||||
}
|
||||
|
||||
func poll() {
|
||||
NextcloudKit.shared.getLoginFlowV2Poll(token: self.loginFlowV2Token, endpoint: self.loginFlowV2Endpoint) { server, loginName, appPassword, _, error in
|
||||
if error == .success, let urlBase = server, let user = loginName, let appPassword {
|
||||
self.isLoading = true
|
||||
self.appDelegate.createAccount(urlBase: urlBase, user: user, password: appPassword) { error in
|
||||
if error == .success {
|
||||
self.pollFinished = true
|
||||
let queue = DispatchQueue.global(qos: .background)
|
||||
timer = DispatchSource.makeTimerSource(queue: queue)
|
||||
|
||||
guard let timer = timer else { return }
|
||||
|
||||
timer.schedule(deadline: .now(), repeating: .seconds(1), leeway: .seconds(1))
|
||||
timer.setEventHandler(handler: {
|
||||
DispatchQueue.main.async {
|
||||
let controller = UIApplication.shared.firstWindow?.rootViewController as? NCMainTabBarController
|
||||
NextcloudKit.shared.getLoginFlowV2Poll(token: self.loginFlowV2Token, endpoint: self.loginFlowV2Endpoint) { server, loginName, appPassword, _, error in
|
||||
if error == .success, let urlBase = server, let user = loginName, let appPassword {
|
||||
self.isLoading = true
|
||||
NCAccount().createAccount(urlBase: urlBase, user: user, password: appPassword, controller: controller) { account, error in
|
||||
if error == .success {
|
||||
self.account = account
|
||||
self.pollFinished = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
timer.resume()
|
||||
}
|
||||
|
||||
func onDisappear() {
|
||||
timer?.cancel()
|
||||
}
|
||||
|
||||
func openLoginInBrowser() {
|
||||
|
|
|
@ -22,13 +22,12 @@
|
|||
//
|
||||
|
||||
import UIKit
|
||||
import WebKit
|
||||
@preconcurrency import WebKit
|
||||
import NextcloudKit
|
||||
import FloatingPanel
|
||||
|
||||
class NCLoginProvider: UIViewController {
|
||||
var webView: WKWebView?
|
||||
let appDelegate = (UIApplication.shared.delegate as? AppDelegate)!
|
||||
let utility = NCUtility()
|
||||
var titleView: String = ""
|
||||
var urlBase = ""
|
||||
|
@ -58,24 +57,17 @@ class NCLoginProvider: UIViewController {
|
|||
|
||||
if let host = URL(string: urlBase)?.host {
|
||||
titleView = host
|
||||
if let account = NCManageDatabase.shared.getActiveAccount(), NCKeychain().getPassword(account: account.account).isEmpty {
|
||||
titleView = NSLocalizedString("_user_", comment: "") + " " + account.userId + " " + NSLocalizedString("_in_", comment: "") + " " + host
|
||||
if let activeTableAccount = NCManageDatabase.shared.getActiveTableAccount(), NCKeychain().getPassword(account: activeTableAccount.account).isEmpty {
|
||||
titleView = NSLocalizedString("_user_", comment: "") + " " + activeTableAccount.userId + " " + NSLocalizedString("_in_", comment: "") + " " + host
|
||||
}
|
||||
}
|
||||
|
||||
self.title = titleView
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
// Stop timer error network
|
||||
appDelegate.timerErrorNetworkingDisabled = true
|
||||
}
|
||||
|
||||
override func viewDidDisappear(_ animated: Bool) {
|
||||
super.viewDidDisappear(animated)
|
||||
NCActivityIndicator.shared.stop()
|
||||
appDelegate.timerErrorNetworkingDisabled = false
|
||||
}
|
||||
|
||||
func loadWebPage(webView: WKWebView, url: URL) {
|
||||
|
@ -166,17 +158,27 @@ extension NCLoginProvider: WKNavigationDelegate {
|
|||
let account: String = "\(username) \(urlBase)"
|
||||
let user = username
|
||||
|
||||
NextcloudKit.shared.setup(account: account, user: user, userId: user, password: password, urlBase: urlBase)
|
||||
NextcloudKit.shared.getUserProfile(account: account) { _, userProfile, _, error in
|
||||
NextcloudKit.shared.getUserProfile(account: account) { account, userProfile, _, error in
|
||||
if error == .success, let userProfile {
|
||||
NCManageDatabase.shared.deleteAccount(account)
|
||||
NextcloudKit.shared.appendSession(account: account,
|
||||
urlBase: urlBase,
|
||||
user: user,
|
||||
userId: user,
|
||||
password: password,
|
||||
userAgent: userAgent,
|
||||
nextcloudVersion: NCCapabilities.shared.getCapabilities(account: account).capabilityServerVersionMajor,
|
||||
groupIdentifier: NCBrandOptions.shared.capabilitiesGroup)
|
||||
NCSession.shared.appendSession(account: account, urlBase: urlBase, user: user, userId: userProfile.userId)
|
||||
NCManageDatabase.shared.addAccount(account, urlBase: urlBase, user: user, userId: userProfile.userId, password: password)
|
||||
self.appDelegate.changeAccount(account, userProfile: userProfile) { }
|
||||
NCAccount().changeAccount(account, userProfile: userProfile, controller: nil) { }
|
||||
|
||||
let window = UIApplication.shared.firstWindow
|
||||
if window?.rootViewController is NCMainTabBarController {
|
||||
if let controller = window?.rootViewController as? NCMainTabBarController {
|
||||
controller.account = account
|
||||
self.dismiss(animated: true)
|
||||
} else {
|
||||
if let controller = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController() as? NCMainTabBarController {
|
||||
controller.account = account
|
||||
controller.modalPresentationStyle = .fullScreen
|
||||
controller.view.alpha = 0
|
||||
window?.rootViewController = controller
|
||||
|
|
|
@ -25,26 +25,32 @@ import UIKit
|
|||
|
||||
protocol NCCellProtocol {
|
||||
var fileAvatarImageView: UIImageView? { get }
|
||||
var fileObjectId: String? { get set }
|
||||
var fileAccount: String? { get set }
|
||||
var fileOcId: String? { get set }
|
||||
var fileOcIdTransfer: String? { get set }
|
||||
var filePreviewImageView: UIImageView? { get set }
|
||||
var filePreviewImageBottom: NSLayoutConstraint? { get set }
|
||||
var fileUser: String? { get set }
|
||||
var fileTitleLabel: UILabel? { get set }
|
||||
var fileInfoLabel: UILabel? { get set }
|
||||
var fileSubinfoLabel: UILabel? { get set }
|
||||
var fileProgressView: UIProgressView? { get set }
|
||||
var fileStatusImage: UIImageView? { get set }
|
||||
var fileLocalImage: UIImageView? { get set }
|
||||
var fileFavoriteImage: UIImageView? { get set }
|
||||
var fileSharedImage: UIImageView? { get set }
|
||||
var fileMoreImage: UIImageView? { get set }
|
||||
var cellSeparatorView: UIView? { get set }
|
||||
var indexPath: IndexPath { get set }
|
||||
|
||||
func titleInfoTrailingDefault()
|
||||
func titleInfoTrailingFull()
|
||||
func writeInfoDateSize(date: NSDate, size: Int64)
|
||||
func setButtonMore(named: String, image: UIImage)
|
||||
func setButtonMore(image: UIImage)
|
||||
func hideImageItem(_ status: Bool)
|
||||
func hideImageFavorite(_ status: Bool)
|
||||
func hideImageStatus(_ status: Bool)
|
||||
func hideImageLocal(_ status: Bool)
|
||||
func hideLabelTitle(_ status: Bool)
|
||||
func hideLabelInfo(_ status: Bool)
|
||||
func hideLabelSubinfo(_ status: Bool)
|
||||
func hideButtonShare(_ status: Bool)
|
||||
func hideButtonMore(_ status: Bool)
|
||||
func selected(_ status: Bool, isEditMode: Bool)
|
||||
|
@ -54,11 +60,18 @@ protocol NCCellProtocol {
|
|||
}
|
||||
|
||||
extension NCCellProtocol {
|
||||
|
||||
var fileAvatarImageView: UIImageView? {
|
||||
return nil
|
||||
}
|
||||
var fileObjectId: String? {
|
||||
var fileAccount: String? {
|
||||
get { return nil }
|
||||
set {}
|
||||
}
|
||||
var fileOcId: String? {
|
||||
get { return nil }
|
||||
set {}
|
||||
}
|
||||
var fileOcIdTransfer: String? {
|
||||
get { return nil }
|
||||
set {}
|
||||
}
|
||||
|
@ -66,10 +79,6 @@ extension NCCellProtocol {
|
|||
get { return nil }
|
||||
set {}
|
||||
}
|
||||
var filePreviewImageBottom: NSLayoutConstraint? {
|
||||
get { return nil }
|
||||
set {}
|
||||
}
|
||||
var fileTitleLabel: UILabel? {
|
||||
get { return nil }
|
||||
set {}
|
||||
|
@ -82,10 +91,6 @@ extension NCCellProtocol {
|
|||
get { return nil }
|
||||
set { }
|
||||
}
|
||||
var fileProgressView: UIProgressView? {
|
||||
get { return nil }
|
||||
set {}
|
||||
}
|
||||
var fileStatusImage: UIImageView? {
|
||||
get { return nil }
|
||||
set {}
|
||||
|
@ -114,7 +119,14 @@ extension NCCellProtocol {
|
|||
func titleInfoTrailingDefault() {}
|
||||
func titleInfoTrailingFull() {}
|
||||
func writeInfoDateSize(date: NSDate, size: Int64) {}
|
||||
func setButtonMore(named: String, image: UIImage) {}
|
||||
func setButtonMore(image: UIImage) {}
|
||||
func hideImageItem(_ status: Bool) {}
|
||||
func hideImageFavorite(_ status: Bool) {}
|
||||
func hideImageStatus(_ status: Bool) {}
|
||||
func hideImageLocal(_ status: Bool) {}
|
||||
func hideLabelTitle(_ status: Bool) {}
|
||||
func hideLabelInfo(_ status: Bool) {}
|
||||
func hideLabelSubinfo(_ status: Bool) {}
|
||||
func hideButtonShare(_ status: Bool) {}
|
||||
func hideButtonMore(_ status: Bool) {}
|
||||
func selected(_ status: Bool, isEditMode: Bool) {}
|
||||
|
|
|
@ -35,16 +35,20 @@ class NCGridCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellProto
|
|||
@IBOutlet weak var buttonMore: UIButton!
|
||||
@IBOutlet weak var imageVisualEffect: UIVisualEffectView!
|
||||
|
||||
var objectId = ""
|
||||
var indexPath = IndexPath()
|
||||
private var user = ""
|
||||
var ocId = ""
|
||||
var ocIdTransfer = ""
|
||||
var account = ""
|
||||
var user = ""
|
||||
|
||||
weak var gridCellDelegate: NCGridCellDelegate?
|
||||
var namedButtonMore = ""
|
||||
|
||||
var fileObjectId: String? {
|
||||
get { return objectId }
|
||||
set { objectId = newValue ?? "" }
|
||||
var fileOcId: String? {
|
||||
get { return ocId }
|
||||
set { ocId = newValue ?? "" }
|
||||
}
|
||||
var fileOcIdTransfer: String? {
|
||||
get { return ocIdTransfer }
|
||||
set { ocIdTransfer = newValue ?? "" }
|
||||
}
|
||||
var filePreviewImageView: UIImageView? {
|
||||
get { return imageItem }
|
||||
|
@ -95,25 +99,26 @@ class NCGridCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellProto
|
|||
accessibilityValue = nil
|
||||
isAccessibilityElement = true
|
||||
|
||||
imageItem.image = nil
|
||||
imageItem.layer.cornerRadius = 6
|
||||
imageItem.layer.masksToBounds = true
|
||||
|
||||
imageSelect.isHidden = true
|
||||
imageSelect.image = NCImageCache.shared.getImageCheckedYes()
|
||||
imageStatus.image = nil
|
||||
imageFavorite.image = nil
|
||||
imageLocal.image = nil
|
||||
labelTitle.text = ""
|
||||
labelInfo.text = ""
|
||||
labelSubinfo.text = ""
|
||||
imageVisualEffect.layer.cornerRadius = 6
|
||||
imageVisualEffect.clipsToBounds = true
|
||||
imageVisualEffect.alpha = 0.5
|
||||
|
||||
imageSelect.isHidden = true
|
||||
imageSelect.image = NCImageCache.images.checkedYes
|
||||
|
||||
let longPressedGesture = UILongPressGestureRecognizer(target: self, action: #selector(longPress(gestureRecognizer:)))
|
||||
longPressedGesture.minimumPressDuration = 0.5
|
||||
longPressedGesture.delegate = self
|
||||
longPressedGesture.delaysTouchesBegan = true
|
||||
self.addGestureRecognizer(longPressedGesture)
|
||||
|
||||
labelTitle.text = ""
|
||||
labelInfo.text = ""
|
||||
labelSubinfo.text = ""
|
||||
}
|
||||
|
||||
override func snapshotView(afterScreenUpdates afterUpdates: Bool) -> UIView? {
|
||||
|
@ -121,30 +126,55 @@ class NCGridCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellProto
|
|||
}
|
||||
|
||||
@IBAction func touchUpInsideMore(_ sender: Any) {
|
||||
gridCellDelegate?.tapMoreGridItem(with: objectId, namedButtonMore: namedButtonMore, image: imageItem.image, indexPath: indexPath, sender: sender)
|
||||
gridCellDelegate?.tapMoreGridItem(with: ocId, ocIdTransfer: ocIdTransfer, image: imageItem.image, sender: sender)
|
||||
}
|
||||
|
||||
@objc func longPress(gestureRecognizer: UILongPressGestureRecognizer) {
|
||||
gridCellDelegate?.longPressGridItem(with: objectId, indexPath: indexPath, gestureRecognizer: gestureRecognizer)
|
||||
gridCellDelegate?.longPressGridItem(with: ocId, ocIdTransfer: ocIdTransfer, gestureRecognizer: gestureRecognizer)
|
||||
}
|
||||
|
||||
fileprivate func setA11yActions() {
|
||||
let moreName = namedButtonMore == NCGlobal.shared.buttonMoreStop ? "_cancel_" : "_more_"
|
||||
|
||||
self.accessibilityCustomActions = [
|
||||
UIAccessibilityCustomAction(
|
||||
name: NSLocalizedString(moreName, comment: ""),
|
||||
name: NSLocalizedString("_more_", comment: ""),
|
||||
target: self,
|
||||
selector: #selector(touchUpInsideMore))
|
||||
]
|
||||
}
|
||||
|
||||
func setButtonMore(named: String, image: UIImage) {
|
||||
namedButtonMore = named
|
||||
func setButtonMore(image: UIImage) {
|
||||
buttonMore.setImage(image, for: .normal)
|
||||
setA11yActions()
|
||||
}
|
||||
|
||||
func hideImageItem(_ status: Bool) {
|
||||
imageItem.isHidden = status
|
||||
}
|
||||
|
||||
func hideImageFavorite(_ status: Bool) {
|
||||
imageFavorite.isHidden = status
|
||||
}
|
||||
|
||||
func hideImageStatus(_ status: Bool) {
|
||||
imageStatus.isHidden = status
|
||||
}
|
||||
|
||||
func hideImageLocal(_ status: Bool) {
|
||||
imageLocal.isHidden = status
|
||||
}
|
||||
|
||||
func hideLabelTitle(_ status: Bool) {
|
||||
labelTitle.isHidden = status
|
||||
}
|
||||
|
||||
func hideLabelInfo(_ status: Bool) {
|
||||
labelInfo.isHidden = status
|
||||
}
|
||||
|
||||
func hideLabelSubinfo(_ status: Bool) {
|
||||
labelSubinfo.isHidden = status
|
||||
}
|
||||
|
||||
func hideButtonMore(_ status: Bool) {
|
||||
buttonMore.isHidden = status
|
||||
}
|
||||
|
@ -159,6 +189,7 @@ class NCGridCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellProto
|
|||
}
|
||||
if status {
|
||||
imageSelect.isHidden = false
|
||||
imageSelect.image = NCImageCache.shared.getImageCheckedYes()
|
||||
imageVisualEffect.isHidden = false
|
||||
} else {
|
||||
imageSelect.isHidden = true
|
||||
|
@ -191,8 +222,8 @@ class NCGridCell: UICollectionViewCell, UIGestureRecognizerDelegate, NCCellProto
|
|||
}
|
||||
|
||||
protocol NCGridCellDelegate: AnyObject {
|
||||
func tapMoreGridItem(with objectId: String, namedButtonMore: String, image: UIImage?, indexPath: IndexPath, sender: Any)
|
||||
func longPressGridItem(with objectId: String, indexPath: IndexPath, gestureRecognizer: UILongPressGestureRecognizer)
|
||||
func tapMoreGridItem(with ocId: String, ocIdTransfer: String, image: UIImage?, sender: Any)
|
||||
func longPressGridItem(with ocId: String, ocIdTransfer: String, gestureRecognizer: UILongPressGestureRecognizer)
|
||||
}
|
||||
|
||||
// MARK: - Grid Layout
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче