feat: 添加 H5 快照调试信息面板,优化调试体验;更新版本号至 6.9.2+2

This commit is contained in:
Booker
2026-05-26 19:46:18 +07:00
parent 7702dee27f
commit 81aeaa8f22
2 changed files with 94 additions and 2 deletions

View File

@@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:permission_handler/permission_handler.dart';
@@ -339,6 +340,7 @@ class _H5ShellPageState extends State<H5ShellPage> with WidgetsBindingObserver {
bool _showShellCover = true;
bool _runtimeCachePurgeStarted = false;
bool _runtimeCachePurgeReloaded = false;
String? _h5SnapshotDebugText;
Timer? _shellCoverTimer;
Timer? _runtimeCachePurgeFallbackTimer;
@@ -688,14 +690,65 @@ class _H5ShellPageState extends State<H5ShellPage> with WidgetsBindingObserver {
final result = await _controller.runJavaScriptReturningResult(
_inspectH5SnapshotScript,
);
final snapshot = _decodeJavaScriptStringResult(result);
debugPrint(
'[H5Shell] loaded H5 snapshot: ${_decodeJavaScriptStringResult(result)}',
'[H5Shell] loaded H5 snapshot: $snapshot',
);
_updateH5SnapshotDebugText(snapshot);
} catch (error) {
debugPrint('[H5Shell] loaded H5 snapshot failed: $error');
}
}
void _updateH5SnapshotDebugText(String snapshot) {
if (!kDebugMode || !mounted) {
return;
}
setState(() {
_h5SnapshotDebugText = _formatH5SnapshotDebugText(snapshot);
});
}
String _formatH5SnapshotDebugText(String snapshot) {
try {
final decoded = jsonDecode(snapshot);
if (decoded is! Map) {
return snapshot;
}
final href = (decoded['href'] as String? ?? '').trim();
final title = (decoded['title'] as String? ?? '').trim();
final bodyText = (decoded['bodyText'] as String? ?? '').trim();
final scripts = decoded['scripts'];
final links = decoded['links'];
final assets = <String>[
if (scripts is List)
...scripts.whereType<String>().where((value) => value.isNotEmpty),
if (links is List)
...links.whereType<String>().where((value) => value.isNotEmpty),
];
final importantAssets = assets
.where(
(asset) =>
asset.contains('/assets/index-') ||
asset.contains('LoginBrandHeader') ||
asset.contains('useLoginBranding'),
)
.take(8)
.join('\n');
return [
if (title.isNotEmpty) 'title: $title',
if (href.isNotEmpty) 'url: $href',
if (importantAssets.isNotEmpty) 'assets:\n$importantAssets',
if (bodyText.isNotEmpty) 'text: $bodyText',
].join('\n');
} catch (_) {
return snapshot;
}
}
String _decodeJavaScriptStringResult(Object? result) {
if (result == null) {
return '';
@@ -864,6 +917,15 @@ class _H5ShellPageState extends State<H5ShellPage> with WidgetsBindingObserver {
message: _loadError!,
onRetry: () => unawaited(_loadHome()),
),
if (kDebugMode && _h5SnapshotDebugText != null)
Positioned(
left: 8,
right: 8,
bottom: 12,
child: IgnorePointer(
child: _H5SnapshotDebugPanel(text: _h5SnapshotDebugText!),
),
),
],
),
),
@@ -872,6 +934,36 @@ class _H5ShellPageState extends State<H5ShellPage> with WidgetsBindingObserver {
}
}
class _H5SnapshotDebugPanel extends StatelessWidget {
const _H5SnapshotDebugPanel({required this.text});
final String text;
@override
Widget build(BuildContext context) {
return DecoratedBox(
decoration: BoxDecoration(
color: Colors.black.withValues(alpha: 0.72),
borderRadius: BorderRadius.circular(8),
),
child: Padding(
padding: const EdgeInsets.all(8),
child: Text(
text,
maxLines: 10,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: Colors.white,
fontSize: 10,
height: 1.25,
letterSpacing: 0,
),
),
),
);
}
}
class _ErrorPanel extends StatelessWidget {
const _ErrorPanel({required this.message, required this.onRetry});

View File

@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 6.9.1+1
version: 6.9.2+2
environment:
sdk: ">=3.6.0 <4.0.0"