master
jackning 3 years ago
parent c328d98721
commit ca0dd47e6d

@ -30,7 +30,7 @@ android {
defaultConfig { defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.bytedesk.bytedesk_demo" applicationId "com.bytedesk.bytedesk_demo"
minSdkVersion 16 minSdkVersion 19
targetSdkVersion 30 targetSdkVersion 30
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName

@ -10,7 +10,7 @@ import 'package:bytedesk_demo/page/setting_page.dart';
import 'package:bytedesk_demo/page/user_info_page.dart'; import 'package:bytedesk_demo/page/user_info_page.dart';
import 'package:overlay_support/overlay_support.dart'; import 'package:overlay_support/overlay_support.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:vibration/vibration.dart'; // import 'package:vibration/vibration.dart';
import 'package:audioplayers/audioplayers.dart'; import 'package:audioplayers/audioplayers.dart';
void main() { void main() {
@ -41,10 +41,11 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
// //
String _title = '萝卜丝客服Demo(连接中...)'; String _title = '萝卜丝客服Demo(连接中...)';
AudioCache audioCache = AudioCache(); AudioCache audioCache = AudioCache();
// bool _isConnected = false;
// //
@override @override
void initState() { void initState() {
WidgetsBinding.instance.addObserver(this); WidgetsBinding.instance?.addObserver(this);
super.initState(); super.initState();
_listener(); _listener();
} }
@ -130,6 +131,16 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
) )
], ],
).toList()), ).toList()),
// floatingActionButton: FloatingActionButton(
// onPressed: () {
// // ->- IDwId, wid
// // 访
// String _workGroupWid = "201807171659201"; //
// BytedeskKefu.startWorkGroupChat(context, _workGroupWid, "技能组客服-默认人工");
// },
// tooltip: '客服',
// child: Icon(Icons.message),
// ), // Th
); );
} }
@ -157,7 +168,7 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
// print('receive message:' + event.message.content); // print('receive message:' + event.message.content);
// 1. example/assets/audio2.pubspec.yamlassets // 1. example/assets/audio2.pubspec.yamlassets
// //
if (BytedeskKefu.getPlayAudioOnSendMessage() && if (BytedeskKefu.getPlayAudioOnSendMessage()! &&
event.message.isSend == 1) { event.message.isSend == 1) {
print('play send audio'); print('play send audio');
// //
@ -168,49 +179,53 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
return; return;
} }
// //
if (BytedeskKefu.getPlayAudioOnReceiveMessage() && if (BytedeskKefu.getPlayAudioOnReceiveMessage()! &&
event.message.isSend == 0) { event.message.isSend == 0) {
print('play receive audio'); print('play receive audio');
audioCache.play('audio/bytedesk_dingdong.wav'); audioCache.play('audio/bytedesk_dingdong.wav');
} }
// //
if (BytedeskKefu.getVibrateOnReceiveMessage() && if (BytedeskKefu.getVibrateOnReceiveMessage()! &&
event.message.isSend == 0) { event.message.isSend == 0) {
print('should vibrate'); print('should vibrate');
vibrate(); vibrate();
} }
if (event.message.type == BytedeskConstants.MESSAGE_TYPE_TEXT) { 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 // https://github.com/boyan01/overlay_support
showOverlayNotification((context) { showOverlayNotification((context) {
return MessageNotification( return MessageNotification(
avatar: event.message.user.avatar, avatar: event.message.user!.avatar!,
nickname: event.message.user.nickname, nickname: event.message.user!.nickname!,
content: event.message.content, content: event.message.content!,
onReply: () { onReply: () {
// //
OverlaySupportEntry.of(context).dismiss(); OverlaySupportEntry.of(context)!.dismiss();
// //
BytedeskKefu.startChatThread(context, event.message.thread, BytedeskKefu.startChatThread(context, event.message.thread!,
title: '客服会话'); title: '客服会话');
}, },
); );
}, duration: Duration(milliseconds: 4000)); }, duration: Duration(milliseconds: 4000));
} }
} else if (event.message.type == BytedeskConstants.MESSAGE_TYPE_IMAGE) { } 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) { } 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) { } 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) { } else if (event.message.type == BytedeskConstants.MESSAGE_TYPE_FILE) {
print('文件消息:' + event.message.fileUrl); print('文件消息:' + event.message.fileUrl!);
} else { } else {
print('其他类型消息'); print('其他类型消息');
} }
}); });
// token
bytedeskEventBus.on<InvalidTokenEventBus>().listen((event) {
//
});
} }
// @override // @override
@ -232,14 +247,15 @@ class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
// //
void vibrate() async { void vibrate() async {
if (await Vibration.hasVibrator()) { // if (await Vibration.hasVibrator()) {
Vibration.vibrate(); // Vibration.vibrate();
} // }
} }
@override @override
void dispose() { void dispose() {
WidgetsBinding.instance.removeObserver(this); WidgetsBinding.instance?.removeObserver(this);
super.dispose(); super.dispose();
// audioCache?
} }
} }

