From 93dfe2be64e8658839bcfe5356adf35f8cde7075 Mon Sep 17 00:00:00 2001 From: Nicolas James Date: Thu, 13 Feb 2025 18:04:18 +1100 Subject: initial commit --- src/web/components/posts/Posts.jsx | 163 +++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 src/web/components/posts/Posts.jsx (limited to 'src/web/components/posts/Posts.jsx') diff --git a/src/web/components/posts/Posts.jsx b/src/web/components/posts/Posts.jsx new file mode 100644 index 0000000..3944f67 --- /dev/null +++ b/src/web/components/posts/Posts.jsx @@ -0,0 +1,163 @@ +import React, {useState, useEffect, useRef} from "react"; +import {Route, Routes, useLocation, useNavigate} from "react-router-dom"; + + +import Button from "components/button/Button.jsx"; +import Submission from "components/submission/Submission.jsx"; +import Post from "components/post/Post.jsx"; +import {getSubreactFromLocation} from "helpers/Location.jsx"; + +import styles from "./Posts.css"; + +async function makePostsRequest(location, setPosts, setError, mounted) { + const init = { + method: "GET", + referrer: "same-origin", + } + const url = "/api/posts?" + new URLSearchParams({ + page: 0, + amount: 25, + subreact: getSubreactFromLocation(location), + }); + return fetch(url, init) + .then((response) => { + return response.json() + .catch(() => { + throw new Error("unexpected response from server") + }) + }) + .then((json) => { + if ("error" in json) { + throw new Error(json.error); + } + if (!mounted) { + return; + } + setPosts(json.posts); + }) + .catch((error) => { + console.log(error); + if (!mounted) { + return; + } + setError(error.message); + }); +} + +function PostsError({navigate, error}) { + return ( +
+

Something's wrong!

+

Sorry, but an unexpected issue has forced us to stop early. Here are the technical details:

+

Error: {error}

+ +
+ ); +} + +function PostsLoading() { + return ( +
+ {[...Array(3)].map((_, i) => + + )} +
+ ); +} + +function PostsEmpty({navigate}) { + return ( +
+

There's nothing here?!?

+

Try changing subreacts.

+ +
+ ); +} + +function PostsStates({error, posts, navigate}) { + if (error !== null) { // Error message. + return ( + + ); + } + + if (posts == null) { + return ( + + ) + } + + + if (posts.length == 0) { + return ( + + ); + } + + return ( + posts.map(({uid, title, contents, time_updated, thumbnail, subreact}, i) => + ) + ); +} + +export default function Posts() { + const navigate = useNavigate(); + const location = useLocation(); + const locationRef = useRef(location); + + const [posts, setPosts] = useState(null); + const [error, setError] = useState(null); + const [submissionActive, setSubmissionActive] = useState(false); + + + // We make a request if we're at the homepage or if we're changing subreacts. + const shouldMakeRequest = () => { + if (posts === null) { + return true; + } + const [previous, current] = + [locationRef.current, location].map((loc) => getSubreactFromLocation(loc)); + return previous != current; + }; + // This is a bit ugly, we're caching off our previous location so that we know + // if we should update or not. + useEffect(() => { + let mounted = true; + + if (shouldMakeRequest()) { + setPosts(null); + makePostsRequest(location, setPosts, setError, mounted); + } + + locationRef.current = location; + return () => { + setError(null); + mounted = false; + } + }, [location]); + + return ( +
+
+
{setSubmissionActive(false);} : null)}> +
+ +
+
+
+ +
+ ); +} -- cgit v1.2.3