接入原生壳应用角标能力

新增 HostBridge app.setBadgeCount 契约和 H5 能力门控

Expo 壳按平台声明能力并在 iOS 调用系统角标 API

Tauri 壳通过主窗口设置任务栏角标并校验 payload

补齐角标能力测试、漂移检查和架构文档
This commit is contained in:
2026-06-18 01:50:15 +08:00
parent 910625d5e1
commit 6b39bdbe19
15 changed files with 336 additions and 19 deletions

View File

@@ -25,6 +25,7 @@ import {
requestWechatMiniProgramPhoneLogin,
resetHostRuntimeCacheForTest,
resolveHostRuntime,
setHostAppBadgeCount,
setHostAppTitle,
setHostShareTarget,
subscribeHostRuntimeChange,
@@ -443,6 +444,7 @@ describe('hostBridge', () => {
'haptics.impact',
'app.openExternalUrl',
'app.setTitle',
'app.setBadgeCount',
'share.open',
'file.exportImage',
]),
@@ -477,6 +479,7 @@ describe('hostBridge', () => {
await expect(setHostAppTitle({ title: ' 拼图 - 陶泥儿 ' })).resolves.toBe(
true,
);
await expect(setHostAppBadgeCount({ count: 7 })).resolves.toBe(true);
await expect(
openHostShare({
title: '暖灯猫街',
@@ -544,6 +547,14 @@ describe('hostBridge', () => {
},
}),
});
expect(invoke).toHaveBeenCalledWith('host_bridge_request', {
request: expect.objectContaining({
method: 'app.setBadgeCount',
payload: {
count: 7,
},
}),
});
expect(invoke).toHaveBeenCalledWith('host_bridge_request', {
request: expect.objectContaining({
method: 'share.open',
@@ -611,6 +622,9 @@ describe('hostBridge', () => {
false,
);
await expect(setHostAppTitle({ title: ' ' })).resolves.toBe(false);
await expect(setHostAppBadgeCount({ count: 1 })).resolves.toBe(false);
await expect(setHostAppBadgeCount({ count: -1 })).resolves.toBe(false);
await expect(setHostAppBadgeCount({ count: 1.5 })).resolves.toBe(false);
await expect(
openHostShare({
title: '暖灯猫街',

View File

@@ -8,10 +8,12 @@ import type {
HostBridgeMethod,
HostBridgeRuntimeResult,
OpenExternalUrlPayload,
SetBadgeCountPayload,
ShareOpenPayload,
} from '../../../packages/shared/src/contracts/hostBridge';
import {
isHostBridgeCapability,
normalizeHostBridgeBadgeCount,
normalizeHostBridgeExternalUrl,
} from '../../../packages/shared/src/contracts/hostBridge';
import type {
@@ -87,6 +89,8 @@ export type HostAppTitleRequest = {
title: string;
};
export type HostAppBadgeCountRequest = SetBadgeCountPayload;
export type HostShareOpenRequest = ShareOpenPayload;
export type HostExternalUrlRequest = OpenExternalUrlPayload;
@@ -740,3 +744,23 @@ export async function setHostAppTitle({ title }: HostAppTitleRequest) {
return false;
}
}
export async function setHostAppBadgeCount({
count,
}: HostAppBadgeCountRequest) {
const normalizedCount = normalizeHostBridgeBadgeCount(count);
if (
normalizedCount === null ||
!canUseNativeHostCapability('app.setBadgeCount')
) {
return false;
}
try {
return await requestNativeHostBoolean('app.setBadgeCount', {
count: normalizedCount,
});
} catch {
return false;
}
}