using CaritasPWA.Shared.Models; using Microsoft.JSInterop; using System; using System.Threading.Tasks; namespace CaritasPWA.Shared.Services { public sealed class UserDataProvider { private const string KeyName = "account"; private readonly IJSRuntime _jsRuntime; private bool _initialized; private UserData _data = new (); public UserData Data { get => _data; set => _data = value; } public event EventHandler Changed; public bool AutoSave { get; set; } = true; public UserDataProvider(IJSRuntime jsRuntime) { _jsRuntime = jsRuntime; } public async ValueTask Get() { // Register the Storage event handler. This handler calls OnStorageUpdated when the storage changed. // This way, you can reload the settings when another instance of the application (tab / window) save the settings if (!_initialized) { // Create a reference to the current object, so the JS function can call the public method "OnStorageUpdated" var reference = DotNetObjectReference.Create(this); await _jsRuntime.InvokeVoidAsync("BlazorRegisterStorageEvent", reference); _initialized = true; } // Read the JSON string that contains the data from the local storage UserData result; var str = await _jsRuntime.InvokeAsync("BlazorGetLocalStorage", KeyName); if (str != null) { result = System.Text.Json.JsonSerializer.Deserialize(str) ?? new UserData(); } else { result = new UserData(); } _data = result; return result; } public async Task Save() { var json = System.Text.Json.JsonSerializer.Serialize(_data); await _jsRuntime.InvokeVoidAsync("BlazorSetLocalStorage", KeyName, json); } // This method is called from BlazorRegisterStorageEvent when the storage changed [JSInvokable] public void OnStorageUpdated(string key) { if (key == KeyName) { // Reset the settings. The next call to Get will reload the data _data = null; Changed?.Invoke(this, EventArgs.Empty); } } } }