|
import * as React from 'react'; |
|
import { CREATE_MUTATION, DESTROY_MUTATION } from './Mutation'; |
|
import MutationButton, { |
|
IProps as IButtonProps, |
|
} from '~/components/MutationButton'; |
|
import { polymorphicInput } from '~/utils/graphql'; |
|
import { FollowButtonFragment } from '~/graphql/types'; |
|
import useViewerProfile from '~/hooks/useViewerProfile'; |
|
|
|
type Subject = FollowButtonFragment & { |
|
profile?: { |
|
id: string; |
|
}; |
|
}; |
|
|
|
interface IProps { |
|
subject: Subject; |
|
className?: string; |
|
showCount: boolean; |
|
size: IButtonProps['size']; |
|
variant: IButtonProps['variant']; |
|
} |
|
|
|
export default function FollowButton({ |
|
subject, |
|
showCount, |
|
className, |
|
size, |
|
variant, |
|
}: IProps) { |
|
const viewerProfile = useViewerProfile(); |
|
|
|
if ( |
|
subject.__typename === 'Profile' && |
|
viewerProfile && |
|
viewerProfile.id === subject.id |
|
) { |
|
return null; |
|
} |
|
|
|
if ( |
|
subject.profile && |
|
viewerProfile && |
|
viewerProfile.id === subject.profile.id |
|
) { |
|
return null; |
|
} |
|
|
|
const mutation = subject.isFollowed ? DESTROY_MUTATION : CREATE_MUTATION; |
|
const optimistic = subject.isFollowed ? optimisticDestroy : optimisticCreate; |
|
|
|
return ( |
|
<MutationButton |
|
input={polymorphicInput('subject', subject)} |
|
mutation={mutation} |
|
optimisticResponse={optimistic(subject)} |
|
size={size} |
|
variant={variant} |
|
requireLogin={true} |
|
className={className} |
|
active={subject.isFollowed} |
|
label={subject.isFollowed ? 'Following' : 'Follow'} |
|
count={showCount ? subject.followersCount : null} |
|
/> |
|
); |
|
} |
|
|
|
FollowButton.defaultProps = { |
|
showCount: false, |
|
size: 'medium', |
|
variant: 'line', |
|
}; |
|
|
|
const optimisticCreate = (node: Subject) => ({ |
|
response: { |
|
__typename: 'FollowCreatePayload', |
|
node: { |
|
...node, |
|
isFollowed: true, |
|
followersCount: node.followersCount + 1, |
|
}, |
|
errors: null, |
|
}, |
|
}); |
|
|
|
const optimisticDestroy = (node: Subject) => ({ |
|
response: { |
|
__typename: 'FollowDestroyPayload', |
|
node: { |
|
...node, |
|
isFollowed: false, |
|
followersCount: node.followersCount - 1, |
|
}, |
|
errors: null, |
|
}, |
|
}); |