Skip to content

Commit

Permalink
fix(ui): image bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
Chilfish committed Mar 9, 2024
1 parent 1382565 commit e22fce8
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 49 deletions.
39 changes: 39 additions & 0 deletions apps/web/server/api/img.ts
Original file line number Diff line number Diff line change
@@ -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(),
},
})
})
4 changes: 3 additions & 1 deletion apps/web/src/layouts/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
<app-main>
<nuxt-loading-indicator />
<main-header />
<img-viewer />
<client-only>
<img-viewer />
</client-only>
<main class="mt-16 h-full">
<slot />
</main>
Expand Down
31 changes: 19 additions & 12 deletions packages/ui/src/ImgViewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { storeToRefs } from 'pinia'
const { globalImg } = storeToRefs(usePublicStore())
const imgRef = ref<HTMLImageElement | null>(null)
async function onClose() {
const btn = await waitForElement('.n-image-preview-toolbar')
const mask = await waitForElement('.n-image-preview-overlay')
Expand All @@ -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<HTMLImageElement>('#img-viewer img')
img?.click()
imgRef.value?.click()
const img = await waitForElement<HTMLImageElement>('img.n-image-preview')
if (!img)
return
img.src = replaceImg(globalImg.value)
await onClose()
})
onMounted(() => {
imgRef.value = document.querySelector<HTMLImageElement>('#img-viewer img')
})
</script>

<template>
<div
<main-image
id="img-viewer"
class="absolute right-0 top-0 hidden"
>
<main-image
class="h-0 w-0"
:lazy="false"
:src="globalImg"
/>
</div>
class="absolute right-0 top-0 hidden h-0 w-0"
:lazy="false"
:src="imgViewSrc"
/>
</template>
23 changes: 8 additions & 15 deletions packages/ui/src/UserProfile.vue
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
<script setup lang="ts">
import type { UserInfo } from '@types'
const props = withDefaults(defineProps<{
withDefaults(defineProps<{
user: UserInfo
showMore?: boolean
}>(), {
showMore: true,
})
const avatar = computed(() => {
const url = props.user.avatar
if (!url)
return '/placeholder.webp'
const { pathname } = new URL(url)
return `${imgCdn}${pathname}`
})
</script>

<template>
Expand All @@ -24,13 +15,15 @@ const avatar = computed(() => {
>
<div class="flex items-center gap-4">
<n-avatar
lazy round
fallback-src="/placeholder.webp"
lazy
round
bordered
color="#9ca3af"
text="3 center"
:size="56"
:src="avatar"
:src="`/api/img?url=${encodeURIComponent(user.avatar)}`"
:img-props="{
alt: `${user.name} avatar`,
title: `${user.name} avatar`,
alt: `${user.name}'s avatar`,
}"
class="ring-2 ring-white"
/>
Expand Down
3 changes: 1 addition & 2 deletions packages/ui/src/post/List.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ defineProps<{
:key="item.id"
:post="item"
/>

<post-pagination />
</div>
<post-pagination />
</template>
22 changes: 10 additions & 12 deletions packages/ui/src/post/Pagination.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,15 @@ onMounted(async () => {
</script>

<template>
<div>
<n-pagination
v-model:page="curPage"
v-model:page-size="pageSize"
show-quick-jumper
show-size-picker
:page-sizes="[10, 20, 30]"
:item-count="postStore.total"
<n-pagination
v-model:page="curPage"
v-model:page-size="pageSize"
show-quick-jumper
show-size-picker
:page-sizes="[10, 20, 30]"
:item-count="postStore.total"

class="center flex-wrap"
@update:page-size="fixPagePanel"
/>
</div>
class="center flex-wrap"
@update:page-size="fixPagePanel"
/>
</template>
22 changes: 15 additions & 7 deletions packages/ui/src/post/Profile.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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}`
})
Expand All @@ -18,22 +24,24 @@ const avatar = computed(() => {
<template>
<a
class="mr-auto flex items-center gap-3"
:href="`https://weibo.com/u/${user.id}`"
target="_blank"
:href="`https://weibo.com/u/${user.id}`"
>
<n-avatar
lazy round
fallback-src="/placeholder.webp"
:size="30"
lazy
round
bordered
color="#9ca3af"
text="2.5 center"
:size="36"
:src="avatar"
:img-props="{
alt: `${user.screen_name} avatar`,
title: `${user.screen_name} avatar`,
alt: `${user.screen_name}'s avatar`,
}"
/>

<span
class="text-3.5! font-bold! hover:text-teal-700!"
class="font-bold hover:text-teal-700!"
>
{{ user.screen_name }}
</span>
Expand Down

0 comments on commit e22fce8

Please sign in to comment.