Stage 07.3.3: multi live screens and UI optimization

This commit is contained in:
2026-04-29 12:38:29 +03:00
parent 93cdd164ae
commit 861f98024c
3 changed files with 111 additions and 89 deletions

View File

@@ -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()