feat: implement server-side NativeStorageService for browser storage interoperability
This commit is contained in:
@@ -0,0 +1,82 @@
|
|||||||
|
using FluentResults;
|
||||||
|
using Microsoft.JSInterop;
|
||||||
|
using NexusReader.Application.Abstractions.Services;
|
||||||
|
|
||||||
|
namespace NexusReader.Web.New.Services;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Server-side implementation of INativeStorageService for Blazor Server.
|
||||||
|
/// Uses JS Interop to access browser local storage.
|
||||||
|
/// </summary>
|
||||||
|
public class NativeStorageService : INativeStorageService
|
||||||
|
{
|
||||||
|
private readonly IJSRuntime _jsRuntime;
|
||||||
|
|
||||||
|
public NativeStorageService(IJSRuntime jsRuntime)
|
||||||
|
{
|
||||||
|
_jsRuntime = jsRuntime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Result<string>> GetSecureString(string key)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var value = await _jsRuntime.InvokeAsync<string>("localStorage.getItem", key);
|
||||||
|
return Result.Ok(value ?? string.Empty);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return Result.Fail(new Error("Failed to read from local storage").CausedBy(ex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Result> SaveSecureString(string key, string value)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _jsRuntime.InvokeVoidAsync("localStorage.setItem", key, value);
|
||||||
|
return Result.Ok();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return Result.Fail(new Error("Failed to write to local storage").CausedBy(ex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Result<bool>> GetBool(string key)
|
||||||
|
{
|
||||||
|
var result = await GetSecureString(key);
|
||||||
|
if (result.IsFailed) return Result.Fail(result.Errors);
|
||||||
|
return Result.Ok(bool.TryParse(result.Value, out var val) && val);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Result> SaveBool(string key, bool value)
|
||||||
|
{
|
||||||
|
return await SaveSecureString(key, value.ToString().ToLower());
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Result<int>> GetInt(string key)
|
||||||
|
{
|
||||||
|
var result = await GetSecureString(key);
|
||||||
|
if (result.IsFailed) return Result.Fail(result.Errors);
|
||||||
|
return Result.Ok(int.TryParse(result.Value, out var val) ? val : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Result> SaveInt(string key, int value)
|
||||||
|
{
|
||||||
|
return await SaveSecureString(key, value.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Result> ClearAll()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _jsRuntime.InvokeVoidAsync("localStorage.clear");
|
||||||
|
return Result.Ok();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return Result.Fail(new Error("Failed to clear local storage").CausedBy(ex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user