mirror of
https://github.com/morgan9e/macos-stats
synced 2026-04-14 00:04:15 +09:00
feat: added an option to manually refresh disk space information (allow to reset cached purgable space)
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user