@@ -4,6 +4,7 @@ import 'package:cached_network_image/cached_network_image.dart';
44import 'package:flutter/material.dart' ;
55import 'package:shimmer/shimmer.dart' ;
66import 'package:stream_chat_flutter/src/attachment/thumbnail/thumbnail_error.dart' ;
7+ import 'package:stream_chat_flutter/src/attachment/thumbnail/thumbnail_size_calculator.dart' ;
78import 'package:stream_chat_flutter/src/theme/stream_chat_theme.dart' ;
89import 'package:stream_chat_flutter/src/utils/utils.dart' ;
910import 'package:stream_chat_flutter_core/stream_chat_flutter_core.dart' ;
@@ -72,43 +73,64 @@ class StreamImageAttachmentThumbnail extends StatelessWidget {
7273
7374 @override
7475 Widget build (BuildContext context) {
75- final file = image.file;
76- if (file != null ) {
77- return _LocalImageAttachment (
78- file: file,
79- width: width,
80- height: height,
81- fit: fit,
82- errorBuilder: errorBuilder,
83- );
84- }
76+ return LayoutBuilder (
77+ builder: (context, constraints) {
78+ // Calculate optimal thumbnail size once for all paths
79+ final effectiveThumbnailSize = switch (thumbnailSize) {
80+ final thumbnailSize? => thumbnailSize,
81+ _ => ThumbnailSizeCalculator .calculate (
82+ targetSize: constraints.biggest,
83+ originalSize: image.originalSize,
84+ pixelRatio: MediaQuery .devicePixelRatioOf (context),
85+ ),
86+ };
87+
88+ final cacheWidth = effectiveThumbnailSize? .width.round ();
89+ final cacheHeight = effectiveThumbnailSize? .height.round ();
90+
91+ // If the remote image URL is available, we can directly show it using
92+ // the _RemoteImageAttachment widget.
93+ if (image.thumbUrl ?? image.imageUrl case final imageUrl? ) {
94+ var resizedImageUrl = imageUrl;
95+ if (effectiveThumbnailSize case final thumbnailSize? ) {
96+ resizedImageUrl = imageUrl.getResizedImageUrl (
97+ crop: thumbnailCropType,
98+ resize: thumbnailResizeType,
99+ width: thumbnailSize.width,
100+ height: thumbnailSize.height,
101+ );
102+ }
103+
104+ return _RemoteImageAttachment (
105+ url: resizedImageUrl,
106+ width: width,
107+ height: height,
108+ fit: fit,
109+ cacheWidth: cacheWidth,
110+ cacheHeight: cacheHeight,
111+ errorBuilder: errorBuilder,
112+ );
113+ }
114+
115+ // Otherwise, we try to show the local image file.
116+ if (image.file case final file? ) {
117+ return _LocalImageAttachment (
118+ file: file,
119+ width: width,
120+ height: height,
121+ fit: fit,
122+ cacheWidth: cacheWidth,
123+ cacheHeight: cacheHeight,
124+ errorBuilder: errorBuilder,
125+ );
126+ }
85127
86- var imageUrl = image.thumbUrl ?? image.imageUrl ?? image.assetUrl;
87- if (imageUrl != null ) {
88- final thumbnailSize = this .thumbnailSize;
89- if (thumbnailSize != null ) {
90- imageUrl = imageUrl.getResizedImageUrl (
91- width: thumbnailSize.width,
92- height: thumbnailSize.height,
93- resize: thumbnailResizeType,
94- crop: thumbnailCropType,
128+ return errorBuilder (
129+ context,
130+ 'Image attachment is not valid' ,
131+ StackTrace .current,
95132 );
96- }
97-
98- return _RemoteImageAttachment (
99- url: imageUrl,
100- width: width,
101- height: height,
102- fit: fit,
103- errorBuilder: errorBuilder,
104- );
105- }
106-
107- // Return error widget if no image is found.
108- return errorBuilder (
109- context,
110- 'Image attachment is not valid' ,
111- StackTrace .current,
133+ },
112134 );
113135 }
114136}
@@ -119,12 +141,16 @@ class _LocalImageAttachment extends StatelessWidget {
119141 required this .errorBuilder,
120142 this .width,
121143 this .height,
144+ this .cacheWidth,
145+ this .cacheHeight,
122146 this .fit,
123147 });
124148
125149 final AttachmentFile file;
126150 final double ? width;
127151 final double ? height;
152+ final int ? cacheWidth;
153+ final int ? cacheHeight;
128154 final BoxFit ? fit;
129155 final ThumbnailErrorBuilder errorBuilder;
130156
@@ -136,6 +162,8 @@ class _LocalImageAttachment extends StatelessWidget {
136162 bytes,
137163 width: width,
138164 height: height,
165+ cacheWidth: cacheWidth,
166+ cacheHeight: cacheHeight,
139167 fit: fit,
140168 errorBuilder: errorBuilder,
141169 );
@@ -147,6 +175,8 @@ class _LocalImageAttachment extends StatelessWidget {
147175 File (path),
148176 width: width,
149177 height: height,
178+ cacheWidth: cacheWidth,
179+ cacheHeight: cacheHeight,
150180 fit: fit,
151181 errorBuilder: errorBuilder,
152182 );
@@ -167,12 +197,16 @@ class _RemoteImageAttachment extends StatelessWidget {
167197 required this .errorBuilder,
168198 this .width,
169199 this .height,
200+ this .cacheWidth,
201+ this .cacheHeight,
170202 this .fit,
171203 });
172204
173205 final String url;
174206 final double ? width;
175207 final double ? height;
208+ final int ? cacheWidth;
209+ final int ? cacheHeight;
176210 final BoxFit ? fit;
177211 final ThumbnailErrorBuilder errorBuilder;
178212
@@ -182,6 +216,8 @@ class _RemoteImageAttachment extends StatelessWidget {
182216 imageUrl: url,
183217 width: width,
184218 height: height,
219+ memCacheWidth: cacheWidth,
220+ memCacheHeight: cacheHeight,
185221 fit: fit,
186222 placeholder: (context, __) {
187223 final image = Image .asset (
0 commit comments