setNewRoutePath method
Navigation state to app state
Implementation
@override
Future<void> setNewRoutePath(RouteInformation routeInformation) async {
if (routeInformation.location != null && !_ignoreNextBrowserCalls) {
final newUrl = routeInformation.location!;
final routeState = routeInformation.state as Map<String, dynamic>?;
final newJsonState = routeState?['app'];
// Get the new state
final Map<String, String> newState = newJsonState != null
? newJsonState.map<String, String>(
(key, value) => MapEntry(
key.toString(),
value.toString(),
),
)
: <String, String>{};
int? newHistoryIndex = routeState?['historyIndex'];
// Check if this is the first route
if (newHistoryIndex == null || newHistoryIndex == 0) {
// If so, check is the url reported by the browser is the same as the initial url
// We check "routeInformation.location == '/'" to enable deep linking
if (newUrl == '/' && newUrl != initialUrl) {
return;
}
}
// Whether we are visiting a previously visited url
// or a new one has been pushed
final bool isPush = newHistoryIndex == null;
final vNavigationMethod = isPush
? VNavigationMethod.browserPush
: VNavigationMethod.browserHistory;
final newUri = Uri.parse(newUrl);
// Update the app with the new url
await _updateUrl(
newUri,
newVRoute: _getNewVRoute(uri: newUri, historyState: newState),
newHistoryState: newState,
onCancel: () async {
VLogPrinter.show(
VStoppedNavigationTo(
vNavigationMethod: vNavigationMethod,
url: newUrl,
),
);
// If the navigation is canceled and we are on the web, we need to sync the browser
if (Platform.isWeb) {
// How much we need to jump in the url history to go back to the previous location
final historyDelta = isPush
? -1
: _vRouterScope.vHistory.historyIndex - newHistoryIndex;
// If we can't go simply don't
if (!historyCanGo(historyDelta)) {
return;
}
// If delta is 0 just stay
if (historyDelta == 0) {
return;
}
// Else go and wait for the change to happen
BrowserHelpers.browserGo(historyDelta);
await BrowserHelpers.onBrowserPopState.first;
}
},
onUpdate: () {
VLogPrinter.show(
VSuccessfulNavigationTo(
vNavigationMethod: vNavigationMethod,
url: newUrl,
),
);
// If the navigation is successful, sync the vHistory
if (isPush) {
_vRouterScope.vHistory.pushLocation(
VRouteInformation(url: newUrl, state: newState),
);
} else {
_vRouterScope.vHistory.go(
newHistoryIndex - _vRouterScope.vHistory.historyIndex,
);
}
},
);
}
}