Compare commits
3 Commits
8ee5cc3861
...
5ece854340
| Author | SHA1 | Date | |
|---|---|---|---|
| 5ece854340 | |||
| 2ef7de4e58 | |||
| 16c045e7cc |
@@ -342,6 +342,38 @@
|
|||||||
transform: rotate(180deg);
|
transform: rotate(180deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Refresh button: hidden by default, revealed only when the card is open.
|
||||||
|
Larger than the desktop icon to give a comfortable touch target (≥44px). */
|
||||||
|
.m-card__head .m-refresh-icon {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-card.is-open .m-card__head .m-refresh-icon {
|
||||||
|
display: grid;
|
||||||
|
width: 44px;
|
||||||
|
height: 44px;
|
||||||
|
margin-left: 0;
|
||||||
|
font-size: 15px;
|
||||||
|
opacity: 0.7;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-card.is-open .m-card__head .m-refresh-icon:active {
|
||||||
|
opacity: 1;
|
||||||
|
color: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Spin only the icon glyph, not the 44px button box — otherwise the button's
|
||||||
|
lingering touch-hover frame (background + border) rotates too, which looks odd. */
|
||||||
|
.m-card.is-open .m-card__head .m-refresh-icon.spinning {
|
||||||
|
animation: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.m-card.is-open .m-card__head .m-refresh-icon.spinning i {
|
||||||
|
display: inline-block;
|
||||||
|
animation: spin 0.8s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
.m-card__body {
|
.m-card__body {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: minmax(0, 1fr) auto;
|
grid-template-columns: minmax(0, 1fr) auto;
|
||||||
|
|||||||
+10
-4
@@ -131,10 +131,16 @@ async function clearCache() {
|
|||||||
// Refreshes both the current rating and the prediction in one click, then
|
// Refreshes both the current rating and the prediction in one click, then
|
||||||
// re-swaps the table so every derived value (deltas, pills, sparkline) reflects
|
// re-swaps the table so every derived value (deltas, pills, sparkline) reflects
|
||||||
// the new state. Cheaper than fine-grained DOM updates and guaranteed consistent
|
// the new state. Cheaper than fine-grained DOM updates and guaranteed consistent
|
||||||
// because the server renders the truth.
|
// because the server renders the truth. The mobile cards partial is included
|
||||||
|
// inside ratings-table, so swapping #ratings-table re-renders both views at once.
|
||||||
async function refreshPlayerData(pdgaNumber) {
|
async function refreshPlayerData(pdgaNumber) {
|
||||||
const icon = document.querySelector(`#row-${pdgaNumber} .cell-actions .refresh-icon`);
|
// The desktop row exists in the DOM even on mobile (hidden via CSS), so spin
|
||||||
if (icon) icon.classList.add('spinning');
|
// both possible icons; only the one visible in the active viewport is seen.
|
||||||
|
const icons = [
|
||||||
|
document.querySelector(`#row-${pdgaNumber} .cell-actions .refresh-icon`),
|
||||||
|
document.querySelector(`#m-card-${pdgaNumber} .m-refresh-icon`)
|
||||||
|
].filter(Boolean);
|
||||||
|
icons.forEach(icon => icon.classList.add('spinning'));
|
||||||
try {
|
try {
|
||||||
await Promise.allSettled([
|
await Promise.allSettled([
|
||||||
fetch(`/api/refresh-player/${pdgaNumber}`, { method: 'POST' }),
|
fetch(`/api/refresh-player/${pdgaNumber}`, { method: 'POST' }),
|
||||||
@@ -144,7 +150,7 @@ async function refreshPlayerData(pdgaNumber) {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error refreshing player data:', error);
|
console.error('Error refreshing player data:', error);
|
||||||
} finally {
|
} finally {
|
||||||
if (icon) icon.classList.remove('spinning');
|
icons.forEach(icon => icon.classList.remove('spinning'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,11 @@ function renderSparkline(values, opts) {
|
|||||||
<span class="m-player-name"><%= player.name %></span>
|
<span class="m-player-name"><%= player.name %></span>
|
||||||
<span class="m-pdga-num">#<%= player.pdgaNumber %></span>
|
<span class="m-pdga-num">#<%= player.pdgaNumber %></span>
|
||||||
</div>
|
</div>
|
||||||
|
<button class="icon-btn refresh-icon m-refresh-icon" type="button"
|
||||||
|
onclick="event.stopPropagation(); refreshPlayerData(<%= player.pdgaNumber %>)"
|
||||||
|
title="Refresh rating + prediction" aria-label="Refresh rating and prediction">
|
||||||
|
<i class="fas fa-sync-alt"></i>
|
||||||
|
</button>
|
||||||
<span class="m-chevron">▼</span>
|
<span class="m-chevron">▼</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user