Fix options select UI and false contract-missing quotes.
Keep the order host out of tbody wipes, sync pick-button labels, and retry/fallback OKX meta under rate limits so live contracts are not reported as missing. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -3754,8 +3754,11 @@ html[data-theme="light"] .opt-pending-item {
|
||||
.options-page-wrap .opt-order-panel-inner .opt-order-title {
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
.opt-order-panel-host {
|
||||
display: none;
|
||||
.opt-order-panel-host:not([hidden]) {
|
||||
display: block;
|
||||
}
|
||||
.opt-order-panel-host[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
.options-order-grid {
|
||||
display: grid;
|
||||
|
||||
@@ -27,11 +27,16 @@
|
||||
let lastGoodPositionsAt = 0;
|
||||
let positionsRefreshSeq = 0;
|
||||
let chainLoadSeq = 0;
|
||||
let selectSeq = 0;
|
||||
let refreshAllTimer = null;
|
||||
let pendingRefreshTimer = null;
|
||||
let pendingTtlSeconds = 600;
|
||||
const POSITIONS_STALE_MS = 45000;
|
||||
const PENDING_POLL_MS = 8000;
|
||||
const orderPanelHome = (function () {
|
||||
const host = document.getElementById("opt-order-panel-host");
|
||||
return host ? host.parentElement : null;
|
||||
})();
|
||||
|
||||
function fmt(v, d) {
|
||||
if (v === null || v === undefined || Number.isNaN(Number(v))) return "—";
|
||||
@@ -75,59 +80,71 @@
|
||||
return document.getElementById("opt-order-panel-host");
|
||||
}
|
||||
|
||||
function syncPickButtons(instId) {
|
||||
document.querySelectorAll(".opt-pick-btn").forEach(function (btn) {
|
||||
const on = !!instId && btn.getAttribute("data-inst") === instId;
|
||||
btn.classList.toggle("active", on);
|
||||
btn.disabled = false;
|
||||
if (!btn.dataset.origText) btn.dataset.origText = "选择";
|
||||
btn.textContent = on ? "已选" : btn.dataset.origText;
|
||||
});
|
||||
}
|
||||
|
||||
function parkOrderPanel() {
|
||||
stopPendingOrdersPoll();
|
||||
const panel = orderPanel();
|
||||
const host = orderPanelHost();
|
||||
// 先把面板移回 host,再删行内 tr,避免 tbody.innerHTML 清空时把 #opt-order-panel 一起销毁
|
||||
if (panel && host) {
|
||||
if (panel.parentElement !== host) host.appendChild(panel);
|
||||
host.hidden = true;
|
||||
panel.style.display = "none";
|
||||
// 把整块 host(含面板)移回原位,再删行内 tr,避免 tbody 重绘销毁下单 DOM
|
||||
if (host && orderPanelHome && host.parentElement !== orderPanelHome) {
|
||||
orderPanelHome.appendChild(host);
|
||||
} else if (panel && host && panel.parentElement !== host) {
|
||||
host.appendChild(panel);
|
||||
}
|
||||
if (host) host.hidden = true;
|
||||
if (panel) panel.style.display = "none";
|
||||
const inline = document.querySelector(".opt-order-inline-row");
|
||||
if (inline) inline.remove();
|
||||
document.querySelectorAll(".opt-strike-row").forEach(function (r) {
|
||||
r.classList.remove("opt-row-selected");
|
||||
});
|
||||
document.querySelectorAll(".opt-pick-btn").forEach(function (b) {
|
||||
b.classList.remove("active");
|
||||
b.disabled = false;
|
||||
if (b.dataset.origText) b.textContent = b.dataset.origText;
|
||||
});
|
||||
syncPickButtons(null);
|
||||
}
|
||||
|
||||
function placeOrderPanelAfter(instId) {
|
||||
const panel = orderPanel();
|
||||
if (!panel || !instId) return;
|
||||
const host = orderPanelHost();
|
||||
if (!panel || !host || !instId) {
|
||||
syncPickButtons(instId || null);
|
||||
return false;
|
||||
}
|
||||
const row =
|
||||
document.querySelector('#opt-strike-tbody tr.opt-strike-row[data-inst="' + CSS.escape(instId) + '"]') ||
|
||||
document.querySelector('#opt-strike-tbody tr.opt-strike-row[data-call-inst="' + CSS.escape(instId) + '"]') ||
|
||||
document.querySelector('#opt-strike-tbody tr.opt-strike-row[data-put-inst="' + CSS.escape(instId) + '"]');
|
||||
if (!row) return;
|
||||
if (!row) {
|
||||
syncPickButtons(null);
|
||||
return false;
|
||||
}
|
||||
document.querySelectorAll(".opt-strike-row").forEach(function (r) {
|
||||
r.classList.toggle("opt-row-selected", r === row);
|
||||
});
|
||||
document.querySelectorAll(".opt-pick-btn").forEach(function (btn) {
|
||||
const on = btn.getAttribute("data-inst") === instId;
|
||||
btn.classList.toggle("active", on);
|
||||
if (!btn.dataset.origText) btn.dataset.origText = btn.textContent;
|
||||
if (on) btn.textContent = "已选";
|
||||
});
|
||||
syncPickButtons(instId);
|
||||
const oldInline = document.querySelector(".opt-order-inline-row");
|
||||
if (oldInline) oldInline.remove();
|
||||
if (panel.parentElement !== host) host.appendChild(panel);
|
||||
const tr = document.createElement("tr");
|
||||
tr.className = "opt-order-inline-row";
|
||||
const td = document.createElement("td");
|
||||
td.colSpan = strikeTableColspan();
|
||||
td.appendChild(panel);
|
||||
td.appendChild(host);
|
||||
tr.appendChild(td);
|
||||
row.after(tr);
|
||||
host.hidden = false;
|
||||
panel.style.display = "";
|
||||
orderPanelHost().hidden = true;
|
||||
tr.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
||||
refreshPendingOrders();
|
||||
startPendingOrdersPoll();
|
||||
return true;
|
||||
}
|
||||
|
||||
function fmtPendingAge(sec) {
|
||||
@@ -920,6 +937,7 @@
|
||||
}
|
||||
|
||||
async function selectContract(instId, pickBtn, silent) {
|
||||
const seq = ++selectSeq;
|
||||
state.selectedInst = instId;
|
||||
placeOrderPanelAfter(instId);
|
||||
if (pickBtn) {
|
||||
@@ -929,15 +947,14 @@
|
||||
}
|
||||
try {
|
||||
const d = await apiJson(quoteUrl(instId));
|
||||
if (seq !== selectSeq) return d;
|
||||
fillOrderPanel(d);
|
||||
return d;
|
||||
} finally {
|
||||
if (pickBtn) {
|
||||
pickBtn.disabled = false;
|
||||
pickBtn.textContent = "已选";
|
||||
pickBtn.classList.add("active");
|
||||
if (seq === selectSeq) {
|
||||
syncPickButtons(instId);
|
||||
if (!silent) placeOrderPanelAfter(instId);
|
||||
}
|
||||
if (!silent) placeOrderPanelAfter(instId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user