mirror of
https://github.com/permissionlesstech/bitchat.git
synced 2026-07-25 16:25:21 +00:00
Ensure /clear and panic triple-tap delete media files
Fix: /clear command and panicClearAllData() now properly delete media files 1. /clear (triple-tap on chat): - Deletes outgoing media (voice notes, images, files) - Conservative: only our sent media, preserves received media - Runs in background to avoid UI freeze 2. panicClearAllData() (triple-tap on bitchat/ header): - Deletes ALL media files (incoming + outgoing) - Removes entire files directory and recreates structure - Ensures complete data wipe for emergency scenarios Both operations run async on .utility queue to prevent blocking UI.
This commit is contained in:
@@ -3691,9 +3691,34 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
|||||||
nostrRelayManager?.connect()
|
nostrRelayManager?.connect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete ALL media files (incoming and outgoing) in background
|
||||||
|
Task.detached(priority: .utility) {
|
||||||
|
do {
|
||||||
|
let base = try FileManager.default.url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
|
||||||
|
let filesDir = base.appendingPathComponent("files", isDirectory: true)
|
||||||
|
|
||||||
|
// Delete the entire files directory and recreate it
|
||||||
|
if FileManager.default.fileExists(atPath: filesDir.path) {
|
||||||
|
try FileManager.default.removeItem(at: filesDir)
|
||||||
|
SecureLogger.info("🗑️ Deleted all media files during panic clear", category: .session)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recreate empty directory structure
|
||||||
|
try FileManager.default.createDirectory(at: filesDir, withIntermediateDirectories: true, attributes: nil)
|
||||||
|
try FileManager.default.createDirectory(at: filesDir.appendingPathComponent("voicenotes/incoming", isDirectory: true), withIntermediateDirectories: true, attributes: nil)
|
||||||
|
try FileManager.default.createDirectory(at: filesDir.appendingPathComponent("voicenotes/outgoing", isDirectory: true), withIntermediateDirectories: true, attributes: nil)
|
||||||
|
try FileManager.default.createDirectory(at: filesDir.appendingPathComponent("images/incoming", isDirectory: true), withIntermediateDirectories: true, attributes: nil)
|
||||||
|
try FileManager.default.createDirectory(at: filesDir.appendingPathComponent("images/outgoing", isDirectory: true), withIntermediateDirectories: true, attributes: nil)
|
||||||
|
try FileManager.default.createDirectory(at: filesDir.appendingPathComponent("files/incoming", isDirectory: true), withIntermediateDirectories: true, attributes: nil)
|
||||||
|
try FileManager.default.createDirectory(at: filesDir.appendingPathComponent("files/outgoing", isDirectory: true), withIntermediateDirectories: true, attributes: nil)
|
||||||
|
} catch {
|
||||||
|
SecureLogger.error("Failed to clear media files during panic: \(error)", category: .session)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Force immediate UI update for panic mode
|
// Force immediate UI update for panic mode
|
||||||
// UI updates immediately - no flushing needed
|
// UI updates immediately - no flushing needed
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Autocomplete
|
// MARK: - Autocomplete
|
||||||
@@ -4695,6 +4720,7 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
|||||||
// Clear the current public channel's timeline (visible + persistent buffer)
|
// Clear the current public channel's timeline (visible + persistent buffer)
|
||||||
@MainActor
|
@MainActor
|
||||||
func clearCurrentPublicTimeline() {
|
func clearCurrentPublicTimeline() {
|
||||||
|
// Clear messages from current timeline
|
||||||
switch activeChannel {
|
switch activeChannel {
|
||||||
case .mesh:
|
case .mesh:
|
||||||
messages.removeAll()
|
messages.removeAll()
|
||||||
@@ -4703,6 +4729,32 @@ final class ChatViewModel: ObservableObject, BitchatDelegate {
|
|||||||
messages.removeAll()
|
messages.removeAll()
|
||||||
geoTimelines[ch.geohash] = []
|
geoTimelines[ch.geohash] = []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete associated media files (images, voice notes, files) in background
|
||||||
|
// Only delete from current chat to avoid removing private chat media
|
||||||
|
Task.detached(priority: .utility) {
|
||||||
|
do {
|
||||||
|
let base = try FileManager.default.url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
|
||||||
|
let filesDir = base.appendingPathComponent("files", isDirectory: true)
|
||||||
|
|
||||||
|
// Only clear public media (mesh channel only - geohash media is separate)
|
||||||
|
// Note: This is conservative - only clears outgoing since we authored those
|
||||||
|
let outgoingDirs = [
|
||||||
|
filesDir.appendingPathComponent("voicenotes/outgoing", isDirectory: true),
|
||||||
|
filesDir.appendingPathComponent("images/outgoing", isDirectory: true),
|
||||||
|
filesDir.appendingPathComponent("files/outgoing", isDirectory: true)
|
||||||
|
]
|
||||||
|
|
||||||
|
for dir in outgoingDirs {
|
||||||
|
if FileManager.default.fileExists(atPath: dir.path) {
|
||||||
|
try? FileManager.default.removeItem(at: dir)
|
||||||
|
try? FileManager.default.createDirectory(at: dir, withIntermediateDirectories: true, attributes: nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
SecureLogger.error("Failed to clear media files: \(error)", category: .session)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Message Management
|
// MARK: - Message Management
|
||||||
|
|||||||
Reference in New Issue
Block a user