refactor: Refactor Article component to use hooks

This commit is contained in:
2025-07-07 17:29:10 +00:00
committed by Tanner Collin
parent 633429c976
commit 7ac4dfa01c

View File

@@ -1,32 +1,24 @@
import React from 'react'; import React, { useState, useEffect, useMemo } from 'react';
import { useParams } from 'react-router-dom';
import { Helmet } from 'react-helmet'; import { Helmet } from 'react-helmet';
import localForage from 'localforage'; import localForage from 'localforage';
import { sourceLink, infoLine, ToggleDot } from './utils.js'; import { sourceLink, infoLine, ToggleDot } from './utils.js';
class Article extends React.Component { function Article({ cache }) {
constructor(props) { const { id } = useParams();
super(props);
const id = this.props.match ? this.props.match.params.id : 'CLOL'; if (id in cache) console.log('cache hit');
const cache = this.props.cache;
if (id in cache) console.log('cache hit'); const [story, setStory] = useState(cache[id] || false);
const [error, setError] = useState(false);
this.state = { const [pConv, setPConv] = useState([]);
story: cache[id] || false,
error: false,
pConv: [],
};
}
componentDidMount() {
const id = this.props.match ? this.props.match.params.id : 'CLOL';
useEffect(() => {
localForage.getItem(id) localForage.getItem(id)
.then( .then(
(value) => { (value) => {
if (value) { if (value) {
this.setState({ story: value }); setStory(value);
} }
} }
); );
@@ -35,79 +27,76 @@ class Article extends React.Component {
.then(res => res.json()) .then(res => res.json())
.then( .then(
(result) => { (result) => {
this.setState({ story: result.story }); setStory(result.story);
localForage.setItem(id, result.story); localForage.setItem(id, result.story);
}, },
(error) => { (error) => {
this.setState({ error: true }); setError(true);
} }
); );
} }, [id]);
pConvert = (n) => { const pConvert = (n) => {
this.setState({ pConv: [...this.state.pConv, n]}); setPConv(prevPConv => [...prevPConv, n]);
} };
render() { const nodes = useMemo(() => {
const id = this.props.match ? this.props.match.params.id : 'CLOL'; if (story && story.text) {
const story = this.state.story;
const error = this.state.error;
const pConv = this.state.pConv;
let nodes = null;
if (story.text) {
let div = document.createElement('div'); let div = document.createElement('div');
div.innerHTML = story.text; div.innerHTML = story.text;
nodes = div.childNodes; return div.childNodes;
} }
return null;
}, [story]);
return ( return (
<div className='article-container'> <div className='article-container'>
{error && <p>Connection error?</p>} {error && <p>Connection error?</p>}
{story ? {story ?
<div className='article'> <div className='article'>
<Helmet> <Helmet>
<title>{story.title} | QotNews</title> <title>{story.title} | QotNews</title>
<meta name="robots" content="noindex" /> <meta name="robots" content="noindex" />
</Helmet> </Helmet>
<h1>{story.title}</h1> <h1>{story.title}</h1>
<div className='info'> <div className='info'>
Source: {sourceLink(story)} Source: {sourceLink(story)}
</div>
{infoLine(story)}
{nodes ?
<div className='story-text'>
{Object.entries(nodes).map(([k, v]) =>
pConv.includes(k) ?
v.innerHTML.split('\n\n').map(x =>
<p dangerouslySetInnerHTML={{ __html: x }} />
)
:
(v.nodeName === '#text' ?
<p>{v.data}</p>
:
<>
<v.localName dangerouslySetInnerHTML={v.innerHTML ? { __html: v.innerHTML } : null} />
{v.localName == 'pre' && <button onClick={() => this.pConvert(k)}>Convert Code to Paragraph</button>}
</>
)
)}
</div>
:
<p>Problem getting article :(</p>
}
</div> </div>
:
<p>loading...</p> {infoLine(story)}
}
<ToggleDot id={id} article={false} /> {nodes ?
</div> <div className='story-text'>
); {Object.entries(nodes).map(([k, v]) =>
} pConv.includes(k) ?
<React.Fragment key={k}>
{v.innerHTML.split('\n\n').map((x, i) =>
<p key={i} dangerouslySetInnerHTML={{ __html: x }} />
)}
</React.Fragment>
:
(v.nodeName === '#text' ?
<p key={k}>{v.data}</p>
:
<React.Fragment key={k}>
<v.localName dangerouslySetInnerHTML={v.innerHTML ? { __html: v.innerHTML } : null} />
{v.localName === 'pre' && <button onClick={() => pConvert(k)}>Convert Code to Paragraph</button>}
</React.Fragment>
)
)}
</div>
:
<p>Problem getting article :(</p>
}
</div>
:
<p>loading...</p>
}
<ToggleDot id={id} article={false} />
</div>
);
} }
export default Article; export default Article;