Spaces:
Running
Running
fix: рынок читает новый формат базы (shops+listings), живые источники первыми
#3
by Iosteps - opened
- assets/market.js +46 -23
assets/market.js
CHANGED
|
@@ -58,6 +58,15 @@
|
|
| 58 |
return { '&': '&', '<': '<', '>': '>', '"': '"' }[c];
|
| 59 |
});
|
| 60 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
function money(n) { return String(n).replace(/\B(?=(\d{3})+(?!\d))/g, ' '); }
|
| 62 |
function catName(c) { return CATS[c] || c || 'Прочее'; }
|
| 63 |
|
|
@@ -165,50 +174,64 @@
|
|
| 165 |
if (lot) lot.classList.toggle('open');
|
| 166 |
});
|
| 167 |
|
| 168 |
-
var
|
| 169 |
-
|
| 170 |
'https://dfo.spaceghosts.com/vendors.json',
|
| 171 |
'https://api.allorigins.win/raw?url=' + encodeURIComponent('https://dfo.spaceghosts.com/vendors.json'),
|
| 172 |
'https://api.codetabs.com/v1/proxy?quest=' + encodeURIComponent('https://dfo.spaceghosts.com/vendors.json')
|
| 173 |
];
|
| 174 |
|
| 175 |
-
function
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
return fetch(u, { cache: 'no-store' }).then(function (r) {
|
| 180 |
-
if (!r.ok) throw new Error('HTTP ' + r.status);
|
| 181 |
-
return r.json();
|
| 182 |
-
});
|
| 183 |
-
});
|
| 184 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 185 |
return p;
|
| 186 |
}
|
| 187 |
|
| 188 |
-
function
|
| 189 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 190 |
buildControls();
|
| 191 |
-
var
|
| 192 |
document.getElementById('mk-updated').innerHTML =
|
| 193 |
-
(live ? 'Рынок онлайн' : 'Снимок рынка') + ': ' + (
|
| 194 |
-
' · <button class="mk-refresh" id="mk-refresh" type="button">обновить</button>
|
| 195 |
-
'<
|
|
|
|
| 196 |
var rb = document.getElementById('mk-refresh');
|
| 197 |
if (rb) rb.addEventListener('click', function () { load(true); });
|
| 198 |
update();
|
| 199 |
if (data.refreshMinutes && !load._t) {
|
| 200 |
-
load._t = setInterval(function () { load(
|
| 201 |
}
|
| 202 |
}
|
| 203 |
|
| 204 |
function load(manual) {
|
| 205 |
var note = document.getElementById('mk-updated');
|
| 206 |
if (manual && note) note.textContent = 'Обновляю рынок…';
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
.
|
| 210 |
-
|
| 211 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 212 |
});
|
| 213 |
}
|
| 214 |
|
|
|
|
| 58 |
return { '&': '&', '<': '<', '>': '>', '"': '"' }[c];
|
| 59 |
});
|
| 60 |
}
|
| 61 |
+
function norm(raw) {
|
| 62 |
+
return {
|
| 63 |
+
updatedAt: raw.updatedAt,
|
| 64 |
+
refreshMinutes: raw.refreshMinutes || 60,
|
| 65 |
+
listings: raw.listings || [],
|
| 66 |
+
vendors: raw.vendors || raw.shops || [],
|
| 67 |
+
coverage: raw.coverage || null
|
| 68 |
+
};
|
| 69 |
+
}
|
| 70 |
function money(n) { return String(n).replace(/\B(?=(\d{3})+(?!\d))/g, ' '); }
|
| 71 |
function catName(c) { return CATS[c] || c || 'Прочее'; }
|
| 72 |
|
|
|
|
| 174 |
if (lot) lot.classList.toggle('open');
|
| 175 |
});
|
| 176 |
|
| 177 |
+
var LOCAL_SRC = 'assets/vendors.json';
|
| 178 |
+
var LIVE_SOURCES = [
|
| 179 |
'https://dfo.spaceghosts.com/vendors.json',
|
| 180 |
'https://api.allorigins.win/raw?url=' + encodeURIComponent('https://dfo.spaceghosts.com/vendors.json'),
|
| 181 |
'https://api.codetabs.com/v1/proxy?quest=' + encodeURIComponent('https://dfo.spaceghosts.com/vendors.json')
|
| 182 |
];
|
| 183 |
|
| 184 |
+
function getJson(url) {
|
| 185 |
+
return fetch(url, { cache: 'no-store' }).then(function (r) {
|
| 186 |
+
if (!r.ok) throw new Error('HTTP ' + r.status + ' ' + url);
|
| 187 |
+
return r.json().then(function (j) { return { json: j, url: url }; });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 188 |
});
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
function tryChain(urls) {
|
| 192 |
+
var p = Promise.reject(new Error('no sources'));
|
| 193 |
+
urls.forEach(function (u) { p = p.catch(function () { return getJson(u); }); });
|
| 194 |
return p;
|
| 195 |
}
|
| 196 |
|
| 197 |
+
function fmtUpd(ts) {
|
| 198 |
+
if (!ts) return '—';
|
| 199 |
+
var d = new Date(ts);
|
| 200 |
+
if (isNaN(d.getTime())) return '—';
|
| 201 |
+
return d.toLocaleString('ru-RU', { day: 'numeric', month: 'long', hour: '2-digit', minute: '2-digit', second: '2-digit' });
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
function startData(pack, live) {
|
| 205 |
+
data = norm(pack.json);
|
| 206 |
buildControls();
|
| 207 |
+
var where = live ? ('живьём · ' + pack.url) : 'локальный снимок';
|
| 208 |
document.getElementById('mk-updated').innerHTML =
|
| 209 |
+
(live ? 'Рынок онлайн' : 'Снимок рынка') + ': ' + fmtUpd(data.updatedAt) +
|
| 210 |
+
' · <button class="mk-refresh" id="mk-refresh" type="button">обновить</button><br>' +
|
| 211 |
+
'<span class="mk-src">' + esc(where) + ' · каждые ' + (data.refreshMinutes || 60) + ' мин · данные ' +
|
| 212 |
+
'<a href="https://dfo.spaceghosts.com/#vendors" target="_blank" rel="noopener">Daggerfall Watch</a></span>';
|
| 213 |
var rb = document.getElementById('mk-refresh');
|
| 214 |
if (rb) rb.addEventListener('click', function () { load(true); });
|
| 215 |
update();
|
| 216 |
if (data.refreshMinutes && !load._t) {
|
| 217 |
+
load._t = setInterval(function () { load(false); }, Math.max(5, data.refreshMinutes) * 60000);
|
| 218 |
}
|
| 219 |
}
|
| 220 |
|
| 221 |
function load(manual) {
|
| 222 |
var note = document.getElementById('mk-updated');
|
| 223 |
if (manual && note) note.textContent = 'Обновляю рынок…';
|
| 224 |
+
// свежие источники первыми; локальный снимок — только страховка
|
| 225 |
+
tryChain(LIVE_SOURCES)
|
| 226 |
+
.then(function (pack) { startData(pack, true); })
|
| 227 |
+
.catch(function (errLive) {
|
| 228 |
+
getJson(LOCAL_SRC)
|
| 229 |
+
.then(function (pack) { startData(pack, false); })
|
| 230 |
+
.catch(function (err) {
|
| 231 |
+
if (note) note.textContent = 'Не удалось загрузить рынок (' + errLive.message + ').';
|
| 232 |
+
listEl.innerHTML = '<p class="note">Не удалось загрузить рынок (' + esc(errLive.message) +
|
| 233 |
+
'). Живые данные — на <a href="https://dfo.spaceghosts.com/#vendors" target="_blank" rel="noopener">dfo.spaceghosts.com</a>.</p>';
|
| 234 |
+
});
|
| 235 |
});
|
| 236 |
}
|
| 237 |
|