pickImages method
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;
}
}