a tool for shared writing and social publishing
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

extract generate feed function to seperate file

+87 -84
+1 -1
app/lish/[did]/[publication]/atom/route.ts
··· 1 1 import { NextResponse } from "next/server"; 2 - import { generateFeed } from "../layout"; 2 + import { generateFeed } from "../generateFeed"; 3 3 4 4 export async function GET( 5 5 req: Request,
+83
app/lish/[did]/[publication]/generateFeed.ts
··· 1 + import { AtUri } from "@atproto/syntax"; 2 + import { Feed } from "feed"; 3 + import { 4 + PubLeafletDocument, 5 + PubLeafletPagesLinearDocument, 6 + PubLeafletPublication, 7 + } from "lexicons/api"; 8 + import { createElement } from "react"; 9 + import { renderToReadableStream } from "react-dom/server"; 10 + import { StaticPostContent } from "./[rkey]/StaticPostContent"; 11 + import { get_publication_data } from "app/api/rpc/[command]/get_publication_data"; 12 + import { supabaseServerClient } from "supabase/serverClient"; 13 + import { NextResponse } from "next/server"; 14 + 15 + export async function generateFeed( 16 + did: string, 17 + publication_name: string, 18 + ): Promise<Feed | NextResponse<unknown>> { 19 + let { result: publication } = await get_publication_data.handler( 20 + { 21 + did: did, 22 + publication_name: publication_name, 23 + }, 24 + { supabase: supabaseServerClient }, 25 + ); 26 + 27 + let pubRecord = publication?.record as PubLeafletPublication.Record; 28 + if (!publication || !pubRecord) 29 + return new NextResponse(null, { status: 404 }); 30 + 31 + const feed = new Feed({ 32 + title: pubRecord.name, 33 + description: pubRecord.description, 34 + id: `https://${pubRecord.base_path}`, 35 + link: `https://${pubRecord.base_path}`, 36 + language: "en", // optional, used only in RSS 2.0, possible values: http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes 37 + copyright: "", 38 + feedLinks: { 39 + rss: `https://${pubRecord.base_path}/rss`, 40 + atom: `https://${pubRecord.base_path}/atom`, 41 + json: `https://${pubRecord.base_path}/json`, 42 + }, 43 + }); 44 + 45 + await Promise.all( 46 + publication.documents_in_publications.map(async (doc) => { 47 + if (!doc.documents) return; 48 + let record = doc.documents?.data as PubLeafletDocument.Record; 49 + let uri = new AtUri(doc.documents?.uri); 50 + let rkey = uri.rkey; 51 + if (!record) return; 52 + let firstPage = record.pages[0]; 53 + let blocks: PubLeafletPagesLinearDocument.Block[] = []; 54 + if (PubLeafletPagesLinearDocument.isMain(firstPage)) { 55 + blocks = firstPage.blocks || []; 56 + } 57 + let stream = await renderToReadableStream( 58 + createElement(StaticPostContent, { blocks, did: uri.host }), 59 + ); 60 + const reader = stream.getReader(); 61 + const chunks = []; 62 + 63 + let done, value; 64 + while (!done) { 65 + ({ done, value } = await reader.read()); 66 + if (value) { 67 + chunks.push(new TextDecoder().decode(value)); 68 + } 69 + } 70 + 71 + feed.addItem({ 72 + title: record.title, 73 + description: record.description, 74 + date: record.publishedAt ? new Date(record.publishedAt) : new Date(), 75 + id: `https://${pubRecord.base_path}/${rkey}`, 76 + link: `https://${pubRecord.base_path}/${rkey}`, 77 + content: chunks.join(""), 78 + }); 79 + }), 80 + ); 81 + 82 + return feed; 83 + }
+1 -1
app/lish/[did]/[publication]/json/route.ts
··· 1 1 import { NextResponse } from "next/server"; 2 - import { generateFeed } from "../layout"; 2 + import { generateFeed } from "../generateFeed"; 3 3 4 4 export async function GET( 5 5 req: Request,
+1 -81
app/lish/[did]/[publication]/layout.tsx
··· 1 - import { AtUri } from "@atproto/syntax"; 2 - import { Feed } from "feed"; 3 - import { 4 - PubLeafletDocument, 5 - PubLeafletPagesLinearDocument, 6 - PubLeafletPublication, 7 - } from "lexicons/api"; 8 - import { createElement } from "react"; 9 - import { renderToReadableStream } from "react-dom/server"; 10 - import { StaticPostContent } from "./[rkey]/StaticPostContent"; 1 + import { PubLeafletPublication } from "lexicons/api"; 11 2 import { get_publication_data } from "app/api/rpc/[command]/get_publication_data"; 12 3 import { supabaseServerClient } from "supabase/serverClient"; 13 - import { NextResponse } from "next/server"; 14 4 import { Metadata } from "next"; 15 5 16 6 export default async function PublicationLayout(props: { ··· 49 39 : undefined, 50 40 }; 51 41 } 52 - 53 - export async function generateFeed( 54 - did: string, 55 - publication_name: string, 56 - ): Promise<Feed | NextResponse<unknown>> { 57 - let { result: publication } = await get_publication_data.handler( 58 - { 59 - did: did, 60 - publication_name: publication_name, 61 - }, 62 - { supabase: supabaseServerClient }, 63 - ); 64 - 65 - let pubRecord = publication?.record as PubLeafletPublication.Record; 66 - if (!publication || !pubRecord) 67 - return new NextResponse(null, { status: 404 }); 68 - 69 - const feed = new Feed({ 70 - title: pubRecord.name, 71 - description: pubRecord.description, 72 - id: `https://${pubRecord.base_path}`, 73 - link: `https://${pubRecord.base_path}`, 74 - language: "en", // optional, used only in RSS 2.0, possible values: http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes 75 - copyright: "", 76 - feedLinks: { 77 - rss: `https://${pubRecord.base_path}/rss`, 78 - atom: `https://${pubRecord.base_path}/atom`, 79 - json: `https://${pubRecord.base_path}/json`, 80 - }, 81 - }); 82 - 83 - await Promise.all( 84 - publication.documents_in_publications.map(async (doc) => { 85 - if (!doc.documents) return; 86 - let record = doc.documents?.data as PubLeafletDocument.Record; 87 - let uri = new AtUri(doc.documents?.uri); 88 - let rkey = uri.rkey; 89 - if (!record) return; 90 - let firstPage = record.pages[0]; 91 - let blocks: PubLeafletPagesLinearDocument.Block[] = []; 92 - if (PubLeafletPagesLinearDocument.isMain(firstPage)) { 93 - blocks = firstPage.blocks || []; 94 - } 95 - let stream = await renderToReadableStream( 96 - createElement(StaticPostContent, { blocks, did: uri.host }), 97 - ); 98 - const reader = stream.getReader(); 99 - const chunks = []; 100 - 101 - let done, value; 102 - while (!done) { 103 - ({ done, value } = await reader.read()); 104 - if (value) { 105 - chunks.push(new TextDecoder().decode(value)); 106 - } 107 - } 108 - 109 - feed.addItem({ 110 - title: record.title, 111 - description: record.description, 112 - date: record.publishedAt ? new Date(record.publishedAt) : new Date(), 113 - id: `https://${pubRecord.base_path}/${rkey}`, 114 - link: `https://${pubRecord.base_path}/${rkey}`, 115 - content: chunks.join(""), 116 - }); 117 - }), 118 - ); 119 - 120 - return feed; 121 - }
+1 -1
app/lish/[did]/[publication]/rss/route.ts
··· 1 1 import { NextResponse } from "next/server"; 2 - import { generateFeed } from "../layout"; 2 + import { generateFeed } from "../generateFeed"; 3 3 4 4 export async function GET( 5 5 req: Request,