mirror of
https://github.com/alexta69/metube.git
synced 2026-06-13 16:40:05 +00:00
feat(ui): warn before share + surface failures for large files
Web Share fails silently when iOS' share sheet refuses the payload, typically because the file exceeds the platform's soft size limit (~50–100 MB depending on iOS version). The previous patch logged to the console but the user saw nothing — staring at a button that 'does nothing' is poor UX. Adds two layers of feedback: 1. Pre-flight size check (SHARE_SIZE_WARN_BYTES = 80 MB, conservative relative to iOS' actual limit) with a confirm() dialog before the fetch. Avoids spending bandwidth pulling a 150 MB blob into the browser only for navigator.canShare to reject it. 2. Surfaces canShare-rejection AND share()-failure as a visible alert() suggesting the user fall back to the download link next to the share button. Tested locally with files from 0.7 MB up to 150.7 MB: small files share unchanged, the 150 MB file now produces a pre-flight warning the user can dismiss, and any subsequent rejection produces a clear alert instead of silently no-op'ing.
This commit is contained in:
+34
-8
@@ -1203,10 +1203,28 @@ export class App implements AfterViewInit, OnInit, OnDestroy {
|
|||||||
&& typeof navigator.canShare === 'function';
|
&& typeof navigator.canShare === 'function';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Conservative warning threshold for the share sheet — iOS' actual
|
||||||
|
// refusal limit varies between ~50 MB (older versions) and ~150 MB
|
||||||
|
// (recent ones). 80 MB warns the user before the time-wasting fetch+
|
||||||
|
// copy of a too-large file that the platform will then reject.
|
||||||
|
private static readonly SHARE_SIZE_WARN_BYTES = 80 * 1024 * 1024;
|
||||||
|
|
||||||
async shareDownload(download: Download): Promise<void> {
|
async shareDownload(download: Download): Promise<void> {
|
||||||
if (!this.canShareDownloads()) {
|
if (!this.canShareDownloads()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Pre-flight size check: warn the user about the iOS share-sheet
|
||||||
|
// soft-fail on large files, before we spend time fetching the whole
|
||||||
|
// file into memory only to have navigator.canShare reject it.
|
||||||
|
if (download.size && download.size > App.SHARE_SIZE_WARN_BYTES) {
|
||||||
|
const sizeMb = Math.round(download.size / 1024 / 1024);
|
||||||
|
const proceed = window.confirm(
|
||||||
|
`This file is ${sizeMb} MB. iOS' share sheet often refuses files ` +
|
||||||
|
`larger than ~100 MB and the share will silently fail. ` +
|
||||||
|
`Try anyway? (Use the download button instead if it fails.)`
|
||||||
|
);
|
||||||
|
if (!proceed) return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const response = await fetch(this.buildDownloadLink(download));
|
const response = await fetch(this.buildDownloadLink(download));
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
@@ -1218,20 +1236,28 @@ export class App implements AfterViewInit, OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
const payload: ShareData = { files: [file], title: download.title };
|
const payload: ShareData = { files: [file], title: download.title };
|
||||||
if (!navigator.canShare(payload)) {
|
if (!navigator.canShare(payload)) {
|
||||||
// File type not shareable on this platform (e.g. desktop browsers,
|
// The platform refused the payload — most commonly because the
|
||||||
// or some MIME types iOS refuses). Bail out so the user can still
|
// file is too large for the iOS share sheet, or the MIME type
|
||||||
// use the regular download button right next to this one.
|
// isn't accepted. Tell the user so they can fall back to the
|
||||||
|
// download button right next to this one instead of staring at
|
||||||
|
// a button that quietly did nothing.
|
||||||
console.warn('navigator.canShare rejected payload for', download.filename);
|
console.warn('navigator.canShare rejected payload for', download.filename);
|
||||||
|
window.alert(
|
||||||
|
`Your device's share sheet doesn't accept this file ` +
|
||||||
|
`(most likely because it's too large). ` +
|
||||||
|
`Please use the download button instead.`
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await navigator.share(payload);
|
await navigator.share(payload);
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
// AbortError = user dismissed the share sheet → silent no-op.
|
// AbortError = user dismissed the share sheet → silent no-op.
|
||||||
// Other errors (network, file too big, …) get logged but we don't
|
if (err?.name === 'AbortError') return;
|
||||||
// surface a UI error: the regular download link remains a fallback.
|
console.error('Share failed:', err);
|
||||||
if (err?.name !== 'AbortError') {
|
window.alert(
|
||||||
console.error('Share failed:', err);
|
`Share failed: ${err?.message || 'unknown error'}. ` +
|
||||||
}
|
`Please use the download button instead.`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user