接入原生壳分享卡图片导出
新增 file.exportImage 宿主能力契约 分享卡下载在原生壳中优先走宿主图片导出 Expo 壳写入缓存图片并调用系统分享保存 Tauri 壳通过保存对话框写入图片字节 补齐能力漂移检查、测试和架构文档
This commit is contained in:
@@ -6,6 +6,7 @@ import type { HostBridgeCapability } from '../../../packages/shared/src/contract
|
||||
import {
|
||||
canUseHostShareGrid,
|
||||
canUseNativeHostCapability,
|
||||
exportHostImageFile,
|
||||
exportHostTextFile,
|
||||
getHostRuntime,
|
||||
getNativeAppHostRuntime,
|
||||
@@ -443,6 +444,7 @@ describe('hostBridge', () => {
|
||||
'app.openExternalUrl',
|
||||
'app.setTitle',
|
||||
'share.open',
|
||||
'file.exportImage',
|
||||
]),
|
||||
);
|
||||
window.__TAURI__ = {
|
||||
@@ -482,6 +484,13 @@ describe('hostBridge', () => {
|
||||
url: 'https://app.genarrative.world/works/detail?work=PZ-1',
|
||||
}),
|
||||
).resolves.toBe(true);
|
||||
await expect(
|
||||
exportHostImageFile({
|
||||
fileName: '分享卡.png',
|
||||
base64Data: 'c2hhcmUtY2FyZA==',
|
||||
mimeType: 'image/png',
|
||||
}),
|
||||
).resolves.toBe(true);
|
||||
|
||||
expect(invoke).toHaveBeenCalledWith('host_bridge_request', {
|
||||
request: expect.objectContaining({
|
||||
@@ -545,6 +554,17 @@ describe('hostBridge', () => {
|
||||
},
|
||||
}),
|
||||
});
|
||||
expect(invoke).toHaveBeenCalledWith('host_bridge_request', {
|
||||
request: expect.objectContaining({
|
||||
method: 'file.exportImage',
|
||||
payload: {
|
||||
fileName: '分享卡.png',
|
||||
base64Data: 'c2hhcmUtY2FyZA==',
|
||||
mimeType: 'image/png',
|
||||
},
|
||||
timeoutMs: 30000,
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
test('原生 App 宿主不支持能力时回退到 H5 路径', async () => {
|
||||
@@ -598,15 +618,29 @@ describe('hostBridge', () => {
|
||||
url: 'https://app.genarrative.world/works/detail?work=PZ-1',
|
||||
}),
|
||||
).resolves.toBe(false);
|
||||
await expect(
|
||||
exportHostImageFile({
|
||||
fileName: '分享卡.png',
|
||||
base64Data: 'c2hhcmUtY2FyZA==',
|
||||
mimeType: 'image/png',
|
||||
}),
|
||||
).resolves.toBe(false);
|
||||
});
|
||||
|
||||
test('普通浏览器不处理宿主文本导出', async () => {
|
||||
test('普通浏览器不处理宿主文件导出', async () => {
|
||||
await expect(
|
||||
exportHostTextFile({
|
||||
fileName: '作品记录.txt',
|
||||
content: 'content',
|
||||
}),
|
||||
).resolves.toBe(false);
|
||||
await expect(
|
||||
exportHostImageFile({
|
||||
fileName: '分享卡.png',
|
||||
base64Data: 'c2hhcmUtY2FyZA==',
|
||||
mimeType: 'image/png',
|
||||
}),
|
||||
).resolves.toBe(false);
|
||||
});
|
||||
|
||||
test('原生 App 宿主通过 HostBridge 导出文本文件', async () => {
|
||||
@@ -694,4 +728,57 @@ describe('hostBridge', () => {
|
||||
}),
|
||||
).resolves.toBe(false);
|
||||
});
|
||||
|
||||
test('原生 App 宿主通过 HostBridge 导出图片文件', async () => {
|
||||
const invoke = vi.fn(
|
||||
async (_command: string, args?: Record<string, unknown>) => {
|
||||
const request = (args as { request: { id: string } }).request;
|
||||
return {
|
||||
bridge: 'GenarrativeHostBridge',
|
||||
version: 1,
|
||||
id: request.id,
|
||||
ok: true,
|
||||
result: {
|
||||
action: 'saved',
|
||||
fileName: '分享卡.png',
|
||||
bytes: 10,
|
||||
},
|
||||
};
|
||||
},
|
||||
);
|
||||
window.history.replaceState(
|
||||
null,
|
||||
'',
|
||||
nativeAppPath(['file.exportImage']),
|
||||
);
|
||||
window.__TAURI__ = {
|
||||
core: {
|
||||
invoke: asTauriInvoke(invoke),
|
||||
},
|
||||
};
|
||||
|
||||
await expect(
|
||||
exportHostImageFile({
|
||||
fileName: '分享卡.png',
|
||||
base64Data: 'c2hhcmUtY2FyZA==',
|
||||
mimeType: 'image/png',
|
||||
}),
|
||||
).resolves.toEqual({
|
||||
action: 'saved',
|
||||
fileName: '分享卡.png',
|
||||
bytes: 10,
|
||||
});
|
||||
|
||||
expect(invoke).toHaveBeenCalledWith('host_bridge_request', {
|
||||
request: expect.objectContaining({
|
||||
method: 'file.exportImage',
|
||||
payload: {
|
||||
fileName: '分享卡.png',
|
||||
base64Data: 'c2hhcmUtY2FyZA==',
|
||||
mimeType: 'image/png',
|
||||
},
|
||||
timeoutMs: 30000,
|
||||
}),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user