0

大家好,我正在开发一个聊天应用程序,我在 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,
                                        );
                                },
                              )
                            ],
                          ),
                        )
                      ],
                    ));
                //   }
                // )
              });
        //});
4

0 回答 0