aboutsummaryrefslogtreecommitdiffstats
path: root/frontend/src/components/FeedItem.tsx
diff options
context:
space:
mode:
authorAdam Mathes <adam@adammathes.com>2026-02-14 09:58:11 -0800
committerAdam Mathes <adam@adammathes.com>2026-02-14 09:58:11 -0800
commitc9c3469ce90f5e1cf624a9a97d66fd6db3aba8cb (patch)
treedfc78feec1eff6cc5411b511123e6eefbdaf625b /frontend/src/components/FeedItem.tsx
parentae2b06f7a702ea432b801985f534ade405d0299a (diff)
downloadneko-c9c3469ce90f5e1cf624a9a97d66fd6db3aba8cb.tar.gz
neko-c9c3469ce90f5e1cf624a9a97d66fd6db3aba8cb.tar.bz2
neko-c9c3469ce90f5e1cf624a9a97d66fd6db3aba8cb.zip
feature: add scrape full text button to feed items (fixing NK-8hu7z1)
Diffstat (limited to 'frontend/src/components/FeedItem.tsx')
-rw-r--r--frontend/src/components/FeedItem.tsx33
1 files changed, 30 insertions, 3 deletions
diff --git a/frontend/src/components/FeedItem.tsx b/frontend/src/components/FeedItem.tsx
index ae4462a..ac142dc 100644
--- a/frontend/src/components/FeedItem.tsx
+++ b/frontend/src/components/FeedItem.tsx
@@ -56,6 +56,24 @@ export default function FeedItem({ item: initialItem }: FeedItemProps) {
});
};
+ const loadFullContent = (e: React.MouseEvent) => {
+ e.stopPropagation();
+ setLoading(true);
+ apiFetch(`/api/item/${item._id}`)
+ .then((res) => {
+ if (!res.ok) throw new Error('Failed to fetch full content');
+ return res.json();
+ })
+ .then((data) => {
+ setItem({ ...item, ...data });
+ setLoading(false);
+ })
+ .catch((err) => {
+ console.error('Error fetching full content:', err);
+ setLoading(false);
+ });
+ };
+
return (
<li className={`feed-item ${item.read ? 'read' : 'unread'} ${loading ? 'loading' : ''}`}>
<div className="item-header">
@@ -78,10 +96,19 @@ export default function FeedItem({ item: initialItem }: FeedItemProps) {
{new Date(item.publish_date).toLocaleDateString()}
{item.feed_title && ` - ${item.feed_title}`}
</a>
- <div className="item-actions" style={{ display: 'inline-block', float: 'right' }}></div>
+ <div className="item-actions" style={{ display: 'inline-block', float: 'right' }}>
+ {!item.full_content && (
+ <button onClick={loadFullContent} className="scrape-btn" title="Load Full Content">
+ text
+ </button>
+ )}
+ </div>
</div>
- {item.description && (
- <div className="item-description" dangerouslySetInnerHTML={{ __html: item.description }} />
+ {(item.full_content || item.description) && (
+ <div
+ className="item-description"
+ dangerouslySetInnerHTML={{ __html: item.full_content || item.description }}
+ />
)}
</li>
);