From dbc0c298bd3bb3bb2c51315101bce905ce6a7f97 Mon Sep 17 00:00:00 2001 From: Chris Troutner Date: Wed, 3 Jun 2026 12:24:27 -0700 Subject: [PATCH] Adding Posts page --- src/components/app-body/index.js | 2 + src/components/app-body/posts/index.js | 106 +++++++++++++++++++++++++ src/components/nav-menu/index.js | 8 ++ src/services/memo-db.js | 13 +++ 4 files changed, 129 insertions(+) create mode 100644 src/components/app-body/posts/index.js diff --git a/src/components/app-body/index.js b/src/components/app-body/index.js index 0827cd4..d21caf6 100644 --- a/src/components/app-body/index.js +++ b/src/components/app-body/index.js @@ -24,6 +24,7 @@ import SignMessage from './sign/index.js' import ServerSelectView from './configuration/select-server-view' import UserDataReview from './user-data-review' import RecentProfiles from './recent-profiles' +import RecentPosts from './posts' function AppBody (props) { // Dependency injection through props @@ -38,6 +39,7 @@ function AppBody (props) { } /> } /> } /> + } /> } /> } /> } /> diff --git a/src/components/app-body/posts/index.js b/src/components/app-body/posts/index.js new file mode 100644 index 0000000..c2f6117 --- /dev/null +++ b/src/components/app-body/posts/index.js @@ -0,0 +1,106 @@ +/* + Display the most recent Memo posts from psf-memo-db. +*/ + +// Global npm libraries +import React, { useState, useEffect } from 'react' +import { Container, Row, Col, Spinner, Table } from 'react-bootstrap' + +// Local libraries +import MemoDb from '../../../services/memo-db' +import '../../../App.css' + +function truncate (str, maxLen = 16) { + if (!str || str.length <= maxLen) return str + const half = Math.floor((maxLen - 3) / 2) + return `${str.slice(0, half)}...${str.slice(-half)}` +} + +function formatSeen (seen) { + if (!seen) return '' + const ms = seen > 1e12 ? seen : seen * 1000 + return new Date(ms).toLocaleString() +} + +function RecentPosts () { + const [loading, setLoading] = useState(true) + const [error, setError] = useState(null) + const [posts, setPosts] = useState([]) + const [pagination, setPagination] = useState(null) + + useEffect(() => { + const loadPosts = async () => { + try { + const memoDb = new MemoDb() + const data = await memoDb.getRecentPosts({ limit: 100, offset: 0 }) + setPosts(data.posts || []) + setPagination(data.pagination || null) + } catch (err) { + setError(err.message || 'Failed to load recent posts') + } + setLoading(false) + } + + loadPosts() + }, []) + + return ( + + + +

Recent Posts

+ {pagination && ( +

+ Showing {posts.length} of {pagination.total} posts +

+ )} + + {error &&

{error}

} + + {loading && ( +
+ + Loading... + +
+ )} + + {!loading && !error && ( + + + + + + + + + + + + {posts.map((post) => ( + + + + + + + + ))} + +
AddressPostBlockSeenTxID
+ + {truncate(post.addr, 24)} + + {post.text}{post.blockHeight}{formatSeen(post.seen)} + + {truncate(post.txid, 20)} + +
+ )} + +
+
+ ) +} + +export default RecentPosts diff --git a/src/components/nav-menu/index.js b/src/components/nav-menu/index.js index 1286895..9c1a7ae 100644 --- a/src/components/nav-menu/index.js +++ b/src/components/nav-menu/index.js @@ -62,6 +62,14 @@ function NavMenu (props) { Profiles + + Posts + +