第十阶段 stage 2(四):浏览器页(全局账本)、Web3 页签折行

This commit is contained in:
ZHU MINCHAO committed 2026-11-05 07:22:01 +08:00
1 parent e3e5ec2d6e
commit a3e955ca59
17 files changed
+199 -6

No files matched your search

+65 -6
View File
@@ -1279,19 +1279,31 @@ namespace Decentralized
if (_web3Tab == Web3Tab.Mixer && !Unlock.MixerUnlocked) _web3Tab = Web3Tab.Trade;
if (_web3Tab == Web3Tab.Black && !Unlock.BlackUnlocked) _web3Tab = Web3Tab.Trade;
if (_web3Tab == Web3Tab.Predict && !PredictGame.Available(StoreStation.GetDayCounter())) _web3Tab = Web3Tab.Trade;
b.BeginRow(4f);
foreach (Web3Tab t in Enum.GetValues(typeof(Web3Tab)))
var tabs = Enum.GetValues(typeof(Web3Tab)).Cast<Web3Tab>()
.Where(t => !((t == Web3Tab.Mixer && !Unlock.MixerUnlocked) || (t == Web3Tab.Black && !Unlock.BlackUnlocked) || (t == Web3Tab.Predict && !PredictGame.Available(StoreStation.GetDayCounter()))))
.ToList();
// 页签按字数估宽,超出一行就折到下一行;连接钱包的控件放在最后一行右端,放不下就单独一行
float avail = ScreenW - 40f, used = 0f;
Func<string, float> px = txt => txt.Sum(c => c > 0x2E80 ? 18f : 9f) + 28f;
bool open = false;
foreach (var t in tabs)
{
if ((t == Web3Tab.Mixer && !Unlock.MixerUnlocked) || (t == Web3Tab.Black && !Unlock.BlackUnlocked) || (t == Web3Tab.Predict && !PredictGame.Available(StoreStation.GetDayCounter()))) continue;
var tab = t;
string name = L.T("web3.sub." + t.ToString().ToLowerInvariant());
float wpx = px(name);
if (open && used + wpx > avail) { b.End(); open = false; used = 0f; }
if (!open) { b.BeginRow(4f); open = true; }
used += wpx + 4f;
var tab = t;
PledgerSkin.Pick(b, name, tab == _web3Tab, () => { _web3Tab = tab; _message = null; _edit = null; Open(); }, _picked);
}
float widget = 120f + (Session.Data.Connected ? px(L.T("web3.conn", WalletWindow.NameOf(Session.Data.Hot), ChainAddress.Short(Session.Data.Hot.Address))) : px(L.T("web3.connect")));
if (open && used + widget > avail) { b.End(); open = false; }
if (!open) b.BeginRow(4f);
b.AddFlexibleSpace();
ConnectWidget(b);
b.End();
ConnectPicker(b);
if (!Session.Data.Connected) b.AddLabel(L.T("web3.err.noconn"), "term_note");
if (!Session.Data.Connected && _web3Tab != Web3Tab.Explorer) b.AddLabel(L.T("web3.err.noconn"), "term_note");
if (_web3Tab == Web3Tab.Stake) { StakePage(b); return; }
if (_web3Tab == Web3Tab.Predict) { PredictPage(b); return; }
if (_web3Tab == Web3Tab.Ponzi) { YieldPage(b); return; }
@@ -1299,6 +1311,7 @@ namespace Decentralized
if (_web3Tab == Web3Tab.Mining) { ReportPage(b); return; }
if (_web3Tab == Web3Tab.Mixer) { MixerPage(b); return; }
if (_web3Tab == Web3Tab.Black) { BlackPage(b); return; }
if (_web3Tab == Web3Tab.Explorer) { ExplorerPage(b); return; }
}
Columns(b, l =>
{
@@ -1352,6 +1365,52 @@ namespace Decentralized
b.End();
}
private static string _explorerQuery = "";
private static readonly float[] ExplWBase = new[] { 80f, 300f, 160f };
private static float[] ExplW => Sc(ExplWBase);
private static readonly TextAnchor[] ExplAligns = { TextAnchor.MiddleLeft, TextAnchor.MiddleLeft, TextAnchor.MiddleRight };
/// <summary>地址的显示名:自己的钱包、Poinbase、混币器、全网矿池、黑市卖家,其余是缩写。</summary>
private static string AddressLabel(string a)
{
var d = Session.Data;
if (string.IsNullOrEmpty(a)) return "—";
if (a == "network") return L.T("explorer.net");
var own = d.Own(a);
if (own != null) return WalletWindow.NameOf(own);
if (ChainAddress.Same(a, d.Address("poinbase"))) return "Poinbase";
if (d.Addresses.TryGetValue("mixer", out var mx) && ChainAddress.Same(a, mx)) return L.T("explorer.mixer");
return ChainAddress.Short(a);
}
/// <summary>浏览器:公共数据,不需要连接钱包。查任意地址的转账,只显示真实发生的。</summary>
private static void ExplorerPage(CustomUIBuilder b)
{
var d = Session.Data;
b.BeginPanel(RightW - 30f, -1f, TextAnchor.MiddleCenter, 0f, 0f);
_clear.Add(b.Last.image);
b.AddInput(L.T("explorer.search"), _explorerQuery, s => _explorerQuery = s, "explorer", s => { _explorerQuery = s; Open(); });
b.End();
if (d.Wallets.Count > 0)
{
b.BeginRow(4f);
PledgerSkin.Pick(b, L.T("explorer.all"), string.IsNullOrWhiteSpace(_explorerQuery), () => { _explorerQuery = ""; Open(); }, _picked);
foreach (var ow in d.Wallets)
{
var own = ow;
PledgerSkin.Pick(b, WalletWindow.NameOf(own), ChainAddress.Same(_explorerQuery, own.Address), () => { _explorerQuery = own.Address; Open(); }, _picked);
}
b.End();
}
b.AddSeparator();
var rows = d.Ledger.Of(_explorerQuery, Tuning.LedgerShow);
if (rows.Count == 0) { b.AddLabel(L.T("explorer.none"), "explorer_none_dim"); return; }
TableHeader(b, ExplW.Sum() + 8f, ExplW, ExplAligns, L.T("explorer.col.block"), L.T("explorer.col.flow"), L.T("explorer.col.amount"));
foreach (var e in rows)
TableRow(b, ExplW.Sum() + 8f, ExplW, ExplAligns,
new[] { "#" + e.Block, AddressLabel(e.From) + " → " + AddressLabel(e.To), Fmt.Num(e.Amount) + " " + e.Asset });
}
private enum BlackTab { Buy, Sell, Orders }
private static BlackTab _blackTab = BlackTab.Buy;
private static PayMode _mode = PayMode.Escrow;
@@ -2184,7 +2243,7 @@ namespace Decentralized
Open();
}
private enum Web3Tab { Trade, Stake, Airdrop, Predict, Ponzi, Mining, Mixer, Black }
private enum Web3Tab { Trade, Stake, Airdrop, Predict, Ponzi, Mining, Mixer, Black, Explorer }
private static Web3Tab _web3Tab = Web3Tab.Trade;
private static string _mixAsset = Assets.PSC;
private static int _mixRounds = 2;