market revert fix
This commit is contained in:
128
static/js/api.js
128
static/js/api.js
@@ -261,132 +261,4 @@ window.requestLiveSync = async function() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
window.scanMarket = async function() {
|
|
||||||
if (!window.clientOnline) return alert('Το script είναι offline.');
|
|
||||||
const town = window.getSelectedTown();
|
|
||||||
if (!town) return alert('Select a town first.');
|
|
||||||
|
|
||||||
try {
|
|
||||||
const res = await fetch('/dashboard/commands', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({
|
|
||||||
town_id: town.town_id,
|
|
||||||
town_name: town.town_name,
|
|
||||||
type: 'scan_market',
|
|
||||||
payload: {},
|
|
||||||
player_id: window.PLAYER_ID
|
|
||||||
})
|
|
||||||
});
|
|
||||||
const data = await res.json();
|
|
||||||
if (data.ok) {
|
|
||||||
document.getElementById('market-offers-content').innerHTML = '<span style="color:#c8a44a;">⏳ Αναζήτηση σε εξέλιξη... Περιμένετε!</span>';
|
|
||||||
window.fetchLog();
|
|
||||||
|
|
||||||
// Auto fetch market data every 2 seconds for the next 15 seconds
|
|
||||||
let attempts = 0;
|
|
||||||
const interval = setInterval(() => {
|
|
||||||
window.fetchMarketData();
|
|
||||||
attempts++;
|
|
||||||
if (attempts > 7) clearInterval(interval);
|
|
||||||
}, 2000);
|
|
||||||
} else {
|
|
||||||
alert('Error: ' + JSON.stringify(data));
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
alert('Failed to send scan_market command: ' + e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
window.acceptMarketOffer = async function(offer_id, amount) {
|
|
||||||
if (!window.clientOnline) return alert('Το script είναι offline.');
|
|
||||||
const town = window.getSelectedTown();
|
|
||||||
if (!town) return alert('Select a town first.');
|
|
||||||
|
|
||||||
try {
|
|
||||||
const res = await fetch('/dashboard/commands', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({
|
|
||||||
town_id: town.town_id,
|
|
||||||
town_name: town.town_name,
|
|
||||||
type: 'accept_market_offer',
|
|
||||||
payload: { offer_id: parseInt(offer_id), amount: parseInt(amount) },
|
|
||||||
player_id: window.PLAYER_ID
|
|
||||||
})
|
|
||||||
});
|
|
||||||
const data = await res.json();
|
|
||||||
if (data.ok) {
|
|
||||||
window.fetchLog();
|
|
||||||
alert(`Εστάλη εντολή αποδοχής για την προσφορά #${offer_id}!`);
|
|
||||||
// Update local UI immediately so user doesn't double click
|
|
||||||
document.getElementById(`offer-btn-${offer_id}`).disabled = true;
|
|
||||||
document.getElementById(`offer-btn-${offer_id}`).innerText = '⏳';
|
|
||||||
} else {
|
|
||||||
alert('Error: ' + JSON.stringify(data));
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
alert('Failed to send accept_market_offer command: ' + e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
window.lastMarketUpdate = null;
|
|
||||||
window.fetchMarketData = async function() {
|
|
||||||
try {
|
|
||||||
const res = await fetch('/dashboard/market-data?player_id=' + window.PLAYER_ID);
|
|
||||||
const data = await res.json();
|
|
||||||
if (!data || !data.data || !data.data.offers) return;
|
|
||||||
|
|
||||||
// Only re-render if the timestamp has changed
|
|
||||||
if (window.lastMarketUpdate === data.updated_at) return;
|
|
||||||
window.lastMarketUpdate = data.updated_at;
|
|
||||||
|
|
||||||
const offers = data.data.offers;
|
|
||||||
if (offers.length === 0) {
|
|
||||||
document.getElementById('market-offers-content').innerHTML = '<span style="color:#aaa;">Καμία διαθέσιμη προσφορά.</span>';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let html = `<table style="width:100%; border-collapse:collapse; font-size:0.75rem;">
|
|
||||||
<tr style="border-bottom:1px solid #2a4a6a; color:#c8a44a;">
|
|
||||||
<th style="padding:4px; text-align:left;">Παίκτης</th>
|
|
||||||
<th style="padding:4px; text-align:right;">Προσφέρει</th>
|
|
||||||
<th style="padding:4px; text-align:right;">Ζητάει</th>
|
|
||||||
<th style="padding:4px; text-align:center;">Λόγος</th>
|
|
||||||
<th style="padding:4px; text-align:center;">Διάρκεια</th>
|
|
||||||
<th style="padding:4px;"></th>
|
|
||||||
</tr>`;
|
|
||||||
|
|
||||||
for (const off of offers) {
|
|
||||||
const ratio = (off.demand / off.offer).toFixed(2);
|
|
||||||
// Map resources to emoji
|
|
||||||
const offerEmoji = off.offer_type === 'wood' ? '🪵' : off.offer_type === 'stone' ? '🪨' : '🪙';
|
|
||||||
const demandEmoji = off.demand_type === 'wood' ? '🪵' : off.demand_type === 'stone' ? '🪨' : '🪙';
|
|
||||||
|
|
||||||
let seconds = off.delivery_time;
|
|
||||||
let h = Math.floor(seconds / 3600);
|
|
||||||
let m = Math.floor((seconds % 3600) / 60);
|
|
||||||
let timeStr = `${h}h ${m}m`;
|
|
||||||
|
|
||||||
html += `<tr style="border-bottom:1px solid #1a3a5a;">
|
|
||||||
<td style="padding:6px 4px; color:#ddd;">${off.player_name || 'NPC'}</td>
|
|
||||||
<td style="padding:6px 4px; text-align:right; color:#88aa55;">${off.offer} ${offerEmoji}</td>
|
|
||||||
<td style="padding:6px 4px; text-align:right; color:#ee4444;">${off.demand} ${demandEmoji}</td>
|
|
||||||
<td style="padding:6px 4px; text-align:center; color:#aaa;">1 : ${ratio}</td>
|
|
||||||
<td style="padding:6px 4px; text-align:center; color:#aaa;">${timeStr}</td>
|
|
||||||
<td style="padding:6px 4px; text-align:right;">
|
|
||||||
<button id="offer-btn-${off.id}" class="btn btn-gold btn-sm" onclick="window.acceptMarketOffer(${off.id}, ${off.offer})">✓</button>
|
|
||||||
</td>
|
|
||||||
</tr>`;
|
|
||||||
}
|
|
||||||
html += '</table>';
|
|
||||||
|
|
||||||
// Add timestamp note
|
|
||||||
let d = new Date(data.updated_at + "Z"); // SQLite UTC
|
|
||||||
html += `<div style="text-align:right; font-size:0.65rem; color:#666; margin-top:5px; padding-right:5px;">Τελευταία ανανέωση: ${d.toLocaleTimeString()}</div>`;
|
|
||||||
|
|
||||||
document.getElementById('market-offers-content').innerHTML = html;
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Failed to fetch market data:', e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -205,17 +205,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr style="border: 0; border-top: 1px solid #2a2a4a; margin: 15px 0 10px 0; width: 100%;"/>
|
|
||||||
<div style="display:flex; justify-content: space-between; align-items: center; width: 100%;">
|
|
||||||
<label style="color:#c8a44a; font-size: 0.8rem;">Λίστα Παζαριού (Προσφορές Άλλων)</label>
|
|
||||||
<div>
|
|
||||||
<span id="market-capacity-label" style="font-size:0.75rem; color:#aaa; margin-right: 10px;">Χωρητικότητα: 0</span>
|
|
||||||
<button class="btn btn-gold btn-sm" id="btn-scan-market" type="button" onclick="window.scanMarket()">Αναζήτηση (Scan)</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="market-offers-container" style="max-height: 300px; overflow-y: auto; width: 100%; margin-top: 10px; background: #0f2a50; border-radius: 4px; border: 1px solid #2a4a6a;">
|
|
||||||
<div id="market-offers-content" style="color: #888; font-size: 0.8rem; text-align: center; padding: 15px;">Πατήστε "Αναζήτηση" για να φορτώσετε τη λίστα.</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group" id="amount-group" style="display:none">
|
<div class="form-group" id="amount-group" style="display:none">
|
||||||
|
|||||||
Reference in New Issue
Block a user