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 localForage from 'localforage';
import { sourceLink, infoLine, ToggleDot } from './utils.js';
class Article extends React.Component {
constructor(props) {
super(props);
function Article({ cache }) {
const { id } = useParams();
const id = this.props.match ? this.props.match.params.id : 'CLOL';
const cache = this.props.cache;
if (id in cache) console.log('cache hit');
if (id in cache) console.log('cache hit');
this.state = {
story: cache[id] || false,
error: false,
pConv: [],
};
}
componentDidMount() {
const id = this.props.match ? this.props.match.params.id : 'CLOL';
const [story, setStory] = useState(cache[id] || false);
const [error, setError] = useState(false);
const [pConv, setPConv] = useState([]);
useEffect(() => {
localForage.getItem(id)
.then(
(value) => {
if (value) {
this.setState({ story: value });
setStory(value);
}
}
);
@@ -35,79 +27,76 @@ class Article extends React.Component {
.then(res => res.json())
.then(
(result) => {
this.setState({ story: result.story });
setStory(result.story);
localForage.setItem(id, result.story);
},
(error) => {
this.setState({ error: true });
setError(true);
}
);
}
}, [id]);
pConvert = (n) => {
this.setState({ pConv: [...this.state.pConv, n]});
}
const pConvert = (n) => {
setPConv(prevPConv => [...prevPConv, n]);
};
render() {
const id = this.props.match ? this.props.match.params.id : 'CLOL';
const story = this.state.story;
const error = this.state.error;
const pConv = this.state.pConv;
let nodes = null;
if (story.text) {
const nodes = useMemo(() => {
if (story && story.text) {
let div = document.createElement('div');
div.innerHTML = story.text;
nodes = div.childNodes;
return div.childNodes;
}
return null;
}, [story]);
return (
<div className='article-container'>
{error && <p>Connection error?</p>}
{story ?
<div className='article'>
<Helmet>
<title>{story.title} | QotNews</title>
<meta name="robots" content="noindex" />
</Helmet>
return (
<div className='article-container'>
{error && <p>Connection error?</p>}
{story ?
<div className='article'>
<Helmet>
<title>{story.title} | QotNews</title>
<meta name="robots" content="noindex" />
</Helmet>
<h1>{story.title}</h1>
<h1>{story.title}</h1>
<div className='info'>
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 className='info'>
Source: {sourceLink(story)}
</div>
:
<p>loading...</p>
}
<ToggleDot id={id} article={false} />
</div>
);
}
{infoLine(story)}
{nodes ?
<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;