Skip to content

Commit 4ba6867

Browse files
committed
feat: add system resources info
1 parent 9c5cb4c commit 4ba6867

5 files changed

Lines changed: 725 additions & 0 deletions

File tree

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using System.Diagnostics;
2+
using System.Runtime.InteropServices;
3+
4+
namespace TelegramDownloader.Models
5+
{
6+
public class SystemMetrics
7+
{
8+
// CPU
9+
public double SystemCpuUsage { get; set; }
10+
public double AppCpuUsage { get; set; }
11+
public int ProcessorCount { get; set; }
12+
13+
// Memory
14+
public long TotalMemoryBytes { get; set; }
15+
public long UsedMemoryBytes { get; set; }
16+
public long AvailableMemoryBytes { get; set; }
17+
public double MemoryUsagePercent { get; set; }
18+
19+
// App Memory
20+
public long AppMemoryBytes { get; set; }
21+
public long AppPrivateMemoryBytes { get; set; }
22+
23+
// Disk
24+
public string TempFolderPath { get; set; }
25+
public long TempFolderSizeBytes { get; set; }
26+
public long DiskTotalBytes { get; set; }
27+
public long DiskUsedBytes { get; set; }
28+
public long DiskFreeBytes { get; set; }
29+
public double DiskUsagePercent { get; set; }
30+
31+
// Formatted strings
32+
public string TotalMemory => FormatBytes(TotalMemoryBytes);
33+
public string UsedMemory => FormatBytes(UsedMemoryBytes);
34+
public string AvailableMemory => FormatBytes(AvailableMemoryBytes);
35+
public string AppMemory => FormatBytes(AppMemoryBytes);
36+
public string AppPrivateMemory => FormatBytes(AppPrivateMemoryBytes);
37+
public string TempFolderSize => FormatBytes(TempFolderSizeBytes);
38+
public string DiskTotal => FormatBytes(DiskTotalBytes);
39+
public string DiskUsed => FormatBytes(DiskUsedBytes);
40+
public string DiskFree => FormatBytes(DiskFreeBytes);
41+
42+
private static string FormatBytes(long bytes)
43+
{
44+
string[] suffixes = { "B", "KB", "MB", "GB", "TB" };
45+
int i = 0;
46+
double value = bytes;
47+
while (value >= 1024 && i < suffixes.Length - 1)
48+
{
49+
value /= 1024;
50+
i++;
51+
}
52+
return $"{value:F1} {suffixes[i]}";
53+
}
54+
}
55+
}

TelegramDownloader/Pages/InfoPage.razor

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
@inject ITelegramService ts
77
@inject IFileService fs
88
@inject IJSRuntime JSRuntime
9+
@inject ISystemMetricsService metricsService
10+
@implements IDisposable
911

