diff --git a/apps/ios/Shared/Views/UserSettings/StorageView.swift b/apps/ios/Shared/Views/UserSettings/StorageView.swift index 094c1cb3d6..9d88e02be2 100644 --- a/apps/ios/Shared/Views/UserSettings/StorageView.swift +++ b/apps/ios/Shared/Views/UserSettings/StorageView.swift @@ -10,33 +10,66 @@ import SwiftUI import SimpleXChat struct StorageView: View { + @EnvironmentObject var m: ChatModel + @EnvironmentObject var theme: AppTheme @State var appGroupFiles: [String: Int64] = [:] @State var documentsFiles: [String: Int64] = [:] var body: some View { ScrollView { VStack(alignment: .leading) { - directoryView("App group:", appGroupFiles) + directoryView("App group:", getGroupContainerDirectory(), appGroupFiles) if !documentsFiles.isEmpty { - directoryView("Documents:", documentsFiles) + directoryView("Documents:", getDocumentsDirectory(), documentsFiles) } } } .padding() - .onAppear { - appGroupFiles = traverseFiles(in: getGroupContainerDirectory()) - documentsFiles = traverseFiles(in: getDocumentsDirectory()) - } + .onAppear(perform: loadFiles) + } + + private func loadFiles() { + appGroupFiles = traverseFiles(in: getGroupContainerDirectory()) + documentsFiles = traverseFiles(in: getDocumentsDirectory()) } @ViewBuilder - private func directoryView(_ name: LocalizedStringKey, _ contents: [String: Int64]) -> some View { + private func directoryView(_ name: LocalizedStringKey, _ dir: URL, _ contents: [String: Int64]) -> some View { Text(name).font(.headline) ForEach(Array(contents), id: \.key) { (key, value) in - Text(key).bold() + Text(verbatim: " ") + Text((ByteCountFormatter.string(fromByteCount: value, countStyle: .binary))) + let sizeText = Text(key).bold() + Text(verbatim: " ") + Text((ByteCountFormatter.string(fromByteCount: value, countStyle: .binary))) + if dir.appendingPathComponent(key).path == getTempFilesDirectory().path { + let stopped = m.chatRunning == false + HStack { + sizeText + Button("Delete temp data", role: .destructive, action: confirmDeleteTempFiles) + .disabled(!stopped) + } + if !stopped { + Text("Stop chat in Settings → Chat data → Database passphrase & export to delete temp data.") + .font(.footnote) + .foregroundColor(theme.colors.secondary) + } + } else { + sizeText + } } } + private func confirmDeleteTempFiles() { + showAlert( + NSLocalizedString("Delete temp data?", comment: "alert title"), + message: NSLocalizedString("Files being sent or received will never complete. Videos in unsent drafts will be sent without the file.", comment: "alert message"), + actions: {[ + UIAlertAction(title: NSLocalizedString("Delete", comment: "alert action"), style: .destructive) { _ in + deleteTempFiles() + loadFiles() + }, + cancelAlertAction + ]} + ) + } + private func traverseFiles(in dir: URL) -> [String: Int64] { var res: [String: Int64] = [:] let fm = FileManager.default diff --git a/apps/ios/SimpleXChat/FileUtils.swift b/apps/ios/SimpleXChat/FileUtils.swift index 1641541ef7..ba40a6817d 100644 --- a/apps/ios/SimpleXChat/FileUtils.swift +++ b/apps/ios/SimpleXChat/FileUtils.swift @@ -140,6 +140,16 @@ public func deleteAppFiles() { } } +public func deleteTempFiles() { + let fm = FileManager.default + do { + try fm.removeItem(at: getTempFilesDirectory()) + try fm.createDirectory(at: getTempFilesDirectory(), withIntermediateDirectories: true) + } catch { + logger.error("FileUtils deleteTempFiles error: \(error.localizedDescription)") + } +} + public func fileSize(_ url: URL) -> Int? { // in bytes do { let val = try url.resourceValues(forKeys: [.totalFileAllocatedSizeKey, .fileAllocatedSizeKey])