大家好,我正在开发一个聊天应用程序,我在 graphql flutter 中的订阅有问题,我看不到在查询(消息)中更新我的数据(新消息)的方法,有人可以告诉我我错过了什么在我的代码中。
我已经尝试过我的代码,但它会显示一个 CircularProgressIndicator,直到接收者向发送者发送消息。
这是我的代码
Widget build(BuildContext context) {
return
Subscription(
options: SubscriptionOptions(
document: gql(onNewChatMessage),
variables: {'chatroom': MyApp.deviceId}),
builder: (result) {
if (result.hasException) {
return Text(result.exception.toString());
}
if (result.isLoading) {
return Center(
child: CircularProgressIndicator(),
);
}
var newMessage = result.data['onNewChatMessage'];
//print(newMessage);
Query(
options: QueryOptions(
document: gql(myMessagesQuery),
variables: {
'userName': MyApp.username,
'deviceId': MyApp.deviceId
},
// pollInterval: 10,
),
builder: (QueryResult result,
{VoidCallback refetch, FetchMore fetchMore}) {
_refetch = refetch;
if (result.hasException) {
return Text(result.exception.toString());
}
if (result.isLoading) {
return Center(
child: CircularProgressIndicator(),
);
}
scrollToBottom();
List messages = result.data['myMessages'];
if (newMessage['sender'] != MyApp.username)
messages.add({
'createdAt': newMessage['createdAt'],
'receiver': newMessage['receiver'],
'sender': newMessage['sender'],
'message': newMessage['text']
});
//print(messages);
return
GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child:
Column(
children: [
Expanded(
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30.0),
topRight: Radius.circular(30.0),
),
),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30.0),
topRight: Radius.circular(30.0),
),
child: ListView.builder(
controller: _scrollController,
padding: EdgeInsets.only(top: 15.0),
itemCount: messages.length,
itemBuilder: (context, index) {
final message = messages[index];
DateTime date =
DateTime.parse(message['createdAt']);
return Container(
padding: EdgeInsets.only(
left: 16,
right: 16,
top: 10,
bottom: 10),
child: Align(
alignment:
(message['sender'] == MyApp.username
? Alignment.topRight
: Alignment.topLeft),
child: Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(20),
color: (message['sender'] ==
MyApp.username
? Colors.blue[200]
: Colors.grey.shade200),
),
padding: EdgeInsets.all(16),
child: Container(
width: message['message'].length >
10 ||
message['sender'].length >
10
? 200
: 80,
child: message['sender'] !=
MyApp.username
? Column(
children: [
Align(
alignment:
Alignment.topLeft,
child: Text(
'~${message['sender']}',
style: TextStyle(
fontWeight:
FontWeight
.bold),
)),
SizedBox(height: 5),
Align(
alignment:
Alignment.topLeft,
child: Text(
message['message'],
style: TextStyle(
fontSize: 15),
),
),
SizedBox(height: 5),
Align(
alignment: Alignment
.bottomRight,
//child:
//Text(DateFormat.yMEd().format(date),),
child: Text(
DateFormat.Hm()
.format(date)
//DateFormat.yMEd().format(date)
),
)
],
)
: Column(
children: [
Align(
alignment:
Alignment.topLeft,
child: Text(
message['message'],
style: TextStyle(
fontSize: 15),
),
),
SizedBox(height: 5),
Align(
alignment: Alignment
.bottomRight,
//child: Text(DateFormat.yMEd().format(date),),
child: Text(
DateFormat.Hm()
.format(date)),
)
],
),
),
),
),
);
}),
),
),
),
Container(
padding:
EdgeInsets.only(left: 10, bottom: 10, top: 10),
height: 60,
width: double.infinity,
color: Colors.white,
child: Row(
children: [
GestureDetector(
//onTap: _showNotification,
child: Container(
height: 30,
width: 30,
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(30),
),
child: Icon(
Icons.chat_bubble,
color: Colors.white,
size: 20,
),
),
),
SizedBox(width: 15),
Expanded(
child: TextField(
onTap: () {
MyApp.username != null
? //print('hh')
scrollToBottom()
: showDialog(
context: context,
builder: (BuildContext context) =>
//ButtonBarTheme to align dialog button
ButtonBarTheme(
data: ButtonBarThemeData(
alignment:
MainAxisAlignment
.center),
child: AlertDialog(
content:
SingleChildScrollView(
child: Column(
children: [
Text(getTranslated(
context,
'username_request_title')),
FormBuilderTextField(
onTap: () {
showDialog(
context:
context,
builder: (BuildContext
context) =>
//ButtonBarTheme to align dialog button
ButtonBarTheme(
data:
ButtonBarThemeData(alignment: MainAxisAlignment.center),
child: AlertDialog(
content: Text(
getTranslated(context, 'username_save_message'),
textAlign: TextAlign.center,
),
actions: [
MaterialButton(
onPressed: () {
Navigator.of(context).pop(false);
},
child: Text(getTranslated(context, 'okay_btn')),
),
]),
));
},
name: 'name',
decoration: InputDecoration(
labelText:
getTranslated(
context,
'username_label')),
onChanged: (val) {
scrollToBottom();
MyApp.username =
val;
},
validator:
FormBuilderValidators
.compose(
[
FormBuilderValidators
.required(
context),
],
),
textInputAction:
TextInputAction
.done,
),
],
),
),
actions: [
MaterialButton(
onPressed: () async {
prefs =
await SharedPreferences
.getInstance();
setState(() {
prefs.setString(
'username',
MyApp
.username);
MyApp.username =
prefs.getString(
'username');
});
Navigator.of(
context)
.pop(false);
},
child: Text(
getTranslated(
context,
'save_btn')),
),
]),
));
},
textAlignVertical: TextAlignVertical.center,
textCapitalization:
TextCapitalization.sentences,
decoration: InputDecoration.collapsed(
hintText: getTranslated(
context, 'message_placeholder'),
hintStyle:
TextStyle(color: Colors.black54),
border: InputBorder.none),
controller: _textController,
keyboardType: TextInputType.multiline,
maxLines: null,
),
),
SizedBox(width: 15),
Mutation(
options: MutationOptions(
document: gql(sendChatMessage),
update: (cache, result) {
return cache;
},
onCompleted: (dynamic resultData) async {
List errors =
resultData['sendMessage']['errors'];
if (errors == null || errors.isEmpty) {
if (MyApp.deviceId == '' ||
MyApp.deviceId == null) {
prefs = await SharedPreferences
.getInstance();
setState(() {
MyApp.deviceId =
resultData['sendMessage']
['message']['deviceId'];
prefs.setString(
'deviceId', MyApp.deviceId);
MyApp.deviceId =
prefs.getString('deviceId');
});
}
_refetch();
} else {
for (int i = 0;
i < errors.length;
i++) {
setState(() {
field = errors[i]['field'];
error = errors[i]['message'];
});
}
if (field == 'sender_username') {
print(error);
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) =>
ButtonBarTheme(
data: ButtonBarThemeData(
alignment:
MainAxisAlignment
.center),
child: AlertDialog(
content: Text(
error,
textAlign:
TextAlign.center,
),
actions: [
MaterialButton(
onPressed: () {
prefs.remove(
'username');
setState(() {
MyApp.username =
null;
MyApp.deviceId =
null;
});
FocusScope.of(
context)
.unfocus();
Navigator.of(
context)
.pop(false);
},
child: Text(
getTranslated(
context,
'okay_btn')),
),
]),
));
}
print(errors);
}
}),
builder: (RunMutation runMutation,
QueryResult result) {
return result.isLoading
? Container(
width: 25,
height: 25,
margin: EdgeInsets.only(right: 15),
child: CircularProgressIndicator(),
)
: FloatingActionButton(
onPressed: () {
var text =
_textController.text.trim();
setState(() {
formData = {
'deviceId': MyApp.deviceId,
'senderUsername':
MyApp.username,
'message': text
};
});
if (text != '')
runMutation({'input': formData});
_textController.clear();
scrollToBottom();
},
child: Icon(
Icons.send,
color: Colors.white,
size: 18,
),
backgroundColor:
Theme.of(context).primaryColor,
elevation: 0,
);
},
)
],
),
)
],
));
// }
// )
});
//});