Prevent blob eviction: store as ArrayBuffer + request persistence
iOS Safari evicts Blob file-backed data from IndexedDB under memory pressure, causing upload POSTs to throw 'Load failed' without ever reaching the server. Two-pronged fix: 1. Store photos as ArrayBuffer (inline bytes) instead of Blob (file reference) in IndexedDB — ArrayBuffers are not subject to eviction 2. Request navigator.storage.persist() to signal the browser not to evict our storage under pressure Also adds Storage.getBlob() helper for converting stored ArrayBuffer back to Blob at upload/display time, with backward compat for any existing Blob-stored photos. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -452,9 +452,10 @@ function createQueueItem(photo, isCompleted) {
|
||||
// Create thumbnail (use placeholder if blob was stripped)
|
||||
const thumbnail = document.createElement('div');
|
||||
thumbnail.className = 'queue-item-thumbnail';
|
||||
if (photo.blob && photo.blob.size > 0) {
|
||||
const photoBlob = Storage.getBlob(photo);
|
||||
if (photoBlob && photoBlob.size > 0) {
|
||||
const img = document.createElement('img');
|
||||
img.src = URL.createObjectURL(photo.blob);
|
||||
img.src = URL.createObjectURL(photoBlob);
|
||||
thumbnail.appendChild(img);
|
||||
} else {
|
||||
thumbnail.innerHTML = '<span class="thumbnail-placeholder">' +
|
||||
@@ -472,8 +473,8 @@ function createQueueItem(photo, isCompleted) {
|
||||
const meta = document.createElement('div');
|
||||
meta.className = 'queue-item-meta';
|
||||
const date = new Date(photo.completedAt || photo.timestamp).toLocaleString();
|
||||
if (photo.blob && photo.blob.size > 0) {
|
||||
const size = (photo.blob.size / 1024 / 1024).toFixed(2);
|
||||
if (photoBlob && photoBlob.size > 0) {
|
||||
const size = (photoBlob.size / 1024 / 1024).toFixed(2);
|
||||
meta.textContent = size + ' MB \u2022 ' + date;
|
||||
} else {
|
||||
meta.textContent = date;
|
||||
@@ -552,8 +553,9 @@ async function updateStats() {
|
||||
const pendingCount = photos.filter(p => p.status === 'pending').length;
|
||||
const uploadingCount = photos.filter(p => p.status === 'uploading').length;
|
||||
const totalSize = photos
|
||||
.filter(p => p.blob && p.blob.size)
|
||||
.reduce((sum, p) => sum + p.blob.size, 0) / 1024 / 1024;
|
||||
.map(p => Storage.getBlob(p))
|
||||
.filter(b => b && b.size)
|
||||
.reduce((sum, b) => sum + b.size, 0) / 1024 / 1024;
|
||||
|
||||
document.getElementById('pending-stat').textContent = pendingCount;
|
||||
document.getElementById('uploading-stat').textContent = uploadingCount;
|
||||
|
||||
Reference in New Issue
Block a user