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
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);
|
|
}
|
|
}
|
|
}
|