diff --git a/packages/app/src/components/content/ImageCard.vue b/packages/app/src/components/content/ImageCard.vue
index 744572e2..b9ab1ce3 100644
--- a/packages/app/src/components/content/ImageCard.vue
+++ b/packages/app/src/components/content/ImageCard.vue
@@ -18,13 +18,9 @@
/>
+ class="w-full h-full bg-cover bg-center"
+ :style="{ backgroundImage: `url(${fallbackImg})` }"
+ />
@@ -45,13 +41,18 @@
diff --git a/packages/app/src/components/content/NewsCard.vue b/packages/app/src/components/content/NewsCard.vue
index 63c6864e..f0fb0353 100644
--- a/packages/app/src/components/content/NewsCard.vue
+++ b/packages/app/src/components/content/NewsCard.vue
@@ -17,13 +17,9 @@
/>
- 📰
-
+ class="w-full h-full rounded-[6px] bg-cover bg-center"
+ :style="{ backgroundImage: `url(${fallbackImg})` }"
+ />
@@ -52,6 +48,7 @@ import { ref, computed } from 'vue'
import type { WebSearchResult } from '@aiui/core/types/message'
import { useTheme } from '@/composables/useTheme'
import { isSafeUrl, formatDomain } from '@/utils/html'
+import { generateNewsFallback } from '@/composables/useImageFallback'
const props = defineProps<{ article: WebSearchResult }>()
defineEmits<{ 'select-article': [article: WebSearchResult] }>()
@@ -65,15 +62,8 @@ const imgSrc = computed(() => {
return isSafeUrl(u) ? u : null
})
-const faviconUrl = computed(() => {
- if (imgSrc.value) return null
- try {
- const u = new URL(props.article.url)
- if (!/^https?:\/\//i.test(props.article.url)) return null
- return `https://www.google.com/s2/favicons?domain=${encodeURIComponent(u.hostname)}&sz=64`
- } catch {
- return null
- }
-})
+const fallbackImg = computed(() =>
+ generateNewsFallback(props.article.title, formatDomain(props.article.url))
+)
diff --git a/packages/app/src/components/content/NewsGrid.vue b/packages/app/src/components/content/NewsGrid.vue
index 5edf6cd6..5f6e8632 100644
--- a/packages/app/src/components/content/NewsGrid.vue
+++ b/packages/app/src/components/content/NewsGrid.vue
@@ -49,37 +49,9 @@
/>
-
-
-
![]()
-
🌐
-
-
-
-
- 📰
-
-
+ class="absolute inset-0 bg-cover bg-center"
+ :style="{ backgroundImage: `url(${newsFallback(article)})` }"
+ />
@@ -122,6 +94,7 @@ import { ref, computed } from 'vue'
import type { WebSearchResult } from '@aiui/core/types/message'
import { useTheme } from '@/composables/useTheme'
import { useContentPanel } from '@/composables/useContentPanel'
+import { generateNewsFallback } from '@/composables/useImageFallback'
const props = withDefaults(defineProps<{
articles: WebSearchResult[]
@@ -158,14 +131,8 @@ function formatDomain(url: string): string {
}
}
-function faviconUrl(url: string): string | null {
- try {
- if (!/^https?:\/\//i.test(url)) return null
- const u = new URL(url)
- return `https://www.google.com/s2/favicons?domain=${encodeURIComponent(u.hostname)}&sz=64`
- } catch {
- return null
- }
+function newsFallback(article: WebSearchResult): string {
+ return generateNewsFallback(article.title, formatDomain(article.url))
}
function openArticle(article: WebSearchResult) {
diff --git a/packages/app/src/components/content/PlaceCard.vue b/packages/app/src/components/content/PlaceCard.vue
index 325b80d9..afaa284d 100644
--- a/packages/app/src/components/content/PlaceCard.vue
+++ b/packages/app/src/components/content/PlaceCard.vue
@@ -8,11 +8,12 @@
>