|
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('') |
|
} |
|
|