perform<T> method

Future<T> perform<T>(
  1. ApiRequest<T> request, {
  2. bool sessionRequest = true,
  3. bool video = false,
  4. void progressHandler(
    1. double progress
    )?,
})

Implementation

Future<T> perform<T>(
    ApiRequest<T> request, {
      bool sessionRequest = true,
      bool video = false,
      void Function(double progress)? progressHandler,
    }) async {
  var endpoint = request.endpoint;

  if (sessionRequest) {
    if (sessionToken != null) {
      endpoint = "/sessions/$sessionToken$endpoint";
    } else {
      throw ApiError(ApiErrorType.invalidData);
    }
  }

  final url = Uri.parse("$baseURL$endpoint");

  final headers = {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
  };

  if (apiKey != null && !sessionRequest) {
    headers['Authorization'] = apiKey!;
  }
  http.Request httpRequest = http.Request(request.method.value, url);
  httpRequest.headers.addAll(headers);

  if (request.method != HttpMethod.get) {
    final requestBody = request.toJson();
    httpRequest.body = jsonEncode(requestBody);
  }

  try {
    final streamedResponse = await httpRequest.send();

    if (progressHandler != null) {
      final contentLength = streamedResponse.contentLength ?? 0;
      int received = 0;

      final stream = streamedResponse.stream.map((chunk) {
        received += chunk.length;
        if (contentLength > 0) {
          progressHandler(received / contentLength);
        }
        return chunk;
      });

      final response = await http.Response.fromStream(
          http.StreamedResponse(stream, streamedResponse.statusCode,
            contentLength: streamedResponse.contentLength,
            headers: streamedResponse.headers,
            isRedirect: streamedResponse.isRedirect,
            persistentConnection: streamedResponse.persistentConnection,
            reasonPhrase: streamedResponse.reasonPhrase,
            request: streamedResponse.request,
          )
      );

      return _processResponse(response, request);
    } else {
      final response = await http.Response.fromStream(streamedResponse);
      return _processResponse(response, request);
    }
  } catch (error) {
    if (error is Error) {
      throw ApiError(ApiErrorType.networkError, error: error);
    } else {
      rethrow;
    }
  }
}