move more code to Shared.js
This commit is contained in:
parent
bcc923d37c
commit
7bb466fd6f
@ -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: `<p>Poll data is invalid or missing.</p>`,
|
||||
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 = `
|
||||
<div class="poll-details-container" id'"${creator}-poll-details">
|
||||
<h1 style ="color:rgb(123, 123, 85); text-align: center; font-size: 2.0rem">${creator}'s</h1><h3 style="color: white; text-align: center; font-size: 1.8rem"> Support Poll Result Details</h3>
|
||||
<h4 style="color: green; text-align: center;">Yes Vote Details</h4>
|
||||
${yesTableHtml}
|
||||
<h4 style="color: red; text-align: center; margin-top: 2em;">No Vote Details</h4>
|
||||
${noTableHtml}
|
||||
</div>
|
||||
`
|
||||
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 `<p>No voters here.</p>`
|
||||
}
|
||||
|
||||
// Decide extremely dark background for the <tbody>
|
||||
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 <thead>, bodyBackground for the <tbody>
|
||||
const minterColor = 'rgb(98, 122, 167)'
|
||||
const adminColor = 'rgb(44, 209, 151)'
|
||||
const userColor = 'rgb(102, 102, 102)'
|
||||
return `
|
||||
<table style="
|
||||
width: 100%;
|
||||
border-style: dotted;
|
||||
border-width: 0.15rem;
|
||||
border-color: #576b6f;
|
||||
margin-bottom: 1em;
|
||||
border-collapse: collapse;
|
||||
">
|
||||
<thead style="background: ${tableColor}; color:rgb(238, 238, 238) ;">
|
||||
<tr style="font-size: 1.5rem;">
|
||||
<th style="padding: 0.1rem; text-align: center;">Voter Name/Address</th>
|
||||
<th style="padding: 0.1rem; text-align: center;">Voter Type</th>
|
||||
<th style="padding: 0.1rem; text-align: center;">Voter Weight(=BlocksMinted)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<!-- Tbody with extremely dark green or red -->
|
||||
<tbody style="background-color: ${bodyBackground}; color: #c6c6c6;">
|
||||
${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 `
|
||||
<tr style="font-size: 1.2rem; border-width: 0.1rem; border-style: dotted; border-color: lightgrey; font-weight: bold;">
|
||||
<td style="padding: 1.2rem; border-width: 0.1rem; border-style: dotted; border-color: lightgrey; text-align: center;
|
||||
color:${userType === 'Admin' ? adminColor : v.isMinter? minterColor : userColor };">${displayName}</td>
|
||||
<td style="padding: 1.2rem; border-width: 0.1rem; border-style: dotted; border-color: lightgrey; text-align: center;
|
||||
color:${userType === 'Admin' ? adminColor : v.isMinter? minterColor : userColor };">${userType}</td>
|
||||
<td style="padding: 1.2rem; border-width: 0.1rem; border-style: dotted; border-color: lightgrey; text-align: center;
|
||||
color:${userType === 'Admin' ? adminColor : v.isMinter? minterColor : userColor };">${v.blocksMinted}</td>
|
||||
</tr>
|
||||
`
|
||||
})
|
||||
.join("")}
|
||||
</tbody>
|
||||
</table>
|
||||
`
|
||||
}
|
||||
|
||||
|
||||
// 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()
|
||||
|
@ -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: `<p>Poll data is invalid or missing.</p>`,
|
||||
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 = `
|
||||
<div class="poll-details-container" id'"${creator}-poll-details">
|
||||
<h1 style ="color:rgb(123, 123, 85); text-align: center; font-size: 2.0rem">${creator}'s</h1><h3 style="color: white; text-align: center; font-size: 1.8rem"> Support Poll Result Details</h3>
|
||||
<h4 style="color: green; text-align: center;">Yes Vote Details</h4>
|
||||
${yesTableHtml}
|
||||
<h4 style="color: red; text-align: center; margin-top: 2em;">No Vote Details</h4>
|
||||
${noTableHtml}
|
||||
</div>
|
||||
`
|
||||
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 `<p>No voters here.</p>`
|
||||
}
|
||||
|
||||
// Decide extremely dark background for the <tbody>
|
||||
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 <thead>, bodyBackground for the <tbody>
|
||||
const minterColor = 'rgb(98, 122, 167)'
|
||||
const adminColor = 'rgb(44, 209, 151)'
|
||||
const userColor = 'rgb(102, 102, 102)'
|
||||
return `
|
||||
<table style="
|
||||
width: 100%;
|
||||
border-style: dotted;
|
||||
border-width: 0.15rem;
|
||||
border-color: #576b6f;
|
||||
margin-bottom: 1em;
|
||||
border-collapse: collapse;
|
||||
">
|
||||
<thead style="background: ${tableColor}; color:rgb(238, 238, 238) ;">
|
||||
<tr style="font-size: 1.5rem;">
|
||||
<th style="padding: 0.1rem; text-align: center;">Voter Name/Address</th>
|
||||
<th style="padding: 0.1rem; text-align: center;">Voter Type</th>
|
||||
<th style="padding: 0.1rem; text-align: center;">Voter Weight(=BlocksMinted)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<!-- Tbody with extremely dark green or red -->
|
||||
<tbody style="background-color: ${bodyBackground}; color: #c6c6c6;">
|
||||
${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 `
|
||||
<tr style="font-size: 1.2rem; border-width: 0.1rem; border-style: dotted; border-color: lightgrey; font-weight: bold;">
|
||||
<td style="padding: 1.2rem; border-width: 0.1rem; border-style: dotted; border-color: lightgrey; text-align: center;
|
||||
color:${userType === 'Admin' ? adminColor : v.isMinter? minterColor : userColor };">${displayName}</td>
|
||||
<td style="padding: 1.2rem; border-width: 0.1rem; border-style: dotted; border-color: lightgrey; text-align: center;
|
||||
color:${userType === 'Admin' ? adminColor : v.isMinter? minterColor : userColor };">${userType}</td>
|
||||
<td style="padding: 1.2rem; border-width: 0.1rem; border-style: dotted; border-color: lightgrey; text-align: center;
|
||||
color:${userType === 'Admin' ? adminColor : v.isMinter? minterColor : userColor };">${v.blocksMinted}</td>
|
||||
</tr>
|
||||
`
|
||||
})
|
||||
.join("")}
|
||||
</tbody>
|
||||
</table>
|
||||
`
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user