chore: removed comments for now 70257d55
Steve · 2026-02-01 19:37 6 file(s) · +454 −660
packages/client/src/components/now/GuestReply.tsx +9 −230
1 -
import { useState, useEffect } from "react";
2 -
3 -
const API_URL = import.meta.env.PUBLIC_API_URL || "https://api.stevedylan.dev";
4 -
5 -
interface GuestAuthState {
6 -
	authenticated: boolean;
7 -
	did?: string;
8 -
	handle?: string;
9 -
	isGuest?: boolean;
10 -
	loading: boolean;
11 -
}
1 +
// COMMENTS FUNCTIONALITY DISABLED - Only email reply remains
12 2
13 3
interface GuestReplyProps {
14 4
	atUri: string;
21 11
	postTitle,
22 12
	onReplyPosted,
23 13
}: GuestReplyProps) {
24 -
	const [authState, setAuthState] = useState<GuestAuthState>({
25 -
		authenticated: false,
26 -
		loading: true,
27 -
	});
28 -
	const [replyContent, setReplyContent] = useState("");
29 -
	const [handleInput, setHandleInput] = useState("");
30 -
	const [showHandleForm, setShowHandleForm] = useState(false);
31 -
	const [isSubmitting, setIsSubmitting] = useState(false);
32 -
	const [error, setError] = useState<string | null>(null);
33 -
	const [success, setSuccess] = useState(false);
34 -
35 -
	useEffect(() => {
36 -
		checkAuthStatus();
37 -
	}, []);
38 -
39 -
	const checkAuthStatus = async () => {
40 -
		try {
41 -
			const response = await fetch(`${API_URL}/guest-auth/status`, {
42 -
				credentials: "include",
43 -
			});
44 -
			const data = await response.json();
45 -
			setAuthState({
46 -
				authenticated: data.authenticated,
47 -
				did: data.did,
48 -
				handle: data.handle,
49 -
				isGuest: data.isGuest,
50 -
				loading: false,
51 -
			});
52 -
		} catch (error) {
53 -
			console.error("Failed to check auth status:", error);
54 -
			setAuthState({ authenticated: false, loading: false });
55 -
		}
56 -
	};
57 -
58 -
	const handleLogin = (e: React.FormEvent) => {
59 -
		e.preventDefault();
60 -
		if (!handleInput.trim()) {
61 -
			setError("Handle is required");
62 -
			return;
63 -
		}
64 -
		// Pass current URL as returnTo parameter and handle
65 -
		const currentPath = window.location.pathname;
66 -
		const handle = handleInput.trim().replace(/^@/, ""); // Remove leading @ if present
67 -
		window.location.href = `${API_URL}/guest-auth/login?handle=${encodeURIComponent(handle)}&returnTo=${encodeURIComponent(currentPath)}`;
68 -
	};
69 -
70 -
	const handleLogout = async () => {
71 -
		try {
72 -
			await fetch(`${API_URL}/guest-auth/logout`, {
73 -
				method: "POST",
74 -
				credentials: "include",
75 -
			});
76 -
			setAuthState({ authenticated: false, loading: false });
77 -
			setReplyContent("");
78 -
		} catch (error) {
79 -
			console.error("Logout failed:", error);
80 -
		}
81 -
	};
82 -
83 -
	const handleReply = async (e: React.FormEvent) => {
84 -
		e.preventDefault();
85 -
86 -
		if (!replyContent.trim()) {
87 -
			setError("Reply content is required");
88 -
			return;
89 -
		}
90 -
91 -
		setIsSubmitting(true);
92 -
		setError(null);
93 -
		setSuccess(false);
94 -
95 -
		try {
96 -
			const response = await fetch(`${API_URL}/now/reply`, {
97 -
				method: "POST",
98 -
				credentials: "include",
99 -
				headers: {
100 -
					"Content-Type": "application/json",
101 -
				},
102 -
				body: JSON.stringify({
103 -
					parentUri: atUri,
104 -
					content: replyContent.trim(),
105 -
				}),
106 -
			});
107 -
108 -
			const data = await response.json();
109 -
110 -
			if (!response.ok) {
111 -
				throw new Error(data.error || "Failed to post reply");
112 -
			}
113 -
114 -
			setReplyContent("");
115 -
			setSuccess(true);
116 -
			setTimeout(() => setSuccess(false), 5000);
117 -
118 -
			// Notify parent to refresh replies list
119 -
			setTimeout(() => {
120 -
				onReplyPosted?.();
121 -
			}, 2000);
122 -
		} catch (err) {
123 -
			setError(err instanceof Error ? err.message : "Failed to post reply");
124 -
		} finally {
125 -
			setIsSubmitting(false);
126 -
		}
127 -
	};
128 -
129 14
	const emailSubject = encodeURIComponent(`Re: ${postTitle}`);
130 15
	const mailtoLink = `mailto:contact@stevedylan.dev?subject=${emailSubject}`;
131 16
132 -
	if (authState.loading) {
133 -
		return (
134 -
			<div className="mt-8 p-6 border border-gray-700 rounded-lg">
135 -
				<p className="text-sm text-gray-400">Loading...</p>
136 -
			</div>
137 -
		);
138 -
	}
139 -
140 17
	return (
141 18
		<div className="mt-8 space-y-4">
142 -
			<h2 className="text-xl font-bold">Reply</h2>
143 -
144 -
			{!authState.authenticated ? (
145 -
				<div className="space-y-4">
146 -
					{!showHandleForm ? (
147 -
						<>
148 -
							{/*<p className="text-sm text-gray-400">
149 -
								Sign in with your ATProto account to reply, or send an email.
150 -
							</p>*/}
151 -
							<div className="flex gap-3 flex-wrap">
152 -
								<button
153 -
									onClick={() => setShowHandleForm(true)}
154 -
									className="px-2 py-0.5 border border-white hover:border-gray-400 hover:text-gray-400 transition-colors text-xs"
155 -
								>
156 -
									Sign in with ATProto
157 -
								</button>
158 -
								<a
159 -
									href={mailtoLink}
160 -
									className="px-2 py-0.5 border border-white hover:border-gray-400 hover:text-gray-400 transition-colors text-xs"
161 -
								>
162 -
									Reply via Email
163 -
								</a>
164 -
							</div>
165 -
						</>
166 -
					) : (
167 -
						<form onSubmit={handleLogin} className="space-y-3">
168 -
							<p className="text-sm text-gray-400">
169 -
								Enter your handle to sign in:
170 -
							</p>
171 -
							<div className="flex gap-2">
172 -
								<input
173 -
									type="text"
174 -
									value={handleInput}
175 -
									onChange={(e) => setHandleInput(e.target.value)}
176 -
									placeholder="user.bsky.social or mydomain.com"
177 -
									className="flex-1 bg-transparent px-3 py-1 border border-white text-white text-sm"
178 -
								/>
179 -
								<button
180 -
									type="submit"
181 -
									className="px-3 py-1 border border-white hover:border-gray-400 hover:text-gray-400 transition-colors text-xs"
182 -
								>
183 -
									Sign in
184 -
								</button>
185 -
								<button
186 -
									type="button"
187 -
									onClick={() => {
188 -
										setShowHandleForm(false);
189 -
										setHandleInput("");
190 -
										setError(null);
191 -
									}}
192 -
									className="px-3 py-1 text-gray-500 hover:text-gray-300 transition-colors text-xs"
193 -
								>
194 -
									Cancel
195 -
								</button>
196 -
							</div>
197 -
							{error && <p className="text-sm text-red-500">{error}</p>}
198 -
						</form>
199 -
					)}
200 -
				</div>
201 -
			) : (
202 -
				<div className="space-y-4">
203 -
					<div className="flex items-center justify-between">
204 -
						<p className="text-sm text-gray-400">
205 -
							Signed in as {authState.handle || authState.did}
206 -
						</p>
207 -
						<button
208 -
							onClick={handleLogout}
209 -
							className="text-xs text-gray-500 hover:text-gray-300 transition-colors"
210 -
						>
211 -
							Sign out
212 -
						</button>
213 -
					</div>
214 -
215 -
					<form onSubmit={handleReply} className="space-y-3">
216 -
						<textarea
217 -
							value={replyContent}
218 -
							onChange={(e) => setReplyContent(e.target.value)}
219 -
							placeholder="Write your reply..."
220 -
							rows={4}
221 -
							className="w-full bg-transparent p-3 border border-white text-white resize-none"
222 -
							disabled={isSubmitting}
223 -
						/>
224 -
225 -
						<div className="flex items-center justify-between">
226 -
							<div className="flex items-center gap-3">
227 -
								{error && <span className="text-sm text-red-500">{error}</span>}
228 -
								{success && (
229 -
									<span className="text-sm text-white">
230 -
										Reply posted successfully!
231 -
									</span>
232 -
								)}
233 -
							</div>
234 -
235 -
							<div className="flex gap-3">
236 -
								<button
237 -
									type="submit"
238 -
									disabled={isSubmitting || !replyContent.trim()}
239 -
									className="px-4 py-0.5 border border-white hover:border-gray-400 hover:text-gray-400 disabled:border-opacity-50 disabled:cursor-not-allowed transition-colors text-xs"
240 -
								>
241 -
									{isSubmitting ? "Posting..." : "Post Reply"}
242 -
								</button>
243 -
							</div>
244 -
						</div>
245 -
					</form>
246 -
				</div>
247 -
			)}
19 +
			<div className="flex gap-3 flex-wrap">
20 +
				<a
21 +
					href={mailtoLink}
22 +
					className="px-2 py-0.5 border border-white hover:border-gray-400 hover:text-gray-400 transition-colors text-xs"
23 +
				>
24 +
					Reply via Email
25 +
				</a>
26 +
			</div>
248 27
		</div>
249 28
	);
250 29
}
packages/client/src/components/now/ReplyContainer.tsx +9 −9
1 -
import { useState } from "react";
2 -
import { ReplyList } from "./ReplyList";
1 +
// COMMENTS FUNCTIONALITY DISABLED - Only email reply remains
2 +
// import { useState } from "react";
3 +
// import { ReplyList } from "./ReplyList";
3 4
import { GuestReply } from "./GuestReply";
4 5
5 6
interface ReplyContainerProps {
8 9
}
9 10
10 11
export function ReplyContainer({ atUri, postTitle }: ReplyContainerProps) {
11 -
	const [refreshKey, setRefreshKey] = useState(0);
12 +
	// const [refreshKey, setRefreshKey] = useState(0);
12 13
13 -
	const handleReplyPosted = () => {
14 -
		// Increment key to force ReplyList to re-fetch
15 -
		setRefreshKey((prev) => prev + 1);
16 -
	};
14 +
	// const handleReplyPosted = () => {
15 +
	// 	setRefreshKey((prev) => prev + 1);
16 +
	// };
17 17
18 18
	return (
19 19
		<>
20 -
			<ReplyList key={refreshKey} atUri={atUri} />
20 +
			{/* <ReplyList key={refreshKey} atUri={atUri} /> */}
21 21
			<GuestReply
22 22
				atUri={atUri}
23 23
				postTitle={postTitle}
24 -
				onReplyPosted={handleReplyPosted}
24 +
				// onReplyPosted={handleReplyPosted}
25 25
			/>
26 26
		</>
27 27
	);
packages/client/src/components/now/ReplyList.tsx +162 −153
1 -
import { useState, useEffect } from "react";
1 +
// COMMENTS FUNCTIONALITY DISABLED
2 +
// import { useState, useEffect } from "react";
2 3
3 -
const API_URL = import.meta.env.PUBLIC_API_URL || "https://api.stevedylan.dev";
4 +
// const API_URL = import.meta.env.PUBLIC_API_URL || "https://api.stevedylan.dev";
4 5
5 -
interface Author {
6 -
	did: string;
7 -
	handle: string;
8 -
	displayName?: string;
9 -
	avatar?: string;
10 -
}
6 +
// interface Author {
7 +
// 	did: string;
8 +
// 	handle: string;
9 +
// 	displayName?: string;
10 +
// 	avatar?: string;
11 +
// }
11 12
12 -
interface CommentReference {
13 -
	createdAt: string;
14 -
	did: string;
15 -
	uri: string;
16 -
}
13 +
// interface CommentReference {
14 +
// 	createdAt: string;
15 +
// 	did: string;
16 +
// 	uri: string;
17 +
// }
17 18
18 -
interface Reply {
19 -
	uri: string;
20 -
	cid: string;
21 -
	author: Author;
22 -
	root: {
23 -
		cid: string;
24 -
		uri: string;
25 -
	};
26 -
	parent: {
27 -
		cid: string;
28 -
		uri: string;
29 -
	};
30 -
	content: string;
31 -
	createdAt: string;
32 -
	$type: string;
33 -
}
19 +
// interface Reply {
20 +
// 	uri: string;
21 +
// 	cid: string;
22 +
// 	author: Author;
23 +
// 	root: {
24 +
// 		cid: string;
25 +
// 		uri: string;
26 +
// 	};
27 +
// 	parent: {
28 +
// 		cid: string;
29 +
// 		uri: string;
30 +
// 	};
31 +
// 	content: string;
32 +
// 	createdAt: string;
33 +
// 	$type: string;
34 +
// }
34 35
35 -
interface ReplyListProps {
36 -
	atUri: string;
37 -
}
36 +
// interface ReplyListProps {
37 +
// 	atUri: string;
38 +
// }
38 39
39 -
export function ReplyList({ atUri }: ReplyListProps) {
40 -
	const [replies, setReplies] = useState<Reply[]>([]);
41 -
	const [loading, setLoading] = useState(true);
42 -
	const [error, setError] = useState<string | null>(null);
40 +
// export function ReplyList({ atUri }: ReplyListProps) {
41 +
// 	const [replies, setReplies] = useState<Reply[]>([]);
42 +
// 	const [loading, setLoading] = useState(true);
43 +
// 	const [error, setError] = useState<string | null>(null);
43 44
44 -
	useEffect(() => {
45 -
		fetchReplies();
46 -
	}, [atUri]);
45 +
// 	useEffect(() => {
46 +
// 		fetchReplies();
47 +
// 	}, [atUri]);
47 48
48 -
	const fetchReplies = async () => {
49 -
		try {
50 -
			setLoading(true);
51 -
			setError(null);
49 +
// 	const fetchReplies = async () => {
50 +
// 		try {
51 +
// 			setLoading(true);
52 +
// 			setError(null);
52 53
53 -
			const encodedUri = encodeURIComponent(atUri);
54 -
			const response = await fetch(`${API_URL}/now/comments/${encodedUri}`);
54 +
// 			const encodedUri = encodeURIComponent(atUri);
55 +
// 			const response = await fetch(`${API_URL}/now/comments/${encodedUri}`);
55 56
56 -
			if (!response.ok) {
57 -
				throw new Error("Failed to fetch comments");
58 -
			}
57 +
// 			if (!response.ok) {
58 +
// 				throw new Error("Failed to fetch comments");
59 +
// 			}
59 60
60 -
			const data = await response.json();
61 -
			setReplies(data.replies || []);
62 -
		} catch (err) {
63 -
			console.error("Error fetching replies:", err);
64 -
			setError(err instanceof Error ? err.message : "Failed to load replies");
65 -
		} finally {
66 -
			setLoading(false);
67 -
		}
68 -
	};
61 +
// 			const data = await response.json();
62 +
// 			setReplies(data.replies || []);
63 +
// 		} catch (err) {
64 +
// 			console.error("Error fetching replies:", err);
65 +
// 			setError(err instanceof Error ? err.message : "Failed to load replies");
66 +
// 		} finally {
67 +
// 			setLoading(false);
68 +
// 		}
69 +
// 	};
70 +
71 +
// 	const formatDate = (dateString: string) => {
72 +
// 		const date = new Date(dateString);
73 +
// 		const now = new Date();
74 +
// 		const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000);
75 +
76 +
// 		if (diffInSeconds < 60) {
77 +
// 			return `${diffInSeconds}s ago`;
78 +
// 		} else if (diffInSeconds < 3600) {
79 +
// 			return `${Math.floor(diffInSeconds / 60)}m ago`;
80 +
// 		} else if (diffInSeconds < 86400) {
81 +
// 			return `${Math.floor(diffInSeconds / 3600)}h ago`;
82 +
// 		} else if (diffInSeconds < 604800) {
83 +
// 			return `${Math.floor(diffInSeconds / 86400)}d ago`;
84 +
// 		} else {
85 +
// 			return date.toLocaleDateString();
86 +
// 		}
87 +
// 	};
69 88
70 -
	const formatDate = (dateString: string) => {
71 -
		const date = new Date(dateString);
72 -
		const now = new Date();
73 -
		const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000);
89 +
// 	if (loading) {
90 +
// 		return (
91 +
// 			<div className="mt-8">
92 +
// 				<h3 className="text-lg font-bold mb-4">Replies</h3>
93 +
// 				<p className="text-sm text-gray-400">Loading replies...</p>
94 +
// 			</div>
95 +
// 		);
96 +
// 	}
74 97
75 -
		if (diffInSeconds < 60) {
76 -
			return `${diffInSeconds}s ago`;
77 -
		} else if (diffInSeconds < 3600) {
78 -
			return `${Math.floor(diffInSeconds / 60)}m ago`;
79 -
		} else if (diffInSeconds < 86400) {
80 -
			return `${Math.floor(diffInSeconds / 3600)}h ago`;
81 -
		} else if (diffInSeconds < 604800) {
82 -
			return `${Math.floor(diffInSeconds / 86400)}d ago`;
83 -
		} else {
84 -
			return date.toLocaleDateString();
85 -
		}
86 -
	};
98 +
// 	if (error) {
99 +
// 		return (
100 +
// 			<div className="mt-8">
101 +
// 				<h3 className="text-lg font-bold mb-4">Replies</h3>
102 +
// 				<p className="text-sm text-red-500">{error}</p>
103 +
// 			</div>
104 +
// 		);
105 +
// 	}
87 106
88 -
	if (loading) {
89 -
		return (
90 -
			<div className="mt-8">
91 -
				<h3 className="text-lg font-bold mb-4">Replies</h3>
92 -
				<p className="text-sm text-gray-400">Loading replies...</p>
93 -
			</div>
94 -
		);
95 -
	}
107 +
// 	if (replies.length === 0) {
108 +
// 		return (
109 +
// 			<div className="mt-8">
110 +
// 				<h3 className="text-lg font-bold mb-4">Replies</h3>
111 +
// 				<p className="text-sm text-gray-400">
112 +
// 					No replies yet. Be the first to reply!
113 +
// 				</p>
114 +
// 			</div>
115 +
// 		);
116 +
// 	}
96 117
97 -
	if (error) {
98 -
		return (
99 -
			<div className="mt-8">
100 -
				<h3 className="text-lg font-bold mb-4">Replies</h3>
101 -
				<p className="text-sm text-red-500">{error}</p>
102 -
			</div>
103 -
		);
104 -
	}
118 +
// 	return (
119 +
// 		<div className="mt-8">
120 +
// 			<h3 className="text-lg font-bold mb-4">Replies</h3>
121 +
// 			<div className="space-y-6">
122 +
// 				{replies.map((reply) => (
123 +
// 					<div key={reply.uri}>
124 +
// 						<div className="flex items-start gap-3">
125 +
// 							{reply.author.avatar ? (
126 +
// 								<img
127 +
// 									src={reply.author.avatar}
128 +
// 									alt={reply.author.handle}
129 +
// 									className="w-10 h-10 rounded-full"
130 +
// 								/>
131 +
// 							) : (
132 +
// 								<div className="w-10 h-10 rounded-full bg-gray-700 flex items-center justify-center">
133 +
// 									<span className="text-gray-400 text-sm">
134 +
// 										{reply.author.handle.charAt(0).toUpperCase()}
135 +
// 									</span>
136 +
// 								</div>
137 +
// 							)}
105 138
106 -
	if (replies.length === 0) {
107 -
		return (
108 -
			<div className="mt-8">
109 -
				<h3 className="text-lg font-bold mb-4">Replies</h3>
110 -
				<p className="text-sm text-gray-400">
111 -
					No replies yet. Be the first to reply!
112 -
				</p>
113 -
			</div>
114 -
		);
115 -
	}
139 +
// 							<div className="flex-1 min-w-0">
140 +
// 								<div className="flex items-center gap-2 flex-wrap">
141 +
// 									<span className="font-semibold text-sm">
142 +
// 										{reply.author.displayName || reply.author.handle}
143 +
// 									</span>
144 +
// 									{reply.author.displayName && (
145 +
// 										<a
146 +
// 											href={`https://pdsls.dev/at://${reply.author.did}`}
147 +
// 											target="_blank"
148 +
// 											rel="noopener noreferrer"
149 +
// 											className="text-xs text-gray-400 hover:text-gray-300"
150 +
// 										>
151 +
// 											@{reply.author.handle}
152 +
// 										</a>
153 +
// 									)}
154 +
// 									<a
155 +
// 										href={`https://pdsls.dev/${reply.uri}`}
156 +
// 										target="_blank"
157 +
// 										rel="noopener noreferrer"
158 +
// 										className="text-xs text-gray-400 hover:text-gray-300"
159 +
// 									>
160 +
// 										{formatDate(reply.createdAt)}
161 +
// 									</a>
162 +
// 								</div>
116 163
117 -
	return (
118 -
		<div className="mt-8">
119 -
			<h3 className="text-lg font-bold mb-4">Replies</h3>
120 -
			<div className="space-y-6">
121 -
				{replies.map((reply) => (
122 -
					<div key={reply.uri}>
123 -
						<div className="flex items-start gap-3">
124 -
							{reply.author.avatar ? (
125 -
								<img
126 -
									src={reply.author.avatar}
127 -
									alt={reply.author.handle}
128 -
									className="w-10 h-10 rounded-full"
129 -
								/>
130 -
							) : (
131 -
								<div className="w-10 h-10 rounded-full bg-gray-700 flex items-center justify-center">
132 -
									<span className="text-gray-400 text-sm">
133 -
										{reply.author.handle.charAt(0).toUpperCase()}
134 -
									</span>
135 -
								</div>
136 -
							)}
164 +
// 								<p className="mt-2 text-sm whitespace-pre-wrap break-words">
165 +
// 									{reply.content}
166 +
// 								</p>
167 +
// 							</div>
168 +
// 						</div>
169 +
// 					</div>
170 +
// 				))}
171 +
// 			</div>
172 +
// 		</div>
173 +
// 	);
174 +
// }
137 175
138 -
							<div className="flex-1 min-w-0">
139 -
								<div className="flex items-center gap-2 flex-wrap">
140 -
									<span className="font-semibold text-sm">
141 -
										{reply.author.displayName || reply.author.handle}
142 -
									</span>
143 -
									{reply.author.displayName && (
144 -
										<a
145 -
											href={`https://pdsls.dev/at://${reply.author.did}`}
146 -
											target="_blank"
147 -
											rel="noopener noreferrer"
148 -
											className="text-xs text-gray-400 hover:text-gray-300"
149 -
										>
150 -
											@{reply.author.handle}
151 -
										</a>
152 -
									)}
153 -
									<a
154 -
										href={`https://pdsls.dev/${reply.uri}`}
155 -
										target="_blank"
156 -
										rel="noopener noreferrer"
157 -
										className="text-xs text-gray-400 hover:text-gray-300"
158 -
									>
159 -
										{formatDate(reply.createdAt)}
160 -
									</a>
161 -
								</div>
176 +
interface ReplyListProps {
177 +
	atUri: string;
178 +
}
162 179
163 -
								<p className="mt-2 text-sm whitespace-pre-wrap break-words">
164 -
									{reply.content}
165 -
								</p>
166 -
							</div>
167 -
						</div>
168 -
					</div>
169 -
				))}
170 -
			</div>
171 -
		</div>
172 -
	);
180 +
export function ReplyList({ atUri }: ReplyListProps) {
181 +
	return null;
173 182
}
packages/server/src/index.ts +5 −2
1 1
import { Hono } from "hono";
2 2
import { cors } from "hono/cors";
3 -
import { home, now, auth, guestAuth } from "./routes";
3 +
// COMMENTS FUNCTIONALITY DISABLED
4 +
// import { home, now, auth, guestAuth } from "./routes";
5 +
import { home, now, auth } from "./routes";
4 6
5 7
interface Env {
6 8
	SESSIONS: KVNamespace;
32 34
app.route("/", home);
33 35
app.route("/now", now);
34 36
app.route("/auth", auth);
35 -
app.route("/guest-auth", guestAuth);
37 +
// COMMENTS FUNCTIONALITY DISABLED
38 +
// app.route("/guest-auth", guestAuth);
36 39
37 40
export default app;
packages/server/src/routes/index.ts +2 −1
1 1
export { default as home } from "./home";
2 2
export { default as now } from "./now";
3 3
export { default as auth } from "./auth";
4 -
export { default as guestAuth } from "./guest-auth";
4 +
// COMMENTS FUNCTIONALITY DISABLED
5 +
// export { default as guestAuth } from "./guest-auth";
packages/server/src/routes/now.ts +267 −265
22 22
23 23
const PDS_URL = "https://andromeda.social";
24 24
25 -
// Helper function to get session for both admin and guest users
26 -
async function getAnySession(c: any, sessionId: string) {
27 -
	if (sessionId.startsWith("guest_")) {
28 -
		// Guest session
29 -
		const originalSessionId = await c.env.SESSIONS.get(
30 -
			`guest_session:${sessionId}`,
31 -
		);
32 -
		if (!originalSessionId) return null;
33 -
		return await getSession(c.env.SESSIONS, originalSessionId);
34 -
	} else {
35 -
		// Admin session
36 -
		return await getSession(c.env.SESSIONS, sessionId);
37 -
	}
38 -
}
25 +
// COMMENTS FUNCTIONALITY DISABLED
26 +
// // Helper function to get session for both admin and guest users
27 +
// async function getAnySession(c: any, sessionId: string) {
28 +
// 	if (sessionId.startsWith("guest_")) {
29 +
// 		// Guest session
30 +
// 		const originalSessionId = await c.env.SESSIONS.get(
31 +
// 			`guest_session:${sessionId}`,
32 +
// 		);
33 +
// 		if (!originalSessionId) return null;
34 +
// 		return await getSession(c.env.SESSIONS, originalSessionId);
35 +
// 	} else {
36 +
// 		// Admin session
37 +
// 		return await getSession(c.env.SESSIONS, sessionId);
38 +
// 	}
39 +
// }
39 40
40 41
// Create a new post
41 42
now.post("/post", async (c) => {
328 329
	}
329 330
});
330 331
331 -
// Create a reply to a post (for guests)
332 -
now.post("/reply", async (c) => {
333 -
	try {
334 -
		// Get session from cookie
335 -
		const sessionId = getSessionIdFromCookie(c);
336 -
		if (!sessionId) {
337 -
			return c.json({ error: "Not authenticated" }, 401);
338 -
		}
332 +
// COMMENTS FUNCTIONALITY DISABLED
333 +
// // Create a reply to a post (for guests)
334 +
// now.post("/reply", async (c) => {
335 +
// 	try {
336 +
// 		// Get session from cookie
337 +
// 		const sessionId = getSessionIdFromCookie(c);
338 +
// 		if (!sessionId) {
339 +
// 			return c.json({ error: "Not authenticated" }, 401);
340 +
// 		}
339 341
340 -
		const sessionData = await getAnySession(c, sessionId);
341 -
		if (!sessionData) {
342 -
			return c.json({ error: "Session not found" }, 401);
343 -
		}
342 +
// 		const sessionData = await getAnySession(c, sessionId);
343 +
// 		if (!sessionData) {
344 +
// 			return c.json({ error: "Session not found" }, 401);
345 +
// 		}
344 346
345 -
		let { session, dpopKeyPair } = sessionData;
347 +
// 		let { session, dpopKeyPair } = sessionData;
346 348
347 -
		// Determine which PDS to use (user's PDS for guests, env PDS for admin)
348 -
		const isGuest = sessionId.startsWith("guest_");
349 -
		const pdsUrl = isGuest && session.pdsUrl ? session.pdsUrl : c.env.PDS_URL;
349 +
// 		// Determine which PDS to use (user's PDS for guests, env PDS for admin)
350 +
// 		const isGuest = sessionId.startsWith("guest_");
351 +
// 		const pdsUrl = isGuest && session.pdsUrl ? session.pdsUrl : c.env.PDS_URL;
350 352
351 -
		// Refresh token if expired
352 -
		if (isTokenExpired(session.expiresAt) && session.refreshToken) {
353 -
			const metadata = await fetchOAuthMetadata(pdsUrl);
354 -
			const clientId = isGuest
355 -
				? `${c.env.API_URL}/guest-auth/client-metadata.json`
356 -
				: `${c.env.API_URL}/auth/client-metadata.json`;
353 +
// 		// Refresh token if expired
354 +
// 		if (isTokenExpired(session.expiresAt) && session.refreshToken) {
355 +
// 			const metadata = await fetchOAuthMetadata(pdsUrl);
356 +
// 			const clientId = isGuest
357 +
// 				? `${c.env.API_URL}/guest-auth/client-metadata.json`
358 +
// 				: `${c.env.API_URL}/auth/client-metadata.json`;
357 359
358 -
			const { tokenResponse, dpopNonce } = await refreshAccessToken(
359 -
				metadata,
360 -
				session.refreshToken,
361 -
				clientId,
362 -
				dpopKeyPair,
363 -
				session.dpopNonce,
364 -
			);
360 +
// 			const { tokenResponse, dpopNonce } = await refreshAccessToken(
361 +
// 				metadata,
362 +
// 				session.refreshToken,
363 +
// 				clientId,
364 +
// 				dpopKeyPair,
365 +
// 				session.dpopNonce,
366 +
// 			);
365 367
366 -
			// Get the actual session ID for update
367 -
			const actualSessionId = isGuest
368 -
				? (await c.env.SESSIONS.get(`guest_session:${sessionId}`)) || ""
369 -
				: sessionId;
368 +
// 			// Get the actual session ID for update
369 +
// 			const actualSessionId = isGuest
370 +
// 				? (await c.env.SESSIONS.get(`guest_session:${sessionId}`)) || ""
371 +
// 				: sessionId;
370 372
371 -
			// Update session with new tokens
372 -
			await updateSession(
373 -
				c.env.SESSIONS,
374 -
				actualSessionId,
375 -
				tokenResponse.access_token,
376 -
				tokenResponse.refresh_token || session.refreshToken,
377 -
				dpopNonce,
378 -
				tokenResponse.expires_in,
379 -
			);
373 +
// 			// Update session with new tokens
374 +
// 			await updateSession(
375 +
// 				c.env.SESSIONS,
376 +
// 				actualSessionId,
377 +
// 				tokenResponse.access_token,
378 +
// 				tokenResponse.refresh_token || session.refreshToken,
379 +
// 				dpopNonce,
380 +
// 				tokenResponse.expires_in,
381 +
// 			);
380 382
381 -
			// Update local session object
382 -
			session.accessToken = tokenResponse.access_token;
383 -
			session.dpopNonce = dpopNonce;
384 -
		}
383 +
// 			// Update local session object
384 +
// 			session.accessToken = tokenResponse.access_token;
385 +
// 			session.dpopNonce = dpopNonce;
386 +
// 		}
385 387
386 -
		// Parse request body
387 -
		const body = await c.req.json<{
388 -
			parentUri: string;
389 -
			content: string;
390 -
		}>();
388 +
// 		// Parse request body
389 +
// 		const body = await c.req.json<{
390 +
// 			parentUri: string;
391 +
// 			content: string;
392 +
// 		}>();
391 393
392 -
		if (!body.parentUri || body.parentUri.trim().length === 0) {
393 -
			return c.json({ error: "Parent URI is required" }, 400);
394 -
		}
394 +
// 		if (!body.parentUri || body.parentUri.trim().length === 0) {
395 +
// 			return c.json({ error: "Parent URI is required" }, 400);
396 +
// 		}
395 397
396 -
		if (!body.content || body.content.trim().length === 0) {
397 -
			return c.json({ error: "Content is required" }, 400);
398 -
		}
398 +
// 		if (!body.content || body.content.trim().length === 0) {
399 +
// 			return c.json({ error: "Content is required" }, 400);
400 +
// 		}
399 401
400 -
		// Fetch the parent post to get its CID (use owner's PDS since that's where the post lives)
401 -
		const getRecordUrl =
402 -
			`${c.env.PDS_URL}/xrpc/com.atproto.repo.getRecord?` +
403 -
			new URLSearchParams({
404 -
				repo: body.parentUri.split("/")[2], // Extract DID from URI
405 -
				collection: body.parentUri.split("/")[3], // Extract collection
406 -
				rkey: body.parentUri.split("/")[4], // Extract rkey
407 -
			});
402 +
// 		// Fetch the parent post to get its CID (use owner's PDS since that's where the post lives)
403 +
// 		const getRecordUrl =
404 +
// 			`${c.env.PDS_URL}/xrpc/com.atproto.repo.getRecord?` +
405 +
// 			new URLSearchParams({
406 +
// 				repo: body.parentUri.split("/")[2], // Extract DID from URI
407 +
// 				collection: body.parentUri.split("/")[3], // Extract collection
408 +
// 				rkey: body.parentUri.split("/")[4], // Extract rkey
409 +
// 			});
408 410
409 -
		const parentResponse = await fetch(getRecordUrl);
410 -
		if (!parentResponse.ok) {
411 -
			console.error("Failed to fetch parent post");
412 -
			return c.json({ error: "Failed to fetch parent post" }, 400);
413 -
		}
411 +
// 		const parentResponse = await fetch(getRecordUrl);
412 +
// 		if (!parentResponse.ok) {
413 +
// 			console.error("Failed to fetch parent post");
414 +
// 			return c.json({ error: "Failed to fetch parent post" }, 400);
415 +
// 		}
414 416
415 -
		const parentData = (await parentResponse.json()) as { cid: string };
416 -
		const parentCid = parentData.cid;
417 +
// 		const parentData = (await parentResponse.json()) as { cid: string };
418 +
// 		const parentCid = parentData.cid;
417 419
418 -
		// Fetch author profile to get handle, displayName, and avatar from Bluesky public API
419 -
		let authorHandle = session.did;
420 -
		let authorDisplayName: string | undefined;
421 -
		let authorAvatar: string | undefined;
420 +
// 		// Fetch author profile to get handle, displayName, and avatar from Bluesky public API
421 +
// 		let authorHandle = session.did;
422 +
// 		let authorDisplayName: string | undefined;
423 +
// 		let authorAvatar: string | undefined;
422 424
423 -
		try {
424 -
			const profileUrl = `https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor=${session.did}`;
425 -
			const profileResponse = await fetch(profileUrl);
426 -
			if (profileResponse.ok) {
427 -
				const profileData = (await profileResponse.json()) as {
428 -
					handle?: string;
429 -
					displayName?: string;
430 -
					avatar?: string;
431 -
				};
432 -
				authorHandle = profileData.handle || session.did;
433 -
				authorDisplayName = profileData.displayName;
434 -
				authorAvatar = profileData.avatar;
435 -
			}
436 -
		} catch (err) {
437 -
			console.error("Failed to fetch author profile:", err);
438 -
		}
425 +
// 		try {
426 +
// 			const profileUrl = `https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor=${session.did}`;
427 +
// 			const profileResponse = await fetch(profileUrl);
428 +
// 			if (profileResponse.ok) {
429 +
// 				const profileData = (await profileResponse.json()) as {
430 +
// 					handle?: string;
431 +
// 					displayName?: string;
432 +
// 					avatar?: string;
433 +
// 				};
434 +
// 				authorHandle = profileData.handle || session.did;
435 +
// 				authorDisplayName = profileData.displayName;
436 +
// 				authorAvatar = profileData.avatar;
437 +
// 			}
438 +
// 		} catch (err) {
439 +
// 			console.error("Failed to fetch author profile:", err);
440 +
// 		}
439 441
440 -
		// Create the comment record using site.standard.document.comment lexicon
441 -
		// Use the user's PDS URL since the record is stored in THEIR repo
442 -
		const createRecordUrl = `${pdsUrl}/xrpc/com.atproto.repo.createRecord`;
442 +
// 		// Create the comment record using site.standard.document.comment lexicon
443 +
// 		// Use the user's PDS URL since the record is stored in THEIR repo
444 +
// 		const createRecordUrl = `${pdsUrl}/xrpc/com.atproto.repo.createRecord`;
443 445
444 -
		const commentRecord = {
445 -
			repo: session.did,
446 -
			collection: "site.standard.document.comment",
447 -
			record: {
448 -
				$type: "site.standard.document.comment",
449 -
				parent: {
450 -
					uri: body.parentUri,
451 -
					cid: parentCid,
452 -
				},
453 -
				root: {
454 -
					uri: body.parentUri,
455 -
					cid: parentCid,
456 -
				},
457 -
				content: body.content.trim(),
458 -
				author: {
459 -
					did: session.did,
460 -
					handle: authorHandle,
461 -
					...(authorDisplayName && { displayName: authorDisplayName }),
462 -
					...(authorAvatar && { avatar: authorAvatar }),
463 -
				},
464 -
				createdAt: new Date().toISOString(),
465 -
			},
466 -
		};
446 +
// 		const commentRecord = {
447 +
// 			repo: session.did,
448 +
// 			collection: "site.standard.document.comment",
449 +
// 			record: {
450 +
// 				$type: "site.standard.document.comment",
451 +
// 				parent: {
452 +
// 					uri: body.parentUri,
453 +
// 					cid: parentCid,
454 +
// 				},
455 +
// 				root: {
456 +
// 					uri: body.parentUri,
457 +
// 					cid: parentCid,
458 +
// 				},
459 +
// 				content: body.content.trim(),
460 +
// 				author: {
461 +
// 					did: session.did,
462 +
// 					handle: authorHandle,
463 +
// 					...(authorDisplayName && { displayName: authorDisplayName }),
464 +
// 					...(authorAvatar && { avatar: authorAvatar }),
465 +
// 				},
466 +
// 				createdAt: new Date().toISOString(),
467 +
// 			},
468 +
// 		};
467 469
468 -
		// Make request with DPoP
469 -
		const makeRequest = async (nonce?: string): Promise<Response> => {
470 -
			const dpopProof = await createDPoPProof(dpopKeyPair, {
471 -
				method: "POST",
472 -
				url: createRecordUrl,
473 -
				nonce: nonce || session.dpopNonce,
474 -
				accessToken: session.accessToken,
475 -
			});
470 +
// 		// Make request with DPoP
471 +
// 		const makeRequest = async (nonce?: string): Promise<Response> => {
472 +
// 			const dpopProof = await createDPoPProof(dpopKeyPair, {
473 +
// 				method: "POST",
474 +
// 				url: createRecordUrl,
475 +
// 				nonce: nonce || session.dpopNonce,
476 +
// 				accessToken: session.accessToken,
477 +
// 			});
476 478
477 -
			return fetch(createRecordUrl, {
478 -
				method: "POST",
479 -
				headers: {
480 -
					"Content-Type": "application/json",
481 -
					Authorization: `DPoP ${session.accessToken}`,
482 -
					DPoP: dpopProof,
483 -
				},
484 -
				body: JSON.stringify(commentRecord),
485 -
			});
486 -
		};
479 +
// 			return fetch(createRecordUrl, {
480 +
// 				method: "POST",
481 +
// 				headers: {
482 +
// 					"Content-Type": "application/json",
483 +
// 					Authorization: `DPoP ${session.accessToken}`,
484 +
// 					DPoP: dpopProof,
485 +
// 				},
486 +
// 				body: JSON.stringify(commentRecord),
487 +
// 			});
488 +
// 		};
487 489
488 -
		let response = await makeRequest();
490 +
// 		let response = await makeRequest();
489 491
490 -
		// Handle DPoP nonce requirement
491 -
		if (response.status === 401) {
492 -
			const newNonce = extractDPoPNonce(response);
493 -
			if (newNonce) {
494 -
				// Retry with new nonce
495 -
				response = await makeRequest(newNonce);
492 +
// 		// Handle DPoP nonce requirement
493 +
// 		if (response.status === 401) {
494 +
// 			const newNonce = extractDPoPNonce(response);
495 +
// 			if (newNonce) {
496 +
// 				// Retry with new nonce
497 +
// 				response = await makeRequest(newNonce);
496 498
497 -
				// Get the actual session ID for update
498 -
				const actualSessionId = isGuest
499 -
					? (await c.env.SESSIONS.get(`guest_session:${sessionId}`)) || ""
500 -
					: sessionId;
499 +
// 				// Get the actual session ID for update
500 +
// 				const actualSessionId = isGuest
501 +
// 					? (await c.env.SESSIONS.get(`guest_session:${sessionId}`)) || ""
502 +
// 					: sessionId;
501 503
502 -
				// Update session with new nonce
503 -
				await updateSession(
504 -
					c.env.SESSIONS,
505 -
					actualSessionId,
506 -
					session.accessToken,
507 -
					session.refreshToken,
508 -
					newNonce,
509 -
					Math.floor((session.expiresAt - Date.now()) / 1000),
510 -
				);
511 -
			}
512 -
		}
504 +
// 				// Update session with new nonce
505 +
// 				await updateSession(
506 +
// 					c.env.SESSIONS,
507 +
// 					actualSessionId,
508 +
// 					session.accessToken,
509 +
// 					session.refreshToken,
510 +
// 					newNonce,
511 +
// 					Math.floor((session.expiresAt - Date.now()) / 1000),
512 +
// 				);
513 +
// 			}
514 +
// 		}
513 515
514 -
		if (!response.ok) {
515 -
			const errorData = await response.json();
516 -
			console.error("Failed to create reply:", errorData);
517 -
			return c.json(
518 -
				{ error: "Failed to create reply", details: errorData },
519 -
				response.status as 400 | 401 | 403 | 500,
520 -
			);
521 -
		}
516 +
// 		if (!response.ok) {
517 +
// 			const errorData = await response.json();
518 +
// 			console.error("Failed to create reply:", errorData);
519 +
// 			return c.json(
520 +
// 				{ error: "Failed to create reply", details: errorData },
521 +
// 				response.status as 400 | 401 | 403 | 500,
522 +
// 			);
523 +
// 		}
522 524
523 -
		const result = (await response.json()) as { uri: string; cid: string };
524 -
		return c.json({ success: true, uri: result.uri, cid: result.cid });
525 -
	} catch (error) {
526 -
		console.error("Error creating reply:", error);
527 -
		return c.json({ error: "Internal server error" }, 500);
528 -
	}
529 -
});
525 +
// 		const result = (await response.json()) as { uri: string; cid: string };
526 +
// 		return c.json({ success: true, uri: result.uri, cid: result.cid });
527 +
// 	} catch (error) {
528 +
// 		console.error("Error creating reply:", error);
529 +
// 		return c.json({ error: "Internal server error" }, 500);
530 +
// 	}
531 +
// });
530 532
531 -
// Get comments for a post via TAP API
532 -
now.get("/comments/:uri", async (c) => {
533 -
	try {
534 -
		const encodedUri = c.req.param("uri");
535 -
		const uri = decodeURIComponent(encodedUri);
533 +
// // Get comments for a post via TAP API
534 +
// now.get("/comments/:uri", async (c) => {
535 +
// 	try {
536 +
// 		const encodedUri = c.req.param("uri");
537 +
// 		const uri = decodeURIComponent(encodedUri);
536 538
537 -
		// First, get the list of comment URIs from TAP API
538 -
		const tapUrl = `https://tap.stevedylan.dev/comments?document=${encodeURIComponent(uri)}`;
539 -
		const response = await fetch(tapUrl);
539 +
// 		// First, get the list of comment URIs from TAP API
540 +
// 		const tapUrl = `https://tap.stevedylan.dev/comments?document=${encodeURIComponent(uri)}`;
541 +
// 		const response = await fetch(tapUrl);
540 542
541 -
		if (!response.ok) {
542 -
			console.error("Failed to fetch comment list from TAP:", response.status);
543 -
			return c.json({ replies: [] });
544 -
		}
543 +
// 		if (!response.ok) {
544 +
// 			console.error("Failed to fetch comment list from TAP:", response.status);
545 +
// 			return c.json({ replies: [] });
546 +
// 		}
545 547
546 -
		interface CommentReference {
547 -
			createdAt: string;
548 -
			did: string;
549 -
			uri: string;
550 -
		}
548 +
// 		interface CommentReference {
549 +
// 			createdAt: string;
550 +
// 			did: string;
551 +
// 			uri: string;
552 +
// 		}
551 553
552 -
		const commentRefs: CommentReference[] = await response.json();
554 +
// 		const commentRefs: CommentReference[] = await response.json();
553 555
554 -
		// Fetch each individual comment using ATProto getRecord
555 -
		const commentPromises = commentRefs.map(async (ref) => {
556 -
			try {
557 -
				// Parse the AT URI: at://did:plc:.../collection/rkey
558 -
				const parts = ref.uri.split("/");
559 -
				const did = parts[2];
560 -
				const collection = parts[3];
561 -
				const rkey = parts[4];
556 +
// 		// Fetch each individual comment using ATProto getRecord
557 +
// 		const commentPromises = commentRefs.map(async (ref) => {
558 +
// 			try {
559 +
// 				// Parse the AT URI: at://did:plc:.../collection/rkey
560 +
// 				const parts = ref.uri.split("/");
561 +
// 				const did = parts[2];
562 +
// 				const collection = parts[3];
563 +
// 				const rkey = parts[4];
562 564
563 -
				// Resolve the DID to find the PDS endpoint
564 -
				const didDoc = (await fetch(`https://plc.directory/${did}`).then((r) =>
565 -
					r.json(),
566 -
				)) as {
567 -
					service?: Array<{ type: string; serviceEndpoint: string }>;
568 -
				};
565 +
// 				// Resolve the DID to find the PDS endpoint
566 +
// 				const didDoc = (await fetch(`https://plc.directory/${did}`).then((r) =>
567 +
// 					r.json(),
568 +
// 				)) as {
569 +
// 					service?: Array<{ type: string; serviceEndpoint: string }>;
570 +
// 				};
569 571
570 -
				// Find the PDS service endpoint
571 -
				const pdsService = didDoc.service?.find(
572 -
					(s) => s.type === "AtprotoPersonalDataServer",
573 -
				);
572 +
// 				// Find the PDS service endpoint
573 +
// 				const pdsService = didDoc.service?.find(
574 +
// 					(s) => s.type === "AtprotoPersonalDataServer",
575 +
// 				);
574 576
575 -
				if (!pdsService?.serviceEndpoint) {
576 -
					console.error(`No PDS found for DID: ${did}`);
577 -
					return null;
578 -
				}
577 +
// 				if (!pdsService?.serviceEndpoint) {
578 +
// 					console.error(`No PDS found for DID: ${did}`);
579 +
// 					return null;
580 +
// 				}
579 581
580 -
				const pdsUrl = pdsService.serviceEndpoint;
582 +
// 				const pdsUrl = pdsService.serviceEndpoint;
581 583
582 -
				// Fetch the record from the user's PDS
583 -
				const getRecordUrl =
584 -
					`${pdsUrl}/xrpc/com.atproto.repo.getRecord?` +
585 -
					new URLSearchParams({
586 -
						repo: did,
587 -
						collection: collection,
588 -
						rkey: rkey,
589 -
					});
584 +
// 				// Fetch the record from the user's PDS
585 +
// 				const getRecordUrl =
586 +
// 					`${pdsUrl}/xrpc/com.atproto.repo.getRecord?` +
587 +
// 					new URLSearchParams({
588 +
// 						repo: did,
589 +
// 						collection: collection,
590 +
// 						rkey: rkey,
591 +
// 					});
590 592
591 -
				const recordResponse = await fetch(getRecordUrl);
592 -
				if (!recordResponse.ok) {
593 -
					console.error(
594 -
						`Failed to fetch comment from PDS ${pdsUrl}: ${ref.uri}`,
595 -
					);
596 -
					return null;
597 -
				}
593 +
// 				const recordResponse = await fetch(getRecordUrl);
594 +
// 				if (!recordResponse.ok) {
595 +
// 					console.error(
596 +
// 						`Failed to fetch comment from PDS ${pdsUrl}: ${ref.uri}`,
597 +
// 					);
598 +
// 					return null;
599 +
// 				}
598 600
599 -
				const data = (await recordResponse.json()) as {
600 -
					value: Record<string, unknown>;
601 -
					cid: string;
602 -
				};
603 -
				return {
604 -
					...data.value,
605 -
					uri: ref.uri,
606 -
					cid: data.cid,
607 -
				};
608 -
			} catch (err) {
609 -
				console.error(`Error fetching comment ${ref.uri}:`, err);
610 -
				return null;
611 -
			}
612 -
		});
601 +
// 				const data = (await recordResponse.json()) as {
602 +
// 					value: Record<string, unknown>;
603 +
// 					cid: string;
604 +
// 				};
605 +
// 				return {
606 +
// 					...data.value,
607 +
// 					uri: ref.uri,
608 +
// 					cid: data.cid,
609 +
// 				};
610 +
// 			} catch (err) {
611 +
// 				console.error(`Error fetching comment ${ref.uri}:`, err);
612 +
// 				return null;
613 +
// 			}
614 +
// 		});
613 615
614 -
		const comments = await Promise.all(commentPromises);
615 -
		const validComments = comments.filter((comment) => comment !== null);
616 +
// 		const comments = await Promise.all(commentPromises);
617 +
// 		const validComments = comments.filter((comment) => comment !== null);
616 618
617 -
		return c.json({ replies: validComments });
618 -
	} catch (error) {
619 -
		console.error("Error fetching comments:", error);
620 -
		return c.json({ replies: [] });
621 -
	}
622 -
});
619 +
// 		return c.json({ replies: validComments });
620 +
// 	} catch (error) {
621 +
// 		console.error("Error fetching comments:", error);
622 +
// 		return c.json({ replies: [] });
623 +
// 	}
624 +
// });
623 625
624 626
export default now;