@inherits LocalizableComponentBase @* On a phone the menu opens from the hamburger over the page, and closes after a choice (any navigation, a persona switch), on a tap outside it or on Escape; from md it is the sidebar, which scrolls on its own when the window is short (a phone held sideways). *@ @code { bool isMenuOpen; bool isPersonaMenuOpen; string PersonaBackground => CascadingState.Persona?.Header is { Length: > 0 } header && !header.Contains("/missing-") ? $"background-image:linear-gradient(to left, var(--color-base-100) 55%, transparent), url('{header}');" : null; // The toggle and the slider work on the variant that is showing; with system theming that is the OS's choice. bool IsDark => CascadingState.Status.IsDarkTheme(); short ThemeIndexColour => IsDark ? CascadingState.PublicCacheData.PageSettings.DarkThemeIndexColour : CascadingState.PublicCacheData.PageSettings.LightThemeIndexColour; protected override void OnInitialized() { IsLoading = false; Navigation.LocationChanged += OnLocationChanged; } void OnLocationChanged(object sender, LocationChangedEventArgs e) { if (!isMenuOpen) return; isMenuOpen = false; InvokeAsync(StateHasChanged); } void CloseMenu() => isMenuOpen = false; void OnKeyDown(KeyboardEventArgs e) { if (e.Key == "Escape") isMenuOpen = false; } public override async ValueTask DisposeAsync() { Navigation.LocationChanged -= OnLocationChanged; await base.DisposeAsync(); } async Task SwitchPersona(string personaId) { isMenuOpen = false; var result = await CascadingState.SwitchPersona(personaId); if (result.IsInvalid) Toast.AddResponseError(result); } private void ToggleNavMenu() => isMenuOpen = !isMenuOpen; protected async Task ResetToOriginalColour() { var isDark = IsDark; await CascadingState.UpdatePageSettings(settings => settings.SetHue(isDark, isDark ? PageSettings.DefaultDarkThemeIndexColour : PageSettings.DefaultLightThemeIndexColour)); // if (AuthData?.User != null) // { // AuthData.User.UserSettings.ThemeIndexColour = ThemeIndexColour; // await Storage.SetItemAsync(nameof(AuthData), AuthData); // } } // Picking a hue also leaves the grey themes, which otherwise ignore it. protected async Task UpdateThemeColour(short indexColour) { var isDark = IsDark; await CascadingState.UpdatePageSettings(settings => settings.SetHue(isDark, indexColour)); // if (AuthData?.User != null) // { // AuthData.User.UserSettings.ThemeIndexColour = ThemeIndexColour; // await Storage.SetItemAsync(nameof(AuthData), AuthData); // } } // Choosing light or dark here leaves system theming; Settings can turn it back on. protected async Task UpdateThemeDarkMode(bool isDarkMode) { await CascadingState.UpdatePageSettings(settings => settings.SetDarkMode(isDarkMode)); // if (AuthData?.User != null) // { // AuthData.User.UserSettings.ThemeIsDarkMode = ThemeIsDarkMode; // await Storage.SetItemAsync(nameof(AuthData), AuthData); // } } }