setNewRoutePath method

  1. @override
Future<void> setNewRoutePath(
  1. RouteInformation routeInformation
)
override

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,
          );
        }
      },
    );
  }
}