ios: clear storage (#1069)
* wip * display current storage state * alert * fix * simplify * remove unused function * fix log * replace prints with logger * Apply suggestions from code review Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com> * low res will remain text Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
This commit is contained in:
@@ -17,6 +17,7 @@ enum DatabaseAlert: Identifiable {
|
||||
case deleteChat
|
||||
case chatDeleted
|
||||
case deleteLegacyDatabase
|
||||
case deleteFilesAndMedia
|
||||
case error(title: LocalizedStringKey, error: String = "")
|
||||
|
||||
var id: String {
|
||||
@@ -28,6 +29,7 @@ enum DatabaseAlert: Identifiable {
|
||||
case .deleteChat: return "deleteChat"
|
||||
case .chatDeleted: return "chatDeleted"
|
||||
case .deleteLegacyDatabase: return "deleteLegacyDatabase"
|
||||
case .deleteFilesAndMedia: return "deleteFilesAndMedia"
|
||||
case let .error(title, _): return "error \(title)"
|
||||
}
|
||||
}
|
||||
@@ -46,6 +48,7 @@ struct DatabaseView: View {
|
||||
@State private var dbContainer = dbContainerGroupDefault.get()
|
||||
@State private var legacyDatabase = hasLegacyDatabase()
|
||||
@State private var useKeychain = storeDBPassphraseGroupDefault.get()
|
||||
@State private var appFilesCountAndSize: (Int, Int)?
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
@@ -147,8 +150,27 @@ struct DatabaseView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Section {
|
||||
Button("Delete files & media", role: .destructive) {
|
||||
alert = .deleteFilesAndMedia
|
||||
}
|
||||
} header: {
|
||||
Text("Files")
|
||||
} footer: {
|
||||
if let (fileCount, size) = appFilesCountAndSize {
|
||||
if fileCount == 0 {
|
||||
Text("No received or sent files")
|
||||
} else {
|
||||
Text("\(fileCount) file(s) with total size of \(ByteCountFormatter().string(fromByteCount: Int64(size)))")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
runChat = m.chatRunning ?? true
|
||||
appFilesCountAndSize = directoryFileCountAndSize(getAppFilesDirectory())
|
||||
}
|
||||
.onAppear { runChat = m.chatRunning ?? true }
|
||||
.alert(item: $alert) { item in databaseAlert(item) }
|
||||
.fileImporter(
|
||||
isPresented: $showFileImporter,
|
||||
@@ -222,6 +244,15 @@ struct DatabaseView: View {
|
||||
},
|
||||
secondaryButton: .cancel()
|
||||
)
|
||||
case .deleteFilesAndMedia:
|
||||
return Alert(
|
||||
title: Text("Delete files and media?"),
|
||||
message: Text("This action cannot be undone - all received and sent files and media will be deleted. Low resolution pictures will remain."),
|
||||
primaryButton: .destructive(Text("Delete")) {
|
||||
deleteFiles()
|
||||
},
|
||||
secondaryButton: .cancel()
|
||||
)
|
||||
case let .error(title, error):
|
||||
return Alert(title: Text(title), message: Text("\(error)"))
|
||||
}
|
||||
@@ -354,6 +385,11 @@ struct DatabaseView: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func deleteFiles() {
|
||||
deleteAppFiles()
|
||||
appFilesCountAndSize = directoryFileCountAndSize(getAppFilesDirectory())
|
||||
}
|
||||
}
|
||||
|
||||
struct DatabaseView_Previews: PreviewProvider {
|
||||
|
||||
@@ -61,6 +61,46 @@ func fileModificationDate(_ path: String) -> Date? {
|
||||
}
|
||||
}
|
||||
|
||||
public func deleteAppFiles() {
|
||||
let fm = FileManager.default
|
||||
do {
|
||||
let fileNames = try fm.contentsOfDirectory(atPath: getAppFilesDirectory().path)
|
||||
for fileName in fileNames {
|
||||
removeFile(fileName)
|
||||
}
|
||||
} catch {
|
||||
logger.error("FileUtils deleteAppFiles error: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
|
||||
func fileSize(_ url: URL) -> Int? { // in bytes
|
||||
do {
|
||||
let val = try url.resourceValues(forKeys: [.totalFileAllocatedSizeKey, .fileAllocatedSizeKey])
|
||||
return val.totalFileAllocatedSize ?? val.fileAllocatedSize
|
||||
} catch {
|
||||
logger.error("FileUtils fileSize error: \(error.localizedDescription)")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
public func directoryFileCountAndSize(_ dir: URL) -> (Int, Int)? { // size in bytes
|
||||
let fm = FileManager.default
|
||||
if let enumerator = fm.enumerator(at: dir, includingPropertiesForKeys: [.totalFileAllocatedSizeKey, .fileAllocatedSizeKey], options: [], errorHandler: { (_, error) -> Bool in
|
||||
logger.error("FileUtils directoryFileCountAndSize error: \(error.localizedDescription)")
|
||||
return false
|
||||
}) {
|
||||
var fileCount = 0
|
||||
var bytes = 0
|
||||
for case let url as URL in enumerator {
|
||||
fileCount += 1
|
||||
bytes += fileSize(url) ?? 0
|
||||
}
|
||||
return (fileCount, bytes)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
public func hasBackup(newerThan date: Date) -> Bool {
|
||||
let dbPath = getAppDatabasePath().path
|
||||
return hasBackupFile(dbPath + AGENT_DB_BAK, newerThan: date)
|
||||
|
||||
Reference in New Issue
Block a user