diff --git a/assets/js/MinterBoard.js b/assets/js/MinterBoard.js index 2be1819..aa71a94 100644 --- a/assets/js/MinterBoard.js +++ b/assets/js/MinterBoard.js @@ -745,236 +745,6 @@ const publishCard = async (cardIdentifierPrefix) => { } } -let globalVoterMap = new Map() - -const processPollData= async (pollData, minterGroupMembers, minterAdmins, creator, cardIdentifier) => { - if (!pollData || !Array.isArray(pollData.voteWeights) || !Array.isArray(pollData.votes)) { - console.warn("Poll data is missing or invalid. pollData:", pollData) - return { - adminYes: 0, - adminNo: 0, - minterYes: 0, - minterNo: 0, - totalYes: 0, - totalNo: 0, - totalYesWeight: 0, - totalNoWeight: 0, - detailsHtml: `

Poll data is invalid or missing.

`, - userVote: null - } - } - - const memberAddresses = minterGroupMembers.map(m => m.member) - const minterAdminAddresses = minterAdmins.map(m => m.member) - const adminGroupsMembers = await fetchAllAdminGroupsMembers() - const featureTriggerPassed = await featureTriggerCheck() - const groupAdminAddresses = adminGroupsMembers.map(m => m.member) - let adminAddresses = [...minterAdminAddresses] - - if (!featureTriggerPassed) { - console.log(`featureTrigger is NOT passed, only showing admin results from Minter Admins and Group Admins`) - adminAddresses = [...minterAdminAddresses, ...groupAdminAddresses] - } - - let adminYes = 0, adminNo = 0 - let minterYes = 0, minterNo = 0 - let yesWeight = 0, noWeight = 0 - let userVote = null - - for (const w of pollData.voteWeights) { - if (w.optionName.toLowerCase() === 'yes') { - yesWeight = w.voteWeight - } else if (w.optionName.toLowerCase() === 'no') { - noWeight = w.voteWeight - } - } - - const voterPromises = pollData.votes.map(async (vote) => { - const optionIndex = vote.optionIndex; // 0 => yes, 1 => no - const voterPublicKey = vote.voterPublicKey - const voterAddress = await getAddressFromPublicKey(voterPublicKey) - - if (voterAddress === userState.accountAddress) { - userVote = optionIndex - } - - if (optionIndex === 0) { - if (adminAddresses.includes(voterAddress)) { - adminYes++ - } else if (memberAddresses.includes(voterAddress)) { - minterYes++ - } else { - console.log(`voter ${voterAddress} is not a minter nor an admin... Not included in aggregates.`) - } - } else if (optionIndex === 1) { - if (adminAddresses.includes(voterAddress)) { - adminNo++ - } else if (memberAddresses.includes(voterAddress)) { - minterNo++ - } else { - console.log(`voter ${voterAddress} is not a minter nor an admin... Not included in aggregates.`) - } - } - - let voterName = '' - try { - const nameInfo = await getNameFromAddress(voterAddress) - if (nameInfo) { - voterName = nameInfo - if (nameInfo === voterAddress) voterName = '' - } - } catch (err) { - console.warn(`No name for address ${voterAddress}`, err) - } - - let blocksMinted = 0 - try { - const addressInfo = await getAddressInfo(voterAddress) - blocksMinted = addressInfo?.blocksMinted || 0 - } catch (e) { - console.warn(`Failed to get addressInfo for ${voterAddress}`, e) - } - const isAdmin = adminAddresses.includes(voterAddress) - const isMinter = memberAddresses.includes(voterAddress) - - return { - optionIndex, - voterPublicKey, - voterAddress, - voterName, - isAdmin, - isMinter, - blocksMinted - } - }) - - const allVoters = await Promise.all(voterPromises) - const yesVoters = [] - const noVoters = [] - let totalMinterAndAdminYesWeight = 0 - let totalMinterAndAdminNoWeight = 0 - - for (const v of allVoters) { - if (v.optionIndex === 0) { - yesVoters.push(v) - totalMinterAndAdminYesWeight+=v.blocksMinted - } else if (v.optionIndex === 1) { - noVoters.push(v) - totalMinterAndAdminNoWeight+=v.blocksMinted - } - } - - yesVoters.sort((a,b) => b.blocksMinted - a.blocksMinted) - noVoters.sort((a,b) => b.blocksMinted - a.blocksMinted) - const sortedAllVoters = allVoters.sort((a,b) => b.blocksMinted - a.blocksMinted) - await createVoterMap(sortedAllVoters, cardIdentifier) - - const yesTableHtml = buildVotersTableHtml(yesVoters, /* tableColor= */ "green") - const noTableHtml = buildVotersTableHtml(noVoters, /* tableColor= */ "red") - const detailsHtml = ` -
-

${creator}'s

Support Poll Result Details

-

Yes Vote Details

- ${yesTableHtml} -

No Vote Details

- ${noTableHtml} -
- ` - const totalYes = adminYes + minterYes - const totalNo = adminNo + minterNo - - return { - adminYes, - adminNo, - minterYes, - minterNo, - totalYes, - totalNo, - totalYesWeight: totalMinterAndAdminYesWeight, - totalNoWeight: totalMinterAndAdminNoWeight, - detailsHtml, - userVote - } -} - -const createVoterMap = async (voters, cardIdentifier) => { - const voterMap = new Map() - voters.forEach((voter) => { - const voterNameOrAddress = voter.voterName || voter.voterAddress - voterMap.set(voterNameOrAddress, { - vote: voter.optionIndex === 0 ? "yes" : "no", // Use optionIndex directly - voterType: voter.isAdmin ? "Admin" : voter.isMinter ? "Minter" : "User", - blocksMinted: voter.blocksMinted, - }) - }) - globalVoterMap.set(cardIdentifier, voterMap) -} - -const buildVotersTableHtml = (voters, tableColor) => { - if (!voters.length) { - return `

No voters here.

` - } - - // Decide extremely dark background for the - let bodyBackground - if (tableColor === "green") { - bodyBackground = "rgba(0, 18, 0, 0.8)" // near-black green - } else if (tableColor === "red") { - bodyBackground = "rgba(30, 0, 0, 0.8)" // near-black red - } else { - // fallback color if needed - bodyBackground = "rgba(40, 20, 10, 0.8)" - } - - // tableColor is used for the , bodyBackground for the - const minterColor = 'rgb(98, 122, 167)' - const adminColor = 'rgb(44, 209, 151)' - const userColor = 'rgb(102, 102, 102)' - return ` - - - - - - - - - - - - ${voters - .map(v => { - const userType = v.isAdmin ? "Admin" : v.isMinter ? "Minter" : "User" - const pollName = v.pollName - const displayName = - v.voterName - ? v.voterName - : v.voterAddress - return ` - - - - - - ` - }) - .join("")} - -
Voter Name/AddressVoter TypeVoter Weight(=BlocksMinted)
${displayName}${userType}${v.blocksMinted}
- ` -} - - // Post a comment on a card. --------------------------------- const postComment = async (cardIdentifier) => { const commentInput = document.getElementById(`new-comment-${cardIdentifier}`) @@ -1345,20 +1115,6 @@ const createInviteButtonHtml = (creator, cardIdentifier) => { ` } -const featureTriggerCheck = async () => { - const latestBlockInfo = await getLatestBlockInfo() - const isBlockPassed = latestBlockInfo.height >= GROUP_APPROVAL_FEATURE_TRIGGER_HEIGHT - if (isBlockPassed) { - console.warn(`featureTrigger check (verifyFeatureTrigger) determined block has PASSED:`, isBlockPassed) - featureTriggerPassed = true - return true - } else { - console.warn(`featureTrigger check (verifyFeatureTrigger) determined block has NOT PASSED:`, isBlockPassed) - featureTriggerPassed = false - return false - } -} - const checkAndDisplayInviteButton = async (adminYes, creator, cardIdentifier) => { const isSomeTypaAdmin = userState.isAdmin || userState.isMinterAdmin const isBlockPassed = await featureTriggerCheck() diff --git a/assets/js/Shared.js b/assets/js/Shared.js index 996e440..faadfcc 100644 --- a/assets/js/Shared.js +++ b/assets/js/Shared.js @@ -315,3 +315,246 @@ const applyVoteSortingData = async (cards, ascending = true) => { }) } } + +let globalVoterMap = new Map() + +const processPollData= async (pollData, minterGroupMembers, minterAdmins, creator, cardIdentifier) => { + if (!pollData || !Array.isArray(pollData.voteWeights) || !Array.isArray(pollData.votes)) { + console.warn("Poll data is missing or invalid. pollData:", pollData) + return { + adminYes: 0, + adminNo: 0, + minterYes: 0, + minterNo: 0, + totalYes: 0, + totalNo: 0, + totalYesWeight: 0, + totalNoWeight: 0, + detailsHtml: `

Poll data is invalid or missing.

`, + userVote: null + } + } + + const memberAddresses = minterGroupMembers.map(m => m.member) + const minterAdminAddresses = minterAdmins.map(m => m.member) + const adminGroupsMembers = await fetchAllAdminGroupsMembers() + const featureTriggerPassed = await featureTriggerCheck() + const groupAdminAddresses = adminGroupsMembers.map(m => m.member) + let adminAddresses = [...minterAdminAddresses] + + if (!featureTriggerPassed) { + console.log(`featureTrigger is NOT passed, only showing admin results from Minter Admins and Group Admins`) + adminAddresses = [...minterAdminAddresses, ...groupAdminAddresses] + } + + let adminYes = 0, adminNo = 0 + let minterYes = 0, minterNo = 0 + let yesWeight = 0, noWeight = 0 + let userVote = null + + for (const w of pollData.voteWeights) { + if (w.optionName.toLowerCase() === 'yes') { + yesWeight = w.voteWeight + } else if (w.optionName.toLowerCase() === 'no') { + noWeight = w.voteWeight + } + } + + const voterPromises = pollData.votes.map(async (vote) => { + const optionIndex = vote.optionIndex; // 0 => yes, 1 => no + const voterPublicKey = vote.voterPublicKey + const voterAddress = await getAddressFromPublicKey(voterPublicKey) + + if (voterAddress === userState.accountAddress) { + userVote = optionIndex + } + + if (optionIndex === 0) { + if (adminAddresses.includes(voterAddress)) { + adminYes++ + } else if (memberAddresses.includes(voterAddress)) { + minterYes++ + } else { + console.log(`voter ${voterAddress} is not a minter nor an admin... Not included in aggregates.`) + } + } else if (optionIndex === 1) { + if (adminAddresses.includes(voterAddress)) { + adminNo++ + } else if (memberAddresses.includes(voterAddress)) { + minterNo++ + } else { + console.log(`voter ${voterAddress} is not a minter nor an admin... Not included in aggregates.`) + } + } + + let voterName = '' + try { + const nameInfo = await getNameFromAddress(voterAddress) + if (nameInfo) { + voterName = nameInfo + if (nameInfo === voterAddress) voterName = '' + } + } catch (err) { + console.warn(`No name for address ${voterAddress}`, err) + } + + let blocksMinted = 0 + try { + const addressInfo = await getAddressInfo(voterAddress) + blocksMinted = addressInfo?.blocksMinted || 0 + } catch (e) { + console.warn(`Failed to get addressInfo for ${voterAddress}`, e) + } + const isAdmin = adminAddresses.includes(voterAddress) + const isMinter = memberAddresses.includes(voterAddress) + + return { + optionIndex, + voterPublicKey, + voterAddress, + voterName, + isAdmin, + isMinter, + blocksMinted + } + }) + + const allVoters = await Promise.all(voterPromises) + const yesVoters = [] + const noVoters = [] + let totalMinterAndAdminYesWeight = 0 + let totalMinterAndAdminNoWeight = 0 + + for (const v of allVoters) { + if (v.optionIndex === 0) { + yesVoters.push(v) + totalMinterAndAdminYesWeight+=v.blocksMinted + } else if (v.optionIndex === 1) { + noVoters.push(v) + totalMinterAndAdminNoWeight+=v.blocksMinted + } + } + + yesVoters.sort((a,b) => b.blocksMinted - a.blocksMinted) + noVoters.sort((a,b) => b.blocksMinted - a.blocksMinted) + const sortedAllVoters = allVoters.sort((a,b) => b.blocksMinted - a.blocksMinted) + await createVoterMap(sortedAllVoters, cardIdentifier) + + const yesTableHtml = buildVotersTableHtml(yesVoters, /* tableColor= */ "green") + const noTableHtml = buildVotersTableHtml(noVoters, /* tableColor= */ "red") + const detailsHtml = ` +
+

${creator}'s

Support Poll Result Details

+

Yes Vote Details

+ ${yesTableHtml} +

No Vote Details

+ ${noTableHtml} +
+ ` + const totalYes = adminYes + minterYes + const totalNo = adminNo + minterNo + + return { + adminYes, + adminNo, + minterYes, + minterNo, + totalYes, + totalNo, + totalYesWeight: totalMinterAndAdminYesWeight, + totalNoWeight: totalMinterAndAdminNoWeight, + detailsHtml, + userVote + } +} + +const createVoterMap = async (voters, cardIdentifier) => { + const voterMap = new Map() + voters.forEach((voter) => { + const voterNameOrAddress = voter.voterName || voter.voterAddress + voterMap.set(voterNameOrAddress, { + vote: voter.optionIndex === 0 ? "yes" : "no", // Use optionIndex directly + voterType: voter.isAdmin ? "Admin" : voter.isMinter ? "Minter" : "User", + blocksMinted: voter.blocksMinted, + }) + }) + globalVoterMap.set(cardIdentifier, voterMap) +} + +const buildVotersTableHtml = (voters, tableColor) => { + if (!voters.length) { + return `

No voters here.

` + } + + // Decide extremely dark background for the + let bodyBackground + if (tableColor === "green") { + bodyBackground = "rgba(0, 18, 0, 0.8)" // near-black green + } else if (tableColor === "red") { + bodyBackground = "rgba(30, 0, 0, 0.8)" // near-black red + } else { + // fallback color if needed + bodyBackground = "rgba(40, 20, 10, 0.8)" + } + + // tableColor is used for the , bodyBackground for the + const minterColor = 'rgb(98, 122, 167)' + const adminColor = 'rgb(44, 209, 151)' + const userColor = 'rgb(102, 102, 102)' + return ` + + + + + + + + + + + + ${voters + .map(v => { + const userType = v.isAdmin ? "Admin" : v.isMinter ? "Minter" : "User" + const pollName = v.pollName + const displayName = + v.voterName + ? v.voterName + : v.voterAddress + return ` + + + + + + ` + }) + .join("")} + +
Voter Name/AddressVoter TypeVoter Weight(=BlocksMinted)
${displayName}${userType}${v.blocksMinted}
+ ` +} + +const featureTriggerCheck = async () => { + const latestBlockInfo = await getLatestBlockInfo() + const isBlockPassed = latestBlockInfo.height >= GROUP_APPROVAL_FEATURE_TRIGGER_HEIGHT + if (isBlockPassed) { + console.warn(`featureTrigger check (verifyFeatureTrigger) determined block has PASSED:`, isBlockPassed) + featureTriggerPassed = true + return true + } else { + console.warn(`featureTrigger check (verifyFeatureTrigger) determined block has NOT PASSED:`, isBlockPassed) + featureTriggerPassed = false + return false + } +}