Skip to content

Commit

Permalink
Post links
Browse files Browse the repository at this point in the history
  • Loading branch information
mybearworld committed Jul 26, 2024
1 parent f36ef8e commit fc6c5c6
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 21 deletions.
4 changes: 4 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Chat } from "./components/Chat";
import { Chats } from "./components/Chats";
import { Button } from "./components/Button";
import { Ulist } from "./components/Ulist";
import { PostPopup } from "./components/PostPopup";
import { Popup } from "./components/Popup";
import { User } from "./components/User";
import { IconButton } from "./components/IconButton";
Expand All @@ -19,6 +20,7 @@ export const App = () => {
useShallow((state) => [state.openChat, state.setOpenChat]),
);
const user = new URLSearchParams(location.search).get("user");
const post = new URLSearchParams(location.search).get("post");

return (
<div className="flex h-dvh max-h-dvh w-screen snap-x snap-mandatory divide-x divide-gray-200 overflow-auto bg-white dark:divide-gray-800 dark:bg-gray-950">
Expand Down Expand Up @@ -70,6 +72,8 @@ export const App = () => {
</Tabs.Root>
{user ?
<User username={user} children={undefined} openInitially />
: post ?
<PostPopup id={post} children={undefined} openInitially />
: undefined}
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/MarkdownInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ export const MarkdownInput = (props: MarkdownInputProps) => {
{replies.map((reply, index) => (
<div className="flex gap-2" key={index}>
<div className="grow">
<Post id={reply} reply="topLevel" />
<Post id={reply} reply />
</div>
<button
type="button"
Expand Down
6 changes: 4 additions & 2 deletions src/components/Popup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export type PopupProps = {
onOpenChange: (open: boolean) => void;
};
className?: string;
wide?: boolean;
size?: "regular" | "extend" | "wide";
};
export const Popup = (props: PopupProps) => {
return (
Expand All @@ -26,7 +26,9 @@ export const Popup = (props: PopupProps) => {
className={twMerge(
"absolute inset-0 z-[--z-popup] m-auto h-fit max-h-[80vh] w-fit overflow-auto rounded-xl bg-white px-4 py-2 focus:outline-0 dark:bg-gray-900",
props.className,
props.wide ? "max-w-[90vw]" : "max-w-[min(90vw,30rem)]",
props.size === "wide" ? "max-w-[90vw]"
: props.size === "extend" ? "w-[min(90vw,30rem)]"
: "max-w-[min(90vw,30rem)]",
)}
>
{props.children}
Expand Down
58 changes: 40 additions & 18 deletions src/components/Post.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ import { IconButton } from "./IconButton";

export type PostProps = {
id: string;
reply?: boolean | "topLevel";
reply?: boolean;
topLevel?: boolean;
onReply?: (id: string, content: string, username: string) => void;
};
export const Post = (props: PostProps) => {
Expand All @@ -42,7 +43,8 @@ export const Post = (props: PostProps) => {
/>
}
bubble="This post was deleted."
reply
reply={props.reply}
topLevel={props.topLevel}
/>
);
}
Expand All @@ -60,6 +62,7 @@ export const Post = (props: PostProps) => {
/>
}
reply={props.reply}
topLevel={props.topLevel}
bubble="Loading..."
/>
);
Expand All @@ -74,6 +77,7 @@ export const Post = (props: PostProps) => {
/>
}
reply={props.reply}
topLevel={props.topLevel}
bubble={
<>
There was an error loading this post.
Expand All @@ -85,12 +89,20 @@ export const Post = (props: PostProps) => {
);
}

return <PostBase post={post} reply={props.reply} onReply={props.onReply} />;
return (
<PostBase
post={post}
reply={props.reply}
topLevel={props.topLevel}
onReply={props.onReply}
/>
);
};

type PostBaseProps = {
post: APIPost;
reply?: boolean | "topLevel";
reply?: boolean;
topLevel?: boolean;
onReply?: (id: string, content: string, username: string) => void;
};
const PostBase = memo((props: PostBaseProps) => {
Expand Down Expand Up @@ -168,8 +180,9 @@ const PostBase = memo((props: PostBaseProps) => {
<div>
<SpeechBubble
reply={props.reply}
topLevel={props.topLevel}
transparent={!!props.post.optimistic}
arrow={false}
arrow={!props.reply}
speaker={
props.reply ? undefined : (
<User username={props.post.u}>
Expand Down Expand Up @@ -258,6 +271,15 @@ const PostBase = memo((props: PostBaseProps) => {
: "View source"}
</MenuItem>
: undefined}
<MenuItem
onClick={() => {
navigator.clipboard.writeText(
`https://mybearworld.github.io/roarer-2?post=${props.post.post_id}`,
);
}}
>
Copy link
</MenuItem>
{credentials.username === props.post.u ?
<>
<MenuItem
Expand Down Expand Up @@ -295,7 +317,7 @@ const PostBase = memo((props: PostBaseProps) => {
) ?
<div className="my-1 flex flex-col gap-2">
{reply.ids.map((id) => (
<Post id={id} reply key={id} />
<Post id={id} reply topLevel={false} key={id} />
))}
</div>
: undefined}
Expand All @@ -317,9 +339,7 @@ const PostBase = memo((props: PostBaseProps) => {
: viewState === "view" ?
<>
<Markdown
secondaryBackground={
props.reply === "topLevel" ? false : props.reply
}
secondaryBackground={props.topLevel ? false : props.reply}
inline={!!props.reply}
bigEmoji={!props.reply}
>
Expand Down Expand Up @@ -374,18 +394,20 @@ const PostBase = memo((props: PostBaseProps) => {
});

type SpeechBubbleProps = {
reply?: boolean | "topLevel";
reply?: boolean;
topLevel?: boolean;
speaker: ReactNode;
bubble: ReactNode;
transparent?: boolean;
arrow?: boolean;
};
const SpeechBubble = (props: SpeechBubbleProps) => {
const topLevel = props.topLevel ?? true;
return (
<div
className={twMerge(
"flex",
(props.arrow ?? true) ? "gap-3" : "gap-1",
(props.arrow ?? true) ? "gap-2" : "gap-1",
props.reply ? "items-center" : "",
props.transparent ? "opacity-70" : "",
)}
Expand All @@ -394,19 +416,19 @@ const SpeechBubble = (props: SpeechBubbleProps) => {
<div
className={twMerge(
"relative min-w-0 grow break-words rounded-lg px-2 py-1",
props.reply && props.reply !== "topLevel" ?
"bg-gray-200 dark:bg-gray-800"
: "bg-gray-100 dark:bg-gray-900",
topLevel ?
"bg-gray-100 dark:bg-gray-900"
: "bg-gray-200 dark:bg-gray-800",
(props.arrow ?? true) ? "rounded-ss-none" : "",
)}
>
{(props.arrow ?? true) ?
<div
className={twMerge(
"absolute left-[calc(-0.5rem-theme(spacing.2))] top-0 box-content h-0 w-0 border-[length:0.5rem] border-transparent border-r-gray-100 contrast-more:hidden",
props.reply && props.reply !== "topLevel" ?
"border-r-gray-200 dark:border-r-gray-800"
: "border-r-gray-100 dark:border-r-gray-900",
topLevel ?
"border-r-gray-100 dark:border-r-gray-900"
: "border-r-gray-200 dark:border-r-gray-800",
)}
aria-hidden
/>
Expand Down Expand Up @@ -457,7 +479,7 @@ export const AttachmentView = (props: AttachmentViewProps) => {
return (
<Popup
triggerAsChild
wide
size="wide"
trigger={
<div className="flex flex-col items-center">
{closeRow}
Expand Down
21 changes: 21 additions & 0 deletions src/components/PostPopup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { useState, ReactNode } from "react";
import { Popup } from "./Popup";
import { Post } from "./Post";

export type PostPopupProps = {
id: string;
children: ReactNode;
openInitially?: boolean;
};
export const PostPopup = (props: PostPopupProps) => {
const [open, setOpen] = useState(props.openInitially ?? false);
return (
<Popup
trigger={props.children}
controlled={{ open, onOpenChange: setOpen }}
size="extend"
>
<Post id={props.id} topLevel={false} />
</Popup>
);
};

0 comments on commit fc6c5c6

Please sign in to comment.