createPresentationBloc method

void createPresentationBloc(
  1. String pathPage,
  2. String pageName,
  3. String apiName,
  4. String method,
  5. bool bodyList,
  6. bool responseList,
)

Implementation

void createPresentationBloc(
  String pathPage,
  String pageName,
  String apiName,
  String method,
  bool bodyList,
  bool responseList,
) {
  final apiClassName = apiName.pascalCase;

  final path = join(pathPage, 'presentation', 'bloc', apiName);
  DirectoryHelper.createDir(path);

  final bodyClass = getBodyClass(apiClassName, bodyList);
  final entityClass = getEntityClass(apiClassName, responseList);

  join(path, '${apiName}_state.dart').write('''part of '${apiName}_bloc.dart';

@immutable
abstract class ${apiClassName}State extends Equatable {
bool get isInitial => this is ${apiClassName}Initial;
bool get isLoading => this is ${apiClassName}Loading;
bool get isFailed => this is ${apiClassName}Failed;
bool get isSuccess => this is ${apiClassName}Success;
bool get isCanceled => this is ${apiClassName}Canceled;
${whenMethod(
    method,
    onStream: () {
      return '''bool get isStream => this is ${apiClassName}Stream;
bool get isPaused => this is ${apiClassName}Paused;
bool get isResumed => this is ${apiClassName}Resumed;''';
    },
    onFuture: () => '',
  )}

bool get isNotInitial => this is! ${apiClassName}Initial;
bool get isNotLoading => this is! ${apiClassName}Loading;
bool get isNotFailed => this is! ${apiClassName}Failed;
bool get isNotSuccess => this is! ${apiClassName}Success;
bool get isNotCanceled => this is! ${apiClassName}Canceled;
${whenMethod(
    method,
    onStream: () {
      return '''bool get isNotStream => this is! ${apiClassName}Stream;
bool get isNotPaused => this is! ${apiClassName}Paused;
bool get isNotResumed => this is! ${apiClassName}Resumed;''';
    },
    onFuture: () => '',
  )}

void when({
  void Function(${apiClassName}Initial state)? onInitial,
  void Function(${apiClassName}Loading state)? onLoading,
  void Function(${apiClassName}Failed state)? onFailed,
  void Function(${apiClassName}Success state)? onSuccess,
  void Function(${apiClassName}Canceled state)? onCanceled,
  ${whenMethod(
    method,
    onStream: () {
      return '''void Function(${apiClassName}Stream state)? onStream,
void Function(${apiClassName}Paused state)? onPaused,
void Function(${apiClassName}Resumed state)? onResumed,''';
    },
    onFuture: () => '',
  )}
}) {
  final state = this;
  if (state is ${apiClassName}Initial) {
    onInitial?.call(state);
  } else if (state is ${apiClassName}Loading) {
    onLoading?.call(state);
  } else if (state is ${apiClassName}Failed) {
    onFailed?.call(state);
  } else if (state is ${apiClassName}Success) {
    onSuccess?.call(state);
  } else if (state is ${apiClassName}Canceled) {
    onCanceled?.call(state);
  } ${whenMethod(
    method,
    onStream: () {
      return '''else if (state is ${apiClassName}Stream) {
    onStream?.call(state);
  } else if (state is ${apiClassName}Paused) {
    onPaused?.call(state);
  } else if (state is ${apiClassName}Resumed) {
    onResumed?.call(state);
  }''';
    },
    onFuture: () => '',
  )}
}

Widget builder({
  Widget Function(${apiClassName}Initial state)? onInitial,
  Widget Function(${apiClassName}Loading state)? onLoading,
  Widget Function(${apiClassName}Failed state)? onFailed,
  Widget Function(${apiClassName}Success state)? onSuccess,
  Widget Function(${apiClassName}Canceled state)? onCanceled,
  ${whenMethod(
    method,
    onStream: () {
      return '''Widget Function(${apiClassName}Stream state)? onStream,
 Widget Function(${apiClassName}Paused state)? onPaused,
 Widget Function(${apiClassName}Resumed state)? onResumed,''';
    },
    onFuture: () => '',
  )}
  Widget Function(${apiClassName}State state)? onStateBuilder,
}) {
  final state = this;
  final defaultWidget = onStateBuilder?.call(this) ?? const SizedBox.shrink();

  if (state is ${apiClassName}Initial) {
    return onInitial?.call(state) ?? defaultWidget;
  } else if (state is ${apiClassName}Loading) {
    return onLoading?.call(state) ?? defaultWidget;
  } else if (state is ${apiClassName}Failed) {
    return onFailed?.call(state) ?? defaultWidget;
  } else if (state is ${apiClassName}Success) {
    return onSuccess?.call(state) ?? defaultWidget;
  } else if (state is ${apiClassName}Canceled) {
    return onCanceled?.call(state) ?? defaultWidget;
  } ${whenMethod(
    method,
    onStream: () {
      return '''else if (state is ${apiClassName}Stream) {
    return onStream?.call(state) ?? defaultWidget;
  } else if (state is ${apiClassName}Paused) {
    return onPaused?.call(state) ?? defaultWidget;
  } else if (state is ${apiClassName}Resumed) {
    return onResumed?.call(state) ?? defaultWidget;
  }''';
    },
    onFuture: () => '',
  )}
  else {
    return defaultWidget;
  }
}
}

class ${apiClassName}Initial extends ${apiClassName}State {
@override
List<Object?> get props => [];
}

class ${apiClassName}Loading extends ${apiClassName}State {
 ${apiClassName}Loading(this.body, this.headers, this.extra,);

final $bodyClass body;
final Map<String, String>? headers;
final dynamic extra;

@override
List<Object?> get props => [body, headers, extra,];
}

class ${apiClassName}Failed extends ${apiClassName}State {
${apiClassName}Failed(this.body, this.headers, this.failure, this.extra,);

final $bodyClass body;
final Map<String, String>? headers;
final MorphemeFailure failure;
final dynamic extra;

@override
List<Object?> get props => [body, headers, failure, extra,];
}

class ${apiClassName}Canceled extends ${apiClassName}State {
${apiClassName}Canceled(this.extra);

final dynamic extra;

@override
List<Object?> get props => [extra];
}

${whenMethod(
    method,
    onStream: () {
      return '''class ${apiClassName}Stream extends ${apiClassName}State {
${apiClassName}Stream(this.body, this.headers, this.data, this.extra,);

final $bodyClass body;
final Map<String, String>? headers;
final $entityClass data;
final dynamic extra;

@override
List<Object?> get props => [body, headers, data, extra,];
}

class ${apiClassName}Paused extends ${apiClassName}State {
${apiClassName}Paused(this.extra);

final dynamic extra;

@override
List<Object?> get props => [extra];
}

class ${apiClassName}Resumed extends ${apiClassName}State {
${apiClassName}Resumed(this.extra);

final dynamic extra;

@override
List<Object?> get props => [extra];
}

class ${apiClassName}Success extends ${apiClassName}State {
${apiClassName}Success(this.body, this.headers, this.data, this.extra,);

final $bodyClass body;
final Map<String, String>? headers;
final List<$entityClass> data;
final dynamic extra;

@override
List<Object?> get props => [body, headers, data, extra,];
}''';
    },
    onFuture: () =>
        '''class ${apiClassName}Success extends ${apiClassName}State {
${apiClassName}Success(this.body, this.headers, this.data, this.extra,);

final $bodyClass body;
final Map<String, String>? headers;
final $entityClass data;
final dynamic extra;

@override
List<Object?> get props => [body, headers, data, extra,];
}''',
  )}
''');

  join(path, '${apiName}_event.dart').write('''part of '${apiName}_bloc.dart';

@immutable
abstract class ${apiClassName}Event extends Equatable {}

class Fetch$apiClassName extends ${apiClassName}Event {
Fetch$apiClassName(this.body, {this.headers, this.extra, ${isApplyCacheStrategy(method) ? 'this.cacheStrategy,' : ''}});

final $bodyClass body;
final Map<String, String>? headers;
final dynamic extra;
${isApplyCacheStrategy(method) ? 'final CacheStrategy? cacheStrategy;' : ''}

@override
List<Object?> get props => [body, headers, extra, ${isApplyCacheStrategy(method) ? 'cacheStrategy,' : ''}];
}

class Cancel$apiClassName extends ${apiClassName}Event {
Cancel$apiClassName({this.extra});

final dynamic extra;

@override
List<Object?> get props => [extra];
}

${whenMethod(
    method,
    onStream: () {
      return '''class Pause$apiClassName extends ${apiClassName}Event {
Pause$apiClassName({this.extra});

final dynamic extra;

@override
List<Object?> get props => [extra];
}

class Resume$apiClassName extends ${apiClassName}Event {
Resume$apiClassName({this.extra});

final dynamic extra;

@override
List<Object?> get props => [extra];
}''';
    },
    onFuture: () => '',
  )}''');

  join(path, '${apiName}_bloc.dart').write('''${whenMethod(
    method,
    onStream: () => "import 'dart:async';",
    onFuture: () => '',
  )}
${returnData == 'body_bytes' ? "import 'dart:typed_data';" : ''}

import 'package:core/core.dart';
import 'package:flutter/material.dart';

import '../../../data/models/body/${apiName}_body.dart';
${isReturnDataModel ? '''import '../../../domain/entities/${apiName}_entity.dart';''' : ''}
import '../../../domain/usecases/${apiName}_use_case.dart';

part '${apiName}_event.dart';
part '${apiName}_state.dart';

class ${apiClassName}Bloc extends MorphemeBloc<${apiClassName}Event, ${apiClassName}State> {
${apiClassName}Bloc({
  required this.useCase,
}) : super(${apiClassName}Initial()) {
  on<Fetch$apiClassName>((event, emit) async {
    emit(${apiClassName}Loading(event.body, event.headers, event.extra,),);
    ${whenMethod(
    method,
    onStream: () {
      return '''final results = useCase(event.body, headers: event.headers,);
    final completer = Completer();
    final List<$entityClass> buffer = [];
    _streamSubscription = results.listen(
      (result) {
        emit(
          result.fold(
            (failure) => ${apiClassName}Failed(
              event.body,
              event.headers,
              failure,
              event.extra,
            ),
            (success) {
              buffer.add(success);
              return ${apiClassName}Stream(
                event.body,
                event.headers,
                success,
                event.extra,
              );
            },
          ),
        );
      },
      onError: (error) {
        emit(
          ${apiClassName}Failed(
            event.body,
            event.headers,
            InternalFailure('An unexpected error occurred: \$error'),
            event.extra,
          ),
        );
        completer.complete();
      },
      onDone: () {
        emit(
          ${apiClassName}Success(
            event.body,
            event.headers,
            buffer,
            event.extra,
          ),
        );
        completer.complete();
      },
    );
    await completer.future;
  });
  on<Cancel$apiClassName>((event, emit) async {
    _streamSubscription?.cancel();
    _streamSubscription = null;
    emit(${apiClassName}Canceled(event.extra));
  });
  on<Pause$apiClassName>((event, emit) async {
    _streamSubscription?.pause();
    emit(${apiClassName}Paused(event.extra));
  });
  on<Resume$apiClassName>((event, emit) async {
    _streamSubscription?.resume();
    emit(${apiClassName}Resumed(event.extra));
  });''';
    },
    onFuture: () {
      return '''_cancelableOperation = CancelableOperation.fromFuture(
      useCase(
        event.body,
        headers: event.headers,
        ${isApplyCacheStrategy(method) ? 'cacheStrategy: event.cacheStrategy,' : ''}
      ),
    );
    final result = await _cancelableOperation?.valueOrCancellation();

    if (result == null) {
      emit(${apiClassName}Canceled(event.extra));
      return;
    }
    emit(
      result.fold(
        (failure) => ${apiClassName}Failed(event.body, event.headers, failure, event.extra,),
        (success) => ${apiClassName}Success(event.body, event.headers, success, event.extra,),
      ),
    );
  });
  on<Cancel$apiClassName>((event, emit) async {
    _cancelableOperation?.cancel();
    _cancelableOperation = null;
    emit(${apiClassName}Canceled(event.extra));
  });''';
    },
  )}

}

final ${apiClassName}UseCase useCase;

${whenMethod(
    method,
    onStream: () {
      return '''StreamSubscription<Either<MorphemeFailure, $entityClass>>? _streamSubscription;

@override
Future<void> close() {
  _streamSubscription?.cancel();
  _streamSubscription = null;
  return super.close();
}''';
    },
    onFuture: () {
      return '''CancelableOperation<Either<MorphemeFailure, $entityClass>>? _cancelableOperation;

@override
Future<void> close() {
  _cancelableOperation?.cancel();
  _cancelableOperation = null;
  return super.close();
}''';
    },
  )}
}''');

  StatusHelper.generated(join(path, '${apiName}_state.dart'));
  StatusHelper.generated(join(path, '${apiName}_event.dart'));
  StatusHelper.generated(join(path, '${apiName}_bloc.dart'));
}