feat: 测试缓存 test
This commit is contained in:
121
lib/main.dart
121
lib/main.dart
@@ -16,6 +16,8 @@ const _shellBackground = Color(0xFFF8FBFF);
|
|||||||
const _shellAccent = Color(0xFF0089FF);
|
const _shellAccent = Color(0xFF0089FF);
|
||||||
const _shellSubText = Color(0xFF8E9AB0);
|
const _shellSubText = Color(0xFF8E9AB0);
|
||||||
const _resumeCoverDuration = Duration(milliseconds: 700);
|
const _resumeCoverDuration = Duration(milliseconds: 700);
|
||||||
|
const _urlOnlyShellMode = true;
|
||||||
|
const _urlOnlyWebViewUrl = 'https://h5-im.imharry.work/';
|
||||||
const _noCacheHeaders = {
|
const _noCacheHeaders = {
|
||||||
'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate',
|
'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate',
|
||||||
'Pragma': 'no-cache',
|
'Pragma': 'no-cache',
|
||||||
@@ -263,6 +265,10 @@ Future<void> main() async {
|
|||||||
systemNavigationBarIconBrightness: Brightness.dark,
|
systemNavigationBarIconBrightness: Brightness.dark,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
if (_urlOnlyShellMode) {
|
||||||
|
runApp(const UrlOnlyWebViewApp());
|
||||||
|
return;
|
||||||
|
}
|
||||||
final shellBranding = await ShellBranding.load();
|
final shellBranding = await ShellBranding.load();
|
||||||
runApp(ImWebViewApp(shellBranding: shellBranding));
|
runApp(ImWebViewApp(shellBranding: shellBranding));
|
||||||
}
|
}
|
||||||
@@ -300,6 +306,121 @@ class ShellBranding {
|
|||||||
static String _trim(String? value) => value?.trim() ?? '';
|
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 {
|
class ImWebViewApp extends StatelessWidget {
|
||||||
const ImWebViewApp({
|
const ImWebViewApp({
|
||||||
super.key,
|
super.key,
|
||||||
|
|||||||
Reference in New Issue
Block a user