From 3835b6ac2ea9d68dfa33e9f143092ba7ac4ae807 Mon Sep 17 00:00:00 2001 From: Stefano Sansone Date: Wed, 7 Feb 2024 17:33:28 +0000 Subject: [PATCH] refactor packages --- android/Omnivore/app/build.gradle | 84 +-- .../Omnivore/app/src/main/AndroidManifest.xml | 6 +- .../app/omnivore/omnivore/EventTracker.kt | 45 -- .../app/omnivore/omnivore/MainActivity.kt | 18 +- .../main/java/app/omnivore/omnivore/Routes.kt | 11 - .../omnivore/core/analytics/EventTracker.kt | 45 ++ .../{dataService => core/data}/DataService.kt | 10 +- .../data}/HighlightActionHandlers.kt | 17 +- .../{dataService => core/data}/LibrarySync.kt | 13 +- .../{dataService => core/data}/NanoId.kt | 2 +- .../data}/ReadingProgressChangeHandler.kt | 8 +- .../data}/SavedItemLabelSync.kt | 4 +- .../data}/SavedItemMenuActionHandlers.kt | 11 +- .../data}/SyncOfflineChanges.kt | 19 +- .../omnivore/core/database/AppDatabase.kt | 42 ++ .../{persistence => core/database}/BaseDao.kt | 2 +- .../database}/entities/Highlight.kt | 4 +- .../database}/entities/HighlightChange.kt | 6 +- .../database}/entities/NewsletterEmail.kt | 2 +- .../database}/entities/RecentSearchItem.kt | 2 +- .../database}/entities/Recommendation.kt | 2 +- .../database}/entities/RecommendationGroup.kt | 2 +- .../database}/entities/SavedItem.kt | 5 +- .../database}/entities/SavedItemLabel.kt | 4 +- .../database}/entities/UserProfile.kt | 2 +- .../database}/entities/Viewer.kt | 3 +- .../datastore}/DatastoreRepository.kt | 4 +- .../omnivore/core/model/ServerSyncStatus.kt | 10 + .../{ => core}/network/HighlightMutations.kt | 4 +- .../omnivore/{ => core}/network/Networker.kt | 8 +- .../{ => core/network}/RESTNetworker.kt | 3 +- .../network/ReadingProgressMutations.kt | 2 +- .../network/SavedItemLabelMutations.kt | 2 +- .../{ => core}/network/SavedItemLabelQuery.kt | 4 +- .../{ => core}/network/SavedItemMutations.kt | 2 +- .../{ => core}/network/SavedItemQuery.kt | 8 +- .../network/SavedItemUpdatesQuery.kt | 2 +- .../{ => core}/network/SearchQuery.kt | 8 +- .../{ => core}/network/TypeaheadSearch.kt | 4 +- .../{ => core}/network/ViewerQuery.kt | 4 +- .../omnivore/omnivore/{ => di}/AppModule.kt | 9 +- .../omnivore/{ui => feature}/LabelUtils.kt | 12 +- .../{ui => feature}/ResourceProvider.kt | 2 +- .../{ui => feature}/auth/AppleAuth.kt | 4 +- .../{ui => feature}/auth/AuthUtils.kt | 2 +- .../{ui => feature}/auth/CreateUserProfile.kt | 2 +- .../{ui => feature}/auth/EmailLogin.kt | 4 +- .../{ui => feature}/auth/EmailSignUpView.kt | 4 +- .../{ui => feature}/auth/GoogleAuth.kt | 2 +- .../auth/LoadingButtonWithIcon.kt | 2 +- .../{ui => feature}/auth/LoginViewModel.kt | 25 +- .../{ui => feature}/auth/SelfHostedView.kt | 13 +- .../{ui => feature}/auth/WelcomeScreen.kt | 4 +- .../components/AddLinkSheet.kt | 7 +- .../components/HighlightColor.kt | 2 +- .../components/HighlightColorPalette.kt | 2 +- .../components/HighlightColorPaletteItem.kt | 2 +- .../components/HighlightColorPaletteMode.kt | 2 +- .../components/LabelChipColors.kt | 2 +- .../components/LabelCreationDialog.kt | 2 +- .../feature/components/LabelFilterChip.kt | 47 ++ .../components/LabelSelectionSheetContent.kt | 144 +++++ .../components/LabelsSelectionSheet.kt | 16 +- .../components/LabelsViewModel.kt | 6 +- .../components/SegmentedControl.kt | 2 +- .../{ui => feature}/editinfo/EditInfoSheet.kt | 3 +- .../editinfo/EditInfoViewModel.kt | 12 +- .../library/LibraryBottomSheetState.kt | 2 +- .../library/LibraryFilterBar.kt | 6 +- .../feature/library/LibraryNavigationBar.kt | 234 ++++++++ .../{ui => feature}/library/LibraryView.kt | 28 +- .../library/LibraryViewModel.kt | 63 ++- .../library/SavedItemFilter.kt | 2 +- .../library/SavedItemLibraryContextMenu.kt | 48 ++ .../feature/library/SavedItemSortFilter.kt | 39 ++ .../library/SavedItemViewModel.kt | 4 +- .../omnivore/feature/library/SearchView.kt | 226 ++++++++ .../library/SearchViewModel.kt | 79 ++- .../{ui => feature}/notebook/NotebookView.kt | 9 +- .../notebook/NotebookViewModel.kt | 14 +- .../reader/AnnotationEditView.kt | 6 +- .../{ui => feature}/reader/OpenLinkView.kt | 2 +- .../{ui => feature}/reader/PDFReader.kt | 4 +- .../reader/PDFReaderViewModel.kt | 17 +- .../reader/ReaderPreferencesView.kt | 4 +- .../{ui => feature}/reader/WebReader.kt | 2 +- .../reader/WebReaderContent.kt | 6 +- .../reader/WebReaderLoadingContainer.kt | 528 ++++++++++++++++++ .../reader/WebReaderViewModel.kt | 58 +- .../omnivore/{ui => feature}/root/RootView.kt | 28 +- .../{ui => feature}/save/SaveContent.kt | 4 +- .../{ui => feature}/save/SaveSheetActivity.kt | 3 +- .../{ui => feature}/save/SaveViewModel.kt | 10 +- .../savedItemViews/SavedItemCard.kt | 21 +- .../savedItemViews/SavedItemContextMenu.kt | 72 +++ .../savedItemViews/TypeaheadSearchCard.kt | 6 +- .../{ui => feature}/settings/LogoutDialog.kt | 2 +- .../{ui => feature}/settings/ManageAccount.kt | 2 +- .../{ui => feature}/settings/PolicyWebView.kt | 4 +- .../settings/SettingsContent.kt | 6 +- .../settings/SettingsViewModel.kt | 12 +- .../omnivore/{ui => feature}/theme/Color.kt | 2 +- .../omnivore/{ui => feature}/theme/Shape.kt | 2 +- .../omnivore/{ui => feature}/theme/Theme.kt | 2 +- .../omnivore/{ui => feature}/theme/Type.kt | 2 +- .../omnivore/models/ServerSyncStatus.kt | 10 - .../omnivore/omnivore/navigation/Routes.kt | 11 + .../omnivore/persistence/AppDatabase.kt | 28 - .../omnivore/ui/components/LabelChip.kt | 33 -- .../ui/library/LibraryNavigationBar.kt | 276 --------- .../ui/library/SavedItemSortFilter.kt | 35 -- .../omnivore/ui/library/SearchView.kt | 199 ------- .../ui/reader/WebReaderLoadingContainer.kt | 473 ---------------- .../ui/savedItemViews/SavedItemContextMenu.kt | 119 ---- .../omnivore/{ => utils}/Constants.kt | 4 +- .../app/src/main/res/values/strings.xml | 2 + android/Omnivore/build.gradle | 9 +- android/Omnivore/gradle.properties | 1 - 118 files changed, 1906 insertions(+), 1621 deletions(-) delete mode 100644 android/Omnivore/app/src/main/java/app/omnivore/omnivore/EventTracker.kt delete mode 100644 android/Omnivore/app/src/main/java/app/omnivore/omnivore/Routes.kt create mode 100644 android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/analytics/EventTracker.kt rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{dataService => core/data}/DataService.kt (73%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{dataService => core/data}/HighlightActionHandlers.kt (90%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{dataService => core/data}/LibrarySync.kt (90%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{dataService => core/data}/NanoId.kt (99%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{dataService => core/data}/ReadingProgressChangeHandler.kt (81%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{dataService => core/data}/SavedItemLabelSync.kt (59%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{dataService => core/data}/SavedItemMenuActionHandlers.kt (86%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{dataService => core/data}/SyncOfflineChanges.kt (89%) create mode 100644 android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/AppDatabase.kt rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{persistence => core/database}/BaseDao.kt (94%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{persistence => core/database}/entities/Highlight.kt (96%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{persistence => core/database}/entities/HighlightChange.kt (95%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{persistence => core/database}/entities/NewsletterEmail.kt (79%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{persistence => core/database}/entities/RecentSearchItem.kt (78%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{persistence => core/database}/entities/Recommendation.kt (82%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{persistence => core/database}/entities/RecommendationGroup.kt (87%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{persistence => core/database}/entities/SavedItem.kt (98%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{persistence => core/database}/entities/SavedItemLabel.kt (94%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{persistence => core/database}/entities/UserProfile.kt (79%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{persistence => core/database}/entities/Viewer.kt (84%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ => core/datastore}/DatastoreRepository.kt (94%) create mode 100644 android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/model/ServerSyncStatus.kt rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ => core}/network/HighlightMutations.kt (98%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ => core}/network/Networker.kt (77%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ => core/network}/RESTNetworker.kt (96%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ => core}/network/ReadingProgressMutations.kt (97%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ => core}/network/SavedItemLabelMutations.kt (95%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ => core}/network/SavedItemLabelQuery.kt (85%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ => core}/network/SavedItemMutations.kt (98%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ => core}/network/SavedItemQuery.kt (94%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ => core}/network/SavedItemUpdatesQuery.kt (97%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ => core}/network/SearchQuery.kt (92%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ => core}/network/TypeaheadSearch.kt (88%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ => core}/network/ViewerQuery.kt (83%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ => di}/AppModule.kt (71%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/LabelUtils.kt (84%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/ResourceProvider.kt (91%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/auth/AppleAuth.kt (96%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/auth/AuthUtils.kt (96%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/auth/CreateUserProfile.kt (99%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/auth/EmailLogin.kt (98%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/auth/EmailSignUpView.kt (98%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/auth/GoogleAuth.kt (98%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/auth/LoadingButtonWithIcon.kt (98%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/auth/LoginViewModel.kt (91%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/auth/SelfHostedView.kt (93%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/auth/WelcomeScreen.kt (98%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/components/AddLinkSheet.kt (96%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/components/HighlightColor.kt (75%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/components/HighlightColorPalette.kt (97%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/components/HighlightColorPaletteItem.kt (96%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/components/HighlightColorPaletteMode.kt (76%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/components/LabelChipColors.kt (90%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/components/LabelCreationDialog.kt (99%) create mode 100644 android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/LabelFilterChip.kt create mode 100644 android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/LabelSelectionSheetContent.kt rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/components/LabelsSelectionSheet.kt (96%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/components/LabelsViewModel.kt (88%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/components/SegmentedControl.kt (98%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/editinfo/EditInfoSheet.kt (98%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/editinfo/EditInfoViewModel.kt (91%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/library/LibraryBottomSheetState.kt (65%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/library/LibraryFilterBar.kt (96%) create mode 100644 android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/LibraryNavigationBar.kt rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/library/LibraryView.kt (95%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/library/LibraryViewModel.kt (88%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/library/SavedItemFilter.kt (97%) create mode 100644 android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/SavedItemLibraryContextMenu.kt create mode 100644 android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/SavedItemSortFilter.kt rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/library/SavedItemViewModel.kt (70%) create mode 100644 android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/SearchView.kt rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/library/SearchViewModel.kt (72%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/notebook/NotebookView.kt (98%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/notebook/NotebookViewModel.kt (82%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/reader/AnnotationEditView.kt (91%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/reader/OpenLinkView.kt (98%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/reader/PDFReader.kt (99%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/reader/PDFReaderViewModel.kt (92%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/reader/ReaderPreferencesView.kt (98%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/reader/WebReader.kt (99%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/reader/WebReaderContent.kt (96%) create mode 100644 android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReaderLoadingContainer.kt rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/reader/WebReaderViewModel.kt (92%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/root/RootView.kt (79%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/save/SaveContent.kt (95%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/save/SaveSheetActivity.kt (98%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/save/SaveViewModel.kt (93%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/savedItemViews/SavedItemCard.kt (93%) create mode 100644 android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/savedItemViews/SavedItemContextMenu.kt rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/savedItemViews/TypeaheadSearchCard.kt (90%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/settings/LogoutDialog.kt (96%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/settings/ManageAccount.kt (97%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/settings/PolicyWebView.kt (96%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/settings/SettingsContent.kt (97%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/settings/SettingsViewModel.kt (75%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/theme/Color.kt (98%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/theme/Shape.kt (85%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/theme/Theme.kt (98%) rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ui => feature}/theme/Type.kt (96%) delete mode 100644 android/Omnivore/app/src/main/java/app/omnivore/omnivore/models/ServerSyncStatus.kt create mode 100644 android/Omnivore/app/src/main/java/app/omnivore/omnivore/navigation/Routes.kt delete mode 100644 android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/AppDatabase.kt delete mode 100644 android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelChip.kt delete mode 100644 android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryNavigationBar.kt delete mode 100644 android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/SavedItemSortFilter.kt delete mode 100644 android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/SearchView.kt delete mode 100644 android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderLoadingContainer.kt delete mode 100644 android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/savedItemViews/SavedItemContextMenu.kt rename android/Omnivore/app/src/main/java/app/omnivore/omnivore/{ => utils}/Constants.kt (94%) diff --git a/android/Omnivore/app/build.gradle b/android/Omnivore/app/build.gradle index c206af119..e847b3c50 100644 --- a/android/Omnivore/app/build.gradle +++ b/android/Omnivore/app/build.gradle @@ -67,45 +67,52 @@ android { targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = "1.8" } buildFeatures { compose true + buildConfig true } composeOptions { - kotlinCompilerExtensionVersion = '1.3.1' + kotlinCompilerExtensionVersion = "1.5.8" } packagingOptions { resources { excludes += '/META-INF/{AL2.0,LGPL2.1}' } } - namespace 'app.omnivore.omnivore' + namespace "app.omnivore.omnivore" } dependencies { - def nav_version = "2.5.3" + def nav_version = "" implementation("androidx.core:core-ktx:1.12.0") - implementation "androidx.compose.ui:ui:$compose_version" - implementation "androidx.compose.material:material:$compose_version" - implementation "androidx.compose.ui:ui-tooling-preview:$compose_version" - implementation "androidx.compose.material:material-icons-extended:$compose_version" - implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' - implementation 'androidx.activity:activity-compose:1.8.2' - implementation 'androidx.appcompat:appcompat:1.5.1' - implementation 'com.google.android.gms:play-services-base:18.1.0' + implementation("androidx.appcompat:appcompat:1.6.1") + implementation("com.google.android.gms:play-services-base:18.3.0") + implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.7.0") - implementation "androidx.navigation:navigation-compose:$nav_version" + // Compose + def composeBom = platform('androidx.compose:compose-bom:2024.01.00') + implementation(composeBom) + androidTestImplementation(composeBom) - testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.ext:junit:1.1.4' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0' - androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version" - debugImplementation "androidx.compose.ui:ui-tooling:$compose_version" - debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version" + implementation("androidx.compose.material3:material3") + implementation("androidx.compose.ui:ui:") + implementation("androidx.compose.material:material") + implementation("androidx.compose.ui:ui-tooling-preview") + implementation("androidx.compose.material:material-icons-extended") + implementation("androidx.activity:activity-compose:1.8.2") + implementation("androidx.navigation:navigation-compose:2.7.6") + androidTestImplementation("androidx.compose.ui:ui-test-junit4") + debugImplementation("androidx.compose.ui:ui-tooling") + debugImplementation("androidx.compose.ui:ui-test-manifest") + + // Testing + testImplementation("junit:junit:4.13.2") + androidTestImplementation("androidx.test.ext:junit:1.1.5") + androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") - // Jetpack Lifecycle deps // ViewModel implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version") @@ -114,7 +121,7 @@ dependencies { // LiveData implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version") - implementation("androidx.compose.runtime:runtime-livedata:1.3.2") + implementation("androidx.compose.runtime:runtime-livedata:1.6.0") // Saved state module for ViewModel implementation("androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version") @@ -126,8 +133,8 @@ dependencies { implementation 'com.squareup.retrofit2:retrofit:2.9.0' // coroutines - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4' - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4' + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3' + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3' implementation "androidx.security:security-crypto:1.0.0" implementation "androidx.datastore:datastore-preferences:1.0.0" @@ -138,29 +145,28 @@ dependencies { implementation("com.apollographql.apollo3:apollo-runtime:3.8.2") - implementation("androidx.compose.material3:material3:1.1.2") - implementation 'androidx.compose.material3:material3-window-size-class:1.1.2' - implementation 'com.google.android.gms:play-services-auth:20.4.0' - implementation "com.google.accompanist:accompanist-systemuicontroller:0.25.1" - implementation "com.google.accompanist:accompanist-flowlayout:0.25.1" - implementation 'io.coil-kt:coil-compose:2.3.0' + implementation("com.google.android.gms:play-services-auth:20.7.0") + implementation("com.google.accompanist:accompanist-systemuicontroller:0.34.0") + implementation("com.google.accompanist:accompanist-flowlayout:0.32.0") - implementation 'com.google.code.gson:gson:2.9.0' - implementation 'com.pspdfkit:pspdfkit:8.9.1' + implementation("io.coil-kt:coil-compose:2.5.0") - implementation 'com.posthog.android:posthog:2.0.3' - implementation 'io.intercom.android:intercom-sdk:15.1.0' + implementation("com.google.code.gson:gson:2.10") + implementation("com.pspdfkit:pspdfkit:8.9.1") + + implementation("com.posthog.android:posthog:2.0.3") + implementation("io.intercom.android:intercom-sdk:15.1.0") // Room Deps - implementation "androidx.room:room-runtime:$room_version" - implementation "androidx.room:room-ktx:$room_version" - annotationProcessor "androidx.room:room-compiler:$room_version" - kapt "androidx.room:room-compiler:$room_version" + implementation("androidx.room:room-runtime:$room_version") + implementation("androidx.room:room-ktx:$room_version") + annotationProcessor("androidx.room:room-compiler:$room_version") + kapt("androidx.room:room-compiler:$room_version") - implementation 'com.github.jeziellago:compose-markdown:0.3.3' - implementation "io.github.dokar3:chiptextfield:0.4.7" + implementation("com.github.jeziellago:compose-markdown:0.3.3") + implementation("io.github.dokar3:chiptextfield-m3:0.6.5") } apollo { diff --git a/android/Omnivore/app/src/main/AndroidManifest.xml b/android/Omnivore/app/src/main/AndroidManifest.xml index 4ebf91f5d..dce141df0 100644 --- a/android/Omnivore/app/src/main/AndroidManifest.xml +++ b/android/Omnivore/app/src/main/AndroidManifest.xml @@ -31,7 +31,7 @@ @@ -47,12 +47,12 @@ android:windowSoftInputMode="adjustNothing" /> diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/EventTracker.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/EventTracker.kt deleted file mode 100644 index 38abeeda0..000000000 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/EventTracker.kt +++ /dev/null @@ -1,45 +0,0 @@ -package app.omnivore.omnivore - -import android.content.Context -import com.posthog.android.PostHog -import com.posthog.android.Properties -import io.intercom.android.sdk.Intercom -import io.intercom.android.sdk.identity.Registration -import org.json.JSONObject -import javax.inject.Inject - - -class EventTracker @Inject constructor(val app: Context) { - private val posthog: PostHog - - init { - val posthogClientKey = app.getString(R.string.posthog_client_key) - val posthogInstanceAddress = app.getString(R.string.posthog_instance_address) - - posthog = PostHog.Builder(app, posthogClientKey, posthogInstanceAddress) - .captureApplicationLifecycleEvents() - .collectDeviceId(false) - .build() - - PostHog.setSingletonInstance(posthog) - } - - fun registerUser(userID: String, intercomHash: String?, isDebug: Boolean) { - posthog.identify(userID) - if (!isDebug) { - Intercom.client().loginIdentifiedUser(Registration.create().withUserId(userID)) - intercomHash?.let { intercomHash -> - Intercom.client().setUserHash(intercomHash) - } - } - - } - - fun track(eventName: String, properties: Properties = Properties()) { - posthog.capture(eventName, properties) - } - - fun logout() { - posthog.reset() - } -} diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/MainActivity.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/MainActivity.kt index 8996416ad..b6e878e04 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/MainActivity.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/MainActivity.kt @@ -12,15 +12,15 @@ import androidx.compose.ui.Modifier import androidx.core.view.ViewCompat import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsCompat -import app.omnivore.omnivore.ui.auth.LoginViewModel -import app.omnivore.omnivore.ui.components.LabelsViewModel -import app.omnivore.omnivore.ui.editinfo.EditInfoViewModel -import app.omnivore.omnivore.ui.library.LibraryViewModel -import app.omnivore.omnivore.ui.library.SearchViewModel -import app.omnivore.omnivore.ui.root.RootView -import app.omnivore.omnivore.ui.save.SaveViewModel -import app.omnivore.omnivore.ui.settings.SettingsViewModel -import app.omnivore.omnivore.ui.theme.OmnivoreTheme +import app.omnivore.omnivore.feature.auth.LoginViewModel +import app.omnivore.omnivore.feature.components.LabelsViewModel +import app.omnivore.omnivore.feature.editinfo.EditInfoViewModel +import app.omnivore.omnivore.feature.library.LibraryViewModel +import app.omnivore.omnivore.feature.library.SearchViewModel +import app.omnivore.omnivore.feature.root.RootView +import app.omnivore.omnivore.feature.save.SaveViewModel +import app.omnivore.omnivore.feature.settings.SettingsViewModel +import app.omnivore.omnivore.feature.theme.OmnivoreTheme import com.pspdfkit.PSPDFKit import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.DelicateCoroutinesApi diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/Routes.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/Routes.kt deleted file mode 100644 index 01b4b9a6f..000000000 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/Routes.kt +++ /dev/null @@ -1,11 +0,0 @@ -package app.omnivore.omnivore - -sealed class Routes(val route: String) { - object Library : Routes("Library") - object Settings: Routes("Settings") - object Search: Routes("Search") - object Documentation: Routes("Documentation") - object PrivacyPolicy: Routes("PrivacyPolicy") - object TermsAndConditions: Routes("TermsAndConditions") - object Notebook: Routes("Notebook") -} diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/analytics/EventTracker.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/analytics/EventTracker.kt new file mode 100644 index 000000000..4f5a95898 --- /dev/null +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/analytics/EventTracker.kt @@ -0,0 +1,45 @@ +package app.omnivore.omnivore.core.analytics + +import android.content.Context +import app.omnivore.omnivore.R +import com.posthog.android.PostHog +import com.posthog.android.Properties +import io.intercom.android.sdk.Intercom +import io.intercom.android.sdk.identity.Registration +import javax.inject.Inject + + +class EventTracker @Inject constructor(val app: Context) { + private val posthog: PostHog + + init { + val posthogClientKey = app.getString(R.string.posthog_client_key) + val posthogInstanceAddress = app.getString(R.string.posthog_instance_address) + + posthog = PostHog.Builder(app, posthogClientKey, posthogInstanceAddress) + .captureApplicationLifecycleEvents() + .collectDeviceId(false) + .build() + + PostHog.setSingletonInstance(posthog) + } + + fun registerUser(userID: String, intercomHash: String?, isDebug: Boolean) { + posthog.identify(userID) + if (!isDebug) { + Intercom.client().loginIdentifiedUser(Registration.create().withUserId(userID)) + intercomHash?.let { intercomHash -> + Intercom.client().setUserHash(intercomHash) + } + } + + } + + fun track(eventName: String, properties: Properties = Properties()) { + posthog.capture(eventName, properties) + } + + fun logout() { + posthog.reset() + } +} diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/DataService.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/data/DataService.kt similarity index 73% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/DataService.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/data/DataService.kt index a7685a872..921eaeed2 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/DataService.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/data/DataService.kt @@ -1,11 +1,11 @@ -package app.omnivore.omnivore.dataService +package app.omnivore.omnivore.core.data import android.content.Context import androidx.room.Room -import app.omnivore.omnivore.network.* -import app.omnivore.omnivore.persistence.AppDatabase -import app.omnivore.omnivore.persistence.entities.Highlight -import app.omnivore.omnivore.persistence.entities.SavedItem +import app.omnivore.omnivore.core.network.Networker +import app.omnivore.omnivore.core.database.AppDatabase +import app.omnivore.omnivore.core.database.entities.Highlight +import app.omnivore.omnivore.core.database.entities.SavedItem import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel import javax.inject.Inject diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/HighlightActionHandlers.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/data/HighlightActionHandlers.kt similarity index 90% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/HighlightActionHandlers.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/data/HighlightActionHandlers.kt index 675291519..bc2d8e9a7 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/HighlightActionHandlers.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/data/HighlightActionHandlers.kt @@ -1,11 +1,14 @@ -package app.omnivore.omnivore.dataService +package app.omnivore.omnivore.core.data import android.util.Log -import app.omnivore.omnivore.models.ServerSyncStatus -import app.omnivore.omnivore.network.* -import app.omnivore.omnivore.persistence.entities.Highlight -import app.omnivore.omnivore.persistence.entities.SavedItemAndHighlightCrossRef -import app.omnivore.omnivore.persistence.entities.saveHighlightChange +import app.omnivore.omnivore.core.network.CreateHighlightParams +import app.omnivore.omnivore.core.network.DeleteHighlightParams +import app.omnivore.omnivore.core.network.MergeHighlightsParams +import app.omnivore.omnivore.core.network.UpdateHighlightParams +import app.omnivore.omnivore.core.model.ServerSyncStatus +import app.omnivore.omnivore.core.database.entities.Highlight +import app.omnivore.omnivore.core.database.entities.SavedItemAndHighlightCrossRef +import app.omnivore.omnivore.core.database.entities.saveHighlightChange import com.google.gson.Gson import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -49,7 +52,7 @@ suspend fun DataService.createWebHighlight(jsonString: String, colorName: String } suspend fun DataService.createNoteHighlight(savedItemId: String, note: String): String { - val shortId = NanoId.generate(size=14) + val shortId = NanoId.generate(size = 14) val createHighlightId = UUID.randomUUID().toString() withContext(Dispatchers.IO) { diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/LibrarySync.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/data/LibrarySync.kt similarity index 90% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/LibrarySync.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/data/LibrarySync.kt index 2e73b0741..dabe14122 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/LibrarySync.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/data/LibrarySync.kt @@ -1,9 +1,14 @@ -package app.omnivore.omnivore.dataService +package app.omnivore.omnivore.core.data import android.util.Log -import app.omnivore.omnivore.models.ServerSyncStatus -import app.omnivore.omnivore.network.* -import app.omnivore.omnivore.persistence.entities.* +import app.omnivore.omnivore.core.database.entities.Highlight +import app.omnivore.omnivore.core.database.entities.SavedItem +import app.omnivore.omnivore.core.database.entities.SavedItemLabel +import app.omnivore.omnivore.core.database.entities.SavedItemWithLabelsAndHighlights +import app.omnivore.omnivore.core.network.savedItem +import app.omnivore.omnivore.core.network.savedItemUpdates +import app.omnivore.omnivore.core.network.search +import app.omnivore.omnivore.core.model.ServerSyncStatus suspend fun DataService.librarySearch(cursor: String?, query: String): SearchResult { val searchResult = networker.search(cursor = cursor, limit = 10, query = query) diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/NanoId.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/data/NanoId.kt similarity index 99% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/NanoId.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/data/NanoId.kt index 925c8f498..71d5e2d4a 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/NanoId.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/data/NanoId.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.dataService +package app.omnivore.omnivore.core.data import java.security.SecureRandom diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/ReadingProgressChangeHandler.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/data/ReadingProgressChangeHandler.kt similarity index 81% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/ReadingProgressChangeHandler.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/data/ReadingProgressChangeHandler.kt index 64cd652f9..43f6b27b5 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/ReadingProgressChangeHandler.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/data/ReadingProgressChangeHandler.kt @@ -1,8 +1,8 @@ -package app.omnivore.omnivore.dataService +package app.omnivore.omnivore.core.data -import app.omnivore.omnivore.models.ServerSyncStatus -import app.omnivore.omnivore.network.ReadingProgressParams -import app.omnivore.omnivore.network.updateReadingProgress +import app.omnivore.omnivore.core.model.ServerSyncStatus +import app.omnivore.omnivore.core.network.ReadingProgressParams +import app.omnivore.omnivore.core.network.updateReadingProgress import com.google.gson.Gson import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/SavedItemLabelSync.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/data/SavedItemLabelSync.kt similarity index 59% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/SavedItemLabelSync.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/data/SavedItemLabelSync.kt index c77f24995..8ad37f25e 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/SavedItemLabelSync.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/data/SavedItemLabelSync.kt @@ -1,6 +1,6 @@ -package app.omnivore.omnivore.dataService +package app.omnivore.omnivore.core.data -import app.omnivore.omnivore.network.savedItemLabels +import app.omnivore.omnivore.core.network.savedItemLabels suspend fun DataService.syncLabels() { val fetchedLabels = networker.savedItemLabels() diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/SavedItemMenuActionHandlers.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/data/SavedItemMenuActionHandlers.kt similarity index 86% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/SavedItemMenuActionHandlers.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/data/SavedItemMenuActionHandlers.kt index 6b9f7183f..471e5afb7 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/SavedItemMenuActionHandlers.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/data/SavedItemMenuActionHandlers.kt @@ -1,9 +1,9 @@ -package app.omnivore.omnivore.dataService +package app.omnivore.omnivore.core.data -import app.omnivore.omnivore.models.ServerSyncStatus -import app.omnivore.omnivore.network.archiveSavedItem -import app.omnivore.omnivore.network.deleteSavedItem -import app.omnivore.omnivore.network.unarchiveSavedItem +import app.omnivore.omnivore.core.model.ServerSyncStatus +import app.omnivore.omnivore.core.network.archiveSavedItem +import app.omnivore.omnivore.core.network.deleteSavedItem +import app.omnivore.omnivore.core.network.unarchiveSavedItem import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -54,3 +54,4 @@ suspend fun DataService.unarchiveSavedItem(itemID: String) { } } } + diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/SyncOfflineChanges.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/data/SyncOfflineChanges.kt similarity index 89% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/SyncOfflineChanges.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/data/SyncOfflineChanges.kt index 839ddd64b..c818af698 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/SyncOfflineChanges.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/data/SyncOfflineChanges.kt @@ -1,15 +1,22 @@ -package app.omnivore.omnivore.dataService +package app.omnivore.omnivore.core.data import android.util.Log +import app.omnivore.omnivore.core.network.ReadingProgressParams +import app.omnivore.omnivore.core.network.createHighlight +import app.omnivore.omnivore.core.network.deleteHighlights +import app.omnivore.omnivore.core.network.deleteSavedItem +import app.omnivore.omnivore.core.network.mergeHighlights +import app.omnivore.omnivore.core.network.updateArchiveStatusSavedItem +import app.omnivore.omnivore.core.network.updateHighlight +import app.omnivore.omnivore.core.network.updateReadingProgress import app.omnivore.omnivore.graphql.generated.type.CreateHighlightInput import app.omnivore.omnivore.graphql.generated.type.HighlightType import app.omnivore.omnivore.graphql.generated.type.MergeHighlightInput import app.omnivore.omnivore.graphql.generated.type.UpdateHighlightInput -import app.omnivore.omnivore.models.ServerSyncStatus -import app.omnivore.omnivore.network.* -import app.omnivore.omnivore.persistence.entities.HighlightChange -import app.omnivore.omnivore.persistence.entities.SavedItem -import app.omnivore.omnivore.persistence.entities.highlightChangeToHighlight +import app.omnivore.omnivore.core.model.ServerSyncStatus +import app.omnivore.omnivore.core.database.entities.HighlightChange +import app.omnivore.omnivore.core.database.entities.SavedItem +import app.omnivore.omnivore.core.database.entities.highlightChangeToHighlight import com.apollographql.apollo3.api.Optional import kotlinx.coroutines.delay diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/AppDatabase.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/AppDatabase.kt new file mode 100644 index 000000000..188787184 --- /dev/null +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/AppDatabase.kt @@ -0,0 +1,42 @@ +package app.omnivore.omnivore.core.database + +import androidx.room.Database +import androidx.room.RoomDatabase +import app.omnivore.omnivore.core.database.entities.Highlight +import app.omnivore.omnivore.core.database.entities.HighlightChange +import app.omnivore.omnivore.core.database.entities.HighlightChangesDao +import app.omnivore.omnivore.core.database.entities.HighlightDao +import app.omnivore.omnivore.core.database.entities.SavedItem +import app.omnivore.omnivore.core.database.entities.SavedItemAndHighlightCrossRef +import app.omnivore.omnivore.core.database.entities.SavedItemAndHighlightCrossRefDao +import app.omnivore.omnivore.core.database.entities.SavedItemAndSavedItemLabelCrossRef +import app.omnivore.omnivore.core.database.entities.SavedItemAndSavedItemLabelCrossRefDao +import app.omnivore.omnivore.core.database.entities.SavedItemDao +import app.omnivore.omnivore.core.database.entities.SavedItemLabel +import app.omnivore.omnivore.core.database.entities.SavedItemLabelDao +import app.omnivore.omnivore.core.database.entities.SavedItemWithLabelsAndHighlightsDao +import app.omnivore.omnivore.core.database.entities.Viewer +import app.omnivore.omnivore.core.database.entities.ViewerDao + +@Database( + entities = [ + Viewer::class, + SavedItem::class, + SavedItemLabel::class, + Highlight::class, + HighlightChange::class, + SavedItemAndSavedItemLabelCrossRef::class, + SavedItemAndHighlightCrossRef::class + ], + version = 24 +) +abstract class AppDatabase : RoomDatabase() { + abstract fun viewerDao(): ViewerDao + abstract fun savedItemDao(): SavedItemDao + abstract fun highlightDao(): HighlightDao + abstract fun highlightChangesDao(): HighlightChangesDao + abstract fun savedItemLabelDao(): SavedItemLabelDao + abstract fun savedItemWithLabelsAndHighlightsDao(): SavedItemWithLabelsAndHighlightsDao + abstract fun savedItemAndSavedItemLabelCrossRefDao(): SavedItemAndSavedItemLabelCrossRefDao + abstract fun savedItemAndHighlightCrossRefDao(): SavedItemAndHighlightCrossRefDao +} diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/BaseDao.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/BaseDao.kt similarity index 94% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/BaseDao.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/BaseDao.kt index e422079ae..2b5bcbc7f 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/BaseDao.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/BaseDao.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.persistence +package app.omnivore.omnivore.core.database import androidx.room.Delete import androidx.room.Insert diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/Highlight.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/Highlight.kt similarity index 96% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/Highlight.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/Highlight.kt index 8d133ad89..6d52e6203 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/Highlight.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/Highlight.kt @@ -1,7 +1,7 @@ -package app.omnivore.omnivore.persistence.entities +package app.omnivore.omnivore.core.database.entities import androidx.room.* -import app.omnivore.omnivore.models.ServerSyncStatus +import app.omnivore.omnivore.core.model.ServerSyncStatus import com.google.gson.annotations.SerializedName diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/HighlightChange.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/HighlightChange.kt similarity index 95% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/HighlightChange.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/HighlightChange.kt index b2b5e0bfb..33be6c46c 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/HighlightChange.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/HighlightChange.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.persistence.entities +package app.omnivore.omnivore.core.database.entities import android.util.Log import androidx.room.Dao @@ -9,11 +9,9 @@ import androidx.room.PrimaryKey import androidx.room.Query import androidx.room.TypeConverter import androidx.room.TypeConverters -import app.omnivore.omnivore.models.ServerSyncStatus +import app.omnivore.omnivore.core.model.ServerSyncStatus import com.google.gson.Gson -import com.google.gson.annotations.SerializedName import com.google.gson.reflect.TypeToken -import kotlinx.serialization.json.Json @Entity @TypeConverters(StringListTypeConverter::class) diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/NewsletterEmail.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/NewsletterEmail.kt similarity index 79% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/NewsletterEmail.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/NewsletterEmail.kt index c9b38351e..5d52fc636 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/NewsletterEmail.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/NewsletterEmail.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.persistence.entities +package app.omnivore.omnivore.core.database.entities import androidx.room.Entity import androidx.room.PrimaryKey diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/RecentSearchItem.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/RecentSearchItem.kt similarity index 78% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/RecentSearchItem.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/RecentSearchItem.kt index ec5f41bb4..e45912374 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/RecentSearchItem.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/RecentSearchItem.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.persistence.entities +package app.omnivore.omnivore.core.database.entities import androidx.room.Entity import androidx.room.PrimaryKey diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/Recommendation.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/Recommendation.kt similarity index 82% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/Recommendation.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/Recommendation.kt index 2c41c9473..ed5b612fd 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/Recommendation.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/Recommendation.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.persistence.entities +package app.omnivore.omnivore.core.database.entities import androidx.room.Entity import androidx.room.PrimaryKey diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/RecommendationGroup.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/RecommendationGroup.kt similarity index 87% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/RecommendationGroup.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/RecommendationGroup.kt index f168922f0..e635b8b05 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/RecommendationGroup.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/RecommendationGroup.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.persistence.entities +package app.omnivore.omnivore.core.database.entities import androidx.room.Entity import androidx.room.PrimaryKey diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/SavedItem.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/SavedItem.kt similarity index 98% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/SavedItem.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/SavedItem.kt index b17d48dd2..33df145a5 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/SavedItem.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/SavedItem.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.persistence.entities +package app.omnivore.omnivore.core.database.entities import androidx.core.net.toUri import androidx.lifecycle.LiveData @@ -225,7 +225,7 @@ interface SavedItemDao { excludedLabels: List, allowedContentReaders: List ): LiveData> { - val result = _filteredLibraryData( + return _filteredLibraryData( allowedArchiveStates = allowedArchiveStates, sortKey = sortKey, hasRequiredLabels = requiredLabels.size, @@ -234,7 +234,6 @@ interface SavedItemDao { excludedLabels = excludedLabels, allowedContentReaders = allowedContentReaders ) - return result } } diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/SavedItemLabel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/SavedItemLabel.kt similarity index 94% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/SavedItemLabel.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/SavedItemLabel.kt index 47e6f513f..485238ff5 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/SavedItemLabel.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/SavedItemLabel.kt @@ -1,8 +1,8 @@ -package app.omnivore.omnivore.persistence.entities +package app.omnivore.omnivore.core.database.entities import androidx.lifecycle.LiveData import androidx.room.* -import app.omnivore.omnivore.models.ServerSyncStatus +import app.omnivore.omnivore.core.model.ServerSyncStatus @Entity data class SavedItemLabel( diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/UserProfile.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/UserProfile.kt similarity index 79% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/UserProfile.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/UserProfile.kt index 12408f40c..48866e307 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/UserProfile.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/UserProfile.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.persistence.entities +package app.omnivore.omnivore.core.database.entities import androidx.room.Entity import androidx.room.PrimaryKey diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/Viewer.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/Viewer.kt similarity index 84% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/Viewer.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/Viewer.kt index e323a8257..a2c64b70c 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/Viewer.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/database/entities/Viewer.kt @@ -1,7 +1,6 @@ -package app.omnivore.omnivore.persistence.entities +package app.omnivore.omnivore.core.database.entities import androidx.room.* -import app.omnivore.omnivore.persistence.BaseDao @Entity data class Viewer( diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/DatastoreRepository.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/datastore/DatastoreRepository.kt similarity index 94% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/DatastoreRepository.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/datastore/DatastoreRepository.kt index 9fa050fa4..1d9a6fa86 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/DatastoreRepository.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/datastore/DatastoreRepository.kt @@ -1,9 +1,11 @@ -package app.omnivore.omnivore +package app.omnivore.omnivore.core.datastore import android.content.Context import androidx.datastore.core.DataStore import androidx.datastore.preferences.core.* import androidx.datastore.preferences.preferencesDataStore +import app.omnivore.omnivore.utils.Constants +import app.omnivore.omnivore.utils.DatastoreKeys import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/model/ServerSyncStatus.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/model/ServerSyncStatus.kt new file mode 100644 index 000000000..2bbb6c930 --- /dev/null +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/model/ServerSyncStatus.kt @@ -0,0 +1,10 @@ +package app.omnivore.omnivore.core.model + +enum class ServerSyncStatus(val rawValue: Int) { + IS_SYNCED(0), + IS_SYNCING(1), + NEEDS_DELETION(2), + NEEDS_CREATION(3), + NEEDS_UPDATE(4), + NEEDS_MERGE(5) +} diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/HighlightMutations.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/HighlightMutations.kt similarity index 98% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/HighlightMutations.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/HighlightMutations.kt index 397fe114b..359137fbb 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/HighlightMutations.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/HighlightMutations.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.network +package app.omnivore.omnivore.core.network import android.util.Log import app.omnivore.omnivore.graphql.generated.CreateHighlightMutation @@ -10,7 +10,7 @@ import app.omnivore.omnivore.graphql.generated.type.CreateHighlightInput import app.omnivore.omnivore.graphql.generated.type.HighlightType import app.omnivore.omnivore.graphql.generated.type.MergeHighlightInput import app.omnivore.omnivore.graphql.generated.type.UpdateHighlightInput -import app.omnivore.omnivore.persistence.entities.Highlight +import app.omnivore.omnivore.core.database.entities.Highlight import com.apollographql.apollo3.api.Optional import com.google.gson.Gson diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/Networker.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/Networker.kt similarity index 77% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/Networker.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/Networker.kt index 79990bef7..6a2194b96 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/Networker.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/Networker.kt @@ -1,8 +1,8 @@ -package app.omnivore.omnivore.network +package app.omnivore.omnivore.core.network -import app.omnivore.omnivore.Constants -import app.omnivore.omnivore.DatastoreKeys -import app.omnivore.omnivore.DatastoreRepository +import app.omnivore.omnivore.utils.Constants +import app.omnivore.omnivore.utils.DatastoreKeys +import app.omnivore.omnivore.core.datastore.DatastoreRepository import com.apollographql.apollo3.ApolloClient import javax.inject.Inject diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/RESTNetworker.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/RESTNetworker.kt similarity index 96% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/RESTNetworker.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/RESTNetworker.kt index b5923d3d7..b82c64c44 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/RESTNetworker.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/RESTNetworker.kt @@ -1,6 +1,5 @@ -package app.omnivore.omnivore +package app.omnivore.omnivore.core.network -import app.omnivore.omnivore.network.Networker import retrofit2.Response import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/ReadingProgressMutations.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/ReadingProgressMutations.kt similarity index 97% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/ReadingProgressMutations.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/ReadingProgressMutations.kt index d10f6c722..1e33d801b 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/ReadingProgressMutations.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/ReadingProgressMutations.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.network +package app.omnivore.omnivore.core.network import app.omnivore.omnivore.graphql.generated.SaveArticleReadingProgressMutation import app.omnivore.omnivore.graphql.generated.type.SaveArticleReadingProgressInput diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/SavedItemLabelMutations.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/SavedItemLabelMutations.kt similarity index 95% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/SavedItemLabelMutations.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/SavedItemLabelMutations.kt index 11cca9ebe..a1d7df7d1 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/SavedItemLabelMutations.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/SavedItemLabelMutations.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.network +package app.omnivore.omnivore.core.network import app.omnivore.omnivore.graphql.generated.CreateLabelMutation import app.omnivore.omnivore.graphql.generated.SetLabelsMutation diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/SavedItemLabelQuery.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/SavedItemLabelQuery.kt similarity index 85% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/SavedItemLabelQuery.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/SavedItemLabelQuery.kt index 3ccc516c7..27c21a8aa 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/SavedItemLabelQuery.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/SavedItemLabelQuery.kt @@ -1,7 +1,7 @@ -package app.omnivore.omnivore.network +package app.omnivore.omnivore.core.network import app.omnivore.omnivore.graphql.generated.GetLabelsQuery -import app.omnivore.omnivore.persistence.entities.SavedItemLabel +import app.omnivore.omnivore.core.database.entities.SavedItemLabel suspend fun Networker.savedItemLabels(): List { diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/SavedItemMutations.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/SavedItemMutations.kt similarity index 98% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/SavedItemMutations.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/SavedItemMutations.kt index 66e079622..eb55da347 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/SavedItemMutations.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/SavedItemMutations.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.network +package app.omnivore.omnivore.core.network import android.net.Uri import androidx.compose.ui.text.intl.Locale diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/SavedItemQuery.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/SavedItemQuery.kt similarity index 94% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/SavedItemQuery.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/SavedItemQuery.kt index 8021b0b59..856b1d8ea 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/SavedItemQuery.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/SavedItemQuery.kt @@ -1,11 +1,11 @@ -package app.omnivore.omnivore.network +package app.omnivore.omnivore.core.network import android.util.Log import app.omnivore.omnivore.graphql.generated.GetArticleQuery import app.omnivore.omnivore.graphql.generated.type.ContentReader -import app.omnivore.omnivore.persistence.entities.SavedItem -import app.omnivore.omnivore.persistence.entities.SavedItemLabel -import app.omnivore.omnivore.persistence.entities.Highlight +import app.omnivore.omnivore.core.database.entities.SavedItem +import app.omnivore.omnivore.core.database.entities.SavedItemLabel +import app.omnivore.omnivore.core.database.entities.Highlight import java.io.File import java.net.URL import java.nio.file.Files diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/SavedItemUpdatesQuery.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/SavedItemUpdatesQuery.kt similarity index 97% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/SavedItemUpdatesQuery.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/SavedItemUpdatesQuery.kt index 4d5832664..d195e7cd5 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/SavedItemUpdatesQuery.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/SavedItemUpdatesQuery.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.network +package app.omnivore.omnivore.core.network import app.omnivore.omnivore.graphql.generated.UpdatesSinceQuery import app.omnivore.omnivore.graphql.generated.type.UpdateReason diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/SearchQuery.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/SearchQuery.kt similarity index 92% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/SearchQuery.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/SearchQuery.kt index 1f3fad630..31664e652 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/SearchQuery.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/SearchQuery.kt @@ -1,8 +1,10 @@ -package app.omnivore.omnivore.network +package app.omnivore.omnivore.core.network +import app.omnivore.omnivore.core.database.entities.Highlight +import app.omnivore.omnivore.core.database.entities.SavedItem +import app.omnivore.omnivore.core.database.entities.SavedItemLabel import app.omnivore.omnivore.graphql.generated.SearchQuery -import app.omnivore.omnivore.models.ServerSyncStatus -import app.omnivore.omnivore.persistence.entities.* +import app.omnivore.omnivore.core.model.ServerSyncStatus import com.apollographql.apollo3.api.Optional data class LibrarySearchQueryResponse( diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/TypeaheadSearch.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/TypeaheadSearch.kt similarity index 88% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/TypeaheadSearch.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/TypeaheadSearch.kt index 2f008fca6..4b6f70cd6 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/TypeaheadSearch.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/TypeaheadSearch.kt @@ -1,7 +1,7 @@ -package app.omnivore.omnivore.network +package app.omnivore.omnivore.core.network import app.omnivore.omnivore.graphql.generated.TypeaheadSearchQuery -import app.omnivore.omnivore.persistence.entities.TypeaheadCardData +import app.omnivore.omnivore.core.database.entities.TypeaheadCardData data class SearchQueryResponse( val cursor: String?, diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/ViewerQuery.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/ViewerQuery.kt similarity index 83% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/ViewerQuery.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/ViewerQuery.kt index b382bc877..a9e16957e 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/network/ViewerQuery.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/core/network/ViewerQuery.kt @@ -1,7 +1,7 @@ -package app.omnivore.omnivore.network +package app.omnivore.omnivore.core.network import app.omnivore.omnivore.graphql.generated.ViewerQuery -import app.omnivore.omnivore.persistence.entities.Viewer +import app.omnivore.omnivore.core.database.entities.Viewer suspend fun Networker.viewer(): Viewer? { try { diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/AppModule.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/di/AppModule.kt similarity index 71% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/AppModule.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/di/AppModule.kt index 09486bebb..70de06127 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/AppModule.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/di/AppModule.kt @@ -1,8 +1,11 @@ -package app.omnivore.omnivore +package app.omnivore.omnivore.di import android.content.Context -import app.omnivore.omnivore.dataService.DataService -import app.omnivore.omnivore.network.Networker +import app.omnivore.omnivore.core.datastore.DatastoreRepository +import app.omnivore.omnivore.core.analytics.EventTracker +import app.omnivore.omnivore.core.datastore.OmnivoreDatastore +import app.omnivore.omnivore.core.data.DataService +import app.omnivore.omnivore.core.network.Networker import dagger.Module import dagger.Provides import dagger.hilt.InstallIn diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/LabelUtils.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/LabelUtils.kt similarity index 84% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/LabelUtils.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/LabelUtils.kt index 9e7d16faa..0826d78b2 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/LabelUtils.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/LabelUtils.kt @@ -1,12 +1,12 @@ -package app.omnivore.omnivore.ui +package app.omnivore.omnivore.feature -import app.omnivore.omnivore.dataService.DataService +import app.omnivore.omnivore.core.data.DataService import app.omnivore.omnivore.graphql.generated.type.CreateLabelInput import app.omnivore.omnivore.graphql.generated.type.SetLabelsInput -import app.omnivore.omnivore.network.Networker -import app.omnivore.omnivore.network.updateLabelsForSavedItem -import app.omnivore.omnivore.persistence.entities.SavedItemAndSavedItemLabelCrossRef -import app.omnivore.omnivore.persistence.entities.SavedItemLabel +import app.omnivore.omnivore.core.network.Networker +import app.omnivore.omnivore.core.network.updateLabelsForSavedItem +import app.omnivore.omnivore.core.database.entities.SavedItemAndSavedItemLabelCrossRef +import app.omnivore.omnivore.core.database.entities.SavedItemLabel import com.apollographql.apollo3.api.Optional diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/ResourceProvider.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/ResourceProvider.kt similarity index 91% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/ResourceProvider.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/ResourceProvider.kt index 192486f16..9e5ed576c 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/ResourceProvider.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/ResourceProvider.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui +package app.omnivore.omnivore.feature import android.content.Context import androidx.annotation.StringRes diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/AppleAuth.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/AppleAuth.kt similarity index 96% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/AppleAuth.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/AppleAuth.kt index 040ce7762..16c8e5227 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/AppleAuth.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/AppleAuth.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.auth +package app.omnivore.omnivore.feature.auth import android.annotation.SuppressLint import android.net.Uri @@ -17,7 +17,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.window.Dialog -import app.omnivore.omnivore.AppleConstants +import app.omnivore.omnivore.utils.AppleConstants import app.omnivore.omnivore.R import java.net.URLEncoder import java.util.* diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/AuthUtils.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/AuthUtils.kt similarity index 96% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/AuthUtils.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/AuthUtils.kt index c51f93b50..f5ad49c98 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/AuthUtils.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/AuthUtils.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.auth +package app.omnivore.omnivore.feature.auth import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/CreateUserProfile.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/CreateUserProfile.kt similarity index 99% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/CreateUserProfile.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/CreateUserProfile.kt index 276ec6cab..43b1e7413 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/CreateUserProfile.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/CreateUserProfile.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.auth +package app.omnivore.omnivore.feature.auth import android.annotation.SuppressLint import android.widget.Toast diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/EmailLogin.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/EmailLogin.kt similarity index 98% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/EmailLogin.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/EmailLogin.kt index 67ed205c2..5f9f4d57e 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/EmailLogin.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/EmailLogin.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.auth +package app.omnivore.omnivore.feature.auth import android.annotation.SuppressLint import android.widget.Toast @@ -27,7 +27,7 @@ import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.unit.dp import app.omnivore.omnivore.BuildConfig import app.omnivore.omnivore.R -import app.omnivore.omnivore.ui.auth.AuthUtils.autofill +import app.omnivore.omnivore.feature.auth.AuthUtils.autofill @SuppressLint("CoroutineCreationDuringComposition") @Composable diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/EmailSignUpView.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/EmailSignUpView.kt similarity index 98% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/EmailSignUpView.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/EmailSignUpView.kt index 268aad3dc..d8ad8b808 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/EmailSignUpView.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/EmailSignUpView.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.auth +package app.omnivore.omnivore.feature.auth import android.annotation.SuppressLint import android.widget.Toast @@ -29,7 +29,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.unit.dp import app.omnivore.omnivore.R -import app.omnivore.omnivore.ui.auth.AuthUtils.autofill +import app.omnivore.omnivore.feature.auth.AuthUtils.autofill @Composable fun EmailSignUpView(viewModel: LoginViewModel) { diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/GoogleAuth.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/GoogleAuth.kt similarity index 98% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/GoogleAuth.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/GoogleAuth.kt index 46055919d..bee519a98 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/GoogleAuth.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/GoogleAuth.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.auth +package app.omnivore.omnivore.feature.auth import android.app.Activity import androidx.activity.compose.rememberLauncherForActivityResult diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/LoadingButtonWithIcon.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/LoadingButtonWithIcon.kt similarity index 98% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/LoadingButtonWithIcon.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/LoadingButtonWithIcon.kt index 5593e029c..2c1a9f136 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/LoadingButtonWithIcon.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/LoadingButtonWithIcon.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.auth +package app.omnivore.omnivore.feature.auth import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.clickable diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/LoginViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/LoginViewModel.kt similarity index 91% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/LoginViewModel.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/LoginViewModel.kt index f98bb2504..7ced32d09 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/LoginViewModel.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/LoginViewModel.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.auth +package app.omnivore.omnivore.feature.auth import android.content.Context import android.widget.Toast @@ -7,11 +7,26 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.* import app.omnivore.omnivore.* -import app.omnivore.omnivore.dataService.DataService +import app.omnivore.omnivore.core.analytics.EventTracker +import app.omnivore.omnivore.core.data.DataService +import app.omnivore.omnivore.core.datastore.DatastoreRepository +import app.omnivore.omnivore.core.network.AuthProviderLoginSubmit +import app.omnivore.omnivore.core.network.CreateAccountParams +import app.omnivore.omnivore.core.network.CreateAccountSubmit +import app.omnivore.omnivore.core.network.CreateEmailAccountSubmit +import app.omnivore.omnivore.core.network.EmailLoginCredentials +import app.omnivore.omnivore.core.network.EmailLoginSubmit +import app.omnivore.omnivore.core.network.EmailSignUpParams import app.omnivore.omnivore.graphql.generated.ValidateUsernameQuery -import app.omnivore.omnivore.network.Networker -import app.omnivore.omnivore.network.viewer -import app.omnivore.omnivore.ui.ResourceProvider +import app.omnivore.omnivore.core.network.Networker +import app.omnivore.omnivore.core.network.PendingUserSubmit +import app.omnivore.omnivore.core.network.RetrofitHelper +import app.omnivore.omnivore.core.network.SignInParams +import app.omnivore.omnivore.core.network.UserProfile +import app.omnivore.omnivore.core.network.viewer +import app.omnivore.omnivore.feature.ResourceProvider +import app.omnivore.omnivore.utils.Constants +import app.omnivore.omnivore.utils.DatastoreKeys import com.apollographql.apollo3.ApolloClient import com.google.android.gms.auth.api.signin.GoogleSignInAccount import com.google.android.gms.common.api.ApiException diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/SelfHostedView.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/SelfHostedView.kt similarity index 93% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/SelfHostedView.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/SelfHostedView.kt index bf8389434..616c3c7e7 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/SelfHostedView.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/SelfHostedView.kt @@ -1,13 +1,8 @@ -package app.omnivore.omnivore.ui.auth +package app.omnivore.omnivore.feature.auth import android.annotation.SuppressLint -import android.content.Context import android.content.Intent import android.net.Uri -import android.view.ViewGroup -import android.webkit.CookieManager -import android.webkit.WebView -import android.webkit.WebViewClient import android.widget.Toast import androidx.compose.foundation.layout.* import androidx.compose.foundation.text.ClickableText @@ -19,22 +14,16 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType -import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.unit.dp -import androidx.compose.ui.viewinterop.AndroidView import androidx.core.content.ContextCompat -import app.omnivore.omnivore.BuildConfig -import app.omnivore.omnivore.DatastoreKeys import app.omnivore.omnivore.R @SuppressLint("CoroutineCreationDuringComposition") diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/WelcomeScreen.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/WelcomeScreen.kt similarity index 98% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/WelcomeScreen.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/WelcomeScreen.kt index 45dfe5095..38f2c156d 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/auth/WelcomeScreen.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/auth/WelcomeScreen.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.auth +package app.omnivore.omnivore.feature.auth import android.annotation.SuppressLint import android.content.Intent @@ -21,7 +21,7 @@ import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.unit.dp import app.omnivore.omnivore.R -import app.omnivore.omnivore.ui.theme.OmnivoreTheme +import app.omnivore.omnivore.feature.theme.OmnivoreTheme import com.google.accompanist.systemuicontroller.rememberSystemUiController import com.google.android.gms.common.GoogleApiAvailability import kotlinx.coroutines.launch diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/AddLinkSheet.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/AddLinkSheet.kt similarity index 96% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/AddLinkSheet.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/AddLinkSheet.kt index 1174bb6c3..acbfe48cd 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/AddLinkSheet.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/AddLinkSheet.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.components +package app.omnivore.omnivore.feature.components import android.widget.Toast import androidx.compose.foundation.* @@ -18,14 +18,13 @@ import androidx.compose.ui.platform.LocalClipboardManager import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.TextRange -import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.unit.dp import androidx.lifecycle.MutableLiveData import app.omnivore.omnivore.R -import app.omnivore.omnivore.ui.save.SaveState -import app.omnivore.omnivore.ui.save.SaveViewModel +import app.omnivore.omnivore.feature.save.SaveState +import app.omnivore.omnivore.feature.save.SaveViewModel @OptIn(ExperimentalMaterial3Api::class) @Composable diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/HighlightColor.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/HighlightColor.kt similarity index 75% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/HighlightColor.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/HighlightColor.kt index 666489828..eb5adb9b3 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/HighlightColor.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/HighlightColor.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.components +package app.omnivore.omnivore.feature.components import androidx.compose.ui.graphics.Color diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/HighlightColorPalette.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/HighlightColorPalette.kt similarity index 97% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/HighlightColorPalette.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/HighlightColorPalette.kt index 8fc4aee03..d2167c039 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/HighlightColorPalette.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/HighlightColorPalette.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.components +package app.omnivore.omnivore.feature.components import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/HighlightColorPaletteItem.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/HighlightColorPaletteItem.kt similarity index 96% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/HighlightColorPaletteItem.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/HighlightColorPaletteItem.kt index 8f00fed31..c267d373e 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/HighlightColorPaletteItem.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/HighlightColorPaletteItem.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.components +package app.omnivore.omnivore.feature.components import androidx.compose.foundation.background import androidx.compose.foundation.clickable diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/HighlightColorPaletteMode.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/HighlightColorPaletteMode.kt similarity index 76% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/HighlightColorPaletteMode.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/HighlightColorPaletteMode.kt index 29eca575d..9b775060b 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/HighlightColorPaletteMode.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/HighlightColorPaletteMode.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.components +package app.omnivore.omnivore.feature.components import androidx.compose.ui.graphics.Color enum class HighlightColorPaletteMode(val backgroundColor: Color) { diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelChipColors.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/LabelChipColors.kt similarity index 90% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelChipColors.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/LabelChipColors.kt index 2ee6b8434..98827dac9 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelChipColors.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/LabelChipColors.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.components +package app.omnivore.omnivore.feature.components import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.luminance diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelCreationDialog.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/LabelCreationDialog.kt similarity index 99% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelCreationDialog.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/LabelCreationDialog.kt index fcadcdaea..0f34953ee 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelCreationDialog.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/LabelCreationDialog.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.components +package app.omnivore.omnivore.feature.components import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.background diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/LabelFilterChip.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/LabelFilterChip.kt new file mode 100644 index 000000000..b7aa77763 --- /dev/null +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/LabelFilterChip.kt @@ -0,0 +1,47 @@ +package app.omnivore.omnivore.feature.components + +import androidx.compose.foundation.layout.size +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Done +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.FilterChip +import androidx.compose.material3.FilterChipDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun LabelFilterChip( + onClick: () -> Unit, + label: String +) { + var selected by remember { mutableStateOf(false) } + + FilterChip( + onClick = { + selected = !selected + onClick() + }, + label = { + Text(label) + }, + selected = selected, + leadingIcon = if (selected) { + { + Icon( + imageVector = Icons.Filled.Done, + contentDescription = "Done icon", + modifier = Modifier.size(FilterChipDefaults.IconSize) + ) + } + } else { + null + }, + ) +} diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/LabelSelectionSheetContent.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/LabelSelectionSheetContent.kt new file mode 100644 index 000000000..12e22775f --- /dev/null +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/LabelSelectionSheetContent.kt @@ -0,0 +1,144 @@ +package app.omnivore.omnivore.feature.components + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.rounded.ArrowBack +import androidx.compose.material.icons.filled.Add +import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material.icons.filled.Check +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.FilterChip +import androidx.compose.material3.FilterChipDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateMapOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import app.omnivore.omnivore.R +import app.omnivore.omnivore.core.database.entities.SavedItemLabel + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun LabelsSelectionSheetContent2( + isLibraryMode: Boolean, + labels: List, + initialSelectedLabels: List, + labelsViewModel: LabelsViewModel, + onCancel: () -> Unit, + onSave: (List) -> Unit, + onCreateLabel: (String, String) -> Unit +) { + // Use mutableStateMapOf for more idiomatic management of collection state + val selectedLabels = remember { + mutableStateMapOf().apply { + initialSelectedLabels.forEach { + put( + it, + true + ) + } + } + } + var newLabelName by remember { mutableStateOf("") } + + Scaffold( + modifier = Modifier.fillMaxSize(), + topBar = { + TopAppBar( + title = { + Text( + text = if (isLibraryMode) stringResource(R.string.label_selection_sheet_title) else + stringResource(R.string.label_selection_sheet_title_alt) + ) + }, + navigationIcon = { + IconButton(onClick = onCancel) { + Icon(Icons.AutoMirrored.Rounded.ArrowBack, contentDescription = "Back") + } + }, + actions = { + IconButton(onClick = { onSave(selectedLabels.filter { it.value }.keys.toList()) }) { + Text( + text = if (isLibraryMode) + stringResource(R.string.label_selection_sheet_action_search) else + stringResource(R.string.label_selection_sheet_action_save) + ) + } + }, + colors = TopAppBarDefaults.topAppBarColors( + containerColor = MaterialTheme.colorScheme.background + ) + ) + } + ) { paddingValues -> + Column( + modifier = Modifier + .fillMaxSize() + .padding(top = paddingValues.calculateTopPadding()) + .verticalScroll(rememberScrollState()), + verticalArrangement = Arrangement.Top, + horizontalAlignment = Alignment.Start + ) { + OutlinedTextField( + value = newLabelName, + onValueChange = { newLabelName = it }, + label = { Text("New Label Name") }, + singleLine = true, + trailingIcon = { + IconButton(onClick = { + val labelHexValue = "#FFFFFF" + onCreateLabel(newLabelName, labelHexValue) + newLabelName = "" + }) { + Icon(Icons.Filled.Add, contentDescription = "Create Label") + } + }, + modifier = Modifier + .fillMaxWidth() + .padding(8.dp) + ) + Row { + labels.forEach { label -> + FilterChip( + selected = selectedLabels[label] ?: false, + onClick = { + selectedLabels[label] = !(selectedLabels[label] ?: false) + }, + label = { Text(label.name) }, + leadingIcon = if (selectedLabels[label] == true) { + { + Icon( + imageVector = Icons.Filled.Check, + contentDescription = "Selected", + modifier = Modifier.size(FilterChipDefaults.IconSize) + ) + } + } else null, + modifier = Modifier.padding(8.dp) + ) + } + } + } + } +} diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsSelectionSheet.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/LabelsSelectionSheet.kt similarity index 96% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsSelectionSheet.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/LabelsSelectionSheet.kt index 9f3ca3606..1dd1aeb7d 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsSelectionSheet.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/LabelsSelectionSheet.kt @@ -1,6 +1,6 @@ @file:OptIn(ExperimentalMaterialApi::class) -package app.omnivore.omnivore.ui.components +package app.omnivore.omnivore.feature.components import android.widget.Toast import androidx.compose.foundation.Canvas @@ -8,7 +8,6 @@ import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row @@ -25,17 +24,12 @@ import androidx.compose.material.Scaffold import androidx.compose.material.TextFieldDefaults import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.AddCircle -import androidx.compose.material.icons.filled.MoreVert import androidx.compose.material3.CenterAlignedTopAppBar import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.SmallTopAppBar -import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TextButton -import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider @@ -58,20 +52,18 @@ import androidx.compose.ui.platform.LocalViewConfiguration import androidx.compose.ui.platform.ViewConfiguration import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.intl.Locale import androidx.compose.ui.text.toLowerCase import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import app.omnivore.omnivore.R -import app.omnivore.omnivore.persistence.entities.SavedItemLabel +import app.omnivore.omnivore.core.database.entities.SavedItemLabel import com.dokar.chiptextfield.Chip -import com.dokar.chiptextfield.ChipTextField -import com.dokar.chiptextfield.ChipTextFieldDefaults import com.dokar.chiptextfield.ChipTextFieldState +import com.dokar.chiptextfield.m3.ChipTextField +import com.dokar.chiptextfield.m3.ChipTextFieldDefaults import com.dokar.chiptextfield.rememberChipTextFieldState import com.google.accompanist.flowlayout.FlowRow diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/LabelsViewModel.kt similarity index 88% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsViewModel.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/LabelsViewModel.kt index 9b8ba18b1..ecc1bc741 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelsViewModel.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/LabelsViewModel.kt @@ -1,8 +1,8 @@ -package app.omnivore.omnivore.ui.components +package app.omnivore.omnivore.feature.components import androidx.lifecycle.* -import app.omnivore.omnivore.models.ServerSyncStatus -import app.omnivore.omnivore.persistence.entities.SavedItemLabel +import app.omnivore.omnivore.core.model.ServerSyncStatus +import app.omnivore.omnivore.core.database.entities.SavedItemLabel import dagger.hilt.android.lifecycle.HiltViewModel import java.time.LocalDate import java.time.ZoneOffset diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/SegmentedControl.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/SegmentedControl.kt similarity index 98% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/SegmentedControl.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/SegmentedControl.kt index 2ebf45e94..e21008710 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/SegmentedControl.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/components/SegmentedControl.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.components +package app.omnivore.omnivore.feature.components import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.layout.Row diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/editinfo/EditInfoSheet.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/editinfo/EditInfoSheet.kt similarity index 98% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/editinfo/EditInfoSheet.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/editinfo/EditInfoSheet.kt index ad2b04f1b..799419970 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/editinfo/EditInfoSheet.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/editinfo/EditInfoSheet.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.editinfo +package app.omnivore.omnivore.feature.editinfo import android.widget.Toast import androidx.compose.foundation.* @@ -11,7 +11,6 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.unit.dp diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/editinfo/EditInfoViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/editinfo/EditInfoViewModel.kt similarity index 91% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/editinfo/EditInfoViewModel.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/editinfo/EditInfoViewModel.kt index a27bc4817..befbe8f67 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/editinfo/EditInfoViewModel.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/editinfo/EditInfoViewModel.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.editinfo +package app.omnivore.omnivore.feature.editinfo import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -6,14 +6,14 @@ import androidx.compose.runtime.setValue import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import app.omnivore.omnivore.Constants -import app.omnivore.omnivore.DatastoreKeys -import app.omnivore.omnivore.DatastoreRepository +import app.omnivore.omnivore.utils.Constants +import app.omnivore.omnivore.utils.DatastoreKeys +import app.omnivore.omnivore.core.datastore.DatastoreRepository import app.omnivore.omnivore.R -import app.omnivore.omnivore.dataService.DataService +import app.omnivore.omnivore.core.data.DataService import app.omnivore.omnivore.graphql.generated.UpdatePageMutation import app.omnivore.omnivore.graphql.generated.type.UpdatePageInput -import app.omnivore.omnivore.ui.ResourceProvider +import app.omnivore.omnivore.feature.ResourceProvider import com.apollographql.apollo3.ApolloClient import com.apollographql.apollo3.api.Optional import dagger.hilt.android.lifecycle.HiltViewModel diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryBottomSheetState.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/LibraryBottomSheetState.kt similarity index 65% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryBottomSheetState.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/LibraryBottomSheetState.kt index 4bd866b45..f2c907d06 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryBottomSheetState.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/LibraryBottomSheetState.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.library +package app.omnivore.omnivore.feature.library enum class LibraryBottomSheetState { HIDDEN, diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryFilterBar.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/LibraryFilterBar.kt similarity index 96% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryFilterBar.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/LibraryFilterBar.kt index 576b21e9d..4c9c317ec 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryFilterBar.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/LibraryFilterBar.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.library +package app.omnivore.omnivore.feature.library import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyRow @@ -17,8 +17,8 @@ import androidx.compose.ui.text.intl.Locale import androidx.compose.ui.text.toLowerCase import androidx.compose.ui.unit.dp import app.omnivore.omnivore.R -import app.omnivore.omnivore.persistence.entities.SavedItemLabel -import app.omnivore.omnivore.ui.components.LabelChipColors +import app.omnivore.omnivore.core.database.entities.SavedItemLabel +import app.omnivore.omnivore.feature.components.LabelChipColors @Composable fun LibraryFilterBar(viewModel: LibraryViewModel) { diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/LibraryNavigationBar.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/LibraryNavigationBar.kt new file mode 100644 index 000000000..74ae4438d --- /dev/null +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/LibraryNavigationBar.kt @@ -0,0 +1,234 @@ +package app.omnivore.omnivore.feature.library + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material.icons.filled.Add +import androidx.compose.material.icons.filled.Close +import androidx.compose.material.icons.filled.MoreVert +import androidx.compose.material.icons.filled.Search +import androidx.compose.material.icons.outlined.Delete +import androidx.compose.material.icons.outlined.Info +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.livedata.observeAsState +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.focus.onFocusChanged +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.input.ImeAction +import androidx.navigation.NavHostController +import app.omnivore.omnivore.R +import app.omnivore.omnivore.core.database.entities.SavedItemWithLabelsAndHighlights + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun LibraryNavigationBar( + savedItemViewModel: SavedItemViewModel, + onSearchClicked: () -> Unit, + onAddLinkClicked: () -> Unit, + onSettingsIconClick: () -> Unit +) { + val actionsMenuItem: SavedItemWithLabelsAndHighlights? by savedItemViewModel.actionsMenuItemLiveData.observeAsState( + null + ) + + var isMenuExpanded by remember { mutableStateOf(false) } + + TopAppBar( + title = { + Text( + if (actionsMenuItem == null) + stringResource(R.string.library_nav_bar_title) else + stringResource(R.string.library_nav_bar_title_alt) + ) + }, + colors = TopAppBarDefaults.topAppBarColors( + containerColor = if (actionsMenuItem == null) MaterialTheme.colorScheme.background else MaterialTheme.colorScheme.surfaceVariant + ), + navigationIcon = { + if (actionsMenuItem != null) { + IconButton(onClick = { + savedItemViewModel.actionsMenuItemLiveData.postValue(null) + }) { + Icon( + imageVector = Icons.AutoMirrored.Filled.ArrowBack, + modifier = Modifier, + contentDescription = "Back" + ) + } + } + }, + actions = { + actionsMenuItem?.let { + IconButton(onClick = { + savedItemViewModel.handleSavedItemAction( + it.savedItem.savedItemId, + if (it.savedItem.isArchived) SavedItemAction.Unarchive else SavedItemAction.Archive + ) + }) { + if (it.savedItem.isArchived) { + Icon( + painter = painterResource(id = R.drawable.unarchive), + contentDescription = null + ) + } else { + Icon( + painter = painterResource(id = R.drawable.archive_outline), + contentDescription = null + ) + } + } + IconButton(onClick = { + savedItemViewModel.handleSavedItemAction( + it.savedItem.savedItemId, + SavedItemAction.EditInfo + ) + }) { + Icon( + Icons.Outlined.Info, + contentDescription = null + ) + } + IconButton(onClick = { + savedItemViewModel.handleSavedItemAction( + it.savedItem.savedItemId, + SavedItemAction.EditLabels + ) + }) { + Icon( + painter = painterResource(id = R.drawable.tag), + contentDescription = null + ) + } + IconButton(onClick = { + savedItemViewModel.handleSavedItemAction( + it.savedItem.savedItemId, + SavedItemAction.Delete + ) + }) { + Icon( + imageVector = Icons.Outlined.Delete, + contentDescription = null + ) + } + IconButton(onClick = { isMenuExpanded = true } ) { + Icon( + imageVector = Icons.Default.MoreVert, + contentDescription = null + ) + if (isMenuExpanded) { + SavedItemLibraryContextMenu( + savedItemViewModel = savedItemViewModel, + savedItem = it.savedItem, + isExpanded = true, + onDismiss = { isMenuExpanded = false }, + ) + } + } + } ?: run { + IconButton(onClick = onSearchClicked) { + Icon( + imageVector = Icons.Filled.Search, + contentDescription = null + ) + } + + IconButton(onClick = onAddLinkClicked) { + Icon( + imageVector = Icons.Filled.Add, + contentDescription = null + ) + } + + IconButton(onClick = onSettingsIconClick) { + Icon( + imageVector = Icons.Default.MoreVert, + contentDescription = null + ) + } + } + } + ) +} + +@Composable +fun SearchField( + searchText: String, + onSearch: () -> Unit, + onSearchTextChanged: (String) -> Unit, + navController: NavHostController, +) { + var showClearButton by remember { mutableStateOf(false) } + val focusRequester = remember { FocusRequester() } + + TextField( + modifier = Modifier + .fillMaxWidth() + .onFocusChanged { focusState -> + showClearButton = (focusState.isFocused) + } + .focusRequester(focusRequester), + value = searchText, + onValueChange = onSearchTextChanged, + placeholder = { + Text(text = stringResource(R.string.library_nav_bar_field_placeholder_search)) + }, + leadingIcon = { + IconButton( + onClick = { + onSearchTextChanged("") + navController.popBackStack() + }) { + Icon( + imageVector = Icons.AutoMirrored.Filled.ArrowBack, + contentDescription = "Back" + ) + } + }, + trailingIcon = { + AnimatedVisibility( + visible = showClearButton, + enter = fadeIn(), + exit = fadeOut() + ) { + IconButton(onClick = { onSearchTextChanged("") }) { + Icon( + imageVector = Icons.Filled.Close, + contentDescription = null + ) + } + + } + }, + maxLines = 1, + singleLine = true, + keyboardOptions = KeyboardOptions.Default.copy(imeAction = ImeAction.Search), + keyboardActions = KeyboardActions(onSearch = { + onSearch() + }), + ) + + LaunchedEffect(Unit) { + focusRequester.requestFocus() + } +} diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryView.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/LibraryView.kt similarity index 95% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryView.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/LibraryView.kt index 32e0d66a4..c45230d77 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryView.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/LibraryView.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.library +package app.omnivore.omnivore.feature.library import android.content.Intent import android.util.Log @@ -53,19 +53,19 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp import androidx.navigation.NavHostController -import app.omnivore.omnivore.Routes -import app.omnivore.omnivore.persistence.entities.SavedItemLabel -import app.omnivore.omnivore.persistence.entities.SavedItemWithLabelsAndHighlights -import app.omnivore.omnivore.ui.components.AddLinkSheetContent -import app.omnivore.omnivore.ui.components.LabelsSelectionSheetContent -import app.omnivore.omnivore.ui.components.LabelsViewModel -import app.omnivore.omnivore.ui.editinfo.EditInfoSheetContent -import app.omnivore.omnivore.ui.editinfo.EditInfoViewModel -import app.omnivore.omnivore.ui.reader.PDFReaderActivity -import app.omnivore.omnivore.ui.reader.WebReaderLoadingContainerActivity -import app.omnivore.omnivore.ui.save.SaveState -import app.omnivore.omnivore.ui.save.SaveViewModel -import app.omnivore.omnivore.ui.savedItemViews.SavedItemCard +import app.omnivore.omnivore.core.database.entities.SavedItemLabel +import app.omnivore.omnivore.core.database.entities.SavedItemWithLabelsAndHighlights +import app.omnivore.omnivore.feature.components.AddLinkSheetContent +import app.omnivore.omnivore.feature.components.LabelsSelectionSheetContent +import app.omnivore.omnivore.feature.components.LabelsViewModel +import app.omnivore.omnivore.feature.editinfo.EditInfoSheetContent +import app.omnivore.omnivore.feature.editinfo.EditInfoViewModel +import app.omnivore.omnivore.feature.reader.PDFReaderActivity +import app.omnivore.omnivore.feature.reader.WebReaderLoadingContainerActivity +import app.omnivore.omnivore.feature.save.SaveState +import app.omnivore.omnivore.feature.save.SaveViewModel +import app.omnivore.omnivore.feature.savedItemViews.SavedItemCard +import app.omnivore.omnivore.navigation.Routes import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.launch diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/LibraryViewModel.kt similarity index 88% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryViewModel.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/LibraryViewModel.kt index 652be91d5..376a28074 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryViewModel.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/LibraryViewModel.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.library +package app.omnivore.omnivore.feature.library import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -7,27 +7,27 @@ import androidx.lifecycle.MediatorLiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import app.omnivore.omnivore.DatastoreKeys -import app.omnivore.omnivore.DatastoreRepository +import app.omnivore.omnivore.utils.DatastoreKeys +import app.omnivore.omnivore.core.datastore.DatastoreRepository import app.omnivore.omnivore.R -import app.omnivore.omnivore.dataService.DataService -import app.omnivore.omnivore.dataService.archiveSavedItem -import app.omnivore.omnivore.dataService.deleteSavedItem -import app.omnivore.omnivore.dataService.fetchSavedItemContent -import app.omnivore.omnivore.dataService.isSavedItemContentStoredInDB -import app.omnivore.omnivore.dataService.librarySearch -import app.omnivore.omnivore.dataService.sync -import app.omnivore.omnivore.dataService.syncLabels -import app.omnivore.omnivore.dataService.syncOfflineItemsWithServerIfNeeded -import app.omnivore.omnivore.dataService.unarchiveSavedItem -import app.omnivore.omnivore.dataService.updateWebReadingProgress +import app.omnivore.omnivore.core.data.DataService +import app.omnivore.omnivore.core.data.archiveSavedItem +import app.omnivore.omnivore.core.data.deleteSavedItem +import app.omnivore.omnivore.core.data.fetchSavedItemContent +import app.omnivore.omnivore.core.data.isSavedItemContentStoredInDB +import app.omnivore.omnivore.core.data.librarySearch +import app.omnivore.omnivore.core.data.sync +import app.omnivore.omnivore.core.data.syncLabels +import app.omnivore.omnivore.core.data.syncOfflineItemsWithServerIfNeeded +import app.omnivore.omnivore.core.data.unarchiveSavedItem +import app.omnivore.omnivore.core.data.updateWebReadingProgress import app.omnivore.omnivore.graphql.generated.type.CreateLabelInput -import app.omnivore.omnivore.network.Networker -import app.omnivore.omnivore.network.createNewLabel -import app.omnivore.omnivore.persistence.entities.SavedItemLabel -import app.omnivore.omnivore.persistence.entities.SavedItemWithLabelsAndHighlights -import app.omnivore.omnivore.ui.ResourceProvider -import app.omnivore.omnivore.ui.setSavedItemLabels +import app.omnivore.omnivore.core.network.Networker +import app.omnivore.omnivore.core.network.createNewLabel +import app.omnivore.omnivore.core.database.entities.SavedItemLabel +import app.omnivore.omnivore.core.database.entities.SavedItemWithLabelsAndHighlights +import app.omnivore.omnivore.feature.ResourceProvider +import app.omnivore.omnivore.feature.setSavedItemLabels import com.apollographql.apollo3.api.Optional import com.google.gson.Gson import dagger.hilt.android.lifecycle.HiltViewModel @@ -198,12 +198,6 @@ class LibraryViewModel @Inject constructor( } } -// fun sortKey(appliedSortKey: String) { -// when(appliedSortKey) { -// -// } -// } - private fun handleFilterChanges() { librarySearchCursor = null @@ -344,6 +338,20 @@ class LibraryViewModel @Inject constructor( ) } } + + SavedItemAction.MarkUnread -> { + viewModelScope.launch { + dataService.updateWebReadingProgress( + jsonString = Gson().toJson( + mapOf( + "id" to itemID, + "readingProgressPercent" to 0, + "readingProgressAnchorIndex" to 0 + ) + ) + ) + } + } } actionsMenuItemLiveData.postValue(null) } @@ -442,5 +450,6 @@ enum class SavedItemAction { Unarchive, EditLabels, EditInfo, - MarkRead + MarkRead, + MarkUnread } diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/SavedItemFilter.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/SavedItemFilter.kt similarity index 97% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/SavedItemFilter.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/SavedItemFilter.kt index 503a261bf..c15b0fd6e 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/SavedItemFilter.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/SavedItemFilter.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.library +package app.omnivore.omnivore.feature.library import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/SavedItemLibraryContextMenu.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/SavedItemLibraryContextMenu.kt new file mode 100644 index 000000000..44d6af865 --- /dev/null +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/SavedItemLibraryContextMenu.kt @@ -0,0 +1,48 @@ +package app.omnivore.omnivore.feature.library + +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import app.omnivore.omnivore.R +import app.omnivore.omnivore.core.database.entities.SavedItem +import app.omnivore.omnivore.core.database.entities.SavedItemWithLabelsAndHighlights + +@Composable +fun SavedItemLibraryContextMenu( + savedItemViewModel: SavedItemViewModel, + savedItem: SavedItem, + isExpanded: Boolean, + onDismiss: () -> Unit, +) { + val menuOptions = listOf( + if (savedItemViewModel.actionsMenuItemLiveData.value?.savedItem?.readingProgress == 100.0) { + MenuItemOption(R.string.saved_item_context_menu_action_mark_unread, SavedItemAction.MarkUnread) + } else { + MenuItemOption(R.string.saved_item_context_menu_action_mark_read, SavedItemAction.MarkRead) + } + ) + + DropdownMenu( + expanded = isExpanded, + onDismissRequest = onDismiss + ) { + menuOptions.forEach { option -> + DropdownMenuItem( + text = { Text( text = stringResource(option.textResourceId), fontWeight = FontWeight.Normal) }, + onClick = { + savedItemViewModel.handleSavedItemAction(savedItem.savedItemId, option.action) + onDismiss() + } + ) + } + } +} + +data class MenuItemOption( + val textResourceId: Int, + val action: SavedItemAction, + val customAction: (() -> Unit)? = null +) diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/SavedItemSortFilter.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/SavedItemSortFilter.kt new file mode 100644 index 000000000..ab0641d35 --- /dev/null +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/SavedItemSortFilter.kt @@ -0,0 +1,39 @@ +package app.omnivore.omnivore.feature.library + +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable + +enum class SavedItemSortFilter( + val displayText: String, + val rawValue: String, + val queryString: String +) { + NEWEST("Newest", rawValue = "newest", "sort:saved"), + OLDEST("Oldest", rawValue = "oldest", "sort:saved-ASC"), + RECENTLY_READ("Recently Read", rawValue = "recentlyRead", "sort:read"), + RECENTLY_PUBLISHED("Recently Published", rawValue = "recentlyPublished", "sort:published"), +} + +@Composable +fun SavedItemSortFilterContextMenu( + isExpanded: Boolean, + onDismiss: () -> Unit, + actionHandler: (SavedItemSortFilter) -> Unit +) { + DropdownMenu( + expanded = isExpanded, + onDismissRequest = onDismiss + ) { + SavedItemSortFilter.values().forEach { + DropdownMenuItem( + text = { Text(it.displayText) }, + onClick = { + actionHandler(it) + onDismiss() + } + ) + } + } +} diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/SavedItemViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/SavedItemViewModel.kt similarity index 70% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/SavedItemViewModel.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/SavedItemViewModel.kt index 199c668ce..559caa299 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/SavedItemViewModel.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/SavedItemViewModel.kt @@ -1,7 +1,7 @@ -package app.omnivore.omnivore.ui.library +package app.omnivore.omnivore.feature.library import androidx.lifecycle.MutableLiveData -import app.omnivore.omnivore.persistence.entities.SavedItemWithLabelsAndHighlights +import app.omnivore.omnivore.core.database.entities.SavedItemWithLabelsAndHighlights interface SavedItemViewModel { diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/SearchView.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/SearchView.kt new file mode 100644 index 000000000..3df01dea5 --- /dev/null +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/SearchView.kt @@ -0,0 +1,226 @@ +package app.omnivore.omnivore.feature.library + +import android.content.Intent +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material.icons.filled.MoreVert +import androidx.compose.material.icons.outlined.Delete +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.livedata.observeAsState +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.colorResource +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import androidx.navigation.NavHostController +import app.omnivore.omnivore.R +import app.omnivore.omnivore.core.database.entities.SavedItemWithLabelsAndHighlights +import app.omnivore.omnivore.core.database.entities.TypeaheadCardData +import app.omnivore.omnivore.feature.reader.PDFReaderActivity +import app.omnivore.omnivore.feature.reader.WebReaderLoadingContainerActivity +import app.omnivore.omnivore.feature.savedItemViews.SavedItemCard +import app.omnivore.omnivore.feature.savedItemViews.TypeaheadSearchCard + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun SearchView( + viewModel: SearchViewModel, + navController: NavHostController +) { + val isRefreshing: Boolean by viewModel.isRefreshing.observeAsState(false) + val typeaheadMode: Boolean by viewModel.typeaheadMode.observeAsState(true) + val searchText: String by viewModel.searchTextLiveData.observeAsState("") + val actionsMenuItem: SavedItemWithLabelsAndHighlights? by viewModel.actionsMenuItemLiveData.observeAsState( + null + ) + + Scaffold( + topBar = { + TopAppBar( + title = { Text("") }, + colors = TopAppBarDefaults.topAppBarColors( + containerColor = MaterialTheme.colorScheme.surfaceVariant + ), + navigationIcon = { + if (actionsMenuItem != null) { + IconButton(onClick = { + viewModel.actionsMenuItemLiveData.postValue(null) + }) { + Icon( + imageVector = Icons.AutoMirrored.Filled.ArrowBack, + modifier = Modifier, + contentDescription = "Back" + ) + } + } + }, + actions = { + if (actionsMenuItem != null) { + IconButton(onClick = { }) { + Icon( + painter = painterResource(id = R.drawable.archive_outline), + contentDescription = null + ) + } + IconButton(onClick = { }) { + Icon( + painter = painterResource(id = R.drawable.tag), + contentDescription = null + ) + } + IconButton(onClick = { }) { + Icon( + imageVector = Icons.Outlined.Delete, + contentDescription = null + ) + } + IconButton(onClick = { }) { + Icon( + imageVector = Icons.Default.MoreVert, + contentDescription = null + ) + } + } else { + Row { + SearchField( + searchText, + onSearch = { + viewModel.performSearch() + }, + onSearchTextChanged = { viewModel.updateSearchText(it) }, + navController = navController + ) + } + } + } + ) + + } + ) { paddingValues -> + if (isRefreshing) { + Row( + horizontalArrangement = Arrangement.Center, + modifier = Modifier + .padding(top = paddingValues.calculateTopPadding()) + .fillMaxWidth() + ) { + CircularProgressIndicator( + modifier = Modifier + .height(45.dp) + .width(45.dp), + strokeWidth = 5.dp, + color = colorResource(R.color.green_55B938) + ) + } + } else if (typeaheadMode) { + TypeaheadSearchViewContent( + viewModel, + modifier = Modifier + .padding(top = paddingValues.calculateTopPadding()) + ) + } else { + SearchViewContent( + viewModel, + modifier = Modifier + .padding(top = paddingValues.calculateTopPadding()) + ) + } + } +} + +@Composable +fun TypeaheadSearchViewContent(viewModel: SearchViewModel, modifier: Modifier) { + val context = LocalContext.current + val listState = rememberLazyListState() + + val searchedCardsData: List by viewModel.searchItemsLiveData.observeAsState( + listOf() + ) + + LazyColumn( + state = listState, + verticalArrangement = Arrangement.Top, + horizontalAlignment = Alignment.CenterHorizontally, + modifier = modifier + .background(MaterialTheme.colorScheme.background) + .fillMaxSize() + + ) { + items(searchedCardsData) { cardData -> + TypeaheadSearchCard( + cardData = cardData, + onClickHandler = { + // val activityClass = if (cardData.isPDF()) PDFReaderActivity::class.java else WebReaderLoadingContainerActivity::class.java + val activityClass = WebReaderLoadingContainerActivity::class.java + val intent = Intent(context, activityClass) + intent.putExtra("SAVED_ITEM_SLUG", cardData.slug) + context.startActivity(intent) + }, + actionHandler = { viewModel.handleSavedItemAction(cardData.savedItemId, it) } + ) + } + } +} + +@Composable +fun SearchViewContent(viewModel: SearchViewModel, modifier: Modifier) { + val context = LocalContext.current + val listState = rememberLazyListState() + + val cardsData: List by viewModel.itemsLiveData.observeAsState( + listOf() + ) + + LazyColumn( + state = listState, + verticalArrangement = Arrangement.Top, + horizontalAlignment = Alignment.CenterHorizontally, + modifier = modifier + .background(MaterialTheme.colorScheme.background) + .fillMaxSize() + + ) { + items(cardsData) { cardDataWithLabels -> + SavedItemCard( + selected = false, + savedItemViewModel = viewModel, + savedItem = cardDataWithLabels, + onClickHandler = { + val activityClass = + if (cardDataWithLabels.savedItem.contentReader == "PDF") PDFReaderActivity::class.java else WebReaderLoadingContainerActivity::class.java + val intent = Intent(context, activityClass) + intent.putExtra("SAVED_ITEM_SLUG", cardDataWithLabels.savedItem.slug) + context.startActivity(intent) + }, + actionHandler = { + viewModel.handleSavedItemAction( + cardDataWithLabels.savedItem.savedItemId, + it + ) + } + ) + } + } +} diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/SearchViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/SearchViewModel.kt similarity index 72% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/SearchViewModel.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/SearchViewModel.kt index 2fb7a1236..1ad2360cb 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/SearchViewModel.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/library/SearchViewModel.kt @@ -1,16 +1,27 @@ -package app.omnivore.omnivore.ui.library +package app.omnivore.omnivore.feature.library import androidx.lifecycle.MediatorLiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import app.omnivore.omnivore.* -import app.omnivore.omnivore.dataService.* -import app.omnivore.omnivore.network.* -import app.omnivore.omnivore.persistence.entities.* +import app.omnivore.omnivore.core.data.DataService +import app.omnivore.omnivore.core.data.archiveSavedItem +import app.omnivore.omnivore.core.data.deleteSavedItem +import app.omnivore.omnivore.core.data.isSavedItemContentStoredInDB +import app.omnivore.omnivore.core.data.librarySearch +import app.omnivore.omnivore.core.data.unarchiveSavedItem +import app.omnivore.omnivore.core.database.entities.SavedItemLabel +import app.omnivore.omnivore.core.database.entities.SavedItemWithLabelsAndHighlights +import app.omnivore.omnivore.core.database.entities.TypeaheadCardData +import app.omnivore.omnivore.core.datastore.DatastoreRepository +import app.omnivore.omnivore.core.network.Networker +import app.omnivore.omnivore.core.network.typeaheadSearch import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.* +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import javax.inject.Inject @HiltViewModel @@ -18,7 +29,7 @@ class SearchViewModel @Inject constructor( private val networker: Networker, private val dataService: DataService, private val datastoreRepo: DatastoreRepository -): ViewModel(), SavedItemViewModel { +) : ViewModel(), SavedItemViewModel { private val contentRequestChannel = Channel(capacity = Channel.UNLIMITED) private var cursor: String? = null @@ -66,7 +77,10 @@ class SearchViewModel @Inject constructor( private fun loadUsingSearchAPI() { viewModelScope.launch { withContext(Dispatchers.IO) { - val result = dataService.librarySearch(cursor = librarySearchCursor, query = searchQueryString()) + val result = dataService.librarySearch( + cursor = librarySearchCursor, + query = searchQueryString() + ) result.cursor?.let { librarySearchCursor = it } @@ -81,29 +95,29 @@ class SearchViewModel @Inject constructor( } val newItems = result.savedItems - /* - .map { - SavedItemCardDataWithLabels( - cardData = SavedItemCardData( - savedItemId = it.savedItem.savedItemId, - slug = it.savedItem.slug, - publisherURLString = it.savedItem.publisherURLString, - title = it.savedItem.title, - author = it.savedItem.author, - imageURLString = it.savedItem.imageURLString, - isArchived = it.savedItem.isArchived, - pageURLString = it.savedItem.pageURLString, - contentReader = it.savedItem.contentReader, - savedAt = it.savedItem.savedAt, - readingProgress = it.savedItem.readingProgress, - wordsCount = it.savedItem.wordsCount - ), - labels = listOf() - ) - } - */ + /* + .map { + SavedItemCardDataWithLabels( + cardData = SavedItemCardData( + savedItemId = it.savedItem.savedItemId, + slug = it.savedItem.slug, + publisherURLString = it.savedItem.publisherURLString, + title = it.savedItem.title, + author = it.savedItem.author, + imageURLString = it.savedItem.imageURLString, + isArchived = it.savedItem.isArchived, + pageURLString = it.savedItem.pageURLString, + contentReader = it.savedItem.contentReader, + savedAt = it.savedItem.savedAt, + readingProgress = it.savedItem.readingProgress, + wordsCount = it.savedItem.wordsCount + ), + labels = listOf() + ) + } + */ - itemsLiveData.value?.let{ + itemsLiveData.value?.let { itemsLiveData.postValue(newItems + it) } ?: run { itemsLiveData.postValue(newItems) @@ -146,24 +160,29 @@ class SearchViewModel @Inject constructor( dataService.deleteSavedItem(itemID) } } + SavedItemAction.Archive -> { viewModelScope.launch { dataService.archiveSavedItem(itemID) } } + SavedItemAction.Unarchive -> { viewModelScope.launch { dataService.unarchiveSavedItem(itemID) } } + SavedItemAction.EditLabels -> { // TODO } + SavedItemAction.EditInfo -> { // TODO } SavedItemAction.MarkRead -> TODO() + SavedItemAction.MarkUnread -> TODO() } actionsMenuItemLiveData.postValue(null) } diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/notebook/NotebookView.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/notebook/NotebookView.kt similarity index 98% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/notebook/NotebookView.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/notebook/NotebookView.kt index 0780d0f84..6e381e7d8 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/notebook/NotebookView.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/notebook/NotebookView.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.notebook +package app.omnivore.omnivore.feature.notebook import android.content.ClipData import android.content.ClipboardManager @@ -6,7 +6,6 @@ import android.content.Context import androidx.compose.foundation.* import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.* import androidx.compose.material3.* @@ -36,11 +35,11 @@ import androidx.compose.ui.text.TextStyle import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import app.omnivore.omnivore.R -import app.omnivore.omnivore.persistence.entities.SavedItemWithLabelsAndHighlights +import app.omnivore.omnivore.core.database.entities.SavedItemWithLabelsAndHighlights import dev.jeziellago.compose.markdowntext.MarkdownText import kotlinx.coroutines.launch -import app.omnivore.omnivore.persistence.entities.Highlight -import app.omnivore.omnivore.ui.theme.OmnivoreTheme +import app.omnivore.omnivore.core.database.entities.Highlight +import app.omnivore.omnivore.feature.theme.OmnivoreTheme import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.res.stringResource diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/notebook/NotebookViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/notebook/NotebookViewModel.kt similarity index 82% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/notebook/NotebookViewModel.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/notebook/NotebookViewModel.kt index 510076c0d..a785b5886 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/notebook/NotebookViewModel.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/notebook/NotebookViewModel.kt @@ -1,13 +1,13 @@ -package app.omnivore.omnivore.ui.notebook +package app.omnivore.omnivore.feature.notebook import androidx.lifecycle.* -import app.omnivore.omnivore.dataService.DataService -import app.omnivore.omnivore.dataService.createNoteHighlight +import app.omnivore.omnivore.core.data.DataService +import app.omnivore.omnivore.core.data.createNoteHighlight import app.omnivore.omnivore.graphql.generated.type.UpdateHighlightInput -import app.omnivore.omnivore.network.Networker -import app.omnivore.omnivore.network.updateHighlight -import app.omnivore.omnivore.persistence.entities.Highlight -import app.omnivore.omnivore.persistence.entities.SavedItemWithLabelsAndHighlights +import app.omnivore.omnivore.core.network.Networker +import app.omnivore.omnivore.core.network.updateHighlight +import app.omnivore.omnivore.core.database.entities.Highlight +import app.omnivore.omnivore.core.database.entities.SavedItemWithLabelsAndHighlights import com.apollographql.apollo3.api.Optional import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/AnnotationEditView.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/AnnotationEditView.kt similarity index 91% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/AnnotationEditView.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/AnnotationEditView.kt index 03a4c3fdf..85bc28d38 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/AnnotationEditView.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/AnnotationEditView.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.reader +package app.omnivore.omnivore.feature.reader import android.content.DialogInterface import android.os.Bundle @@ -9,8 +9,8 @@ import android.view.WindowManager import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.platform.ViewCompositionStrategy import androidx.fragment.app.DialogFragment -import app.omnivore.omnivore.ui.notebook.EditNoteModal -import app.omnivore.omnivore.ui.theme.OmnivoreTheme +import app.omnivore.omnivore.feature.notebook.EditNoteModal +import app.omnivore.omnivore.feature.theme.OmnivoreTheme import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_EXPANDED import com.google.android.material.bottomsheet.BottomSheetDialog diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/OpenLinkView.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/OpenLinkView.kt similarity index 98% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/OpenLinkView.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/OpenLinkView.kt index c658d4b27..b97b7030e 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/OpenLinkView.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/OpenLinkView.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.reader +package app.omnivore.omnivore.feature.reader import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Arrangement diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/PDFReader.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/PDFReader.kt similarity index 99% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/PDFReader.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/PDFReader.kt index 8763fa5c3..b8721e05c 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/PDFReader.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/PDFReader.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.reader +package app.omnivore.omnivore.feature.reader import android.annotation.SuppressLint import android.content.ClipData @@ -19,7 +19,7 @@ import androidx.core.content.ContextCompat import androidx.core.graphics.drawable.DrawableCompat import androidx.lifecycle.Observer import app.omnivore.omnivore.R -import app.omnivore.omnivore.persistence.entities.Highlight +import app.omnivore.omnivore.core.database.entities.Highlight import com.pspdfkit.annotations.Annotation import com.pspdfkit.annotations.HighlightAnnotation import com.pspdfkit.configuration.PdfConfiguration diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/PDFReaderViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/PDFReaderViewModel.kt similarity index 92% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/PDFReaderViewModel.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/PDFReaderViewModel.kt index 9b4892982..90f0b1839 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/PDFReaderViewModel.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/PDFReaderViewModel.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.reader +package app.omnivore.omnivore.feature.reader import android.content.Context import android.net.Uri @@ -6,13 +6,20 @@ import android.util.Log import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import app.omnivore.omnivore.dataService.DataService -import app.omnivore.omnivore.dataService.NanoId +import app.omnivore.omnivore.core.network.Networker +import app.omnivore.omnivore.core.network.ReadingProgressParams +import app.omnivore.omnivore.core.network.createHighlight +import app.omnivore.omnivore.core.network.deleteHighlights +import app.omnivore.omnivore.core.network.mergeHighlights +import app.omnivore.omnivore.core.network.savedItem +import app.omnivore.omnivore.core.network.updateHighlight +import app.omnivore.omnivore.core.network.updateReadingProgress +import app.omnivore.omnivore.core.data.DataService +import app.omnivore.omnivore.core.data.NanoId import app.omnivore.omnivore.graphql.generated.type.CreateHighlightInput import app.omnivore.omnivore.graphql.generated.type.MergeHighlightInput import app.omnivore.omnivore.graphql.generated.type.UpdateHighlightInput -import app.omnivore.omnivore.persistence.entities.SavedItem -import app.omnivore.omnivore.network.* +import app.omnivore.omnivore.core.database.entities.SavedItem import com.apollographql.apollo3.api.Optional import com.google.gson.Gson import com.pspdfkit.annotations.Annotation diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/ReaderPreferencesView.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/ReaderPreferencesView.kt similarity index 98% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/ReaderPreferencesView.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/ReaderPreferencesView.kt index 40e967f22..5505cd6bb 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/ReaderPreferencesView.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/ReaderPreferencesView.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.reader +package app.omnivore.omnivore.feature.reader import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.isSystemInDarkTheme @@ -24,7 +24,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import app.omnivore.omnivore.R -import app.omnivore.omnivore.ui.theme.OmnivoreTheme +import app.omnivore.omnivore.feature.theme.OmnivoreTheme @Composable fun ReaderPreferencesView(webReaderViewModel: WebReaderViewModel) { diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReader.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReader.kt similarity index 99% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReader.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReader.kt index 85155f0c6..8b519330d 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReader.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReader.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.reader +package app.omnivore.omnivore.feature.reader import android.annotation.SuppressLint import android.content.ClipData diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderContent.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReaderContent.kt similarity index 96% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderContent.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReaderContent.kt index 79f8fbeb3..2616303ff 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderContent.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReaderContent.kt @@ -1,8 +1,8 @@ -package app.omnivore.omnivore.ui.reader +package app.omnivore.omnivore.feature.reader import android.util.Log -import app.omnivore.omnivore.persistence.entities.SavedItem -import app.omnivore.omnivore.persistence.entities.Highlight +import app.omnivore.omnivore.core.database.entities.SavedItem +import app.omnivore.omnivore.core.database.entities.Highlight import com.google.gson.Gson enum class WebFont(val displayText: String, val rawValue: String) { diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReaderLoadingContainer.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReaderLoadingContainer.kt new file mode 100644 index 000000000..4b29fa702 --- /dev/null +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReaderLoadingContainer.kt @@ -0,0 +1,528 @@ +package app.omnivore.omnivore.feature.reader + +import android.content.Intent +import android.os.Bundle +import android.view.View +import androidx.activity.ComponentActivity +import androidx.activity.compose.LocalOnBackPressedDispatcherOwner +import androidx.activity.compose.setContent +import androidx.activity.viewModels +import androidx.compose.foundation.background +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.ModalBottomSheetLayout +import androidx.compose.material.ModalBottomSheetValue +import androidx.compose.material.TopAppBar +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material.icons.filled.Home +import androidx.compose.material.rememberModalBottomSheetState +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.livedata.observeAsState +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import androidx.core.view.ViewCompat +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat +import app.omnivore.omnivore.MainActivity +import app.omnivore.omnivore.R +import app.omnivore.omnivore.core.database.entities.SavedItemLabel +import app.omnivore.omnivore.feature.components.LabelsSelectionSheetContent2 +import app.omnivore.omnivore.feature.components.LabelsViewModel +import app.omnivore.omnivore.feature.editinfo.EditInfoSheetContent +import app.omnivore.omnivore.feature.editinfo.EditInfoViewModel +import app.omnivore.omnivore.feature.notebook.EditNoteModal +import app.omnivore.omnivore.feature.notebook.NotebookView +import app.omnivore.omnivore.feature.notebook.NotebookViewModel +import app.omnivore.omnivore.feature.savedItemViews.SavedItemContextMenu +import app.omnivore.omnivore.feature.theme.OmnivoreTheme +import com.google.accompanist.systemuicontroller.rememberSystemUiController +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.launch +import kotlin.math.roundToInt + +@AndroidEntryPoint +class WebReaderLoadingContainerActivity : ComponentActivity() { + val viewModel: WebReaderViewModel by viewModels() + private val notebookViewModel: NotebookViewModel by viewModels() + private val labelsViewModel: LabelsViewModel by viewModels() + private val editInfoViewModel: EditInfoViewModel by viewModels() + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val requestID = intent.getStringExtra("SAVED_ITEM_REQUEST_ID") + val slug = intent.getStringExtra("SAVED_ITEM_SLUG") + + viewModel.loadItem(slug = slug, requestID = requestID) + + setContent { + val systemUiController = rememberSystemUiController() + val useDarkIcons = !isSystemInDarkTheme() + + DisposableEffect(systemUiController, useDarkIcons) { + systemUiController.setSystemBarsColor( + color = Color.Black, + darkIcons = false + ) + + onDispose {} + } + + OmnivoreTheme { + Box( + modifier = Modifier + .fillMaxSize() + .background(color = Color.Black) + ) { + if (viewModel.hasFetchError.value == true) { + Text(stringResource(R.string.web_reader_loading_container_error_msg)) + } else { + WebReaderLoadingContainer( + onLibraryIconTap = if (requestID != null) { + { startMainActivity() } + } else null, + webReaderViewModel = viewModel, + notebookViewModel = notebookViewModel, + labelsViewModel = labelsViewModel, + editInfoViewModel = editInfoViewModel, + ) + } + } + } + } + + // animate the view up when keyboard appears + WindowCompat.setDecorFitsSystemWindows(window, false) + val rootView = findViewById(android.R.id.content).rootView + ViewCompat.setOnApplyWindowInsetsListener(rootView) { _, insets -> + val imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom + rootView.setPadding(0, 0, 0, imeHeight) + insets + } + } + + private fun startMainActivity() { + val intent = Intent(this, MainActivity::class.java) + this.startActivity(intent) + } +} + +enum class BottomSheetState { + NONE, + PREFERENCES, + NOTEBOOK, + EDITNOTE, + HIGHLIGHTNOTE, + LABELS, + LINK, + EDIT_INFO, +} + + +@OptIn(ExperimentalMaterialApi::class) +@Composable +fun WebReaderLoadingContainer( + onLibraryIconTap: (() -> Unit)? = null, + webReaderViewModel: WebReaderViewModel, + notebookViewModel: NotebookViewModel, + labelsViewModel: LabelsViewModel, + editInfoViewModel: EditInfoViewModel +) { + val currentThemeKey = webReaderViewModel.currentThemeKey.observeAsState() + val currentTheme = Themes.values().find { it.themeKey == currentThemeKey.value } + val onBackPressedDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher + val bottomSheetState: BottomSheetState? by webReaderViewModel.bottomSheetStateLiveData.observeAsState( + BottomSheetState.NONE + ) + + val webReaderParams: WebReaderParams? by webReaderViewModel.webReaderParamsLiveData.observeAsState( + null + ) + val shouldPopView: Boolean by webReaderViewModel.shouldPopViewLiveData.observeAsState(false) + + val labels: List by webReaderViewModel.savedItemLabelsLiveData.observeAsState( + listOf() + ) + + val maxToolbarHeight = 48.dp + webReaderViewModel.maxToolbarHeightPx = + with(LocalDensity.current) { maxToolbarHeight.roundToPx().toFloat() } + + val coroutineScope = rememberCoroutineScope() + + val styledContent = webReaderParams?.let { + val webReaderContent = WebReaderContent( + preferences = webReaderViewModel.storedWebPreferences(isSystemInDarkTheme()), + item = it.item, + articleContent = it.articleContent, + ) + webReaderContent.styledContent() + } + + + val modalBottomSheetState = rememberModalBottomSheetState( + initialValue = ModalBottomSheetValue.Hidden, + skipHalfExpanded = bottomSheetState == BottomSheetState.EDITNOTE || bottomSheetState == BottomSheetState.HIGHLIGHTNOTE, + confirmValueChange = { + if (it == ModalBottomSheetValue.Hidden) { + webReaderViewModel.resetBottomSheet() + } + true + } + ) + + val showMenu = { + coroutineScope.launch { + modalBottomSheetState.show() + } + } + + when (bottomSheetState) { + BottomSheetState.PREFERENCES -> { + coroutineScope.launch { + if (!modalBottomSheetState.isVisible) { + modalBottomSheetState.show() + } + } + } + + BottomSheetState.NOTEBOOK, BottomSheetState.EDITNOTE, + BottomSheetState.HIGHLIGHTNOTE, BottomSheetState.LABELS, BottomSheetState.EDIT_INFO, + BottomSheetState.LINK, + -> { + showMenu() + } + + else -> { + coroutineScope.launch { + modalBottomSheetState.hide() + } + } + } + + ModalBottomSheetLayout( + modifier = Modifier + .statusBarsPadding(), + sheetBackgroundColor = Color.Transparent, + sheetState = modalBottomSheetState, + sheetContent = { + when (bottomSheetState) { + BottomSheetState.PREFERENCES -> { + BottomSheetUI { + ReaderPreferencesView(webReaderViewModel) + } + } + + BottomSheetState.NOTEBOOK -> { + webReaderParams?.let { params -> + BottomSheetUI { + NotebookView( + savedItemId = params.item.savedItemId, + viewModel = notebookViewModel, + onEditNote = { + notebookViewModel.highlightUnderEdit = it + webReaderViewModel.setBottomSheet(BottomSheetState.EDITNOTE) + }) + } + } + } + + BottomSheetState.EDITNOTE -> { + webReaderParams?.let { params -> + EditNoteModal( + initialValue = notebookViewModel.highlightUnderEdit?.annotation, + onDismiss = { save, note -> + coroutineScope.launch { + if (save) { + notebookViewModel.highlightUnderEdit?.let { highlight -> + notebookViewModel.updateHighlightNote( + highlight.highlightId, + note + ) + } ?: run { + if (note != null) { + notebookViewModel.addArticleNote( + savedItemId = params.item.savedItemId, + note = note + ) + } + } + } + notebookViewModel.highlightUnderEdit = null + } + webReaderViewModel.setBottomSheet(BottomSheetState.NOTEBOOK) + }) + } + } + + BottomSheetState.HIGHLIGHTNOTE -> { + EditNoteModal( + initialValue = webReaderViewModel.annotation, + onDismiss = { save, note -> + coroutineScope.launch { + if (save) { + webReaderViewModel.saveAnnotation(note ?: "") + } else { + webReaderViewModel.cancelAnnotation() + } + webReaderViewModel.annotation = null + } + webReaderViewModel.resetBottomSheet() + } + ) + } + + BottomSheetState.LABELS -> { + BottomSheetUI { + LabelsSelectionSheetContent2( + labels = labels, + labelsViewModel = labelsViewModel, + initialSelectedLabels = webReaderParams?.labels ?: listOf(), + onCancel = { + coroutineScope.launch { + webReaderViewModel.resetBottomSheet() + } + }, + isLibraryMode = false, + onSave = { + if (it != labels) { + webReaderViewModel.updateSavedItemLabels( + savedItemID = webReaderParams?.item?.savedItemId ?: "", + labels = it + ) + } + coroutineScope.launch { + webReaderViewModel.resetBottomSheet() + } + }, + onCreateLabel = { newLabelName, labelHexValue -> + webReaderViewModel.createNewSavedItemLabel( + newLabelName, + labelHexValue + ) + } + ) + } + } + + BottomSheetState.EDIT_INFO -> { + BottomSheetUI { + EditInfoSheetContent( + savedItemId = webReaderParams?.item?.savedItemId, + title = webReaderParams?.item?.title, + author = webReaderParams?.item?.author, + description = webReaderParams?.item?.descriptionText, + viewModel = editInfoViewModel, + onCancel = { + coroutineScope.launch { + webReaderViewModel.resetBottomSheet() + } + }, + onUpdated = { + coroutineScope.launch { + webReaderViewModel.updateItemTitle() + webReaderViewModel.resetBottomSheet() + } + } + ) + } + } + + BottomSheetState.LINK -> { + BottomSheetUI { + OpenLinkView(webReaderViewModel) + } + } + + BottomSheetState.NONE -> { + + } + + else -> { + + } + } + Spacer(modifier = Modifier.weight(1.0F)) + } + ) { + Scaffold( + topBar = { + ReaderTopAppBar(webReaderViewModel, onLibraryIconTap) + }) { paddingValues -> + if (styledContent != null) { + WebReader( + styledContent = styledContent, + webReaderViewModel = webReaderViewModel, + currentTheme = currentTheme, + ) + } + + LaunchedEffect(shouldPopView) { + if (shouldPopView) { + onBackPressedDispatcher?.onBackPressed() + } + } + } + } +} + +@Composable +fun ReaderTopAppBar( + webReaderViewModel: WebReaderViewModel, + onLibraryIconTap: (() -> Unit)? = null +) { + val context = LocalContext.current + val onBackPressedDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher + + val isDarkMode = isSystemInDarkTheme() + val currentThemeKey = webReaderViewModel.currentThemeKey.observeAsState() + val currentTheme = Themes.values().find { it.themeKey == currentThemeKey.value } + val toolbarHeightPx: Float by webReaderViewModel.currentToolbarHeightLiveData.observeAsState( + 0.0f + ) + val webReaderParams: WebReaderParams? by webReaderViewModel.webReaderParamsLiveData.observeAsState( + null + ) + var isMenuExpanded by remember { mutableStateOf(false) } + + val themeBackgroundColor = currentTheme?.let { + if (it.themeKey == "System" && isDarkMode) { + Color(0xFF000000) + } else if (it.themeKey == "System") { + Color(0xFFFFFFFF) + } else { + Color(it.backgroundColor) + } + } ?: Color(0xFFFFFFFF) + + val themeTintColor = currentTheme?.let { + if (it.themeKey == "System" && isDarkMode) { + Color(0xFFFFFFFF) + } else if (it.themeKey == "System") { + Color(0xFF000000) + } else { + Color(it.foregroundColor) + } + } ?: Color(0xFF000000) + + + TopAppBar( + modifier = Modifier + .height(height = with(LocalDensity.current) { + toolbarHeightPx.roundToInt().toDp() + }), + backgroundColor = themeBackgroundColor, + elevation = 0.dp, + title = {}, + navigationIcon = { + IconButton(onClick = { + onBackPressedDispatcher?.onBackPressed() + }) { + Icon( + imageVector = Icons.AutoMirrored.Filled.ArrowBack, + modifier = Modifier, + contentDescription = "Back", + tint = themeTintColor + ) + } + }, + actions = { + if (onLibraryIconTap != null) { + IconButton(onClick = { onLibraryIconTap() }) { + Icon( + imageVector = Icons.Default.Home, + contentDescription = null, + tint = themeTintColor, + ) + } + } + webReaderParams?.let { + IconButton(onClick = { + webReaderViewModel.setBottomSheet(BottomSheetState.NOTEBOOK) + }) { + Icon( + painter = painterResource(id = R.drawable.notebook), + contentDescription = null, + tint = themeTintColor + ) + } + } + IconButton(onClick = { + webReaderViewModel.setBottomSheet(BottomSheetState.PREFERENCES) + }) { + Icon( + painter = painterResource(id = R.drawable.format_letter_case), + contentDescription = null, + tint = themeTintColor + ) + } + IconButton(onClick = { isMenuExpanded = true }) { + Icon( + painter = painterResource(id = R.drawable.dots_horizontal), + contentDescription = null, + tint = themeTintColor + ) + if (isMenuExpanded) { + webReaderParams?.let { params -> + SavedItemContextMenu( + context = context, + isExpanded = true, + isArchived = params.item.isArchived, + onDismiss = { isMenuExpanded = false }, + webReaderViewModel = webReaderViewModel, + actionHandler = { + webReaderViewModel.handleSavedItemAction( + params.item.savedItemId, + it + ) + } + ) + } + } + } + }, + ) +} + +@Composable +fun BottomSheetUI(content: @Composable () -> Unit) { + Box( + modifier = Modifier + .wrapContentHeight() + .fillMaxWidth() + .clip(RoundedCornerShape(topEnd = 20.dp, topStart = 20.dp)) + .background(Color.White) + .statusBarsPadding() + ) { + Scaffold { paddingValues -> + Box(modifier = Modifier.fillMaxSize()) { + content() + } + } + } +} diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReaderViewModel.kt similarity index 92% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderViewModel.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReaderViewModel.kt index 9b6b4db2a..43848ceeb 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderViewModel.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/reader/WebReaderViewModel.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.reader +package app.omnivore.omnivore.feature.reader import android.content.ClipData import android.content.ClipboardManager @@ -13,29 +13,29 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.asLiveData import androidx.lifecycle.viewModelScope -import app.omnivore.omnivore.DatastoreKeys -import app.omnivore.omnivore.DatastoreRepository -import app.omnivore.omnivore.EventTracker +import app.omnivore.omnivore.utils.DatastoreKeys +import app.omnivore.omnivore.core.datastore.DatastoreRepository +import app.omnivore.omnivore.core.analytics.EventTracker import app.omnivore.omnivore.R -import app.omnivore.omnivore.dataService.DataService -import app.omnivore.omnivore.dataService.archiveSavedItem -import app.omnivore.omnivore.dataService.createWebHighlight -import app.omnivore.omnivore.dataService.deleteHighlightFromJSON -import app.omnivore.omnivore.dataService.deleteSavedItem -import app.omnivore.omnivore.dataService.mergeWebHighlights -import app.omnivore.omnivore.dataService.unarchiveSavedItem -import app.omnivore.omnivore.dataService.updateWebHighlight -import app.omnivore.omnivore.dataService.updateWebReadingProgress +import app.omnivore.omnivore.core.data.DataService +import app.omnivore.omnivore.core.data.archiveSavedItem +import app.omnivore.omnivore.core.data.createWebHighlight +import app.omnivore.omnivore.core.data.deleteHighlightFromJSON +import app.omnivore.omnivore.core.data.deleteSavedItem +import app.omnivore.omnivore.core.data.mergeWebHighlights +import app.omnivore.omnivore.core.data.unarchiveSavedItem +import app.omnivore.omnivore.core.data.updateWebHighlight +import app.omnivore.omnivore.core.data.updateWebReadingProgress import app.omnivore.omnivore.graphql.generated.type.CreateLabelInput -import app.omnivore.omnivore.network.Networker -import app.omnivore.omnivore.network.createNewLabel -import app.omnivore.omnivore.network.saveUrl -import app.omnivore.omnivore.network.savedItem -import app.omnivore.omnivore.persistence.entities.SavedItem -import app.omnivore.omnivore.persistence.entities.SavedItemLabel -import app.omnivore.omnivore.ui.components.HighlightColor -import app.omnivore.omnivore.ui.library.SavedItemAction -import app.omnivore.omnivore.ui.setSavedItemLabels +import app.omnivore.omnivore.core.network.Networker +import app.omnivore.omnivore.core.network.createNewLabel +import app.omnivore.omnivore.core.network.saveUrl +import app.omnivore.omnivore.core.network.savedItem +import app.omnivore.omnivore.core.database.entities.SavedItem +import app.omnivore.omnivore.core.database.entities.SavedItemLabel +import app.omnivore.omnivore.feature.components.HighlightColor +import app.omnivore.omnivore.feature.library.SavedItemAction +import app.omnivore.omnivore.feature.setSavedItemLabels import com.apollographql.apollo3.api.Optional.Companion.presentIfNotNull import com.google.gson.Gson import dagger.hilt.android.lifecycle.HiltViewModel @@ -345,6 +345,20 @@ class WebReaderViewModel @Inject constructor( ) } } + + SavedItemAction.MarkUnread -> { + viewModelScope.launch { + dataService.updateWebReadingProgress( + jsonString = Gson().toJson( + mapOf( + "id" to itemID, + "readingProgressPercent" to 0, + "readingProgressAnchorIndex" to 0 + ) + ) + ) + } + } } } diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/root/RootView.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/root/RootView.kt similarity index 79% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/root/RootView.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/root/RootView.kt index cdb12f527..42643e2f3 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/root/RootView.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/root/RootView.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.root +package app.omnivore.omnivore.feature.root import androidx.compose.foundation.layout.Box import androidx.compose.runtime.Composable @@ -8,19 +8,19 @@ import androidx.compose.runtime.livedata.observeAsState import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController -import app.omnivore.omnivore.Routes -import app.omnivore.omnivore.ui.auth.LoginViewModel -import app.omnivore.omnivore.ui.auth.WelcomeScreen -import app.omnivore.omnivore.ui.components.LabelsViewModel -import app.omnivore.omnivore.ui.editinfo.EditInfoViewModel -import app.omnivore.omnivore.ui.library.LibraryView -import app.omnivore.omnivore.ui.library.LibraryViewModel -import app.omnivore.omnivore.ui.library.SearchView -import app.omnivore.omnivore.ui.library.SearchViewModel -import app.omnivore.omnivore.ui.save.SaveViewModel -import app.omnivore.omnivore.ui.settings.PolicyWebView -import app.omnivore.omnivore.ui.settings.SettingsView -import app.omnivore.omnivore.ui.settings.SettingsViewModel +import app.omnivore.omnivore.navigation.Routes +import app.omnivore.omnivore.feature.auth.LoginViewModel +import app.omnivore.omnivore.feature.auth.WelcomeScreen +import app.omnivore.omnivore.feature.components.LabelsViewModel +import app.omnivore.omnivore.feature.editinfo.EditInfoViewModel +import app.omnivore.omnivore.feature.library.LibraryView +import app.omnivore.omnivore.feature.library.LibraryViewModel +import app.omnivore.omnivore.feature.library.SearchView +import app.omnivore.omnivore.feature.library.SearchViewModel +import app.omnivore.omnivore.feature.save.SaveViewModel +import app.omnivore.omnivore.feature.settings.PolicyWebView +import app.omnivore.omnivore.feature.settings.SettingsView +import app.omnivore.omnivore.feature.settings.SettingsViewModel @Composable fun RootView( diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/save/SaveContent.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/save/SaveContent.kt similarity index 95% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/save/SaveContent.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/save/SaveContent.kt index 203f41700..8d6f352b4 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/save/SaveContent.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/save/SaveContent.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.save +package app.omnivore.omnivore.feature.save import android.content.Intent import androidx.compose.foundation.background @@ -16,7 +16,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import app.omnivore.omnivore.R -import app.omnivore.omnivore.ui.reader.WebReaderLoadingContainerActivity +import app.omnivore.omnivore.feature.reader.WebReaderLoadingContainerActivity import kotlinx.coroutines.launch @Composable diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/save/SaveSheetActivity.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/save/SaveSheetActivity.kt similarity index 98% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/save/SaveSheetActivity.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/save/SaveSheetActivity.kt index 42d9f83e8..f1e6dbf1e 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/save/SaveSheetActivity.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/save/SaveSheetActivity.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.save +package app.omnivore.omnivore.feature.save import android.content.ContentValues import android.content.Intent @@ -12,7 +12,6 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.* -import androidx.compose.material.icons.filled.* import androidx.compose.runtime.* import androidx.compose.runtime.livedata.observeAsState import androidx.compose.ui.Alignment.Companion.TopCenter diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/save/SaveViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/save/SaveViewModel.kt similarity index 93% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/save/SaveViewModel.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/save/SaveViewModel.kt index 437982b0b..f2dba6cf7 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/save/SaveViewModel.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/save/SaveViewModel.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.save +package app.omnivore.omnivore.feature.save import android.util.Patterns import androidx.compose.runtime.getValue @@ -8,13 +8,13 @@ import androidx.compose.ui.text.intl.Locale import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import app.omnivore.omnivore.Constants -import app.omnivore.omnivore.DatastoreKeys -import app.omnivore.omnivore.DatastoreRepository +import app.omnivore.omnivore.utils.Constants +import app.omnivore.omnivore.utils.DatastoreKeys +import app.omnivore.omnivore.core.datastore.DatastoreRepository import app.omnivore.omnivore.R import app.omnivore.omnivore.graphql.generated.SaveUrlMutation import app.omnivore.omnivore.graphql.generated.type.SaveUrlInput -import app.omnivore.omnivore.ui.ResourceProvider +import app.omnivore.omnivore.feature.ResourceProvider import com.apollographql.apollo3.ApolloClient import com.apollographql.apollo3.api.Optional import dagger.hilt.android.lifecycle.HiltViewModel diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/savedItemViews/SavedItemCard.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/savedItemViews/SavedItemCard.kt similarity index 93% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/savedItemViews/SavedItemCard.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/savedItemViews/SavedItemCard.kt index 35f90976f..806cc7c9b 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/savedItemViews/SavedItemCard.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/savedItemViews/SavedItemCard.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.savedItemViews +package app.omnivore.omnivore.feature.savedItemViews import androidx.compose.foundation.* import androidx.compose.foundation.layout.* @@ -19,12 +19,12 @@ import androidx.compose.ui.text.toLowerCase import androidx.compose.ui.text.toUpperCase import androidx.compose.ui.unit.* import app.omnivore.omnivore.R -import app.omnivore.omnivore.persistence.entities.SavedItemLabel -import app.omnivore.omnivore.persistence.entities.SavedItemWithLabelsAndHighlights -import app.omnivore.omnivore.ui.components.LabelChip -import app.omnivore.omnivore.ui.components.LabelChipColors -import app.omnivore.omnivore.ui.library.SavedItemAction -import app.omnivore.omnivore.ui.library.SavedItemViewModel +import app.omnivore.omnivore.core.database.entities.SavedItemLabel +import app.omnivore.omnivore.core.database.entities.SavedItemWithLabelsAndHighlights +import app.omnivore.omnivore.feature.components.LabelChipColors +import app.omnivore.omnivore.feature.components.LabelFilterChip +import app.omnivore.omnivore.feature.library.SavedItemAction +import app.omnivore.omnivore.feature.library.SavedItemViewModel import coil.compose.rememberAsyncImagePainter @OptIn(ExperimentalFoundationApi::class, ExperimentalLayoutApi::class) @@ -108,9 +108,10 @@ fun SavedItemCard( savedItem.labels.filter { !isFlairLabel(it) }.sortedWith(compareBy { it.name.toLowerCase(Locale.current) }).forEach { label -> val chipColors = LabelChipColors.fromHex(label.color) - LabelChip( - name = label.name, - colors = chipColors, + LabelFilterChip( + onClick = { }, + label = label.name, + //colors = chipColors, ) } } diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/savedItemViews/SavedItemContextMenu.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/savedItemViews/SavedItemContextMenu.kt new file mode 100644 index 000000000..de7278973 --- /dev/null +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/savedItemViews/SavedItemContextMenu.kt @@ -0,0 +1,72 @@ +package app.omnivore.omnivore.feature.savedItemViews + +import android.content.Context +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import app.omnivore.omnivore.R +import app.omnivore.omnivore.feature.library.SavedItemAction +import app.omnivore.omnivore.feature.reader.WebReaderViewModel + +@Composable +fun SavedItemContextMenu( + isExpanded: Boolean, + isArchived: Boolean, + context: Context, + webReaderViewModel: WebReaderViewModel, + onDismiss: () -> Unit, + actionHandler: (SavedItemAction) -> Unit +) { + val menuOptions = listOf( + MenuItemOption(R.string.saved_item_context_menu_action_edit_info, SavedItemAction.EditInfo), + MenuItemOption( + R.string.saved_item_context_menu_action_edit_labels, + SavedItemAction.EditLabels + ), + MenuItemOption( + textResourceId = if (isArchived) R.string.saved_item_context_menu_action_unarchive else R.string.saved_item_context_menu_action_archive, + action = if (isArchived) SavedItemAction.Unarchive else SavedItemAction.Archive + ), + MenuItemOption( + textResourceId = R.string.saved_item_context_menu_action_share_original, + customAction = { + webReaderViewModel.showShareLinkSheet(context) + onDismiss() + } + ), + MenuItemOption(R.string.saved_item_context_menu_action_remove_item, SavedItemAction.Delete) + ) + + DropdownMenu( + expanded = isExpanded, + onDismissRequest = onDismiss + ) { + menuOptions.forEach { option -> + if (option.customAction != null) { + DropdownMenuItem( + text = { Text( text = stringResource(option.textResourceId), fontWeight = FontWeight.Normal) }, + onClick = { + option.customAction.invoke() + } + ) + } else { + DropdownMenuItem( + text = { Text( text = stringResource(option.textResourceId), fontWeight = FontWeight.Normal) }, + onClick = { + option.action?.let { actionHandler(it) } + onDismiss() + } + ) + } + } + } +} + +data class MenuItemOption( + val textResourceId: Int, + val action: SavedItemAction? = null, + val customAction: (() -> Unit)? = null +) diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/savedItemViews/TypeaheadSearchCard.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/savedItemViews/TypeaheadSearchCard.kt similarity index 90% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/savedItemViews/TypeaheadSearchCard.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/savedItemViews/TypeaheadSearchCard.kt index 551594bd1..2eb86e04a 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/savedItemViews/TypeaheadSearchCard.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/savedItemViews/TypeaheadSearchCard.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.savedItemViews +package app.omnivore.omnivore.feature.savedItemViews import androidx.compose.foundation.* import androidx.compose.foundation.layout.* @@ -10,8 +10,8 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.* -import app.omnivore.omnivore.persistence.entities.TypeaheadCardData -import app.omnivore.omnivore.ui.library.SavedItemAction +import app.omnivore.omnivore.core.database.entities.TypeaheadCardData +import app.omnivore.omnivore.feature.library.SavedItemAction @OptIn(ExperimentalFoundationApi::class) @Composable diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/settings/LogoutDialog.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/LogoutDialog.kt similarity index 96% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/settings/LogoutDialog.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/LogoutDialog.kt index 569990988..993944f8f 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/settings/LogoutDialog.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/LogoutDialog.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.settings +package app.omnivore.omnivore.feature.settings import androidx.compose.material3.AlertDialog import androidx.compose.material3.Button diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/settings/ManageAccount.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/ManageAccount.kt similarity index 97% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/settings/ManageAccount.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/ManageAccount.kt index 9d73fe181..242290ffb 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/settings/ManageAccount.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/ManageAccount.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.settings +package app.omnivore.omnivore.feature.settings import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/settings/PolicyWebView.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/PolicyWebView.kt similarity index 96% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/settings/PolicyWebView.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/PolicyWebView.kt index 71553eb41..b7f7d6d8f 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/settings/PolicyWebView.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/PolicyWebView.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.settings +package app.omnivore.omnivore.feature.settings import android.annotation.SuppressLint import android.view.ViewGroup @@ -14,7 +14,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.viewinterop.AndroidView import androidx.navigation.NavHostController -import app.omnivore.omnivore.Routes +import app.omnivore.omnivore.navigation.Routes import app.omnivore.omnivore.R @SuppressLint("UnusedMaterial3ScaffoldPaddingParameter", "SetJavaScriptEnabled") diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/settings/SettingsContent.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/SettingsContent.kt similarity index 97% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/settings/SettingsContent.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/SettingsContent.kt index 56de10295..a2e34294d 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/settings/SettingsContent.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/SettingsContent.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.settings +package app.omnivore.omnivore.feature.settings import androidx.compose.foundation.background import androidx.compose.foundation.clickable @@ -18,8 +18,8 @@ import androidx.compose.ui.unit.sp import androidx.navigation.NavHostController import app.omnivore.omnivore.BuildConfig import app.omnivore.omnivore.R -import app.omnivore.omnivore.Routes -import app.omnivore.omnivore.ui.auth.LoginViewModel +import app.omnivore.omnivore.navigation.Routes +import app.omnivore.omnivore.feature.auth.LoginViewModel @OptIn(ExperimentalMaterial3Api::class) @Composable diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/settings/SettingsViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/SettingsViewModel.kt similarity index 75% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/settings/SettingsViewModel.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/SettingsViewModel.kt index aca0f17ff..6dde3d23f 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/settings/SettingsViewModel.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/settings/SettingsViewModel.kt @@ -1,12 +1,12 @@ -package app.omnivore.omnivore.ui.settings +package app.omnivore.omnivore.feature.settings import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import app.omnivore.omnivore.DatastoreKeys -import app.omnivore.omnivore.DatastoreRepository -import app.omnivore.omnivore.dataService.DataService -import app.omnivore.omnivore.network.Networker -import app.omnivore.omnivore.network.viewer +import app.omnivore.omnivore.utils.DatastoreKeys +import app.omnivore.omnivore.core.datastore.DatastoreRepository +import app.omnivore.omnivore.core.data.DataService +import app.omnivore.omnivore.core.network.Networker +import app.omnivore.omnivore.core.network.viewer import dagger.hilt.android.lifecycle.HiltViewModel import io.intercom.android.sdk.Intercom import io.intercom.android.sdk.IntercomSpace diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/theme/Color.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/theme/Color.kt similarity index 98% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/theme/Color.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/theme/Color.kt index 8939caf19..13e96a379 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/theme/Color.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/theme/Color.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.theme +package app.omnivore.omnivore.feature.theme import androidx.compose.ui.graphics.Color diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/theme/Shape.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/theme/Shape.kt similarity index 85% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/theme/Shape.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/theme/Shape.kt index a8b1533e7..15ff7fd39 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/theme/Shape.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/theme/Shape.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.theme +package app.omnivore.omnivore.feature.theme import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Shapes diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/theme/Theme.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/theme/Theme.kt similarity index 98% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/theme/Theme.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/theme/Theme.kt index 9384a2ce8..2b795260d 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/theme/Theme.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/theme/Theme.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.theme +package app.omnivore.omnivore.feature.theme import android.os.Build import androidx.compose.foundation.isSystemInDarkTheme diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/theme/Type.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/theme/Type.kt similarity index 96% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/theme/Type.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/theme/Type.kt index 86df5fe88..b9786c14a 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/theme/Type.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/feature/theme/Type.kt @@ -1,4 +1,4 @@ -package app.omnivore.omnivore.ui.theme +package app.omnivore.omnivore.feature.theme import androidx.compose.material3.Typography diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/models/ServerSyncStatus.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/models/ServerSyncStatus.kt deleted file mode 100644 index 46871ee93..000000000 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/models/ServerSyncStatus.kt +++ /dev/null @@ -1,10 +0,0 @@ -package app.omnivore.omnivore.models - -enum class ServerSyncStatus(val rawValue: Int) { - IS_SYNCED(0), - IS_SYNCING(1), - NEEDS_DELETION(2), - NEEDS_CREATION(3), - NEEDS_UPDATE(4), - NEEDS_MERGE(5) -} diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/navigation/Routes.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/navigation/Routes.kt new file mode 100644 index 000000000..62f1a780b --- /dev/null +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/navigation/Routes.kt @@ -0,0 +1,11 @@ +package app.omnivore.omnivore.navigation + +sealed class Routes(val route: String) { + object Library : Routes("Library") + object Settings : Routes("Settings") + object Search : Routes("Search") + object Documentation : Routes("Documentation") + object PrivacyPolicy : Routes("PrivacyPolicy") + object TermsAndConditions : Routes("TermsAndConditions") + object Notebook : Routes("Notebook") +} diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/AppDatabase.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/AppDatabase.kt deleted file mode 100644 index b1a6bd3ab..000000000 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/AppDatabase.kt +++ /dev/null @@ -1,28 +0,0 @@ -package app.omnivore.omnivore.persistence - -import androidx.room.Database -import androidx.room.RoomDatabase -import app.omnivore.omnivore.persistence.entities.* - -@Database( - entities = [ - Viewer::class, - SavedItem::class, - SavedItemLabel::class, - Highlight::class, - HighlightChange::class, - SavedItemAndSavedItemLabelCrossRef::class, - SavedItemAndHighlightCrossRef::class - ], - version = 24 -) -abstract class AppDatabase : RoomDatabase() { - abstract fun viewerDao(): ViewerDao - abstract fun savedItemDao(): SavedItemDao - abstract fun highlightDao(): HighlightDao - abstract fun highlightChangesDao(): HighlightChangesDao - abstract fun savedItemLabelDao(): SavedItemLabelDao - abstract fun savedItemWithLabelsAndHighlightsDao(): SavedItemWithLabelsAndHighlightsDao - abstract fun savedItemAndSavedItemLabelCrossRefDao(): SavedItemAndSavedItemLabelCrossRefDao - abstract fun savedItemAndHighlightCrossRefDao(): SavedItemAndHighlightCrossRefDao -} diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelChip.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelChip.kt deleted file mode 100644 index a7342b9d9..000000000 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/components/LabelChip.kt +++ /dev/null @@ -1,33 +0,0 @@ -package app.omnivore.omnivore.ui.components - -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.padding -import androidx.compose.material.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp - -@Composable -fun LabelChip( - modifier: Modifier = Modifier, - name: String, - colors: LabelChipColors, -) { - Surface( - modifier = modifier.padding(2.dp), - shape = MaterialTheme.shapes.medium, - color = colors.containerColor - ) { - Row(modifier = Modifier - ) { - Text( - text = name, - color = colors.textColor, - style = MaterialTheme.typography.subtitle2, - modifier = Modifier.padding(vertical = 3.dp, horizontal = 5.dp) - ) - } - } -} diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryNavigationBar.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryNavigationBar.kt deleted file mode 100644 index cd17e939a..000000000 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/LibraryNavigationBar.kt +++ /dev/null @@ -1,276 +0,0 @@ -package app.omnivore.omnivore.ui.library - -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.* -import androidx.compose.material.icons.outlined.Delete -import androidx.compose.material.icons.outlined.Info -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.runtime.livedata.observeAsState -import androidx.compose.ui.Modifier -import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.focus.focusRequester -import androidx.compose.ui.focus.onFocusChanged -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.input.ImeAction -import androidx.navigation.NavHostController -import app.omnivore.omnivore.R -import app.omnivore.omnivore.persistence.entities.SavedItemWithLabelsAndHighlights - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun LibraryNavigationBar( - savedItemViewModel: SavedItemViewModel, - onSearchClicked: () -> Unit, - onAddLinkClicked: () -> Unit, - onSettingsIconClick: () -> Unit -) { - val actionsMenuItem: SavedItemWithLabelsAndHighlights? by savedItemViewModel.actionsMenuItemLiveData.observeAsState(null) - - TopAppBar( - title = { - Text(if (actionsMenuItem == null) - stringResource(R.string.library_nav_bar_title) else - stringResource(R.string.library_nav_bar_title_alt)) - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = if (actionsMenuItem == null) MaterialTheme.colorScheme.background else MaterialTheme.colorScheme.surfaceVariant - ), - navigationIcon = { - if (actionsMenuItem != null) { - IconButton(onClick = { - savedItemViewModel.actionsMenuItemLiveData.postValue(null) - }) { - Icon( - imageVector = Icons.Filled.ArrowBack, - modifier = Modifier, - contentDescription = "Back" - ) - } - } - }, - actions = { - actionsMenuItem?.let { - IconButton(onClick = { - savedItemViewModel.handleSavedItemAction( - it.savedItem.savedItemId, - if (it.savedItem.isArchived) SavedItemAction.Unarchive else SavedItemAction.Archive - ) }) { - if (it.savedItem.isArchived) { - Icon( - painter = painterResource(id = R.drawable.unarchive), - contentDescription = null - ) - } else { - Icon( - painter = painterResource(id = R.drawable.archive_outline), - contentDescription = null - ) - } - } - IconButton(onClick = { savedItemViewModel.handleSavedItemAction(it.savedItem.savedItemId, SavedItemAction.EditInfo) }) { - Icon( - Icons.Outlined.Info, - contentDescription = null - ) - } - IconButton(onClick = { savedItemViewModel.handleSavedItemAction(it.savedItem.savedItemId, SavedItemAction.EditLabels) }) { - Icon( - painter = painterResource(id = R.drawable.tag), - contentDescription = null - ) - } - IconButton(onClick = { savedItemViewModel.handleSavedItemAction(it.savedItem.savedItemId, SavedItemAction.Delete) }) { - Icon( - imageVector = Icons.Outlined.Delete, - contentDescription = null - ) - } -// IconButton(onClick = onSettingsIconClick) { -// Icon( -// imageVector = Icons.Default.MoreVert, -// contentDescription = null -// ) -// } - } ?: run { - IconButton(onClick = onSearchClicked) { - Icon( - imageVector = Icons.Filled.Search, - contentDescription = null - ) - } - - IconButton(onClick = onAddLinkClicked) { - Icon( - imageVector = Icons.Filled.Add, - contentDescription = null - ) - } - - IconButton(onClick = onSettingsIconClick) { - Icon( - imageVector = Icons.Default.MoreVert, - contentDescription = null - ) - } - } - } - ) -} -// -//@OptIn(ExperimentalMaterial3Api::class) -//@Composable -//fun LibraryBottomBar( -// savedItemViewModel: SavedItemViewModel, -// onSearchClicked: () -> Unit, -// onSettingsIconClick: () -> Unit -//) { -// val actionsMenuItem: SavedItemCardData? by savedItemViewModel.actionsMenuItemLiveData.observeAsState(null) -// -// BottomAppBar( -//// colors = TopAppBarDefaults.topAppBarColors( -//// containerColor = if (actionsMenuItem == null) MaterialTheme.colorScheme.background else MaterialTheme.colorScheme.surfaceVariant -//// ), -//// trailingIcon = { -//// if (actionsMenuItem != null) { -//// IconButton(onClick = { -//// savedItemViewModel.actionsMenuItemLiveData.postValue(null) -//// }) { -//// Icon( -//// imageVector = androidx.compose.material.icons.Icons.Filled.ArrowBack, -//// modifier = Modifier, -//// contentDescription = "Back" -//// ) -//// } -//// } -//// }, -// floatingActionButton = { -// IconButton(onClick = onSearchClicked) { -// Icon( -// imageVector = Icons.Outlined.Close, -// contentDescription = null -// ) -// } -// }, -// actions = { -// actionsMenuItem?.let { -// IconButton(onClick = onSearchClicked) { -// if (it.isArchived) { -// Icon( -// painter = painterResource(id = R.drawable.unarchive), -// contentDescription = null -// ) -// } else { -// Icon( -// painter = painterResource(id = R.drawable.archive_outline), -// contentDescription = null -// ) -// } -// } -// IconButton(onClick = onSearchClicked) { -// Icon( -// painter = painterResource(id = R.drawable.tag), -// contentDescription = null -// ) -// } -// IconButton(onClick = onSearchClicked) { -// Icon( -// imageVector = Icons.Outlined.Delete, -// contentDescription = null -// ) -// } -// IconButton(onClick = onSettingsIconClick) { -// Icon( -// imageVector = Icons.Default.MoreVert, -// contentDescription = null -// ) -// } -// } ?: run { -// IconButton(onClick = onSearchClicked) { -// Icon( -// imageVector = Icons.Filled.Search, -// contentDescription = null -// ) -// } -// -// IconButton(onClick = onSettingsIconClick) { -// Icon( -// imageVector = Icons.Default.MoreVert, -// contentDescription = null -// ) -// } -// } -// } -// ) -//} - - - -@Composable -fun SearchField( - searchText: String, - onSearch: () -> Unit, - onSearchTextChanged: (String) -> Unit, - navController: NavHostController, -) { - var showClearButton by remember { mutableStateOf(false) } - val focusRequester = remember { FocusRequester() } - - TextField( - modifier = Modifier - .fillMaxWidth() - .onFocusChanged { focusState -> - showClearButton = (focusState.isFocused) - } - .focusRequester(focusRequester), - value = searchText, - onValueChange = onSearchTextChanged, - placeholder = { - Text(text = stringResource(R.string.library_nav_bar_field_placeholder_search)) - }, - leadingIcon = { - IconButton( - onClick = { - onSearchTextChanged("") - navController.popBackStack() - }) { - Icon( - imageVector = Icons.Filled.ArrowBack, - contentDescription = "Back" - ) - } - }, - trailingIcon = { - AnimatedVisibility( - visible = showClearButton, - enter = fadeIn(), - exit = fadeOut() - ) { - IconButton(onClick = { onSearchTextChanged("") }) { - Icon( - imageVector = Icons.Filled.Close, - contentDescription = null - ) - } - - } - }, - maxLines = 1, - singleLine = true, - keyboardOptions = KeyboardOptions.Default.copy(imeAction = ImeAction.Search), - keyboardActions = KeyboardActions(onSearch = { - onSearch() - }), - ) - - LaunchedEffect(Unit) { - focusRequester.requestFocus() - } -} diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/SavedItemSortFilter.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/SavedItemSortFilter.kt deleted file mode 100644 index 58f24174b..000000000 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/SavedItemSortFilter.kt +++ /dev/null @@ -1,35 +0,0 @@ -package app.omnivore.omnivore.ui.library - -import androidx.compose.material3.DropdownMenu -import androidx.compose.material3.DropdownMenuItem -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable - -enum class SavedItemSortFilter(val displayText: String, val rawValue: String, val queryString: String) { - NEWEST("Newest", rawValue = "newest", "sort:saved"), - OLDEST("Oldest", rawValue = "oldest", "sort:saved-ASC"), - RECENTLY_READ("Recently Read", rawValue = "recentlyRead", "sort:read"), - RECENTLY_PUBLISHED("Recently Published", rawValue = "recentlyPublished", "sort:published"), -} - -@Composable -fun SavedItemSortFilterContextMenu( - isExpanded: Boolean, - onDismiss: () -> Unit, - actionHandler: (SavedItemSortFilter) -> Unit -) { - DropdownMenu( - expanded = isExpanded, - onDismissRequest = onDismiss - ) { - SavedItemSortFilter.values().forEach { - DropdownMenuItem( - text = { Text(it.displayText) }, - onClick = { - actionHandler(it) - onDismiss() - } - ) - } - } -} diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/SearchView.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/SearchView.kt deleted file mode 100644 index a8b609253..000000000 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/library/SearchView.kt +++ /dev/null @@ -1,199 +0,0 @@ -package app.omnivore.omnivore.ui.library - -import android.content.Intent -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ArrowBack -import androidx.compose.material.icons.filled.MoreVert -import androidx.compose.material.icons.outlined.Delete -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.runtime.livedata.observeAsState -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.colorResource -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.unit.dp -import androidx.navigation.NavHostController -import app.omnivore.omnivore.R -import app.omnivore.omnivore.persistence.entities.SavedItemWithLabelsAndHighlights -import app.omnivore.omnivore.ui.reader.WebReaderLoadingContainerActivity -import app.omnivore.omnivore.persistence.entities.TypeaheadCardData -import app.omnivore.omnivore.ui.reader.PDFReaderActivity -import app.omnivore.omnivore.ui.savedItemViews.SavedItemCard -import app.omnivore.omnivore.ui.savedItemViews.TypeaheadSearchCard - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun SearchView( - viewModel: SearchViewModel, - navController: NavHostController -) { - val isRefreshing: Boolean by viewModel.isRefreshing.observeAsState(false) - val typeaheadMode: Boolean by viewModel.typeaheadMode.observeAsState(true) - val searchText: String by viewModel.searchTextLiveData.observeAsState("") - val actionsMenuItem: SavedItemWithLabelsAndHighlights? by viewModel.actionsMenuItemLiveData.observeAsState(null) - - Scaffold( - topBar = { - TopAppBar( - title = { Text("") }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = MaterialTheme.colorScheme.surfaceVariant - ), - navigationIcon = { - if (actionsMenuItem != null) { - IconButton(onClick = { - viewModel.actionsMenuItemLiveData.postValue(null) - }) { - Icon( - imageVector = Icons.Filled.ArrowBack, - modifier = Modifier, - contentDescription = "Back" - ) - } - } - }, - actions = { - if (actionsMenuItem != null) { - IconButton(onClick = { }) { - Icon( - painter = painterResource(id = R.drawable.archive_outline), - contentDescription = null - ) - } - IconButton(onClick = { }) { - Icon( - painter = painterResource(id = R.drawable.tag), - contentDescription = null - ) - } - IconButton(onClick = { }) { - Icon( - imageVector = Icons.Outlined.Delete, - contentDescription = null - ) - } - IconButton(onClick = { }) { - Icon( - imageVector = Icons.Default.MoreVert, - contentDescription = null - ) - } - } else { - Row { - SearchField( - searchText, - onSearch = { - viewModel.performSearch() - }, - onSearchTextChanged = { viewModel.updateSearchText(it) }, - navController = navController - ) - } - } - } - ) - - } - ) { paddingValues -> - if (isRefreshing) { - Row( - horizontalArrangement = Arrangement.Center, - modifier = Modifier - .padding(top = paddingValues.calculateTopPadding()) - .fillMaxWidth() - ) { - CircularProgressIndicator( - modifier = Modifier - .height(45.dp) - .width(45.dp), - strokeWidth = 5.dp, - color = colorResource(R.color.green_55B938) - ) - } - } else if (typeaheadMode) { - TypeaheadSearchViewContent( - viewModel, - modifier = Modifier - .padding(top = paddingValues.calculateTopPadding()) - ) - } else { - SearchViewContent( - viewModel, - modifier = Modifier - .padding(top = paddingValues.calculateTopPadding()) - ) - } - } -} - -@Composable -fun TypeaheadSearchViewContent(viewModel: SearchViewModel, modifier: Modifier) { - val context = LocalContext.current - val listState = rememberLazyListState() - - val searchedCardsData: List by viewModel.searchItemsLiveData.observeAsState(listOf()) - - LazyColumn( - state = listState, - verticalArrangement = Arrangement.Top, - horizontalAlignment = Alignment.CenterHorizontally, - modifier = modifier - .background(MaterialTheme.colorScheme.background) - .fillMaxSize() - - ) { - items(searchedCardsData) { cardData -> - TypeaheadSearchCard( - cardData = cardData, - onClickHandler = { - // val activityClass = if (cardData.isPDF()) PDFReaderActivity::class.java else WebReaderLoadingContainerActivity::class.java - val activityClass = WebReaderLoadingContainerActivity::class.java - val intent = Intent(context, activityClass) - intent.putExtra("SAVED_ITEM_SLUG", cardData.slug) - context.startActivity(intent) - }, - actionHandler = { viewModel.handleSavedItemAction(cardData.savedItemId, it) } - ) - } - } -} - -@Composable -fun SearchViewContent(viewModel: SearchViewModel, modifier: Modifier) { - val context = LocalContext.current - val listState = rememberLazyListState() - - val cardsData: List by viewModel.itemsLiveData.observeAsState(listOf()) - - LazyColumn( - state = listState, - verticalArrangement = Arrangement.Top, - horizontalAlignment = Alignment.CenterHorizontally, - modifier = modifier - .background(MaterialTheme.colorScheme.background) - .fillMaxSize() - - ) { - items(cardsData) { cardDataWithLabels -> - SavedItemCard( - selected = false, - savedItemViewModel = viewModel, - savedItem = cardDataWithLabels, - onClickHandler = { - val activityClass = if (cardDataWithLabels.savedItem.contentReader == "PDF") PDFReaderActivity::class.java else WebReaderLoadingContainerActivity::class.java - val intent = Intent(context, activityClass) - intent.putExtra("SAVED_ITEM_SLUG", cardDataWithLabels.savedItem.slug) - context.startActivity(intent) - }, - actionHandler = { viewModel.handleSavedItemAction(cardDataWithLabels.savedItem.savedItemId, it) } - ) - } - } -} diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderLoadingContainer.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderLoadingContainer.kt deleted file mode 100644 index f3945e24c..000000000 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderLoadingContainer.kt +++ /dev/null @@ -1,473 +0,0 @@ -package app.omnivore.omnivore.ui.reader - -import android.content.Intent -import android.os.Bundle -import android.view.View -import androidx.activity.ComponentActivity -import androidx.activity.compose.LocalOnBackPressedDispatcherOwner -import androidx.activity.compose.setContent -import androidx.activity.viewModels -import androidx.compose.foundation.background -import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.* -import androidx.compose.material.MaterialTheme -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ArrowBack -import androidx.compose.material.icons.filled.Home -import androidx.compose.material3.* -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.Text -import androidx.compose.runtime.* -import androidx.compose.runtime.livedata.observeAsState -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.unit.dp -import androidx.core.view.ViewCompat -import androidx.core.view.WindowCompat -import androidx.core.view.WindowInsetsCompat -import app.omnivore.omnivore.MainActivity -import app.omnivore.omnivore.R -import app.omnivore.omnivore.persistence.entities.SavedItemLabel -import app.omnivore.omnivore.ui.components.LabelsSelectionSheetContent -import app.omnivore.omnivore.ui.notebook.NotebookView -import app.omnivore.omnivore.ui.notebook.NotebookViewModel -import app.omnivore.omnivore.ui.savedItemViews.SavedItemContextMenu -import app.omnivore.omnivore.ui.theme.OmnivoreTheme -import com.google.accompanist.systemuicontroller.rememberSystemUiController -import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.launch -import kotlin.math.roundToInt -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.stringResource -import app.omnivore.omnivore.ui.editinfo.EditInfoSheetContent -import app.omnivore.omnivore.ui.components.LabelsViewModel -import app.omnivore.omnivore.ui.editinfo.EditInfoViewModel -import app.omnivore.omnivore.ui.notebook.EditNoteModal - -@AndroidEntryPoint -class WebReaderLoadingContainerActivity: ComponentActivity() { - val viewModel: WebReaderViewModel by viewModels() - private val notebookViewModel: NotebookViewModel by viewModels() - private val labelsViewModel: LabelsViewModel by viewModels() - private val editInfoViewModel: EditInfoViewModel by viewModels() - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - val requestID = intent.getStringExtra("SAVED_ITEM_REQUEST_ID") - val slug = intent.getStringExtra("SAVED_ITEM_SLUG") - - viewModel.loadItem(slug = slug, requestID = requestID) - - setContent { - val systemUiController = rememberSystemUiController() - val useDarkIcons = !isSystemInDarkTheme() - - DisposableEffect(systemUiController, useDarkIcons) { - systemUiController.setSystemBarsColor( - color = Color.Black, - darkIcons = false - ) - - onDispose {} - } - - OmnivoreTheme { - Box( - modifier = Modifier - .fillMaxSize() - .background(color = Color.Black) - ) { - if (viewModel.hasFetchError.value == true) { - Text(stringResource(R.string.web_reader_loading_container_error_msg)) - } else { - WebReaderLoadingContainer( - onLibraryIconTap = if (requestID != null) { { startMainActivity() } } else null, - webReaderViewModel = viewModel, - notebookViewModel = notebookViewModel, - labelsViewModel = labelsViewModel, - editInfoViewModel = editInfoViewModel, - ) - } - } - } - } - - // animate the view up when keyboard appears - WindowCompat.setDecorFitsSystemWindows(window, false) - val rootView = findViewById(android.R.id.content).rootView - ViewCompat.setOnApplyWindowInsetsListener(rootView) { _, insets -> - val imeHeight = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom - rootView.setPadding(0, 0, 0, imeHeight) - insets - } - } - - private fun startMainActivity() { - val intent = Intent(this, MainActivity::class.java) - this.startActivity(intent) - } -} - -enum class BottomSheetState { - NONE, - PREFERENCES, - NOTEBOOK, - EDITNOTE, - HIGHLIGHTNOTE, - LABELS, - LINK, - EDIT_INFO, -} - - -@OptIn(ExperimentalMaterialApi::class) -@Composable -fun WebReaderLoadingContainer(onLibraryIconTap: (() -> Unit)? = null, - webReaderViewModel: WebReaderViewModel, - notebookViewModel: NotebookViewModel, - labelsViewModel: LabelsViewModel, - editInfoViewModel: EditInfoViewModel) { - val currentThemeKey = webReaderViewModel.currentThemeKey.observeAsState() - val currentTheme = Themes.values().find { it.themeKey == currentThemeKey.value } - val onBackPressedDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher - val bottomSheetState: BottomSheetState? by webReaderViewModel.bottomSheetStateLiveData.observeAsState(BottomSheetState.NONE) - - val webReaderParams: WebReaderParams? by webReaderViewModel.webReaderParamsLiveData.observeAsState(null) - val shouldPopView: Boolean by webReaderViewModel.shouldPopViewLiveData.observeAsState(false) - - val labels: List by webReaderViewModel.savedItemLabelsLiveData.observeAsState(listOf()) - - val maxToolbarHeight = 48.dp - webReaderViewModel.maxToolbarHeightPx = with(LocalDensity.current) { maxToolbarHeight.roundToPx().toFloat() } - - val coroutineScope = rememberCoroutineScope() - - val styledContent = webReaderParams?.let { - val webReaderContent = WebReaderContent( - preferences = webReaderViewModel.storedWebPreferences(isSystemInDarkTheme()), - item = it.item, - articleContent = it.articleContent, - ) - webReaderContent.styledContent() - } - - - val modalBottomSheetState = rememberModalBottomSheetState( - initialValue = ModalBottomSheetValue.Hidden, - skipHalfExpanded = bottomSheetState == BottomSheetState.EDITNOTE || bottomSheetState == BottomSheetState.HIGHLIGHTNOTE, - confirmValueChange = { - if (it == ModalBottomSheetValue.Hidden) { - webReaderViewModel.resetBottomSheet() - } - true - } - ) - - val showMenu = { - coroutineScope.launch { - modalBottomSheetState.show() - } - } - - when (bottomSheetState) { - BottomSheetState.PREFERENCES -> { - coroutineScope.launch { - if (!modalBottomSheetState.isVisible) { - modalBottomSheetState.show() - } - } - } - BottomSheetState.NOTEBOOK, BottomSheetState.EDITNOTE, - BottomSheetState.HIGHLIGHTNOTE, BottomSheetState.LABELS, BottomSheetState.EDIT_INFO, - BottomSheetState.LINK, -> { - showMenu() - } - else -> { - coroutineScope.launch { - modalBottomSheetState.hide() - } - } - } - - ModalBottomSheetLayout( - modifier = Modifier - .statusBarsPadding(), - sheetBackgroundColor = Color.Transparent, - sheetState = modalBottomSheetState, - sheetContent = { - when (bottomSheetState) { - BottomSheetState.PREFERENCES -> { - BottomSheetUI { - ReaderPreferencesView(webReaderViewModel) - } - } - BottomSheetState.NOTEBOOK -> { - webReaderParams?.let { params -> - BottomSheetUI { - NotebookView(savedItemId = params.item.savedItemId, viewModel = notebookViewModel, onEditNote = { - notebookViewModel.highlightUnderEdit = it - webReaderViewModel.setBottomSheet(BottomSheetState.EDITNOTE) - }) - } - } - } - BottomSheetState.EDITNOTE -> { - webReaderParams?.let { params -> - EditNoteModal( - initialValue = notebookViewModel.highlightUnderEdit?.annotation, - onDismiss = { save, note -> - coroutineScope.launch { - if (save) { - notebookViewModel.highlightUnderEdit?.let { highlight -> - notebookViewModel.updateHighlightNote(highlight.highlightId, note) - } ?: run { - if (note != null) { - notebookViewModel.addArticleNote( - savedItemId = params.item.savedItemId, - note = note - ) - } - } - } - notebookViewModel.highlightUnderEdit = null - } - webReaderViewModel.setBottomSheet(BottomSheetState.NOTEBOOK) - }) - } - } - BottomSheetState.HIGHLIGHTNOTE -> { - EditNoteModal( - initialValue = webReaderViewModel.annotation, - onDismiss = { save, note -> - coroutineScope.launch { - if (save) { - webReaderViewModel.saveAnnotation(note ?: "") - } else { - webReaderViewModel.cancelAnnotation() - } - webReaderViewModel.annotation = null - } - webReaderViewModel.resetBottomSheet() - } - ) - } - BottomSheetState.LABELS -> { - BottomSheetUI { - LabelsSelectionSheetContent( - labels = labels, - labelsViewModel = labelsViewModel, - initialSelectedLabels = webReaderParams?.labels ?: listOf(), - onCancel = { - coroutineScope.launch { - webReaderViewModel.resetBottomSheet() - } - }, - isLibraryMode = false, - onSave = { - if (it != labels) { - webReaderViewModel.updateSavedItemLabels( - savedItemID = webReaderParams?.item?.savedItemId ?: "", labels = it - ) - } - coroutineScope.launch { - webReaderViewModel.resetBottomSheet() - } - }, - onCreateLabel = { newLabelName, labelHexValue -> - webReaderViewModel.createNewSavedItemLabel(newLabelName, labelHexValue) - } - ) - } - } - BottomSheetState.EDIT_INFO -> { - BottomSheetUI { - EditInfoSheetContent( - savedItemId = webReaderParams?.item?.savedItemId, - title = webReaderParams?.item?.title, - author = webReaderParams?.item?.author, - description = webReaderParams?.item?.descriptionText, - viewModel = editInfoViewModel, - onCancel = { - coroutineScope.launch { - webReaderViewModel.resetBottomSheet() - } - }, - onUpdated = { - coroutineScope.launch { - webReaderViewModel.updateItemTitle() - webReaderViewModel.resetBottomSheet() - } - } - ) - } - } - BottomSheetState.LINK -> { - BottomSheetUI { - OpenLinkView(webReaderViewModel) - } - } - BottomSheetState.NONE -> { - - } - else -> { - - } - } - Spacer(modifier = Modifier.weight(1.0F)) - } - ) { - Scaffold( - topBar = { - ReaderTopAppBar(webReaderViewModel, onLibraryIconTap) - }) { paddingValues -> - if (styledContent != null) { - WebReader( - styledContent = styledContent, - webReaderViewModel = webReaderViewModel, - currentTheme = currentTheme, - ) - } - - LaunchedEffect(shouldPopView) { - if (shouldPopView) { - onBackPressedDispatcher?.onBackPressed() - } - } - } - } -} - -@Composable -fun ReaderTopAppBar(webReaderViewModel: WebReaderViewModel, onLibraryIconTap: (() -> Unit)? = null) { - val context = LocalContext.current - val onBackPressedDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher - - val isDarkMode = isSystemInDarkTheme() - val currentThemeKey = webReaderViewModel.currentThemeKey.observeAsState() - val currentTheme = Themes.values().find { it.themeKey == currentThemeKey.value } - val toolbarHeightPx: Float by webReaderViewModel.currentToolbarHeightLiveData.observeAsState(0.0f) - val webReaderParams: WebReaderParams? by webReaderViewModel.webReaderParamsLiveData.observeAsState(null) - var isMenuExpanded by remember { mutableStateOf(false) } - - val themeBackgroundColor = currentTheme?.let { - if (it.themeKey == "System" && isDarkMode) { - Color(0xFF000000) - } else if (it.themeKey == "System" ) { - Color(0xFFFFFFFF) - } else { - Color(it.backgroundColor) - } - } ?: Color(0xFFFFFFFF) - - val themeTintColor = currentTheme?.let { - if (it.themeKey == "System" && isDarkMode) { - Color(0xFFFFFFFF) - } else if (it.themeKey == "System" ) { - Color(0xFF000000) - } else { - Color(it.foregroundColor ?: 0xFF000000) - } - } ?: Color(0xFF000000) - - - TopAppBar( - modifier = Modifier - .height(height = with(LocalDensity.current) { - toolbarHeightPx.roundToInt().toDp() - }), - backgroundColor = themeBackgroundColor, - elevation = 0.dp, - title = {}, - navigationIcon = { - IconButton(onClick = { - onBackPressedDispatcher?.onBackPressed() - }) { - Icon( - imageVector = Icons.Filled.ArrowBack, - modifier = Modifier, - contentDescription = "Back", - tint = themeTintColor - ) - } - }, - actions = { - if (onLibraryIconTap != null) { - IconButton(onClick = { onLibraryIconTap() }) { - Icon( - imageVector = Icons.Default.Home, - contentDescription = null, - tint = themeTintColor, - ) - } - } - webReaderParams?.let { - IconButton(onClick = { - webReaderViewModel.setBottomSheet(BottomSheetState.NOTEBOOK) - }) { - Icon( - painter = painterResource(id = R.drawable.notebook), - contentDescription = null, - tint = themeTintColor - ) - } - } - IconButton(onClick = { - webReaderViewModel.setBottomSheet(BottomSheetState.PREFERENCES) - }) { - Icon( - painter = painterResource(id = R.drawable.format_letter_case), - contentDescription = null, - tint = themeTintColor - ) - } - IconButton(onClick = { isMenuExpanded = true }) { - Icon( - painter = painterResource(id = R.drawable.dots_horizontal), - contentDescription = null, - tint = themeTintColor - ) - if (isMenuExpanded) { - webReaderParams?.let { params -> - SavedItemContextMenu( - context = context, - isExpanded = true, - isArchived = params.item.isArchived, - onDismiss = { isMenuExpanded = false }, - webReaderViewModel = webReaderViewModel, - actionHandler = { - webReaderViewModel.handleSavedItemAction( - params.item.savedItemId, - it - ) - } - ) - } - } - } - }, - ) -} - -@Composable -fun BottomSheetUI(content: @Composable () -> Unit) { - Box( - modifier = Modifier - .wrapContentHeight() - .fillMaxWidth() - .clip(RoundedCornerShape(topEnd = 20.dp, topStart = 20.dp)) - .background(Color.White) - .statusBarsPadding() - ) { - Scaffold { paddingValues -> - Box(modifier = Modifier.fillMaxSize()) { - content() - } - } - } -} diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/savedItemViews/SavedItemContextMenu.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/savedItemViews/SavedItemContextMenu.kt deleted file mode 100644 index eb7789609..000000000 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/savedItemViews/SavedItemContextMenu.kt +++ /dev/null @@ -1,119 +0,0 @@ -package app.omnivore.omnivore.ui.savedItemViews - -import android.content.Context -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.outlined.Check -import androidx.compose.material.icons.outlined.Delete -import androidx.compose.material.icons.outlined.Info -import androidx.compose.material.icons.outlined.Share -import androidx.compose.material3.DropdownMenu -import androidx.compose.material3.DropdownMenuItem -import androidx.compose.material3.Icon -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import app.omnivore.omnivore.R -import app.omnivore.omnivore.ui.library.SavedItemAction -import app.omnivore.omnivore.ui.reader.WebReaderViewModel - -@Composable -fun SavedItemContextMenu( - isExpanded: Boolean, - isArchived: Boolean, - context: Context, - webReaderViewModel: WebReaderViewModel, - onDismiss: () -> Unit, - actionHandler: (SavedItemAction) -> Unit -) { - DropdownMenu( - expanded = isExpanded, - onDismissRequest = onDismiss - ) { - DropdownMenuItem( - text = { Text(stringResource(R.string.saved_item_context_menu_action_edit_info)) }, - onClick = { - actionHandler(SavedItemAction.EditInfo) - onDismiss() - }, - leadingIcon = { - Icon( - Icons.Outlined.Info, - contentDescription = null - ) - } - ) - DropdownMenuItem( - text = { Text(stringResource(R.string.saved_item_context_menu_action_edit_labels)) }, - onClick = { - actionHandler(SavedItemAction.EditLabels) - onDismiss() - }, - leadingIcon = { - Icon( - painter = painterResource(id = R.drawable.tag), - contentDescription = null - ) - } - ) - DropdownMenuItem( - text = { - Text( - if (isArchived) - stringResource(R.string.saved_item_context_menu_action_unarchive) else - stringResource(R.string.saved_item_context_menu_action_archive) - ) - }, - onClick = { - val action = if (isArchived) SavedItemAction.Unarchive else SavedItemAction.Archive - actionHandler(action) - onDismiss() - }, - leadingIcon = { - Icon( - painter = painterResource(id = R.drawable.archive_outline), - contentDescription = null - ) - } - ) - DropdownMenuItem( - text = { Text(stringResource(R.string.saved_item_context_menu_action_share_original)) }, - onClick = { - webReaderViewModel.showShareLinkSheet(context) - onDismiss() - }, - leadingIcon = { - Icon( - Icons.Outlined.Share, - contentDescription = null - ) - } - ) - DropdownMenuItem( - text = { Text(stringResource(R.string.saved_item_context_menu_action_remove_item)) }, - onClick = { - actionHandler(SavedItemAction.Delete) - onDismiss() - }, - leadingIcon = { - Icon( - Icons.Outlined.Delete, - contentDescription = null - ) - } - ) - DropdownMenuItem( - text = { Text(stringResource(R.string.saved_item_context_menu_action_mark_read)) }, - onClick = { - actionHandler(SavedItemAction.MarkRead) - onDismiss() - }, - leadingIcon = { - Icon( - Icons.Outlined.Check, - contentDescription = null - ) - } - ) - } -} diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/Constants.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/utils/Constants.kt similarity index 94% rename from android/Omnivore/app/src/main/java/app/omnivore/omnivore/Constants.kt rename to android/Omnivore/app/src/main/java/app/omnivore/omnivore/utils/Constants.kt index 27b2829f9..b4962979a 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/Constants.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/utils/Constants.kt @@ -1,4 +1,6 @@ -package app.omnivore.omnivore +package app.omnivore.omnivore.utils + +import app.omnivore.omnivore.BuildConfig object Constants { const val apiURL = BuildConfig.OMNIVORE_API_URL diff --git a/android/Omnivore/app/src/main/res/values/strings.xml b/android/Omnivore/app/src/main/res/values/strings.xml index b90e1a3dc..d1cce247c 100644 --- a/android/Omnivore/app/src/main/res/values/strings.xml +++ b/android/Omnivore/app/src/main/res/values/strings.xml @@ -12,6 +12,7 @@ Note Copy Note + Back Continue with Apple @@ -187,6 +188,7 @@ Share Original Remove Item Mark read + Mark unread Logout diff --git a/android/Omnivore/build.gradle b/android/Omnivore/build.gradle index 325f20a00..eb3032ec3 100644 --- a/android/Omnivore/build.gradle +++ b/android/Omnivore/build.gradle @@ -1,10 +1,9 @@ buildscript { ext { - compose_version = '1.6.0' - lifecycle_version = '2.5.1' - hilt_version = '2.44.2' + lifecycle_version = "2.7.0" + hilt_version = "2.50" gradle_plugin_version = '8.2.2' - room_version = '2.4.3' + room_version = "2.6.1" kotlin_version = '1.7.10' } @@ -21,7 +20,7 @@ buildscript { plugins { id 'com.android.application' version "$gradle_plugin_version" apply false id 'com.android.library' version "$gradle_plugin_version" apply false - id 'org.jetbrains.kotlin.android' version '1.7.10' apply false + id "org.jetbrains.kotlin.android" version "1.9.22" apply false } task clean(type: Delete) { diff --git a/android/Omnivore/gradle.properties b/android/Omnivore/gradle.properties index a7cfaffbc..dd3e782bb 100644 --- a/android/Omnivore/gradle.properties +++ b/android/Omnivore/gradle.properties @@ -22,5 +22,4 @@ kotlin.code.style=official # resources declared in the library itself and none from the library's dependencies, # thereby reducing the size of the R class for that library android.nonTransitiveRClass=true -android.defaults.buildfeatures.buildconfig=true android.nonFinalResIds=false