feat: persist settings and enrich conversation context
This commit is contained in:
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}
|
||||
</>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user