From f9dde0f4a4ec56d042aaacac7c627f46c1f67175 Mon Sep 17 00:00:00 2001 From: Yisrael_Rosen <148ylr@gmail.com> Date: Tue, 27 Aug 2024 22:50:36 +0300 Subject: [PATCH 1/9] Prevent duplicate bookmarks and improve user feedback - Updated addBookmark function in AppModel to return a boolean value - Added check to prevent creation of duplicate bookmarks - Updated bookmark addition logic in TextBookViewer and PdfBookViewr - Improved user feedback when adding a bookmark: - "Bookmark added successfully" when a new bookmark is added - "Bookmark already exists" when attempting to add a duplicate bookmark These changes prevent the creation of duplicate bookmarks and provide clear feedback to the user when adding bookmarks, both in text books and PDF books. --- lib/models/app_model.dart | 21 ++++++++++++--- lib/screens/pdf_book_screen.dart | 45 +++++++++++++++++-------------- lib/screens/text_book_screen.dart | 26 +++++++++--------- 3 files changed, 56 insertions(+), 36 deletions(-) diff --git a/lib/models/app_model.dart b/lib/models/app_model.dart index 8d38bd1b..48aacaf5 100644 --- a/lib/models/app_model.dart +++ b/lib/models/app_model.dart @@ -311,21 +311,34 @@ class AppModel with ChangeNotifier { Hive.box(name: 'tabs').put("key-current-tab", currentTab); } - void addBookmark( + bool addBookmark( {required String ref, required Book book, required int index}) { - bookmarks.add(Bookmark(ref: ref, book: book, index: index)); - // write to disk - Hive.box(name: 'bookmarks').put('key-bookmarks', bookmarks); + // Check if a bookmark with the same ref, book, and index already exists + bool bookmarkExists = bookmarks.any((bookmark) => + bookmark.ref == ref && + bookmark.book.title == book.title && + bookmark.index == index); + + if (!bookmarkExists) { + bookmarks.add(Bookmark(ref: ref, book: book, index: index)); + // write to disk + Hive.box(name: 'bookmarks').put('key-bookmarks', bookmarks); + notifyListeners(); + return true; + } + return false; } void removeBookmark(int index) { bookmarks.removeAt(index); Hive.box(name: 'bookmarks').put('key-bookmarks', bookmarks); + notifyListeners(); } void clearBookmarks() { bookmarks.clear(); Hive.box(name: 'bookmarks').clear(); + notifyListeners(); } void addHistory( diff --git a/lib/screens/pdf_book_screen.dart b/lib/screens/pdf_book_screen.dart index 12d2a5d0..11b0a9d6 100644 --- a/lib/screens/pdf_book_screen.dart +++ b/lib/screens/pdf_book_screen.dart @@ -60,31 +60,36 @@ class _PdfBookViewrState extends State ), actions: [ IconButton( - icon: const Icon(Icons.bookmark_add), - tooltip: 'הוספת סימניה', - onPressed: () { - int index = widget.tab.pdfViewerController.isReady - ? widget.tab.pdfViewerController.pageNumber! - : 1; - Provider.of(context, listen: false).addBookmark( - ref: '${widget.tab.title} עמוד $index', - book: widget.tab.book, - index: index); - // notify user - if (mounted) { - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text('הסימניה נוספה בהצלחה'), - ), - ); - } - }), + icon: const Icon( + Icons.bookmark_add, + ), + tooltip: 'הוספת סימניה', + onPressed: () { + int index = widget.tab.pdfViewerController.isReady + ? widget.tab.pdfViewerController.pageNumber! + : 1; + bool bookmarkAdded = Provider.of(context, listen: false).addBookmark( + ref: '${widget.tab.title} עמוד $index', + book: widget.tab.book, + index: index); + // notify user + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(bookmarkAdded + ? 'הסימניה נוספה בהצלחה' + : 'הסימניה כבר קיימת'), + ), + ); + } + }, + ), IconButton( icon: const Icon( Icons.zoom_in, ), tooltip: 'הגדל', - onPressed: () => widget..tab.pdfViewerController.zoomUp(), + onPressed: () => widget.tab.pdfViewerController.zoomUp(), ), IconButton( icon: const Icon(Icons.zoom_out), diff --git a/lib/screens/text_book_screen.dart b/lib/screens/text_book_screen.dart index b1098d63..f55aaf58 100644 --- a/lib/screens/text_book_screen.dart +++ b/lib/screens/text_book_screen.dart @@ -134,21 +134,23 @@ class _TextBookViewerState extends State ), //button to add a bookmark IconButton( - onPressed: () { - () async { - int index = widget - .tab.positionsListener.itemPositions.value.first.index; - Provider.of(context, listen: false).addBookmark( - ref: await utils.refFromIndex( - index, widget.tab.tableOfContents), - book: widget.tab.book, - index: index); - }(); + onPressed: () async { + int index = widget + .tab.positionsListener.itemPositions.value.first.index; + String ref = await utils.refFromIndex( + index, widget.tab.tableOfContents); + bool bookmarkAdded = Provider.of(context, listen: false) + .addBookmark( + ref: ref, + book: widget.tab.book, + index: index); // notify user if (mounted) { ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text('הסימניה נוספה בהצלחה'), + SnackBar( + content: Text(bookmarkAdded + ? 'הסימניה נוספה בהצלחה' + : 'הסימניה כבר קיימת'), ), ); } From 486516e727e540cee0a5b79944d990ac9a130140 Mon Sep 17 00:00:00 2001 From: Yisrael Rosen <57872424+yisrael-rosen@users.noreply.github.com> Date: Tue, 27 Aug 2024 22:57:15 +0300 Subject: [PATCH 2/9] Update app_model.dart Cleanup --- lib/models/app_model.dart | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/models/app_model.dart b/lib/models/app_model.dart index 48aacaf5..bddaa655 100644 --- a/lib/models/app_model.dart +++ b/lib/models/app_model.dart @@ -323,7 +323,6 @@ class AppModel with ChangeNotifier { bookmarks.add(Bookmark(ref: ref, book: book, index: index)); // write to disk Hive.box(name: 'bookmarks').put('key-bookmarks', bookmarks); - notifyListeners(); return true; } return false; @@ -332,13 +331,11 @@ class AppModel with ChangeNotifier { void removeBookmark(int index) { bookmarks.removeAt(index); Hive.box(name: 'bookmarks').put('key-bookmarks', bookmarks); - notifyListeners(); } void clearBookmarks() { bookmarks.clear(); Hive.box(name: 'bookmarks').clear(); - notifyListeners(); } void addHistory( From c96e4c300eb43d5ada4f9fc7b79be2c314730333 Mon Sep 17 00:00:00 2001 From: Yisrael Rosen <57872424+yisrael-rosen@users.noreply.github.com> Date: Tue, 27 Aug 2024 23:02:14 +0300 Subject: [PATCH 3/9] Update pdf_book_screen.dart format --- lib/screens/pdf_book_screen.dart | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/screens/pdf_book_screen.dart b/lib/screens/pdf_book_screen.dart index 11b0a9d6..9fa71075 100644 --- a/lib/screens/pdf_book_screen.dart +++ b/lib/screens/pdf_book_screen.dart @@ -60,7 +60,7 @@ class _PdfBookViewrState extends State ), actions: [ IconButton( - icon: const Icon( + icon: const Icon( Icons.bookmark_add, ), tooltip: 'הוספת סימניה', @@ -68,10 +68,11 @@ class _PdfBookViewrState extends State int index = widget.tab.pdfViewerController.isReady ? widget.tab.pdfViewerController.pageNumber! : 1; - bool bookmarkAdded = Provider.of(context, listen: false).addBookmark( - ref: '${widget.tab.title} עמוד $index', - book: widget.tab.book, - index: index); + bool bookmarkAdded = Provider.of(context, listen: false) + .addBookmark( + ref: '${widget.tab.title} עמוד $index', + book: widget.tab.book, + index: index); // notify user if (mounted) { ScaffoldMessenger.of(context).showSnackBar( From af7b94b59fba274e72682c50fd9dbd494a76fb50 Mon Sep 17 00:00:00 2001 From: Yisrael Rosen <57872424+yisrael-rosen@users.noreply.github.com> Date: Wed, 28 Aug 2024 18:20:06 +0300 Subject: [PATCH 4/9] Fix: Add PDF books to history - Remove condition that only added TextBooks to history --- lib/models/app_model.dart | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/models/app_model.dart b/lib/models/app_model.dart index bddaa655..301c885b 100644 --- a/lib/models/app_model.dart +++ b/lib/models/app_model.dart @@ -340,9 +340,7 @@ class AppModel with ChangeNotifier { void addHistory( {required String ref, required Book book, required int index}) { - if (book is TextBook) { - history.insert(0, Bookmark(ref: ref, book: book, index: index)); - } + history.insert(0, Bookmark(ref: ref, book: book, index: index)); // write to disk Hive.box(name: 'history').put('key-history', history); } From f44fcbacf9d0559b45ed4feabd6368a6cae25e9a Mon Sep 17 00:00:00 2001 From: ShlomoCode <78599753+ShlomoCode@users.noreply.github.com> Date: Wed, 28 Aug 2024 23:53:37 +0300 Subject: [PATCH 5/9] fix: upgrade archive dependency for flutter 3.5.0 https://github.com/jonataslaw/get_cli/issues/263#issuecomment-2273260052 https://github.com/brendan-duncan/archive/issues/350, https://github.com/brendan-duncan/archive/issues/346 --- pubspec.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pubspec.lock b/pubspec.lock index 1f79efd7..2dd4925e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -21,10 +21,10 @@ packages: dependency: transitive description: name: archive - sha256: "22600aa1e926be775fa5fe7e6894e7fb3df9efda8891c73f70fb3262399a432d" + sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d url: "https://pub.dev" source: hosted - version: "3.4.10" + version: "3.6.1" args: dependency: transitive description: From da60ef738be39494a7807f17c920d04d7b59fb5e Mon Sep 17 00:00:00 2001 From: Shlomo <78599753+ShlomoCode@users.noreply.github.com> Date: Thu, 29 Aug 2024 14:03:29 +0300 Subject: [PATCH 6/9] chore: create conventional-pr-title.yml (#209) --- .github/workflows/conventional-pr-title.yml | 44 +++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 .github/workflows/conventional-pr-title.yml diff --git a/.github/workflows/conventional-pr-title.yml b/.github/workflows/conventional-pr-title.yml new file mode 100644 index 00000000..4fd3e664 --- /dev/null +++ b/.github/workflows/conventional-pr-title.yml @@ -0,0 +1,44 @@ +name: "Conventional PR Title" + +on: + pull_request_target: + types: + - opened + - reopened + - edited + - synchronize + +permissions: + pull-requests: write + +jobs: + main: + name: Validate PR title + runs-on: ubuntu-latest + steps: + - uses: amannn/action-semantic-pull-request@v5 + id: lint_pr_title + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - uses: marocchino/sticky-pull-request-comment@v2 + # When the previous steps fails, the workflow would stop. By adding this + # condition you can continue the execution with the populated error message. + if: always() && (steps.lint_pr_title.outputs.error_message != null) + with: + header: pr-title-lint-error + message: | + Hey there and thank you for opening this pull request! 👋🏼 + + We require pull request titles to follow the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/) and it looks like your proposed title needs to be adjusted. + Details: + + ``` + ${{ steps.lint_pr_title.outputs.error_message }} + ``` + # Delete a previous comment when the issue has been resolved + - if: ${{ steps.lint_pr_title.outputs.error_message == null }} + uses: marocchino/sticky-pull-request-comment@v2 + with: + header: pr-title-lint-error + delete: true From 2d1bcbb234fe5f512ef6a2df3a8d5107643dc6e0 Mon Sep 17 00:00:00 2001 From: Shlomo <78599753+ShlomoCode@users.noreply.github.com> Date: Thu, 29 Aug 2024 14:04:13 +0300 Subject: [PATCH 7/9] chore: automatic Flutter-generated changes for iOS and macOS (#210) * refactor(macos): replace deprecated `@NSApplicationMain` with `@main` Automatic update by Flutter * chore(ios/macos): integrate CocoaPods for dependency management The following changes were automatically generated by Flutter: - Add Podfile configurations to iOS and macOS projects - Update Xcode project settings for CocoaPods usage - Upgrade macOS Runner scheme to Xcode 15.1 - Create Podfile and Podfile.lock files in iOS and macOS directories --- ios/Flutter/Debug.xcconfig | 1 + ios/Flutter/Release.xcconfig | 1 + ios/Podfile | 44 ++++++++ macos/Flutter/Flutter-Debug.xcconfig | 1 + macos/Flutter/Flutter-Release.xcconfig | 1 + macos/Podfile | 43 ++++++++ macos/Podfile.lock | 73 +++++++++++++ macos/Runner.xcodeproj/project.pbxproj | 100 +++++++++++++++++- .../xcshareddata/xcschemes/Runner.xcscheme | 2 +- .../contents.xcworkspacedata | 3 + macos/Runner/AppDelegate.swift | 2 +- 11 files changed, 267 insertions(+), 4 deletions(-) create mode 100644 ios/Podfile create mode 100644 macos/Podfile create mode 100644 macos/Podfile.lock diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig index 592ceee8..ec97fc6f 100644 --- a/ios/Flutter/Debug.xcconfig +++ b/ios/Flutter/Debug.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig index 592ceee8..c4855bfe 100644 --- a/ios/Flutter/Release.xcconfig +++ b/ios/Flutter/Release.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" diff --git a/ios/Podfile b/ios/Podfile new file mode 100644 index 00000000..d97f17e2 --- /dev/null +++ b/ios/Podfile @@ -0,0 +1,44 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '12.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) + target 'RunnerTests' do + inherit! :search_paths + end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/macos/Flutter/Flutter-Debug.xcconfig b/macos/Flutter/Flutter-Debug.xcconfig index c2efd0b6..4b81f9b2 100644 --- a/macos/Flutter/Flutter-Debug.xcconfig +++ b/macos/Flutter/Flutter-Debug.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" diff --git a/macos/Flutter/Flutter-Release.xcconfig b/macos/Flutter/Flutter-Release.xcconfig index c2efd0b6..5caa9d15 100644 --- a/macos/Flutter/Flutter-Release.xcconfig +++ b/macos/Flutter/Flutter-Release.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" diff --git a/macos/Podfile b/macos/Podfile new file mode 100644 index 00000000..c795730d --- /dev/null +++ b/macos/Podfile @@ -0,0 +1,43 @@ +platform :osx, '10.14' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_macos_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) + target 'RunnerTests' do + inherit! :search_paths + end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_macos_build_settings(target) + end +end diff --git a/macos/Podfile.lock b/macos/Podfile.lock new file mode 100644 index 00000000..ce181209 --- /dev/null +++ b/macos/Podfile.lock @@ -0,0 +1,73 @@ +PODS: + - FlutterMacOS (1.0.0) + - isar_flutter_libs (1.0.0): + - FlutterMacOS + - package_info_plus (0.0.1): + - FlutterMacOS + - path_provider_foundation (0.0.1): + - Flutter + - FlutterMacOS + - pdfrx (0.0.1): + - Flutter + - FlutterMacOS + - printing (1.0.0): + - FlutterMacOS + - screen_retriever (0.0.1): + - FlutterMacOS + - shared_preferences_foundation (0.0.1): + - Flutter + - FlutterMacOS + - url_launcher_macos (0.0.1): + - FlutterMacOS + - window_manager (0.2.0): + - FlutterMacOS + +DEPENDENCIES: + - FlutterMacOS (from `Flutter/ephemeral`) + - isar_flutter_libs (from `Flutter/ephemeral/.symlinks/plugins/isar_flutter_libs/macos`) + - package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`) + - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`) + - pdfrx (from `Flutter/ephemeral/.symlinks/plugins/pdfrx/darwin`) + - printing (from `Flutter/ephemeral/.symlinks/plugins/printing/macos`) + - screen_retriever (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos`) + - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`) + - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) + - window_manager (from `Flutter/ephemeral/.symlinks/plugins/window_manager/macos`) + +EXTERNAL SOURCES: + FlutterMacOS: + :path: Flutter/ephemeral + isar_flutter_libs: + :path: Flutter/ephemeral/.symlinks/plugins/isar_flutter_libs/macos + package_info_plus: + :path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos + path_provider_foundation: + :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin + pdfrx: + :path: Flutter/ephemeral/.symlinks/plugins/pdfrx/darwin + printing: + :path: Flutter/ephemeral/.symlinks/plugins/printing/macos + screen_retriever: + :path: Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos + shared_preferences_foundation: + :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin + url_launcher_macos: + :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos + window_manager: + :path: Flutter/ephemeral/.symlinks/plugins/window_manager/macos + +SPEC CHECKSUMS: + FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 + isar_flutter_libs: 43385c99864c168fadba7c9adeddc5d38838ca6a + package_info_plus: fa739dd842b393193c5ca93c26798dff6e3d0e0c + path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c + pdfrx: 8c711fadb19f76c70e3326ceaa718fe4b6703c37 + printing: 1dd6a1fce2209ec240698e2439a4adbb9b427637 + screen_retriever: 59634572a57080243dd1bf715e55b6c54f241a38 + shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695 + url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95 + window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8 + +PODFILE CHECKSUM: 236401fc2c932af29a9fcf0e97baeeb2d750d367 + +COCOAPODS: 1.15.2 diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 800198d4..c95cd921 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -27,6 +27,8 @@ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; + 79F23E06B00A5FF06E565027 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A84E11165A38C1F48CD6CF0B /* Pods_Runner.framework */; }; + E33C2F452CB68412250286D2 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E53B3BB205F534BB0D1D28E9 /* Pods_RunnerTests.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -60,11 +62,12 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 117DDBEBB841300EE3C59E5A /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; 331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; - 33CC10ED2044A3C60003C045 /* otzaria.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "otzaria.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10ED2044A3C60003C045 /* otzaria.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = otzaria.app; sourceTree = BUILT_PRODUCTS_DIR; }; 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; @@ -76,8 +79,15 @@ 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 49FE1A282605E6CCFD3CF46B /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 4ADB39DDCF482AB72B8C172A /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; + 5A86C986B7373DFCF97FE8CD /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 9341277F1DF77B60AC337BC8 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + A84E11165A38C1F48CD6CF0B /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + B150B28F8705627EBC9FF79D /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + E53B3BB205F534BB0D1D28E9 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -85,6 +95,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + E33C2F452CB68412250286D2 /* Pods_RunnerTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -92,6 +103,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 79F23E06B00A5FF06E565027 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -125,6 +137,7 @@ 331C80D6294CF71000263BE5 /* RunnerTests */, 33CC10EE2044A3C60003C045 /* Products */, D73912EC22F37F3D000D13A0 /* Frameworks */, + A2B778A93A09DF5D32B14690 /* Pods */, ); sourceTree = ""; }; @@ -172,9 +185,25 @@ path = Runner; sourceTree = ""; }; + A2B778A93A09DF5D32B14690 /* Pods */ = { + isa = PBXGroup; + children = ( + B150B28F8705627EBC9FF79D /* Pods-Runner.debug.xcconfig */, + 49FE1A282605E6CCFD3CF46B /* Pods-Runner.release.xcconfig */, + 5A86C986B7373DFCF97FE8CD /* Pods-Runner.profile.xcconfig */, + 9341277F1DF77B60AC337BC8 /* Pods-RunnerTests.debug.xcconfig */, + 4ADB39DDCF482AB72B8C172A /* Pods-RunnerTests.release.xcconfig */, + 117DDBEBB841300EE3C59E5A /* Pods-RunnerTests.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; D73912EC22F37F3D000D13A0 /* Frameworks */ = { isa = PBXGroup; children = ( + A84E11165A38C1F48CD6CF0B /* Pods_Runner.framework */, + E53B3BB205F534BB0D1D28E9 /* Pods_RunnerTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -186,6 +215,7 @@ isa = PBXNativeTarget; buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( + FEBB8F16F1A0F41D8C028E29 /* [CP] Check Pods Manifest.lock */, 331C80D1294CF70F00263BE5 /* Sources */, 331C80D2294CF70F00263BE5 /* Frameworks */, 331C80D3294CF70F00263BE5 /* Resources */, @@ -204,11 +234,13 @@ isa = PBXNativeTarget; buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + 3A513D6542A3247C4936F15C /* [CP] Check Pods Manifest.lock */, 33CC10E92044A3C60003C045 /* Sources */, 33CC10EA2044A3C60003C045 /* Frameworks */, 33CC10EB2044A3C60003C045 /* Resources */, 33CC110E2044A8840003C045 /* Bundle Framework */, 3399D490228B24CF009A79C7 /* ShellScript */, + 916C0D27308C0DAB3ECEC970 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -227,7 +259,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 1430; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 331C80D4294CF70F00263BE5 = { @@ -328,6 +360,67 @@ shellPath = /bin/sh; shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; }; + 3A513D6542A3247C4936F15C /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 916C0D27308C0DAB3ECEC970 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + FEBB8F16F1A0F41D8C028E29 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -379,6 +472,7 @@ /* Begin XCBuildConfiguration section */ 331C80DB294CF71000263BE5 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 9341277F1DF77B60AC337BC8 /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; @@ -393,6 +487,7 @@ }; 331C80DC294CF71000263BE5 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 4ADB39DDCF482AB72B8C172A /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; @@ -407,6 +502,7 @@ }; 331C80DD294CF71000263BE5 /* Profile */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 117DDBEBB841300EE3C59E5A /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; diff --git a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index be70ebf0..91e724de 100644 --- a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ + + diff --git a/macos/Runner/AppDelegate.swift b/macos/Runner/AppDelegate.swift index d53ef643..8e02df28 100644 --- a/macos/Runner/AppDelegate.swift +++ b/macos/Runner/AppDelegate.swift @@ -1,7 +1,7 @@ import Cocoa import FlutterMacOS -@NSApplicationMain +@main class AppDelegate: FlutterAppDelegate { override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { return true From b18807656ef774b2d989686074643633fbbd306d Mon Sep 17 00:00:00 2001 From: Sivan Ratson <89018301+Sivan22@users.noreply.github.com> Date: Thu, 29 Aug 2024 14:13:42 +0300 Subject: [PATCH 8/9] Update README.md --- README.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d8dbf3ec..c71336c3 100644 --- a/README.md +++ b/README.md @@ -87,6 +87,7 @@ Key features of the project: * The app is designed to be as user friendly as possible. * A thorough selection process has been undertaken to ensure that the books are suitable for the Torah community * the library is flexible, means that you can add or remove books from the library. +* fast search engine, including the user-added books. * the app supports the following formats: TXT, Docx and PDF. I hope that my work will help the Torah community to learn easiely and effectively anytime and anywhere. @@ -151,15 +152,12 @@ See the Wiki section for documentation. ## Roadmap -- [ ] Add ViewModel layer -- [ ] Transfer database to isar +- [ ] Add business logic layer by switching the state management library to Bloc. +- [ ] Transfer books data from text files to SQLite database +- [ ] add option for semantic search using an embedding ML model and vector database - [ ] language Support - [ ] English - [X] Hebrew -- [ ] full-text search with index -- [ ] add more features - - [ ] search for references - - [ ] save history See the [open issues](https://github.com/sivan22/otzaria/issues) for a full list of proposed features (and known issues). From 3c6ed2446ad76be37aed92f25ed98a6ef762601e Mon Sep 17 00:00:00 2001 From: Y-PLONI <7353755@gmail.com> Date: Thu, 29 Aug 2024 22:28:10 +0300 Subject: [PATCH 9/9] =?UTF-8?q?=D7=AA=D7=99=D7=A7=D7=95=D7=9F=20=D7=A7?= =?UTF-8?q?=D7=95=D7=91=D7=A5=20=D7=94MD=20=D7=A2=D7=9D=20=D7=93=D7=99?= =?UTF-8?q?=D7=A7=D7=98=D7=94=20(#205)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add files via upload * Rename icra_logo.jpg to dicta_logo.jpg * Add files via upload * Update README.md * Update README.md * Update README.md --- README.md | 8 ++++++-- images/dicta_logo.jpg | Bin 0 -> 14435 bytes images/safria logo.png | Bin 0 -> 9228 bytes 3 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 images/dicta_logo.jpg create mode 100644 images/safria logo.png diff --git a/README.md b/README.md index c71336c3..860f175b 100644 --- a/README.md +++ b/README.md @@ -209,8 +209,12 @@ Project Link: [https://github.com/sivan22/otzaria](https://github.com/sivan22/ot ## Acknowledgments the project was avavilable because of Sefaria's amazing project. - -drawing +
+and Dicta association, by which many important books were added. +
+
+ספריא +דיקטה the PDF viewer is powered by [pdfrx](https://pub.dev/packages/pdfrx). diff --git a/images/dicta_logo.jpg b/images/dicta_logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ce104c4da17cbfed3c4d10dfa68b89d53c0697ac GIT binary patch literal 14435 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 T_s=h${8I=1kLUmo=g)ru^cZ2; literal 0 HcmV?d00001 diff --git a/images/safria logo.png b/images/safria logo.png new file mode 100644 index 0000000000000000000000000000000000000000..78ff5a1cf12aafff1181bfc77f6dba158a0cd68c GIT binary patch literal 9228 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 literal 0 HcmV?d00001