Commit Graph

24 Commits

Author SHA1 Message Date
Ricardo
ee2cd26208 feat: extract images from HTML content for photo-based feeds
Feeds like xkcd embed images as <img> tags in the RSS description
rather than using enclosures or media:content. Similarly, h-feed
photo posts may have images only in e-content HTML without explicit
u-photo properties.

Add extractImagesFromHtml() that pulls <img> src URLs from sanitized
HTML content as a fallback when no explicit photos exist. Applied to
all three normalizers (RSS/Atom, JSON Feed, h-feed).

This makes comics, photo posts, and other image-centric feeds display
their images in the reader timeline card's photo grid.
2026-02-25 15:22:04 +01:00
Ricardo
b4d2b7418d fix: decode HTML entities in feed titles to prevent literal display
Feedparser passes through HTML entities (&#8220;, &#8217;, etc.) as
literal strings in item titles. Nunjucks auto-escaping then double-encodes
them, causing entities to render literally in the reader UI.

Apply sanitizeHtml with no allowed tags to decode entities in title fields
across RSS/Atom, JSON Feed, and feed metadata normalizers.
2026-02-24 14:20:55 +01:00
Ricardo
114998bf03 feat: add source capability detection, protocol indicators, and reply routing
- Add lib/feeds/capabilities.js: detect feed source capabilities
  (webmention, micropub, platform type) on subscribe and first fetch
- Enrich timeline items with source_type from capabilities or URL inference
- Add protocol indicator icons (Bluesky/Mastodon/web) to item-card.njk
- Auto-select syndication target in compose based on interaction URL protocol
- Modified: follow.js, processor.js, reader.js, item-card.njk

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 18:26:18 +01:00
Ricardo
1f4a6876ec chore: bump version to 1.0.32 2026-02-19 18:12:52 +01:00
Ricardo
8868dfcdcb feat: add ActivityPub integration - actor profiles, follow/unfollow, timeline items
- Add actor profile page with outbox fetcher for viewing AP actor posts
- Add follow/unfollow buttons on actor profile (delegates to AP plugin)
- Add AP actor link on item cards for posts from ActivityPub sources
- Add ensureActivityPubChannel() for auto-creating Fediverse channel
- Add AP-aware item storage with dedup, attachments, and categories
- Add CSS styles for actor profile cards and AP-specific UI elements
- Bump version to 1.0.31
2026-02-19 18:11:37 +01:00
Ricardo
3de1020d35 chore: bump version to 1.0.30 2026-02-15 14:42:10 +01:00
Ricardo
9bcfac5d8a feat: add i18n support for 14 languages
Add translations for de, es, es-419, fr, hi, id, it, nl, pl, pt, pt-BR, sr, sv, zh-Hans-CN
to match upstream Indiekit's supported locales. Also add missing localesDirectory getter.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 22:33:25 +01:00
Ricardo
02bfff7ce9 fix: store dates as ISO strings instead of Date objects
Prevents dateString.split crash when Nunjucks | date filter receives
Date objects from MongoDB. Audit timestamps (createdAt, updatedAt,
lastFetchedAt, etc.) now use .toISOString(). Query-used fields
(published, nextFetchAt) kept as Date objects for MongoDB compatibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 22:30:40 +01:00
Ricardo
1009a2d6f6 fix: Only count unread items within 30-day retention period
- Add date filter to channel unread counts (UNREAD_RETENTION_DAYS = 30)
- Update getUnreadCount to also filter by date
- Prevents inflated counts from old accumulated items

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-08 13:58:55 +01:00
Ricardo
2ffce9a74f fix: correct invalid icon names and date filter issue
- Replace invalid icons (edit→updatePost, discover→syndicate, refresh→repost)
- Remove date("relative") filter that fails on Date objects
- Bump to 1.0.25

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-07 02:11:34 +01:00
Ricardo
1182b8ae79 feat: Feed management with status tracking, edit, and rediscover
- Integrate updateFeedStatus into polling processor for health tracking
- Add feed management UI showing status (active/error), errors, actions
- Add edit feed URL feature to change non-RSS URLs to actual feeds
- Add rediscover feature to run feed discovery and update URL
- Add refresh button to force immediate poll
- Update UI to use Indiekit's badge/button classes (badge--green/red, button--warning)
- Add routes: /feeds/:feedId/edit, /feeds/:feedId/rediscover, /feeds/:feedId/refresh

Fixes broken feeds by allowing users to:
1. Edit URL directly to the RSS/Atom feed
2. Click "Rediscover" to auto-find the feed from a blog URL
3. View error details and consecutive error counts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-07 01:47:07 +01:00
Ricardo
ab6f81bf72 feat: Phase 1 - Enhanced feed discovery with validation
- Add validator.js: validateFeedUrl with comments feed detection
- Add discovery.js: discoverAndValidateFeeds with type labels
- Add opml.js: OPML 2.0 export of all subscriptions
- Update reader.js: searchFeeds uses validation, subscribe validates
- Update feeds.js: updateFeedStatus for health tracking
- Update search.njk: Show feed types, validation status, error messages
- Add CSS for badges, notices, and invalid feed styling
- Register OPML export route at /reader/opml

Phase 1 of blogroll implementation plan.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-07 01:39:58 +01:00
Ricardo
6caf37a003 feat: add startup cleanup for old read items
Runs cleanupAllReadItems on server startup to clean up accumulated
read items from all channels, keeping only the 30 most recent per
channel per user.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-07 00:52:29 +01:00
Ricardo
722a884ca3 fix: allow action buttons to wrap on mobile
Add flex-wrap to .item-actions so all buttons remain visible on
narrow screens. Previously the mark-as-read button was cut off.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-07 00:09:48 +01:00
Ricardo
61819f1aeb feat: cleanup old read items (keep last 30 per channel)
Prevents database accumulation by automatically deleting older read
items when marking items as read. Keeps the 30 most recent read items
per channel per user to allow revisiting recently read content.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 22:59:46 +01:00
Ricardo
59cbe7c238 feat: add bookmark to timeline, mark-read to item view
- Add bookmark button to item-card.njk (timeline view)
- Add mark-read button to item.njk (full item view)
- Add JavaScript handler for mark-read on item page
- Pass channel info to item template for mark-read API call

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 22:56:03 +01:00
Ricardo
6b19ac4cc7 fix: correct API URL for individual mark-read
The JavaScript was POSTing to /microsub/reader but the Microsub API
is at /microsub. Fixed by computing parent path from baseUrl.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 22:34:09 +01:00
Ricardo
c830ad5df6 feat: add show/hide read items and fix individual mark-read
- Add countReadItems function to storage/items.js
- Update getTimelineItems to filter out read items by default
- Add showRead query param support to channel controller
- Update channel.njk with show/hide read toggle buttons
- Add "All caught up!" state when all items are read
- Add JavaScript handler for individual mark-read buttons
- Mark-read now hides the item with smooth animation
- Add locale strings: showRead, hideRead, allRead

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 21:24:33 +01:00
Ricardo
8d373dca5f fix: add markAllRead function and route
Restore the "Mark all as read" button functionality in channel view.
The button form posts to /api/mark-read but the route and controller
function were missing from the standalone repo.

- Add markAllRead function to reader controller
- Add /api/mark-read route to index.js
- Import markItemsRead from storage/items.js

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 21:08:49 +01:00
Ricardo
99cb4de4e8 feat: add syndication target selection to compose form
- Fetch syndication targets from Micropub config
- Display checkboxes for each target in compose form
- Include mp-syndicate-to in Micropub request
- Include optional content/comments for likes and reposts
2026-02-06 20:44:53 +01:00
Ricardo
fabadd8585 feat: allow comments on likes, reposts, and bookmarks
- Show textarea for all compose actions, not just replies
- Add bookmark button to item actions
- Comments will be included in syndication
2026-02-06 20:41:16 +01:00
Ricardo
4819c229cd feat: restore full microsub implementation with reader UI
Restores complete implementation from feat/endpoint-microsub branch:
- Reader UI with views (reader.njk, channel.njk, feeds.njk, etc.)
- Feed polling, parsing, and normalization
- WebSub subscriber
- SSE realtime updates
- Redis caching
- Search indexing
- Media proxy
- Webmention processing
2026-02-06 20:20:25 +01:00
Ricardo
66dd5b5c91 chore: bump version to 1.0.12 2026-02-06 16:41:09 +01:00
Ricardo
30f9939b3a feat: initial commit - Microsub endpoint for Indiekit
Fork of @indiekit/endpoint-microsub with customizations.
Enables subscribing to feeds and reading content using the Microsub protocol.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-06 16:32:55 +01:00