@@ -6,15 +6,17 @@ import MDXContent from "@theme/MDXContent";
66import useDocusaurusContext from "@docusaurus/useDocusaurusContext" ;
77
88const TypingComponent = ( { text, speed = 100 } ) => {
9+ const safeText = text || '摘要生成中...' ;
910 const [ displayedText , setDisplayedText ] = useState ( '' ) ;
1011
1112 useEffect ( ( ) => {
1213 let index = 0 ;
14+ setDisplayedText ( '' ) ;
1315
1416 const typingInterval = setInterval ( ( ) => {
1517 setDisplayedText ( ( prevText ) => {
16- if ( index < text . length ) {
17- return prevText + text [ index ++ ] ;
18+ if ( index < safeText . length ) {
19+ return prevText + safeText [ index ++ ] ;
1820 } else {
1921 clearInterval ( typingInterval ) ;
2022 return prevText ;
@@ -23,7 +25,7 @@ const TypingComponent = ({ text, speed = 100 }) => {
2325 } , speed ) ;
2426
2527 return ( ) => clearInterval ( typingInterval ) ;
26- } , [ text , speed ] ) ;
28+ } , [ safeText , speed ] ) ;
2729
2830 return < > { displayedText } </ > ;
2931} ;
@@ -33,17 +35,18 @@ const JsonReader = ({
3335} ) => {
3436 // 替换url与/
3537 const path = fieldToMatch . replace ( / h t t p s : \/ \/ j i a n g m i e m i e .c o m \/ / , "" ) . replace ( / \/ / g, "_" ) ;
36- const url = `https://chat.jiangyang.fun/summary/${ path } .json` ;
38+ const url = `https://chat.jiangyang.fun/static/ summary/${ path } .json` ;
3739 const [ jsonData , setJsonData ] = useState ( null ) ;
3840
3941 useEffect ( ( ) => {
4042 const fetchData = async ( ) => {
4143 try {
4244 const response = await fetch ( url ) ;
45+ if ( ! response . ok ) return ;
4346 const data = await response . json ( ) ;
4447 setJsonData ( data ) ;
4548 } catch ( error ) {
46- console . error ( "Error fetching JSON:" , error ) ;
49+ // fetch failed, keep jsonData as null to show fallback text
4750 }
4851 } ;
4952
@@ -97,19 +100,24 @@ function formatTime(seconds) {
97100
98101const AiPodcast = ( { pageurl } ) => {
99102 const path = pageurl . replace ( / h t t p s : \/ \/ j i a n g m i e m i e .c o m \/ / , "" ) . replace ( / \/ / g, "_" ) ;
100- const audioUrl = `https://chat.jiangyang.fun/summary/${ path } .mp3` ;
103+ const audioUrl = `https://chat.jiangyang.fun/static/ summary/${ path } .mp3` ;
101104
102105 const audioRef = useRef ( null ) ;
103106 const [ available , setAvailable ] = useState ( null ) ;
104107 const [ playing , setPlaying ] = useState ( false ) ;
105108 const [ currentTime , setCurrentTime ] = useState ( 0 ) ;
106109 const [ duration , setDuration ] = useState ( 0 ) ;
107110
108- useEffect ( ( ) => {
109- fetch ( audioUrl , { method : "HEAD" } )
110- . then ( ( res ) => setAvailable ( res . ok ) )
111- . catch ( ( ) => setAvailable ( false ) ) ;
112- } , [ audioUrl ] ) ;
111+ const handleLoaded = useCallback ( ( ) => {
112+ if ( audioRef . current ) {
113+ setDuration ( audioRef . current . duration ) ;
114+ setAvailable ( true ) ;
115+ }
116+ } , [ ] ) ;
117+
118+ const handleError = useCallback ( ( ) => {
119+ setAvailable ( false ) ;
120+ } , [ ] ) ;
113121
114122 const togglePlay = useCallback ( ( ) => {
115123 const audio = audioRef . current ;
@@ -126,10 +134,6 @@ const AiPodcast = ({ pageurl }) => {
126134 if ( audioRef . current ) setCurrentTime ( audioRef . current . currentTime ) ;
127135 } , [ ] ) ;
128136
129- const handleLoaded = useCallback ( ( ) => {
130- if ( audioRef . current ) setDuration ( audioRef . current . duration ) ;
131- } , [ ] ) ;
132-
133137 const handleEnded = useCallback ( ( ) => setPlaying ( false ) , [ ] ) ;
134138
135139 const handleSeek = useCallback ( ( e ) => {
@@ -140,20 +144,23 @@ const AiPodcast = ({ pageurl }) => {
140144 audio . currentTime = ratio * duration ;
141145 } , [ duration ] ) ;
142146
143- if ( available === null || available === false ) return null ;
147+ if ( available === false ) return null ;
144148
145149 const progress = duration > 0 ? ( currentTime / duration ) * 100 : 0 ;
146150
147151 return (
148- < div className = "post-ai podcast-player" >
152+ < >
149153 < audio
150154 ref = { audioRef }
151155 src = { audioUrl }
152156 preload = "metadata"
153157 onTimeUpdate = { handleTimeUpdate }
154158 onLoadedMetadata = { handleLoaded }
155159 onEnded = { handleEnded }
160+ onError = { handleError }
156161 />
162+ { available === true && (
163+ < div className = "post-ai podcast-player" >
157164 < div className = "ai-title" >
158165 < div className = "ai-title-left" >
159166 < div className = "ai-title-text" > AI 对谈</ div >
@@ -189,6 +196,8 @@ const AiPodcast = ({ pageurl }) => {
189196 < div className = "ai-tips" > AI 根据文章生成的播客对话,仅供参考</ div >
190197 </ div >
191198 </ div >
199+ ) }
200+ </ >
192201 ) ;
193202} ;
194203
0 commit comments