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
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:
parent
ed345b1fa9
commit
b8dd01fc37
@ -25,6 +25,7 @@ class ProfileScreenState extends State<ProfileScreen> {
|
|||||||
late String? imageData;
|
late String? imageData;
|
||||||
bool isNameEmpty = true;
|
bool isNameEmpty = true;
|
||||||
final ImagePicker _picker = ImagePicker();
|
final ImagePicker _picker = ImagePicker();
|
||||||
|
Image? _cachedImage; // Cache the Image widget
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -33,8 +34,8 @@ class ProfileScreenState extends State<ProfileScreen> {
|
|||||||
Provider.of<SharedPreferencesProvider>(context, listen: false);
|
Provider.of<SharedPreferencesProvider>(context, listen: false);
|
||||||
_nameController.text = prefsProvider.getUserName();
|
_nameController.text = prefsProvider.getUserName();
|
||||||
imageData = prefsProvider.getUserLogo();
|
imageData = prefsProvider.getUserLogo();
|
||||||
|
_cachedImage = _buildLogoImage(imageData); // Initialize the cached image
|
||||||
|
|
||||||
// Check initial state of the name field and add listener
|
|
||||||
_nameController.addListener(_checkNameField);
|
_nameController.addListener(_checkNameField);
|
||||||
isNameEmpty = _nameController.text.trim().isEmpty;
|
isNameEmpty = _nameController.text.trim().isEmpty;
|
||||||
}
|
}
|
||||||
@ -58,9 +59,9 @@ class ProfileScreenState extends State<ProfileScreen> {
|
|||||||
if (mounted) {
|
if (mounted) {
|
||||||
final prefsProvider =
|
final prefsProvider =
|
||||||
Provider.of<SharedPreferencesProvider>(context, listen: false);
|
Provider.of<SharedPreferencesProvider>(context, listen: false);
|
||||||
prefsProvider
|
|
||||||
.setUserLogo(base64Encode(imageBytes)); // Cache the image
|
|
||||||
imageData = base64Encode(imageBytes);
|
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.setUserName(name);
|
||||||
await prefsProvider.setUserLogo(imageData);
|
await prefsProvider.setUserLogo(imageData);
|
||||||
|
|
||||||
// Close the screen after saving if the name is valid
|
|
||||||
widget.onClose();
|
widget.onClose();
|
||||||
} else {
|
} else {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
@ -91,7 +91,7 @@ class ProfileScreenState extends State<ProfileScreen> {
|
|||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
Image getLogoImage(String? logo) {
|
Image _buildLogoImage(String? logo) {
|
||||||
if (logo != null) {
|
if (logo != null) {
|
||||||
return Image.memory(base64Decode(logo));
|
return Image.memory(base64Decode(logo));
|
||||||
} else {
|
} else {
|
||||||
@ -101,9 +101,6 @@ class ProfileScreenState extends State<ProfileScreen> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final prefsProvider = Provider.of<SharedPreferencesProvider>(context);
|
|
||||||
final userLogo = prefsProvider.getUserLogo();
|
|
||||||
|
|
||||||
return Center(
|
return Center(
|
||||||
child: Material(
|
child: Material(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
@ -136,7 +133,7 @@ class ProfileScreenState extends State<ProfileScreen> {
|
|||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
CircleAvatar(
|
CircleAvatar(
|
||||||
radius: 50,
|
radius: 50,
|
||||||
backgroundImage: getLogoImage(userLogo).image,
|
backgroundImage: _cachedImage?.image,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
TextField(
|
TextField(
|
||||||
|
@ -23,8 +23,8 @@ class StatusPageState extends State<StatusPage> {
|
|||||||
|
|
||||||
late final Stream<dynamic> broadcastStream;
|
late final Stream<dynamic> broadcastStream;
|
||||||
late StreamController<dynamic> controller;
|
late StreamController<dynamic> controller;
|
||||||
|
List<Map<String, dynamic>> messages = [];
|
||||||
List<Map<String, dynamic>> messages = []; // To hold user messages
|
final Map<String, ImageProvider> _imageCache = {}; // Cache for decoded images
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -44,14 +44,11 @@ class StatusPageState extends State<StatusPage> {
|
|||||||
|
|
||||||
if (!mounted) return;
|
if (!mounted) return;
|
||||||
|
|
||||||
// Check if the status is already active; if so, clear it, otherwise set it
|
|
||||||
final isStatusActive = prefsProvider.getCurrentStatus() == status;
|
final isStatusActive = prefsProvider.getCurrentStatus() == status;
|
||||||
final newStatus = isStatusActive ? '' : status;
|
final newStatus = isStatusActive ? '' : status;
|
||||||
|
|
||||||
// Update the status in SharedPreferences
|
|
||||||
await prefsProvider.setCurrentStatus(newStatus);
|
await prefsProvider.setCurrentStatus(newStatus);
|
||||||
|
|
||||||
// Send the message to the WebSocket
|
|
||||||
final message = jsonEncode({
|
final message = jsonEncode({
|
||||||
'Id': id,
|
'Id': id,
|
||||||
'Name': name,
|
'Name': name,
|
||||||
@ -76,18 +73,29 @@ class StatusPageState extends State<StatusPage> {
|
|||||||
|
|
||||||
final status = message['Status'];
|
final status = message['Status'];
|
||||||
final incomingId = message['Id'];
|
final incomingId = message['Id'];
|
||||||
|
final image = message['Image'];
|
||||||
|
|
||||||
messages.removeWhere((msg) => msg['Id'] == incomingId);
|
messages.removeWhere((msg) => msg['Id'] == incomingId);
|
||||||
|
|
||||||
// Check if the message status is "expired" and update SharedPreferences
|
|
||||||
if (status == 'expired') {
|
if (status == 'expired') {
|
||||||
await prefsProvider.setCurrentStatus('');
|
await prefsProvider.setCurrentStatus('');
|
||||||
} else {
|
} else {
|
||||||
messages.add(message);
|
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) {
|
Widget _buildMessageItem(Map<String, dynamic> message) {
|
||||||
|
final imageId = message['Id'];
|
||||||
|
final imageProvider = _imageCache[imageId] ??
|
||||||
|
const AssetImage('assets/default_profile_image.png');
|
||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
||||||
child: Align(
|
child: Align(
|
||||||
@ -105,9 +113,7 @@ class StatusPageState extends State<StatusPage> {
|
|||||||
children: [
|
children: [
|
||||||
CircleAvatar(
|
CircleAvatar(
|
||||||
radius: 20,
|
radius: 20,
|
||||||
backgroundImage: message['Image'] != null
|
backgroundImage: imageProvider,
|
||||||
? Image.memory(base64Decode(message['Image'])).image
|
|
||||||
: const AssetImage('assets/default_profile_image.png'),
|
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
Text(
|
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) {
|
Color getButtonColor(String buttonStatus) {
|
||||||
final prefsProvider = Provider.of<SharedPreferencesProvider>(context);
|
final prefsProvider = Provider.of<SharedPreferencesProvider>(context);
|
||||||
final currentStatus = prefsProvider.getCurrentStatus();
|
final currentStatus = prefsProvider.getCurrentStatus();
|
||||||
return currentStatus == buttonStatus ? Colors.blueAccent : Colors.grey;
|
return currentStatus == buttonStatus ? Colors.blueAccent : Colors.grey;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to get the text color based on the current status
|
|
||||||
Color getButtonTextColor(String buttonStatus) {
|
Color getButtonTextColor(String buttonStatus) {
|
||||||
final prefsProvider = Provider.of<SharedPreferencesProvider>(context);
|
final prefsProvider = Provider.of<SharedPreferencesProvider>(context);
|
||||||
final currentStatus = prefsProvider.getCurrentStatus();
|
final currentStatus = prefsProvider.getCurrentStatus();
|
||||||
@ -265,6 +269,7 @@ class StatusPageState extends State<StatusPage> {
|
|||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
channel.sink.close();
|
channel.sink.close();
|
||||||
|
controller.close();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user