Added caching of images to reduce flickering
All checks were successful
Build Flutter Web and Docker Image for Local Registry / Build Flutter Web App (push) Successful in 3m13s

This commit is contained in:
whysman 2024-11-10 02:18:16 -05:00
parent ed345b1fa9
commit b8dd01fc37
2 changed files with 22 additions and 20 deletions

View File

@ -25,6 +25,7 @@ class ProfileScreenState extends State<ProfileScreen> {
late String? imageData;
bool isNameEmpty = true;
final ImagePicker _picker = ImagePicker();
Image? _cachedImage; // Cache the Image widget
@override
void initState() {
@ -33,8 +34,8 @@ class ProfileScreenState extends State<ProfileScreen> {
Provider.of<SharedPreferencesProvider>(context, listen: false);
_nameController.text = prefsProvider.getUserName();
imageData = prefsProvider.getUserLogo();
_cachedImage = _buildLogoImage(imageData); // Initialize the cached image
// Check initial state of the name field and add listener
_nameController.addListener(_checkNameField);
isNameEmpty = _nameController.text.trim().isEmpty;
}
@ -58,9 +59,9 @@ class ProfileScreenState extends State<ProfileScreen> {
if (mounted) {
final prefsProvider =
Provider.of<SharedPreferencesProvider>(context, listen: false);
prefsProvider
.setUserLogo(base64Encode(imageBytes)); // Cache the image
imageData = base64Encode(imageBytes);
prefsProvider.setUserLogo(imageData!); // Cache the image data
_cachedImage = _buildLogoImage(imageData); // Update the cached image
}
});
}
@ -74,7 +75,6 @@ class ProfileScreenState extends State<ProfileScreen> {
await prefsProvider.setUserName(name);
await prefsProvider.setUserLogo(imageData);
// Close the screen after saving if the name is valid
widget.onClose();
} else {
ScaffoldMessenger.of(context).showSnackBar(
@ -91,7 +91,7 @@ class ProfileScreenState extends State<ProfileScreen> {
super.dispose();
}
Image getLogoImage(String? logo) {
Image _buildLogoImage(String? logo) {
if (logo != null) {
return Image.memory(base64Decode(logo));
} else {
@ -101,9 +101,6 @@ class ProfileScreenState extends State<ProfileScreen> {
@override
Widget build(BuildContext context) {
final prefsProvider = Provider.of<SharedPreferencesProvider>(context);
final userLogo = prefsProvider.getUserLogo();
return Center(
child: Material(
color: Colors.white,
@ -136,7 +133,7 @@ class ProfileScreenState extends State<ProfileScreen> {
const SizedBox(height: 20),
CircleAvatar(
radius: 50,
backgroundImage: getLogoImage(userLogo).image,
backgroundImage: _cachedImage?.image,
),
const SizedBox(height: 20),
TextField(

View File

@ -23,8 +23,8 @@ class StatusPageState extends State<StatusPage> {
late final Stream<dynamic> broadcastStream;
late StreamController<dynamic> controller;
List<Map<String, dynamic>> messages = []; // To hold user messages
List<Map<String, dynamic>> messages = [];
final Map<String, ImageProvider> _imageCache = {}; // Cache for decoded images
@override
void initState() {
@ -44,14 +44,11 @@ class StatusPageState extends State<StatusPage> {
if (!mounted) return;
// Check if the status is already active; if so, clear it, otherwise set it
final isStatusActive = prefsProvider.getCurrentStatus() == status;
final newStatus = isStatusActive ? '' : status;
// Update the status in SharedPreferences
await prefsProvider.setCurrentStatus(newStatus);
// Send the message to the WebSocket
final message = jsonEncode({
'Id': id,
'Name': name,
@ -76,18 +73,29 @@ class StatusPageState extends State<StatusPage> {
final status = message['Status'];
final incomingId = message['Id'];
final image = message['Image'];
messages.removeWhere((msg) => msg['Id'] == incomingId);
// Check if the message status is "expired" and update SharedPreferences
if (status == 'expired') {
await prefsProvider.setCurrentStatus('');
} else {
messages.add(message);
_cacheImage(incomingId, image); // Cache image on message receive
}
}
void _cacheImage(String id, String? base64Image) {
if (base64Image != null && !_imageCache.containsKey(id)) {
_imageCache[id] = Image.memory(base64Decode(base64Image)).image;
}
}
Widget _buildMessageItem(Map<String, dynamic> message) {
final imageId = message['Id'];
final imageProvider = _imageCache[imageId] ??
const AssetImage('assets/default_profile_image.png');
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Align(
@ -105,9 +113,7 @@ class StatusPageState extends State<StatusPage> {
children: [
CircleAvatar(
radius: 20,
backgroundImage: message['Image'] != null
? Image.memory(base64Decode(message['Image'])).image
: const AssetImage('assets/default_profile_image.png'),
backgroundImage: imageProvider,
),
const SizedBox(width: 8),
Text(
@ -129,14 +135,12 @@ class StatusPageState extends State<StatusPage> {
);
}
// Function to get the background color based on the current status
Color getButtonColor(String buttonStatus) {
final prefsProvider = Provider.of<SharedPreferencesProvider>(context);
final currentStatus = prefsProvider.getCurrentStatus();
return currentStatus == buttonStatus ? Colors.blueAccent : Colors.grey;
}
// Function to get the text color based on the current status
Color getButtonTextColor(String buttonStatus) {
final prefsProvider = Provider.of<SharedPreferencesProvider>(context);
final currentStatus = prefsProvider.getCurrentStatus();
@ -265,6 +269,7 @@ class StatusPageState extends State<StatusPage> {
@override
void dispose() {
channel.sink.close();
controller.close();
super.dispose();
}
}