feat(nostr-feed): Add submission voting with persistence

- Implement downvote() for submissions using dislikeEvent
- Add refreshAllSubmissionVotes() to update all votes after EOSE
- Refresh submission votes after loading reactions in both subscribe methods
- Fixes vote state not displaying correctly on page load

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Patrick Mulligan 2026-01-01 20:31:13 +01:00
parent fa93cc56ba
commit afdab94beb

View file

@ -148,6 +148,8 @@ export class SubmissionService extends BaseService {
onEvent: (event: NostrEvent) => this.handleEvent(event), onEvent: (event: NostrEvent) => this.handleEvent(event),
onEose: () => { onEose: () => {
this.debug('End of stored events') this.debug('End of stored events')
// Refresh all submission votes from loaded reactions
this.refreshAllSubmissionVotes()
this._isLoading.value = false this._isLoading.value = false
}, },
onClose: () => { onClose: () => {
@ -229,6 +231,8 @@ export class SubmissionService extends BaseService {
onEvent: (event: NostrEvent) => this.handleEvent(event), onEvent: (event: NostrEvent) => this.handleEvent(event),
onEose: () => { onEose: () => {
this.debug('End of stored events for submission') this.debug('End of stored events for submission')
// Refresh submission votes from loaded reactions
this.refreshSubmissionVotes(submissionId)
// After loading comments, fetch their reactions // After loading comments, fetch their reactions
this.fetchCommentReactions(submissionId) this.fetchCommentReactions(submissionId)
this._isLoading.value = false this._isLoading.value = false
@ -907,12 +911,23 @@ export class SubmissionService extends BaseService {
* Downvote a submission * Downvote a submission
*/ */
async downvote(submissionId: string): Promise<void> { async downvote(submissionId: string): Promise<void> {
// TODO: Implement downvote using '-' reaction content
// For now, this is a placeholder that mirrors the upvote logic
const submission = this._submissions.get(submissionId) const submission = this._submissions.get(submissionId)
if (!submission) throw new Error('Submission not found') if (!submission) throw new Error('Submission not found')
this.debug('Downvote not yet implemented') if (submission.votes.userVote === 'downvote') {
// Remove downvote
await this.reactionService?.undislikeEvent(submissionId)
} else {
// Add downvote (ReactionService keeps only latest reaction per user)
await this.reactionService?.dislikeEvent(
submissionId,
submission.pubkey,
SUBMISSION_KINDS.SUBMISSION
)
}
// Refresh votes
this.refreshSubmissionVotes(submissionId)
} }
/** /**
@ -926,6 +941,15 @@ export class SubmissionService extends BaseService {
submission.ranking = this.calculateRanking(submission, submission.votes) submission.ranking = this.calculateRanking(submission, submission.votes)
} }
/**
* Refresh votes for all submissions
*/
private refreshAllSubmissionVotes(): void {
for (const submissionId of this._submissions.keys()) {
this.refreshSubmissionVotes(submissionId)
}
}
/** /**
* Upvote a comment * Upvote a comment
*/ */