pickImages method

Future<MiniProgramGalleryResult> pickImages({
  1. required String miniProgramId,
  2. required MiniProgramGalleryPolicy policy,
  3. int maxImages = 1,
  4. int maxWidth = 2048,
  5. int maxHeight = 2048,
  6. int quality = 90,
})

Implementation

Future<MiniProgramGalleryResult> pickImages({
  required String miniProgramId,
  required MiniProgramGalleryPolicy policy,
  int maxImages = 1,
  int maxWidth = 2048,
  int maxHeight = 2048,
  int quality = 90,
}) async {
  if (_disposed) throw StateError('MiniProgramGalleryManager is disposed.');
  if (!policy.enabled) {
    throw const MiniProgramGalleryException(
      errorCode: MiniProgramErrorCodes.galleryNotAccepted,
      message: 'Gallery selection is not accepted by host policy.',
    );
  }
  if (maxImages < 1 ||
      maxImages > miniProgramGalleryMaxImages ||
      policy.maxImages < 1 ||
      policy.maxImages > miniProgramGalleryMaxImages ||
      policy.maxImageBytes < 1 ||
      policy.maxImageBytes > 100 * 1024 * 1024 ||
      policy.maxTotalBytes < 1 ||
      policy.maxTotalBytes > 300 * 1024 * 1024 ||
      maxWidth < 64 ||
      maxWidth > 8192 ||
      maxHeight < 64 ||
      maxHeight > 8192 ||
      quality < 1 ||
      quality > 100) {
    throw const MiniProgramGalleryException(
      errorCode: MiniProgramErrorCodes.galleryInvalidRequest,
      message: 'The gallery request or accepted limits are invalid.',
    );
  }
  if (_active != null) {
    throw const MiniProgramGalleryException(
      errorCode: MiniProgramErrorCodes.galleryRequestInProgress,
      message: 'A gallery selection is already in progress.',
    );
  }
  final operation = _GalleryOperation(
    'gallery_${DateTime.now().microsecondsSinceEpoch}_${++_sequence}',
    miniProgramId,
  );
  _active = operation;
  final limit = math.min(maxImages, policy.maxImages);
  MiniProgramGalleryResult? result;
  final registered = <String>[];
  try {
    result = await provider.pickImages(
      MiniProgramGalleryRequest(
        selectionId: operation.id,
        miniProgramId: miniProgramId,
        maxImages: limit,
        maxImageBytes: policy.maxImageBytes,
        maxTotalBytes: policy.maxTotalBytes,
        maxWidth: maxWidth,
        maxHeight: maxHeight,
        quality: quality,
      ),
    );
    if (operation.cancelled || _disposed) {
      throw const MiniProgramGalleryException(
        errorCode: MiniProgramErrorCodes.gallerySelectionCancelled,
        message: 'Photo selection was cancelled.',
      );
    }
    result.validate();
    if (result.selectionId != operation.id ||
        result.images.length > limit ||
        result.images.any(
          (image) => mediaManager.isRegistered(image.mediaRef),
        )) {
      throw const MiniProgramGalleryException(
        errorCode: MiniProgramErrorCodes.galleryInvalidResult,
        message: 'The host returned invalid gallery references.',
      );
    }
    final total = result.images.fold<int>(
      0,
      (sum, image) => sum + image.bytes,
    );
    if (total > policy.maxTotalBytes ||
        result.images.any(
          (image) =>
              image.bytes > policy.maxImageBytes ||
              image.width > maxWidth ||
              image.height > maxHeight,
        )) {
      throw const MiniProgramGalleryException(
        errorCode: MiniProgramErrorCodes.galleryLimitExceeded,
        message: 'The selected photos exceed accepted gallery limits.',
      );
    }
    for (final image in result.images) {
      mediaManager.register(
        miniProgramId: miniProgramId,
        mediaRef: image.mediaRef,
      );
      registered.add(image.mediaRef);
      _owners[image.mediaRef] = miniProgramId;
    }
    return result;
  } catch (error) {
    if (result != null) {
      for (final ref
          in result.images.map((image) => image.mediaRef).toSet()) {
        if (registered.contains(ref)) {
          await _release(miniProgramId, ref);
        } else if (!mediaManager.isRegistered(ref)) {
          await _releaseNative(miniProgramId, ref);
        }
      }
    }
    if (error is FormatException || error is MiniProgramMediaException) {
      throw const MiniProgramGalleryException(
        errorCode: MiniProgramErrorCodes.galleryInvalidResult,
        message: 'The host returned invalid gallery metadata.',
      );
    }
    rethrow;
  } finally {
    if (identical(_active, operation)) _active = null;
  }
}