diff --git a/lib/data/models/transaction.dart b/lib/data/models/transaction.dart index 3244a8b..14e83df 100644 --- a/lib/data/models/transaction.dart +++ b/lib/data/models/transaction.dart @@ -4,8 +4,18 @@ class Transaction { final String? date; final String? amount; final String? type; + final String? balance; + final String? balanceType; + + Transaction( + {this.id, + this.name, + this.date, + this.amount, + this.type, + this.balance, + this.balanceType}); - Transaction({this.id, this.name, this.date, this.amount, this.type}); Map toJson() { return { 'id': id, @@ -13,16 +23,19 @@ class Transaction { 'date': date, 'amount': amount, 'type': type, + 'balance': balance, + 'balanceType': balanceType }; } factory Transaction.fromJson(Map json) { return Transaction( - id: json['id'] as String?, - name: json['name'] as String?, - date: json['date'] as String?, - amount: json['amount'] as String?, - type: json['type'] as String?, - ); + id: json['id'] as String?, + name: json['name'] as String?, + date: json['date'] as String?, + amount: json['amount'] as String?, + type: json['type'] as String?, + balance: json['balance'] as String?, + balanceType: json['balanceType'] as String?); } } diff --git a/lib/data/repositories/transaction_repository.dart b/lib/data/repositories/transaction_repository.dart index 164ed6c..2a53ee3 100644 --- a/lib/data/repositories/transaction_repository.dart +++ b/lib/data/repositories/transaction_repository.dart @@ -25,8 +25,6 @@ class TransactionRepositoryImpl implements TransactionRepository { queryParameters['toDate'] = DateFormat('ddMMyyyy').format(toDate); } - log('query params below'); - log(queryParameters.toString()); final resp = await _dio.get( '/api/transactions/account/$accountNo', queryParameters: queryParameters.isNotEmpty ? queryParameters : null, diff --git a/lib/di/injection.dart b/lib/di/injection.dart index eb462e2..32e34f6 100644 --- a/lib/di/injection.dart +++ b/lib/di/injection.dart @@ -63,9 +63,9 @@ Dio _createDioClient() { final dio = Dio( BaseOptions( baseUrl: - // 'http://lb-test-mobile-banking-app-192209417.ap-south-1.elb.amazonaws.com:8080', + 'http://lb-test-mobile-banking-app-192209417.ap-south-1.elb.amazonaws.com:8080', //'http://localhost:8081', - 'http://localhost:8082', + // 'http://localhost:8082', connectTimeout: const Duration(seconds: 5), receiveTimeout: const Duration(seconds: 10), headers: { diff --git a/lib/features/accounts/screens/account_statement_screen.dart b/lib/features/accounts/screens/account_statement_screen.dart index aa37ad7..3e2c16e 100644 --- a/lib/features/accounts/screens/account_statement_screen.dart +++ b/lib/features/accounts/screens/account_statement_screen.dart @@ -11,9 +11,6 @@ import 'transaction_details_screen.dart'; import 'package:pdf/widgets.dart' as pw; import 'package:permission_handler/permission_handler.dart'; import 'package:device_info_plus/device_info_plus.dart'; -import 'package:flutter/foundation.dart' show kIsWeb; -import 'dart:html' as html; // Import for web-specific code -import 'dart:typed_data'; class AccountStatementScreen extends StatefulWidget { final String accountNo; @@ -319,115 +316,114 @@ class _AccountStatementScreen extends State { ], ), ), - floatingActionButton: FloatingActionButton( - onPressed: () { - _exportToPdf(); - }, - child: const Icon(Icons.download), - ), + floatingActionButton: FloatingActionButton( + onPressed: () { + _exportToPdf(); + }, + child: const Icon(Icons.download), + ), ); } Future _exportToPdf() async { - // Step 1: Check if there are any transactions to export. - if (_transactions.isEmpty) { - if (mounted) { - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text('No transactions to export.'), - ), - ); - } - return; - } - - // Step 2: Handle storage permissions for Android. - /*if (Platform.isAndroid) { - final androidInfo = await DeviceInfoPlugin().androidInfo; - if (androidInfo.version.sdkInt < 33) { // Target Android 12 & below - final status = await Permission.storage.status; - if (status.isDenied) { - final result = await Permission.storage.request(); - if (result.isDenied) { - if (mounted) { - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text('Storage permission is required to save PDF'), - ), - ); - } - return; - } + // Step 1: Check if there are any transactions to export. + if (_transactions.isEmpty) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('No transactions to export.'), + ), + ); } + return; } - } - - // Step 3: Load assets for the PDF. - // IMPORTANT: The original path 'assets/logos/logo.svg' is incorrect. - // I've corrected it to 'assets/images/icon.svg' based on your project structure. - String logoSvg = await rootBundle.loadString('assets/images/icon.svg'); - var rubik = await rootBundle.load("assets/fonts/Rubik-Regular.ttf"); - - try { + var logo = await rootBundle.load('assets/images/logo.png'); + var rubik = await rootBundle.load("assets/fonts/Rubik-Regular.ttf"); final pdf = pw.Document(); - pdf.addPage( - pw.MultiPage( + + pdf.addPage(pw.MultiPage( margin: const pw.EdgeInsets.all(20), build: (pw.Context context) { return [ pw.Row( - mainAxisAlignment: pw.MainAxisAlignment.start, - crossAxisAlignment: pw.CrossAxisAlignment.center, - children: [ - pw.SvgImage(svg: logoSvg, width: 50, height: 50), - pw.SizedBox(width: 20), - pw.Text( - "Account Statement - KCCB", - style: pw.TextStyle( - fontSize: 24, - fontWeight: pw.FontWeight.bold, - ), - ), - ], - ), + mainAxisAlignment: pw.MainAxisAlignment.start, + crossAxisAlignment: pw.CrossAxisAlignment.center, + children: [ + pw.Image(pw.MemoryImage(logo.buffer.asUint8List()), + width: 50, height: 50), + pw.SizedBox(width: 20), + pw.Text('Account Statement - KCCB', + style: pw.TextStyle( + fontSize: 24, fontWeight: pw.FontWeight.bold)), + ]), pw.SizedBox(height: 20), pw.Row( - mainAxisAlignment: pw.MainAxisAlignment.spaceBetween, - children: [ - pw.Text( - 'Account Number: ${widget.accountNo}', - style: pw.TextStyle(font: pw.Font.ttf(rubik), fontSize: 15), - ), - pw.Text( - 'Account Type: ${widget.accountType}', - style: pw.TextStyle(font: pw.Font.ttf(rubik), fontSize: 15), - ), - ], - ), + mainAxisAlignment: pw.MainAxisAlignment.spaceBetween, + children: [ + pw.Text('Account Number: ${widget.accountNo}', + style: + pw.TextStyle(font: pw.Font.ttf(rubik), fontSize: 15)), + pw.Text('Account Type: ${widget.accountType}', + style: pw.TextStyle( + fontSize: 15, + font: pw.Font.ttf(rubik), + )), + ]), pw.SizedBox(height: 20), - // Step 4: Build the table from the _transactions list. - pw.Table.fromTextArray( - border: pw.TableBorder.all(), - headerStyle: pw.TextStyle(fontWeight: pw.FontWeight.bold), - headerDecoration: const pw.BoxDecoration( - color: PdfColors.grey300, + pw.Table(border: pw.TableBorder.all(), columnWidths: { + 0: const pw.FractionColumnWidth(0.2), + 1: const pw.FractionColumnWidth(0.45), + 2: const pw.FractionColumnWidth(0.15), + 3: const pw.FractionColumnWidth(0.20), + }, children: [ + pw.TableRow( + children: [ + pw.Padding( + padding: const pw.EdgeInsets.all(4), + child: pw.Text('Date')), + pw.Padding( + padding: const pw.EdgeInsets.all(4), + child: pw.Text('Description', softWrap: true)), + pw.Padding( + padding: const pw.EdgeInsets.all(4), + child: pw.Text('Amount')), + pw.Padding( + padding: const pw.EdgeInsets.all(4), + child: pw.Text('Balance')), + ], ), - cellHeight: 30, - cellAlignments: { - 0: pw.Alignment.centerLeft, - 1: pw.Alignment.centerLeft, - 2: pw.Alignment.centerRight, - 3: pw.Alignment.center, - }, - headers: ['Date', 'Description', 'Amount', 'Type'], - data: _transactions.map((tx) => [ - tx.date ?? 'N/A', - tx.name ?? 'N/A', - '₹${tx.amount}', - tx.type ?? 'N/A', - ]).toList(), - ), + ..._transactions.map((tx) { + return pw.TableRow(children: [ + pw.Padding( + padding: const pw.EdgeInsets.all(10), + child: pw.Text(tx.date ?? '', + style: pw.TextStyle( + fontSize: 12, + font: pw.Font.ttf(rubik), + ))), + pw.Padding( + padding: const pw.EdgeInsets.all(10), + child: pw.Text(tx.name ?? '', + style: pw.TextStyle( + fontSize: 12, font: pw.Font.ttf(rubik)))), + pw.Padding( + padding: const pw.EdgeInsets.all(10), + child: pw.Text("₹${tx.amount} ${tx.type}", + style: pw.TextStyle( + fontSize: 12, + font: pw.Font.ttf(rubik), + ))), + pw.Padding( + padding: const pw.EdgeInsets.all(10), + child: pw.Text("₹${tx.balance} ${tx.balanceType}", + style: pw.TextStyle( + fontSize: 12, + font: pw.Font.ttf(rubik), + ))), + ]); + }), + ]) ]; }, footer: (pw.Context context) { @@ -435,213 +431,64 @@ class _AccountStatementScreen extends State { alignment: pw.Alignment.centerRight, margin: const pw.EdgeInsets.only(top: 10), child: pw.Text( - 'Kangra Central Co-Operative bank Pvt Ltd. ©. All rights reserved.', + 'Kangra Central Co-Operative Bank Pvt Ltd. ©. All rights reserved.', style: pw.TextStyle( font: pw.Font.ttf(rubik), fontSize: 8, ), ), ); - }, - ), - ); + })); - // Step 5: Save the PDF to the device. - Directory? directory = await getDownloadsDirectory(); - if (directory == null) { - throw Exception('Could not access downloads directory'); + //Logic For all platforms + try { + final Uint8List pdfBytes = await pdf.save(); + final String timestamp = DateTime.now().millisecondsSinceEpoch.toString(); + final String fileName = 'account_statement_$timestamp.pdf'; + + // For Android + if (Platform.isAndroid) { + final androidInfo = await DeviceInfoPlugin().androidInfo; + if (androidInfo.version.sdkInt < 29) { + final status = await Permission.storage.status; + if (status.isDenied) { + final result = await Permission.storage.request(); + if (result.isDenied) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Storage permission is required to save PDF'), + ), + ); + } + return; + } + } + } + + final directory = Directory('/storage/emulated/0/Download'); + final file = File('${directory.path}/$fileName'); + await file.writeAsBytes(pdfBytes); + + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('PDF saved to: ${file.path}'), + ), + ); + } + } + // Add for IOS + } catch (e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Error saving PDF: $e'), + ), + ); + } } - final String timestamp = DateTime.now().millisecondsSinceEpoch.toString(); - final file = File('${directory.path}/account_statement_$timestamp.pdf'); - - await file.writeAsBytes(await pdf.save()); - - if (mounted) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text('PDF saved to: ${file.path}'), - duration: const Duration(seconds: 3), - ), - ); - } - } catch (e) { - if (mounted) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text('Error saving PDF: $e'), - ), - ); - } - }*/ - String logoSvg = await rootBundle.loadString('assets/images/kccb_logo.svg'); // Corrected asset path - var rubik = await rootBundle.load("assets/fonts/Rubik-Regular.ttf"); - final pdf = pw.Document(); - - pdf.addPage(pw.MultiPage( - margin: const pw.EdgeInsets.all(20), - build: (pw.Context context) { - return [ - pw.Row( - mainAxisAlignment: pw.MainAxisAlignment.start, - crossAxisAlignment: pw.CrossAxisAlignment.center, - children: [ - pw.SvgImage(svg: logoSvg, width: 50, height: 50), - pw.SizedBox(width: 20), - pw.Text('Account Statement - KCCB', - style: pw.TextStyle( - fontSize: 24, fontWeight: pw.FontWeight.bold)), - ]), - pw.SizedBox(height: 20), - pw.Row( - mainAxisAlignment: pw.MainAxisAlignment.spaceBetween, - children: [ - pw.Text('Account Number: ${widget.accountNo}', - style: pw.TextStyle( - font: pw.Font.ttf(rubik), fontSize: 15)), - pw.Text('Account Type: ${widget.accountType}', - style: pw.TextStyle( - fontSize: 15, - font: pw.Font.ttf(rubik), - )), - ]), - pw.SizedBox(height: 20), - pw.Table(border: pw.TableBorder.all(), columnWidths: { - 0: const pw.FractionColumnWidth(0.2), - 1: const pw.FractionColumnWidth(0.5), - 2: const pw.FractionColumnWidth(0.15), - 3: const pw.FractionColumnWidth(0.15), - }, children: [ - pw.TableRow( - children: [ - pw.Padding( - padding: const pw.EdgeInsets.all(4), - child: pw.Text('Date')), - pw.Padding( - padding: const pw.EdgeInsets.all(4), - child: pw.Text('Description', softWrap: true)), - pw.Padding( - padding: const pw.EdgeInsets.all(4), - child: pw.Text('Amount')), - pw.Padding( - padding: const pw.EdgeInsets.all(4), - child: pw.Text('Balance')), - ], - ), - ..._transactions.map((tx) { - return pw.TableRow(children: [ - pw.Padding( - padding: const pw.EdgeInsets.all(10), - child: pw.Text(tx.date ?? '', - style: pw.TextStyle( - fontSize: 12, - font: pw.Font.ttf(rubik), - ))), - pw.Padding( - padding: const pw.EdgeInsets.all(10), - child: pw.Text(tx.name ?? '', - style: pw.TextStyle( - fontSize: 12, font: pw.Font.ttf(rubik)))), - pw.Padding( - padding: const pw.EdgeInsets.all(10), - child: pw.Text("₹${tx.amount}", - style: pw.TextStyle( - fontSize: 12, - font: pw.Font.ttf(rubik), - ))), -]); - }).toList(), - ]) - ]; - }, - footer: (pw.Context context) { - return pw.Container( - alignment: pw.Alignment.centerRight, - margin: const pw.EdgeInsets.only(top: 10), - child: pw.Text( - 'Kangra Central Co-Operative Bank Pvt Ltd. ©. All rights reserved.', - style: pw.TextStyle( - font: pw.Font.ttf(rubik), - fontSize: 8, - ), - ), - ); - })); - - //Logic For all platforms - try { - final Uint8List pdfBytes = await pdf.save(); - final String timestamp = DateTime.now().millisecondsSinceEpoch.toString(); - final String fileName = 'account_statement_$timestamp.pdf'; - - // For Web - if (kIsWeb) { - final blob = html.Blob([pdfBytes], 'application/pdf'); - final url = html.Url.createObjectUrlFromBlob(blob); - html.Url.revokeObjectUrl(url); - print('Generated PDF Blob URL for web: $url'); - - final anchor = html.document.createElement('a') as html.AnchorElement - ..href = url - ..style.display = 'none' - ..download = fileName; - -html.document.body!.children.add(anchor); -anchor.click(); -html.document.body!.children.remove(anchor); - -html.Url.revokeObjectUrl(url); - if (mounted) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text('PDF download started: $fileName'), - ), - ); - } - } - // For Android - else if (Platform.isAndroid) { - final androidInfo = await DeviceInfoPlugin().androidInfo; - if (androidInfo.version.sdkInt < 29) { - final status = await Permission.storage.status; - if (status.isDenied) { - final result = await Permission.storage.request(); - if (result.isDenied) { - if (mounted) { - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text('Storage permission is required to save PDF'), - ), - ); - } - return; - } - } - } - - final directory = Directory('/storage/emulated/0/Download'); - final file = File('${directory.path}/$fileName'); - await file.writeAsBytes(pdfBytes); - - if (mounted) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text('PDF saved to: ${file.path}'), - ), - ); - } - } - // Add for IOS - - } catch (e) { - if (mounted) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text('Error saving PDF: $e'), - ), - ); - } - } -} + } Widget buildDateBox(String label, DateTime? date) { return Container( diff --git a/pubspec.lock b/pubspec.lock index 10b95d9..072ec50 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -21,10 +21,10 @@ packages: dependency: transitive description: name: async - sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" url: "https://pub.dev" source: hosted - version: "2.11.0" + version: "2.13.0" barcode: dependency: transitive description: @@ -53,10 +53,10 @@ packages: dependency: transitive description: name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" chalkdart: dependency: transitive description: @@ -69,10 +69,10 @@ packages: dependency: transitive description: name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 url: "https://pub.dev" source: hosted - version: "1.3.0" + version: "1.4.0" checked_yaml: dependency: transitive description: @@ -93,18 +93,18 @@ packages: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" collection: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.19.1" confetti: dependency: "direct main" description: @@ -181,10 +181,10 @@ packages: dependency: transitive description: name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.3" ffi: dependency: transitive description: @@ -385,10 +385,10 @@ packages: dependency: "direct main" description: name: intl - sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf + sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" url: "https://pub.dev" source: hosted - version: "0.19.0" + version: "0.20.2" jailbreak_root_detection: dependency: "direct main" description: @@ -417,18 +417,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0" url: "https://pub.dev" source: hosted - version: "10.0.5" + version: "10.0.9" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.0.9" leak_tracker_testing: dependency: transitive description: @@ -497,10 +497,10 @@ packages: dependency: transitive description: name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.16+1" + version: "0.12.17" material_color_utilities: dependency: transitive description: @@ -521,10 +521,10 @@ packages: dependency: transitive description: name: meta - sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c url: "https://pub.dev" source: hosted - version: "1.15.0" + version: "1.16.0" mime: dependency: transitive description: @@ -545,10 +545,10 @@ packages: dependency: transitive description: name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.9.1" path_parsing: dependency: transitive description: @@ -793,15 +793,15 @@ packages: dependency: transitive description: flutter source: sdk - version: "0.0.99" + version: "0.0.0" source_span: dependency: transitive description: name: source_span - sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.10.1" sprintf: dependency: transitive description: @@ -814,42 +814,42 @@ packages: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.12.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" string_scanner: dependency: transitive description: name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.4.1" term_glyph: dependency: transitive description: name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.2.2" test_api: dependency: transitive description: name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd url: "https://pub.dev" source: hosted - version: "0.7.2" + version: "0.7.4" typed_data: dependency: transitive description: @@ -966,10 +966,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02 url: "https://pub.dev" source: hosted - version: "14.2.5" + version: "15.0.0" web: dependency: transitive description: @@ -1019,5 +1019,5 @@ packages: source: hosted version: "3.1.3" sdks: - dart: ">=3.5.0 <4.0.0" + dart: ">=3.7.0-0 <4.0.0" flutter: ">=3.24.0"