createContextForDiff method

AFBuildContext<TStateView, TRouteParam>? createContextForDiff(
  1. AFStore store,
  2. AFScreenID screenId,
  3. AFWidgetID wid, {
  4. required AFRouteParam? launchParam,
})
inherited

Implementation

AFBuildContext<TStateView, TRouteParam>? createContextForDiff(AFStore store, AFScreenID screenId, AFWidgetID wid, { required AFRouteParam? launchParam }) {
  TRouteParam? actualLaunchParam;
  if(launchParam is TRouteParam) {
    actualLaunchParam = launchParam;
  } else if(launchParam is AFRouteParamRef) {
    final foundSeg = store.state.public.route.findRouteParamFull(screenId: launchParam.screenId, wid: launchParam.wid, routeLocation: launchParam.routeLocation);
    final foundParam = foundSeg?.param;
    if(foundParam != null && foundParam is TRouteParam) {
      actualLaunchParam = foundParam;
    } else {
      throw AFException("Invalid type ${foundParam?.runtimeType} for route param, expected $TRouteParam");
    }
  }

  if(AFibD.config.isTestContext) {
    final testContext = _createTestContext(store, screenId, wid, launchParam: actualLaunchParam);
    if(testContext != null) {
      return testContext;
    }
  }
  var paramSeg = findRouteSegment(store.state, screenId, wid, launchParam: actualLaunchParam);

  /// drawers can be dragged onto the screen spontaneously, without any kind of navigation.   In that case, we need to
  /// dynamically create a launch param
  if(paramSeg == null) {
    final createDefault = createDefaultRouteParam;
    if(createDefault != null) {
      final source = AFRouteParamRef(screenId: screenId, wid: wid, routeLocation: AFRouteLocation.globalPool);
      launchParam = createDefault(source, store.state.public) as TRouteParam?;
      paramSeg = findRouteSegment(store.state, screenId, wid, launchParam: actualLaunchParam);
    }
  }

  // this is a super weird case where we are transitioning between the demo mode store and the real store,
  // with different route states in each one.
  if(screenId == AFUIScreenID.screenDemoModeEnter || screenId == AFUIScreenID.screenDemoModeExit) {
    paramSeg = AFRouteSegment.withParam(AFRouteParamUnused.unused, null, null);
  }

  if(paramSeg == null) {
    assert(false, "No route param was found for ${this.runtimeType}.  If you reached this in testing, you may not be on the screen you think you are on in your test scenario.  You might have forgotten to navigate to the screen.  Or, you might have failed to close a dialog/bottomsheet/drawer in a test that displays one, which can lead to this error.");
    return null;
  }

  var children = paramSeg.children;
  // this is a child widget, propagate its parent's children down.
  if(wid != AFUIWidgetID.useScreenParam) {
    final parentSeg = findRouteSegment(store.state, screenId, AFUIWidgetID.useScreenParam, launchParam: null);
    children = parentSeg?.children;
  }

  final param = paramSeg.param as TRouteParam;
  // load in the state view.
  final stateModels = createStateViewAF(store.state, param, children);

  // lookup all the themes

  final standard = AFStandardBuildContextData(
    screenId: screenId,
    context: null,
    config: this,
    dispatcher:  createDispatcher(store),
    themes: store.state.public.themes,
  );

  final sourceModels = stateModels.where((e) => e != null);
  final models = List<Object>.from(sourceModels);


  // now, create the state view.
  final modelMap = AFFlexibleStateView.createModels(models);
  final stateView = stateViewCreator(modelMap);

  final context = createContext(standard, stateView, param, children);
  return context;
}