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;
}
}
}
}