| .. | .. |
|---|
| 270 | 270 | return const Text('Image unavailable'); |
|---|
| 271 | 271 | } |
|---|
| 272 | 272 | |
|---|
| 273 | | - // Cache decoded bytes to prevent flicker on rebuild |
|---|
| 274 | | - final bytes = _imageCache.putIfAbsent(message.id, () { |
|---|
| 273 | + // Cache decoded bytes to prevent flicker on rebuild; evict oldest if over 50 entries |
|---|
| 274 | + if (!_imageCache.containsKey(message.id)) { |
|---|
| 275 | + if (_imageCache.length >= 50) { |
|---|
| 276 | + _imageCache.remove(_imageCache.keys.first); |
|---|
| 277 | + } |
|---|
| 275 | 278 | final raw = message.imageBase64!; |
|---|
| 276 | | - return Uint8List.fromList(base64Decode( |
|---|
| 279 | + _imageCache[message.id] = Uint8List.fromList(base64Decode( |
|---|
| 277 | 280 | raw.contains(',') ? raw.split(',').last : raw, |
|---|
| 278 | 281 | )); |
|---|
| 279 | | - }); |
|---|
| 282 | + } |
|---|
| 283 | + final bytes = _imageCache[message.id]!; |
|---|
| 280 | 284 | |
|---|
| 281 | 285 | return Column( |
|---|
| 282 | 286 | crossAxisAlignment: CrossAxisAlignment.start, |
|---|