Render startup immediately and defer native work with a smooth home transition
This commit is contained in:
@@ -21,78 +21,79 @@ enum SchoolConnectionState {
|
||||
}
|
||||
|
||||
class SchoolSession extends ChangeNotifier {
|
||||
SchoolSession() {
|
||||
web = WebViewController()
|
||||
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
||||
..setNavigationDelegate(
|
||||
NavigationDelegate(
|
||||
onNavigationRequest: (request) async {
|
||||
final uri = Uri.tryParse(request.url);
|
||||
final upgrade = uri == null || !request.isMainFrame
|
||||
? null
|
||||
: SchoolNavigationPolicy.secureIdentityRedirect(uri);
|
||||
if (upgrade != null) {
|
||||
final generation = _pageGeneration;
|
||||
try {
|
||||
await web.loadRequest(upgrade);
|
||||
} catch (_) {
|
||||
if (generation == _pageGeneration) {
|
||||
_failure('学校身份认证暂时无法打开,请重试。');
|
||||
}
|
||||
}
|
||||
return NavigationDecision.prevent;
|
||||
}
|
||||
if (uri == null ||
|
||||
!SchoolNavigationPolicy.canNavigate(
|
||||
uri,
|
||||
isMainFrame: request.isMainFrame,
|
||||
)) {
|
||||
if (kDebugMode && request.isMainFrame) {
|
||||
debugPrint(
|
||||
'Blocked school navigation origin: ${uri?.scheme}://${uri?.host}',
|
||||
);
|
||||
}
|
||||
if (request.isMainFrame) _failure('学校跳转到了其他地址,请返回学校认证入口重试。');
|
||||
return NavigationDecision.prevent;
|
||||
}
|
||||
return NavigationDecision.navigate;
|
||||
},
|
||||
onPageStarted: (_) {
|
||||
_poll?.cancel();
|
||||
_manualRead = false;
|
||||
_pageGeneration++;
|
||||
_reader.invalidate();
|
||||
pendingDraft = null;
|
||||
pendingExams = null;
|
||||
if (!hasOpened || _routeClosed) return;
|
||||
_loading = true;
|
||||
notifyListeners();
|
||||
},
|
||||
onPageFinished: _loaded,
|
||||
onWebResourceError: (error) async {
|
||||
if (error.isForMainFrame != true || error.url == null) return;
|
||||
SchoolSession();
|
||||
// Creating Android WebView starts its browser engine. Do it on school access,
|
||||
// not while the student is opening an offline timetable.
|
||||
late final WebViewController web = _createWeb();
|
||||
WebViewController _createWeb() => WebViewController()
|
||||
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
||||
..setNavigationDelegate(
|
||||
NavigationDelegate(
|
||||
onNavigationRequest: (request) async {
|
||||
final uri = Uri.tryParse(request.url);
|
||||
final upgrade = uri == null || !request.isMainFrame
|
||||
? null
|
||||
: SchoolNavigationPolicy.secureIdentityRedirect(uri);
|
||||
if (upgrade != null) {
|
||||
final generation = _pageGeneration;
|
||||
final current = await web.currentUrl();
|
||||
if (hasOpened &&
|
||||
generation == _pageGeneration &&
|
||||
error.url == current) {
|
||||
_failure('学校页面暂时未能加载,请检查网络后重试。');
|
||||
try {
|
||||
await web.loadRequest(upgrade);
|
||||
} catch (_) {
|
||||
if (generation == _pageGeneration) {
|
||||
_failure('学校身份认证暂时无法打开,请重试。');
|
||||
}
|
||||
}
|
||||
},
|
||||
onHttpError: (error) async {
|
||||
final generation = _pageGeneration;
|
||||
final current = Uri.tryParse(await web.currentUrl() ?? '');
|
||||
if (hasOpened &&
|
||||
generation == _pageGeneration &&
|
||||
error.request != null &&
|
||||
error.request!.uri == current) {
|
||||
_failure('学校请求未完成,请稍后重试。');
|
||||
return NavigationDecision.prevent;
|
||||
}
|
||||
if (uri == null ||
|
||||
!SchoolNavigationPolicy.canNavigate(
|
||||
uri,
|
||||
isMainFrame: request.isMainFrame,
|
||||
)) {
|
||||
if (kDebugMode && request.isMainFrame) {
|
||||
debugPrint(
|
||||
'Blocked school navigation origin: ${uri?.scheme}://${uri?.host}',
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
late final WebViewController web;
|
||||
if (request.isMainFrame) _failure('学校跳转到了其他地址,请返回学校认证入口重试。');
|
||||
return NavigationDecision.prevent;
|
||||
}
|
||||
return NavigationDecision.navigate;
|
||||
},
|
||||
onPageStarted: (_) {
|
||||
_poll?.cancel();
|
||||
_manualRead = false;
|
||||
_pageGeneration++;
|
||||
_reader.invalidate();
|
||||
pendingDraft = null;
|
||||
pendingExams = null;
|
||||
if (!hasOpened || _routeClosed) return;
|
||||
_loading = true;
|
||||
notifyListeners();
|
||||
},
|
||||
onPageFinished: _loaded,
|
||||
onWebResourceError: (error) async {
|
||||
if (error.isForMainFrame != true || error.url == null) return;
|
||||
final generation = _pageGeneration;
|
||||
final current = await web.currentUrl();
|
||||
if (hasOpened &&
|
||||
generation == _pageGeneration &&
|
||||
error.url == current) {
|
||||
_failure('学校页面暂时未能加载,请检查网络后重试。');
|
||||
}
|
||||
},
|
||||
onHttpError: (error) async {
|
||||
final generation = _pageGeneration;
|
||||
final current = Uri.tryParse(await web.currentUrl() ?? '');
|
||||
if (hasOpened &&
|
||||
generation == _pageGeneration &&
|
||||
error.request != null &&
|
||||
error.request!.uri == current) {
|
||||
_failure('学校请求未完成,请稍后重试。');
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
final _reader = SchoolReader(SchoolPageAdapter());
|
||||
final _flow = SchoolLoginFlow();
|
||||
Timer? _timeout;
|
||||
|
||||
Reference in New Issue
Block a user