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.
131 lines
5.4 KiB
131 lines
5.4 KiB
/**
|
|
* 小游戏宿主设备信息。
|
|
* 微信:getSystemInfo 自 2.20.1 停维,鸿蒙 3.7.0+ 用 getDeviceInfo / getWindowInfo / getAppBaseInfo。
|
|
* https://developers.weixin.qq.com/minigame/dev/guide/open-ability/ohos.html
|
|
*/
|
|
export type MiniGameHostApi = {
|
|
getDeviceInfo?: () => Record<string, unknown>;
|
|
getWindowInfo?: () => Record<string, unknown>;
|
|
getAppBaseInfo?: () => Record<string, unknown>;
|
|
getSystemInfoSync?: () => Record<string, unknown>;
|
|
};
|
|
|
|
/**
|
|
* 合并新/旧宿主信息接口。appName 等字段可能只在 getSystemInfoSync / getAppBaseInfo。
|
|
* @param api 微信 / 抖音 jsbridge
|
|
*/
|
|
export function readMiniGameHostInfo(api: MiniGameHostApi | null | undefined): Record<string, unknown> | null {
|
|
if (!api) return null;
|
|
const merged: Record<string, unknown> = {};
|
|
try {
|
|
if (typeof api.getDeviceInfo === 'function') {
|
|
Object.assign(merged, api.getDeviceInfo() ?? {});
|
|
}
|
|
} catch { /* jsbridge 未就绪 */ }
|
|
try {
|
|
if (typeof api.getWindowInfo === 'function') {
|
|
const win = api.getWindowInfo() ?? {};
|
|
if (win.screenWidth != null) merged.screenWidth = win.screenWidth;
|
|
if (win.screenHeight != null) merged.screenHeight = win.screenHeight;
|
|
if (win.windowWidth != null) merged.windowWidth = win.windowWidth;
|
|
if (win.windowHeight != null) merged.windowHeight = win.windowHeight;
|
|
if (win.pixelRatio != null) {
|
|
merged.pixelRatio = win.pixelRatio;
|
|
merged.devicePixelRatio = win.pixelRatio;
|
|
}
|
|
if (win.statusBarHeight != null) merged.statusBarHeight = win.statusBarHeight;
|
|
if (win.safeArea != null) merged.safeArea = win.safeArea;
|
|
}
|
|
} catch { /* jsbridge 未就绪 */ }
|
|
try {
|
|
if (typeof api.getAppBaseInfo === 'function') {
|
|
const app = api.getAppBaseInfo() ?? {};
|
|
if (app.SDKVersion != null) merged.SDKVersion = app.SDKVersion;
|
|
if (app.language != null) merged.language = app.language;
|
|
if (app.version != null) merged.version = app.version;
|
|
if (app.theme != null) merged.theme = app.theme;
|
|
if (app.enableDebug != null) merged.enableDebug = app.enableDebug;
|
|
if (app.host != null) merged.host = app.host;
|
|
if (app.appName != null) merged.appName = app.appName;
|
|
}
|
|
} catch { /* jsbridge 未就绪 */ }
|
|
if (typeof api.getSystemInfoSync === 'function') {
|
|
try {
|
|
const sys = api.getSystemInfoSync() ?? {};
|
|
if (merged.platform == null && sys.platform != null) merged.platform = sys.platform;
|
|
if (merged.system == null && sys.system != null) merged.system = sys.system;
|
|
if (merged.model == null && sys.model != null) merged.model = sys.model;
|
|
if (merged.appName == null && sys.appName != null) merged.appName = sys.appName;
|
|
if (merged.brand == null && sys.brand != null) merged.brand = sys.brand;
|
|
} catch { /* 旧接口失败则保持已合并字段 */ }
|
|
}
|
|
if (!merged.platform && !merged.system && !merged.model && !merged.appName) {
|
|
return null;
|
|
}
|
|
return merged;
|
|
}
|
|
|
|
/**
|
|
* 微信鸿蒙:platform=ohos;开发者工具模拟鸿蒙 platform=devtools 且 system=HarmonyOS。
|
|
* @param info 宿主信息
|
|
*/
|
|
export function isHarmonyHost(info: { platform?: unknown; system?: unknown } | null): boolean {
|
|
if (!info) return false;
|
|
const platform = String(info.platform ?? '').toLowerCase();
|
|
const system = String(info.system ?? '').toLowerCase();
|
|
return platform === 'ohos'
|
|
|| platform === 'ohos_pc'
|
|
|| platform === 'openharmony'
|
|
|| system.includes('harmony')
|
|
|| system.includes('openharmony');
|
|
}
|
|
|
|
/** 小游戏运行时平台(与 window 全局对象对应) */
|
|
export type MiniGamePfId = 'ks' | 'tt' | 'qg' | 'qq' | 'bl' | 'my' | 'wx';
|
|
|
|
/**
|
|
* 运行时宿主探测。wx 必须最后,避免快手「兼容微信」时 window.wx 抢先。
|
|
* my 在 wx 之前:支付宝全局对象是 my。
|
|
*/
|
|
export class MiniGamePf {
|
|
/** 探测顺序:ks → tt → qg → qq → bl → my → wx */
|
|
private static readonly _order: MiniGamePfId[] = ['ks', 'tt', 'qg', 'qq', 'bl', 'my', 'wx'];
|
|
|
|
/** 当前平台 id;非小游戏返回 null */
|
|
static id(): MiniGamePfId | null {
|
|
const order = MiniGamePf._order;
|
|
for (let i = 0; i < order.length; i++) {
|
|
const k = order[i];
|
|
if ((window as Record<string, unknown>)[k]) return k;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/** 当前平台全局对象 */
|
|
static api(): Record<string, any> | null {
|
|
const id = MiniGamePf.id();
|
|
if (!id) return null;
|
|
return ((window as Record<string, unknown>)[id] as Record<string, any>) ?? null;
|
|
}
|
|
|
|
/** 是否快手(含微信兼容包) */
|
|
static isKs(): boolean {
|
|
return !!(window as Record<string, unknown>)['ks'];
|
|
}
|
|
|
|
/** 是否 B 站小游戏 */
|
|
static isBl(): boolean {
|
|
return MiniGamePf.id() === 'bl';
|
|
}
|
|
|
|
/** 是否支付宝小游戏(全局对象 my) */
|
|
static isMy(): boolean {
|
|
return MiniGamePf.id() === 'my';
|
|
}
|
|
|
|
/** 是否走 ZYSDK 上报(抖音 / 快手 / B 站 / 微信)。支付宝不进 ZYSDK */
|
|
static canReport(): boolean {
|
|
const id = MiniGamePf.id();
|
|
return id === 'tt' || id === 'ks' || id === 'bl' || id === 'wx';
|
|
}
|
|
}
|
|
|