Skip to content

Commit

Permalink
Merge branch 'main' into will/un-71-frontpage-moderation
Browse files Browse the repository at this point in the history
  • Loading branch information
WillCorrigan committed Sep 23, 2024
2 parents 06f8fb6 + 30654d1 commit 19d9dcc
Show file tree
Hide file tree
Showing 49 changed files with 2,188 additions and 517 deletions.
3 changes: 3 additions & 0 deletions packages/atproto-browser/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
module.exports = {
root: true,
extends: ["@repo/eslint-config/next.js"],
rules: {
"no-restricted-imports": ["error", "next/link"],
},
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { listRecords } from "@/lib/atproto";
import { resolveIdentity } from "@/lib/atproto-server";
import { getPds } from "@atproto/identity";
import Link from "next/link";
import Link from "@/lib/link";
import { SWRConfig } from "swr";
import { CollectionItems } from "../../_lib/collection";

Expand Down
2 changes: 1 addition & 1 deletion packages/atproto-browser/app/at/[identifier]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getAtUriPath, isNotNull, utcDateFormatter } from "@/lib/util";
import Link from "next/link";
import Link from "@/lib/link";
import { Fragment, Suspense } from "react";
import { ErrorBoundary } from "react-error-boundary";
import { z } from "zod";
Expand Down
6 changes: 2 additions & 4 deletions packages/atproto-browser/app/at/_lib/atproto-json.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { isDid } from "@atproto/did";
import Link from "next/link";
import Link from "@/lib/link";
import { AtBlob } from "../../../lib/at-blob";
import { getAtUriPath } from "@/lib/util";
import { AtUri } from "@atproto/syntax";
Expand Down Expand Up @@ -101,9 +101,7 @@ function JSONObject({
<pre>{key}:</pre>
</dt>
<dd style={{ margin: 0 }}>
{parseBlobResult.success &&
key === "$link" &&
typeof value === "string" ? (
{key === "$link" && typeof value === "string" ? (
<pre>
<a href={`/blob/${repo}/${value}`}>{value}</a>
</pre>
Expand Down
6 changes: 4 additions & 2 deletions packages/atproto-browser/app/at/_lib/collection-server.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { resolveIdentity } from "@/lib/atproto-server";
import { getPds } from "@atproto/identity";
import Link from "next/link";
import Link from "@/lib/link";

export async function DidCollections({ identifier }: { identifier: string }) {
const identityResult = await resolveIdentity(identifier);
Expand Down Expand Up @@ -40,7 +40,9 @@ export async function DidCollections({ identifier }: { identifier: string }) {
collections.map((nsid) => {
return (
<li key={nsid}>
<Link href={`/at/${identifier}/${nsid}`}>{nsid}</Link>
<Link href={`/at/${identifier}/${nsid}`} prefetch={false}>
{nsid}
</Link>
</li>
);
})
Expand Down
2 changes: 1 addition & 1 deletion packages/atproto-browser/app/at/_lib/collection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { listRecords } from "@/lib/atproto";
import { getAtUriPath } from "@/lib/util";
import { AtUri } from "@atproto/syntax";
import Link from "next/link";
import Link from "@/lib/link";
import { Suspense, useState } from "react";
import useSWR from "swr";

Expand Down
2 changes: 1 addition & 1 deletion packages/atproto-browser/app/at/_lib/did-components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { JSONType, JSONValue } from "./atproto-json";
import { resolveIdentity } from "@/lib/atproto-server";
import { DidCollections } from "./collection-server";
import { Suspense } from "react";
import Link from "next/link";
import Link from "@/lib/link";

export function CollapsedDidSummary({ did }: { did: string }) {
return (
Expand Down
2 changes: 1 addition & 1 deletion packages/atproto-browser/app/at/_lib/uri-bar.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client";

import Link from "next/link";
import Link from "@/lib/link";
import { useParams, usePathname, useSearchParams } from "next/navigation";
import { AtUriForm } from "../../aturi-form";

Expand Down
2 changes: 1 addition & 1 deletion packages/atproto-browser/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Link from "next/link";
import Link from "@/lib/link";
import { AtUriForm } from "./aturi-form";
import type { Metadata } from "next";

Expand Down
21 changes: 21 additions & 0 deletions packages/atproto-browser/lib/link.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"use client";
// eslint-disable-next-line no-restricted-imports
import NextLink from "next/link";
import { useRouter } from "next/navigation";
import { ComponentProps } from "react";

export default function Link(props: ComponentProps<typeof NextLink>) {
const router = useRouter();
function prefetch() {
router.prefetch(props.href.toString());
}

return (
<NextLink
{...props}
prefetch={false}
onMouseEnter={props.prefetch ? prefetch : undefined}
onTouchStart={props.prefetch ? prefetch : undefined}
/>
);
}
2 changes: 0 additions & 2 deletions packages/frontpage/.env.1pw
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
AUTH_SECRET="op://Unravel Dev/Frontpage Dev Env/DRAINPIPE_CONSUMER_SECRET"
# DISCORD_WEBHOOK_URL="op://Unravel Dev/Frontpage Dev Env/DISCORD_WEBHOOK_URL"
DRAINPIPE_CONSUMER_SECRET="op://Unravel Dev/Frontpage Dev Env/DRAINPIPE_CONSUMER_SECRET"
PRIVATE_JWK="op://Unravel Dev/Frontpage Dev Env/PRIVATE_JWK"
PUBLIC_JWK="op://Unravel Dev/Frontpage Dev Env/PUBLIC_JWK"

TURSO_CONNECTION_URL="op://Unravel Dev/Frontpage Dev Env/TURSO_CONNECTION_URL"
TURSO_AUTH_TOKEN="op://Unravel Dev/Frontpage Dev Env/TURSO_AUTH_TOKEN"
20 changes: 20 additions & 0 deletions packages/frontpage/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
# frontpage

Frontpage AppView and frontend client.

## Running locally

If you just need to work on the app in a logged-out state, then you just need to run the following:

```bash
pnpm run dev
```

If you need to login, you need to setup some additional env vars and serve your dev server over the public internet. You can do this with `cloudflared` altho other options are available eg. `ngrok` or `tailscale`:

```bash
pnpm exec tsx ./scripts/generate-jwks.mts # Copy this output into .env.local

# In one terminal, start the dev server
pnpm run dev

# In another terminal, open the tunnel. This example uses `cloudflared`
cloudflared tunnel --url http://localhost:3000
```
3 changes: 2 additions & 1 deletion packages/frontpage/app/(app)/_components/post-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import { ensureUser, getUser } from "@/lib/data/user";
import { TimeAgo } from "@/lib/components/time-ago";
import { VoteButton } from "./vote-button";
import { PostCollection } from "@/lib/data/atproto/post";
import { DID, getVerifiedHandle } from "@/lib/data/atproto/did";
import { getVerifiedHandle } from "@/lib/data/atproto/identity";
import { UserHoverCard } from "@/lib/components/user-hover-card";
import type { DID } from "@/lib/data/atproto/did";

type PostProps = {
id: number;
Expand Down
1 change: 1 addition & 0 deletions packages/frontpage/app/(app)/_components/vote-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export function VoteButton({
initialState,
votes,
}: VoteButtonProps) {
// TODO: useOptimistic here to fix cached vote count bug
const [hasVoted, setHasVoted] = useState(
initialState === "voted" || initialState === "authored",
);
Expand Down
29 changes: 18 additions & 11 deletions packages/frontpage/app/(app)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { getSession, signOut } from "@/lib/auth";
import { deleteAuthCookie, getSession, signOut } from "@/lib/auth";
import Link from "next/link";
import { Suspense } from "react";
import { Button } from "@/lib/components/ui/button";
import { isBetaUser } from "@/lib/data/user";
import { OpenInNewWindowIcon } from "@radix-ui/react-icons";
import { ThemeToggle } from "./_components/theme-toggle";
import { getDidFromHandleOrDid } from "@/lib/data/atproto/did";
import {
getDidFromHandleOrDid,
getVerifiedHandle,
} from "@/lib/data/atproto/identity";

import {
DropdownMenu,
Expand All @@ -17,6 +20,9 @@ import {
import { DropdownMenuTrigger } from "@radix-ui/react-dropdown-menu";
import { UserAvatar } from "@/lib/components/user-avatar";
import { FRONTPAGE_ATPROTO_HANDLE } from "@/lib/constants";
import { redirect } from "next/navigation";
import { cookies } from "next/headers";
import { revalidatePath } from "next/cache";

export default async function Layout({
children,
Expand Down Expand Up @@ -97,26 +103,24 @@ export default async function Layout({
async function LoginOrLogout() {
const session = await getSession();
if (session) {
const did = await getDidFromHandleOrDid(session.user.name as string);
const [did, handle] = await Promise.all([
getDidFromHandleOrDid(session.user.username),
getVerifiedHandle(session.user.did),
]);
return (
<DropdownMenu>
<DropdownMenuTrigger>
{did ? (
<UserAvatar did={did} size="smedium" />
) : (
<span>{session.user.name}</span>
<span>{handle}</span>
)}
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56" side="bottom" align="end">
<DropdownMenuLabel className="truncate">
{session.user.name}
</DropdownMenuLabel>
<DropdownMenuLabel className="truncate">{handle}</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem asChild>
<Link
href={`/profile/${session.user.name}`}
className="cursor-pointer"
>
<Link href={`/profile/${handle}`} className="cursor-pointer">
Profile
</Link>
</DropdownMenuItem>
Expand All @@ -125,6 +129,9 @@ async function LoginOrLogout() {
action={async () => {
"use server";
await signOut();
deleteAuthCookie(cookies());
revalidatePath("/", "layout");
redirect("/");
}}
>
<DropdownMenuItem asChild>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import "server-only";
import { getDidFromHandleOrDid } from "@/lib/data/atproto/did";
import { getDidFromHandleOrDid } from "@/lib/data/atproto/identity";
import {
getCommentWithChildren,
shouldHideComment,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Comment } from "../../_lib/comment";
import Link from "next/link";
import { Metadata } from "next";
import { getVerifiedHandle } from "@/lib/data/atproto/did";
import { getVerifiedHandle } from "@/lib/data/atproto/identity";
import { CommentPageParams, getCommentPageData } from "./_lib/page-data";

function truncateText(text: string, maxLength: number) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Link from "next/link";
import {
getDidFromHandleOrDid,
getVerifiedHandle,
} from "@/lib/data/atproto/did";
} from "@/lib/data/atproto/identity";
import { UserHoverCard } from "@/lib/components/user-hover-card";
import { VariantProps, cva } from "class-variance-authority";
import { cn } from "@/lib/utils";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import "server-only";
import { getDidFromHandleOrDid } from "@/lib/data/atproto/did";
import { getDidFromHandleOrDid } from "@/lib/data/atproto/identity";
import { getPost } from "@/lib/data/db/post";
import { notFound } from "next/navigation";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { notFound } from "next/navigation";
import { PostCard } from "../../../_components/post-card";
import { DeletePostButton } from "./_lib/delete-post-button";
import { getPost } from "@/lib/data/db/post";
import { getDidFromHandleOrDid } from "@/lib/data/atproto/did";
import { getDidFromHandleOrDid } from "@/lib/data/atproto/identity";

type Params = {
postRkey: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { NewComment } from "./_lib/comment-client";
import { Comment } from "./_lib/comment";
import { getCommentsForPost } from "@/lib/data/db/comment";
import { Metadata } from "next";
import { getVerifiedHandle } from "@/lib/data/atproto/did";
import { getVerifiedHandle } from "@/lib/data/atproto/identity";
import { PostPageParams, getPostPageData } from "./_lib/page-data";

export async function generateMetadata({
Expand Down
3 changes: 2 additions & 1 deletion packages/frontpage/app/(app)/post/new/_action.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use server";

import { DID, getVerifiedHandle } from "@/lib/data/atproto/did";
import { DID } from "@/lib/data/atproto/did";
import { getVerifiedHandle } from "@/lib/data/atproto/identity";
import { createPost } from "@/lib/data/atproto/post";
import { uncached_doesPostExist } from "@/lib/data/db/post";
import { DataLayerError } from "@/lib/data/error";
Expand Down
3 changes: 2 additions & 1 deletion packages/frontpage/app/(app)/profile/[user]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DID, getDidFromHandleOrDid } from "@/lib/data/atproto/did";
import type { DID } from "@/lib/data/atproto/did";
import { getUserPosts } from "@/lib/data/db/post";
import { unstable_noStore } from "next/cache";
import { notFound } from "next/navigation";
Expand All @@ -14,6 +14,7 @@ import { getBlueskyProfile } from "@/lib/data/user";
import { getUserComments } from "@/lib/data/db/comment";
import { Comment } from "../../post/[postAuthor]/[postRkey]/_lib/comment";
import { Suspense } from "react";
import { getDidFromHandleOrDid } from "@/lib/data/atproto/identity";

type Params = {
user: string;
Expand Down
17 changes: 7 additions & 10 deletions packages/frontpage/app/(auth)/login/_lib/action.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
"use server";
import { signIn } from "@/lib/auth";
import { AuthError } from "next-auth";
import { signIn } from "@/lib/auth-sign-in";

export async function loginAction(_prevStart: unknown, formData: FormData) {
try {
formData.set("redirectTo", "/");
await signIn(formData);
} catch (error) {
if (error instanceof AuthError) {
return { error: "Failed to sign in." };
}
throw error;
const identifier = formData.get("identifier") as string;
const result = await signIn(identifier.replace(/^@/, ""));
if (result && "error" in result) {
return {
error: `An error occured while signing in (${result.error})`,
};
}
}
Loading

0 comments on commit 19d9dcc

Please sign in to comment.