feat: 添加登录页面 URL 检测功能;更新 H5ShellPage 状态管理以支持路由变化
This commit is contained in:
@@ -133,11 +133,12 @@ class _H5ShellPageState extends State<H5ShellPage> {
|
||||
setState(() => _lineSlots[lineIndex].progress = progress);
|
||||
}
|
||||
},
|
||||
onPageStarted: (_) {
|
||||
onPageStarted: (url) {
|
||||
final slot = _lineSlots[lineIndex];
|
||||
slot.shellCoverFallbackTimer?.cancel();
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
slot.setCurrentUrl(url);
|
||||
slot.loadError = null;
|
||||
slot.progress = 0;
|
||||
slot.showShellCover = true;
|
||||
@@ -147,6 +148,9 @@ class _H5ShellPageState extends State<H5ShellPage> {
|
||||
onPageFinished: (_) {
|
||||
unawaited(_handlePageFinished(lineIndex));
|
||||
},
|
||||
onUrlChange: (change) {
|
||||
_updateSlotUrl(lineIndex, change.url);
|
||||
},
|
||||
onWebResourceError: (error) {
|
||||
if (error.isForMainFrame ?? true) {
|
||||
final slot = _lineSlots[lineIndex];
|
||||
@@ -183,6 +187,7 @@ class _H5ShellPageState extends State<H5ShellPage> {
|
||||
Future<void> _handlePageFinished(int lineIndex) async {
|
||||
await _loadShellBrandingIfNeeded();
|
||||
await _syncShellBranding(lineIndex);
|
||||
await _installRouteObserver(lineIndex);
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_lineSlots[lineIndex].progress = 100;
|
||||
@@ -196,6 +201,8 @@ class _H5ShellPageState extends State<H5ShellPage> {
|
||||
final decoded = jsonDecode(message.message);
|
||||
if (decoded is Map && decoded['type'] == 'first-screen-ready') {
|
||||
_hideShellCover(lineIndex);
|
||||
} else if (decoded is Map && decoded['type'] == 'route-changed') {
|
||||
_updateSlotUrl(lineIndex, decoded['url']?.toString());
|
||||
}
|
||||
} catch (_) {
|
||||
if (message.message == 'first-screen-ready') {
|
||||
@@ -260,6 +267,60 @@ class _H5ShellPageState extends State<H5ShellPage> {
|
||||
return _runJavaScriptSafely(lineIndex, script);
|
||||
}
|
||||
|
||||
Future<void> _installRouteObserver(int lineIndex) {
|
||||
const script = '''
|
||||
(() => {
|
||||
try {
|
||||
const notify = () => {
|
||||
try {
|
||||
window.OpenIMShell.postMessage(JSON.stringify({
|
||||
type: 'route-changed',
|
||||
url: window.location.href
|
||||
}));
|
||||
} catch (_) {}
|
||||
};
|
||||
|
||||
if (window.__OPENIM_FLUTTER_ROUTE_OBSERVER__) {
|
||||
window.__OPENIM_FLUTTER_ROUTE_OBSERVER__.notify();
|
||||
return;
|
||||
}
|
||||
|
||||
const originalPushState = window.history.pushState;
|
||||
const originalReplaceState = window.history.replaceState;
|
||||
|
||||
window.history.pushState = function() {
|
||||
const result = originalPushState.apply(this, arguments);
|
||||
notify();
|
||||
return result;
|
||||
};
|
||||
|
||||
window.history.replaceState = function() {
|
||||
const result = originalReplaceState.apply(this, arguments);
|
||||
notify();
|
||||
return result;
|
||||
};
|
||||
|
||||
window.addEventListener('popstate', notify);
|
||||
window.__OPENIM_FLUTTER_ROUTE_OBSERVER__ = { notify };
|
||||
notify();
|
||||
} catch (_) {}
|
||||
})();
|
||||
''';
|
||||
return _runJavaScriptSafely(lineIndex, script);
|
||||
}
|
||||
|
||||
void _updateSlotUrl(int lineIndex, String? url) {
|
||||
if (url == null || lineIndex < 0 || lineIndex >= _lineSlots.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
final slot = _lineSlots[lineIndex];
|
||||
final changed = slot.setCurrentUrl(url);
|
||||
if (changed && mounted) {
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _ensureLineLoaded(int lineIndex) async {
|
||||
final slot = _lineSlots[lineIndex];
|
||||
if (slot.hasLoadedInitialRequest) {
|
||||
@@ -270,6 +331,7 @@ class _H5ShellPageState extends State<H5ShellPage> {
|
||||
if (mounted) {
|
||||
slot.shellCoverFallbackTimer?.cancel();
|
||||
setState(() {
|
||||
slot.setCurrentUrl(slot.line.url);
|
||||
slot.loadError = null;
|
||||
slot.progress = 0;
|
||||
slot.showShellCover = true;
|
||||
@@ -369,6 +431,7 @@ class _H5ShellPageState extends State<H5ShellPage> {
|
||||
final bottomInset = MediaQuery.viewInsetsOf(context).bottom;
|
||||
final showLineSwitch = !currentSlot.showShellCover &&
|
||||
currentSlot.loadError == null &&
|
||||
currentSlot.isLoginPage &&
|
||||
bottomInset == 0;
|
||||
|
||||
return PopScope(
|
||||
@@ -448,8 +511,21 @@ class _H5LineWebViewSlot {
|
||||
String? loadError;
|
||||
bool showShellCover = true;
|
||||
bool hasLoadedInitialRequest = false;
|
||||
bool isLoginPage = false;
|
||||
String? currentUrl;
|
||||
Timer? shellCoverFallbackTimer;
|
||||
|
||||
bool setCurrentUrl(String url) {
|
||||
final nextIsLoginPage = AppConfig.isLoginPageUrl(url);
|
||||
if (currentUrl == url && isLoginPage == nextIsLoginPage) {
|
||||
return false;
|
||||
}
|
||||
|
||||
currentUrl = url;
|
||||
isLoginPage = nextIsLoginPage;
|
||||
return true;
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
shellCoverFallbackTimer?.cancel();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user