NCSettingsAdvancedModel.swift 10 KB

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