You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

95 lines
2.9 KiB

import { Subject } from 'rxjs';
declare global {
interface Window {
WebViewJavascriptBridge: {
callHandler: (
name: string,
args: Record<string, any>,
callback: (res: string) => void
) => void;
registerHandler: (
name: string,
func: (data: string, callback: (res: string) => void) => void
) => void;
};
WVJBCallbacks: Array<(bridge: typeof window.WebViewJavascriptBridge) => void>;
}
}
export function setupWebViewJavascriptBridge(
callback: (bridge: typeof window.WebViewJavascriptBridge) => void
) {
if (window.WebViewJavascriptBridge) {
return callback(window.WebViewJavascriptBridge);
}
if (/android/i.test(navigator.userAgent)) {
document.addEventListener(
'WebViewJavascriptBridgeReady',
function () {
callback(window.WebViewJavascriptBridge);
},
false
);
} else {
if (window.WVJBCallbacks) {
return window.WVJBCallbacks.push(callback);
}
window.WVJBCallbacks = [callback];
var WVJBIframe = document.createElement('iframe');
WVJBIframe.style.display = 'none';
WVJBIframe.src = 'https://__bridge_loaded__';
document.documentElement.appendChild(WVJBIframe);
setTimeout(function () {
document.documentElement.removeChild(WVJBIframe);
}, 0);
}
}
type ShowModelParam = Partial<{
title: string; // 非必填,但 title 和 content 至少要填一个
content: string; // 非必填,但 title 和 content 至少要填一个
contentAlignCenter: boolean; // 内容文本水平居中? 默认 false, 居左
showCancel: boolean; // 默认 true
cancelText: string; //默认 '取消'
// cancelColor: string; // 默认'#333333'
confirmText: string; // 默认 '确定'
// confirmColor: string; // 默认 APP主题色
}>;
// 是否运行在 原生APP 的 WebView 中
const appWebview = navigator.userAgent.includes('iFlyTop-mobile');
const bridgeSub = new Subject<{ func: string; data: Record<string, any> | any[] }>();
export const bridgeOb = bridgeSub.asObservable();
export function registerBridgeFunc() {
const jsFuncs = ['funcInJs'];
jsFuncs.forEach((funcName) => {
window.WebViewJavascriptBridge.registerHandler(funcName, (data, callback) => {
bridgeSub.next({ func: funcName, data: JSON.parse(data) });
callback(JSON.stringify({ success: true }));
});
});
}
export default class Bridge {
static register(name: string, func: (data: string, callback: (res: string) => void) => void) {
if (appWebview) {
window.WebViewJavascriptBridge.registerHandler(name, func);
}
}
static showModal(param: ShowModelParam) {
if (appWebview) {
return new Promise<'confirm' | 'cancel'>((resolve) => {
window.WebViewJavascriptBridge.callHandler('showModal', param, (res) => {
resolve(res as 'confirm' | 'cancel');
});
});
} else {
return Promise.resolve('confirm' as const);
}
}
}