|
3 | 3 | import { onMount } from 'svelte'; |
4 | 4 | import type { CupertinoPane } from 'cupertino-pane'; |
5 | 5 | import { Comment, MessageInput } from '$lib/fragments'; |
6 | | - import type { CommentType, userProfile } from '$lib/types'; |
| 6 | + import type { userProfile } from '$lib/types'; |
7 | 7 | import { showComments } from '$lib/store/store.svelte'; |
8 | 8 | import { posts, isLoading, error, fetchFeed, toggleLike } from '$lib/stores/posts'; |
9 | | - import { activePostId } from '$lib/stores/comments'; |
| 9 | + import { activePostId, comments, createComment } from '$lib/stores/comments'; |
10 | 10 | import { apiClient, getAuthId } from '$lib/utils'; |
11 | 11 |
|
12 | 12 | let listElement: HTMLElement; |
13 | 13 | let drawer: CupertinoPane | undefined = $state(); |
14 | 14 | let commentValue: string = $state(''); |
15 | 15 | let commentInput: HTMLInputElement | undefined = $state(); |
16 | | - let _comments = $state<CommentType[]>([]); |
17 | 16 | let activeReplyToId: string | null = $state(null); |
18 | 17 | let followError = $state<string | null>(null); |
19 | 18 | let ownerId: string | null = $state(null); |
20 | 19 | let profile = $state<userProfile | null>(null); |
21 | 20 | let loading = $state(true); |
| 21 | + let isCommentsLoading = $state(false); |
| 22 | + let commentsError = $state<string | null>(null); |
22 | 23 |
|
23 | 24 | const onScroll = () => { |
24 | 25 | if (listElement.scrollTop + listElement.clientHeight >= listElement.scrollHeight) { |
|
27 | 28 | }; |
28 | 29 |
|
29 | 30 | const handleSend = async () => { |
30 | | - const newComment = { |
31 | | - userImgSrc: 'https://www.gravatar.com/avatar/2c7d99fe281ecd3bcd65ab915bac6dd5?s=250', |
32 | | - name: 'You', |
33 | | - commentId: Date.now().toString(), |
34 | | - comment: commentValue, |
35 | | - isUpVoted: false, |
36 | | - isDownVoted: false, |
37 | | - upVotes: 0, |
38 | | - time: 'Just now', |
39 | | - replies: [] |
40 | | - }; |
| 31 | + console.log($activePostId, commentValue); |
| 32 | + if (!$activePostId || !commentValue.trim()) return; |
41 | 33 |
|
42 | | - if (activeReplyToId) { |
43 | | - // Find the parent comment by id and push reply |
44 | | - const addReplyToComment = (commentsArray: CommentType[]) => { |
45 | | - for (const c of commentsArray) { |
46 | | - if (c.commentId === activeReplyToId) { |
47 | | - c.replies.push(newComment); |
48 | | - return true; |
49 | | - } else if (c.replies.length) { |
50 | | - if (addReplyToComment(c.replies)) return true; |
51 | | - } |
52 | | - } |
53 | | - return false; |
54 | | - }; |
55 | | - addReplyToComment(_comments); |
56 | | - } else { |
57 | | - // If no activeReplyToId, add as a new parent comment |
58 | | - _comments = [newComment, ..._comments]; |
| 34 | + try { |
| 35 | + await createComment($activePostId, commentValue); |
| 36 | + commentValue = ''; |
| 37 | + activeReplyToId = null; |
| 38 | + } catch (err) { |
| 39 | + console.error('Failed to create comment:', err); |
59 | 40 | } |
60 | | - commentValue = ''; |
61 | | - activeReplyToId = null; |
62 | 41 | }; |
63 | 42 |
|
64 | 43 | async function handleFollow(profileId: string) { |
|
140 | 119 | </div> |
141 | 120 |
|
142 | 121 | <Drawer bind:drawer> |
143 | | - <ul class="pb-4"> |
144 | | - <h3 class="text-black-600 mb-6 text-center">{_comments.length} Comments</h3> |
145 | | - {#each _comments as comment} |
146 | | - <li class="mb-4"> |
147 | | - <Comment |
148 | | - {comment} |
149 | | - handleReply={() => { |
150 | | - activeReplyToId = comment.commentId; |
151 | | - commentInput?.focus(); |
152 | | - }} |
153 | | - /> |
154 | | - </li> |
155 | | - {/each} |
156 | | - <MessageInput |
157 | | - class="fixed start-0 bottom-4 mt-4 w-full px-5" |
158 | | - variant="comment" |
159 | | - src={profile?.avatarUrl || 'https://picsum.photos/200/200'} |
160 | | - bind:value={commentValue} |
161 | | - {handleSend} |
162 | | - bind:input={commentInput} |
163 | | - /> |
164 | | - </ul> |
| 122 | + {#if showComments.value} |
| 123 | + <ul class="pb-4"> |
| 124 | + <h3 class="text-black-600 mb-6 text-center">{$comments.length} Comments</h3> |
| 125 | + {#if isCommentsLoading} |
| 126 | + <li class="text-center text-gray-500">Loading comments...</li> |
| 127 | + {:else if commentsError} |
| 128 | + <li class="text-center text-red-500">{commentsError}</li> |
| 129 | + {:else} |
| 130 | + {#each $comments as comment} |
| 131 | + <li class="mb-4"> |
| 132 | + <Comment |
| 133 | + comment={{ |
| 134 | + userImgSrc: |
| 135 | + comment.author.avatarUrl || |
| 136 | + 'https://picsum.photos/200/200', |
| 137 | + name: comment.author.name || comment.author.handle, |
| 138 | + commentId: comment.id, |
| 139 | + comment: comment.text, |
| 140 | + isUpVoted: false, |
| 141 | + isDownVoted: false, |
| 142 | + upVotes: 0, |
| 143 | + time: new Date(comment.createdAt).toLocaleDateString(), |
| 144 | + replies: [] |
| 145 | + }} |
| 146 | + handleReply={() => { |
| 147 | + activeReplyToId = comment.id; |
| 148 | + commentInput?.focus(); |
| 149 | + }} |
| 150 | + /> |
| 151 | + </li> |
| 152 | + {/each} |
| 153 | + {/if} |
| 154 | + <MessageInput |
| 155 | + class="sticky start-0 bottom-4 mt-4 w-full px-2" |
| 156 | + variant="comment" |
| 157 | + src={profile?.avatarUrl || 'https://picsum.photos/200/200'} |
| 158 | + bind:value={commentValue} |
| 159 | + {handleSend} |
| 160 | + bind:input={commentInput} |
| 161 | + /> |
| 162 | + </ul> |
| 163 | + {/if} |
165 | 164 | </Drawer> |
0 commit comments