From 69c37c43074ad20ab9c7a5b7f4464863c4d298d4 Mon Sep 17 00:00:00 2001
From: Matthias Nott <mnott@mnsoft.org>
Date: Sun, 22 Mar 2026 15:58:16 +0100
Subject: [PATCH] fix: image flicker, screenshot indicator, cross-session message storage

---
 lib/widgets/message_bubble.dart |   17 ++++++++++++-----
 1 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/lib/widgets/message_bubble.dart b/lib/widgets/message_bubble.dart
index e9c4882..c5df417 100644
--- a/lib/widgets/message_bubble.dart
+++ b/lib/widgets/message_bubble.dart
@@ -1,5 +1,6 @@
 import 'dart:convert';
 import 'dart:math';
+import 'dart:typed_data';
 
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
@@ -8,6 +9,9 @@
 import '../models/message.dart';
 import '../theme/app_theme.dart';
 import 'image_viewer.dart';
+
+// Cache decoded image bytes to prevent flicker on widget rebuild
+final Map<String, Uint8List> _imageCache = {};
 
 /// Chat message bubble with support for text, voice, and image types.
 class MessageBubble extends StatelessWidget {
@@ -208,11 +212,13 @@
       return const Text('Image unavailable');
     }
 
-    final bytes = base64Decode(
-      message.imageBase64!.contains(',')
-          ? message.imageBase64!.split(',').last
-          : message.imageBase64!,
-    );
+    // Cache decoded bytes to prevent flicker on rebuild
+    final bytes = _imageCache.putIfAbsent(message.id, () {
+      final raw = message.imageBase64!;
+      return Uint8List.fromList(base64Decode(
+        raw.contains(',') ? raw.split(',').last : raw,
+      ));
+    });
 
     return Column(
       crossAxisAlignment: CrossAxisAlignment.start,
@@ -232,6 +238,7 @@
               width: 260,
               height: 180,
               fit: BoxFit.cover,
+              gaplessPlayback: true,
               errorBuilder: (_, e, st) => const SizedBox(
                 width: 260,
                 height: 60,

--
Gitblit v1.3.1