New router implementation

This commit is contained in:
sairaj mote 2023-01-20 22:27:58 +05:30
parent 842be7ebbf
commit c3e2d1bef7

View File

@ -186,7 +186,7 @@
return timestamp; return timestamp;
} }
} }
window.addEventListener('hashchange', e => routeTo(window.location.hash)) // window.addEventListener('hashchange', e => routeTo(window.location.hash))
window.addEventListener("load", () => { window.addEventListener("load", () => {
document.body.classList.remove('hidden') document.body.classList.remove('hidden')
document.addEventListener("pointerdown", (e) => { document.addEventListener("pointerdown", (e) => {
@ -198,7 +198,7 @@
notify('copied', 'success') notify('copied', 'success')
}) })
getAllSuggestions().then(suggestions => { getAllSuggestions().then(suggestions => {
routeTo(window.location.hash) router.routeTo(window.location.hash)
}).catch(e => { }).catch(e => {
console.error(e) console.error(e)
notify(e, 'error') notify(e, 'error')
@ -268,47 +268,64 @@
}; };
} }
const appState = { class Router {
params: {}, constructor(options = {}) {
const { routes = {}, state = {}, routingStart, routingEnd } = options
this.routes = routes
this.state = state
this.routingStart = routingStart
this.routingEnd = routingEnd
window.addEventListener('hashchange', e => this.routeTo(window.location.hash))
} }
async function routeTo(targetPage) { addRoute(route, callback) {
const routingAnimation = { in: slideInUp, out: slideOutUp } this.routes[route] = callback
let pageId }
let subPageId1 async routeTo(path) {
let searchParams let page
let wildcards = []
let queryString
let params let params
if (targetPage === '') { [path, queryString] = path.split('?');
pageId = 'home' if (path.includes('#'))
history.replaceState(null, null, '#/home'); path = path.split('#')[1];
if (path.includes('/'))
[, page, ...wildcards] = path.split('/')
else
page = path
this.state = { page, wildcards }
if (queryString) {
params = new URLSearchParams(queryString)
this.state.params = Object.fromEntries(params)
}
if (this.routingStart) {
this.routingStart(this.state)
}
if (this.routes[page]) {
await this.routes[page](this.state)
this.state.lastPage = page
} else { } else {
if (targetPage.includes('/')) { this.routes['404'](this.state)
if (targetPage.includes('?')) {
const splitAddress = targetPage.split('?')
searchParams = splitAddress.pop();
[, pageId, subPageId1] = splitAddress.pop().split('/')
} else {
[, pageId, subPageId1] = targetPage.split('/')
} }
} else { if (this.routingEnd) {
pageId = targetPage this.routingEnd(this.state)
} }
} }
appState.currentPage = pageId
if (searchParams) {
const urlSearchParams = new URLSearchParams('?' + searchParams);
params = Object.fromEntries(urlSearchParams.entries());
} }
if (params) const router = new Router({
appState.params = params routingStart(state) {
loading() loading()
if ("scrollRestoration" in history) { if ("scrollRestoration" in history) {
history.scrollRestoration = "manual"; history.scrollRestoration = "manual";
} }
window.scrollTo(0, 0); window.scrollTo(0, 0);
if (pageId !== 'home') if (state.page !== 'home')
getRef("page_header").classList.remove("hidden"); getRef("page_header").classList.remove("hidden");
switch (pageId) { },
case "home": { routingEnd() {
loading(false)
}
})
async function renderHome(state) {
getRef("page_header").classList.add("hidden"); getRef("page_header").classList.add("hidden");
let [data, latestTxs, latestBlocks] = await Promise.all([getBannerData(), getLatestTxs(), getAllBlocks(6)]) let [data, latestTxs, latestBlocks] = await Promise.all([getBannerData(), getLatestTxs(), getAllBlocks(6)])
renderElem(getRef("page_container"), html`${render.homepage(data)}`); renderElem(getRef("page_container"), html`${render.homepage(data)}`);
@ -316,11 +333,16 @@
const renderedBlocks = latestBlocks.map(block => render.blockCard(block)) const renderedBlocks = latestBlocks.map(block => render.blockCard(block))
renderElem(document.getElementById('top_blocks_container'), html`${renderedBlocks}`) renderElem(document.getElementById('top_blocks_container'), html`${renderedBlocks}`)
} }
break router.addRoute('', (state) => {
case "address": { history.replaceState({}, '', '#/home')
if (!subPageId1) return; renderHome(state)
let [addressInfo, addressBalance, addressTxs] = await Promise.all([getAddressInfo(subPageId1), getAddressBalance(subPageId1), getAddressTxs(subPageId1)]) })
renderElem(getRef("page_container"), html`${render.addressPage({ balance: addressBalance, address: subPageId1 })}`); router.addRoute('home', renderHome)
router.addRoute('address', async state => {
const [floAddress] = state.wildcards
if (!floAddress) return;
let [addressInfo, addressBalance, addressTxs] = await Promise.all([getAddressInfo(floAddress), getAddressBalance(floAddress), getAddressTxs(floAddress)])
renderElem(getRef("page_container"), html`${render.addressPage({ balance: addressBalance, address: floAddress })}`);
getRef("page_title").textContent = 'Address' getRef("page_title").textContent = 'Address'
renderTransactions('address_transaction_container', addressTxs) renderTransactions('address_transaction_container', addressTxs)
@ -329,10 +351,11 @@
tokenHolders.push(render.tokenBalanceCard(token, addressInfo[token].balance)) tokenHolders.push(render.tokenBalanceCard(token, addressInfo[token].balance))
} }
renderElem(document.getElementById('token_balance_container'), html`${tokenHolders}`) renderElem(document.getElementById('token_balance_container'), html`${tokenHolders}`)
} break; })
case "token": { router.addRoute('token', async state => {
if (!subPageId1) return; const token = state.wildcards[0].toLowerCase()
const token = subPageId1.toLowerCase() if (!token) return;
try {
let [tokenInfo, tokenBalances, tokenTransactions] = await Promise.all([getTokenInfo(token), getTokenBalances(token), getTokenTransactions(token)]) let [tokenInfo, tokenBalances, tokenTransactions] = await Promise.all([getTokenInfo(token), getTokenBalances(token), getTokenTransactions(token)])
const tokenHolders = [] const tokenHolders = []
for (const address in tokenBalances) { for (const address in tokenBalances) {
@ -342,13 +365,16 @@
getRef("page_title").textContent = "Token"; getRef("page_title").textContent = "Token";
renderElem(document.getElementById('token_balance_container'), html`${tokenHolders}`) renderElem(document.getElementById('token_balance_container'), html`${tokenHolders}`)
renderTransactions('token_transaction_container', tokenTransactions) renderTransactions('token_transaction_container', tokenTransactions)
} catch (e) {
console.log(e)
renderElem(getRef("page_container"), html`${render.errorPage(e)}`);
} }
break })
router.addRoute('contract', async state => {
case "contract": { const [contractId] = state.wildcards
if (!contractId) return;
// todo: load contract variable dynamically // todo: load contract variable dynamically
if (!subPageId1) return; const contract = splitContractNameAddress(contractId);
const contract = splitContractNameAddress(subPageId1);
let [contractInfo, contractTransactions, contractParticipants] = await Promise.all([getContractInfo(contract), getContractTransactions(contract), getContractParticipants(contract)]) let [contractInfo, contractTransactions, contractParticipants] = await Promise.all([getContractInfo(contract), getContractTransactions(contract), getContractParticipants(contract)])
// todo : check the type of contract & then further checks like fetching details of contractParticipant // todo : check the type of contract & then further checks like fetching details of contractParticipant
getRef("page_container").append(render.contractPage(contractInfo)); getRef("page_container").append(render.contractPage(contractInfo));
@ -373,18 +399,17 @@
frag.append(render.contractChoiceCard(participantFloAddress, tokenIdentification, userChoice, tokenAmount, winningAmount)) frag.append(render.contractChoiceCard(participantFloAddress, tokenIdentification, userChoice, tokenAmount, winningAmount))
}) })
document.getElementById('winners_container').append(frag) document.getElementById('winners_container').append(frag)
} })
break;
case "block": {
if (!subPageId1) return;
let [blockInfo, blockTransactions] = await Promise.all([getBlockInfo(subPageId1), getBlockTransactions(subPageId1)])
getRef("page_title").textContent = "block";
renderElem(getRef("page_container"), html`${render.blockPage(blockInfo)}`);
renderTransactions('block_transaction_container', blockTransactions)
}
break
case "blocks": { router.addRoute('block', async state => {
const [blockId] = state.wildcards
if (!blockId) return;
let [blockInfo, blockTxs] = await Promise.all([getBlockInfo(blockId), getBlockTxs(blockId)])
renderElem(getRef("page_container"), html`${render.blockPage(blockInfo)}`);
getRef("page_title").textContent = 'Block'
renderTransactions('block_transaction_container', blockTxs)
})
router.addRoute('blocks', async state => {
let allBlocks = await getAllBlocks(100); let allBlocks = await getAllBlocks(100);
getRef("page_title").textContent = "All Blocks"; getRef("page_title").textContent = "All Blocks";
const renderedBlocks = allBlocks.map(block => render.blockCard(block)) const renderedBlocks = allBlocks.map(block => render.blockCard(block))
@ -393,62 +418,30 @@
${renderedBlocks} ${renderedBlocks}
</div> </div>
`) `)
})
} router.addRoute('transactions', async state => {
break
case "transactions": {
let allTxs = await getAllTxs(); let allTxs = await getAllTxs();
getRef("page_title").textContent = "All Transactions"; getRef("page_title").textContent = "All Transactions";
renderElem(getRef("page_container"), html` renderElem(getRef("page_container"), html`
<div id="all_transactions_page" class="page transaction-container"> </div> <div id="all_transactions_page" class="page transaction-container"> </div>
`) `)
renderTransactions('all_transactions_page', allTxs) renderTransactions('all_transactions_page', allTxs)
} })
break router.addRoute('transaction', async state => {
case "transaction": { const [txId] = state.wildcards
if (!subPageId1) return if (!txId) return
const [status, txInfo] = await getTxInfo(subPageId1); const [status, txInfo] = await getTxInfo(txId);
if (status) { if (status) {
renderElem(getRef("page_container"), html`${render.transactionPage(txInfo)}`); renderElem(getRef("page_container"), html`${render.transactionPage(txInfo)}`);
getRef("page_title").textContent = "transaction"; getRef("page_title").textContent = "transaction";
} else { } else {
render('error_page', txInfo) renderElem(getRef("page_container"), html`${render.errorPage(txInfo)}`);
}
}
break
case 'error_page': {
getRef("page_container").append(render.errorPage(field));
}
break;
}
switch (appState.lastPage) {
case 'intern':
routingAnimation.in = slideInRight;
routingAnimation.out = slideOutRight;
break;
}
switch (pageId) {
case 'intern':
routingAnimation.in = slideInLeft;
routingAnimation.out = slideOutLeft;
break;
}
loading(false)
if (appState.lastPage !== pageId) {
// if (appState.lastPage) {
// getRef(appState.lastPage).animate(routingAnimation.out, { duration: floGlobals.prefersReducedMotion ? 0 : 150, fill: 'forwards', easing: 'ease' }).onfinish = (e) => {
// e.target.effect.target.classList.add('hidden')
// }
// }
// getRef(pageId).classList.remove('hidden')
// getRef(pageId).animate(routingAnimation.in, { duration: floGlobals.prefersReducedMotion ? 0 : 150, fill: 'forwards', easing: 'ease' }).onfinish = (e) => {
// appState.lastPage = pageId
// }
}
} }
})
router.addRoute('404', state => {
renderElem(getRef("page_container"), html`${render.errorPage('404 Not Found')}`);
})
function loading(show = true) { function loading(show = true) {
if (show) { if (show) {
getRef('loading').classList.remove('hidden') getRef('loading').classList.remove('hidden')
@ -1182,23 +1175,27 @@
} }
function getTokenInfo(thisToken) { function getTokenInfo(thisToken) {
return fetchJson( return new Promise((resolve, reject) => {
fetchJson(
`${tokenApiUrl}/api/v1.0/getTokenInfo?token=${thisToken.toLowerCase()}` `${tokenApiUrl}/api/v1.0/getTokenInfo?token=${thisToken.toLowerCase()}`
) ).then(function (tokenInfo) {
.then(function (tokenInfo) { if (tokenInfo.result === "error")
reject(tokenInfo.description);
let associatedSC = {}; let associatedSC = {};
for (let i = 0, associatedScList = tokenInfo["associatedSmartContracts"]; i < associatedScList.length; i++) { tokenInfo.associatedSmartContracts.forEach((sc) => {
associatedSC[`${associatedScList[i]["contractName"]}-${associatedScList[i]["contractAddress"]}`] = associatedScList[i]; associatedSC[`${sc.contractName}-${sc.contractAddress}`] = sc;
} });
let obj = { resolve({
token: tokenInfo["token"], token: tokenInfo["token"],
supply: tokenInfo["tokenSupply"], supply: tokenInfo["tokenSupply"],
incAddress: tokenInfo["incorporationAddress"], incAddress: tokenInfo["incorporationAddress"],
associatedContracts: associatedSC, associatedContracts: associatedSC,
blockchainReference: tokenInfo["blockchainReference"], blockchainReference: tokenInfo["blockchainReference"],
};
return obj;
}); });
}).catch((err) => {
reject(err);
});
})
} }
async function getTokenBalances(tokenName) { async function getTokenBalances(tokenName) {