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.
This commit is contained in:
2025-10-17 18:29:00 -06:00
parent ced637a7a9
commit 5bb5e5092e
17 changed files with 367 additions and 1 deletions

View File

@@ -420,6 +420,11 @@
const { user } = useAuthentik()
const toast = useToast()
// Props
const props = defineProps<{
sharedImageUrl?: string | null
}>()
// Emits
const emit = defineEmits(['close'])
@@ -544,6 +549,13 @@ if (import.meta.client) {
onUnmounted(() => {
window.removeEventListener('beforeunload', handleBeforeUnload)
})
// Detectar y procesar imagen compartida automáticamente
watch(() => props.sharedImageUrl, async (newUrl) => {
if (newUrl && import.meta.client) {
await processSharedImage(newUrl)
}
}, { immediate: true })
}
// Enviar formulario
@@ -802,6 +814,55 @@ const processImageFile = async (file: File) => {
const blob = new Blob([file], { type: file.type })
await handleAvatarCapture(blob)
}
// Procesar imagen compartida desde Web Share Target
const processSharedImage = async (imageUrl: string) => {
try {
// Mostrar notificación
toast.add({
title: 'Imagen compartida recibida',
description: 'Procesando imagen para tu avatar...',
color: 'info',
icon: 'i-heroicons-photo'
})
// Descargar la imagen del servidor
const response = await fetch(imageUrl)
if (!response.ok) {
throw new Error('No se pudo cargar la imagen compartida')
}
const blob = await response.blob()
// Validar que sea una imagen
if (!blob.type.startsWith('image/')) {
throw new Error('El archivo compartido no es una imagen válida')
}
// Procesar y subir la imagen
await handleAvatarCapture(blob)
// Limpiar archivo temporal del servidor
try {
await $fetch('/api/share-target/cleanup', {
method: 'POST',
body: { imageUrl }
})
} catch (cleanupError) {
console.error('Error limpiando archivo temporal:', cleanupError)
// No es crítico si falla la limpieza
}
} catch (error: any) {
console.error('Error procesando imagen compartida:', error)
toast.add({
title: 'Error',
description: error.message || 'No se pudo procesar la imagen compartida',
color: 'error',
icon: 'i-heroicons-exclamation-triangle'
})
}
}
</script>
<style scoped>