@bluesyoung/call-app
Version:
194 lines (181 loc) • 4.1 kB
text/typescript
/*
* @Author: zhangyang
* @Date: 2022-04-28 14:22:04
* @LastEditTime: 2023-02-02 09:54:34
* @Description:
*/
import { copy, detector } from '@bluesyoung/share-dom';
import { defu } from 'defu';
import type { SetOptional } from '@bluesyoung/utils';
const isIos = detector.os.name === 'ios';
const inWeixin = detector.browser.name === 'micromessenger';
// const inQQ = detector.browser.name === 'qq';
// const inWeibo = detector.browser.name === 'weibo';
// const inBaidu = detector.browser.name === 'baidu';
enum QuickCall {
wechat = 'weixin://',
}
/**
* 快捷唤端的配置
*/
type QuickCallConfig = {
/**
* 快速唤起的类型
*/
quickType: QuickCall;
/**
* 需要复制到剪切板的文本
*/
copyInfo?: string;
};
/**
* 基本唤端配置
*/
type CommonCallConfig = {
/**
* 安卓唤端地址
*/
android_shceme: string;
/**
* ios 唤端地址
*/
ios_shceme: string;
/**
* 特定渠道的下载地址
*/
download?: {
/**
* 安卓
*/
android?: string;
/**
* ios
*/
ios?: string;
/**
* 应用宝
*/
yyb?: string;
};
/**
* 唤端路径
*/
path?: string;
/**
* 需要传递的参数
*/
params?: Record<string, string>;
/**
* 兜底的落地页
*/
landpage?: string;
};
type Cbk = () => void;
type Options = {
/**
* 超时时间
* @default 2500 ms
*/
timeout: number;
/**
* 特殊环境的遮罩
*/
mask: {
wechat: Cbk;
};
startCall: Cbk;
callFail: Cbk;
};
const defaultOptions: Options = {
timeout: 2500,
mask: {
wechat: () => null,
},
startCall: () => console.log('---开始唤端---'),
callFail: () => console.log('---唤起失败,跳转下载---'),
};
class YoungCallApp {
static QuickCall = QuickCall;
public scheme: string;
public download: string;
public info: string;
public options: Options;
constructor(conf: QuickCallConfig, options?: SetOptional<Options, keyof Options>);
constructor(conf: CommonCallConfig, options?: SetOptional<Options, keyof Options>);
constructor(conf: any, options: SetOptional<Options, keyof Options> = {}) {
this.options = defu(options, defaultOptions);
if (conf.quickType) {
this.scheme = conf.quickType;
this.info = conf?.copyInfo || '';
} else {
this.generateScheme(conf);
}
}
/**
* 生成通用唤端地址
*/
generateScheme(conf: CommonCallConfig) {
let scheme = '',
download = '',
info = '(复制此消息打开app)|';
if (isIos) {
if (conf.ios_shceme.includes('://')) {
scheme = conf.ios_shceme;
} else {
scheme = `${conf.ios_shceme}://`;
}
download = conf?.download?.ios || conf.landpage;
} else {
if (conf.android_shceme.includes('://')) {
scheme = conf.android_shceme;
} else {
scheme = `${conf.android_shceme}://`;
}
download = conf?.download?.yyb || conf.landpage;
if (inWeixin && conf?.download?.yyb) {
download = conf.download.yyb;
}
}
if (conf.path) {
scheme += conf.path;
}
if (conf.params) {
const query = new URLSearchParams(conf.params).toString();
scheme += `?${query}`;
info += query;
}
this.scheme = scheme;
this.download = download;
this.info = info;
}
call() {
const { mask, startCall } = this.options;
if (inWeixin && mask.wechat) {
mask.wechat();
return;
}
copy(this.info);
startCall?.();
// 开始唤端
window.location.href = this.scheme;
this.fallback();
}
fallback() {
const t = setTimeout(() => {
/**
* 调用唤起失败的回调函数
*/
this.options.callFail();
if (this.download) {
/**
* 拥有兜底的落地页,跳转
*/
window.location.href = this.download;
}
}, this.options.timeout);
setTimeout(() => {
window.addEventListener('blur', () => clearTimeout(t));
}, this.options.timeout - 500);
}
}
export default YoungCallApp;