app/BTCPayApp.UI/Features/UIState.cs
Dennis Reimann 5a83df36de
Unify states
2024-06-25 17:00:56 +02:00

124 lines
3.7 KiB
C#

using BTCPayApp.CommonServer.Models;
using BTCPayApp.Core;
using Fluxor;
using Microsoft.JSInterop;
using Newtonsoft.Json;
namespace BTCPayApp.UI.Features;
public static class Themes
{
public const string Dark = "dark";
public const string Light = "light";
public const string System = "system";
}
[FeatureState]
public record UIState
{
public string SelectedTheme = Themes.System;
public string SystemTheme = Themes.Light;
public bool IsDarkMode;
[JsonIgnore]
public RemoteData<AppInstanceInfo>? Instance;
public record ApplyUserTheme(string Theme);
public record SetUserTheme(string Theme);
protected class SetUserThemeReducer : Reducer<UIState, SetUserTheme>
{
public override UIState Reduce(UIState state, SetUserTheme action)
{
var effectiveTheme = action.Theme == Themes.System ? state.SystemTheme : action.Theme;
return state with
{
SystemTheme = state.SystemTheme,
SelectedTheme = action.Theme,
IsDarkMode = effectiveTheme == Themes.Dark
};
}
}
public record FetchInstanceInfo(string? Url);
protected class FetchInstanceInfoReducer : Reducer<UIState, FetchInstanceInfo>
{
public override UIState Reduce(UIState state, FetchInstanceInfo action)
{
return state with
{
Instance = (state.Instance ?? new RemoteData<AppInstanceInfo>()) with
{
Loading = true
}
};
}
}
public record SetInstanceInfo(AppInstanceInfo? Instance, string? Error);
protected class SetInstanceInfoReducer : Reducer<UIState, SetInstanceInfo>
{
public override UIState Reduce(UIState state, SetInstanceInfo action)
{
return state with
{
Instance = (state.Instance ?? new RemoteData<AppInstanceInfo>()) with
{
Data = action.Instance,
Error = action.Error,
Loading = false
}
};
}
}
public class UIEffects
{
private readonly IJSRuntime _jsRuntime;
public UIEffects(IJSRuntime jsRuntime)
{
_jsRuntime = jsRuntime;
}
[EffectMethod]
public async Task ApplyUserThemeEffect(ApplyUserTheme action, IDispatcher dispatcher)
{
// store
dispatcher.Dispatch(new SetUserTheme(action.Theme));
// ui
await _jsRuntime.InvokeVoidAsync("Interop.setColorMode", action.Theme);
}
[EffectMethod]
public async Task FetchInstanceInfoEffect(FetchInstanceInfo action, IDispatcher dispatcher)
{
try
{
var instance = !string.IsNullOrEmpty(action.Url)
? await new BTCPayAppClient(action.Url).GetInstanceInfo()
: null;
var error = !string.IsNullOrEmpty(action.Url) && instance == null
? "This server does not seem to support the BTCPay app."
: null;
dispatcher.Dispatch(new SetInstanceInfo(instance, error));
}
catch (Exception e)
{
var error = e.InnerException?.Message ?? e.Message;
dispatcher.Dispatch(new SetInstanceInfo(null, error));
}
}
[EffectMethod]
public async Task SetInstanceInfoEffect(SetInstanceInfo action, IDispatcher dispatcher)
{
var info = action.Instance;
await _jsRuntime.InvokeVoidAsync("Interop.setInstanceInfo", info?.CustomThemeExtension, info?.CustomThemeCssUrl, info?.LogoUrl);
}
}
}