Implementar Web Share Target API para compartir fotos con la PWA
Some checks failed
build-and-deploy / build-and-deploy (push) Has been cancelled
- Agregar share_target al manifest de la PWA - Crear endpoint /api/share-target para recibir archivos compartidos - Guardar archivos temporalmente en /public/temp-shared - Modificar UserProfileForm para aceptar imágenes externas - Detectar automáticamente imágenes compartidas y procesarlas - Crear endpoint /api/share-target/cleanup para limpiar temporales - Mostrar toast informativo al recibir imagen compartida - Redirigir automáticamente al formulario de perfil - Soportar compartir desde galería, otras apps, etc.
BIN
pwa_assets/icons/icon-128x128.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
pwa_assets/icons/icon-144x144.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
pwa_assets/icons/icon-152x152.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
pwa_assets/icons/icon-192x192.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
pwa_assets/icons/icon-256x256.png
Normal file
|
After Width: | Height: | Size: 76 KiB |
BIN
pwa_assets/icons/icon-384x384.png
Normal file
|
After Width: | Height: | Size: 173 KiB |
BIN
pwa_assets/icons/icon-512x512.png
Normal file
|
After Width: | Height: | Size: 323 KiB |
BIN
pwa_assets/icons/icon-72x72.png
Normal file
|
After Width: | Height: | Size: 8.5 KiB |
BIN
pwa_assets/icons/icon-96x96.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
30
pwa_assets/index.html
Normal file
@@ -0,0 +1,30 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<!-- El manifest proporciona información sobre el nombre, iconos y URL de inicio de la app 【407831617096888†L240-L248】. -->
|
||||
<link rel="manifest" href="manifest.json">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
<title>DayNight PWA</title>
|
||||
<link rel="icon" href="icons/icon-192x192.png" sizes="192x192">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Bienvenido a la app DayNight PWA</h1>
|
||||
<p>Esta es una versión instalable de la app con soporte offline.</p>
|
||||
|
||||
<script>
|
||||
// Registramos el service worker para habilitar caché y funcionalidad offline【407555884650804†L205-L213】.
|
||||
if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', function() {
|
||||
navigator.serviceWorker.register('/sw.js')
|
||||
.then(function(reg) {
|
||||
console.log('Service worker registrado con scope:', reg.scope);
|
||||
}).catch(function(err) {
|
||||
console.error('Error al registrar el service worker:', err);
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
22
pwa_assets/manifest.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "DayNight PWA",
|
||||
"short_name": "DayNight",
|
||||
"description": "Aplicación de ejemplo PWA instalable y offline.",
|
||||
"id": "/",
|
||||
"start_url": "/index.html",
|
||||
"scope": "/",
|
||||
"display": "standalone",
|
||||
"background_color": "#ffffff",
|
||||
"theme_color": "#ffffff",
|
||||
"icons": [
|
||||
{ "src": "icons/icon-72x72.png", "sizes": "72x72", "type": "image/png" },
|
||||
{ "src": "icons/icon-96x96.png", "sizes": "96x96", "type": "image/png" },
|
||||
{ "src": "icons/icon-128x128.png", "sizes": "128x128", "type": "image/png" },
|
||||
{ "src": "icons/icon-144x144.png", "sizes": "144x144", "type": "image/png" },
|
||||
{ "src": "icons/icon-152x152.png", "sizes": "152x152", "type": "image/png" },
|
||||
{ "src": "icons/icon-192x192.png", "sizes": "192x192", "type": "image/png", "purpose": "any maskable" },
|
||||
{ "src": "icons/icon-256x256.png", "sizes": "256x256", "type": "image/png" },
|
||||
{ "src": "icons/icon-384x384.png", "sizes": "384x384", "type": "image/png" },
|
||||
{ "src": "icons/icon-512x512.png", "sizes": "512x512", "type": "image/png", "purpose": "any maskable" }
|
||||
]
|
||||
}
|
||||
65
pwa_assets/sw.js
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
Service worker para la app DayNight. Este script cachea recursos estáticos
|
||||
durante la instalación para que se puedan servir sin conexión. Según MDN, en
|
||||
el evento de instalación se deben abrir los caches y agregar recursos con
|
||||
`addAll()`【407555884650804†L360-L410】, y luego interceptar las peticiones y
|
||||
responder desde el cache cuando sea posible【407555884650804†L205-L213】.
|
||||
*/
|
||||
|
||||
const CACHE_NAME = 'daynight-cache-v1';
|
||||
const ASSETS = [
|
||||
'/',
|
||||
'/index.html',
|
||||
'/manifest.json',
|
||||
'/icons/icon-72x72.png',
|
||||
'/icons/icon-96x96.png',
|
||||
'/icons/icon-128x128.png',
|
||||
'/icons/icon-144x144.png',
|
||||
'/icons/icon-152x152.png',
|
||||
'/icons/icon-192x192.png',
|
||||
'/icons/icon-256x256.png',
|
||||
'/icons/icon-384x384.png',
|
||||
'/icons/icon-512x512.png'
|
||||
];
|
||||
|
||||
self.addEventListener('install', (event) => {
|
||||
event.waitUntil(
|
||||
caches.open(CACHE_NAME).then((cache) => {
|
||||
return cache.addAll(ASSETS);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
self.addEventListener('activate', (event) => {
|
||||
event.waitUntil(
|
||||
caches.keys().then((names) => {
|
||||
return Promise.all(
|
||||
names.map((name) => {
|
||||
if (name !== CACHE_NAME) {
|
||||
return caches.delete(name);
|
||||
}
|
||||
})
|
||||
);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
self.addEventListener('fetch', (event) => {
|
||||
event.respondWith(
|
||||
caches.match(event.request).then((cached) => {
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
return fetch(event.request).then((networkResponse) => {
|
||||
if (!networkResponse || networkResponse.status !== 200 || networkResponse.type !== 'basic') {
|
||||
return networkResponse;
|
||||
}
|
||||
const responseClone = networkResponse.clone();
|
||||
caches.open(CACHE_NAME).then((cache) => {
|
||||
cache.put(event.request, responseClone);
|
||||
});
|
||||
return networkResponse;
|
||||
});
|
||||
})
|
||||
);
|
||||
});
|
||||