| 
									
										
										
										
											2024-01-20 23:16:18 +08:00
										 |  |  | import 'dart:convert'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import 'package:appflowy/shared/custom_image_cache_manager.dart'; | 
					
						
							| 
									
										
										
										
											2024-01-30 22:39:42 +08:00
										 |  |  | import 'package:appflowy/util/string_extension.dart'; | 
					
						
							| 
									
										
										
										
											2024-02-05 21:53:14 +07:00
										 |  |  | import 'package:appflowy_backend/log.dart'; | 
					
						
							| 
									
										
										
										
											2024-01-20 23:16:18 +08:00
										 |  |  | import 'package:appflowy_backend/protobuf/flowy-user/protobuf.dart'; | 
					
						
							|  |  |  | import 'package:cached_network_image/cached_network_image.dart'; | 
					
						
							|  |  |  | import 'package:flutter/material.dart'; | 
					
						
							|  |  |  | import 'package:string_validator/string_validator.dart'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// This widget handles the downloading and caching of either internal or network images.
 | 
					
						
							|  |  |  | ///
 | 
					
						
							|  |  |  | /// It will append the access token to the URL if the URL is internal.
 | 
					
						
							|  |  |  | class FlowyNetworkImage extends StatelessWidget { | 
					
						
							|  |  |  |   const FlowyNetworkImage({ | 
					
						
							|  |  |  |     super.key, | 
					
						
							|  |  |  |     this.userProfilePB, | 
					
						
							|  |  |  |     this.width, | 
					
						
							|  |  |  |     this.height, | 
					
						
							|  |  |  |     this.fit = BoxFit.cover, | 
					
						
							|  |  |  |     this.progressIndicatorBuilder, | 
					
						
							|  |  |  |     this.errorWidgetBuilder, | 
					
						
							|  |  |  |     required this.url, | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   final UserProfilePB? userProfilePB; | 
					
						
							|  |  |  |   final String url; | 
					
						
							|  |  |  |   final double? width; | 
					
						
							|  |  |  |   final double? height; | 
					
						
							|  |  |  |   final BoxFit fit; | 
					
						
							|  |  |  |   final ProgressIndicatorBuilder? progressIndicatorBuilder; | 
					
						
							|  |  |  |   final LoadingErrorWidgetBuilder? errorWidgetBuilder; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @override | 
					
						
							|  |  |  |   Widget build(BuildContext context) { | 
					
						
							|  |  |  |     assert(isURL(url)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-30 22:39:42 +08:00
										 |  |  |     if (url.isAppFlowyCloudUrl) { | 
					
						
							| 
									
										
										
										
											2024-01-20 23:16:18 +08:00
										 |  |  |       assert(userProfilePB != null && userProfilePB!.token.isNotEmpty); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-04 11:24:25 +07:00
										 |  |  |     final manager = CustomImageCacheManager(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-01-20 23:16:18 +08:00
										 |  |  |     return CachedNetworkImage( | 
					
						
							| 
									
										
										
										
											2024-03-04 11:24:25 +07:00
										 |  |  |       cacheManager: manager, | 
					
						
							| 
									
										
										
										
											2024-01-20 23:16:18 +08:00
										 |  |  |       httpHeaders: _header(), | 
					
						
							|  |  |  |       imageUrl: url, | 
					
						
							|  |  |  |       fit: fit, | 
					
						
							|  |  |  |       width: width, | 
					
						
							|  |  |  |       height: height, | 
					
						
							|  |  |  |       progressIndicatorBuilder: progressIndicatorBuilder, | 
					
						
							|  |  |  |       errorWidget: (context, url, error) => | 
					
						
							|  |  |  |           errorWidgetBuilder?.call(context, url, error) ?? | 
					
						
							|  |  |  |           const SizedBox.shrink(), | 
					
						
							| 
									
										
										
										
											2024-03-04 11:24:25 +07:00
										 |  |  |       errorListener: (value) { | 
					
						
							|  |  |  |         // try to clear the image cache.
 | 
					
						
							|  |  |  |         manager.removeFile(url); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Log.error(value.toString()); | 
					
						
							|  |  |  |       }, | 
					
						
							| 
									
										
										
										
											2024-01-20 23:16:18 +08:00
										 |  |  |     ); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   Map<String, String> _header() { | 
					
						
							|  |  |  |     final header = <String, String>{}; | 
					
						
							|  |  |  |     final token = userProfilePB?.token; | 
					
						
							|  |  |  |     if (token != null) { | 
					
						
							| 
									
										
										
										
											2024-02-05 21:53:14 +07:00
										 |  |  |       try { | 
					
						
							|  |  |  |         final decodedToken = jsonDecode(token); | 
					
						
							|  |  |  |         header['Authorization'] = 'Bearer ${decodedToken['access_token']}'; | 
					
						
							|  |  |  |       } catch (e) { | 
					
						
							|  |  |  |         Log.error('unable to decode token: $e'); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2024-01-20 23:16:18 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |     return header; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |