89 lines
2.6 KiB
Dart
89 lines
2.6 KiB
Dart
// ignore_for_file: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member
|
|
|
|
part of 'chat_bloc.dart';
|
|
|
|
extension _ChatBlocAttachments on ChatBloc {
|
|
void _syncUploadedAttachments({
|
|
required String messageId,
|
|
required List<UploadedAttachment> uploadedAttachments,
|
|
}) {
|
|
if (uploadedAttachments.isEmpty) {
|
|
_markAttachmentUploadDone(messageId);
|
|
return;
|
|
}
|
|
final items = state.items.map((item) {
|
|
if (item is! TextMessageItem || item.id != messageId) {
|
|
return item;
|
|
}
|
|
final synced = item.attachments.map((attachment) {
|
|
final localPath = attachment['path'];
|
|
if (localPath is! String || localPath.isEmpty) {
|
|
return <String, dynamic>{...attachment, 'uploading': false};
|
|
}
|
|
UploadedAttachment? matched;
|
|
for (final candidate in uploadedAttachments) {
|
|
if (candidate.localPath == localPath) {
|
|
matched = candidate;
|
|
break;
|
|
}
|
|
}
|
|
if (matched == null) {
|
|
return <String, dynamic>{...attachment, 'uploading': false};
|
|
}
|
|
return <String, dynamic>{
|
|
...attachment,
|
|
'url': matched.url,
|
|
'mimeType': matched.mimeType,
|
|
'uploading': false,
|
|
};
|
|
}).toList();
|
|
return item.copyWith(attachments: synced);
|
|
}).toList();
|
|
emit(state.copyWith(items: items));
|
|
}
|
|
|
|
void _markAttachmentUploadDone(String messageId) {
|
|
final items = state.items.map((item) {
|
|
if (item is! TextMessageItem || item.id != messageId) {
|
|
return item;
|
|
}
|
|
final done = item.attachments
|
|
.map(
|
|
(attachment) => <String, dynamic>{
|
|
...attachment,
|
|
'uploading': false,
|
|
},
|
|
)
|
|
.toList();
|
|
return item.copyWith(attachments: done);
|
|
}).toList();
|
|
emit(state.copyWith(items: items));
|
|
}
|
|
|
|
Future<Uint8List?> _loadAttachmentPreview(String previewPath) async {
|
|
final cached = _attachmentPreviewCache[previewPath];
|
|
if (cached != null) {
|
|
return cached;
|
|
}
|
|
final pending = _attachmentPreviewInflight[previewPath];
|
|
if (pending != null) {
|
|
return pending;
|
|
}
|
|
|
|
final future = (() async {
|
|
try {
|
|
final bytes = await _service.fetchAttachmentPreview(previewPath);
|
|
_attachmentPreviewCache[previewPath] = bytes;
|
|
return bytes;
|
|
} catch (_) {
|
|
return null;
|
|
} finally {
|
|
_attachmentPreviewInflight.remove(previewPath);
|
|
}
|
|
})();
|
|
|
|
_attachmentPreviewInflight[previewPath] = future;
|
|
return future;
|
|
}
|
|
}
|