145 lines
4.9 KiB
Dart
145 lines
4.9 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:yumi/modules/room_game/data/models/room_game_models.dart';
|
|
|
|
class BaishunBridgeActions {
|
|
static const String getConfig = 'getConfig';
|
|
static const String gameLoaded = 'gameLoaded';
|
|
static const String gameRecharge = 'gameRecharge';
|
|
static const String destroy = 'destroy';
|
|
}
|
|
|
|
class BaishunBridgeMessage {
|
|
const BaishunBridgeMessage({
|
|
required this.action,
|
|
this.payload = const <String, dynamic>{},
|
|
});
|
|
|
|
final String action;
|
|
final Map<String, dynamic> payload;
|
|
|
|
static BaishunBridgeMessage parse(String rawMessage) {
|
|
try {
|
|
final dynamic decoded = jsonDecode(rawMessage);
|
|
if (decoded is Map<String, dynamic>) {
|
|
final rawPayload = decoded['payload'];
|
|
return BaishunBridgeMessage(
|
|
action: (decoded['action'] ?? '').toString(),
|
|
payload:
|
|
rawPayload is Map<String, dynamic>
|
|
? rawPayload
|
|
: const <String, dynamic>{},
|
|
);
|
|
}
|
|
} catch (_) {}
|
|
return BaishunBridgeMessage(action: rawMessage.trim());
|
|
}
|
|
}
|
|
|
|
class BaishunJsBridge {
|
|
static const String channelName = 'BaishunBridgeChannel';
|
|
|
|
static String bootstrapScript() {
|
|
return '''
|
|
(function() {
|
|
if (window.__baishunBridgeReady) {
|
|
return;
|
|
}
|
|
window.__baishunBridgeReady = true;
|
|
window.NativeBridge = window.NativeBridge || {};
|
|
window.NativeBridge.getConfig = function(callback) {
|
|
if (typeof callback === 'function') {
|
|
window.__baishunGetConfigCallback = callback;
|
|
}
|
|
$channelName.postMessage(JSON.stringify({ action: '${BaishunBridgeActions.getConfig}' }));
|
|
return window.__baishunLastConfig || null;
|
|
};
|
|
window.NativeBridge.destroy = function(payload) {
|
|
$channelName.postMessage(JSON.stringify({ action: '${BaishunBridgeActions.destroy}', payload: payload || {} }));
|
|
};
|
|
window.NativeBridge.gameRecharge = function(payload) {
|
|
$channelName.postMessage(JSON.stringify({ action: '${BaishunBridgeActions.gameRecharge}', payload: payload || {} }));
|
|
};
|
|
window.NativeBridge.gameLoaded = function(payload) {
|
|
$channelName.postMessage(JSON.stringify({ action: '${BaishunBridgeActions.gameLoaded}', payload: payload || {} }));
|
|
};
|
|
window.baishunChannel = window.baishunChannel || {};
|
|
window.baishunChannel.walletUpdate = function(payload) {
|
|
window.__baishunLastWalletPayload = payload || {};
|
|
if (typeof window.walletUpdate === 'function') {
|
|
window.walletUpdate(payload || {});
|
|
}
|
|
if (typeof window.onWalletUpdate === 'function') {
|
|
window.onWalletUpdate(payload || {});
|
|
}
|
|
if (typeof window.dispatchEvent === 'function') {
|
|
window.dispatchEvent(new CustomEvent('walletUpdate', { detail: payload || {} }));
|
|
}
|
|
};
|
|
if (typeof window.onBaishunBridgeReady === 'function') {
|
|
window.onBaishunBridgeReady(window.NativeBridge);
|
|
}
|
|
if (typeof window.dispatchEvent === 'function') {
|
|
window.dispatchEvent(new CustomEvent('baishunBridgeReady', { detail: { nativeBridge: true } }));
|
|
}
|
|
})();
|
|
''';
|
|
}
|
|
|
|
static String buildConfigScript(BaishunBridgeConfigModel config) {
|
|
final payload = jsonEncode(config.toJson());
|
|
return '''
|
|
(function() {
|
|
const config = $payload;
|
|
window.__baishunLastConfig = config;
|
|
if (typeof window.__baishunGetConfigCallback === 'function') {
|
|
window.__baishunGetConfigCallback(config);
|
|
}
|
|
if (typeof window.onBaishunConfig === 'function') {
|
|
window.onBaishunConfig(config);
|
|
}
|
|
if (typeof window.dispatchEvent === 'function') {
|
|
window.dispatchEvent(new CustomEvent('baishunConfig', { detail: config }));
|
|
}
|
|
})();
|
|
''';
|
|
}
|
|
|
|
static String buildWalletUpdateScript({Map<String, dynamic>? payload}) {
|
|
final safePayload = jsonEncode(
|
|
payload ??
|
|
<String, dynamic>{'timestamp': DateTime.now().millisecondsSinceEpoch},
|
|
);
|
|
return '''
|
|
(function() {
|
|
const payload = $safePayload;
|
|
if (window.baishunChannel && typeof window.baishunChannel.walletUpdate === 'function') {
|
|
window.baishunChannel.walletUpdate(payload);
|
|
}
|
|
})();
|
|
''';
|
|
}
|
|
|
|
static String injectBootstrapHtml({
|
|
required String html,
|
|
required Uri entryUri,
|
|
required BaishunBridgeConfigModel config,
|
|
}) {
|
|
final baseHref = htmlEscape.convert(entryUri.toString());
|
|
final injection = '''
|
|
<base href="$baseHref" />
|
|
<script>
|
|
${bootstrapScript()}
|
|
${buildConfigScript(config)}
|
|
</script>
|
|
''';
|
|
|
|
final headPattern = RegExp(r'<head[^>]*>', caseSensitive: false);
|
|
final headMatch = headPattern.firstMatch(html);
|
|
if (headMatch != null) {
|
|
return html.replaceRange(headMatch.end, headMatch.end, injection);
|
|
}
|
|
return '$injection$html';
|
|
}
|
|
}
|