feat: added an option to manually refresh disk space information (allow to reset cached purgable space)

This commit is contained in:
Serhiy Mytrovtsiy
2026-01-27 21:09:57 +01:00
parent 481f94d511
commit eb5fb353d9
3 changed files with 51 additions and 14 deletions

View File

@@ -251,6 +251,11 @@ public class Disk: Module {
} }
} }
self.popupView.refreshCallback = { [weak self] uuid in
self?.capacityReader?.resetPurgableSpace(for: uuid)
self?.capacityReader?.read()
}
self.selectedDisk = Store.shared.string(key: "\(ModuleType.disk.stringValue)_disk", defaultValue: self.selectedDisk) self.selectedDisk = Store.shared.string(key: "\(ModuleType.disk.stringValue)_disk", defaultValue: self.selectedDisk)
self.settingsView.selectedDiskHandler = { [weak self] value in self.settingsView.selectedDiskHandler = { [weak self] value in

View File

@@ -13,6 +13,8 @@ import Cocoa
import Kit import Kit
internal class Popup: PopupWrapper { internal class Popup: PopupWrapper {
public var refreshCallback: ((String) -> Void) = {_ in }
private var readColorState: SColor = .secondBlue private var readColorState: SColor = .secondBlue
private var readColor: NSColor { self.readColorState.additional as? NSColor ?? NSColor.systemRed } private var readColor: NSColor { self.readColorState.additional as? NSColor ?? NSColor.systemRed }
private var writeColorState: SColor = .secondRed private var writeColorState: SColor = .secondRed
@@ -140,7 +142,8 @@ internal class Popup: PopupWrapper {
free: drive.free, free: drive.free,
path: drive.path, path: drive.path,
smart: drive.smart, smart: drive.smart,
resize: self.recalculateHeight resize: self.recalculateHeight,
refresh: self.refreshCallback
)) ))
} }
} }
@@ -271,6 +274,7 @@ internal class Popup: PopupWrapper {
internal class DiskView: NSStackView { internal class DiskView: NSStackView {
internal var sizeCallback: (() -> Void) = {} internal var sizeCallback: (() -> Void) = {}
internal var refreshCallback: ((String) -> Void) = {_ in }
public var name: String public var name: String
public var uuid: String public var uuid: String
@@ -287,8 +291,9 @@ internal class DiskView: NSStackView {
set { Store.shared.set(key: "\(self.uuid)_details", value: newValue) } set { Store.shared.set(key: "\(self.uuid)_details", value: newValue) }
} }
init(width: CGFloat, uuid: String = "", name: String = "", size: Int64 = 1, free: Int64 = 1, path: URL? = nil, smart: smart_t? = nil, resize: @escaping () -> Void) { init(width: CGFloat, uuid: String, name: String, size: Int64 = 1, free: Int64 = 1, path: URL? = nil, smart: smart_t? = nil, resize: @escaping () -> Void, refresh: @escaping (String) -> Void) {
self.sizeCallback = resize self.sizeCallback = resize
self.refreshCallback = refresh
self.uuid = uuid self.uuid = uuid
self.name = name self.name = name
self.width = width self.width = width
@@ -314,6 +319,10 @@ internal class DiskView: NSStackView {
s.detailsState = !s.detailsState s.detailsState = !s.detailsState
s.toggleDetails() s.toggleDetails()
} }
self.nameView.refreshCallback = { [weak self] in
guard let uuid = self?.uuid else { return }
self?.refreshCallback(uuid)
}
self.addArrangedSubview(self.nameView) self.addArrangedSubview(self.nameView)
self.addArrangedSubview(self.chartView) self.addArrangedSubview(self.chartView)
@@ -366,6 +375,7 @@ internal class DiskView: NSStackView {
internal class NameView: NSStackView { internal class NameView: NSStackView {
internal var detailsCallback: (() -> Void) = {} internal var detailsCallback: (() -> Void) = {}
internal var refreshCallback: (() -> Void) = {}
private let size: Int64 private let size: Int64
private let uri: URL? private let uri: URL?
@@ -401,7 +411,7 @@ internal class NameView: NSStackView {
nameField.contentTintColor = .labelColor nameField.contentTintColor = .labelColor
nameField.action = #selector(self.openDisk) nameField.action = #selector(self.openDisk)
nameField.target = self nameField.target = self
nameField.toolTip = localizedString("Control") nameField.toolTip = name
nameField.title = name nameField.title = name
nameField.cell?.truncatesLastVisibleLine = true nameField.cell?.truncatesLastVisibleLine = true
@@ -429,21 +439,33 @@ internal class NameView: NSStackView {
activity.addArrangedSubview(readState) activity.addArrangedSubview(readState)
activity.addArrangedSubview(writeState) activity.addArrangedSubview(writeState)
let button = NSButton() let refreshButton = NSButton()
button.frame = CGRect(x: (self.frame.width/3)-20, y: 10, width: 15, height: 15) refreshButton.frame = CGRect(x: (self.frame.width/3)-40, y: 10, width: 15, height: 15)
button.bezelStyle = .regularSquare refreshButton.bezelStyle = .regularSquare
button.isBordered = false refreshButton.isBordered = false
button.imageScaling = NSImageScaling.scaleAxesIndependently refreshButton.imageScaling = NSImageScaling.scaleAxesIndependently
button.contentTintColor = .lightGray refreshButton.contentTintColor = .lightGray
button.action = #selector(self.toggleDetails) refreshButton.action = #selector(self.refreshDisk)
button.target = self refreshButton.target = self
button.toolTip = localizedString("Control") refreshButton.toolTip = localizedString("Refresh disk information")
button.image = Bundle(for: Module.self).image(forResource: "tune")! refreshButton.image = Bundle(for: Module.self).image(forResource: "refresh")!
let detailsButton = NSButton()
detailsButton.frame = CGRect(x: (self.frame.width/3)-20, y: 10, width: 15, height: 15)
detailsButton.bezelStyle = .regularSquare
detailsButton.isBordered = false
detailsButton.imageScaling = NSImageScaling.scaleAxesIndependently
detailsButton.contentTintColor = .lightGray
detailsButton.action = #selector(self.toggleDetails)
detailsButton.target = self
detailsButton.toolTip = localizedString("Disk details")
detailsButton.image = Bundle(for: Module.self).image(forResource: "tune")!
self.addArrangedSubview(nameField) self.addArrangedSubview(nameField)
self.addArrangedSubview(activity) self.addArrangedSubview(activity)
self.addArrangedSubview(NSView()) self.addArrangedSubview(NSView())
self.addArrangedSubview(button) self.addArrangedSubview(refreshButton)
self.addArrangedSubview(detailsButton)
self.widthAnchor.constraint(equalToConstant: self.frame.width).isActive = true self.widthAnchor.constraint(equalToConstant: self.frame.width).isActive = true
self.heightAnchor.constraint(equalToConstant: self.frame.height).isActive = true self.heightAnchor.constraint(equalToConstant: self.frame.height).isActive = true
@@ -476,6 +498,10 @@ internal class NameView: NSStackView {
@objc private func toggleDetails() { @objc private func toggleDetails() {
self.detailsCallback() self.detailsCallback()
} }
@objc private func refreshDisk() {
self.refreshCallback()
}
} }
internal class ChartView: NSStackView { internal class ChartView: NSStackView {

View File

@@ -97,6 +97,12 @@ internal class CapacityReader: Reader<Disks> {
self.callback(self.list) self.callback(self.list)
} }
public func resetPurgableSpace(for uuid: String) {
if let disk = self.list.first(where: { $0.uuid == uuid }), let path = disk.path {
self.purgableSpace.removeValue(forKey: path)
}
}
private func freeDiskSpaceInBytes(_ path: URL) -> Int64 { private func freeDiskSpaceInBytes(_ path: URL) -> Int64 {
var stat = statfs() var stat = statfs()
if statfs(path.path, &stat) == 0 { if statfs(path.path, &stat) == 0 {