diff --git a/src/components/content/PostCard.astro b/src/components/content/PostCard.astro index 7de83e2..a5b3797 100644 --- a/src/components/content/PostCard.astro +++ b/src/components/content/PostCard.astro @@ -24,6 +24,15 @@ const date = publishedAt ?? sharedAt; const authorLabel = author.displayName || `@${author.handle}`; const tag = tags?.[0]; const community = `@${source}`; + +function hueFromString(input: string): number { + let h = 0; + for (let i = 0; i < input.length; i++) { + h = (h * 31 + input.charCodeAt(i)) | 0; + } + return ((h % 360) + 360) % 360; +} +const communityHue = hueFromString(source); ---
@@ -38,12 +47,15 @@ const community = `@${source}`;

{title}

{excerpt &&

{excerpt}

}
- {tag && {tag}} - {community} + {community} {authorLabel} + {tag && #{tag}}
@@ -130,8 +142,20 @@ const community = `@${source}`; .post-card__date { color: var(--separator-fg); } - .post-card__date::before { - content: '·'; - margin-right: var(--space-sm); + + .post-card__tag { + color: var(--link); + font-weight: 500; + text-decoration: underline; + text-decoration-color: color-mix(in oklch, var(--link) 35%, transparent); + text-underline-offset: 2px; + } + .post-card__link:hover .post-card__tag { + text-decoration-color: currentColor; + } + + .post-card :global(.badge--location) { + background: oklch(94% 0.04 var(--community-hue, 250)); + color: oklch(38% 0.12 var(--community-hue, 250)); } diff --git a/src/components/events/EventCard.astro b/src/components/events/EventCard.astro index 5d798bf..6f5fa38 100644 --- a/src/components/events/EventCard.astro +++ b/src/components/events/EventCard.astro @@ -3,6 +3,7 @@ import { actions } from "astro:actions"; import EventLocation from "./EventLocation.astro"; import CheckIcon from "./icons/CheckIcon.astro"; import ExternalLinkIcon from "./icons/ExternalLinkIcon.astro"; +import { eventAnchorId } from "../../lib/community/happening-now"; interface Props { atUri: string; @@ -27,6 +28,7 @@ const { cid, name, startsAt, + endsAt, location, mode = "inperson", description, @@ -37,6 +39,23 @@ const { rsvpStatus, } = Astro.props; +const anchorId = eventAnchorId(atUri); +const DEFAULT_DURATION_MS = 2 * 60 * 60 * 1000; +const computedEndsAt = endsAt ?? new Date(startsAt.getTime() + DEFAULT_DURATION_MS); +const nowMs = Date.now(); +const isLive = + startsAt.getTime() <= nowMs && nowMs < computedEndsAt.getTime(); + +const dateKeyFmt = new Intl.DateTimeFormat("en-CA", { + year: "numeric", + month: "2-digit", + day: "2-digit", +}); +const isToday = + !isLive && + startsAt.getTime() > nowMs && + dateKeyFmt.format(startsAt) === dateKeyFmt.format(new Date(nowMs)); + const formattedDate = startsAt.toLocaleDateString("en-US", { weekday: "short", month: "short", @@ -64,7 +83,17 @@ const rsvpButtonAriaLabel = isGoing const canRsvp = showRsvp && isLoggedIn && Boolean(cid); --- -
+
{ sourceLabel && (