const cardIdentifierPrefix = "test-board-card"; let isExistingCard = false let existingCard = {} document.addEventListener("DOMContentLoaded", async () => { const minterBoardLinks = document.querySelectorAll('a[href="MINTER-BOARD"], a[href="MINTERS"]'); minterBoardLinks.forEach(link => { link.addEventListener("click", async (event) => { event.preventDefault(); if (!userState.isLoggedIn) { await login(); } await loadMinterBoardPage(); }); }); }); async function loadMinterBoardPage() { // Clear existing content on the page const bodyChildren = document.body.children; for (let i = bodyChildren.length - 1; i >= 0; i--) { const child = bodyChildren[i]; if (!child.classList.contains("menu")) { child.remove(); } } // Add the "Minter Board" content const mainContent = document.createElement("div"); mainContent.innerHTML = `
Loading cards...
"; try { const response = await qortalRequest({ action: "SEARCH_QDN_RESOURCES", service: "BLOG_POST", query: cardIdentifierPrefix, }); if (!response || response.length === 0) { cardsContainer.innerHTML = "No cards found.
"; return; } cardsContainer.innerHTML = ""; const pollResultsCache = {}; for (const card of response) { const cardDataResponse = await qortalRequest({ action: "FETCH_QDN_RESOURCE", name: card.name, service: "BLOG_POST", identifier: card.identifier, }); const cardData = cardDataResponse; // Cache poll results if (!pollResultsCache[cardData.poll]) { pollResultsCache[cardData.poll] = await fetchPollResults(cardData.poll); } const pollResults = pollResultsCache[cardData.poll]; const cardHTML = await createCardHTML(cardData, pollResults); cardsContainer.insertAdjacentHTML("beforeend", cardHTML); } } catch (error) { console.error("Error loading cards:", error); cardsContainer.innerHTML = "Failed to load cards.
"; } } const calculatePollResults = (pollData, minterGroupMembers) => { const memberAddresses = minterGroupMembers.map(member => member.member); let adminYes = 0, adminNo = 0, minterYes = 0, minterNo = 0; pollData.votes.forEach(vote => { const voterAddress = vote.voterPublicKey; const isAdmin = minterGroupMembers.some(member => member.member === voterAddress && member.isAdmin); if (vote.optionIndex === 1) { isAdmin ? adminYes++ : memberAddresses.includes(voterAddress) ? minterYes++ : null; } else if (vote.optionIndex === 0) { isAdmin ? adminNo++ : memberAddresses.includes(voterAddress) ? minterNo++ : null; } }); const totalYes = adminYes + minterYes; const totalNo = adminNo + minterNo; return { adminYes, adminNo, minterYes, minterNo, totalYes, totalNo }; }; const postComment = async (cardIdentifier) => { const commentInput = document.getElementById(`new-comment-${cardIdentifier}`); const commentText = commentInput.value.trim(); if (!commentText) { alert('Comment cannot be empty!'); return; } const commentData = { content: commentText, creator: userState.accountName, timestamp: Date.now(), }; const commentIdentifier = `${cardIdentifier}-comment-${await uid()}`; try { const base64CommentData = await objectToBase64(commentData); if (!base64CommentData) { console.log(`initial base64 object creation with objectToBase64 failed, using btoa...`); base64CommentData = btoa(JSON.stringify(commentData)); } // const base64CommentData = btoa(JSON.stringify(commentData)); await qortalRequest({ action: 'PUBLISH_QDN_RESOURCE', name: userState.accountName, service: 'BLOG_POST', identifier: commentIdentifier, data64: base64CommentData, }); alert('Comment posted successfully!'); commentInput.value = ''; // Clear input await displayComments(cardIdentifier); // Refresh comments } catch (error) { console.error('Error posting comment:', error); alert('Failed to post comment.'); } }; const fetchCommentsForCard = async (cardIdentifier) => { try { const response = await qortalRequest({ action: 'SEARCH_QDN_RESOURCES', service: 'BLOG_POST', query: `${cardIdentifier}-comment`, }); return response; } catch (error) { console.error(`Error fetching comments for ${cardIdentifier}:`, error); return []; } }; const displayComments = async (cardIdentifier) => { const comments = await fetchCommentsForCard(cardIdentifier); const commentsContainer = document.getElementById(`comments-container-${cardIdentifier}`); commentsContainer.innerHTML = comments.map(comment => `Loading cards...
"; try { const response = await qortalRequest({ action: "SEARCH_QDN_RESOURCES", service: "BLOG_POST", query: cardIdentifierPrefix, }); if (!response || response.length === 0) { cardsContainer.innerHTML = "No cards found.
"; return; } cardsContainer.innerHTML = ""; const pollResultsCache = {}; for (const card of response) { const cardDataResponse = await qortalRequest({ action: "FETCH_QDN_RESOURCE", name: card.name, service: "BLOG_POST", identifier: card.identifier, }); const cardData = cardDataResponse; // Cache poll results if (!pollResultsCache[cardData.poll]) { pollResultsCache[cardData.poll] = await fetchPollResults(cardData.poll); } const pollResults = pollResultsCache[cardData.poll]; const cardHTML = await createCardHTML(cardData, pollResults); cardsContainer.insertAdjacentHTML("beforeend", cardHTML); } } catch (error) { console.error("Error loading cards:", error); cardsContainer.innerHTML = "Failed to load cards.
"; } } function toggleFullContent(cardIdentifier, fullContent) { const contentPreview = document.getElementById(`content-preview-${cardIdentifier}`); const toggleButton = document.getElementById(`toggle-content-${cardIdentifier}`); const isExpanded = contentPreview.getAttribute("data-expanded") === "true"; if (isExpanded) { // Collapse the content contentPreview.innerText = `${fullContent.substring(0, 150)}...`; toggleButton.innerText = "Display Full Text"; contentPreview.setAttribute("data-expanded", "false"); } else { // Expand the content contentPreview.innerText = fullContent; toggleButton.innerText = "Show Less"; contentPreview.setAttribute("data-expanded", "true"); } } async function createCardHTML(cardData, pollResults) { const { header, content, links, creator, timestamp, poll } = cardData; const formattedDate = new Date(timestamp).toLocaleString(); const linksHTML = links.map((link, index) => ` `).join(""); const minterGroupMembers = await fetchMinterGroupMembers(); const { adminYes, adminNo, minterYes, minterNo, totalYes, totalNo } = calculatePollResults(pollResults, minterGroupMembers); const trimmedContent = content.length > 150 ? `${content.substring(0, 150)}...` : content; return `${header}
Published by: ${creator} on ${formattedDate}
${comment.creator}:
${comment.content}
${timestampToHumanReadableDate(comment.timestamp)}