From 960565482ff0954052675014742fc0f1d9678279 Mon Sep 17 00:00:00 2001 From: dekun Date: Sun, 16 Aug 2026 16:38:37 +0800 Subject: [PATCH] Add proper PWA install icons and sim-aware app manifest. Co-authored-by: Cursor --- app.py | 71 +++++++++++++- lib/instance/instance_embed_lib.py | 17 +++- lib/instance/templates/embed_shell.html | 7 ++ lib/instance/templates/index.html | 10 +- lib/instance/templates/login.html | 10 +- scripts/generate_pwa_icons.py | 119 ++++++++++++++++++++++++ static/icons/apple-touch-icon.png | Bin 1032 -> 1596 bytes static/icons/favicon.ico | Bin 133 -> 1949 bytes static/icons/icon-16.png | Bin 108 -> 281 bytes static/icons/icon-192-maskable.png | Bin 0 -> 1679 bytes static/icons/icon-192.png | Bin 1165 -> 1757 bytes static/icons/icon-32.png | Bin 254 -> 378 bytes static/icons/icon-512-maskable.png | Bin 0 -> 4577 bytes static/icons/icon-512.png | Bin 3920 -> 4847 bytes static/icons/icon.svg | 13 +-- static/icons/manifest.webmanifest | 26 ++++-- 16 files changed, 247 insertions(+), 26 deletions(-) create mode 100644 scripts/generate_pwa_icons.py create mode 100644 static/icons/icon-192-maskable.png create mode 100644 static/icons/icon-512-maskable.png diff --git a/app.py b/app.py index 07d67c0..5b5d29e 100644 --- a/app.py +++ b/app.py @@ -4953,10 +4953,19 @@ def login(): return redirect("/") else: flash("账号或密码错误") + is_sim = False + try: + from lib.sim.mode_lib import is_sim_mode as _is_sim_mode_fn + + is_sim = bool(_is_sim_mode_fn(get_db)) + except Exception: + is_sim = False + from lib.instance.instance_embed_lib import pwa_app_name + return render_template( "login.html", exchange_display=EXCHANGE_DISPLAY_NAME, - pwa_app_name="OKX 交易系统", + pwa_app_name=pwa_app_name("okx", is_sim=is_sim), ) @app.route("/logout") @@ -5319,7 +5328,7 @@ def render_main_page(page="options", embed_mode=None): funding_usdt=funding_usdt, exchange_pnl_sync=exchange_pnl_sync, **strategy_extra, - **embed_context_extras("okx"), + **embed_context_extras("okx", is_sim=_sim_mode_for_header), **_display_ctx, **settings_page_context( page, @@ -7016,6 +7025,64 @@ def delete_journal(jid): return jsonify({"ok": True}) +@app.route("/manifest.webmanifest") +@app.route("/static/icons/manifest.webmanifest") +def pwa_manifest(): + """安装 App 用 manifest;模拟盘 short_name=OKX_sim.""" + is_sim = False + try: + from lib.sim.mode_lib import is_sim_mode as _is_sim_mode_fn + + is_sim = bool(_is_sim_mode_fn(get_db)) + except Exception: + is_sim = False + from lib.instance.instance_embed_lib import pwa_app_name + + name = pwa_app_name("okx", is_sim=is_sim) + short = "OKX_sim" if is_sim else "OKX" + payload = { + "name": name, + "short_name": short, + "description": "OKX 期权与对冲交易监控", + "id": "/", + "start_url": "/", + "scope": "/", + "display": "standalone", + "background_color": "#0b0d14", + "theme_color": "#0b0d14", + "icons": [ + { + "src": "/static/icons/icon-192.png?v=2", + "sizes": "192x192", + "type": "image/png", + "purpose": "any", + }, + { + "src": "/static/icons/icon-512.png?v=2", + "sizes": "512x512", + "type": "image/png", + "purpose": "any", + }, + { + "src": "/static/icons/icon-192-maskable.png?v=2", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable", + }, + { + "src": "/static/icons/icon-512-maskable.png?v=2", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable", + }, + ], + } + resp = jsonify(payload) + resp.headers["Content-Type"] = "application/manifest+json; charset=utf-8" + resp.headers["Cache-Control"] = "no-cache" + return resp + + _REPO_STATIC_DIR = common_static_dir(_REPO_ROOT) _FORM_SUBMIT_GUARD_JS = os.path.join(_REPO_STATIC_DIR, "form_submit_guard.js") _MANUAL_ORDER_RR_PREVIEW_JS = os.path.join(_REPO_STATIC_DIR, "manual_order_rr_preview.js") diff --git a/lib/instance/instance_embed_lib.py b/lib/instance/instance_embed_lib.py index fa666e3..308b1f0 100644 --- a/lib/instance/instance_embed_lib.py +++ b/lib/instance/instance_embed_lib.py @@ -201,9 +201,18 @@ def register_embed_routes( return resp -def pwa_app_name(exchange_key: str) -> str: - """安装 App / 主屏幕显示名(各所独立标识).""" +def pwa_app_name(exchange_key: str, *, is_sim: bool | None = None) -> str: + """安装 App / 主屏幕显示名(各所独立标识;模拟盘带 _sim).""" ex = (exchange_key or "").strip().lower() + base = { + "binance": "Binance", + "okx": "OKX", + "gate": "Gate", + }.get(ex, "Crypto") + if is_sim is True: + return f"{base}_sim" + if is_sim is False: + return f"{base}_live" return { "binance": "Binance 交易系统", "okx": "OKX 交易系统", @@ -211,11 +220,11 @@ def pwa_app_name(exchange_key: str) -> str: }.get(ex, "交易系统") -def embed_context_extras(exchange_key: str) -> dict: +def embed_context_extras(exchange_key: str, *, is_sim: bool | None = None) -> dict: return { "order_rule_tips_tpl": order_rule_tips_template(exchange_key), "include_transfer_block": include_transfer_block(exchange_key), "ui_open_guard_enabled": ui_open_guard_enabled(exchange_key), "ui_orphan_recovery_enabled": ui_orphan_recovery_enabled(exchange_key), - "pwa_app_name": pwa_app_name(exchange_key), + "pwa_app_name": pwa_app_name(exchange_key, is_sim=is_sim), } diff --git a/lib/instance/templates/embed_shell.html b/lib/instance/templates/embed_shell.html index b901411..e9b57c8 100644 --- a/lib/instance/templates/embed_shell.html +++ b/lib/instance/templates/embed_shell.html @@ -12,6 +12,13 @@ + + + + + + + {{ pwa_app_name }} + - - - - + + + + + {{ pwa_app_name }} diff --git a/lib/instance/templates/login.html b/lib/instance/templates/login.html index ef81ec9..edd4ec2 100644 --- a/lib/instance/templates/login.html +++ b/lib/instance/templates/login.html @@ -5,11 +5,13 @@ + - - - - + + + + + 登录 · {{ pwa_app_name }}