Compare commits

..

No commits in common. "bcad10ae976e8dd14612aedbad2543813c5ba75f" and "509aae27df9554d9babd8d27868d11f0f4e749e7" have entirely different histories.

7 changed files with 174 additions and 199 deletions

View File

@ -288,6 +288,7 @@ class _DemoPageState extends State<DemoPage> {
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
color: Colors.grey[600], color: Colors.grey[600],
fontFamily: 'monospace',
), ),
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),

View File

@ -145,6 +145,7 @@ class _DioDemoPageState extends State<DioDemoPage> {
child: const Text( child: const Text(
'dependencies:\n dio: ^5.3.0', 'dependencies:\n dio: ^5.3.0',
style: TextStyle( style: TextStyle(
fontFamily: 'monospace',
fontSize: 13, fontSize: 13,
), ),
), ),
@ -210,6 +211,7 @@ dio.interceptors.add(YxNetInspectorDioInterceptor());
// Dio // Dio
final response = await dio.get('https://api.example.com/users');''', final response = await dio.get('https://api.example.com/users');''',
style: TextStyle( style: TextStyle(
fontFamily: 'monospace',
fontSize: 12, fontSize: 12,
height: 1.4, height: 1.4,
), ),

View File

@ -238,7 +238,7 @@ packages:
path: ".." path: ".."
relative: true relative: true
source: path source: path
version: "1.0.2" version: "1.0.0"
sdks: sdks:
dart: ">=3.7.0-0 <4.0.0" dart: ">=3.7.0-0 <4.0.0"
flutter: ">=3.18.0-18.0.pre.54" flutter: ">=3.18.0-18.0.pre.54"

View File

@ -102,8 +102,8 @@ class NetworkLogEntry {
String get formattedDuration { String get formattedDuration {
if (duration == null) return '未知'; if (duration == null) return '未知';
final ms = duration!.inMilliseconds; final ms = duration!.inMilliseconds;
if (ms < 1000) return '${ms} ms'; if (ms < 1000) return '${ms}毫秒';
return '${(ms / 1000).toStringAsFixed(1)} s'; return '${(ms / 1000).toStringAsFixed(1)}';
} }
/// URL /// URL
@ -116,15 +116,6 @@ class NetworkLogEntry {
} }
} }
String get hostUrl {
try {
final uri = Uri.parse(url);
return '${uri.host}';
} catch (e) {
return url;
}
}
/// ///
NetworkLogEntry copyWith({ NetworkLogEntry copyWith({
String? id, String? id,

View File

@ -103,16 +103,14 @@ class _YxInspectorPanelState extends State<YxInspectorPanel> {
} }
if (_isFullScreen) { if (_isFullScreen) {
// - //
return Material( return Material(
color: Colors.black.withValues(alpha: 0.5), color: Colors.black.withValues(alpha: 0.5),
child: SafeArea( child: Container(
child: Container( width: MediaQuery.of(context).size.width,
width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height,
height: double.infinity, color: widget.theme.backgroundColor,
color: widget.theme.backgroundColor, child: content,
child: content,
),
), ),
); );
} else { } else {
@ -135,150 +133,126 @@ class _YxInspectorPanelState extends State<YxInspectorPanel> {
} }
Widget _buildDetailHeader() { Widget _buildDetailHeader() {
final actions = [ return Container(
IconButton( padding: const EdgeInsets.all(16),
onPressed: () => _copyLogDetails(_selectedLog!), decoration: BoxDecoration(
icon: const Icon( color: widget.theme.primaryColor,
Icons.copy, borderRadius: _isFullScreen
color: Colors.white, ? BorderRadius.zero
), : const BorderRadius.only(
tooltip: '复制详情', topLeft: Radius.circular(16),
), topRight: Radius.circular(16),
IconButton(
onPressed: () {
_isFullScreen = !_isFullScreen;
setState(() {});
},
icon: Icon(
_isFullScreen ? Icons.fullscreen_exit : Icons.fullscreen,
color: Colors.white,
),
tooltip: _isFullScreen ? '退出全屏' : '全屏显示',
),
IconButton(
onPressed: widget.onClose,
icon: const Icon(
Icons.close,
color: Colors.white,
),
tooltip: '关闭',
),
];
return _isFullScreen
? AppBar(
title: Text('请求详情'),
backgroundColor: widget.theme.primaryColor,
foregroundColor: Colors.white,
// excludeHeaderSemantics: false
leading: IconButton(
onPressed: _hideLogDetail,
icon: const Icon(
Icons.arrow_back,
color: Colors.white,
), ),
),
child: Row(
children: [
IconButton(
onPressed: _hideLogDetail,
icon: const Icon(
Icons.arrow_back,
color: Colors.white,
), ),
centerTitle: false, tooltip: '返回列表',
actions: actions, ),
) const SizedBox(width: 8),
: Container( const Icon(
padding: const EdgeInsets.all(16), Icons.article_outlined,
decoration: BoxDecoration( color: Colors.white,
color: widget.theme.primaryColor, size: 24,
borderRadius: _isFullScreen ),
? BorderRadius.zero const SizedBox(width: 8),
: const BorderRadius.only( const Text(
topLeft: Radius.circular(16), '请求详情',
topRight: Radius.circular(16), style: TextStyle(
), color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold,
), ),
child: Row( ),
children: [ const Spacer(),
IconButton( IconButton(
onPressed: _hideLogDetail, onPressed: () => _copyLogDetails(_selectedLog!),
icon: const Icon( icon: const Icon(
Icons.arrow_back, Icons.copy,
color: Colors.white, color: Colors.white,
),
tooltip: '返回列表',
),
const Text(
'请求详情',
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
const Spacer(),
...actions
],
), ),
); tooltip: '复制详情',
),
IconButton(
onPressed: () {
_isFullScreen = !_isFullScreen;
setState(() {});
},
icon: Icon(
_isFullScreen ? Icons.fullscreen_exit : Icons.fullscreen,
color: Colors.white,
),
tooltip: _isFullScreen ? '退出全屏' : '全屏显示',
),
IconButton(
onPressed: widget.onClose,
icon: const Icon(
Icons.close,
color: Colors.white,
),
tooltip: '关闭',
),
],
),
);
} }
Widget _buildHeader() { Widget _buildHeader() {
final actions = [ return Container(
IconButton( padding: const EdgeInsets.all(16),
onPressed: () { decoration: BoxDecoration(
setState(() { color: widget.theme.primaryColor,
_isFullScreen = !_isFullScreen; borderRadius: _isFullScreen
}); ? BorderRadius.zero
}, : const BorderRadius.only(
icon: Icon( topLeft: Radius.circular(16),
_isFullScreen ? Icons.fullscreen_exit : Icons.fullscreen, topRight: Radius.circular(16),
color: Colors.white, ),
),
tooltip: _isFullScreen ? '退出全屏' : '全屏',
), ),
IconButton( child: Row(
onPressed: () { children: [
widget.controller.clearLogs(); const Icon(Icons.network_check, color: Colors.white, size: 24),
}, const SizedBox(width: 8),
icon: const Icon(Icons.clear_all, color: Colors.white), const Text(
tooltip: '清空日志', '网络检查器',
), style: TextStyle(
IconButton( color: Colors.white,
onPressed: widget.onClose, fontSize: 18,
icon: const Icon(Icons.close, color: Colors.white), fontWeight: FontWeight.bold,
),
];
return _isFullScreen
? AppBar(
title: Text('网络检查器'),
backgroundColor: widget.theme.primaryColor,
foregroundColor: Colors.white,
centerTitle: false,
actions: actions,
)
: Container(
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
decoration: BoxDecoration(
color: widget.theme.primaryColor,
borderRadius: _isFullScreen
? BorderRadius.zero
: const BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),
),
), ),
child: Row( ),
children: [ const Spacer(),
const Icon(Icons.network_check, color: Colors.white, size: 24), IconButton(
const SizedBox(width: 8), onPressed: () {
const Text( setState(() {
'网络检查器', _isFullScreen = !_isFullScreen;
style: TextStyle( });
color: Colors.white, },
fontSize: 18, icon: Icon(
fontWeight: FontWeight.bold, _isFullScreen ? Icons.fullscreen_exit : Icons.fullscreen,
), color: Colors.white,
),
const Spacer(),
...actions
],
), ),
); tooltip: _isFullScreen ? '退出全屏' : '全屏',
),
IconButton(
onPressed: () {
widget.controller.clearLogs();
},
icon: const Icon(Icons.clear_all, color: Colors.white),
tooltip: '清空日志',
),
IconButton(
onPressed: widget.onClose,
icon: const Icon(Icons.close, color: Colors.white),
),
],
),
);
} }
Widget _buildStatistics() { Widget _buildStatistics() {
@ -455,6 +429,35 @@ class _YxInspectorPanelState extends State<YxInspectorPanel> {
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10), padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
child: Row( child: Row(
children: [ children: [
//
Container(
width: 6,
height: 6,
decoration: BoxDecoration(
color: log.statusColor,
shape: BoxShape.circle,
),
),
const SizedBox(width: 8),
//
Container(
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
decoration: BoxDecoration(
color: _getMethodColor(log.method).withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(4),
),
child: Text(
log.method,
style: TextStyle(
fontSize: 10,
fontWeight: FontWeight.bold,
color: _getMethodColor(log.method),
),
),
),
const SizedBox(width: 8),
// URL和状态 // URL和状态
Expanded( Expanded(
child: Column( child: Column(
@ -473,39 +476,8 @@ class _YxInspectorPanelState extends State<YxInspectorPanel> {
const SizedBox(height: 2), const SizedBox(height: 2),
Row( Row(
children: [ children: [
//
Container(
width: 6,
height: 6,
decoration: BoxDecoration(
color: log.statusColor,
shape: BoxShape.circle,
),
),
const SizedBox(width: 8),
//
Container(
padding: const EdgeInsets.symmetric(
horizontal: 6, vertical: 2),
decoration: BoxDecoration(
color: _getMethodColor(log.method)
.withValues(alpha: 0.1),
borderRadius: BorderRadius.circular(4),
),
child: Text(
log.method,
style: TextStyle(
fontSize: 10,
fontWeight: FontWeight.bold,
color: _getMethodColor(log.method),
),
),
),
const SizedBox(width: 8),
Text( Text(
'${log.statusCode ?? "?"} ${log.formattedDuration}', '${log.statusCode ?? "?"}${log.formattedDuration}',
style: TextStyle( style: TextStyle(
fontSize: 11, fontSize: 11,
color: log.statusColor, color: log.statusColor,
@ -520,22 +492,28 @@ class _YxInspectorPanelState extends State<YxInspectorPanel> {
color: widget.theme.errorColor, color: widget.theme.errorColor,
), ),
], ],
Spacer(),
//
Text(
log.formattedTime.contains(' ')
? log.formattedTime.split(' ')[1]
: log.formattedTime, //
style: TextStyle(
fontSize: 10,
color: widget.theme.secondaryTextColor,
),
),
], ],
), ),
], ],
), ),
), ),
//
Text(
log.formattedTime.contains(' ')
? log.formattedTime.split(' ')[1]
: log.formattedTime, //
style: TextStyle(
fontSize: 10,
color: widget.theme.secondaryTextColor,
),
),
const SizedBox(width: 4),
Icon(
Icons.chevron_right,
size: 16,
color: widget.theme.secondaryTextColor.withValues(alpha: 0.5),
),
], ],
), ),
), ),

View File

@ -122,7 +122,6 @@ class YxLogDetailPage extends StatelessWidget {
], ],
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
_buildInfoRow('HOST', log.hostUrl, isUrl: true),
_buildInfoRow('URL', log.displayUrl, isUrl: true), _buildInfoRow('URL', log.displayUrl, isUrl: true),
if (log.requestData != null) ...[ if (log.requestData != null) ...[
const SizedBox(height: 8), const SizedBox(height: 8),
@ -145,6 +144,7 @@ class YxLogDetailPage extends StatelessWidget {
_formatRequestBody(log.requestData), _formatRequestBody(log.requestData),
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
fontFamily: 'monospace',
color: theme.textColor, color: theme.textColor,
), ),
), ),
@ -199,6 +199,7 @@ class YxLogDetailPage extends StatelessWidget {
log.responseData.toString(), log.responseData.toString(),
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
fontFamily: 'monospace',
color: theme.textColor, color: theme.textColor,
), ),
), ),
@ -256,6 +257,7 @@ class YxLogDetailPage extends StatelessWidget {
style: TextStyle( style: TextStyle(
color: theme.errorColor, color: theme.errorColor,
fontSize: 14, fontSize: 14,
fontFamily: 'monospace',
), ),
), ),
), ),
@ -351,6 +353,7 @@ class YxLogDetailPage extends StatelessWidget {
value, value,
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
fontFamily: 'monospace',
color: theme.primaryColor, color: theme.primaryColor,
), ),
) )

View File

@ -1,6 +1,6 @@
name: yx_net_inspector name: yx_net_inspector
description: A powerful network inspector with floating debug ball for Flutter apps. Monitor HTTP requests, responses, and debug network issues in real-time. description: A powerful network inspector with floating debug ball for Flutter apps. Monitor HTTP requests, responses, and debug network issues in real-time.
version: 1.0.3 version: 1.0.2
homepage: https://github.com/your-username/yx_net_inspector homepage: https://github.com/your-username/yx_net_inspector
environment: environment: