NCSettingsAdvancedModel.swift 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  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 whether hidden files are shown.
  35. @Published var showHiddenFiles: Bool = false
  36. /// State variable for indicating the most compatible format.
  37. @Published var mostCompatible: Bool = false
  38. /// State variable for enabling live photo uploads.
  39. @Published var livePhoto: Bool = false
  40. /// State variable for indicating whether to remove photos from the camera roll after upload.
  41. @Published var removeFromCameraRoll: Bool = false
  42. /// State variable for app integration.
  43. @Published var appIntegration: Bool = false
  44. /// State variable for enabling the crash reporter.
  45. @Published var crashReporter: Bool = false
  46. /// State variable for indicating whether the log file has been cleared.
  47. @Published var logFileCleared: Bool = false
  48. // Properties for log level and cache deletion
  49. /// State variable for storing the selected log level.
  50. @Published var selectedLogLevel: LogLevel = .standard
  51. /// State variable for storing the selected cache deletion interval.
  52. @Published var selectedInterval: CacheDeletionInterval = .never
  53. /// State variable for storing the footer title, usually used for cache deletion.
  54. @Published var footerTitle: String = ""
  55. /// Root View Controller
  56. @Published var controller: NCMainTabBarController?
  57. /// Initializes the view model with default values.
  58. init(controller: NCMainTabBarController?) {
  59. self.controller = controller
  60. onViewAppear()
  61. }
  62. /// Triggered when the view appears.
  63. func onViewAppear() {
  64. showHiddenFiles = keychain.showHiddenFiles
  65. mostCompatible = keychain.formatCompatibility
  66. livePhoto = keychain.livePhoto
  67. removeFromCameraRoll = keychain.removePhotoCameraRoll
  68. appIntegration = keychain.disableFilesApp
  69. crashReporter = keychain.disableCrashservice
  70. selectedLogLevel = LogLevel(rawValue: keychain.logLevel) ?? .standard
  71. selectedInterval = CacheDeletionInterval(rawValue: keychain.cleanUpDay) ?? .never
  72. DispatchQueue.global().async {
  73. self.calculateSize()
  74. }
  75. }
  76. // MARK: - All functions
  77. /// Updates the value of `showHiddenFiles` in the keychain.
  78. func updateShowHiddenFiles() {
  79. keychain.showHiddenFiles = showHiddenFiles
  80. }
  81. /// Updates the value of `mostCompatible` in the keychain.
  82. func updateMostCompatible() {
  83. keychain.formatCompatibility = mostCompatible
  84. }
  85. /// Updates the value of `livePhoto` in the keychain.
  86. func updateLivePhoto() {
  87. keychain.livePhoto = livePhoto
  88. }
  89. /// Updates the value of `removeFromCameraRoll` in the keychain.
  90. func updateRemoveFromCameraRoll() {
  91. keychain.removePhotoCameraRoll = removeFromCameraRoll
  92. }
  93. /// Updates the value of `appIntegration` in the keychain.
  94. func updateAppIntegration() {
  95. keychain.disableFilesApp = appIntegration
  96. }
  97. /// Updates the value of `crashReporter` in the keychain.
  98. func updateCrashReporter() {
  99. keychain.disableCrashservice = crashReporter
  100. }
  101. /// Updates the value of `selectedLogLevel` in the keychain and sets it for NextcloudKit.
  102. func updateSelectedLogLevel() {
  103. keychain.logLevel = selectedLogLevel.rawValue
  104. NextcloudKit.shared.nkCommonInstance.levelLog = selectedLogLevel.rawValue
  105. }
  106. /// Updates the value of `selectedInterval` in the keychain.
  107. func updateSelectedInterval() {
  108. keychain.cleanUpDay = selectedInterval.rawValue
  109. }
  110. /// Clears cache associated with the specified account.
  111. func clearCache() {
  112. NCActivityIndicator.shared.startActivity(style: .large, blurEffect: true)
  113. // Cancel all networking tasks
  114. NCNetworking.shared.cancelAllTask()
  115. DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
  116. URLCache.shared.memoryCapacity = 0
  117. URLCache.shared.diskCapacity = 0
  118. NCManageDatabase.shared.clearDatabase(account: self.appDelegate.account, removeAccount: false)
  119. let ufs = NCUtilityFileSystem()
  120. ufs.removeGroupDirectoryProviderStorage()
  121. ufs.removeGroupLibraryDirectory()
  122. ufs.removeDocumentsDirectory()
  123. ufs.removeTemporaryDirectory()
  124. ufs.createDirectoryStandard()
  125. NCAutoUpload.shared.alignPhotoLibrary(viewController: self.controller)
  126. NCImageCache.shared.createMediaCache(account: self.appDelegate.account, withCacheSize: true)
  127. NCActivityIndicator.shared.stop()
  128. self.calculateSize()
  129. }
  130. }
  131. /// Asynchronously calculates the size of cache directory and updates the footer title.
  132. func calculateSize() {
  133. let ufs = NCUtilityFileSystem()
  134. let directory = ufs.directoryProviderStorage
  135. let totalSize = ufs.getDirectorySize(directory: directory)
  136. DispatchQueue.main.async {
  137. self.footerTitle = "\(NSLocalizedString("_clear_cache_footer_", comment: "")). (\(NSLocalizedString("_used_space_", comment: "")) \(ufs.transformedSize(totalSize)))"
  138. }
  139. }
  140. /// Removes all accounts & exits the Nextcloud application if specified.
  141. ///
  142. /// - Parameter
  143. /// exit: Boolean indicating whether to reset the application.
  144. func resetNextCloud(exit: Bool) {
  145. if exit {
  146. self.appDelegate.resetApplication()
  147. } else { }
  148. }
  149. /// Exits the Nextcloud application if specified.
  150. ///
  151. /// - Parameter
  152. /// exit: Boolean indicating whether to exit the application.
  153. func exitNextCloud(ext: Bool) {
  154. if ext {
  155. exit(0)
  156. } else { }
  157. }
  158. /// Presents the log file viewer.
  159. func viewLogFile() {
  160. // Instantiate NCViewerQuickLook with the log file URL, editing disabled, and no metadata
  161. let viewerQuickLook = NCViewerQuickLook(with: NSURL(fileURLWithPath: NextcloudKit.shared.nkCommonInstance.filenamePathLog) as URL, isEditingEnabled: false, metadata: nil)
  162. // Present the NCViewerQuickLook view controller
  163. controller?.present(viewerQuickLook, animated: true, completion: nil)
  164. }
  165. /// Clears the log file.
  166. func clearLogFile() {
  167. // Clear the log file using NextcloudKit
  168. NextcloudKit.shared.nkCommonInstance.clearFileLog()
  169. // Fetch the log level from the keychain
  170. let logLevel = keychain.logLevel
  171. // Check if the app is running in a simulator or TestFlight environment
  172. let isSimulatorOrTestFlight = NCUtility().isSimulatorOrTestFlight()
  173. // Get the app's version and copyright information
  174. let versionNextcloudiOS = String(format: NCBrandOptions.shared.textCopyrightNextcloudiOS, NCUtility().getVersionApp(withBuild: true))
  175. // Construct the log message
  176. let logMessage = "[INFO] Clear log with level \(logLevel) \(versionNextcloudiOS)" + (isSimulatorOrTestFlight ? " (Simulator / TestFlight)" : "")
  177. // Write the log entry about the log clearance
  178. NextcloudKit.shared.nkCommonInstance.writeLog(logMessage)
  179. // Set the alert state to show that log file has been cleared
  180. self.logFileCleared = true
  181. }
  182. }
  183. /// An enum that represents the level of the log
  184. enum LogLevel: Int, CaseIterable, Identifiable, Equatable {
  185. /// Represents that logging is disabled
  186. case disabled = 0
  187. /// Represents standard logging level
  188. case standard = 1
  189. /// Represents maximum logging level
  190. case maximum = 2
  191. var id: Int { self.rawValue }
  192. }
  193. extension LogLevel {
  194. var displayText: String {
  195. switch self {
  196. case .disabled:
  197. return NSLocalizedString("_disabled_", comment: "")
  198. case .standard:
  199. return NSLocalizedString("_standard_", comment: "")
  200. case .maximum:
  201. return NSLocalizedString("_maximum_", comment: "")
  202. }
  203. }
  204. }
  205. /// An enum that represents the intervals for cache deletion
  206. enum CacheDeletionInterval: Int, CaseIterable, Identifiable {
  207. case never = 0
  208. case oneYear = 365
  209. case sixMonths = 180
  210. case threeMonths = 90
  211. case oneMonth = 30
  212. case oneWeek = 7
  213. var id: Int { self.rawValue }
  214. }
  215. extension CacheDeletionInterval {
  216. var displayText: String {
  217. switch self {
  218. case .never:
  219. return NSLocalizedString("_never_", comment: "")
  220. case .oneYear:
  221. return NSLocalizedString("_1_year_", comment: "")
  222. case .sixMonths:
  223. return NSLocalizedString("_6_months_", comment: "")
  224. case .threeMonths:
  225. return NSLocalizedString("_3_months_", comment: "")
  226. case .oneMonth:
  227. return NSLocalizedString("_1_month_", comment: "")
  228. case .oneWeek:
  229. return NSLocalizedString("_1_week_", comment: "")
  230. }
  231. }
  232. }