Passport File Download

This commit is contained in:
venbaittech 2025-10-29 10:20:48 +05:30
parent a838aaeae0
commit 816d8b1bf1
2 changed files with 153 additions and 51 deletions

View File

@ -2230,7 +2230,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
print("Raw file path: $passportFileUrlFromApi"); print("Raw file path: $passportFileUrlFromApi");
apiService.getPassportDocDownload( apiService.getPassportDocDownload(
context, context,
widget.userIdApi, widget.userIdApi!,
); );
// // Extract public part of the path starting from "/assets" // // Extract public part of the path starting from "/assets"

View File

@ -1152,12 +1152,11 @@ class ApiService {
} }
} }
Future<void> getPassportDocDownload(BuildContext context, userId) async { Future<void> getPassportDocDownload(
// final String apiUrldata = '$apiUrl/api/plans/download?plan_id=$planId'; BuildContext context,
String userId,
) async {
final String apiUrldata = '$apiUrl/api/downloadPassport?user_id=$userId'; final String apiUrldata = '$apiUrl/api/downloadPassport?user_id=$userId';
// final String apiUrldata = '$apiUrl/auth/googlelogin';
final token = await getToken(); final token = await getToken();
if (token == null) { if (token == null) {
@ -1175,80 +1174,183 @@ class ApiService {
if (response.statusCode == 200) { if (response.statusCode == 200) {
try { try {
print("PDf Dowloaded"); print("✅ File download started");
final contentType = response.headers['content-type'] ?? '';
// print('contentType - $contentType'); // Get MIME type from response
// String fileName = "Document"; final contentType =
// if (contentType.contains("pdf")) { response.headers['content-type'] ?? 'application/octet-stream';
// fileName += ".pdf";
// } else if (contentType.contains("png")) {
// fileName += ".png";
// } else if (contentType.contains("jpeg") ||
// contentType.contains("jpg")) {
// fileName += ".jpg";
// } else {
// // fallback (unknown type, save as bin)
// fileName += ".$contentType";
// }
// Try extracting filename from Content-Disposition
final disposition = response.headers['content-disposition'] ?? ''; final disposition = response.headers['content-disposition'] ?? '';
String fileName = "passport_$userId"; String fileName = "passport_$userId";
final regExp = RegExp( final regExp = RegExp(
r'filename[^;=\n]*=(([' r'filename[^;=\n]=((['
'"]).*?\2|[^;\n]*)', '"]).?\2|[^;\n]*)',
); );
final match = regExp.firstMatch(disposition); final match = regExp.firstMatch(disposition);
if (match != null) { if (match != null) {
fileName = match.group(1)!.replaceAll('"', ''); fileName = match.group(1)!.replaceAll('"', '');
// 🔧 Remove UTF-8'' prefix if present
fileName = fileName.replaceFirst(RegExp(r"^UTF-8''"), '');
} else {
// If no filename in header, determine by content type
if (contentType.contains('pdf')) {
fileName += '.pdf';
} else if (contentType.contains('png')) {
fileName += '.png';
} else if (contentType.contains('jpeg') ||
contentType.contains('jpg')) {
fileName += '.jpg';
} else if (contentType.contains('json')) {
fileName += '.json';
} else if (contentType.contains('plain')) {
fileName += '.txt';
} else {
// default fallback
fileName += '.bin';
}
} }
// Create a blob from the response body // FIX: Include content type for correct format
final blob = html.Blob([response.bodyBytes]); final blob = html.Blob([response.bodyBytes], contentType);
// Generate a download URL for the blob
final url = html.Url.createObjectUrlFromBlob(blob); final url = html.Url.createObjectUrlFromBlob(blob);
// Create a link element to trigger the download // Trigger download
final anchor = final anchor =
html.AnchorElement(href: url) html.AnchorElement(href: url)
..setAttribute('download', fileName) ..setAttribute('download', fileName)
..click(); ..click();
// Revoke the download URL to free up resources
html.Url.revokeObjectUrl(url); html.Url.revokeObjectUrl(url);
print("📥 Downloaded as $fileName");
} catch (e) { } catch (e) {
throw Exception('Error parsing response: $e'); throw Exception('Error while saving file: $e');
} }
} else if (response.statusCode == 403) { } else if (response.statusCode == 403) {
print("403-FORB"); print("403 Forbidden");
await logout(context); await logout(context);
return null;
// throw Exception('Failed to load users');
} else if (response.statusCode == 404) { } else if (response.statusCode == 404) {
// showDialog( print("❌ File not found");
// context: context, showDialog(
// builder: (BuildContext context) { context: context,
// return AlertDialog( builder:
// title: Text('File not found.'), (_) => AlertDialog(
// // content: Text('File not found.'), title: const Text('File not found'),
// actions: [ content: const Text('The requested file could not be found.'),
// TextButton( actions: [
// child: Text('OK'), TextButton(
// onPressed: () { child: const Text('OK'),
// Navigator.of(context).pop(); // Close the dialog onPressed: () => Navigator.of(context).pop(),
// }, ),
// ), ],
// ], ),
// ); );
// },
// );
} else { } else {
throw Exception('Failed to load plans'); throw Exception('Failed to download passport document');
} }
} }
// Future<void> getPassportDocDownload(BuildContext context, userId) async {
// // final String apiUrldata = '$apiUrl/api/plans/download?plan_id=$planId';
// final String apiUrldata = '$apiUrl/api/downloadPassport?user_id=$userId';
//
// // final String apiUrldata = '$apiUrl/auth/googlelogin';
//
// final token = await getToken();
//
// if (token == null) {
// throw Exception('Token not found. Please log in.');
// }
//
// final response = await http.get(
// Uri.parse(apiUrldata),
// headers: {
// 'Authorization': 'Bearer $token',
// 'Content-Type': 'application/json',
// 'app-signature': 'ts-traveltool-2025-signature-123456',
// },
// );
//
// if (response.statusCode == 200) {
// try {
// print("PDf Dowloaded");
// final contentType = response.headers['content-type'] ?? '';
//
// // print('contentType - $contentType');
// // String fileName = "Document";
// // if (contentType.contains("pdf")) {
// // fileName += ".pdf";
// // } else if (contentType.contains("png")) {
// // fileName += ".png";
// // } else if (contentType.contains("jpeg") ||
// // contentType.contains("jpg")) {
// // fileName += ".jpg";
// // } else {
// // // fallback (unknown type, save as bin)
// // fileName += ".$contentType";
// // }
//
// final disposition = response.headers['content-disposition'] ?? '';
// String fileName = "passport_$userId";
//
// final regExp = RegExp(
// r'filename[^;=\n]*=((['
// '"]).*?\2|[^;\n]*)',
// );
// final match = regExp.firstMatch(disposition);
// if (match != null) {
// fileName = match.group(1)!.replaceAll('"', '');
// }
//
// // Create a blob from the response body
// final blob = html.Blob([response.bodyBytes]);
//
// // Generate a download URL for the blob
// final url = html.Url.createObjectUrlFromBlob(blob);
//
// // Create a link element to trigger the download
// final anchor =
// html.AnchorElement(href: url)
// ..setAttribute('download', fileName)
// ..click();
//
// // Revoke the download URL to free up resources
// html.Url.revokeObjectUrl(url);
// } catch (e) {
// throw Exception('Error parsing response: $e');
// }
// }
//
//
// else if (response.statusCode == 403) {
// print("403-FORB");
// await logout(context);
// return null;
// // throw Exception('Failed to load users');
// } else if (response.statusCode == 404) {
// // showDialog(
// // context: context,
// // builder: (BuildContext context) {
// // return AlertDialog(
// // title: Text('File not found.'),
// // // content: Text('File not found.'),
// // actions: [
// // TextButton(
// // child: Text('OK'),
// // onPressed: () {
// // Navigator.of(context).pop(); // Close the dialog
// // },
// // ),
// // ],
// // );
// // },
// // );
// } else {
// throw Exception('Failed to load plans');
// }
// }
Future<void> getForexPdfDownload(BuildContext context, forexId) async { Future<void> getForexPdfDownload(BuildContext context, forexId) async {
final String apiUrldata = final String apiUrldata =
'$apiUrl/api/plans/forexDownload?forex_id=$forexId'; '$apiUrl/api/plans/forexDownload?forex_id=$forexId';