mirror of
https://github.com/dstark5/Openlib.git
synced 2025-09-19 22:31:18 +08:00
Compare commits
6 Commits
v1.0.3-bet
...
v1.0.4-bet
Author | SHA1 | Date | |
---|---|---|---|
74793e5d65 | |||
88c1612184 | |||
2924020eb7 | |||
3bda1a7284 | |||
b0579a5c15 | |||
092f6029b6 |
@ -3,7 +3,7 @@
|
||||
|
||||
#### An Open source app to download and read books from shadow library ([Anna’s Archive](https://annas-archive.org/)).
|
||||
|
||||
[](https://flutter.dev/) [](https://opensource.org/licenses/) 
|
||||
[](https://flutter.dev/) [](https://opensource.org/licenses/) [](https://github.com/dstark5/Openlib/releases)
|
||||
|
||||
[<img src="github_releases.png"
|
||||
alt="Download from GitHub"
|
||||
@ -40,7 +40,7 @@
|
||||
##### As [Anna’s Archive](https://annas-archive.org/) Doesn't Have An API.The App Works By Sending Request To Anna’s Archive And Parses The Response To objects.The App Extracts The Mirrors From Response And Downloads The Book.
|
||||
|
||||
## Features
|
||||
- Trending Books
|
||||
- Trending Books
|
||||
- Download And Read Books With In-Built Viewer
|
||||
- Supports Epub And Pdf Formats
|
||||
- Open Books In Your Favourite Ebook Reader
|
||||
@ -50,7 +50,7 @@
|
||||
|
||||
## Roadmap
|
||||
|
||||
- Additing More Book Format supports (cbz,cbr,azw3,etc...)
|
||||
- Adding More Book Format supports (cbz,cbr,azw3,etc...)
|
||||
- Adding Support For Background Downloads
|
||||
- Adding Support For Multiple Downloads
|
||||
|
||||
|
@ -24,7 +24,6 @@
|
||||
android:label="Openlib"
|
||||
android:name="${applicationName}"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
android:usesCleartextTraffic="true"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:icon="@mipmap/launcher_icon">
|
||||
|
||||
|
32
android/app/src/main/res/raw/annas_archive
Normal file
32
android/app/src/main/res/raw/annas_archive
Normal 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-----
|
17
android/app/src/main/res/xml/network_security_config.xml
Normal file
17
android/app/src/main/res/xml/network_security_config.xml
Normal 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>
|
@ -66,8 +66,7 @@ class AnnasArchieve {
|
||||
List<BookData> _parser(resData, String fileType) {
|
||||
var document =
|
||||
parse(resData.toString().replaceAll(RegExp(r"<!--|-->"), ''));
|
||||
var books = document.querySelectorAll(
|
||||
'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 "]');
|
||||
var books = document.querySelectorAll('a');
|
||||
|
||||
List<BookData> bookList = [];
|
||||
|
||||
@ -154,8 +153,8 @@ class AnnasArchieve {
|
||||
|
||||
var document = parse(response.data.toString());
|
||||
|
||||
var pTag = document.querySelector('p[class="mb-4"]');
|
||||
String? link = pTag?.querySelector('a')?.attributes['href'];
|
||||
var pTag = document.querySelectorAll('p[class="mb-4"]');
|
||||
String? link = pTag[1].querySelector('a')?.attributes['href'];
|
||||
return link;
|
||||
} catch (e) {
|
||||
// print('${url} ${e}');
|
||||
@ -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(
|
||||
{required String searchQuery,
|
||||
String content = "",
|
||||
String sort = "",
|
||||
String fileType = ""}) async {
|
||||
String fileType = "",
|
||||
bool enableFilters = true}) async {
|
||||
try {
|
||||
final String encodedURL = content == ""
|
||||
? '$baseUrl/search?index=&q=$searchQuery&ext=$fileType&sort=$sort'
|
||||
: '$baseUrl/search?index=&q=$searchQuery&content=$content&ext=$fileType&sort=$sort';
|
||||
final String encodedURL = urlEncoder(
|
||||
searchQuery: searchQuery,
|
||||
content: content,
|
||||
sort: sort,
|
||||
fileType: fileType,
|
||||
enableFilters: enableFilters);
|
||||
|
||||
final response = await dio.get(encodedURL,
|
||||
options: Options(headers: defaultDioHeaders));
|
||||
if (!enableFilters) {
|
||||
return _parser(response.data, "");
|
||||
}
|
||||
return _parser(response.data, fileType);
|
||||
} on DioException catch (e) {
|
||||
if (e.type == DioExceptionType.unknown) {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:chunked_downloader/chunked_downloader.dart';
|
||||
import 'files.dart';
|
||||
|
||||
Future<String> _getFilePath(String fileName) async {
|
||||
@ -60,31 +61,21 @@ Future<void> downloadFile(
|
||||
|
||||
if (workingMirror != null) {
|
||||
try {
|
||||
CancelToken cancelToken = CancelToken();
|
||||
|
||||
dio.download(
|
||||
workingMirror,
|
||||
path,
|
||||
options: Options(headers: {
|
||||
'Connection': 'Keep-Alive',
|
||||
'User-Agent':
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'
|
||||
}),
|
||||
onReceiveProgress: (rcv, total) {
|
||||
onProgress(rcv, total);
|
||||
},
|
||||
deleteOnError: true,
|
||||
cancelToken: cancelToken,
|
||||
).catchError((err) {
|
||||
if (err.type != DioExceptionType.cancel) {
|
||||
onDownlaodFailed();
|
||||
}
|
||||
throw err;
|
||||
});
|
||||
var chunkedDownloader = await ChunkedDownloader(
|
||||
url: workingMirror,
|
||||
saveFilePath: path,
|
||||
chunkSize: 32 * 1024,
|
||||
onError: (error) {
|
||||
onDownlaodFailed();
|
||||
},
|
||||
onProgress: (received, total, speed) {
|
||||
onProgress(received, total);
|
||||
},
|
||||
onDone: (file) {})
|
||||
.start();
|
||||
|
||||
mirrorStatus(true);
|
||||
|
||||
cancelDownlaod(cancelToken);
|
||||
cancelDownlaod(chunkedDownloader);
|
||||
} catch (e) {
|
||||
onDownlaodFailed();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import 'dart:math';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.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/annas_archieve.dart';
|
||||
@ -65,9 +65,22 @@ final searchQueryProvider = StateProvider<String>((ref) => "");
|
||||
|
||||
final getTrendingBooks = FutureProvider<List<TrendingBookData>>((ref) async {
|
||||
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
|
||||
final searchProvider = FutureProvider.family
|
||||
.autoDispose<List<BookData>, String>((ref, searchQuery) async {
|
||||
@ -76,7 +89,8 @@ final searchProvider = FutureProvider.family
|
||||
searchQuery: searchQuery,
|
||||
content: ref.watch(getTypeValue),
|
||||
sort: ref.watch(getSortValue),
|
||||
fileType: ref.watch(getFileTypeValue));
|
||||
fileType: ref.watch(getFileTypeValue),
|
||||
enableFilters: ref.watch(enableFiltersState));
|
||||
return data;
|
||||
});
|
||||
|
||||
@ -118,8 +132,8 @@ final getDownloadedFileSize = StateProvider.autoDispose<String>((ref) {
|
||||
return bytesToFileSize(ref.watch(downloadedFileSizeInBytes));
|
||||
});
|
||||
|
||||
final cancelCurrentDownload = StateProvider<CancelToken>((ref) {
|
||||
return CancelToken();
|
||||
final cancelCurrentDownload = StateProvider<ChunkedDownloader>((ref) {
|
||||
return ChunkedDownloader(saveFilePath: "", url: "");
|
||||
});
|
||||
|
||||
final dbProvider = Provider<MyLibraryDb>((ref) => throw UnimplementedError());
|
||||
|
@ -43,7 +43,7 @@ class AboutPage extends StatelessWidget {
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 7, right: 7, top: 5),
|
||||
child: Text(
|
||||
"1.0.3",
|
||||
"1.0.4",
|
||||
style: TextStyle(
|
||||
fontSize: 15,
|
||||
fontWeight: FontWeight.bold,
|
||||
|
@ -1,4 +1,3 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
@ -21,6 +20,9 @@ import 'package:openlib/state/state.dart'
|
||||
dbProvider,
|
||||
checkIdExists,
|
||||
myLibraryProvider;
|
||||
|
||||
import 'package:chunked_downloader/chunked_downloader.dart';
|
||||
|
||||
import 'package:openlib/ui/components/book_info_widget.dart';
|
||||
import 'package:openlib/ui/components/file_buttons_widget.dart';
|
||||
import 'package:openlib/ui/components/snack_bar_widget.dart';
|
||||
@ -141,6 +143,7 @@ class BookInfoPage extends ConsumerWidget {
|
||||
height: 25,
|
||||
child: CircularProgressIndicator(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
strokeCap: StrokeCap.round,
|
||||
),
|
||||
));
|
||||
},
|
||||
@ -203,6 +206,7 @@ class _ActionButtonWidgetState extends ConsumerState<ActionButtonWidget> {
|
||||
loading: () {
|
||||
return CircularProgressIndicator(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
strokeCap: StrokeCap.round,
|
||||
);
|
||||
},
|
||||
);
|
||||
@ -241,7 +245,7 @@ Future<void> downloadFileWidget(
|
||||
showSnackBar(context: context, message: 'Book has been downloaded!');
|
||||
}
|
||||
},
|
||||
cancelDownlaod: (CancelToken downloadToken) {
|
||||
cancelDownlaod: (ChunkedDownloader downloadToken) {
|
||||
ref.read(cancelCurrentDownload.notifier).state = downloadToken;
|
||||
},
|
||||
mirrorStatus: (val) {
|
||||
@ -341,6 +345,7 @@ class _ShowDialog extends ConsumerWidget {
|
||||
color:
|
||||
Theme.of(context).colorScheme.secondary,
|
||||
strokeWidth: 2.5,
|
||||
strokeCap: StrokeCap.round,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
@ -412,7 +417,7 @@ class _ShowDialog extends ConsumerWidget {
|
||||
color: Colors.white,
|
||||
)),
|
||||
onPressed: () {
|
||||
ref.read(cancelCurrentDownload).cancel();
|
||||
ref.read(cancelCurrentDownload).stop();
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: const Padding(
|
||||
|
@ -10,10 +10,7 @@ import 'package:openlib/ui/components/book_card_widget.dart';
|
||||
import 'package:openlib/state/state.dart' show searchProvider;
|
||||
|
||||
class ResultPage extends ConsumerWidget {
|
||||
const ResultPage({
|
||||
super.key,
|
||||
required this.searchQuery,
|
||||
});
|
||||
const ResultPage({super.key, required this.searchQuery});
|
||||
|
||||
final String searchQuery;
|
||||
|
||||
@ -119,6 +116,7 @@ class ResultPage extends ConsumerWidget {
|
||||
height: 25,
|
||||
child: CircularProgressIndicator(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
strokeCap: StrokeCap.round,
|
||||
),
|
||||
))
|
||||
],
|
||||
|
@ -10,7 +10,8 @@ import 'package:openlib/state/state.dart'
|
||||
selectedFileTypeState,
|
||||
typeValues,
|
||||
fileType,
|
||||
sortValues;
|
||||
sortValues,
|
||||
enableFiltersState;
|
||||
import 'components/snack_bar_widget.dart';
|
||||
|
||||
class SearchPage extends ConsumerWidget {
|
||||
@ -18,11 +19,10 @@ class SearchPage extends ConsumerWidget {
|
||||
|
||||
void onSubmit(BuildContext context, WidgetRef ref) {
|
||||
if (ref.read(searchQueryProvider).isNotEmpty) {
|
||||
ref.read(enableFiltersState.notifier).state = true;
|
||||
Navigator.push(context,
|
||||
MaterialPageRoute(builder: (BuildContext context) {
|
||||
return ResultPage(
|
||||
searchQuery: ref.read(searchQueryProvider),
|
||||
);
|
||||
return ResultPage(searchQuery: ref.read(searchQueryProvider));
|
||||
}));
|
||||
} else {
|
||||
showSnackBar(context: context, message: 'Search field is empty');
|
||||
|
@ -6,7 +6,8 @@ import 'extensions.dart';
|
||||
import 'package:openlib/ui/components/page_title_widget.dart';
|
||||
import 'package:openlib/ui/components/error_widget.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 {
|
||||
const TrendingPage({super.key});
|
||||
@ -42,11 +43,11 @@ class TrendingPage extends ConsumerWidget {
|
||||
(BuildContext context, int index) {
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
ref.read(enableFiltersState.notifier).state = false;
|
||||
Navigator.push(context, MaterialPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return ResultPage(
|
||||
searchQuery: data[index].title!,
|
||||
);
|
||||
searchQuery: data[index].title!);
|
||||
}));
|
||||
},
|
||||
child: SizedBox(
|
||||
@ -142,6 +143,7 @@ class TrendingPage extends ConsumerWidget {
|
||||
height: 25,
|
||||
child: CircularProgressIndicator(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
strokeCap: StrokeCap.round,
|
||||
),
|
||||
));
|
||||
});
|
||||
|
20
pubspec.lock
20
pubspec.lock
@ -73,6 +73,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
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:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -141,10 +149,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: dio
|
||||
sha256: ce75a1b40947fea0a0e16ce73337122a86762e38b982e1ccb909daa3b9bc4197
|
||||
sha256: "797e1e341c3dd2f69f2dad42564a6feff3bfb87187d05abb93b9609e6f1645c3"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.3.2"
|
||||
version: "5.4.0"
|
||||
epub_view:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -284,10 +292,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: google_fonts
|
||||
sha256: e20ff62b158b96f392bfc8afe29dee1503c94fbea2cbe8186fd59b756b8ae982
|
||||
sha256: "6b6f10f0ce3c42f6552d1c70d2c28d764cf22bb487f50f66cca31dcd5194f4d6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.1.0"
|
||||
version: "4.0.4"
|
||||
google_nav_bar:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -308,10 +316,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http
|
||||
sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
|
||||
sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "0.13.6"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -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
|
||||
# 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.
|
||||
version: 1.0.3+1
|
||||
version: 1.0.4+7
|
||||
|
||||
environment:
|
||||
sdk: '>=3.0.5 <4.0.0'
|
||||
@ -34,13 +34,13 @@ dependencies:
|
||||
|
||||
google_nav_bar: ^5.0.6
|
||||
|
||||
epub_view: ^3.2.0
|
||||
flutter_pdfview: ^1.2.7
|
||||
vocsy_epub_viewer: ^2.0.0
|
||||
epub_view: ^3.2.0
|
||||
# syncfusion_flutter_pdfviewer: ^22.2.5
|
||||
# pdfx: ^2.4.0
|
||||
|
||||
dio: ^5.3.0
|
||||
dio: ^5.4.0
|
||||
html: ^0.15.4
|
||||
|
||||
sqflite: ^2.3.0
|
||||
@ -51,9 +51,10 @@ dependencies:
|
||||
webview_cookie_manager: ^2.0.6
|
||||
|
||||
flutter_svg: ^2.0.7
|
||||
google_fonts: ^5.1.0
|
||||
google_fonts:
|
||||
|
||||
cached_network_image: ^3.2.3
|
||||
chunked_downloader: ^0.0.2
|
||||
|
||||
sqflite_common_ffi: ^2.3.0+2
|
||||
url_launcher: ^6.1.12
|
||||
|
Reference in New Issue
Block a user