feat: persist settings and enrich conversation context

This commit is contained in:
jjbrunton committed 2026-08-08 18:18:28 +01:00
1 parent a36723a325
commit 2c100d72b6
84 files changed
+2248 -644

No files matched your search

@@ -0,0 +1,72 @@
import { useEffect, useRef, useState, type ReactNode } from 'react';
export interface OriginPost {
title: string;
url: string;
imageUrl?: string | null;
subreddit?: string;
}
export function OriginPostCard({ post }: { post: OriginPost }) {
return (
<a aria-label={post.title} className="origin-post-card" href={post.url} rel="noreferrer" target="_blank">
{post.imageUrl ? <img alt={`Source post: ${post.title}`} loading="lazy" src={post.imageUrl} /> : null}
<span>
<small>Started from {post.subreddit ? `r/${post.subreddit}` : 'Reddit'}</small>
<strong>{post.title}</strong>
<span>Open original post</span>
</span>
</a>
);
}
export function OriginPostButton({ children, post }: { children: ReactNode; post: OriginPost }) {
const [isOpen, setIsOpen] = useState(false);
const triggerRef = useRef<HTMLButtonElement>(null);
const closeRef = useRef<HTMLButtonElement>(null);
useEffect(() => {
if (!isOpen) return;
closeRef.current?.focus();
const closeOnEscape = (event: KeyboardEvent) => {
if (event.key === 'Escape') setIsOpen(false);
};
document.addEventListener('keydown', closeOnEscape);
return () => document.removeEventListener('keydown', closeOnEscape);
}, [isOpen]);
function close() {
setIsOpen(false);
queueMicrotask(() => triggerRef.current?.focus());
}
return (
<>
<button className="origin-post-trigger" onClick={() => setIsOpen(true)} ref={triggerRef} type="button">
{children}
</button>
{isOpen ? (
<div
aria-labelledby="origin-post-dialog-title"
aria-modal="true"
className="origin-post-backdrop"
onMouseDown={(event) => { if (event.target === event.currentTarget) close(); }}
role="dialog"
>
<article className="origin-post-dialog">
<div className="origin-post-dialog-heading">
<span>Conversation origin</span>
<button aria-label="Close source post" onClick={close} ref={closeRef} type="button">×</button>
</div>
{post.imageUrl ? <img alt={`Source post: ${post.title}`} loading="lazy" src={post.imageUrl} /> : null}
<div className="origin-post-dialog-copy">
{post.subreddit ? <small>r/{post.subreddit}</small> : null}
<h2 id="origin-post-dialog-title">{post.title}</h2>
<a className="button primary" href={post.url} rel="noreferrer" target="_blank">Open Reddit post</a>
</div>
</article>
</div>
) : null}
</>
);
}