NCSettingsAdvancedModel.swift 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. //
  2. // NCSettingsAdvancedViewModel.swift
  3. // Nextcloud
  4. //
  5. // Created by Aditya Tyagi on 08/03/24.
  6. // Created by Marino Faggiana on 30/05/24.
  7. // Copyright © 2024 Marino Faggiana. All rights reserved.
  8. //
  9. // Author Aditya Tyagi <adityagi02@yahoo.com>
  10. //
  11. // This program is free software: you can redistribute it and/or modify
  12. // it under the terms of the GNU General Public License as published by
  13. // the Free Software Foundation, either version 3 of the License, or
  14. // (at your option) any later version.
  15. //
  16. // This program is distributed in the hope that it will be useful,
  17. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. // GNU General Public License for more details.
  20. //
  21. // You should have received a copy of the GNU General Public License
  22. // along with this program. If not, see <http://www.gnu.org/licenses/>.
  23. //
  24. import Foundation
  25. import UIKit
  26. import NextcloudKit
  27. import Combine
  28. import SwiftUI
  29. class NCSettingsAdvancedModel: ObservableObject, ViewOnAppearHandling {
  30. /// AppDelegate
  31. let appDelegate = (UIApplication.shared.delegate as? AppDelegate)!
  32. /// Keychain access
  33. var keychain = NCKeychain()
  34. /// State variable for indicating if the user is in Admin group
  35. @Published var isAdminGroup: Bool = false
  36. /// State variable for indicating whether hidden files are shown.
  37. @Published var showHiddenFiles: Bool = false
  38. /// State variable for indicating the most compatible format.
  39. @Published var mostCompatible: Bool = false
  40. /// State variable for enabling live photo uploads.
  41. @Published var livePhoto: Bool = false
  42. /// State variable for indicating whether to remove photos from the camera roll after upload.
  43. @Published var removeFromCameraRoll: Bool = false
  44. /// State variable for app integration.
  45. @Published var appIntegration: Bool = false
  46. /// State variable for enabling the crash reporter.
  47. @Published var crashReporter: Bool = false
  48. /// State variable for indicating whether the log file has been cleared.
  49. @Published var logFileCleared: Bool = false
  50. // Properties for log level and cache deletion
  51. /// State variable for storing the selected log level.
  52. @Published var selectedLogLevel: LogLevel = .standard
  53. /// State variable for storing the selected cache deletion interval.
  54. @Published var selectedInterval: CacheDeletionInterval = .never
  55. /// State variable for storing the footer title, usually used for cache deletion.
  56. @Published var footerTitle: String = ""
  57. /// Root View Controller
  58. @Published var controller: NCMainTabBarController?
  59. /// Initializes the view model with default values.
  60. init(controller: NCMainTabBarController?) {
  61. self.controller = controller
  62. onViewAppear()
  63. }
  64. /// Triggered when the view appears.
  65. func onViewAppear() {
  66. let groups = NCManageDatabase.shared.getAccountGroups(account: appDelegate.account)
  67. isAdminGroup = groups.contains(NCGlobal.shared.groupAdmin)
  68. showHiddenFiles = keychain.showHiddenFiles
  69. mostCompatible = keychain.formatCompatibility
  70. livePhoto = keychain.livePhoto
  71. removeFromCameraRoll = keychain.removePhotoCameraRoll
  72. appIntegration = keychain.disableFilesApp
  73. crashReporter = keychain.disableCrashservice
  74. selectedLogLevel = LogLevel(rawValue: keychain.logLevel) ?? .standard
  75. selectedInterval = CacheDeletionInterval(rawValue: keychain.cleanUpDay) ?? .never
  76. DispatchQueue.global().async {
  77. self.calculateSize()
  78. }
  79. }
  80. // MARK: - All functions
  81. /// Updates the value of `showHiddenFiles` in the keychain.
  82. func updateShowHiddenFiles() {
  83. keychain.showHiddenFiles = showHiddenFiles
  84. }
  85. /// Updates the value of `mostCompatible` in the keychain.
  86. func updateMostCompatible() {
  87. keychain.formatCompatibility = mostCompatible
  88. }
  89. /// Updates the value of `livePhoto` in the keychain.
  90. func updateLivePhoto() {
  91. keychain.livePhoto = livePhoto
  92. }
  93. /// Updates the value of `removeFromCameraRoll` in the keychain.
  94. func updateRemoveFromCameraRoll() {
  95. keychain.removePhotoCameraRoll = removeFromCameraRoll
  96. }
  97. /// Updates the value of `appIntegration` in the keychain.
  98. func updateAppIntegration() {
  99. NSFileProviderManager.removeAllDomains { _ in }
  100. keychain.disableFilesApp = appIntegration
  101. }
  102. /// Updates the value of `crashReporter` in the keychain.
  103. func updateCrashReporter() {
  104. keychain.disableCrashservice = crashReporter
  105. }
  106. /// Updates the value of `selectedLogLevel` in the keychain and sets it for NextcloudKit.
  107. func updateSelectedLogLevel() {
  108. keychain.logLevel = selectedLogLevel.rawValue
  109. NextcloudKit.shared.nkCommonInstance.levelLog = selectedLogLevel.rawValue
  110. }
  111. /// Updates the value of `selectedInterval` in the keychain.
  112. func updateSelectedInterval() {
  113. keychain.cleanUpDay = selectedInterval.rawValue
  114. }
  115. /// Clears cache associated with the specified account.
  116. func clearCache() {
  117. NCActivityIndicator.shared.startActivity(style: .large, blurEffect: true)
  118. // Cancel all networking tasks
  119. NCNetworking.shared.cancelAllTask()
  120. DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
  121. URLCache.shared.memoryCapacity = 0
  122. URLCache.shared.diskCapacity = 0
  123. NCManageDatabase.shared.clearDatabase(account: self.appDelegate.account, removeAccount: false)
  124. let ufs = NCUtilityFileSystem()
  125. ufs.removeGroupDirectoryProviderStorage()
  126. ufs.removeGroupLibraryDirectory()
  127. ufs.removeDocumentsDirectory()
  128. ufs.removeTemporaryDirectory()
  129. ufs.createDirectoryStandard()
  130. NCAutoUpload.shared.alignPhotoLibrary(viewController: self.controller)
  131. NCImageCache.shared.createMediaCache(account: self.appDelegate.account, withCacheSize: true)
  132. NCActivityIndicator.shared.stop()
  133. self.calculateSize()
  134. }
  135. }
  136. /// Asynchronously calculates the size of cache directory and updates the footer title.
  137. func calculateSize() {
  138. let ufs = NCUtilityFileSystem()
  139. let directory = ufs.directoryProviderStorage
  140. let totalSize = ufs.getDirectorySize(directory: directory)
  141. DispatchQueue.main.async {
  142. self.footerTitle = "\(NSLocalizedString("_clear_cache_footer_", comment: "")). (\(NSLocalizedString("_used_space_", comment: "")) \(ufs.transformedSize(totalSize)))"
  143. }
  144. }
  145. /// Removes all accounts & exits the Nextcloud application if specified.
  146. ///
  147. /// - Parameter
  148. /// exit: Boolean indicating whether to reset the application.
  149. func resetNextCloud() {
  150. self.appDelegate.resetApplication()
  151. }
  152. /// Exits the Nextcloud application if specified.
  153. ///
  154. /// - Parameter
  155. /// exit: Boolean indicating whether to exit the application.
  156. func exitNextCloud(ext: Bool) {
  157. if ext {
  158. exit(0)
  159. } else { }
  160. }
  161. /// Presents the log file viewer.
  162. func viewLogFile() {
  163. // Instantiate NCViewerQuickLook with the log file URL, editing disabled, and no metadata
  164. let viewerQuickLook = NCViewerQuickLook(with: NSURL(fileURLWithPath: NextcloudKit.shared.nkCommonInstance.filenamePathLog) as URL, isEditingEnabled: false, metadata: nil)
  165. // Present the NCViewerQuickLook view controller
  166. controller?.present(viewerQuickLook, animated: true, completion: nil)
  167. }
  168. /// Clears the log file.
  169. func clearLogFile() {
  170. // Clear the log file using NextcloudKit
  171. NextcloudKit.shared.nkCommonInstance.clearFileLog()
  172. // Fetch the log level from the keychain
  173. let logLevel = keychain.logLevel
  174. // Check if the app is running in a simulator or TestFlight environment
  175. let isSimulatorOrTestFlight = NCUtility().isSimulatorOrTestFlight()
  176. // Get the app's version and copyright information
  177. let versionNextcloudiOS = String(format: NCBrandOptions.shared.textCopyrightNextcloudiOS, NCUtility().getVersionApp(withBuild: true))
  178. // Construct the log message
  179. let logMessage = "[INFO] Clear log with level \(logLevel) \(versionNextcloudiOS)" + (isSimulatorOrTestFlight ? " (Simulator / TestFlight)" : "")
  180. // Write the log entry about the log clearance
  181. NextcloudKit.shared.nkCommonInstance.writeLog(logMessage)
  182. // Set the alert state to show that log file has been cleared
  183. self.logFileCleared = true
  184. }
  185. }
  186. /// An enum that represents the level of the log
  187. enum LogLevel: Int, CaseIterable, Identifiable, Equatable {
  188. /// Represents that logging is disabled
  189. case disabled = 0
  190. /// Represents standard logging level
  191. case standard = 1
  192. /// Represents maximum logging level
  193. case maximum = 2
  194. var id: Int { self.rawValue }
  195. }
  196. extension LogLevel {
  197. var displayText: String {
  198. switch self {
  199. case .disabled:
  200. return NSLocalizedString("_disabled_", comment: "")
  201. case .standard:
  202. return NSLocalizedString("_standard_", comment: "")
  203. case .maximum:
  204. return NSLocalizedString("_maximum_", comment: "")
  205. }
  206. }
  207. }
  208. /// An enum that represents the intervals for cache deletion
  209. enum CacheDeletionInterval: Int, CaseIterable, Identifiable {
  210. case never = 0
  211. case oneYear = 365
  212. case sixMonths = 180
  213. case threeMonths = 90
  214. case oneMonth = 30
  215. case oneWeek = 7
  216. var id: Int { self.rawValue }
  217. }
  218. extension CacheDeletionInterval {
  219. var displayText: String {
  220. switch self {
  221. case .never:
  222. return NSLocalizedString("_never_", comment: "")
  223. case .oneYear:
  224. return NSLocalizedString("_1_year_", comment: "")
  225. case .sixMonths:
  226. return NSLocalizedString("_6_months_", comment: "")
  227. case .threeMonths:
  228. return NSLocalizedString("_3_months_", comment: "")
  229. case .oneMonth:
  230. return NSLocalizedString("_1_month_", comment: "")
  231. case .oneWeek:
  232. return NSLocalizedString("_1_week_", comment: "")
  233. }
  234. }
  235. }