Browse Source

feat(component): add star button to each comment with login prompt

main
Mohan 1 month ago
parent
commit
fd769d1acc
  1. 58
      src/components/CommentSection.vue

58
src/components/CommentSection.vue

@ -81,6 +81,35 @@ function openForm() {
formOpen.value = true
}
const commentStarBusy = ref<Set<number>>(new Set())
async function toggleCommentStar(comment: CommentResponse) {
if (!localStorage.getItem('token')) {
window.location.href = '/login'
return
}
const id = comment.id!
if (commentStarBusy.value.has(id)) return
commentStarBusy.value = new Set([...commentStarBusy.value, id])
const was = comment.hasStarred ?? false
comment.hasStarred = !was
comment.starCount = (comment.starCount ?? 0) + (was ? -1 : 1)
try {
if (was) {
await commentApi.apiCommentsIdStarDelete(id)
} else {
await commentApi.apiCommentsIdStarPost(id)
}
} catch {
comment.hasStarred = was
comment.starCount = (comment.starCount ?? 0) + (was ? 1 : -1)
} finally {
const next = new Set(commentStarBusy.value)
next.delete(id)
commentStarBusy.value = next
}
}
onMounted(load)
</script>
@ -98,6 +127,12 @@ onMounted(load)
<span class="comment-time">{{ formatDate(comment.createdAt) }}</span>
</div>
<p class="comment-content">{{ comment.content }}</p>
<button class="comment-star" :class="{ starred: comment.hasStarred }" @click="toggleCommentStar(comment)">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14">
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" fill="currentColor"/>
</svg>
<span>{{ comment.starCount ?? 0 }}</span>
</button>
</div>
</article>
</div>
@ -199,6 +234,29 @@ onMounted(load)
word-break: break-word;
}
.comment-star {
display: inline-flex;
align-items: center;
gap: 3px;
margin-top: 6px;
border: none;
background: none;
color: var(--ac-text-disabled);
cursor: pointer;
font-size: 12px;
padding: 2px 6px;
border-radius: var(--song-radius-s);
transition: color var(--song-dur-1) var(--song-ease);
}
.comment-star:hover {
color: var(--ac-primary-ink);
}
.comment-star.starred {
color: var(--ac-primary);
}
.comment-write {
margin-top: 8px;
display: flex;

Loading…
Cancel
Save