feat: 💨
This commit is contained in:
parent
a9f115d202
commit
f48f7d9edd
3 changed files with 56 additions and 27 deletions
|
|
@ -1,8 +1,8 @@
|
||||||
import { FormattedTimestamp } from '@/components/FormattedTimestamp'
|
import { FormattedTimestamp } from '@/components/FormattedTimestamp'
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
import { Skeleton } from '@/components/ui/skeleton'
|
import { Skeleton } from '@/components/ui/skeleton'
|
||||||
import UserAvatar from '@/components/UserAvatar'
|
import UserAvatar, { SimpleUserAvatar } from '@/components/UserAvatar'
|
||||||
import Username from '@/components/Username'
|
import Username, { SimpleUsername } from '@/components/Username'
|
||||||
import { isMentioningMutedUsers } from '@/lib/event'
|
import { isMentioningMutedUsers } from '@/lib/event'
|
||||||
import { toNote, toUserAggregationDetail } from '@/lib/link'
|
import { toNote, toUserAggregationDetail } from '@/lib/link'
|
||||||
import { cn, isTouchDevice } from '@/lib/utils'
|
import { cn, isTouchDevice } from '@/lib/utils'
|
||||||
|
|
@ -371,6 +371,7 @@ function UserAggregationItem({
|
||||||
onClick: () => void
|
onClick: () => void
|
||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
const supportTouch = useMemo(() => isTouchDevice(), [])
|
||||||
const [hasNewEvents, setHasNewEvents] = useState(true)
|
const [hasNewEvents, setHasNewEvents] = useState(true)
|
||||||
const [isPinned, setIsPinned] = useState(userAggregationService.isPinned(aggregation.pubkey))
|
const [isPinned, setIsPinned] = useState(userAggregationService.isPinned(aggregation.pubkey))
|
||||||
|
|
||||||
|
|
@ -418,14 +419,26 @@ function UserAggregationItem({
|
||||||
className="group relative flex items-center gap-4 px-4 py-3 border-b hover:bg-accent/30 cursor-pointer transition-all duration-200"
|
className="group relative flex items-center gap-4 px-4 py-3 border-b hover:bg-accent/30 cursor-pointer transition-all duration-200"
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
>
|
>
|
||||||
<UserAvatar userId={aggregation.pubkey} />
|
{supportTouch ? (
|
||||||
|
<SimpleUserAvatar userId={aggregation.pubkey} />
|
||||||
|
) : (
|
||||||
|
<UserAvatar userId={aggregation.pubkey} />
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="flex-1 min-w-0 flex flex-col">
|
<div className="flex-1 min-w-0 flex flex-col">
|
||||||
<Username
|
{supportTouch ? (
|
||||||
userId={aggregation.pubkey}
|
<SimpleUsername
|
||||||
className="font-semibold text-base truncate max-w-fit"
|
userId={aggregation.pubkey}
|
||||||
skeletonClassName="h-4"
|
className="font-semibold text-base truncate max-w-fit"
|
||||||
/>
|
skeletonClassName="h-4"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Username
|
||||||
|
userId={aggregation.pubkey}
|
||||||
|
className="font-semibold text-base truncate max-w-fit"
|
||||||
|
skeletonClassName="h-4"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<FormattedTimestamp
|
<FormattedTimestamp
|
||||||
timestamp={aggregation.lastEventTime}
|
timestamp={aggregation.lastEventTime}
|
||||||
className="text-sm text-muted-foreground"
|
className="text-sm text-muted-foreground"
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { Skeleton } from '@/components/ui/skeleton'
|
||||||
import { useFetchProfile } from '@/hooks'
|
import { useFetchProfile } from '@/hooks'
|
||||||
import { toProfile } from '@/lib/link'
|
import { toProfile } from '@/lib/link'
|
||||||
import { generateImageByPubkey } from '@/lib/pubkey'
|
import { generateImageByPubkey } from '@/lib/pubkey'
|
||||||
import { cn } from '@/lib/utils'
|
import { cn, isTouchDevice } from '@/lib/utils'
|
||||||
import { SecondaryPageLink } from '@/PageManager'
|
import { SecondaryPageLink } from '@/PageManager'
|
||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import Image from '../Image'
|
import Image from '../Image'
|
||||||
|
|
@ -29,13 +29,21 @@ export default function UserAvatar({
|
||||||
className?: string
|
className?: string
|
||||||
size?: 'large' | 'big' | 'semiBig' | 'normal' | 'medium' | 'small' | 'xSmall' | 'tiny'
|
size?: 'large' | 'big' | 'semiBig' | 'normal' | 'medium' | 'small' | 'xSmall' | 'tiny'
|
||||||
}) {
|
}) {
|
||||||
|
const supportTouch = useMemo(() => isTouchDevice(), [])
|
||||||
|
|
||||||
|
const trigger = (
|
||||||
|
<SecondaryPageLink to={toProfile(userId)} onClick={(e) => e.stopPropagation()}>
|
||||||
|
<SimpleUserAvatar userId={userId} size={size} className={className} />
|
||||||
|
</SecondaryPageLink>
|
||||||
|
)
|
||||||
|
|
||||||
|
if (supportTouch) {
|
||||||
|
return trigger
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HoverCard>
|
<HoverCard>
|
||||||
<HoverCardTrigger>
|
<HoverCardTrigger>{trigger}</HoverCardTrigger>
|
||||||
<SecondaryPageLink to={toProfile(userId)} onClick={(e) => e.stopPropagation()}>
|
|
||||||
<SimpleUserAvatar userId={userId} size={size} className={className} />
|
|
||||||
</SecondaryPageLink>
|
|
||||||
</HoverCardTrigger>
|
|
||||||
<HoverCardContent className="w-72">
|
<HoverCardContent className="w-72">
|
||||||
<ProfileCard userId={userId} />
|
<ProfileCard userId={userId} />
|
||||||
</HoverCardContent>
|
</HoverCardContent>
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,11 @@ import { HoverCard, HoverCardContent, HoverCardTrigger } from '@/components/ui/h
|
||||||
import { Skeleton } from '@/components/ui/skeleton'
|
import { Skeleton } from '@/components/ui/skeleton'
|
||||||
import { useFetchProfile } from '@/hooks'
|
import { useFetchProfile } from '@/hooks'
|
||||||
import { toProfile } from '@/lib/link'
|
import { toProfile } from '@/lib/link'
|
||||||
import { cn } from '@/lib/utils'
|
import { cn, isTouchDevice } from '@/lib/utils'
|
||||||
import { SecondaryPageLink } from '@/PageManager'
|
import { SecondaryPageLink } from '@/PageManager'
|
||||||
import ProfileCard from '../ProfileCard'
|
import ProfileCard from '../ProfileCard'
|
||||||
import TextWithEmojis from '../TextWithEmojis'
|
import TextWithEmojis from '../TextWithEmojis'
|
||||||
|
import { useMemo } from 'react'
|
||||||
|
|
||||||
export default function Username({
|
export default function Username({
|
||||||
userId,
|
userId,
|
||||||
|
|
@ -21,6 +22,7 @@ export default function Username({
|
||||||
withoutSkeleton?: boolean
|
withoutSkeleton?: boolean
|
||||||
}) {
|
}) {
|
||||||
const { profile, isFetching } = useFetchProfile(userId)
|
const { profile, isFetching } = useFetchProfile(userId)
|
||||||
|
const supportTouch = useMemo(() => isTouchDevice(), [])
|
||||||
if (!profile && isFetching && !withoutSkeleton) {
|
if (!profile && isFetching && !withoutSkeleton) {
|
||||||
return (
|
return (
|
||||||
<div className="py-1">
|
<div className="py-1">
|
||||||
|
|
@ -30,20 +32,26 @@ export default function Username({
|
||||||
}
|
}
|
||||||
if (!profile) return null
|
if (!profile) return null
|
||||||
|
|
||||||
|
const trigger = (
|
||||||
|
<div className={className}>
|
||||||
|
<SecondaryPageLink
|
||||||
|
to={toProfile(userId)}
|
||||||
|
className="truncate hover:underline"
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
>
|
||||||
|
{showAt && '@'}
|
||||||
|
<TextWithEmojis text={profile.username} emojis={profile.emojis} emojiClassName="mb-1" />
|
||||||
|
</SecondaryPageLink>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
if (supportTouch) {
|
||||||
|
return trigger
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HoverCard>
|
<HoverCard>
|
||||||
<HoverCardTrigger asChild>
|
<HoverCardTrigger asChild>{trigger}</HoverCardTrigger>
|
||||||
<div className={className}>
|
|
||||||
<SecondaryPageLink
|
|
||||||
to={toProfile(userId)}
|
|
||||||
className="truncate hover:underline"
|
|
||||||
onClick={(e) => e.stopPropagation()}
|
|
||||||
>
|
|
||||||
{showAt && '@'}
|
|
||||||
<TextWithEmojis text={profile.username} emojis={profile.emojis} emojiClassName="mb-1" />
|
|
||||||
</SecondaryPageLink>
|
|
||||||
</div>
|
|
||||||
</HoverCardTrigger>
|
|
||||||
<HoverCardContent className="w-80">
|
<HoverCardContent className="w-80">
|
||||||
<ProfileCard userId={userId} />
|
<ProfileCard userId={userId} />
|
||||||
</HoverCardContent>
|
</HoverCardContent>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue