Add Yomi Flutter bridge shim

This commit is contained in:
zhx 2026-06-10 18:58:46 +08:00
parent 300b251645
commit c7a9801549

View File

@ -1,5 +1,5 @@
(function () {
var remoteBridgeVersion = '20260610.1';
var remoteBridgeVersion = '20260610.2';
function safeCall(fn, args) {
try {
@ -132,6 +132,9 @@
if (values.indexOf('reyou') >= 0 || values.indexOf('hotgame') >= 0) {
return 'reyou_v1';
}
if (values.indexOf('yomi') >= 0) {
return 'yomi_v4';
}
return 'generic';
}
@ -179,6 +182,238 @@
window.webkit.messageHandlers[name] = { postMessage: fn.postMessage };
}
function parseBridgePayload(value) {
if (typeof value === 'string') {
var text = value.trim();
if (!text) {
return {};
}
try {
var decoded = JSON.parse(text);
return decoded && typeof decoded === 'object'
? decoded
: { value: decoded };
} catch (_) {
return { raw: text };
}
}
if (value && typeof value === 'object') {
return value;
}
if (value === null || value === undefined) {
return {};
}
return { value: value };
}
function actionFromPayload(payload, fallbackAction) {
return (
readString(
payload.type ||
payload.action ||
payload.method ||
payload.name ||
payload.cmd ||
payload.event
) || fallbackAction
);
}
function invokeNamedCallback(callbackName, payload) {
var text = readString(callbackName);
if (
!/^[A-Za-z_$][0-9A-Za-z_$]*(\.[A-Za-z_$][0-9A-Za-z_$]*)*$/.test(
text
)
) {
return false;
}
var parts = text.split('.');
var target = window;
for (var i = 0; i < parts.length; i += 1) {
target = target[parts[i]];
if (target === null || target === undefined) {
return false;
}
}
if (typeof target !== 'function') {
return false;
}
safeCall(target, [payload || {}]);
return true;
}
function yomiActionResult(action, payload) {
var normalized = readString(action).toLowerCase();
if (normalized === 'insufficient') {
return {
action: 'insufficient',
result: 'success',
balance: payload && payload.balance,
};
}
if (normalized === 'hidesplash') {
return { action: 'hideSplash', result: 'success' };
}
if (normalized === 'closegame') {
return { action: 'closeGame', result: 'success' };
}
return { action: action, result: 'success' };
}
function postYomiAction(action, input) {
var payload = parseBridgePayload(input);
var normalized = actionFromPayload(payload, action);
if (!normalized) {
normalized = 'NativeBridge';
}
payload.type = payload.type || normalized;
payload.action = payload.action || normalized;
post(normalized, payload);
invokeNamedCallback(
payload.callback || payload.callbackName || payload.cb,
yomiActionResult(normalized, payload)
);
return yomiActionResult(normalized, payload);
}
function extractYomiBalance(payload) {
var body = parseBridgePayload(payload);
if (body.balance !== null && body.balance !== undefined) {
return body.balance;
}
if (body.amount !== null && body.amount !== undefined) {
return body.amount;
}
if (body.coin !== null && body.coin !== undefined) {
return body.coin;
}
if (body.balanceLabel !== null && body.balanceLabel !== undefined) {
return body.balanceLabel;
}
return undefined;
}
function notifyYomiGame(action, body) {
var normalized = readString(action);
if (normalized === 'onBalanceUpdate') {
var balance = extractYomiBalance(body);
if (balance === undefined) {
safeCall(window.onBalanceUpdate, []);
} else {
safeCall(window.onBalanceUpdate, [balance]);
}
}
if (normalized === 'setSound') {
var payload = parseBridgePayload(body);
var soundEnabled =
payload.bool !== undefined
? payload.bool
: payload.enabled !== undefined
? payload.enabled
: payload.value;
safeCall(window.setSound, [!!soundEnabled]);
}
if (normalized === 'passiveCloseGame') {
safeCall(window.passiveCloseGame, []);
}
try {
window.dispatchEvent(
new CustomEvent('yomiBridgeAction', {
detail: { action: normalized, payload: body || {} },
})
);
} catch (_) {}
}
function installYomiPostMessageListener() {
if (window.__hyappYomiPostMessageListenerInstalled) {
return;
}
window.__hyappYomiPostMessageListenerInstalled = true;
window.addEventListener('message', function (event) {
var data = parseBridgePayload(event && event.data);
if (readString(data.from).toLowerCase() !== 'yomi') {
return;
}
var action = actionFromPayload(data, '');
if (!action) {
return;
}
postYomiAction(action, data);
});
}
function installYomiBridgeAliases(nativeBridge) {
var previousYomi = window.yomi || {};
var yomiBridge = {};
var previousUpdateCoin =
typeof nativeBridge.updateCoin === 'function'
? nativeBridge.updateCoin.bind(nativeBridge)
: null;
yomiBridge.postMessage = function (message) {
var payload = parseBridgePayload(message);
return postYomiAction(
actionFromPayload(payload, 'NativeBridge'),
payload
);
};
yomiBridge.closeGame = function (body) {
return postYomiAction('closeGame', body || {});
};
yomiBridge.hideSplash = function (body) {
return postYomiAction('hideSplash', body || {});
};
yomiBridge.insufficient = function (body) {
return postYomiAction('insufficient', body || {});
};
yomiBridge.onBalanceUpdate = function (body) {
notifyYomiGame('onBalanceUpdate', body || {});
};
yomiBridge.setSound = function (body) {
notifyYomiGame('setSound', body || {});
};
yomiBridge.passiveCloseGame = function () {
notifyYomiGame('passiveCloseGame', {});
};
Object.keys(previousYomi).forEach(function (key) {
if (yomiBridge[key] === undefined) {
yomiBridge[key] = previousYomi[key];
}
});
window.yomi = yomiBridge;
window.webkit = window.webkit || {};
window.webkit.messageHandlers = window.webkit.messageHandlers || {};
window.webkit.messageHandlers.yomi = {
postMessage: yomiBridge.postMessage,
};
nativeBridge.insufficient = function (body) {
postYomiAction('insufficient', body || {});
};
nativeBridge.hideSplash = function (body) {
postYomiAction('hideSplash', body || {});
};
nativeBridge.onBalanceUpdate = function (body) {
notifyYomiGame('onBalanceUpdate', body || {});
};
nativeBridge.setSound = function (body) {
notifyYomiGame('setSound', body || {});
};
nativeBridge.passiveCloseGame = function () {
notifyYomiGame('passiveCloseGame', {});
};
nativeBridge.updateCoin = function (body) {
if (previousUpdateCoin) {
previousUpdateCoin(body || {});
}
notifyYomiGame('onBalanceUpdate', body || {});
};
installYomiPostMessageListener();
}
function notifyReyouRechargeSuccess(body) {
var payload = body || {};
var notified = false;
@ -348,12 +583,15 @@
callNativeBridge('debugLog', body || {});
};
installReyouBridgeAliases(nativeBridge);
installYomiBridgeAliases(nativeBridge);
window.NativeBridge = nativeBridge;
[
['getConfig', 'getConfig'],
['destroy', 'destroy'],
['closeGame', 'closeGame'],
['hideSplash', 'hideSplash'],
['insufficient', 'insufficient'],
['gameStart', 'gameStart'],
['gameLoading', 'gameLoading'],
['gameLoaded', 'gameLoaded'],