import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:openlib/services/database.dart'; import 'package:chunked_downloader/chunked_downloader.dart'; import 'package:openlib/services/open_library.dart'; import 'package:openlib/services/annas_archieve.dart'; import 'package:openlib/services/files.dart'; //Provider for dropdownbutton in search page Map typeValues = { 'All': '', 'Any Books': 'book_any', 'Unknown Books': 'book_unknown', 'Fiction Books': 'book_fiction', 'Non-fiction Books': 'book_nonfiction', 'Comic Books': 'book_comic', 'Magazine': 'magazine', 'Standards Document': 'standards_document', 'Journal Article': 'journal_article' }; Map sortValues = { 'Most Relevant': '', 'Newest': 'newest', 'Oldest': 'oldest', 'Largest': 'largest', 'Smallest': 'smallest', }; List fileType = ["All", "PDF", "Epub", "Cbr", "Cbz"]; final selectedIndexProvider = StateProvider((ref) => 0); final themeModeProvider = StateProvider((ref) => ThemeMode.light); final selectedTypeState = StateProvider((ref) => "All"); final getTypeValue = Provider.autoDispose((ref) { return typeValues[ref.read(selectedTypeState)] ?? ''; }); final selectedSortState = StateProvider((ref) => "Most Relevant"); final getSortValue = Provider.autoDispose((ref) { return sortValues[ref.read(selectedSortState)] ?? ''; }); final selectedFileTypeState = StateProvider((ref) => "All"); final getFileTypeValue = Provider.autoDispose((ref) { if (ref.read(selectedFileTypeState) == "All") { return ''; } return ref.read(selectedFileTypeState).toLowerCase(); }); //searchQueryProvider final searchQueryProvider = StateProvider((ref) => ""); //Provider for Trending Books final getTrendingBooks = FutureProvider>((ref) async { OpenLibrary openLibrary = OpenLibrary(); GoodReads goodReads = GoodReads(); PenguinRandomHouse penguinTrending = PenguinRandomHouse(); List trendingBooks = await Future.wait>([ openLibrary.trendingBooks(), goodReads.trendingBooks(), penguinTrending.trendingBooks() ]).then((List> listOfData) => listOfData.expand((element) => element).toList()); trendingBooks.shuffle(); return trendingBooks; }); final enableFiltersState = StateProvider((ref) => true); //Provider for Trending Books final searchProvider = FutureProvider.family .autoDispose, String>((ref, searchQuery) async { AnnasArchieve annasArchieve = AnnasArchieve(); List data = await annasArchieve.searchBooks( searchQuery: searchQuery, content: ref.watch(getTypeValue), sort: ref.watch(getSortValue), fileType: ref.watch(getFileTypeValue), enableFilters: ref.watch(enableFiltersState)); return data; }); final cookieProvider = StateProvider((ref) => ""); final userAgentProvider = StateProvider((ref) => ""); //Provider for Book Info final bookInfoProvider = FutureProvider.family((ref, url) async { AnnasArchieve annasArchieve = AnnasArchieve(); BookInfoData data = await annasArchieve.bookInfo( url: url, userAgent: ref.read(userAgentProvider), cookie: ref.read(cookieProvider)); return data; }); final downloadProgressProvider = StateProvider.autoDispose((ref) => 0.0); final mirrorStatusProvider = StateProvider.autoDispose((ref) => false); final totalFileSizeInBytes = StateProvider.autoDispose((ref) => 0); final downloadedFileSizeInBytes = StateProvider.autoDispose((ref) => 0); String bytesToFileSize(int bytes) { const int decimals = 1; const suffixes = ["b", " Kb", "Mb", "Gb", "Tb"]; if (bytes == 0) return '0${suffixes[0]}'; var i = (log(bytes) / log(1024)).floor(); return ((bytes / pow(1024, i)).toStringAsFixed(decimals)) + suffixes[i]; } final getTotalFileSize = StateProvider.autoDispose((ref) { return bytesToFileSize(ref.watch(totalFileSizeInBytes)); }); final getDownloadedFileSize = StateProvider.autoDispose((ref) { return bytesToFileSize(ref.watch(downloadedFileSizeInBytes)); }); final cancelCurrentDownload = StateProvider((ref) { return ChunkedDownloader(saveFilePath: "", url: ""); }); enum ProcessState { waiting, running, complete } enum CheckSumProcessState { waiting, running, failed, success } final downloadState = StateProvider.autoDispose((ref) => ProcessState.waiting); final checkSumState = StateProvider.autoDispose( (ref) => CheckSumProcessState.waiting); final dbProvider = Provider((ref) => throw UnimplementedError()); final myLibraryProvider = FutureProvider((ref) async { return await ref.read(dbProvider).getAll(); }); final checkIdExists = FutureProvider.family.autoDispose((ref, id) async { return await ref.read(dbProvider).checkIdExists(id); }); class FileName { final String md5; final String format; FileName({required this.md5, required this.format}); } final deleteFileFromMyLib = FutureProvider.family((ref, fileName) async { return await deleteFileWithDbData(ref, fileName.md5, fileName.format); }); final pdfCurrentPage = StateProvider.autoDispose((ref) => 0); final totalPdfPage = StateProvider.autoDispose((ref) => 0); Future savePdfState(String fileName, WidgetRef ref) async { String position = ref.watch(pdfCurrentPage).toString(); await ref.watch(dbProvider).saveBookState(fileName, position); } Future saveEpubState( String fileName, String? position, WidgetRef ref) async { String pos = position ?? ''; await ref.watch(dbProvider).saveBookState(fileName, pos); } final getBookPosition = FutureProvider.family.autoDispose((ref, fileName) async { return await ref.read(dbProvider).getBookState(fileName); }); final openPdfWithExternalAppProvider = StateProvider((ref) => false); final openEpubWithExternalAppProvider = StateProvider((ref) => false); final filePathProvider = FutureProvider.family((ref, fileName) async { String path = await getFilePath(fileName); return path; });