|
@@ -1,9 +1,12 @@
|
|
|
-import React from 'react'
|
|
|
+import React, { useState, useEffect } from 'react'
|
|
|
import { RouteComponentProps, useParams } from '@reach/router'
|
|
|
-import { useQuery } from '@apollo/client'
|
|
|
+import { useQuery, useMutation } from '@apollo/client'
|
|
|
|
|
|
-import { GET_CHANNEL } from '@/api/queries/channels'
|
|
|
+import { GET_CHANNEL, FOLLOW_CHANNEL, UNFOLLOW_CHANNEL } from '@/api/queries/channels'
|
|
|
import { GetChannel, GetChannelVariables } from '@/api/queries/__generated__/GetChannel'
|
|
|
+import { FollowChannel, FollowChannelVariables } from '@/api/queries/__generated__/followChannel'
|
|
|
+import { UnfollowChannel, UnfollowChannelVariables } from '@/api/queries/__generated__/unfollowChannel'
|
|
|
+import { usePersonalData } from '@/hooks'
|
|
|
|
|
|
import {
|
|
|
CoverImage,
|
|
@@ -18,18 +21,81 @@ import {
|
|
|
VideoSection,
|
|
|
SubTitle,
|
|
|
SubTitlePlaceholder,
|
|
|
+ StyledButtonContainer,
|
|
|
} from './ChannelView.style'
|
|
|
import { BackgroundPattern, InfiniteVideoGrid } from '@/components'
|
|
|
+import { Button } from '@/shared/components'
|
|
|
import { CSSTransition, TransitionGroup } from 'react-transition-group'
|
|
|
import { transitions } from '@/shared/theme'
|
|
|
import { formatNumberShort } from '@/utils/number'
|
|
|
|
|
|
+type FollowedChannel = {
|
|
|
+ id: string
|
|
|
+}
|
|
|
+
|
|
|
const ChannelView: React.FC<RouteComponentProps> = () => {
|
|
|
const { id } = useParams()
|
|
|
const { data, loading, error } = useQuery<GetChannel, GetChannelVariables>(GET_CHANNEL, {
|
|
|
variables: { id },
|
|
|
})
|
|
|
+ const [followChannel] = useMutation<FollowChannel, FollowChannelVariables>(FOLLOW_CHANNEL, {
|
|
|
+ variables: {
|
|
|
+ channelId: id,
|
|
|
+ },
|
|
|
+ update: (cache, mutationResult) => {
|
|
|
+ cache.modify({
|
|
|
+ id: cache.identify({
|
|
|
+ __typename: 'Channel',
|
|
|
+ id,
|
|
|
+ }),
|
|
|
+ fields: {
|
|
|
+ follows: () => mutationResult.data?.followChannel.follows,
|
|
|
+ },
|
|
|
+ })
|
|
|
+ },
|
|
|
+ })
|
|
|
+ const [unfollowChannel] = useMutation<UnfollowChannel, UnfollowChannelVariables>(UNFOLLOW_CHANNEL, {
|
|
|
+ variables: {
|
|
|
+ channelId: id,
|
|
|
+ },
|
|
|
+ update: (cache, mutationResult) => {
|
|
|
+ cache.modify({
|
|
|
+ id: cache.identify({
|
|
|
+ __typename: 'Channel',
|
|
|
+ id,
|
|
|
+ }),
|
|
|
+ fields: {
|
|
|
+ follows: () => mutationResult.data?.unfollowChannel.follows,
|
|
|
+ },
|
|
|
+ })
|
|
|
+ },
|
|
|
+ })
|
|
|
+ const {
|
|
|
+ state: { followedChannels },
|
|
|
+ updateChannelFollowing,
|
|
|
+ } = usePersonalData()
|
|
|
+ const [isFollowing, setFollowing] = useState<boolean>()
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ const isFollowing = followedChannels.some((channel) => channel.id === id)
|
|
|
+ setFollowing(isFollowing)
|
|
|
+ }, [followedChannels, id])
|
|
|
|
|
|
+ const handleFollow = () => {
|
|
|
+ try {
|
|
|
+ if (isFollowing) {
|
|
|
+ updateChannelFollowing(id, false)
|
|
|
+ unfollowChannel()
|
|
|
+ setFollowing(false)
|
|
|
+ } else {
|
|
|
+ updateChannelFollowing(id, true)
|
|
|
+ followChannel()
|
|
|
+ setFollowing(true)
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.warn('Failed to update Channel following', { error })
|
|
|
+ }
|
|
|
+ }
|
|
|
if (error) {
|
|
|
throw error
|
|
|
}
|
|
@@ -71,6 +137,11 @@ const ChannelView: React.FC<RouteComponentProps> = () => {
|
|
|
</>
|
|
|
)}
|
|
|
</TitleContainer>
|
|
|
+ <StyledButtonContainer>
|
|
|
+ <Button variant={isFollowing ? 'secondary' : 'primary'} onClick={handleFollow}>
|
|
|
+ {isFollowing ? 'Unfollow' : 'Follow'}
|
|
|
+ </Button>
|
|
|
+ </StyledButtonContainer>
|
|
|
</TitleSection>
|
|
|
</Header>
|
|
|
<VideoSection>
|