chore: update dependencies and version in pubspec.yaml
- Bump version to 1.10.0+14 - Update http from ^1.1.0 to ^1.6.0 - Update google_sign_in from ^7.1.1 to ^7.2.0 - Update flutter_secure_storage from ^10.3.1 to ^11.2.0 - Update firebase_core from ^4.12.1 to ^4.15.0 - Update firebase_crashlytics from ^5.2.6 to ^5.4.0 - Update go_router from ^17.2.3 to ^18.0.1 - Update flutter_riverpod from ^3.3.1 to ^3.4.3 - Update table_calendar from ^3.2.0 to ^3.2.1 - Update intl from ^0.20.2 to ^0.20.3 - Update url_launcher from ^6.3.1 to ^6.3.2 - Update file_picker from ^11.0.3 to ^13.1.0 - Update google_fonts from ^8.1.0 to ^8.2.1 - Update lucide_icons_flutter from ^3.1.15 to ^3.1.20 - Add cross_file dependency for testing test: add FakePlatformFile for testing file uploads - Introduce FakePlatformFile to mock file picker behavior in tests - Update attachment_upload_test, csv_import_provider_test, support_ticket_test, and csv_import_sheet_test to use FakePlatformFile
This commit is contained in:
parent
2c70c62eaf
commit
d920cc294f
13 changed files with 321 additions and 356 deletions
|
|
@ -433,14 +433,16 @@ class CsvImportNotifier extends Notifier<CsvImportState> {
|
|||
/// file is refused without loading it, and the size again on the bytes.
|
||||
Future<void> choose(PlatformFile? picked) async {
|
||||
if (picked == null) return;
|
||||
final early = _refuse(picked.name, picked.size);
|
||||
// `lengthSync` is what the picker reported, without I/O. Unknown counts
|
||||
// as 0 here; the bytes are checked again below either way.
|
||||
final early = _refuse(picked.name, picked.lengthSync() ?? 0);
|
||||
if (early != null) {
|
||||
state = CsvImportState(error: early);
|
||||
return;
|
||||
}
|
||||
final Uint8List bytes;
|
||||
try {
|
||||
bytes = picked.bytes ?? await picked.xFile.readAsBytes();
|
||||
bytes = await picked.readAsBytes();
|
||||
} catch (_) {
|
||||
if (ref.mounted) {
|
||||
state = const CsvImportState(
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ class SupportRepository {
|
|||
required String body,
|
||||
PlatformFile? attachment,
|
||||
}) async {
|
||||
final invalid = _attachmentError(attachment);
|
||||
final invalid = await _attachmentError(attachment);
|
||||
if (invalid != null) return SupportMutationResult(error: invalid);
|
||||
final response = attachment == null
|
||||
? await _api.post(ApiConfig.supportTickets, {
|
||||
|
|
@ -102,7 +102,7 @@ class SupportRepository {
|
|||
required String body,
|
||||
PlatformFile? attachment,
|
||||
}) async {
|
||||
final invalid = _attachmentError(attachment);
|
||||
final invalid = await _attachmentError(attachment);
|
||||
if (invalid != null) return SupportMutationResult(error: invalid);
|
||||
final response = attachment == null
|
||||
? await _api.post(ApiConfig.supportTicketReplies(ticketId), {
|
||||
|
|
@ -118,12 +118,13 @@ class SupportRepository {
|
|||
return _ticketResult(response);
|
||||
}
|
||||
|
||||
String? _attachmentError(PlatformFile? file) {
|
||||
Future<String?> _attachmentError(PlatformFile? file) async {
|
||||
if (file == null) return null;
|
||||
if ((file.path ?? '').isEmpty) {
|
||||
final size = await file.length();
|
||||
if ((file.path ?? '').isEmpty || size == null) {
|
||||
return 'That file could not be read. Try picking it again.';
|
||||
}
|
||||
if (file.size > attachmentMaxBytes) {
|
||||
if (size > attachmentMaxBytes) {
|
||||
return 'Files must be 25 MB or smaller.';
|
||||
}
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -120,14 +120,7 @@ class _InvoiceTemplateFormScreenState
|
|||
// images because `logo` is an ImageField: Pillow refuses anything else
|
||||
// server-side, and a 400 after an upload is a poor way to learn that.
|
||||
final result = await selectAttachment(
|
||||
pickFile: () async {
|
||||
final picked = await FilePicker.pickFiles(
|
||||
type: FileType.image,
|
||||
withReadStream: false,
|
||||
);
|
||||
if (picked == null || picked.files.isEmpty) return null;
|
||||
return picked.files.first;
|
||||
},
|
||||
pickFile: () => FilePicker.pickFile(type: FileType.image),
|
||||
);
|
||||
if (result.cancelled || !mounted) return;
|
||||
if (result.error != null) {
|
||||
|
|
|
|||
|
|
@ -74,10 +74,16 @@ Future<AttachmentSelectionResult> selectAttachment({
|
|||
'That file could not be read. Try picking it again.',
|
||||
);
|
||||
}
|
||||
if (picked.size > attachmentMaxBytes) {
|
||||
final size = await picked.length();
|
||||
if (size == null) {
|
||||
return const AttachmentSelectionResult.failed(
|
||||
'That file could not be read. Try picking it again.',
|
||||
);
|
||||
}
|
||||
if (size > attachmentMaxBytes) {
|
||||
final limit = attachmentMaxBytes ~/ (1024 * 1024);
|
||||
return AttachmentSelectionResult.failed(
|
||||
'${picked.name} is ${_megabytes(picked.size)} MB. '
|
||||
'${picked.name} is ${_megabytes(size)} MB. '
|
||||
'Files must be $limit MB or smaller.',
|
||||
);
|
||||
}
|
||||
|
|
@ -117,12 +123,12 @@ Future<AttachmentDownloadResult> downloadAttachment({
|
|||
}
|
||||
}
|
||||
|
||||
Future<String?> _saveFile(Uint8List bytes, String fileName) =>
|
||||
FilePicker.saveFile(
|
||||
Future<String?> _saveFile(Uint8List bytes, String fileName) async =>
|
||||
(await FilePicker.saveFile(
|
||||
dialogTitle: 'Save attachment',
|
||||
fileName: fileName,
|
||||
bytes: bytes,
|
||||
);
|
||||
))?.toString();
|
||||
|
||||
/// Remove the temporary copy made by the native picker after a form uploads it.
|
||||
Future<void> clearAttachmentPickerCache() => _clearPickerCache();
|
||||
|
|
@ -175,13 +181,21 @@ Future<AttachmentUploadResult> pickAndUploadAttachment({
|
|||
);
|
||||
}
|
||||
|
||||
if (picked.size > attachmentMaxBytes) {
|
||||
final size = await picked.length();
|
||||
if (size == null) {
|
||||
if (pickFile == null) await _clearPickerCache();
|
||||
return const AttachmentUploadResult.failed(
|
||||
'That file could not be read. Try picking it again.',
|
||||
);
|
||||
}
|
||||
|
||||
if (size > attachmentMaxBytes) {
|
||||
// Clear it here too. This is the case where the copy matters most: the
|
||||
// file that was too big to send is the one it hurts to keep.
|
||||
if (pickFile == null) await _clearPickerCache();
|
||||
final limit = attachmentMaxBytes ~/ (1024 * 1024);
|
||||
return AttachmentUploadResult.failed(
|
||||
'${picked.name} is ${_megabytes(picked.size)} MB. '
|
||||
'${picked.name} is ${_megabytes(size)} MB. '
|
||||
'Files must be $limit MB or smaller.',
|
||||
);
|
||||
}
|
||||
|
|
@ -203,15 +217,11 @@ Future<AttachmentUploadResult> pickAndUploadAttachment({
|
|||
return AttachmentUploadResult.uploaded(response.data);
|
||||
}
|
||||
|
||||
Future<PlatformFile?> _pickOneFile() async {
|
||||
final result = await FilePicker.pickFiles(withReadStream: false);
|
||||
if (result == null || result.files.isEmpty) return null;
|
||||
return result.files.first;
|
||||
}
|
||||
Future<PlatformFile?> _pickOneFile() => FilePicker.pickFile();
|
||||
|
||||
/// Drop the picker's cached copy of what was just uploaded.
|
||||
///
|
||||
/// `pickFiles` copies the chosen file into the app's cache directory, so
|
||||
/// `pickFile` copies the chosen file into the app's cache directory, so
|
||||
/// without this every attachment a person sends stays on their phone a second
|
||||
/// time, in a directory they never see. Only when the real picker ran: an
|
||||
/// injected one has nothing to clear, and the platform channel is not there in
|
||||
|
|
|
|||
|
|
@ -81,9 +81,9 @@ Future<RecordExportResult> exportRecordsCsv({
|
|||
}
|
||||
}
|
||||
|
||||
Future<String?> _saveWithPicker(Uint8List bytes, String fileName) =>
|
||||
FilePicker.saveFile(
|
||||
Future<String?> _saveWithPicker(Uint8List bytes, String fileName) async =>
|
||||
(await FilePicker.saveFile(
|
||||
dialogTitle: 'Save CSV export',
|
||||
fileName: fileName,
|
||||
bytes: bytes,
|
||||
);
|
||||
))?.toString();
|
||||
|
|
|
|||
|
|
@ -70,13 +70,9 @@ class _CsvImportSheetState extends ConsumerState<CsvImportSheet> {
|
|||
if (injected == null && picked != null) await clearAttachmentPickerCache();
|
||||
}
|
||||
|
||||
static Future<PlatformFile?> _pickOne() async {
|
||||
// Any type, then refused by name: a CSV is labelled text/plain by some
|
||||
// Android file managers, and filtering on MIME type would hide it.
|
||||
final result = await FilePicker.pickFiles();
|
||||
if (result == null || result.files.isEmpty) return null;
|
||||
return result.files.first;
|
||||
}
|
||||
// Any type, then refused by name: a CSV is labelled text/plain by some
|
||||
// Android file managers, and filtering on MIME type would hide it.
|
||||
static Future<PlatformFile?> _pickOne() => FilePicker.pickFile();
|
||||
|
||||
/// Ask where to keep [content] as [fileName]. `null` when the person
|
||||
/// closed the dialog, a sentence to show otherwise.
|
||||
|
|
@ -118,12 +114,14 @@ class _CsvImportSheetState extends ConsumerState<CsvImportSheet> {
|
|||
if (mounted) setState(() => _errorsNote = note);
|
||||
}
|
||||
|
||||
static Future<String?> _saveWithPicker(String fileName, List<int> bytes) =>
|
||||
FilePicker.saveFile(
|
||||
dialogTitle: 'Save CSV file',
|
||||
fileName: fileName,
|
||||
bytes: Uint8List.fromList(bytes),
|
||||
);
|
||||
static Future<String?> _saveWithPicker(
|
||||
String fileName,
|
||||
List<int> bytes,
|
||||
) async => (await FilePicker.saveFile(
|
||||
dialogTitle: 'Save CSV file',
|
||||
fileName: fileName,
|
||||
bytes: Uint8List.fromList(bytes),
|
||||
))?.toString();
|
||||
|
||||
Future<void> _commit() async {
|
||||
final ok = await _notifier.commit();
|
||||
|
|
|
|||
|
|
@ -1,38 +1,30 @@
|
|||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
_fe_analyzer_shared:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: _fe_analyzer_shared
|
||||
sha256: a49d6cf99e8d8e7a8e93668d09ced0bbdb954d0b4fccc2f5f9241c6b87fad95c
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "99.0.0"
|
||||
_flutterfire_internals:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: _flutterfire_internals
|
||||
sha256: "6727cf2ced9b104abca9daa278380be2eca2b98ce33d4b46f11708e387dc6b4d"
|
||||
sha256: f6966125633a34f82d9be2ee895b755cff3554087b1d00a9eb884e5947f4bca9
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.76"
|
||||
analyzer:
|
||||
version: "1.3.77"
|
||||
android_file_picker:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
sha256: "663efa951fb8a45e06f491223a604c93820598f20e6a99c25617a1576065e8b7"
|
||||
name: android_file_picker
|
||||
sha256: "14ab27769b54c48d5a8a71aa9858372b7a3ae77572ea0a8aee744643c5d8c53d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "12.1.0"
|
||||
version: "2.0.0"
|
||||
archive:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: archive
|
||||
sha256: a96e8b390886ee8abb49b7bd3ac8df6f451c621619f52a26e815fdcf568959ff
|
||||
sha256: "6c5bcd986e06b94e3c40244af471750840a3d2341d1f9763a1100a14add517b4"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.9"
|
||||
version: "4.3.0"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -73,14 +65,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.4"
|
||||
cli_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cli_config
|
||||
sha256: ac20a183a07002b700f0c25e61b7ee46b23c309d76ab7b7640a028f18e4d99ec
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
cli_util:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -93,18 +77,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: clock
|
||||
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
|
||||
sha256: e51d50bca3217c9a9fa2b41a30e4a38971133f5f9ec7a3d57bae095007f1d28e
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
version: "1.1.3"
|
||||
code_assets:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: code_assets
|
||||
sha256: bf394f466ba9205f1812a0433b392d6af280f155f56651eda7c18cc32ed493b8
|
||||
sha256: "828110d598123b5ea96c00c9f3c72105bf79f8ee36c20a39b26209ade421ec57"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
version: "2.1.0"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -113,30 +97,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.19.1"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: convert
|
||||
sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
coverage:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: coverage
|
||||
sha256: "956a3de0725ca232ad353565a8290d3357592bf4250f6f298a185e2d949c5d3d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.15.1"
|
||||
cross_file:
|
||||
dependency: transitive
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: cross_file
|
||||
sha256: "92c9c43c383bfa1c32079d3bc492d55d6d4318044b7b47edaff8971cbb555c51"
|
||||
sha256: f141ea4f277af142a0356955707f6556f37b03947d39d55585981a06ca437bd6
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.5+4"
|
||||
version: "0.3.5+5"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -153,14 +121,22 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.9"
|
||||
cupertino_ui:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cupertino_ui
|
||||
sha256: c23816577a1280cff409e989541767887011f8f1d8c1863a794ed308af46f2a9
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
dbus:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dbus
|
||||
sha256: "0ce9b0a839e6dee59a37a623d2fc26a35bbbe6404213e419b0d6411023d62645"
|
||||
sha256: f7db8504e715b835f5ebe5fe74604ccd961d504c73389a5d8e81bafc2e2f3612
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.14"
|
||||
version: "0.8.0"
|
||||
equatable:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -185,6 +161,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
ffi_leak_tracker:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: ffi_leak_tracker
|
||||
sha256: "4093d4ef9ca06ffe2786e73bfb25e22aa92112b9bb4ec941f11e3e6b61489a97"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.2"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -197,50 +181,82 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: file_picker
|
||||
sha256: "29cc1fdb20613876cc7afc529738c1c0f11a9ca159b010edad0c566ac330847e"
|
||||
sha256: "98c0b156b6380ba55bc767a14e2e6b3feb246e713ad40092424596fa79005bea"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "11.0.3"
|
||||
version: "13.1.0"
|
||||
file_picker_darwin:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_picker_darwin
|
||||
sha256: "51aef9f4c80449c736e7cc02198675fda73689f0bd45a84da642cfeab0250d46"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
file_picker_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_picker_linux
|
||||
sha256: "9c870771500c758eb46506c98532c3ee60e6e51d0a62dcde24a849ef213ea5ce"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
file_picker_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_picker_platform_interface
|
||||
sha256: bbdc085a6f168e63f147e9ce8988f79fa0800a58e7f25a48f762c60837107ba5
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.0"
|
||||
file_picker_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_picker_web
|
||||
sha256: b3004268da0c1b52baa18df430e7ec4438194de855a807d26b447cbf07ef3496
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.0"
|
||||
firebase_core:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_core
|
||||
sha256: "9478ca6700c02d315c6aba37e206e612317f98bb4f335bb1cbd6e0ce67dcf764"
|
||||
sha256: "5fbbaa2aeb08a52feee559f92a62f5a6b04c9bdff81c8f608636771cf0d7b680"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.13.0"
|
||||
version: "4.15.0"
|
||||
firebase_core_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_core_platform_interface
|
||||
sha256: e28f9afdcb5b0f0a8ea74ea3b322f5a7592c81cb45dd9d189913bdae08a2089a
|
||||
sha256: "9bfbc85faca09346471ac56fbcee00757ebcfd85887c6f602764eff0001902d8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.1.0"
|
||||
version: "8.1.1"
|
||||
firebase_core_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_core_web
|
||||
sha256: f471a288b0101a45567548322ac4a5ad31e3ecbf87a576dcc0e424e6a11e04ea
|
||||
sha256: "8ed84f5001dbd7a0390e2818d46bc858ceebb970edededdfc8d6552c76fc2f6e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.10.0"
|
||||
version: "3.12.0"
|
||||
firebase_crashlytics:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_crashlytics
|
||||
sha256: "96c1d85de9eddc07061d3f7e2fb75596e75a45c9cec9c2e3a7cc9f97e6f3a748"
|
||||
sha256: f37fe0df162f08bd549114b784037c73a093c64d22625632f97dbbddf18669b9
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.2.7"
|
||||
version: "5.4.0"
|
||||
firebase_crashlytics_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_crashlytics_platform_interface
|
||||
sha256: "47d83b71fd39c580297c696a507a7c2652680ea2045e40c6c4e3c371b0ee7bc6"
|
||||
sha256: "8270dcdb1800db3e5f888ce30a2d5e8f92c379c461f022297c83b2c794aa1792"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.8.27"
|
||||
version: "3.9.0"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -278,54 +294,51 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.0.0"
|
||||
flutter_plugin_android_lifecycle:
|
||||
flutter_localizations:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_plugin_android_lifecycle
|
||||
sha256: "3854fe5e3bff0b113c658f260b90c95dea17c92db0f2addeac2e343dd9969785"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.35"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_riverpod:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_riverpod
|
||||
sha256: "56e81e662e6e54e59b231da57e90ac0d06ac67d8e3f2273c129a37ae6282b40c"
|
||||
sha256: "2b7f9d2a3c730ac1a98221b420cef966b990fca7ab546ede324642ca57a533e3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.4.2"
|
||||
version: "3.4.3"
|
||||
flutter_secure_storage:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_secure_storage
|
||||
sha256: "7686b1d6a29985dcbb808c59518226e603e3bfa7c0ddfd1a0d00e4cda77c868e"
|
||||
sha256: d4e1fb6b2cb524868929e78dc0282fa000554b22060fb53789dc481c9fc95bb8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.3.1"
|
||||
version: "11.2.0"
|
||||
flutter_secure_storage_darwin:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_darwin
|
||||
sha256: "82329fa5cdf343773b1b6897dea959105a29f092454259edff92f9f6637e8149"
|
||||
sha256: a031ceac9b070e62ef183cd7f7d1a8798ebde402d5049f0fe6eb3a51bd797a21
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.3.2"
|
||||
version: "0.4.3"
|
||||
flutter_secure_storage_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_linux
|
||||
sha256: "76fa9c841b3b1619fc5b5bc36efc7d158fa2356f223b6caeb1d0c80a54168546"
|
||||
sha256: caa75bd78f017422912e3a904933113b2428eb79f981ac37acd2dd2a700458ea
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
version: "3.0.3"
|
||||
flutter_secure_storage_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_platform_interface
|
||||
sha256: "788060052712555182aba55ecb5f8b6e5cb9cfe8f776c83249a61fe3ce877db4"
|
||||
sha256: "64951127f001f546891c86f414972bf49ef2c4c8a4c92c65f5790cc0c9100045"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.3"
|
||||
version: "2.1.1"
|
||||
flutter_secure_storage_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -338,10 +351,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: flutter_secure_storage_windows
|
||||
sha256: "3b7c8e068875dfd46719ff57c90d8c459c87f2302ed6b00ff006b3c9fcad1613"
|
||||
sha256: "471951813a97006d899db4948acc654a4f28c440083ea08178935ce20b173ec1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.0"
|
||||
version: "4.2.2"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
|
|
@ -352,30 +365,14 @@ packages:
|
|||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
frontend_server_client:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: frontend_server_client
|
||||
sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.0"
|
||||
glob:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: glob
|
||||
sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.3"
|
||||
go_router:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: go_router
|
||||
sha256: "55973bf1b27790489f8710ea615fe939f911ddcc5986fe97305e4fc19fa29ee9"
|
||||
sha256: "008ab21d89d0de8ccd79586838f7533f126c2d894f50bf25f2947888d3c225b5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "17.4.0"
|
||||
version: "18.0.1"
|
||||
google_fonts:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -404,18 +401,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: google_sign_in_android
|
||||
sha256: "57782125965ca87b03d42a147d40b046f1fd6a09141a58913e1b86671a5ef22e"
|
||||
sha256: c403315d87aba1f815a0a401093f97808cab6cb2bdd11ca431ff8587fd7f1c00
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.2.16"
|
||||
version: "7.2.17"
|
||||
google_sign_in_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: google_sign_in_ios
|
||||
sha256: ac1e4c1205267cb7999d1d81333fccffdfda29e853f434bbaf71525498bb6950
|
||||
sha256: c2154d2849310a0286aab2e35e3bee585f2034afdf8ac364c4d7b3638e4c40b6
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.3.0"
|
||||
version: "6.3.5"
|
||||
google_sign_in_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -436,10 +433,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: hooks
|
||||
sha256: "9a62a50b50b769a737bc0a8ff381f333529df3ab746b2f6b02e83760231455ba"
|
||||
sha256: eaac480a35ec0814146c2c48d96aaa829e0e44a7662c88ae84c9edf4bc35651f
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
version: "2.2.0"
|
||||
http:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -448,14 +445,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.6.0"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.2"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -468,10 +457,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: image
|
||||
sha256: f9881ff4998044947ec38d098bc7c8316ae1186fa786eddffdb867b9bc94dfce
|
||||
sha256: a1e7f4951e538a568e14b856702afc9ae1d2f4b202daced8d22c1b9cd211ce89
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.8.0"
|
||||
version: "4.10.1"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -480,14 +469,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.20.3"
|
||||
io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: io
|
||||
sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.5"
|
||||
jni:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -500,10 +481,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: jni_flutter
|
||||
sha256: "7b717011ea40d04fd47c2731d3d1d36eb99eba3435c2753d62489e8c3c9991d5"
|
||||
sha256: b2310cdd4c18c65c081ab141a41efa94aa26c65431803703ece51996f174f351
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
version: "1.0.3"
|
||||
jni_util:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -580,10 +561,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: lucide_icons_flutter
|
||||
sha256: "234155b10641b8ef7bab8a077b93ea6c92fe849c06740cf89dcd86dcf350934f"
|
||||
sha256: "50a21003cfe094e33b87e780d62ed5be84c32273dec1ba04547aab7df3cba00c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.15"
|
||||
version: "3.1.20"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -600,6 +581,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.13.0"
|
||||
material_ui:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_ui
|
||||
sha256: "134ab2f0843545c4e661e4ba2753fe1bcf0753cb690d5a9ee4870638a40411e9"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -608,38 +597,22 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.19.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: mime
|
||||
sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
node_preamble:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_preamble
|
||||
sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
objective_c:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: objective_c
|
||||
sha256: b7fb95a6d9a4f009edd63dc5ac69f07420b23a16161c6dd8660290b59c602e8e
|
||||
sha256: ad56fd53a78ff6b1472fa59ff2a4e8b8ccabafc586fc263a1dfad0b99b5553e3
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.5.0"
|
||||
version: "9.6.0"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc
|
||||
sha256: ffcf4cf3d6c0b74ac43708d9f56625506e8a68aa935abe9d267a7330f320eb5d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
version: "3.0.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -700,18 +673,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: petitparser
|
||||
sha256: "91bd59303e9f769f108f8df05e371341b15d59e995e6806aefab827b58336675"
|
||||
sha256: "2f1564aadb14215e478563b5406cb80729d022158c01dc50c96013c2f7eb4790"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.2"
|
||||
version: "7.1.0"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: platform
|
||||
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
|
||||
sha256: a36d119c13416516a7b5913fbe8af8531e11633d784c550b2125f76c758524ec
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.6"
|
||||
version: "3.2.0"
|
||||
plugin_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -720,14 +693,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.8"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pool
|
||||
sha256: "978783255c543aa3586a1b3c21f6e9d720eb315376a915872c61ef8b5c20177d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.2"
|
||||
posix:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -740,26 +705,26 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: pub_semver
|
||||
sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585"
|
||||
sha256: "261236774e8b1d69cfc6b9eabbc96c40f25e7a2d6b171f3385d4f65d5734fb24"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
version: "2.2.1"
|
||||
record_use:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: record_use
|
||||
sha256: "2551bd8eecfe95d14ae75f6021ad0248be5c27f138c2ec12fcb52b500b3ba1ed"
|
||||
sha256: "1cb8564af8d43b464294411db9217f5ec04891c6f22ee2c32d73ae05e88a6bd2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.0"
|
||||
version: "1.1.1"
|
||||
riverpod:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: riverpod
|
||||
sha256: "84351b3472a447f7b89f961f95c73287009d58c59d8cc1267425d995f78e50f1"
|
||||
sha256: "484dfc873ea4c4f4240e5635444fa066f87b07862b7279ebd004a2b71fba4b7a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.4.2"
|
||||
version: "3.4.3"
|
||||
shared_preferences:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -772,18 +737,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_android
|
||||
sha256: "0634e64bd719f89c012f392938e173521f535d3ecaf66558fa94a056d22b5cc7"
|
||||
sha256: "1e12aafe408aa50da80edfd679a2a6bf63ba7ab37c7fa98286da459a757b3399"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.27"
|
||||
version: "2.4.28"
|
||||
shared_preferences_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_foundation
|
||||
sha256: "4e7eaffc2b17ba398759f1151415869a34771ba11ebbccd1b0145472a619a64f"
|
||||
sha256: "2ec3934efa51e46117f23031cc141b8fc878e8525b94ec1ea4f7f586cf1b47ea"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.5.6"
|
||||
version: "2.5.7"
|
||||
shared_preferences_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -816,38 +781,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.1"
|
||||
shelf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf
|
||||
sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.2"
|
||||
shelf_packages_handler:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_packages_handler
|
||||
sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
shelf_static:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_static
|
||||
sha256: c87c3875f91262785dade62d135760c2c69cb217ac759485334c5857ad89f6e3
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.3"
|
||||
shelf_web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
simple_gesture_detector:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -861,22 +794,6 @@ packages:
|
|||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
source_map_stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_map_stack_trace
|
||||
sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
source_maps:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_maps
|
||||
sha256: "190222579a448b03896e0ca6eca5998fa810fda630c1d65e2f78b3f638f54812"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.10.13"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -889,10 +806,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
|
||||
sha256: "277654b3034d17ac6f9f1cb5595db011b1d5d41e8806866db28e0abaa101c490"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.12.1"
|
||||
version: "1.12.2"
|
||||
state_notifier:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -921,10 +838,10 @@ packages:
|
|||
dependency: "direct main"
|
||||
description:
|
||||
name: table_calendar
|
||||
sha256: "0c0c6219878b363a2d5f40c7afb159d845f253d061dc3c822aa0d5fe0f721982"
|
||||
sha256: f276347cad425ef837a41e8d9ad43f3ee7d59227aa4c36d7430607a5a18fa3b3
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.0"
|
||||
version: "3.2.1"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -933,14 +850,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.2"
|
||||
test:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test
|
||||
sha256: ca578dc12bb8b2f40b67b7d3bd2fac4f31c01a6ff7130a14e2597b919934507f
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.31.1"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -949,14 +858,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.12"
|
||||
test_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_core
|
||||
sha256: d2e98ec12998368dc59ddd47ab709f2cd55acd6b66dc7db764455a44082f4bc5
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.18"
|
||||
timezone:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -985,34 +886,34 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_android
|
||||
sha256: b413d49b73867ac08dd2f9890efd3cc11f2a0e577618d50843440a1fb3776c32
|
||||
sha256: "611e87fb320b70d1dd721dc46af89c98aceccea9b31fde49e084591414e0c610"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.3.32"
|
||||
version: "6.3.33"
|
||||
url_launcher_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_ios
|
||||
sha256: "580fe5dfb51671ae38191d316e027f6b76272b026370708c2d898799750a02b0"
|
||||
sha256: "8faa1aab294f1ab4040b43660c887b0418d5fa4f0cffef76a484e6aa1092eb4a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.4.1"
|
||||
version: "6.4.2"
|
||||
url_launcher_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_linux
|
||||
sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a
|
||||
sha256: "10f86fef4c2c43563fa6c211ff9cf757adf4d3ab762c56bd430664a947d70cd0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.2"
|
||||
version: "3.2.3"
|
||||
url_launcher_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_macos
|
||||
sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18"
|
||||
sha256: "5e835a3b869c2d70325349c81c5a45c28e20791265b67b2669da6b08c5cd5201"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.5"
|
||||
version: "3.2.6"
|
||||
url_launcher_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -1033,10 +934,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_windows
|
||||
sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f"
|
||||
sha256: "6c5ad3f22cd4c38e089b81963b3cd7bb83b111b2df5dce008bb066162f42e429"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.5"
|
||||
version: "3.1.6"
|
||||
uuid:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -1057,18 +958,10 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: "0016aef94fc66495ac78af5859181e3f3bf2026bd8eecc72b9565601e19ab360"
|
||||
sha256: "5f37239c4851efcef929cea7824e76df7f2f0970aef85d66bbc430afa40e72f0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "15.2.0"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: watcher
|
||||
sha256: "1398c9f081a753f9226febe8900fce8f7d0a67163334e1c94a2438339d79d635"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
version: "15.3.0"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -1077,38 +970,22 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web_socket
|
||||
sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
web_socket_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web_socket_channel
|
||||
sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.3"
|
||||
webkit_inspection_protocol:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webkit_inspection_protocol
|
||||
sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e
|
||||
sha256: a0b93865d5644f11cf6a8c3f6db909f1ec168958b5805f6cc684adea957cd63d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.15.0"
|
||||
version: "6.4.0"
|
||||
windows_file_picker:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: windows_file_picker
|
||||
sha256: "9f3aa833068b09e380fdc59560ad260a4a14e9397173abb533699f967443602e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -1121,18 +998,18 @@ packages:
|
|||
dependency: transitive
|
||||
description:
|
||||
name: xml
|
||||
sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025"
|
||||
sha256: "67f0aff7be013d107995e9b75bf4e7f2c3ef2dfdb2c8e68024bba0a7fd5756a4"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.6.1"
|
||||
version: "7.0.1"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: yaml
|
||||
sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
|
||||
sha256: f67cdd8e07d3c6329146aaef1ba043542b3134c12489f553ca9a7435d1068aea
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.3"
|
||||
version: "3.1.4"
|
||||
sdks:
|
||||
dart: ">=3.12.0 <4.0.0"
|
||||
flutter: ">=3.44.0"
|
||||
dart: ">=3.13.0 <4.0.0"
|
||||
flutter: ">=3.47.0"
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ description: "CRM for everyone."
|
|||
# pub.dev using `flutter pub publish`. This is preferred for private packages.
|
||||
publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
||||
|
||||
version: 1.9.0+13
|
||||
version: 1.10.0+14
|
||||
|
||||
environment:
|
||||
sdk: ^3.8.1
|
||||
|
|
@ -13,44 +13,44 @@ dependencies:
|
|||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
http: ^1.1.0
|
||||
google_sign_in: ^7.1.1
|
||||
http: ^1.6.0
|
||||
google_sign_in: ^7.2.0
|
||||
shared_preferences: ^2.5.5
|
||||
# Tokens live here, never in shared_preferences. Keystore-backed on Android,
|
||||
# Keychain on iOS. See lib/services/token_storage.dart.
|
||||
flutter_secure_storage: ^10.3.1
|
||||
flutter_secure_storage: ^11.2.0
|
||||
jwt_decoder: ^2.0.1
|
||||
|
||||
# Firebase / Crashlytics (Android only, no iOS GoogleService-Info.plist yet)
|
||||
firebase_core: ^4.12.1
|
||||
firebase_crashlytics: ^5.2.6
|
||||
firebase_core: ^4.15.0
|
||||
firebase_crashlytics: ^5.4.0
|
||||
# Not referenced by name anywhere in lib/, but SwitchListTile.adaptive in
|
||||
# deals_list_screen.dart pulls in Flutter's Cupertino library, whose retained
|
||||
# CupertinoIcons constants need this font present. Dropping it builds fine and
|
||||
# then renders a missing-glyph box. Keep it.
|
||||
cupertino_icons: ^1.0.9
|
||||
# Navigation
|
||||
go_router: ^17.2.3
|
||||
go_router: ^18.0.1
|
||||
|
||||
# State Management
|
||||
flutter_riverpod: ^3.3.1
|
||||
flutter_riverpod: ^3.4.3
|
||||
|
||||
# Charts
|
||||
fl_chart: ^1.2.0
|
||||
|
||||
# Calendar
|
||||
table_calendar: ^3.2.0
|
||||
table_calendar: ^3.2.1
|
||||
|
||||
# Utilities
|
||||
intl: ^0.20.2
|
||||
url_launcher: ^6.3.1
|
||||
intl: ^0.20.3
|
||||
url_launcher: ^6.3.2
|
||||
# Attachment picking. Chosen over image_picker because a CRM attaches
|
||||
# contracts and PDFs at least as often as photos, and this covers both.
|
||||
file_picker: ^11.0.3
|
||||
file_picker: ^13.1.0
|
||||
|
||||
# Google Fonts for distinctive typography
|
||||
google_fonts: ^8.1.0
|
||||
lucide_icons_flutter: ^3.1.15
|
||||
google_fonts: ^8.2.1
|
||||
lucide_icons_flutter: ^3.1.20
|
||||
|
||||
# The org's calendar day for form defaults (lib/services/org_date.dart).
|
||||
# Publisher labs.dart.dev. The `all` database, because `latest` and
|
||||
|
|
@ -67,6 +67,7 @@ dev_dependencies:
|
|||
# rules and activating additional ones.
|
||||
flutter_lints: ^6.0.0
|
||||
flutter_launcher_icons: "^0.14.4"
|
||||
cross_file: ^0.3.5+5
|
||||
|
||||
flutter_launcher_icons:
|
||||
android: "launcher_icon"
|
||||
|
|
|
|||
59
mobile/test/helpers/fake_platform_file.dart
Normal file
59
mobile/test/helpers/fake_platform_file.dart
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:cross_file/cross_file.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
|
||||
/// A picked file for tests.
|
||||
///
|
||||
/// `PlatformFile` is abstract since file_picker 12, and the real subclass is
|
||||
/// built from a platform-channel map. This mirrors `AndroidPlatformFile`, the
|
||||
/// one that ships: [size] is what the picker reported (0 means it did not say),
|
||||
/// and `length()` falls back to measuring [bytes] or the file at [path].
|
||||
///
|
||||
/// [size] can disagree with the content on purpose, so a limit test can
|
||||
/// report 25 MB for a file that holds three bytes.
|
||||
final class FakePlatformFile extends PlatformFile {
|
||||
FakePlatformFile({
|
||||
required this.name,
|
||||
this.size = 0,
|
||||
String? path,
|
||||
this.bytes,
|
||||
}) : uri = path == null ? Uri(path: name) : Uri.file(path);
|
||||
|
||||
@override
|
||||
final String name;
|
||||
|
||||
@override
|
||||
final Uri uri;
|
||||
|
||||
final int size;
|
||||
final Uint8List? bytes;
|
||||
|
||||
@override
|
||||
XFile get xFile => bytes != null
|
||||
? XFile.fromData(bytes!, name: name)
|
||||
: XFile(path ?? name, name: name);
|
||||
|
||||
@override
|
||||
int? lengthSync() => size > 0 ? size : null;
|
||||
|
||||
@override
|
||||
Future<int?> length() async {
|
||||
if (size > 0) return size;
|
||||
if (bytes != null) return bytes!.length;
|
||||
final onDisk = path;
|
||||
if (onDisk == null) return null;
|
||||
try {
|
||||
return await File(onDisk).length();
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Uint8List> readAsBytes() => xFile.readAsBytes();
|
||||
|
||||
@override
|
||||
Stream<Uint8List> readAsByteStream() => xFile.openRead();
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import 'package:bottle_crm/services/attachment_upload.dart';
|
|||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import '../helpers/fake_platform_file.dart';
|
||||
|
||||
/// The app could delete an attachment it had no way to create.
|
||||
///
|
||||
|
|
@ -53,7 +54,7 @@ void main() {
|
|||
/// the boundary test from writing 25 MB on every run.
|
||||
PlatformFile file({String name = 'quote.pdf', int size = 2048}) {
|
||||
final onDisk = File('${tempDir.path}/$name')..writeAsBytesSync([1, 2, 3]);
|
||||
return PlatformFile(name: name, size: size, path: onDisk.path);
|
||||
return FakePlatformFile(name: name, size: size, path: onDisk.path);
|
||||
}
|
||||
|
||||
setUp(() {
|
||||
|
|
@ -188,12 +189,34 @@ void main() {
|
|||
final result = await pickAndUploadAttachment(
|
||||
target: AttachmentTarget.task,
|
||||
recordId: 'task-1',
|
||||
pickFile: () async => PlatformFile(name: 'ghost.txt', size: 10),
|
||||
pickFile: () async => FakePlatformFile(name: 'ghost.txt', size: 10),
|
||||
);
|
||||
|
||||
expect(result.succeeded, isFalse);
|
||||
expect(client.sent, isNull);
|
||||
});
|
||||
|
||||
test(
|
||||
'a pick whose size cannot be measured is reported, not sent',
|
||||
() async {
|
||||
// file_picker 13 returns null from length() when the picker reported no
|
||||
// size and the copy cannot be read, so the limit could not be checked.
|
||||
final result = await pickAndUploadAttachment(
|
||||
target: AttachmentTarget.task,
|
||||
recordId: 'task-1',
|
||||
pickFile: () async => FakePlatformFile(
|
||||
name: 'gone.pdf',
|
||||
path: '${tempDir.path}/does-not-exist.pdf',
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
result.error,
|
||||
'That file could not be read. Try picking it again.',
|
||||
);
|
||||
expect(client.sent, isNull);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
group('when the server refuses', () {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import 'package:file_picker/file_picker.dart';
|
|||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import '../helpers/fake_platform_file.dart';
|
||||
|
||||
/// Answers each request with the next queued reply and keeps what was sent,
|
||||
/// so a test can check the wire as well as the state.
|
||||
|
|
@ -32,7 +33,7 @@ const _csv = 'first_name,last_name\nAda,Lovelace\nAlan,Turing\n';
|
|||
|
||||
PlatformFile _file({String name = 'people.csv', String content = _csv}) {
|
||||
final bytes = Uint8List.fromList(utf8.encode(content));
|
||||
return PlatformFile(name: name, size: bytes.length, bytes: bytes);
|
||||
return FakePlatformFile(name: name, size: bytes.length, bytes: bytes);
|
||||
}
|
||||
|
||||
String _previewBody({
|
||||
|
|
@ -261,7 +262,7 @@ void main() {
|
|||
test('a file the picker reports as over 5 MB, before reading it', () async {
|
||||
final bytes = Uint8List.fromList(utf8.encode(_csv));
|
||||
await notifier().choose(
|
||||
PlatformFile(name: 'big.csv', size: 6 * 1024 * 1024, bytes: bytes),
|
||||
FakePlatformFile(name: 'big.csv', size: 6 * 1024 * 1024, bytes: bytes),
|
||||
);
|
||||
|
||||
expect(
|
||||
|
|
@ -275,7 +276,7 @@ void main() {
|
|||
test('bytes over 5 MB when the picker did not know the size', () async {
|
||||
final bytes = Uint8List(csvImportMaxBytes + 1);
|
||||
await notifier().choose(
|
||||
PlatformFile(name: 'big.csv', size: 0, bytes: bytes),
|
||||
FakePlatformFile(name: 'big.csv', size: 0, bytes: bytes),
|
||||
);
|
||||
|
||||
expect(stateOf().error, contains('CSV files must be 5 MB or smaller'));
|
||||
|
|
@ -286,7 +287,7 @@ void main() {
|
|||
client.replies.add((200, _previewBody()));
|
||||
final bytes = Uint8List(csvImportMaxBytes);
|
||||
await notifier().choose(
|
||||
PlatformFile(name: 'edge.csv', size: bytes.length, bytes: bytes),
|
||||
FakePlatformFile(name: 'edge.csv', size: bytes.length, bytes: bytes),
|
||||
);
|
||||
|
||||
expect(stateOf().error, isNull);
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ import 'package:bottle_crm/config/api_config.dart';
|
|||
import 'package:bottle_crm/data/models/support_ticket.dart';
|
||||
import 'package:bottle_crm/providers/support_provider.dart';
|
||||
import 'package:bottle_crm/services/api_service.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import '../helpers/fake_platform_file.dart';
|
||||
|
||||
Map<String, dynamic> ticketJson({
|
||||
List<Map<String, dynamic>> messages = const [],
|
||||
|
|
@ -109,7 +109,7 @@ void main() {
|
|||
subject: 'Export failed',
|
||||
category: SupportCategory.technical,
|
||||
body: 'Attached.',
|
||||
attachment: PlatformFile(
|
||||
attachment: FakePlatformFile(
|
||||
name: 'error.txt',
|
||||
size: file.lengthSync(),
|
||||
path: file.path,
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@ import 'dart:typed_data';
|
|||
import 'package:bottle_crm/providers/csv_import_provider.dart';
|
||||
import 'package:bottle_crm/services/api_service.dart';
|
||||
import 'package:bottle_crm/widgets/forms/csv_import_sheet.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import '../helpers/fake_platform_file.dart';
|
||||
|
||||
class _QueueClient extends http.BaseClient {
|
||||
final List<(int, String)> replies = [];
|
||||
|
|
@ -96,7 +96,7 @@ void main() {
|
|||
context,
|
||||
target,
|
||||
onImported: () => refreshed++,
|
||||
pickFile: () async => PlatformFile(
|
||||
pickFile: () async => FakePlatformFile(
|
||||
name: 'people.csv',
|
||||
size: bytes.length,
|
||||
bytes: bytes,
|
||||
|
|
|
|||
Loading…
Reference in a new issue