Some checks failed
PR Preview / teardown-preview (pull_request) Has been skipped
Test / unit-test (push) Successful in 6s
Test / build-check (push) Successful in 3s
PR Preview / test (pull_request) Successful in 5s
PR Preview / deploy-preview (pull_request) Successful in 13s
Test / e2e-test (push) Failing after 53s
- html2canvas 参数: backgroundColor=null, scale=3, allowTaint=false (与 RecipeDetailOverlay.generateCardImage 完全一致) - useSaveImage 精简为只有 share + download 两条路径 - 截图失败时显示具体错误信息便于调试 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
39 lines
1.2 KiB
JavaScript
39 lines
1.2 KiB
JavaScript
/**
|
|
* Save image — on mobile use navigator.share (same as recipe card),
|
|
* on desktop trigger download.
|
|
*/
|
|
|
|
const isMobile = () => /iPhone|iPad|iPod|Android/i.test(navigator.userAgent)
|
|
|
|
/**
|
|
* Save from a data URL.
|
|
* Mobile: navigator.share({files}) → system share sheet (save to photos / AirDrop etc)
|
|
* Desktop: download link.
|
|
*/
|
|
export async function saveImageFromUrl(dataUrl, filename) {
|
|
// Try navigator.share with files (works on iOS Safari, Chrome mobile)
|
|
if (navigator.share && navigator.canShare) {
|
|
try {
|
|
const res = await fetch(dataUrl)
|
|
const blob = await res.blob()
|
|
const file = new File([blob], filename + '.png', { type: 'image/png' })
|
|
if (navigator.canShare({ files: [file] })) {
|
|
await navigator.share({ files: [file] })
|
|
return 'shared'
|
|
}
|
|
} catch (e) {
|
|
// User cancelled share or share failed, fall through to download
|
|
if (e.name === 'AbortError') return 'cancelled'
|
|
}
|
|
}
|
|
|
|
// Fallback: direct download
|
|
const a = document.createElement('a')
|
|
a.href = dataUrl
|
|
a.download = filename + '.png'
|
|
document.body.appendChild(a)
|
|
a.click()
|
|
setTimeout(() => a.remove(), 100)
|
|
return 'downloaded'
|
|
}
|