I have an array that stores objects of two types. These two types are OwnMessageCard
and ReplyCard
. I use Socket.IO in my project.
late IO.Socket _socket;
var myMessagesList = < Widget > [];
_connectSocket() async {
final prefs = await SharedPreferences.getInstance();
myUsername = prefs.getString('myUsername') !;
_socket.onConnect((data) => print('Connection established'));
_socket.onConnectError((data) => print('Connection error: $data'));
_socket.onDisconnect((data) => print('Socket disconnected.'));
_socket.on(myUsername, (data) {
setState(() {
myMessagesList.add(ReplyCard(
senderMessage: data['message'].toString(),
sentAt: data['sentAt'].toString(),
));
});
_socket.emit('seen', {
'sender': myUsername,
'target': targetUsername
});
});
_socket.on("$myUsername/seen", (data) {
setState(() {
myMessagesList.forEach((element) {
if (element == OwnMessageCard) {
//Some codes here to change 'isSeen' property to 'true'
}
});
});
});
}
I want to set isSeen
property of all OwnMessageCard
object to true
when a message comes from _socket.on("$myUsername/seen", (data){}
.
OwnMessageCard
has two properties of myMessage
and isSeen
.
How can I do that?
Update: OwnMessageCard
class:
class OwnMessageCard extends StatelessWidget {
OwnMessageCard({super.key, required this.myMessage, required this.isSeen});
final String myMessage;
bool isSeen;
@override
Widget build(BuildContext context) {
final currentTime = DateTime.now();
return Align(
alignment: Alignment.centerRight,
child: ConstrainedBox(
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width - 45, minWidth: 180),
child: Card(
elevation: 1,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
color: ownMessageBackColor,
margin: const EdgeInsets.symmetric(horizontal: 15, vertical: 5),
child: Stack(
children: [
Padding(
padding: const EdgeInsets.only(
left: 25, right: 10, top: 5, bottom: 25),
child: Text(
myMessage,
style: const TextStyle(fontSize: 18, fontFamily: 'FMitra'),
),
),
Positioned(
bottom: 4,
right: 10,
child: Row(
children: [
Icon(
Icons.done_all,
size: 20,
color: isSeen ? Colors.blue : Colors.grey,
),
const SizedBox(
width: 5,
),
Text(
"${currentTime.hour}:${currentTime.minute} | ${currentTime.year}-${currentTime.month}-${currentTime.day}",
style: TextStyle(fontSize: 12, color: Colors.grey),
)
],
),
)
],
),
),
),
);
}
}
CodePudding user response:
First of all you can't compare variable with type by ==
, you need to use is
, second you can change your data like this, I assume this is your class model:
class OwnMessageCard {
final bool isSeen;
final String message;
OwnMessageCard({
required this.isSeen,
required this.message,
});
}
and you can change your data like this:
_socket.on("$myUsername/seen", (data) {
var newList = myMessagesList.map((e) => e is OwnMessageCard ? OwnMessageCard(isSeen: true,message: e.message ) : e)
.toList();
setState(() {
myMessagesList = newList;
});
});