mirror of
https://github.com/lumehq/lume.git
synced 2025-09-26 14:57:21 +02:00
add image component
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { AvatarUploader } from '@lume/shared/avatarUploader';
|
||||
import CancelIcon from '@lume/shared/icons/cancel';
|
||||
import PlusIcon from '@lume/shared/icons/plus';
|
||||
import { Image } from '@lume/shared/image';
|
||||
import { RelayContext } from '@lume/shared/relayProvider';
|
||||
import { DEFAULT_AVATAR, WRITEONLY_RELAYS } from '@lume/stores/constants';
|
||||
import { dateToUnix } from '@lume/utils/getDate';
|
||||
@@ -150,7 +151,7 @@ export default function ChannelCreateModal() {
|
||||
<div className="flex flex-col gap-1">
|
||||
<label className="text-xs font-semibold uppercase tracking-wider text-zinc-400">Picture</label>
|
||||
<div className="relative inline-flex h-36 w-full items-center justify-center overflow-hidden rounded-lg border border-zinc-900 bg-zinc-950">
|
||||
<img src={image} alt="channel picture" className="relative z-10 h-11 w-11 rounded-md" />
|
||||
<Image src={image} alt="channel picture" className="relative z-10 h-11 w-11 rounded-md" />
|
||||
<div className="absolute bottom-3 right-3 z-10">
|
||||
<AvatarUploader valueState={setImage} />
|
||||
</div>
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { Image } from '@lume/shared/image';
|
||||
import { DEFAULT_AVATAR, IMGPROXY_URL } from '@lume/stores/constants';
|
||||
import { useProfile } from '@lume/utils/hooks/useProfile';
|
||||
import { shortenKey } from '@lume/utils/shortenKey';
|
||||
@@ -24,12 +25,10 @@ export default function ChannelMessageUser({ pubkey, time }: { pubkey: string; t
|
||||
) : (
|
||||
<>
|
||||
<div className="relative h-9 w-9 shrink rounded-md">
|
||||
<img
|
||||
<Image
|
||||
src={`${IMGPROXY_URL}/rs:fit:100:100/plain/${user?.picture ? user.picture : DEFAULT_AVATAR}`}
|
||||
alt={pubkey}
|
||||
className="h-9 w-9 rounded-md object-cover"
|
||||
loading="lazy"
|
||||
fetchpriority="high"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex w-full flex-1 items-start justify-between">
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { Image } from '@lume/shared/image';
|
||||
import { DEFAULT_AVATAR, IMGPROXY_URL } from '@lume/stores/constants';
|
||||
import { useProfile } from '@lume/utils/hooks/useProfile';
|
||||
import { shortenKey } from '@lume/utils/shortenKey';
|
||||
@@ -15,12 +16,10 @@ export default function UserReply({ pubkey }: { pubkey: string }) {
|
||||
) : (
|
||||
<>
|
||||
<div className="relative h-7 w-7 shrink overflow-hidden rounded">
|
||||
<img
|
||||
<Image
|
||||
src={`${IMGPROXY_URL}/rs:fit:100:100/plain/${user?.picture ? user.picture : DEFAULT_AVATAR}`}
|
||||
alt={pubkey}
|
||||
className="h-7 w-7 rounded object-cover"
|
||||
loading="lazy"
|
||||
fetchpriority="high"
|
||||
/>
|
||||
</div>
|
||||
<span className="text-xs font-medium leading-none text-zinc-500">
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import CopyIcon from '@lume/shared/icons/copy';
|
||||
import { Image } from '@lume/shared/image';
|
||||
import { DEFAULT_AVATAR } from '@lume/stores/constants';
|
||||
import { useChannelProfile } from '@lume/utils/hooks/useChannelProfile';
|
||||
|
||||
@@ -18,7 +19,7 @@ export default function ChannelMetadata({ id, pubkey }: { id: string; pubkey: st
|
||||
return (
|
||||
<div className="inline-flex items-center gap-2">
|
||||
<div className="relative shrink-0 rounded-md">
|
||||
<img
|
||||
<Image
|
||||
src={metadata?.picture || DEFAULT_AVATAR}
|
||||
alt={id}
|
||||
className="h-8 w-8 rounded bg-zinc-900 object-contain ring-2 ring-zinc-950"
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { Image } from '@lume/shared/image';
|
||||
import { DEFAULT_AVATAR } from '@lume/stores/constants';
|
||||
import { useProfile } from '@lume/utils/hooks/useProfile';
|
||||
|
||||
@@ -9,7 +10,7 @@ export default function MiniMember({ pubkey }: { pubkey: string }) {
|
||||
{isError || isLoading ? (
|
||||
<div className="h-8 w-8 animate-pulse rounded-md bg-zinc-800"></div>
|
||||
) : (
|
||||
<img
|
||||
<Image
|
||||
className="inline-block h-8 w-8 rounded-md bg-white ring-2 ring-zinc-950 transition-all duration-150 ease-in-out"
|
||||
src={user?.picture || DEFAULT_AVATAR}
|
||||
alt={user?.pubkey || 'user avatar'}
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { Image } from '@lume/shared/image';
|
||||
import { DEFAULT_AVATAR } from '@lume/stores/constants';
|
||||
import { useProfile } from '@lume/utils/hooks/useProfile';
|
||||
import { shortenKey } from '@lume/utils/shortenKey';
|
||||
@@ -40,11 +41,10 @@ export default function MutedItem({ data }: { data: any }) {
|
||||
<>
|
||||
<div className="flex items-center gap-1.5">
|
||||
<div className="relative h-9 w-9 shrink rounded-md">
|
||||
<img
|
||||
<Image
|
||||
src={user?.picture || DEFAULT_AVATAR}
|
||||
alt={data.content}
|
||||
className="h-9 w-9 rounded-md object-cover"
|
||||
loading="lazy"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex w-full flex-1 flex-col items-start gap-0.5 text-start">
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { AvatarUploader } from '@lume/shared/avatarUploader';
|
||||
import CancelIcon from '@lume/shared/icons/cancel';
|
||||
import EditIcon from '@lume/shared/icons/edit';
|
||||
import { Image } from '@lume/shared/image';
|
||||
import { RelayContext } from '@lume/shared/relayProvider';
|
||||
import { DEFAULT_AVATAR, WRITEONLY_RELAYS } from '@lume/stores/constants';
|
||||
import { dateToUnix } from '@lume/utils/getDate';
|
||||
@@ -145,7 +146,7 @@ export default function ChannelUpdateModal({ id }: { id: string }) {
|
||||
<div className="flex flex-col gap-1">
|
||||
<label className="text-xs font-semibold uppercase tracking-wider text-zinc-400">Picture</label>
|
||||
<div className="relative inline-flex h-36 w-full items-center justify-center overflow-hidden rounded-lg border border-zinc-900 bg-zinc-950">
|
||||
<img src={image} alt="channel picture" className="relative z-10 h-11 w-11 rounded-md" />
|
||||
<Image src={image} alt="channel picture" className="relative z-10 h-11 w-11 rounded-md" />
|
||||
<div className="absolute bottom-3 right-3 z-10">
|
||||
<AvatarUploader valueState={setImage} />
|
||||
</div>
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { Image } from '@lume/shared/image';
|
||||
import { DEFAULT_AVATAR } from '@lume/stores/constants';
|
||||
import { usePageContext } from '@lume/utils/hooks/usePageContext';
|
||||
import { useProfile } from '@lume/utils/hooks/useProfile';
|
||||
@@ -32,7 +33,11 @@ export default function ChatsListItem({ pubkey }: { pubkey: string }) {
|
||||
)}
|
||||
>
|
||||
<div className="relative h-5 w-5 shrink-0 rounded">
|
||||
<img src={user.picture || DEFAULT_AVATAR} alt={pubkey} className="h-5 w-5 rounded bg-white object-cover" />
|
||||
<Image
|
||||
src={user.picture || DEFAULT_AVATAR}
|
||||
alt={pubkey}
|
||||
className="h-5 w-5 rounded bg-white object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<h5 className="truncate text-[13px] font-semibold text-zinc-400 group-hover:text-zinc-200">
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { Image } from '@lume/shared/image';
|
||||
import { DEFAULT_AVATAR, IMGPROXY_URL } from '@lume/stores/constants';
|
||||
import { useProfile } from '@lume/utils/hooks/useProfile';
|
||||
import { shortenKey } from '@lume/utils/shortenKey';
|
||||
@@ -24,12 +25,10 @@ export default function ChatMessageUser({ pubkey, time }: { pubkey: string; time
|
||||
) : (
|
||||
<>
|
||||
<div className="relative h-9 w-9 shrink rounded-md">
|
||||
<img
|
||||
<Image
|
||||
src={`${IMGPROXY_URL}/rs:fit:100:100/plain/${user?.picture ? user.picture : DEFAULT_AVATAR}`}
|
||||
alt={pubkey}
|
||||
className="h-9 w-9 rounded-md object-cover"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex w-full flex-1 items-start justify-between">
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { Image } from '@lume/shared/image';
|
||||
import { DEFAULT_AVATAR } from '@lume/stores/constants';
|
||||
import { useActiveAccount } from '@lume/utils/hooks/useActiveAccount';
|
||||
import { usePageContext } from '@lume/utils/hooks/usePageContext';
|
||||
@@ -33,7 +34,7 @@ export default function ChatsListSelfItem() {
|
||||
)}
|
||||
>
|
||||
<div className="relative h-5 w-5 shrink-0 rounded">
|
||||
<img
|
||||
<Image
|
||||
src={profile?.picture || DEFAULT_AVATAR}
|
||||
alt={account.pubkey}
|
||||
className="h-5 w-5 rounded bg-white object-cover"
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { Image } from '@lume/shared/image';
|
||||
import { RelayContext } from '@lume/shared/relayProvider';
|
||||
import { WRITEONLY_RELAYS } from '@lume/stores/constants';
|
||||
import { dateToUnix } from '@lume/utils/getDate';
|
||||
@@ -38,7 +39,7 @@ export default function NoteReplyForm({ id }: { id: string }) {
|
||||
<div className="flex gap-3 px-5 py-4">
|
||||
<div>
|
||||
<div className="relative h-9 w-9 shrink-0 overflow-hidden rounded-md">
|
||||
<img src={profile?.picture} alt={account?.pubkey} className="h-9 w-9 rounded-md object-cover" />
|
||||
<Image src={profile?.picture} alt={account?.pubkey} className="h-9 w-9 rounded-md object-cover" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative h-24 w-full flex-1 overflow-hidden before:pointer-events-none before:absolute before:-inset-1 before:rounded-[11px] before:border before:border-fuchsia-500 before:opacity-0 before:ring-2 before:ring-fuchsia-500/20 before:transition after:pointer-events-none after:absolute after:inset-px after:rounded-[7px] after:shadow-highlight after:shadow-white/5 after:transition focus-within:before:opacity-100 focus-within:after:shadow-fuchsia-500/100 dark:focus-within:after:shadow-fuchsia-500/20">
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import ReplyIcon from '@lume/shared/icons/reply';
|
||||
import { Image } from '@lume/shared/image';
|
||||
import { RelayContext } from '@lume/shared/relayProvider';
|
||||
import { WRITEONLY_RELAYS } from '@lume/stores/constants';
|
||||
import { dateToUnix } from '@lume/utils/getDate';
|
||||
@@ -87,7 +88,7 @@ export default function NoteReply({ id, replies }: { id: string; replies: number
|
||||
<div className="flex gap-2">
|
||||
<div>
|
||||
<div className="relative h-11 w-11 shrink-0 overflow-hidden rounded-md border border-white/10">
|
||||
<img src={profile?.picture} alt="user's avatar" className="h-11 w-11 rounded-md object-cover" />
|
||||
<Image src={profile?.picture} alt="user's avatar" className="h-11 w-11 rounded-md object-cover" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative h-24 w-full flex-1 overflow-hidden before:pointer-events-none before:absolute before:-inset-1 before:rounded-[11px] before:border before:border-blue-500 before:opacity-0 before:ring-2 before:ring-blue-500/20 before:transition after:pointer-events-none after:absolute after:inset-px after:rounded-[7px] after:shadow-highlight after:shadow-white/5 after:transition focus-within:before:opacity-100 focus-within:after:shadow-blue-500/100 dark:focus-within:after:shadow-blue-500/20">
|
||||
|
@@ -1,26 +1,24 @@
|
||||
import { Image } from '@lume/shared/image';
|
||||
|
||||
export default function ImagePreview({ urls }: { urls: string[] }) {
|
||||
return (
|
||||
<div className="mt-2 grid h-full w-full grid-cols-2">
|
||||
{urls.length === 1 ? (
|
||||
<div className="col-span-2">
|
||||
<img
|
||||
<Image
|
||||
src={urls[0]}
|
||||
alt="image"
|
||||
className="h-auto w-full rounded-lg object-cover"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
style={{ contentVisibility: 'auto' }}
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
urls.map((url: string) => (
|
||||
<div key={url} className="col-span-1">
|
||||
<img
|
||||
<Image
|
||||
src={url}
|
||||
alt="image"
|
||||
className="h-auto w-full rounded-lg object-cover"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
style={{ contentVisibility: 'auto' }}
|
||||
/>
|
||||
</div>
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { Image } from '@lume/shared/image';
|
||||
import { DEFAULT_AVATAR, IMGPROXY_URL } from '@lume/stores/constants';
|
||||
import { useProfile } from '@lume/utils/hooks/useProfile';
|
||||
import { shortenKey } from '@lume/utils/shortenKey';
|
||||
@@ -14,7 +15,7 @@ export const NoteDefaultUser = ({ pubkey, time }: { pubkey: string; time: number
|
||||
<div className="group relative z-10 flex h-11 items-center gap-2">
|
||||
{isError || isLoading ? (
|
||||
<>
|
||||
<div className="h-11 w-11 shrink animate-pulse overflow-hidden rounded-md bg-white"></div>
|
||||
<div className="h-11 w-11 shrink animate-pulse overflow-hidden rounded-md"></div>
|
||||
<div className="flex w-full flex-1 items-start justify-between">
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="flex items-baseline gap-2">
|
||||
@@ -26,13 +27,11 @@ export const NoteDefaultUser = ({ pubkey, time }: { pubkey: string; time: number
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<div className="h-11 w-11 shrink overflow-hidden rounded-md bg-white">
|
||||
<img
|
||||
<div className="h-11 w-11 shrink overflow-hidden rounded-md bg-zinc-900">
|
||||
<Image
|
||||
src={`${IMGPROXY_URL}/rs:fit:100:100/plain/${user?.picture ? user.picture : DEFAULT_AVATAR}`}
|
||||
alt={pubkey}
|
||||
className="h-11 w-11 rounded-md object-cover"
|
||||
loading="lazy"
|
||||
fetchpriority="high"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex w-full flex-1 items-start justify-between">
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { Image } from '@lume/shared/image';
|
||||
import { DEFAULT_AVATAR, IMGPROXY_URL } from '@lume/stores/constants';
|
||||
import { useProfile } from '@lume/utils/hooks/useProfile';
|
||||
import { shortenKey } from '@lume/utils/shortenKey';
|
||||
@@ -24,12 +25,10 @@ export default function NoteReplyUser({ pubkey, time }: { pubkey: string; time:
|
||||
) : (
|
||||
<>
|
||||
<div className="relative h-9 w-9 shrink rounded-md">
|
||||
<img
|
||||
<Image
|
||||
src={`${IMGPROXY_URL}/rs:fit:100:100/plain/${user?.picture ? user.picture : DEFAULT_AVATAR}`}
|
||||
alt={pubkey}
|
||||
className="h-9 w-9 rounded-md object-cover"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex w-full flex-1 items-start justify-between">
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { Image } from '@lume/shared/image';
|
||||
import { DEFAULT_AVATAR, IMGPROXY_URL } from '@lume/stores/constants';
|
||||
import { useProfile } from '@lume/utils/hooks/useProfile';
|
||||
import { shortenKey } from '@lume/utils/shortenKey';
|
||||
@@ -14,7 +15,7 @@ export const NoteRepostUser = ({ pubkey, time }: { pubkey: string; time: number
|
||||
<div className="group flex items-center gap-2">
|
||||
{isError || isLoading ? (
|
||||
<>
|
||||
<div className="relative h-11 w-11 shrink animate-pulse overflow-hidden rounded-md bg-white"></div>
|
||||
<div className="relative h-11 w-11 shrink animate-pulse overflow-hidden rounded-md"></div>
|
||||
<div className="flex w-full flex-1 items-start justify-between">
|
||||
<div className="flex flex-col gap-1">
|
||||
<div className="flex items-baseline gap-2">
|
||||
@@ -25,13 +26,11 @@ export const NoteRepostUser = ({ pubkey, time }: { pubkey: string; time: number
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<div className="relative h-11 w-11 shrink overflow-hidden rounded-md bg-white">
|
||||
<img
|
||||
<div className="relative h-11 w-11 shrink overflow-hidden rounded-md bg-zinc-900">
|
||||
<Image
|
||||
src={`${IMGPROXY_URL}/rs:fit:100:100/plain/${user?.picture ? user.picture : DEFAULT_AVATAR}`}
|
||||
alt={pubkey}
|
||||
className="h-11 w-11 rounded-md object-cover"
|
||||
loading="lazy"
|
||||
fetchpriority="high"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-baseline gap-2 text-sm">
|
||||
|
@@ -1,15 +1,16 @@
|
||||
import { Image } from '@lume/shared/image';
|
||||
import { DEFAULT_AVATAR } from '@lume/stores/constants';
|
||||
import { useProfile } from '@lume/utils/hooks/useProfile';
|
||||
import { shortenKey } from '@lume/utils/shortenKey';
|
||||
|
||||
export default function User({ pubkey }: { pubkey: string }) {
|
||||
const profile = useProfile(pubkey);
|
||||
const { user } = useProfile(pubkey);
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="relative h-11 w-11 shrink rounded-md">
|
||||
<img
|
||||
src={profile?.picture || DEFAULT_AVATAR}
|
||||
<Image
|
||||
src={user?.picture || DEFAULT_AVATAR}
|
||||
alt={pubkey}
|
||||
className="h-11 w-11 rounded-md object-cover"
|
||||
loading="lazy"
|
||||
@@ -17,12 +18,8 @@ export default function User({ pubkey }: { pubkey: string }) {
|
||||
/>
|
||||
</div>
|
||||
<div className="flex w-full flex-1 flex-col items-start text-start">
|
||||
<span className="truncate font-medium leading-tight text-zinc-200">
|
||||
{profile?.display_name || profile?.name}
|
||||
</span>
|
||||
<span className="text-sm leading-tight text-zinc-400">
|
||||
{profile?.nip05?.toLowerCase() || shortenKey(pubkey)}
|
||||
</span>
|
||||
<span className="truncate font-medium leading-tight text-zinc-200">{user?.display_name || user?.name}</span>
|
||||
<span className="text-sm leading-tight text-zinc-400">{user?.nip05?.toLowerCase() || shortenKey(pubkey)}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { AvatarUploader } from '@lume/shared/avatarUploader';
|
||||
import { Image } from '@lume/shared/image';
|
||||
import { DEFAULT_AVATAR } from '@lume/stores/constants';
|
||||
import { onboardingAtom } from '@lume/stores/onboarding';
|
||||
|
||||
@@ -54,7 +55,7 @@ export function Page() {
|
||||
<div className="flex flex-col gap-1">
|
||||
<label className="text-xs font-semibold uppercase tracking-wider text-zinc-400">Avatar</label>
|
||||
<div className="relative inline-flex h-36 w-full items-center justify-center overflow-hidden rounded-lg border border-zinc-900 bg-zinc-950">
|
||||
<img src={image} alt="avatar" className="relative z-10 h-11 w-11 rounded-md" />
|
||||
<Image src={image} alt="avatar" className="relative z-10 h-11 w-11 rounded-md" />
|
||||
<div className="absolute bottom-3 right-3 z-10">
|
||||
<AvatarUploader valueState={setImage} />
|
||||
</div>
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { Image } from '@lume/shared/image';
|
||||
import { RelayContext } from '@lume/shared/relayProvider';
|
||||
import { DEFAULT_AVATAR, READONLY_RELAYS } from '@lume/stores/constants';
|
||||
import { onboardingAtom } from '@lume/stores/onboarding';
|
||||
@@ -91,7 +92,7 @@ export function Page() {
|
||||
) : (
|
||||
<div className="flex flex-col gap-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<img
|
||||
<Image
|
||||
className="relative inline-flex h-11 w-11 rounded-lg ring-2 ring-zinc-900"
|
||||
src={data.picture || DEFAULT_AVATAR}
|
||||
alt={pubkey}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import ArrowRightIcon from '@lume/shared/icons/arrowRight';
|
||||
import { Image } from '@lume/shared/image';
|
||||
|
||||
const PLEBS = [
|
||||
'https://133332.xyz/p.jpg',
|
||||
@@ -81,7 +82,7 @@ export function Page() {
|
||||
.slice(0, PLEBS_PER_ROW)
|
||||
.map((tag) => (
|
||||
<div key={tag} className="relative mr-4 h-11 w-11 gap-2 rounded-md bg-zinc-900 shadow-xl">
|
||||
<img src={tag} alt={tag} className="h-11 w-11 rounded-md border border-zinc-900" />
|
||||
<Image src={tag} alt={tag} className="h-11 w-11 rounded-md border border-zinc-900" />
|
||||
</div>
|
||||
))}
|
||||
</InfiniteLoopSlider>
|
||||
|
@@ -5,7 +5,7 @@
|
||||
/* Fixed webkit bug: https://bugs.webkit.org/show_bug.cgi?id=243601 */
|
||||
@supports (font: -apple-system-body) and (-webkit-appearance: none) {
|
||||
img[loading='lazy'] {
|
||||
clip-path: inset(0.1px);
|
||||
clip-path: inset(0.6px);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { Image } from '@lume/shared/image';
|
||||
import { DEFAULT_AVATAR } from '@lume/stores/constants';
|
||||
|
||||
export default function ActiveAccount({ user }: { user: any }) {
|
||||
@@ -5,7 +6,11 @@ export default function ActiveAccount({ user }: { user: any }) {
|
||||
|
||||
return (
|
||||
<button className="relative h-11 w-11 rounded-lg">
|
||||
<img src={userData.picture || DEFAULT_AVATAR} alt="user's avatar" className="h-11 w-11 rounded-lg object-cover" />
|
||||
<Image
|
||||
src={userData.picture || DEFAULT_AVATAR}
|
||||
alt="user's avatar"
|
||||
className="h-11 w-11 rounded-lg object-cover"
|
||||
/>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import { Image } from '@lume/shared/image';
|
||||
import { DEFAULT_AVATAR } from '@lume/stores/constants';
|
||||
|
||||
export default function InactiveAccount({ user }: { user: any }) {
|
||||
@@ -5,7 +6,11 @@ export default function InactiveAccount({ user }: { user: any }) {
|
||||
|
||||
return (
|
||||
<div className="relative h-11 w-11 shrink rounded-lg">
|
||||
<img src={userData.picture || DEFAULT_AVATAR} alt="user's avatar" className="h-11 w-11 rounded-lg object-cover" />
|
||||
<Image
|
||||
src={userData.picture || DEFAULT_AVATAR}
|
||||
alt="user's avatar"
|
||||
className="h-11 w-11 rounded-lg object-cover"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
9
src/shared/image.tsx
Normal file
9
src/shared/image.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import { DEFAULT_AVATAR } from '@lume/stores/constants';
|
||||
|
||||
export const Image = (props) => {
|
||||
const addImageFallback = (event) => {
|
||||
event.currentTarget.src = DEFAULT_AVATAR;
|
||||
};
|
||||
|
||||
return <img {...props} loading="lazy" decoding="async" onError={addImageFallback} />;
|
||||
};
|
@@ -1,4 +1,5 @@
|
||||
import { RelayContext } from '@lume/shared/relaysProvider';
|
||||
import { Image } from '@lume/shared/image';
|
||||
import { RelayContext } from '@lume/shared/relayProvider';
|
||||
import { DEFAULT_AVATAR, READONLY_RELAYS } from '@lume/stores/constants';
|
||||
import { shortenKey } from '@lume/utils/shortenKey';
|
||||
|
||||
@@ -21,11 +22,11 @@ export default function ProfileMetadata({ id }: { id: string }) {
|
||||
<>
|
||||
<div className="relative">
|
||||
<div className="relative h-56 w-full rounded-t-lg bg-zinc-800">
|
||||
<img src={profile?.banner || DEFAULT_BANNER} alt="user's banner" className="h-58 w-full object-cover" />
|
||||
<Image src={profile?.banner || DEFAULT_BANNER} alt="user's banner" className="h-58 w-full object-cover" />
|
||||
</div>
|
||||
<div className="relative -top-8 z-10 px-4">
|
||||
<div className="relative h-16 w-16 rounded-lg bg-zinc-900 ring-2 ring-zinc-900">
|
||||
<img src={profile?.picture || DEFAULT_AVATAR} alt={id} className="h-16 w-16 rounded-lg object-cover" />
|
||||
<Image src={profile?.picture || DEFAULT_AVATAR} alt={id} className="h-16 w-16 rounded-lg object-cover" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
Reference in New Issue
Block a user