{"version":3,"file":"Comments-ed029e9c.js","sources":["../src/hooks/useComments.js","../src/hooks/useCommentPost.js","../src/hooks/usePolling.js","../src/components/Comments.jsx"],"sourcesContent":["import { useRef, useState, useCallback, useEffect } from 'react';\nimport { GetToken } from '@utils/storage';\nimport * as config from '@config';\nimport PropTypes from 'prop-types';\nimport { useWs } from '../contexts/WsContext';\nimport { PubSubDataType, PubSubCMD } from '../wsManager';\n\nfunction useComments() {\n const [fetching, setFetching] = useState(false);\n const [comments, setComments] = useState([]);\n const abortControllerRef = useRef(null);\n const fetchParamsRef = useRef({ commentOnID: null, selfOnly: false }); // Store the current query params\n const { wsManager } = useWs();\n\n useEffect(() => {\n if (!wsManager) return;\n const handleMessage = (data) => {\n // console.log('useComments received message:', data);\n try {\n const message = JSON.parse(data);\n switch (message.type) {\n case PubSubDataType.CMD:\n if (message.data === PubSubCMD.REFRESH_COMMENTS) {\n console.log('cmd to refresh comments');\n const { commentOnID, selfOnly } = fetchParamsRef.current;\n fetchComments(commentOnID, { selfOnly }).catch((err) => {\n console.error('Error refreshing comments:', err);\n });\n }\n break;\n default:\n console.log('dont know what to do with this message');\n break;\n }\n } catch (error) {\n console.err('Error parsing message');\n }\n };\n wsManager.addMessageListener(handleMessage);\n // Cleanup function to remove the listener when the component unmounts\n return () => {\n wsManager.removeMessageListener(handleMessage);\n };\n }, [wsManager]);\n\n const fetchComments = useCallback(async (commentOnID, { selfOnly = false }) => {\n setFetching(true);\n abortControllerRef.current = new AbortController();\n const query = {\n id: commentOnID,\n selfOnly: selfOnly,\n };\n const queryString = new URLSearchParams(query).toString();\n fetchParamsRef.current = { commentOnID, selfOnly };\n try {\n const response = await fetch(`${config.apiURL}/comments?${queryString}`, {\n method: 'GET',\n headers: { Authorization: `Bearer ${GetToken()}` },\n signal: abortControllerRef.current.signal,\n });\n\n //Uses response.ok to check for successful responses, which covers all 2xx status codes.\n if (!response.ok) {\n const data = await response.json();\n throw new Error(data.error || 'An error occurred while updating the order');\n }\n const data = await response.json();\n setComments(data.comments || []);\n return data;\n } catch (error) {\n if (error.name === 'AbortError') {\n console.log('Request was aborted');\n throw new Error('Request was aborted');\n } else {\n console.error('Error fetch comments:', error);\n }\n throw error;\n } finally {\n setFetching(false);\n }\n }, []);\n\n fetchComments.propTypes = {\n commentOnID: PropTypes.string.isRequired,\n options: PropTypes.shape({\n selfOnly: PropTypes.bool,\n }),\n };\n\n const abort = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n }, []);\n\n return { fetching, comments, fetchComments, abort };\n}\n\nexport default useComments;\n","import { useState, useRef, useCallback } from 'react';\nimport PropTypes from 'prop-types';\nimport { GetToken } from '@utils/storage';\nimport * as config from '@config';\n\nfunction useConmmentPost() {\n const [posting, setPosting] = useState(false);\n const abortControllerRef = useRef(null);\n\n const postComment = useCallback(async ({ commentOnID, comment }) => {\n if (!comment) return;\n //use fetch to post comment\n setPosting(true);\n const req = {\n comment: comment,\n commentOnID: commentOnID,\n };\n console.log('req', req);\n abortControllerRef.current = new AbortController();\n try {\n const response = await fetch(`${config.apiURL}/comments`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${GetToken()}`,\n },\n body: JSON.stringify(req),\n signal: abortControllerRef.current.signal,\n });\n if (!response.ok) {\n const data = await response.json();\n throw new Error(data.error || 'An error occurred post a comment');\n }\n const result = await response.json();\n return result;\n } catch (error) {\n if (error.name === 'AbortError') {\n console.log('Request was aborted');\n throw new Error('Request was aborted');\n } else {\n console.error('Error posting a comment:', error);\n }\n throw error;\n } finally {\n setPosting(false);\n }\n }, []);\n\n postComment.propTypes = {\n commentOnID: PropTypes.string.isRequired,\n comment: PropTypes.string.isRequired,\n };\n\n const abort = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n }, []);\n\n return { posting, postComment, abort };\n}\n\nuseConmmentPost.propTypes = {};\n\nexport default useConmmentPost;\n","import { useEffect, useCallback, useRef, useState } from 'react';\n\n/**\n * Custom hook for polling any async function with progress indication\n * @param {function} action - Async function to be called periodically\n * @param {Object} options - Configuration options\n * @param {number} options.interval - Polling interval in milliseconds (default: 5000)\n * @param {boolean} options.immediate - Whether to execute immediately on mount (default: true)\n * @param {boolean} options.enabled - Whether polling should be active (default: true)\n * @returns {Object} - Contains polling control functions, status and progress\n */\nconst usePolling = (action, { interval = 5000, immediate = true, enabled = true } = {}) => {\n const timeoutRef = useRef(null);\n const progressIntervalRef = useRef(null);\n const mountedRef = useRef(true);\n const actionRef = useRef(action);\n const [isActive, setIsActive] = useState(enabled);\n const [nextPollIn, setNextPollIn] = useState(interval);\n\n // Keep the latest action function in ref\n useEffect(() => {\n actionRef.current = action;\n }, [action]);\n\n // Clear all timers\n const clearTimers = useCallback(() => {\n if (timeoutRef.current) {\n clearTimeout(timeoutRef.current);\n }\n if (progressIntervalRef.current) {\n clearInterval(progressIntervalRef.current);\n }\n }, []);\n\n // Start progress tracking\n const startProgressTracking = useCallback(() => {\n setNextPollIn(interval);\n const startTime = Date.now();\n\n progressIntervalRef.current = setInterval(() => {\n const elapsed = Date.now() - startTime;\n const remaining = interval - elapsed;\n\n if (remaining <= 0) {\n clearInterval(progressIntervalRef.current);\n } else {\n setNextPollIn(remaining);\n }\n }, 1000); // Update every second\n }, [interval]);\n\n const execute = useCallback(async () => {\n if (!isActive || !mountedRef.current) return;\n\n clearTimers();\n\n try {\n await actionRef.current();\n } finally {\n if (mountedRef.current && isActive) {\n timeoutRef.current = setTimeout(execute, interval);\n startProgressTracking();\n }\n }\n }, [interval, isActive, clearTimers, startProgressTracking]);\n\n const start = useCallback(() => {\n setIsActive(true);\n }, []);\n\n const stop = useCallback(() => {\n setIsActive(false);\n clearTimers();\n setNextPollIn(interval);\n }, [clearTimers, interval]);\n\n const refresh = useCallback(() => {\n clearTimers();\n execute();\n }, [execute, clearTimers]);\n\n // Cleanup on unmount\n useEffect(() => {\n mountedRef.current = true;\n\n return () => {\n mountedRef.current = false;\n clearTimers();\n };\n }, [clearTimers]);\n\n // Handle enabled prop changes\n useEffect(() => {\n setIsActive(enabled);\n }, [enabled]);\n\n // Start/stop polling based on isActive state\n useEffect(() => {\n if (isActive) {\n if (immediate) {\n execute();\n } else {\n timeoutRef.current = setTimeout(execute, interval);\n startProgressTracking();\n }\n } else {\n clearTimers();\n }\n\n return clearTimers;\n }, [execute, isActive, immediate, interval, clearTimers, startProgressTracking]);\n\n return {\n start,\n stop,\n refresh,\n isPolling: isActive,\n nextPollIn, // Milliseconds until next poll\n progress: ((interval - nextPollIn) / interval) * 100, //// Percentage complete (0-100)\n };\n};\n\nexport default usePolling;\n","import React from 'react';\nimport PropTypes from 'prop-types';\nimport { useState, useEffect } from 'react';\nimport { Timeago } from '@utils/utils';\nimport { GetUserInfo } from '../utils/storage';\nimport useComments from '../hooks/useComments';\nimport { App, Button, Space, Tag } from 'antd';\nimport useConmmentPost from '../hooks/useCommentPost';\nimport { List, Input } from 'antd';\nimport usePolling from '@hooks/usePolling';\n\nconst { TextArea } = Input;\n\nfunction Comments({ commentOnID = '' }) {\n const loginInfo = GetUserInfo();\n const { fetching, comments, fetchComments, abort: abortFetch } = useComments();\n const { posting, postComment, abort: abortPost } = useConmmentPost();\n const { message } = App.useApp();\n const [addedComment, setAddedComment] = useState('');\n\n useEffect(() => {\n fetchData();\n return () => {\n abortFetch();\n abortPost();\n };\n }, [commentOnID]);\n\n const fetchData = () => {\n // console.log('Polling:', commentOnID);\n if (commentOnID) {\n fetchComments(commentOnID, { selfOnly: false }).catch((err) => {\n message.error(err.toString());\n });\n }\n };\n\n //TODO: manaully start polling when `commentOnID` is not empty\n const { progress, stop, start } = usePolling(fetchData, {\n interval: 10000,\n immediate: true,\n enabled: true,\n });\n\n const handleSubmit = () => {\n if (addedComment) {\n const req = {\n comment: addedComment,\n commentOnID: commentOnID,\n };\n postComment(req)\n .then((res) => {\n setAddedComment('');\n fetchData();\n message.success(res.reply);\n })\n .catch((err) => {\n let msg = err.toString();\n if (err.response?.data?.error) {\n console.log('***', err.response.data.error);\n msg = err.response.data.error;\n }\n window.alert(msg);\n });\n }\n };\n\n return (\n
\n (\n \n
\n

\n {comment.accName} {loginInfo.id == comment.accountID && Me}\n

\n {Timeago(comment.createdAt)}\n
\n
{comment.content}
\n
\n )}\n />\n \n setAddedComment(e.target.value)}\n placeholder=\"留言\"\n autoSize={{\n minRows: 5,\n }}\n />\n \n \n
\n );\n}\n\nComments.propTypes = {\n commentOnID: PropTypes.string,\n};\n\nexport default Comments;\n"],"names":["useComments","fetching","setFetching","useState","comments","setComments","abortControllerRef","useRef","fetchParamsRef","wsManager","useWs","useEffect","handleMessage","data","message","PubSubDataType","PubSubCMD","commentOnID","selfOnly","fetchComments","err","useCallback","query","queryString","response","config.apiURL","GetToken","error","PropTypes","abort","useConmmentPost","posting","setPosting","postComment","comment","req","usePolling","action","interval","immediate","enabled","timeoutRef","progressIntervalRef","mountedRef","actionRef","isActive","setIsActive","nextPollIn","setNextPollIn","clearTimers","startProgressTracking","startTime","elapsed","remaining","execute","start","stop","refresh","TextArea","Input","Comments","loginInfo","GetUserInfo","abortFetch","abortPost","App","addedComment","setAddedComment","fetchData","handleSubmit","res","msg","_b","_a","jsx","List","index","jsxs","Tag","Timeago","Space","e","Button"],"mappings":"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"}