import 'dart:io' show Platform; import 'package:flutter/foundation.dart' show kIsWeb; import 'package:flutter/material.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:url_launcher/url_launcher.dart'; import '../config/app_config.dart'; import '../main.dart'; class WebViewHomePage extends StatefulWidget { const WebViewHomePage({super.key, required this.config}); final AppConfig config; @override State createState() => _WebViewHomePageState(); } class _WebViewHomePageState extends State { InAppWebViewController? _controller; int _progress = 0; bool get _platformSupportsWebView => !kIsWeb && (Platform.isAndroid || Platform.isIOS || Platform.isMacOS || Platform.isWindows); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Swyx'), actions: [ if (_platformSupportsWebView) IconButton( tooltip: 'Neu laden', onPressed: () => _controller?.reload(), icon: const Icon(Icons.refresh), ), IconButton( tooltip: 'Im Browser öffnen', onPressed: _openExternally, icon: const Icon(Icons.open_in_browser), ), IconButton( tooltip: 'STOMP', onPressed: _openStomp, icon: const Icon(Icons.bolt), ), ], ), body: _platformSupportsWebView ? _buildWebView() : _buildLinuxFallback(), ); } Widget _buildWebView() { return Column( children: [ if (_progress < 100) LinearProgressIndicator(value: _progress / 100), Expanded( child: InAppWebView( initialUrlRequest: URLRequest(url: WebUri(widget.config.webviewUrl)), initialSettings: InAppWebViewSettings( javaScriptEnabled: true, transparentBackground: true, ), onWebViewCreated: (controller) => _controller = controller, onProgressChanged: (_, progress) => setState(() => _progress = progress), onLoadStart: (_, _) => setState(() => _progress = 0), onLoadStop: (_, _) => setState(() => _progress = 100), ), ), ], ); } Widget _buildLinuxFallback() { return Center( child: Padding( padding: const EdgeInsets.all(32), child: Column( mainAxisSize: MainAxisSize.min, children: [ const Icon(Icons.web_asset_off, size: 48), const SizedBox(height: 16), Text( 'Eingebettete Webansicht ist unter Linux nicht verfügbar.', textAlign: TextAlign.center, style: Theme.of(context).textTheme.titleMedium, ), const SizedBox(height: 8), SelectableText( widget.config.webviewUrl, style: const TextStyle(fontFamily: 'monospace'), ), const SizedBox(height: 24), FilledButton.icon( onPressed: _openExternally, icon: const Icon(Icons.open_in_browser), label: const Text('Im Browser öffnen'), ), ], ), ), ); } Future _openExternally() async { final uri = Uri.parse(widget.config.webviewUrl); if (!await launchUrl(uri, mode: LaunchMode.externalApplication)) { if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Konnte ${widget.config.webviewUrl} nicht öffnen')), ); } } void _openStomp() { Navigator.of(context).push(MaterialPageRoute( builder: (_) => StompDemoPage(config: widget.config), )); } }