generated from nathanwoodburn/python-webserver-template
feat: Add scroll when viewing a mempool tx
This commit is contained in:
@@ -89,6 +89,10 @@ main {
|
|||||||
padding: 2rem 0;
|
padding: 2rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
section {
|
||||||
|
scroll-margin-top: 140px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Cards */
|
/* Cards */
|
||||||
.card {
|
.card {
|
||||||
background: var(--card-bg);
|
background: var(--card-bg);
|
||||||
@@ -255,12 +259,16 @@ main {
|
|||||||
border: 1px solid var(--card-border);
|
border: 1px solid var(--card-border);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
margin-bottom: 0.75rem;
|
margin-bottom: 0.75rem;
|
||||||
transition: border-color 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
animation: staggerFade 0.4s ease forwards;
|
animation: staggerFade 0.4s ease forwards;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tx-item:hover {
|
.tx-item:hover {
|
||||||
border-color: rgba(139, 92, 246, 0.3);
|
border-color: rgba(139, 92, 246, 0.3);
|
||||||
|
background: rgba(139, 92, 246, 0.05);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.tx-hash {
|
.tx-hash {
|
||||||
@@ -708,6 +716,38 @@ a:hover {
|
|||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Loading Spinner */
|
||||||
|
.loading-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 3rem;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
animation: fadeIn 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-spinner {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border: 3px solid rgba(139, 92, 246, 0.1);
|
||||||
|
border-radius: 50%;
|
||||||
|
border-top-color: var(--accent-color);
|
||||||
|
animation: spin 1s cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-text {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-weight: 500;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
animation: pulse 1.5s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
to { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
/* New Animations */
|
/* New Animations */
|
||||||
@keyframes slideUp {
|
@keyframes slideUp {
|
||||||
from {
|
from {
|
||||||
|
|||||||
@@ -236,7 +236,6 @@
|
|||||||
document.getElementById('tx-input').value = txId;
|
document.getElementById('tx-input').value = txId;
|
||||||
document.querySelector('[data-tab="tx"]').click();
|
document.querySelector('[data-tab="tx"]').click();
|
||||||
searchTx();
|
searchTx();
|
||||||
document.querySelector('.search-section').scrollIntoView({ behavior: 'smooth' });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format mempool data nicely
|
// Format mempool data nicely
|
||||||
@@ -254,9 +253,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="tx-list">
|
<div class="tx-list">
|
||||||
${mempool.map(txId => `
|
${mempool.map(txId => `
|
||||||
<div class="tx-item">
|
<div class="tx-item" onclick="openTx('${txId}')">
|
||||||
<span class="tx-hash mono">${txId}</span>
|
<span class="tx-hash mono">${txId}</span>
|
||||||
<button class="tx-view-btn" onclick="openTx('${txId}')">View</button>
|
|
||||||
</div>
|
</div>
|
||||||
`).join('')}
|
`).join('')}
|
||||||
</div>
|
</div>
|
||||||
@@ -924,6 +922,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Show loading animation
|
||||||
|
function showLoading(elementId) {
|
||||||
|
const element = document.getElementById(elementId);
|
||||||
|
element.style.display = 'block';
|
||||||
|
element.innerHTML = `
|
||||||
|
<div class="loading-container">
|
||||||
|
<div class="loading-spinner"></div>
|
||||||
|
<div class="loading-text">Searching Fire...</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
// Load status on page load
|
// Load status on page load
|
||||||
async function loadStatus() {
|
async function loadStatus() {
|
||||||
const chainStatus = await apiCall('chain');
|
const chainStatus = await apiCall('chain');
|
||||||
@@ -948,6 +958,8 @@
|
|||||||
alert('Please enter a block height or hash');
|
alert('Please enter a block height or hash');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
showLoading('block-result');
|
||||||
updateURL('block', blockId);
|
updateURL('block', blockId);
|
||||||
const data = await apiCall(`block/${blockId}`);
|
const data = await apiCall(`block/${blockId}`);
|
||||||
|
|
||||||
@@ -966,6 +978,8 @@
|
|||||||
alert('Please enter a block height or hash');
|
alert('Please enter a block height or hash');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
showLoading('block-result');
|
||||||
updateURL('header', blockId);
|
updateURL('header', blockId);
|
||||||
const data = await apiCall(`header/${blockId}`);
|
const data = await apiCall(`header/${blockId}`);
|
||||||
|
|
||||||
@@ -984,11 +998,17 @@
|
|||||||
alert('Please enter a transaction ID');
|
alert('Please enter a transaction ID');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const resultElement = document.getElementById('tx-result');
|
||||||
|
showLoading('tx-result');
|
||||||
|
|
||||||
|
// Scroll to the search section
|
||||||
|
document.querySelector('.search-section').scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||||
|
|
||||||
updateURL('tx', txId);
|
updateURL('tx', txId);
|
||||||
const data = await apiCall(`tx/${txId}`);
|
const data = await apiCall(`tx/${txId}`);
|
||||||
|
|
||||||
// Use formatted display instead of raw JSON
|
// Use formatted display instead of raw JSON
|
||||||
const resultElement = document.getElementById('tx-result');
|
|
||||||
if (data.error) {
|
if (data.error) {
|
||||||
resultElement.innerHTML = `<div class="error">Error: ${data.error}</div>`;
|
resultElement.innerHTML = `<div class="error">Error: ${data.error}</div>`;
|
||||||
} else {
|
} else {
|
||||||
@@ -1002,6 +1022,8 @@
|
|||||||
alert('Please enter an address');
|
alert('Please enter an address');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
showLoading('address-result');
|
||||||
updateURL('address', address);
|
updateURL('address', address);
|
||||||
const data = await apiCall(`tx/address/${address}`);
|
const data = await apiCall(`tx/address/${address}`);
|
||||||
|
|
||||||
@@ -1020,6 +1042,8 @@
|
|||||||
alert('Please enter an address');
|
alert('Please enter an address');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
showLoading('address-result');
|
||||||
updateURL('address', address);
|
updateURL('address', address);
|
||||||
const data = await apiCall(`coin/address/${address}`);
|
const data = await apiCall(`coin/address/${address}`);
|
||||||
|
|
||||||
@@ -1038,6 +1062,8 @@
|
|||||||
alert('Please enter a name');
|
alert('Please enter a name');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
showLoading('name-result');
|
||||||
const punyName = toPunycode(name);
|
const punyName = toPunycode(name);
|
||||||
updateURL('name', punyName);
|
updateURL('name', punyName);
|
||||||
const data = await apiCall(`name/${punyName}`);
|
const data = await apiCall(`name/${punyName}`);
|
||||||
@@ -1057,6 +1083,8 @@
|
|||||||
alert('Please enter a name');
|
alert('Please enter a name');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
showLoading('name-result');
|
||||||
const punyName = toPunycode(name);
|
const punyName = toPunycode(name);
|
||||||
const data = await apiCall(`nameresource/${punyName}`);
|
const data = await apiCall(`nameresource/${punyName}`);
|
||||||
|
|
||||||
@@ -1075,6 +1103,8 @@
|
|||||||
alert('Please enter a name');
|
alert('Please enter a name');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
showLoading('name-result');
|
||||||
const punyName = toPunycode(name);
|
const punyName = toPunycode(name);
|
||||||
const data = await apiCall(`namesummary/${punyName}`);
|
const data = await apiCall(`namesummary/${punyName}`);
|
||||||
|
|
||||||
@@ -1093,6 +1123,8 @@
|
|||||||
alert('Please enter a name hash');
|
alert('Please enter a name hash');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
showLoading('name-result');
|
||||||
const data = await apiCall(`namehash/${nameHash}`);
|
const data = await apiCall(`namehash/${nameHash}`);
|
||||||
|
|
||||||
// Check if result is valid and redirect to name page
|
// Check if result is valid and redirect to name page
|
||||||
|
|||||||
Reference in New Issue
Block a user