diff --git a/assets/html/index.html b/assets/html/index.html new file mode 100644 index 0000000..76a8495 --- /dev/null +++ b/assets/html/index.html @@ -0,0 +1,48 @@ + + + + + + + Document + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/features/auth/pages/page_auth.dart b/lib/features/auth/pages/page_auth.dart index c135f88..c126b69 100644 --- a/lib/features/auth/pages/page_auth.dart +++ b/lib/features/auth/pages/page_auth.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:recording_tool/app/router/app_navigator.dart'; -import 'package:recording_tool/features/scan_qrcode/pages/page_scan_qrcode.dart'; +import 'package:recording_tool/shared/widgets/app_webview.dart'; import 'package:recording_tool/shared/widgets/widgets.dart'; class AuthPageWidget extends StatefulWidget { @@ -35,7 +35,10 @@ class _AuthPageWidgetState extends State { child: AppButton( label: '确定', onPressed: () { - AppNavigator.push(const ScanQrCodePage()); + // AppNavigator.push(const ScanQrCodePage()); + AppNavigator.push( + const WebviewPage(assetPath: 'assets/html/index.html'), + ); }, variant: AppButtonVariant.secondary, ), diff --git a/lib/features/scan_qrcode/pages/page_push_test.dart b/lib/features/scan_qrcode/pages/page_push_test.dart index 317fbaf..5cc30aa 100644 --- a/lib/features/scan_qrcode/pages/page_push_test.dart +++ b/lib/features/scan_qrcode/pages/page_push_test.dart @@ -1,6 +1,5 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/material.dart'; import 'package:apivideo_live_stream/apivideo_live_stream.dart'; +import 'package:flutter/material.dart'; import 'package:recording_tool/shared/widgets/app_bar.dart'; class PushSteamTestWidget extends StatefulWidget { diff --git a/lib/gen/assets.gen.dart b/lib/gen/assets.gen.dart index d2870ba..80a04cf 100644 --- a/lib/gen/assets.gen.dart +++ b/lib/gen/assets.gen.dart @@ -11,6 +11,16 @@ import 'package:flutter/widgets.dart'; +class $AssetsHtmlGen { + const $AssetsHtmlGen(); + + /// File path: assets/html/index.html + String get index => 'assets/html/index.html'; + + /// List of all assets + List get values => [index]; +} + class $AssetsImagesGen { const $AssetsImagesGen(); @@ -30,18 +40,24 @@ class $AssetsImagesGen { AssetGenImage get imageLogo => const AssetGenImage('assets/images/image_logo.png'); + /// File path: assets/images/image_vs.png + AssetGenImage get imageVs => + const AssetGenImage('assets/images/image_vs.png'); + /// List of all assets List get values => [ imageCopy, imageDelete, imageDialogBg, imageLogo, + imageVs, ]; } class Assets { const Assets._(); + static const $AssetsHtmlGen html = $AssetsHtmlGen(); static const $AssetsImagesGen images = $AssetsImagesGen(); } diff --git a/lib/shared/widgets/app_webview.dart b/lib/shared/widgets/app_webview.dart index 0c724fb..92e2f2a 100644 --- a/lib/shared/widgets/app_webview.dart +++ b/lib/shared/widgets/app_webview.dart @@ -5,16 +5,19 @@ import 'package:webview_flutter_android/webview_flutter_android.dart'; import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart'; class WebviewPage extends StatefulWidget { - final String url; + final String? url; final String? title; + final String? assetPath; - const WebviewPage({super.key, required this.url, this.title}); + const WebviewPage({super.key, this.url, this.title, this.assetPath}); @override State createState() => WebviewPageState(); } class WebviewPageState extends State { + static const String _javaScriptChannelName = 'AppBridge'; + WebViewController? _controller; bool _isLoading = true; String? _errorMessage; @@ -26,11 +29,12 @@ class WebviewPageState extends State { } Future _initController() async { - if (widget.url?.isEmpty ?? true) { + if ((widget.url?.isEmpty ?? true) && widget.assetPath == null) { return; } final params = _createPlatformParams(); - final controller = WebViewController.fromPlatformCreationParams(params) + late final WebViewController controller; + controller = WebViewController.fromPlatformCreationParams(params) ..setJavaScriptMode(JavaScriptMode.unrestricted) ..setBackgroundColor(Colors.transparent) ..setNavigationDelegate( @@ -46,8 +50,9 @@ class WebviewPageState extends State { _errorMessage = null; }); }, - onPageFinished: (String url) { + onPageFinished: (String url) async { debugPrint('webview - page finished: $url'); + await _injectPostMessageBridge(controller); if (!mounted) return; setState(() => _isLoading = false); }, @@ -72,17 +77,28 @@ class WebviewPageState extends State { ), ); + controller.addJavaScriptChannel( + _javaScriptChannelName, + onMessageReceived: (JavaScriptMessage message) { + _onMessageReceived(message); + }, + ); + if (controller.platform is AndroidWebViewController) { AndroidWebViewController.enableDebugging(kDebugMode); await (controller.platform as AndroidWebViewController) .setMediaPlaybackRequiresUserGesture(false); } - final targetUrl = widget.url ?? ''; try { - await controller.loadRequest(Uri.parse(targetUrl)); + if (widget.assetPath != null) { + await controller.loadFlutterAsset(widget.assetPath!); + } else { + final targetUrl = widget.url ?? ''; + await controller.loadRequest(Uri.parse(targetUrl)); + } } catch (e) { - debugPrint('webview - loadRequest failed: $e'); + debugPrint('webview - load failed: $e'); if (!mounted) return; setState(() { _isLoading = false; @@ -95,6 +111,81 @@ class WebviewPageState extends State { setState(() => _controller = controller); } + void _onMessageReceived(JavaScriptMessage message) { + debugPrint('收到来自 WebView 的消息: ${message.message}'); + } + + /// 脚本注入传输给h5 数据 + Future _injectH5NeedData(WebViewController controller) async { + try { + await controller.runJavaScript(''' + (function () { + if (window.__appBridgePostMessageBridgeInstalled) { + return; + } + + window.__appBridgePostMessageBridgeInstalled = true; + window.addEventListener('message', function (event) { + if (!window.AppBridge || !window.AppBridge.postMessage) { + return; + } + + var payload = event.data; + if (typeof payload !== 'string') { + try { + payload = JSON.stringify(payload); + if (typeof payload === 'undefined') { + payload = String(event.data); + } + } catch (error) { + payload = String(payload); + } + } + + window.AppBridge.postMessage(payload); + }); + })(); + '''); + } catch (e) { + debugPrint('webview - inject postMessage bridge failed: $e'); + } + } + + Future _injectPostMessageBridge(WebViewController controller) async { + // try { + // await controller.runJavaScript(''' + // (function () { + // if (window.__appBridgePostMessageBridgeInstalled) { + // return; + // } + + // window.__appBridgePostMessageBridgeInstalled = true; + // window.addEventListener('message', function (event) { + // if (!window.AppBridge || !window.AppBridge.postMessage) { + // return; + // } + + // var payload = event.data; + // if (typeof payload !== 'string') { + // try { + // payload = JSON.stringify(payload); + // if (typeof payload === 'undefined') { + // payload = String(event.data); + // } + // } catch (error) { + // payload = String(payload); + // } + // } + + // window.AppBridge.postMessage(payload); + // }); + // })(); + // '''); + // } catch (e) { + // debugPrint('webview - inject postMessage bridge failed: $e'); + // } + } + PlatformWebViewControllerCreationParams _createPlatformParams() { if (WebViewPlatform.instance is WebKitWebViewPlatform) { return WebKitWebViewControllerCreationParams( @@ -110,27 +201,8 @@ class WebviewPageState extends State { return Scaffold( backgroundColor: Colors.transparent, extendBodyBehindAppBar: true, - appBar: AppBar( - backgroundColor: Colors.transparent, - elevation: 0, - title: Text( - widget.title ?? '', - style: const TextStyle(color: Colors.white), - ), - leading: IconButton( - icon: const Icon(Icons.arrow_back, color: Colors.white), - onPressed: () async { - final controller = _controller; - if (controller != null && await controller.canGoBack()) { - await controller.goBack(); - } else { - if (context.mounted) Navigator.of(context).maybePop(); - } - }, - ), - iconTheme: const IconThemeData(color: Colors.white), - ), + // appBar: myAppBar(context: context), body: _buildBody(), ); } diff --git a/pubspec.yaml b/pubspec.yaml index 4669b82..e7d265a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -80,6 +80,8 @@ flutter: # To add assets to your application, add an assets section, like this: assets: - assets/images/ + - assets/html/ + # To add assets to your application, add an assets section, like this: # assets: # - images/a_dot_burr.jpeg