added file verification with md5 checksum

This commit is contained in:
dstark5
2024-02-04 12:41:48 +05:30
parent 5fa66ba42f
commit c068714e52
18 changed files with 355 additions and 189 deletions

@ -76,7 +76,7 @@ class MyApp extends ConsumerWidget {
builder: (BuildContext context, Widget? child) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaleFactor: 1.0,
textScaler: const TextScaler.linear(1.0),
),
child: child!,
);

@ -28,24 +28,16 @@ class BookInfoData extends BookData {
final String? format;
BookInfoData(
{required String title,
required String? author,
required String? thumbnail,
required String? publisher,
required String? info,
required String link,
required String md5,
{required super.title,
required super.author,
required super.thumbnail,
required super.publisher,
required super.info,
required super.link,
required super.md5,
required this.mirrors,
required this.format,
required this.description})
: super(
title: title,
author: author,
thumbnail: thumbnail,
publisher: publisher,
info: info,
link: link,
md5: md5);
required this.description});
}
class AnnasArchieve {

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:crypto/crypto.dart';
import 'package:dio/dio.dart';
import 'package:chunked_downloader/chunked_downloader.dart';
import 'files.dart';
@ -28,8 +30,9 @@ Future<String?> _getAliveMirror(List<String> mirrors, Dio dio) async {
for (var url in mirrors) {
try {
final response = await dio.head(url,
options: Options(receiveTimeout: const Duration(seconds: 5)));
options: Options(receiveTimeout: const Duration(seconds: 10)));
if (response.statusCode == 200) {
dio.close();
return url;
}
} catch (e) {
@ -43,6 +46,7 @@ Future<void> downloadFile(
{required List<String> mirrors,
required String md5,
required String format,
required Function onStart,
required Function onProgress,
required Function cancelDownlaod,
required Function mirrorStatus,
@ -60,6 +64,7 @@ Future<void> downloadFile(
// print(orderedMirrors[0]);
if (workingMirror != null) {
onStart();
try {
var chunkedDownloader = await ChunkedDownloader(
url: workingMirror,
@ -83,3 +88,23 @@ Future<void> downloadFile(
onDownlaodFailed();
}
}
Future<bool> verifyFileCheckSum(
{required String md5Hash, required String format}) async {
try {
final path = await getAppDirectoryPath;
final filePath = '$path/$md5Hash.$format';
final file = File(filePath);
final stream = file.openRead();
final hash = await md5.bind(stream).first;
print('md5 Checksum $md5Hash');
print('file hash ${hash.toString()}');
if (md5Hash == hash.toString()) {
return true;
}
return false;
} catch (e) {
print(e);
return false;
}
}

@ -136,6 +136,15 @@ final cancelCurrentDownload = StateProvider<ChunkedDownloader>((ref) {
return ChunkedDownloader(saveFilePath: "", url: "");
});
enum ProcessState { waiting, running, complete }
enum CheckSumProcessState { waiting, running, failed, success }
final downloadState =
StateProvider.autoDispose<ProcessState>((ref) => ProcessState.waiting);
final checkSumState = StateProvider.autoDispose<CheckSumProcessState>(
(ref) => CheckSumProcessState.waiting);
final dbProvider = Provider<MyLibraryDb>((ref) => throw UnimplementedError());
final myLibraryProvider = FutureProvider((ref) async {

@ -5,7 +5,7 @@ import 'package:openlib/ui/components/snack_bar_widget.dart';
import 'package:openlib/ui/components/page_title_widget.dart';
class AboutPage extends StatelessWidget {
const AboutPage({Key? key}) : super(key: key);
const AboutPage({super.key});
@override
Widget build(BuildContext context) {
@ -87,8 +87,7 @@ class AboutPage extends StatelessWidget {
}
class _UrlText extends StatelessWidget {
const _UrlText({Key? key, required this.text, required this.url})
: super(key: key);
const _UrlText({required this.text, required this.url});
final String url;
final String text;

@ -17,6 +17,10 @@ import 'package:openlib/state/state.dart'
getDownloadedFileSize,
cancelCurrentDownload,
mirrorStatusProvider,
ProcessState,
CheckSumProcessState,
downloadState,
checkSumState,
dbProvider,
checkIdExists,
myLibraryProvider;
@ -30,7 +34,7 @@ import 'package:flutter_svg/svg.dart';
import 'package:openlib/ui/webview_page.dart';
class BookInfoPage extends ConsumerWidget {
const BookInfoPage({Key? key, required this.url}) : super(key: key);
const BookInfoPage({super.key, required this.url});
final String url;
@ -219,30 +223,55 @@ Future<void> downloadFileWidget(
mirrors: data.mirrors!,
md5: data.md5,
format: data.format!,
onStart: () {
ref.read(downloadState.notifier).state = ProcessState.running;
},
onProgress: (int rcv, int total) async {
if (ref.read(totalFileSizeInBytes) != total) {
ref.read(totalFileSizeInBytes.notifier).state = total;
}
ref.read(downloadedFileSizeInBytes.notifier).state = rcv;
ref.read(downloadProgressProvider.notifier).state = rcv / total;
if (rcv / total == 1.0) {
await ref.read(dbProvider).insert(MyBook(
id: data.md5,
title: data.title,
author: data.author,
thumbnail: data.thumbnail,
link: data.link,
publisher: data.publisher,
info: data.info,
format: data.format,
description: data.description));
if (!rcv.isNaN && !total.isNaN) {
ref.read(downloadedFileSizeInBytes.notifier).state = rcv;
ref.read(downloadProgressProvider.notifier).state = rcv / total;
// ignore: unused_result
ref.refresh(checkIdExists(data.md5));
// ignore: unused_result
ref.refresh(myLibraryProvider);
// ignore: use_build_context_synchronously
showSnackBar(context: context, message: 'Book has been downloaded!');
if (rcv / total == 1.0) {
await ref.read(dbProvider).insert(MyBook(
id: data.md5,
title: data.title,
author: data.author,
thumbnail: data.thumbnail,
link: data.link,
publisher: data.publisher,
info: data.info,
format: data.format,
description: data.description));
ref.read(downloadState.notifier).state = ProcessState.complete;
ref.read(checkSumState.notifier).state =
CheckSumProcessState.running;
try {
final checkSum = await verifyFileCheckSum(
md5Hash: data.md5, format: data.format);
if (checkSum == true) {
ref.read(checkSumState.notifier).state =
CheckSumProcessState.success;
} else {
ref.read(checkSumState.notifier).state =
CheckSumProcessState.failed;
}
} catch (_) {
ref.read(checkSumState.notifier).state =
CheckSumProcessState.failed;
}
// ignore: unused_result
ref.refresh(checkIdExists(data.md5));
// ignore: unused_result
ref.refresh(myLibraryProvider);
// ignore: use_build_context_synchronously
showSnackBar(
context: context, message: 'Book has been downloaded!');
}
}
},
cancelDownlaod: (ChunkedDownloader downloadToken) {
@ -276,9 +305,15 @@ class _ShowDialog extends ConsumerWidget {
final fileSize = ref.watch(getTotalFileSize);
final downloadedFileSize = ref.watch(getDownloadedFileSize);
final mirrorStatus = ref.watch(mirrorStatusProvider);
final downloadProcessState = ref.watch(downloadState);
final checkSumVerifyState = ref.watch(checkSumState);
if (downloadProgress == 1.0) {
Navigator.of(context).pop();
if (downloadProgress == 1.0 &&
(checkSumVerifyState == CheckSumProcessState.failed ||
checkSumVerifyState == CheckSumProcessState.success)) {
Future.delayed(const Duration(seconds: 3), () {
Navigator.of(context).pop();
});
}
return Stack(
@ -288,7 +323,7 @@ class _ShowDialog extends ConsumerWidget {
padding: const EdgeInsets.all(15.0),
child: Container(
width: double.infinity,
height: 285,
height: 345,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
color: Theme.of(context).colorScheme.tertiaryContainer,
@ -367,6 +402,109 @@ class _ShowDialog extends ConsumerWidget {
),
]),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
switch (downloadProcessState) {
ProcessState.waiting => Icon(
Icons.timer,
size: 15,
color: Theme.of(context)
.colorScheme
.tertiary
.withAlpha(140),
),
ProcessState.running => SizedBox(
width: 9,
height: 9,
child: CircularProgressIndicator(
color:
Theme.of(context).colorScheme.secondary,
strokeWidth: 2.5,
strokeCap: StrokeCap.round,
),
),
ProcessState.complete => const Icon(
Icons.check_circle,
size: 15,
color: Colors.green,
),
},
const SizedBox(
width: 3,
),
Text(
"Downloading",
style: TextStyle(
fontSize: 11.5,
fontWeight: FontWeight.bold,
color: Theme.of(context)
.colorScheme
.tertiary
.withAlpha(140),
decoration: TextDecoration.none),
overflow: TextOverflow.ellipsis,
maxLines: 2,
textAlign: TextAlign.start,
),
]),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
switch (checkSumVerifyState) {
CheckSumProcessState.waiting => Icon(
Icons.timer,
size: 15,
color: Theme.of(context)
.colorScheme
.tertiary
.withAlpha(140),
),
CheckSumProcessState.running => SizedBox(
width: 9,
height: 9,
child: CircularProgressIndicator(
color:
Theme.of(context).colorScheme.secondary,
strokeWidth: 2.5,
strokeCap: StrokeCap.round,
),
),
CheckSumProcessState.failed => const Icon(
Icons.close,
size: 15,
color: Colors.red,
),
CheckSumProcessState.success => const Icon(
Icons.check_circle,
size: 15,
color: Colors.green,
),
},
const SizedBox(
width: 3,
),
Text(
"Verifying file checksum",
style: TextStyle(
fontSize: 11.5,
fontWeight: FontWeight.bold,
color: Theme.of(context)
.colorScheme
.tertiary
.withAlpha(140),
decoration: TextDecoration.none),
overflow: TextOverflow.ellipsis,
maxLines: 2,
textAlign: TextAlign.start,
),
]),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [

@ -16,15 +16,14 @@ String? getFileType(String? info) {
class BookInfoCard extends StatelessWidget {
const BookInfoCard(
{Key? key,
{super.key,
required this.title,
required this.author,
required this.publisher,
required this.thumbnail,
required this.info,
required this.link,
required this.onClick})
: super(key: key);
required this.onClick});
final String title;
final String author;

@ -5,8 +5,7 @@ class BookInfoWidget extends StatelessWidget {
final Widget child;
final dynamic data;
const BookInfoWidget({Key? key, required this.child, required this.data})
: super(key: key);
const BookInfoWidget({super.key, required this.child, required this.data});
@override
Widget build(BuildContext context) {
@ -145,9 +144,7 @@ class _TopPaddedText extends StatelessWidget {
required this.fontSize,
required this.topPadding,
required this.color,
required this.maxLines,
Key? key})
: super(key: key);
required this.maxLines});
@override
Widget build(BuildContext context) {

@ -9,8 +9,10 @@ class CustomErrorWidget extends StatelessWidget {
VoidCallback? onRefresh;
CustomErrorWidget(
{Key? key, required this.error, required this.stackTrace, this.onRefresh})
: super(key: key);
{super.key,
required this.error,
required this.stackTrace,
this.onRefresh});
@override
Widget build(BuildContext context) {

@ -14,11 +14,10 @@ class FileOpenAndDeleteButtons extends ConsumerWidget {
final Function onDelete;
const FileOpenAndDeleteButtons(
{Key? key,
{super.key,
required this.id,
required this.format,
required this.onDelete})
: super(key: key);
required this.onDelete});
@override
Widget build(BuildContext context, WidgetRef ref) {

@ -109,8 +109,7 @@ class _EpubViewState extends ConsumerState<EpubViewerWidget> {
}
class EpubViewer extends ConsumerStatefulWidget {
const EpubViewer({Key? key, required this.filePath, required this.fileName})
: super(key: key);
const EpubViewer({super.key, required this.filePath, required this.fileName});
final String filePath;
final String fileName;

@ -7,7 +7,7 @@ import 'package:openlib/ui/components/book_info_widget.dart';
import 'package:openlib/ui/components/file_buttons_widget.dart';
class BookPage extends StatelessWidget {
const BookPage({Key? key, required this.id}) : super(key: key);
const BookPage({super.key, required this.id});
final String id;

@ -77,8 +77,7 @@ class _PdfViewState extends ConsumerState<PdfView> {
}
class PdfViewer extends ConsumerStatefulWidget {
const PdfViewer({Key? key, required this.filePath, required this.fileName})
: super(key: key);
const PdfViewer({super.key, required this.filePath, required this.fileName});
final String filePath;
final String fileName;

@ -15,7 +15,7 @@ import 'package:openlib/state/state.dart'
import 'components/snack_bar_widget.dart';
class SearchPage extends ConsumerWidget {
const SearchPage({Key? key}) : super(key: key);
const SearchPage({super.key});
void onSubmit(BuildContext context, WidgetRef ref) {
if (ref.read(searchQueryProvider).isNotEmpty) {

@ -13,7 +13,7 @@ import 'package:openlib/state/state.dart'
dbProvider;
class SettingsPage extends ConsumerWidget {
const SettingsPage({Key? key}) : super(key: key);
const SettingsPage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
@ -130,8 +130,7 @@ class SettingsPage extends ConsumerWidget {
}
class _PaddedContainer extends StatelessWidget {
const _PaddedContainer({Key? key, this.onClick, required this.children})
: super(key: key);
const _PaddedContainer({this.onClick, required this.children});
final VoidCallback? onClick;
final List<Widget> children;

@ -8,7 +8,7 @@ import 'package:openlib/state/state.dart'
show cookieProvider, userAgentProvider, dbProvider, bookInfoProvider;
class Webview extends ConsumerStatefulWidget {
const Webview({Key? key, required this.url}) : super(key: key);
const Webview({super.key, required this.url});
final String url;
@override
// ignore: library_private_types_in_public_api

@ -5,10 +5,10 @@ packages:
dependency: transitive
description:
name: archive
sha256: "49b1fad315e57ab0bbc15bcbb874e83116a1d78f77ebd500a4af6c9407d6b28e"
sha256: "22600aa1e926be775fa5fe7e6894e7fb3df9efda8891c73f70fb3262399a432d"
url: "https://pub.dev"
source: hosted
version: "3.3.8"
version: "3.4.10"
args:
dependency: transitive
description:
@ -37,26 +37,26 @@ packages:
dependency: "direct main"
description:
name: cached_network_image
sha256: fd3d0dc1d451f9a252b32d95d3f0c3c487bc41a75eba2e6097cb0b9c71491b15
sha256: "28ea9690a8207179c319965c13cd8df184d5ee721ae2ce60f398ced1219cea1f"
url: "https://pub.dev"
source: hosted
version: "3.2.3"
version: "3.3.1"
cached_network_image_platform_interface:
dependency: transitive
description:
name: cached_network_image_platform_interface
sha256: bb2b8403b4ccdc60ef5f25c70dead1f3d32d24b9d6117cfc087f496b178594a7
sha256: "9e90e78ae72caa874a323d78fa6301b3fb8fa7ea76a8f96dc5b5bf79f283bf2f"
url: "https://pub.dev"
source: hosted
version: "2.0.0"
version: "4.0.0"
cached_network_image_web:
dependency: transitive
description:
name: cached_network_image_web
sha256: b8eb814ebfcb4dea049680f8c1ffb2df399e4d03bf7a352c775e26fa06e02fa0
sha256: "42a835caa27c220d1294311ac409a43361088625a4f23c820b006dd9bffb3316"
url: "https://pub.dev"
source: hosted
version: "1.0.2"
version: "1.1.1"
characters:
dependency: transitive
description:
@ -101,10 +101,10 @@ packages:
dependency: transitive
description:
name: collection
sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted
version: "1.17.2"
version: "1.18.0"
convert:
dependency: transitive
description:
@ -114,7 +114,7 @@ packages:
source: hosted
version: "3.1.1"
crypto:
dependency: transitive
dependency: "direct main"
description:
name: crypto
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
@ -201,19 +201,19 @@ packages:
url: "https://pub.dev"
source: hosted
version: "7.0.0"
fixnum:
dependency: transitive
description:
name: fixnum
sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_blurhash:
dependency: transitive
description:
name: flutter_blurhash
sha256: "05001537bd3fac7644fa6558b09ec8c0a3f2eba78c0765f88912882b1331a5c6"
url: "https://pub.dev"
source: hosted
version: "0.7.0"
flutter_cache_manager:
dependency: transitive
description:
@ -242,34 +242,34 @@ packages:
dependency: "direct dev"
description:
name: flutter_lints
sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04
sha256: e2a421b7e59244faef694ba7b30562e489c2b489866e505074eb005cd7060db7
url: "https://pub.dev"
source: hosted
version: "2.0.3"
version: "3.0.1"
flutter_pdfview:
dependency: "direct main"
description:
name: flutter_pdfview
sha256: d9735fd8991609910742a25c63a5f87060849e57e60112c677b802ddb64bed72
sha256: a9055bf920c7095bf08c2781db431ba23577aa5da5a056a7152dc89a18fbec6f
url: "https://pub.dev"
source: hosted
version: "1.3.1"
version: "1.3.2"
flutter_riverpod:
dependency: "direct main"
description:
name: flutter_riverpod
sha256: b04d4e9435a563673746ccb328d22018c6c9496bb547e11dd56c1b0cc9829fe5
sha256: da9591d1f8d5881628ccd5c25c40e74fc3eef50ba45e40c3905a06e1712412d5
url: "https://pub.dev"
source: hosted
version: "2.3.10"
version: "2.4.9"
flutter_svg:
dependency: "direct main"
description:
name: flutter_svg
sha256: "8c5d68a82add3ca76d792f058b186a0599414f279f00ece4830b9b231b570338"
sha256: d39e7f95621fc84376bc0f7d504f05c3a41488c562f4a8ad410569127507402c
url: "https://pub.dev"
source: hosted
version: "2.0.7"
version: "2.0.9"
flutter_test:
dependency: "direct dev"
description: flutter
@ -356,10 +356,10 @@ packages:
dependency: transitive
description:
name: lints
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "3.0.0"
list_counter:
dependency: transitive
description:
@ -388,18 +388,18 @@ packages:
dependency: transitive
description:
name: meta
sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e
url: "https://pub.dev"
source: hosted
version: "1.9.1"
version: "1.10.0"
octo_image:
dependency: transitive
description:
name: octo_image
sha256: "107f3ed1330006a3bea63615e81cf637433f5135a52466c7caa0e7152bca9143"
sha256: "45b40f99622f11901238e18d48f5f12ea36426d8eced9f4cbf58479c7aa2430d"
url: "https://pub.dev"
source: hosted
version: "1.0.2"
version: "2.0.0"
open_file:
dependency: "direct main"
description:
@ -428,26 +428,26 @@ packages:
dependency: "direct main"
description:
name: path_provider
sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa
sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "2.1.2"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
sha256: "6b8b19bd80da4f11ce91b2d1fb931f3006911477cec227cce23d3253d80df3f1"
sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668"
url: "https://pub.dev"
source: hosted
version: "2.2.0"
version: "2.2.2"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d"
sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f"
url: "https://pub.dev"
source: hosted
version: "2.3.1"
version: "2.3.2"
path_provider_linux:
dependency: transitive
description:
@ -460,10 +460,10 @@ packages:
dependency: transitive
description:
name: path_provider_platform_interface
sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c"
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "2.1.2"
path_provider_windows:
dependency: transitive
description:
@ -476,74 +476,82 @@ packages:
dependency: "direct main"
description:
name: permission_handler
sha256: "63e5216aae014a72fe9579ccd027323395ce7a98271d9defa9d57320d001af81"
sha256: "45ff3fbcb99040fde55c528d5e3e6ca29171298a85436274d49c6201002087d6"
url: "https://pub.dev"
source: hosted
version: "10.4.3"
version: "11.2.0"
permission_handler_android:
dependency: transitive
description:
name: permission_handler_android
sha256: d74e77a5ecd38649905db0a7d05ef16bed42ff263b9efb73ed794317c5764ec3
sha256: "758284a0976772f9c744d6384fc5dc4834aa61e3f7aa40492927f244767374eb"
url: "https://pub.dev"
source: hosted
version: "10.3.4"
version: "12.0.3"
permission_handler_apple:
dependency: transitive
description:
name: permission_handler_apple
sha256: "99e220bce3f8877c78e4ace901082fb29fa1b4ebde529ad0932d8d664b34f3f5"
sha256: c6bf440f80acd2a873d3d91a699e4cc770f86e7e6b576dda98759e8b92b39830
url: "https://pub.dev"
source: hosted
version: "9.1.4"
version: "9.3.0"
permission_handler_html:
dependency: transitive
description:
name: permission_handler_html
sha256: "54bf176b90f6eddd4ece307e2c06cf977fb3973719c35a93b85cc7093eb6070d"
url: "https://pub.dev"
source: hosted
version: "0.1.1"
permission_handler_platform_interface:
dependency: transitive
description:
name: permission_handler_platform_interface
sha256: "7c6b1500385dd1d2ca61bb89e2488ca178e274a69144d26bbd65e33eae7c02a9"
sha256: "5c43148f2bfb6d14c5a8162c0a712afe891f2d847f35fcff29c406b37da43c3c"
url: "https://pub.dev"
source: hosted
version: "3.11.3"
version: "4.1.0"
permission_handler_windows:
dependency: transitive
description:
name: permission_handler_windows
sha256: cc074aace208760f1eee6aa4fae766b45d947df85bc831cde77009cdb4720098
sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e"
url: "https://pub.dev"
source: hosted
version: "0.1.3"
version: "0.2.1"
petitparser:
dependency: transitive
description:
name: petitparser
sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750
sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
url: "https://pub.dev"
source: hosted
version: "5.4.0"
version: "6.0.2"
platform:
dependency: transitive
description:
name: platform
sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102
sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec"
url: "https://pub.dev"
source: hosted
version: "3.1.2"
version: "3.1.4"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
url: "https://pub.dev"
source: hosted
version: "2.1.6"
version: "2.1.8"
pointycastle:
dependency: transitive
description:
name: pointycastle
sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c"
sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29"
url: "https://pub.dev"
source: hosted
version: "3.7.3"
version: "3.7.4"
quiver:
dependency: transitive
description:
@ -556,10 +564,10 @@ packages:
dependency: transitive
description:
name: riverpod
sha256: "6c0a2c30c04206ac05494bcccd8148b76866e1a9248a5a8c84ca7b16fbcb3f6a"
sha256: "942999ee48b899f8a46a860f1e13cee36f2f77609eb54c5b7a669bb20d550b11"
url: "https://pub.dev"
source: hosted
version: "2.3.10"
version: "2.4.9"
rxdart:
dependency: transitive
description:
@ -601,42 +609,42 @@ packages:
dependency: "direct main"
description:
name: sqflite
sha256: "591f1602816e9c31377d5f008c2d9ef7b8aca8941c3f89cc5fd9d84da0c38a9a"
sha256: a9016f495c927cb90557c909ff26a6d92d9bd54fc42ba92e19d4e79d61e798c6
url: "https://pub.dev"
source: hosted
version: "2.3.0"
version: "2.3.2"
sqflite_common:
dependency: transitive
description:
name: sqflite_common
sha256: "1b92f368f44b0dee2425bb861cfa17b6f6cf3961f762ff6f941d20b33355660a"
sha256: "28d8c66baee4968519fb8bd6cdbedad982d6e53359091f0b74544a9f32ec72d5"
url: "https://pub.dev"
source: hosted
version: "2.5.0"
version: "2.5.3"
sqflite_common_ffi:
dependency: "direct main"
description:
name: sqflite_common_ffi
sha256: "0d5cc1be2eb18400ac6701c31211d44164393aa75886093002ecdd947be04f93"
sha256: "754927d82de369a6b9e760fb60640aa81da650f35ffd468d5a992814d6022908"
url: "https://pub.dev"
source: hosted
version: "2.3.0+2"
version: "2.3.2+1"
sqlite3:
dependency: transitive
description:
name: sqlite3
sha256: db65233e6b99e99b2548932f55a987961bc06d82a31a0665451fa0b4fff4c3fb
sha256: c4a4c5a4b2a32e2d0f6837b33d7c91a67903891a5b7dbe706cf4b1f6b0c798c5
url: "https://pub.dev"
source: hosted
version: "2.1.0"
version: "2.3.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.dev"
source: hosted
version: "1.11.0"
version: "1.11.1"
state_notifier:
dependency: transitive
description:
@ -649,10 +657,10 @@ packages:
dependency: transitive
description:
name: stream_channel
sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "2.1.2"
string_scanner:
dependency: transitive
description:
@ -665,10 +673,10 @@ packages:
dependency: transitive
description:
name: synchronized
sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60"
sha256: "539ef412b170d65ecdafd780f924e5be3f60032a1128df156adad6c5b373d558"
url: "https://pub.dev"
source: hosted
version: "3.1.0"
version: "3.1.0+1"
term_glyph:
dependency: transitive
description:
@ -681,10 +689,10 @@ packages:
dependency: transitive
description:
name: test_api
sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
url: "https://pub.dev"
source: hosted
version: "0.6.0"
version: "0.6.1"
typed_data:
dependency: transitive
description:
@ -705,98 +713,98 @@ packages:
dependency: "direct main"
description:
name: url_launcher
sha256: "47e208a6711459d813ba18af120d9663c20bdf6985d6ad39fe165d2538378d27"
sha256: c512655380d241a337521703af62d2c122bf7b77a46ff7dd750092aa9433499c
url: "https://pub.dev"
source: hosted
version: "6.1.14"
version: "6.2.4"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
sha256: b04af59516ab45762b2ca6da40fa830d72d0f6045cd97744450b73493fa76330
sha256: "507dc655b1d9cb5ebc756032eb785f114e415f91557b73bf60b7e201dfedeb2f"
url: "https://pub.dev"
source: hosted
version: "6.1.0"
version: "6.2.2"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
sha256: "7c65021d5dee51813d652357bc65b8dd4a6177082a9966bc8ba6ee477baa795f"
sha256: "75bb6fe3f60070407704282a2d295630cab232991eb52542b18347a8a941df03"
url: "https://pub.dev"
source: hosted
version: "6.1.5"
version: "6.2.4"
url_launcher_linux:
dependency: transitive
description:
name: url_launcher_linux
sha256: b651aad005e0cb06a01dbd84b428a301916dc75f0e7ea6165f80057fee2d8e8e
sha256: ab360eb661f8879369acac07b6bb3ff09d9471155357da8443fd5d3cf7363811
url: "https://pub.dev"
source: hosted
version: "3.0.6"
version: "3.1.1"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
sha256: b55486791f666e62e0e8ff825e58a023fd6b1f71c49926483f1128d3bbd8fe88
sha256: b7244901ea3cf489c5335bdacda07264a6e960b1c1b1a9f91e4bc371d9e68234
url: "https://pub.dev"
source: hosted
version: "3.0.7"
version: "3.1.0"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
sha256: "95465b39f83bfe95fcb9d174829d6476216f2d548b79c38ab2506e0458787618"
sha256: a932c3a8082e118f80a475ce692fde89dc20fddb24c57360b96bc56f7035de1f
url: "https://pub.dev"
source: hosted
version: "2.1.5"
version: "2.3.1"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
sha256: "2942294a500b4fa0b918685aff406773ba0a4cd34b7f42198742a94083020ce5"
sha256: fff0932192afeedf63cdd50ecbb1bc825d31aed259f02bb8dba0f3b729a5e88b
url: "https://pub.dev"
source: hosted
version: "2.0.20"
version: "2.2.3"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
sha256: "95fef3129dc7cfaba2bc3d5ba2e16063bb561fc6d78e63eee16162bc70029069"
sha256: ecf9725510600aa2bb6d7ddabe16357691b6d2805f66216a97d1b881e21beff7
url: "https://pub.dev"
source: hosted
version: "3.0.8"
version: "3.1.1"
uuid:
dependency: transitive
description:
name: uuid
sha256: e03928880bdbcbf496fb415573f5ab7b1ea99b9b04f669c01104d085893c3134
sha256: cd210a09f7c18cbe5a02511718e0334de6559871052c90a90c0cca46a4aa81c8
url: "https://pub.dev"
source: hosted
version: "4.0.0"
version: "4.3.3"
vector_graphics:
dependency: transitive
description:
name: vector_graphics
sha256: "670f6e07aca990b4a2bcdc08a784193c4ccdd1932620244c3a86bb72a0eac67f"
sha256: "18f6690295af52d081f6808f2f7c69f0eed6d7e23a71539d75f4aeb8f0062172"
url: "https://pub.dev"
source: hosted
version: "1.1.7"
version: "1.1.9+2"
vector_graphics_codec:
dependency: transitive
description:
name: vector_graphics_codec
sha256: "7451721781d967db9933b63f5733b1c4533022c0ba373a01bdd79d1a5457f69f"
sha256: "531d20465c10dfac7f5cd90b60bbe4dd9921f1ec4ca54c83ebb176dbacb7bb2d"
url: "https://pub.dev"
source: hosted
version: "1.1.7"
version: "1.1.9+2"
vector_graphics_compiler:
dependency: transitive
description:
name: vector_graphics_compiler
sha256: "80a13c613c8bde758b1464a1755a7b3a8f2b6cec61fbf0f5a53c94c30f03ba2e"
sha256: "03012b0a33775c5530576b70240308080e1d5050f0faf000118c20e6463bc0ad"
url: "https://pub.dev"
source: hosted
version: "1.1.7"
version: "1.1.9+2"
vector_math:
dependency: transitive
description:
@ -817,10 +825,10 @@ packages:
dependency: transitive
description:
name: web
sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152
url: "https://pub.dev"
source: hosted
version: "0.1.4-beta"
version: "0.3.0"
webview_cookie_manager:
dependency: "direct main"
description:
@ -833,58 +841,58 @@ packages:
dependency: "direct main"
description:
name: webview_flutter
sha256: c1ab9b81090705c6069197d9fdc1625e587b52b8d70cdde2339d177ad0dbb98e
sha256: d81b68e88cc353e546afb93fb38958e3717282c5ac6e5d3be4a4aef9fc3c1413
url: "https://pub.dev"
source: hosted
version: "4.4.1"
version: "4.5.0"
webview_flutter_android:
dependency: transitive
description:
name: webview_flutter_android
sha256: b0cd33dd7d3dd8e5f664e11a19e17ba12c352647269921a3b568406b001f1dff
sha256: "4ea3c4e1b8ed590162b15b8a61b41b1ef3ff179a314627c16ce40c086d94b8af"
url: "https://pub.dev"
source: hosted
version: "3.12.0"
version: "3.14.0"
webview_flutter_platform_interface:
dependency: transitive
description:
name: webview_flutter_platform_interface
sha256: "6d9213c65f1060116757a7c473247c60f3f7f332cac33dc417c9e362a9a13e4f"
sha256: d937581d6e558908d7ae3dc1989c4f87b786891ab47bb9df7de548a151779d8d
url: "https://pub.dev"
source: hosted
version: "2.6.0"
version: "2.10.0"
webview_flutter_wkwebview:
dependency: transitive
description:
name: webview_flutter_wkwebview
sha256: "30b9af6bdd457b44c08748b9190d23208b5165357cc2eb57914fee1366c42974"
sha256: b99ca8d8bae9c6b43d568218691aa537fb0aeae1d7d34eadf112a6aa36d26506
url: "https://pub.dev"
source: hosted
version: "3.9.1"
version: "3.11.0"
win32:
dependency: transitive
description:
name: win32
sha256: "9e82a402b7f3d518fb9c02d0e9ae45952df31b9bf34d77baf19da2de03fc2aaa"
sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8"
url: "https://pub.dev"
source: hosted
version: "5.0.7"
version: "5.2.0"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2"
sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
url: "https://pub.dev"
source: hosted
version: "1.0.3"
version: "1.0.4"
xml:
dependency: transitive
description:
name: xml
sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84"
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
url: "https://pub.dev"
source: hosted
version: "6.3.0"
version: "6.5.0"
yaml:
dependency: transitive
description:
@ -894,5 +902,5 @@ packages:
source: hosted
version: "3.1.2"
sdks:
dart: ">=3.1.0 <4.0.0"
flutter: ">=3.13.0"
dart: ">=3.2.3 <4.0.0"
flutter: ">=3.16.6"

@ -45,13 +45,13 @@ dependencies:
sqflite: ^2.3.0
path_provider: ^2.0.15
permission_handler: ^10.4.3
permission_handler: ^11.2.0
open_file: ^3.3.2
webview_flutter: ^4.4.1
webview_cookie_manager: ^2.0.6
flutter_svg: ^2.0.7
google_fonts:
google_fonts: ^4.0.4
cached_network_image: ^3.2.3
chunked_downloader: ^0.0.2
@ -62,6 +62,7 @@ dependencies:
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
dev: ^1.0.0
crypto: ^3.0.3
dev_dependencies:
flutter_test:
@ -73,7 +74,7 @@ dev_dependencies:
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^2.0.0
flutter_lints: ^3.0.1
flutter_icons: