diff --git a/chat.db b/chat.db
index bf0161f..23b1d02 100644
Binary files a/chat.db and b/chat.db differ
diff --git a/index.html b/index.html
index a1850b9..11a8663 100644
--- a/index.html
+++ b/index.html
@@ -523,7 +523,6 @@
let pollInterval = null;
let selectedGifUrl = null;
let votedPolls = new Set();
- let pollsData = [];
function loadVotedPolls() {
try {
@@ -711,7 +710,7 @@
if (data.success) {
showToast('Poll created!', 'success');
pollModal.classList.remove('open');
- loadPolls();
+ loadMessages();
} else {
showToast(data.error || 'Failed to create poll', 'error');
}
@@ -745,57 +744,6 @@
renderChannels();
messagesEl.innerHTML = '
Loading...
';
loadMessages();
- loadPolls();
- }
-
- async function loadPolls() {
- try {
- const r = await fetch(`/api/polls?channel=${currentChannel}`);
- const data = await r.json();
- if (data.success) pollsData = data.polls || [];
- else pollsData = [];
- } catch (e) {
- pollsData = [];
- }
- }
-
- function renderPolls() {
- if (!pollsData.length) return '';
- let html = '';
- pollsData.forEach(poll => {
- const isClosed = poll.status === 'closed';
- const isExpired = poll.expires_at && Date.now() > poll.expires_at;
- const hasVoted = votedPolls.has(poll.id) || poll.options.some(o => o.votes > 0 && false);
- const total = poll.total_votes || 0;
- let optionsHtml = '';
- poll.options.forEach(opt => {
- const pct = total > 0 ? Math.round((opt.votes / total) * 100) : 0;
- const votedClass = hasVoted ? ' voted' : '';
- if (isClosed || isExpired || hasVoted) {
- optionsHtml += `
-
-
${escapeHtml(opt.label)}
-
${pct}%
-
${opt.votes}
-
`;
- } else {
- optionsHtml += `
- ${escapeHtml(opt.label)}
- ${opt.votes} votes
-
`;
- }
- });
- const statusLabel = isClosed || poll.status === 'closed' ? 'Closed' :
- isExpired ? 'Expired' : 'Active';
- const statusClass = isClosed || isExpired ? 'closed' : 'active';
- const creatorLabel = poll.is_anonymous ? 'Anonymous' : escapeHtml(poll.creator_ip);
- html += `
-
๐ ${escapeHtml(poll.question)}
-
by ${creatorLabel} ยท ${total} vote${total !== 1 ? 's' : ''} ยท ${statusLabel}
-
${optionsHtml}
-
`;
- });
- return html;
}
async function loadMessages() {
@@ -813,28 +761,61 @@
}
function renderMessages(msgs) {
- const pollsHtml = renderPolls();
- if (msgs.length === 0 && !pollsHtml) {
+ if (msgs.length === 0) {
messagesEl.innerHTML = '๐ฌ No messages yet. Be the first!
';
return;
}
- let html = pollsHtml;
+ let html = '';
msgs.forEach(msg => {
- const time = new Date(msg.timestamp).toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' });
- let contentHtml = escapeHtml(msg.content || '');
- let gifToShow = msg.gif_url || null;
- if (!gifToShow) {
- const gifMatch = msg.content.match(/https?:\/\/[^\s]+\.(gif|webp)(\?[^\s]*)?/i);
- if (gifMatch) gifToShow = gifMatch[0];
+ if (msg.poll) {
+ const poll = msg.poll;
+ const isClosed = poll.status === 'closed';
+ const isExpired = poll.expires_at && Date.now() > poll.expires_at;
+ const hasVoted = votedPolls.has(poll.id);
+ const total = poll.total_votes || 0;
+ let optionsHtml = '';
+ poll.options.forEach(opt => {
+ const pct = total > 0 ? Math.round((opt.votes / total) * 100) : 0;
+ const votedClass = hasVoted ? ' voted' : '';
+ if (isClosed || isExpired || hasVoted) {
+ optionsHtml += `
+
+
${escapeHtml(opt.label)}
+
${pct}%
+
${opt.votes}
+
`;
+ } else {
+ optionsHtml += `
+ ${escapeHtml(opt.label)}
+ ${opt.votes} votes
+
`;
+ }
+ });
+ const statusLabel = isClosed ? 'Closed' : isExpired ? 'Expired' : 'Active';
+ const statusClass = isClosed || isExpired ? 'closed' : 'active';
+ const creatorLabel = poll.is_anonymous ? 'Anonymous' : escapeHtml(poll.creator_ip);
+ html += `
+
๐ ${escapeHtml(poll.question)}
+
by ${creatorLabel} ยท ${total} vote${total !== 1 ? 's' : ''} ยท ${statusLabel}
+
${optionsHtml}
+
`;
+ } else {
+ const time = new Date(msg.timestamp).toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit' });
+ let contentHtml = escapeHtml(msg.content || '');
+ let gifToShow = msg.gif_url || null;
+ if (!gifToShow) {
+ const gifMatch = msg.content.match(/https?:\/\/[^\s]+\.(gif|webp)(\?[^\s]*)?/i);
+ if (gifMatch) gifToShow = gifMatch[0];
+ }
+ if (gifToShow) {
+ contentHtml += `
`;
+ }
+ html += `
+
๐ ${escapeHtml(msg.ip)}
+
${contentHtml}
+
${time}
+
`;
}
- if (gifToShow) {
- contentHtml += `
`;
- }
- html += `
-
๐ ${escapeHtml(msg.ip)}
-
${contentHtml}
-
${time}
-
`;
});
messagesEl.innerHTML = html;
attachPollHandlers();
@@ -859,10 +840,10 @@
votedPolls.add(pollId);
saveVotedPolls();
showToast('Vote recorded!', 'success');
- loadPolls().then(() => renderMessages(window._lastMessages || []));
+ loadMessages();
} else {
showToast(data.error || 'Failed to vote', 'error');
- loadPolls().then(() => renderMessages(window._lastMessages || []));
+ loadMessages();
}
} catch (e) {
showToast('Network error', 'error');
@@ -904,17 +885,13 @@
loadVotedPolls();
renderChannels();
loadMessages();
- loadPolls();
sendBtn.addEventListener('click', sendMessage);
inputEl.addEventListener('keydown', e => { if (e.key === 'Enter') sendMessage(); });
- // Auto-poll every 3 seconds
+ // Auto-refresh every 3 seconds
setInterval(() => {
loadMessages();
- loadPolls().then(() => {
- if (window._lastMessages) renderMessages(window._lastMessages);
- });
}, 3000);