View Issue Details

IDProjectCategoryView StatusLast Update
0009691Talerwallet (WebExtension)public2026-11-11 01:43
ReporterAntoine A Assigned ToResolution deadline
ImplementerReviewer 
Release signed byDeployed by 
VerifierCommunicator 
Data protection authority notification requiredNo  
CSIRT notification requiredNo  
Estimated effort (hours)Actual effort (hours)0 
Fast-trackNo
Work packagenone
PrioritynormalSeveritytweakReproducibilityhave not tried
Status implementingResolutionopen 
Target Versionpost-1.0 
Summary0009691: Better network issue UI
DescriptionWhen making a P2P payment, the user interface does not indicate that the URI and QR code load asynchronously in the user interface. When the network is slow, the display may take some time, and when there is no network, nothing is displayed.

The extension doesn't recover properly when it comes back online and the page has to be reloaded.

We should display a loading indicator and an attempt counter and/or a network warning to let the user know that something is taking time or not working.
I also think we should display the QR code by default as in other applications.
Tagsux
Attached Files

Required notifications

Address or linkRemarkAdded byNotifiedActions

Activities

bot-cg [agent]

2026-11-11 01:43

updater   ~0030399

Cross-wallet comparison, 2026-11-11 (WebExtension built from taler-typescript-core bf2e571a2): the "network warning" part of this issue is still open. The request-progress panel ("This request is taking longer than expected" / "The service is not responding", with the latest error, the retry countdown, Cancel and "Retry now") now covers the loading indicator and the attempt counter. But when the browser is offline the wallet still says nothing, while the Android and iOS wallets show a banner.

- WebExtension, browser offline (Chromium network emulation; navigator.onLine === false): the balances page looks exactly as when online (before-web-1.png). The wallet tells wallet-core about it (platform/lifecycle.ts:122-151, hintNetworkAvailability) and renders nothing. The only status element is the screen-reader-only "Wallet host: Connected" (ui/Shell.tsx:54-56), which describes the background worker, not the Internet.
- Android: red strip "No internet access" under the title bar on every screen (before-android-1.png; compose/NetworkStatusBanner.kt:51-57).
- iOS: red bar "Network unavailable!" on the main view and every sheet (Views/Main/MainView.swift:270-275, 442-451; the iOS bar was 0007931).

Attached patch web-F407-offline-strip.patch (ui/Shell.tsx only): a useBrowserOnline() hook on navigator.onLine plus the online/offline events, and while offline a role="status" strip at the top of the shell: "No internet connection. The wallet will continue when you are back online." (one new translatable string). after-web-1.png shows the same page with the patch, while offline; the strip disappears when the browser is back online.

Verified: wc-web build of the patched tree; `pnpm --filter @gnu-taler/wallet-webui typecheck` reports the same pre-existing errors as master (observations.ts, demo-wallet.ts, tests) and none in Shell.tsx.

Assisted by LLM
before-web-1.png (97,541 bytes)   
before-web-1.png (97,541 bytes)   
before-android-1.png (121,452 bytes)   
before-android-1.png (121,452 bytes)   
after-web-1.png (109,893 bytes)   
after-web-1.png (109,893 bytes)   
web-F407-offline-strip.patch (2,096 bytes)   
diff --git a/packages/wallet-webui/src/ui/Shell.tsx b/packages/wallet-webui/src/ui/Shell.tsx
index e13a98baa..51d048224 100644
--- a/packages/wallet-webui/src/ui/Shell.tsx
+++ b/packages/wallet-webui/src/ui/Shell.tsx
@@ -1,4 +1,5 @@
 import type { ComponentChildren } from "preact";
+import { useEffect, useState } from "preact/hooks";
 import { Link, useLocation } from "wouter-preact";
 import { WalletBrand } from "./WalletBrand.js";
 import { WalletIcon, type WalletIconName } from "./WalletIcon.js";
@@ -17,6 +18,7 @@ export function Shell(props: {
   };
 }) {
   const [location] = useLocation();
+  const online = useBrowserOnline();
   const route = location.split("?", 1)[0];
   const selected = (href: string) =>
     href === "/"
@@ -38,6 +40,14 @@ export function Shell(props: {
   const balancesLabel = i18n.str`Balances`;
   return (
     <div class="min-h-screen bg-background pb-24 text-onBackground md:pb-0">
+      {!online && (
+        <p
+          role="status"
+          class="bg-errorContainer px-4 py-2 text-center text-sm font-medium text-onErrorContainer"
+        >{
+          /* Translators: Shown while the browser reports that the device has no network connection. */ i18n.str`No internet connection. The wallet will continue when you are back online.`
+        }</p>
+      )}
       <header
         class={`${props.demo ? "block" : "hidden"} border-b border-outlineVariant bg-surface md:block`}
       >
@@ -211,3 +221,21 @@ function MobileNav(props: {
     </Link>
   );
 }
+
+/** The browser's own idea of network connectivity (navigator.onLine). */
+function useBrowserOnline(): boolean {
+  const [online, setOnline] = useState(
+    typeof navigator === "undefined" ? true : navigator.onLine,
+  );
+  useEffect(() => {
+    const update = () => setOnline(navigator.onLine);
+    window.addEventListener("online", update);
+    window.addEventListener("offline", update);
+    update();
+    return () => {
+      window.removeEventListener("online", update);
+      window.removeEventListener("offline", update);
+    };
+  }, []);
+  return online;
+}
web-F407-offline-strip.patch (2,096 bytes)   

Issue History

Date ModifiedUsernameFieldChange
2025-04-02 09:44Antoine ANew Issue
2025-04-02 09:44Antoine AStatusnew => assigned
2025-04-02 09:44Antoine AAssigned To => Florian Dold
2025-04-17 20:35Christian GrothoffTag Attached: ux
2025-04-17 20:35Christian GrothoffTarget Version1.1 => post-1.0
2025-04-17 22:15Christian GrothoffAssigned ToFlorian Dold =>
2025-04-17 22:15Christian GrothoffSeverityminor => tweak
2025-04-17 22:15Christian GrothoffStatusassigned => implementing
2026-11-11 01:43bot-cgNote Added: 0030399
2026-11-11 01:43bot-cgFile Added: before-web-1.png
2026-11-11 01:43bot-cgFile Added: before-android-1.png
2026-11-11 01:43bot-cgFile Added: after-web-1.png
2026-11-11 01:43bot-cgFile Added: web-F407-offline-strip.patch