Files
Genarrative/apps/mobile-shell/src/host-bridge/share.ts
T
kdletters 05d278f8f7 收口移动壳能力诊断日志
移动壳 HostBridge 能力失败日志只记录稳定阶段标签

更新 badge notification haptics network share navigation 失败测试断言

扩展移动壳配置门禁禁止能力日志打印原生 error 对象

补充 Expo 与 Tauri 宿主壳方案中的移动诊断日志边界
2026-06-20 23:09:49 +08:00

81 lines
2.3 KiB
TypeScript

import { Share } from 'react-native';
import {
type HostBridgeError,
type HostBridgeRequest,
normalizeHostBridgeShareOpenPayload,
type ShareOpenPayload,
} from '../../../../packages/shared/src/contracts/hostBridge';
import { invalidRequest, ok } from './protocol';
let currentShareTarget: ShareOpenPayload | null = null;
function logMobileShareFailure(label: string, _error: unknown) {
console.warn(`mobile share failed for ${label}`);
}
export function setMobileHostBridgeShareTarget(request: HostBridgeRequest) {
const payload = request.payload;
const target =
payload && typeof payload === 'object'
? (payload as { target?: unknown }).target
: undefined;
if (target === undefined) {
throw invalidRequest('target is required');
}
const normalizedTarget = normalizeHostBridgeShareOpenPayload(target);
if (normalizedTarget.status !== 'valid') {
throw invalidRequest(
normalizedTarget.status === 'invalid'
? 'share target is invalid'
: 'share target is required',
);
}
currentShareTarget = normalizedTarget.payload;
return ok(request, true);
}
export function resetMobileHostBridgeShareTargetForTest() {
currentShareTarget = null;
}
export async function openShare(request: HostBridgeRequest) {
const explicitPayload = normalizeHostBridgeShareOpenPayload(request.payload);
if (explicitPayload.status === 'invalid') {
throw invalidRequest('share target is invalid');
}
const cachedPayload =
explicitPayload.status === 'valid'
? explicitPayload
: normalizeHostBridgeShareOpenPayload(currentShareTarget);
if (cachedPayload.status === 'invalid') {
throw invalidRequest('share target is invalid');
}
const sharePayload =
cachedPayload.status === 'valid' ? cachedPayload.payload : undefined;
if (!sharePayload) {
throw invalidRequest('share target is required');
}
const url = sharePayload?.url;
const message = [sharePayload?.message, url].filter(Boolean).join('\n');
try {
await Share.share({
title: sharePayload?.title,
message: message || url || sharePayload?.title || '',
url,
});
} catch (error) {
logMobileShareFailure('open.share', error);
throw {
code: 'host_error',
message: 'share unavailable',
} satisfies HostBridgeError;
}
return ok(request, true);
}