loadAndCacheAll<ChildData extends WithLangText, ParentData extends WithOffline, DDModel extends DropDownModel<ChildData, ParentData>> method

Future<bool> loadAndCacheAll<ChildData extends WithLangText, ParentData extends WithOffline, DDModel extends DropDownModel<ChildData, ParentData>>(
  1. DDModel caller,
  2. int depth, {
  3. String? name,
  4. String? parentID,
  5. List<Data>? assetCollector,
})

Implementation

Future<bool> loadAndCacheAll<
    ChildData extends WithLangText,
    ParentData extends WithOffline,
    DDModel extends DropDownModel<ChildData, ParentData>>(
  DDModel caller,
  int depth, {
  String? name,
  String? parentID,
  List<Data>? assetCollector,
}) async {
  final progressSession = DownloadProgress.instance.active;
  final isRootDownloadCall = assetCollector == null;
  final collectedAssets = assetCollector ?? <Data>[];

  void collectAssetData(Data data) {
    collectedAssets.add(data);
  }

  // base-case: CheckPointDefects have no children
  if (depth == 0) return true;
  depth--;
  try {
    //fail early if no connection
    await API().tryNetwork(requestType: Helper.SimulatedRequestType.GET);

    var localAssetsSucceeded = true;
    collectAssetData(caller.currentData);

    //get all children, this will also cache them internally
    if (caller.currentData is CheckPoint) {
      progressSession?.setStep(
        InspectionDownloadSteps.defects,
        label: InspectionDownloadSteps.defectsLabel,
      );
    } else if (caller.currentData is CheckCategory) {
      progressSession?.setStep(
        InspectionDownloadSteps.checkpoints,
        label: InspectionDownloadSteps.checkpointsLabel,
      );
    } else {
      progressSession?.setStep(
        InspectionDownloadSteps.categories,
        label: InspectionDownloadSteps.categoriesLabel,
      );
    }
    var children = await caller.all(preloadFullImages: false).last;
    for (final child in children) {
      collectAssetData(child as Data);
    }

    final childResults = <bool>[];
    for (final child in children) {
      if (depth == 0) {
        childResults.add(true); //base-case as to not call generateNextModel
        continue;
      }
      final childSucceeded = await loadAndCacheAll(
        caller.generateNextModel(child),
        depth,
        name: name,
        parentID: caller.currentData.id,
        assetCollector: collectedAssets,
      );
      childResults.add(childSucceeded);
    }

    if (caller.currentData is InspectionLocation) {
      if (isRootDownloadCall) {
        final photosSucceeded = await cacheInspectionImagesForDownload(
          collectedAssets,
          progressSession: progressSession,
        );
        localAssetsSucceeded = localAssetsSucceeded && photosSucceeded;
      }
      progressSession?.setStep(
        InspectionDownloadSteps.documents,
        label: InspectionDownloadSteps.documentsPrepareLabel,
      );
      final documentsSucceeded = await cacheInspectionDocumentsForDownload(
        caller.currentData as InspectionLocation,
        progressSession: progressSession,
      );
      localAssetsSucceeded = localAssetsSucceeded && documentsSucceeded;
    }

    //if all children succeeded recursive calling succeeded
    bool success = localAssetsSucceeded && childResults.every((el) => el);
    if (success) {
      caller.currentData.forceOffline = true;
      if (parentID == null) return false;

      try {
        await API().local.storeData(caller.currentData, forId: parentID);
      } catch (e) {
        return false;
      }
    }

    return success;
  } catch (error) {
    debugPrint('failed! ${depth + 1}');
    showToast(error.toString() +
        "\n" +
        'Probiere es später nochmal'); // Using string directly instead of S.current
    return false; //failed
  }
}