Skip to content

Commit

Permalink
Migrate frontpage post to be lexicon first
Browse files Browse the repository at this point in the history
  • Loading branch information
tom-sherman committed Nov 6, 2024
1 parent ce0f68d commit c4853a9
Show file tree
Hide file tree
Showing 16 changed files with 81 additions and 106 deletions.
13 changes: 8 additions & 5 deletions packages/frontpage/app/(app)/_components/post-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { getVoteForPost } from "@/lib/data/db/vote";
import { ensureUser, getUser } from "@/lib/data/user";
import { TimeAgo } from "@/lib/components/time-ago";
import { VoteButton } from "./vote-button";
import { PostCollection, deletePost } from "@/lib/data/atproto/post";
import { getVerifiedHandle } from "@/lib/data/atproto/identity";
import { UserHoverCard } from "@/lib/components/user-hover-card";
import type { DID } from "@/lib/data/atproto/did";
Expand All @@ -15,6 +14,7 @@ import { revalidatePath } from "next/cache";
import { ReportDialogDropdownButton } from "./report-dialog";
import { DeleteButton } from "./delete-button";
import { ShareDropdownButton } from "./share-button";
import { atprotoClient, nsids } from "@/lib/data/atproto/repo";

type PostProps = {
id: number;
Expand Down Expand Up @@ -59,7 +59,7 @@ export async function PostCard({
subjectAuthorDid: author,
subjectCid: cid,
subjectRkey: rkey,
subjectCollection: PostCollection,
subjectCollection: nsids.FyiUnravelFrontpagePost,
});
}}
unvoteAction={async () => {
Expand Down Expand Up @@ -147,7 +147,10 @@ export async function PostCard({
export async function deletePostAction(rkey: string) {
"use server";
await ensureUser();
await deletePost(rkey);
const atproto = atprotoClient();
await atproto.fyi.unravel.frontpage.post.delete({
rkey,
});

revalidatePath("/");
}
Expand All @@ -170,9 +173,9 @@ export async function reportPostAction(

await createReport({
...formResult.data,
subjectUri: `at://${input.author}/${PostCollection}/${input.rkey}`,
subjectUri: `at://${input.author}/${nsids.FyiUnravelFrontpagePost}/${input.rkey}`,
subjectDid: input.author,
subjectCollection: PostCollection,
subjectCollection: nsids.FyiUnravelFrontpagePost,
subjectRkey: input.rkey,
subjectCid: input.cid,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ import { UserHandle } from "./user-handle";
import Link from "next/link";
import { cn } from "@/lib/utils";
import { CommentCollection } from "@/lib/data/atproto/comment";
import { PostCollection } from "@/lib/data/atproto/post";
import { getPostFromComment } from "@/lib/data/db/post";
import { getCommentLink, getPostLink } from "@/lib/navigation";
import { nsids } from "@/lib/data/atproto/repo";

const createLink = async (
collection?: string | null,
author?: DID | null,
rkey?: string | null,
) => {
switch (collection) {
case PostCollection:
case nsids.FyiUnravelFrontpagePost:
return getPostLink({ handleOrDid: author!, rkey: rkey! });

case CommentCollection:
Expand Down
8 changes: 4 additions & 4 deletions packages/frontpage/app/(app)/moderation/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {
ModerationEventDTO,
createModerationEvent,
} from "@/lib/data/db/moderation";
import { PostCollection } from "@/lib/data/atproto/post";
import { CommentCollection } from "@/lib/data/atproto/comment";
import { revalidatePath } from "next/cache";
import Link from "next/link";
Expand All @@ -26,6 +25,7 @@ import { moderatePost } from "@/lib/data/db/post";
import { DID } from "@/lib/data/atproto/did";
import { moderateComment } from "@/lib/data/db/comment";
import { moderateUser } from "@/lib/data/db/user";
import { nsids } from "@/lib/data/atproto/repo";

export async function performModerationAction(
input: { reportId: number; status: "accepted" | "rejected" },
Expand All @@ -49,8 +49,8 @@ export async function performModerationAction(
};

if (report.subjectCollection) {
if (report.subjectCollection === PostCollection) {
newModEvent.subjectCollection = PostCollection;
if (report.subjectCollection === nsids.FyiUnravelFrontpagePost) {
newModEvent.subjectCollection = nsids.FyiUnravelFrontpagePost;
} else if (report.subjectCollection === CommentCollection) {
newModEvent.subjectCollection = CommentCollection;
}
Expand All @@ -61,7 +61,7 @@ export async function performModerationAction(

const modAction = async () => {
switch (report.subjectCollection) {
case PostCollection:
case nsids.FyiUnravelFrontpagePost:
return await moderatePost({
rkey: report.subjectRkey!,
authorDid: report.subjectDid! as DID,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Metadata } from "next";
import { getVerifiedHandle } from "@/lib/data/atproto/identity";
import { PostPageParams, getPostPageData } from "./_lib/page-data";
import { LinkAlternateAtUri } from "@/lib/components/link-alternate-at";
import { PostCollection } from "@/lib/data/atproto/post";
import { nsids } from "@/lib/data/atproto/repo";

export async function generateMetadata(props: {
params: Promise<PostPageParams>;
Expand Down Expand Up @@ -47,7 +47,7 @@ export default async function Post(props: { params: Promise<PostPageParams> }) {
<>
<LinkAlternateAtUri
authority={authorDid}
collection={PostCollection}
collection={nsids.FyiUnravelFrontpagePost}
rkey={post.rkey}
/>
{post.status === "live" ? (
Expand Down
20 changes: 16 additions & 4 deletions packages/frontpage/app/(app)/post/new/_action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

import { DID } from "@/lib/data/atproto/did";
import { getVerifiedHandle } from "@/lib/data/atproto/identity";
import { createPost } from "@/lib/data/atproto/post";
import { atprotoClient } from "@/lib/data/atproto/repo";
import { uncached_doesPostExist } from "@/lib/data/db/post";
import { DataLayerError } from "@/lib/data/error";
import { ensureUser } from "@/lib/data/user";
import { AtUri } from "@atproto/syntax";
import { redirect } from "next/navigation";

export async function newPostAction(_prevState: unknown, formData: FormData) {
Expand All @@ -26,13 +27,24 @@ export async function newPostAction(_prevState: unknown, formData: FormData) {
return { error: "Invalid URL" };
}

const atproto = atprotoClient();

try {
const { rkey } = await createPost({ title, url });
const record = await atproto.fyi.unravel.frontpage.post.create(
{},
{
title,
url,
createdAt: new Date().toISOString(),
},
);
const uri = new AtUri(record.uri);

const [handle] = await Promise.all([
getVerifiedHandle(user.did),
waitForPost(user.did, rkey),
waitForPost(user.did, uri.rkey),
]);
redirect(`/post/${handle}/${rkey}`);
redirect(`/post/${handle}/${uri.rkey}`);
} catch (error) {
if (!(error instanceof DataLayerError)) throw error;
return { error: "Failed to create post" };
Expand Down
17 changes: 8 additions & 9 deletions packages/frontpage/app/api/receive_hook/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { db } from "@/lib/db";
import * as schema from "@/lib/schema";
import { atprotoGetRecord } from "@/lib/data/atproto/record";
import { Commit } from "@/lib/data/atproto/event";
import * as atprotoPost from "@/lib/data/atproto/post";
import * as dbPost from "@/lib/data/db/post";
import * as atprotoComment from "@/lib/data/atproto/comment";
import { VoteRecord } from "@/lib/data/atproto/vote";
Expand All @@ -17,6 +16,7 @@ import {
unauthed_createCommentVote,
} from "@/lib/data/db/vote";
import { unauthed_createNotification } from "@/lib/data/db/notification";
import { atprotoClient, nsids } from "@/lib/data/atproto/repo";

export async function POST(request: Request) {
const auth = request.headers.get("Authorization");
Expand All @@ -36,24 +36,23 @@ export async function POST(request: Request) {
throw new Error("No AtprotoPersonalDataServer service found");
}

const atproto = atprotoClient(service);

const promises = ops.map(async (op) => {
const { collection, rkey } = op.path;
console.log("Processing", collection, rkey, op.action);

if (collection === atprotoPost.PostCollection) {
if (collection === nsids.FyiUnravelFrontpagePost) {
if (op.action === "create") {
const record = await atprotoGetRecord({
serviceEndpoint: service,
const postRecord = await atproto.fyi.unravel.frontpage.post.get({
repo,
collection,
rkey,
});
const postRecord = atprotoPost.PostRecord.parse(record.value);
await dbPost.unauthed_createPost({
post: postRecord,
post: postRecord.value,
rkey,
authorDid: repo,
cid: record.cid,
cid: postRecord.cid,
offset: seq,
});
} else if (op.action === "delete") {
Expand Down Expand Up @@ -108,7 +107,7 @@ export async function POST(request: Request) {

if (
hydratedVoteRecordValue.subject.uri.collection ===
atprotoPost.PostCollection
nsids.FyiUnravelFrontpagePost
) {
await unauthed_createPostVote({
repo,
Expand Down
2 changes: 1 addition & 1 deletion packages/frontpage/lib/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ export async function importDpopJwks({
}

export async function fetchAuthenticatedAtproto(
input: RequestInfo,
input: string | Request | URL,
init?: RequestInit,
) {
const session = await getSession();
Expand Down
6 changes: 3 additions & 3 deletions packages/frontpage/lib/data/atproto/comment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ import {
import { createAtUriParser } from "./uri";
import { DataLayerError } from "../error";
import { z } from "zod";
import { PostCollection } from "./post";
import { DID, getPdsUrl } from "./did";
import { MAX_COMMENT_LENGTH } from "../db/constants";
import { nsids } from "./repo";

export const CommentCollection = "fyi.unravel.frontpage.comment";

Expand All @@ -23,7 +23,7 @@ export const CommentRecord = z.object({
.optional(),
post: z.object({
cid: z.string(),
uri: createAtUriParser(z.literal(PostCollection)),
uri: createAtUriParser(z.literal(nsids.FyiUnravelFrontpagePost)),
}),
createdAt: z.string(),
});
Expand All @@ -49,7 +49,7 @@ export async function createComment({ parent, post, content }: CommentInput) {
: undefined,
post: {
cid: post.cid,
uri: `at://${post.authorDid}/${PostCollection}/${post.rkey}`,
uri: `at://${post.authorDid}/${nsids.FyiUnravelFrontpagePost}/${post.rkey}`,
},
createdAt: new Date().toISOString(),
};
Expand Down
4 changes: 2 additions & 2 deletions packages/frontpage/lib/data/atproto/event.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import "server-only";
import { z } from "zod";
import { CommentCollection } from "./comment";
import { PostCollection } from "./post";
import { isDid } from "./did";
import { nsids } from "./repo";

// This module refers to the event emitted by the Firehose

export const Collection = z.union([
z.literal(PostCollection),
z.literal(nsids.FyiUnravelFrontpagePost),
z.literal(CommentCollection),
z.literal("fyi.unravel.frontpage.vote"),
]);
Expand Down
68 changes: 0 additions & 68 deletions packages/frontpage/lib/data/atproto/post.ts

This file was deleted.

25 changes: 25 additions & 0 deletions packages/frontpage/lib/data/atproto/repo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { AtpBaseClient } from "@repo/frontpage-atproto-client";
import { getUser } from "../user";
import { fetchAuthenticatedAtproto } from "@/lib/auth";
import { cache } from "react";

export { ids as nsids } from "@repo/frontpage-atproto-client/lexicons";

export const atprotoClient = cache(
(service?: string) =>
new AtpBaseClient(async (url: string, init: RequestInit) => {
const user = await getUser();
const s = service ?? user?.pdsUrl;
if (!s) {
throw new Error("No service url");
}

const u = new URL(url, s);

if (user) {
return fetchAuthenticatedAtproto(u, init);
}

return fetch(u, init);
}),
);
4 changes: 2 additions & 2 deletions packages/frontpage/lib/data/atproto/vote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import "server-only";
import { ensureUser } from "../user";
import { atprotoCreateRecord, atprotoDeleteRecord } from "./record";
import { z } from "zod";
import { PostCollection } from "./post";
import { CommentCollection } from "./comment";
import { DID } from "./did";
import { createAtUriParser } from "./uri";
import { nsids } from "./repo";

const VoteSubjectCollection = z.union([
z.literal(PostCollection),
z.literal(nsids.FyiUnravelFrontpagePost),
z.literal(CommentCollection),
]);

Expand Down
Loading

0 comments on commit c4853a9

Please sign in to comment.