complete method

Future<StoryModel> complete()

Complete editing and return the story model

Implementation

Future<StoryModel> complete() async {
  assets.value.forEach((StoryElement element) {
    element.layerIndex = assets.value.indexOf(element);
  });

  assets.value.forEach((StoryElement element) {
    element.videoController?.video.pause();
    element.audioController?.pause();
  });
  final StoryModel result;
  final bool isContainsVideo = assets.value
      .any((StoryElement element) => element.type == ItemType.video);
  storyModel.colorFilter = selectedFilter.value.name;
  if (isContainsVideo) {
    storyModel.isVideoIncluded = true;
  }
  final List<StoryElement> elements = <StoryElement>[...assets.value];

  final DateTime startTime = DateTime.now();
  print('#Comptression started# : ${startTime.toIso8601String()}');
  bool isAudioIncluded = false;
  bool isVideoIncluded = false;
  bool isImageIncluded = false;

  await Future.forEach(elements, (StoryElement element) async {
    final String filePath = '${element.elementFile?.path}';
    print('#element.elementFile?# : ${filePath}');
    print('#element.type?# : ${element.type}');
    final File file = File(filePath);

    if (await file.exists()) {
      final int sizeInBytes = await file.length();
      print('element.elementFile? : ${sizeInBytes / (1024 * 1024)} MB');
    } else {
      print('element.elementFile? : File does not exist');
    }

    if (element.type == ItemType.video) {
      isVideoIncluded = true;
      if (element.videoController != null) {
        storyModel.videoDuration = element
            .videoController!.trimmedDuration.inMilliseconds
            .toDouble();
        element.elementFile = await CompressService.trimVideoAndCompress(
            element.videoController!);
      }
    } else if (element.type == ItemType.image) {
      isImageIncluded = true;
      element.elementFile =
          await CompressService.compressImage(XFile(element.value));
    } else if (!storyModel.isVideoIncluded &&
        element.type == ItemType.audio) {
      isAudioIncluded = true;
      storyModel.videoDuration = element.elementDuration + 0.0;
    } else if (element.type == ItemType.audio) {
      isAudioIncluded = true;
    }
  });

  if (isAudioIncluded && isVideoIncluded) {
    final StoryElement? videoElement = elements.firstWhereOrNull(
      (StoryElement element) => element.type == ItemType.video,
    );
    final StoryElement? audioElement = elements.firstWhereOrNull(
      (StoryElement element) => element.type == ItemType.audio,
    );
    if (audioElement != null && videoElement != null) {
      final XFile videoWithNewAudio = await VideoUtils.addAudioToVideo(
        audioPath: audioElement.elementFile!.path,
        videoPath: videoElement.elementFile!.path,
      );
      videoElement.elementFile = videoWithNewAudio;
      videoElement.value = videoWithNewAudio.path;
      elements.removeWhere(
          (StoryElement element) => element.id == audioElement.id);
    }
  } else if (isAudioIncluded && isImageIncluded) {
    final StoryElement? audioElement = elements.firstWhereOrNull(
      (StoryElement element) => element.type == ItemType.audio,
    );
    final StoryElement? imageElement = elements.firstWhereOrNull(
      (StoryElement element) => element.type == ItemType.image,
    );
    if (audioElement != null && imageElement != null) {
      if (imageElement.elementFile!.path.isNetworkImage()) {
        final HttpClient httpClient = HttpClient();
        try {
          final Directory cacheDir = await getTemporaryDirectory();
          final File imageFile = File(
              '${cacheDir.path}/${DateTime.now().millisecondsSinceEpoch}.png');
          final HttpClientRequest request = await httpClient
              .getUrl(Uri.parse(imageElement.elementFile!.path));
          final HttpClientResponse response = await request.close();
          if (response.statusCode == 200) {
            final Uint8List bytes =
                await consolidateHttpClientResponseBytes(response);
            await imageFile.writeAsBytes(bytes);
            imageElement.elementFile = XFile(imageFile.path);
          } else {}
        } catch (ex) {
          print(ex);
        } finally {
          httpClient.close();
        }
      }
      final XFile videoWithNewAudio = await VideoUtils.addAudioImage(
        audioPath: audioElement.elementFile!.path,
        imagePath: imageElement.elementFile!.path,
      );
      imageElement.elementFile = videoWithNewAudio;
      imageElement.type = ItemType.imageVideo;
      imageElement.value = videoWithNewAudio.path;
      elements.removeWhere(
          (StoryElement element) => element.id == audioElement.id);
      storyModel.isVideoIncluded = true;
    }
  }
  result = storyModel.copyWith(
    elements: elements,
  );
  result.isVideoIncluded = isVideoIncluded || isAudioIncluded;
  assets.value.clear();
  selectedFilter.value = PresetFilters.none;
  selectedItem.value = null;

  if (result.paletteColors.length == 1) {
    result.paletteColors.add(result.paletteColors.first);
  }
  Future.delayed(const Duration(seconds: 5), () {
    assets.value.forEach((StoryElement element) {
      element.videoController?.dispose();
      element.videoControllerView?.dispose();
      element.audioController?.dispose();
    });
  });

  final DateTime endTime = DateTime.now();
  print('#Comptression end# : ${endTime.toIso8601String()}');
  print(
      '#Comptression Duration# : ${endTime.difference(startTime).inSeconds} seconds');

  debugPrint('storyModel :${result.toJson()}');
  return result;
}