Handle offline upload fallback as deferred pending state

This commit is contained in:
2026-05-18 14:50:58 +08:00
parent c94d453e3a
commit c85c4a3f5b

View File

@@ -143,6 +143,8 @@ class _UploadPageState extends State<UploadPage> {
} }
Future<void> _uploadAll() async { Future<void> _uploadAll() async {
var deferredCount = 0;
var failedCount = 0;
for (final item in _photos.where((i) => i.status == UploadStatus.pending)) { for (final item in _photos.where((i) => i.status == UploadStatus.pending)) {
setState(() => item.status = UploadStatus.uploading); setState(() => item.status = UploadStatus.uploading);
try { try {
@@ -152,9 +154,31 @@ class _UploadPageState extends State<UploadPage> {
? UploadStatus.done ? UploadStatus.done
: UploadStatus.failed; : UploadStatus.failed;
}); });
} catch (_) { if (res.statusCode != 200) {
setState(() => item.status = UploadStatus.failed); failedCount++;
} }
} catch (e) {
if (_isNetworkError(e)) {
setState(() => item.status = UploadStatus.pending);
deferredCount++;
} else {
setState(() => item.status = UploadStatus.failed);
failedCount++;
}
}
}
if (mounted && deferredCount > 0) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'$deferredCount upload(s) deferred: network unavailable. Try again when connection is back.',
),
),
);
} else if (mounted && failedCount > 0) {
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('$failedCount upload(s) failed.')));
} }
await _loadGallery(); await _loadGallery();
} }
@@ -213,7 +237,7 @@ class _UploadPageState extends State<UploadPage> {
req.headers['Authorization'] = 'Bearer $token'; req.headers['Authorization'] = 'Bearer $token';
req.files.add(await http.MultipartFile.fromPath('file', file.path)); req.files.add(await http.MultipartFile.fromPath('file', file.path));
req.fields['filename'] = p.basename(file.path); req.fields['filename'] = p.basename(file.path);
return await req.send(); return await req.send().timeout(const Duration(seconds: 4));
} catch (_) { } catch (_) {
return null; return null;
} }
@@ -226,7 +250,14 @@ class _UploadPageState extends State<UploadPage> {
Uri.parse('$brokerUrl/upload/$filename'), Uri.parse('$brokerUrl/upload/$filename'),
); );
req.files.add(await http.MultipartFile.fromPath('file', file.path)); req.files.add(await http.MultipartFile.fromPath('file', file.path));
return req.send(); return req.send().timeout(const Duration(seconds: 20));
}
bool _isNetworkError(Object error) {
return error is SocketException ||
error is TimeoutException ||
error is HttpException ||
error is http.ClientException;
} }
Uri? _normalizeDirectEndpoint(String value) { Uri? _normalizeDirectEndpoint(String value) {