@page "/" @inject TwitchArchive.Core.Workers.StreamWorkerManager WorkerManager @inject TwitchArchive.Web.Services.SessionCacheService SessionCache

Dashboard

@if (streamers.Count == 0) {
No streamers configured. Add one on the Add Streamer page.
}
@foreach (var s in streamers) {
@s Edit @(WorkerManager.IsRunning(s) ? "Live" : "Offline")
Last session: @(lastStarts.ContainsKey(s) ? lastStarts[s].ToLocalTime().ToString() : "-")
}
@* Show global feedback when there are streamers but no recent sessions *@ @if (streamers.Count > 0 && (lastStarts == null || lastStarts.Count == 0)) {
No recent sessions found for configured streamers.
} @code { private List streamers = new(); private Dictionary lastStarts = new(); private void OnCacheUpdatedHandler() { _ = InvokeAsync(() => { lastStarts = SessionCache.GetSnapshot(); StateHasChanged(); }); } protected override async Task OnInitializedAsync() { LoadStreamers(); lastStarts = SessionCache.GetSnapshot(); SessionCache.Updated += OnCacheUpdatedHandler; } private void LoadStreamers() { // Try to find the config/streamers folder from the app content root and parent folders. string? cfgDir = FindConfigStreamersFolder(); if (!string.IsNullOrEmpty(cfgDir) && Directory.Exists(cfgDir)) { streamers = Directory.GetFiles(cfgDir, "*.json").Select(f => Path.GetFileNameWithoutExtension(f)).ToList(); } } private string? FindConfigStreamersFolder() { // Prefer ContentRoot if available, fall back to Environment.CurrentDirectory. var start = AppContext.BaseDirectory ?? Environment.CurrentDirectory; var dir = new DirectoryInfo(start); for (int i = 0; i < 6 && dir != null; i++) { var candidate = Path.Combine(dir.FullName, "config", "streamers"); if (Directory.Exists(candidate)) return candidate; dir = dir.Parent; } // final attempt: repo-root relative (use project parent heuristics) var alt = Path.Combine(Environment.CurrentDirectory, "..", "..", "..", "config", "streamers"); try { alt = Path.GetFullPath(alt); } catch { } if (Directory.Exists(alt)) return alt; return null; } // Index reads from the singleton SessionCacheService; updates are pushed via the Updated event. private void Start(string u) { WorkerManager.StartWorker(u); } private async Task Stop(string u) { await WorkerManager.StopWorkerAsync(u); } public async ValueTask DisposeAsync() { SessionCache.Updated -= OnCacheUpdatedHandler; await Task.CompletedTask; } }