create project
This commit is contained in:
commit
66fb0b7157
34
.gitignore
vendored
Normal file
34
.gitignore
vendored
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
# Miscellaneous
|
||||||
|
*.class
|
||||||
|
*.log
|
||||||
|
*.pyc
|
||||||
|
*.swp
|
||||||
|
.DS_Store
|
||||||
|
.atom/
|
||||||
|
.buildlog/
|
||||||
|
.history
|
||||||
|
.svn/
|
||||||
|
migrate_working_dir/
|
||||||
|
|
||||||
|
# IntelliJ related
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
*.iws
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# The .vscode folder contains launch configuration and tasks you configure in
|
||||||
|
# VS Code which you may wish to be included in version control, so this line
|
||||||
|
# is commented out by default.
|
||||||
|
#.vscode/
|
||||||
|
|
||||||
|
# Flutter/Dart/Pub related
|
||||||
|
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
|
||||||
|
/pubspec.lock
|
||||||
|
**/doc/api/
|
||||||
|
.dart_tool/
|
||||||
|
.flutter-plugins
|
||||||
|
.flutter-plugins-dependencies
|
||||||
|
build/
|
||||||
|
|
||||||
|
# FVM Version Cache
|
||||||
|
.fvm/
|
||||||
10
.metadata
Normal file
10
.metadata
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# This file tracks properties of this Flutter project.
|
||||||
|
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||||
|
#
|
||||||
|
# This file should be version controlled and should not be manually edited.
|
||||||
|
|
||||||
|
version:
|
||||||
|
revision: "ea121f8859e4b13e47a8f845e4586164519588bc"
|
||||||
|
channel: "stable"
|
||||||
|
|
||||||
|
project_type: package
|
||||||
3
CHANGELOG.md
Normal file
3
CHANGELOG.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
## 0.0.1
|
||||||
|
|
||||||
|
* TODO: Describe initial release.
|
||||||
39
README.md
Normal file
39
README.md
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<!--
|
||||||
|
This README describes the package. If you publish this package to pub.dev,
|
||||||
|
this README's contents appear on the landing page for your package.
|
||||||
|
|
||||||
|
For information about how to write a good package README, see the guide for
|
||||||
|
[writing package pages](https://dart.dev/tools/pub/writing-package-pages).
|
||||||
|
|
||||||
|
For general information about developing packages, see the Dart guide for
|
||||||
|
[creating packages](https://dart.dev/guides/libraries/create-packages)
|
||||||
|
and the Flutter guide for
|
||||||
|
[developing packages and plugins](https://flutter.dev/to/develop-packages).
|
||||||
|
-->
|
||||||
|
|
||||||
|
TODO: Put a short description of the package here that helps potential users
|
||||||
|
know whether this package might be useful for them.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
TODO: List what your package can do. Maybe include images, gifs, or videos.
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
TODO: List prerequisites and provide or point to information on how to
|
||||||
|
start using the package.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
TODO: Include short and useful examples for package users. Add longer examples
|
||||||
|
to `/example` folder.
|
||||||
|
|
||||||
|
```dart
|
||||||
|
const like = 'sample';
|
||||||
|
```
|
||||||
|
|
||||||
|
## Additional information
|
||||||
|
|
||||||
|
TODO: Tell users more about the package: where to find more information, how to
|
||||||
|
contribute to the package, how to file issues, what response they can expect
|
||||||
|
from the package authors, and more.
|
||||||
4
analysis_options.yaml
Normal file
4
analysis_options.yaml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
include: package:flutter_lints/flutter.yaml
|
||||||
|
|
||||||
|
# Additional information about this file can be found at
|
||||||
|
# https://dart.dev/guides/language/analysis-options
|
||||||
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';
|
||||||
58
pubspec.yaml
Normal file
58
pubspec.yaml
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
name: web_tools
|
||||||
|
description: "A new Flutter package project."
|
||||||
|
version: 0.0.1
|
||||||
|
publish_to: 'none' # 不发布到pub.dev
|
||||||
|
homepage: https://gitea.sdws.shop/xim/web_tools.git
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: ^3.5.3
|
||||||
|
flutter: ">=1.17.0"
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
flutter:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
|
js: ^0.6.3
|
||||||
|
|
||||||
|
|
||||||
|
dev_dependencies:
|
||||||
|
flutter_test:
|
||||||
|
sdk: flutter
|
||||||
|
flutter_lints: ^5.0.0
|
||||||
|
|
||||||
|
# For information on the generic Dart part of this file, see the
|
||||||
|
# following page: https://dart.dev/tools/pub/pubspec
|
||||||
|
|
||||||
|
# The following section is specific to Flutter packages.
|
||||||
|
flutter:
|
||||||
|
|
||||||
|
# To add assets to your package, add an assets section, like this:
|
||||||
|
# assets:
|
||||||
|
# - images/a_dot_burr.jpeg
|
||||||
|
# - images/a_dot_ham.jpeg
|
||||||
|
#
|
||||||
|
# For details regarding assets in packages, see
|
||||||
|
# https://flutter.dev/to/asset-from-package
|
||||||
|
#
|
||||||
|
# An image asset can refer to one or more resolution-specific "variants", see
|
||||||
|
# https://flutter.dev/to/resolution-aware-images
|
||||||
|
|
||||||
|
# To add custom fonts to your package, add a fonts section here,
|
||||||
|
# in this "flutter" section. Each entry in this list should have a
|
||||||
|
# "family" key with the font family name, and a "fonts" key with a
|
||||||
|
# list giving the asset and other descriptors for the font. For
|
||||||
|
# example:
|
||||||
|
# fonts:
|
||||||
|
# - family: Schyler
|
||||||
|
# fonts:
|
||||||
|
# - asset: fonts/Schyler-Regular.ttf
|
||||||
|
# - asset: fonts/Schyler-Italic.ttf
|
||||||
|
# style: italic
|
||||||
|
# - family: Trajan Pro
|
||||||
|
# fonts:
|
||||||
|
# - asset: fonts/TrajanPro.ttf
|
||||||
|
# - asset: fonts/TrajanPro_Bold.ttf
|
||||||
|
# weight: 700
|
||||||
|
#
|
||||||
|
# For details regarding fonts in packages, see
|
||||||
|
# https://flutter.dev/to/font-from-package
|
||||||
5
test/web_tools_test.dart
Normal file
5
test/web_tools_test.dart
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
test('adds one to input values', () {});
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user