Org emails, rich links, and My Events calendar with iCal/Google Calendar export - #56
Merged
Merged
Conversation
lib/rich-text.ts parses html-to-text output into blocks and inline runs: paragraphs and line breaks, '* '/'- ' list items, '[https://…]' as a 'host ↗' link, '[text](url)' markdown links and bare URLs. Only http/https/mailto hrefs are produced; links open in a new tab with noopener noreferrer; no dangerouslySetInnerHTML. Used for event descriptions and org About; card previews use the same plainPreview so bracketed URLs don't eat the clamped lines. Unit tests included.
- env: optional server vars INBOX_ENGINE_URL / INBOX_ENGINE_TOKEN (env.ts, runtimeEnv, both .env examples) - lib/inbox-engine.ts: server-side fetch with Bearer auth and a 5s timeout; lists cached 5 min, single emails per request; missing config, timeouts, non-2xx and malformed payloads resolve to empty/null so the org page never fails; payloads are validated field by field - actions/inbox.ts: getInboxEmail for the reader (signed-in, rate limited, never throws) - getOrg exposes externalId (MyPrincetonU 'mpu:<id>') - OrgEmails: compact rows (subject, sender, NY-time date, list badges, preview), total count and 'Browse all N emails in TigerInbox'; a row opens a Sheet that lazily loads the email and renders it with RichText, with Open in TigerInbox / listserv archive links - Placement: emails lead (and events collapse to one line) when the org has no upcoming events; otherwise they follow Upcoming events
Nullable, unique varchar(64); created on first use and rotatable. Migration 0005_user_calendar_token.
VCALENDAR with PRODID, VERSION 2.0, X-WR-CALNAME and X-WR-TIMEZONE America/New_York; VEVENTs with stable UIDs (<id>@forum.tigerapps.org), DTSTAMP, UTC DTSTART/DTEND (1h default), SUMMARY, LOCATION (venue + room), DESCRIPTION and URL. TEXT escaping, 75-octet UTF-8-safe folding and CRLF line endings, with unit tests. buildGCalUrl now uses the same end-time default and 'Venue, Room' location.
- lib/calendar-feeds.ts: token create/rotate/lookup; Going, Saved, per-org and combined 'all' feeds; RSVP/saved events filtered by eventVisibleTo, org events by eventDiscoverableBy (published + public unless you manage the org); 60 days of history, capped at 1000 - GET /cal/<token>/<going|saved|all|org-<id>>.ics: public in proxy.ts, authorized only by the token (unknown token and unknown feed both 404), text/calendar; charset=utf-8, noindex/no-referrer headers, ?download=1 for an attachment; /cal/ disallowed in robots.txt - actions/calendar.ts: getMyCalendars (calendars with feed URLs — the token is created on first use — and their events, each tagged with every calendar it belongs to; unfollowed orgs of your RSVP'd/saved events are offered as suggestions) and resetCalendarLink
InboxEngine may fetch an email's body from LISTSERV on demand (~10s on first open), so single-email fetches get 15s while list fetches stay at 5s. The reader shows a loading state over the dimmed preview, and when the engine only has the RSS preview (complete: false) it says 'Only a preview is archived. Open in TigerInbox for the original.'
- Cards / List / Calendar toggle (remembered); the calendar shows Going, Saved and every followed org's events, color-coded by calendar and bucketed by Princeton day: a month grid on desktop, a week strip + day agenda on phones - Calendars panel: toggle visibility per calendar (remembered per browser); orgs behind your RSVPs/saves that you don't follow are offered, hidden by default - Export per calendar and for 'All my Forum events': Add to Google Calendar (calendar.google.com/calendar/r?cid=<webcal URL>), webcal subscribe, copy link, download .ics; 'Reset link' rotates the secret after a confirmation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Report (with real-data screenshots): https://claude.ai/artifact/EhAQm1uNu8aG1pSbKQHG7D