web_tools/lib/utils/app_bridge.dart
2025-12-13 17:01:32 +08:00

301 lines
11 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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,
);
}
}
//通用交互
enum WebInteractionType {
taskKeyWatchLive('TaskKeyWatchLive'), // 观看直播
taskKeyCollectRoom('TaskKeyCollectRoom'), // 收藏房间
taskKeyFollowUser('TaskKeyFollowUser'), // 关注主播
taskKeySendRoomMessage('TaskKeySendRoomMessage'), // 发送房间消息
taskKeySendGift('TaskKeySendGift'), // 赠送礼物
taskKeySendGiftId('TaskKeySendGiftId'), // 赠送指定礼物
taskKeySendBackpackGift('TaskKeySendBackpackGift'), // 赠送礼物到背包
taskKeyPlayGame('TaskKeyPlayGame'), // 玩游戏
taskKeySendPrivateMessage('TaskKeySendPrivateMessage'), // 发送私聊消息
taskKeyShareActivity('TaskKeyShareActivity'), // 分享活动
taskKeyTimelineTopic('TaskKeyTimelineTopic'), // 参与动态话题
taskKeyLikeTimeline('TaskKeyLikeTimeline'), // 点赞动态
taskKeyReplayTimeline('TaskKeyReplayTimeline'), // 评论动态
taskKeySignIn('TaskKeySignIn'), // 签到
taskKeyOtherPage('TaskKeyOtherPage'), // 其他页面
taskKeyMineBackpack('TaskKeyMineBackpack'), // 我的装扮背包页面(或者是称号)
taskKeyMineWallet('TaskKeyMineWallet'), // 我的钱包页面
unknown('unknown'),
;
const WebInteractionType(
this.code,
);
final String code; //服务端 key
factory WebInteractionType.fromCode(String? code) => values.firstWhere(
(element) => element.code == code,
orElse: () => WebInteractionType.unknown,
);
}
// 原生交互通知 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, {});
/** 通用封装方法 无需传参可直接调用需要传参需要调用sendToFlutter*/
void commonInteraction(Map<String, dynamic> data) =>
sendToFlutter(ToFlutterAppEnum.commonInteraction.code, data);
}