27
28### POST /api/likes
29Fetches a user's likes, with optional search filtering.
30
31**Request Body:**
75 useEffect(() => {
76 if (isLoggedIn && sessionToken) {
77 fetchLikes(true);
78 }
79 }, [isLoggedIn, sessionToken]);
94 setCursor(undefined);
95 setHasMore(true);
96 fetchLikes(true);
97 }
98 }, [debouncedSearchQuery]);
104
105 try {
106 const response = await fetch("/api/login", {
107 method: "POST",
108 headers: {
138 };
139
140 const fetchLikes = async (reset = false) => {
141 if (isLoading || !sessionToken) return;
142
145
146 try {
147 const response = await fetch("/api/likes", {
148 method: "POST",
149 headers: {
172 setHasMore(!!data.cursor);
173 } else {
174 setError(data.error || "Failed to fetch likes");
175 }
176 } catch (err) {
185 try {
186 // Call logout API to clear session on server
187 await fetch("/api/logout", {
188 method: "POST",
189 headers: {
220
221 if (scrollTop + clientHeight >= scrollHeight - 100) {
222 fetchLikes();
223 }
224 }, [isLoading, hasMore, cursor, sessionToken]);
88
89// This is the entry point for HTTP vals
90export default app.fetch;
81
82 // Load tasks on page load
83 document.addEventListener('DOMContentLoaded', fetchTasks);
84
85 // Add task form submission
91
92 try {
93 const response = await fetch(API_URL, {
94 method: 'POST',
95 headers: {
113 });
114
115 // Fetch all tasks
116 async function fetchTasks() {
117 try {
118 const response = await fetch(API_URL);
119
120 if (!response.ok) {
121 throw new Error('Failed to fetch tasks');
122 }
123
135 }
136 } catch (error) {
137 console.error('Error fetching tasks:', error);
138 alert('Failed to load tasks. Please refresh the page.');
139 }
176 async function toggleTaskStatus(taskId, completed) {
177 try {
178 const response = await fetch(`${API_URL}/${taskId}`, {
179 method: 'PUT',
180 headers: {
213
214 try {
215 const response = await fetch(`${API_URL}/${taskId}`, {
216 method: 'DELETE'
217 });
83});
84
85// API endpoint to fetch user likes
86app.post("/api/likes", async c => {
87 try {
108 });
109
110 // Fetch likes
111 const likesResponse = await agent.getLikes({
112 actor: sessionData.did,
139 });
140 } catch (error) {
141 console.error("Fetch likes error:", error);
142 return c.json({
143 success: false,
173
174// Export the Hono app for HTTP vals
175export default app.fetch;
50 files={project.data?.files}
51 branchId={branchId}
52 refetch={project.refetch}
53 />
54 </ProjectContext>
60 files,
61 branchId,
62 refetch,
63}: {
64 project: any;
65 files: any[];
66 branchId: string;
67 refetch: () => void;
68}) {
69 const [images, setImages] = useState<(string|null)[]>([]);
94 if (!messages?.length) return;
95 let last = messages.at(-1);
96 if (shouldRefetch(last)) {
97 refetch();
98 }
99 }, [messages]);
177}
178
179function shouldRefetch (message) {
180 for (let i = 0; i < message?.parts?.length; i++) {
181 let part = message.parts[i];
44 files={project.data?.files}
45 branchId={branchId}
46 refetch={project.refetch}
47 />
48 </>
54 files,
55 branchId,
56 refetch,
57}: {
58 project: any;
59 files: any[];
60 branchId: string;
61 refetch: () => void;
62}) {
63 const [images, setImages] = useState<(string | null)[]>([]);
88 if (!messages?.length) return;
89 let last = messages.at(-1);
90 if (shouldRefetch(last)) {
91 refetch();
92 }
93 }, [messages]);
163}
164
165function shouldRefetch(message) {
166 for (let i = 0; i < message?.parts?.length; i++) {
167 let part = message.parts[i];
170 case "str_replace_editor":
171 if (part.toolInvocation?.args?.command === "create") {
172 // console.log("REFETCH (create)");
173 return true;
174 }
176 case "delete_file":
177 case "change_val_type":
178 // console.log("REFETCH (change type or delete)");
179 return true;
180 }
32 return;
33 }
34 branches.refetch();
35 if (res?.branch?.id) {
36 navigate(`/chat/${projectId}/branch/${res.branch.id}`);
206});
207
208export default app.fetch;
209
18## Implementation Details
19
20The frontend is built with React and uses the Twind library for styling (Tailwind CSS in JS). It communicates with the backend API to authenticate users and fetch their liked posts from Bluesky.
21
22The application processes post text to make mentions and links clickable, and displays images when available.