diff --git a/bytedesk_demo/lib/page/user_info_page.dart b/bytedesk_demo/lib/page/user_info_page.dart index 437931a..b7d95d9 100755 --- a/bytedesk_demo/lib/page/user_info_page.dart +++ b/bytedesk_demo/lib/page/user_info_page.dart @@ -122,4 +122,22 @@ class _UserInfoPageState extends State { Fluttertoast.showToast(msg: "设置备注成功") }); } + + // 一次调用接口,同时设置:昵称、头像、备注 + void _updateProfile() { + // + String mynickname = '自定义APP昵称flutter'; + String myavatarurl = + 'https://bytedesk.oss-cn-shenzhen.aliyuncs.com/avatars/girl.png'; // 头像网址url + String mydescription = '自定义用户备注'; + BytedeskKefu.updateProfile(mynickname, myavatarurl, mydescription) + .then((user) => { + setState(() { + _nickname = mynickname; + _avatar = myavatarurl; + _description = mydescription; + }), + Fluttertoast.showToast(msg: "设置成功") + }); + } } diff --git a/bytedesk_demo/pubspec.yaml b/bytedesk_demo/pubspec.yaml index f8019cd..a1124f6 100644 --- a/bytedesk_demo/pubspec.yaml +++ b/bytedesk_demo/pubspec.yaml @@ -46,7 +46,7 @@ dependencies: # 请在ios/Podfile中添加:use_frameworks! vibration: ^1.7.3 # 在线客服 https://pub.dev/packages/bytedesk_kefu - bytedesk_kefu: ^1.2.8 + bytedesk_kefu: ^1.2.9 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. diff --git a/bytedesk_kefu/CHANGELOG.md b/bytedesk_kefu/CHANGELOG.md index 72eced0..6cb0943 100644 --- a/bytedesk_kefu/CHANGELOG.md +++ b/bytedesk_kefu/CHANGELOG.md @@ -1,5 +1,9 @@ # Upgrade Log +## 1.2.9 + +* optimize user experience + ## 1.2.8 * optimize user experience diff --git a/bytedesk_kefu/example/lib/page/user_info_page.dart b/bytedesk_kefu/example/lib/page/user_info_page.dart index a8739c8..49054d6 100755 --- a/bytedesk_kefu/example/lib/page/user_info_page.dart +++ b/bytedesk_kefu/example/lib/page/user_info_page.dart @@ -102,8 +102,7 @@ class _UserInfoPageState extends State { void _setAvatar() { // 可自定义用户头像url-客服端可见,注意:是头像网址,非本地图片路径 - String myavatarurl = - 'https://chainsnow.oss-cn-shenzhen.aliyuncs.com/avatars/visitor_default_avatar.png'; // 头像网址url + String myavatarurl = 'https://bytedesk.oss-cn-shenzhen.aliyuncs.com/avatars/girl.png'; // 头像网址url BytedeskKefu.updateAvatar(myavatarurl).then((user) => { setState(() { _avatar = myavatarurl; @@ -122,4 +121,20 @@ class _UserInfoPageState extends State { Fluttertoast.showToast(msg: "设置备注成功") }); } + + // 一次调用接口,同时设置:昵称、头像、备注 + void _updateProfile() { + // + String mynickname = '自定义APP昵称flutter'; + String myavatarurl = 'https://bytedesk.oss-cn-shenzhen.aliyuncs.com/avatars/girl.png'; // 头像网址url + String mydescription = '自定义用户备注'; + BytedeskKefu.updateProfile(mynickname, myavatarurl, mydescription).then((user) => { + setState(() { + _nickname = mynickname; + _avatar = myavatarurl; + _description = mydescription; + }), + Fluttertoast.showToast(msg: "设置成功") + }); + } } diff --git a/bytedesk_kefu/lib/bytedesk_kefu.dart b/bytedesk_kefu/lib/bytedesk_kefu.dart index d0979ea..032ec9e 100644 --- a/bytedesk_kefu/lib/bytedesk_kefu.dart +++ b/bytedesk_kefu/lib/bytedesk_kefu.dart @@ -394,8 +394,13 @@ class BytedeskKefu { } // 设置用户备注 - static Future updateDescription(String avatar) async { - return BytedeskUserHttpApi().updateDescription(avatar); + static Future updateDescription(String description) async { + return BytedeskUserHttpApi().updateDescription(description); + } + + // 一个接口,设置:昵称、头像、备注 + static Future updateProfile(String nickname, String avatar, String description) async { + return BytedeskUserHttpApi().updateProfile(nickname, avatar, description); } // 查询技能组在线状态 diff --git a/bytedesk_kefu/lib/http/bytedesk_user_api.dart b/bytedesk_kefu/lib/http/bytedesk_user_api.dart index 0aa9481..c90f02e 100755 --- a/bytedesk_kefu/lib/http/bytedesk_user_api.dart +++ b/bytedesk_kefu/lib/http/bytedesk_user_api.dart @@ -334,7 +334,8 @@ class BytedeskUserHttpApi extends BytedeskBaseHttpApi { //将string类型数据 转换为json类型的数据 final responseJson = json.decode(utf8decoder.convert(initResponse.bodyBytes)); - // print("responseJson $responseJson"); + print("updateNickname:"); + print(responseJson); // 更新本地数据 SpUtil.putString(BytedeskConstants.nickname, nickname!); @@ -355,7 +356,8 @@ class BytedeskUserHttpApi extends BytedeskBaseHttpApi { //将string类型数据 转换为json类型的数据 final responseJson = json.decode(utf8decoder.convert(initResponse.bodyBytes)); - // print("responseJson $responseJson"); + print("updateAvatar:"); + print(responseJson); // 更新本地数据 SpUtil.putString(BytedeskConstants.avatar, avatar!); @@ -376,13 +378,37 @@ class BytedeskUserHttpApi extends BytedeskBaseHttpApi { //将string类型数据 转换为json类型的数据 final responseJson = json.decode(utf8decoder.convert(initResponse.bodyBytes)); - // print("updateDescription $responseJson"); + print("updateDescription:"); + print(responseJson); // 更新本地数据 SpUtil.putString(BytedeskConstants.description, description!); return User.fromJson(responseJson['data']); } + // 一个接口同时设置:昵称、头像、备注 + Future updateProfile(String? nickname, String? avatar, String? description) async { + // + var body = json.encode({"nickname": nickname, "avatar": avatar, "description": description, "client": client}); + // + final initUrl = Uri.http(BytedeskConstants.host, '/api/user/update/visitor/profile'); + final initResponse = + await this.httpClient.post(initUrl, headers: getHeaders(), body: body); + //解决json解析中的乱码问题 + Utf8Decoder utf8decoder = Utf8Decoder(); // fix 中文乱码 + //将string类型数据 转换为json类型的数据 + final responseJson = + json.decode(utf8decoder.convert(initResponse.bodyBytes)); + print("updateProfile:"); + print(responseJson); + // 更新本地数据 + SpUtil.putString(BytedeskConstants.nickname, nickname!); + SpUtil.putString(BytedeskConstants.avatar, avatar!); + SpUtil.putString(BytedeskConstants.description, description!); + + return User.fromJson(responseJson['data']); + } + // 更新性别 Future updateSex(bool? sex) async { // diff --git a/bytedesk_kefu/lib/model/messageProvider.dart b/bytedesk_kefu/lib/model/messageProvider.dart index 8d223b7..e1da2d7 100755 --- a/bytedesk_kefu/lib/model/messageProvider.dart +++ b/bytedesk_kefu/lib/model/messageProvider.dart @@ -1,9 +1,9 @@ import 'dart:async'; -import 'dart:convert'; +// import 'dart:convert'; import 'package:bytedesk_kefu/model/answer.dart'; import 'package:bytedesk_kefu/model/category.dart'; -import 'package:bytedesk_kefu/util/bytedesk_constants.dart'; +// import 'package:bytedesk_kefu/util/bytedesk_constants.dart'; import 'package:bytedesk_kefu/util/bytedesk_utils.dart'; import 'package:path/path.dart'; import 'package:sqflite/sqflite.dart'; diff --git a/bytedesk_kefu/lib/model/thread.dart b/bytedesk_kefu/lib/model/thread.dart index ee29961..b74ce3c 100755 --- a/bytedesk_kefu/lib/model/thread.dart +++ b/bytedesk_kefu/lib/model/thread.dart @@ -1,33 +1,34 @@ import 'package:bytedesk_kefu/util/bytedesk_constants.dart'; import 'package:bytedesk_kefu/util/bytedesk_utils.dart'; import 'package:equatable/equatable.dart'; +import 'package:sp_util/sp_util.dart'; class Thread extends Equatable { // - String? tid; - String? topic; - String? wid; - String? uid; - String? nickname; - String? avatar; - String? content; - String? timestamp; - int? unreadCount; - String? type; + final String? tid; + final String? topic; + final String? wid; + final String? uid; + final String? nickname; + final String? avatar; + final String? content; + final String? timestamp; + final int? unreadCount; + final String? type; // - bool? current; + final bool? current; // - bool? top; - bool? topVisitor; + final bool? top; + final bool? topVisitor; // - bool? nodisturb; - bool? nodisturbVisitor; + final bool? nodisturb; + final bool? nodisturbVisitor; // - bool? unread; - bool? unreadVisitor; + final bool? unread; + final bool? unreadVisitor; // - String? client; - String? currentUid; + final String? client; + final String? currentUid; Thread( {this.tid, @@ -177,8 +178,10 @@ class Thread extends Equatable { tid: json['tid'], topic: json['topic'], uid: json['visitor']['uid'], - nickname: json['visitor']['nickname'], - avatar: json['visitor']['avatar'], + // nickname: json['visitor']['nickname'], + nickname: SpUtil.getString(BytedeskConstants.nickname)!, + // avatar: json['visitor']['avatar'], + avatar: SpUtil.getString(BytedeskConstants.avatar)!, content: json['content'], timestamp: BytedeskUtils.getTimeDuration(json['timestamp']), unreadCount: json['unreadCount'], @@ -262,26 +265,26 @@ class Thread extends Equatable { }; } - Thread.fromMap(Map map) { - tid = map['tid']; - topic = map['topic']; - wid = map['wid']; - uid = map['uid']; - nickname = map['nickname']; - avatar = map['avatar']; - content = map['content']; - timestamp = map['timestamp']; - unreadCount = map['unreadCount']; - type = map['type']; - current = map['current']; - client = map['client']; - top = map['top']; - topVisitor = map['topVisitor']; - nodisturb = map['nodisturb']; - nodisturbVisitor = map['nodisturbVisitor']; - unread = map['unread']; - unreadVisitor = map['unreadVisitor']; - currentUid = map['currentUid']; - client = map['client']; - } + // Thread.fromMap(Map map) { + // tid = map['tid']; + // topic = map['topic']; + // wid = map['wid']; + // uid = map['uid']; + // nickname = map['nickname']; + // avatar = map['avatar']; + // content = map['content']; + // timestamp = map['timestamp']; + // unreadCount = map['unreadCount']; + // type = map['type']; + // current = map['current']; + // client = map['client']; + // top = map['top']; + // topVisitor = map['topVisitor']; + // nodisturb = map['nodisturb']; + // nodisturbVisitor = map['nodisturbVisitor']; + // unread = map['unread']; + // unreadVisitor = map['unreadVisitor']; + // currentUid = map['currentUid']; + // client = map['client']; + // } } diff --git a/bytedesk_kefu/lib/ui/chat/page/chat_im_page.dart b/bytedesk_kefu/lib/ui/chat/page/chat_im_page.dart index 913799d..c90676f 100755 --- a/bytedesk_kefu/lib/ui/chat/page/chat_im_page.dart +++ b/bytedesk_kefu/lib/ui/chat/page/chat_im_page.dart @@ -659,11 +659,11 @@ class _ChatIMPageState extends State print( 'aid ${event.aid}, question ${event.question}, answer ${event.answer}'); // 可以直接将问题和答案插入本地,并显示,但为了服务器保存查询记录,特将请求发送给服务器 - BlocProvider.of(context) - ..add(QueryAnswerEvent( - tid: _currentThread!.tid, - aid: event.aid, - )); + // BlocProvider.of(context) + // ..add(QueryAnswerEvent( + // tid: _currentThread!.tid, + // aid: event.aid, + // )); } }); // 滚动监听, https://learnku.com/articles/30338 diff --git a/bytedesk_kefu/lib/ui/chat/page/chat_kf_page.dart b/bytedesk_kefu/lib/ui/chat/page/chat_kf_page.dart index 405295d..1e9eb8b 100755 --- a/bytedesk_kefu/lib/ui/chat/page/chat_kf_page.dart +++ b/bytedesk_kefu/lib/ui/chat/page/chat_kf_page.dart @@ -198,8 +198,6 @@ class _ChatKFPageState extends State if (state.threadResult.statusCode == 200 || state.threadResult.statusCode == 201) { print('创建新会话'); - // 插入本地 - // _messageProvider.insert(state.threadResult.msg!); // TODO: 参考拼多多,在发送按钮上方显示pop商品信息,用户确认之后才会发送商品信息 // 发送商品信息 if (widget.custom != null && @@ -218,7 +216,6 @@ class _ChatKFPageState extends State // 插入本地 _messageProvider.insert(state.threadResult.msg!); // 加载本地历史消息 - // _getMessages(_page, _size); _appendMessage(state.threadResult.msg!); // 发送商品信息 if (widget.custom != null && @@ -240,7 +237,6 @@ class _ChatKFPageState extends State // 插入本地 _messageProvider.insert(state.threadResult.msg!); // TODO: 加载本地历史消息 - // _getMessages(_page, _size); _appendMessage(state.threadResult.msg!); // 跳转留言页面,TODO: 关闭当前页面? Navigator.of(context) @@ -358,10 +354,8 @@ class _ChatKFPageState extends State // _messageProvider.insert(state.answer!); // _appendMessage(state.answer!); } else if (state is QueryCategorySuccess) { - _messageProvider.insert(state.answer!); _appendMessage(state.answer!); - } else if (state is MessageAnswerSuccess) { // Message queryMessage = state.query!; // queryMessage.isSend = 1; @@ -859,8 +853,7 @@ class _ChatKFPageState extends State appendQueryMessage(event.name); // BlocProvider.of(context) - ..add(QueryCategoryEvent( - tid: _currentThread!.tid, cid: event.cid)); + ..add(QueryCategoryEvent(tid: _currentThread!.tid, cid: event.cid)); } }); // 点击机器人消息 ‘人工客服’ @@ -1109,6 +1102,8 @@ class _ChatKFPageState extends State if (message.status != BytedeskConstants.MESSAGE_STATUS_READ) { // 发送已读回执 if (message.isSend == 0) { + print('message.mid ${message.mid}'); + print('_currentThread ${_currentThread!.tid}'); _bdMqtt.sendReceiptReadMessage(message.mid!, _currentThread!); } } diff --git a/bytedesk_kefu/lib/ui/chat/page/chat_ls_page.dart b/bytedesk_kefu/lib/ui/chat/page/chat_ls_page.dart index 89603e2..cb5d29e 100755 --- a/bytedesk_kefu/lib/ui/chat/page/chat_ls_page.dart +++ b/bytedesk_kefu/lib/ui/chat/page/chat_ls_page.dart @@ -571,11 +571,11 @@ class _ChatLSPageState extends State print( 'aid ${event.aid}, question ${event.question}, answer ${event.answer}'); // 可以直接将问题和答案插入本地,并显示,但为了服务器保存查询记录,特将请求发送给服务器 - BlocProvider.of(context) - ..add(QueryAnswerEvent( - tid: _currentThread!.tid, - aid: event.aid, - )); + // BlocProvider.of(context) + // ..add(QueryAnswerEvent( + // tid: _currentThread!.tid, + // aid: event.aid, + // )); } }); // 滚动监听, https://learnku.com/articles/30338 diff --git a/bytedesk_kefu/lib/ui/widget/expanded_viewport.dart b/bytedesk_kefu/lib/ui/widget/expanded_viewport.dart index c4398a0..8bd423f 100755 --- a/bytedesk_kefu/lib/ui/widget/expanded_viewport.dart +++ b/bytedesk_kefu/lib/ui/widget/expanded_viewport.dart @@ -86,8 +86,8 @@ class _RenderExpandedViewport extends RenderViewport { p = childAfter(p); } - if (expand! != null && size.height > totalLayoutExtent) { - _attemptLayout(expand, size.height, size.width, + if (size.height > totalLayoutExtent) { + _attemptLayout(expand!, size.height, size.width, offset.pixels - frontExtent - (size.height - totalLayoutExtent)); } } diff --git a/bytedesk_kefu/lib/ui/widget/my_button.dart b/bytedesk_kefu/lib/ui/widget/my_button.dart index e8d047a..d4c4ec0 100755 --- a/bytedesk_kefu/lib/ui/widget/my_button.dart +++ b/bytedesk_kefu/lib/ui/widget/my_button.dart @@ -12,9 +12,9 @@ class MyButton extends StatelessWidget { @override Widget build(BuildContext context) { - return FlatButton( + return TextButton( // FlatButton onPressed: onPressed, - textColor: Colors.white, + // textColor: Colors.white, child: Container( height: 48, width: double.infinity, diff --git a/bytedesk_kefu/pubspec.yaml b/bytedesk_kefu/pubspec.yaml index 72aab18..955e271 100644 --- a/bytedesk_kefu/pubspec.yaml +++ b/bytedesk_kefu/pubspec.yaml @@ -1,6 +1,6 @@ name: bytedesk_kefu description: the best app chat sdk in china, you can chat with the agent freely at anytime. the agent can chat with the visitor by web/pc/mac/ios/android client. -version: 1.2.8 +version: 1.2.9 homepage: https://www.weikefu.net environment: