From 696938eebafa83f1812695c4585260657c8116b1 Mon Sep 17 00:00:00 2001
From: Kashvi Garg <97344852+kashvigarg@users.noreply.github.com>
Date: Thu, 10 Apr 2025 13:42:17 +0000
Subject: [PATCH] Untested Changes
---
web2/app/api/[...path]/route.ts | 149 +++++++++++----------
web2/app/api/sse/[...path]/route.ts | 38 ++++++
web2/app/page.tsx | 4 +-
web2/app/timeline/page.tsx | 10 ++
web2/components/comments-list.tsx | 2 +-
web2/components/notification-indicator.tsx | 57 +++++++-
web2/components/notifications-list.tsx | 2 +-
web2/components/timeline.tsx | 5 +-
web2/components/users-list.tsx | 1 +
web2/lib/use-sse.tsx | 65 ++++++---
10 files changed, 234 insertions(+), 99 deletions(-)
create mode 100644 web2/app/api/sse/[...path]/route.ts
create mode 100644 web2/app/timeline/page.tsx
diff --git a/web2/app/api/[...path]/route.ts b/web2/app/api/[...path]/route.ts
index 51d7c71..4c1684d 100644
--- a/web2/app/api/[...path]/route.ts
+++ b/web2/app/api/[...path]/route.ts
@@ -8,80 +8,81 @@ export async function GET(request: NextRequest, { params }: { params: { path: st
const token = searchParams.get("token") || request.headers.get("Authorization")?.split(" ")[1];
// Check if this is an SSE endpoint
- const isSSE = path === "timeline" || path === "notifications" || path.includes("/comments");
-
- if (isSSE) {
- try {
- // Try SSE first
- const response = await fetch(`${process.env.API_URL}/api/${path}`, {
- headers: {
- Authorization: `Bearer ${token}`,
- Accept: "text/event-stream",
- },
- });
-
- const text = await response.text();
-
- if (response.ok && text.trim()) {
- try {
- const data = JSON.parse(text);
-
- // Set up SSE response
- const encoder = new TextEncoder();
- const stream = new ReadableStream({
- async start(controller) {
- controller.enqueue(encoder.encode(`data: ${JSON.stringify(data)}\n\n`));
-
- // Keep the connection open
- const interval = setInterval(() => {
- controller.enqueue(encoder.encode(": keepalive\n\n"));
- }, 30000);
-
- // Clean up on close
- request.signal.addEventListener("abort", () => {
- clearInterval(interval);
- controller.close();
- });
- },
- });
-
- return new NextResponse(stream, {
- headers: {
- "Content-Type": "text/event-stream",
- "Cache-Control": "no-cache",
- Connection: "keep-alive",
- },
- });
- } catch (jsonError) {
- console.error("SSE JSON parse error:", jsonError);
- return NextResponse.json({ error: "Invalid JSON response from SSE" }, { status: 502 });
- }
- } else {
- console.log("SSE response empty, falling back to basic fetch...");
-
- const fallbackResponse = await fetch(`${process.env.API_URL}/api/${path}`, {
- headers: { Authorization: `Bearer ${token}` },
- });
-
- const fallbackText = await fallbackResponse.text();
-
- if (!fallbackText.trim()) {
- return NextResponse.json({ error: "Empty response from server" }, { status: 502 });
- }
-
- try {
- return NextResponse.json(JSON.parse(fallbackText), { status: fallbackResponse.status });
- } catch {
- return NextResponse.json({ error: "Invalid JSON from fallback" }, { status: 502 });
- }
- }
- } catch (error: any) {
- console.error("SSE error:", error);
- if (error.code !== "UND_ERR_HEADERS_TIMEOUT") {
- return NextResponse.json({ error: "Failed to connect to SSE" }, { status: 500 });
- }
- }
- }
+ // const isSSE = path === "timeline" || path === "notifications" ||path.includes("/comments");
+
+ // if (isSSE) {
+ // try {
+ // // Try SSE first
+ // const response = await fetch(`${process.env.API_URL}/api/${path}`, {
+ // headers: {
+ // Authorization: `Bearer ${token}`,
+ // Accept: "text/event-stream",
+ // },
+ // });
+ // console.log(response)
+
+ // const text = await response.text();
+
+ // if (response.ok && !text.trim()) {
+ // try {
+ // const data = JSON.parse(text);
+
+ // // Set up SSE response
+ // const encoder = new TextEncoder();
+ // const stream = new ReadableStream({
+ // async start(controller) {
+ // controller.enqueue(encoder.encode(`data: ${JSON.stringify(data)}\n\n`));
+
+ // // Keep the connection open
+ // const interval = setInterval(() => {
+ // controller.enqueue(encoder.encode(": keepalive\n\n"));
+ // }, 30000);
+
+ // // Clean up on close
+ // request.signal.addEventListener("abort", () => {
+ // clearInterval(interval);
+ // controller.close();
+ // });
+ // },
+ // });
+
+ // return new NextResponse(stream, {
+ // headers: {
+ // "Content-Type": "text/event-stream",
+ // "Cache-Control": "no-cache",
+ // Connection: "keep-alive",
+ // },
+ // });
+ // } catch (jsonError) {
+ // console.error("SSE JSON parse error:", jsonError);
+ // return NextResponse.json({ error: "Invalid JSON response from SSE" }, { status: 502 });
+ // }
+ // } else {
+ // console.log("SSE response empty, falling back to basic fetch...");
+
+ // const fallbackResponse = await fetch(`${process.env.API_URL}/api/${path}`, {
+ // headers: { Authorization: `Bearer ${token}` },
+ // });
+
+ // const fallbackText = await fallbackResponse.text();
+
+ // if (!fallbackText.trim()) {
+ // return NextResponse.json({ error: "Empty response from server" }, { status: 502 });
+ // }
+
+ // try {
+ // return NextResponse.json(JSON.parse(fallbackText), { status: fallbackResponse.status });
+ // } catch {
+ // return NextResponse.json({ error: "Invalid JSON from fallback" }, { status: 502 });
+ // }
+ // }
+ // } catch (error: any) {
+ // console.error("SSE error:", error);
+ // if (error.code !== "UND_ERR_HEADERS_TIMEOUT") {
+ // return NextResponse.json({ error: "Failed to connect to SSE" }, { status: 500 });
+ // }
+ // }
+ // }
// Regular API request
try {
diff --git a/web2/app/api/sse/[...path]/route.ts b/web2/app/api/sse/[...path]/route.ts
new file mode 100644
index 0000000..8e61a83
--- /dev/null
+++ b/web2/app/api/sse/[...path]/route.ts
@@ -0,0 +1,38 @@
+// app/api/sse/[...path]/route.ts
+import { type NextRequest } from "next/server";
+
+export async function GET(request: NextRequest) {
+ const url = new URL(request.url);
+ const path = url.pathname.replace("/api/sse/", ""); // e.g., "timeline" or "comments/123"
+ const token =
+ url.searchParams.get("token") ||
+ request.headers.get("Authorization")?.split(" ")[1];
+
+ try {
+ const backendResponse = await fetch(
+ `${process.env.API_URL}/api/${path}?${url.searchParams.toString()}`,
+ {
+ method: "GET",
+ headers: {
+ Authorization: token ? `Bearer ${token}` : "",
+ Accept: "text/event-stream",
+ },
+ }
+ );
+
+ // Proxy the backend SSE stream directly to the client
+ return new Response(backendResponse.body, {
+ status: 200,
+ headers: {
+ "Content-Type": "text/event-stream",
+ "Cache-Control": "no-cache",
+ Connection: "keep-alive",
+ // Optional headers for CORS (if needed):
+ // "Access-Control-Allow-Origin": "*",
+ },
+ });
+ } catch (error) {
+ console.error("SSE proxy error:", error);
+ return new Response("Failed to connect to SSE", { status: 502 });
+ }
+}
diff --git a/web2/app/page.tsx b/web2/app/page.tsx
index f84db81..66cf2ad 100644
--- a/web2/app/page.tsx
+++ b/web2/app/page.tsx
@@ -1,7 +1,7 @@
import { redirect } from "next/navigation"
import { cookies } from "next/headers"
-import { Timeline } from "@/components/timeline"
import { MainLayout } from "@/components/main-layout"
+import TimelinePage from "./timeline/page"
export default async function Home() {
const cookieStore = await cookies()
@@ -13,7 +13,7 @@ export default async function Home() {
return (