Files
decePubClient/Services/AppStatusService.cs
T
thepraandClaude Opus 5.5 697b2c8897
Build / Build (push) Successful in 33s
Animations, GIFs and the globe now move for every reader
decePub no longer looks at the system's "reduce motion" setting, so everything moves the same way whatever it says:
- a GIF video in a post plays by itself, muted and looping, instead of waiting for a tap; it now also starts on a page
  just opened, before the first tap, where the browser used to hold it still;
- animated custom emoji move in the emoji picker instead of showing a still picture;
- the globe turns by itself while no located post is in view, flies to the posts, and its pulses, arcs and Sun move;
- going back to the top of a feed scrolls smoothly;
- tooltips, dropdowns, menus, folding sections, toasts, loading spinners, placeholders, progress bars, radio buttons
  and ratings keep their animations: the build now takes daisyUI's reduce-motion rules out of the stylesheet
  (tools/css/motion.py, run after every Tailwind build, in watch mode too).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W4YtEKqxKjKyHkFzuRVMNA
2026-11-09 20:48:47 +01:00

47 lines
2.1 KiB
C#

using Microsoft.AspNetCore.Components;
using decePubClient.Models;
using Microsoft.JSInterop;
namespace decePubClient.Services;
public class AppStatusService(IJSRuntime jsRuntime)
{
readonly IJSInProcessRuntime JsSyncRuntime = (IJSInProcessRuntime)jsRuntime;
public async ValueTask<bool> IsOnline(CancellationToken cancellationToken = default) =>
await jsRuntime.InvokeAsync<bool>("isOnline", cancellationToken);
public string Language() => JsSyncRuntime.Invoke<string>("getLanguage");
public void SetAppBadge(int counter) => JsSyncRuntime.InvokeVoid("setAppBadge", counter);
public void ClearAppBadge() => JsSyncRuntime.InvokeVoid("clearAppBadge");
// wwwroot/js/theme.js
public void ApplyTheme(PageSettings pageSettings) => JsSyncRuntime.InvokeVoid("neoTheme.apply", pageSettings);
public bool IsDarkTheme() => JsSyncRuntime.Invoke<bool>("neoTheme.isDark");
public bool IsMobileMedia() => JsSyncRuntime.Invoke<bool>("isMobileMedia");
// whether the navigation being decided came from the Back (or Forward) button
public bool TookBack() => JsSyncRuntime.Invoke<bool>("tookBack");
// whether the pointer can hover (a mouse); a touch screen can't, so what shows on hover there opens on a tap
public bool CanHover() => JsSyncRuntime.Invoke<bool>("canHover");
// puts the text on the clipboard; false when the browser refused it, which main.js reports through logFromJs
public async ValueTask<bool> CopyText(string text, CancellationToken cancellationToken = default) =>
await jsRuntime.InvokeAsync<bool>("copyText", cancellationToken, text);
// a sideways-scrolling strip of tabs shows its selected tab
public void RevealActive(ElementReference strip) => JsSyncRuntime.InvokeVoid("revealActive", strip);
// where a text field's selection starts and ends (the caret, when nothing is selected), in UTF-16 units as C# counts
// them; null when it can't say
public int[] CaretOf(ElementReference field) => JsSyncRuntime.Invoke<int[]>("caretOf", field);
// the field takes the focus with its caret there
public void PlaceCaret(ElementReference field, int at) => JsSyncRuntime.InvokeVoid("placeCaret", field, at);
}