From e22fce8da319baad3f9e08674262bc6247633754 Mon Sep 17 00:00:00 2001 From: Chilfish Date: Sun, 10 Mar 2024 01:07:15 +0800 Subject: [PATCH] fix(ui): image bugs --- apps/web/server/api/img.ts | 39 +++++++++++++++++++++++++++++ apps/web/src/layouts/default.vue | 4 ++- packages/ui/src/ImgViewer.vue | 31 ++++++++++++++--------- packages/ui/src/UserProfile.vue | 23 ++++++----------- packages/ui/src/post/List.vue | 3 +-- packages/ui/src/post/Pagination.vue | 22 ++++++++-------- packages/ui/src/post/Profile.vue | 22 ++++++++++------ 7 files changed, 95 insertions(+), 49 deletions(-) create mode 100644 apps/web/server/api/img.ts diff --git a/apps/web/server/api/img.ts b/apps/web/server/api/img.ts new file mode 100644 index 0000000..06e3bb5 --- /dev/null +++ b/apps/web/server/api/img.ts @@ -0,0 +1,39 @@ +function returnError(statusCode: number, message: string) { + return new Response(JSON.stringify({ + statusCode, + message, + }), { + status: statusCode, + headers: { + 'Content-Type': 'application/json', + }, + }) +} + +export default defineEventHandler(async (event) => { + const { url } = getQuery<{ url: string }>(event) + + if (!url.includes('crop')) + return returnError(400, 'url should be an avatar url.') + + const res = await fetch(url, { + headers: { + referrer: 'https://weibo.com/', + }, + }).catch(() => returnError(404, 'image Not Found')) + + // 如果不是图片 + if (!res.headers.get('content-type')?.includes('image')) + return returnError(res.status, 'image Not Found') + + const blob = await res.blob() + + // cache 7 days + return new Response(blob, { + headers: { + 'Content-Type': res.headers.get('content-type') || 'image/jpeg', + 'Cache-Control': 'max-age=604800', + 'Expires': new Date(Date.now() + 604800000).toUTCString(), + }, + }) +}) diff --git a/apps/web/src/layouts/default.vue b/apps/web/src/layouts/default.vue index 395944f..5f490f9 100644 --- a/apps/web/src/layouts/default.vue +++ b/apps/web/src/layouts/default.vue @@ -6,7 +6,9 @@ - + + +
diff --git a/packages/ui/src/ImgViewer.vue b/packages/ui/src/ImgViewer.vue index 82c9a20..0af26cc 100644 --- a/packages/ui/src/ImgViewer.vue +++ b/packages/ui/src/ImgViewer.vue @@ -3,6 +3,8 @@ import { storeToRefs } from 'pinia' const { globalImg } = storeToRefs(usePublicStore()) +const imgRef = ref(null) + async function onClose() { const btn = await waitForElement('.n-image-preview-toolbar') const mask = await waitForElement('.n-image-preview-overlay') @@ -11,28 +13,33 @@ async function onClose() { arr.forEach(e => e?.addEventListener('click', () => { globalImg.value = imgViewSrc - }, { once: true })) + })) } watch(globalImg, async () => { if (globalImg.value === imgViewSrc) return - const img = await waitForElement('#img-viewer img') - img?.click() + imgRef.value?.click() + + const img = await waitForElement('img.n-image-preview') + + if (!img) + return + img.src = replaceImg(globalImg.value) await onClose() }) + +onMounted(() => { + imgRef.value = document.querySelector('#img-viewer img') +}) diff --git a/packages/ui/src/UserProfile.vue b/packages/ui/src/UserProfile.vue index f60a668..615a3bb 100644 --- a/packages/ui/src/UserProfile.vue +++ b/packages/ui/src/UserProfile.vue @@ -1,21 +1,12 @@ diff --git a/packages/ui/src/post/Pagination.vue b/packages/ui/src/post/Pagination.vue index 249971e..e18da65 100644 --- a/packages/ui/src/post/Pagination.vue +++ b/packages/ui/src/post/Pagination.vue @@ -25,17 +25,15 @@ onMounted(async () => { diff --git a/packages/ui/src/post/Profile.vue b/packages/ui/src/post/Profile.vue index 9383c6f..80b43a5 100644 --- a/packages/ui/src/post/Profile.vue +++ b/packages/ui/src/post/Profile.vue @@ -5,11 +5,17 @@ const props = defineProps<{ user: User }>() +const publicStore = usePublicStore() + const avatar = computed(() => { const url = props.user.profile_image_url if (!url) return '/placeholder.webp' + if (publicStore.curUid === props.user.id) + return replaceImg(url) + + // 对于其他人的头像,就使用 CDN const { pathname } = new URL(url) return `${imgCdn}${pathname}` }) @@ -18,22 +24,24 @@ const avatar = computed(() => {