fix: 🐛

This commit is contained in:
codytseng
2025-10-25 14:54:37 +08:00
parent 402bc91566
commit 92041b73f1
3 changed files with 58 additions and 18 deletions

View File

@@ -1,20 +1,15 @@
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { Skeleton } from '@/components/ui/skeleton' import { Skeleton } from '@/components/ui/skeleton'
import { generateImageByPubkey } from '@/lib/pubkey'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
import { usePrimaryPage } from '@/PageManager' import { usePrimaryPage } from '@/PageManager'
import { useNostr } from '@/providers/NostrProvider' import { useNostr } from '@/providers/NostrProvider'
import { UserRound } from 'lucide-react' import { UserRound } from 'lucide-react'
import { useMemo } from 'react' import { useMemo } from 'react'
import { SimpleUserAvatar } from '../UserAvatar'
import BottomNavigationBarItem from './BottomNavigationBarItem' import BottomNavigationBarItem from './BottomNavigationBarItem'
export default function AccountButton() { export default function AccountButton() {
const { navigate, current, display } = usePrimaryPage() const { navigate, current, display } = usePrimaryPage()
const { pubkey, profile } = useNostr() const { pubkey, profile } = useNostr()
const defaultAvatar = useMemo(
() => (profile?.pubkey ? generateImageByPubkey(profile.pubkey) : ''),
[profile]
)
const active = useMemo(() => current === 'me' && display, [display, current]) const active = useMemo(() => current === 'me' && display, [display, current])
return ( return (
@@ -26,12 +21,10 @@ export default function AccountButton() {
> >
{pubkey ? ( {pubkey ? (
profile ? ( profile ? (
<Avatar className={cn('w-7 h-7', active ? 'ring-primary ring-1' : '')}> <SimpleUserAvatar
<AvatarImage src={profile.avatar} className="object-cover object-center" /> userId={pubkey}
<AvatarFallback> className={cn('w-7 h-7', active ? 'ring-primary ring-1' : '')}
<img src={defaultAvatar} /> />
</AvatarFallback>
</Avatar>
) : ( ) : (
<Skeleton className={cn('w-7 h-7 rounded-full', active ? 'ring-primary ring-1' : '')} /> <Skeleton className={cn('w-7 h-7 rounded-full', active ? 'ring-primary ring-1' : '')} />
) )

View File

@@ -89,7 +89,6 @@ export default function Image({
src={imageUrl} src={imageUrl}
alt={alt} alt={alt}
decoding="async" decoding="async"
loading="lazy"
draggable={false} draggable={false}
{...props} {...props}
onLoad={handleLoad} onLoad={handleLoad}

View File

@@ -1,6 +1,7 @@
import { randomString } from '@/lib/random' import { randomString } from '@/lib/random'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
import { useContentPolicy } from '@/providers/ContentPolicyProvider' import { useContentPolicy } from '@/providers/ContentPolicyProvider'
import blossomService from '@/services/blossom.service'
import modalManager from '@/services/modal-manager.service' import modalManager from '@/services/modal-manager.service'
import { TImetaInfo } from '@/types' import { TImetaInfo } from '@/types'
import { ReactNode, useEffect, useMemo, useState } from 'react' import { ReactNode, useEffect, useMemo, useState } from 'react'
@@ -26,6 +27,7 @@ export default function ImageGallery({
const id = useMemo(() => `image-gallery-${randomString()}`, []) const id = useMemo(() => `image-gallery-${randomString()}`, [])
const { autoLoadMedia } = useContentPolicy() const { autoLoadMedia } = useContentPolicy()
const [index, setIndex] = useState(-1) const [index, setIndex] = useState(-1)
const [slides, setSlides] = useState<{ src: string }[]>(images.map(({ url }) => ({ src: url })))
useEffect(() => { useEffect(() => {
if (index >= 0) { if (index >= 0) {
modalManager.register(id, () => { modalManager.register(id, () => {
@@ -36,6 +38,49 @@ export default function ImageGallery({
} }
}, [index]) }, [index])
useEffect(() => {
const loadImages = async () => {
const slides = await Promise.all(
images.map(({ url, pubkey }) => {
return new Promise<{ src: string }>((resolve) => {
const img = new window.Image()
let validUrl = url
img.onload = () => {
blossomService.markAsSuccess(url, validUrl)
resolve({ src: validUrl })
}
img.onerror = () => {
blossomService.tryNextUrl(url).then((nextUrl) => {
if (nextUrl) {
validUrl = nextUrl
resolve({ src: validUrl })
} else {
resolve({ src: url })
}
})
}
if (pubkey) {
blossomService
.getValidUrl(url, pubkey)
.then((u) => {
validUrl = u
img.src = validUrl
})
.catch(() => {
resolve({ src: url })
})
} else {
img.src = url
}
})
})
)
setSlides(slides)
}
loadImages()
}, [images])
const handlePhotoClick = (event: React.MouseEvent, current: number) => { const handlePhotoClick = (event: React.MouseEvent, current: number) => {
event.stopPropagation() event.stopPropagation()
event.preventDefault() event.preventDefault()
@@ -62,9 +107,10 @@ export default function ImageGallery({
imageContent = ( imageContent = (
<Image <Image
key={0} key={0}
className="max-h-[80vh] sm:max-h-[50vh] cursor-zoom-in object-contain" className="max-h-[80vh] sm:max-h-[50vh] object-contain"
classNames={{ classNames={{
errorPlaceholder: 'aspect-square h-[30vh]' errorPlaceholder: 'aspect-square h-[30vh]',
wrapper: 'cursor-zoom-in'
}} }}
image={displayImages[0]} image={displayImages[0]}
onClick={(e) => handlePhotoClick(e, 0)} onClick={(e) => handlePhotoClick(e, 0)}
@@ -76,7 +122,8 @@ export default function ImageGallery({
{displayImages.map((image, i) => ( {displayImages.map((image, i) => (
<Image <Image
key={i} key={i}
className="aspect-square w-full cursor-zoom-in" className="aspect-square w-full"
classNames={{ wrapper: 'cursor-zoom-in' }}
image={image} image={image}
onClick={(e) => handlePhotoClick(e, i)} onClick={(e) => handlePhotoClick(e, i)}
/> />
@@ -89,7 +136,8 @@ export default function ImageGallery({
{displayImages.map((image, i) => ( {displayImages.map((image, i) => (
<Image <Image
key={i} key={i}
className="aspect-square w-full cursor-zoom-in" className="aspect-square w-full"
classNames={{ wrapper: 'cursor-zoom-in' }}
image={image} image={image}
onClick={(e) => handlePhotoClick(e, i)} onClick={(e) => handlePhotoClick(e, i)}
/> />
@@ -106,7 +154,7 @@ export default function ImageGallery({
<div onClick={(e) => e.stopPropagation()}> <div onClick={(e) => e.stopPropagation()}>
<Lightbox <Lightbox
index={index} index={index}
slides={images.map(({ url }) => ({ src: url }))} slides={slides}
plugins={[Zoom]} plugins={[Zoom]}
open={index >= 0} open={index >= 0}
close={() => setIndex(-1)} close={() => setIndex(-1)}