diff --git a/src/components/ProfileBanner/index.tsx b/src/components/ProfileBanner/index.tsx
index dbf025d..04d4080 100644
--- a/src/components/ProfileBanner/index.tsx
+++ b/src/components/ProfileBanner/index.tsx
@@ -1,6 +1,11 @@
import { generateImageByPubkey } from '@/lib/pubkey'
+import { randomString } from '@/lib/random'
import { cn } from '@/lib/utils'
+import modalManager from '@/services/modal-manager.service'
import { useEffect, useMemo, useState } from 'react'
+import { createPortal } from 'react-dom'
+import Lightbox from 'yet-another-react-lightbox'
+import Zoom from 'yet-another-react-lightbox/plugins/zoom'
import Image from '../Image'
export default function ProfileBanner({
@@ -32,3 +37,78 @@ export default function ProfileBanner({
/>
)
}
+
+export function BannerWithLightbox({
+ pubkey,
+ banner,
+ className
+}: {
+ pubkey: string
+ banner?: string
+ className?: string
+}) {
+ const id = useMemo(() => `profile-banner-lightbox-${randomString()}`, [])
+ const defaultBanner = useMemo(() => generateImageByPubkey(pubkey), [pubkey])
+ const [bannerUrl, setBannerUrl] = useState(banner ?? defaultBanner)
+ const [index, setIndex] = useState(-1)
+
+ useEffect(() => {
+ if (banner) {
+ setBannerUrl(banner)
+ } else {
+ setBannerUrl(defaultBanner)
+ }
+ }, [defaultBanner, banner])
+
+ useEffect(() => {
+ if (index >= 0) {
+ modalManager.register(id, () => {
+ setIndex(-1)
+ })
+ } else {
+ modalManager.unregister(id)
+ }
+ }, [index, id])
+
+ const handleBannerClick = (event: React.MouseEvent) => {
+ event.stopPropagation()
+ event.preventDefault()
+ setIndex(0)
+ }
+
+ return (
+ <>
+
+ {index >= 0 &&
+ createPortal(
+
e.stopPropagation()}>
+ = 0}
+ close={() => setIndex(-1)}
+ controller={{
+ closeOnBackdropClick: true,
+ closeOnPullUp: true,
+ closeOnPullDown: true
+ }}
+ styles={{
+ toolbar: { paddingTop: '2.25rem' }
+ }}
+ />
+
,
+ document.body
+ )}
+ >
+ )
+}
diff --git a/src/components/UserAvatar/index.tsx b/src/components/UserAvatar/index.tsx
index 38fa393..4782091 100644
--- a/src/components/UserAvatar/index.tsx
+++ b/src/components/UserAvatar/index.tsx
@@ -3,9 +3,14 @@ import { Skeleton } from '@/components/ui/skeleton'
import { useFetchProfile } from '@/hooks'
import { toProfile } from '@/lib/link'
import { generateImageByPubkey } from '@/lib/pubkey'
+import { randomString } from '@/lib/random'
import { cn } from '@/lib/utils'
import { SecondaryPageLink } from '@/PageManager'
-import { useMemo } from 'react'
+import modalManager from '@/services/modal-manager.service'
+import { useEffect, useMemo, useState } from 'react'
+import { createPortal } from 'react-dom'
+import Lightbox from 'yet-another-react-lightbox'
+import Zoom from 'yet-another-react-lightbox/plugins/zoom'
import Image from '../Image'
import ProfileCard from '../ProfileCard'
@@ -79,3 +84,71 @@ export function SimpleUserAvatar({
/>
)
}
+
+export function AvatarWithLightbox({
+ userId,
+ size = 'normal',
+ className
+}: {
+ userId: string
+ size?: 'large' | 'big' | 'semiBig' | 'normal' | 'medium' | 'small' | 'xSmall' | 'tiny'
+ className?: string
+}) {
+ const id = useMemo(() => `user-avatar-lightbox-${randomString()}`, [])
+ const { profile } = useFetchProfile(userId)
+ const defaultAvatar = useMemo(
+ () => (profile?.pubkey ? generateImageByPubkey(profile.pubkey) : ''),
+ [profile]
+ )
+ const [index, setIndex] = useState(-1)
+
+ useEffect(() => {
+ if (index >= 0) {
+ modalManager.register(id, () => {
+ setIndex(-1)
+ })
+ } else {
+ modalManager.unregister(id)
+ }
+ }, [index, id])
+
+ const handleClick = (e: React.MouseEvent
) => {
+ e.stopPropagation()
+ e.preventDefault()
+ setIndex(0)
+ }
+
+ const imageUrl = profile?.avatar ?? defaultAvatar
+
+ return (
+ <>
+
+ {index >= 0 &&
+ createPortal(
+ e.stopPropagation()}>
+ = 0}
+ close={() => setIndex(-1)}
+ controller={{
+ closeOnBackdropClick: true,
+ closeOnPullUp: true,
+ closeOnPullDown: true
+ }}
+ styles={{
+ toolbar: { paddingTop: '2.25rem' }
+ }}
+ />
+
,
+ document.body
+ )}
+ >
+ )
+}