I'm new to bloc and trying to implement a chat with flutter_bloc
package. The service for my messaging is twilio conversations api. My function works perfectly fine, Im simply not able to refresh my list of messages. Could somebody show me what I'm missing here? If I access the chatpage I can see all the messages, it only doesnt refresh if we have a new one.
I updated my code since I have a small success. Whenever User A or User B joins the chat, all messages are displayed. If I'm sending a message as User A, it will be visible in the UI for User A now and it is part of the conversation, BUT User B doesnt receive the new message which was added to the conversation without reloading. Which step is missing here so that the other User also receives the message? I just need help converting my code so I have a stream where the other participants of the chat can listen to so their conversation is refreshing too.
my chat_event.dart
abstract class ChatEvent extends Equatable{
const ChatEvent();
@override
List<Object> get props => [];
}
class InitialChatEvent extends ChatEvent {}
class AddMessage extends ChatEvent {
final String messageToPost;
AddMessage(this.messageToPost);
}
my chat_state.dart
class ChatState extends Equatable {
final Messages messages;
const ChatState({required this.messages});
factory ChatState.initial() => ChatState(messages: Messages(messages: []));
@override
List<Object> get props => [messages];
@override
bool get stringify => true;
ChatState copyWith({
List<Messages>? messages,
}) {
return ChatState(
messages: this.messages,
);
}
}
part of chatpage
...
Expanded(
child: BlocBuilder<ChatBloc, ChatState>(
builder: (context, state) {
print('chatpage builder: ' + state.messages.toString());
return ListView.builder(
itemCount: state.messages.messages.length,
scrollDirection: Axis.vertical,
itemBuilder: (context, i) {
return ListTile(
tileColor: state.messages.messages[i].author.toString() == username ? Colors.amber : Colors.amber.shade100,
title: Text(
state.messages.messages[i].body.toString(),
style: TextStyle(color: Colors.black),
),
);
});
},
),
),
...
Container(
height: 50,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
child: RaisedButton(
textColor: Colors.white,
color: Colors.red,
child: Text('Button'),
onPressed: () async {
// print(chatMessage.text);
context.read<ChatBloc>().add(AddMessage(chatMessage.text));
},
)),
],
...
chat_bloc.dart
class ChatBloc extends Bloc<ChatEvent, ChatState> {
ChatBloc() : super(ChatState.initial()) {
// print('wird ausgeführt');
on<InitialChatEvent>((event, emit) async {
final chatFeed = await HttpService().getMessages();
emit(ChatState(messages: chatFeed));
});
on<AddMessage>((event, emit) async {
final newConversation = await HttpService().postMessage(event.messageToPost);
final chatFeed = await HttpService().getMessages();
emit(ChatState(messages: chatFeed));
});
}
}
main.dart if needed
...
void main() => runApp(MultiBlocProvider(
providers: [
BlocProvider(create: (context) => ColorBloc()),
BlocProvider(create: (context) => ChatBloc()),
],
child: MaterialApp(
title: "App",
home: MyApp(),
)));
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
// This widget is the root of your application.
TextEditingController nameController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
...
child: RaisedButton(
textColor: Colors.white,
color: Colors.red,
child: Text('Button'),
onPressed: () {
print(nameController.text);
context.read<ChatBloc>().add(InitialChatEvent());
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => ChatPage(userText: nameController.text)
),
);
},
)),
],
),
);
}
}
http_service.dart
Future postMessage(String messageToPost) async {
Map<String, String> _messageToPost = {
'Author': 'User A',
'Body': messageToPost,
};
try {
// print(messageToPost);
var response = await dio.post(
"https://conversations.twilio.com/v1/Conversations/$sid/Messages",
data: _messageToPost,
options: Options(
contentType: Headers.formUrlEncodedContentType,
headers: <String, String>{'authorization': basicAuth},
));
return messageToPost;
} catch (e) {
print('exception: ' + e.toString());
Future.error(e.toString());
}
}
Future getMessages() async {
try {
final response = await dio.get(
"https://conversations.twilio.com/v1/Conversations/$sid/Messages",
// data: _messageToPost,
options: Options(
// contentType: Headers.formUrlEncodedContentType,
headers: <String, String>{'authorization': basicAuth},
));
print(response.data);
final messageList = Messages.fromJson(response.data);
print(messageList);
return messageList;
} catch (e) {
print('exception: ' + e.toString());
return Future.error(e.toString());
}
}
}