File size: 2,510 Bytes
8f2b05f
1185ec1
8f2b05f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29f166e
 
8f2b05f
 
 
 
29f166e
 
8f2b05f
 
29f166e
 
 
 
 
 
8f2b05f
 
 
 
29f166e
 
8f2b05f
 
 
 
29f166e
 
8f2b05f
 
29f166e
 
 
 
 
 
8f2b05f
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import { useEffect, useState, useTransition } from "react"
import { VideoInfo, VideoRating } from "@/types/general"

import { GenericLikeButton } from "./generic"
import { getVideoRating, rateVideo } from "@/app/server/actions/stats"
import { useLocalStorage } from "usehooks-ts"
import { localStorageKeys } from "@/app/state/localStorageKeys"
import { defaultSettings } from "@/app/state/defaultSettings"

export function LikeButton({
  video
}: {
  video?: VideoInfo
}) {
  const [_pending, startTransition] = useTransition()

  const [rating, setRating] = useState<VideoRating>({
    isLikedByUser: false,
    isDislikedByUser: false,
    numberOfLikes: 0,
    numberOfDislikes: 0,
  })

  const [huggingfaceApiKey] = useLocalStorage<string>(
    localStorageKeys.huggingfaceApiKey,
    defaultSettings.huggingfaceApiKey
  )

  useEffect(() => {
    startTransition(async () => {
      if (!video || !video?.id) { return }

      const freshRating = await getVideoRating(video.id, huggingfaceApiKey)
      setRating(freshRating)

    })
  }, [video?.id, huggingfaceApiKey])

  if (!video) { return null }
  
  if (!huggingfaceApiKey) { return null }

  const handleLike = huggingfaceApiKey ? () => {
    // we use optimistic updates
    const previousRating = { ...rating }
    setRating({
      ...rating,
      isLikedByUser: true,
      isDislikedByUser: false,
      numberOfLikes:  Math.abs(Math.max(0, rating.numberOfLikes + 1)),
      numberOfDislikes:  Math.abs(Math.max(0, rating.numberOfDislikes - 1)),
    })
    startTransition(async () => {
      try {
        const freshRating = await rateVideo(video.id, true, huggingfaceApiKey)
        // setRating(freshRating)
      } catch (err) {
        setRating(previousRating)
      }
    })
  } : undefined

  const handleDislike = huggingfaceApiKey ? () => {
    // we use optimistic updates
    const previousRating = { ...rating }
    setRating({
      ...rating,
      isLikedByUser: false,
      isDislikedByUser: true,
      numberOfLikes: Math.abs(Math.max(0, rating.numberOfLikes - 1)),
      numberOfDislikes: Math.abs(Math.max(0, rating.numberOfDislikes + 1)),
    })
    startTransition(async () => {
      try {
        const freshRating = await rateVideo(video.id, false, huggingfaceApiKey)
        // setRating(freshRating)
      } catch (err) {
        setRating(previousRating)
      }
    })
  } : undefined

  return (
    <GenericLikeButton
      {...rating}
      onLike={handleLike}
      onDislike={handleDislike}
    />
  )
}