402 lines
14 KiB
JavaScript
402 lines
14 KiB
JavaScript
|
|
function setActiveView(view) {
|
|||
|
|
if (view === "transactions") {
|
|||
|
|
view = "history";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const previousView = currentView;
|
|||
|
|
if (previousView === "send" && view !== "send" && typeof resetTransactionForms === "function") {
|
|||
|
|
resetTransactionForms();
|
|||
|
|
}
|
|||
|
|
if (previousView === "marketing" && view !== "marketing" && typeof resetMarketingCampaignPage === "function") {
|
|||
|
|
resetMarketingCampaignPage();
|
|||
|
|
}
|
|||
|
|
if (previousView === "nfts" && view !== "nfts" && typeof resetNftsPage === "function") {
|
|||
|
|
resetNftsPage();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const [title, subtitle] = titles[view] || titles.dashboard;
|
|||
|
|
currentView = view;
|
|||
|
|
|
|||
|
|
navButtons.forEach((button) => {
|
|||
|
|
button.classList.toggle("active", button.dataset.view === view);
|
|||
|
|
});
|
|||
|
|
closeMobileMoreMenu();
|
|||
|
|
document.querySelector("[data-mobile-more]")?.classList.toggle(
|
|||
|
|
"active",
|
|||
|
|
["assets", "marketing", "addressbook", "settings"].includes(view)
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
if (viewTitle) {
|
|||
|
|
viewTitle.textContent = title;
|
|||
|
|
}
|
|||
|
|
if (viewSubtitle) {
|
|||
|
|
viewSubtitle.textContent = subtitle;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (view === "dashboard") {
|
|||
|
|
dashboardView.classList.remove("hidden");
|
|||
|
|
transactionView.classList.add("hidden");
|
|||
|
|
receiveView.classList.add("hidden");
|
|||
|
|
historyView.classList.add("hidden");
|
|||
|
|
assetsView.classList.add("hidden");
|
|||
|
|
nftsView.classList.add("hidden");
|
|||
|
|
loansView.classList.add("hidden");
|
|||
|
|
marketingView.classList.add("hidden");
|
|||
|
|
addressbookView.classList.add("hidden");
|
|||
|
|
settingsView.classList.add("hidden");
|
|||
|
|
updateNetworkInfoRefreshState();
|
|||
|
|
if (registrationRegistered) {
|
|||
|
|
startRegisteredDashboardLoadSequence({ quiet: true });
|
|||
|
|
} else {
|
|||
|
|
updateBalanceRefreshState();
|
|||
|
|
updateLatestDashboardTransactionsPolling();
|
|||
|
|
}
|
|||
|
|
updateHistoryRefreshState();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
updateBalanceRefreshState();
|
|||
|
|
updateNetworkInfoRefreshState();
|
|||
|
|
updateLatestDashboardTransactionsPolling();
|
|||
|
|
updateHistoryRefreshState();
|
|||
|
|
dashboardView.classList.add("hidden");
|
|||
|
|
transactionView.classList.add("hidden");
|
|||
|
|
receiveView.classList.add("hidden");
|
|||
|
|
historyView.classList.add("hidden");
|
|||
|
|
assetsView.classList.add("hidden");
|
|||
|
|
nftsView.classList.add("hidden");
|
|||
|
|
loansView.classList.add("hidden");
|
|||
|
|
marketingView.classList.add("hidden");
|
|||
|
|
addressbookView.classList.add("hidden");
|
|||
|
|
settingsView.classList.add("hidden");
|
|||
|
|
|
|||
|
|
if (view === "receive") {
|
|||
|
|
receiveView.classList.remove("hidden");
|
|||
|
|
refreshReceivePage();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (view === "history") {
|
|||
|
|
historyView.classList.remove("hidden");
|
|||
|
|
updateHistoryRefreshState();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (view === "assets") {
|
|||
|
|
assetsView.classList.remove("hidden");
|
|||
|
|
prepareAssetsPage();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (view === "nfts") {
|
|||
|
|
nftsView.classList.remove("hidden");
|
|||
|
|
prepareNftsPage();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (view === "loans") {
|
|||
|
|
loansView.classList.remove("hidden");
|
|||
|
|
prepareLoansPage();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (view === "marketing") {
|
|||
|
|
marketingView.classList.remove("hidden");
|
|||
|
|
prepareMarketingCampaignPage();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (view === "addressbook") {
|
|||
|
|
addressbookView.classList.remove("hidden");
|
|||
|
|
prepareAddressBookPage();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (view === "settings") {
|
|||
|
|
settingsView.classList.remove("hidden");
|
|||
|
|
loadSettingsPage();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
transactionView.classList.remove("hidden");
|
|||
|
|
|
|||
|
|
if (view === "send") {
|
|||
|
|
setActiveTransactionType("Transfer");
|
|||
|
|
showTransactionList();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
showTransactionList(title, subtitle);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
navButtons.forEach((button) => {
|
|||
|
|
button.addEventListener("click", () => setActiveView(button.dataset.view));
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
function setMobileMoreMenuOpen(open) {
|
|||
|
|
const moreButton = document.querySelector("[data-mobile-more]");
|
|||
|
|
const backdrop = document.querySelector("[data-mobile-more-backdrop]");
|
|||
|
|
const sheet = document.querySelector("[data-mobile-more-sheet]");
|
|||
|
|
moreButton?.setAttribute("aria-expanded", open ? "true" : "false");
|
|||
|
|
backdrop?.classList.toggle("hidden", !open);
|
|||
|
|
sheet?.classList.toggle("hidden", !open);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function closeMobileMoreMenu() {
|
|||
|
|
setMobileMoreMenuOpen(false);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
document.querySelector("[data-mobile-more]")?.addEventListener("click", () => {
|
|||
|
|
const moreButton = document.querySelector("[data-mobile-more]");
|
|||
|
|
setMobileMoreMenuOpen(moreButton?.getAttribute("aria-expanded") !== "true");
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
document.querySelector("[data-mobile-more-backdrop]")?.addEventListener("click", closeMobileMoreMenu);
|
|||
|
|
|
|||
|
|
function showTransactionList(title = "Unbroadcast Transactions", copy = "Transactions saved locally and waiting for review.") {
|
|||
|
|
currentTransactionType = "";
|
|||
|
|
transactionTitle.textContent = title;
|
|||
|
|
transactionCopy.textContent = copy;
|
|||
|
|
transactionList.classList.remove("hidden");
|
|||
|
|
formPanel.classList.add("hidden");
|
|||
|
|
reviewPanel.classList.add("hidden");
|
|||
|
|
unbroadcastListMessage?.classList.remove("hidden");
|
|||
|
|
if (typeof refreshUnbroadcastTransactions === "function") {
|
|||
|
|
refreshUnbroadcastTransactions();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function setActiveTransactionType(type = "Transfer") {
|
|||
|
|
document
|
|||
|
|
.querySelectorAll("[data-transaction-type]")
|
|||
|
|
.forEach((item) => item.classList.toggle("active", item.dataset.transactionType === type));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function refreshActiveTransactionFormAfterWalletData() {
|
|||
|
|
if (currentView !== "send" || !currentTransactionType || !walletLoaded || !registrationRegistered) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (currentTransactionType === "Transfer" && typeof refreshTransferBalancesIfNeeded === "function") {
|
|||
|
|
refreshTransferBalancesIfNeeded().catch(() => {});
|
|||
|
|
} else if (currentTransactionType === "Issue More Tokens" && typeof prepareIssueTokenForm === "function") {
|
|||
|
|
prepareIssueTokenForm();
|
|||
|
|
} else if (currentTransactionType === "Create NFT" && typeof prepareCreateNftForm === "function") {
|
|||
|
|
prepareCreateNftForm();
|
|||
|
|
} else if (currentTransactionType === "Swap" && typeof prepareSwapOfferForm === "function") {
|
|||
|
|
prepareSwapOfferForm();
|
|||
|
|
} else if (currentTransactionType === "Create Loan" && typeof prepareLoanOfferForm === "function") {
|
|||
|
|
prepareLoanOfferForm();
|
|||
|
|
} else if (currentTransactionType === "Loan Payment" && typeof prepareLoanPaymentForm === "function") {
|
|||
|
|
prepareLoanPaymentForm();
|
|||
|
|
} else if (currentTransactionType === "Collateral Claim" && typeof prepareCollateralClaimForm === "function") {
|
|||
|
|
prepareCollateralClaimForm();
|
|||
|
|
} else if (currentTransactionType === "Burn" && typeof prepareBurnForm === "function") {
|
|||
|
|
prepareBurnForm();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function isActiveTransactionType(type) {
|
|||
|
|
return currentView === "send" && currentTransactionType === type;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function clearInactiveTransactionMessages(activeType) {
|
|||
|
|
const messageByType = {
|
|||
|
|
"Transfer": transferMessage,
|
|||
|
|
"Create Token": createTokenMessage,
|
|||
|
|
"Issue More Tokens": issueTokenMessage,
|
|||
|
|
"Create NFT": createNftMessage,
|
|||
|
|
"Swap": swapOfferMessage,
|
|||
|
|
"Create Loan": loanOfferMessage,
|
|||
|
|
"Loan Payment": loanPaymentMessage,
|
|||
|
|
"Collateral Claim": collateralClaimMessage,
|
|||
|
|
"Burn": burnMessage,
|
|||
|
|
"Marketing": marketingMessage,
|
|||
|
|
"Vanity Address": vanityMessage
|
|||
|
|
};
|
|||
|
|
Object.entries(messageByType).forEach(([type, element]) => {
|
|||
|
|
if (!element || type === activeType) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
element.textContent = "";
|
|||
|
|
element.classList.add("hidden");
|
|||
|
|
element.classList.remove("error", "success");
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function showTransactionForm(type) {
|
|||
|
|
currentTransactionType = type;
|
|||
|
|
clearInactiveTransactionMessages(type);
|
|||
|
|
transactionTitle.textContent = type;
|
|||
|
|
transactionCopy.textContent = "Create, save, or broadcast this transaction type.";
|
|||
|
|
transactionList.classList.add("hidden");
|
|||
|
|
unbroadcastListMessage?.classList.add("hidden");
|
|||
|
|
reviewPanel.classList.add("hidden");
|
|||
|
|
formPanel.classList.remove("hidden");
|
|||
|
|
|
|||
|
|
const isTransfer = type === "Transfer";
|
|||
|
|
const isCreateToken = type === "Create Token";
|
|||
|
|
const isIssueToken = type === "Issue More Tokens";
|
|||
|
|
const isCreateNft = type === "Create NFT";
|
|||
|
|
const isSwap = type === "Swap";
|
|||
|
|
const isLoan = type === "Create Loan";
|
|||
|
|
const isLoanPayment = type === "Loan Payment";
|
|||
|
|
const isCollateralClaim = type === "Collateral Claim";
|
|||
|
|
const isBurn = type === "Burn";
|
|||
|
|
const isMarketing = type === "Marketing";
|
|||
|
|
const isVanity = type === "Vanity Address";
|
|||
|
|
document.querySelector("[data-transfer-form]")?.classList.toggle("hidden", !isTransfer);
|
|||
|
|
transferActions?.classList.toggle("hidden", !isTransfer);
|
|||
|
|
transferMessage?.classList.toggle("hidden", !isTransfer);
|
|||
|
|
createTokenForm?.classList.toggle("hidden", !isCreateToken);
|
|||
|
|
createTokenActions?.classList.toggle("hidden", !isCreateToken);
|
|||
|
|
createTokenMessage?.classList.toggle("hidden", !isCreateToken);
|
|||
|
|
issueTokenForm?.classList.toggle("hidden", !isIssueToken);
|
|||
|
|
issueTokenActions?.classList.toggle("hidden", !isIssueToken);
|
|||
|
|
issueTokenMessage?.classList.toggle("hidden", !isIssueToken);
|
|||
|
|
createNftForm?.classList.toggle("hidden", !isCreateNft);
|
|||
|
|
createNftActions?.classList.toggle("hidden", !isCreateNft);
|
|||
|
|
createNftMessage?.classList.toggle("hidden", !isCreateNft);
|
|||
|
|
swapOfferForm?.classList.toggle("hidden", !isSwap);
|
|||
|
|
swapOfferActions?.classList.toggle("hidden", !isSwap);
|
|||
|
|
swapOfferMessage?.classList.toggle("hidden", !isSwap);
|
|||
|
|
loanOfferForm?.classList.toggle("hidden", !isLoan);
|
|||
|
|
loanOfferActions?.classList.toggle("hidden", !isLoan);
|
|||
|
|
loanSavedPathPanel?.classList.toggle("hidden", !isLoan || !loanSavedPathInput?.value);
|
|||
|
|
loanOfferMessage?.classList.toggle("hidden", !isLoan);
|
|||
|
|
loanPaymentForm?.classList.toggle("hidden", !isLoanPayment);
|
|||
|
|
loanPaymentActions?.classList.toggle("hidden", !isLoanPayment);
|
|||
|
|
loanPaymentMessage?.classList.toggle("hidden", !isLoanPayment);
|
|||
|
|
collateralClaimForm?.classList.toggle("hidden", !isCollateralClaim);
|
|||
|
|
collateralClaimActions?.classList.toggle("hidden", !isCollateralClaim);
|
|||
|
|
collateralClaimMessage?.classList.toggle("hidden", !isCollateralClaim);
|
|||
|
|
burnForm?.classList.toggle("hidden", !isBurn);
|
|||
|
|
burnActions?.classList.toggle("hidden", !isBurn);
|
|||
|
|
burnMessage?.classList.toggle("hidden", !isBurn);
|
|||
|
|
marketingForm?.classList.toggle("hidden", !isMarketing);
|
|||
|
|
marketingActions?.classList.toggle("hidden", !isMarketing);
|
|||
|
|
marketingMessage?.classList.toggle("hidden", !isMarketing);
|
|||
|
|
vanityForm?.classList.toggle("hidden", !isVanity);
|
|||
|
|
vanityActions?.classList.toggle("hidden", !isVanity);
|
|||
|
|
vanityMessage?.classList.toggle("hidden", !isVanity);
|
|||
|
|
|
|||
|
|
if (isTransfer && typeof prepareTransferForm === "function") {
|
|||
|
|
prepareTransferForm();
|
|||
|
|
} else if (isCreateToken && typeof prepareCreateTokenForm === "function") {
|
|||
|
|
prepareCreateTokenForm();
|
|||
|
|
} else if (isIssueToken && typeof prepareIssueTokenForm === "function") {
|
|||
|
|
prepareIssueTokenForm();
|
|||
|
|
} else if (isCreateNft && typeof prepareCreateNftForm === "function") {
|
|||
|
|
prepareCreateNftForm();
|
|||
|
|
} else if (isSwap && typeof prepareSwapOfferForm === "function") {
|
|||
|
|
prepareSwapOfferForm();
|
|||
|
|
} else if (isLoan && typeof prepareLoanOfferForm === "function") {
|
|||
|
|
prepareLoanOfferForm();
|
|||
|
|
} else if (isLoanPayment && typeof prepareLoanPaymentForm === "function") {
|
|||
|
|
prepareLoanPaymentForm();
|
|||
|
|
} else if (isCollateralClaim && typeof prepareCollateralClaimForm === "function") {
|
|||
|
|
prepareCollateralClaimForm();
|
|||
|
|
} else if (isBurn && typeof prepareBurnForm === "function") {
|
|||
|
|
prepareBurnForm();
|
|||
|
|
} else if (isMarketing && typeof prepareMarketingForm === "function") {
|
|||
|
|
prepareMarketingForm();
|
|||
|
|
} else if (isVanity && typeof prepareVanityAddressForm === "function") {
|
|||
|
|
prepareVanityAddressForm();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function openTransactionType(type) {
|
|||
|
|
setActiveView("send");
|
|||
|
|
setActiveTransactionType(type);
|
|||
|
|
showTransactionForm(type);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function openImportTransaction() {
|
|||
|
|
setActiveView("send");
|
|||
|
|
if (typeof showUnbroadcastList === "function") {
|
|||
|
|
showUnbroadcastList();
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
showTransactionList();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function showTransactionReview() {
|
|||
|
|
transactionTitle.textContent = "Review Transaction";
|
|||
|
|
transactionCopy.textContent = "Inspect this local transaction before broadcasting.";
|
|||
|
|
transactionList.classList.add("hidden");
|
|||
|
|
formPanel.classList.add("hidden");
|
|||
|
|
reviewPanel.classList.remove("hidden");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
document.querySelectorAll("[data-transaction-type]").forEach((button) => {
|
|||
|
|
button.addEventListener("click", () => {
|
|||
|
|
setActiveTransactionType(button.dataset.transactionType);
|
|||
|
|
showTransactionForm(button.dataset.transactionType);
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
document.querySelector("[data-open-create-transaction]")?.addEventListener("click", () => {
|
|||
|
|
openTransactionType("Transfer");
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
document.querySelector("[data-view-all-transactions]")?.addEventListener("click", () => {
|
|||
|
|
setActiveView("history");
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
document.querySelector("[data-open-import-transaction]")?.addEventListener("click", () => {
|
|||
|
|
openImportTransaction();
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
document.querySelector("[data-open-vanity-transaction]")?.addEventListener("click", () => {
|
|||
|
|
openTransactionType("Vanity Address");
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
document.querySelector("[data-open-address-book]")?.addEventListener("click", () => {
|
|||
|
|
setActiveView("addressbook");
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
function flashCopyButton(button) {
|
|||
|
|
if (!button) {
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
const original = button.textContent || "Copy";
|
|||
|
|
button.textContent = "Copied";
|
|||
|
|
setTimeout(() => {
|
|||
|
|
button.textContent = original;
|
|||
|
|
}, 1200);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async function copyReceiveValue(selector, button) {
|
|||
|
|
const value = document.querySelector(selector)?.textContent?.trim();
|
|||
|
|
if (value && value !== "N/A" && await writeClipboardText(value)) {
|
|||
|
|
flashCopyButton(button);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
document.querySelector("[data-copy-address]")?.addEventListener("click", async (event) => {
|
|||
|
|
await copyReceiveValue("[data-active-address]", event.currentTarget);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
document.querySelector("[data-copy-vanity]")?.addEventListener("click", async (event) => {
|
|||
|
|
await copyReceiveValue("[data-active-vanity]", event.currentTarget);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
document.querySelectorAll("[data-copy-hash]").forEach((button) => {
|
|||
|
|
button.addEventListener("click", () => {
|
|||
|
|
const original = button.textContent;
|
|||
|
|
button.textContent = "Copied";
|
|||
|
|
setTimeout(() => {
|
|||
|
|
button.textContent = original;
|
|||
|
|
}, 1200);
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
document.querySelectorAll("[data-loan-card]").forEach((button) => {
|
|||
|
|
button.addEventListener("click", () => {
|
|||
|
|
document
|
|||
|
|
.querySelectorAll("[data-loan-card]")
|
|||
|
|
.forEach((item) => item.classList.toggle("active", item === button));
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
|