👽 Fix attachment uploading

This commit is contained in:
2024-12-28 17:19:20 +08:00
parent 91c85e8a58
commit cf0df91d8c
6 changed files with 785 additions and 152 deletions

View File

@ -21,7 +21,7 @@ class SnAttachmentProvider {
void putCache(Iterable<SnAttachment> items, {bool noCheck = false}) {
for (final item in items) {
if ((item.isAnalyzed && item.isUploaded) || noCheck) {
if (item.isAnalyzed || noCheck) {
_cache[item.rid] = item;
}
}
@ -34,7 +34,7 @@ class SnAttachmentProvider {
final resp = await _sn.client.get('/cgi/uc/attachments/$rid/meta');
final out = SnAttachment.fromJson(resp.data);
if (out.isAnalyzed && out.isUploaded) {
if (out.isAnalyzed) {
_cache[rid] = out;
}
@ -62,11 +62,12 @@ class SnAttachmentProvider {
'id': pendingFetch.join(','),
},
);
final out = resp.data['data'].map((e) => e['id'] == 0 ? null : SnAttachment.fromJson(e)).toList();
final List<SnAttachment?> out =
resp.data['data'].map((e) => e['id'] == 0 ? null : SnAttachment.fromJson(e)).cast<SnAttachment?>().toList();
for (final item in out) {
if (item == null) continue;
if (item.isAnalyzed && item.isUploaded) {
if (item.isAnalyzed) {
_cache[item.rid] = item;
}
result[randomMapping[item.rid]!] = item;
@ -117,7 +118,7 @@ class SnAttachmentProvider {
return SnAttachment.fromJson(resp.data);
}
Future<(SnAttachment, int)> chunkedUploadInitialize(
Future<(SnAttachmentFragment, int)> chunkedUploadInitialize(
int size,
String filename,
String pool,
@ -134,7 +135,7 @@ class SnAttachmentProvider {
mimetypeOverride = mimetype;
}
final resp = await _sn.client.post('/cgi/uc/attachments/multipart', data: {
final resp = await _sn.client.post('/cgi/uc/fragments', data: {
'alt': fileAlt,
'name': filename,
'pool': pool,
@ -143,17 +144,17 @@ class SnAttachmentProvider {
if (mimetypeOverride != null) 'mimetype': mimetypeOverride,
});
return (SnAttachment.fromJson(resp.data['meta']), resp.data['chunk_size'] as int);
return (SnAttachmentFragment.fromJson(resp.data['meta']), resp.data['chunk_size'] as int);
}
Future<SnAttachment> _chunkedUploadOnePart(
Future<dynamic> _chunkedUploadOnePart(
Uint8List data,
String rid,
String cid, {
Function(double progress)? onProgress,
}) async {
final resp = await _sn.client.post(
'/cgi/uc/attachments/multipart/$rid/$cid',
'/cgi/uc/fragments/$rid/$cid',
data: data,
options: Options(headers: {'Content-Type': 'application/octet-stream'}),
onSendProgress: (count, total) {
@ -163,21 +164,27 @@ class SnAttachmentProvider {
},
);
return SnAttachment.fromJson(resp.data);
if (resp.data['attachment'] != null) {
return SnAttachment.fromJson(resp.data['attachment']);
} else {
return SnAttachmentFragment.fromJson(resp.data['fragment']);
}
}
Future<SnAttachment> chunkedUploadParts(
XFile file,
SnAttachment place,
SnAttachmentFragment place,
int chunkSize, {
Function(double progress)? onProgress,
}) async {
final Map<String, dynamic> chunks = place.fileChunks ?? {};
final Map<String, dynamic> chunks = place.fileChunks;
var currentTask = 0;
final queue = Queue<Future<void>>();
final activeTasks = <Future<void>>[];
late SnAttachment out;
for (final entry in chunks.entries) {
queue.add(() async {
final beginCursor = entry.value * chunkSize;
@ -187,7 +194,7 @@ class SnAttachmentProvider {
);
final data = Uint8List.fromList(await file.openRead(beginCursor, endCursor).expand((chunk) => chunk).toList());
place = await _chunkedUploadOnePart(
final result = await _chunkedUploadOnePart(
data,
place.rid,
entry.key,
@ -197,6 +204,12 @@ class SnAttachmentProvider {
onProgress?.call(overallProgress);
currentTask++;
if (result is SnAttachmentFragment) {
place = result;
} else {
out = result as SnAttachment;
}
}());
}
@ -213,7 +226,7 @@ class SnAttachmentProvider {
}
}
return place;
return out;
}
Future<SnAttachment> updateOne(