File size: 1,573 Bytes
a8b3f00
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import { useEffect, useRef, useState } from 'react'
import type { ModerationService } from '@/models/common'

function splitStringByLength(inputString: string, chunkLength: number) {
  const resultArray = []
  for (let i = 0; i < inputString.length; i += chunkLength)
    resultArray.push(inputString.substring(i, i + chunkLength))

  return resultArray
}

export const useModerate = (
  content: string,
  stop: boolean,
  moderationService: (text: string) => ReturnType<ModerationService>,
  separateLength = 50,
) => {
  const moderatedContentMap = useRef<Map<number, string>>(new Map())
  const moderatingIndex = useRef<number[]>([])
  const [contentArr, setContentArr] = useState<string[]>([])

  const handleModerate = () => {
    const stringArr = splitStringByLength(content, separateLength)

    const lastIndex = stringArr.length - 1
    stringArr.forEach((item, index) => {
      if (!(index in moderatingIndex.current) && !moderatedContentMap.current.get(index)) {
        if (index === lastIndex && !stop)
          return

        moderatingIndex.current.push(index)
        moderationService(item).then((res) => {
          if (res.flagged) {
            moderatedContentMap.current.set(index, res.text)
            setContentArr([...stringArr.slice(0, index), res.text, ...stringArr.slice(index + 1)])
          }
        })
      }
    })

    setContentArr(stringArr)
  }
  useEffect(() => {
    if (content)
      handleModerate()
  }, [content, stop])

  return contentArr.map((item, index) => moderatedContentMap.current.get(index) || item).join('')
}