Files
pictureFrame-webApp/public/build/assets/LibraryView-VsVWZmi0.css
T
football2801 82a42011d8
CI / test (push) Has been cancelled
fix(upload): persistent file <input> to survive iOS PWA cold launch
A dynamically-created <input type="file"> that's never attached to the
DOM drops its first `change` event on a cold-launched iOS PWA — the
native photo picker resolves out of the original user-gesture context
and the closure that captured the input is gone. Symptom Matt hit
2026-05-14: first image-pick after hard-close + reopen of the PWA
silently failed to advance to the crop tool; the second attempt worked.

HomeView and LibraryView now keep a hidden <input ref="fileInputEl"
type="file"> live in their templates. onAddPhoto clicks that input
inside the user-gesture context; @change fires reliably even on cold
launches. The picker resets input.value between selections so picking
the same file twice still fires.

Tests updated to query the template input via wrapper.find() instead
of stubbing document.createElement; 347/347 frontend tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 13:02:26 -04:00

2 lines
6.9 KiB
CSS

.approve-card[data-v-6d3dd8b4]{gap:var(--space-3);padding:var(--space-3);background:var(--color-surface);border:1px solid var(--color-border);border-radius:var(--radius-md);display:flex}.approve-card__thumb[data-v-6d3dd8b4]{object-fit:cover;border-radius:var(--radius-sm);background:var(--color-border);flex-shrink:0;width:80px;height:80px}.approve-card__body[data-v-6d3dd8b4]{gap:var(--space-1);flex-direction:column;flex:1;display:flex}.approve-card__from[data-v-6d3dd8b4]{font-size:var(--text-sm)}.approve-card__date[data-v-6d3dd8b4]{font-size:var(--text-xs);color:var(--color-text-muted)}.approve-card__badge[data-v-6d3dd8b4]{font-size:var(--text-xs);text-transform:capitalize;border-radius:999px;padding:2px 8px;font-weight:600;display:inline-block}.approve-card__badge--approved[data-v-6d3dd8b4]{color:#1a7f4b;background:#d4edda}.approve-card__badge--declined[data-v-6d3dd8b4]{color:#d93025;background:#fde8e8}.approve-card__actions[data-v-6d3dd8b4]{gap:var(--space-2);flex-wrap:wrap;margin-top:auto;display:flex}.share-sheet__title[data-v-24296e7b]{font-size:var(--text-md);margin-bottom:var(--space-1);font-weight:700}.share-sheet__sub[data-v-24296e7b]{font-size:var(--text-sm);color:var(--color-text-muted);margin-bottom:var(--space-4)}.share-sheet__field[data-v-24296e7b]{margin-bottom:var(--space-3)}.share-sheet__input[data-v-24296e7b]{width:100%;min-height:var(--touch-min);padding:0 var(--space-3);border:1.5px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-surface);color:var(--color-text);font-size:var(--text-sm);font-family:inherit}.share-sheet__input[data-v-24296e7b]:focus{outline:2px solid var(--color-primary);outline-offset:2px}.share-sheet__error[data-v-24296e7b]{font-size:var(--text-sm);color:var(--color-danger,#d93025);margin-bottom:var(--space-3)}.share-sheet__success[data-v-24296e7b]{font-size:var(--text-sm);color:var(--color-success,#1a7f4b);margin-bottom:var(--space-3)}.share-sheet__btn[data-v-24296e7b]{width:100%}.library[data-v-010dc991]{padding-bottom:calc(var(--bottom-nav-height) + var(--space-4))}.library__header[data-v-010dc991]{padding:var(--space-4) var(--space-4) var(--space-3)}.library__add-btn[data-v-010dc991]{width:100%}.library__tabs[data-v-010dc991]{border-bottom:1px solid var(--color-border);top:env(safe-area-inset-top);background:var(--color-bg);z-index:5;display:flex;position:sticky}.library__tab[data-v-010dc991]{padding:var(--space-3) 0;font-size:var(--text-sm);color:var(--color-text-muted);cursor:pointer;transition:all var(--duration-fast);background:0 0;border:none;border-bottom:2px solid #0000;flex:1;font-weight:600}.library__tab--active[data-v-010dc991]{color:var(--color-primary);border-bottom-color:var(--color-primary)}.library__loading[data-v-010dc991]{color:var(--color-text-muted);font-size:var(--text-sm);padding:var(--space-4);text-align:center}.library__subtabs[data-v-010dc991]{border-bottom:1px solid var(--color-border);background:var(--color-bg);display:flex}.library__subtab[data-v-010dc991]{padding:var(--space-2) 0;font-size:var(--text-xs);color:var(--color-text-muted);cursor:pointer;transition:all var(--duration-fast);background:0 0;border:none;border-bottom:2px solid #0000;flex:1;font-weight:600}.library__subtab--active[data-v-010dc991]{color:var(--color-primary);border-bottom-color:var(--color-primary)}.library__shared-list[data-v-010dc991]{gap:var(--space-3);padding:var(--space-4);flex-direction:column;display:flex}.library__pagination[data-v-010dc991]{justify-content:center;align-items:center;gap:var(--space-3);padding:var(--space-4);display:flex}.library__page-btn[data-v-010dc991]{padding:var(--space-2) var(--space-3);border:1.5px solid var(--color-border);border-radius:var(--radius-md);font-size:var(--text-sm);color:var(--color-text);cursor:pointer;background:0 0;font-weight:600}.library__page-btn[data-v-010dc991]:disabled{opacity:.4;cursor:default}.library__page-info[data-v-010dc991]{font-size:var(--text-sm);color:var(--color-text-muted)}.library__empty[data-v-010dc991],.library__shared-empty[data-v-010dc991]{align-items:center;gap:var(--space-3);padding:var(--space-6) var(--space-4);color:var(--color-text-muted);text-align:center;flex-direction:column;display:flex}.library__empty-title[data-v-010dc991]{font-size:var(--text-md);color:var(--color-text);font-weight:700}.library__empty-sub[data-v-010dc991]{font-size:var(--text-sm);max-width:280px;line-height:1.5}.library__grid[data-v-010dc991]{gap:var(--space-3);padding:var(--space-4);grid-template-columns:repeat(2,1fr);display:grid}.library__item[data-v-010dc991]{gap:var(--space-2);flex-direction:column;display:flex}.library__thumb[data-v-010dc991]{aspect-ratio:4/3;border-radius:var(--radius-sm);background:var(--color-surface-2);position:relative;overflow:hidden}.library__img[data-v-010dc991]{object-fit:cover;width:100%;height:100%;display:block}.library__thumb-actions[data-v-010dc991]{top:var(--space-2);right:var(--space-2);gap:4px;display:flex;position:absolute}.library__action-btn[data-v-010dc991]{cursor:pointer;color:#fff;width:28px;height:28px;transition:background var(--duration-fast);background:#0000008c;border:none;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;display:flex}.library__action-btn[data-v-010dc991]:disabled{opacity:.5;cursor:default}.library__action-btn[data-v-010dc991]:hover:not(:disabled){background:#000000bf}.library__action-btn--danger[data-v-010dc991]:hover:not(:disabled){background:#b40000cc}.library__action-btn--warn[data-v-010dc991]{background:var(--color-warning,#f59e0b)}.library__action-btn--warn[data-v-010dc991]:hover:not(:disabled){background:color-mix(in srgb, var(--color-warning,#f59e0b) 85%, black)}.library__approvals[data-v-010dc991]{gap:var(--space-1);flex-wrap:wrap;display:flex}.library__approval-chip[data-v-010dc991]{border:1.5px solid var(--color-border);font-size:var(--text-xs,11px);cursor:pointer;color:var(--color-text-muted);transition:all var(--duration-fast);background:0 0;border-radius:999px;padding:3px 10px;font-weight:600}.library__approval-chip--on[data-v-010dc991]{background:var(--color-primary);border-color:var(--color-primary);color:#fff}.library__locks[data-v-010dc991]{gap:var(--space-1);flex-wrap:wrap;display:flex}.library__lock-chip[data-v-010dc991]{border:1.5px dashed var(--color-border);font-size:var(--text-xs,11px);cursor:pointer;color:var(--color-text-muted);transition:all var(--duration-fast);background:0 0;border-radius:999px;align-items:center;gap:4px;padding:3px 8px;font-weight:600;display:flex}.library__lock-chip--on[data-v-010dc991]{background:var(--color-warning,#f59e0b);border-color:var(--color-warning,#f59e0b);color:#fff;border-style:solid}.library__sheet-title[data-v-010dc991]{font-size:var(--text-md);margin-bottom:var(--space-2);font-weight:700}.library__sheet-sub[data-v-010dc991]{font-size:var(--text-sm);color:var(--color-text-muted);margin-bottom:var(--space-5)}.library__sheet-actions[data-v-010dc991]{gap:var(--space-3);display:flex}.library__sheet-actions[data-v-010dc991]>*{flex:1}