From af09949f341a44b815e2886da73b58c6148f2982 Mon Sep 17 00:00:00 2001 From: Kara-Zor-El Date: Fri, 12 Jan 2024 11:42:21 -0500 Subject: [PATCH 01/28] Add infinate scroll pagination dependency --- pubspec.lock | 100 +++++++++++++++++++++++++++++++-------------------- pubspec.yaml | 1 + 2 files changed, 63 insertions(+), 38 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index c99023a..f5b402e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -21,10 +21,10 @@ packages: dependency: "direct main" description: name: archive - sha256: "7b875fd4a20b165a3084bd2d210439b22ebc653f21cea4842729c0c30c82596b" + sha256: "22600aa1e926be775fa5fe7e6894e7fb3df9efda8891c73f70fb3262399a432d" url: "https://pub.dev" source: hosted - version: "3.4.9" + version: "3.4.10" args: dependency: transitive description: @@ -181,26 +181,26 @@ packages: dependency: "direct main" description: name: cached_network_image - sha256: f98972704692ba679db144261172a8e20feb145636c617af0eb4022132a6797f + sha256: "28ea9690a8207179c319965c13cd8df184d5ee721ae2ce60f398ced1219cea1f" url: "https://pub.dev" source: hosted - version: "3.3.0" + version: "3.3.1" cached_network_image_platform_interface: dependency: transitive description: name: cached_network_image_platform_interface - sha256: "56aa42a7a01e3c9db8456d9f3f999931f1e05535b5a424271e9a38cabf066613" + sha256: "9e90e78ae72caa874a323d78fa6301b3fb8fa7ea76a8f96dc5b5bf79f283bf2f" url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "4.0.0" cached_network_image_web: dependency: transitive description: name: cached_network_image_web - sha256: "759b9a9f8f6ccbb66c185df805fac107f05730b1dab9c64626d1008cca532257" + sha256: "42a835caa27c220d1294311ac409a43361088625a4f23c820b006dd9bffb3316" url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.1.1" characters: dependency: transitive description: @@ -519,10 +519,10 @@ packages: dependency: "direct main" description: name: flutter_markdown - sha256: "35108526a233cc0755664d445f8a6b4b61e6f8fe993b3658b80b4a26827fc196" + sha256: "30088ce826b5b9cfbf9e8bece34c716c8a59fa54461dcae1e4ac01a94639e762" url: "https://pub.dev" source: hosted - version: "0.6.18+2" + version: "0.6.18+3" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -587,6 +587,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.3.3-null-safety+2" + flutter_staggered_grid_view: + dependency: transitive + description: + name: flutter_staggered_grid_view + sha256: "19e7abb550c96fbfeb546b23f3ff356ee7c59a019a651f8f102a4ba9b7349395" + url: "https://pub.dev" + source: hosted + version: "0.7.0" flutter_star: dependency: "direct main" description: @@ -684,18 +692,18 @@ packages: dependency: "direct main" description: name: image_picker - sha256: fc712337719239b0b6e41316aa133350b078fa39b6cbd706b61f3fd421b03c77 + sha256: "340efe08645537d6b088a30620ee5752298b1630f23a829181172610b868262b" url: "https://pub.dev" source: hosted - version: "1.0.5" + version: "1.0.6" image_picker_android: dependency: transitive description: name: image_picker_android - sha256: ecdc963d2aa67af5195e723a40580f802d4392e31457a12a562b3e2bd6a396fe + sha256: "1a27bf4cc0330389cebe465bab08fe6dec97e44015b4899637344bb7297759ec" url: "https://pub.dev" source: hosted - version: "0.8.9+1" + version: "0.8.9+2" image_picker_for_web: dependency: transitive description: @@ -732,10 +740,10 @@ packages: dependency: transitive description: name: image_picker_platform_interface - sha256: ed9b00e63977c93b0d2d2b343685bed9c324534ba5abafbb3dfbd6a780b1b514 + sha256: "0e827c156e3a90edd3bbe7f6de048b39247b16e58173b08a835b7eb00aba239e" url: "https://pub.dev" source: hosted - version: "2.9.1" + version: "2.9.2" image_picker_windows: dependency: transitive description: @@ -744,6 +752,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.1+1" + infinite_scroll_pagination: + dependency: "direct main" + description: + name: infinite_scroll_pagination + sha256: b68bce20752fcf36c7739e60de4175494f74e99e9a69b4dd2fe3a1dd07a7f16a + url: "https://pub.dev" + source: hosted + version: "4.0.0" intl: dependency: "direct main" description: @@ -869,10 +885,10 @@ packages: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: @@ -1127,18 +1143,18 @@ packages: dependency: transitive description: name: platform - sha256: "0a279f0707af40c890e80b1e9df8bb761694c074ba7e1d4ab1bc4b728e200b59" + sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" url: "https://pub.dev" source: hosted - version: "3.1.3" + version: "3.1.4" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface - sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8 + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" url: "https://pub.dev" source: hosted - version: "2.1.7" + version: "2.1.8" pointycastle: dependency: transitive description: @@ -1288,6 +1304,14 @@ packages: description: flutter source: sdk version: "0.0.99" + sliver_tools: + dependency: transitive + description: + name: sliver_tools + sha256: eae28220badfb9d0559207badcbbc9ad5331aac829a88cb0964d330d2a4636a6 + url: "https://pub.dev" + source: hosted + version: "0.2.12" source_gen: dependency: transitive description: @@ -1388,10 +1412,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.7.0" time: dependency: transitive description: @@ -1468,18 +1492,18 @@ packages: dependency: transitive description: name: url_launcher_android - sha256: "31222ffb0063171b526d3e569079cf1f8b294075ba323443fdc690842bfd4def" + sha256: c0766a55ab42cefaa728cabc951e82919ab41a3a4fee0aaa96176ca82da8cc51 url: "https://pub.dev" source: hosted - version: "6.2.0" + version: "6.2.1" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: bba3373219b7abb6b5e0d071b0fe66dfbe005d07517a68e38d4fc3638f35c6d3 + sha256: "46b81e3109cbb2d6b81702ad3077540789a3e74e22795eb9f0b7d494dbaa72ea" url: "https://pub.dev" source: hosted - version: "6.2.1" + version: "6.2.2" url_launcher_linux: dependency: transitive description: @@ -1500,18 +1524,18 @@ packages: dependency: transitive description: name: url_launcher_platform_interface - sha256: "980e8d9af422f477be6948bdfb68df8433be71f5743a188968b0c1b887807e50" + sha256: "4aca1e060978e19b2998ee28503f40b5ba6226819c2b5e3e4d1821e8ccd92198" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.3.0" url_launcher_web: dependency: transitive description: name: url_launcher_web - sha256: "7286aec002c8feecc338cc33269e96b73955ab227456e9fb2a91f7fab8a358e9" + sha256: fff0932192afeedf63cdd50ecbb1bc825d31aed259f02bb8dba0f3b729a5e88b url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.2.3" url_launcher_windows: dependency: transitive description: @@ -1556,18 +1580,18 @@ packages: dependency: transitive description: name: web_socket_channel - sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b + sha256: cc1f6c632a248278a091fd7d9a68f624906830f7c1c5aa66503fae0804633e1c url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.4.2" win32: dependency: transitive description: name: win32 - sha256: b0f37db61ba2f2e9b7a78a1caece0052564d1bc70668156cf3a29d676fe4e574 + sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8" url: "https://pub.dev" source: hosted - version: "5.1.1" + version: "5.2.0" win32_registry: dependency: transitive description: @@ -1580,10 +1604,10 @@ packages: 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: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index b1f9051..69add88 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -89,6 +89,7 @@ dependencies: flutter_html: ^3.0.0-beta.2 flutter_markdown: ^0.6.15 image_picker: ^1.0.4 + infinite_scroll_pagination: ^4.0.0 dev_dependencies: # flutter_test: From 038ac2b98c9572794244ac96c2526108ceb47569 Mon Sep 17 00:00:00 2001 From: Kara-Zor-El Date: Fri, 12 Jan 2024 11:44:14 -0500 Subject: [PATCH 02/28] Specify url field is for keyboard type url --- lib/screens/loginScreen.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/screens/loginScreen.dart b/lib/screens/loginScreen.dart index ac4acae..8fd0631 100644 --- a/lib/screens/loginScreen.dart +++ b/lib/screens/loginScreen.dart @@ -119,6 +119,7 @@ class _LoginScreenState extends State { key: const Key('urlField'), controller: _url, focusNode: _focusNode1, + keyboardType: TextInputType.url, decoration: InputDecoration( labelText: AppLocalizations.of(context)?.pageLoginAddress ?? "Your Address", From e07e64384bca6f06e27f618930af860506f8c652 Mon Sep 17 00:00:00 2001 From: Kara-Zor-El Date: Fri, 12 Jan 2024 11:46:06 -0500 Subject: [PATCH 03/28] Fix infoscreen button color --- lib/screens/infoScreen.dart | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/screens/infoScreen.dart b/lib/screens/infoScreen.dart index 72db5be..c19d821 100644 --- a/lib/screens/infoScreen.dart +++ b/lib/screens/infoScreen.dart @@ -442,9 +442,7 @@ class _InfoScreenState extends State { child: !entry.downloaded ? Icon( Icons.download_for_offline_outlined, - color: !offline - ? Theme.of(context).iconTheme.color - : Colors.white, + color: !offline ? Colors.grey[200] : Colors.white, ) : const Icon( Icons.download_done, From c35ad00f0ce10f7fc03de67386681e6e9907efbc Mon Sep 17 00:00:00 2001 From: Kara-Zor-El Date: Fri, 12 Jan 2024 12:13:35 -0500 Subject: [PATCH 04/28] Use pdfx_plugin --- lib/screens/readingScreens/pdfReader.dart | 2 +- pubspec.lock | 13 ++++++------- pubspec.yaml | 7 +------ 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/lib/screens/readingScreens/pdfReader.dart b/lib/screens/readingScreens/pdfReader.dart index 30996eb..c7f554e 100644 --- a/lib/screens/readingScreens/pdfReader.dart +++ b/lib/screens/readingScreens/pdfReader.dart @@ -9,7 +9,7 @@ import 'package:permission_handler/permission_handler.dart'; import 'package:isar/isar.dart'; import 'package:isar_flutter_libs/isar_flutter_libs.dart'; import 'package:jellybook/models/entry.dart'; -import 'package:pdfx/pdfx.dart'; +import 'package:pdfx_plugin/pdfx_plugin.dart'; import 'package:jellybook/providers/progress.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:jellybook/variables.dart'; diff --git a/pubspec.lock b/pubspec.lock index f5b402e..751429f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1058,15 +1058,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.1" - pdfx: + pdfx_plugin: dependency: "direct main" description: - path: "packages/pdfx" - ref: "4be9de9ffed5398fd7d5f44bbb07dcd3d3f1711b" - resolved-ref: "4be9de9ffed5398fd7d5f44bbb07dcd3d3f1711b" - url: "https://github.com/ScerIO/packages.flutter" - source: git - version: "2.5.0" + name: pdfx_plugin + sha256: "174ff8f2d0208c6a7efd6bbca0f8ceefbc3c8af47c64c3e6aad71da16ad3deff" + url: "https://pub.dev" + source: hosted + version: "1.1.0" pedantic: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 69add88..fb935ff 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -59,12 +59,7 @@ dependencies: flutter_html_to_pdf: ^0.7.0 isar: ^3.0.5 isar_flutter_libs: ^3.0.5 - pdfx: - git: - url: 'https://github.com/ScerIO/packages.flutter' - ref: '4be9de9ffed5398fd7d5f44bbb07dcd3d3f1711b' - path: packages/pdfx - + pdfx_plugin: ^1.1.0 package_info_plus: ^5.0.1 auto_size_text: ^3.0.0 google_nav_bar: ^5.0.6 From 8c0bcbdfc3f62d68daa79667f20fc31346357de4 Mon Sep 17 00:00:00 2001 From: Kara-Zor-El Date: Fri, 12 Jan 2024 13:04:23 -0500 Subject: [PATCH 05/28] Little fixes --- lib/providers/fetchBooks.dart | 7 +------ lib/providers/fetchCategories.dart | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/lib/providers/fetchBooks.dart b/lib/providers/fetchBooks.dart index 2b5b455..c0c9c76 100644 --- a/lib/providers/fetchBooks.dart +++ b/lib/providers/fetchBooks.dart @@ -12,7 +12,7 @@ import 'package:isar/isar.dart'; import 'package:jellybook/variables.dart'; // get comics -Future> getComics(String comicsId) async { +Future getComics(String comicsId) async { logger.d('getting comics'); final prefs = await SharedPreferences.getInstance(); final token = prefs.getString('accessToken'); @@ -149,11 +149,6 @@ Future> getComics(String comicsId) async { // update folders await updateFolders(); - - final List entrys = - await isar.entrys.filter().not().typeEqualTo(EntryType.folder).findAll(); - - return entrys; } Future updateFolders() async { diff --git a/lib/providers/fetchCategories.dart b/lib/providers/fetchCategories.dart index 944e70d..7025a49 100644 --- a/lib/providers/fetchCategories.dart +++ b/lib/providers/fetchCategories.dart @@ -63,7 +63,7 @@ Future<(List, List)> getServerCategories({ } logger.d("got response"); - logger.d(response.statusCode.toString()); + logger.d(response?.statusCode.toString()); final data = response.data.items .where((element) => element.collectionType == 'books') .toList(); From e373fd3bd69a2fad7a9f2d2856271f2a8ee9c449 Mon Sep 17 00:00:00 2001 From: Kara-Zor-El Date: Fri, 12 Jan 2024 13:04:39 -0500 Subject: [PATCH 06/28] start infinate scroll pagination --- lib/screens/MainScreens/mainMenu.dart | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/screens/MainScreens/mainMenu.dart b/lib/screens/MainScreens/mainMenu.dart index 4318548..b77d954 100644 --- a/lib/screens/MainScreens/mainMenu.dart +++ b/lib/screens/MainScreens/mainMenu.dart @@ -16,6 +16,7 @@ import 'package:fancy_shimmer_image/fancy_shimmer_image.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:jellybook/variables.dart'; import 'package:jellybook/widgets/roundedImageWithShadow.dart'; +import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; class MainMenu extends StatefulWidget { @override @@ -38,6 +39,9 @@ class _MainMenuState extends State { - a search section - a settings section */ + static const _pageSize = 20; + final PagingController _pagingController = + PagingController(firstPageKey: 0); Future logout() async { final isar = Isar.getInstance(); List logins = await isar!.logins.where().findAll(); @@ -66,6 +70,10 @@ class _MainMenuState extends State { @override void initState() { + _pagingController.addPageRequestListener((pageKey) { + logger.i('pageKey: $pageKey'); + // fetchEntries(pageKey); + }); super.initState(); // fetchCategories(); } From a303ec3ac647e67f1d86da9975c219b541378349 Mon Sep 17 00:00:00 2001 From: Kara-Zor-El Date: Fri, 12 Jan 2024 13:04:51 -0500 Subject: [PATCH 07/28] Update Log File location --- lib/variables.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/variables.dart b/lib/variables.dart index 6a8a428..4e87903 100644 --- a/lib/variables.dart +++ b/lib/variables.dart @@ -17,10 +17,10 @@ Logger logger = Logger( output: kDebugMode ? ConsoleOutput() : FileOutput( - file: File(logStoragePath + "jellybook.log"), - overrideExisting: true, + file: File(localPath + "jellybook.log"), + overrideExisting: false, encoding: utf8, - sink: IOSink(File(logStoragePath + "jellybook.log") + sink: IOSink(File(localPath + "jellybook.log") .openWrite(mode: FileMode.writeOnlyAppend, encoding: utf8)), ), level: Level.debug, From 8b6a1e1df8315ed19a53e6ca4ced8b3ea5ffc75b Mon Sep 17 00:00:00 2001 From: Kara-Zor-El Date: Fri, 12 Jan 2024 13:05:18 -0500 Subject: [PATCH 08/28] Update jellybook_epub_view --- submodules/jellybook_epub_view | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/jellybook_epub_view b/submodules/jellybook_epub_view index 51132be..e7eac4b 160000 --- a/submodules/jellybook_epub_view +++ b/submodules/jellybook_epub_view @@ -1 +1 @@ -Subproject commit 51132be9e19cc091152480278c8139087cec2e58 +Subproject commit e7eac4b6ad357c498ff7b204891db33b7935b22c From 80be629b5d60d7f815bacbb9cbdb34cad7635282 Mon Sep 17 00:00:00 2001 From: Kara-Zor-El Date: Fri, 12 Jan 2024 13:07:00 -0500 Subject: [PATCH 09/28] Add seamless vertical scrolling --- lib/screens/readingScreens/cbrCbzReader.dart | 57 ++++++++++++-------- lib/screens/readingScreens/pdfReader.dart | 13 +++++ 2 files changed, 47 insertions(+), 23 deletions(-) diff --git a/lib/screens/readingScreens/cbrCbzReader.dart b/lib/screens/readingScreens/cbrCbzReader.dart index 6e2dd08..05ec0e7 100644 --- a/lib/screens/readingScreens/cbrCbzReader.dart +++ b/lib/screens/readingScreens/cbrCbzReader.dart @@ -338,30 +338,41 @@ class _CbrCbzReaderState extends State { return Column( children: [ Expanded( - child: PageView.builder( - scrollDirection: - direction.toLowerCase() == 'vertical' - ? Axis.vertical - : Axis.horizontal, - reverse: direction == 'rtl', - // scrollDirection: Axis.vertical, - itemCount: pages.length, - controller: PageController( - initialPage: pageNum, - ), - itemBuilder: (context, index) { - return InteractiveViewer( - child: Image.file( - File(pages[index]), - fit: BoxFit.contain, + child: direction.toLowerCase() == 'vertical' + ? InteractiveViewer( + child: SingleChildScrollView( + child: Column( + children: [ + for (var page in pages) + Image.file( + File(page), + fit: BoxFit.fitHeight, + ), + ], + ), + ), + ) + : PageView.builder( + scrollDirection: Axis.horizontal, + reverse: direction == 'rtl', + // scrollDirection: Axis.vertical, + itemCount: pages.length, + controller: PageController( + initialPage: pageNum, + ), + itemBuilder: (context, index) { + return InteractiveViewer( + child: Image.file( + File(pages[index]), + fit: BoxFit.contain, + ), + ); + }, + onPageChanged: (index) { + saveProgress(index); + progress = index / pageNums; + }, ), - ); - }, - onPageChanged: (index) { - saveProgress(index); - progress = index / pageNums; - }, - ), ), ], ); diff --git a/lib/screens/readingScreens/pdfReader.dart b/lib/screens/readingScreens/pdfReader.dart index 30996eb..6dc2286 100644 --- a/lib/screens/readingScreens/pdfReader.dart +++ b/lib/screens/readingScreens/pdfReader.dart @@ -17,6 +17,7 @@ import 'package:audioplayers/audioplayers.dart'; import 'package:jellybook/screens/AudioPicker.dart'; import 'package:flutter_background_service/flutter_background_service.dart'; import 'package:jellybook/widgets/AudioPlayerWidget.dart'; +import 'package:shared_preferences/shared_preferences.dart'; class PdfReader extends StatefulWidget { final String comicId; @@ -56,12 +57,19 @@ class _PdfReaderState extends State { // pages int _totalPages = 0; late PdfController pdfController; + late String direction; _PdfReaderState({ required this.comicId, required this.title, }); + void setDirection() async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + direction = prefs.getString('readingDirection') ?? 'ltr'; + logger.f("direction: $direction"); + } + // first, we want to see if the user has given us permission to access their files // if they have, we want to check if the comic has been downloaded // if it has, we want to get the file extension to determine how to read it @@ -69,6 +77,7 @@ class _PdfReaderState extends State { @override void initState() { super.initState(); + setDirection(); } @override @@ -135,6 +144,10 @@ class _PdfReaderState extends State { body: Center( child: Container( child: PdfView( + scrollDirection: direction.toLowerCase() == 'vertical' + ? Axis.vertical + : Axis.horizontal, + reverse: direction.toLowerCase() == 'rtl' ? true : false, controller: pdfController, onPageChanged: (page) { saveProgress(page: page, comicId: comicId); From 2513514ee51530f352227c428c96e342911dea80 Mon Sep 17 00:00:00 2001 From: Kara-Zor-El Date: Mon, 15 Jan 2024 19:47:33 -0500 Subject: [PATCH 10/28] Remove legacy build script --- build-android.sh | 47 -------------------- build.sh | 110 ----------------------------------------------- 2 files changed, 157 deletions(-) delete mode 100755 build-android.sh delete mode 100755 build.sh diff --git a/build-android.sh b/build-android.sh deleted file mode 100755 index 4dec675..0000000 --- a/build-android.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env bash - -# Check if file exists -if [ -f "sha1sums.txt" ]; then - rm sha1sums.txt -fi -touch sha1sums.txt - -# Build debug version -flutter build apk --debug -flutter build apk --debug --split-per-abi - -# Get the SHA1 Checksums of the APKs and save them to a file with the following format: -# filename: checksum -declare -a fileName=( $(find build/app/outputs/flutter-apk -type f -name "*.apk") ) -declare -a fileChecksum - -# Build debug AAB version -flutter build appbundle --debug -fileName=$(find build/app/outputs/bundle/debug/ -type f -name "*.aab") -fileChecksum=$(sha1sum "$fileName" | awk '{print $1}') -fileName=${fileName##*/} -fileName=${fileName/app-/JellyBook-} -echo "$fileName: $fileChecksum" | tee -a sha1sums.txt - -# Build release version -flutter build apk --release -flutter build apk --release --split-per-abi - -declare -a fileName=( $(find build/app/outputs/flutter-apk/ -type f -name "*.apk") ) -declare -a fileChecksum - -for file in "${fileName[@]}"; do - checksum=$(sha1sum "$file" | awk '{print $1}') - fileChecksum+=("$checksum") - file=${file##*/} - file=${file/app-/JellyBook-} - echo "$file: $checksum" | tee -a sha1sums.txt -done - -# Build release AAB version -flutter build appbundle --release -fileName=$(find build/app/outputs/bundle/release/ -type f -name "*.aab") -fileChecksum=$(sha1sum "$fileName" | awk '{print $1}') -fileName=${fileName##*/} -fileName=${fileName/app-/JellyBook-} -echo "$fileName: $fileChecksum" | tee -a sha1sums.txt diff --git a/build.sh b/build.sh deleted file mode 100755 index aa40cbd..0000000 --- a/build.sh +++ /dev/null @@ -1,110 +0,0 @@ -#!/usr/bin/env bash -# Function to display a green checkmark -print_checkmark() { - tput setaf 2 # Set text color to green - echo -e "\xE2\x9C\x94" # Green checkmark Unicode character - tput sgr0 # Reset text color -} - -# Function to display a progress bar -print_progress_bar() { - local progress=$1 - local length=50 - local fill="" - local empty="" - local i - - for ((i = 0; i < length * progress / 100; i++)); do fill+="█"; done - for ((i = 0; i < length - i; i++)); do empty+=" "; done - - echo -ne "[$fill$empty] $progress%\r" -} - -# Get file version -version=$(yq eval '.version' pubspec.yaml) - -# Make directory -mkdir -p $version - -# Build iOS -# release -echo "Building iOS release IPA..." -flutter build ipa --release >/dev/null 2>&1 -print_checkmark -# Add to the folder -cp build/ios/ipa/jellybook.ipa $version/JellyBook-Release.ipa -# print on the same line -echo -ne "\rComplete release IPA\n" - -# debug -echo "Building iOS debug IPA..." -flutter build ipa --debug -print_checkmark -# Add to the folder -cp build/ios/ipa/jellybook.ipa $version/JellyBook-Debug.ipa -echo "Complete debug IPA" - -# Build Android -## Apk -# release -echo "Building Android release APK..." -flutter build apk --release -print_checkmark -# Add to the folder -cp build/app/outputs/flutter-apk/app-release.apk $version/JellyBook-Release.apk - -echo "Complete release APK" - -# Split apk by abi -echo "Building Android release APK (split by ABI)..." -flutter build apk --split-per-abi --release -cp build/app/outputs/flutter-apk/app-armeabi-v7a-release.apk $version/JellyBook-Release-arm32.apk -cp build/app/outputs/flutter-apk/app-arm64-v8a-release.apk $version/JellyBook-Release-arm64.apk -cp build/app/outputs/flutter-apk/app-x86_64-release.apk $version/JellyBook-Release-x86_64.apk -print_checkmark -echo "Complete release APK (split by ABI)" - -# debug -echo "Building Android debug APK..." -flutter build apk --debug -print_checkmark -cp build/app/outputs/flutter-apk/app-debug.apk $version/JellyBook-Debug.apk -echo "Complete debug APK" - -# Split apk by abi -echo "Building Android debug APK (split by ABI)..." -flutter build apk --split-per-abi --debug -print_checkmark -cp build/app/outputs/flutter-apk/app-armeabi-v7a-debug.apk $version/JellyBook-Debug-arm32.apk -cp build/app/outputs/flutter-apk/app-arm64-v8a-debug.apk $version/JellyBook-Debug-arm64.apk -cp build/app/outputs/flutter-apk/app-x86_64-debug.apk $version/JellyBook-Debug-x86_64.apk -echo "Complete debug APK (split by ABI)" - -# Build appbundle -# release -echo "Building Android release App Bundle..." -flutter build appbundle --release -print_checkmark -cp build/app/outputs/bundle/release/app-release.aab $version/JellyBook-Release.aab -echo "Complete release App Bundle" - -# debug -echo "Building Android debug App Bundle..." -flutter build appbundle --debug -print_checkmark -cp build/app/outputs/bundle/debug/app-debug.aab $version/JellyBook-Debug.aab -echo "Complete debug App Bundle" - -# Print a list of their sha1 hashes -echo " -
-SHA1 -
    " -for file in "$version"/*; do - hash=$(sha1sum "$file" | awk '{print $1}') - file=$(basename "$file") - echo "
  • $file: $hash
  • " -done -echo "
