diff --git a/.sync_b2a788d19481.db b/.sync_b2a788d19481.db index 1599c7d..447bc37 100644 Binary files a/.sync_b2a788d19481.db and b/.sync_b2a788d19481.db differ diff --git a/.sync_b2a788d19481.db-shm b/.sync_b2a788d19481.db-shm index dbf9e6a..69fd27b 100644 Binary files a/.sync_b2a788d19481.db-shm and b/.sync_b2a788d19481.db-shm differ diff --git a/.sync_b2a788d19481.db-wal b/.sync_b2a788d19481.db-wal index ffdfa0b..467da76 100644 Binary files a/.sync_b2a788d19481.db-wal and b/.sync_b2a788d19481.db-wal differ diff --git a/assets/js/AdminTools.js b/assets/js/AdminTools.js index d396314..f5c3907 100644 --- a/assets/js/AdminTools.js +++ b/assets/js/AdminTools.js @@ -6,57 +6,6 @@ async function verifyMinterAdminState() { return minterGroupAdmins.members.some(admin => admin.member === userState.accountAddress && admin.isAdmin); } -document.addEventListener('DOMContentLoaded', async () => { - const isAdmin = await verifyUserIsAdmin(); - - if (isAdmin) { - console.log(`User is an Admin, buttons for MA Tools not removed. userState.isAdmin = ${userState.isMinterAdmin}`); - } else { - // Remove all "TOOLS" links and their related elements - const toolsLinks = document.querySelectorAll('a[href="TOOLS"], a[href="DATA-BOARD"]'); - toolsLinks.forEach(link => { - // If the link is within a button, remove the button - const buttonParent = link.closest('button'); - if (buttonParent) { - buttonParent.remove(); - } - - // If the link is within an image card or any other element, remove that element - const cardParent = link.closest('.item.features-image'); - if (cardParent) { - cardParent.remove(); - } - - // Finally, remove the link itself if it's not covered by the above removals - link.remove(); - }); - - console.log(`User is NOT a Minter Admin, buttons for MA Tools removed. userState.isMinterAdmin = ${userState.isMinterAdmin}`); - - // Center the remaining card if it exists - const remainingCard = document.querySelector('.features7 .row .item.features-image'); - if (remainingCard) { - remainingCard.classList.remove('col-lg-6', 'col-md-6'); - remainingCard.classList.add('col-12', 'text-center'); - } - - return; - } - - // Add event listener for admin tools link if the user is an admin - const toolsLinks = document.querySelectorAll('a[href="TOOLS"]'); - toolsLinks.forEach(link => { - link.addEventListener('click', async (event) => { - event.preventDefault(); - if (!userState.isLoggedIn) { - await login(); - } - await loadMinterAdminToolsPage(); - }); - }); -}); - - async function loadMinterAdminToolsPage() { // Remove all body content except for menu elements const bodyChildren = document.body.children; diff --git a/assets/js/MinterBoard.js b/assets/js/MinterBoard.js index ceec74f..dca1909 100644 --- a/assets/js/MinterBoard.js +++ b/assets/js/MinterBoard.js @@ -1,24 +1,10 @@ -// const cardIdentifierPrefix = "test-board-card" +// // NOTE - Change isTestMode to false prior to actual release ---- !important - You may also change identifier if you want to not show older cards. const testMode = true; const cardIdentifierPrefix = "testMB-board-card"; let isExistingCard = false; let existingCardData = {}; let existingCardIdentifier = {}; -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(); - }); - }); -}); - const loadMinterBoardPage = async () => { // Clear existing content on the page const bodyChildren = document.body.children; diff --git a/assets/js/MinterDataBoard.js b/assets/js/MinterDataBoard.js deleted file mode 100644 index c9b75ed..0000000 --- a/assets/js/MinterDataBoard.js +++ /dev/null @@ -1,598 +0,0 @@ -// const cardIdentifierPrefix = "test-board-card" -const testMode = true; -const cardIdentifierPrefix = "test-mData-card"; -let isExistingCard = false; -let existingCardData = {}; -let existingCardIdentifier = {}; - -const isAdmin = await verifyUserIsAdmin() - -document.addEventListener("DOMContentLoaded", async () => { -// Verify admin status and hide/show buttons -if (await isAdmin()) { - document.addEventListener("DOMContentLoaded", async () => { - const minterDataBoardLinks = document.querySelectorAll('a[href="DATA-BOARD"]'); - - minterDataBoardLinks.forEach(link => { - link.addEventListener("click", async (event) => { - event.preventDefault(); - if (!userState.isLoggedIn) { - await login(); - } - await loadMinterDataBoardPage(); - }); - }); - }); - } -}) - -const loadMinterDataBoardPage = async () => { - // 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 = ` -
-

Minter Board

-

The Minter Data Board is an encrypted card publishing board to keep track of minter data for the Minter Admins. Any Admin may publish a card, and related data, make comments on existing cards, and vote on existing card data in support or not of the name on the card.

- - -
- -
- `; - document.body.appendChild(mainContent); - - document.getElementById("publish-card-button").addEventListener("click", async () => { - try { - const fetchedCard = await checkDuplicateEncryptedCard(); - if (fetchedCard) { - // An existing card is found - if (testMode) { - // In test mode, ask user what to do - const updateCard = confirm("A card already exists. Do you want to update it? Note, updating it will overwrite the data of the original publisher, only do this if necessary!"); - if (updateCard) { - isExistingCard = true; - await loadEncryptedCardIntoForm(existingCardData); - alert("Edit the existing "); - } else { - alert("Test mode: You can now create a new card."); - isExistingCard = false; - existingCardData = {}; // Reset - document.getElementById("publish-card-form").reset(); - } - } else { - // Not in test mode, force editing - alert("A card already exists. Publishing of multiple cards for the same minter is not allowed, either use existing card or update it."); - isExistingCard = true; - await loadEncryptedCardIntoForm(existingCardData); - } - } else { - // No existing card found - alert("No existing card found. Create a new card."); - isExistingCard = false; - } - - // Show the form - const publishCardView = document.getElementById("publish-card-view"); - publishCardView.style.display = "flex"; - document.getElementById("cards-container").style.display = "none"; - } catch (error) { - console.error("Error checking for existing card:", error); - alert("Failed to check for existing card. Please try again."); - } - }); - - const checkDuplicateEncryptedCard = async (minterName) => { - const response = await qortalRequest({ - action: "SEARCH_QDN_RESOURCES", - service: "MAIL_PRIVATE", - query: `${cardIdentifierPrefix}-${minterName}`, - mode: "ALL", - }); - return response && response.length > 0; - }; - - document.getElementById("refresh-cards-button").addEventListener("click", async () => { - const cardsContainer = document.getElementById("cards-container"); - cardsContainer.innerHTML = "

Refreshing cards...

"; - await fetchEncryptedCards(); - }); - - - document.getElementById("cancel-publish-button").addEventListener("click", async () => { - const cardsContainer = document.getElementById("cards-container"); - cardsContainer.style.display = "flex"; // Restore visibility - const publishCardView = document.getElementById("publish-card-view"); - publishCardView.style.display = "none"; // Hide the publish form - }); - - document.getElementById("add-link-button").addEventListener("click", async () => { - const linksContainer = document.getElementById("links-container"); - const newLinkInput = document.createElement("input"); - newLinkInput.type = "text"; - newLinkInput.className = "card-link"; - newLinkInput.placeholder = "Enter QDN link"; - linksContainer.appendChild(newLinkInput); - }); - - document.getElementById("publish-card-form").addEventListener("submit", async (event) => { - event.preventDefault(); - await publishEncryptedCard(); - }); - - await fetchEncryptedCards(); -} - -//Main function to load the Minter Cards ---------------------------------------- -const fetchEncryptedCards = async () => { - const cardsContainer = document.getElementById("cards-container"); - cardsContainer.innerHTML = "

Loading cards...

"; - - try { - const response = await qortalRequest({ - action: "SEARCH_QDN_RESOURCES", - service: "MAIL_PRIVATE", - query: cardIdentifierPrefix, - mode: "ALL" - }); - - if (!response || !Array.isArray(response) || response.length === 0) { - cardsContainer.innerHTML = "

No cards found.

"; - return; - } - - // Validate cards and filter - const validatedCards = await Promise.all( - response.map(async card => { - const isValid = await validateEncryptedCardStructure(card); - return isValid ? card : null; - }) - ); - - const validCards = validatedCards.filter(card => card !== null); - - if (validCards.length === 0) { - cardsContainer.innerHTML = "

No valid cards found.

"; - return; - } - - // Sort cards by timestamp descending (newest first) - validCards.sort((a, b) => { - const timestampA = a.updated || a.created || 0; - const timestampB = b.updated || b.created || 0; - return timestampB - timestampA; - }); - - // Display skeleton cards immediately - cardsContainer.innerHTML = ""; - validCards.forEach(card => { - const skeletonHTML = createSkeletonCardHTML(card.identifier); - cardsContainer.insertAdjacentHTML("beforeend", skeletonHTML); - }); - - // Fetch and update each card - validCards.forEach(async card => { - try { - const cardDataResponse = await qortalRequest({ - action: "FETCH_QDN_RESOURCE", - name: card.name, - service: "MAIL_PRIVATE", - identifier: card.identifier, - }); - - if (!cardDataResponse) { - console.warn(`Skipping invalid card: ${JSON.stringify(card)}`); - removeSkeleton(card.identifier); - return; - } - - // Skip cards without polls - if (!cardDataResponse.poll) { - console.warn(`Skipping card with no poll: ${card.identifier}`); - removeSkeleton(card.identifier); - return; - } - - // Fetch poll results - const pollResults = await fetchPollResults(cardDataResponse.poll); - - // Generate final card HTML - const finalCardHTML = await createCardHTML(cardDataResponse, pollResults, card.identifier); - replaceSkeleton(card.identifier, finalCardHTML); - } catch (error) { - console.error(`Error processing card ${card.identifier}:`, error); - removeSkeleton(card.identifier); // Silently remove skeleton on error - } - }); - - } catch (error) { - console.error("Error loading cards:", error); - cardsContainer.innerHTML = "

Failed to load cards.

"; - } -}; - - -// Function to check and fech an existing Minter Card if attempting to publish twice ---------------------------------------- -const fetchExistingEncryptedCard = async () => { - try { - // Step 1: Perform the search - const response = await qortalRequest({ - action: "SEARCH_QDN_RESOURCES", - service: "BLOG_POST", - identifier: cardIdentifierPrefix, - name: userState.accountName, - mode: "ALL", - exactMatchNames: true // Search for the exact userName only when finding existing cards - }); - - console.log(`SEARCH_QDN_RESOURCES response: ${JSON.stringify(response, null, 2)}`); - - // Step 2: Check if the response is an array and not empty - if (!response || !Array.isArray(response) || response.length === 0) { - console.log("No cards found for the current user."); - return null; - } - - // Step 3: Validate cards asynchronously - const validatedCards = await Promise.all( - response.map(async card => { - const isValid = await validateEncryptedCardStructure(card); - return isValid ? card : null; - }) - ); - - // Step 4: Filter out invalid cards - const validCards = validatedCards.filter(card => card !== null); - - if (validCards.length > 0) { - // Step 5: Sort by most recent timestamp - const mostRecentCard = validCards.sort((a, b) => b.created - a.created)[0]; - - // Step 6: Fetch full card data - const cardDataResponse = await qortalRequest({ - action: "FETCH_QDN_RESOURCE", - name: userState.accountName, // User's account name - service: "BLOG_POST", - identifier: mostRecentCard.identifier - }); - - existingCardIdentifier = mostRecentCard.identifier; - existingCardData = cardDataResponse; - - console.log("Full card data fetched successfully:", cardDataResponse); - - return cardDataResponse; - } - - console.log("No valid cards found."); - return null; - } catch (error) { - console.error("Error fetching existing card:", error); - return null; - } -}; - -// Validate that a card is indeed a card and not a comment. ------------------------------------- -const validateEncryptedCardStructure = async (card) => { - return ( - typeof card === "object" && - card.name && - card.service === "BLOG_POST" && - card.identifier && !card.identifier.includes("comment") && - card.created - ); -} - -// Load existing card data passed, into the form for editing ------------------------------------- -const loadEncryptedCardIntoForm = async (cardData) => { - console.log("Loading existing card data:", cardData); - document.getElementById("card-header").value = cardData.header; - document.getElementById("card-content").value = cardData.content; - - const linksContainer = document.getElementById("links-container"); - linksContainer.innerHTML = ""; // Clear previous links - cardData.links.forEach(link => { - const linkInput = document.createElement("input"); - linkInput.type = "text"; - linkInput.className = "card-link"; - linkInput.value = link; - linksContainer.appendChild(linkInput); - }); -} - -// Main function to publish a new Minter Card ----------------------------------------------- -const publishEncryptedCard = async () => { - const header = document.getElementById("card-header").value.trim(); - const content = document.getElementById("card-content").value.trim(); - const links = Array.from(document.querySelectorAll(".card-link")) - .map(input => input.value.trim()) - .filter(link => link.startsWith("qortal://")); - - if (!header || !content) { - alert("Header and content are required!"); - return; - } - - const cardIdentifier = isExistingCard ? existingCardIdentifier : `${cardIdentifierPrefix}-${await uid()}`; - const pollName = `${cardIdentifier}-poll`; - const pollDescription = `Mintership Board Poll for ${userState.accountName}`; - - const cardData = { - header, - content, - links, - creator: userState.accountName, - timestamp: Date.now(), - poll: pollName, - }; - - try { - - let base64CardData = await objectToBase64(cardData); - if (!base64CardData) { - console.log(`initial base64 object creation with objectToBase64 failed, using btoa...`); - base64CardData = btoa(JSON.stringify(cardData)); - } - - await qortalRequest({ - action: "PUBLISH_QDN_RESOURCE", - name: userState.accountName, - service: "BLOG_POST", - identifier: cardIdentifier, - data64: base64CardData, - }); - if (!isExistingCard){ - await qortalRequest({ - action: "CREATE_POLL", - pollName, - pollDescription, - pollOptions: ['Yes, No'], - pollOwnerAddress: userState.accountAddress, - }); - - alert("Card and poll published successfully!"); - } - if (isExistingCard){ - alert("Card Updated Successfully! (No poll updates are possible at this time...)") - } - document.getElementById("publish-card-form").reset(); - document.getElementById("publish-card-view").style.display = "none"; - document.getElementById("cards-container").style.display = "flex"; - await loadCards(); - } catch (error) { - console.error("Error publishing card or poll:", error); - alert("Failed to publish card and poll."); - } -} - -// Post a comment on a card. --------------------------------- -const postEncryptedComment = 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 = `comment-${cardIdentifier}-${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)); - } - - 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 - We don't need to do this as comments will be displayed only after confirmation. - } catch (error) { - console.error('Error posting comment:', error); - alert('Failed to post comment.'); - } -}; - -//Fetch the comments for a card with passed card identifier ---------------------------- -const fetchCommentsForEncryptedCard = async (cardIdentifier) => { - try { - const response = await qortalRequest({ - action: 'SEARCH_QDN_RESOURCES', - service: 'BLOG_POST', - query: `comment-${cardIdentifier}`, - mode: "ALL" - }); - return response; - } catch (error) { - console.error(`Error fetching comments for ${cardIdentifier}:`, error); - return []; - } -}; - -// display the comments on the card, with passed cardIdentifier to identify the card -------------- -const displayEncryptedComments = async (cardIdentifier) => { - try { - const comments = await fetchCommentsForCard(cardIdentifier); - const commentsContainer = document.getElementById(`comments-container-${cardIdentifier}`); - - // Fetch and display each comment - for (const comment of comments) { - const commentDataResponse = await qortalRequest({ - action: "FETCH_QDN_RESOURCE", - name: comment.name, - service: "BLOG_POST", - identifier: comment.identifier, - }); - const timestamp = await timestampToHumanReadableDate(commentDataResponse.timestamp); - //TODO - add fetching of poll results and checking to see if the commenter has voted and display it as 'supports minter' section. - const commentHTML = ` -
-

${commentDataResponse.creator}:

-

${commentDataResponse.content}

-

${timestamp}

-
- `; - commentsContainer.insertAdjacentHTML('beforeend', commentHTML); - } - } catch (error) { - console.error(`Error displaying comments for ${cardIdentifier}:`, error); - alert("Failed to load comments. Please try again."); - } -}; - - - -// Toggle comments from being shown or not, with passed cardIdentifier for comments being toggled -------------------- -const toggleComments = async (cardIdentifier) => { - const commentsSection = document.getElementById(`comments-section-${cardIdentifier}`); - if (commentsSection.style.display === 'none' || !commentsSection.style.display) { - await displayComments(cardIdentifier); - commentsSection.style.display = 'block'; - } else { - commentsSection.style.display = 'none'; - } -}; - -const createModal = async () => { - const modalHTML = ` - - `; - document.body.insertAdjacentHTML('beforeend', modalHTML); -} - -// Function to open the modal -const openModal = async (link) => { - const processedLink = await processLink(link) // Process the link to replace `qortal://` for rendering in modal - const modal = document.getElementById('modal'); - const modalContent = document.getElementById('modalContent'); - modalContent.src = processedLink; // Set the iframe source to the link - modal.style.display = 'block'; // Show the modal -} - -// Function to close the modal -const closeModal = async () => { - const modal = document.getElementById('modal'); - const modalContent = document.getElementById('modalContent'); - modal.style.display = 'none'; // Hide the modal - modalContent.src = ''; // Clear the iframe source -} - -const processLink = async (link) => { - if (link.startsWith('qortal://')) { - const match = link.match(/^qortal:\/\/([^/]+)(\/.*)?$/); - if (match) { - const firstParam = match[1].toUpperCase(); // Convert to uppercase - const remainingPath = match[2] || ""; // Rest of the URL - // Perform any asynchronous operation if necessary - await new Promise(resolve => setTimeout(resolve, 10)); // Simulating async operation - return `/render/${firstParam}${remainingPath}`; - } - } - return link; // Return unchanged if not a Qortal link -} - - -// Create the overall Minter Card HTML ----------------------------------------------- -const createEncryptedCardHTML = async (cardData, pollResults, cardIdentifier) => { - const { header, content, links, creator, timestamp, poll } = cardData; - const formattedDate = new Date(timestamp).toLocaleString(); - const avatarUrl = `/arbitrary/THUMBNAIL/${creator}/qortal_avatar`; - const linksHTML = links.map((link, index) => ` - - `).join(""); - - const minterGroupMembers = await fetchMinterGroupMembers(); - const minterAdmins = await fetchMinterGroupAdmins(); - const { adminYes = 0, adminNo = 0, minterYes = 0, minterNo = 0, totalYes = 0, totalNo = 0, totalYesWeight = 0, totalNoWeight = 0 } = await calculatePollResults(pollResults, minterGroupMembers, minterAdmins) - await createModal() - return ` -
-
- User Avatar -

${creator}

-

${header}

-
-
Minter Post:
-
- ${content} -
-
Minter Links:
- -
Current Results:
-
-
- Admin Yes: ${adminYes} - Admin No: ${adminNo} -
-
- Minter Yes: ${minterYes} - Minter No: ${minterNo} -
-
- Total Yes: ${totalYes} - Total No: ${totalNo} -
-
-
Support Minter?
-
-
- - - -
-
- -

Published by: ${creator} on ${formattedDate}

-
- `; -} - diff --git a/assets/js/Q-Mintership.js b/assets/js/Q-Mintership.js index 66ad09b..ec28aaa 100644 --- a/assets/js/Q-Mintership.js +++ b/assets/js/Q-Mintership.js @@ -15,23 +15,112 @@ if (localStorage.getItem("latestMessageIdentifiers")) { } document.addEventListener("DOMContentLoaded", async () => { - // Identify the links for 'Mintership Forum' and apply functionality - const mintershipForumLinks = document.querySelectorAll('a[href="MINTERSHIP-FORUM"]'); + console.log("DOMContentLoaded fired!"); + // --- GENERAL LINKS (MINTERSHIP-FORUM and MINTER-BOARD) --- + const mintershipForumLinks = document.querySelectorAll('a[href="MINTERSHIP-FORUM"]'); mintershipForumLinks.forEach(link => { link.addEventListener('click', async (event) => { event.preventDefault(); - //login if not already logged in. if (!userState.isLoggedIn) { await login(); } await loadForumPage(); - loadRoomContent("general"); // Automatically load General Room on forum load - startPollingForNewMessages(); // Start polling for new messages after loading the forum page + loadRoomContent("general"); + startPollingForNewMessages(); }); }); + + 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(); + } + if (typeof loadMinterBoardPage === "undefined") { + console.log("loadMinterBoardPage not found, loading script dynamically..."); + await loadScript("./assets/js/MinterBoard.js"); + } + await loadMinterBoardPage(); + }); + }); + + // --- ADMIN CHECK --- + await verifyUserIsAdmin(); + + if (userState.isAdmin) { + console.log(`User is an Admin. Admin-specific buttons will remain visible.`); + + // DATA-BOARD Links for Admins + const minterDataBoardLinks = document.querySelectorAll('a[href="ADMINBOARD"]'); + minterDataBoardLinks.forEach(link => { + link.addEventListener("click", async (event) => { + event.preventDefault(); + if (!userState.isLoggedIn) { + await login(); + } + if (typeof loadAdminBoardPage === "undefined") { + console.log("loadAdminBoardPage function not found, loading script dynamically..."); + await loadScript("./assets/js/AdminBoard.js"); + } + await loadAdminBoardPage(); + }); + }); + + // TOOLS Links for Admins + const toolsLinks = document.querySelectorAll('a[href="TOOLS"]'); + toolsLinks.forEach(link => { + link.addEventListener('click', async (event) => { + event.preventDefault(); + if (!userState.isLoggedIn) { + await login(); + } + if (typeof loadMinterAdminToolsPage === "undefined") { + console.log("loadMinterAdminToolsPage function not found, loading script dynamically..."); + await loadScript("./assets/js/AdminTools.js"); + } + await loadMinterAdminToolsPage(); + }); + }); + + } else { + console.log("User is NOT an Admin. Removing admin-specific links."); + + // Remove all admin-specific links and their parents + const toolsLinks = document.querySelectorAll('a[href="TOOLS"], a[href="DATA-BOARD"]'); + toolsLinks.forEach(link => { + const buttonParent = link.closest('button'); + if (buttonParent) buttonParent.remove(); + + const cardParent = link.closest('.item.features-image'); + if (cardParent) cardParent.remove(); + + link.remove(); + }); + + // Center the remaining card if it exists + const remainingCard = document.querySelector('.features7 .row .item.features-image'); + if (remainingCard) { + remainingCard.classList.remove('col-lg-6', 'col-md-6'); + remainingCard.classList.add('col-12', 'text-center'); + } + } + + console.log("All DOMContentLoaded tasks completed."); }); +async function loadScript(src) { + return new Promise((resolve, reject) => { + const script = document.createElement("script"); + script.src = src; + script.onload = resolve; + script.onerror = reject; + document.head.appendChild(script); + }); +} + + // Main load function to clear existing HTML and load the forum page ----------------------------------------------------- const loadForumPage = async () => { // remove everything that isn't the menu from the body to use js to generate page content. @@ -452,6 +541,7 @@ const showSuccessNotification = () => { notification.style.color = "green"; notification.style.marginTop = "1em"; document.querySelector(".message-input-section").appendChild(notification); + alert(`Successfully Published! Please note that messages will not display until after they are CONFIRMED, be patient!`) setTimeout(() => { notification.remove(); @@ -464,17 +554,6 @@ const generateAttachmentID = (room, fileIndex = null) => { return fileIndex !== null ? `${baseID}-${fileIndex}` : baseID; }; -const decryptObject = async (encryptedData) => { - // const publicKey = await getPublicKeyFromAddress(userState.accountAddress) - const response = await qortalRequest({ - action: 'DECRYPT_DATA', - encryptedData, // has to be in base64 format - // publicKey: publisherPublicKey // requires the public key of the opposite user with whom you've created the encrypted data. For DIRECT messages only. - }); - const decryptedObject = response - return decryptedObject -} - const decryptFile = async (encryptedData) => { const publicKey = await getPublicKeyByName(userState.accountName) const response = await qortalRequest({ diff --git a/assets/js/QortalApi.js b/assets/js/QortalApi.js index da933c5..aad133a 100644 --- a/assets/js/QortalApi.js +++ b/assets/js/QortalApi.js @@ -453,7 +453,7 @@ const fetchAdminGroupsMembersPublicKeys = async () => { }; -// QDN data calls +// QDN data calls -------------------------------------------------------------------------------------------------- const searchLatestDataByIdentifier = async (identifier) => { console.log('fetchAllDataByIdentifier called'); console.log('identifier:', identifier); @@ -493,6 +493,22 @@ const publishMultipleResources = async (resources, publicKeys = null, isPrivate }; }; +// the object must be in base64 when sent +const decryptObject = async (encryptedData) => { + // const publicKey = await getPublicKeyFromAddress(userState.accountAddress) + const response = await qortalRequest({ + action: 'DECRYPT_DATA', + encryptedData, // has to be in base64 format + // publicKey: publisherPublicKey // requires the public key of the opposite user with whom you've created the encrypted data. For DIRECT messages only. + }); + const decryptedObject = response + return decryptedObject +} + + const decryptAndParseObject = async (base64Data) => { + const decrypted = await decryptObject(base64Data); + return JSON.parse(atob(decrypted)); +}; const searchResourcesWithMetadata = async (query, limit) => { console.log('searchResourcesWithMetadata called'); diff --git a/assets/mobirise/css/mbr-additional.css b/assets/mobirise/css/mbr-additional.css index 79f868f..626c1f4 100644 --- a/assets/mobirise/css/mbr-additional.css +++ b/assets/mobirise/css/mbr-additional.css @@ -138,7 +138,7 @@ body { } .btn-secondary, .btn-secondary:active { - background-color: #a4a2a2 !important; + background-color: #7cddff !important; border-color: #a4a2a2 !important; color: #ffffff !important; box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.2); @@ -148,7 +148,7 @@ body { .btn-secondary.focus, .btn-secondary.active { color: #ffffff !important; - background-color: #797676 !important; + background-color: #50abf1b5 !important; border-color: #797676 !important; box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.2); } @@ -1283,6 +1283,10 @@ a { } } .cid-ttRnktJ11Q .mbr-section-btn .btn, +.cid-ttRnktJ11Q .mbr-section-btn-main .btn .admin-btn { + background-image: linear-gradient(99deg, rgba(23, 64, 86, 0.468) 30%, #77dff6 100%), radial-gradient(circle at 50% 50%, #64f7cb 0, rgba(255, 255, 255, 0) 70%); + ; +} .cid-ttRnktJ11Q .mbr-section-btn-main .btn { background-image: linear-gradient(99deg, rgba(255, 255, 255, 0) 30%, #ffffff 100%), radial-gradient(circle at 50% 50%, #ffffff 0, rgba(255, 255, 255, 0) 70%); ; diff --git a/index.html b/index.html index f6889f8..1bd63d4 100644 --- a/index.html +++ b/index.html @@ -68,12 +68,12 @@ - Q-Mintership Alpha v0.41b
+ Q-Mintership Alpha v0.5b
-
FORUM
ADMIN TOOLSMINTER BOARD
+
FORUM
ADMIN TOOLSADMIN BOARDMINTER BOARD
@@ -185,7 +185,7 @@

- More information...

+ Updates and information
@@ -196,6 +196,40 @@
+
+
+
+
+

+ a few things remaining

+
+
+
+
+

+ There are still a few things remaining, such as downloading of encrypted attachments in the Admin Room on the forum, and final testing of the Minter Data Board, with potentially a rename of that section to 'Minter Management' in the future. Many additional changes will be coming as time goes on as well. Turning Q-Mintership-Alpha into a fully featured Mintership app! Hope you enjoy it and that it is useful for you, and if you have any suggestions in regard to new features or modifications to existing ones, send a Q-Mail message to crowetic.

+
+
+
+
+ +
+
+
+
+

+ Updates 12.17.2024

+
+
+
+
+

+ The Q-Mintership-Alpha application is now published on the Q-Mintership name, and has a plethora of new features. Including the Minter Board, where new minters will publish information about themselves so that the admins can make informed decisions, and the Minter Data Board as a new Minter Admin Tool to manage the data regarding minters they want to add/remove from the MINTER group. The Forum portion of the app now also contains an encrypted Admin room, and has had a ton of improvements made as well.

+
+
+
+
+
@@ -244,18 +278,18 @@ - - - - - - - - + + + + + + + - - + + + \ No newline at end of file