manifold/web/components/follow-button.tsx

123 lines
2.9 KiB
TypeScript
Raw Normal View History

import { CheckCircleIcon, PlusCircleIcon } from '@heroicons/react/solid'
import clsx from 'clsx'
import { useEffect, useRef, useState } from 'react'
import { useFollows } from 'web/hooks/use-follows'
import { useUser } from 'web/hooks/use-user'
import { follow, unfollow } from 'web/lib/firebase/users'
import { withTracking } from 'web/lib/service/analytics'
import { Button } from './button'
export function FollowButton(props: {
isFollowing: boolean | undefined
onFollow: () => void
onUnfollow: () => void
className?: string
}) {
const { isFollowing, onFollow, onUnfollow, className } = props
const user = useUser()
if (!user || isFollowing === undefined)
return (
<Button size="sm" color="gray" className={clsx(className, 'invisible')}>
Follow
</Button>
)
if (isFollowing) {
return (
<Button
size="sm"
color="gray-outline"
className={clsx('my-auto', className)}
onClick={withTracking(onUnfollow, 'unfollow')}
>
Following
</Button>
)
}
return (
<Button
size="sm"
color="indigo"
className={clsx(className, 'my-auto')}
onClick={withTracking(onFollow, 'follow')}
>
Follow
</Button>
)
}
export function UserFollowButton(props: { userId: string }) {
const { userId } = props
const user = useUser()
const following = useFollows(user?.id)
const isFollowing = following?.includes(userId)
if (!user || user.id === userId) return null
return (
<FollowButton
isFollowing={isFollowing}
onFollow={() => follow(user.id, userId)}
onUnfollow={() => unfollow(user.id, userId)}
/>
)
}
export function MiniUserFollowButton(props: { userId: string }) {
const { userId } = props
const user = useUser()
const following = useFollows(user?.id)
const isFollowing = following?.includes(userId)
const isFirstRender = useRef(true)
const [justFollowed, setJustFollowed] = useState(false)
useEffect(() => {
if (isFirstRender.current) {
if (isFollowing != undefined) {
isFirstRender.current = false
}
return
}
if (isFollowing) {
setJustFollowed(true)
setTimeout(() => {
setJustFollowed(false)
}, 1000)
}
}, [isFollowing])
if (justFollowed) {
return (
<CheckCircleIcon
className={clsx(
'text-highlight-blue ml-3 mt-2 h-5 w-5 rounded-full bg-white sm:mr-2'
)}
aria-hidden="true"
/>
)
}
if (
!user ||
user.id === userId ||
isFollowing ||
!user ||
isFollowing === undefined
)
return null
return (
<>
<button onClick={withTracking(() => follow(user.id, userId), 'follow')}>
<PlusCircleIcon
className={clsx(
'text-highlight-blue hover:text-hover-blue mt-2 ml-3 h-5 w-5 rounded-full bg-white sm:mr-2'
)}
aria-hidden="true"
/>
</button>
</>
)
}