Feature: Kamera-Fotos im Tagebuch in Mediathek speichern anbieten
Nach capture-Aufnahmen erscheint Button 'Zum Fotoalbum hinzufügen'. Nutzt Web Share API (iOS/Android) mit <a download> als Fallback. UI.saveToAlbum() als wiederverwendbare Utility in ui.js. SW by-v200, APP_VER 168.
This commit is contained in:
parent
8fdca1f211
commit
e97bd744e9
4 changed files with 64 additions and 3 deletions
|
|
@ -3,7 +3,7 @@
|
|||
Router, State-Management, Navigation, Initialisierung.
|
||||
============================================================ */
|
||||
|
||||
const APP_VER = '167'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
|
||||
const APP_VER = '168'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
|
||||
|
||||
const App = (() => {
|
||||
|
||||
|
|
|
|||
|
|
@ -643,13 +643,37 @@ window.Page_diary = (() => {
|
|||
}
|
||||
}
|
||||
|
||||
mediaInput?.addEventListener('change', () => _showPreview(mediaInput.files[0]));
|
||||
function _showAlbumBtn(file) {
|
||||
// Vorherigen Button entfernen falls vorhanden
|
||||
document.getElementById('diary-save-album-btn')?.remove();
|
||||
// Nur anbieten wenn Share-API File-Support hat ODER als Download-Fallback
|
||||
const canShare = navigator.canShare && navigator.canShare({ files: [file] });
|
||||
const canDownload = true; // <a download> funktioniert immer als Fallback
|
||||
if (!canShare && !canDownload) return;
|
||||
const btn = document.createElement('button');
|
||||
btn.type = 'button';
|
||||
btn.id = 'diary-save-album-btn';
|
||||
btn.className = 'btn btn-secondary btn-sm';
|
||||
btn.style.cssText = 'display:flex;align-items:center;gap:var(--space-1);margin-top:var(--space-2);width:100%';
|
||||
btn.innerHTML = `<svg class="ph-icon" aria-hidden="true"><use href="/icons/phosphor.svg#images"></use></svg>
|
||||
<span>${canShare ? 'Zum Fotoalbum hinzufügen' : 'Foto herunterladen'}</span>`;
|
||||
btn.addEventListener('click', () => UI.saveToAlbum(file));
|
||||
previewWrap.after(btn);
|
||||
}
|
||||
|
||||
mediaInput?.addEventListener('change', () => {
|
||||
_showPreview(mediaInput.files[0]);
|
||||
// Kein Album-Button bei Mediathek-Picks (Fotos sind bereits dort)
|
||||
document.getElementById('diary-save-album-btn')?.remove();
|
||||
});
|
||||
cameraInput?.addEventListener('change', () => {
|
||||
// Auswahl in mediaInput spiegeln damit Submit-Handler nur einen Ort abfragt
|
||||
const dt = new DataTransfer();
|
||||
if (cameraInput.files[0]) dt.items.add(cameraInput.files[0]);
|
||||
mediaInput.files = dt.files;
|
||||
_showPreview(cameraInput.files[0]);
|
||||
// Album-Button nach Kamera-Aufnahme anzeigen
|
||||
if (cameraInput.files[0]) _showAlbumBtn(cameraInput.files[0]);
|
||||
});
|
||||
|
||||
document.getElementById('diary-btn-camera') ?.addEventListener('click', () => cameraInput.click());
|
||||
|
|
@ -677,6 +701,7 @@ window.Page_diary = (() => {
|
|||
previewWrap.style.display = 'none';
|
||||
photoPreview.src = ''; videoPreview.src = '';
|
||||
mediaInput.value = '';
|
||||
document.getElementById('diary-save-album-btn')?.remove();
|
||||
});
|
||||
|
||||
// "Entfernen"-Button löscht Medium direkt
|
||||
|
|
|
|||
|
|
@ -307,6 +307,41 @@ const UI = (() => {
|
|||
if (parseFloat(tip.style.left) > maxL) tip.style.left = maxL + 'px';
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// SAVE TO ALBUM — Foto/Video nach Kamera-Aufnahme in Mediathek
|
||||
// anbieten. Nur bei capture-Aufnahmen aufrufen (nicht Galerie).
|
||||
// Nutzt Web Share API wenn verfügbar, sonst <a download> Fallback.
|
||||
// ----------------------------------------------------------
|
||||
async function saveToAlbum(file) {
|
||||
if (!file) return;
|
||||
|
||||
// Web Share API mit Datei-Support (iOS Safari 15+, Chrome Android)
|
||||
if (navigator.canShare && navigator.canShare({ files: [file] })) {
|
||||
try {
|
||||
await navigator.share({
|
||||
files: [file],
|
||||
title: file.name || 'Foto',
|
||||
});
|
||||
} catch (err) {
|
||||
// AbortError = User hat Sheet geschlossen — kein Fehler anzeigen
|
||||
if (err?.name !== 'AbortError') {
|
||||
console.warn('saveToAlbum share error:', err);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Fallback: direkter Download per <a download>
|
||||
const url = URL.createObjectURL(file);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = file.name || ('foto_' + Date.now() + (file.type === 'video/mp4' ? '.mp4' : '.jpg'));
|
||||
a.style.display = 'none';
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
setTimeout(() => { URL.revokeObjectURL(url); a.remove(); }, 2000);
|
||||
}
|
||||
|
||||
// Öffentliche API
|
||||
return {
|
||||
toast, modal,
|
||||
|
|
@ -316,6 +351,7 @@ const UI = (() => {
|
|||
setupPhotoPreview, scrollTop, skeleton,
|
||||
icon: _svgIcon,
|
||||
escape, help,
|
||||
saveToAlbum,
|
||||
};
|
||||
|
||||
})();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue