Files
pangolin/client/lib/widgets/country_code.dart
T
wangjia 8eb7d04fe1 feat(client): 节点地区图标改国旗(SVG 填满裁切),未知码回退码块
CountryCode 由 2 字母码块改为渲染真国旗:country_flags 包按 region 码出 SVG
旗(BoxFit.cover 填满裁切),全平台含 Windows 都显示(emoji 国旗在 Windows
不渲染,故走 SVG)。FlagCode 判定无效码(AUTO/占位/非地区码)时回退原码块;
选中态由 accent 底色改为 accent 边框环。

CountryCode 共享于节点列表/连接页/统计页,故三处节点图标统一变国旗,
对应 tablet_servers/connect/stats + desktop_stats golden 已 Mac 重生成
(这些页非 CI golden 闸;CI 闸的 components/auth 基线未动)。

依赖:country_flags ^3.1.0(解析 3.3.0)。analyze 干净,非 golden 测试全过。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 16:25:48 +08:00

86 lines
2.7 KiB
Dart

// country_code.dart — 节点地区图标(国旗,未知码回退码块) + 信号条
import 'package:country_flags/country_flags.dart';
import 'package:flutter/material.dart';
import '../pangolin_theme.dart';
/// 节点地区图标:有效 2 字母地区码渲染国旗(SVG,填满裁切,全平台含 Windows 都显示);
/// 未知码(AUTO / ·· / 空等)回退为原 2 字母码块。选中态加 accent 边框环。
class CountryCode extends StatelessWidget {
const CountryCode({super.key, required this.code, this.active = false, this.size = 38});
final String code;
final bool active;
final double size;
@override
Widget build(BuildContext context) {
final c = context.pangolin;
final radius = BorderRadius.circular(PangolinRadius.md);
final hasFlag = FlagCode.fromCountryCode(code.toUpperCase()) != null;
if (!hasFlag) {
// 回退:原码块样式(AUTO / 占位 / 非地区码)。
return Container(
width: size,
height: size,
alignment: Alignment.center,
decoration: BoxDecoration(
color: active ? c.accent : c.bgSubtle,
borderRadius: radius,
),
child: Text(
code,
style: PangolinText.mono.copyWith(
fontSize: size * 0.31,
fontWeight: FontWeight.w600,
color: active ? PangolinColors.white : c.fg2,
),
),
);
}
// 国旗:外层 Container 控圆角 + 选中边框,内层 CountryFlag 以 BoxFit.cover 填满裁切。
return Container(
width: size,
height: size,
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(
borderRadius: radius,
border: active ? Border.all(color: c.accent, width: 2) : null,
),
child: CountryFlag.fromCountryCode(
code.toUpperCase(),
width: size,
height: size,
),
);
}
}
/// 三格信号条,依据延迟 ping 显示强度。
class SignalBars extends StatelessWidget {
const SignalBars({super.key, required this.ping});
final int ping;
@override
Widget build(BuildContext context) {
final c = context.pangolin;
final level = ping < 40 ? 3 : ping < 90 ? 2 : 1;
const heights = [4.0, 8.0, 13.0];
return Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.end,
children: List.generate(3, (i) {
return Container(
width: 3,
height: heights[i],
margin: EdgeInsets.only(left: i == 0 ? 0 : 2),
decoration: BoxDecoration(
color: i < level ? c.success : c.borderStrong,
borderRadius: BorderRadius.circular(1),
),
);
}),
);
}
}