File size: 2,507 Bytes
8f2b05f
 
ac7030c
 
3d4392e
8f2b05f
 
 
ac7030c
8f2b05f
ac7030c
8f2b05f
ac7030c
8f2b05f
 
 
ac7030c
8f2b05f
 
 
 
 
 
 
 
 
 
 
 
 
ac7030c
8f2b05f
ac7030c
8f2b05f
 
 
ac7030c
8f2b05f
ac7030c
8f2b05f
 
 
 
29f166e
 
8f2b05f
 
 
 
29f166e
 
8f2b05f
 
29f166e
ac7030c
29f166e
 
 
 
8f2b05f
 
 
 
29f166e
 
8f2b05f
 
 
 
29f166e
 
8f2b05f
 
29f166e
ac7030c
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 { useLocalStorage } from "usehooks-ts"

import { MediaInfo, MediaRating } from "@/types/general"
import { getMediaRating, rateMedia } from "@/app/api/actions/stats"
import { localStorageKeys } from "@/app/state/localStorageKeys"
import { defaultSettings } from "@/app/state/defaultSettings"

import { GenericLikeButton } from "./generic"
export function LikeButton({
  media
}: {
  media?: MediaInfo
}) {
  const [_pending, startTransition] = useTransition()

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

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

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

      const freshRating = await getMediaRating(media.id, huggingfaceApiKey)
      setRating(freshRating)

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

  if (!media) { 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 rateMedia(media.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 rateMedia(media.id, false, huggingfaceApiKey)
        // setRating(freshRating)
      } catch (err) {
        setRating(previousRating)
      }
    })
  } : undefined

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