Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8924ee3ed | ||
|
|
9545928a35 | ||
|
|
95e5c65709 | ||
|
|
d6d83fbc46 | ||
|
|
63b38704dc | ||
|
|
587af2c22a | ||
|
|
cbd3d8eff8 | ||
|
|
20f557c668 | ||
|
|
e54e11fef1 | ||
|
|
d71234da78 |
141
README.md
141
README.md
@@ -51,18 +51,6 @@ bridge.share(
|
||||
);
|
||||
```
|
||||
|
||||
### 监听来自 Flutter 的消息
|
||||
|
||||
```dart
|
||||
// 注册监听器
|
||||
FlutterBridge.instance.on(FromFlutterAppEnum.translateResult.code, (data) {
|
||||
print("收到翻译结果: ${data['data']}");
|
||||
// 处理翻译结果
|
||||
});
|
||||
|
||||
// 使用完毕后记得取消监听
|
||||
FlutterBridge.instance.off(FromFlutterAppEnum.translateResult.code);
|
||||
```
|
||||
|
||||
## API 文档
|
||||
|
||||
@@ -76,28 +64,42 @@ FlutterBridge.instance.off(FromFlutterAppEnum.translateResult.code);
|
||||
final bridge = FlutterBridge.instance;
|
||||
```
|
||||
|
||||
#### 消息监听方法
|
||||
|
||||
### 监听来自 Flutter 的消息 (支持一对多监听)
|
||||
### 不走队列。这是“广播”模式
|
||||
##### `on(String type, Function(Map<String, dynamic>) callback)`
|
||||
|
||||
注册一个消息监听器。
|
||||
注册一个消息监听器。现在支持为同一 `type` 注册多个监听器。
|
||||
|
||||
- `type`: 消息类型(使用 `FromFlutterAppEnum` 中的 code)
|
||||
- `callback`: 回调函数,接收消息数据
|
||||
|
||||
**返回** `VoidCallback`: 调用此函数可以精确地移除当前注册的这个监听器。
|
||||
|
||||
```dart
|
||||
bridge.on(FromFlutterAppEnum.translateResult.code, (data) {
|
||||
// 处理消息
|
||||
// 注册第一个监听器
|
||||
final cancelListener1 = bridge.on(FromFlutterAppEnum.translateResult.code, (data) {
|
||||
print("监听器1收到翻译结果: ${data['data']}");
|
||||
});
|
||||
|
||||
// 注册第二个监听器
|
||||
final cancelListener2 = bridge.on(FromFlutterAppEnum.translateResult.code, (data) {
|
||||
print("监听器2收到翻译结果: ${data['data']}");
|
||||
});
|
||||
|
||||
// 当不再需要第一个监听器时,调用其返回的函数
|
||||
cancelListener1.call();// 仅移除监听器1
|
||||
// 当不再需要第二个监听器时,调用其返回的函数
|
||||
cancelListener2.call();// 仅移除监听器2
|
||||
```
|
||||
|
||||
##### `off(String type)`
|
||||
|
||||
取消注册消息监听器。
|
||||
取消注册某个 `type` 的【所有】消息监听器。此方法主要用于需要一次性清空所有同类型监听的场景。
|
||||
|
||||
- `type`: 要取消监听的消息类型
|
||||
- `type`: 要取消监听的【所有】消息类型
|
||||
|
||||
```dart
|
||||
// 警告:这将移除 FromFlutterAppEnum.translateResult.code 对应的所有监听器
|
||||
bridge.off(FromFlutterAppEnum.translateResult.code);
|
||||
```
|
||||
|
||||
@@ -178,14 +180,22 @@ bridge.share(
|
||||
);
|
||||
```
|
||||
|
||||
##### 翻译功能
|
||||
|
||||
##### 翻译功能(发送翻译消息+监听返回结果)
|
||||
##### 只有当你调用 sendRequest 方法时,才会走队列
|
||||
```dart
|
||||
bridge.translateRequest({
|
||||
'text': 'Hello',
|
||||
'from': 'en',
|
||||
'to': 'zh',
|
||||
});
|
||||
bridge.sendRequest(
|
||||
sendType: ToFlutterAppEnum.translateRequest, // 1. 发送类型
|
||||
listenType: FromFlutterAppEnum.translateResult, // 2. 监听类型
|
||||
params: {
|
||||
'text00001': 'text00001',
|
||||
'text00002': 'text00002',
|
||||
'text00003': 'text00003',
|
||||
}, // 3. 参数
|
||||
onSuccess: (data) {
|
||||
// 4. 成功回调 (自动排队,安全)
|
||||
print("翻译结果: $data");
|
||||
},
|
||||
);
|
||||
```
|
||||
|
||||
##### 直播间相关
|
||||
@@ -274,27 +284,28 @@ Flutter 向 H5 发送的消息类型枚举。包含:
|
||||
```dart
|
||||
import 'package:web_tools/web_tools.dart';
|
||||
|
||||
//需要翻译的map
|
||||
var textMap = <String, String>{};
|
||||
|
||||
void setupTranslation() {
|
||||
final bridge = FlutterBridge.instance;
|
||||
// 使用 sendRequest (发送请求并队列监听回调,内部自动释放监听回调),该方法只监听一次,
|
||||
// 如果需要多次监听,请使用 FlutterBridge.instance.on,并且手动释放监听回调
|
||||
FlutterBridge.instance.sendRequest(
|
||||
sendType: ToFlutterAppEnum.translateRequest, // 1. 发送类型
|
||||
listenType: FromFlutterAppEnum.translateResult, // 2. 监听类型
|
||||
params: textMap, // 3. 参数
|
||||
onSuccess: (data) {
|
||||
// 4. 成功回调 (自动排队,安全)
|
||||
print("翻译结果: $data");
|
||||
|
||||
// 注册翻译结果监听器
|
||||
bridge.on(FromFlutterAppEnum.translateResult.code, (data) {
|
||||
final translatedText = data['data']['text'];
|
||||
print('翻译结果: $translatedText');
|
||||
// 更新 UI 显示翻译结果
|
||||
});
|
||||
final Map<String, String> result =
|
||||
data.map((key, value) => MapEntry(key, value.toString()));
|
||||
|
||||
// 发送翻译请求
|
||||
bridge.translateRequest({
|
||||
'text': 'Hello World',
|
||||
'from': 'en',
|
||||
'to': 'zh',
|
||||
});
|
||||
}
|
||||
|
||||
void cleanup() {
|
||||
// 清理监听器
|
||||
FlutterBridge.instance.off(FromFlutterAppEnum.translateResult.code);
|
||||
textMap.clear();// 清空临时变量
|
||||
FlutterBridge.instance.textMap.addAll(translated);//全局变量追加翻译结果
|
||||
update(['your_id']);
|
||||
},
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
@@ -303,29 +314,51 @@ void cleanup() {
|
||||
```dart
|
||||
import 'package:web_tools/web_tools.dart';
|
||||
|
||||
void setupShare() {
|
||||
final bridge = FlutterBridge.instance;
|
||||
class SantaLogic extends GetxController {
|
||||
|
||||
// 注册分享完成监听器
|
||||
bridge.on(FromFlutterAppEnum.shareFinished.code, (data) {
|
||||
print('分享完成');
|
||||
// 处理分享完成后的逻辑
|
||||
});
|
||||
// 1. 定义一个变量来持有取消函数
|
||||
VoidCallback? _cancelShareListener;
|
||||
|
||||
// 触发分享
|
||||
bridge.share(
|
||||
@override
|
||||
void onReady() {
|
||||
super.onReady();
|
||||
|
||||
// 2. 注册监听(需要监听分享回调时)
|
||||
// on 方法现在会返回一个取消函数,专门用来取消“这一个”监听
|
||||
_cancelShareListener = FlutterBridge.instance.on(
|
||||
FromFlutterAppEnum.shareFinished.code,
|
||||
(data) {
|
||||
print("SantaLogic: 收到分享成功的广播");
|
||||
// 执行业务,比如刷新任务列表
|
||||
requestTaskInfo();
|
||||
}
|
||||
);
|
||||
// 1. 触发分享(有些分享不需要监听,只需要触发分享)
|
||||
FlutterBridge.instance.share(
|
||||
activityId: 'activity_123',
|
||||
needShareReport: true,
|
||||
extraParams: {'source': 'web'},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
// 3. ⚠️⚠️⚠️ 如果注册了监听,必须在页面销毁时调用取消函数
|
||||
// 如果不调用,SantaLogic 即使退出了,这个闭包还在 Bridge 里,
|
||||
// 下次分享成功时,代码还会跑,且 SantaLogic 无法被垃圾回收!
|
||||
_cancelShareListener?.call();
|
||||
|
||||
super.onClose();
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **单例模式**:`FlutterBridge` 使用单例模式,在整个应用中只有一个实例。
|
||||
|
||||
2. **监听器管理**:使用 `on()` 注册的监听器在使用完毕后应该使用 `off()` 取消注册,避免内存泄漏。
|
||||
2. **监听器管理**:使用 `on()` 注册的监听器在使用完毕后必须使用`_listener1.call()` 取消注册,避免内存泄漏, `off()` 慎用,这将移除对应type的所有监听器。`sendRequest()`方法是融合了发送消息+监听回调,不用手动取消监听,内部自动清理监听。并且只监听一次,防止多次回调。
|
||||
|
||||
3. **消息格式**:所有消息都遵循 `{'type': '消息类型', 'data': {...}}` 的格式。
|
||||
|
||||
|
||||
@@ -4,10 +4,12 @@ import 'dart:html' as html;
|
||||
|
||||
import 'package:js/js.dart';
|
||||
import 'package:web_tools/utils/model/model.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
// h5交互通知 原生 {type:'enum',data:'所需参数,可无'}
|
||||
enum ToFlutterAppEnum {
|
||||
close('close'),
|
||||
reload('reload'), // 刷新
|
||||
gameExit('gameExit'),
|
||||
createGame('createGame'),
|
||||
wantToPlay('wantToPlay'),
|
||||
@@ -57,8 +59,21 @@ enum ToFlutterAppEnum {
|
||||
//前往语音房
|
||||
shouldGoToVoiceRoom('shouldGoToVoiceRoom'),
|
||||
|
||||
// 恩爱节活动跳转选择好友
|
||||
lovingDayChooseFriend('lovingDayChooseFriend'),
|
||||
// 恩爱节我的邀请页面
|
||||
lovingDayMyInvite('lovingDayMyInvite'),
|
||||
// 常驻cp活动规则页面
|
||||
taskKeyToCPRule('taskKeyToCPRule'),
|
||||
|
||||
// 定向充值
|
||||
rechargeItem('rechargeItem'),
|
||||
//专属见面礼
|
||||
shouldInviteCodeGift('InviteCodeGiftPackageDialogPage'),
|
||||
//解析 URL 并跳转
|
||||
showCommandJump('commandJump'),
|
||||
//跳转至网页
|
||||
showToWebViewPage('toWebViewPage'),
|
||||
|
||||
///通用交互 别往这下面加,👆🏻加
|
||||
commonInteraction('commonInteraction'),
|
||||
@@ -99,12 +114,9 @@ enum WebInteractionType {
|
||||
taskKeyOtherPage('TaskKeyOtherPage'), // 其他页面
|
||||
taskKeyMineBackpack('TaskKeyMineBackpack'), // 我的装扮背包页面(或者是称号)
|
||||
taskKeyMineWallet('TaskKeyMineWallet'), // 我的钱包页面
|
||||
unknown('unknown'),
|
||||
;
|
||||
unknown('unknown');
|
||||
|
||||
const WebInteractionType(
|
||||
this.code,
|
||||
);
|
||||
const WebInteractionType(this.code);
|
||||
final String code; //服务端 key
|
||||
|
||||
factory WebInteractionType.fromCode(String? code) => values.firstWhere(
|
||||
@@ -118,6 +130,7 @@ enum FromFlutterAppEnum {
|
||||
translateResult('translateResult'), //翻译
|
||||
redDiamondRecharge('diamond_recharge'), //钻石充值
|
||||
shareFinished('share_finished'), //分享完成
|
||||
cpSendRingCallBack('cp_send_ring_callback'), //送戒指后回调
|
||||
defaultCode('');
|
||||
|
||||
const FromFlutterAppEnum(this.code);
|
||||
@@ -127,22 +140,29 @@ enum FromFlutterAppEnum {
|
||||
@JS()
|
||||
external void sendMessageToNative(String data);
|
||||
|
||||
/// 🆕 [新增] 通用请求任务模型
|
||||
class _RequestTask {
|
||||
final String sendType; // 发送给 Native 的类型
|
||||
final Map<String, dynamic> params; // 发送的参数
|
||||
final Function(Map<String, dynamic>) callback; // 成功回调
|
||||
|
||||
_RequestTask(this.sendType, this.params, this.callback);
|
||||
}
|
||||
|
||||
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>)>{};
|
||||
// final _messageListeners = <String, Function(Map<String, dynamic>)>{};
|
||||
// 1. 修改这里:Value 从 Function 变成 List<Function>
|
||||
final _messageListeners = <String, List<Function(Map<String, dynamic>)>>{};
|
||||
var textMap = <String, String>{}; //多语言翻译
|
||||
|
||||
/// 🆕 [新增] 通用请求队列池 (Key: listenType, Value: 任务列表)
|
||||
final Map<String, List<_RequestTask>> _requestQueues = {};
|
||||
|
||||
/// 🆕 [新增] 忙碌状态池 (记录哪些 listenType 当前正在等待 Native 回复)
|
||||
final Set<String> _activeResponseTypes = {};
|
||||
|
||||
FlutterBridge._internal() {
|
||||
_initListener();
|
||||
}
|
||||
@@ -154,8 +174,19 @@ class FlutterBridge {
|
||||
try {
|
||||
final Map<String, dynamic> data = jsonDecode(event.data);
|
||||
final String? type = data['type'];
|
||||
// 找到监听列表,遍历调用
|
||||
if (type != null && _messageListeners.containsKey(type)) {
|
||||
_messageListeners[type]?.call(data);
|
||||
final listeners = _messageListeners[type];
|
||||
if (listeners != null && listeners.isNotEmpty) {
|
||||
// 使用 List.from 浅拷贝一份进行遍历,防止在回调中移除监听导致并发修改异常
|
||||
for (final callback in List.from(listeners)) {
|
||||
try {
|
||||
callback(data); // 这里的 data 是已经解析好的 Map
|
||||
} catch (e) {
|
||||
print("Error in listener callback: $e");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
print('Invalid message format from Flutter: $type');
|
||||
} catch (e) {
|
||||
@@ -164,8 +195,19 @@ class FlutterBridge {
|
||||
} else {
|
||||
try {
|
||||
final String? type = event.data['type'];
|
||||
// 找到监听列表,遍历调用
|
||||
if (type != null && _messageListeners.containsKey(type)) {
|
||||
_messageListeners[type]?.call(event.data);
|
||||
final listeners = _messageListeners[type];
|
||||
if (listeners != null && listeners.isNotEmpty) {
|
||||
// 使用 List.from 浅拷贝一份进行遍历,防止在回调中移除监听导致并发修改异常
|
||||
for (final callback in List.from(listeners)) {
|
||||
try {
|
||||
callback(event.data); // 这里的 data 是已经解析好的 Map
|
||||
} catch (e) {
|
||||
print("Error in listener callback: $e");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
print('Invalid message format from Flutter: $type');
|
||||
} catch (e) {
|
||||
@@ -175,24 +217,113 @@ class FlutterBridge {
|
||||
});
|
||||
}
|
||||
|
||||
// 注册监听某个 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.");
|
||||
/// 3. 核心修改:on 方法
|
||||
/// 返回一个 VoidCallback,调用它即可取消本次监听
|
||||
VoidCallback on(String type, Function(Map<String, dynamic>) callback) {
|
||||
if (!_messageListeners.containsKey(type)) {
|
||||
_messageListeners[type] = [];
|
||||
}
|
||||
|
||||
// 取消监听某个 type 的消息
|
||||
void off(String type) {
|
||||
if (!_messageListeners.containsKey(type)) {
|
||||
print("No listener found for '$type'.");
|
||||
return; // 如果没有找到监听器,直接返回
|
||||
}
|
||||
_messageListeners[type]!.add(callback);
|
||||
print(
|
||||
"Listener added for '$type'. Total listeners: ${_messageListeners[type]!.length}",
|
||||
);
|
||||
|
||||
// 返回一个闭包,用于精确移除当前的 callback
|
||||
return () {
|
||||
if (_messageListeners.containsKey(type)) {
|
||||
_messageListeners[type]?.remove(callback);
|
||||
print(
|
||||
"One listener removed for '$type'. Remaining: ${_messageListeners[type]?.length}",
|
||||
);
|
||||
|
||||
// 如果该类型没有监听者了,可以选择清理 key
|
||||
if (_messageListeners[type]!.isEmpty) {
|
||||
_messageListeners.remove(type);
|
||||
print("Listener for '$type' has been removed.");
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// 警告:这会移除该类型下的【所有】监听器 (慎用,通常用于全局重置,一旦调用,该 type 别的地方监听器将失效)
|
||||
void off(String type) {
|
||||
if (_messageListeners.containsKey(type)) {
|
||||
_messageListeners.remove(type);
|
||||
print("All listeners for '$type' have been removed.");
|
||||
}
|
||||
}
|
||||
// =========================================================
|
||||
// 👇 🆕 [新增] 核心通用请求方法 (替代了旧的 requestTranslate)
|
||||
// =========================================================
|
||||
|
||||
/// 发送请求并等待回调 (自动排队,防并发)
|
||||
/// [sendType] 发送给 Native 的类型
|
||||
/// [listenType] 等待 Native 回复的类型
|
||||
/// [params] 参数
|
||||
/// [onSuccess] 成功回调
|
||||
void sendRequest({
|
||||
required ToFlutterAppEnum sendType,
|
||||
required FromFlutterAppEnum listenType,
|
||||
required Map<String, dynamic> params,
|
||||
required Function(Map<String, dynamic>) onSuccess,
|
||||
}) {
|
||||
final responseKey = listenType.code;
|
||||
|
||||
// 1. 初始化该类型的队列
|
||||
if (!_requestQueues.containsKey(responseKey)) {
|
||||
_requestQueues[responseKey] = [];
|
||||
}
|
||||
|
||||
// 2. 入队
|
||||
_requestQueues[responseKey]!.add(_RequestTask(
|
||||
sendType.code,
|
||||
params,
|
||||
onSuccess,
|
||||
));
|
||||
|
||||
// 3. 调度执行
|
||||
_processRequestQueue(responseKey);
|
||||
}
|
||||
|
||||
/// 🆕 [新增] 内部队列调度方法
|
||||
void _processRequestQueue(String responseKey) {
|
||||
// 如果该类型正在忙,或者队列空了,直接返回
|
||||
if (_activeResponseTypes.contains(responseKey) ||
|
||||
(_requestQueues[responseKey]?.isEmpty ?? true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. 标记忙碌
|
||||
_activeResponseTypes.add(responseKey);
|
||||
|
||||
// 2. 取出队首任务
|
||||
final task = _requestQueues[responseKey]!.removeAt(0);
|
||||
|
||||
// 3. 注册临时监听 (使用 on 的多播特性)
|
||||
VoidCallback? cancelRef;
|
||||
|
||||
cancelRef = on(responseKey, (data) {
|
||||
try {
|
||||
final innerData = data['data'] ?? {};
|
||||
// 执行业务回调
|
||||
task.callback(innerData);
|
||||
} catch (e) {
|
||||
print("Queue processing error: $e");
|
||||
} finally {
|
||||
// --- 任务闭环 ---
|
||||
// A. 移除当前临时监听 (不影响全局监听)
|
||||
cancelRef?.call();
|
||||
|
||||
// B. 解除忙碌状态
|
||||
_activeResponseTypes.remove(responseKey);
|
||||
|
||||
// C. 递归处理下一个任务
|
||||
_processRequestQueue(responseKey);
|
||||
}
|
||||
});
|
||||
|
||||
// 4. 发送 Native 消息
|
||||
sendToFlutter(task.sendType, task.params);
|
||||
}
|
||||
|
||||
// 发送消息给 App(通过 WebView 调用 JS 方法)
|
||||
@@ -222,28 +353,36 @@ class FlutterBridge {
|
||||
|
||||
// 具体封装的常用方法,直接发送消息给 Flutter Web
|
||||
void close() => sendToFlutter(ToFlutterAppEnum.close.code, {});
|
||||
void reload() => sendToFlutter(ToFlutterAppEnum.reload.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 translateRequest(Map<String, String> data) =>
|
||||
// sendToFlutter(ToFlutterAppEnum.translateRequest.code, data);//移除,建议使用sendRequest方法
|
||||
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});
|
||||
ToFlutterAppEnum.jumpToH5.code,
|
||||
{'path': path, 'title': title},
|
||||
);
|
||||
void toHomepage(String userId) =>
|
||||
sendToFlutter(ToFlutterAppEnum.toHomepage.code, {'userId': userId});
|
||||
void toMonthCardPay(String googleProductId, String iosProductId,
|
||||
{otherUserId = ''}) =>
|
||||
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});
|
||||
ToFlutterAppEnum.checkGameState.code,
|
||||
{'gameCode': gameCode},
|
||||
);
|
||||
|
||||
void share({
|
||||
required String activityId, // 活动id
|
||||
@@ -256,6 +395,27 @@ class FlutterBridge {
|
||||
...shareCardModel?.toJson() ?? {},
|
||||
});
|
||||
|
||||
//专属见面礼
|
||||
void taskInviteCodeGift() =>
|
||||
sendToFlutter(ToFlutterAppEnum.shouldInviteCodeGift.code, {});
|
||||
|
||||
//解析 URL 并跳转
|
||||
void taskCommandJump({required String scheme, required String activityId}) =>
|
||||
sendToFlutter(ToFlutterAppEnum.showCommandJump.code, {
|
||||
"scheme": scheme,
|
||||
"activityId": activityId,
|
||||
});
|
||||
|
||||
//跳转至网页
|
||||
void taskToWebViewPage({
|
||||
required String linkUrl,
|
||||
required String activityId,
|
||||
}) =>
|
||||
sendToFlutter(ToFlutterAppEnum.showToWebViewPage.code, {
|
||||
"linkUrl": linkUrl,
|
||||
"activityId": activityId,
|
||||
});
|
||||
|
||||
void checkStartBroadcaster() =>
|
||||
sendToFlutter(ToFlutterAppEnum.checkStartBroadcaster.code, {});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: web_tools
|
||||
description: "A new Flutter package project."
|
||||
version: 0.0.4
|
||||
version: 0.0.5
|
||||
publish_to: 'none' # 不发布到pub.dev
|
||||
homepage: https://gitea.sdws.shop/xim/web_tools.git
|
||||
|
||||
|
||||
Reference in New Issue
Block a user