import 'dart:async'; import 'dart:js_interop'; import 'package:web/web.dart' as web; /// Provided by the inline Firebase bootstrap in web/index.html. Returns an FCM /// registration token, or null if push isn't configured / permission denied. @JS('kcGetPushToken') external JSPromise _kcGetPushToken(); Future getPushToken() async { try { final result = await _kcGetPushToken().toDart; return result?.toDart; } catch (_) { return null; } } /// Per-tab storage for the PKCE verifier + CSRF state (cleared when the tab /// closes), and the little bit of `window` access the OIDC redirect needs. void setSession(String key, String value) => web.window.sessionStorage.setItem(key, value); String? getSession(String key) => web.window.sessionStorage.getItem(key); void removeSession(String key) => web.window.sessionStorage.removeItem(key); void redirect(String url) => web.window.location.assign(url); Map currentQueryParameters() => Uri.parse(web.window.location.href).queryParameters; /// Drop the OIDC callback path + `?code=…&state=…` from the address bar /// without reloading (back to the app root). void clearQuery() { web.window.history.replaceState(null, '', '/'); } /// Opens the OS file picker and reads the chosen file's bytes. Future<({String name, List bytes})?> pickFile() { final completer = Completer<({String name, List bytes})?>(); final input = web.HTMLInputElement()..type = 'file'; input.onchange = ((web.Event _) { final files = input.files; if (files == null || files.length == 0) { completer.complete(null); return; } final file = files.item(0)!; final reader = web.FileReader(); reader.onload = ((web.Event _) { final buffer = (reader.result as JSArrayBuffer).toDart; completer.complete((name: file.name, bytes: buffer.asUint8List())); }).toJS; reader.onerror = ((web.Event _) => completer.complete(null)).toJS; reader.readAsArrayBuffer(file); }).toJS; input.click(); return completer.future; } /// Triggers a browser download of an in-memory string (e.g. the CSV export). void downloadText( String filename, String content, { String mime = 'text/csv;charset=utf-8', }) { final blob = web.Blob([content.toJS].toJS, web.BlobPropertyBag(type: mime)); final url = web.URL.createObjectURL(blob); web.HTMLAnchorElement() ..href = url ..download = filename ..click(); web.URL.revokeObjectURL(url); }