create project
This commit is contained in:
264
lib/utils/app_bridge.dart
Normal file
264
lib/utils/app_bridge.dart
Normal file
@@ -0,0 +1,264 @@
|
||||
import 'dart:convert';
|
||||
// import 'dart:html';
|
||||
import 'dart:html' as html;
|
||||
|
||||
import 'package:js/js.dart';
|
||||
|
||||
// h5交互通知 原生 {type:'enum',data:'所需参数,可无'}
|
||||
enum ToFlutterAppEnum {
|
||||
close('close'),
|
||||
gameExit('gameExit'),
|
||||
createGame('createGame'),
|
||||
wantToPlay('wantToPlay'),
|
||||
gameOver('gameOver'),
|
||||
uploadImage('upload_image'),
|
||||
soundRecord('sound_recording'),
|
||||
toRecharge('toRecharge'),
|
||||
playing('playing'),
|
||||
toRedDiamond('toRedDiamond'),
|
||||
gameType('gameType'),
|
||||
jumpToH5('jumpToH5'),
|
||||
toHomepage('toHomepage'),
|
||||
toMonthCardPay('toMonthCardPay'),
|
||||
|
||||
checkGameState('checkGameState'),
|
||||
closeObserving('closeObserving'),
|
||||
translateRequest('translateRequest'),
|
||||
share('share'),
|
||||
//开播检测
|
||||
checkStartBroadcaster('checkStartBroadcaster'),
|
||||
//直播间发言
|
||||
taskLiveRoomChat('taskLiveRoomChat'),
|
||||
//直播间送礼
|
||||
taskLiveRoomGift('taskLiveRoomGift'),
|
||||
//直播间其他任务 close
|
||||
taskLiveRoomOther('taskLiveRoomOther'),
|
||||
//跳转从业者申请
|
||||
toApplyAdmissionPage('toApplyAdmissionPage'),
|
||||
//直播预约设置
|
||||
shouLiveBookingPicker('shouLiveBookingPicker'),
|
||||
//完善个人信息
|
||||
shouldCompleteProfile('shouldCompleteProfile'),
|
||||
//在直播间或聊天室停留观看n分钟
|
||||
shouldWatchDuration('shouldWatchDuration'),
|
||||
//在直播间或聊天室发送n条公屏消息
|
||||
shouldSendPublicMessage('shouldSendPublicMessage'),
|
||||
//在直播间或聊天室上麦互动n分钟
|
||||
shouldMicInteraction('shouldMicInteraction'),
|
||||
//向任意用户,发送n条信息
|
||||
shouldSendPrivateMessage('shouldSendPrivateMessage'),
|
||||
//发布n条动态
|
||||
shouldPostFeed('shouldPostFeed'),
|
||||
//分享n次直播间或聊天室至任意平台
|
||||
shouldShareRoom('shouldShareRoom'),
|
||||
//佩戴任意装扮
|
||||
shouldWearDecoration('shouldWearDecoration'),
|
||||
//前往语音房
|
||||
shouldGoToVoiceRoom('shouldGoToVoiceRoom'),
|
||||
|
||||
// 定向充值
|
||||
rechargeItem('rechargeItem'),
|
||||
|
||||
///通用交互 别往这下面加,👆🏻加
|
||||
commonInteraction('commonInteraction'),
|
||||
defaultCode('');
|
||||
|
||||
const ToFlutterAppEnum(this.code);
|
||||
final String code;
|
||||
|
||||
static ToFlutterAppEnum? fromCode(String code) {
|
||||
return ToFlutterAppEnum.values.firstWhere(
|
||||
(e) => e.code == code,
|
||||
orElse: () => ToFlutterAppEnum.defaultCode,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// 原生交互通知 h5 {type:'enum',data:'所需参数 '}
|
||||
enum FromFlutterAppEnum {
|
||||
translateResult('translateResult'), //翻译
|
||||
redDiamondRecharge('diamond_recharge'), //钻石充值
|
||||
shareFinished('share_finished'), //分享完成
|
||||
defaultCode('');
|
||||
|
||||
const FromFlutterAppEnum(this.code);
|
||||
final String code;
|
||||
}
|
||||
|
||||
@JS()
|
||||
external void sendMessageToNative(String data);
|
||||
|
||||
class FlutterBridge {
|
||||
static final FlutterBridge instance = FlutterBridge._internal();
|
||||
|
||||
/**
|
||||
* 在需要处理 WebView 消息的地方注册监听器:
|
||||
* FlutterBridge.instance.on(FromJsEnum.translateResult.code, (data) {
|
||||
print("收到来自 WebView 的消息: $data");
|
||||
// 执行你需要的逻辑
|
||||
});
|
||||
使用过需要释放
|
||||
// 取消监听 'translateResult' 类型的消息
|
||||
FlutterBridge.instance.off(FromJsEnum.translateResult.code);
|
||||
* */
|
||||
final _messageListeners = <String, Function(Map<String, dynamic>)>{};
|
||||
var textMap = <String, String>{}; //多语言翻译
|
||||
|
||||
FlutterBridge._internal() {
|
||||
_initListener();
|
||||
}
|
||||
|
||||
// 只初始化一次,监听 WebView 消息
|
||||
void _initListener() {
|
||||
html.window.onMessage.listen((event) {
|
||||
if (event.data is String) {
|
||||
try {
|
||||
final Map<String, dynamic> data = jsonDecode(event.data);
|
||||
final String? type = data['type'];
|
||||
if (type != null && _messageListeners.containsKey(type)) {
|
||||
_messageListeners[type]?.call(data);
|
||||
}
|
||||
print('Invalid message format from Flutter: $type');
|
||||
} catch (e) {
|
||||
print('Invalid message format from Flutter: ${event.data}');
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
final String? type = event.data['type'];
|
||||
if (type != null && _messageListeners.containsKey(type)) {
|
||||
_messageListeners[type]?.call(event.data);
|
||||
}
|
||||
print('Invalid message format from Flutter: $type');
|
||||
} catch (e) {
|
||||
print('Invalid message format from Flutter: ${event.data}');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 注册监听某个 type 的消息
|
||||
void on(String type, Function(Map<String, dynamic>) callback) {
|
||||
if (_messageListeners.containsKey(type)) {
|
||||
print("Listener for '$type' is already registered.");
|
||||
return; // 如果已经注册了这个类型的监听器,就不再重复添加
|
||||
}
|
||||
_messageListeners[type] = callback;
|
||||
print("Listener for '$type' has been registered.");
|
||||
}
|
||||
|
||||
// 取消监听某个 type 的消息
|
||||
void off(String type) {
|
||||
if (!_messageListeners.containsKey(type)) {
|
||||
print("No listener found for '$type'.");
|
||||
return; // 如果没有找到监听器,直接返回
|
||||
}
|
||||
_messageListeners.remove(type);
|
||||
print("Listener for '$type' has been removed.");
|
||||
}
|
||||
|
||||
// 发送消息给 App(通过 WebView 调用 JS 方法)
|
||||
void sendToFlutter(String type, Map<String, dynamic> data) {
|
||||
final dataStr = jsonEncode({'type': type, 'data': data});
|
||||
print('$dataStr');
|
||||
sendMessageToNative(dataStr);
|
||||
}
|
||||
|
||||
void sendToFlutterTest() {
|
||||
// final message = jsonEncode({
|
||||
// 'type': type,
|
||||
// 'data': data,
|
||||
// });
|
||||
// _runJs("receiveMessageFromFlutter($message);");
|
||||
final dataStr = jsonEncode({'type': close, 'data': {}});
|
||||
sendMessageToNative(dataStr);
|
||||
}
|
||||
// 执行 JS 代码
|
||||
// void _runJs(String js) {
|
||||
// final script = ScriptElement()
|
||||
// ..innerHtml = js
|
||||
// ..type = 'application/javascript';
|
||||
// document.body?.append(script);
|
||||
// script.remove();
|
||||
// }
|
||||
|
||||
// 具体封装的常用方法,直接发送消息给 Flutter Web
|
||||
void close() => sendToFlutter(ToFlutterAppEnum.close.code, {});
|
||||
void gameOver() => sendToFlutter(ToFlutterAppEnum.gameOver.code, {});
|
||||
void createGame(String gameId) =>
|
||||
sendToFlutter(ToFlutterAppEnum.createGame.code, {'gameId': gameId});
|
||||
void wantToPlay(String gameId) =>
|
||||
sendToFlutter(ToFlutterAppEnum.wantToPlay.code, {'gameId': gameId});
|
||||
void translateRequest(Map<String, String> data) =>
|
||||
sendToFlutter(ToFlutterAppEnum.translateRequest.code, data);
|
||||
void toRecharge() => sendToFlutter(ToFlutterAppEnum.toRecharge.code, {});
|
||||
void toRedDiamond() => sendToFlutter(ToFlutterAppEnum.toRedDiamond.code, {});
|
||||
void jumpToH5(String path, String title) => sendToFlutter(
|
||||
ToFlutterAppEnum.jumpToH5.code, {'path': path, 'title': title});
|
||||
void toHomepage(String userId) =>
|
||||
sendToFlutter(ToFlutterAppEnum.toHomepage.code, {'userId': userId});
|
||||
void toMonthCardPay(String googleProductId, String iosProductId,
|
||||
{otherUserId = ''}) =>
|
||||
sendToFlutter(ToFlutterAppEnum.toMonthCardPay.code, {
|
||||
'googleProductId': googleProductId,
|
||||
'iosProductId': iosProductId,
|
||||
'otherUserId': otherUserId,
|
||||
});
|
||||
void checkGameState(String gameCode) => sendToFlutter(
|
||||
ToFlutterAppEnum.checkGameState.code, {'gameCode': gameCode});
|
||||
void share({
|
||||
required String activityId,
|
||||
required bool needShareReport,
|
||||
Map<String, dynamic> extraParams = const {},
|
||||
}) =>
|
||||
sendToFlutter(ToFlutterAppEnum.share.code, {
|
||||
"activityId": activityId,
|
||||
"shareReportKey": needShareReport ? "ActivityShared" : "",
|
||||
...extraParams
|
||||
});
|
||||
|
||||
void checkStartBroadcaster() =>
|
||||
sendToFlutter(ToFlutterAppEnum.checkStartBroadcaster.code, {});
|
||||
|
||||
void taskLiveRoomChat() =>
|
||||
sendToFlutter(ToFlutterAppEnum.taskLiveRoomChat.code, {});
|
||||
void taskLiveRoomGift() =>
|
||||
sendToFlutter(ToFlutterAppEnum.taskLiveRoomGift.code, {});
|
||||
void taskLiveRoomOther() =>
|
||||
sendToFlutter(ToFlutterAppEnum.taskLiveRoomOther.code, {});
|
||||
void toApplyAdmissionPage() =>
|
||||
sendToFlutter(ToFlutterAppEnum.toApplyAdmissionPage.code, {});
|
||||
void shouLiveBookingPicker() =>
|
||||
sendToFlutter(ToFlutterAppEnum.shouLiveBookingPicker.code, {});
|
||||
/** 完善个人信息 */
|
||||
void shouldCompleteProfile() =>
|
||||
sendToFlutter(ToFlutterAppEnum.shouldCompleteProfile.code, {});
|
||||
/** 在直播间或聊天室停留观看n分钟 */
|
||||
void shouldWatchDuration() =>
|
||||
sendToFlutter(ToFlutterAppEnum.shouldWatchDuration.code, {});
|
||||
/** 在直播间或聊天室发送n条公屏消息 */
|
||||
void shouldSendPublicMessage() =>
|
||||
sendToFlutter(ToFlutterAppEnum.shouldSendPublicMessage.code, {});
|
||||
/** 在直播间或聊天室上麦互动n分钟 */
|
||||
void shouldMicInteraction() =>
|
||||
sendToFlutter(ToFlutterAppEnum.shouldMicInteraction.code, {});
|
||||
/** 向任意用户,发送n条信息*/
|
||||
void shouldSendPrivateMessage() =>
|
||||
sendToFlutter(ToFlutterAppEnum.shouldSendPrivateMessage.code, {});
|
||||
/** 发布n条动态*/
|
||||
void shouldPostFeed() =>
|
||||
sendToFlutter(ToFlutterAppEnum.shouldPostFeed.code, {});
|
||||
/** 分享n次直播间或聊天室至任意平台 */
|
||||
void shouldShareRoom() =>
|
||||
sendToFlutter(ToFlutterAppEnum.shouldShareRoom.code, {});
|
||||
/** 佩戴任意装扮 */
|
||||
void shouldWearDecoration() =>
|
||||
sendToFlutter(ToFlutterAppEnum.shouldWearDecoration.code, {});
|
||||
/** 前往语音房 */
|
||||
void shouldGoToVoiceRoom() =>
|
||||
sendToFlutter(ToFlutterAppEnum.shouldGoToVoiceRoom.code, {});
|
||||
|
||||
///通用交互 targetId gameId 或者 话题id 或者 分享活动 ShareEvenType.type 或者 其他活动的 url 地址不含 域名部分
|
||||
void commonInteraction(String type, {dynamic targetId}) => sendToFlutter(
|
||||
ToFlutterAppEnum.commonInteraction.code,
|
||||
{'interactionType': type, 'targetId': targetId});
|
||||
}
|
||||
3
lib/web_tools.dart
Normal file
3
lib/web_tools.dart
Normal file
@@ -0,0 +1,3 @@
|
||||
library;
|
||||
|
||||
export 'package:web_tools/utils/app_bridge.dart';
|
||||
Reference in New Issue
Block a user