feat: redesign wallet login and favorites, fix desktop/mobile bugs

- Remove forced BNB chain switch on injected login (signature is chain-agnostic)
- Refine isMobileDevice so touch Macs stay on desktop flow
- Wire RainbowKit/WalletConnect as a real MetaMask/imToken QR fallback,
  gated on a valid VITE_WALLETCONNECT_PROJECT_ID
- Rebuild login modal: single desktop primary action, collapsible other
  methods, mobile open-app fallback feedback, brand icons
- Add My Favorites entry points (header, mobile menu, wallet dropdown)
- Favorites page: error retry, mobile filter drawer
- Auto sign-out and re-login prompt on favorites 401
- Full native translations for all wallet strings across 7 locales

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
TerryM
2026-06-02 03:43:13 +08:00
parent f935f122f9
commit 7abe4a868c
17 changed files with 715 additions and 155 deletions

View File

@@ -171,7 +171,7 @@ export const enDict: Dict = {
walletDisconnect: "Disconnect",
walletLoginTitle: "Connect wallet",
walletLoginDesc:
"Sign a message to verify your BNB Chain wallet address. No transaction or gas fee.",
"Sign a message to verify your wallet address. No transaction or gas fee.",
walletInjected: "Use browser wallet",
walletInjectedDesc: "Sign with the wallet available in this browser.",
walletNoBrowserWallet: "No browser wallet detected",
@@ -183,14 +183,19 @@ export const enDict: Dict = {
walletTokenPocket: "TokenPocket",
walletMetaMask: "MetaMask",
walletImToken: "imToken",
favoritesFilters: "Filters",
favoriteSessionExpired: "Your session expired. Please sign in again.",
walletChooseDesktop:
"Choose the wallet you want to use. On desktop, install the matching browser extension and switch to BNB Chain.",
"Choose the wallet you want to use. On desktop, install the matching browser extension.",
walletChooseMobile: "Choose a wallet app to open this site.",
walletDesktopHint:
"If no wallet opens after clicking, make sure the matching browser extension is installed and enabled.",
walletInstallSelected:
"No {wallet} browser extension detected. Install or enable it, then try again.",
walletOpen: "Open",
walletQrLogin: "QR login",
walletMobileQrDesc:
"Use another device to scan this QR code and log in to this browser.",
walletTokenPocketQr: "TokenPocket QR login",
walletTokenPocketQrDesc:
"Recommended for China users. Scan with TokenPocket and sign to return login to this browser.",
@@ -212,6 +217,13 @@ export const enDict: Dict = {
walletLoginSuccess: "Wallet connected",
walletLoginFailed: "Wallet login failed",
walletDisconnected: "Wallet disconnected",
walletOtherMethods: "Other login methods",
walletUseCurrent: "Use current wallet",
walletOpening: "Opening {wallet}…",
walletAppNotInstalled: "If nothing opened, the app may not be installed.",
walletDownloadApp: "Download {wallet}",
walletRetry: "Try again",
walletConnecting: "Connecting…",
featureUnavailable: "Not available yet",
featureUnavailableDesc: "This feature is not available yet.",
confirm: "Got it",

View File

@@ -171,8 +171,31 @@ export const idDict: Dict = {
walletLoginTitle: "Hubungkan dompet",
walletLoginDesc:
"Tanda tangani pesan untuk memverifikasi alamat dompet. Tidak ada transaksi atau gas.",
walletInjected: "Dompet browser / browser DApp",
walletInjectedDesc: "Gunakan dompet yang tersedia di browser ini.",
walletInjected: "Gunakan dompet browser",
walletInjectedDesc:
"Tanda tangani dengan dompet yang tersedia di browser ini.",
walletNoBrowserWallet: "Tidak ada dompet browser terdeteksi",
walletNoBrowserWalletDesc:
"Pasang atau aktifkan ekstensi dompet browser, seperti MetaMask.",
walletOpenWalletApp: "Buka aplikasi dompet",
walletOpenWalletAppDesc:
"Buka situs ini di aplikasi dompet Anda, lalu tanda tangani untuk masuk.",
walletTokenPocket: "TokenPocket",
walletMetaMask: "MetaMask",
walletImToken: "imToken",
favoritesFilters: "Filter",
favoriteSessionExpired: "Sesi Anda telah berakhir. Silakan masuk lagi.",
walletChooseDesktop:
"Pilih dompet yang ingin digunakan. Di desktop, pasang ekstensi browser yang sesuai.",
walletChooseMobile: "Pilih aplikasi dompet untuk membuka situs ini.",
walletDesktopHint:
"Jika tidak ada dompet terbuka setelah diklik, pastikan ekstensi browser yang sesuai sudah terpasang dan diaktifkan.",
walletInstallSelected:
"Ekstensi browser {wallet} tidak terdeteksi. Pasang atau aktifkan, lalu coba lagi.",
walletOpen: "Buka",
walletQrLogin: "Login QR",
walletMobileQrDesc:
"Gunakan perangkat lain untuk memindai kode QR ini dan masuk di browser ini.",
walletTokenPocketQr: "Login QR TokenPocket",
walletTokenPocketQrDesc:
"Direkomendasikan untuk pengguna Tiongkok. Pindai dengan TokenPocket dan tanda tangani untuk login di browser ini.",
@@ -194,6 +217,14 @@ export const idDict: Dict = {
walletLoginSuccess: "Dompet terhubung",
walletLoginFailed: "Login dompet gagal",
walletDisconnected: "Dompet terputus",
walletOtherMethods: "Metode login lainnya",
walletUseCurrent: "Gunakan dompet saat ini",
walletOpening: "Membuka {wallet}…",
walletAppNotInstalled:
"Jika tidak ada yang terbuka, aplikasi mungkin belum terpasang.",
walletDownloadApp: "Unduh {wallet}",
walletRetry: "Coba lagi",
walletConnecting: "Menghubungkan…",
featureUnavailable: "Belum tersedia",
featureUnavailableDesc: "Fitur ini belum tersedia.",
confirm: "Mengerti",

View File

@@ -194,6 +194,37 @@ export const jaDict: Dict = {
walletLoginSuccess: "ウォレットを接続しました",
walletLoginFailed: "ウォレットログインに失敗しました",
walletDisconnected: "ウォレットを切断しました",
walletNoBrowserWallet: "ブラウザウォレットが見つかりません",
walletNoBrowserWalletDesc:
"MetaMask などのブラウザウォレット拡張機能をインストールまたは有効にしてください。",
walletOpenWalletApp: "ウォレットアプリで開く",
walletOpenWalletAppDesc:
"このサイトをウォレットアプリで開き、署名してログインしてください。",
walletTokenPocket: "TokenPocket",
walletMetaMask: "MetaMask",
walletImToken: "imToken",
favoritesFilters: "フィルター",
favoriteSessionExpired:
"セッションの有効期限が切れました。もう一度ログインしてください。",
walletChooseDesktop:
"使用するウォレットを選択してください。デスクトップの場合は対応するブラウザ拡張機能をインストールしてください。",
walletChooseMobile: "このサイトを開くウォレットアプリを選択してください。",
walletDesktopHint:
"クリックしてもウォレットが開かない場合は、対応するブラウザ拡張機能がインストールされ有効になっているか確認してください。",
walletInstallSelected:
"{wallet} のブラウザ拡張機能が検出されません。インストールまたは有効にしてから再試行してください。",
walletOpen: "開く",
walletQrLogin: "QR ログイン",
walletMobileQrDesc:
"別のデバイスでこの QR コードをスキャンして、このブラウザにログインしてください。",
walletOtherMethods: "他のログイン方法",
walletUseCurrent: "現在のウォレットを使用",
walletOpening: "{wallet} を起動中…",
walletAppNotInstalled:
"何も起動しない場合は、アプリがインストールされていない可能性があります。",
walletDownloadApp: "{wallet} をダウンロード",
walletRetry: "再試行",
walletConnecting: "接続中…",
featureUnavailable: "未公開",
featureUnavailableDesc: "この機能はまだご利用いただけません。",
confirm: "了解",

View File

@@ -170,8 +170,30 @@ export const koDict: Dict = {
walletLoginTitle: "지갑 연결",
walletLoginDesc:
"메시지 서명으로 지갑 주소를 확인합니다. 트랜잭션이나 가스 수수료는 없습니다.",
walletInjected: "브라우저 지갑 / DApp 브라우저",
walletInjectedDesc: "현재 브라우저에서 사용 가능한 지갑을 사용합니다.",
walletInjected: "브라우저 지갑 사용",
walletInjectedDesc: " 브라우저에서 사용 가능한 지갑으로 서명합니다.",
walletNoBrowserWallet: "브라우저 지갑을 찾을 수 없습니다",
walletNoBrowserWalletDesc:
"MetaMask 등의 브라우저 지갑 확장 프로그램을 설치하거나 활성화하세요.",
walletOpenWalletApp: "지갑 앱으로 열기",
walletOpenWalletAppDesc:
"지갑 앱에서 이 사이트를 열고 서명하여 로그인하세요.",
walletTokenPocket: "TokenPocket",
walletMetaMask: "MetaMask",
walletImToken: "imToken",
favoritesFilters: "필터",
favoriteSessionExpired: "세션이 만료되었습니다. 다시 로그인해 주세요.",
walletChooseDesktop:
"사용할 지갑을 선택하세요. 데스크톱에서는 해당 브라우저 확장 프로그램을 설치하세요.",
walletChooseMobile: "이 사이트를 열 지갑 앱을 선택하세요.",
walletDesktopHint:
"클릭 후 지갑이 열리지 않으면 해당 브라우저 확장 프로그램이 설치되고 활성화되어 있는지 확인하세요.",
walletInstallSelected:
"{wallet} 브라우저 확장 프로그램을 찾을 수 없습니다. 설치하거나 활성화한 후 다시 시도하세요.",
walletOpen: "열기",
walletQrLogin: "QR 로그인",
walletMobileQrDesc:
"다른 기기로 이 QR 코드를 스캔하여 이 브라우저에 로그인하세요.",
walletTokenPocketQr: "TokenPocket QR 로그인",
walletTokenPocketQrDesc:
"중국 사용자에게 권장됩니다. TokenPocket으로 스캔하고 서명하면 이 브라우저에서 로그인이 완료됩니다.",
@@ -193,6 +215,13 @@ export const koDict: Dict = {
walletLoginSuccess: "지갑이 연결되었습니다",
walletLoginFailed: "지갑 로그인에 실패했습니다",
walletDisconnected: "지갑 연결이 해제되었습니다",
walletOtherMethods: "다른 로그인 방법",
walletUseCurrent: "현재 지갑 사용",
walletOpening: "{wallet} 열는 중…",
walletAppNotInstalled: "열리지 않으면 앱이 설치되어 있지 않을 수 있습니다.",
walletDownloadApp: "{wallet} 다운로드",
walletRetry: "다시 시도",
walletConnecting: "연결 중…",
featureUnavailable: "준비 중",
featureUnavailableDesc: "이 기능은 아직 사용할 수 없습니다.",
confirm: "확인",

View File

@@ -171,8 +171,31 @@ export const msDict: Dict = {
walletLoginTitle: "Sambung dompet",
walletLoginDesc:
"Tandatangani mesej untuk mengesahkan alamat dompet. Tiada transaksi atau gas.",
walletInjected: "Dompet pelayar / pelayar DApp",
walletInjectedDesc: "Gunakan dompet yang tersedia dalam pelayar ini.",
walletInjected: "Guna dompet pelayar",
walletInjectedDesc:
"Tandatangani dengan dompet yang tersedia dalam pelayar ini.",
walletNoBrowserWallet: "Tiada dompet pelayar dikesan",
walletNoBrowserWalletDesc:
"Pasang atau aktifkan sambungan dompet pelayar, seperti MetaMask.",
walletOpenWalletApp: "Buka aplikasi dompet",
walletOpenWalletAppDesc:
"Buka laman ini dalam aplikasi dompet anda, kemudian tandatangani untuk log masuk.",
walletTokenPocket: "TokenPocket",
walletMetaMask: "MetaMask",
walletImToken: "imToken",
favoritesFilters: "Penapis",
favoriteSessionExpired: "Sesi anda telah tamat. Sila log masuk semula.",
walletChooseDesktop:
"Pilih dompet yang ingin anda gunakan. Pada desktop, pasang sambungan pelayar yang sepadan.",
walletChooseMobile: "Pilih aplikasi dompet untuk membuka laman ini.",
walletDesktopHint:
"Jika tiada dompet terbuka selepas klik, pastikan sambungan pelayar yang sepadan telah dipasang dan diaktifkan.",
walletInstallSelected:
"Tiada sambungan pelayar {wallet} dikesan. Pasang atau aktifkannya, kemudian cuba lagi.",
walletOpen: "Buka",
walletQrLogin: "Log masuk QR",
walletMobileQrDesc:
"Guna peranti lain untuk mengimbas kod QR ini dan log masuk pada pelayar ini.",
walletTokenPocketQr: "Log masuk QR TokenPocket",
walletTokenPocketQrDesc:
"Disyorkan untuk pengguna China. Imbas dengan TokenPocket dan tandatangani untuk log masuk pada pelayar ini.",
@@ -194,6 +217,14 @@ export const msDict: Dict = {
walletLoginSuccess: "Dompet disambungkan",
walletLoginFailed: "Log masuk dompet gagal",
walletDisconnected: "Dompet diputuskan",
walletOtherMethods: "Kaedah log masuk lain",
walletUseCurrent: "Guna dompet semasa",
walletOpening: "Membuka {wallet}…",
walletAppNotInstalled:
"Jika tiada yang terbuka, aplikasi mungkin belum dipasang.",
walletDownloadApp: "Muat turun {wallet}",
walletRetry: "Cuba lagi",
walletConnecting: "Menyambung…",
featureUnavailable: "Belum tersedia",
featureUnavailableDesc: "Ciri ini belum tersedia.",
confirm: "Faham",

View File

@@ -170,8 +170,30 @@ export const viDict: Dict = {
walletLoginTitle: "Kết nối ví",
walletLoginDesc:
"Ký tin nhắn để xác minh địa chỉ ví. Không có giao dịch hay phí gas.",
walletInjected: "Ví trình duyệt / trình duyệt DApp",
walletInjectedDesc: "ng ví đã có trong trình duyệt hiện tại.",
walletInjected: "Dùng ví trình duyệt",
walletInjectedDesc: "Ký bằng ví đã có trong trình duyệt này.",
walletNoBrowserWallet: "Không tìm thấy ví trình duyệt",
walletNoBrowserWalletDesc:
"Cài đặt hoặc bật tiện ích mở rộng ví trình duyệt, chẳng hạn như MetaMask.",
walletOpenWalletApp: "Mở ứng dụng ví",
walletOpenWalletAppDesc:
"Mở trang này trong ứng dụng ví của bạn, sau đó ký để đăng nhập.",
walletTokenPocket: "TokenPocket",
walletMetaMask: "MetaMask",
walletImToken: "imToken",
favoritesFilters: "Bộ lọc",
favoriteSessionExpired: "Phiên đăng nhập đã hết hạn. Vui lòng đăng nhập lại.",
walletChooseDesktop:
"Chọn ví bạn muốn dùng. Trên máy tính, hãy cài tiện ích mở rộng trình duyệt tương ứng.",
walletChooseMobile: "Chọn ứng dụng ví để mở trang này.",
walletDesktopHint:
"Nếu không có ví nào mở sau khi nhấn, hãy đảm bảo tiện ích mở rộng tương ứng đã được cài đặt và bật.",
walletInstallSelected:
"Không tìm thấy tiện ích mở rộng {wallet}. Hãy cài đặt hoặc bật nó, rồi thử lại.",
walletOpen: "Mở",
walletQrLogin: "Đăng nhập QR",
walletMobileQrDesc:
"Dùng thiết bị khác quét mã QR này để đăng nhập trên trình duyệt này.",
walletTokenPocketQr: "Đăng nhập QR TokenPocket",
walletTokenPocketQrDesc:
"Khuyến nghị cho người dùng Trung Quốc. Quét bằng TokenPocket và ký để đăng nhập trên trình duyệt này.",
@@ -193,6 +215,14 @@ export const viDict: Dict = {
walletLoginSuccess: "Đã kết nối ví",
walletLoginFailed: "Đăng nhập ví thất bại",
walletDisconnected: "Đã ngắt kết nối ví",
walletOtherMethods: "Phương thức đăng nhập khác",
walletUseCurrent: "Dùng ví hiện tại",
walletOpening: "Đang mở {wallet}…",
walletAppNotInstalled:
"Nếu không có gì mở, ứng dụng có thể chưa được cài đặt.",
walletDownloadApp: "Tải {wallet}",
walletRetry: "Thử lại",
walletConnecting: "Đang kết nối…",
featureUnavailable: "Chưa khả dụng",
featureUnavailableDesc: "Tính năng này hiện chưa khả dụng.",
confirm: "Đã hiểu",

View File

@@ -164,7 +164,7 @@ export const zhDict: Dict = {
walletConnectedAs: "已连接钱包",
walletDisconnect: "断开连接",
walletLoginTitle: "连接钱包",
walletLoginDesc: "签名验证 BNB Chain 钱包地址,不会发起交易,也不需要 Gas。",
walletLoginDesc: "签名验证钱包地址,不会发起交易,也不需要 Gas。",
walletInjected: "使用浏览器钱包登录",
walletInjectedDesc: "签名验证当前浏览器里的钱包。",
walletNoBrowserWallet: "未检测到浏览器钱包",
@@ -174,13 +174,16 @@ export const zhDict: Dict = {
walletTokenPocket: "TokenPocket",
walletMetaMask: "MetaMask",
walletImToken: "imToken",
walletChooseDesktop:
"选择你要使用的钱包。电脑端需要先安装对应浏览器插件,并切换到 BNB Chain。",
favoritesFilters: "筛选",
favoriteSessionExpired: "登录已过期,请重新登录。",
walletChooseDesktop: "选择你要使用的钱包。电脑端需要先安装对应浏览器插件。",
walletChooseMobile: "选择钱包 App 打开本站。",
walletDesktopHint:
"如果点击后没有弹出钱包,请确认已安装并启用对应的钱包浏览器插件。",
walletInstallSelected: "未检测到 {wallet} 浏览器插件,请先安装或启用后再试。",
walletOpen: "打开",
walletQrLogin: "扫码登录",
walletMobileQrDesc: "适合用另一台设备扫描二维码登录当前浏览器。",
walletTokenPocketQr: "TokenPocket 扫码登录",
walletTokenPocketQrDesc:
"推荐中国用户使用。用 TokenPocket 扫码签名后,会回到当前浏览器完成登录。",
@@ -202,6 +205,13 @@ export const zhDict: Dict = {
walletLoginSuccess: "钱包已连接",
walletLoginFailed: "钱包登录失败",
walletDisconnected: "钱包已断开",
walletOtherMethods: "其他登录方式",
walletUseCurrent: "使用当前钱包登录",
walletOpening: "正在打开 {wallet}…",
walletAppNotInstalled: "如果没有跳转,可能是未安装该 App。",
walletDownloadApp: "下载 {wallet}",
walletRetry: "重试",
walletConnecting: "连接中…",
featureUnavailable: "未开放",
featureUnavailableDesc: "该功能暂未开放。",
confirm: "知道了",