import 'package:dio/dio.dart'; import 'package:stream_chat/src/api/responses.dart'; import 'package:stream_chat/src/client.dart'; import 'package:stream_chat/src/extensions/string_extension.dart'; import 'package:stream_chat/src/models/attachment_file.dart'; /// Class responsible for uploading images and files to a given channel abstract class AttachmentFileUploader { /// Uploads a [image] to the given channel. /// Returns [SendImageResponse] once sent successfully. /// /// Optionally, access upload progress using [onSendProgress] /// and cancel the request using [cancelToken] Future sendImage( AttachmentFile image, String channelId, String channelType, { ProgressCallback? onSendProgress, CancelToken? cancelToken, }); /// Uploads a [file] to the given channel. /// Returns [SendFileResponse] once sent successfully. /// /// Optionally, access upload progress using [onSendProgress] /// and cancel the request using [cancelToken] Future sendFile( AttachmentFile file, String channelId, String channelType, { ProgressCallback? onSendProgress, CancelToken? cancelToken, }); /// Deletes a image using its [url] from the given channel. /// Returns [EmptyResponse] once deleted successfully. /// /// Optionally, cancel the request using [cancelToken] Future deleteImage( String url, String channelId, String channelType, { CancelToken? cancelToken, }); /// Deletes a file using its [url] from the given channel. /// Returns [EmptyResponse] once deleted successfully. /// /// Optionally, cancel the request using [cancelToken] Future deleteFile( String url, String channelId, String channelType, { CancelToken? cancelToken, }); } /// Stream's default implementation of [AttachmentFileUploader] class StreamAttachmentFileUploader implements AttachmentFileUploader { /// Creates a new [StreamAttachmentFileUploader] instance. const StreamAttachmentFileUploader(this._client); final StreamChatClient _client; @override Future sendImage( AttachmentFile file, String channelId, String channelType, { ProgressCallback? onSendProgress, CancelToken? cancelToken, }) async { final filename = file.path?.split('/').last ?? file.name; final mimeType = filename?.mimeType; MultipartFile? multiPartFile; if (file.path != null) { multiPartFile = await MultipartFile.fromFile( file.path!, filename: filename, contentType: mimeType, ); } else if (file.bytes != null) { multiPartFile = MultipartFile.fromBytes( file.bytes!, filename: filename, contentType: mimeType, ); } final response = await _client.post( '/channels/$channelType/$channelId/image', data: FormData.fromMap({ 'file': multiPartFile, }), onSendProgress: onSendProgress, cancelToken: cancelToken, ); return _client.decode(response.data, SendImageResponse.fromJson); } @override Future sendFile( AttachmentFile file, String channelId, String channelType, { ProgressCallback? onSendProgress, CancelToken? cancelToken, }) async { final filename = file.path?.split('/').last ?? file.name; final mimeType = filename?.mimeType; MultipartFile? multiPartFile; if (file.path != null) { multiPartFile = await MultipartFile.fromFile( file.path!, filename: filename, contentType: mimeType, ); } else if (file.bytes != null) { multiPartFile = MultipartFile.fromBytes( file.bytes!, filename: filename, contentType: mimeType, ); } final response = await _client.post( '/channels/$channelType/$channelId/file', data: FormData.fromMap({ 'file': multiPartFile, }), onSendProgress: onSendProgress, cancelToken: cancelToken, ); return _client.decode(response.data, SendFileResponse.fromJson); } @override Future deleteImage( String url, String channelId, String channelType, { CancelToken? cancelToken, }) async { final response = await _client.delete( '/channels/$channelType/$channelId/image', queryParameters: {'url': url}, cancelToken: cancelToken, ); return _client.decode(response.data, EmptyResponse.fromJson); } @override Future deleteFile( String url, String channelId, String channelType, { CancelToken? cancelToken, }) async { final response = await _client.delete( '/channels/$channelType/$channelId/file', queryParameters: {'url': url}, cancelToken: cancelToken, ); return _client.decode(response.data, EmptyResponse.fromJson); } }