diff --git a/bytedesk_demo/android/app/build.gradle b/bytedesk_demo/android/app/build.gradle index 7f00281..5afe2f0 100644 --- a/bytedesk_demo/android/app/build.gradle +++ b/bytedesk_demo/android/app/build.gradle @@ -30,7 +30,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.bytedesk.bytedesk_demo" - minSdkVersion 16 + minSdkVersion 19 targetSdkVersion 30 versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/bytedesk_demo/lib/main.dart b/bytedesk_demo/lib/main.dart index 4b34b7a..0e9efdc 100644 --- a/bytedesk_demo/lib/main.dart +++ b/bytedesk_demo/lib/main.dart @@ -10,7 +10,7 @@ import 'package:bytedesk_demo/page/setting_page.dart'; import 'package:bytedesk_demo/page/user_info_page.dart'; import 'package:overlay_support/overlay_support.dart'; import 'package:flutter/material.dart'; -import 'package:vibration/vibration.dart'; +// import 'package:vibration/vibration.dart'; import 'package:audioplayers/audioplayers.dart'; void main() { @@ -41,10 +41,11 @@ class _MyAppState extends State with WidgetsBindingObserver { // String _title = '萝卜丝客服Demo(连接中...)'; AudioCache audioCache = AudioCache(); + // bool _isConnected = false; // @override void initState() { - WidgetsBinding.instance.addObserver(this); + WidgetsBinding.instance?.addObserver(this); super.initState(); _listener(); } @@ -130,6 +131,16 @@ class _MyAppState extends State with WidgetsBindingObserver { ) ], ).toList()), + // floatingActionButton: FloatingActionButton( + // onPressed: () { + // // 第二步:到 客服管理->技能组-有一列 ‘唯一ID(wId)’, 默认设置工作组wid + // // 说明:一个技能组可以分配多个客服,访客会按照一定的规则分配给组内的各个客服账号 + // String _workGroupWid = "201807171659201"; // 默认人工 + // BytedeskKefu.startWorkGroupChat(context, _workGroupWid, "技能组客服-默认人工"); + // }, + // tooltip: '客服', + // child: Icon(Icons.message), + // ), // Th ); } @@ -157,7 +168,7 @@ class _MyAppState extends State with WidgetsBindingObserver { // print('receive message:' + event.message.content); // 1. 首先将example/assets/audio文件夹中文件拷贝到自己项目;2.在自己项目pubspec.yaml中添加assets // 播放发送消息提示音 - if (BytedeskKefu.getPlayAudioOnSendMessage() && + if (BytedeskKefu.getPlayAudioOnSendMessage()! && event.message.isSend == 1) { print('play send audio'); // 修改为自己项目中语音文件路径 @@ -168,49 +179,53 @@ class _MyAppState extends State with WidgetsBindingObserver { return; } // 接收消息播放提示音 - if (BytedeskKefu.getPlayAudioOnReceiveMessage() && + if (BytedeskKefu.getPlayAudioOnReceiveMessage()! && event.message.isSend == 0) { print('play receive audio'); audioCache.play('audio/bytedesk_dingdong.wav'); } // 振动 - if (BytedeskKefu.getVibrateOnReceiveMessage() && + if (BytedeskKefu.getVibrateOnReceiveMessage()! && event.message.isSend == 0) { print('should vibrate'); vibrate(); } if (event.message.type == BytedeskConstants.MESSAGE_TYPE_TEXT) { - print('文字消息: ' + event.message.content); + print('文字消息: ' + event.message.content!); // 判断当前是否客服页面,如否,则显示顶部通知栏 - if (!BytedeskUtils.isCurrentChatKfPage()) { + if (!BytedeskUtils.isCurrentChatKfPage()!) { // https://github.com/boyan01/overlay_support showOverlayNotification((context) { return MessageNotification( - avatar: event.message.user.avatar, - nickname: event.message.user.nickname, - content: event.message.content, + avatar: event.message.user!.avatar!, + nickname: event.message.user!.nickname!, + content: event.message.content!, onReply: () { // - OverlaySupportEntry.of(context).dismiss(); + OverlaySupportEntry.of(context)!.dismiss(); // 进入客服页面,支持自定义页面标题 - BytedeskKefu.startChatThread(context, event.message.thread, + BytedeskKefu.startChatThread(context, event.message.thread!, title: '客服会话'); }, ); }, duration: Duration(milliseconds: 4000)); } } else if (event.message.type == BytedeskConstants.MESSAGE_TYPE_IMAGE) { - print('图片消息:' + event.message.imageUrl); + print('图片消息:' + event.message.imageUrl!); } else if (event.message.type == BytedeskConstants.MESSAGE_TYPE_VOICE) { - print('语音消息:' + event.message.voiceUrl); + print('语音消息:' + event.message.voiceUrl!); } else if (event.message.type == BytedeskConstants.MESSAGE_TYPE_VIDEO) { - print('视频消息:' + event.message.videoUrl); + print('视频消息:' + event.message.videoUrl!); } else if (event.message.type == BytedeskConstants.MESSAGE_TYPE_FILE) { - print('文件消息:' + event.message.fileUrl); + print('文件消息:' + event.message.fileUrl!); } else { print('其他类型消息'); } }); + // token过期 + bytedeskEventBus.on().listen((event) { + // 执行重新初始化 + }); } // @override @@ -232,14 +247,15 @@ class _MyAppState extends State with WidgetsBindingObserver { // 振动 void vibrate() async { - if (await Vibration.hasVibrator()) { - Vibration.vibrate(); - } + // if (await Vibration.hasVibrator()) { + // Vibration.vibrate(); + // } } @override void dispose() { - WidgetsBinding.instance.removeObserver(this); + WidgetsBinding.instance?.removeObserver(this); super.dispose(); + // audioCache? } } diff --git a/bytedesk_demo/lib/notification/custom_animation.dart b/bytedesk_demo/lib/notification/custom_animation.dart index abe84df..b6d1f03 100755 --- a/bytedesk_demo/lib/notification/custom_animation.dart +++ b/bytedesk_demo/lib/notification/custom_animation.dart @@ -3,21 +3,21 @@ import 'ios_toast.dart'; /// Example to show how to popup overlay with custom animation. class CustomAnimationToast extends StatelessWidget { - final double value; + final double? value; static final Tween tweenOffset = Tween(begin: Offset(0, 40), end: Offset(0, 0)); static final Tween tweenOpacity = Tween(begin: 0, end: 1); - const CustomAnimationToast({Key key, @required this.value}) : super(key: key); + const CustomAnimationToast({Key? key, @required this.value}) : super(key: key); @override Widget build(BuildContext context) { return Transform.translate( - offset: tweenOffset.transform(value), + offset: tweenOffset.transform(value!), child: Opacity( child: IosStyleToast(), - opacity: tweenOpacity.transform(value), + opacity: tweenOpacity.transform(value!), ), ); } diff --git a/bytedesk_demo/lib/notification/custom_notification.dart b/bytedesk_demo/lib/notification/custom_notification.dart index 168caf9..8a0dede 100755 --- a/bytedesk_demo/lib/notification/custom_notification.dart +++ b/bytedesk_demo/lib/notification/custom_notification.dart @@ -2,13 +2,13 @@ import 'package:flutter/material.dart'; class MessageNotification extends StatelessWidget { // - final VoidCallback onReply; - final String avatar; - final String nickname; - final String content; + final VoidCallback? onReply; + final String? avatar; + final String? nickname; + final String? content; const MessageNotification({ - Key key, + Key? key, @required this.onReply, @required this.avatar, @required this.nickname, @@ -23,13 +23,13 @@ class MessageNotification extends StatelessWidget { child: ListTile( leading: SizedBox.fromSize( size: const Size(40, 40), - child: ClipOval(child: Image.network(avatar))), - title: Text(nickname), - subtitle: Text(content), + child: ClipOval(child: Image.network(avatar!))), + title: Text(nickname!), + subtitle: Text(content!), trailing: IconButton( icon: Icon(Icons.reply), onPressed: () { - if (onReply != null) onReply(); + if (onReply != null) onReply!(); }), ), ), diff --git a/bytedesk_demo/lib/notification/ios_toast.dart b/bytedesk_demo/lib/notification/ios_toast.dart index 00929b3..2cbb76c 100755 --- a/bytedesk_demo/lib/notification/ios_toast.dart +++ b/bytedesk_demo/lib/notification/ios_toast.dart @@ -5,7 +5,7 @@ class IosStyleToast extends StatelessWidget { Widget build(BuildContext context) { return SafeArea( child: DefaultTextStyle( - style: Theme.of(context).textTheme.bodyText2.copyWith(color: Colors.white), + style: Theme.of(context).textTheme.bodyText2!.copyWith(color: Colors.white), child: Padding( padding: const EdgeInsets.all(16), child: Center( diff --git a/bytedesk_demo/lib/page/chat_type_page.dart b/bytedesk_demo/lib/page/chat_type_page.dart index 85e8688..0d28bbe 100755 --- a/bytedesk_demo/lib/page/chat_type_page.dart +++ b/bytedesk_demo/lib/page/chat_type_page.dart @@ -6,7 +6,7 @@ import 'package:flutter/material.dart'; // 多种客服对话类型列表页面 class ChatTypePage extends StatefulWidget { - ChatTypePage({Key key}) : super(key: key); + ChatTypePage({Key? key}) : super(key: key); @override _ChatTypePageState createState() => _ChatTypePageState(); diff --git a/bytedesk_demo/lib/page/history_thread_page.dart b/bytedesk_demo/lib/page/history_thread_page.dart index 48ed2f1..edfabac 100755 --- a/bytedesk_demo/lib/page/history_thread_page.dart +++ b/bytedesk_demo/lib/page/history_thread_page.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; // 历史会话列表 class HistoryThreadPage extends StatefulWidget { - HistoryThreadPage({Key key}) : super(key: key); + HistoryThreadPage({Key? key}) : super(key: key); @override _HistoryThreadPageState createState() => _HistoryThreadPageState(); @@ -34,7 +34,7 @@ class _HistoryThreadPageState extends State { child: ListView.builder( padding: EdgeInsets.all(8.0), itemBuilder: (_, int index) => ListTile( - leading: Image.network(_historyThreadList[index].avatar), + leading: Image.network(_historyThreadList[index].avatar!), title: Text('${_historyThreadList[index].nickname}, ${_historyThreadList[index].timestamp}'), subtitle: Text('${_historyThreadList[index].content}'), onTap: () { diff --git a/bytedesk_demo/lib/page/online_status_page.dart b/bytedesk_demo/lib/page/online_status_page.dart index 3bf8af8..59f7c61 100755 --- a/bytedesk_demo/lib/page/online_status_page.dart +++ b/bytedesk_demo/lib/page/online_status_page.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; // 查询技能组和指定客服账号的在线状态 class OnlineStatusPage extends StatefulWidget { - OnlineStatusPage({Key key}) : super(key: key); + OnlineStatusPage({Key? key}) : super(key: key); @override _OnlineStatusPageState createState() => _OnlineStatusPageState(); diff --git a/bytedesk_demo/lib/page/setting_page.dart b/bytedesk_demo/lib/page/setting_page.dart index 6eac97c..d189717 100755 --- a/bytedesk_demo/lib/page/setting_page.dart +++ b/bytedesk_demo/lib/page/setting_page.dart @@ -4,7 +4,7 @@ import 'package:list_tile_switch/list_tile_switch.dart'; // 消息声音、振动设置页面 class SettingPage extends StatefulWidget { - SettingPage({Key key}) : super(key: key); + SettingPage({Key? key}) : super(key: key); @override _SettingPageState createState() => _SettingPageState(); @@ -17,9 +17,9 @@ class _SettingPageState extends State { // @override void initState() { - _playAudioOnSendMessage = BytedeskKefu.getPlayAudioOnSendMessage(); - _playAudioOnReceiveMessage = BytedeskKefu.getPlayAudioOnReceiveMessage(); - _vibrateOnReceiveMessage = BytedeskKefu.getVibrateOnReceiveMessage(); + _playAudioOnSendMessage = BytedeskKefu.getPlayAudioOnSendMessage()!; + _playAudioOnReceiveMessage = BytedeskKefu.getPlayAudioOnReceiveMessage()!; + _vibrateOnReceiveMessage = BytedeskKefu.getVibrateOnReceiveMessage()!; super.initState(); } diff --git a/bytedesk_demo/lib/page/user_info_page.dart b/bytedesk_demo/lib/page/user_info_page.dart index d5fed3c..5af3308 100755 --- a/bytedesk_demo/lib/page/user_info_page.dart +++ b/bytedesk_demo/lib/page/user_info_page.dart @@ -6,7 +6,7 @@ import 'package:fluttertoast/fluttertoast.dart'; // 需要首先调用anonymousLogin之后,再调用此接口 // 自定义用户信息接口-对接APP用户信息 class UserInfoPage extends StatefulWidget { - UserInfoPage({Key key}) : super(key: key); + UserInfoPage({Key? key}) : super(key: key); @override _UserInfoPageState createState() => _UserInfoPageState(); @@ -34,7 +34,7 @@ class _UserInfoPageState extends State { tiles: [ ListTile( title: Text('设置昵称(见代码)'), - subtitle: Text(_nickname ?? ''), + subtitle: Text(_nickname), onTap: () { // _setNickname(); @@ -42,7 +42,7 @@ class _UserInfoPageState extends State { ), ListTile( leading: Image.network( - _avatar ?? BytedeskConstants.DEFAULT_AVATA, + _avatar, height: 30, width: 30, ), @@ -61,8 +61,8 @@ class _UserInfoPageState extends State { // 查询当前用户信息:昵称、头像 BytedeskKefu.getProfile().then((user) => { setState(() { - _nickname = user.nickname; - _avatar = user.avatar; + _nickname = user.nickname!; + _avatar = user.avatar!; }) }); } diff --git a/bytedesk_demo/pubspec.yaml b/bytedesk_demo/pubspec.yaml index 13db50e..130b1c2 100644 --- a/bytedesk_demo/pubspec.yaml +++ b/bytedesk_demo/pubspec.yaml @@ -15,10 +15,10 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 +version: 1.0.0+10 environment: - sdk: ">=2.7.0 <3.0.0" + sdk: ">=2.12.0 <3.0.0" dependencies: flutter: @@ -28,19 +28,19 @@ dependencies: # https://pub.dev/packages/event_bus event_bus: ^2.0.0 # toast https://pub.dev/packages/fluttertoast - fluttertoast: ^8.0.7 + fluttertoast: ^8.0.8 # 消息设置switch https://pub.dev/packages/list_tile_switch list_tile_switch: ^1.0.0 # 应用内-顶部通知栏 https://pub.dev/packages/overlay_support/ overlay_support: ^1.2.1 # 播放提示音 https://pub.dev/packages/audioplayers - audioplayers: ^0.19.1 + audioplayers: ^0.20.1 # 振动 https://pub.dev/packages/vibration # 针对报错fatal error: 'vibration/vibration-Swift.h' file not found #import , ld: library not found for -lvibration # 请在ios/Podfile中添加:use_frameworks! vibration: ^1.7.3 # 在线客服 https://pub.dev/packages/bytedesk_kefu - bytedesk_kefu: ^1.0.6 + bytedesk_kefu: ^1.1.1 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. diff --git a/bytedesk_demo/windows/flutter/generated_plugin_registrant.cc b/bytedesk_demo/windows/flutter/generated_plugin_registrant.cc index cffaf8f..50989f9 100644 --- a/bytedesk_demo/windows/flutter/generated_plugin_registrant.cc +++ b/bytedesk_demo/windows/flutter/generated_plugin_registrant.cc @@ -2,6 +2,8 @@ // Generated file. Do not edit. // +// clang-format off + #include "generated_plugin_registrant.h" #include diff --git a/bytedesk_demo/windows/flutter/generated_plugin_registrant.h b/bytedesk_demo/windows/flutter/generated_plugin_registrant.h index 9846246..dc139d8 100644 --- a/bytedesk_demo/windows/flutter/generated_plugin_registrant.h +++ b/bytedesk_demo/windows/flutter/generated_plugin_registrant.h @@ -2,6 +2,8 @@ // Generated file. Do not edit. // +// clang-format off + #ifndef GENERATED_PLUGIN_REGISTRANT_ #define GENERATED_PLUGIN_REGISTRANT_