💄 Optimize embed view renderer loading logic
This commit is contained in:
		| @@ -1,4 +1,5 @@ | |||||||
| import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||||
|  | import 'package:flutter_hooks/flutter_hooks.dart'; | ||||||
| import 'package:flutter_inappwebview/flutter_inappwebview.dart'; | import 'package:flutter_inappwebview/flutter_inappwebview.dart'; | ||||||
| import 'package:hooks_riverpod/hooks_riverpod.dart'; | import 'package:hooks_riverpod/hooks_riverpod.dart'; | ||||||
| import 'package:island/models/post.dart'; | import 'package:island/models/post.dart'; | ||||||
| @@ -22,6 +23,10 @@ class EmbedViewRenderer extends HookConsumerWidget { | |||||||
|     final theme = Theme.of(context); |     final theme = Theme.of(context); | ||||||
|     final colorScheme = theme.colorScheme; |     final colorScheme = theme.colorScheme; | ||||||
|  |  | ||||||
|  |     // State management for lazy loading | ||||||
|  |     final shouldLoad = useState(false); | ||||||
|  |     final isLoading = useState(false); | ||||||
|  |  | ||||||
|     return Container( |     return Container( | ||||||
|       constraints: BoxConstraints(maxHeight: maxHeight ?? 400), |       constraints: BoxConstraints(maxHeight: maxHeight ?? 400), | ||||||
|       decoration: BoxDecoration( |       decoration: BoxDecoration( | ||||||
| @@ -93,11 +98,17 @@ class EmbedViewRenderer extends HookConsumerWidget { | |||||||
|               ), |               ), | ||||||
|             ), |             ), | ||||||
|  |  | ||||||
|             // WebView content |             // WebView content with lazy loading | ||||||
|             AspectRatio( |             AspectRatio( | ||||||
|               aspectRatio: embedView.aspectRatio ?? 1, |               aspectRatio: embedView.aspectRatio ?? 1, | ||||||
|               child: InAppWebView( |               child: | ||||||
|                 initialUrlRequest: URLRequest(url: WebUri(embedView.uri)), |                   shouldLoad.value | ||||||
|  |                       ? Stack( | ||||||
|  |                         children: [ | ||||||
|  |                           InAppWebView( | ||||||
|  |                             initialUrlRequest: URLRequest( | ||||||
|  |                               url: WebUri(embedView.uri), | ||||||
|  |                             ), | ||||||
|                             initialSettings: InAppWebViewSettings( |                             initialSettings: InAppWebViewSettings( | ||||||
|                               javaScriptEnabled: true, |                               javaScriptEnabled: true, | ||||||
|                               mediaPlaybackRequiresUserGesture: false, |                               mediaPlaybackRequiresUserGesture: false, | ||||||
| @@ -110,7 +121,8 @@ class EmbedViewRenderer extends HookConsumerWidget { | |||||||
|                               builtInZoomControls: false, |                               builtInZoomControls: false, | ||||||
|                               displayZoomControls: false, |                               displayZoomControls: false, | ||||||
|                               minimumFontSize: 12, |                               minimumFontSize: 12, | ||||||
|                   preferredContentMode: UserPreferredContentMode.RECOMMENDED, |                               preferredContentMode: | ||||||
|  |                                   UserPreferredContentMode.RECOMMENDED, | ||||||
|                               allowsBackForwardNavigationGestures: false, |                               allowsBackForwardNavigationGestures: false, | ||||||
|                               allowsLinkPreview: false, |                               allowsLinkPreview: false, | ||||||
|                               isInspectable: false, |                               isInspectable: false, | ||||||
| @@ -125,9 +137,10 @@ class EmbedViewRenderer extends HookConsumerWidget { | |||||||
|                               ); |                               ); | ||||||
|                             }, |                             }, | ||||||
|                             onLoadStart: (controller, url) { |                             onLoadStart: (controller, url) { | ||||||
|                   // Handle load start |                               isLoading.value = true; | ||||||
|                             }, |                             }, | ||||||
|                             onLoadStop: (controller, url) async { |                             onLoadStop: (controller, url) async { | ||||||
|  |                               isLoading.value = false; | ||||||
|                               // Inject CSS to improve mobile display and remove borders |                               // Inject CSS to improve mobile display and remove borders | ||||||
|                               await controller.evaluateJavascript( |                               await controller.evaluateJavascript( | ||||||
|                                 source: ''' |                                 source: ''' | ||||||
| @@ -190,14 +203,23 @@ class EmbedViewRenderer extends HookConsumerWidget { | |||||||
|                               ); |                               ); | ||||||
|                             }, |                             }, | ||||||
|                             onLoadError: (controller, url, code, message) { |                             onLoadError: (controller, url, code, message) { | ||||||
|                   // Handle load errors |                               isLoading.value = false; | ||||||
|                             }, |                             }, | ||||||
|                 onLoadHttpError: (controller, url, statusCode, description) { |                             onLoadHttpError: ( | ||||||
|                   // Handle HTTP errors |                               controller, | ||||||
|  |                               url, | ||||||
|  |                               statusCode, | ||||||
|  |                               description, | ||||||
|  |                             ) { | ||||||
|  |                               isLoading.value = false; | ||||||
|                             }, |                             }, | ||||||
|                 shouldOverrideUrlLoading: (controller, navigationAction) async { |                             shouldOverrideUrlLoading: ( | ||||||
|  |                               controller, | ||||||
|  |                               navigationAction, | ||||||
|  |                             ) async { | ||||||
|                               final uri = navigationAction.request.url; |                               final uri = navigationAction.request.url; | ||||||
|                   if (uri != null && uri.toString() != embedView.uri) { |                               if (uri != null && | ||||||
|  |                                   uri.toString() != embedView.uri) { | ||||||
|                                 // Open external links in browser |                                 // Open external links in browser | ||||||
|                                 // You might want to use url_launcher here |                                 // You might want to use url_launcher here | ||||||
|                                 return NavigationActionPolicy.CANCEL; |                                 return NavigationActionPolicy.CANCEL; | ||||||
| @@ -209,9 +231,48 @@ class EmbedViewRenderer extends HookConsumerWidget { | |||||||
|                             }, |                             }, | ||||||
|                             onConsoleMessage: (controller, consoleMessage) { |                             onConsoleMessage: (controller, consoleMessage) { | ||||||
|                               // Handle console messages for debugging |                               // Handle console messages for debugging | ||||||
|                   debugPrint('WebView Console: ${consoleMessage.message}'); |                               debugPrint( | ||||||
|  |                                 'WebView Console: ${consoleMessage.message}', | ||||||
|  |                               ); | ||||||
|                             }, |                             }, | ||||||
|                           ), |                           ), | ||||||
|  |                           if (isLoading.value) | ||||||
|  |                             Container( | ||||||
|  |                               color: colorScheme.surfaceContainerLowest, | ||||||
|  |                               child: const Center( | ||||||
|  |                                 child: CircularProgressIndicator(), | ||||||
|  |                               ), | ||||||
|  |                             ), | ||||||
|  |                         ], | ||||||
|  |                       ) | ||||||
|  |                       : GestureDetector( | ||||||
|  |                         onTap: () { | ||||||
|  |                           shouldLoad.value = true; | ||||||
|  |                         }, | ||||||
|  |                         child: Container( | ||||||
|  |                           color: colorScheme.surfaceContainerLowest, | ||||||
|  |                           child: Column( | ||||||
|  |                             mainAxisAlignment: MainAxisAlignment.center, | ||||||
|  |                             children: [ | ||||||
|  |                               Icon( | ||||||
|  |                                 Symbols.play_arrow, | ||||||
|  |                                 size: 48, | ||||||
|  |                                 color: colorScheme.onSurfaceVariant.withOpacity( | ||||||
|  |                                   0.6, | ||||||
|  |                                 ), | ||||||
|  |                               ), | ||||||
|  |                               const SizedBox(height: 8), | ||||||
|  |                               Text( | ||||||
|  |                                 'Tap to load content', | ||||||
|  |                                 style: theme.textTheme.bodyMedium?.copyWith( | ||||||
|  |                                   color: colorScheme.onSurfaceVariant | ||||||
|  |                                       .withOpacity(0.6), | ||||||
|  |                                 ), | ||||||
|  |                               ), | ||||||
|  |                             ], | ||||||
|  |                           ), | ||||||
|  |                         ), | ||||||
|  |                       ), | ||||||
|             ), |             ), | ||||||
|           ], |           ], | ||||||
|         ), |         ), | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user