fix: Remove old cycling vote handler, skip if already voted same way

- Remove old truthBadge click handler that cycled through votes
- Add check to skip vote if already voted that way (no double-click bug)
- Fetch initial vote state and show active button
- Update button styles to show current vote

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Your Name 2026-01-19 21:29:11 +00:00
parent 59019f493f
commit 471d5ab544
2 changed files with 29 additions and 61 deletions

View File

@ -1,7 +1,7 @@
{ {
"name": "sociowire-frontend", "name": "sociowire-frontend",
"private": true, "private": true,
"version": "0.0.65", "version": "0.0.66",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite --host 0.0.0.0", "dev": "vite --host 0.0.0.0",

View File

@ -1874,6 +1874,17 @@ export function openCenteredOverlay({ map, post, theme, fullScreen = false }) {
let currentVote = null; let currentVote = null;
let isVoting = false; let isVoting = false;
const updateButtonStyles = () => {
if (upvoteBtn) {
upvoteBtn.style.background = currentVote === 'true' ? 'rgba(52, 211, 153, 0.5)' : 'rgba(52, 211, 153, 0.15)';
upvoteBtn.style.borderColor = currentVote === 'true' ? 'rgba(52, 211, 153, 0.8)' : 'rgba(52, 211, 153, 0.4)';
}
if (downvoteBtn) {
downvoteBtn.style.background = currentVote === 'false' ? 'rgba(239, 68, 68, 0.5)' : 'rgba(239, 68, 68, 0.15)';
downvoteBtn.style.borderColor = currentVote === 'false' ? 'rgba(239, 68, 68, 0.8)' : 'rgba(239, 68, 68, 0.4)';
}
};
const updateTruthUI = (newScore) => { const updateTruthUI = (newScore) => {
if (scoreDisplay && Number.isFinite(newScore)) { if (scoreDisplay && Number.isFinite(newScore)) {
const score = Math.round(newScore); const score = Math.round(newScore);
@ -1887,16 +1898,16 @@ export function openCenteredOverlay({ map, post, theme, fullScreen = false }) {
requestAuth("Please sign in or create a free account to vote on truth."); requestAuth("Please sign in or create a free account to vote on truth.");
return; return;
} }
// Skip if already voted this way
if (currentVote === vote) return;
if (isVoting) return; if (isVoting) return;
isVoting = true; isVoting = true;
// Visual feedback // Visual feedback
if (vote === 'true' && upvoteBtn) { if (vote === 'true' && upvoteBtn) {
upvoteBtn.style.transform = 'scale(1.2)'; upvoteBtn.style.transform = 'scale(1.2)';
upvoteBtn.style.background = 'rgba(52, 211, 153, 0.5)';
} else if (vote === 'false' && downvoteBtn) { } else if (vote === 'false' && downvoteBtn) {
downvoteBtn.style.transform = 'scale(1.2)'; downvoteBtn.style.transform = 'scale(1.2)';
downvoteBtn.style.background = 'rgba(239, 68, 68, 0.5)';
} }
try { try {
@ -1904,6 +1915,7 @@ export function openCenteredOverlay({ map, post, theme, fullScreen = false }) {
const stats = await votePostTruth(postID, vote); const stats = await votePostTruth(postID, vote);
if (stats) { if (stats) {
currentVote = vote; currentVote = vote;
updateButtonStyles();
if (stats.truth_score !== null && Number.isFinite(stats.truth_score)) { if (stats.truth_score !== null && Number.isFinite(stats.truth_score)) {
updateTruthUI(stats.truth_score); updateTruthUI(stats.truth_score);
} }
@ -1912,20 +1924,24 @@ export function openCenteredOverlay({ map, post, theme, fullScreen = false }) {
console.error('Truth vote error:', err); console.error('Truth vote error:', err);
} }
// Reset button visuals // Reset transform
setTimeout(() => { setTimeout(() => {
if (upvoteBtn) { if (upvoteBtn) upvoteBtn.style.transform = '';
upvoteBtn.style.transform = ''; if (downvoteBtn) downvoteBtn.style.transform = '';
upvoteBtn.style.background = currentVote === 'true' ? 'rgba(52, 211, 153, 0.4)' : 'rgba(52, 211, 153, 0.15)';
}
if (downvoteBtn) {
downvoteBtn.style.transform = '';
downvoteBtn.style.background = currentVote === 'false' ? 'rgba(239, 68, 68, 0.4)' : 'rgba(239, 68, 68, 0.15)';
}
isVoting = false; isVoting = false;
}, 200); }, 200);
}; };
// Fetch initial vote state
if (isAuthed()) {
fetchPostTruth(postID).then((stats) => {
if (stats?.user_vote) {
currentVote = stats.user_vote.toString();
updateButtonStyles();
}
}).catch(() => {});
}
if (downvoteBtn) { if (downvoteBtn) {
downvoteBtn.addEventListener('click', (e) => { downvoteBtn.addEventListener('click', (e) => {
e.stopPropagation(); e.stopPropagation();
@ -2182,55 +2198,7 @@ export function openCenteredOverlay({ map, post, theme, fullScreen = false }) {
}); });
} }
const truthBadge = modalWrap.querySelector(".sw-truth-badge"); // Old badge click handler removed - using thumbs up/down buttons instead
if (truthBadge && postID > 0 && !truthBadge.hasAttribute("data-vote-bound")) {
truthBadge.setAttribute("data-vote-bound", "1");
let currentVote = null;
let isVoting = false;
const doVote = async (vote) => {
if (!isAuthed()) {
requestAuth("Please sign in or create a free account to vote on truth.");
return;
}
if (currentVote === vote || isVoting) return;
isVoting = true;
truthBadge.style.opacity = "0.5";
try {
const stats = await votePostTruth(postID, vote);
if (stats) {
currentVote = vote;
// Update badge score display
const scoreEl = truthBadge.querySelector(".sw-truth-badge-score");
if (scoreEl && stats.truth_score !== null && Number.isFinite(stats.truth_score)) {
const newScore = Math.round(stats.truth_score);
scoreEl.textContent = String(newScore);
scoreEl.style.background = truthColor(newScore);
}
}
} catch {}
isVoting = false;
truthBadge.style.opacity = "1";
};
// Click on badge cycles vote: none -> true -> false -> none
truthBadge.style.cursor = "pointer";
truthBadge.addEventListener("click", (e) => {
e.stopPropagation();
if (currentVote === null) doVote("true");
else if (currentVote === "true") doVote("false");
else doVote("true"); // Toggle back
});
// Fetch initial vote state
if (isAuthed()) {
fetchPostTruth(postID).then((stats) => {
if (stats?.user_vote || stats?.UserVote) {
currentVote = (stats.user_vote || stats.UserVote).toString();
}
}).catch(() => {});
}
}
applyAuthUI(); applyAuthUI();
const onAuth = () => { const onAuth = () => {