Feature: Obtener iconos automáticamente de las aplicaciones
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 54s
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 54s
- Intentar meta_icon de Authentik primero - Buscar apple-touch-icon.png del dominio (PWA) - Intentar favicon.ico como fallback - Mostrar icono por defecto si todo falla - Sistema de retry inteligente para evitar requests duplicados
This commit is contained in:
@@ -57,10 +57,12 @@
|
||||
>
|
||||
<div class="app-card-content">
|
||||
<div class="app-icon">
|
||||
<UIcon
|
||||
v-if="app.icon"
|
||||
:name="app.icon"
|
||||
class="w-7 h-7"
|
||||
<img
|
||||
v-if="getAppIconUrl(app)"
|
||||
:src="getAppIconUrl(app)"
|
||||
:alt="app.name"
|
||||
class="w-7 h-7 object-contain"
|
||||
@error="handleIconError($event, app)"
|
||||
/>
|
||||
<UIcon
|
||||
v-else
|
||||
@@ -123,6 +125,65 @@ const { data: applications, pending, error, refresh } = await useFetch<Applicati
|
||||
// Estado de filtros
|
||||
const selectedGroups = ref<string[]>([])
|
||||
|
||||
// Estado para iconos fallidos (para no intentar cargarlos de nuevo)
|
||||
const failedIcons = ref<Set<string>>(new Set())
|
||||
|
||||
// Función para obtener la URL del icono de una app
|
||||
const getAppIconUrl = (app: Application): string | null => {
|
||||
// Si el icono ya falló, no intentar de nuevo
|
||||
if (failedIcons.value.has(app.pk)) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Si tiene meta_icon de Authentik, usarlo
|
||||
if (app.icon) {
|
||||
// Si es una URL completa
|
||||
if (app.icon.startsWith('http://') || app.icon.startsWith('https://')) {
|
||||
return app.icon
|
||||
}
|
||||
// Si es una ruta relativa, usar el dominio de la app
|
||||
try {
|
||||
const url = new URL(app.launchUrl)
|
||||
return `${url.origin}${app.icon.startsWith('/') ? '' : '/'}${app.icon}`
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
// Intentar obtener el favicon de la URL
|
||||
try {
|
||||
const url = new URL(app.launchUrl)
|
||||
// Intentar primero apple-touch-icon (suele ser de mejor calidad)
|
||||
return `${url.origin}/apple-touch-icon.png`
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
// Manejar error al cargar icono
|
||||
const handleIconError = (event: Event, app: Application) => {
|
||||
const imgElement = event.target as HTMLImageElement
|
||||
const currentSrc = imgElement.src
|
||||
|
||||
// Marcar como fallido
|
||||
failedIcons.value.add(app.pk)
|
||||
|
||||
// Si estábamos intentando apple-touch-icon, intentar favicon.ico
|
||||
if (currentSrc.includes('apple-touch-icon')) {
|
||||
try {
|
||||
const url = new URL(app.launchUrl)
|
||||
imgElement.src = `${url.origin}/favicon.ico`
|
||||
failedIcons.value.delete(app.pk) // Dar otra oportunidad
|
||||
return
|
||||
} catch {
|
||||
// Si falla, el v-else mostrará el icono por defecto
|
||||
}
|
||||
}
|
||||
|
||||
// Ocultar la imagen para que se muestre el icono por defecto
|
||||
imgElement.style.display = 'none'
|
||||
}
|
||||
|
||||
// Extraer todos los grupos únicos de las aplicaciones
|
||||
const availableGroups = computed(() => {
|
||||
const groups = new Set<string>()
|
||||
|
||||
Reference in New Issue
Block a user