diff --git a/assets/css/dashboard.css b/assets/css/dashboard.css
index d2667ea..4f48ad9 100644
--- a/assets/css/dashboard.css
+++ b/assets/css/dashboard.css
@@ -108,3 +108,32 @@
.piperless-dash-info-storage {
border-left: 4px solid #2271b1;
}
+
+/* ── Storage usage bar ─────────────────────────────────────────────────── */
+.piperless-dash-info-body {
+ flex: 1;
+ min-width: 0;
+ display: flex;
+ flex-direction: column;
+ gap: 6px;
+}
+
+.piperless-dash-bar {
+ width: 100%;
+ height: 6px;
+ background: #dcdcde;
+ border-radius: 3px;
+ overflow: hidden;
+}
+
+.piperless-dash-bar-fill {
+ height: 100%;
+ background: #2271b1;
+ border-radius: 3px;
+ transition: width 0.3s ease;
+}
+
+.piperless-dash-bar-label {
+ font-size: 11px;
+ color: #757575;
+}
diff --git a/includes/class-dashboard.php b/includes/class-dashboard.php
index 7707239..61d00b9 100644
--- a/includes/class-dashboard.php
+++ b/includes/class-dashboard.php
@@ -72,7 +72,7 @@ class Dashboard {
public function render(): void {
$file_stats = $this->get_file_stats();
$without = $this->get_posts_without_audio();
- $disk_free = $this->get_disk_free();
+ $disk = $this->get_disk_usage();
$total_files = ( $file_stats['mp3']['count'] ?? 0 )
+ ( $file_stats['wav']['count'] ?? 0 )
+ ( $file_stats['opus']['count'] ?? 0 );
@@ -127,15 +127,30 @@ class Dashboard {
⌨
-
-
-
+
+
+ human_size( $disk['free'] ) ),
+ esc_html( $this->human_size( $disk['total'] ) )
+ );
+ ?>
+
+
+
+
+
+
@@ -224,11 +239,11 @@ class Dashboard {
}
/**
- * Get human-readable free disk space on the uploads directory volume.
+ * Get disk usage stats for the uploads directory volume.
*
- * @return string e.g. "12.3 GB"
+ * @return array{total:float,free:float,used:float,pct:float}
*/
- private function get_disk_free(): string {
+ private function get_disk_usage(): array {
$dir = $this->cache->dir();
// Walk up until we find a directory that exists.
@@ -236,19 +251,30 @@ class Dashboard {
$dir = dirname( $dir );
}
- $free = @disk_free_space( $dir );
+ $total = @disk_total_space( $dir );
+ $free = @disk_free_space( $dir );
- if ( false === $free || null === $free ) {
- return __( 'Unavailable', 'piperless' );
+ $fallback = [ 'total' => 0.0, 'free' => 0.0, 'used' => 0.0, 'pct' => 0.0 ];
+
+ if ( false === $total || null === $total || false === $free || null === $free || $total <= 0.0 ) {
+ return $fallback;
}
- return $this->human_size( $free );
+ $used = $total - $free;
+ $pct = ( $used / $total ) * 100.0;
+
+ return [
+ 'total' => (float) $total,
+ 'free' => (float) $free,
+ 'used' => (float) $used,
+ 'pct' => (float) $pct,
+ ];
}
/**
* Format bytes as a human-readable string.
*
- * @param int $bytes Raw byte count.
+ * @param float $bytes Raw byte count.
* @return string e.g. "24.5 MB"
*/
private function human_size( float $bytes ): string {