diff --git a/webclient/src/Comments.js b/webclient/src/Comments.js
index 91a517f..0da6c6b 100644
--- a/webclient/src/Comments.js
+++ b/webclient/src/Comments.js
@@ -1,35 +1,32 @@
-import React from 'react';
-import { Link } from 'react-router-dom';
+import React, { useState, useEffect, useCallback } from 'react';
+import { Link, useParams } from 'react-router-dom';
import { HashLink } from 'react-router-hash-link';
import { Helmet } from 'react-helmet';
import moment from 'moment';
import localForage from 'localforage';
import { infoLine, ToggleDot } from './utils.js';
-class Comments extends React.Component {
- constructor(props) {
- super(props);
+function countComments(c) {
+ return c.comments.reduce((sum, x) => sum + countComments(x), 1);
+}
- const id = this.props.match.params.id;
- const cache = this.props.cache;
+function Comments({ cache }) {
+ const { id } = useParams();
- if (id in cache) console.log('cache hit');
+ if (id in cache) console.log('cache hit');
- this.state = {
- story: cache[id] || false,
- error: false,
- collapsed: [],
- expanded: [],
- };
- }
-
- componentDidMount() {
- const id = this.props.match.params.id;
+ const [story, setStory] = useState(cache[id] || false);
+ const [error, setError] = useState(false);
+ const [collapsed, setCollapsed] = useState([]);
+ const [expanded, setExpanded] = useState([]);
+ useEffect(() => {
localForage.getItem(id)
.then(
(value) => {
- this.setState({ story: value });
+ if (value) {
+ setStory(value);
+ }
}
);
@@ -37,47 +34,41 @@ class Comments extends React.Component {
.then(res => res.json())
.then(
(result) => {
- this.setState({ story: result.story }, () => {
- const hash = window.location.hash.substring(1);
- if (hash) {
- document.getElementById(hash).scrollIntoView();
- }
- });
+ setStory(result.story);
localForage.setItem(id, result.story);
+ const hash = window.location.hash.substring(1);
+ if (hash) {
+ setTimeout(() => {
+ const element = document.getElementById(hash);
+ if (element) {
+ element.scrollIntoView();
+ }
+ }, 0);
+ }
},
(error) => {
- this.setState({ error: true });
+ setError(true);
}
);
- }
+ }, [id]);
- collapseComment(cid) {
- this.setState(prevState => ({
- ...prevState,
- collapsed: [...prevState.collapsed, cid],
- expanded: prevState.expanded.filter(x => x !== cid),
- }));
- }
+ const collapseComment = useCallback((cid) => {
+ setCollapsed(prev => [...prev, cid]);
+ setExpanded(prev => prev.filter(x => x !== cid));
+ }, []);
- expandComment(cid) {
- this.setState(prevState => ({
- ...prevState,
- collapsed: prevState.collapsed.filter(x => x !== cid),
- expanded: [...prevState.expanded, cid],
- }));
- }
+ const expandComment = useCallback((cid) => {
+ setCollapsed(prev => prev.filter(x => x !== cid));
+ setExpanded(prev => [...prev, cid]);
+ }, []);
- countComments(c) {
- return c.comments.reduce((sum, x) => sum + this.countComments(x), 1);
- }
-
- displayComment(story, c, level) {
+ const displayComment = useCallback((story, c, level) => {
const cid = c.author+c.date;
- const collapsed = this.state.collapsed.includes(cid);
- const expanded = this.state.expanded.includes(cid);
+ const isCollapsed = collapsed.includes(cid);
+ const isExpanded = expanded.includes(cid);
- const hidden = collapsed || (level == 4 && !expanded);
+ const hidden = isCollapsed || (level == 4 && !isExpanded);
const hasChildren = c.comments.length !== 0;
return (
@@ -88,56 +79,50 @@ class Comments extends React.Component {
{' '} |
Connection error?
} + {story ? +Connection error?
} - {story ? -loading...
- } -loading...
+ } +