1012
@if(user != null)
1113
{
@@ -169,6 +171,118 @@
169171
</div>
170172
</div>
171173

174+
<!-- System Resources Section -->
175+
<div class="system-resources-section">
176+
<div class="section-header">
177+
<i class="bi bi-pc-display"></i>
178+
<h4>System Resources</h4>
179+
<span class="refresh-indicator @(isRefreshing ? "active" : "")">
180+
<i class="bi bi-arrow-repeat"></i>
181+
</span>
182+
</div>
183+
184+
<div class="resources-grid">
185+
<!-- CPU Card -->
186+
<div class="resource-card cpu-card">
187+
<div class="resource-icon">
188+
<i class="bi bi-cpu"></i>
189+
</div>
190+
<div class="resource-content">
191+
<h5>CPU Usage</h5>
192+
<div class="resource-bars">
193+
<div class="resource-bar-item">
194+
<div class="bar-label">
195+
<span>Application</span>
196+
<span class="bar-value">@(metrics?.AppCpuUsage.ToString("F1") ?? "0")%</span>
197+
</div>
198+
<div class="progress-bar-container">
199+
<div class="progress-bar app" style="width: @(metrics?.AppCpuUsage ?? 0)%"></div>
200+
</div>
201+
</div>
202+
<div class="resource-bar-item">
203+
<div class="bar-label">
204+
<span>System</span>
205+
<span class="bar-value">@(metrics?.SystemCpuUsage.ToString("F1") ?? "0")%</span>
206+
</div>
207+
<div class="progress-bar-container">
208+
<div class="progress-bar system" style="width: @(metrics?.SystemCpuUsage ?? 0)%"></div>
209+
</div>
210+
</div>
211+
</div>
212+
<div class="resource-footer">
213+
<span><i class="bi bi-cpu"></i> @(metrics?.ProcessorCount ?? 0) cores</span>
214+
</div>
215+
</div>
216+
</div>
217+
218+
<!-- Memory Card -->
219+
<div class="resource-card memory-card">
220+
<div class="resource-icon">
221+
<i class="bi bi-memory"></i>
222+
</div>
223+
<div class="resource-content">
224+
<h5>Memory Usage</h5>
225+
<div class="resource-bars">
226+
<div class="resource-bar-item">
227+
<div class="bar-label">
228+
<span>Application</span>
229+
<span class="bar-value">@(metrics?.AppMemory ?? "0 B")</span>
230+
</div>
231+
<div class="progress-bar-container">
232+
<div class="progress-bar app" style="width: @(metrics != null && metrics.TotalMemoryBytes > 0 ? (double)metrics.AppMemoryBytes / metrics.TotalMemoryBytes * 100 : 0)%"></div>
233+
</div>
234+
</div>
235+
<div class="resource-bar-item">
236+
<div class="bar-label">
237+
<span>System</span>
238+
<span class="bar-value">@(metrics?.UsedMemory ?? "0 B") / @(metrics?.TotalMemory ?? "0 B")</span>
239+
</div>
240+
<div class="progress-bar-container">
241+
<div class="progress-bar system" style="width: @(metrics?.MemoryUsagePercent ?? 0)%"></div>
242+
</div>
243+
</div>
244+
</div>
245+
<div class="resource-footer">
246+
<span><i class="bi bi-box"></i> Available: @(metrics?.AvailableMemory ?? "0 B")</span>
247+
</div>
248+
</div>
249+
</div>
250+
251+
<!-- Disk Card -->
252+
<div class="resource-card disk-card">
253+
<div class="resource-icon">
254+
<i class="bi bi-hdd"></i>
255+
</div>
256+
<div class="resource-content">
257+
<h5>Disk Storage</h5>
258+
<div class="resource-bars">
259+
<div class="resource-bar-item">
260+
<div class="bar-label">
261+
<span>Temp Folder</span>
262+
<span class="bar-value">@(metrics?.TempFolderSize ?? "0 B")</span>
263+
</div>
264+
<div class="progress-bar-container">
265+
<div class="progress-bar temp" style="width: @(metrics != null && metrics.DiskTotalBytes > 0 ? (double)metrics.TempFolderSizeBytes / metrics.DiskTotalBytes * 100 : 0)%"></div>
266+
</div>
267+
</div>
268+
<div class="resource-bar-item">
269+
<div class="bar-label">
270+
<span>Disk Used</span>
271+
<span class="bar-value">@(metrics?.DiskUsed ?? "0 B") / @(metrics?.DiskTotal ?? "0 B")</span>
272+
</div>
273+
<div class="progress-bar-container">
274+
<div class="progress-bar system @(metrics?.DiskUsagePercent > 90 ? "critical" : metrics?.DiskUsagePercent > 75 ? "warning" : "")" style="width: @(metrics?.DiskUsagePercent ?? 0)%"></div>
275+
</div>
276+
</div>
277+
</div>
278+
<div class="resource-footer">
279+
<span><i class="bi bi-hdd"></i> Free: @(metrics?.DiskFree ?? "0 B")</span>
280+
</div>
281+
</div>
282+
</div>
283+
</div>
284+
</div>
285+
172286
<!-- Speed Chart Section -->
173287
<div class="chart-section">
174288
<div class="chart-header">
@@ -186,7 +300,10 @@
186300
@code {
187301
private User user { get; set; }
188302
private DirectorySizeModel? dirSize { get; set; }
303+
private SystemMetrics? metrics { get; set; }
189304
private bool showFilesBreakdown { get; set; } = false;
305+
private bool isRefreshing { get; set; } = false;
306+
private Timer? refreshTimer;
190307
private string AppVersion => typeof(Program).Assembly.GetName().Version?.ToString() ?? "0.0.0";
191308

192309
private void ToggleFilesBreakdown()
@@ -198,6 +315,32 @@
198315
{
199316
user = await ts.GetUser();
200317
await calculateTempDirSize();
318+
await RefreshMetrics();
319+
320+
// Start auto-refresh timer (every 3 seconds)
321+
refreshTimer = new Timer(async _ =>
322+
{
323+
await InvokeAsync(async () =>
324+
{
325+
isRefreshing = true;
326+
StateHasChanged();
327+
await RefreshMetrics();
328+
isRefreshing = false;
329+
StateHasChanged();
330+
});
331+
}, null, 3000, 3000);
332+
}
333+
334+
private async Task RefreshMetrics()
335+
{
336+
try
337+
{
338+
metrics = await metricsService.GetMetricsAsync();
339+
}
340+
catch
341+
{
342+
// Ignore metrics errors
343+
}
201344
}
202345

203346
private async Task calculateTempDirSize()
@@ -209,11 +352,17 @@
209352
{
210353
fs.cleanTempFolder();
211354
await calculateTempDirSize();
355+
await RefreshMetrics();
212356
await TriggerCelebration();
213357
}
214358

215359
private async Task TriggerCelebration()
216360
{
217361
await JSRuntime.InvokeVoidAsync("triggerConfetti");
218362
}
363+
364+
public void Dispose()
365+
{
366+
refreshTimer?.Dispose();
367+
}
219368
}

TelegramDownloader/Program.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@
113113
builder.Services.AddSingleton<ILogQueryService>(sp =>
114114
new LogQueryService(mongoConnectionString, sp.GetRequiredService<ILogger<LogQueryService>>()));
115115

116+
// System metrics service
117+
builder.Services.AddSingleton<ISystemMetricsService, SystemMetricsService>();
118+
116119
ServiceLocator.ServiceProvider = builder.Services.BuildServiceProvider();
117120
builder.Services.AddBlazorBootstrap();
118121

0 commit comments

Comments
 (0)