-
-" From 1c0975461336ab43edd7721e1b297c23fc18d864 Mon Sep 17 00:00:00 2001 From: Kara-Zor-El Date: Thu, 25 Jan 2024 14:20:56 -0500 Subject: [PATCH 11/28] Update .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index b330fd6..c6c777a 100644 --- a/.gitignore +++ b/.gitignore @@ -57,3 +57,5 @@ flutter_jank_metrics_01.json Jellyfin/ linux/flutter/generated_plugin_registrant.cc linux/flutter/generated_plugins.cmake +linux/flutter/generated_plugin_registrant.cc +linux/flutter/generated_plugins.cmake From 9645949bc41be891c55f39d6784882a3afd94bf0 Mon Sep 17 00:00:00 2001 From: Kara-Zor-El Date: Fri, 9 Feb 2024 12:32:09 -0500 Subject: [PATCH 12/28] Begin work for using infinate page scrolling --- lib/providers/fetchCategories.dart | 21 ++ lib/screens/MainScreens/mainMenu.dart | 310 ++++++++++++-------------- 2 files changed, 166 insertions(+), 165 deletions(-) diff --git a/lib/providers/fetchCategories.dart b/lib/providers/fetchCategories.dart index 7025a49..f316d0a 100644 --- a/lib/providers/fetchCategories.dart +++ b/lib/providers/fetchCategories.dart @@ -132,10 +132,31 @@ Future<(List, List)> getServerCategories({ // logger.d("${comics[i].title} : ${comics[i].isarId}"); // } + // first 50 comics + comics = comics.take(50).toList(); + return (comics, folders); } } +Future<(int, List)> fetchEntries(int offset, int limit) async { + final isar = Isar.getInstance(); + // group the favorites and list them first + QueryBuilder typeNotBook = + isar!.entrys.filter().not().typeEqualTo(EntryType.folder); + List entries = + await typeNotBook.and().isFavoritedEqualTo(true).sortByTitle().findAll(); + entries.addAll(await typeNotBook + .and() + .isFavoritedEqualTo(false) + .sortByTitle() + .findAll()); + entries = entries.skip(offset).take(limit).toList(); + int length = entries.length; + logger.f("entries: " + entries.length.toString()); + return (length, entries); +} + // check to see if a folder isn't a subfolder of another folder Future>> compareFolders( List> folders, diff --git a/lib/screens/MainScreens/mainMenu.dart b/lib/screens/MainScreens/mainMenu.dart index b77d954..e12335c 100644 --- a/lib/screens/MainScreens/mainMenu.dart +++ b/lib/screens/MainScreens/mainMenu.dart @@ -66,13 +66,23 @@ class _MainMenuState extends State { bool force = false; - int _selectedIndex = 0; - @override void initState() { - _pagingController.addPageRequestListener((pageKey) { + _pagingController.addPageRequestListener((pageKey) async { logger.i('pageKey: $pageKey'); - // fetchEntries(pageKey); + try { + final pageSize = 20; // Define your page size + final result = await fetchEntries(pageKey, pageSize); + final isLastPage = result.$1 < pageSize; + if (isLastPage) { + _pagingController.appendLastPage(result.$2); + } else { + final nextPageKey = pageKey + result.$1; + _pagingController.appendPage(result.$2, nextPageKey); + } + } catch (error) { + _pagingController.error = error; + } }); super.initState(); // fetchCategories(); @@ -301,170 +311,23 @@ class _MainMenuState extends State { const SizedBox( height: 10, ), - GridView.count( - crossAxisCount: 2, - physics: const NeverScrollableScrollPhysics(), + PagedGridView( shrinkWrap: true, - addAutomaticKeepAlives: true, - addSemanticIndexes: true, + physics: const NeverScrollableScrollPhysics(), + pagingController: _pagingController, addRepaintBoundaries: true, - // cacheExtent: 30, - children: List.generate( - snapshot.data.$1.length, - (index) { - return StatefulBuilder( - builder: (context, setState) { - return Card( - borderOnForeground: true, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), - ), - child: InkWell( - onTap: () async { - logger.i("tapped"); - // logger.i(snapshot.data.$1.elementAt(index)); - int selectedIndex = - index; // Store the index of the selected entry - Entry selectedEntry = snapshot.data.$1 - .elementAt(selectedIndex); - - Entry? updatedEntry = await Navigator.push( - context, - MaterialPageRoute( - builder: (context) => - InfoScreen(entry: selectedEntry), - ), - ); - // update state of the card - if (updatedEntry != null) { - // Update the state of the card - setState(() { - // Check if snapshot.data.$1 is a list that can be modified - if (snapshot.data.$1 is List) { - snapshot.data.$1[selectedIndex] = - updatedEntry; - } else { - // If the list is immutable, create a new list with the updated entry - var newList = List.from( - snapshot.data.$1); - newList[selectedIndex] = updatedEntry; - // Update the data source - snapshot.data.$1 = newList; - } - }); - } - }, - child: Column( - children: [ - const SizedBox( - height: 10, - ), - Stack( - children: [ - SizedBox( - // height should be 80% of the card - height: MediaQuery.of(context) - .size - .height / - 6 * - 0.8, - child: RoundedImageWithShadow( - imageUrl: snapshot.data.$1 - .elementAt(index) - .imagePath ?? - 'Asset', - ), - ), - if (snapshot.data.$1 - .elementAt(index) - .isFavorited == - true) - // icon in circle in bottom $2 corner - // allow it to be off the image without being cut off - Positioned( - bottom: 0, - right: 0, - child: Container( - decoration: BoxDecoration( - color: Theme.of(context) - .primaryColor - .withOpacity(0.8), - borderRadius: - BorderRadius.circular( - 100), - ), - child: const Padding( - padding: EdgeInsets.all(5), - child: Icon( - Icons.favorite, - color: Colors.red, - ), - ), - ), - ), - ], - ), - const SizedBox( - height: 10, - ), - // auto size text to fit the width of the card (max 2 lines) - - Expanded( - flex: 3, - // give some padding to the text - child: Padding( - padding: const EdgeInsets.only( - left: 5, right: 5), - child: AutoSizeText( - snapshot.data.$1?[index].title ?? - "null", - maxLines: 3, - minFontSize: 10, - textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - ), - ), - ), - ), - const SizedBox( - height: 5, - ), - - if (snapshot.data.$1 - .elementAt(index) - .releaseDate != - "null") - Flexible( - // give some padding to the text - child: Padding( - padding: const EdgeInsets.only( - left: 5, right: 5), - child: AutoSizeText( - snapshot.data.$1 - .elementAt(index) - .releaseDate, - maxLines: 1, - minFontSize: 10, - textAlign: TextAlign.center, - style: const TextStyle( - fontSize: 13, - fontStyle: FontStyle.italic, - color: Colors.grey, - ), - ), - ), - ), - ], - ), - ), - ); - }, - ); - }, - // itemCount: snapshot.data.$1!.length, + addSemanticIndexes: true, + addAutomaticKeepAlives: true, + // shrinkWrap: true, + gridDelegate: + const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + childAspectRatio: 1, ), + builderDelegate: PagedChildBuilderDelegate( + itemBuilder: (context, entry, index) => SizedBox( + child: GridEntryWidget(entry), + )), ), ]; return Column( @@ -542,3 +405,120 @@ class _MainMenuState extends State { ); } } + +class GridEntryWidget extends StatefulWidget { + final Entry entry; + + const GridEntryWidget(this.entry) : super(key: key); + + // createState function + @override + GridEntryWidgetState createState() => GridEntryWidgetState(); +} + +class GridEntryWidgetState extends State { + @override + Widget build(BuildContext context) { + return Card( + borderOnForeground: true, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + child: InkWell( + onTap: () async { + logger.i("tapped"); + // logger.i(snapshot.data.$1.elementAt(index)); + Entry? updatedEntry = await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => InfoScreen(entry: widget.entry), + ), + ); + setState(() { + widget.entry.isFavorited = + updatedEntry?.isFavorited ?? widget.entry.isFavorited; + }); + }, + child: Column( + children: [ + const SizedBox( + height: 10, + ), + Stack( + children: [ + SizedBox( + // height should be 80% of the card + height: MediaQuery.of(context).size.height / 6 * 0.8, + child: RoundedImageWithShadow( + imageUrl: widget.entry.imagePath ?? 'Asset', + ), + ), + if (widget.entry.isFavorited == true) + // icon in circle in bottom $2 corner + // allow it to be off the image without being cut off + Positioned( + bottom: 0, + right: 0, + child: Container( + decoration: BoxDecoration( + color: Theme.of(context).primaryColor.withOpacity(0.8), + borderRadius: BorderRadius.circular(100), + ), + child: const Padding( + padding: EdgeInsets.all(5), + child: Icon( + Icons.favorite, + color: Colors.red, + ), + ), + ), + ), + ], + ), + const SizedBox( + height: 10, + ), + // auto size text to fit the width of the card (max 2 lines) + + Expanded( + flex: 3, + // give some padding to the text + child: Padding( + padding: const EdgeInsets.only(left: 5, right: 5), + child: AutoSizeText( + widget.entry.title, + maxLines: 3, + minFontSize: 10, + textAlign: TextAlign.center, + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + + if (widget.entry.releaseDate != "null") + Flexible( + // give some padding to the text + child: Padding( + padding: const EdgeInsets.only(left: 5, right: 5), + child: AutoSizeText( + widget.entry.releaseDate, + maxLines: 1, + minFontSize: 10, + textAlign: TextAlign.center, + style: const TextStyle( + fontSize: 13, + fontStyle: FontStyle.italic, + color: Colors.grey, + ), + ), + ), + ), + ], + ), + ), + ); + } +} From a8dc2f9262ce659e1f8b4c6c13866f8360f623b0 Mon Sep 17 00:00:00 2001 From: Kara-Zor-El Date: Fri, 9 Feb 2024 12:32:19 -0500 Subject: [PATCH 13/28] Update prettyPrinter --- lib/variables.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/variables.dart b/lib/variables.dart index 4e87903..62b8bb7 100644 --- a/lib/variables.dart +++ b/lib/variables.dart @@ -25,7 +25,7 @@ Logger logger = Logger( ), level: Level.debug, printer: kDebugMode - ? PrettyPrinter() + ? PrettyPrinter(printTime: true, printEmojis: true, colors: true) : PrettyPrinter( methodCount: 5, errorMethodCount: 8, From b104acdcacb831edfb6bcbed44523abcc1425f0c Mon Sep 17 00:00:00 2001 From: Kara-Zor-El Date: Sun, 11 Feb 2024 15:00:56 -0500 Subject: [PATCH 14/28] Second stage of lazy loading --- lib/screens/MainScreens/mainMenu.dart | 376 ++++++++++++-------------- 1 file changed, 167 insertions(+), 209 deletions(-) diff --git a/lib/screens/MainScreens/mainMenu.dart b/lib/screens/MainScreens/mainMenu.dart index e12335c..6197cfb 100644 --- a/lib/screens/MainScreens/mainMenu.dart +++ b/lib/screens/MainScreens/mainMenu.dart @@ -157,249 +157,207 @@ class _MainMenuState extends State { ), ], ), - body: ListView( - children: [ - const SizedBox(height: 10), - FutureBuilder( + body: CustomScrollView( + slivers: [ + const SliverToBoxAdapter(child: SizedBox(height: 10)), + FutureBuilder<(List, List)>( future: getServerCategories(force: force), builder: (context, AsyncSnapshot snapshot) { if (snapshot.connectionState == ConnectionState.done) { if (snapshot.hasData && snapshot.data != null) { - List collectionChildren = [ - Align( - alignment: Alignment.centerLeft, - child: Padding( - padding: const EdgeInsets.only(left: 10), - child: Text( - AppLocalizations.of(context)?.collections ?? - "Collections", - style: const TextStyle( - // size is the size of a title - fontSize: 30, - // decoration: TextDecoration.underline, - fontWeight: FontWeight.bold, + // Wrap Column in SliverToBoxAdapter for compatibility + return SliverToBoxAdapter( + child: Column( + children: [ + Align( + alignment: Alignment.centerLeft, + child: Padding( + padding: const EdgeInsets.only(left: 10), + child: Text( + AppLocalizations.of(context)?.collections ?? + "Collections", + style: const TextStyle( + fontSize: 30, fontWeight: FontWeight.bold), + ), ), ), - ), - ), - const SizedBox( - height: 10, - ), - SizedBox( - width: double.infinity, - height: MediaQuery.of(context).size.height / 6 * 1.2, - child: ListView.builder( - scrollDirection: Axis.horizontal, - itemCount: snapshot.data.$2?.length, - itemExtent: MediaQuery.of(context).size.width / 3, - itemBuilder: (context, index) { - return SizedBox( - child: Card( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), - child: InkWell( - onTap: () async { - logger.i("tapped"); - await Navigator.push( - context, - MaterialPageRoute( - builder: (context) => collectionScreen( - folderId: snapshot.data.$2 - .elementAt(index) - .id, - name: snapshot.data.$2 - .elementAt(index) - .name, - image: snapshot.data.$2 - .elementAt(index) - .image, - bookIds: snapshot.data.$2 - .elementAt(index) - .bookIds, - ), - ), - ); - }, - child: Column( - children: [ - SizedBox( - height: 10 * - MediaQuery.of(context).size.height / - 1000, - ), - Padding( - padding: EdgeInsets.only( - left: 10 * + const SizedBox(height: 10), + SizedBox( + width: double.infinity, + height: MediaQuery.of(context).size.height / 6 * 1.2, + child: ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: snapshot.data.$2?.length, + itemExtent: MediaQuery.of(context).size.width / 3, + itemBuilder: (context, index) { + return SizedBox( + child: Card( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + child: InkWell( + onTap: () async { + logger.i("tapped"); + await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + collectionScreen( + folderId: snapshot.data.$2 + .elementAt(index) + .id, + name: snapshot.data.$2 + .elementAt(index) + .name, + image: snapshot.data.$2 + .elementAt(index) + .image, + bookIds: snapshot.data.$2 + .elementAt(index) + .bookIds, + ), + ), + ); + }, + child: Column( + children: [ + SizedBox( + height: 10 * MediaQuery.of(context) .size - .width / + .height / 1000, - right: 10 * + ), + Padding( + padding: EdgeInsets.only( + left: 10 * + MediaQuery.of(context) + .size + .width / + 1000, + right: 10 * + MediaQuery.of(context) + .size + .width / + 1000), + child: AutoSizeText( + snapshot.data.$2 + .elementAt(index) + .name, + textAlign: TextAlign.center, + maxLines: 2, + minFontSize: 5, + style: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + ), + ), + ), + // start all images at the same height rather than same offset + SizedBox( + height: 5 * MediaQuery.of(context) .size - .width / - 1000), - child: AutoSizeText( - snapshot.data.$2.elementAt(index).name, - textAlign: TextAlign.center, - maxLines: 2, - minFontSize: 5, - style: const TextStyle( - fontSize: 14, - fontWeight: FontWeight.bold, + .height / + 1000, ), - ), - ), - // start all images at the same height rather than same offset - SizedBox( - height: 5 * - MediaQuery.of(context).size.height / - 1000, - ), - Flexible( - child: SizedBox( - child: RoundedImageWithShadow( - imageUrl: snapshot.data.$2 - .elementAt(index) - .image ?? - 'Asset', + Flexible( + child: SizedBox( + child: RoundedImageWithShadow( + imageUrl: snapshot.data.$2 + .elementAt(index) + .image ?? + 'Asset', + ), + ), ), - ), - ), - const SizedBox( - height: 10, + const SizedBox( + height: 10, + ), + ], ), - ], + ), ), + ); + }, + ), + ), + SizedBox( + height: 10, + ), + Divider( + height: 5, + thickness: 5, + ), + SizedBox( + height: 10, + ), + Align( + alignment: Alignment.centerLeft, + child: Padding( + padding: EdgeInsets.only(left: 10), + child: Text( + AppLocalizations.of(context)?.library ?? + "Library", + style: TextStyle( + fontSize: 30, + fontWeight: FontWeight.bold, ), ), - ); - }, - ), - ), - const SizedBox( - height: 10, - ), - // page break - const Divider( - height: 5, - thickness: 5, - indent: 0, - endIndent: 0, - ), - ]; - List libraryChildren = [ - const SizedBox( - height: 10, - ), - Align( - alignment: Alignment.centerLeft, - child: Padding( - padding: EdgeInsets.only(left: 10), - child: Text( - AppLocalizations.of(context)?.library ?? "Library", - style: TextStyle( - // size is the size of a title - fontSize: 30, - // decoration: TextDecoration.underline, - fontWeight: FontWeight.bold, ), ), - ), - ), - const SizedBox( - height: 10, - ), - PagedGridView( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - pagingController: _pagingController, - addRepaintBoundaries: true, - addSemanticIndexes: true, - addAutomaticKeepAlives: true, - // shrinkWrap: true, - gridDelegate: - const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - childAspectRatio: 1, - ), - builderDelegate: PagedChildBuilderDelegate( - itemBuilder: (context, entry, index) => SizedBox( - child: GridEntryWidget(entry), - )), + SizedBox( + height: 10, + ), + PagedGridView( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + pagingController: _pagingController, + addRepaintBoundaries: true, + addSemanticIndexes: true, + addAutomaticKeepAlives: true, + // shrinkWrap: true, + gridDelegate: + const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + childAspectRatio: 1, + ), + builderDelegate: PagedChildBuilderDelegate( + itemBuilder: (context, entry, index) => SizedBox( + child: GridEntryWidget(entry), + )), + ), + ], ), - ]; - return Column( - children: [ - if (snapshot.data.$2.toString().isNotEmpty && - snapshot.data.$2 != null) - ...collectionChildren, - if (snapshot.data.$1.toString().isNotEmpty) - ...libraryChildren, - // const SizedBox( - // height: 10, - // ), - ], ); } else if (snapshot.hasError) { - logger.e("Error: ${snapshot.error!}"); - logger.e("Stack Trace: ${snapshot.stackTrace}"); - return Center( - // return error message if there is an error - child: Text( - (AppLocalizations.of(context)?.error ?? "Error") + - ": " + - snapshot.error.toString(), - style: TextStyle( - color: Colors.red, - fontSize: 20, + // Handle error state + return SliverToBoxAdapter( + child: Center( + child: Text( + "Error: ${snapshot.error}", + style: TextStyle(color: Colors.red), ), ), ); - // if theres no books in the database, show a message - } else if (snapshot.data == null) { - return Center( - child: Text( - AppLocalizations.of(context)?.noBooks ?? "No books found", - style: TextStyle(fontSize: 20), - ), - ); } else { - return const SizedBox( - height: 100, + // Handle null data state + return SliverToBoxAdapter( child: Center( - child: CircularProgressIndicator(), + child: Text("No data found"), ), ); } } else { - // center both horizontally and vertically (the whole screen) - return Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - height: MediaQuery.of(context).size.height / 2 - 120, - ), - Text( - AppLocalizations.of(context)?.waitToFetchDB ?? - "Please wait while we fetch content from the database", - style: TextStyle(fontSize: 20), - textAlign: TextAlign.center, - ), - const SizedBox( - height: 20, - ), - const CircularProgressIndicator(), - ], + // Handle loading state + return SliverFillRemaining( + child: Center(child: CircularProgressIndicator()), ); } }, ), - const SizedBox( - height: 10, - ), + SliverToBoxAdapter( + child: const SizedBox(height: 10)), // Replaces the last SizedBox ], ), ); @@ -409,7 +367,7 @@ class _MainMenuState extends State { class GridEntryWidget extends StatefulWidget { final Entry entry; - const GridEntryWidget(this.entry) : super(key: key); + const GridEntryWidget(this.entry); // createState function @override From bdf8ec4c41bf731e5722bdddae71a16c5055a863 Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Mon, 12 Feb 2024 14:41:03 +0100 Subject: [PATCH 15/28] render paginated grid as sliver grid - moves the paginated grid out of the SliverToBoxAdapter, because that breaks the scroll listener (and kills performance) --- lib/screens/MainScreens/mainMenu.dart | 350 +++++++++++++------------- 1 file changed, 176 insertions(+), 174 deletions(-) diff --git a/lib/screens/MainScreens/mainMenu.dart b/lib/screens/MainScreens/mainMenu.dart index 6197cfb..c8650e6 100644 --- a/lib/screens/MainScreens/mainMenu.dart +++ b/lib/screens/MainScreens/mainMenu.dart @@ -66,23 +66,28 @@ class _MainMenuState extends State { bool force = false; + Future _fetchPage(int pageKey) async { + logger.i('pageKey: $pageKey'); + try { + final pageSize = 20; // Define your page size + final result = await fetchEntries(pageKey, pageSize); + logger.i("result.\$1: ${result.$1}"); + final isLastPage = result.$1 < pageSize; + if (isLastPage) { + _pagingController.appendLastPage(result.$2); + } else { + final nextPageKey = pageKey + result.$1; + _pagingController.appendPage(result.$2, nextPageKey); + } + } catch (error) { + _pagingController.error = error; + } + } + @override void initState() { - _pagingController.addPageRequestListener((pageKey) async { - logger.i('pageKey: $pageKey'); - try { - final pageSize = 20; // Define your page size - final result = await fetchEntries(pageKey, pageSize); - final isLastPage = result.$1 < pageSize; - if (isLastPage) { - _pagingController.appendLastPage(result.$2); - } else { - final nextPageKey = pageKey + result.$1; - _pagingController.appendPage(result.$2, nextPageKey); - } - } catch (error) { - _pagingController.error = error; - } + _pagingController.addPageRequestListener((pageKey) { + _fetchPage(pageKey); }); super.initState(); // fetchCategories(); @@ -157,179 +162,182 @@ class _MainMenuState extends State { ), ], ), - body: CustomScrollView( - slivers: [ - const SliverToBoxAdapter(child: SizedBox(height: 10)), - FutureBuilder<(List, List)>( + body: FutureBuilder<(List, List)>( future: getServerCategories(force: force), builder: (context, AsyncSnapshot snapshot) { if (snapshot.connectionState == ConnectionState.done) { if (snapshot.hasData && snapshot.data != null) { // Wrap Column in SliverToBoxAdapter for compatibility - return SliverToBoxAdapter( - child: Column( - children: [ - Align( - alignment: Alignment.centerLeft, - child: Padding( - padding: const EdgeInsets.only(left: 10), - child: Text( - AppLocalizations.of(context)?.collections ?? - "Collections", - style: const TextStyle( - fontSize: 30, fontWeight: FontWeight.bold), + return CustomScrollView( + slivers: [ + const SliverToBoxAdapter(child: SizedBox(height: 10)), + SliverToBoxAdapter( + child: Column( + children: [ + Align( + alignment: Alignment.centerLeft, + child: Padding( + padding: const EdgeInsets.only(left: 10), + child: Text( + AppLocalizations.of(context)?.collections ?? + "Collections", + style: const TextStyle( + fontSize: 30, fontWeight: FontWeight.bold), + ), + ), ), - ), - ), - const SizedBox(height: 10), - SizedBox( - width: double.infinity, - height: MediaQuery.of(context).size.height / 6 * 1.2, - child: ListView.builder( - scrollDirection: Axis.horizontal, - itemCount: snapshot.data.$2?.length, - itemExtent: MediaQuery.of(context).size.width / 3, - itemBuilder: (context, index) { - return SizedBox( - child: Card( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), - child: InkWell( - onTap: () async { - logger.i("tapped"); - await Navigator.push( - context, - MaterialPageRoute( - builder: (context) => - collectionScreen( - folderId: snapshot.data.$2 - .elementAt(index) - .id, - name: snapshot.data.$2 - .elementAt(index) - .name, - image: snapshot.data.$2 - .elementAt(index) - .image, - bookIds: snapshot.data.$2 - .elementAt(index) - .bookIds, - ), - ), - ); - }, - child: Column( - children: [ - SizedBox( - height: 10 * - MediaQuery.of(context) - .size - .height / - 1000, - ), - Padding( - padding: EdgeInsets.only( - left: 10 * + const SizedBox(height: 10), + SizedBox( + width: double.infinity, + height: MediaQuery.of(context).size.height / 6 * 1.2, + child: ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: snapshot.data.$2?.length, + itemExtent: MediaQuery.of(context).size.width / 3, + itemBuilder: (context, index) { + return SizedBox( + child: Card( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + child: InkWell( + onTap: () async { + logger.i("tapped"); + await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + collectionScreen( + folderId: snapshot.data.$2 + .elementAt(index) + .id, + name: snapshot.data.$2 + .elementAt(index) + .name, + image: snapshot.data.$2 + .elementAt(index) + .image, + bookIds: snapshot.data.$2 + .elementAt(index) + .bookIds, + ), + ), + ); + }, + child: Column( + children: [ + SizedBox( + height: 10 * MediaQuery.of(context) .size - .width / + .height / 1000, - right: 10 * + ), + Padding( + padding: EdgeInsets.only( + left: 10 * + MediaQuery.of(context) + .size + .width / + 1000, + right: 10 * + MediaQuery.of(context) + .size + .width / + 1000), + child: AutoSizeText( + snapshot.data.$2 + .elementAt(index) + .name, + textAlign: TextAlign.center, + maxLines: 2, + minFontSize: 5, + style: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, + ), + ), + ), + // start all images at the same height rather than same offset + SizedBox( + height: 5 * MediaQuery.of(context) .size - .width / - 1000), - child: AutoSizeText( - snapshot.data.$2 - .elementAt(index) - .name, - textAlign: TextAlign.center, - maxLines: 2, - minFontSize: 5, - style: const TextStyle( - fontSize: 14, - fontWeight: FontWeight.bold, + .height / + 1000, ), - ), - ), - // start all images at the same height rather than same offset - SizedBox( - height: 5 * - MediaQuery.of(context) - .size - .height / - 1000, - ), - Flexible( - child: SizedBox( - child: RoundedImageWithShadow( - imageUrl: snapshot.data.$2 - .elementAt(index) - .image ?? - 'Asset', + Flexible( + child: SizedBox( + child: RoundedImageWithShadow( + imageUrl: snapshot.data.$2 + .elementAt(index) + .image ?? + 'Asset', + ), + ), ), - ), - ), - const SizedBox( - height: 10, + const SizedBox( + height: 10, + ), + ], ), - ], + ), ), + ); + }, + ), + ), + SizedBox( + height: 10, + ), + Divider( + height: 5, + thickness: 5, + ), + SizedBox( + height: 10, + ), + Align( + alignment: Alignment.centerLeft, + child: Padding( + padding: EdgeInsets.only(left: 10), + child: Text( + AppLocalizations.of(context)?.library ?? + "Library", + style: TextStyle( + fontSize: 30, + fontWeight: FontWeight.bold, ), ), - ); - }, - ), - ), - SizedBox( - height: 10, - ), - Divider( - height: 5, - thickness: 5, - ), - SizedBox( - height: 10, - ), - Align( - alignment: Alignment.centerLeft, - child: Padding( - padding: EdgeInsets.only(left: 10), - child: Text( - AppLocalizations.of(context)?.library ?? - "Library", - style: TextStyle( - fontSize: 30, - fontWeight: FontWeight.bold, ), ), - ), - ), - SizedBox( - height: 10, + SizedBox( + height: 10, + ), + ], ), - PagedGridView( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - pagingController: _pagingController, - addRepaintBoundaries: true, - addSemanticIndexes: true, - addAutomaticKeepAlives: true, - // shrinkWrap: true, - gridDelegate: - const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - childAspectRatio: 1, - ), - builderDelegate: PagedChildBuilderDelegate( - itemBuilder: (context, entry, index) => SizedBox( - child: GridEntryWidget(entry), - )), + ), + PagedSliverGrid( + pagingController: _pagingController, + addRepaintBoundaries: true, + addSemanticIndexes: true, + addAutomaticKeepAlives: true, + // shrinkWrap: true, + gridDelegate: + const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + childAspectRatio: 1, ), - ], - ), + builderDelegate: PagedChildBuilderDelegate( + itemBuilder: (context, entry, index) => SizedBox( + child: GridEntryWidget(entry), + )), + ), + SliverToBoxAdapter( + child: const SizedBox(height: 10)), + ], ); + } else if (snapshot.hasError) { // Handle error state return SliverToBoxAdapter( @@ -350,17 +358,11 @@ class _MainMenuState extends State { } } else { // Handle loading state - return SliverFillRemaining( - child: Center(child: CircularProgressIndicator()), - ); + return Center(child: CircularProgressIndicator()); } }, ), - SliverToBoxAdapter( - child: const SizedBox(height: 10)), // Replaces the last SizedBox - ], - ), - ); + ); } } From 6294fafa577e77dbd18efbe34b76bef9fa46afb5 Mon Sep 17 00:00:00 2001 From: Chaphasilor Date: Mon, 12 Feb 2024 14:41:09 +0100 Subject: [PATCH 16/28] formatting --- lib/screens/MainScreens/mainMenu.dart | 364 +++++++++++++------------- 1 file changed, 181 insertions(+), 183 deletions(-) diff --git a/lib/screens/MainScreens/mainMenu.dart b/lib/screens/MainScreens/mainMenu.dart index c8650e6..44a3a66 100644 --- a/lib/screens/MainScreens/mainMenu.dart +++ b/lib/screens/MainScreens/mainMenu.dart @@ -86,7 +86,7 @@ class _MainMenuState extends State { @override void initState() { - _pagingController.addPageRequestListener((pageKey) { + _pagingController.addPageRequestListener((pageKey) { _fetchPage(pageKey); }); super.initState(); @@ -163,206 +163,204 @@ class _MainMenuState extends State { ], ), body: FutureBuilder<(List, List)>( - future: getServerCategories(force: force), - builder: (context, AsyncSnapshot snapshot) { - if (snapshot.connectionState == ConnectionState.done) { - if (snapshot.hasData && snapshot.data != null) { - // Wrap Column in SliverToBoxAdapter for compatibility - return CustomScrollView( - slivers: [ - const SliverToBoxAdapter(child: SizedBox(height: 10)), - SliverToBoxAdapter( - child: Column( - children: [ - Align( - alignment: Alignment.centerLeft, - child: Padding( - padding: const EdgeInsets.only(left: 10), - child: Text( - AppLocalizations.of(context)?.collections ?? - "Collections", - style: const TextStyle( - fontSize: 30, fontWeight: FontWeight.bold), - ), - ), + future: getServerCategories(force: force), + builder: (context, AsyncSnapshot snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + if (snapshot.hasData && snapshot.data != null) { + // Wrap Column in SliverToBoxAdapter for compatibility + return CustomScrollView( + slivers: [ + const SliverToBoxAdapter(child: SizedBox(height: 10)), + SliverToBoxAdapter( + child: Column( + children: [ + Align( + alignment: Alignment.centerLeft, + child: Padding( + padding: const EdgeInsets.only(left: 10), + child: Text( + AppLocalizations.of(context)?.collections ?? + "Collections", + style: const TextStyle( + fontSize: 30, fontWeight: FontWeight.bold), ), - const SizedBox(height: 10), - SizedBox( - width: double.infinity, - height: MediaQuery.of(context).size.height / 6 * 1.2, - child: ListView.builder( - scrollDirection: Axis.horizontal, - itemCount: snapshot.data.$2?.length, - itemExtent: MediaQuery.of(context).size.width / 3, - itemBuilder: (context, index) { - return SizedBox( - child: Card( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(8), - ), - child: InkWell( - onTap: () async { - logger.i("tapped"); - await Navigator.push( - context, - MaterialPageRoute( - builder: (context) => - collectionScreen( - folderId: snapshot.data.$2 - .elementAt(index) - .id, - name: snapshot.data.$2 - .elementAt(index) - .name, - image: snapshot.data.$2 - .elementAt(index) - .image, - bookIds: snapshot.data.$2 - .elementAt(index) - .bookIds, - ), - ), - ); - }, - child: Column( - children: [ - SizedBox( - height: 10 * + ), + ), + const SizedBox(height: 10), + SizedBox( + width: double.infinity, + height: MediaQuery.of(context).size.height / 6 * 1.2, + child: ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: snapshot.data.$2?.length, + itemExtent: MediaQuery.of(context).size.width / 3, + itemBuilder: (context, index) { + return SizedBox( + child: Card( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + ), + child: InkWell( + onTap: () async { + logger.i("tapped"); + await Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + collectionScreen( + folderId: snapshot.data.$2 + .elementAt(index) + .id, + name: snapshot.data.$2 + .elementAt(index) + .name, + image: snapshot.data.$2 + .elementAt(index) + .image, + bookIds: snapshot.data.$2 + .elementAt(index) + .bookIds, + ), + ), + ); + }, + child: Column( + children: [ + SizedBox( + height: 10 * + MediaQuery.of(context) + .size + .height / + 1000, + ), + Padding( + padding: EdgeInsets.only( + left: 10 * MediaQuery.of(context) .size - .height / + .width / 1000, - ), - Padding( - padding: EdgeInsets.only( - left: 10 * - MediaQuery.of(context) - .size - .width / - 1000, - right: 10 * - MediaQuery.of(context) - .size - .width / - 1000), - child: AutoSizeText( - snapshot.data.$2 - .elementAt(index) - .name, - textAlign: TextAlign.center, - maxLines: 2, - minFontSize: 5, - style: const TextStyle( - fontSize: 14, - fontWeight: FontWeight.bold, - ), - ), - ), - // start all images at the same height rather than same offset - SizedBox( - height: 5 * + right: 10 * MediaQuery.of(context) .size - .height / - 1000, + .width / + 1000), + child: AutoSizeText( + snapshot.data.$2 + .elementAt(index) + .name, + textAlign: TextAlign.center, + maxLines: 2, + minFontSize: 5, + style: const TextStyle( + fontSize: 14, + fontWeight: FontWeight.bold, ), - Flexible( - child: SizedBox( - child: RoundedImageWithShadow( - imageUrl: snapshot.data.$2 - .elementAt(index) - .image ?? - 'Asset', - ), - ), - ), - const SizedBox( - height: 10, + ), + ), + // start all images at the same height rather than same offset + SizedBox( + height: 5 * + MediaQuery.of(context) + .size + .height / + 1000, + ), + Flexible( + child: SizedBox( + child: RoundedImageWithShadow( + imageUrl: snapshot.data.$2 + .elementAt(index) + .image ?? + 'Asset', ), - ], + ), ), - ), + const SizedBox( + height: 10, + ), + ], ), - ); - }, - ), - ), - SizedBox( - height: 10, - ), - Divider( - height: 5, - thickness: 5, - ), - SizedBox( - height: 10, - ), - Align( - alignment: Alignment.centerLeft, - child: Padding( - padding: EdgeInsets.only(left: 10), - child: Text( - AppLocalizations.of(context)?.library ?? - "Library", - style: TextStyle( - fontSize: 30, - fontWeight: FontWeight.bold, ), ), + ); + }, + ), + ), + SizedBox( + height: 10, + ), + Divider( + height: 5, + thickness: 5, + ), + SizedBox( + height: 10, + ), + Align( + alignment: Alignment.centerLeft, + child: Padding( + padding: EdgeInsets.only(left: 10), + child: Text( + AppLocalizations.of(context)?.library ?? + "Library", + style: TextStyle( + fontSize: 30, + fontWeight: FontWeight.bold, ), ), - SizedBox( - height: 10, - ), - ], + ), ), - ), - PagedSliverGrid( - pagingController: _pagingController, - addRepaintBoundaries: true, - addSemanticIndexes: true, - addAutomaticKeepAlives: true, - // shrinkWrap: true, - gridDelegate: - const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 2, - childAspectRatio: 1, + SizedBox( + height: 10, ), - builderDelegate: PagedChildBuilderDelegate( - itemBuilder: (context, entry, index) => SizedBox( - child: GridEntryWidget(entry), - )), - ), - SliverToBoxAdapter( - child: const SizedBox(height: 10)), - ], - ); - - } else if (snapshot.hasError) { - // Handle error state - return SliverToBoxAdapter( - child: Center( - child: Text( - "Error: ${snapshot.error}", - style: TextStyle(color: Colors.red), - ), + ], ), - ); - } else { - // Handle null data state - return SliverToBoxAdapter( - child: Center( - child: Text("No data found"), + ), + PagedSliverGrid( + pagingController: _pagingController, + addRepaintBoundaries: true, + addSemanticIndexes: true, + addAutomaticKeepAlives: true, + // shrinkWrap: true, + gridDelegate: + const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + childAspectRatio: 1, ), - ); - } - } else { - // Handle loading state - return Center(child: CircularProgressIndicator()); - } - }, - ), - ); + builderDelegate: PagedChildBuilderDelegate( + itemBuilder: (context, entry, index) => SizedBox( + child: GridEntryWidget(entry), + )), + ), + SliverToBoxAdapter(child: const SizedBox(height: 10)), + ], + ); + } else if (snapshot.hasError) { + // Handle error state + return SliverToBoxAdapter( + child: Center( + child: Text( + "Error: ${snapshot.error}", + style: TextStyle(color: Colors.red), + ), + ), + ); + } else { + // Handle null data state + return SliverToBoxAdapter( + child: Center( + child: Text("No data found"), + ), + ); + } + } else { + // Handle loading state + return Center(child: CircularProgressIndicator()); + } + }, + ), + ); } } From 3879d5de402eb0b401d6a6385dd126ae90c9f6fa Mon Sep 17 00:00:00 2001 From: Kara-Zor-El Date: Mon, 12 Feb 2024 15:33:29 -0500 Subject: [PATCH 17/28] Adjust padding --- lib/screens/MainScreens/mainMenu.dart | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/screens/MainScreens/mainMenu.dart b/lib/screens/MainScreens/mainMenu.dart index 44a3a66..cb39cf0 100644 --- a/lib/screens/MainScreens/mainMenu.dart +++ b/lib/screens/MainScreens/mainMenu.dart @@ -69,7 +69,7 @@ class _MainMenuState extends State { Future _fetchPage(int pageKey) async { logger.i('pageKey: $pageKey'); try { - final pageSize = 20; // Define your page size + const pageSize = 20; // Define your page size final result = await fetchEntries(pageKey, pageSize); logger.i("result.\$1: ${result.$1}"); final isLastPage = result.$1 < pageSize; @@ -287,31 +287,31 @@ class _MainMenuState extends State { }, ), ), - SizedBox( + const SizedBox( height: 10, ), - Divider( + const Divider( height: 5, thickness: 5, ), - SizedBox( + const SizedBox( height: 10, ), Align( alignment: Alignment.centerLeft, child: Padding( - padding: EdgeInsets.only(left: 10), + padding: const EdgeInsets.only(left: 10), child: Text( AppLocalizations.of(context)?.library ?? "Library", - style: TextStyle( + style: const TextStyle( fontSize: 30, fontWeight: FontWeight.bold, ), ), ), ), - SizedBox( + const SizedBox( height: 10, ), ], @@ -333,7 +333,7 @@ class _MainMenuState extends State { child: GridEntryWidget(entry), )), ), - SliverToBoxAdapter(child: const SizedBox(height: 10)), + const SliverToBoxAdapter(child: SizedBox(height: 80)), ], ); } else if (snapshot.hasError) { @@ -342,13 +342,13 @@ class _MainMenuState extends State { child: Center( child: Text( "Error: ${snapshot.error}", - style: TextStyle(color: Colors.red), + style: const TextStyle(color: Colors.red), ), ), ); } else { // Handle null data state - return SliverToBoxAdapter( + return const SliverToBoxAdapter( child: Center( child: Text("No data found"), ), @@ -356,7 +356,7 @@ class _MainMenuState extends State { } } else { // Handle loading state - return Center(child: CircularProgressIndicator()); + return const Center(child: CircularProgressIndicator()); } }, ), From 5d370dfdba5556484a713898e2ce128c09281c2d Mon Sep 17 00:00:00 2001 From: Kara-Zor-El Date: Tue, 13 Feb 2024 16:09:57 -0500 Subject: [PATCH 18/28] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c6c777a..9b0b70a 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,4 @@ linux/flutter/generated_plugin_registrant.cc linux/flutter/generated_plugins.cmake linux/flutter/generated_plugin_registrant.cc linux/flutter/generated_plugins.cmake +sentry.json From 64ee0e6e7149a92a5fe7bd4696b139ff98093567 Mon Sep 17 00:00:00 2001 From: Kara-Zor-El Date: Tue, 13 Feb 2024 16:10:14 -0500 Subject: [PATCH 19/28] set up sentry --- Makefile | 16 +++--- lib/main.dart | 57 ++++++++---------- pubspec.lock | 156 +++++++++++++++++++++++++++++++++++++++++++++++++- pubspec.yaml | 12 +++- 4 files changed, 198 insertions(+), 43 deletions(-) diff --git a/Makefile b/Makefile index 2bbe90d..814421d 100644 --- a/Makefile +++ b/Makefile @@ -47,25 +47,25 @@ endif .PHONY: ios_release ios_release: create_output_dir @echo "Building iOS release IPA..." - @flutter build ipa --release >/dev/null 2>&1 + @flutter build ipa --release --dart-define-from-file=./sentry.json @echo "Complete release IPA" @mv build/ios/ipa/jellybook.ipa "$(OUTPUT_DIR)/JellyBook-Release.ipa" .PHONY: ios_debug ios_debug: create_output_dir @echo "Building iOS debug IPA..." - @flutter build ipa --debug + @flutter build ipa --debug --dart-define-from-file=./sentry.json @echo "Complete debug IPA" @mv build/ios/ipa/jellybook.ipa "$(OUTPUT_DIR)/JellyBook-Debug.ipa" .PHONY: android_release android_release: create_output_dir @echo "Building Android release APK..." - @flutter build apk --release + @flutter build apk --release --dart-define-from-file=./sentry.json @echo "Complete release APK" @mv build/app/outputs/flutter-apk/app-release.apk "$(OUTPUT_DIR)/JellyBook-Release.apk" @echo "Building Android release APK (split by ABI)..." - @flutter build apk --split-per-abi --release + @flutter build apk --split-per-abi --release --dart-define-from-file=./sentry.json @echo "Complete release APK (split by ABI)" @mv build/app/outputs/flutter-apk/app-armeabi-v7a-release.apk "$(OUTPUT_DIR)/JellyBook-Release-arm32.apk" @mv build/app/outputs/flutter-apk/app-arm64-v8a-release.apk "$(OUTPUT_DIR)/JellyBook-Release-arm64.apk" @@ -74,11 +74,11 @@ android_release: create_output_dir .PHONY: android_debug android_debug: create_output_dir @echo "Building Android debug APK..." - @flutter build apk --debug + @flutter build apk --debug --dart-define-from-file=./sentry.json @echo "Complete debug APK" @mv build/app/outputs/flutter-apk/app-debug.apk "$(OUTPUT_DIR)/JellyBook-Debug.apk" @echo "Building Android debug APK (split by ABI)..." - @flutter build apk --split-per-abi --debug + @flutter build apk --split-per-abi --debug --dart-define-from-file=./sentry.json @echo "Complete debug APK (split by ABI)" @mv build/app/outputs/flutter-apk/app-armeabi-v7a-debug.apk "$(OUTPUT_DIR)/JellyBook-Debug-arm32.apk" @mv build/app/outputs/flutter-apk/app-arm64-v8a-debug.apk "$(OUTPUT_DIR)/JellyBook-Debug-arm64.apk" @@ -87,14 +87,14 @@ android_debug: create_output_dir .PHONY: app_bundle_release app_bundle_release: create_output_dir @echo "Building Android release App Bundle..." - @flutter build appbundle --release + @flutter build appbundle --release --dart-define-from-file=./sentry.json @echo "Complete release App Bundle" @mv build/app/outputs/bundle/release/app-release.aab "$(OUTPUT_DIR)/JellyBook-Release.aab" .PHONY: app_bundle_debug app_bundle_debug: create_output_dir @echo "Building Android debug App Bundle..." - @flutter build appbundle --debug + @flutter build appbundle --debug --dart-define-from-file=./sentry.json @echo "Complete debug App Bundle" @mv build/app/outputs/bundle/debug/app-debug.aab "$(OUTPUT_DIR)/JellyBook-Debug.aab" diff --git a/lib/main.dart b/lib/main.dart index f339d6e..bfed7d6 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -20,6 +20,7 @@ import 'package:provider/provider.dart'; import 'package:jellybook/providers/languageProvider.dart'; import 'package:jellybook/providers/themeProvider.dart'; import 'package:jellybook/variables.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; Future get _localPath async { // get the directory that normally is located at /storage/emulated/0/Documents/ @@ -90,6 +91,8 @@ Future main() async { SharedPreferences prefs = await SharedPreferences.getInstance(); + bool useSentry = prefs.getBool("useSentry") ?? false; + // dio allow self signed certificates HttpOverrides.global = MyHttpOverrides(); @@ -111,42 +114,23 @@ Future main() async { // set the logStoragePath variable logStoragePath = "$localPath/Documents/"; - // set language to english - // Settings.setValue("localeString", "en"); - - // if (kDebugMode) { - // try { - // // delete all entries in the database - // // get a list of all the entries ids - // var entries = await isar.entrys.where().findAll(); - // var entryIds = entries.map((e) => e.isarId).toList(); - // await isar.writeTxn(() async { - // isar.entrys.deleteAll(entryIds); - // logger.d("deleted ${entryIds.length} entries"); - // }); - // // delete all folders in the database - // // get a list of all the folders ids - // var folders = await isar.folders.where().findAll(); - // var folderIds = folders.map((e) => e.isarId).toList(); - // await isar.writeTxn(() async { - // isar.folders.deleteAll(folderIds); - // logger.d("deleted ${folderIds.length} folders"); - // }); - // } catch (e) { - // logger.e(e); - // } - // logger.d("cleared Isar boxes"); - // } - var logins = await isar.logins.where().findAll(); if (logins.length != 0) { - logger.d("login username: ${logins[0].username}"); prefs.setString("username", logins[0].username); - if (kDebugMode) { - logger.d("login url: ${logins[0].serverUrl}"); - logger.d("login password: ${logins[0].password}"); + if (useSentry) { + await SentryFlutter.init( + (options) { + options.dsn = const String.fromEnvironment('SENTRY_DSN'); + options.tracesSampleRate = 1.0; + }, + appRunner: () => runApp(MyApp( + url: logins[0].serverUrl, + username: logins[0].username, + password: logins[0].password, + prefs: prefs, + )), + ); } - logger.d("login found"); runApp(MyApp( url: logins[0].serverUrl, username: logins[0].username, @@ -154,6 +138,15 @@ Future main() async { prefs: prefs, )); } else { + if (useSentry) { + await SentryFlutter.init( + (options) { + options.dsn = const String.fromEnvironment('SENTRY_DSN'); + options.tracesSampleRate = 1.0; + }, + appRunner: () => runApp(MyApp(prefs: prefs)), + ); + } runApp(MyApp(prefs: prefs)); } } diff --git a/pubspec.lock b/pubspec.lock index 751429f..78aba4e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -17,6 +17,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.13.0" + ansicolor: + dependency: transitive + description: + name: ansicolor + sha256: "8bf17a8ff6ea17499e40a2d2542c2f481cd7615760c6d34065cb22bfd22e6880" + url: "https://pub.dev" + source: hosted + version: "2.0.2" archive: dependency: "direct main" description: @@ -265,6 +273,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.1" + coverage: + dependency: transitive + description: + name: coverage + sha256: "8acabb8306b57a409bf4c83522065672ee13179297a6bb0cb9ead73948df7c76" + url: "https://pub.dev" + source: hosted + version: "1.7.2" cross_file: dependency: transitive description: @@ -397,10 +413,10 @@ packages: dependency: transitive description: name: file - sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" url: "https://pub.dev" source: hosted - version: "7.0.0" + version: "6.1.4" file_selector_linux: dependency: transitive description: @@ -624,6 +640,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.2" + globbing: + dependency: transitive + description: + name: globbing + sha256: "4f89cfaf6fa74c9c1740a96259da06bd45411ede56744e28017cc534a12b6e2d" + url: "https://pub.dev" + source: hosted + version: "1.0.0" google_nav_bar: dependency: "direct main" description: @@ -760,6 +784,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.0" + injector: + dependency: transitive + description: + name: injector + sha256: ed389bed5b48a699d5b9561c985023d0d5cc88dd5ff2237aadcce5a5ab433e4e + url: "https://pub.dev" + source: hosted + version: "3.0.0" intl: dependency: "direct main" description: @@ -929,6 +961,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.5.0" + node_preamble: + dependency: transitive + description: + name: node_preamble + sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db" + url: "https://pub.dev" + source: hosted + version: "2.0.2" octo_image: dependency: transitive description: @@ -1170,6 +1210,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.1" + process: + dependency: transitive + description: + name: process + sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" + url: "https://pub.dev" + source: hosted + version: "4.2.4" + properties: + dependency: transitive + description: + name: properties + sha256: "975daa001432c70f5f494b50e4c5c72990d2f026e4a307cb4aaec99562f2d0e4" + url: "https://pub.dev" + source: hosted + version: "2.1.0" provider: dependency: "direct main" description: @@ -1218,6 +1274,30 @@ packages: url: "https://pub.dev" source: hosted version: "0.3.8" + sentry: + dependency: transitive + description: + name: sentry + sha256: a7946f4a90b0feb47214981d881b98149e05f6c576da9f2a2f33945bf561de25 + url: "https://pub.dev" + source: hosted + version: "7.16.0" + sentry_dart_plugin: + dependency: "direct dev" + description: + name: sentry_dart_plugin + sha256: b29713fb4db1fb28bd7aca811c43e1f52aa70bf39e0bcdcbdd9a78db37a6005d + url: "https://pub.dev" + source: hosted + version: "1.7.0" + sentry_flutter: + dependency: "direct main" + description: + name: sentry_flutter + sha256: "6db7fa1b076faf2f5dd77d8cc9ef206171f32a290cc638842d78e5d62b441a27" + url: "https://pub.dev" + source: hosted + version: "7.16.0" shared_preferences: dependency: "direct main" description: @@ -1282,6 +1362,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.1" + 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: a41d3f53c4adf0f57480578c1d61d90342cd617de7fc8077b1304643c2d85c1e + url: "https://pub.dev" + source: hosted + version: "1.1.2" shelf_web_socket: dependency: transitive description: @@ -1319,6 +1415,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.0" + source_map_stack_trace: + dependency: transitive + description: + name: source_map_stack_trace + sha256: "84cf769ad83aa6bb61e0aa5a18e53aea683395f196a6f39c4c881fb90ed4f7ae" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + source_maps: + dependency: transitive + description: + name: source_maps + sha256: "708b3f6b97248e5781f493b765c3337db11c5d2c81c3094f10904bfa8004c703" + url: "https://pub.dev" + source: hosted + version: "0.10.12" source_span: dependency: transitive description: @@ -1399,6 +1511,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.0+1" + system_info2: + dependency: transitive + description: + name: system_info2 + sha256: "65206bbef475217008b5827374767550a5420ce70a04d2d7e94d1d2253f3efc9" + url: "https://pub.dev" + source: hosted + version: "4.0.0" term_glyph: dependency: transitive description: @@ -1407,6 +1527,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.1" + test: + dependency: transitive + description: + name: test + sha256: "7ee446762c2c50b3bd4ea96fe13ffac69919352bd3b4b17bac3f3465edc58073" + url: "https://pub.dev" + source: hosted + version: "1.25.2" test_api: dependency: transitive description: @@ -1415,6 +1543,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.0" + test_core: + dependency: transitive + description: + name: test_core + sha256: "2bc4b4ecddd75309300d8096f781c0e3280ca1ef85beda558d33fcbedc2eead4" + url: "https://pub.dev" + source: hosted + version: "0.6.0" time: dependency: transitive description: @@ -1559,6 +1695,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: a2662fb1f114f4296cf3f5a50786a2d888268d7776cf681aa17d660ffa23b246 + url: "https://pub.dev" + source: hosted + version: "14.0.0" watcher: dependency: transitive description: @@ -1583,6 +1727,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.4.2" + 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: diff --git a/pubspec.yaml b/pubspec.yaml index fb935ff..d3698d1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -65,7 +65,6 @@ dependencies: google_nav_bar: ^5.0.6 cached_network_image: ^3.2.3 fancy_shimmer_image: ^2.0.2 - logger: ^2.0.1 openapi: git: https://github.com/Kara-Zor-El/jellyfin_api.git string_similarity: ^2.0.0 @@ -86,6 +85,10 @@ dependencies: image_picker: ^1.0.4 infinite_scroll_pagination: ^4.0.0 + # Logging + logger: ^2.0.1 + sentry_flutter: ^7.16.0 + dev_dependencies: # flutter_test: # sdk: flutter @@ -101,6 +104,7 @@ dev_dependencies: # hive_generator: ^2.0.0 build_runner: ^2.3.2 isar_generator: ^3.0.5 + sentry_dart_plugin: ^1.7.0 # test: ^1.24.3 # dart_code_linter: ^1.1.1 # objectbox_generator: ^1.6.2 @@ -166,3 +170,9 @@ icons_launcher: adaptive_background_color: '#E7E7E7' adaptive_foreground_image: 'assets/images/IconRound.png' # remove_alpha_ios: true + + +sentry: + upload_debug_symbols: true + project: "jellybook" + org: "jellybook" From 0b14283da98bbf7a97ec9723e2ab170db2c58ba3 Mon Sep 17 00:00:00 2001 From: Kara-Zor-El Date: Tue, 13 Feb 2024 16:10:33 -0500 Subject: [PATCH 20/28] Fix up Pods and iOS stuff --- ios/Flutter/AppFrameworkInfo.plist | 40 +++++++++++++++--------------- ios/Podfile | 2 +- ios/Podfile.lock | 31 +++++++++++++++++------ 3 files changed, 44 insertions(+), 29 deletions(-) diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist index 9625e10..658d8c4 100755 --- a/ios/Flutter/AppFrameworkInfo.plist +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -2,25 +2,25 @@ - CFBundleDevelopmentRegion - en - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - MinimumOSVersion - 11.0 + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 12.0 diff --git a/ios/Podfile b/ios/Podfile index f331cd2..181c71f 100755 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -# platform :ios, '11.0' +# platform :ios, '12.0' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/ios/Podfile.lock b/ios/Podfile.lock index f173667..510dd11 100755 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -27,11 +27,18 @@ PODS: - path_provider_foundation (0.0.1): - Flutter - FlutterMacOS - - pdfx (1.0.0): + - pdfx_plugin (1.0.0): - Flutter - permission_handler_apple (9.1.1): - Flutter - ReachabilitySwift (5.0.0) + - Sentry/HybridSDK (8.19.0): + - SentryPrivate (= 8.19.0) + - sentry_flutter (0.0.1): + - Flutter + - FlutterMacOS + - Sentry/HybridSDK (= 8.19.0) + - SentryPrivate (8.19.0) - shared_preferences_foundation (0.0.1): - Flutter - FlutterMacOS @@ -60,8 +67,9 @@ DEPENDENCIES: - open_filex (from `.symlinks/plugins/open_filex/ios`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - - pdfx (from `.symlinks/plugins/pdfx/ios`) + - pdfx_plugin (from `.symlinks/plugins/pdfx_plugin/ios`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) + - sentry_flutter (from `.symlinks/plugins/sentry_flutter/ios`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - sqflite (from `.symlinks/plugins/sqflite/ios`) - unrar_file (from `.symlinks/plugins/unrar_file/ios`) @@ -71,6 +79,8 @@ SPEC REPOS: trunk: - FMDB - ReachabilitySwift + - Sentry + - SentryPrivate - UnrarKit EXTERNAL SOURCES: @@ -98,10 +108,12 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/package_info_plus/ios" path_provider_foundation: :path: ".symlinks/plugins/path_provider_foundation/darwin" - pdfx: - :path: ".symlinks/plugins/pdfx/ios" + pdfx_plugin: + :path: ".symlinks/plugins/pdfx_plugin/ios" permission_handler_apple: :path: ".symlinks/plugins/permission_handler_apple/ios" + sentry_flutter: + :path: ".symlinks/plugins/sentry_flutter/ios" shared_preferences_foundation: :path: ".symlinks/plugins/shared_preferences_foundation/darwin" sqflite: @@ -115,7 +127,7 @@ SPEC CHECKSUMS: audioplayers_darwin: 877d9a4d06331c5c374595e46e16453ac7eafa40 connectivity_plus: bf0076dd84a130856aa636df1c71ccaff908fa1d device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6 - Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 + Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 flutter_background_service_ios: e30e0d3ee69e4cee66272d0c78eacd48c2e94aac flutter_html_to_pdf: 0fd9f8d04f335d68b06a7c4ab5fc85d22e1ef91b flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be @@ -125,15 +137,18 @@ SPEC CHECKSUMS: open_filex: 6e26e659846ec990262224a12ef1c528bb4edbe4 package_info_plus: 115f4ad11e0698c8c1c5d8a689390df880f47e85 path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 - pdfx: 7b876b09de8b7a0bf444a4f82b439ffcff4ee1ec + pdfx_plugin: e02b78e303c23caa858547c49479e061dbf37b40 permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6 ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 + Sentry: 1ebcaef678a27c8ac515f974cb5425dd1bbdec2f + sentry_flutter: ecdfbedee55337205561cfa782ee02d31ec83e1f + SentryPrivate: 765c9b4ebe9ac1a5fcdc067c5a1cfbf3f10e1677 shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126 sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a unrar_file: ead248ffb2e777cb67f083bc1bb1fb45d4157dbd UnrarKit: 99e3f0222a98a212188e1a6975dcf5aa798d26dd url_launcher_ios: bf5ce03e0e2088bad9cc378ea97fa0ed5b49673b -PODFILE CHECKSUM: 4523b5d271d7828b6cdc73fe8b32bf7b646e71e2 +PODFILE CHECKSUM: 279a2687027fca19455562b68ccfb66f53b9663e -COCOAPODS: 1.14.3 +COCOAPODS: 1.15.2 From bdf7102e1f3165740e6c2cba4875f7c1b9e09daa Mon Sep 17 00:00:00 2001 From: Kara-Zor-El Date: Tue, 13 Feb 2024 21:49:26 -0500 Subject: [PATCH 21/28] sentry report exceptions --- ios/Podfile.lock | 35 ++--- lib/main.dart | 13 -- lib/providers/ComicInfoXML.dart | 8 +- lib/providers/deleteComic.dart | 10 +- lib/providers/fetchBooks.dart | 8 +- lib/providers/fetchCategories.dart | 5 +- lib/providers/login.dart | 6 +- lib/providers/parseEpub.dart | 8 +- lib/providers/updateLike.dart | 8 +- lib/providers/updatePagenum.dart | 6 +- lib/screens/EditScreen.dart | 20 ++- lib/screens/MainScreens/mainMenu.dart | 9 +- lib/screens/MainScreens/settingsScreen.dart | 14 +- lib/screens/downloaderScreen.dart | 34 ++-- lib/screens/readingScreen.dart | 13 +- lib/screens/readingScreens/cbrCbzReader.dart | 6 +- lib/screens/readingScreens/pdfReader.dart | 2 +- pubspec.lock | 156 +++++++++---------- pubspec.yaml | 3 +- 19 files changed, 218 insertions(+), 146 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 510dd11..51062cb 100755 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -13,9 +13,6 @@ PODS: - Flutter - flutter_secure_storage (6.0.0): - Flutter - - FMDB (2.7.5): - - FMDB/standard (= 2.7.5) - - FMDB/standard (2.7.5) - image_picker_ios (0.0.1): - Flutter - isar_flutter_libs (1.0.0): @@ -27,9 +24,9 @@ PODS: - path_provider_foundation (0.0.1): - Flutter - FlutterMacOS - - pdfx_plugin (1.0.0): + - pdfx (1.0.0): - Flutter - - permission_handler_apple (9.1.1): + - permission_handler_apple (9.3.0): - Flutter - ReachabilitySwift (5.0.0) - Sentry/HybridSDK (8.19.0): @@ -44,7 +41,7 @@ PODS: - FlutterMacOS - sqflite (0.0.3): - Flutter - - FMDB (>= 2.7.5) + - FlutterMacOS - unrar_file (0.0.1): - Flutter - UnrarKit @@ -67,17 +64,16 @@ DEPENDENCIES: - open_filex (from `.symlinks/plugins/open_filex/ios`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) - - pdfx_plugin (from `.symlinks/plugins/pdfx_plugin/ios`) + - pdfx (from `.symlinks/plugins/pdfx/ios`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) - sentry_flutter (from `.symlinks/plugins/sentry_flutter/ios`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - - sqflite (from `.symlinks/plugins/sqflite/ios`) + - sqflite (from `.symlinks/plugins/sqflite/darwin`) - unrar_file (from `.symlinks/plugins/unrar_file/ios`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) SPEC REPOS: trunk: - - FMDB - ReachabilitySwift - Sentry - SentryPrivate @@ -108,8 +104,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/package_info_plus/ios" path_provider_foundation: :path: ".symlinks/plugins/path_provider_foundation/darwin" - pdfx_plugin: - :path: ".symlinks/plugins/pdfx_plugin/ios" + pdfx: + :path: ".symlinks/plugins/pdfx/ios" permission_handler_apple: :path: ".symlinks/plugins/permission_handler_apple/ios" sentry_flutter: @@ -117,7 +113,7 @@ EXTERNAL SOURCES: shared_preferences_foundation: :path: ".symlinks/plugins/shared_preferences_foundation/darwin" sqflite: - :path: ".symlinks/plugins/sqflite/ios" + :path: ".symlinks/plugins/sqflite/darwin" unrar_file: :path: ".symlinks/plugins/unrar_file/ios" url_launcher_ios: @@ -131,23 +127,22 @@ SPEC CHECKSUMS: flutter_background_service_ios: e30e0d3ee69e4cee66272d0c78eacd48c2e94aac flutter_html_to_pdf: 0fd9f8d04f335d68b06a7c4ab5fc85d22e1ef91b flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be - FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a - image_picker_ios: 4a8aadfbb6dc30ad5141a2ce3832af9214a705b5 + image_picker_ios: 99dfe1854b4fa34d0364e74a78448a0151025425 isar_flutter_libs: b69f437aeab9c521821c3f376198c4371fa21073 open_filex: 6e26e659846ec990262224a12ef1c528bb4edbe4 package_info_plus: 115f4ad11e0698c8c1c5d8a689390df880f47e85 - path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 - pdfx_plugin: e02b78e303c23caa858547c49479e061dbf37b40 - permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6 + path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c + pdfx: 7b876b09de8b7a0bf444a4f82b439ffcff4ee1ec + permission_handler_apple: 036b856153a2b1f61f21030ff725f3e6fece2b78 ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 Sentry: 1ebcaef678a27c8ac515f974cb5425dd1bbdec2f sentry_flutter: ecdfbedee55337205561cfa782ee02d31ec83e1f SentryPrivate: 765c9b4ebe9ac1a5fcdc067c5a1cfbf3f10e1677 - shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126 - sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a + shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695 + sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec unrar_file: ead248ffb2e777cb67f083bc1bb1fb45d4157dbd UnrarKit: 99e3f0222a98a212188e1a6975dcf5aa798d26dd - url_launcher_ios: bf5ce03e0e2088bad9cc378ea97fa0ed5b49673b + url_launcher_ios: bbd758c6e7f9fd7b5b1d4cde34d2b95fcce5e812 PODFILE CHECKSUM: 279a2687027fca19455562b68ccfb66f53b9663e diff --git a/lib/main.dart b/lib/main.dart index bfed7d6..aba3cb6 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -202,24 +202,11 @@ class MyApp extends StatelessWidget { if (snapshot.data == ConnectivityResult.none) { return OfflineBookReader(prefs: prefs); } else { - // try to ping 1.1.1.1 or 8.8.8.8 or whatever their dns is and if network is reachable go to login screen - // if not, go to offline book reader - // Socket.connect('1.1.1.1', 53).then((socket) { - // socket.destroy(); return LoginScreen( url: url, username: username, password: password, ); - // }).catchError((e) { - // logger.e(e); - // return OfflineBookReader(prefs: prefs); - // }); - // return LoginScreen( - // url: url, - // username: username, - // password: password, - // ); } } else { return const CircularProgressIndicator(); diff --git a/lib/providers/ComicInfoXML.dart b/lib/providers/ComicInfoXML.dart index a4320c8..8314170 100644 --- a/lib/providers/ComicInfoXML.dart +++ b/lib/providers/ComicInfoXML.dart @@ -5,6 +5,8 @@ import 'package:xml/xml.dart' as xml; import 'package:jellybook/variables.dart'; import 'package:isar/isar.dart'; import 'package:jellybook/models/entry.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; +import 'package:shared_preferences/shared_preferences.dart'; Future parseXML(Entry entry) async { // find the ComicInfo.xml file @@ -87,11 +89,15 @@ Future parseXML(Entry entry) async { // save to database final isar = Isar.getInstance(); + SharedPreferences prefs = await SharedPreferences.getInstance(); + var useSentry = prefs.getBool('useSentry') ?? false; await isar!.writeTxn(() async { await isar.entrys.put(entry); - }).catchError((error) { + }).catchError((error, stackTrace) async { + if (useSentry) await Sentry.captureException(error, stackTrace: stackTrace); logger.e(error); }).onError((error, stackTrace) { + if (useSentry) Sentry.captureException(error, stackTrace: stackTrace); logger.e(error); }); } diff --git a/lib/providers/deleteComic.dart b/lib/providers/deleteComic.dart index 3413852..793f8ab 100644 --- a/lib/providers/deleteComic.dart +++ b/lib/providers/deleteComic.dart @@ -5,6 +5,8 @@ import 'package:jellybook/models/entry.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'dart:io'; import 'package:jellybook/variables.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; +import 'package:shared_preferences/shared_preferences.dart'; Future deleteComic(String id, context) async { await showDialog( @@ -37,10 +39,13 @@ Future deleteComic(String id, context) async { Future confirmedDelete(String id, context) async { final isar = Isar.getInstance(); final entry = await isar!.entrys.where().idEqualTo(id).findFirst(); + SharedPreferences prefs = await SharedPreferences.getInstance(); + bool useSentry = prefs.getBool('useSentry') ?? false; if (entry!.downloaded) { try { await File(entry.folderPath).delete(recursive: true); - } catch (e) { + } catch (e, s) { + if (useSentry) await Sentry.captureException(e, stackTrace: s); logger.e(e.toString()); } } @@ -51,7 +56,8 @@ Future confirmedDelete(String id, context) async { logger.d(path.toString()); try { Directory(path).deleteSync(recursive: true); - } catch (e) { + } catch (e, s) { + if (useSentry) await Sentry.captureException(e, stackTrace: s); logger.e("error deleting directory: $e"); } diff --git a/lib/providers/fetchBooks.dart b/lib/providers/fetchBooks.dart index c0c9c76..48bce76 100644 --- a/lib/providers/fetchBooks.dart +++ b/lib/providers/fetchBooks.dart @@ -4,6 +4,7 @@ import 'package:dio/dio.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:openapi/openapi.dart'; import 'package:built_collection/built_collection.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; // database imports import 'package:jellybook/models/entry.dart'; @@ -47,6 +48,7 @@ Future getComics(String comicsId) async { // turn into built list final api = Openapi(basePathOverride: url).getItemsApi(); Response? response; + bool useSentry = prefs.getBool('useSentry') ?? false; try { response = await api.getItemsByUserId( userId: userId!, @@ -59,7 +61,8 @@ Future getComics(String comicsId) async { sortBy: BuiltList(["IsFolder", "SortName"]), sortOrder: BuiltList([SortOrder.ascending]), ); - } catch (e) { + } catch (e, s) { + if (useSentry) await Sentry.captureException(e, stackTrace: s); logger.e(e); } BuiltList responseData = response?.data?.items ?? BuiltList(); @@ -72,7 +75,8 @@ Future getComics(String comicsId) async { final entries = await isar!.entrys.where().idEqualTo(comicsId).findAll(); logger.d("entries: $entries"); logger.d("entries length: ${entries.length}"); - } catch (e) { + } catch (e, s) { + if (useSentry) await Sentry.captureException(e, stackTrace: s); logger.e(e.toString()); } diff --git a/lib/providers/fetchCategories.dart b/lib/providers/fetchCategories.dart index f316d0a..28bfd9f 100644 --- a/lib/providers/fetchCategories.dart +++ b/lib/providers/fetchCategories.dart @@ -9,6 +9,7 @@ import 'package:jellybook/models/folder.dart'; import 'package:isar/isar.dart'; import 'package:package_info_plus/package_info_plus.dart' as p_info; import 'package:jellybook/variables.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; // have optional perameter to have the function return the list of folders Future<(List, List)> getServerCategories({ @@ -58,7 +59,9 @@ Future<(List, List)> getServerCategories({ includeHidden: true, ); // logger.d(response); - } catch (e) { + } catch (e, s) { + bool useSentry = prefs.getBool('useSentry') ?? false; + if (useSentry) await Sentry.captureException(e, stackTrace: s); logger.e(e); } diff --git a/lib/providers/login.dart b/lib/providers/login.dart index 497cd16..2dfd555 100644 --- a/lib/providers/login.dart +++ b/lib/providers/login.dart @@ -14,6 +14,7 @@ import 'package:jellybook/models/login.dart'; import 'package:openapi/openapi.dart'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:jellybook/variables.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; class LoginProvider { final String url; @@ -110,7 +111,10 @@ class LoginProvider { headers: headers, ); logger.d("Status Code: ${response.statusCode}"); - } catch (e) { + } catch (e, s) { + SharedPreferences prefs = await SharedPreferences.getInstance(); + bool useSentry = prefs.getBool('useSentry') ?? false; + if (useSentry) await Sentry.captureException(e, stackTrace: s); logger.e("Error:\n$e"); return e.toString(); // logger.e('Exception when calling UserApi->authenticateUserByName: $e\n'); diff --git a/lib/providers/parseEpub.dart b/lib/providers/parseEpub.dart index 085b149..a2b09bd 100644 --- a/lib/providers/parseEpub.dart +++ b/lib/providers/parseEpub.dart @@ -4,9 +4,11 @@ import 'dart:io'; import 'dart:convert'; import 'package:archive/archive.dart'; import 'package:jellybook/variables.dart'; +import 'package:shared_preferences/shared_preferences.dart'; import 'package:xml/xml.dart' as xml; import 'package:isar/isar.dart'; import 'package:jellybook/models/entry.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; Future parseEpub(Entry entry) async { List bytes = File(entry.filePath).readAsBytesSync(); @@ -38,11 +40,15 @@ Future parseEpub(Entry entry) async { logger.d("all tags list: $allTagsList"); entry2.tags = allTagsList; + SharedPreferences prefs = await SharedPreferences.getInstance(); + bool useSentry = prefs.getBool('useSentry') ?? false; await isar!.writeTxn(() async { await isar.entrys.put(entry2); - }).catchError((error) { + }).catchError((error, stackTrace) { + if (useSentry) Sentry.captureException(error, stackTrace: stackTrace); logger.e(error); }).onError((error, stackTrace) { + if (useSentry) Sentry.captureException(error, stackTrace: stackTrace); logger.e(error); }); } diff --git a/lib/providers/updateLike.dart b/lib/providers/updateLike.dart index f12043c..3689303 100644 --- a/lib/providers/updateLike.dart +++ b/lib/providers/updateLike.dart @@ -6,6 +6,7 @@ import 'package:openapi/openapi.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:package_info_plus/package_info_plus.dart' as p_info; import 'package:jellybook/variables.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; Future updateLike(String id) async { final isar = Isar.getInstance(); @@ -39,12 +40,14 @@ Future updateLike(String id) async { }; final api = Openapi(basePathOverride: server).getUserLibraryApi(); logger.d(url); + bool useSentry = prefs.getBool('useSentry') ?? false; if (entries?.isFavorited == false) { try { final response = await api.unmarkFavoriteItem( userId: userId, itemId: id, headers: headers, url: server); logger.d(response.data.toString()); - } catch (e) { + } catch (e, s) { + if (useSentry) await Sentry.captureException(e, stackTrace: s); logger.e(e.toString()); } } else { @@ -52,7 +55,8 @@ Future updateLike(String id) async { final response = await api.markFavoriteItem( userId: userId, itemId: id, headers: headers, url: server); logger.d(response.data.toString()); - } catch (e) { + } catch (e, s) { + if (useSentry) await Sentry.captureException(e, stackTrace: s); logger.e(e.toString()); } } diff --git a/lib/providers/updatePagenum.dart b/lib/providers/updatePagenum.dart index 6901476..ace20c1 100644 --- a/lib/providers/updatePagenum.dart +++ b/lib/providers/updatePagenum.dart @@ -3,6 +3,7 @@ import 'package:openapi/openapi.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:package_info_plus/package_info_plus.dart' as p_info; import 'package:jellybook/variables.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; Future updatePagenum(String id, int pagenum) async { pagenum *= 1000; @@ -40,7 +41,10 @@ Future updatePagenum(String id, int pagenum) async { ); logger.d(response.statusCode); logger.d(response.realUri); - } catch (e) { + } catch (e, s) { logger.e(e.toString()); + SharedPreferences prefs = await SharedPreferences.getInstance(); + bool useSentry = prefs.getBool('useSentry') ?? false; + if (useSentry) await Sentry.captureException(e, stackTrace: s); } } diff --git a/lib/screens/EditScreen.dart b/lib/screens/EditScreen.dart index 669a6ac..b961193 100644 --- a/lib/screens/EditScreen.dart +++ b/lib/screens/EditScreen.dart @@ -26,6 +26,7 @@ import 'package:flutter/cupertino.dart'; import 'dart:io'; import 'package:path_provider/path_provider.dart'; import 'package:path/path.dart' as p; +import 'package:sentry_flutter/sentry_flutter.dart'; class EditScreen extends StatefulWidget { bool offline; @@ -186,14 +187,17 @@ class _EditScreenState extends State { }; final api = Openapi(basePathOverride: server).getItemUpdateApi(); DateTime? dateTime; + bool useSentry = prefs.getBool('useSentry') ?? false; try { dateTime = DateTime.parse(entry.releaseDate); - } catch (e) { + } catch (e, s) { + if (useSentry) await Sentry.captureException(e, stackTrace: s); try { dateTime = DateTime.parse( entry.releaseDate.replaceAll(' ', '-'), ); - } catch (e) { + } catch (e, s) { + if (useSentry) await Sentry.captureException(e, stackTrace: s); logger.e(e.toString()); } } @@ -212,7 +216,8 @@ class _EditScreenState extends State { headers: headers, ); logger.d(response.toString()); - } catch (e) { + } catch (e, s) { + if (useSentry) await Sentry.captureException(e, stackTrace: s); logger.e(e.toString()); // display error message await showDialog( @@ -267,7 +272,8 @@ class _EditScreenState extends State { headers: headers, ); // tell if the image was uploaded or not - } catch (e) { + } catch (e, s) { + if (useSentry) await Sentry.captureException(e, stackTrace: s); logger.e(e.toString()); } } @@ -397,12 +403,14 @@ class _EditScreenState extends State { DateTime dateTime; try { dateTime = DateTime.parse(entry.releaseDate); - } catch (e) { + } catch (e, s) { + Sentry.captureException(e, stackTrace: s); try { dateTime = DateTime.parse( entry.releaseDate.replaceAll(' ', '-'), ); - } catch (e) { + } catch (e, s) { + Sentry.captureException(e, stackTrace: s); dateTime = DateTime.now(); } } diff --git a/lib/screens/MainScreens/mainMenu.dart b/lib/screens/MainScreens/mainMenu.dart index cb39cf0..fbdf973 100644 --- a/lib/screens/MainScreens/mainMenu.dart +++ b/lib/screens/MainScreens/mainMenu.dart @@ -17,6 +17,8 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:jellybook/variables.dart'; import 'package:jellybook/widgets/roundedImageWithShadow.dart'; import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; +import 'package:shared_preferences/shared_preferences.dart'; class MainMenu extends StatefulWidget { @override @@ -79,8 +81,13 @@ class _MainMenuState extends State { final nextPageKey = pageKey + result.$1; _pagingController.appendPage(result.$2, nextPageKey); } - } catch (error) { + } catch (error, stackTrace) { _pagingController.error = error; + SharedPreferences prefs = await SharedPreferences.getInstance(); + bool useSentry = prefs.getBool('useSentry') ?? false; + if (useSentry) { + await Sentry.captureException(error, stackTrace: stackTrace); + } } } diff --git a/lib/screens/MainScreens/settingsScreen.dart b/lib/screens/MainScreens/settingsScreen.dart index 16ad45e..b64f4b4 100644 --- a/lib/screens/MainScreens/settingsScreen.dart +++ b/lib/screens/MainScreens/settingsScreen.dart @@ -14,6 +14,7 @@ import 'package:jellybook/widgets/SimpleUserCard.dart'; import 'package:jellybook/widgets/SettingsItem.dart'; import 'package:jellybook/variables.dart'; import 'package:palette_generator/palette_generator.dart'; +import 'package:sentry/sentry.dart'; import 'package:openapi/openapi.dart'; @@ -312,8 +313,12 @@ class _SettingsScreenState extends State { if (response != null && response.statusCode == 200) { image = response.data!; } - } catch (e) { + } catch (e, s) { logger.e(e.toString()); + await Sentry.captureException( + e, + stackTrace: s, + ); } if (image.isNotEmpty) { imageProvider = MemoryImage(image); @@ -701,8 +706,13 @@ class _SettingsScreenState extends State { mode: LaunchMode.externalApplication, ); } - } catch (e) { + } catch (e, s) { logger.e(e.toString()); + SharedPreferences prefs = + await SharedPreferences.getInstance(); + bool useSentry = prefs.getBool('useSentry') ?? false; + if (useSentry) + await Sentry.captureException(e, stackTrace: s); } }, ), diff --git a/lib/screens/downloaderScreen.dart b/lib/screens/downloaderScreen.dart index 0ade608..68e76b1 100644 --- a/lib/screens/downloaderScreen.dart +++ b/lib/screens/downloaderScreen.dart @@ -25,6 +25,8 @@ import 'package:isar_flutter_libs/isar_flutter_libs.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:jellybook/variables.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; + class DownloadScreen extends StatefulWidget { Entry entry; DownloadScreen({ @@ -343,10 +345,13 @@ class _DownloadScreenState extends State { logger.d('Extracting file'); downloadStatus = DownloadStatus.Decompressing; String fileName2 = await fileNameFromTitle(entry.title); + SharedPreferences prefs = await SharedPreferences.getInstance(); + bool useSentry = prefs.getBool('useSentry') ?? false; // make directory try { await Directory(dirLocation).create(recursive: true); - } catch (e) { + } catch (e, s) { + if (useSentry) await Sentry.captureException(e, stackTrace: s); logger.d(e.toString()); } logger.d('Comic folder created'); @@ -354,7 +359,8 @@ class _DownloadScreenState extends State { try { await Directory(dirLocation + '/' + fileName2).create(recursive: true); - } catch (e) { + } catch (e, s) { + if (useSentry) await Sentry.captureException(e, stackTrace: s); logger.d(e.toString()); } List audioFileTypes = [ @@ -384,7 +390,8 @@ class _DownloadScreenState extends State { try { await Directory(dirLocation + '/' + fileName2 + '/' + filename) .create(recursive: true); - } catch (e) { + } catch (e, s) { + if (useSentry) await Sentry.captureException(e, stackTrace: s); logger.d(e.toString()); } } @@ -407,7 +414,8 @@ class _DownloadScreenState extends State { File(dirLocation + '/' + fileName).deleteSync(); entry.downloaded = true; entry.folderPath = dirLocation + '/' + fileName2; - } catch (e) { + } catch (e, s) { + if (useSentry) await Sentry.captureException(e, stackTrace: s); logger.d(e.toString()); } parseXML(entry); @@ -418,7 +426,8 @@ class _DownloadScreenState extends State { var file = File(dirLocation + '/' + fileName); try { await Directory('$dirLocation/$fileName2').create(recursive: true); - } catch (e) { + } catch (e, s) { + if (useSentry) await Sentry.captureException(e, stackTrace: s); logger.d(e.toString()); } file.renameSync(comicFolder + '/' + fileName); @@ -426,7 +435,8 @@ class _DownloadScreenState extends State { entry.filePath = comicFolder + '/' + fileName; logger.d('PDF file moved'); entry.downloaded = true; - } catch (e) { + } catch (e, s) { + if (useSentry) await Sentry.captureException(e, stackTrace: s); logger.d(e.toString()); } @@ -438,7 +448,8 @@ class _DownloadScreenState extends State { var file = File(dirLocation + '/' + fileName); try { await Directory('$dirLocation/$fileName2').create(recursive: true); - } catch (e) { + } catch (e, s) { + if (useSentry) await Sentry.captureException(e, stackTrace: s); logger.d(e.toString()); } file.renameSync(dirLocation + '/' + fileName2 + '/' + fileName); @@ -446,7 +457,8 @@ class _DownloadScreenState extends State { entry.filePath = dirLocation + '/' + fileName2 + '/' + fileName; logger.d('EPUB file moved'); entry.downloaded = true; - } catch (e) { + } catch (e, s) { + if (useSentry) await Sentry.captureException(e, stackTrace: s); logger.e(e.toString()); } @@ -461,7 +473,8 @@ class _DownloadScreenState extends State { var file = File(dirLocation + '/' + await fileNameFromTitle(fileName)); try { await Directory('$dirLocation/$fileName2').create(recursive: true); - } catch (e) { + } catch (e, s) { + if (useSentry) await Sentry.captureException(e, stackTrace: s); logger.d(e.toString()); } file.renameSync(dirLocation + '/' + fileName2 + '/' + fileName); @@ -470,7 +483,8 @@ class _DownloadScreenState extends State { logger.d('Audio file moved'); entry.downloaded = true; entry.folderPath = dirLocation + '/' + fileName2; - } catch (e) { + } catch (e, s) { + if (useSentry) await Sentry.captureException(e, stackTrace: s); logger.e(e.toString()); } } else { diff --git a/lib/screens/readingScreen.dart b/lib/screens/readingScreen.dart index e74466a..181e811 100644 --- a/lib/screens/readingScreen.dart +++ b/lib/screens/readingScreen.dart @@ -17,6 +17,9 @@ import 'package:jellybook/screens/readingScreens/audiobookReader.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:jellybook/variables.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + class ReadingScreen extends StatefulWidget { final String title; final String comicId; @@ -74,7 +77,10 @@ class _ReadingScreenState extends State { var entry = await isar!.entrys.where().idEqualTo(comicId).findFirst(); logger.i("entry of checkPermission: $entry"); - } catch (e) { + } catch (e, s) { + SharedPreferences prefs = await SharedPreferences.getInstance(); + bool useSentry = prefs.getBool('useSentry') ?? false; + if (useSentry) await Sentry.captureException(e, stackTrace: s); logger.e("entry in checkPermission: $e"); } } @@ -128,7 +134,10 @@ class _ReadingScreenState extends State { try { fileExtension = entry.filePath.split('.').last; logger.i("fileExtension: $fileExtension"); - } catch (e) { + } catch (e, s) { + SharedPreferences prefs = await SharedPreferences.getInstance(); + bool useSentry = prefs.getBool('useSentry') ?? false; + if (useSentry) await Sentry.captureException(e, stackTrace: s); logger.e("error getting file extension: $e"); } diff --git a/lib/screens/readingScreens/cbrCbzReader.dart b/lib/screens/readingScreens/cbrCbzReader.dart index 05ec0e7..90fb149 100644 --- a/lib/screens/readingScreens/cbrCbzReader.dart +++ b/lib/screens/readingScreens/cbrCbzReader.dart @@ -17,6 +17,7 @@ import 'package:jellybook/screens/AudioPicker.dart'; import 'package:flutter_background_service/flutter_background_service.dart'; import 'package:jellybook/widgets/AudioPlayerWidget.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; // cbr/cbz reader class CbrCbzReader extends StatefulWidget { @@ -203,7 +204,10 @@ class _CbrCbzReaderState extends State { for (var file in files) { getChaptersFromDirectory(file); } - } catch (e) { + } catch (e, s) { + SharedPreferences prefs = await SharedPreferences.getInstance(); + bool useSentry = prefs.getBool('useSentry') ?? false; + if (useSentry) await Sentry.captureException(e, stackTrace: s); logger.d( "Error: not a valid directory, its a file", ); diff --git a/lib/screens/readingScreens/pdfReader.dart b/lib/screens/readingScreens/pdfReader.dart index f43deff..6dc2286 100644 --- a/lib/screens/readingScreens/pdfReader.dart +++ b/lib/screens/readingScreens/pdfReader.dart @@ -9,7 +9,7 @@ import 'package:permission_handler/permission_handler.dart'; import 'package:isar/isar.dart'; import 'package:isar_flutter_libs/isar_flutter_libs.dart'; import 'package:jellybook/models/entry.dart'; -import 'package:pdfx_plugin/pdfx_plugin.dart'; +import 'package:pdfx/pdfx.dart'; import 'package:jellybook/providers/progress.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:jellybook/variables.dart'; diff --git a/pubspec.lock b/pubspec.lock index 78aba4e..fd97c29 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -10,7 +10,7 @@ packages: source: hosted version: "61.0.0" analyzer: - dependency: transitive + dependency: "direct dev" description: name: analyzer sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 @@ -157,18 +157,18 @@ packages: dependency: "direct dev" description: name: build_runner - sha256: "67d591d602906ef9201caf93452495ad1812bea2074f04e25dbd7c133785821b" + sha256: "581bacf68f89ec8792f5e5a0b2c4decd1c948e97ce659dc783688c8a88fbec21" url: "https://pub.dev" source: hosted - version: "2.4.7" + version: "2.4.8" build_runner_core: dependency: transitive description: name: build_runner_core - sha256: c9e32d21dd6626b5c163d48b037ce906bbe428bc23ab77bcd77bb21e593b6185 + sha256: "4ae8ffe5ac758da294ecf1802f2aff01558d8b1b00616aa7538ea9a8a5d50799" url: "https://pub.dev" source: hosted - version: "7.2.11" + version: "7.3.0" built_collection: dependency: transitive description: @@ -181,10 +181,10 @@ packages: dependency: transitive description: name: built_value - sha256: c9aabae0718ec394e5bc3c7272e6bb0dc0b32201a08fe185ec1d8401d3e39309 + sha256: a3ec2e0f967bc47f69f95009bb93db936288d61d5343b9436e378b28a2f830c6 url: "https://pub.dev" source: hosted - version: "8.8.1" + version: "8.9.0" cached_network_image: dependency: "direct main" description: @@ -237,10 +237,10 @@ packages: dependency: transitive description: name: code_builder - sha256: feee43a5c05e7b3199bb375a86430b8ada1b04104f2923d0e03cc01ca87b6d84 + sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37 url: "https://pub.dev" source: hosted - version: "4.9.0" + version: "4.10.0" collection: dependency: transitive description: @@ -341,10 +341,10 @@ packages: dependency: "direct main" description: name: device_info_plus - sha256: "0042cb3b2a76413ea5f8a2b40cec2a33e01d0c937e91f0f7c211fde4f7739ba6" + sha256: "77f757b789ff68e4eaf9c56d1752309bd9f7ad557cb105b938a7f8eb89e59110" url: "https://pub.dev" source: hosted - version: "9.1.1" + version: "9.1.2" device_info_plus_platform_interface: dependency: transitive description: @@ -437,10 +437,10 @@ packages: dependency: transitive description: name: file_selector_platform_interface - sha256: "0aa47a725c346825a2bd396343ce63ac00bda6eff2fbc43eabe99737dede8262" + sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b url: "https://pub.dev" source: hosted - version: "2.6.1" + version: "2.6.2" file_selector_windows: dependency: transitive description: @@ -535,10 +535,10 @@ packages: dependency: "direct main" description: name: flutter_markdown - sha256: "30088ce826b5b9cfbf9e8bece34c716c8a59fa54461dcae1e4ac01a94639e762" + sha256: "21b085a1c185e46701373866144ced56cfb7a0c33f63c916bb8fe2d0c1491278" url: "https://pub.dev" source: hosted - version: "0.6.18+3" + version: "0.6.19" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -676,10 +676,10 @@ packages: dependency: transitive description: name: http - sha256: d4872660c46d929f6b8a9ef4e7a7eff7e49bbf0c4ec3f385ee32df5119175139 + sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.2.0" http_multi_server: dependency: transitive description: @@ -716,34 +716,34 @@ packages: dependency: "direct main" description: name: image_picker - sha256: "340efe08645537d6b088a30620ee5752298b1630f23a829181172610b868262b" + sha256: "26222b01a0c9a2c8fe02fc90b8208bd3325da5ed1f4a2acabf75939031ac0bdd" url: "https://pub.dev" source: hosted - version: "1.0.6" + version: "1.0.7" image_picker_android: dependency: transitive description: name: image_picker_android - sha256: "1a27bf4cc0330389cebe465bab08fe6dec97e44015b4899637344bb7297759ec" + sha256: "39f2bfe497e495450c81abcd44b62f56c2a36a37a175da7d137b4454977b51b1" url: "https://pub.dev" source: hosted - version: "0.8.9+2" + version: "0.8.9+3" image_picker_for_web: dependency: transitive description: name: image_picker_for_web - sha256: "50bc9ae6a77eea3a8b11af5eb6c661eeb858fdd2f734c2a4fd17086922347ef7" + sha256: e2423c53a68b579a7c37a1eda967b8ae536c3d98518e5db95ca1fe5719a730a3 url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.2" image_picker_ios: dependency: transitive description: name: image_picker_ios - sha256: eac0a62104fa12feed213596df0321f57ce5a572562f72a68c4ff81e9e4caacf + sha256: fadafce49e8569257a0cad56d24438a6fa1f0cbd7ee0af9b631f7492818a4ca3 url: "https://pub.dev" source: hosted - version: "0.8.9" + version: "0.8.9+1" image_picker_linux: dependency: transitive description: @@ -764,10 +764,10 @@ packages: dependency: transitive description: name: image_picker_platform_interface - sha256: "0e827c156e3a90edd3bbe7f6de048b39247b16e58173b08a835b7eb00aba239e" + sha256: fa4e815e6fcada50e35718727d83ba1c92f1edf95c0b4436554cec301b56233b url: "https://pub.dev" source: hosted - version: "2.9.2" + version: "2.9.3" image_picker_windows: dependency: transitive description: @@ -845,7 +845,7 @@ packages: description: path: "." ref: HEAD - resolved-ref: "51132be9e19cc091152480278c8139087cec2e58" + resolved-ref: e7eac4b6ad357c498ff7b204891db33b7935b22c url: "https://github.com/Kara-Zor-El/jellybook_epub_view.git" source: git version: "3.0.0" @@ -909,10 +909,10 @@ packages: dependency: transitive description: name: markdown - sha256: acf35edccc0463a9d7384e437c015a3535772e09714cf60e07eeef3a15870dcd + sha256: "1b134d9f8ff2da15cb298efe6cd8b7d2a78958c1b00384ebcbdf13fe340a6c90" url: "https://pub.dev" source: hosted - version: "7.1.1" + version: "7.2.1" matcher: dependency: transitive description: @@ -941,10 +941,10 @@ packages: dependency: transitive description: name: mime - sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e + sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2" url: "https://pub.dev" source: hosted - version: "1.0.4" + version: "1.0.5" nested: dependency: transitive description: @@ -997,10 +997,10 @@ packages: dependency: "direct main" description: name: open_filex - sha256: a6c95237767c5647e68b71a476602fcf4f1bfc530c126265e53addae22ef5fc2 + sha256: "74e2280754cf8161e860746c3181db2c996d6c1909c7057b738ede4a469816b8" url: "https://pub.dev" source: hosted - version: "4.3.4" + version: "4.4.0" openapi: dependency: "direct main" description: @@ -1054,10 +1054,10 @@ 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: @@ -1070,10 +1070,10 @@ packages: 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: @@ -1086,10 +1086,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: @@ -1098,14 +1098,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.2.1" - pdfx_plugin: + pdfx: dependency: "direct main" description: - name: pdfx_plugin - sha256: "174ff8f2d0208c6a7efd6bbca0f8ceefbc3c8af47c64c3e6aad71da16ad3deff" + name: pdfx + sha256: c0f70ab6691b7cde02c0c204763a1edb2689ce245ac34eb629c66273a6aa1caf url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "2.6.0" pedantic: dependency: transitive description: @@ -1118,50 +1118,50 @@ packages: dependency: "direct main" description: name: permission_handler - sha256: "860c6b871c94c78e202dc69546d4d8fd84bd59faeb36f8fb9888668a53ff4f78" + sha256: "74e962b7fad7ff75959161bb2c0ad8fe7f2568ee82621c9c2660b751146bfe44" url: "https://pub.dev" source: hosted - version: "11.1.0" + version: "11.3.0" permission_handler_android: dependency: transitive description: name: permission_handler_android - sha256: "2f1bec180ee2f5665c22faada971a8f024761f632e93ddc23310487df52dcfa6" + sha256: "1acac6bae58144b442f11e66621c062aead9c99841093c38f5bcdcc24c1c3474" url: "https://pub.dev" source: hosted - version: "12.0.1" + version: "12.0.5" permission_handler_apple: dependency: transitive description: name: permission_handler_apple - sha256: "1a816084338ada8d574b1cb48390e6e8b19305d5120fe3a37c98825bacc78306" + sha256: bdafc6db74253abb63907f4e357302e6bb786ab41465e8635f362ee71fd8707b url: "https://pub.dev" source: hosted - version: "9.2.0" + version: "9.4.0" permission_handler_html: dependency: transitive description: name: permission_handler_html - sha256: "11b762a8c123dced6461933a88ea1edbbe036078c3f9f41b08886e678e7864df" + sha256: "54bf176b90f6eddd4ece307e2c06cf977fb3973719c35a93b85cc7093eb6070d" url: "https://pub.dev" source: hosted - version: "0.1.0+2" + version: "0.1.1" permission_handler_platform_interface: dependency: transitive description: name: permission_handler_platform_interface - sha256: d87349312f7eaf6ce0adaf668daf700ac5b06af84338bd8b8574dfbd93ffe1a1 + sha256: "23dfba8447c076ab5be3dee9ceb66aad345c4a648f0cac292c77b1eb0e800b78" url: "https://pub.dev" source: hosted - version: "4.0.2" + version: "4.2.0" permission_handler_windows: dependency: transitive description: name: permission_handler_windows - sha256: "1e8640c1e39121128da6b816d236e714d2cf17fac5a105dd6acdd3403a628004" + sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.2.1" petitparser: dependency: transitive description: @@ -1198,10 +1198,10 @@ packages: dependency: transitive description: name: pointycastle - sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c" + sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29" url: "https://pub.dev" source: hosted - version: "3.7.3" + version: "3.7.4" pool: dependency: transitive description: @@ -1318,10 +1318,10 @@ packages: dependency: transitive description: name: shared_preferences_foundation - sha256: "7bf53a9f2d007329ee6f3df7268fd498f8373602f943c975598bbb34649b62a7" + sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c" url: "https://pub.dev" source: hosted - version: "2.3.4" + version: "2.3.5" shared_preferences_linux: dependency: transitive description: @@ -1334,10 +1334,10 @@ packages: dependency: transitive description: name: shared_preferences_platform_interface - sha256: d4ec5fc9ebb2f2e056c617112aa75dcf92fc2e4faaf2ae999caa297473f75d8a + sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" shared_preferences_web: dependency: transitive description: @@ -1451,18 +1451,18 @@ packages: dependency: transitive 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: bb4738f15b23352822f4c42a531677e5c6f522e079461fd240ead29d8d8a54a6 + sha256: "28d8c66baee4968519fb8bd6cdbedad982d6e53359091f0b74544a9f32ec72d5" url: "https://pub.dev" source: hosted - version: "2.5.0+2" + version: "2.5.3" stack_trace: dependency: transitive description: @@ -1555,10 +1555,10 @@ packages: dependency: transitive description: name: time - sha256: "83427e11d9072e038364a5e4da559e85869b227cf699a541be0da74f14140124" + sha256: ad8e018a6c9db36cb917a031853a1aae49467a93e0d464683e029537d848c221 url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.4" timing: dependency: transitive description: @@ -1619,26 +1619,26 @@ packages: dependency: "direct main" description: name: url_launcher - sha256: e9aa5ea75c84cf46b3db4eea212523591211c3cf2e13099ee4ec147f54201c86 + sha256: c512655380d241a337521703af62d2c122bf7b77a46ff7dd750092aa9433499c url: "https://pub.dev" source: hosted - version: "6.2.2" + version: "6.2.4" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: c0766a55ab42cefaa728cabc951e82919ab41a3a4fee0aaa96176ca82da8cc51 + sha256: d4ed0711849dd8e33eb2dd69c25db0d0d3fdc37e0a62e629fe32f57a22db2745 url: "https://pub.dev" source: hosted - version: "6.2.1" + version: "6.3.0" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: "46b81e3109cbb2d6b81702ad3077540789a3e74e22795eb9f0b7d494dbaa72ea" + sha256: "75bb6fe3f60070407704282a2d295630cab232991eb52542b18347a8a941df03" url: "https://pub.dev" source: hosted - version: "6.2.2" + version: "6.2.4" url_launcher_linux: dependency: transitive description: @@ -1659,10 +1659,10 @@ packages: dependency: transitive description: name: url_launcher_platform_interface - sha256: "4aca1e060978e19b2998ee28503f40b5ba6226819c2b5e3e4d1821e8ccd92198" + sha256: a932c3a8082e118f80a475ce692fde89dc20fddb24c57360b96bc56f7035de1f url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.3.1" url_launcher_web: dependency: transitive description: @@ -1683,10 +1683,10 @@ packages: dependency: transitive description: name: uuid - sha256: "22c94e5ad1e75f9934b766b53c742572ee2677c56bc871d850a57dad0f82127f" + sha256: cd210a09f7c18cbe5a02511718e0334de6559871052c90a90c0cca46a4aa81c8 url: "https://pub.dev" source: hosted - version: "4.2.2" + version: "4.3.3" vector_math: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index d3698d1..31fe9eb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -59,7 +59,7 @@ dependencies: flutter_html_to_pdf: ^0.7.0 isar: ^3.0.5 isar_flutter_libs: ^3.0.5 - pdfx_plugin: ^1.1.0 + pdfx: ^2.6.0 package_info_plus: ^5.0.1 auto_size_text: ^3.0.0 google_nav_bar: ^5.0.6 @@ -105,6 +105,7 @@ dev_dependencies: build_runner: ^2.3.2 isar_generator: ^3.0.5 sentry_dart_plugin: ^1.7.0 + analyzer: ^5.13.0 # test: ^1.24.3 # dart_code_linter: ^1.1.1 # objectbox_generator: ^1.6.2 From ab6b013ac3165e007bd7d17744261ec97c96984b Mon Sep 17 00:00:00 2001 From: Kara Date: Wed, 14 Feb 2024 02:55:45 +0000 Subject: [PATCH 22/28] Translated using Weblate (English) Currently translated at 100.0% (102 of 102 strings) Translation: JellyBook/JellyBook App Translate-URL: https://hosted.weblate.org/projects/JellyBook/jellybook-app/en/ --- lib/l10n/app_en.arb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 1ea3efd..2487c22 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -199,5 +199,9 @@ "saveToDevice": "Save to device", "@saveToDevice": {}, "edit": "Edit", - "@edit": {} + "@edit": {}, + "useSentry": "Use Sentry", + "@useSentry": {}, + "sentryExplanation": "Enable Sentry logging to quickly diagnose and fix issues! This provides us with real-time error tracking without compromising your privacy. Please help support JellyBook's development by turning on logging.", + "@sentryExplanation": {} } From d7d6fc08b09d604fbd9267c1f091d18b1d6e787d Mon Sep 17 00:00:00 2001 From: Kara Date: Wed, 14 Feb 2024 04:01:10 +0000 Subject: [PATCH 23/28] Translated using Weblate (English) Currently translated at 100.0% (104 of 104 strings) Translation: JellyBook/JellyBook App Translate-URL: https://hosted.weblate.org/projects/JellyBook/jellybook-app/en/ --- lib/l10n/app_en.arb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 2487c22..dd87ccd 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -203,5 +203,9 @@ "useSentry": "Use Sentry", "@useSentry": {}, "sentryExplanation": "Enable Sentry logging to quickly diagnose and fix issues! This provides us with real-time error tracking without compromising your privacy. Please help support JellyBook's development by turning on logging.", - "@sentryExplanation": {} + "@sentryExplanation": {}, + "yes": "Yes", + "@yes": {}, + "No": "no", + "@No": {} } From 0b8ad7ee897003d46531f629c61968a4f5b32e7f Mon Sep 17 00:00:00 2001 From: Kara Date: Wed, 14 Feb 2024 17:32:04 +0100 Subject: [PATCH 24/28] Translated using Weblate (English) Currently translated at 100.0% (104 of 104 strings) Translation: JellyBook/JellyBook App Translate-URL: https://hosted.weblate.org/projects/JellyBook/jellybook-app/en/ --- lib/l10n/app_en.arb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index dd87ccd..6e1f8c6 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -205,7 +205,5 @@ "sentryExplanation": "Enable Sentry logging to quickly diagnose and fix issues! This provides us with real-time error tracking without compromising your privacy. Please help support JellyBook's development by turning on logging.", "@sentryExplanation": {}, "yes": "Yes", - "@yes": {}, - "No": "no", - "@No": {} + "@yes": {} } From 077fb9ab61d63e8760b143bc21b2748f4d646c11 Mon Sep 17 00:00:00 2001 From: Kara Date: Wed, 14 Feb 2024 16:32:13 +0000 Subject: [PATCH 25/28] Translated using Weblate (English) Currently translated at 100.0% (104 of 104 strings) Translation: JellyBook/JellyBook App Translate-URL: https://hosted.weblate.org/projects/JellyBook/jellybook-app/en/ --- lib/l10n/app_en.arb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 6e1f8c6..5dd0ac7 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -205,5 +205,7 @@ "sentryExplanation": "Enable Sentry logging to quickly diagnose and fix issues! This provides us with real-time error tracking without compromising your privacy. Please help support JellyBook's development by turning on logging.", "@sentryExplanation": {}, "yes": "Yes", - "@yes": {} + "@yes": {}, + "no": "No", + "@no": {} } From b2cd75abff57385573b15412e6f0675a9a5cccc2 Mon Sep 17 00:00:00 2001 From: Kara-Zor-El Date: Wed, 14 Feb 2024 12:16:54 -0500 Subject: [PATCH 26/28] Add sentry to setting and initial popup to main menu --- lib/screens/MainScreens/mainMenu.dart | 50 ++++++++++++++++++++- lib/screens/MainScreens/settingsScreen.dart | 27 +++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/lib/screens/MainScreens/mainMenu.dart b/lib/screens/MainScreens/mainMenu.dart index fbdf973..256575c 100644 --- a/lib/screens/MainScreens/mainMenu.dart +++ b/lib/screens/MainScreens/mainMenu.dart @@ -67,6 +67,7 @@ class _MainMenuState extends State { } bool force = false; + SharedPreferences? prefs; Future _fetchPage(int pageKey) async { logger.i('pageKey: $pageKey'); @@ -91,13 +92,17 @@ class _MainMenuState extends State { } } + Future getSharedPrefs() async { + prefs = await SharedPreferences.getInstance(); + } + @override void initState() { _pagingController.addPageRequestListener((pageKey) { _fetchPage(pageKey); }); super.initState(); - // fetchCategories(); + getSharedPrefs().then((value) => setUseSentry()); } // dispose @@ -106,6 +111,49 @@ class _MainMenuState extends State { super.dispose(); } + bool useSentryNull() { + return prefs?.getBool("useSentry") == null; + } + + Future setUseSentry() async { + if (useSentryNull()) { + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text( + AppLocalizations.of(context)?.useSentry ?? "Use Sentry", + ), + content: Text(AppLocalizations.of(context)?.sentryExplanation ?? + "Enable Sentry logging to quickly diagnose and fix issues! This provides us with real-time error tracking without compromising your privacy. Please help support JellyBook's development by turning on logging."), + actions: [ + TextButton( + onPressed: () { + prefs?.setBool("useSentry", true); + Navigator.of(context).pop(); + // crash app + throw Exception('Test Sentry'); + }, + child: Text( + AppLocalizations.of(context)?.yes ?? "Yes", + ), + ), + TextButton( + onPressed: () { + prefs?.setBool("useSentry", false); + Navigator.of(context).pop(); + }, + child: Text( + AppLocalizations.of(context)?.no ?? "No", + ), + ), + ], + ); + }, + ); + } + } + // should be a futureBuilder @override Widget build(BuildContext context) { diff --git a/lib/screens/MainScreens/settingsScreen.dart b/lib/screens/MainScreens/settingsScreen.dart index b64f4b4..abfc90b 100644 --- a/lib/screens/MainScreens/settingsScreen.dart +++ b/lib/screens/MainScreens/settingsScreen.dart @@ -174,6 +174,15 @@ class _SettingsScreenState extends State { const SizedBox( height: 20, ), + FutureBuilder( + future: useSentrySettings(), + builder: (BuildContext context, AsyncSnapshot snapshot) { + return snapshot.data ?? Container(); + }, + ), + const SizedBox( + height: 20, + ), // experimentalFeaturesSettings(), // button to show log file // logToFile(), @@ -720,4 +729,22 @@ class _SettingsScreenState extends State { ); }, ); + + // useSentry settings + Future useSentrySettings() async => SettingsItem( + // settingKey: 'useSentry', + title: AppLocalizations.of(context)?.useSentry ?? 'Use Sentry', + selected: prefs?.getBool('useSentry').toString() ?? 'false', + backgroundColor: Theme.of(context).splashColor, + icon: Icons.bug_report, + values: { + 'true': AppLocalizations.of(context)?.yes ?? 'Yes', + 'false': AppLocalizations.of(context)?.no ?? 'No', + }, + onChange: (value) async { + debugPrint(value); + prefs?.setBool('useSentry', value.toString() == 'true'); + setState(() {}); + }, + ); } From 8b8c6e469f4c57facc8204cdb6ecced2bc08409d Mon Sep 17 00:00:00 2001 From: Kara-Zor-El Date: Wed, 14 Feb 2024 12:26:30 -0500 Subject: [PATCH 27/28] Version Bump!!!! lets goooo --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 31fe9eb..e16b377 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,7 +17,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.3.0+22 +version: 1.3.1+23 environment: sdk: '>=3.0.0' From 9c588cd02d0c3f0dd93c5c26943d93dd8ac10340 Mon Sep 17 00:00:00 2001 From: Kara-Zor-El Date: Wed, 14 Feb 2024 13:56:18 -0500 Subject: [PATCH 28/28] Thank you's --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 38252b0..e8c97f9 100644 --- a/README.md +++ b/README.md @@ -136,6 +136,8 @@ - Thank you to [u/anekdotos](https://reddit.com/u/anekdotos) on Reddit for donating to the project so it could be published on iOS - Thank you to Weblate for hosting translation - Thank you to IzzyOnDroid for packaging and hosting the app on their repo + - Thank you to [Sentry](https://sentry.io) for providing error tracking (with their open source plan) + - And of course, thank you to all the contributors and users of the app ## 🤔 Why is Development so Slow? - I am a full time student and work part time. I recently had midterms come up which caused me to have to slow down on my working on this project. This project is really fun to work on for me but that being said, without making any money from it or receiving any donations my ability to work on this project is hindered. This is since I do need money to help pay for my education and living expenses. I would really love to be able to work on open source full time but unfortunately that is not possible at this current time to work on it like how I was previously.