import 'dart:async'; import 'package:flutter/material.dart'; import 'package:webview_flutter/webview_flutter.dart'; // #docregion platform_imports // Import for Android features. import 'package:webview_flutter_android/webview_flutter_android.dart'; // Import for iOS features. import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart'; // #enddocregion platform_imports import 'package:mobdr/service/shared_prefs.dart'; import 'package:mobdr/main.dart'; import 'package:mobdr/events.dart'; class TabMP4Page extends StatefulWidget { @override _TabMP4PageState createState() => _TabMP4PageState(); } class _TabMP4PageState extends State with AutomaticKeepAliveClientMixin { late final WebViewController _controller; late StreamSubscription sub; int loadingPercentage = 0; String url = SharedPrefs().urlMP4; @override void initState() { super.initState(); // #docregion platform_features late final PlatformWebViewControllerCreationParams params; if (WebViewPlatform.instance is WebKitWebViewPlatform) { params = WebKitWebViewControllerCreationParams( allowsInlineMediaPlayback: true, mediaTypesRequiringUserAction: const {}, ); } else { params = const PlatformWebViewControllerCreationParams(); } final WebViewController controller = WebViewController.fromPlatformCreationParams(params); // #enddocregion platform_features controller ..setJavaScriptMode(JavaScriptMode.unrestricted) ..setBackgroundColor(const Color(0x00000000)) ..setNavigationDelegate( NavigationDelegate( onProgress: (int progress) { debugPrint('WebView is loading (progress : $progress%)'); }, onPageStarted: (String url) { debugPrint('Page started loading: $url'); }, onPageFinished: (String url) { debugPrint('Page finished loading: $url'); }, onWebResourceError: (WebResourceError error) { debugPrint(''' Page resource error: code: ${error.errorCode} description: ${error.description} errorType: ${error.errorType} isForMainFrame: ${error.isForMainFrame} '''); }, onNavigationRequest: (NavigationRequest request) { if (request.url.startsWith('https://www.youtube.com/')) { debugPrint('blocking navigation to ${request.url}'); return NavigationDecision.prevent; } debugPrint('allowing navigation to ${request.url}'); return NavigationDecision.navigate; }, onUrlChange: (UrlChange change) { debugPrint('url change to ${change.url}'); }, ), ) ..addJavaScriptChannel( 'Toaster', onMessageReceived: (JavaScriptMessage message) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(message.message)), ); }, ) ..loadRequest(Uri.parse(url)); // #docregion platform_features if (controller.platform is AndroidWebViewController) { AndroidWebViewController.enableDebugging(true); (controller.platform as AndroidWebViewController) .setMediaPlaybackRequiresUserGesture(false); } // #enddocregion platform_features _controller = controller; sub = eventBus.on().listen((e) { setState(() { controller.loadRequest( Uri.parse(e.url), ); }); }); } @override void dispose() { sub.cancel(); super.dispose(); } @override Widget build(BuildContext context) { super.build(context); return SafeArea( child: Stack( children: [ WebViewWidget( controller: _controller, ), if (loadingPercentage < 100) LinearProgressIndicator( value: loadingPercentage / 100.0, ), ], ), ); } @override bool get wantKeepAlive => true; }