Move spot sell retry into positions header row per mockup.
Show trading-account coin balance with gradient retry button and icon refresh in the holdings title bar. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -3208,7 +3208,9 @@ html[data-theme="light"] .settings-side-export-label {
|
|||||||
margin: 0 0 8px;
|
margin: 0 0 8px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
.options-page-wrap .options-pos-head h2 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
.options-page-wrap .options-hint,
|
.options-page-wrap .options-hint,
|
||||||
.options-page-wrap #opt-index-line {
|
.options-page-wrap #opt-index-line {
|
||||||
font-size: 0.72rem;
|
font-size: 0.72rem;
|
||||||
@@ -3223,11 +3225,18 @@ html[data-theme="light"] .settings-side-export-label {
|
|||||||
min-height: 28px;
|
min-height: 28px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.options-page-wrap .options-pos-head .btn-secondary {
|
.options-page-wrap .options-pos-head .btn-secondary,
|
||||||
|
.options-page-wrap .options-pos-head .opt-pos-refresh-btn {
|
||||||
font-size: 0.72rem;
|
font-size: 0.72rem;
|
||||||
padding: 3px 10px;
|
padding: 3px 10px;
|
||||||
min-height: 26px;
|
min-height: 26px;
|
||||||
}
|
}
|
||||||
|
.options-page-wrap .options-pos-head .opt-pos-refresh-btn {
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1;
|
||||||
|
min-width: 32px;
|
||||||
|
padding: 4px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.options-funds-grid {
|
.options-funds-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
@@ -5233,24 +5242,6 @@ html[data-theme="light"] .opt-source-badge--oo {
|
|||||||
font-variant-numeric: tabular-nums;
|
font-variant-numeric: tabular-nums;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
.opt-spot-sell-banner {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
align-items: center;
|
|
||||||
gap: 10px 12px;
|
|
||||||
margin: 0 0 10px;
|
|
||||||
padding: 10px 12px;
|
|
||||||
border: 1px solid rgba(255, 170, 80, 0.45);
|
|
||||||
border-radius: 10px;
|
|
||||||
background: rgba(48, 32, 12, 0.55);
|
|
||||||
}
|
|
||||||
.opt-spot-sell-banner-text {
|
|
||||||
flex: 1;
|
|
||||||
min-width: 180px;
|
|
||||||
font-size: 0.82rem;
|
|
||||||
color: #f5d9b8;
|
|
||||||
line-height: 1.45;
|
|
||||||
}
|
|
||||||
.opt-target-monitors {
|
.opt-target-monitors {
|
||||||
margin: 0 0 10px;
|
margin: 0 0 10px;
|
||||||
padding: 10px 12px;
|
padding: 10px 12px;
|
||||||
@@ -5476,11 +5467,46 @@ html[data-theme="light"] .opt-source-badge--oo {
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
gap: 8px;
|
gap: 10px;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
.options-pos-head h2 {
|
.options-pos-head h2 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.options-pos-head-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
margin-left: auto;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
.opt-spot-sell-head {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.opt-spot-sell-avail {
|
||||||
|
font-size: 0.78rem;
|
||||||
|
color: #c9d6f5;
|
||||||
|
font-variant-numeric: tabular-nums;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.options-page-wrap .opt-spot-sell-retry-btn {
|
||||||
|
font-size: 0.72rem;
|
||||||
|
padding: 4px 12px;
|
||||||
|
min-height: 28px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.options-page-wrap .opt-pos-refresh-btn {
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1;
|
||||||
|
padding: 4px 10px;
|
||||||
|
min-width: 32px;
|
||||||
|
min-height: 28px;
|
||||||
}
|
}
|
||||||
.opt-pos-card {
|
.opt-pos-card {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
@@ -5854,12 +5880,8 @@ html[data-theme="light"] .options-page-wrap .pos-empty {
|
|||||||
color: #334155 !important;
|
color: #334155 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
html[data-theme="light"] .options-page-wrap .opt-spot-sell-banner {
|
html[data-theme="light"] .options-page-wrap .opt-spot-sell-avail {
|
||||||
border-color: rgba(180, 110, 40, 0.45);
|
color: #334155 !important;
|
||||||
background: rgba(255, 244, 228, 0.95);
|
|
||||||
}
|
|
||||||
html[data-theme="light"] .options-page-wrap .opt-spot-sell-banner-text {
|
|
||||||
color: #6a4a18;
|
|
||||||
}
|
}
|
||||||
html[data-theme="light"] .options-page-wrap .opt-target-monitors {
|
html[data-theme="light"] .options-page-wrap .opt-target-monitors {
|
||||||
background: #eef4fa !important;
|
background: #eef4fa !important;
|
||||||
|
|||||||
@@ -2166,7 +2166,7 @@
|
|||||||
if (ss && ss.ok && !ss.skipped) {
|
if (ss && ss.ok && !ss.skipped) {
|
||||||
okMsg += "\n已自动卖回 USDT";
|
okMsg += "\n已自动卖回 USDT";
|
||||||
} else if (ss && ss.bridge_status === "pending_sell_spot") {
|
} else if (ss && ss.bridge_status === "pending_sell_spot") {
|
||||||
okMsg += "\n卖回 USDT 失败,请点持仓区「重试卖回」";
|
okMsg += "\n卖回 USDT 失败,请点持仓标题栏「重试卖回」";
|
||||||
}
|
}
|
||||||
alert(okMsg);
|
alert(okMsg);
|
||||||
} else {
|
} else {
|
||||||
@@ -2210,6 +2210,14 @@
|
|||||||
setOptionsPosTab(state.posTab);
|
setOptionsPosTab(state.posTab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function fmtCoinAvail(v) {
|
||||||
|
const n = Number(v);
|
||||||
|
if (!Number.isFinite(n) || n <= 0) return "0";
|
||||||
|
if (n >= 1) return n.toFixed(6).replace(/\.?0+$/, "");
|
||||||
|
if (n >= 0.000001) return n.toFixed(6).replace(/\.?0+$/, "");
|
||||||
|
return n.toFixed(8).replace(/\.?0+$/, "");
|
||||||
|
}
|
||||||
|
|
||||||
function shouldShowSpotSellBanner(d, positions) {
|
function shouldShowSpotSellBanner(d, positions) {
|
||||||
if (!isCoinMarginMode()) return false;
|
if (!isCoinMarginMode()) return false;
|
||||||
const ss = d && d.spot_sell;
|
const ss = d && d.spot_sell;
|
||||||
@@ -2219,7 +2227,7 @@
|
|||||||
if (ss.bridge_status === "pending_sell_spot") return true;
|
if (ss.bridge_status === "pending_sell_spot") return true;
|
||||||
const eth = Number(ss.trading_eth || 0);
|
const eth = Number(ss.trading_eth || 0);
|
||||||
const btc = Number(ss.trading_btc || 0);
|
const btc = Number(ss.trading_btc || 0);
|
||||||
return eth > 0.00001 || btc > 0.000001;
|
return eth > 1e-12 || btc > 1e-12;
|
||||||
}
|
}
|
||||||
|
|
||||||
function spotSellUnderlying(ss) {
|
function spotSellUnderlying(ss) {
|
||||||
@@ -2227,18 +2235,19 @@
|
|||||||
if (ss.bridge_underlying) return String(ss.bridge_underlying).toUpperCase();
|
if (ss.bridge_underlying) return String(ss.bridge_underlying).toUpperCase();
|
||||||
const eth = Number(ss.trading_eth || 0);
|
const eth = Number(ss.trading_eth || 0);
|
||||||
const btc = Number(ss.trading_btc || 0);
|
const btc = Number(ss.trading_btc || 0);
|
||||||
if (btc > eth && btc > 0.000001) return "BTC";
|
if (btc > eth && btc > 1e-12) return "BTC";
|
||||||
if (eth > 0.00001) return "ETH";
|
if (eth > 1e-12) return "ETH";
|
||||||
return (ss.default_underly || state.underlying || "ETH").toUpperCase();
|
return (ss.default_underly || state.underlying || "ETH").toUpperCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
function paintSpotSellBanner(d, positions) {
|
function paintSpotSellBanner(d, positions) {
|
||||||
const banner = document.getElementById("opt-spot-sell-banner");
|
const head = document.getElementById("opt-spot-sell-head");
|
||||||
const textEl = document.getElementById("opt-spot-sell-banner-text");
|
const availEl = document.getElementById("opt-spot-sell-avail-text");
|
||||||
if (!banner || !textEl) return;
|
const retryBtn = document.getElementById("opt-spot-sell-retry-btn");
|
||||||
|
if (!head || !availEl || !retryBtn) return;
|
||||||
const show = shouldShowSpotSellBanner(d, positions);
|
const show = shouldShowSpotSellBanner(d, positions);
|
||||||
if (!show) {
|
if (!show) {
|
||||||
banner.hidden = true;
|
head.hidden = true;
|
||||||
state.spotSellUnderlying = null;
|
state.spotSellUnderlying = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2248,15 +2257,9 @@
|
|||||||
const eth = Number(ss.trading_eth || 0);
|
const eth = Number(ss.trading_eth || 0);
|
||||||
const btc = Number(ss.trading_btc || 0);
|
const btc = Number(ss.trading_btc || 0);
|
||||||
const amt = uly === "BTC" ? btc : eth;
|
const amt = uly === "BTC" ? btc : eth;
|
||||||
let msg = "交易账户残留 " + uly;
|
availEl.textContent = "交易户可用 " + fmtCoinAvail(amt) + " " + uly;
|
||||||
if (amt > 0) msg += " " + fmt(amt, 6);
|
retryBtn.textContent = "重试卖回 " + uly;
|
||||||
if (ss.bridge_status === "pending_sell_spot") {
|
head.hidden = false;
|
||||||
msg += ",自动卖回 USDT 失败";
|
|
||||||
} else {
|
|
||||||
msg += ",可卖回 USDT";
|
|
||||||
}
|
|
||||||
textEl.textContent = msg;
|
|
||||||
banner.hidden = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function retrySpotSell() {
|
async function retrySpotSell() {
|
||||||
|
|||||||
@@ -194,7 +194,13 @@
|
|||||||
<div class="card options-pos-card-wrap">
|
<div class="card options-pos-card-wrap">
|
||||||
<div class="options-pos-head">
|
<div class="options-pos-head">
|
||||||
<h2>持仓</h2>
|
<h2>持仓</h2>
|
||||||
<button type="button" class="btn-secondary" id="opt-refresh-positions">刷新</button>
|
<div class="options-pos-head-actions">
|
||||||
|
<div id="opt-spot-sell-head" class="opt-spot-sell-head" hidden>
|
||||||
|
<span class="opt-spot-sell-avail" id="opt-spot-sell-avail-text"></span>
|
||||||
|
<button type="button" class="btn-primary opt-spot-sell-retry-btn" id="opt-spot-sell-retry-btn">重试卖回 ETH</button>
|
||||||
|
</div>
|
||||||
|
<button type="button" class="btn-secondary opt-pos-refresh-btn" id="opt-refresh-positions" title="刷新" aria-label="刷新">↻</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="options-pos-tabs" role="tablist" aria-label="持仓面板">
|
<div class="options-pos-tabs" role="tablist" aria-label="持仓面板">
|
||||||
<button type="button" class="btn-secondary opt-pos-tab active" data-opt-pos-tab="live" role="tab" aria-selected="true" id="opt-pos-tab-live">当前持仓</button>
|
<button type="button" class="btn-secondary opt-pos-tab active" data-opt-pos-tab="live" role="tab" aria-selected="true" id="opt-pos-tab-live">当前持仓</button>
|
||||||
@@ -204,10 +210,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="options-pos-tab-body">
|
<div class="options-pos-tab-body">
|
||||||
<div class="options-pos-pane is-active" data-opt-pos-pane="live" role="tabpanel" aria-labelledby="opt-pos-tab-live">
|
<div class="options-pos-pane is-active" data-opt-pos-pane="live" role="tabpanel" aria-labelledby="opt-pos-tab-live">
|
||||||
<div id="opt-spot-sell-banner" class="opt-spot-sell-banner" hidden>
|
|
||||||
<div class="opt-spot-sell-banner-text" id="opt-spot-sell-banner-text"></div>
|
|
||||||
<button type="button" class="btn-primary" id="opt-spot-sell-retry-btn">重试卖回</button>
|
|
||||||
</div>
|
|
||||||
<div id="opt-target-monitors" class="opt-target-monitors" hidden>
|
<div id="opt-target-monitors" class="opt-target-monitors" hidden>
|
||||||
<div class="opt-target-monitors-head">目标监控</div>
|
<div class="opt-target-monitors-head">目标监控</div>
|
||||||
<div id="opt-target-monitors-list"></div>
|
<div id="opt-target-monitors-list"></div>
|
||||||
|
|||||||
Reference in New Issue
Block a user