diff --git a/package-lock.json b/package-lock.json
index 3ad5e5b..053181a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,6 +8,7 @@
"dependencies": {
"@atproto/api": "^0.16.6",
"@atproto/oauth-client-browser": "^0.3.33",
+ "@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-slider": "^1.3.6",
"@tailwindcss/vite": "^4.0.6",
diff --git a/package.json b/package.json
index 6f76e53..e9c1102 100644
--- a/package.json
+++ b/package.json
@@ -12,6 +12,7 @@
"dependencies": {
"@atproto/api": "^0.16.6",
"@atproto/oauth-client-browser": "^0.3.33",
+ "@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-slider": "^1.3.6",
"@tailwindcss/vite": "^4.0.6",
diff --git a/src/components/Composer.tsx b/src/components/Composer.tsx
index f1e6256..2dd7f0c 100644
--- a/src/components/Composer.tsx
+++ b/src/components/Composer.tsx
@@ -1,5 +1,6 @@
import { RichText } from "@atproto/api";
import { useAtom } from "jotai";
+import { Dialog } from "radix-ui";
import { useEffect, useRef, useState } from "react";
import { useAuth } from "~/providers/UnifiedAuthProvider";
@@ -9,7 +10,7 @@ import { useQueryPost } from "~/utils/useQuery";
import { ProfileThing } from "./Login";
import { UniversalPostRendererATURILoader } from "./UniversalPostRenderer";
-const MAX_POST_LENGTH = 300
+const MAX_POST_LENGTH = 300;
export function Composer() {
const [composerState, setComposerState] = useAtom(composerAtom);
@@ -31,10 +32,11 @@ export function Composer() {
composerState.kind === "reply"
? composerState.parent
: composerState.kind === "quote"
- ? composerState.subject
- : undefined;
+ ? composerState.subject
+ : undefined;
- const { data: parentPost, isLoading: isParentLoading } = useQueryPost(parentUri);
+ const { data: parentPost, isLoading: isParentLoading } =
+ useQueryPost(parentUri);
async function handlePost() {
if (!agent || !postText.trim() || postText.length > MAX_POST_LENGTH) return;
@@ -95,10 +97,9 @@ export function Composer() {
setPosting(false);
}
}
-
- if (composerState.kind === "closed") {
- return null;
- }
+ // if (composerState.kind === "closed") {
+ // return null;
+ // }
const getPlaceholder = () => {
switch (composerState.kind) {
@@ -111,120 +112,150 @@ export function Composer() {
return "What's happening?!";
}
};
-
+
const charsLeft = MAX_POST_LENGTH - postText.length;
const isPostButtonDisabled =
- posting ||
- !postText.trim() ||
- isParentLoading ||
- charsLeft < 0;
+ posting || !postText.trim() || isParentLoading || charsLeft < 0;
return (
-
-
-
-
-
-
-
- {charsLeft}
-
-
-
-
-
+
{
+ if (!open) setComposerState({ kind: "closed" });
+ }}
+ >
+
+
- {postSuccess ? (
-
- ✓
- Posted!
-
- ) : (
-
- {(composerState.kind === "reply") && (
-
- {isParentLoading ? (
-
- Loading parent post...
-
- ) : parentUri ? (
-
- ) : (
-
- Could not load parent post.
-
- )}
-
- )}
-
-
-
-
-
setPostText(e.target.value)}
+
+
+
+
+
+ aria-label="Close"
+ >
+
+
+
+
+
+
+
+ {charsLeft}
+
+
- {(composerState.kind === "quote") && (
-
- {isParentLoading ? (
-
- Loading parent post...
+
+ {postSuccess ? (
+
+ ✓
+
+ Posted!
+
+
+ ) : (
+
+ {composerState.kind === "reply" && (
+
+ {isParentLoading ? (
+
+ Loading parent post...
+
+ ) : parentUri ? (
+
+ ) : (
+
+ Could not load parent post.
+
+ )}
+
+ )}
+
+
+
+
+
setPostText(e.target.value)}
+ disabled={posting}
+ autoFocus
+ />
- ) : parentUri ? (
-
- ) : (
-
- Could not load parent post.
+
+
+ {composerState.kind === "quote" && (
+
+ {isParentLoading ? (
+
+ Loading parent post...
+
+ ) : parentUri ? (
+
+ ) : (
+
+ Could not load parent post.
+
+ )}
)}
-
- )}
- {postError && (
-
{postError}
+ {postError && (
+
+ {postError}
+
+ )}
+
)}
-
- )}
-
-
+
+
+
);
}
-function AutoGrowTextarea({ value, className, onChange, ...props }: React.DetailedHTMLProps, HTMLTextAreaElement>) {
+function AutoGrowTextarea({
+ value,
+ className,
+ onChange,
+ ...props
+}: React.DetailedHTMLProps<
+ React.TextareaHTMLAttributes,
+ HTMLTextAreaElement
+>) {
const ref = useRef(null);
useEffect(() => {
@@ -243,4 +274,4 @@ function AutoGrowTextarea({ value, className, onChange, ...props }: React.Detail
{...props}
/>
);
-}
\ No newline at end of file
+}
diff --git a/src/components/Login.tsx b/src/components/Login.tsx
index d59402a..5d444b1 100644
--- a/src/components/Login.tsx
+++ b/src/components/Login.tsx
@@ -311,14 +311,13 @@ const PasswordForm = () => {
// --- Profile Component (now supports a `large` prop for styling) ---
export const ProfileThing = ({
- agent: _unused,
+ agent,
large = false,
}: {
- agent?: Agent | null;
+ agent: Agent | null;
large?: boolean;
}) => {
- const { agent } = useAuth();
- const did = ((agent as AtpAgent).session?.did ??
+ const did = ((agent as AtpAgent)?.session?.did ??
(agent as AtpAgent)?.assertDid ??
agent?.did) as string | undefined;
const { data: identity } = useQueryIdentity(did);
diff --git a/src/styles/app.css b/src/styles/app.css
index b40110f..e4760b8 100644
--- a/src/styles/app.css
+++ b/src/styles/app.css
@@ -222,4 +222,9 @@ body {
/* placeholder trick */
.m3input-field.m3input-label.m3input-border input::placeholder {
color: transparent;
+}
+
+/* radix i love you but like cmon man */
+body[data-scroll-locked]{
+ margin-left: var(--removed-body-scroll-bar-size) !important;
}
\ No newline at end of file