mirror of
https://github.com/sudosylabs/vnidrop.git
synced 2026-08-05 02:29:55 +02:00
fix(storage): reclaim transfer cache and track received files
This commit is contained in:
@@ -27,9 +27,10 @@ enum SettingsSection: Hashable {
|
||||
/// On-disk usage breakdown for the Storage screen.
|
||||
struct StorageBreakdown: Equatable {
|
||||
var receivedFiles: UInt64 = 0
|
||||
var transferData: UInt64 = 0
|
||||
var transferCache: UInt64 = 0
|
||||
var appData: UInt64 = 0
|
||||
var temporary: UInt64 = 0
|
||||
var total: UInt64 { receivedFiles + transferData + temporary }
|
||||
var total: UInt64 { receivedFiles + transferCache + appData + temporary }
|
||||
}
|
||||
|
||||
struct SettingsState: Equatable {
|
||||
@@ -286,19 +287,29 @@ final class SettingsModel: ObservableObject {
|
||||
func loadStorageUsage() {
|
||||
if state.isCalculatingStorage { return }
|
||||
state.isCalculatingStorage = true
|
||||
let coreDir = environment.defaultCoreDataDir
|
||||
let receiveDir = state.receiveFolder?.isFileSystemPath == true ? state.receiveFolder?.value : nil
|
||||
let tempDir = NSTemporaryDirectory()
|
||||
Task.detached {
|
||||
let breakdown = StorageBreakdown(
|
||||
receivedFiles: receiveDir.map { SettingsModel.directorySize($0) } ?? 0,
|
||||
transferData: SettingsModel.directorySize(coreDir),
|
||||
temporary: SettingsModel.directorySize(tempDir)
|
||||
)
|
||||
await MainActor.run { [weak self] in
|
||||
self?.state.storage = breakdown
|
||||
self?.state.isCalculatingStorage = false
|
||||
Task {
|
||||
let coreResult = await repository.storageUsage()
|
||||
let artifactsResult = await repository.receivedArtifacts()
|
||||
guard case .success(let core) = coreResult,
|
||||
case .success(let artifacts) = artifactsResult else {
|
||||
state.isCalculatingStorage = false
|
||||
return
|
||||
}
|
||||
let diskSizes = await Task.detached {
|
||||
let received = artifacts.reduce(UInt64(0)) { total, artifact in
|
||||
total + SettingsModel.fileSize(artifact.locator)
|
||||
}
|
||||
return (received, SettingsModel.directorySize(tempDir))
|
||||
}.value
|
||||
let breakdown = StorageBreakdown(
|
||||
receivedFiles: diskSizes.0,
|
||||
transferCache: core.blobStoreBytes,
|
||||
appData: core.appDataBytes,
|
||||
temporary: diskSizes.1
|
||||
)
|
||||
state.storage = breakdown
|
||||
state.isCalculatingStorage = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -309,16 +320,29 @@ final class SettingsModel: ObservableObject {
|
||||
if state.isDeletingTransfers { return }
|
||||
state.isDeletingTransfers = true
|
||||
Task {
|
||||
var failures = 0
|
||||
for id in repository.state.transfers.map(\.transferId) {
|
||||
_ = await repository.delete(transferId: id)
|
||||
if case .failure = await repository.delete(transferId: id) { failures += 1 }
|
||||
}
|
||||
_ = await repository.refresh()
|
||||
state.isDeletingTransfers = false
|
||||
loadStorageUsage()
|
||||
messages.show(UiMessage(text: .resource("storage_transfers_deleted"), tone: .success))
|
||||
if failures == 0 {
|
||||
loadStorageUsage()
|
||||
messages.show(UiMessage(text: .resource("storage_transfers_deleted"), tone: .success))
|
||||
} else {
|
||||
messages.error(InvitationError.message("Could not delete \(failures) transfer records"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nonisolated static func fileSize(_ path: String) -> UInt64 {
|
||||
let values = try? URL(fileURLWithPath: path).resourceValues(
|
||||
forKeys: [.isRegularFileKey, .totalFileAllocatedSizeKey, .fileSizeKey]
|
||||
)
|
||||
guard values?.isRegularFile == true else { return 0 }
|
||||
return UInt64(values?.totalFileAllocatedSize ?? values?.fileSize ?? 0)
|
||||
}
|
||||
|
||||
/// Recursive size of every regular file under `path` (0 if missing).
|
||||
nonisolated static func directorySize(_ path: String) -> UInt64 {
|
||||
let url = URL(fileURLWithPath: path)
|
||||
|
||||
@@ -65,7 +65,8 @@ struct StorageSettings: View {
|
||||
Section {
|
||||
if let storage = model.state.storage {
|
||||
LabeledContent(String(localized: "storage_received_files"), value: formatBytes(storage.receivedFiles))
|
||||
LabeledContent(String(localized: "storage_transfer_data"), value: formatBytes(storage.transferData))
|
||||
LabeledContent(String(localized: "storage_transfer_data"), value: formatBytes(storage.transferCache))
|
||||
LabeledContent(String(localized: "storage_app_data"), value: formatBytes(storage.appData))
|
||||
LabeledContent(String(localized: "storage_temporary"), value: formatBytes(storage.temporary))
|
||||
LabeledContent(String(localized: "storage_total")) {
|
||||
Text(formatBytes(storage.total)).fontWeight(.semibold)
|
||||
|
||||
Reference in New Issue
Block a user