using Microsoft.AspNetCore.Components; using Blog3000.Shared; using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Threading; using System.Threading.Tasks; namespace Blog3000.Client.Shared { public partial class Updater { [Inject] public NetworkStatus NetworkStatus { get; set; } [Inject] private BlogDb BlogDb { get; set; } [Inject] private Config Config{ get; set; } [Inject] private ViewStats ViewStats { get; set; } [Inject] private Services.ImgCacheStorage Cache { get; set; } private int postsLoaded = 0; private string _status; private string Status { get { return _status; } set { _status = value; StateHasChanged(); } } private string netStatus = ""; private bool isEagerLoading = false; private bool isUpdating = false; private bool updateRequested = false; private System.Timers.Timer updateTimer; public void Dispose() { updateTimer?.Dispose(); updateTimer = null; } protected override async Task OnInitializedAsync() { updateRequested = true; NetworkStatus.StatusChanged += NetworkStatus_Changed; NetworkStatus_Changed(this, EventArgs.Empty); // Already run by NetworkStatusChanged! await RunUpdateAsync(); //await Cache.Add("/"); isEagerLoading = await BlogDb.IsEagerLoading(); updateTimer = new System.Timers.Timer(900 * 1000); updateTimer.AutoReset = true; updateTimer.Elapsed += Timer_Elapsed; updateTimer.Start(); } /// /// Forces update. If offline update will be delayed until it comes online /// private void ForceUpdate() { updateRequested = true; _ = RunUpdateAsync(); //_ = Config.FetchAsync(); } private void ToggleLoadingMode() { isEagerLoading = !isEagerLoading; BlogDb.SetEagerLoading(isEagerLoading); if (isEagerLoading) ForceUpdate(); StateHasChanged(); } private void NetworkStatus_Changed(object sender, EventArgs e) { if (NetworkStatus.IsOnline && updateRequested) { Task.Run(async () => { System.Diagnostics.Debug.WriteLine("Network came online"); try { await RunUpdateAsync(); } finally { updateRequested = false; } }); } var ns = NetworkStatus.IsOnline ? "Online" : "Offline"; if (!ns.Equals(netStatus)) { netStatus = ns; this.StateHasChanged(); } } private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { System.Diagnostics.Debug.WriteLine("Update timer elappsed"); ForceUpdate() ; } private async Task RunUpdateAsync() { // TODO: Move most to this to BlogDb if (this.isUpdating) { System.Diagnostics.Debug.WriteLine("Udpdater: already running, abort"); return false; } else { System.Diagnostics.Debug.WriteLine("Updater: start"); this.isUpdating = true; if (!NetworkStatus.IsOnline) { Status = "Updater: Network offline"; return false; } try { Status = "Syncing stats..."; System.Diagnostics.Debug.WriteLine($"Updater: Syncing stats..."); await ViewStats.SyncViewStats(); int changes = 0; BlogPostHeader[] blogPosts = await Http.GetJsonAsync("BlogPosts"); postsLoaded = blogPosts.Length; System.Diagnostics.Debug.WriteLine($"Updater: Total remote blogPosts: {blogPosts.Length}"); Status = $"{blogPosts.Length} verfügbar"; await localStorage.SetItemAsync(BlogDb.DBKEY_PREFIX_HDR + "remotePosts", blogPosts); var dict = new Dictionary(); foreach (var b in blogPosts) { dict.Add(b.Id, true); if (isEagerLoading) { var storedPost = await localStorage.GetItemAsync(BlogDb.DBKEY_PREFIX_BLOGCACHE + b.Id); bool forceSync = false; if (/* TODO: eagerCaching || isInstalled */storedPost != null && (storedPost.ImageRefs?.Count ?? 0) > 0) { forceSync = !await BlogDb.AreImagesCached(b.Id); if (forceSync) System.Diagnostics.Debug.WriteLine($"BlogPosts: forcing sync of {b.Id} due to missing img"); } if ((forceSync) || (storedPost == null) || !((b.Checksum ?? "").Equals(storedPost.Checksum))) { Status = $"Hole '{b.Title}'..."; await BlogDb.SyncPost(b.Id, true); System.Diagnostics.Debug.WriteLine($"BlogPosts: 1 neuer geholt {b.Id}, Update of {storedPost?.Id ?? "new"}"); changes++; } await Task.Delay(50); } } int storedN = await localStorage.LengthAsync(); for (var i = 0; i < storedN; i++) { string id = await localStorage.KeyAsync(i); if (id != null && id.StartsWith(BlogDb.DBKEY_PREFIX_BLOGCACHE)) { var oid = id.Substring(BlogDb.DBKEY_PREFIX_BLOGCACHE.Length); if (!dict.ContainsKey(oid)) { Status = $"Entferne {oid}..."; this.StateHasChanged(); await localStorage.RemoveItemAsync(id); System.Diagnostics.Debug.WriteLine($"BlogPosts: 1 alter entfernt: {oid}"); changes++; } } await Task.Yield(); } Status = $"{DateTime.Now}: {dict.Count} post(s) in store, {changes} changes"; return true; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine("Error updating blogPots", ex); Status = $"Updater failed {ex.Message}"; } finally { System.Diagnostics.Debug.WriteLine("Updater end"); this.isUpdating = false; } return false; } } } }