Stage 07.3.3: multi live screens and UI optimization
This commit is contained in:
@@ -12,6 +12,7 @@ from src.integrations.exchange.models import BalanceSummary
|
||||
from src.integrations.exchange.service import ExchangeService
|
||||
from src.telegram.live.runner import LiveScreen, LiveScreenRunner
|
||||
from src.telegram.ui.common import mode_line, now_line
|
||||
from src.telegram.ui.currency_ui import format_usd_amount
|
||||
from src.telegram.ui.currency_ui import (
|
||||
balance_total,
|
||||
estimate_balance_usd,
|
||||
@@ -39,6 +40,30 @@ PINNED_ORDER = {
|
||||
"ETH": 4,
|
||||
}
|
||||
|
||||
# компактное форматирование количества
|
||||
def _compact_amount(currency: str, value: float) -> str:
|
||||
currency = currency.upper()
|
||||
|
||||
if currency in {"USD", "USDT", "EUR"}:
|
||||
return format_usd_amount(value)
|
||||
|
||||
text = f"{value:.8f}"
|
||||
|
||||
if "." in text:
|
||||
integer, frac = text.split(".")
|
||||
integer = f"{int(integer):,}".replace(",", " ")
|
||||
|
||||
stripped = frac.rstrip("0")
|
||||
|
||||
if stripped == "":
|
||||
return f"{integer}.00"
|
||||
|
||||
if len(stripped) <= 2:
|
||||
return f"{integer}.{stripped.ljust(2, '0')}"
|
||||
|
||||
return f"{integer}.{stripped}"
|
||||
|
||||
return f"{int(text):,}".replace(",", " ")
|
||||
|
||||
# клавиатура портфеля
|
||||
def _portfolio_keyboard() -> InlineKeyboardMarkup:
|
||||
@@ -104,7 +129,6 @@ def _build_portfolio_live_text() -> tuple[str, InlineKeyboardMarkup]:
|
||||
"<b>💼 Портфель</b>",
|
||||
mode_line().rstrip(),
|
||||
"",
|
||||
f"<b>БАЛАНС · АКТИВЫ · {len(visible_balances)}</b>",
|
||||
]
|
||||
|
||||
asset_blocks: list[list[str]] = []
|
||||
@@ -120,18 +144,18 @@ def _build_portfolio_live_text() -> tuple[str, InlineKeyboardMarkup]:
|
||||
elif total > 0:
|
||||
missing_estimate_assets.append(currency)
|
||||
|
||||
block = [
|
||||
"",
|
||||
f"<b>{currency}</b>",
|
||||
f"• доступно: {format_amount(currency, item.available)}",
|
||||
f"• заблокировано: {format_amount(currency, item.locked)}",
|
||||
f"• всего: {format_amount(currency, total)}",
|
||||
]
|
||||
line = f"{currency}: {_compact_amount(currency, total)}"
|
||||
|
||||
if estimated_usd is not None and currency not in {"USD", "USDT"}:
|
||||
block.append(f"≈ {format_usd_amount(estimated_usd)} USD")
|
||||
if item.locked > 0:
|
||||
line += f" · locked {_compact_amount(currency, item.locked)}"
|
||||
|
||||
asset_blocks.append(block)
|
||||
if estimated_usd is not None and currency not in {'USD', 'USDT'}:
|
||||
line += f" ≈ $ {format_usd_amount(estimated_usd)}"
|
||||
|
||||
if currency == "BTC" and any("USD:" in x or "USDT:" in x for x in lines):
|
||||
lines.append("")
|
||||
|
||||
lines.append(line)
|
||||
|
||||
has_partial_data = len(missing_estimate_assets) > 0
|
||||
|
||||
@@ -139,7 +163,8 @@ def _build_portfolio_live_text() -> tuple[str, InlineKeyboardMarkup]:
|
||||
lines.append("🟡 <b>Данные загружены частично</b>")
|
||||
|
||||
if has_any_estimate:
|
||||
lines.append(f"Оценка: <b>~${format_usd_amount(total_estimated_usd)}</b>")
|
||||
lines.insert(3, "")
|
||||
lines.insert(3, f"Оценка: <b>≈ $ {format_usd_amount(total_estimated_usd)}</b>")
|
||||
|
||||
if missing_estimate_assets:
|
||||
lines.append(f"Нет оценки: {', '.join(missing_estimate_assets)}")
|
||||
@@ -196,7 +221,6 @@ async def _render_portfolio_screen(
|
||||
action: str,
|
||||
) -> None:
|
||||
AutoTradeRunner.set_current_screen("portfolio")
|
||||
LiveScreenRunner.set_current_screen("portfolio")
|
||||
|
||||
journal = JournalService()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user