From d457bc18d22617f8111817f7e0fecdcad01453f8 Mon Sep 17 00:00:00 2001 From: Narasimha-sc <166327228+Narasimha-sc@users.noreply.github.com> Date: Sat, 10 Oct 2026 21:38:14 +0000 Subject: [PATCH] ios: delete temp data from storage view (#7626) * ios: delete temp data from storage view The temp folder is the XFTP agent work directory and holds scratch files for received-file encryption and roster transfers, so deleting it under a running chat breaks those writes mid-flight. The button is only enabled while chat is stopped, the same precondition core deleteStorage relies on, and the row says how to stop chat. * ios: show delete temp data alert over settings sheet AlertManager presents from ContentView, which is behind the settings sheet, so the confirmation never appeared. The alert now also warns that interrupted transfers never complete and that videos in unsent drafts, which live in the temp folder, are lost, and the caption names the screen where chat is stopped. * ios: say unsent draft videos are sent without the file A draft video whose converted file was deleted from the temp folder is still sent, as a preview with no file, so "lost" understated it. --------- Co-authored-by: Evgeny Poberezkin --- .../Views/UserSettings/StorageView.swift | 49 ++++++++++++++++--- apps/ios/SimpleXChat/FileUtils.swift | 10 ++++ 2 files changed, 51 insertions(+), 8 deletions(-) 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])