@ -3,21 +3,21 @@ import 'ios_toast.dart';
/// Example to show how to popup overlay with custom animation. /// Example to show how to popup overlay with custom animation.
class CustomAnimationToast extends StatelessWidget { class CustomAnimationToast extends StatelessWidget {
final double value; final double? value;
static final Tween<Offset> tweenOffset = Tween<Offset>(begin: Offset(0, 40), end: Offset(0, 0)); static final Tween<Offset> tweenOffset = Tween<Offset>(begin: Offset(0, 40), end: Offset(0, 0));
static final Tween<double> tweenOpacity = Tween<double>(begin: 0, end: 1); static final Tween<double> tweenOpacity = Tween<double>(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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Transform.translate( return Transform.translate(
offset: tweenOffset.transform(value), offset: tweenOffset.transform(value!),
child: Opacity( child: Opacity(
child: IosStyleToast(), child: IosStyleToast(),
opacity: tweenOpacity.transform(value), opacity: tweenOpacity.transform(value!),
), ),
); );
} }

@ -2,13 +2,13 @@ import 'package:flutter/material.dart';
class MessageNotification extends StatelessWidget { class MessageNotification extends StatelessWidget {
// //
final VoidCallback onReply; final VoidCallback? onReply;
final String avatar; final String? avatar;
final String nickname; final String? nickname;
final String content; final String? content;
const MessageNotification({ const MessageNotification({
Key key, Key? key,
@required this.onReply, @required this.onReply,
@required this.avatar, @required this.avatar,
@required this.nickname, @required this.nickname,
@ -23,13 +23,13 @@ class MessageNotification extends StatelessWidget {
child: ListTile( child: ListTile(
leading: SizedBox.fromSize( leading: SizedBox.fromSize(
size: const Size(40, 40), size: const Size(40, 40),
child: ClipOval(child: Image.network(avatar))), child: ClipOval(child: Image.network(avatar!))),
title: Text(nickname), title: Text(nickname!),
subtitle: Text(content), subtitle: Text(content!),
trailing: IconButton( trailing: IconButton(
icon: Icon(Icons.reply), icon: Icon(Icons.reply),
onPressed: () { onPressed: () {
if (onReply != null) onReply(); if (onReply != null) onReply!();
}), }),
), ),
), ),

@ -5,7 +5,7 @@ class IosStyleToast extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SafeArea( return SafeArea(
child: DefaultTextStyle( child: DefaultTextStyle(
style: Theme.of(context).textTheme.bodyText2.copyWith(color: Colors.white), style: Theme.of(context).textTheme.bodyText2!.copyWith(color: Colors.white),
child: Padding( child: Padding(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: Center( child: Center(

@ -6,7 +6,7 @@ import 'package:flutter/material.dart';
// //
class ChatTypePage extends StatefulWidget { class ChatTypePage extends StatefulWidget {
ChatTypePage({Key key}) : super(key: key); ChatTypePage({Key? key}) : super(key: key);
@override @override
_ChatTypePageState createState() => _ChatTypePageState(); _ChatTypePageState createState() => _ChatTypePageState();

@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
// //
class HistoryThreadPage extends StatefulWidget { class HistoryThreadPage extends StatefulWidget {
HistoryThreadPage({Key key}) : super(key: key); HistoryThreadPage({Key? key}) : super(key: key);
@override @override
_HistoryThreadPageState createState() => _HistoryThreadPageState(); _HistoryThreadPageState createState() => _HistoryThreadPageState();
@ -34,7 +34,7 @@ class _HistoryThreadPageState extends State<HistoryThreadPage> {
child: ListView.builder( child: ListView.builder(
padding: EdgeInsets.all(8.0), padding: EdgeInsets.all(8.0),
itemBuilder: (_, int index) => ListTile( itemBuilder: (_, int index) => ListTile(
leading: Image.network(_historyThreadList[index].avatar), leading: Image.network(_historyThreadList[index].avatar!),
title: Text('${_historyThreadList[index].nickname}, ${_historyThreadList[index].timestamp}'), title: Text('${_historyThreadList[index].nickname}, ${_historyThreadList[index].timestamp}'),
subtitle: Text('${_historyThreadList[index].content}'), subtitle: Text('${_historyThreadList[index].content}'),
onTap: () { onTap: () {

@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
// 线 // 线
class OnlineStatusPage extends StatefulWidget { class OnlineStatusPage extends StatefulWidget {
OnlineStatusPage({Key key}) : super(key: key); OnlineStatusPage({Key? key}) : super(key: key);
@override @override
_OnlineStatusPageState createState() => _OnlineStatusPageState(); _OnlineStatusPageState createState() => _OnlineStatusPageState();

@ -4,7 +4,7 @@ import 'package:list_tile_switch/list_tile_switch.dart';
// //
class SettingPage extends StatefulWidget { class SettingPage extends StatefulWidget {
SettingPage({Key key}) : super(key: key); SettingPage({Key? key}) : super(key: key);
@override @override
_SettingPageState createState() => _SettingPageState(); _SettingPageState createState() => _SettingPageState();
@ -17,9 +17,9 @@ class _SettingPageState extends State<SettingPage> {
// //
@override @override
void initState() { void initState() {
_playAudioOnSendMessage = BytedeskKefu.getPlayAudioOnSendMessage(); _playAudioOnSendMessage = BytedeskKefu.getPlayAudioOnSendMessage()!;
_playAudioOnReceiveMessage = BytedeskKefu.getPlayAudioOnReceiveMessage(); _playAudioOnReceiveMessage = BytedeskKefu.getPlayAudioOnReceiveMessage()!;
_vibrateOnReceiveMessage = BytedeskKefu.getVibrateOnReceiveMessage(); _vibrateOnReceiveMessage = BytedeskKefu.getVibrateOnReceiveMessage()!;
super.initState(); super.initState();
} }

@ -6,7 +6,7 @@ import 'package:fluttertoast/fluttertoast.dart';
// anonymousLogin // anonymousLogin
// -APP // -APP
class UserInfoPage extends StatefulWidget { class UserInfoPage extends StatefulWidget {
UserInfoPage({Key key}) : super(key: key); UserInfoPage({Key? key}) : super(key: key);
@override @override
_UserInfoPageState createState() => _UserInfoPageState(); _UserInfoPageState createState() => _UserInfoPageState();
@ -34,7 +34,7 @@ class _UserInfoPageState extends State<UserInfoPage> {
tiles: [ tiles: [
ListTile( ListTile(
title: Text('设置昵称(见代码)'), title: Text('设置昵称(见代码)'),
subtitle: Text(_nickname ?? ''), subtitle: Text(_nickname),
onTap: () { onTap: () {
// //
_setNickname(); _setNickname();
@ -42,7 +42,7 @@ class _UserInfoPageState extends State<UserInfoPage> {
), ),
ListTile( ListTile(
leading: Image.network( leading: Image.network(
_avatar ?? BytedeskConstants.DEFAULT_AVATA, _avatar,
height: 30, height: 30,
width: 30, width: 30,
), ),
@ -61,8 +61,8 @@ class _UserInfoPageState extends State<UserInfoPage> {
// //
BytedeskKefu.getProfile().then((user) => { BytedeskKefu.getProfile().then((user) => {
setState(() { setState(() {
_nickname = user.nickname; _nickname = user.nickname!;
_avatar = user.avatar; _avatar = user.avatar!;
}) })
}); });
} }

@ -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. # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at # Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1 version: 1.0.0+10
environment: environment:
sdk: ">=2.7.0 <3.0.0" sdk: ">=2.12.0 <3.0.0"
dependencies: dependencies:
flutter: flutter:
@ -28,19 +28,19 @@ dependencies:
# https://pub.dev/packages/event_bus # https://pub.dev/packages/event_bus
event_bus: ^2.0.0 event_bus: ^2.0.0
# toast https://pub.dev/packages/fluttertoast # toast https://pub.dev/packages/fluttertoast
fluttertoast: ^8.0.7 fluttertoast: ^8.0.8
# 消息设置switch https://pub.dev/packages/list_tile_switch # 消息设置switch https://pub.dev/packages/list_tile_switch
list_tile_switch: ^1.0.0 list_tile_switch: ^1.0.0
# 应用内-顶部通知栏 https://pub.dev/packages/overlay_support/ # 应用内-顶部通知栏 https://pub.dev/packages/overlay_support/
overlay_support: ^1.2.1 overlay_support: ^1.2.1
# 播放提示音 https://pub.dev/packages/audioplayers # 播放提示音 https://pub.dev/packages/audioplayers
audioplayers: ^0.19.1 audioplayers: ^0.20.1
# 振动 https://pub.dev/packages/vibration # 振动 https://pub.dev/packages/vibration
# 针对报错fatal error: 'vibration/vibration-Swift.h' file not found #import <vibration/vibration-Swift.h>, ld: library not found for -lvibration # 针对报错fatal error: 'vibration/vibration-Swift.h' file not found #import <vibration/vibration-Swift.h>, ld: library not found for -lvibration
# 请在ios/Podfile中添加use_frameworks! # 请在ios/Podfile中添加use_frameworks!
vibration: ^1.7.3 vibration: ^1.7.3
# 在线客服 https://pub.dev/packages/bytedesk_kefu # 在线客服 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. # The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.

@ -2,6 +2,8 @@
// Generated file. Do not edit. // Generated file. Do not edit.
// //
// clang-format off
#include "generated_plugin_registrant.h" #include "generated_plugin_registrant.h"
#include <bytedesk_kefu/bytedesk_kefu_plugin.h> #include <bytedesk_kefu/bytedesk_kefu_plugin.h>

@ -2,6 +2,8 @@
// Generated file. Do not edit. // Generated file. Do not edit.
// //
// clang-format off
#ifndef GENERATED_PLUGIN_REGISTRANT_ #ifndef GENERATED_PLUGIN_REGISTRANT_
#define GENERATED_PLUGIN_REGISTRANT_ #define GENERATED_PLUGIN_REGISTRANT_

Loading…
Cancel
Save