- 抽出 lib/core 的日期/JSON 工具,收敛各页重复解析 - 主页与音乐风险页拆成组件,风险功能共用一套运行框架 - 修复设置页作为主页页签保存时弹掉根路由导致的黑屏 - 登录对齐 Astral aimedb 协议:84 位二维码校验、签名与请求头修正, 补 GlobalSign 中间证书;Windows 改用 WinHTTP 绕过服务端对 BoringSSL 的 TLS 指纹拦截(证书校验保持开启) - 补开发预览数据与测试
112 lines
3.2 KiB
Dart
112 lines
3.2 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
import '../../config/strings.dart';
|
|
import '../app_card.dart';
|
|
|
|
/// 调试用的原始 API 响应卡,默认折叠。
|
|
class DebugRawJsonCard extends StatefulWidget {
|
|
final String rawJson;
|
|
|
|
const DebugRawJsonCard({super.key, required this.rawJson});
|
|
|
|
@override
|
|
State<DebugRawJsonCard> createState() => _DebugRawJsonCardState();
|
|
}
|
|
|
|
class _DebugRawJsonCardState extends State<DebugRawJsonCard> {
|
|
bool _expanded = false;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final theme = Theme.of(context);
|
|
|
|
return AppCard(
|
|
borderColor: Colors.orange.withValues(alpha: 0.5),
|
|
onTap: () => setState(() => _expanded = !_expanded),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
Icon(Icons.bug_report, size: 16, color: Colors.orange),
|
|
const SizedBox(width: 8),
|
|
Expanded(
|
|
child: Text(
|
|
AppStrings.rawApiResponse,
|
|
style: theme.textTheme.labelLarge?.copyWith(
|
|
color: Colors.orange,
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
),
|
|
),
|
|
Icon(
|
|
_expanded ? Icons.expand_less : Icons.expand_more,
|
|
color: Colors.orange,
|
|
),
|
|
],
|
|
),
|
|
if (_expanded) ...[
|
|
const SizedBox(height: 12),
|
|
Container(
|
|
width: double.infinity,
|
|
padding: const EdgeInsets.all(12),
|
|
decoration: BoxDecoration(
|
|
color: theme.colorScheme.surfaceContainerHighest.withValues(
|
|
alpha: 0.5,
|
|
),
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
child: SelectableText(
|
|
widget.rawJson,
|
|
style: theme.textTheme.bodySmall?.copyWith(
|
|
fontFamily: 'monospace',
|
|
fontSize: 11,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class ErrorIdBanner extends StatelessWidget {
|
|
final int errorId;
|
|
|
|
const ErrorIdBanner({super.key, required this.errorId});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final theme = Theme.of(context);
|
|
return Container(
|
|
width: double.infinity,
|
|
margin: const EdgeInsets.only(bottom: 12),
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
|
decoration: BoxDecoration(
|
|
color: theme.colorScheme.errorContainer,
|
|
borderRadius: BorderRadius.circular(12),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
Icon(
|
|
Icons.warning_amber_rounded,
|
|
size: 20,
|
|
color: theme.colorScheme.onErrorContainer,
|
|
),
|
|
const SizedBox(width: 10),
|
|
Expanded(
|
|
child: Text(
|
|
'API returned errorId: $errorId',
|
|
style: theme.textTheme.bodyMedium?.copyWith(
|
|
color: theme.colorScheme.onErrorContainer,
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|