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 {}, }); final String action; final Map payload; static BaishunBridgeMessage parse(String rawMessage) { try { final dynamic decoded = jsonDecode(rawMessage); if (decoded is Map) { final rawPayload = decoded['payload']; return BaishunBridgeMessage( action: (decoded['action'] ?? '').toString(), payload: rawPayload is Map ? rawPayload : const {}, ); } } 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? payload}) { final safePayload = jsonEncode( payload ?? {'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 = ''' '''; final headPattern = RegExp(r']*>', caseSensitive: false); final headMatch = headPattern.firstMatch(html); if (headMatch != null) { return html.replaceRange(headMatch.end, headMatch.end, injection); } return '$injection$html'; } }