8eb7d04fe1
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>
86 lines
2.7 KiB
Dart
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),
|
|
),
|
|
);
|
|
}),
|
|
);
|
|
}
|
|
}
|