4 Commits

Author SHA1 Message Date
74793e5d65 Merge pull request #54 from inson1/fix-bad-badge-version
Fix bad badge version
2023-12-17 11:16:49 +05:30
88c1612184 Fixed result not found error 2023-12-16 21:45:51 -08:00
2924020eb7 Fix bad badge version 2023-12-17 06:04:22 +01:00
3bda1a7284 Fixed no result found and added new resources for trending books 2023-12-05 05:52:14 -08:00
15 changed files with 242 additions and 61 deletions

View File

@ -3,7 +3,7 @@
#### An Open source app to download and read books from shadow library ([Annas Archive](https://annas-archive.org/)). #### An Open source app to download and read books from shadow library ([Annas Archive](https://annas-archive.org/)).
[![made-with-flutter](https://img.shields.io/badge/Made%20with-Flutter-4361ee.svg)](https://flutter.dev/) [![GPLv3 License](https://img.shields.io/badge/License-GPL%20v3-e63946.svg)](https://opensource.org/licenses/) ![version](https://img.shields.io/badge/version-1.0.2_beta-06d6a0) [![made-with-flutter](https://img.shields.io/badge/Made%20with-Flutter-4361ee.svg)](https://flutter.dev/) [![GPLv3 License](https://img.shields.io/badge/License-GPL%20v3-e63946.svg)](https://opensource.org/licenses/) [![Latest release](https://img.shields.io/github/release/dstark5/Openlib.svg?style=flat)](https://github.com/dstark5/Openlib/releases)
[<img src="github_releases.png" [<img src="github_releases.png"
alt="Download from GitHub" alt="Download from GitHub"

View File

@ -24,7 +24,6 @@
android:label="Openlib" android:label="Openlib"
android:name="${applicationName}" android:name="${applicationName}"
android:requestLegacyExternalStorage="true" android:requestLegacyExternalStorage="true"
android:usesCleartextTraffic="true"
android:networkSecurityConfig="@xml/network_security_config" android:networkSecurityConfig="@xml/network_security_config"
android:icon="@mipmap/launcher_icon"> android:icon="@mipmap/launcher_icon">

View File

@ -0,0 +1,32 @@
-----BEGIN CERTIFICATE-----
MIIFfTCCBGWgAwIBAgIRAI0YQRVveHeTEYLPgc2CDXowDQYJKoZIhvcNAQELBQAw
RjELMAkGA1UEBhMCVVMxIjAgBgNVBAoTGUdvb2dsZSBUcnVzdCBTZXJ2aWNlcyBM
TEMxEzARBgNVBAMTCkdUUyBDQSAxUDUwHhcNMjMxMDMwMjMwOTExWhcNMjQwMTI4
MjMwOTEwWjAcMRowGAYDVQQDExFhbm5hcy1hcmNoaXZlLm9yZzCCASIwDQYJKoZI
hvcNAQEBBQADggEPADCCAQoCggEBAKl79Oj7GW10c1ikBC/sSkyr2tmmIl1/iszu
9DN5w3lbX3q5hLeSB2xPaW6FWPB0u+YR8tgXyk6jG8jkzSe2cdkW0pjKaxSNiQgW
rXipoonUbaceSDd3aFQFGhqe0urkM+84Sgspy39REdxXuQeL2hXH8fouRPA65/pn
2nipwkpZHOezEQfE7BbUYwt4/YQaWXD3ScBLNx0PJuZdL4sfVC41IP8Ml/i5zzU7
mupl6EGgw5IuXwyHN1AC1NHQBU5/8X062/NdVhW/letbsR52Z6DJ727+nWLpdwq4
WgowHui6PthI6h+F4LCu+g3V5akAibsNffqVyWssxaMWFXjMuDECAwEAAaOCAo4w
ggKKMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMB
Af8EAjAAMB0GA1UdDgQWBBSIWJPHr1GutuUbnUApJ/vU3TQP9DAfBgNVHSMEGDAW
gBTV/J4N3x7K3QiXl24rxV/FK/XsuDB4BggrBgEFBQcBAQRsMGowNQYIKwYBBQUH
MAGGKWh0dHA6Ly9vY3NwLnBraS5nb29nL3MvZ3RzMXA1L1VfN25sRDJPX1JRMDEG
CCsGAQUFBzAChiVodHRwOi8vcGtpLmdvb2cvcmVwby9jZXJ0cy9ndHMxcDUuZGVy
MDEGA1UdEQQqMCiCEWFubmFzLWFyY2hpdmUub3JnghMqLmFubmFzLWFyY2hpdmUu
b3JnMCEGA1UdIAQaMBgwCAYGZ4EMAQIBMAwGCisGAQQB1nkCBQMwPAYDVR0fBDUw
MzAxoC+gLYYraHR0cDovL2NybHMucGtpLmdvb2cvZ3RzMXA1L19ZUS1xNlF1bEJB
LmNybDCCAQUGCisGAQQB1nkCBAIEgfYEgfMA8QB2AHb/iD8KtvuVUcJhzPWHujS0
pM27KdxoQgqf5mdMWjp0AAABi4MQGPAAAAQDAEcwRQIhALVAeepoK0WtUPs01yzZ
XjAkdE7WYGw2QNzSkvywFRoIAiAnp1Lec4PqwGPbg/ppC8PgGxb8+yvSlVT0ChUt
NMinWgB3ANq2v2s/tbYin5vCu1xr6HCRcWy7UYSFNL2kPTBI1/urAAABi4MQGP0A
AAQDAEgwRgIhAKbAEYr9qDmiafcnkXIG7xObbI4fz3IsLSht8etA/jSlAiEAkQ7G
t6x81Onpl4RcTtrXLptI0fDkrAZ66hAPWbIH8SAwDQYJKoZIhvcNAQELBQADggEB
AGfvZYtIOPKRvVyfI4tJpetCJmU/DEMbCIyX05M+2P1n2uY1D4tweAMmYf4trh5Z
cuTK3QDeoICus3WK08L3Ni/699QbQ0uonp0IIIOi2NlP2rLhvtETWpmLoX6jM55W
cYGiQldhCgWYEXoANrJshUbjkyM81QMNzSrn33JPkzWUdgVoS/KfABaeymLekXO4
ndLp4ktLlYQZr3JJU39FvwgN8IcmeLWUnpSWsekH+nHSW9e8vOsNQoZyHw0minqz
ZzFbS10reX1kG56+AxDf5fOOM+C+MAozSUnXUjrkpXXakwUooMTklKtYbBiwR2R0
wrcYmVHymn07AUliDOalu2I=
-----END CERTIFICATE-----

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="false">
<trust-anchors>
<certificates src="@raw/annas_archive"/>
<certificates src="system"/>
</trust-anchors>
</base-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">secure.example.com</domain>
<domain includeSubdomains="true">127.0.0.1</domain>
</domain-config>
<domain-config cleartextTrafficPermitted="false">
<domain includeSubdomains="true">annas-archive.org</domain>
</domain-config>
</network-security-config>

View File

@ -66,8 +66,7 @@ class AnnasArchieve {
List<BookData> _parser(resData, String fileType) { List<BookData> _parser(resData, String fileType) {
var document = var document =
parse(resData.toString().replaceAll(RegExp(r"<!--|-->"), '')); parse(resData.toString().replaceAll(RegExp(r"<!--|-->"), ''));
var books = document.querySelectorAll( var books = document.querySelectorAll('a');
'a[class="js-vim-focus custom-a flex items-center relative left-[-10px] w-[calc(100%+20px)] px-[10px] outline-offset-[-2px] outline-2 rounded-[3px] hover:bg-[#00000011] focus:outline "]');
List<BookData> bookList = []; List<BookData> bookList = [];
@ -246,18 +245,39 @@ class AnnasArchieve {
} }
} }
String urlEncoder(
{required String searchQuery,
required String content,
required String sort,
required String fileType,
required bool enableFilters}) {
searchQuery = searchQuery.replaceAll(" ", "+");
if (enableFilters == false) return '$baseUrl/search?q=$searchQuery';
if (content == "" && sort == "" && fileType == "") {
return '$baseUrl/search?q=$searchQuery';
}
return '$baseUrl/search?index=&q=$searchQuery&content=$content&ext=$fileType&sort=$sort';
}
Future<List<BookData>> searchBooks( Future<List<BookData>> searchBooks(
{required String searchQuery, {required String searchQuery,
String content = "", String content = "",
String sort = "", String sort = "",
String fileType = ""}) async { String fileType = "",
bool enableFilters = true}) async {
try { try {
final String encodedURL = content == "" final String encodedURL = urlEncoder(
? '$baseUrl/search?index=&q=$searchQuery&ext=$fileType&sort=$sort' searchQuery: searchQuery,
: '$baseUrl/search?index=&q=$searchQuery&content=$content&ext=$fileType&sort=$sort'; content: content,
sort: sort,
fileType: fileType,
enableFilters: enableFilters);
final response = await dio.get(encodedURL, final response = await dio.get(encodedURL,
options: Options(headers: defaultDioHeaders)); options: Options(headers: defaultDioHeaders));
if (!enableFilters) {
return _parser(response.data, "");
}
return _parser(response.data, fileType); return _parser(response.data, fileType);
} on DioException catch (e) { } on DioException catch (e) {
if (e.type == DioExceptionType.unknown) { if (e.type == DioExceptionType.unknown) {

View File

@ -1,4 +1,5 @@
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:chunked_downloader/chunked_downloader.dart';
import 'files.dart'; import 'files.dart';
Future<String> _getFilePath(String fileName) async { Future<String> _getFilePath(String fileName) async {
@ -60,31 +61,21 @@ Future<void> downloadFile(
if (workingMirror != null) { if (workingMirror != null) {
try { try {
CancelToken cancelToken = CancelToken(); var chunkedDownloader = await ChunkedDownloader(
url: workingMirror,
dio.download( saveFilePath: path,
workingMirror, chunkSize: 32 * 1024,
path, onError: (error) {
options: Options(headers: { onDownlaodFailed();
'Connection': 'Keep-Alive', },
'User-Agent': onProgress: (received, total, speed) {
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36' onProgress(received, total);
}), },
onReceiveProgress: (rcv, total) { onDone: (file) {})
onProgress(rcv, total); .start();
},
deleteOnError: true,
cancelToken: cancelToken,
).catchError((err) {
if (err.type != DioExceptionType.cancel) {
onDownlaodFailed();
}
throw err;
});
mirrorStatus(true); mirrorStatus(true);
cancelDownlaod(chunkedDownloader);
cancelDownlaod(cancelToken);
} catch (e) { } catch (e) {
onDownlaodFailed(); onDownlaodFailed();
} }

View File

@ -52,3 +52,97 @@ class OpenLibrary {
} }
} }
} }
class GoodReads {
String url = "https://www.goodreads.com/shelf/show/trending";
List<TrendingBookData> _parser(data) {
var document = parse(data.toString());
var bookList = document.querySelectorAll('div[class="elementList"]');
List<TrendingBookData> trendingBooks = [];
for (var element in bookList) {
if (element
.querySelector('a[class="leftAlignedImage"]')
?.attributes['title'] !=
null &&
element.querySelector('img')?.attributes['src'] != null) {
String? thumbnail = element.querySelector('img')?.attributes['src'];
trendingBooks.add(
TrendingBookData(
title: element
.querySelector('a[class="leftAlignedImage"]')
?.attributes['title']
.toString()
.trim(),
thumbnail:
thumbnail.toString().replaceAll("._SY75_.", "._SY225_.")),
);
}
}
return trendingBooks;
}
Future<List<TrendingBookData>> trendingBooks() async {
try {
final dio = Dio();
final response = await dio.get(url,
options: Options(
sendTimeout: const Duration(seconds: 20),
receiveTimeout: const Duration(seconds: 20)));
return _parser(response.data.toString());
} on DioException catch (e) {
if (e.type == DioExceptionType.unknown) {
throw "socketException";
}
rethrow;
}
}
}
class PenguinRandomHouse {
String url =
"https://www.penguinrandomhouse.com/ajaxc/categories/books/?from=0&to=50&contentId=&elClass=book&dataType=html&catFilter=best-sellers";
List<TrendingBookData> _parser(data) {
var document = parse(data.toString());
var bookList = document.querySelectorAll('div[class="book"]');
List<TrendingBookData> trendingBooks = [];
for (var element in bookList) {
if (element.querySelector('div[class="title"]')?.text != null &&
element
.querySelector('img[class="responsive_img"]')
?.attributes['src'] !=
null) {
String? thumbnail = element
.querySelector('img[class="responsive_img"]')
?.attributes['src'];
trendingBooks.add(
TrendingBookData(
title: element
.querySelector('div[class="title"]')
?.text
.toString()
.trim(),
thumbnail: thumbnail.toString()),
);
}
}
return trendingBooks;
}
Future<List<TrendingBookData>> trendingBooks() async {
try {
final dio = Dio();
final response = await dio.get(url,
options: Options(
sendTimeout: const Duration(seconds: 20),
receiveTimeout: const Duration(seconds: 20)));
return _parser(response.data.toString());
} on DioException catch (e) {
if (e.type == DioExceptionType.unknown) {
throw "socketException";
}
rethrow;
}
}
}

View File

@ -2,7 +2,7 @@ import 'dart:math';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:openlib/services/database.dart'; import 'package:openlib/services/database.dart';
import 'package:dio/dio.dart'; import 'package:chunked_downloader/chunked_downloader.dart';
import 'package:openlib/services/open_library.dart'; import 'package:openlib/services/open_library.dart';
import 'package:openlib/services/annas_archieve.dart'; import 'package:openlib/services/annas_archieve.dart';
@ -65,9 +65,22 @@ final searchQueryProvider = StateProvider<String>((ref) => "");
final getTrendingBooks = FutureProvider<List<TrendingBookData>>((ref) async { final getTrendingBooks = FutureProvider<List<TrendingBookData>>((ref) async {
OpenLibrary openLibrary = OpenLibrary(); OpenLibrary openLibrary = OpenLibrary();
return await openLibrary.trendingBooks(); GoodReads goodReads = GoodReads();
PenguinRandomHouse penguinTrending = PenguinRandomHouse();
List<TrendingBookData> trendingBooks =
await Future.wait<List<TrendingBookData>>([
openLibrary.trendingBooks(),
goodReads.trendingBooks(),
penguinTrending.trendingBooks()
]).then((List<List<TrendingBookData>> listOfData) =>
listOfData.expand((element) => element).toList());
trendingBooks.shuffle();
return trendingBooks;
}); });
final enableFiltersState = StateProvider<bool>((ref) => true);
//Provider for Trending Books //Provider for Trending Books
final searchProvider = FutureProvider.family final searchProvider = FutureProvider.family
.autoDispose<List<BookData>, String>((ref, searchQuery) async { .autoDispose<List<BookData>, String>((ref, searchQuery) async {
@ -76,7 +89,8 @@ final searchProvider = FutureProvider.family
searchQuery: searchQuery, searchQuery: searchQuery,
content: ref.watch(getTypeValue), content: ref.watch(getTypeValue),
sort: ref.watch(getSortValue), sort: ref.watch(getSortValue),
fileType: ref.watch(getFileTypeValue)); fileType: ref.watch(getFileTypeValue),
enableFilters: ref.watch(enableFiltersState));
return data; return data;
}); });
@ -118,8 +132,8 @@ final getDownloadedFileSize = StateProvider.autoDispose<String>((ref) {
return bytesToFileSize(ref.watch(downloadedFileSizeInBytes)); return bytesToFileSize(ref.watch(downloadedFileSizeInBytes));
}); });
final cancelCurrentDownload = StateProvider<CancelToken>((ref) { final cancelCurrentDownload = StateProvider<ChunkedDownloader>((ref) {
return CancelToken(); return ChunkedDownloader(saveFilePath: "", url: "");
}); });
final dbProvider = Provider<MyLibraryDb>((ref) => throw UnimplementedError()); final dbProvider = Provider<MyLibraryDb>((ref) => throw UnimplementedError());

View File

@ -43,7 +43,7 @@ class AboutPage extends StatelessWidget {
Padding( Padding(
padding: EdgeInsets.only(left: 7, right: 7, top: 5), padding: EdgeInsets.only(left: 7, right: 7, top: 5),
child: Text( child: Text(
"1.0.3", "1.0.4",
style: TextStyle( style: TextStyle(
fontSize: 15, fontSize: 15,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,

View File

@ -1,4 +1,3 @@
import 'package:dio/dio.dart';
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
@ -21,6 +20,9 @@ import 'package:openlib/state/state.dart'
dbProvider, dbProvider,
checkIdExists, checkIdExists,
myLibraryProvider; myLibraryProvider;
import 'package:chunked_downloader/chunked_downloader.dart';
import 'package:openlib/ui/components/book_info_widget.dart'; import 'package:openlib/ui/components/book_info_widget.dart';
import 'package:openlib/ui/components/file_buttons_widget.dart'; import 'package:openlib/ui/components/file_buttons_widget.dart';
import 'package:openlib/ui/components/snack_bar_widget.dart'; import 'package:openlib/ui/components/snack_bar_widget.dart';
@ -141,6 +143,7 @@ class BookInfoPage extends ConsumerWidget {
height: 25, height: 25,
child: CircularProgressIndicator( child: CircularProgressIndicator(
color: Theme.of(context).colorScheme.secondary, color: Theme.of(context).colorScheme.secondary,
strokeCap: StrokeCap.round,
), ),
)); ));
}, },
@ -203,6 +206,7 @@ class _ActionButtonWidgetState extends ConsumerState<ActionButtonWidget> {
loading: () { loading: () {
return CircularProgressIndicator( return CircularProgressIndicator(
color: Theme.of(context).colorScheme.secondary, color: Theme.of(context).colorScheme.secondary,
strokeCap: StrokeCap.round,
); );
}, },
); );
@ -241,7 +245,7 @@ Future<void> downloadFileWidget(
showSnackBar(context: context, message: 'Book has been downloaded!'); showSnackBar(context: context, message: 'Book has been downloaded!');
} }
}, },
cancelDownlaod: (CancelToken downloadToken) { cancelDownlaod: (ChunkedDownloader downloadToken) {
ref.read(cancelCurrentDownload.notifier).state = downloadToken; ref.read(cancelCurrentDownload.notifier).state = downloadToken;
}, },
mirrorStatus: (val) { mirrorStatus: (val) {
@ -341,6 +345,7 @@ class _ShowDialog extends ConsumerWidget {
color: color:
Theme.of(context).colorScheme.secondary, Theme.of(context).colorScheme.secondary,
strokeWidth: 2.5, strokeWidth: 2.5,
strokeCap: StrokeCap.round,
), ),
), ),
const SizedBox( const SizedBox(
@ -412,7 +417,7 @@ class _ShowDialog extends ConsumerWidget {
color: Colors.white, color: Colors.white,
)), )),
onPressed: () { onPressed: () {
ref.read(cancelCurrentDownload).cancel(); ref.read(cancelCurrentDownload).stop();
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
child: const Padding( child: const Padding(

View File

@ -10,10 +10,7 @@ import 'package:openlib/ui/components/book_card_widget.dart';
import 'package:openlib/state/state.dart' show searchProvider; import 'package:openlib/state/state.dart' show searchProvider;
class ResultPage extends ConsumerWidget { class ResultPage extends ConsumerWidget {
const ResultPage({ const ResultPage({super.key, required this.searchQuery});
super.key,
required this.searchQuery,
});
final String searchQuery; final String searchQuery;
@ -119,6 +116,7 @@ class ResultPage extends ConsumerWidget {
height: 25, height: 25,
child: CircularProgressIndicator( child: CircularProgressIndicator(
color: Theme.of(context).colorScheme.secondary, color: Theme.of(context).colorScheme.secondary,
strokeCap: StrokeCap.round,
), ),
)) ))
], ],

View File

@ -10,7 +10,8 @@ import 'package:openlib/state/state.dart'
selectedFileTypeState, selectedFileTypeState,
typeValues, typeValues,
fileType, fileType,
sortValues; sortValues,
enableFiltersState;
import 'components/snack_bar_widget.dart'; import 'components/snack_bar_widget.dart';
class SearchPage extends ConsumerWidget { class SearchPage extends ConsumerWidget {
@ -18,11 +19,10 @@ class SearchPage extends ConsumerWidget {
void onSubmit(BuildContext context, WidgetRef ref) { void onSubmit(BuildContext context, WidgetRef ref) {
if (ref.read(searchQueryProvider).isNotEmpty) { if (ref.read(searchQueryProvider).isNotEmpty) {
ref.read(enableFiltersState.notifier).state = true;
Navigator.push(context, Navigator.push(context,
MaterialPageRoute(builder: (BuildContext context) { MaterialPageRoute(builder: (BuildContext context) {
return ResultPage( return ResultPage(searchQuery: ref.read(searchQueryProvider));
searchQuery: ref.read(searchQueryProvider),
);
})); }));
} else { } else {
showSnackBar(context: context, message: 'Search field is empty'); showSnackBar(context: context, message: 'Search field is empty');

View File

@ -6,7 +6,8 @@ import 'extensions.dart';
import 'package:openlib/ui/components/page_title_widget.dart'; import 'package:openlib/ui/components/page_title_widget.dart';
import 'package:openlib/ui/components/error_widget.dart'; import 'package:openlib/ui/components/error_widget.dart';
import 'package:openlib/ui/results_page.dart'; import 'package:openlib/ui/results_page.dart';
import 'package:openlib/state/state.dart' show getTrendingBooks; import 'package:openlib/state/state.dart'
show getTrendingBooks, enableFiltersState;
class TrendingPage extends ConsumerWidget { class TrendingPage extends ConsumerWidget {
const TrendingPage({super.key}); const TrendingPage({super.key});
@ -42,11 +43,11 @@ class TrendingPage extends ConsumerWidget {
(BuildContext context, int index) { (BuildContext context, int index) {
return InkWell( return InkWell(
onTap: () { onTap: () {
ref.read(enableFiltersState.notifier).state = false;
Navigator.push(context, MaterialPageRoute( Navigator.push(context, MaterialPageRoute(
builder: (BuildContext context) { builder: (BuildContext context) {
return ResultPage( return ResultPage(
searchQuery: data[index].title!, searchQuery: data[index].title!);
);
})); }));
}, },
child: SizedBox( child: SizedBox(
@ -142,6 +143,7 @@ class TrendingPage extends ConsumerWidget {
height: 25, height: 25,
child: CircularProgressIndicator( child: CircularProgressIndicator(
color: Theme.of(context).colorScheme.secondary, color: Theme.of(context).colorScheme.secondary,
strokeCap: StrokeCap.round,
), ),
)); ));
}); });

View File

@ -73,6 +73,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.3" version: "2.0.3"
chunked_downloader:
dependency: "direct main"
description:
name: chunked_downloader
sha256: "7fe3a37a0c7fb1d41f3f922c30937fdccae2647b6f6f71778bffcf4823048754"
url: "https://pub.dev"
source: hosted
version: "0.0.2"
cli_util: cli_util:
dependency: transitive dependency: transitive
description: description:
@ -141,10 +149,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: dio name: dio
sha256: ce75a1b40947fea0a0e16ce73337122a86762e38b982e1ccb909daa3b9bc4197 sha256: "797e1e341c3dd2f69f2dad42564a6feff3bfb87187d05abb93b9609e6f1645c3"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.3.2" version: "5.4.0"
epub_view: epub_view:
dependency: "direct main" dependency: "direct main"
description: description:
@ -284,10 +292,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: google_fonts name: google_fonts
sha256: e20ff62b158b96f392bfc8afe29dee1503c94fbea2cbe8186fd59b756b8ae982 sha256: "6b6f10f0ce3c42f6552d1c70d2c28d764cf22bb487f50f66cca31dcd5194f4d6"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.1.0" version: "4.0.4"
google_nav_bar: google_nav_bar:
dependency: "direct main" dependency: "direct main"
description: description:
@ -308,10 +316,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: http name: http
sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.0" version: "0.13.6"
http_parser: http_parser:
dependency: transitive dependency: transitive
description: description:

View File

@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts # In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix. # of the product and file versions while build-number is used as the build suffix.
version: 1.0.3+5 version: 1.0.4+7
environment: environment:
sdk: '>=3.0.5 <4.0.0' sdk: '>=3.0.5 <4.0.0'
@ -34,13 +34,13 @@ dependencies:
google_nav_bar: ^5.0.6 google_nav_bar: ^5.0.6
epub_view: ^3.2.0
flutter_pdfview: ^1.2.7 flutter_pdfview: ^1.2.7
vocsy_epub_viewer: ^2.0.0 vocsy_epub_viewer: ^2.0.0
epub_view: ^3.2.0
# syncfusion_flutter_pdfviewer: ^22.2.5 # syncfusion_flutter_pdfviewer: ^22.2.5
# pdfx: ^2.4.0 # pdfx: ^2.4.0
dio: ^5.3.0 dio: ^5.4.0
html: ^0.15.4 html: ^0.15.4
sqflite: ^2.3.0 sqflite: ^2.3.0
@ -51,9 +51,10 @@ dependencies:
webview_cookie_manager: ^2.0.6 webview_cookie_manager: ^2.0.6
flutter_svg: ^2.0.7 flutter_svg: ^2.0.7
google_fonts: ^5.1.0 google_fonts:
cached_network_image: ^3.2.3 cached_network_image: ^3.2.3
chunked_downloader: ^0.0.2
sqflite_common_ffi: ^2.3.0+2 sqflite_common_ffi: ^2.3.0+2
url_launcher: ^6.1.12 url_launcher: ^6.1.12