feat: 测试缓存 test

This commit is contained in:
Booker
2026-05-26 19:57:48 +07:00
parent 81aeaa8f22
commit f47895d893

View File

@@ -16,6 +16,8 @@ const _shellBackground = Color(0xFFF8FBFF);
const _shellAccent = Color(0xFF0089FF);
const _shellSubText = Color(0xFF8E9AB0);
const _resumeCoverDuration = Duration(milliseconds: 700);
const _urlOnlyShellMode = true;
const _urlOnlyWebViewUrl = 'https://h5-im.imharry.work/';
const _noCacheHeaders = {
'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate',
'Pragma': 'no-cache',
@@ -263,6 +265,10 @@ Future<void> main() async {
systemNavigationBarIconBrightness: Brightness.dark,
),
);
if (_urlOnlyShellMode) {
runApp(const UrlOnlyWebViewApp());
return;
}
final shellBranding = await ShellBranding.load();
runApp(ImWebViewApp(shellBranding: shellBranding));
}
@@ -300,6 +306,121 @@ class ShellBranding {
static String _trim(String? value) => value?.trim() ?? '';
}
class UrlOnlyWebViewApp extends StatelessWidget {
const UrlOnlyWebViewApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: _urlOnlyWebViewUrl,
debugShowCheckedModeBanner: false,
theme: ThemeData(scaffoldBackgroundColor: Colors.white),
home: const UrlOnlyWebViewPage(),
);
}
}
class UrlOnlyWebViewPage extends StatefulWidget {
const UrlOnlyWebViewPage({super.key});
@override
State<UrlOnlyWebViewPage> createState() => _UrlOnlyWebViewPageState();
}
class _UrlOnlyWebViewPageState extends State<UrlOnlyWebViewPage> {
late final WebViewController _controller;
int _progress = 0;
String? _loadError;
@override
void initState() {
super.initState();
_controller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setBackgroundColor(Colors.white)
..setNavigationDelegate(
NavigationDelegate(
onProgress: (progress) {
if (mounted) {
setState(() => _progress = progress);
}
},
onPageStarted: (_) {
if (mounted) {
setState(() {
_loadError = null;
_progress = 0;
});
}
},
onPageFinished: (url) {
debugPrint('[UrlOnlyWebView] finished: $url');
if (mounted) {
setState(() => _progress = 100);
}
},
onWebResourceError: (error) {
if (error.isForMainFrame ?? true) {
if (mounted) {
setState(() => _loadError = error.description);
}
}
},
onNavigationRequest: _handleUrlOnlyNavigationRequest,
),
)
..loadRequest(Uri.parse(_urlOnlyWebViewUrl));
}
Future<NavigationDecision> _handleUrlOnlyNavigationRequest(
NavigationRequest request,
) async {
final uri = Uri.tryParse(request.url);
if (uri == null) {
return NavigationDecision.prevent;
}
const webSchemes = {'http', 'https', 'about', 'data'};
if (webSchemes.contains(uri.scheme)) {
return NavigationDecision.navigate;
}
try {
await launchUrl(uri, mode: LaunchMode.externalApplication);
} catch (_) {}
return NavigationDecision.prevent;
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: SafeArea(
bottom: false,
child: Stack(
children: [
WebViewWidget(controller: _controller),
if (_progress < 100)
LinearProgressIndicator(
value: _progress == 0 ? null : _progress / 100,
minHeight: 2,
),
if (_loadError != null)
_ErrorPanel(
message: _loadError!,
onRetry: () {
setState(() => _loadError = null);
_controller.loadRequest(Uri.parse(_urlOnlyWebViewUrl));
},
),
],
),
),
);
}
}
class ImWebViewApp extends StatelessWidget {
const ImWebViewApp({
super.key,