From 7d24286c552b9030d73d951e2e0b93d529067c0b Mon Sep 17 00:00:00 2001 From: Koitharu Date: Tue, 17 Nov 2020 21:47:22 +0200 Subject: [PATCH] Migrate to MVVM --- app/build.gradle | 7 +- app/src/main/AndroidManifest.xml | 36 ++-- .../java/org/koitharu/kotatsu/KotatsuApp.kt | 56 ++--- .../{ => base}/domain/MangaDataRepository.kt | 2 +- .../{ => base}/domain/MangaLoaderContext.kt | 2 +- .../{ => base}/domain/MangaProviderFactory.kt | 2 +- .../kotatsu/{ => base}/domain/MangaUtils.kt | 2 +- .../base => base/ui}/AlertDialogFragment.kt | 6 +- .../{ui/base => base/ui}/BaseActivity.kt | 6 +- .../{ui/base => base/ui}/BaseBottomSheet.kt | 6 +- .../{ui/base => base/ui}/BaseFragment.kt | 6 +- .../ui}/BaseFullscreenActivity.kt | 2 +- .../ui}/BasePreferenceFragment.kt | 2 +- .../koitharu/kotatsu/base/ui/BaseService.kt | 5 + .../koitharu/kotatsu/base/ui/BaseViewModel.kt | 40 ++++ .../ui}/dialog/CheckBoxAlertDialog.kt | 2 +- .../ui}/dialog/StorageSelectDialog.kt | 4 +- .../ui}/dialog/TextInputDialog.kt | 2 +- .../base => base/ui}/list/AdapterUpdater.kt | 2 +- .../ui}/list/BaseRecyclerAdapter.kt | 2 +- .../base => base/ui}/list/BaseViewHolder.kt | 2 +- .../ui}/list/BoundsScrollListener.kt | 2 +- .../ui}/list/OnRecyclerItemClickListener.kt | 2 +- .../ui}/list/PaginationScrollListener.kt | 2 +- .../ui}/list/ProgressBarAdapter.kt | 2 +- .../ui}/list/ProgressBarHolder.kt | 2 +- .../list/decor/ItemTypeDividerDecoration.kt | 2 +- .../ui}/list/decor/SectionItemDecoration.kt | 2 +- .../ui}/list/decor/SpacingItemDecoration.kt | 2 +- .../ui}/widgets/CheckableImageView.kt | 2 +- .../ui}/widgets/CoverImageView.kt | 2 +- .../base => base/ui}/widgets/SquareLayout.kt | 2 +- .../{ui => }/browser/BrowserActivity.kt | 4 +- .../{ui => }/browser/BrowserCallback.kt | 2 +- .../kotatsu/{ui => }/browser/BrowserClient.kt | 2 +- .../cloudflare/CloudFlareCallback.kt | 2 +- .../cloudflare/CloudFlareClient.kt | 2 +- .../cloudflare/CloudFlareDialog.kt | 4 +- .../kotatsu/core/backup/BackupRepository.kt | 6 +- .../kotatsu/core/backup/RestoreRepository.kt | 6 +- .../koitharu/kotatsu/core/db/MangaDatabase.kt | 6 + .../kotatsu/core/db/entity/TrackEntity.kt | 2 +- .../kotatsu/core/exceptions/ParseException.kt | 3 +- .../kotatsu/core/model/MangaSource.kt | 6 +- .../kotatsu/core/model/MangaTracking.kt | 4 +- .../kotatsu/core/model/TrackingLogItem.kt | 4 +- .../kotatsu/core/parser/MangaRepository.kt | 13 +- .../kotatsu/core/parser/ParserModule.kt | 29 +-- .../core/parser/RemoteMangaRepository.kt | 2 +- .../core/parser/site/ChanRepository.kt | 2 +- .../core/parser/site/DesuMeRepository.kt | 2 +- .../core/parser/site/GroupleRepository.kt | 2 +- .../core/parser/site/HenChanRepository.kt | 2 +- .../core/parser/site/MangaChanRepository.kt | 2 +- .../core/parser/site/MangaLibRepository.kt | 2 +- .../core/parser/site/MangaTownRepository.kt | 2 +- .../core/parser/site/MangareadRepository.kt | 2 +- .../core/parser/site/MintMangaRepository.kt | 2 +- .../core/parser/site/NudeMoonRepository.kt | 2 +- .../core/parser/site/ReadmangaRepository.kt | 2 +- .../core/parser/site/SelfMangaRepository.kt | 2 +- .../core/parser/site/YaoiChanRepository.kt | 2 +- .../kotatsu/core/prefs/AppSettings.kt | 2 +- .../kotatsu/core/prefs/AppWidgetConfig.kt | 2 +- .../{ui/utils => core/ui}/AppCrashHandler.kt | 2 +- .../{ui/base => core/ui}/ChipsFactory.kt | 2 +- .../{ui/utils => core/ui}/CrashActivity.kt | 4 +- .../kotatsu/{ui/base => core/ui}/uiModule.kt | 4 +- .../koitharu/kotatsu/details/DetailsModule.kt | 11 + .../details => details/ui}/ChapterHolder.kt | 6 +- .../details => details/ui}/ChaptersAdapter.kt | 8 +- .../ui}/ChaptersFragment.kt | 43 ++-- .../ui/DetailsActivity.kt} | 53 ++--- .../ui/DetailsFragment.kt} | 49 +++-- .../kotatsu/details/ui/DetailsViewModel.kt | 135 ++++++++++++ .../ui}/MangaDetailsAdapter.kt | 6 +- .../details/ui/RelatedMangaFragment.kt | 22 ++ .../{ui => }/download/DownloadNotification.kt | 9 +- .../{ui => }/download/DownloadService.kt | 20 +- .../kotatsu/favourites/FavouritesModule.kt | 18 ++ .../data}/FavouriteCategoriesDao.kt | 3 +- .../data}/FavouriteCategoryEntity.kt | 2 +- .../data}/FavouriteEntity.kt | 3 +- .../data}/FavouriteManga.kt | 5 +- .../dao => favourites/data}/FavouritesDao.kt | 4 +- .../domain}/FavouritesRepository.kt | 6 +- .../domain}/OnFavouritesChangeListener.kt | 2 +- .../ui}/FavouritesContainerFragment.kt | 39 ++-- .../ui}/FavouritesPagerAdapter.kt | 5 +- .../ui}/FavouritesTabLongClickListener.kt | 2 +- .../ui}/categories/CategoriesActivity.kt | 29 +-- .../ui}/categories/CategoriesAdapter.kt | 8 +- .../ui}/categories/CategoriesEditDelegate.kt | 4 +- .../ui}/categories/CategoryHolder.kt | 4 +- .../FavouritesCategoriesViewModel.kt | 77 +++++++ .../select/CategoriesSelectAdapter.kt | 6 +- .../select/CategoryCheckableHolder.kt | 4 +- .../select/FavouriteCategoriesDialog.kt | 32 +-- .../select/OnCategoryCheckListener.kt | 2 +- .../ui/list}/FavouritesListFragment.kt | 21 +- .../ui/list/FavouritesListViewModel.kt | 37 ++++ .../koitharu/kotatsu/history/HistoryModule.kt | 14 ++ .../db/dao => history/data}/HistoryDao.kt | 4 +- .../entity => history/data}/HistoryEntity.kt | 3 +- .../data}/HistoryWithManga.kt | 5 +- .../domain}/ChapterExtra.kt | 2 +- .../domain}/HistoryRepository.kt | 6 +- .../domain}/OnHistoryChangeListener.kt | 2 +- .../ui}/HistoryListFragment.kt | 29 +-- .../history/ui/HistoryListViewModel.kt | 50 +++++ .../list => list/ui}/ListModeSelectDialog.kt | 4 +- .../kotatsu/list/ui/MangaFilterConfig.kt | 11 + .../{ui/list => list/ui}/MangaGridHolder.kt | 4 +- .../{ui/list => list/ui}/MangaListAdapter.kt | 6 +- .../ui}/MangaListDetailsHolder.kt | 4 +- .../{ui/list => list/ui}/MangaListFragment.kt | 90 +++----- .../{ui/list => list/ui}/MangaListHolder.kt | 4 +- .../{ui/list => list/ui}/MangaListSheet.kt | 63 ++---- .../kotatsu/list/ui/MangaListViewModel.kt | 11 + .../list => list/ui}/filter/FilterAdapter.kt | 4 +- .../ui}/filter/FilterSortHolder.kt | 4 +- .../ui}/filter/FilterTagHolder.kt | 4 +- .../ui}/filter/OnFilterChangedListener.kt | 2 +- .../org/koitharu/kotatsu/local/LocalModule.kt | 17 ++ .../{core/local => local/data}/Cache.kt | 2 +- .../{core/local => local/data}/CbzFetcher.kt | 2 +- .../{core/local => local/data}/CbzFilter.kt | 2 +- .../local => local/data}/MangaIndex.kt | 2 +- .../{domain/local => local/data}/MangaZip.kt | 3 +- .../{core/local => local/data}/PagesCache.kt | 5 +- .../local => local/data}/WritableCbzFile.kt | 2 +- .../domain}/LocalMangaRepository.kt | 16 +- .../local => local/ui}/LocalListFragment.kt | 29 ++- .../kotatsu/local/ui/LocalListViewModel.kt | 84 ++++++++ .../org/koitharu/kotatsu/main/MainModule.kt | 12 ++ .../{ui/list => main/ui}/MainActivity.kt | 48 +++-- .../ui/MainViewModel.kt} | 20 +- .../ui}/protect/AppProtectHelper.kt | 4 +- .../ui}/protect/ProtectActivity.kt | 24 ++- .../ui/protect/ProtectViewModel.kt} | 14 +- .../koitharu/kotatsu/reader/ReaderModule.kt | 16 ++ .../reader => reader/ui}/ChaptersDialog.kt | 8 +- .../{ui/reader => reader/ui}/PageLoader.kt | 4 +- .../reader => reader/ui}/ReaderActivity.kt | 43 ++-- .../ui}/ReaderConfigDialog.kt | 4 +- .../reader => reader/ui}/ReaderListener.kt | 9 +- .../{ui/reader => reader/ui}/ReaderState.kt | 2 +- .../kotatsu/reader/ui/ReaderViewModel.kt | 119 ++++++++++ .../ui}/SimpleSettingsActivity.kt | 10 +- .../ui}/base/AbstractReader.kt | 10 +- .../ui}/base/BaseReaderAdapter.kt | 4 +- .../ui}/base/OnBoundsScrollListener.kt | 2 +- .../ui}/base/PageHolderDelegate.kt | 4 +- .../reader => reader/ui}/base/ReaderPage.kt | 2 +- .../reversed/ReversedPageAnimTransformer.kt | 2 +- .../ui}/reversed/ReversedPageHolder.kt | 6 +- .../ui}/reversed/ReversedPagesAdapter.kt | 10 +- .../ui}/reversed/ReversedReaderFragment.kt | 14 +- .../ui}/standard/PageAnimTransformer.kt | 2 +- .../ui}/standard/PageHolder.kt | 10 +- .../ui}/standard/PagerPaginationListener.kt | 4 +- .../ui}/standard/PagerReaderFragment.kt | 10 +- .../ui}/standard/PagesAdapter.kt | 8 +- .../ui}/thumbnails/OnPageSelectListener.kt | 2 +- .../ui}/thumbnails/PageThumbnailHolder.kt | 6 +- .../ui}/thumbnails/PagesThumbnailsAdapter.kt | 8 +- .../ui}/thumbnails/PagesThumbnailsSheet.kt | 8 +- .../ui}/wetoon/ListPaginationListener.kt | 4 +- .../ui}/wetoon/WebtoonAdapter.kt | 8 +- .../ui}/wetoon/WebtoonFrameLayout.kt | 2 +- .../ui}/wetoon/WebtoonHolder.kt | 10 +- .../ui}/wetoon/WebtoonImageView.kt | 2 +- .../ui}/wetoon/WebtoonReaderFragment.kt | 10 +- .../ui}/wetoon/WebtoonRecyclerView.kt | 8 +- .../kotatsu/remotelist/RemoteListModule.kt | 15 ++ .../ui}/RemoteListFragment.kt | 19 +- .../remotelist/ui/RemoteListViewModel.kt | 59 +++++ .../koitharu/kotatsu/search/SearchModule.kt | 18 ++ .../domain/MangaSearchRepository.kt | 3 +- .../search => search/ui}/MangaSearchSheet.kt | 31 ++- .../ui}/MangaSuggestionsProvider.kt | 2 +- .../search => search/ui}/SearchActivity.kt | 4 +- .../search => search/ui}/SearchFragment.kt | 15 +- .../{ui/search => search/ui}/SearchHelper.kt | 4 +- .../kotatsu/search/ui/SearchViewModel.kt | 24 +++ .../ui}/global/GlobalSearchActivity.kt | 4 +- .../ui}/global/GlobalSearchFragment.kt | 12 +- .../search/ui/global/GlobalSearchViewModel.kt | 39 ++++ .../{ui => }/settings/AppUpdateChecker.kt | 2 +- .../settings/HistorySettingsFragment.kt | 10 +- .../{ui => }/settings/MainSettingsFragment.kt | 14 +- .../settings/NetworkSettingsFragment.kt | 4 +- .../NotificationSettingsLegacyFragment.kt | 6 +- .../settings/ReaderSettingsFragment.kt | 6 +- .../{ui => }/settings/SettingsActivity.kt | 4 +- .../kotatsu/settings/SettingsModule.kt | 22 ++ .../settings/SourceSettingsFragment.kt | 4 +- .../settings/backup/BackupDialogFragment.kt | 26 ++- .../settings/backup/BackupSettingsFragment.kt | 4 +- .../settings/backup/BackupViewModel.kt | 41 ++++ .../settings/backup/RestoreDialogFragment.kt | 27 +-- .../backup/RestoreViewModel.kt} | 35 +-- .../settings/sources/SourceViewHolder.kt | 4 +- .../settings/sources/SourcesAdapter.kt | 6 +- .../sources/SourcesReorderCallback.kt | 5 +- .../sources/SourcesSettingsFragment.kt | 8 +- .../settings/utils/EditTextSummaryProvider.kt | 2 +- .../settings/utils/MultiSummaryProvider.kt | 2 +- .../settings/utils/RingtonePickContract.kt | 2 +- .../koitharu/kotatsu/tracker/TrackerModule.kt | 14 ++ .../domain}/TrackingRepository.kt | 4 +- .../list/feed => tracker/ui}/FeedAdapter.kt | 8 +- .../list/feed => tracker/ui}/FeedFragment.kt | 48 ++--- .../list/feed => tracker/ui}/FeedHolder.kt | 4 +- .../kotatsu/tracker/ui/FeedViewModel.kt | 24 +++ .../tracker => tracker/work}/TrackWorker.kt | 8 +- .../koitharu/kotatsu/ui/base/BaseMvpView.kt | 14 -- .../koitharu/kotatsu/ui/base/BasePresenter.kt | 44 ---- .../koitharu/kotatsu/ui/base/BaseService.kt | 24 --- .../kotatsu/ui/base/SharedPresenterHolder.kt | 25 --- .../ui/details/MangaDetailsPresenter.kt | 203 ------------------ .../kotatsu/ui/details/MangaDetailsView.kt | 38 ---- .../ui/details/RelatedMangaFragment.kt | 43 ---- .../org/koitharu/kotatsu/ui/list/MainView.kt | 11 - .../koitharu/kotatsu/ui/list/MangaListView.kt | 30 --- .../favourites/FavouritesListPresenter.kt | 59 ----- .../FavouriteCategoriesPresenter.kt | 78 ------- .../categories/FavouriteCategoriesView.kt | 19 -- .../kotatsu/ui/list/feed/FeedPresenter.kt | 44 ---- .../koitharu/kotatsu/ui/list/feed/FeedView.kt | 19 -- .../ui/list/history/HistoryListPresenter.kt | 71 ------ .../ui/list/local/LocalListPresenter.kt | 94 -------- .../ui/list/remote/RemoteListPresenter.kt | 87 -------- .../kotatsu/ui/reader/ReaderPresenter.kt | 127 ----------- .../koitharu/kotatsu/ui/reader/ReaderView.kt | 17 -- .../kotatsu/ui/search/SearchPresenter.kt | 25 --- .../ui/search/global/GlobalSearchPresenter.kt | 42 ---- .../ui/settings/backup/BackupPresenter.kt | 36 ---- .../kotatsu/ui/settings/backup/BackupView.kt | 16 -- .../kotatsu/ui/settings/backup/RestoreView.kt | 16 -- .../kotatsu/ui/utils/protect/ProtectView.kt | 10 - .../koitharu/kotatsu/utils/MangaShortcut.kt | 8 +- .../kotatsu/utils/MediaStoreCompat.kt | 23 +- .../koitharu/kotatsu/utils/SingleLiveEvent.kt | 36 ++++ .../delegates/ParcelableArgumentDelegate.kt | 3 +- .../prefs/NullableStringPreferenceDelegate.kt | 3 +- .../prefs/StringSetPreferenceDelegate.kt | 5 +- .../kotatsu/utils/ext/CoroutineExt.kt | 7 +- .../koitharu/kotatsu/utils/ext/LiveDataExt.kt | 13 ++ .../org/koitharu/kotatsu/utils/ext/ViewExt.kt | 2 +- .../kotatsu/{ui => }/widget/WidgetUpdater.kt | 10 +- .../widget/recent/RecentListFactory.kt | 8 +- .../widget/recent/RecentWidgetProvider.kt | 22 +- .../widget/recent/RecentWidgetService.kt | 2 +- .../widget/shelf/CategorySelectAdapter.kt | 6 +- .../widget/shelf/CategorySelectHolder.kt | 4 +- .../widget/shelf/ShelfConfigActivity.kt | 25 ++- .../{ui => }/widget/shelf/ShelfListFactory.kt | 8 +- .../widget/shelf/ShelfWidgetProvider.kt | 22 +- .../widget/shelf/ShelfWidgetService.kt | 2 +- app/src/main/res/layout/activity_details.xml | 2 +- app/src/main/res/layout/activity_main.xml | 2 +- .../res/layout/fragment_reader_webtoon.xml | 2 +- app/src/main/res/layout/item_manga_grid.xml | 2 +- app/src/main/res/layout/item_manga_list.xml | 2 +- .../res/layout/item_manga_list_details.xml | 2 +- app/src/main/res/layout/item_page_thumb.xml | 2 +- app/src/main/res/layout/item_page_webtoon.xml | 6 +- .../main/res/layout/item_source_config.xml | 2 +- app/src/main/res/layout/item_tracklog.xml | 2 +- app/src/main/res/xml/pref_main.xml | 6 +- app/src/main/res/xml/widget_shelf.xml | 2 +- .../kotatsu/parsers/RemoteRepositoryTest.kt | 2 +- 273 files changed, 1926 insertions(+), 2115 deletions(-) rename app/src/main/java/org/koitharu/kotatsu/{ => base}/domain/MangaDataRepository.kt (96%) rename app/src/main/java/org/koitharu/kotatsu/{ => base}/domain/MangaLoaderContext.kt (97%) rename app/src/main/java/org/koitharu/kotatsu/{ => base}/domain/MangaProviderFactory.kt (94%) rename app/src/main/java/org/koitharu/kotatsu/{ => base}/domain/MangaUtils.kt (97%) rename app/src/main/java/org/koitharu/kotatsu/{ui/base => base/ui}/AlertDialogFragment.kt (88%) rename app/src/main/java/org/koitharu/kotatsu/{ui/base => base/ui}/BaseActivity.kt (86%) rename app/src/main/java/org/koitharu/kotatsu/{ui/base => base/ui}/BaseBottomSheet.kt (83%) rename app/src/main/java/org/koitharu/kotatsu/{ui/base => base/ui}/BaseFragment.kt (78%) rename app/src/main/java/org/koitharu/kotatsu/{ui/base => base/ui}/BaseFullscreenActivity.kt (97%) rename app/src/main/java/org/koitharu/kotatsu/{ui/base => base/ui}/BasePreferenceFragment.kt (91%) create mode 100644 app/src/main/java/org/koitharu/kotatsu/base/ui/BaseService.kt create mode 100644 app/src/main/java/org/koitharu/kotatsu/base/ui/BaseViewModel.kt rename app/src/main/java/org/koitharu/kotatsu/{ui/base => base/ui}/dialog/CheckBoxAlertDialog.kt (97%) rename app/src/main/java/org/koitharu/kotatsu/{ui/base => base/ui}/dialog/StorageSelectDialog.kt (96%) rename app/src/main/java/org/koitharu/kotatsu/{ui/base => base/ui}/dialog/TextInputDialog.kt (98%) rename app/src/main/java/org/koitharu/kotatsu/{ui/base => base/ui}/list/AdapterUpdater.kt (94%) rename app/src/main/java/org/koitharu/kotatsu/{ui/base => base/ui}/list/BaseRecyclerAdapter.kt (98%) rename app/src/main/java/org/koitharu/kotatsu/{ui/base => base/ui}/list/BaseViewHolder.kt (97%) rename app/src/main/java/org/koitharu/kotatsu/{ui/base => base/ui}/list/BoundsScrollListener.kt (96%) rename app/src/main/java/org/koitharu/kotatsu/{ui/base => base/ui}/list/OnRecyclerItemClickListener.kt (81%) rename app/src/main/java/org/koitharu/kotatsu/{ui/base => base/ui}/list/PaginationScrollListener.kt (93%) rename app/src/main/java/org/koitharu/kotatsu/{ui/base => base/ui}/list/ProgressBarAdapter.kt (91%) rename app/src/main/java/org/koitharu/kotatsu/{ui/base => base/ui}/list/ProgressBarHolder.kt (95%) rename app/src/main/java/org/koitharu/kotatsu/{ui/base => base/ui}/list/decor/ItemTypeDividerDecoration.kt (97%) rename app/src/main/java/org/koitharu/kotatsu/{ui/base => base/ui}/list/decor/SectionItemDecoration.kt (98%) rename app/src/main/java/org/koitharu/kotatsu/{ui/base => base/ui}/list/decor/SpacingItemDecoration.kt (94%) rename app/src/main/java/org/koitharu/kotatsu/{ui/base => base/ui}/widgets/CheckableImageView.kt (97%) rename app/src/main/java/org/koitharu/kotatsu/{ui/base => base/ui}/widgets/CoverImageView.kt (97%) rename app/src/main/java/org/koitharu/kotatsu/{ui/base => base/ui}/widgets/SquareLayout.kt (89%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/browser/BrowserActivity.kt (96%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/browser/BrowserCallback.kt (77%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/browser/BrowserClient.kt (97%) rename app/src/main/java/org/koitharu/kotatsu/{ui/utils => browser}/cloudflare/CloudFlareCallback.kt (60%) rename app/src/main/java/org/koitharu/kotatsu/{ui/utils => browser}/cloudflare/CloudFlareClient.kt (96%) rename app/src/main/java/org/koitharu/kotatsu/{ui/utils => browser}/cloudflare/CloudFlareDialog.kt (95%) rename app/src/main/java/org/koitharu/kotatsu/{ui/utils => core/ui}/AppCrashHandler.kt (95%) rename app/src/main/java/org/koitharu/kotatsu/{ui/base => core/ui}/ChipsFactory.kt (95%) rename app/src/main/java/org/koitharu/kotatsu/{ui/utils => core/ui}/CrashActivity.kt (95%) rename app/src/main/java/org/koitharu/kotatsu/{ui/base => core/ui}/uiModule.kt (81%) create mode 100644 app/src/main/java/org/koitharu/kotatsu/details/DetailsModule.kt rename app/src/main/java/org/koitharu/kotatsu/{ui/details => details/ui}/ChapterHolder.kt (91%) rename app/src/main/java/org/koitharu/kotatsu/{ui/details => details/ui}/ChaptersAdapter.kt (91%) rename app/src/main/java/org/koitharu/kotatsu/{ui/details => details/ui}/ChaptersFragment.kt (76%) rename app/src/main/java/org/koitharu/kotatsu/{ui/details/MangaDetailsActivity.kt => details/ui/DetailsActivity.kt} (80%) rename app/src/main/java/org/koitharu/kotatsu/{ui/details/MangaDetailsFragment.kt => details/ui/DetailsFragment.kt} (74%) create mode 100644 app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsViewModel.kt rename app/src/main/java/org/koitharu/kotatsu/{ui/details => details/ui}/MangaDetailsAdapter.kt (73%) create mode 100644 app/src/main/java/org/koitharu/kotatsu/details/ui/RelatedMangaFragment.kt rename app/src/main/java/org/koitharu/kotatsu/{ui => }/download/DownloadNotification.kt (95%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/download/DownloadService.kt (93%) create mode 100644 app/src/main/java/org/koitharu/kotatsu/favourites/FavouritesModule.kt rename app/src/main/java/org/koitharu/kotatsu/{core/db/dao => favourites/data}/FavouriteCategoriesDao.kt (90%) rename app/src/main/java/org/koitharu/kotatsu/{core/db/entity => favourites/data}/FavouriteCategoryEntity.kt (93%) rename app/src/main/java/org/koitharu/kotatsu/{core/db/entity => favourites/data}/FavouriteEntity.kt (87%) rename app/src/main/java/org/koitharu/kotatsu/{core/db/entity => favourites/data}/FavouriteManga.kt (71%) rename app/src/main/java/org/koitharu/kotatsu/{core/db/dao => favourites/data}/FavouritesDao.kt (91%) rename app/src/main/java/org/koitharu/kotatsu/{domain/favourites => favourites/domain}/FavouritesRepository.kt (95%) rename app/src/main/java/org/koitharu/kotatsu/{domain/favourites => favourites/domain}/OnFavouritesChangeListener.kt (71%) rename app/src/main/java/org/koitharu/kotatsu/{ui/list/favourites => favourites/ui}/FavouritesContainerFragment.kt (72%) rename app/src/main/java/org/koitharu/kotatsu/{ui/list/favourites => favourites/ui}/FavouritesPagerAdapter.kt (88%) rename app/src/main/java/org/koitharu/kotatsu/{ui/list/favourites => favourites/ui}/FavouritesTabLongClickListener.kt (80%) rename app/src/main/java/org/koitharu/kotatsu/{ui/list/favourites => favourites/ui}/categories/CategoriesActivity.kt (80%) rename app/src/main/java/org/koitharu/kotatsu/{ui/list/favourites => favourites/ui}/categories/CategoriesAdapter.kt (85%) rename app/src/main/java/org/koitharu/kotatsu/{ui/list/favourites => favourites/ui}/categories/CategoriesEditDelegate.kt (93%) rename app/src/main/java/org/koitharu/kotatsu/{ui/list/favourites => favourites/ui}/categories/CategoryHolder.kt (77%) create mode 100644 app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/FavouritesCategoriesViewModel.kt rename app/src/main/java/org/koitharu/kotatsu/{ui/list/favourites => favourites/ui}/categories/select/CategoriesSelectAdapter.kt (87%) rename app/src/main/java/org/koitharu/kotatsu/{ui/list/favourites => favourites/ui}/categories/select/CategoryCheckableHolder.kt (78%) rename app/src/main/java/org/koitharu/kotatsu/{ui/list/favourites => favourites/ui}/categories/select/FavouriteCategoriesDialog.kt (68%) rename app/src/main/java/org/koitharu/kotatsu/{ui/list/favourites => favourites/ui}/categories/select/OnCategoryCheckListener.kt (75%) rename app/src/main/java/org/koitharu/kotatsu/{ui/list/favourites => favourites/ui/list}/FavouritesListFragment.kt (71%) create mode 100644 app/src/main/java/org/koitharu/kotatsu/favourites/ui/list/FavouritesListViewModel.kt create mode 100644 app/src/main/java/org/koitharu/kotatsu/history/HistoryModule.kt rename app/src/main/java/org/koitharu/kotatsu/{core/db/dao => history/data}/HistoryDao.kt (89%) rename app/src/main/java/org/koitharu/kotatsu/{core/db/entity => history/data}/HistoryEntity.kt (90%) rename app/src/main/java/org/koitharu/kotatsu/{core/db/entity => history/data}/HistoryWithManga.kt (65%) rename app/src/main/java/org/koitharu/kotatsu/{domain/history => history/domain}/ChapterExtra.kt (59%) rename app/src/main/java/org/koitharu/kotatsu/{domain/history => history/domain}/HistoryRepository.kt (93%) rename app/src/main/java/org/koitharu/kotatsu/{domain/history => history/domain}/OnHistoryChangeListener.kt (59%) rename app/src/main/java/org/koitharu/kotatsu/{ui/list/history => history/ui}/HistoryListFragment.kt (75%) create mode 100644 app/src/main/java/org/koitharu/kotatsu/history/ui/HistoryListViewModel.kt rename app/src/main/java/org/koitharu/kotatsu/{ui/list => list/ui}/ListModeSelectDialog.kt (94%) create mode 100644 app/src/main/java/org/koitharu/kotatsu/list/ui/MangaFilterConfig.kt rename app/src/main/java/org/koitharu/kotatsu/{ui/list => list/ui}/MangaGridHolder.kt (91%) rename app/src/main/java/org/koitharu/kotatsu/{ui/list => list/ui}/MangaListAdapter.kt (81%) rename app/src/main/java/org/koitharu/kotatsu/{ui/list => list/ui}/MangaListDetailsHolder.kt (94%) rename app/src/main/java/org/koitharu/kotatsu/{ui/list => list/ui}/MangaListFragment.kt (77%) rename app/src/main/java/org/koitharu/kotatsu/{ui/list => list/ui}/MangaListHolder.kt (92%) rename app/src/main/java/org/koitharu/kotatsu/{ui/list => list/ui}/MangaListSheet.kt (76%) create mode 100644 app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListViewModel.kt rename app/src/main/java/org/koitharu/kotatsu/{ui/list => list/ui}/filter/FilterAdapter.kt (96%) rename app/src/main/java/org/koitharu/kotatsu/{ui/list => list/ui}/filter/FilterSortHolder.kt (80%) rename app/src/main/java/org/koitharu/kotatsu/{ui/list => list/ui}/filter/FilterTagHolder.kt (81%) rename app/src/main/java/org/koitharu/kotatsu/{ui/list => list/ui}/filter/OnFilterChangedListener.kt (75%) create mode 100644 app/src/main/java/org/koitharu/kotatsu/local/LocalModule.kt rename app/src/main/java/org/koitharu/kotatsu/{core/local => local/data}/Cache.kt (65%) rename app/src/main/java/org/koitharu/kotatsu/{core/local => local/data}/CbzFetcher.kt (95%) rename app/src/main/java/org/koitharu/kotatsu/{core/local => local/data}/CbzFilter.kt (87%) rename app/src/main/java/org/koitharu/kotatsu/{domain/local => local/data}/MangaIndex.kt (98%) rename app/src/main/java/org/koitharu/kotatsu/{domain/local => local/data}/MangaZip.kt (94%) rename app/src/main/java/org/koitharu/kotatsu/{core/local => local/data}/PagesCache.kt (83%) rename app/src/main/java/org/koitharu/kotatsu/{core/local => local/data}/WritableCbzFile.kt (98%) rename app/src/main/java/org/koitharu/kotatsu/{core/parser => local/domain}/LocalMangaRepository.kt (92%) rename app/src/main/java/org/koitharu/kotatsu/{ui/list/local => local/ui}/LocalListFragment.kt (79%) create mode 100644 app/src/main/java/org/koitharu/kotatsu/local/ui/LocalListViewModel.kt create mode 100644 app/src/main/java/org/koitharu/kotatsu/main/MainModule.kt rename app/src/main/java/org/koitharu/kotatsu/{ui/list => main/ui}/MainActivity.kt (82%) rename app/src/main/java/org/koitharu/kotatsu/{ui/list/MainPresenter.kt => main/ui/MainViewModel.kt} (50%) rename app/src/main/java/org/koitharu/kotatsu/{ui/utils => main/ui}/protect/AppProtectHelper.kt (89%) rename app/src/main/java/org/koitharu/kotatsu/{ui/utils => main/ui}/protect/ProtectActivity.kt (70%) rename app/src/main/java/org/koitharu/kotatsu/{ui/utils/protect/ProtectPresenter.kt => main/ui/protect/ProtectViewModel.kt} (64%) create mode 100644 app/src/main/java/org/koitharu/kotatsu/reader/ReaderModule.kt rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/ChaptersDialog.kt (91%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/PageLoader.kt (96%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/ReaderActivity.kt (91%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/ReaderConfigDialog.kt (95%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/ReaderListener.kt (52%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/ReaderState.kt (91%) create mode 100644 app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/SimpleSettingsActivity.kt (77%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/base/AbstractReader.kt (96%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/base/BaseReaderAdapter.kt (92%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/base/OnBoundsScrollListener.kt (65%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/base/PageHolderDelegate.kt (96%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/base/ReaderPage.kt (93%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/reversed/ReversedPageAnimTransformer.kt (93%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/reversed/ReversedPageHolder.kt (89%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/reversed/ReversedPagesAdapter.kt (78%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/reversed/ReversedReaderFragment.kt (86%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/standard/PageAnimTransformer.kt (93%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/standard/PageHolder.kt (90%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/standard/PagerPaginationListener.kt (87%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/standard/PagerReaderFragment.kt (89%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/standard/PagesAdapter.kt (51%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/thumbnails/OnPageSelectListener.kt (71%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/thumbnails/PageThumbnailHolder.kt (91%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/thumbnails/PagesThumbnailsAdapter.kt (80%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/thumbnails/PagesThumbnailsSheet.kt (93%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/wetoon/ListPaginationListener.kt (90%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/wetoon/WebtoonAdapter.kt (51%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/wetoon/WebtoonFrameLayout.kt (92%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/wetoon/WebtoonHolder.kt (88%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/wetoon/WebtoonImageView.kt (96%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/wetoon/WebtoonReaderFragment.kt (89%) rename app/src/main/java/org/koitharu/kotatsu/{ui/reader => reader/ui}/wetoon/WebtoonRecyclerView.kt (88%) create mode 100644 app/src/main/java/org/koitharu/kotatsu/remotelist/RemoteListModule.kt rename app/src/main/java/org/koitharu/kotatsu/{ui/list/remote => remotelist/ui}/RemoteListFragment.kt (73%) create mode 100644 app/src/main/java/org/koitharu/kotatsu/remotelist/ui/RemoteListViewModel.kt create mode 100644 app/src/main/java/org/koitharu/kotatsu/search/SearchModule.kt rename app/src/main/java/org/koitharu/kotatsu/{ => search}/domain/MangaSearchRepository.kt (90%) rename app/src/main/java/org/koitharu/kotatsu/{ui/search => search/ui}/MangaSearchSheet.kt (52%) rename app/src/main/java/org/koitharu/kotatsu/{ui/search => search/ui}/MangaSuggestionsProvider.kt (98%) rename app/src/main/java/org/koitharu/kotatsu/{ui/search => search/ui}/SearchActivity.kt (95%) rename app/src/main/java/org/koitharu/kotatsu/{ui/search => search/ui}/SearchFragment.kt (65%) rename app/src/main/java/org/koitharu/kotatsu/{ui/search => search/ui}/SearchHelper.kt (94%) create mode 100644 app/src/main/java/org/koitharu/kotatsu/search/ui/SearchViewModel.kt rename app/src/main/java/org/koitharu/kotatsu/{ui/search => search/ui}/global/GlobalSearchActivity.kt (90%) rename app/src/main/java/org/koitharu/kotatsu/{ui/search => search/ui}/global/GlobalSearchFragment.kt (59%) create mode 100644 app/src/main/java/org/koitharu/kotatsu/search/ui/global/GlobalSearchViewModel.kt rename app/src/main/java/org/koitharu/kotatsu/{ui => }/settings/AppUpdateChecker.kt (99%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/settings/HistorySettingsFragment.kt (93%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/settings/MainSettingsFragment.kt (95%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/settings/NetworkSettingsFragment.kt (74%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/settings/NotificationSettingsLegacyFragment.kt (89%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/settings/ReaderSettingsFragment.kt (85%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/settings/SettingsActivity.kt (94%) create mode 100644 app/src/main/java/org/koitharu/kotatsu/settings/SettingsModule.kt rename app/src/main/java/org/koitharu/kotatsu/{ui => }/settings/SourceSettingsFragment.kt (93%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/settings/backup/BackupDialogFragment.kt (70%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/settings/backup/BackupSettingsFragment.kt (93%) create mode 100644 app/src/main/java/org/koitharu/kotatsu/settings/backup/BackupViewModel.kt rename app/src/main/java/org/koitharu/kotatsu/{ui => }/settings/backup/RestoreDialogFragment.kt (74%) rename app/src/main/java/org/koitharu/kotatsu/{ui/settings/backup/RestorePresenter.kt => settings/backup/RestoreViewModel.kt} (67%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/settings/sources/SourceViewHolder.kt (80%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/settings/sources/SourcesAdapter.kt (92%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/settings/sources/SourcesReorderCallback.kt (78%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/settings/sources/SourcesSettingsFragment.kt (87%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/settings/utils/EditTextSummaryProvider.kt (90%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/settings/utils/MultiSummaryProvider.kt (92%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/settings/utils/RingtonePickContract.kt (95%) create mode 100644 app/src/main/java/org/koitharu/kotatsu/tracker/TrackerModule.kt rename app/src/main/java/org/koitharu/kotatsu/{domain/tracking => tracker/domain}/TrackingRepository.kt (96%) rename app/src/main/java/org/koitharu/kotatsu/{ui/list/feed => tracker/ui}/FeedAdapter.kt (69%) rename app/src/main/java/org/koitharu/kotatsu/{ui/list/feed => tracker/ui}/FeedFragment.kt (70%) rename app/src/main/java/org/koitharu/kotatsu/{ui/list/feed => tracker/ui}/FeedHolder.kt (93%) create mode 100644 app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedViewModel.kt rename app/src/main/java/org/koitharu/kotatsu/{ui/tracker => tracker/work}/TrackWorker.kt (97%) delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/base/BaseMvpView.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/base/BasePresenter.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/base/BaseService.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/base/SharedPresenterHolder.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsPresenter.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsView.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/details/RelatedMangaFragment.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/list/MainView.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/list/MangaListView.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesListPresenter.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/FavouriteCategoriesPresenter.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/FavouriteCategoriesView.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/list/feed/FeedPresenter.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/list/feed/FeedView.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/list/history/HistoryListPresenter.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/list/local/LocalListPresenter.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/list/remote/RemoteListPresenter.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderPresenter.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderView.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/search/SearchPresenter.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/search/global/GlobalSearchPresenter.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/settings/backup/BackupPresenter.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/settings/backup/BackupView.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/settings/backup/RestoreView.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/ui/utils/protect/ProtectView.kt create mode 100644 app/src/main/java/org/koitharu/kotatsu/utils/SingleLiveEvent.kt create mode 100644 app/src/main/java/org/koitharu/kotatsu/utils/ext/LiveDataExt.kt rename app/src/main/java/org/koitharu/kotatsu/{ui => }/widget/WidgetUpdater.kt (72%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/widget/recent/RecentListFactory.kt (87%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/widget/recent/RecentWidgetProvider.kt (71%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/widget/recent/RecentWidgetService.kt (85%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/widget/shelf/CategorySelectAdapter.kt (82%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/widget/shelf/CategorySelectHolder.kt (82%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/widget/shelf/ShelfConfigActivity.kt (79%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/widget/shelf/ShelfListFactory.kt (89%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/widget/shelf/ShelfWidgetProvider.kt (71%) rename app/src/main/java/org/koitharu/kotatsu/{ui => }/widget/shelf/ShelfWidgetService.kt (90%) diff --git a/app/build.gradle b/app/build.gradle index fa799eefe..9833396f6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -84,17 +84,12 @@ dependencies { implementation 'androidx.room:room-ktx:2.2.5' kapt 'androidx.room:room-compiler:2.2.5' - implementation 'com.github.moxy-community:moxy:2.2.0' - implementation 'com.github.moxy-community:moxy-androidx:2.2.0' - implementation 'com.github.moxy-community:moxy-material:2.2.0' - implementation 'com.github.moxy-community:moxy-ktx:2.2.0' - kapt 'com.github.moxy-community:moxy-compiler:2.2.0' - implementation 'com.squareup.okhttp3:okhttp:4.9.0' implementation 'com.squareup.okio:okio:2.9.0' implementation 'org.jsoup:jsoup:1.13.1' implementation 'org.koin:koin-android:2.2.0' + implementation 'org.koin:koin-android-viewmodel:2.2.0' implementation 'io.coil-kt:coil-base:1.0.0' implementation 'com.davemorrissey.labs:subsampling-scale-image-view:3.10.0' implementation 'com.tomclaw.cache:cache:1.0' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1846957cd..9ed804995 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -23,7 +23,7 @@ android:theme="@style/AppTheme" android:usesCleartextTraffic="true" tools:ignore="UnusedAttribute"> - + @@ -32,62 +32,62 @@ android:name="android.app.default_searchable" android:value=".ui.search.SearchActivity" /> - + - + - + @@ -111,7 +111,7 @@ android:resource="@xml/widget_shelf" /> diff --git a/app/src/main/java/org/koitharu/kotatsu/KotatsuApp.kt b/app/src/main/java/org/koitharu/kotatsu/KotatsuApp.kt index e8a4f29b4..7e6f6c5ee 100644 --- a/app/src/main/java/org/koitharu/kotatsu/KotatsuApp.kt +++ b/app/src/main/java/org/koitharu/kotatsu/KotatsuApp.kt @@ -6,25 +6,29 @@ import androidx.appcompat.app.AppCompatDelegate import org.koin.android.ext.android.get import org.koin.android.ext.koin.androidContext import org.koin.core.context.startKoin -import org.koin.dsl.module -import org.koitharu.kotatsu.core.backup.BackupRepository -import org.koitharu.kotatsu.core.backup.RestoreRepository +import org.koitharu.kotatsu.base.domain.MangaLoaderContext import org.koitharu.kotatsu.core.db.databaseModule import org.koitharu.kotatsu.core.github.githubModule -import org.koitharu.kotatsu.core.local.PagesCache import org.koitharu.kotatsu.core.network.networkModule -import org.koitharu.kotatsu.core.parser.LocalMangaRepository import org.koitharu.kotatsu.core.parser.parserModule import org.koitharu.kotatsu.core.prefs.AppSettings -import org.koitharu.kotatsu.domain.MangaDataRepository -import org.koitharu.kotatsu.domain.MangaLoaderContext -import org.koitharu.kotatsu.domain.MangaSearchRepository -import org.koitharu.kotatsu.domain.favourites.FavouritesRepository -import org.koitharu.kotatsu.domain.history.HistoryRepository -import org.koitharu.kotatsu.domain.tracking.TrackingRepository -import org.koitharu.kotatsu.ui.base.uiModule -import org.koitharu.kotatsu.ui.utils.AppCrashHandler -import org.koitharu.kotatsu.ui.widget.WidgetUpdater +import org.koitharu.kotatsu.core.ui.AppCrashHandler +import org.koitharu.kotatsu.core.ui.uiModule +import org.koitharu.kotatsu.details.detailsModule +import org.koitharu.kotatsu.favourites.domain.FavouritesRepository +import org.koitharu.kotatsu.favourites.favouritesModule +import org.koitharu.kotatsu.history.domain.HistoryRepository +import org.koitharu.kotatsu.history.historyModule +import org.koitharu.kotatsu.local.data.PagesCache +import org.koitharu.kotatsu.local.domain.LocalMangaRepository +import org.koitharu.kotatsu.local.localModule +import org.koitharu.kotatsu.main.mainModule +import org.koitharu.kotatsu.reader.readerModule +import org.koitharu.kotatsu.remotelist.remoteListModule +import org.koitharu.kotatsu.search.searchModule +import org.koitharu.kotatsu.settings.settingsModule +import org.koitharu.kotatsu.tracker.trackerModule +import org.koitharu.kotatsu.widget.WidgetUpdater class KotatsuApp : Application() { @@ -62,20 +66,18 @@ class KotatsuApp : Application() { networkModule, databaseModule, githubModule, - parserModule, uiModule, - module { - single { FavouritesRepository(get()) } - single { HistoryRepository(get()) } - single { TrackingRepository(get(), get()) } - single { MangaDataRepository(get()) } - single { BackupRepository(get()) } - single { RestoreRepository(get()) } - single { MangaSearchRepository() } - single { MangaLoaderContext() } - single { AppSettings(get()) } - single { PagesCache(get()) } - } + parserModule, + mainModule, + searchModule, + localModule, + favouritesModule, + historyModule, + remoteListModule, + detailsModule, + trackerModule, + settingsModule, + readerModule ) } } diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/MangaDataRepository.kt b/app/src/main/java/org/koitharu/kotatsu/base/domain/MangaDataRepository.kt similarity index 96% rename from app/src/main/java/org/koitharu/kotatsu/domain/MangaDataRepository.kt rename to app/src/main/java/org/koitharu/kotatsu/base/domain/MangaDataRepository.kt index 5be65ce1c..d8bf6facd 100644 --- a/app/src/main/java/org/koitharu/kotatsu/domain/MangaDataRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/domain/MangaDataRepository.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.domain +package org.koitharu.kotatsu.base.domain import androidx.room.withTransaction import org.koitharu.kotatsu.core.db.MangaDatabase diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/MangaLoaderContext.kt b/app/src/main/java/org/koitharu/kotatsu/base/domain/MangaLoaderContext.kt similarity index 97% rename from app/src/main/java/org/koitharu/kotatsu/domain/MangaLoaderContext.kt rename to app/src/main/java/org/koitharu/kotatsu/base/domain/MangaLoaderContext.kt index c2c884026..45f561580 100644 --- a/app/src/main/java/org/koitharu/kotatsu/domain/MangaLoaderContext.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/domain/MangaLoaderContext.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.domain +package org.koitharu.kotatsu.base.domain import okhttp3.* import org.koin.core.component.KoinComponent diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/MangaProviderFactory.kt b/app/src/main/java/org/koitharu/kotatsu/base/domain/MangaProviderFactory.kt similarity index 94% rename from app/src/main/java/org/koitharu/kotatsu/domain/MangaProviderFactory.kt rename to app/src/main/java/org/koitharu/kotatsu/base/domain/MangaProviderFactory.kt index bf0ce25fb..8498cc190 100644 --- a/app/src/main/java/org/koitharu/kotatsu/domain/MangaProviderFactory.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/domain/MangaProviderFactory.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.domain +package org.koitharu.kotatsu.base.domain import org.koin.core.component.KoinComponent import org.koin.core.component.get diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/MangaUtils.kt b/app/src/main/java/org/koitharu/kotatsu/base/domain/MangaUtils.kt similarity index 97% rename from app/src/main/java/org/koitharu/kotatsu/domain/MangaUtils.kt rename to app/src/main/java/org/koitharu/kotatsu/base/domain/MangaUtils.kt index cf581dc41..cce8023f2 100644 --- a/app/src/main/java/org/koitharu/kotatsu/domain/MangaUtils.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/domain/MangaUtils.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.domain +package org.koitharu.kotatsu.base.domain import android.graphics.BitmapFactory import android.net.Uri diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/AlertDialogFragment.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/AlertDialogFragment.kt similarity index 88% rename from app/src/main/java/org/koitharu/kotatsu/ui/base/AlertDialogFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/base/ui/AlertDialogFragment.kt index 128800038..08f80ed88 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/AlertDialogFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/AlertDialogFragment.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.base +package org.koitharu.kotatsu.base.ui import android.app.Dialog import android.os.Bundle @@ -6,11 +6,11 @@ import android.view.View import androidx.annotation.CallSuper import androidx.annotation.LayoutRes import androidx.appcompat.app.AlertDialog -import moxy.MvpAppCompatDialogFragment +import androidx.fragment.app.DialogFragment abstract class AlertDialogFragment( @LayoutRes private val layoutResId: Int -) : MvpAppCompatDialogFragment() { +) : DialogFragment() { private var rootView: View? = null diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/BaseActivity.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseActivity.kt similarity index 86% rename from app/src/main/java/org/koitharu/kotatsu/ui/base/BaseActivity.kt rename to app/src/main/java/org/koitharu/kotatsu/base/ui/BaseActivity.kt index eb04d30c8..16710be54 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/BaseActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseActivity.kt @@ -1,15 +1,15 @@ -package org.koitharu.kotatsu.ui.base +package org.koitharu.kotatsu.base.ui import android.os.Bundle import android.view.MenuItem import android.view.View +import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar -import moxy.MvpAppCompatActivity import org.koin.android.ext.android.get import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.prefs.AppSettings -abstract class BaseActivity : MvpAppCompatActivity() { +abstract class BaseActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { if (get().isAmoledTheme) { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/BaseBottomSheet.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseBottomSheet.kt similarity index 83% rename from app/src/main/java/org/koitharu/kotatsu/ui/base/BaseBottomSheet.kt rename to app/src/main/java/org/koitharu/kotatsu/base/ui/BaseBottomSheet.kt index 4faa58305..81eaeb5b7 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/BaseBottomSheet.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseBottomSheet.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.base +package org.koitharu.kotatsu.base.ui import android.app.Dialog import android.os.Bundle @@ -7,11 +7,11 @@ import android.view.View import android.view.ViewGroup import androidx.annotation.LayoutRes import androidx.appcompat.app.AppCompatDialog -import moxy.MvpBottomSheetDialogFragment +import com.google.android.material.bottomsheet.BottomSheetDialogFragment import org.koitharu.kotatsu.utils.UiUtils abstract class BaseBottomSheet(@LayoutRes private val layoutResId: Int) : - MvpBottomSheetDialogFragment() { + BottomSheetDialogFragment() { final override fun onCreateView( inflater: LayoutInflater, diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/BaseFragment.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFragment.kt similarity index 78% rename from app/src/main/java/org/koitharu/kotatsu/ui/base/BaseFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFragment.kt index 9ca17d71f..398f85cf8 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/BaseFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFragment.kt @@ -1,14 +1,14 @@ -package org.koitharu.kotatsu.ui.base +package org.koitharu.kotatsu.base.ui import android.content.Context import androidx.annotation.LayoutRes +import androidx.fragment.app.Fragment import coil.ImageLoader -import moxy.MvpAppCompatFragment import org.koin.android.ext.android.inject abstract class BaseFragment( @LayoutRes contentLayoutId: Int -) : MvpAppCompatFragment(contentLayoutId) { +) : Fragment(contentLayoutId) { protected val coil by inject() diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/BaseFullscreenActivity.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFullscreenActivity.kt similarity index 97% rename from app/src/main/java/org/koitharu/kotatsu/ui/base/BaseFullscreenActivity.kt rename to app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFullscreenActivity.kt index 5528576ea..481e54318 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/BaseFullscreenActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFullscreenActivity.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.base +package org.koitharu.kotatsu.base.ui import android.graphics.Color import android.os.Build diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/BasePreferenceFragment.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/BasePreferenceFragment.kt similarity index 91% rename from app/src/main/java/org/koitharu/kotatsu/ui/base/BasePreferenceFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/base/ui/BasePreferenceFragment.kt index 81f787f4f..9f02475fd 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/BasePreferenceFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/BasePreferenceFragment.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.base +package org.koitharu.kotatsu.base.ui import androidx.annotation.StringRes import androidx.preference.PreferenceFragmentCompat diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseService.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseService.kt new file mode 100644 index 000000000..05e07729e --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseService.kt @@ -0,0 +1,5 @@ +package org.koitharu.kotatsu.base.ui + +import androidx.lifecycle.LifecycleService + +abstract class BaseService : LifecycleService() \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseViewModel.kt new file mode 100644 index 000000000..d1237f9ce --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseViewModel.kt @@ -0,0 +1,40 @@ +package org.koitharu.kotatsu.base.ui + +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.* +import org.koitharu.kotatsu.BuildConfig +import org.koitharu.kotatsu.utils.SingleLiveEvent + +abstract class BaseViewModel : ViewModel() { + + val onError = SingleLiveEvent() + val isLoading = MutableLiveData(false) + + protected fun launchJob( + start: CoroutineStart = CoroutineStart.DEFAULT, + block: suspend CoroutineScope.() -> Unit + ): Job = viewModelScope.launch(createErrorHandler(), start, block) + + protected fun launchLoadingJob( + start: CoroutineStart = CoroutineStart.DEFAULT, + block: suspend CoroutineScope.() -> Unit + ): Job = viewModelScope.launch(createErrorHandler(), start) { + isLoading.value = true + try { + block() + } finally { + isLoading.value = false + } + } + + private fun createErrorHandler() = CoroutineExceptionHandler { _, throwable -> + if (BuildConfig.DEBUG) { + throwable.printStackTrace() + } + if (throwable !is CancellationException) { + onError.call(throwable) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/dialog/CheckBoxAlertDialog.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/dialog/CheckBoxAlertDialog.kt similarity index 97% rename from app/src/main/java/org/koitharu/kotatsu/ui/base/dialog/CheckBoxAlertDialog.kt rename to app/src/main/java/org/koitharu/kotatsu/base/ui/dialog/CheckBoxAlertDialog.kt index 3a56aed74..e07b709ff 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/dialog/CheckBoxAlertDialog.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/dialog/CheckBoxAlertDialog.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.base.dialog +package org.koitharu.kotatsu.base.ui.dialog import android.annotation.SuppressLint import android.content.Context diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/dialog/StorageSelectDialog.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/dialog/StorageSelectDialog.kt similarity index 96% rename from app/src/main/java/org/koitharu/kotatsu/ui/base/dialog/StorageSelectDialog.kt rename to app/src/main/java/org/koitharu/kotatsu/base/ui/dialog/StorageSelectDialog.kt index bfcc37f58..594837a7c 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/dialog/StorageSelectDialog.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/dialog/StorageSelectDialog.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.base.dialog +package org.koitharu.kotatsu.base.ui.dialog import android.content.Context import android.content.DialogInterface @@ -10,7 +10,7 @@ import androidx.appcompat.app.AlertDialog import com.google.android.material.dialog.MaterialAlertDialogBuilder import kotlinx.android.synthetic.main.item_storage.view.* import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.core.parser.LocalMangaRepository +import org.koitharu.kotatsu.local.domain.LocalMangaRepository import org.koitharu.kotatsu.utils.ext.getStorageName import org.koitharu.kotatsu.utils.ext.inflate import org.koitharu.kotatsu.utils.ext.longHashCode diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/dialog/TextInputDialog.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/dialog/TextInputDialog.kt similarity index 98% rename from app/src/main/java/org/koitharu/kotatsu/ui/base/dialog/TextInputDialog.kt rename to app/src/main/java/org/koitharu/kotatsu/base/ui/dialog/TextInputDialog.kt index f78ef32c1..8d7634b00 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/dialog/TextInputDialog.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/dialog/TextInputDialog.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.base.dialog +package org.koitharu.kotatsu.base.ui.dialog import android.annotation.SuppressLint import android.content.Context diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/list/AdapterUpdater.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/AdapterUpdater.kt similarity index 94% rename from app/src/main/java/org/koitharu/kotatsu/ui/base/list/AdapterUpdater.kt rename to app/src/main/java/org/koitharu/kotatsu/base/ui/list/AdapterUpdater.kt index f0e982c4a..a68cf666f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/list/AdapterUpdater.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/AdapterUpdater.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.base.list +package org.koitharu.kotatsu.base.ui.list import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/list/BaseRecyclerAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/BaseRecyclerAdapter.kt similarity index 98% rename from app/src/main/java/org/koitharu/kotatsu/ui/base/list/BaseRecyclerAdapter.kt rename to app/src/main/java/org/koitharu/kotatsu/base/ui/list/BaseRecyclerAdapter.kt index ca8245603..0b169bc44 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/list/BaseRecyclerAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/BaseRecyclerAdapter.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.base.list +package org.koitharu.kotatsu.base.ui.list import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/list/BaseViewHolder.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/BaseViewHolder.kt similarity index 97% rename from app/src/main/java/org/koitharu/kotatsu/ui/base/list/BaseViewHolder.kt rename to app/src/main/java/org/koitharu/kotatsu/base/ui/list/BaseViewHolder.kt index 4de7c3f91..23973901d 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/list/BaseViewHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/BaseViewHolder.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.base.list +package org.koitharu.kotatsu.base.ui.list import android.view.View import android.view.ViewGroup diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/list/BoundsScrollListener.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/BoundsScrollListener.kt similarity index 96% rename from app/src/main/java/org/koitharu/kotatsu/ui/base/list/BoundsScrollListener.kt rename to app/src/main/java/org/koitharu/kotatsu/base/ui/list/BoundsScrollListener.kt index 79b7f55ca..4a412d081 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/list/BoundsScrollListener.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/BoundsScrollListener.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.base.list +package org.koitharu.kotatsu.base.ui.list import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/list/OnRecyclerItemClickListener.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/OnRecyclerItemClickListener.kt similarity index 81% rename from app/src/main/java/org/koitharu/kotatsu/ui/base/list/OnRecyclerItemClickListener.kt rename to app/src/main/java/org/koitharu/kotatsu/base/ui/list/OnRecyclerItemClickListener.kt index 6d6f659d1..47a9465c3 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/list/OnRecyclerItemClickListener.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/OnRecyclerItemClickListener.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.base.list +package org.koitharu.kotatsu.base.ui.list import android.view.View diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/list/PaginationScrollListener.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/PaginationScrollListener.kt similarity index 93% rename from app/src/main/java/org/koitharu/kotatsu/ui/base/list/PaginationScrollListener.kt rename to app/src/main/java/org/koitharu/kotatsu/base/ui/list/PaginationScrollListener.kt index 4395da3fa..816110a09 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/list/PaginationScrollListener.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/PaginationScrollListener.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.base.list +package org.koitharu.kotatsu.base.ui.list import androidx.recyclerview.widget.RecyclerView diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/list/ProgressBarAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/ProgressBarAdapter.kt similarity index 91% rename from app/src/main/java/org/koitharu/kotatsu/ui/base/list/ProgressBarAdapter.kt rename to app/src/main/java/org/koitharu/kotatsu/base/ui/list/ProgressBarAdapter.kt index a589c92c7..40946886b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/list/ProgressBarAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/ProgressBarAdapter.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.base.list +package org.koitharu.kotatsu.base.ui.list import android.view.ViewGroup diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/list/ProgressBarHolder.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/ProgressBarHolder.kt similarity index 95% rename from app/src/main/java/org/koitharu/kotatsu/ui/base/list/ProgressBarHolder.kt rename to app/src/main/java/org/koitharu/kotatsu/base/ui/list/ProgressBarHolder.kt index 87070c7d3..bb940b180 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/list/ProgressBarHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/ProgressBarHolder.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.base.list +package org.koitharu.kotatsu.base.ui.list import android.view.View import android.view.ViewGroup diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/list/decor/ItemTypeDividerDecoration.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/decor/ItemTypeDividerDecoration.kt similarity index 97% rename from app/src/main/java/org/koitharu/kotatsu/ui/base/list/decor/ItemTypeDividerDecoration.kt rename to app/src/main/java/org/koitharu/kotatsu/base/ui/list/decor/ItemTypeDividerDecoration.kt index 2ed17fd9f..a887d8311 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/list/decor/ItemTypeDividerDecoration.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/decor/ItemTypeDividerDecoration.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.base.list.decor +package org.koitharu.kotatsu.base.ui.list.decor import android.content.Context import android.graphics.Canvas diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/list/decor/SectionItemDecoration.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/decor/SectionItemDecoration.kt similarity index 98% rename from app/src/main/java/org/koitharu/kotatsu/ui/base/list/decor/SectionItemDecoration.kt rename to app/src/main/java/org/koitharu/kotatsu/base/ui/list/decor/SectionItemDecoration.kt index 0fb82c73b..b5ecb78a2 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/list/decor/SectionItemDecoration.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/decor/SectionItemDecoration.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.base.list.decor +package org.koitharu.kotatsu.base.ui.list.decor import android.graphics.Canvas import android.graphics.Rect diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/list/decor/SpacingItemDecoration.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/decor/SpacingItemDecoration.kt similarity index 94% rename from app/src/main/java/org/koitharu/kotatsu/ui/base/list/decor/SpacingItemDecoration.kt rename to app/src/main/java/org/koitharu/kotatsu/base/ui/list/decor/SpacingItemDecoration.kt index 1fe6d1a34..2369b1cdb 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/list/decor/SpacingItemDecoration.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/list/decor/SpacingItemDecoration.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.base.list.decor +package org.koitharu.kotatsu.base.ui.list.decor import android.graphics.Rect import android.view.View diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/widgets/CheckableImageView.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/CheckableImageView.kt similarity index 97% rename from app/src/main/java/org/koitharu/kotatsu/ui/base/widgets/CheckableImageView.kt rename to app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/CheckableImageView.kt index 09dc3f97f..472f95a78 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/widgets/CheckableImageView.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/CheckableImageView.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.base.widgets +package org.koitharu.kotatsu.base.ui.widgets import android.content.Context import android.util.AttributeSet diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/widgets/CoverImageView.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/CoverImageView.kt similarity index 97% rename from app/src/main/java/org/koitharu/kotatsu/ui/base/widgets/CoverImageView.kt rename to app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/CoverImageView.kt index 4b0e4e1bf..049452f4f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/widgets/CoverImageView.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/CoverImageView.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.base.widgets +package org.koitharu.kotatsu.base.ui.widgets import android.content.Context import android.util.AttributeSet diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/widgets/SquareLayout.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/SquareLayout.kt similarity index 89% rename from app/src/main/java/org/koitharu/kotatsu/ui/base/widgets/SquareLayout.kt rename to app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/SquareLayout.kt index 3eeb91043..589d75382 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/widgets/SquareLayout.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/SquareLayout.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.base.widgets +package org.koitharu.kotatsu.base.ui.widgets import android.content.Context import android.util.AttributeSet diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/browser/BrowserActivity.kt b/app/src/main/java/org/koitharu/kotatsu/browser/BrowserActivity.kt similarity index 96% rename from app/src/main/java/org/koitharu/kotatsu/ui/browser/BrowserActivity.kt rename to app/src/main/java/org/koitharu/kotatsu/browser/BrowserActivity.kt index 5edd7b5ab..5ee23f338 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/browser/BrowserActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/browser/BrowserActivity.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.browser +package org.koitharu.kotatsu.browser import android.annotation.SuppressLint import android.content.ActivityNotFoundException @@ -11,7 +11,7 @@ import android.view.MenuItem import androidx.core.view.isVisible import kotlinx.android.synthetic.main.activity_browser.* import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.ui.base.BaseActivity +import org.koitharu.kotatsu.base.ui.BaseActivity @SuppressLint("SetJavaScriptEnabled") class BrowserActivity : BaseActivity(), BrowserCallback { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/browser/BrowserCallback.kt b/app/src/main/java/org/koitharu/kotatsu/browser/BrowserCallback.kt similarity index 77% rename from app/src/main/java/org/koitharu/kotatsu/ui/browser/BrowserCallback.kt rename to app/src/main/java/org/koitharu/kotatsu/browser/BrowserCallback.kt index 71b1ecfa9..e6f3fae84 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/browser/BrowserCallback.kt +++ b/app/src/main/java/org/koitharu/kotatsu/browser/BrowserCallback.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.browser +package org.koitharu.kotatsu.browser interface BrowserCallback { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/browser/BrowserClient.kt b/app/src/main/java/org/koitharu/kotatsu/browser/BrowserClient.kt similarity index 97% rename from app/src/main/java/org/koitharu/kotatsu/ui/browser/BrowserClient.kt rename to app/src/main/java/org/koitharu/kotatsu/browser/BrowserClient.kt index bda99170d..11ec6827d 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/browser/BrowserClient.kt +++ b/app/src/main/java/org/koitharu/kotatsu/browser/BrowserClient.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.browser +package org.koitharu.kotatsu.browser import android.graphics.Bitmap import android.webkit.WebResourceRequest diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/utils/cloudflare/CloudFlareCallback.kt b/app/src/main/java/org/koitharu/kotatsu/browser/cloudflare/CloudFlareCallback.kt similarity index 60% rename from app/src/main/java/org/koitharu/kotatsu/ui/utils/cloudflare/CloudFlareCallback.kt rename to app/src/main/java/org/koitharu/kotatsu/browser/cloudflare/CloudFlareCallback.kt index 6f3c2514d..aedd22605 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/utils/cloudflare/CloudFlareCallback.kt +++ b/app/src/main/java/org/koitharu/kotatsu/browser/cloudflare/CloudFlareCallback.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.utils.cloudflare +package org.koitharu.kotatsu.browser.cloudflare interface CloudFlareCallback { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/utils/cloudflare/CloudFlareClient.kt b/app/src/main/java/org/koitharu/kotatsu/browser/cloudflare/CloudFlareClient.kt similarity index 96% rename from app/src/main/java/org/koitharu/kotatsu/ui/utils/cloudflare/CloudFlareClient.kt rename to app/src/main/java/org/koitharu/kotatsu/browser/cloudflare/CloudFlareClient.kt index be484f6ce..b955ec529 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/utils/cloudflare/CloudFlareClient.kt +++ b/app/src/main/java/org/koitharu/kotatsu/browser/cloudflare/CloudFlareClient.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.utils.cloudflare +package org.koitharu.kotatsu.browser.cloudflare import android.graphics.Bitmap import android.webkit.CookieManager diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/utils/cloudflare/CloudFlareDialog.kt b/app/src/main/java/org/koitharu/kotatsu/browser/cloudflare/CloudFlareDialog.kt similarity index 95% rename from app/src/main/java/org/koitharu/kotatsu/ui/utils/cloudflare/CloudFlareDialog.kt rename to app/src/main/java/org/koitharu/kotatsu/browser/cloudflare/CloudFlareDialog.kt index 0e7d6a6a4..e34ef8ff1 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/utils/cloudflare/CloudFlareDialog.kt +++ b/app/src/main/java/org/koitharu/kotatsu/browser/cloudflare/CloudFlareDialog.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.utils.cloudflare +package org.koitharu.kotatsu.browser.cloudflare import android.annotation.SuppressLint import android.os.Bundle @@ -10,8 +10,8 @@ import androidx.core.view.isInvisible import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import kotlinx.android.synthetic.main.fragment_cloudflare.* import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.AlertDialogFragment import org.koitharu.kotatsu.core.network.UserAgentInterceptor -import org.koitharu.kotatsu.ui.base.AlertDialogFragment import org.koitharu.kotatsu.utils.ext.stringArgument import org.koitharu.kotatsu.utils.ext.withArgs diff --git a/app/src/main/java/org/koitharu/kotatsu/core/backup/BackupRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/backup/BackupRepository.kt index c8f40b3bb..c82914ff1 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/backup/BackupRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/backup/BackupRepository.kt @@ -4,7 +4,11 @@ import org.json.JSONArray import org.json.JSONObject import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.core.db.MangaDatabase -import org.koitharu.kotatsu.core.db.entity.* +import org.koitharu.kotatsu.core.db.entity.MangaEntity +import org.koitharu.kotatsu.core.db.entity.TagEntity +import org.koitharu.kotatsu.favourites.data.FavouriteCategoryEntity +import org.koitharu.kotatsu.favourites.data.FavouriteEntity +import org.koitharu.kotatsu.history.data.HistoryEntity class BackupRepository(private val db: MangaDatabase) { diff --git a/app/src/main/java/org/koitharu/kotatsu/core/backup/RestoreRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/backup/RestoreRepository.kt index a8afc1b6e..5f97f93d4 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/backup/RestoreRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/backup/RestoreRepository.kt @@ -3,7 +3,11 @@ package org.koitharu.kotatsu.core.backup import androidx.room.withTransaction import org.json.JSONObject import org.koitharu.kotatsu.core.db.MangaDatabase -import org.koitharu.kotatsu.core.db.entity.* +import org.koitharu.kotatsu.core.db.entity.MangaEntity +import org.koitharu.kotatsu.core.db.entity.TagEntity +import org.koitharu.kotatsu.favourites.data.FavouriteCategoryEntity +import org.koitharu.kotatsu.favourites.data.FavouriteEntity +import org.koitharu.kotatsu.history.data.HistoryEntity import org.koitharu.kotatsu.utils.ext.getStringOrNull import org.koitharu.kotatsu.utils.ext.iterator import org.koitharu.kotatsu.utils.ext.map diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/MangaDatabase.kt b/app/src/main/java/org/koitharu/kotatsu/core/db/MangaDatabase.kt index 386b9e4ab..b207504f6 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/db/MangaDatabase.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/db/MangaDatabase.kt @@ -4,6 +4,12 @@ import androidx.room.Database import androidx.room.RoomDatabase import org.koitharu.kotatsu.core.db.dao.* import org.koitharu.kotatsu.core.db.entity.* +import org.koitharu.kotatsu.favourites.data.FavouriteCategoriesDao +import org.koitharu.kotatsu.favourites.data.FavouriteCategoryEntity +import org.koitharu.kotatsu.favourites.data.FavouriteEntity +import org.koitharu.kotatsu.favourites.data.FavouritesDao +import org.koitharu.kotatsu.history.data.HistoryDao +import org.koitharu.kotatsu.history.data.HistoryEntity @Database( entities = [ diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/TrackEntity.kt b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/TrackEntity.kt index 561ff2f46..57a01888f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/TrackEntity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/TrackEntity.kt @@ -15,7 +15,7 @@ import androidx.room.PrimaryKey ) ] ) -data class TrackEntity ( +data class TrackEntity( @PrimaryKey(autoGenerate = false) @ColumnInfo(name = "manga_id") val mangaId: Long, @ColumnInfo(name = "chapters_total") val totalChapters: Int, diff --git a/app/src/main/java/org/koitharu/kotatsu/core/exceptions/ParseException.kt b/app/src/main/java/org/koitharu/kotatsu/core/exceptions/ParseException.kt index d7857b761..2a2bb64dc 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/exceptions/ParseException.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/exceptions/ParseException.kt @@ -1,3 +1,4 @@ package org.koitharu.kotatsu.core.exceptions -class ParseException(message: String? = null, cause: Throwable? = null) : RuntimeException(message, cause) \ No newline at end of file +class ParseException(message: String? = null, cause: Throwable? = null) : + RuntimeException(message, cause) \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaSource.kt b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaSource.kt index 9d1c1baa1..2e430a652 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaSource.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaSource.kt @@ -4,9 +4,10 @@ import android.os.Parcelable import kotlinx.android.parcel.Parcelize import org.koin.core.context.GlobalContext import org.koin.core.error.NoBeanDefFoundException -import org.koitharu.kotatsu.core.parser.LocalMangaRepository +import org.koin.core.qualifier.named import org.koitharu.kotatsu.core.parser.MangaRepository import org.koitharu.kotatsu.core.parser.site.* +import org.koitharu.kotatsu.local.domain.LocalMangaRepository @Suppress("SpellCheckingInspection") @Parcelize @@ -30,6 +31,7 @@ enum class MangaSource( // HENTAILIB("HentaiLib", "ru", HentaiLibRepository::class.java) @get:Throws(NoBeanDefFoundException::class) + @Deprecated("") val repository: MangaRepository - get() = GlobalContext.get().get(cls.kotlin) + get() = GlobalContext.get().get(named(this)) } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaTracking.kt b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaTracking.kt index d5a1ccb39..7a3841c36 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/model/MangaTracking.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/model/MangaTracking.kt @@ -5,10 +5,10 @@ import kotlinx.android.parcel.Parcelize import java.util.* @Parcelize -data class MangaTracking ( +data class MangaTracking( val manga: Manga, val knownChaptersCount: Int, val lastChapterId: Long, val lastNotifiedChapterId: Long, val lastCheck: Date? -): Parcelable \ No newline at end of file +) : Parcelable \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/core/model/TrackingLogItem.kt b/app/src/main/java/org/koitharu/kotatsu/core/model/TrackingLogItem.kt index 3f5d50984..de7adaaa7 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/model/TrackingLogItem.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/model/TrackingLogItem.kt @@ -5,9 +5,9 @@ import kotlinx.android.parcel.Parcelize import java.util.* @Parcelize -data class TrackingLogItem ( +data class TrackingLogItem( val id: Long, val manga: Manga, val chapters: List, val createdAt: Date -): Parcelable \ No newline at end of file +) : Parcelable \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/MangaRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/MangaRepository.kt index 27009db46..e9e928028 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/MangaRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/MangaRepository.kt @@ -6,13 +6,18 @@ interface MangaRepository { val sortOrders: Set - suspend fun getList(offset: Int, query: String? = null, sortOrder: SortOrder? = null, tag: MangaTag? = null): List + suspend fun getList( + offset: Int, + query: String? = null, + sortOrder: SortOrder? = null, + tag: MangaTag? = null + ): List - suspend fun getDetails(manga: Manga) : Manga + suspend fun getDetails(manga: Manga): Manga - suspend fun getPages(chapter: MangaChapter) : List + suspend fun getPages(chapter: MangaChapter): List - suspend fun getPageFullUrl(page: MangaPage) : String + suspend fun getPageFullUrl(page: MangaPage): String suspend fun getTags(): Set } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/ParserModule.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/ParserModule.kt index 5497d1aa0..a1b2ae7e1 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/ParserModule.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/ParserModule.kt @@ -1,22 +1,25 @@ package org.koitharu.kotatsu.core.parser -import org.koin.dsl.bind +import org.koin.core.qualifier.named import org.koin.dsl.module +import org.koitharu.kotatsu.base.domain.MangaLoaderContext +import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.core.parser.site.* val parserModule get() = module { - single { LocalMangaRepository(get()) } bind MangaRepository::class - factory { ReadmangaRepository(get()) } bind MangaRepository::class - factory { MintMangaRepository(get()) } bind MangaRepository::class - factory { SelfMangaRepository(get()) } bind MangaRepository::class - factory { MangaChanRepository(get()) } bind MangaRepository::class - factory { DesuMeRepository(get()) } bind MangaRepository::class - factory { HenChanRepository(get()) } bind MangaRepository::class - factory { YaoiChanRepository(get()) } bind MangaRepository::class - factory { MangaTownRepository(get()) } bind MangaRepository::class - factory { MangaLibRepository(get()) } bind MangaRepository::class - factory { NudeMoonRepository(get()) } bind MangaRepository::class - factory { MangareadRepository(get()) } bind MangaRepository::class + single { MangaLoaderContext() } + + factory(named(MangaSource.READMANGA_RU)) { ReadmangaRepository(get()) } + factory(named(MangaSource.MINTMANGA)) { MintMangaRepository(get()) } + factory(named(MangaSource.SELFMANGA)) { SelfMangaRepository(get()) } + factory(named(MangaSource.MANGACHAN)) { MangaChanRepository(get()) } + factory(named(MangaSource.DESUME)) { DesuMeRepository(get()) } + factory(named(MangaSource.HENCHAN)) { HenChanRepository(get()) } + factory(named(MangaSource.YAOICHAN)) { YaoiChanRepository(get()) } + factory(named(MangaSource.MANGATOWN)) { MangaTownRepository(get()) } + factory(named(MangaSource.MANGALIB)) { MangaLibRepository(get()) } + factory(named(MangaSource.NUDEMOON)) { NudeMoonRepository(get()) } + factory(named(MangaSource.MANGAREAD)) { MangareadRepository(get()) } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/RemoteMangaRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/RemoteMangaRepository.kt index 5965c8a9f..a5d6a4ae7 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/RemoteMangaRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/RemoteMangaRepository.kt @@ -1,10 +1,10 @@ package org.koitharu.kotatsu.core.parser +import org.koitharu.kotatsu.base.domain.MangaLoaderContext import org.koitharu.kotatsu.core.model.MangaPage import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.core.model.MangaTag import org.koitharu.kotatsu.core.model.SortOrder -import org.koitharu.kotatsu.domain.MangaLoaderContext abstract class RemoteMangaRepository( protected val loaderContext: MangaLoaderContext diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/ChanRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/ChanRepository.kt index f2f049e99..54fcb38d5 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/ChanRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/ChanRepository.kt @@ -1,11 +1,11 @@ package org.koitharu.kotatsu.core.parser.site import androidx.collection.arraySetOf +import org.koitharu.kotatsu.base.domain.MangaLoaderContext import org.koitharu.kotatsu.core.exceptions.ParseException import org.koitharu.kotatsu.core.model.* import org.koitharu.kotatsu.core.parser.RemoteMangaRepository import org.koitharu.kotatsu.core.prefs.SourceSettings -import org.koitharu.kotatsu.domain.MangaLoaderContext import org.koitharu.kotatsu.utils.ext.* import java.util.* diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/DesuMeRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/DesuMeRepository.kt index cc807e2cd..aefc070d0 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/DesuMeRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/DesuMeRepository.kt @@ -1,11 +1,11 @@ package org.koitharu.kotatsu.core.parser.site import androidx.collection.arraySetOf +import org.koitharu.kotatsu.base.domain.MangaLoaderContext import org.koitharu.kotatsu.core.exceptions.ParseException import org.koitharu.kotatsu.core.model.* import org.koitharu.kotatsu.core.parser.RemoteMangaRepository import org.koitharu.kotatsu.core.prefs.SourceSettings -import org.koitharu.kotatsu.domain.MangaLoaderContext import org.koitharu.kotatsu.utils.ext.* import java.util.* import kotlin.collections.ArrayList diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/GroupleRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/GroupleRepository.kt index 3ced8edac..53d14a8ec 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/GroupleRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/GroupleRepository.kt @@ -2,11 +2,11 @@ package org.koitharu.kotatsu.core.parser.site import androidx.collection.arraySetOf import androidx.core.net.toUri +import org.koitharu.kotatsu.base.domain.MangaLoaderContext import org.koitharu.kotatsu.core.exceptions.ParseException import org.koitharu.kotatsu.core.model.* import org.koitharu.kotatsu.core.parser.RemoteMangaRepository import org.koitharu.kotatsu.core.prefs.SourceSettings -import org.koitharu.kotatsu.domain.MangaLoaderContext import org.koitharu.kotatsu.utils.ext.* import java.util.* diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/HenChanRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/HenChanRepository.kt index 2ef8aed61..2373f19b8 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/HenChanRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/HenChanRepository.kt @@ -1,8 +1,8 @@ package org.koitharu.kotatsu.core.parser.site +import org.koitharu.kotatsu.base.domain.MangaLoaderContext import org.koitharu.kotatsu.core.exceptions.ParseException import org.koitharu.kotatsu.core.model.* -import org.koitharu.kotatsu.domain.MangaLoaderContext import org.koitharu.kotatsu.utils.ext.longHashCode import org.koitharu.kotatsu.utils.ext.mapToSet import org.koitharu.kotatsu.utils.ext.parseHtml diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaChanRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaChanRepository.kt index 0d6247169..f1ca82252 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaChanRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaChanRepository.kt @@ -1,7 +1,7 @@ package org.koitharu.kotatsu.core.parser.site +import org.koitharu.kotatsu.base.domain.MangaLoaderContext import org.koitharu.kotatsu.core.model.MangaSource -import org.koitharu.kotatsu.domain.MangaLoaderContext class MangaChanRepository(loaderContext: MangaLoaderContext) : ChanRepository(loaderContext) { diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaLibRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaLibRepository.kt index d614c0c97..58bd3a19b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaLibRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaLibRepository.kt @@ -4,11 +4,11 @@ import androidx.collection.ArraySet import androidx.collection.arraySetOf import org.json.JSONArray import org.json.JSONObject +import org.koitharu.kotatsu.base.domain.MangaLoaderContext import org.koitharu.kotatsu.core.exceptions.ParseException import org.koitharu.kotatsu.core.model.* import org.koitharu.kotatsu.core.parser.RemoteMangaRepository import org.koitharu.kotatsu.core.prefs.SourceSettings -import org.koitharu.kotatsu.domain.MangaLoaderContext import org.koitharu.kotatsu.utils.ext.* import java.util.* import kotlin.collections.ArrayList diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaTownRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaTownRepository.kt index 6222d1c74..d51f38564 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaTownRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangaTownRepository.kt @@ -2,11 +2,11 @@ package org.koitharu.kotatsu.core.parser.site import androidx.collection.arraySetOf import org.intellij.lang.annotations.Language +import org.koitharu.kotatsu.base.domain.MangaLoaderContext import org.koitharu.kotatsu.core.exceptions.ParseException import org.koitharu.kotatsu.core.model.* import org.koitharu.kotatsu.core.parser.RemoteMangaRepository import org.koitharu.kotatsu.core.prefs.SourceSettings -import org.koitharu.kotatsu.domain.MangaLoaderContext import org.koitharu.kotatsu.utils.ext.* import java.util.* diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangareadRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangareadRepository.kt index 7205aa1fa..6e9a44eff 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangareadRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MangareadRepository.kt @@ -1,11 +1,11 @@ package org.koitharu.kotatsu.core.parser.site import androidx.collection.arraySetOf +import org.koitharu.kotatsu.base.domain.MangaLoaderContext import org.koitharu.kotatsu.core.exceptions.ParseException import org.koitharu.kotatsu.core.model.* import org.koitharu.kotatsu.core.parser.RemoteMangaRepository import org.koitharu.kotatsu.core.prefs.SourceSettings -import org.koitharu.kotatsu.domain.MangaLoaderContext import org.koitharu.kotatsu.utils.ext.* import java.util.* diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MintMangaRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MintMangaRepository.kt index e0383adea..18bc10626 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MintMangaRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/MintMangaRepository.kt @@ -1,7 +1,7 @@ package org.koitharu.kotatsu.core.parser.site +import org.koitharu.kotatsu.base.domain.MangaLoaderContext import org.koitharu.kotatsu.core.model.MangaSource -import org.koitharu.kotatsu.domain.MangaLoaderContext class MintMangaRepository(loaderContext: MangaLoaderContext) : GroupleRepository(loaderContext) { diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/NudeMoonRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/NudeMoonRepository.kt index e43a37a64..9e45028c0 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/NudeMoonRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/NudeMoonRepository.kt @@ -1,11 +1,11 @@ package org.koitharu.kotatsu.core.parser.site import androidx.collection.arraySetOf +import org.koitharu.kotatsu.base.domain.MangaLoaderContext import org.koitharu.kotatsu.core.exceptions.ParseException import org.koitharu.kotatsu.core.model.* import org.koitharu.kotatsu.core.parser.RemoteMangaRepository import org.koitharu.kotatsu.core.prefs.SourceSettings -import org.koitharu.kotatsu.domain.MangaLoaderContext import org.koitharu.kotatsu.utils.ext.* import java.util.* import java.util.regex.Pattern diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/ReadmangaRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/ReadmangaRepository.kt index 02ec673e8..3871a966f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/ReadmangaRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/ReadmangaRepository.kt @@ -1,7 +1,7 @@ package org.koitharu.kotatsu.core.parser.site +import org.koitharu.kotatsu.base.domain.MangaLoaderContext import org.koitharu.kotatsu.core.model.MangaSource -import org.koitharu.kotatsu.domain.MangaLoaderContext class ReadmangaRepository(loaderContext: MangaLoaderContext) : GroupleRepository(loaderContext) { diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/SelfMangaRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/SelfMangaRepository.kt index 952c29578..d4e194300 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/SelfMangaRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/SelfMangaRepository.kt @@ -1,7 +1,7 @@ package org.koitharu.kotatsu.core.parser.site +import org.koitharu.kotatsu.base.domain.MangaLoaderContext import org.koitharu.kotatsu.core.model.MangaSource -import org.koitharu.kotatsu.domain.MangaLoaderContext class SelfMangaRepository(loaderContext: MangaLoaderContext) : GroupleRepository(loaderContext) { diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/YaoiChanRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/YaoiChanRepository.kt index e40a054b8..590555a42 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/YaoiChanRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/YaoiChanRepository.kt @@ -1,10 +1,10 @@ package org.koitharu.kotatsu.core.parser.site +import org.koitharu.kotatsu.base.domain.MangaLoaderContext import org.koitharu.kotatsu.core.exceptions.ParseException import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaChapter import org.koitharu.kotatsu.core.model.MangaSource -import org.koitharu.kotatsu.domain.MangaLoaderContext import org.koitharu.kotatsu.utils.ext.longHashCode import org.koitharu.kotatsu.utils.ext.parseHtml import org.koitharu.kotatsu.utils.ext.withDomain diff --git a/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt b/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt index 52409ace7..ceb7fc8d3 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppSettings.kt @@ -8,7 +8,7 @@ import androidx.collection.arraySetOf import androidx.core.content.edit import androidx.preference.PreferenceManager import org.koitharu.kotatsu.core.model.ZoomMode -import org.koitharu.kotatsu.core.parser.LocalMangaRepository +import org.koitharu.kotatsu.local.domain.LocalMangaRepository import org.koitharu.kotatsu.utils.delegates.prefs.* import java.io.File diff --git a/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppWidgetConfig.kt b/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppWidgetConfig.kt index fa4d577e9..312764f24 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppWidgetConfig.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/prefs/AppWidgetConfig.kt @@ -7,7 +7,7 @@ import org.koitharu.kotatsu.utils.delegates.prefs.LongPreferenceDelegate class AppWidgetConfig private constructor( private val prefs: SharedPreferences, val widgetId: Int -) : SharedPreferences by prefs { +) : SharedPreferences by prefs { var categoryId by LongPreferenceDelegate(CATEGORY_ID, 0L) diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/utils/AppCrashHandler.kt b/app/src/main/java/org/koitharu/kotatsu/core/ui/AppCrashHandler.kt similarity index 95% rename from app/src/main/java/org/koitharu/kotatsu/ui/utils/AppCrashHandler.kt rename to app/src/main/java/org/koitharu/kotatsu/core/ui/AppCrashHandler.kt index 5f7b5964c..002b8b05e 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/utils/AppCrashHandler.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/ui/AppCrashHandler.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.utils +package org.koitharu.kotatsu.core.ui import android.content.Context import android.content.Intent diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/ChipsFactory.kt b/app/src/main/java/org/koitharu/kotatsu/core/ui/ChipsFactory.kt similarity index 95% rename from app/src/main/java/org/koitharu/kotatsu/ui/base/ChipsFactory.kt rename to app/src/main/java/org/koitharu/kotatsu/core/ui/ChipsFactory.kt index 9120721a5..a4cceb152 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/ChipsFactory.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/ui/ChipsFactory.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.base +package org.koitharu.kotatsu.core.ui import android.content.Context import android.view.View diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/utils/CrashActivity.kt b/app/src/main/java/org/koitharu/kotatsu/core/ui/CrashActivity.kt similarity index 95% rename from app/src/main/java/org/koitharu/kotatsu/ui/utils/CrashActivity.kt rename to app/src/main/java/org/koitharu/kotatsu/core/ui/CrashActivity.kt index 3f035c029..d68e6ae00 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/utils/CrashActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/ui/CrashActivity.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.utils +package org.koitharu.kotatsu.core.ui import android.app.Activity import android.content.ActivityNotFoundException @@ -10,7 +10,7 @@ import android.view.MenuItem import android.view.View import kotlinx.android.synthetic.main.activity_crash.* import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.ui.list.MainActivity +import org.koitharu.kotatsu.main.ui.MainActivity import org.koitharu.kotatsu.utils.ShareHelper class CrashActivity : Activity(), View.OnClickListener { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/uiModule.kt b/app/src/main/java/org/koitharu/kotatsu/core/ui/uiModule.kt similarity index 81% rename from app/src/main/java/org/koitharu/kotatsu/ui/base/uiModule.kt rename to app/src/main/java/org/koitharu/kotatsu/core/ui/uiModule.kt index d4706cc3f..8032d9783 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/uiModule.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/ui/uiModule.kt @@ -1,11 +1,11 @@ -package org.koitharu.kotatsu.ui.base +package org.koitharu.kotatsu.core.ui import coil.ComponentRegistry import coil.ImageLoader import okhttp3.OkHttpClient import org.koin.android.ext.koin.androidContext import org.koin.dsl.module -import org.koitharu.kotatsu.core.local.CbzFetcher +import org.koitharu.kotatsu.local.data.CbzFetcher val uiModule get() = module { diff --git a/app/src/main/java/org/koitharu/kotatsu/details/DetailsModule.kt b/app/src/main/java/org/koitharu/kotatsu/details/DetailsModule.kt new file mode 100644 index 000000000..203b7bd4f --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/details/DetailsModule.kt @@ -0,0 +1,11 @@ +package org.koitharu.kotatsu.details + +import org.koin.android.viewmodel.dsl.viewModel +import org.koin.dsl.module +import org.koitharu.kotatsu.details.ui.DetailsViewModel + +val detailsModule + get() = module { + + viewModel { DetailsViewModel(get(), get(), get(), get(), get(), get()) } + } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/details/ChapterHolder.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/ChapterHolder.kt similarity index 91% rename from app/src/main/java/org/koitharu/kotatsu/ui/details/ChapterHolder.kt rename to app/src/main/java/org/koitharu/kotatsu/details/ui/ChapterHolder.kt index 7afbc88e1..e28c00dc6 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/details/ChapterHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/ChapterHolder.kt @@ -1,13 +1,13 @@ -package org.koitharu.kotatsu.ui.details +package org.koitharu.kotatsu.details.ui import android.graphics.Color import android.view.ViewGroup import androidx.core.view.isVisible import kotlinx.android.synthetic.main.item_chapter.* import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.list.BaseViewHolder import org.koitharu.kotatsu.core.model.MangaChapter -import org.koitharu.kotatsu.domain.history.ChapterExtra -import org.koitharu.kotatsu.ui.base.list.BaseViewHolder +import org.koitharu.kotatsu.history.domain.ChapterExtra import org.koitharu.kotatsu.utils.ext.getThemeColor class ChapterHolder(parent: ViewGroup) : diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/details/ChaptersAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersAdapter.kt similarity index 91% rename from app/src/main/java/org/koitharu/kotatsu/ui/details/ChaptersAdapter.kt rename to app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersAdapter.kt index 6748b539d..71b5e9314 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/details/ChaptersAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersAdapter.kt @@ -1,11 +1,11 @@ -package org.koitharu.kotatsu.ui.details +package org.koitharu.kotatsu.details.ui import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView +import org.koitharu.kotatsu.base.ui.list.BaseRecyclerAdapter +import org.koitharu.kotatsu.base.ui.list.OnRecyclerItemClickListener import org.koitharu.kotatsu.core.model.MangaChapter -import org.koitharu.kotatsu.domain.history.ChapterExtra -import org.koitharu.kotatsu.ui.base.list.BaseRecyclerAdapter -import org.koitharu.kotatsu.ui.base.list.OnRecyclerItemClickListener +import org.koitharu.kotatsu.history.domain.ChapterExtra class ChaptersAdapter(onItemClickListener: OnRecyclerItemClickListener) : BaseRecyclerAdapter(onItemClickListener) { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/details/ChaptersFragment.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt similarity index 76% rename from app/src/main/java/org/koitharu/kotatsu/ui/details/ChaptersFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt index 305ee35ce..b59fe89b8 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/details/ChaptersFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.details +package org.koitharu.kotatsu.details.ui import android.app.ActivityOptions import android.os.Bundle @@ -12,22 +12,22 @@ import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import kotlinx.android.synthetic.main.fragment_chapters.* -import moxy.ktx.moxyPresenter +import org.koin.android.viewmodel.ext.android.sharedViewModel import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.core.model.* -import org.koitharu.kotatsu.ui.base.BaseFragment -import org.koitharu.kotatsu.ui.base.list.OnRecyclerItemClickListener -import org.koitharu.kotatsu.ui.download.DownloadService -import org.koitharu.kotatsu.ui.reader.ReaderActivity +import org.koitharu.kotatsu.base.ui.BaseFragment +import org.koitharu.kotatsu.base.ui.list.OnRecyclerItemClickListener +import org.koitharu.kotatsu.core.model.Manga +import org.koitharu.kotatsu.core.model.MangaChapter +import org.koitharu.kotatsu.core.model.MangaHistory +import org.koitharu.kotatsu.core.model.MangaSource +import org.koitharu.kotatsu.download.DownloadService +import org.koitharu.kotatsu.reader.ui.ReaderActivity import org.koitharu.kotatsu.utils.ext.resolveDp -class ChaptersFragment : BaseFragment(R.layout.fragment_chapters), MangaDetailsView, +class ChaptersFragment : BaseFragment(R.layout.fragment_chapters), OnRecyclerItemClickListener, ActionMode.Callback { - @Suppress("unused") - private val presenter by moxyPresenter { - MangaDetailsPresenter.getInstance(activity.hashCode()) - } + private val viewModel by sharedViewModel() private var manga: Manga? = null @@ -45,33 +45,32 @@ class ChaptersFragment : BaseFragment(R.layout.fragment_chapters), MangaDetailsV ) recyclerView_chapters.setHasFixedSize(true) recyclerView_chapters.adapter = adapter + + viewModel.mangaData.observe(viewLifecycleOwner, this::onMangaUpdated) + viewModel.isLoading.observe(viewLifecycleOwner, this::onLoadingStateChanged) + viewModel.history.observe(viewLifecycleOwner, this::onHistoryChanged) + viewModel.newChapters.observe(viewLifecycleOwner, this::onNewChaptersChanged) } - override fun onMangaUpdated(manga: Manga) { + private fun onMangaUpdated(manga: Manga) { this.manga = manga adapter.replaceData(manga.chapters.orEmpty()) scrollToCurrent() } - override fun onLoadingStateChanged(isLoading: Boolean) { + private fun onLoadingStateChanged(isLoading: Boolean) { progressBar.isVisible = isLoading } - override fun onError(e: Throwable) = Unit //handled in activity - - override fun onMangaRemoved(manga: Manga) = Unit //handled in activity - - override fun onHistoryChanged(history: MangaHistory?) { + private fun onHistoryChanged(history: MangaHistory?) { adapter.currentChapterId = history?.chapterId scrollToCurrent() } - override fun onNewChaptersChanged(newChapters: Int) { + private fun onNewChaptersChanged(newChapters: Int) { adapter.newChaptersCount = newChapters } - override fun onFavouriteChanged(categories: List) = Unit - override fun onItemClick(item: MangaChapter, position: Int, view: View) { if (adapter.checkedItemsCount != 0) { adapter.toggleItemChecked(item.id) diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsActivity.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt similarity index 80% rename from app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsActivity.kt rename to app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt index a4ed4cfd3..36effe5d1 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.details +package org.koitharu.kotatsu.details.ui import android.content.Context import android.content.Intent @@ -18,28 +18,22 @@ import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayoutMediator import kotlinx.android.synthetic.main.activity_details.* import kotlinx.coroutines.launch -import moxy.MvpDelegate -import moxy.ktx.moxyPresenter +import org.koin.android.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.core.model.FavouriteCategory +import org.koitharu.kotatsu.base.ui.BaseActivity +import org.koitharu.kotatsu.browser.BrowserActivity import org.koitharu.kotatsu.core.model.Manga -import org.koitharu.kotatsu.core.model.MangaHistory import org.koitharu.kotatsu.core.model.MangaSource -import org.koitharu.kotatsu.ui.base.BaseActivity -import org.koitharu.kotatsu.ui.browser.BrowserActivity -import org.koitharu.kotatsu.ui.download.DownloadService +import org.koitharu.kotatsu.download.DownloadService import org.koitharu.kotatsu.utils.MangaShortcut import org.koitharu.kotatsu.utils.ShareHelper import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.utils.ext.getThemeColor -class MangaDetailsActivity : BaseActivity(), MangaDetailsView, - TabLayoutMediator.TabConfigurationStrategy { +class DetailsActivity : BaseActivity(), TabLayoutMediator.TabConfigurationStrategy { - private val presenter by moxyPresenter { - MangaDetailsPresenter.getInstance(hashCode()) - } + private val viewModel by viewModel() private var manga: Manga? = null @@ -49,28 +43,27 @@ class MangaDetailsActivity : BaseActivity(), MangaDetailsView, supportActionBar?.setDisplayHomeAsUpEnabled(true) pager.adapter = MangaDetailsAdapter(this) TabLayoutMediator(tabs, pager, this).attach() - if (savedInstanceState?.containsKey(MvpDelegate.MOXY_DELEGATE_TAGS_KEY) != true) { + if (savedInstanceState == null) { intent?.getParcelableExtra(EXTRA_MANGA)?.let { - presenter.loadDetails(it, true) + viewModel.loadDetails(it, true) } ?: intent?.getLongExtra(EXTRA_MANGA_ID, 0)?.takeUnless { it == 0L }?.let { - presenter.findMangaById(it) + viewModel.findMangaById(it) } ?: finishAfterTransition() } + + viewModel.mangaData.observe(this, ::onMangaUpdated) + viewModel.onMangaRemoved.observe(this, ::onMangaRemoved) + viewModel.onError.observe(this, ::onError) + viewModel.newChapters.observe(this, ::onNewChaptersChanged) } - override fun onMangaUpdated(manga: Manga) { + private fun onMangaUpdated(manga: Manga) { this.manga = manga title = manga.title invalidateOptionsMenu() } - override fun onHistoryChanged(history: MangaHistory?) = Unit - - override fun onFavouriteChanged(categories: List) = Unit - - override fun onLoadingStateChanged(isLoading: Boolean) = Unit - - override fun onMangaRemoved(manga: Manga) { + private fun onMangaRemoved(manga: Manga) { Toast.makeText( this, getString(R.string._s_deleted_from_local_storage, manga.title), Toast.LENGTH_SHORT @@ -78,7 +71,7 @@ class MangaDetailsActivity : BaseActivity(), MangaDetailsView, finishAfterTransition() } - override fun onError(e: Throwable) { + private fun onError(e: Throwable) { if (manga == null) { Toast.makeText(this, e.getDisplayMessage(resources), Toast.LENGTH_LONG).show() finishAfterTransition() @@ -87,7 +80,7 @@ class MangaDetailsActivity : BaseActivity(), MangaDetailsView, } } - override fun onNewChaptersChanged(newChapters: Int) { + private fun onNewChaptersChanged(newChapters: Int) { val tab = tabs.getTabAt(1) ?: return if (newChapters == 0) { tab.removeBadge() @@ -132,7 +125,7 @@ class MangaDetailsActivity : BaseActivity(), MangaDetailsView, .setTitle(R.string.delete_manga) .setMessage(getString(R.string.text_delete_local_manga, m.title)) .setPositiveButton(R.string.delete) { _, _ -> - presenter.deleteLocal(m) + viewModel.deleteLocal(m) } .setNegativeButton(android.R.string.cancel, null) .show() @@ -174,7 +167,7 @@ class MangaDetailsActivity : BaseActivity(), MangaDetailsView, R.id.action_shortcut -> { manga?.let { lifecycleScope.launch { - if (!MangaShortcut(it).requestPinShortcut(this@MangaDetailsActivity)) { + if (!MangaShortcut(it).requestPinShortcut(this@DetailsActivity)) { Snackbar.make( pager, R.string.operation_not_supported, @@ -217,11 +210,11 @@ class MangaDetailsActivity : BaseActivity(), MangaDetailsView, const val ACTION_MANGA_VIEW = "${BuildConfig.APPLICATION_ID}.action.VIEW_MANGA" fun newIntent(context: Context, manga: Manga) = - Intent(context, MangaDetailsActivity::class.java) + Intent(context, DetailsActivity::class.java) .putExtra(EXTRA_MANGA, manga) fun newIntent(context: Context, mangaId: Long) = - Intent(context, MangaDetailsActivity::class.java) + Intent(context, DetailsActivity::class.java) .putExtra(EXTRA_MANGA_ID, mangaId) } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt similarity index 74% rename from app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt index 5bc0a6832..d5f5de283 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt @@ -1,5 +1,6 @@ -package org.koitharu.kotatsu.ui.details +package org.koitharu.kotatsu.details.ui +import android.os.Bundle import android.text.Spanned import android.view.View import androidx.core.net.toUri @@ -10,32 +11,36 @@ import kotlinx.android.synthetic.main.fragment_details.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import moxy.ktx.moxyPresenter +import org.koin.android.viewmodel.ext.android.sharedViewModel import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.BaseFragment import org.koitharu.kotatsu.core.model.FavouriteCategory import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaHistory -import org.koitharu.kotatsu.ui.base.BaseFragment -import org.koitharu.kotatsu.ui.list.favourites.categories.select.FavouriteCategoriesDialog -import org.koitharu.kotatsu.ui.reader.ReaderActivity -import org.koitharu.kotatsu.ui.search.MangaSearchSheet +import org.koitharu.kotatsu.favourites.ui.categories.select.FavouriteCategoriesDialog +import org.koitharu.kotatsu.reader.ui.ReaderActivity +import org.koitharu.kotatsu.search.ui.MangaSearchSheet import org.koitharu.kotatsu.utils.FileSizeUtils import org.koitharu.kotatsu.utils.ext.* import kotlin.math.roundToInt -class MangaDetailsFragment : BaseFragment(R.layout.fragment_details), MangaDetailsView, - View.OnClickListener, +class DetailsFragment : BaseFragment(R.layout.fragment_details), View.OnClickListener, View.OnLongClickListener { - @Suppress("unused") - private val presenter by moxyPresenter { - MangaDetailsPresenter.getInstance(activity.hashCode()) - } + private val viewModel by sharedViewModel() private var manga: Manga? = null private var history: MangaHistory? = null - override fun onMangaUpdated(manga: Manga) { + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + viewModel.mangaData.observe(viewLifecycleOwner, ::onMangaUpdated) + viewModel.isLoading.observe(viewLifecycleOwner, ::onLoadingStateChanged) + viewModel.favouriteCategories.observe(viewLifecycleOwner, ::onFavouriteChanged) + viewModel.history.observe(viewLifecycleOwner, ::onHistoryChanged) + } + + private fun onMangaUpdated(manga: Manga) { this.manga = manga imageView_cover.newImageRequest(manga.largeCoverUrl ?: manga.coverUrl) .fallback(R.drawable.ic_placeholder) @@ -59,7 +64,7 @@ class MangaDetailsFragment : BaseFragment(R.layout.fragment_details), MangaDetai text = it, iconRes = R.drawable.ic_chip_user, tag = it, - onClickListener = this@MangaDetailsFragment + onClickListener = this@DetailsFragment ) } } @@ -68,7 +73,7 @@ class MangaDetailsFragment : BaseFragment(R.layout.fragment_details), MangaDetai text = it.title, iconRes = R.drawable.ic_chip_tag, tag = it, - onClickListener = this@MangaDetailsFragment + onClickListener = this@DetailsFragment ) } manga.url.toUri().toFileOrNull()?.let { f -> @@ -81,7 +86,7 @@ class MangaDetailsFragment : BaseFragment(R.layout.fragment_details), MangaDetai text = FileSizeUtils.formatBytes(context, size), iconRes = R.drawable.ic_chip_storage, tag = it, - onClickListener = this@MangaDetailsFragment + onClickListener = this@DetailsFragment ) } } @@ -92,12 +97,12 @@ class MangaDetailsFragment : BaseFragment(R.layout.fragment_details), MangaDetai updateReadButton() } - override fun onHistoryChanged(history: MangaHistory?) { + private fun onHistoryChanged(history: MangaHistory?) { this.history = history updateReadButton() } - override fun onFavouriteChanged(categories: List) { + private fun onFavouriteChanged(categories: List) { imageView_favourite.setImageResource( if (categories.isEmpty()) { R.drawable.ic_heart_outline @@ -107,16 +112,10 @@ class MangaDetailsFragment : BaseFragment(R.layout.fragment_details), MangaDetai ) } - override fun onLoadingStateChanged(isLoading: Boolean) { + private fun onLoadingStateChanged(isLoading: Boolean) { progressBar.isVisible = isLoading } - override fun onError(e: Throwable) = Unit //handled in activity - - override fun onMangaRemoved(manga: Manga) = Unit //handled in activity - - override fun onNewChaptersChanged(newChapters: Int) = Unit - override fun onClick(v: View) { when { v.id == R.id.imageView_favourite -> { diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsViewModel.kt new file mode 100644 index 000000000..f340e7992 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsViewModel.kt @@ -0,0 +1,135 @@ +package org.koitharu.kotatsu.details.ui + +import androidx.lifecycle.MutableLiveData +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.* +import kotlinx.coroutines.withContext +import org.koitharu.kotatsu.base.domain.MangaDataRepository +import org.koitharu.kotatsu.core.exceptions.MangaNotFoundException +import org.koitharu.kotatsu.core.model.FavouriteCategory +import org.koitharu.kotatsu.core.model.Manga +import org.koitharu.kotatsu.core.model.MangaHistory +import org.koitharu.kotatsu.favourites.domain.FavouritesRepository +import org.koitharu.kotatsu.favourites.domain.OnFavouritesChangeListener +import org.koitharu.kotatsu.history.domain.HistoryRepository +import org.koitharu.kotatsu.history.domain.OnHistoryChangeListener +import org.koitharu.kotatsu.list.ui.MangaListViewModel +import org.koitharu.kotatsu.local.domain.LocalMangaRepository +import org.koitharu.kotatsu.search.domain.MangaSearchRepository +import org.koitharu.kotatsu.tracker.domain.TrackingRepository +import org.koitharu.kotatsu.utils.SingleLiveEvent +import org.koitharu.kotatsu.utils.ext.onFirst +import org.koitharu.kotatsu.utils.ext.safe +import java.io.IOException + +class DetailsViewModel( + private val historyRepository: HistoryRepository, + private val favouritesRepository: FavouritesRepository, + private val localMangaRepository: LocalMangaRepository, + private val trackingRepository: TrackingRepository, + private val searchRepository: MangaSearchRepository, + private val mangaDataRepository: MangaDataRepository +) : MangaListViewModel(), OnHistoryChangeListener, OnFavouritesChangeListener { + + val mangaData = MutableLiveData() + val newChapters = MutableLiveData(0) + val onMangaRemoved = SingleLiveEvent() + val history = MutableLiveData() + val favouriteCategories = MutableLiveData>() + + init { + HistoryRepository.subscribe(this) + FavouritesRepository.subscribe(this) + } + + fun findMangaById(id: Long) { + launchLoadingJob { + val manga = mangaDataRepository.findMangaById(id) + ?: throw MangaNotFoundException("Cannot find manga by id") + mangaData.value = manga + loadDetails(manga, true) + } + } + + fun loadDetails(manga: Manga, force: Boolean = false) { + if (!force && mangaData.value == manga) { + return + } + loadHistory(manga) + mangaData.value = manga + loadFavourite(manga) + launchLoadingJob { + val data = withContext(Dispatchers.Default) { + manga.source.repository.getDetails(manga) + } + mangaData.value = data + newChapters.value = trackingRepository.getNewChaptersCount(manga.id) + } + } + + fun deleteLocal(manga: Manga) { + launchLoadingJob { + withContext(Dispatchers.Default) { + val original = localMangaRepository.getRemoteManga(manga) + localMangaRepository.delete(manga) || throw IOException("Unable to delete file") + safe { + historyRepository.deleteOrSwap(manga, original) + } + } + onMangaRemoved.call(manga) + } + } + + private fun loadHistory(manga: Manga) { + launchJob { + history.value = historyRepository.getOne(manga) + } + } + + private fun loadFavourite(manga: Manga) { + launchJob { + favouriteCategories.value = favouritesRepository.getCategories(manga.id) + } + } + + fun loadRelated() { + val manga = mangaData.value ?: return + searchRepository.globalSearch(manga.title) + .map { list -> + list.filter { x -> x.id != manga.id } + }.filterNot { x -> x.isEmpty() } + .flowOn(Dispatchers.IO) + .catch { e -> + if (e is IOException) { + onError.call(e) + } + } + .onEmpty { + content.value = emptyList() + isLoading.value = false + }.onCompletion { + // TODO + }.onFirst { + isLoading.value = false + }.onEach { + content.value = content.value.orEmpty() + it + } + } + + override fun onHistoryChanged() { + loadHistory(mangaData.value ?: return) + } + + override fun onFavouritesChanged(mangaId: Long) { + val manga = mangaData.value ?: return + if (mangaId == manga.id) { + loadFavourite(manga) + } + } + + override fun onCleared() { + HistoryRepository.unsubscribe(this) + FavouritesRepository.unsubscribe(this) + super.onCleared() + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/MangaDetailsAdapter.kt similarity index 73% rename from app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsAdapter.kt rename to app/src/main/java/org/koitharu/kotatsu/details/ui/MangaDetailsAdapter.kt index 2644fd61d..4d048d72f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/MangaDetailsAdapter.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.details +package org.koitharu.kotatsu.details.ui import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentActivity @@ -8,8 +8,8 @@ class MangaDetailsAdapter(activity: FragmentActivity) : FragmentStateAdapter(act override fun getItemCount() = 3 - override fun createFragment(position: Int): Fragment = when(position) { - 0 -> MangaDetailsFragment() + override fun createFragment(position: Int): Fragment = when (position) { + 0 -> DetailsFragment() 1 -> ChaptersFragment() 2 -> RelatedMangaFragment() else -> throw IndexOutOfBoundsException("No fragment for position $position") diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/RelatedMangaFragment.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/RelatedMangaFragment.kt new file mode 100644 index 000000000..2777205c1 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/RelatedMangaFragment.kt @@ -0,0 +1,22 @@ +package org.koitharu.kotatsu.details.ui + +import android.os.Bundle +import android.view.View +import org.koin.android.viewmodel.ext.android.sharedViewModel +import org.koitharu.kotatsu.list.ui.MangaListFragment + +class RelatedMangaFragment : MangaListFragment() { + + override val viewModel by sharedViewModel() + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + isSwipeRefreshEnabled = false + } + + override fun onRequestMoreItems(offset: Int) { + if (offset == 0) { + viewModel.loadRelated() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/download/DownloadNotification.kt b/app/src/main/java/org/koitharu/kotatsu/download/DownloadNotification.kt similarity index 95% rename from app/src/main/java/org/koitharu/kotatsu/ui/download/DownloadNotification.kt rename to app/src/main/java/org/koitharu/kotatsu/download/DownloadNotification.kt index 7eaf3c515..387506326 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/download/DownloadNotification.kt +++ b/app/src/main/java/org/koitharu/kotatsu/download/DownloadNotification.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.download +package org.koitharu.kotatsu.download import android.app.Notification import android.app.NotificationChannel @@ -12,7 +12,7 @@ import androidx.core.content.ContextCompat import androidx.core.graphics.drawable.toBitmap import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.Manga -import org.koitharu.kotatsu.ui.details.MangaDetailsActivity +import org.koitharu.kotatsu.details.ui.DetailsActivity import org.koitharu.kotatsu.utils.ext.getDisplayMessage import kotlin.math.roundToInt @@ -24,7 +24,8 @@ class DownloadNotification(private val context: Context) { init { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O - && manager.getNotificationChannel(CHANNEL_ID) == null) { + && manager.getNotificationChannel(CHANNEL_ID) == null + ) { val channel = NotificationChannel( CHANNEL_ID, context.getString(R.string.downloads), @@ -145,7 +146,7 @@ class DownloadNotification(private val context: Context) { private fun createIntent(context: Context, manga: Manga) = PendingIntent.getActivity( context, manga.hashCode(), - MangaDetailsActivity.newIntent(context, manga), + DetailsActivity.newIntent(context, manga), PendingIntent.FLAG_CANCEL_CURRENT ) } diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/download/DownloadService.kt b/app/src/main/java/org/koitharu/kotatsu/download/DownloadService.kt similarity index 93% rename from app/src/main/java/org/koitharu/kotatsu/ui/download/DownloadService.kt rename to app/src/main/java/org/koitharu/kotatsu/download/DownloadService.kt index 5aef01327..b786e34a6 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/download/DownloadService.kt +++ b/app/src/main/java/org/koitharu/kotatsu/download/DownloadService.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.download +package org.koitharu.kotatsu.download import android.content.Context import android.content.Intent @@ -7,6 +7,7 @@ import android.os.PowerManager import android.webkit.MimeTypeMap import android.widget.Toast import androidx.core.content.ContextCompat +import androidx.lifecycle.lifecycleScope import coil.ImageLoader import coil.request.ImageRequest import kotlinx.coroutines.* @@ -19,13 +20,13 @@ import org.koin.android.ext.android.inject import org.koin.core.context.GlobalContext import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.core.local.PagesCache +import org.koitharu.kotatsu.base.ui.BaseService +import org.koitharu.kotatsu.base.ui.dialog.CheckBoxAlertDialog import org.koitharu.kotatsu.core.model.Manga -import org.koitharu.kotatsu.core.parser.LocalMangaRepository import org.koitharu.kotatsu.core.prefs.AppSettings -import org.koitharu.kotatsu.domain.local.MangaZip -import org.koitharu.kotatsu.ui.base.BaseService -import org.koitharu.kotatsu.ui.base.dialog.CheckBoxAlertDialog +import org.koitharu.kotatsu.local.data.MangaZip +import org.koitharu.kotatsu.local.data.PagesCache +import org.koitharu.kotatsu.local.domain.LocalMangaRepository import org.koitharu.kotatsu.utils.CacheUtils import org.koitharu.kotatsu.utils.ext.* import java.io.File @@ -54,8 +55,9 @@ class DownloadService : BaseService() { .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "kotatsu:downloading") } - override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { - when (intent?.action) { + override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { + super.onStartCommand(intent, flags, startId) + when (intent.action) { ACTION_DOWNLOAD_START -> { val manga = intent.getParcelableExtra(EXTRA_MANGA) val chapters = intent.getLongArrayExtra(EXTRA_CHAPTERS_IDS)?.toArraySet() @@ -77,7 +79,7 @@ class DownloadService : BaseService() { } private fun downloadManga(manga: Manga, chaptersIds: Set?, startId: Int): Job { - return serviceScope.launch(Dispatchers.Default) { + return lifecycleScope.launch(Dispatchers.Default) { mutex.lock() wakeLock.acquire(TimeUnit.HOURS.toMillis(1)) notification.fillFrom(manga) diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/FavouritesModule.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/FavouritesModule.kt new file mode 100644 index 000000000..7efd2c4cd --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/FavouritesModule.kt @@ -0,0 +1,18 @@ +package org.koitharu.kotatsu.favourites + +import org.koin.android.viewmodel.dsl.viewModel +import org.koin.dsl.module +import org.koitharu.kotatsu.favourites.domain.FavouritesRepository +import org.koitharu.kotatsu.favourites.ui.categories.FavouritesCategoriesViewModel +import org.koitharu.kotatsu.favourites.ui.list.FavouritesListViewModel + +val favouritesModule + get() = module { + + single { FavouritesRepository(get()) } + + viewModel { (categoryId: Long) -> + FavouritesListViewModel(categoryId, get()) + } + viewModel { FavouritesCategoriesViewModel(get()) } + } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/dao/FavouriteCategoriesDao.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouriteCategoriesDao.kt similarity index 90% rename from app/src/main/java/org/koitharu/kotatsu/core/db/dao/FavouriteCategoriesDao.kt rename to app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouriteCategoriesDao.kt index 4392261b1..ab40fabbf 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/db/dao/FavouriteCategoriesDao.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouriteCategoriesDao.kt @@ -1,7 +1,6 @@ -package org.koitharu.kotatsu.core.db.dao +package org.koitharu.kotatsu.favourites.data import androidx.room.* -import org.koitharu.kotatsu.core.db.entity.FavouriteCategoryEntity @Dao abstract class FavouriteCategoriesDao { diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/FavouriteCategoryEntity.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouriteCategoryEntity.kt similarity index 93% rename from app/src/main/java/org/koitharu/kotatsu/core/db/entity/FavouriteCategoryEntity.kt rename to app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouriteCategoryEntity.kt index d495a718f..1da715ae5 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/FavouriteCategoryEntity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouriteCategoryEntity.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.core.db.entity +package org.koitharu.kotatsu.favourites.data import androidx.room.ColumnInfo import androidx.room.Entity diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/FavouriteEntity.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouriteEntity.kt similarity index 87% rename from app/src/main/java/org/koitharu/kotatsu/core/db/entity/FavouriteEntity.kt rename to app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouriteEntity.kt index 182afa5e8..95ae66e87 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/FavouriteEntity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouriteEntity.kt @@ -1,8 +1,9 @@ -package org.koitharu.kotatsu.core.db.entity +package org.koitharu.kotatsu.favourites.data import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.ForeignKey +import org.koitharu.kotatsu.core.db.entity.MangaEntity @Entity( tableName = "favourites", primaryKeys = ["manga_id", "category_id"], foreignKeys = [ diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/FavouriteManga.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouriteManga.kt similarity index 71% rename from app/src/main/java/org/koitharu/kotatsu/core/db/entity/FavouriteManga.kt rename to app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouriteManga.kt index d641b2508..5b74bc08f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/FavouriteManga.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouriteManga.kt @@ -1,8 +1,11 @@ -package org.koitharu.kotatsu.core.db.entity +package org.koitharu.kotatsu.favourites.data import androidx.room.Embedded import androidx.room.Junction import androidx.room.Relation +import org.koitharu.kotatsu.core.db.entity.MangaEntity +import org.koitharu.kotatsu.core.db.entity.MangaTagsEntity +import org.koitharu.kotatsu.core.db.entity.TagEntity data class FavouriteManga( @Embedded val favourite: FavouriteEntity, diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/dao/FavouritesDao.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouritesDao.kt similarity index 91% rename from app/src/main/java/org/koitharu/kotatsu/core/db/dao/FavouritesDao.kt rename to app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouritesDao.kt index 52f6018b4..d80b4ec79 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/db/dao/FavouritesDao.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/data/FavouritesDao.kt @@ -1,8 +1,6 @@ -package org.koitharu.kotatsu.core.db.dao +package org.koitharu.kotatsu.favourites.data import androidx.room.* -import org.koitharu.kotatsu.core.db.entity.FavouriteEntity -import org.koitharu.kotatsu.core.db.entity.FavouriteManga import org.koitharu.kotatsu.core.db.entity.MangaEntity @Dao diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/favourites/FavouritesRepository.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/domain/FavouritesRepository.kt similarity index 95% rename from app/src/main/java/org/koitharu/kotatsu/domain/favourites/FavouritesRepository.kt rename to app/src/main/java/org/koitharu/kotatsu/favourites/domain/FavouritesRepository.kt index f8a5bb3ff..f364fd37d 100644 --- a/app/src/main/java/org/koitharu/kotatsu/domain/favourites/FavouritesRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/domain/FavouritesRepository.kt @@ -1,16 +1,16 @@ -package org.koitharu.kotatsu.domain.favourites +package org.koitharu.kotatsu.favourites.domain import androidx.collection.ArraySet import androidx.room.withTransaction import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.koitharu.kotatsu.core.db.MangaDatabase -import org.koitharu.kotatsu.core.db.entity.FavouriteCategoryEntity -import org.koitharu.kotatsu.core.db.entity.FavouriteEntity import org.koitharu.kotatsu.core.db.entity.MangaEntity import org.koitharu.kotatsu.core.db.entity.TagEntity import org.koitharu.kotatsu.core.model.FavouriteCategory import org.koitharu.kotatsu.core.model.Manga +import org.koitharu.kotatsu.favourites.data.FavouriteCategoryEntity +import org.koitharu.kotatsu.favourites.data.FavouriteEntity import org.koitharu.kotatsu.utils.ext.mapToSet class FavouritesRepository(private val db: MangaDatabase) { diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/favourites/OnFavouritesChangeListener.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/domain/OnFavouritesChangeListener.kt similarity index 71% rename from app/src/main/java/org/koitharu/kotatsu/domain/favourites/OnFavouritesChangeListener.kt rename to app/src/main/java/org/koitharu/kotatsu/favourites/domain/OnFavouritesChangeListener.kt index 8796b4439..f7204f86a 100644 --- a/app/src/main/java/org/koitharu/kotatsu/domain/favourites/OnFavouritesChangeListener.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/domain/OnFavouritesChangeListener.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.domain.favourites +package org.koitharu.kotatsu.favourites.domain fun interface OnFavouritesChangeListener { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesContainerFragment.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerFragment.kt similarity index 72% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesContainerFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerFragment.kt index 3bc872ec4..984d61e46 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesContainerFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesContainerFragment.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.list.favourites +package org.koitharu.kotatsu.favourites.ui import android.os.Bundle import android.view.Menu @@ -8,25 +8,25 @@ import android.view.View import com.google.android.material.snackbar.Snackbar import com.google.android.material.tabs.TabLayoutMediator import kotlinx.android.synthetic.main.fragment_favourites.* -import moxy.ktx.moxyPresenter +import org.koin.android.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.BaseFragment import org.koitharu.kotatsu.core.model.FavouriteCategory -import org.koitharu.kotatsu.domain.favourites.FavouritesRepository -import org.koitharu.kotatsu.domain.favourites.OnFavouritesChangeListener -import org.koitharu.kotatsu.ui.base.BaseFragment -import org.koitharu.kotatsu.ui.list.favourites.categories.CategoriesActivity -import org.koitharu.kotatsu.ui.list.favourites.categories.CategoriesEditDelegate -import org.koitharu.kotatsu.ui.list.favourites.categories.FavouriteCategoriesPresenter -import org.koitharu.kotatsu.ui.list.favourites.categories.FavouriteCategoriesView +import org.koitharu.kotatsu.favourites.domain.FavouritesRepository +import org.koitharu.kotatsu.favourites.domain.OnFavouritesChangeListener +import org.koitharu.kotatsu.favourites.ui.categories.CategoriesActivity +import org.koitharu.kotatsu.favourites.ui.categories.CategoriesEditDelegate +import org.koitharu.kotatsu.favourites.ui.categories.FavouritesCategoriesViewModel import org.koitharu.kotatsu.utils.ext.showPopupMenu import java.util.* import kotlin.collections.ArrayList class FavouritesContainerFragment : BaseFragment(R.layout.fragment_favourites), - FavouriteCategoriesView, OnFavouritesChangeListener, FavouritesTabLongClickListener, + OnFavouritesChangeListener, FavouritesTabLongClickListener, CategoriesEditDelegate.CategoriesEditCallback { - private val presenter by moxyPresenter(factory = ::FavouriteCategoriesPresenter) + private val viewModel by viewModel() + private val editDelegate by lazy(LazyThreadSafetyMode.NONE) { CategoriesEditDelegate(requireContext(), this) } @@ -42,6 +42,9 @@ class FavouritesContainerFragment : BaseFragment(R.layout.fragment_favourites), pager.adapter = adapter TabLayoutMediator(tabs, pager, adapter).attach() FavouritesRepository.subscribe(this) + + viewModel.categories.observe(viewLifecycleOwner, ::onCategoriesChanged) + viewModel.onError.observe(viewLifecycleOwner, ::onError) } override fun onDestroyView() { @@ -49,7 +52,7 @@ class FavouritesContainerFragment : BaseFragment(R.layout.fragment_favourites), super.onDestroyView() } - override fun onCategoriesChanged(categories: List) { + fun onCategoriesChanged(categories: List) { val data = ArrayList(categories.size + 1) data += FavouriteCategory(0L, getString(R.string.all_favourites), -1, Date()) data += categories @@ -75,16 +78,14 @@ class FavouritesContainerFragment : BaseFragment(R.layout.fragment_favourites), return getString(R.string.favourites) } - override fun onCheckedCategoriesChanged(checkedIds: Set) = Unit - - override fun onError(e: Throwable) { + private fun onError(e: Throwable) { Snackbar.make(pager, e.message ?: return, Snackbar.LENGTH_LONG).show() } override fun onFavouritesChanged(mangaId: Long) = Unit override fun onCategoriesChanged() { - presenter.loadAllCategories() + viewModel.loadAllCategories() } override fun onTabLongClick(tabView: View, category: FavouriteCategory): Boolean { @@ -101,15 +102,15 @@ class FavouritesContainerFragment : BaseFragment(R.layout.fragment_favourites), } override fun onDeleteCategory(category: FavouriteCategory) { - presenter.deleteCategory(category.id) + viewModel.deleteCategory(category.id) } override fun onRenameCategory(category: FavouriteCategory, newName: String) { - presenter.renameCategory(category.id, newName) + viewModel.renameCategory(category.id, newName) } override fun onCreateCategory(name: String) { - presenter.createCategory(name) + viewModel.createCategory(name) } companion object { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesPagerAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesPagerAdapter.kt similarity index 88% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesPagerAdapter.kt rename to app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesPagerAdapter.kt index f8db9be9c..8da63e64c 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesPagerAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesPagerAdapter.kt @@ -1,12 +1,13 @@ -package org.koitharu.kotatsu.ui.list.favourites +package org.koitharu.kotatsu.favourites.ui import android.view.View import androidx.fragment.app.Fragment import androidx.viewpager2.adapter.FragmentStateAdapter import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayoutMediator +import org.koitharu.kotatsu.base.ui.list.AdapterUpdater import org.koitharu.kotatsu.core.model.FavouriteCategory -import org.koitharu.kotatsu.ui.base.list.AdapterUpdater +import org.koitharu.kotatsu.favourites.ui.list.FavouritesListFragment import org.koitharu.kotatsu.utils.ext.replaceWith class FavouritesPagerAdapter( diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesTabLongClickListener.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesTabLongClickListener.kt similarity index 80% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesTabLongClickListener.kt rename to app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesTabLongClickListener.kt index 63709f134..acc4f89c0 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesTabLongClickListener.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/FavouritesTabLongClickListener.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.list.favourites +package org.koitharu.kotatsu.favourites.ui import android.view.View import org.koitharu.kotatsu.core.model.FavouriteCategory diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/CategoriesActivity.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/CategoriesActivity.kt similarity index 80% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/CategoriesActivity.kt rename to app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/CategoriesActivity.kt index 2ba84ce7d..abfd229e1 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/CategoriesActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/CategoriesActivity.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.list.favourites.categories +package org.koitharu.kotatsu.favourites.ui.categories import android.content.Context import android.content.Intent @@ -12,18 +12,18 @@ import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView import com.google.android.material.snackbar.Snackbar import kotlinx.android.synthetic.main.activity_categories.* -import moxy.ktx.moxyPresenter +import org.koin.android.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.BaseActivity +import org.koitharu.kotatsu.base.ui.list.OnRecyclerItemClickListener import org.koitharu.kotatsu.core.model.FavouriteCategory -import org.koitharu.kotatsu.ui.base.BaseActivity -import org.koitharu.kotatsu.ui.base.list.OnRecyclerItemClickListener import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.utils.ext.showPopupMenu class CategoriesActivity : BaseActivity(), OnRecyclerItemClickListener, - FavouriteCategoriesView, View.OnClickListener, CategoriesEditDelegate.CategoriesEditCallback { + View.OnClickListener, CategoriesEditDelegate.CategoriesEditCallback { - private val presenter by moxyPresenter(factory = ::FavouriteCategoriesPresenter) + private val viewModel by viewModel() private lateinit var adapter: CategoriesAdapter private lateinit var reorderHelper: ItemTouchHelper @@ -41,6 +41,9 @@ class CategoriesActivity : BaseActivity(), OnRecyclerItemClickListener) { + private fun onCategoriesChanged(categories: List) { adapter.replaceData(categories) textView_holder.isVisible = categories.isEmpty() } - override fun onCheckedCategoriesChanged(checkedIds: Set) = Unit - - override fun onError(e: Throwable) { + private fun onError(e: Throwable) { Snackbar.make(recyclerView, e.getDisplayMessage(resources), Snackbar.LENGTH_LONG) .show() } override fun onDeleteCategory(category: FavouriteCategory) { - presenter.deleteCategory(category.id) + viewModel.deleteCategory(category.id) } override fun onRenameCategory(category: FavouriteCategory, newName: String) { - presenter.renameCategory(category.id, newName) + viewModel.renameCategory(category.id, newName) } override fun onCreateCategory(name: String) { - presenter.createCategory(name) + viewModel.createCategory(name) } private inner class ReorderHelperCallback : ItemTouchHelper.SimpleCallback( @@ -102,7 +103,7 @@ class CategoriesActivity : BaseActivity(), OnRecyclerItemClickListener) : BaseRecyclerAdapter() { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/CategoriesEditDelegate.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/CategoriesEditDelegate.kt similarity index 93% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/CategoriesEditDelegate.kt rename to app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/CategoriesEditDelegate.kt index 1401e2213..b60762f11 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/CategoriesEditDelegate.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/CategoriesEditDelegate.kt @@ -1,11 +1,11 @@ -package org.koitharu.kotatsu.ui.list.favourites.categories +package org.koitharu.kotatsu.favourites.ui.categories import android.content.Context import android.text.InputType import com.google.android.material.dialog.MaterialAlertDialogBuilder import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.dialog.TextInputDialog import org.koitharu.kotatsu.core.model.FavouriteCategory -import org.koitharu.kotatsu.ui.base.dialog.TextInputDialog class CategoriesEditDelegate( private val context: Context, diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/CategoryHolder.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/CategoryHolder.kt similarity index 77% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/CategoryHolder.kt rename to app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/CategoryHolder.kt index b70fc3ddd..46899ba42 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/CategoryHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/CategoryHolder.kt @@ -1,10 +1,10 @@ -package org.koitharu.kotatsu.ui.list.favourites.categories +package org.koitharu.kotatsu.favourites.ui.categories import android.view.ViewGroup import kotlinx.android.synthetic.main.item_category.* import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.list.BaseViewHolder import org.koitharu.kotatsu.core.model.FavouriteCategory -import org.koitharu.kotatsu.ui.base.list.BaseViewHolder class CategoryHolder(parent: ViewGroup) : BaseViewHolder(parent, R.layout.item_category) { diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/FavouritesCategoriesViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/FavouritesCategoriesViewModel.kt new file mode 100644 index 000000000..5f7de98a0 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/FavouritesCategoriesViewModel.kt @@ -0,0 +1,77 @@ +package org.koitharu.kotatsu.favourites.ui.categories + +import androidx.lifecycle.MutableLiveData +import kotlinx.coroutines.Job +import org.koitharu.kotatsu.base.ui.BaseViewModel +import org.koitharu.kotatsu.core.model.FavouriteCategory +import org.koitharu.kotatsu.core.model.Manga +import org.koitharu.kotatsu.favourites.domain.FavouritesRepository +import org.koitharu.kotatsu.utils.ext.mapToSet + +class FavouritesCategoriesViewModel( + private val repository: FavouritesRepository +) : BaseViewModel() { + + private var reorderJob: Job? = null + + val categories = MutableLiveData>() + val mangaCategories = MutableLiveData>() + + init { + loadAllCategories() + } + + fun loadAllCategories() { + launchJob { + categories.value = repository.getAllCategories() + } + } + + fun loadMangaCategories(manga: Manga) { + launchJob { + val categories = repository.getCategories(manga.id) + mangaCategories.value = categories.mapToSet { it.id.toInt() } + } + } + + fun createCategory(name: String) { + launchJob { + repository.addCategory(name) + categories.value = repository.getAllCategories() + } + } + + fun renameCategory(id: Long, name: String) { + launchJob { + repository.renameCategory(id, name) + categories.value = repository.getAllCategories() + } + } + + fun deleteCategory(id: Long) { + launchJob { + repository.removeCategory(id) + categories.value = repository.getAllCategories() + } + } + + fun storeCategoriesOrder(orderedIds: List) { + val prevJob = reorderJob + reorderJob = launchJob { + prevJob?.join() + repository.reorderCategories(orderedIds) + } + } + + fun addToCategory(manga: Manga, categoryId: Long) { + launchJob { + repository.addToCategory(manga, categoryId) + } + } + + fun removeFromCategory(manga: Manga, categoryId: Long) { + launchJob { + repository.removeFromCategory(manga, categoryId) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/select/CategoriesSelectAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/CategoriesSelectAdapter.kt similarity index 87% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/select/CategoriesSelectAdapter.kt rename to app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/CategoriesSelectAdapter.kt index b79143f92..59db2ad2e 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/select/CategoriesSelectAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/CategoriesSelectAdapter.kt @@ -1,12 +1,12 @@ -package org.koitharu.kotatsu.ui.list.favourites.categories.select +package org.koitharu.kotatsu.favourites.ui.categories.select import android.util.SparseBooleanArray import android.view.ViewGroup import android.widget.Checkable import androidx.core.util.set +import org.koitharu.kotatsu.base.ui.list.BaseRecyclerAdapter +import org.koitharu.kotatsu.base.ui.list.BaseViewHolder import org.koitharu.kotatsu.core.model.FavouriteCategory -import org.koitharu.kotatsu.ui.base.list.BaseRecyclerAdapter -import org.koitharu.kotatsu.ui.base.list.BaseViewHolder class CategoriesSelectAdapter(private val listener: OnCategoryCheckListener) : BaseRecyclerAdapter() { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/select/CategoryCheckableHolder.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/CategoryCheckableHolder.kt similarity index 78% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/select/CategoryCheckableHolder.kt rename to app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/CategoryCheckableHolder.kt index a02d7ebed..f9f534c84 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/select/CategoryCheckableHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/CategoryCheckableHolder.kt @@ -1,10 +1,10 @@ -package org.koitharu.kotatsu.ui.list.favourites.categories.select +package org.koitharu.kotatsu.favourites.ui.categories.select import android.view.ViewGroup import kotlinx.android.synthetic.main.item_category_checkable.* import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.list.BaseViewHolder import org.koitharu.kotatsu.core.model.FavouriteCategory -import org.koitharu.kotatsu.ui.base.list.BaseViewHolder class CategoryCheckableHolder(parent: ViewGroup) : BaseViewHolder(parent, R.layout.item_category_checkable) { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/select/FavouriteCategoriesDialog.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/FavouriteCategoriesDialog.kt similarity index 68% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/select/FavouriteCategoriesDialog.kt rename to app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/FavouriteCategoriesDialog.kt index 31ea5d817..e90c37b3d 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/select/FavouriteCategoriesDialog.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/FavouriteCategoriesDialog.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.list.favourites.categories.select +package org.koitharu.kotatsu.favourites.ui.categories.select import android.os.Bundle import android.text.InputType @@ -6,22 +6,20 @@ import android.view.View import android.widget.Toast import androidx.fragment.app.FragmentManager import kotlinx.android.synthetic.main.dialog_favorite_categories.* -import moxy.ktx.moxyPresenter +import org.koin.android.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.BaseBottomSheet +import org.koitharu.kotatsu.base.ui.dialog.TextInputDialog import org.koitharu.kotatsu.core.model.FavouriteCategory import org.koitharu.kotatsu.core.model.Manga -import org.koitharu.kotatsu.ui.base.BaseBottomSheet -import org.koitharu.kotatsu.ui.base.dialog.TextInputDialog -import org.koitharu.kotatsu.ui.list.favourites.categories.FavouriteCategoriesPresenter -import org.koitharu.kotatsu.ui.list.favourites.categories.FavouriteCategoriesView +import org.koitharu.kotatsu.favourites.ui.categories.FavouritesCategoriesViewModel import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.utils.ext.withArgs class FavouriteCategoriesDialog : BaseBottomSheet(R.layout.dialog_favorite_categories), - FavouriteCategoriesView, OnCategoryCheckListener { - private val presenter by moxyPresenter(factory = ::FavouriteCategoriesPresenter) + private val viewModel by viewModel() private val manga get() = arguments?.getParcelable(ARG_MANGA) @@ -38,8 +36,12 @@ class FavouriteCategoriesDialog : BaseBottomSheet(R.layout.dialog_favorite_categ createCategory() } manga?.let { - presenter.loadMangaCategories(it) + viewModel.loadMangaCategories(it) } + + viewModel.categories.observe(viewLifecycleOwner, ::onCategoriesChanged) + viewModel.mangaCategories.observe(viewLifecycleOwner, ::onCheckedCategoriesChanged) + viewModel.onError.observe(viewLifecycleOwner, ::onError) } override fun onDestroyView() { @@ -47,23 +49,23 @@ class FavouriteCategoriesDialog : BaseBottomSheet(R.layout.dialog_favorite_categ super.onDestroyView() } - override fun onCategoriesChanged(categories: List) { + private fun onCategoriesChanged(categories: List) { adapter?.replaceData(categories) } - override fun onCheckedCategoriesChanged(checkedIds: Set) { + private fun onCheckedCategoriesChanged(checkedIds: Set) { adapter?.setCheckedIds(checkedIds) } override fun onCategoryChecked(category: FavouriteCategory) { - presenter.addToCategory(manga ?: return, category.id) + viewModel.addToCategory(manga ?: return, category.id) } override fun onCategoryUnchecked(category: FavouriteCategory) { - presenter.removeFromCategory(manga ?: return, category.id) + viewModel.removeFromCategory(manga ?: return, category.id) } - override fun onError(e: Throwable) { + private fun onError(e: Throwable) { Toast.makeText(context ?: return, e.getDisplayMessage(resources), Toast.LENGTH_SHORT).show() } @@ -75,7 +77,7 @@ class FavouriteCategoriesDialog : BaseBottomSheet(R.layout.dialog_favorite_categ .setInputType(InputType.TYPE_TEXT_VARIATION_PERSON_NAME or InputType.TYPE_TEXT_FLAG_CAP_SENTENCES) .setNegativeButton(android.R.string.cancel) .setPositiveButton(R.string.add) { _, name -> - presenter.createCategory(name) + viewModel.createCategory(name) }.create() .show() } diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/select/OnCategoryCheckListener.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/OnCategoryCheckListener.kt similarity index 75% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/select/OnCategoryCheckListener.kt rename to app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/OnCategoryCheckListener.kt index f9aa985da..516524739 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/select/OnCategoryCheckListener.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/categories/select/OnCategoryCheckListener.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.list.favourites.categories.select +package org.koitharu.kotatsu.favourites.ui.categories.select import org.koitharu.kotatsu.core.model.FavouriteCategory diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesListFragment.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/list/FavouritesListFragment.kt similarity index 71% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesListFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/favourites/ui/list/FavouritesListFragment.kt index a9a2d9816..a5adb19db 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesListFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/list/FavouritesListFragment.kt @@ -1,28 +1,27 @@ -package org.koitharu.kotatsu.ui.list.favourites +package org.koitharu.kotatsu.favourites.ui.list import android.view.Menu import android.view.MenuInflater import android.view.MenuItem import kotlinx.android.synthetic.main.fragment_list.* -import moxy.ktx.moxyPresenter -import org.koin.android.ext.android.get +import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.core.parameter.parametersOf import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.Manga -import org.koitharu.kotatsu.ui.list.MangaListFragment -import org.koitharu.kotatsu.ui.list.MangaListView +import org.koitharu.kotatsu.list.ui.MangaListFragment import org.koitharu.kotatsu.utils.ext.withArgs -class FavouritesListFragment : MangaListFragment(), MangaListView { +class FavouritesListFragment : MangaListFragment() { - private val presenter by moxyPresenter { - FavouritesListPresenter(categoryId, get()) + override val viewModel by viewModel { + parametersOf(categoryId) } private val categoryId: Long get() = arguments?.getLong(ARG_CATEGORY_ID) ?: 0L override fun onRequestMoreItems(offset: Int) { - presenter.loadList(offset) + viewModel.loadList(offset) } override fun setUpEmptyListHolder() { @@ -41,9 +40,9 @@ class FavouritesListFragment : MangaListFragment(), MangaListView { inflater.inflate(R.menu.popup_favourites, menu) } - override fun onPopupMenuItemSelected(item: MenuItem, data: Manga) = when(item.itemId) { + override fun onPopupMenuItemSelected(item: MenuItem, data: Manga) = when (item.itemId) { R.id.action_remove -> { - presenter.removeFromFavourites(data) + viewModel.removeFromFavourites(data) true } else -> super.onPopupMenuItemSelected(item, data) diff --git a/app/src/main/java/org/koitharu/kotatsu/favourites/ui/list/FavouritesListViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/list/FavouritesListViewModel.kt new file mode 100644 index 000000000..fb4c3f46f --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/favourites/ui/list/FavouritesListViewModel.kt @@ -0,0 +1,37 @@ +package org.koitharu.kotatsu.favourites.ui.list + +import org.koitharu.kotatsu.core.model.Manga +import org.koitharu.kotatsu.favourites.domain.FavouritesRepository +import org.koitharu.kotatsu.list.ui.MangaListViewModel + +class FavouritesListViewModel( + private val categoryId: Long, + private val repository: FavouritesRepository +) : MangaListViewModel() { + + fun loadList(offset: Int) { + launchLoadingJob { + val list = if (categoryId == 0L) { + repository.getAllManga(offset = offset) + } else { + repository.getManga(categoryId = categoryId, offset = offset) + } + if (offset == 0) { + content.value = list + } else { + content.value = content.value.orEmpty() + list + } + } + } + + fun removeFromFavourites(manga: Manga) { + launchJob { + if (categoryId == 0L) { + repository.removeFromFavourites(manga) + } else { + repository.removeFromCategory(manga, categoryId) + } + content.value = content.value?.filterNot { it.id == manga.id } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/history/HistoryModule.kt b/app/src/main/java/org/koitharu/kotatsu/history/HistoryModule.kt new file mode 100644 index 000000000..e694407e0 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/history/HistoryModule.kt @@ -0,0 +1,14 @@ +package org.koitharu.kotatsu.history + +import org.koin.android.ext.koin.androidContext +import org.koin.android.viewmodel.dsl.viewModel +import org.koin.dsl.module +import org.koitharu.kotatsu.history.domain.HistoryRepository +import org.koitharu.kotatsu.history.ui.HistoryListViewModel + +val historyModule + get() = module { + + single { HistoryRepository(get()) } + viewModel { HistoryListViewModel(get(), androidContext()) } + } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/dao/HistoryDao.kt b/app/src/main/java/org/koitharu/kotatsu/history/data/HistoryDao.kt similarity index 89% rename from app/src/main/java/org/koitharu/kotatsu/core/db/dao/HistoryDao.kt rename to app/src/main/java/org/koitharu/kotatsu/history/data/HistoryDao.kt index ca768f982..a407ed64c 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/db/dao/HistoryDao.kt +++ b/app/src/main/java/org/koitharu/kotatsu/history/data/HistoryDao.kt @@ -1,8 +1,6 @@ -package org.koitharu.kotatsu.core.db.dao +package org.koitharu.kotatsu.history.data import androidx.room.* -import org.koitharu.kotatsu.core.db.entity.HistoryEntity -import org.koitharu.kotatsu.core.db.entity.HistoryWithManga import org.koitharu.kotatsu.core.db.entity.MangaEntity diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/HistoryEntity.kt b/app/src/main/java/org/koitharu/kotatsu/history/data/HistoryEntity.kt similarity index 90% rename from app/src/main/java/org/koitharu/kotatsu/core/db/entity/HistoryEntity.kt rename to app/src/main/java/org/koitharu/kotatsu/history/data/HistoryEntity.kt index 43d865aad..34a75b6a5 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/HistoryEntity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/history/data/HistoryEntity.kt @@ -1,9 +1,10 @@ -package org.koitharu.kotatsu.core.db.entity +package org.koitharu.kotatsu.history.data import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.ForeignKey import androidx.room.PrimaryKey +import org.koitharu.kotatsu.core.db.entity.MangaEntity import org.koitharu.kotatsu.core.model.MangaHistory import java.util.* diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/HistoryWithManga.kt b/app/src/main/java/org/koitharu/kotatsu/history/data/HistoryWithManga.kt similarity index 65% rename from app/src/main/java/org/koitharu/kotatsu/core/db/entity/HistoryWithManga.kt rename to app/src/main/java/org/koitharu/kotatsu/history/data/HistoryWithManga.kt index 76d1edb6a..d1c8ee2b0 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/HistoryWithManga.kt +++ b/app/src/main/java/org/koitharu/kotatsu/history/data/HistoryWithManga.kt @@ -1,8 +1,11 @@ -package org.koitharu.kotatsu.core.db.entity +package org.koitharu.kotatsu.history.data import androidx.room.Embedded import androidx.room.Junction import androidx.room.Relation +import org.koitharu.kotatsu.core.db.entity.MangaEntity +import org.koitharu.kotatsu.core.db.entity.MangaTagsEntity +import org.koitharu.kotatsu.core.db.entity.TagEntity data class HistoryWithManga( @Embedded val history: HistoryEntity, diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/history/ChapterExtra.kt b/app/src/main/java/org/koitharu/kotatsu/history/domain/ChapterExtra.kt similarity index 59% rename from app/src/main/java/org/koitharu/kotatsu/domain/history/ChapterExtra.kt rename to app/src/main/java/org/koitharu/kotatsu/history/domain/ChapterExtra.kt index 4d6d2b411..75d022623 100644 --- a/app/src/main/java/org/koitharu/kotatsu/domain/history/ChapterExtra.kt +++ b/app/src/main/java/org/koitharu/kotatsu/history/domain/ChapterExtra.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.domain.history +package org.koitharu.kotatsu.history.domain enum class ChapterExtra { diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/history/HistoryRepository.kt b/app/src/main/java/org/koitharu/kotatsu/history/domain/HistoryRepository.kt similarity index 93% rename from app/src/main/java/org/koitharu/kotatsu/domain/history/HistoryRepository.kt rename to app/src/main/java/org/koitharu/kotatsu/history/domain/HistoryRepository.kt index 47efb59ac..2f6a98c37 100644 --- a/app/src/main/java/org/koitharu/kotatsu/domain/history/HistoryRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/history/domain/HistoryRepository.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.domain.history +package org.koitharu.kotatsu.history.domain import androidx.collection.ArraySet import androidx.room.withTransaction @@ -7,12 +7,12 @@ import kotlinx.coroutines.withContext import org.koin.core.component.KoinComponent import org.koin.core.component.inject import org.koitharu.kotatsu.core.db.MangaDatabase -import org.koitharu.kotatsu.core.db.entity.HistoryEntity import org.koitharu.kotatsu.core.db.entity.MangaEntity import org.koitharu.kotatsu.core.db.entity.TagEntity import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaHistory -import org.koitharu.kotatsu.domain.tracking.TrackingRepository +import org.koitharu.kotatsu.history.data.HistoryEntity +import org.koitharu.kotatsu.tracker.domain.TrackingRepository import org.koitharu.kotatsu.utils.ext.mapToSet class HistoryRepository(private val db: MangaDatabase) : KoinComponent { diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/history/OnHistoryChangeListener.kt b/app/src/main/java/org/koitharu/kotatsu/history/domain/OnHistoryChangeListener.kt similarity index 59% rename from app/src/main/java/org/koitharu/kotatsu/domain/history/OnHistoryChangeListener.kt rename to app/src/main/java/org/koitharu/kotatsu/history/domain/OnHistoryChangeListener.kt index ee70791a9..f612318a3 100644 --- a/app/src/main/java/org/koitharu/kotatsu/domain/history/OnHistoryChangeListener.kt +++ b/app/src/main/java/org/koitharu/kotatsu/history/domain/OnHistoryChangeListener.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.domain.history +package org.koitharu.kotatsu.history.domain fun interface OnHistoryChangeListener { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/history/HistoryListFragment.kt b/app/src/main/java/org/koitharu/kotatsu/history/ui/HistoryListFragment.kt similarity index 75% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/history/HistoryListFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/history/ui/HistoryListFragment.kt index 79723bf5c..244043dca 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/history/HistoryListFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/history/ui/HistoryListFragment.kt @@ -1,26 +1,30 @@ -package org.koitharu.kotatsu.ui.list.history +package org.koitharu.kotatsu.history.ui +import android.os.Bundle import android.view.Menu import android.view.MenuInflater import android.view.MenuItem +import android.view.View import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar import kotlinx.android.synthetic.main.fragment_list.* -import moxy.ktx.moxyPresenter +import org.koin.android.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.Manga -import org.koitharu.kotatsu.core.model.MangaHistory -import org.koitharu.kotatsu.ui.list.MangaListFragment -import org.koitharu.kotatsu.ui.list.MangaListView +import org.koitharu.kotatsu.list.ui.MangaListFragment import org.koitharu.kotatsu.utils.ext.ellipsize -class HistoryListFragment : MangaListFragment(), - MangaListView { +class HistoryListFragment : MangaListFragment() { - private val presenter by moxyPresenter(factory = ::HistoryListPresenter) + override val viewModel by viewModel() + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + viewModel.onItemRemoved.observe(viewLifecycleOwner, ::onItemRemoved) + } override fun onRequestMoreItems(offset: Int) { - presenter.loadList(offset) + viewModel.loadList(offset) } override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { @@ -36,7 +40,7 @@ class HistoryListFragment : MangaListFragment(), .setMessage(R.string.text_clear_history_prompt) .setNegativeButton(android.R.string.cancel, null) .setPositiveButton(R.string.clear) { _, _ -> - presenter.clearHistory() + viewModel.clearHistory() }.show() true } @@ -61,15 +65,14 @@ class HistoryListFragment : MangaListFragment(), override fun onPopupMenuItemSelected(item: MenuItem, data: Manga): Boolean { return when (item.itemId) { R.id.action_remove -> { - presenter.removeFromHistory(data) + viewModel.removeFromHistory(data) true } else -> super.onPopupMenuItemSelected(item, data) } } - override fun onItemRemoved(item: Manga) { - super.onItemRemoved(item) + fun onItemRemoved(item: Manga) { Snackbar.make( recyclerView, getString( R.string._s_removed_from_history, diff --git a/app/src/main/java/org/koitharu/kotatsu/history/ui/HistoryListViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/history/ui/HistoryListViewModel.kt new file mode 100644 index 000000000..08b391273 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/history/ui/HistoryListViewModel.kt @@ -0,0 +1,50 @@ +package org.koitharu.kotatsu.history.ui + +import android.content.Context +import android.os.Build +import org.koitharu.kotatsu.core.model.Manga +import org.koitharu.kotatsu.history.domain.HistoryRepository +import org.koitharu.kotatsu.list.ui.MangaListViewModel +import org.koitharu.kotatsu.utils.MangaShortcut +import org.koitharu.kotatsu.utils.SingleLiveEvent + +class HistoryListViewModel( + private val repository: HistoryRepository, + private val context: Context //todo create ShortcutRepository +) : MangaListViewModel() { + + val onItemRemoved = SingleLiveEvent() + + fun loadList(offset: Int) { + launchLoadingJob { + val list = repository.getList(offset = offset) + if (offset == 0) { + content.value = list + } else { + content.value = content.value.orEmpty() + list + } + } + } + + fun clearHistory() { + launchLoadingJob { + repository.clear() + content.value = emptyList() + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { + MangaShortcut.clearAppShortcuts(context) + } + } + } + + fun removeFromHistory(manga: Manga) { + launchJob { + repository.delete(manga) + content.value = content.value?.filterNot { it.id == manga.id } + onItemRemoved.call(manga) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { + MangaShortcut(manga).removeAppShortcut(context) + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/ListModeSelectDialog.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/ListModeSelectDialog.kt similarity index 94% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/ListModeSelectDialog.kt rename to app/src/main/java/org/koitharu/kotatsu/list/ui/ListModeSelectDialog.kt index ac4d29fc3..9c204bda2 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/ListModeSelectDialog.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/ListModeSelectDialog.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.list +package org.koitharu.kotatsu.list.ui import android.os.Bundle import android.view.View @@ -7,9 +7,9 @@ import androidx.fragment.app.FragmentManager import kotlinx.android.synthetic.main.dialog_list_mode.* import org.koin.android.ext.android.inject import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.AlertDialogFragment import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.ListMode -import org.koitharu.kotatsu.ui.base.AlertDialogFragment class ListModeSelectDialog : AlertDialogFragment(R.layout.dialog_list_mode), View.OnClickListener { diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaFilterConfig.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaFilterConfig.kt new file mode 100644 index 000000000..e2147aa97 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaFilterConfig.kt @@ -0,0 +1,11 @@ +package org.koitharu.kotatsu.list.ui + +import org.koitharu.kotatsu.core.model.MangaFilter +import org.koitharu.kotatsu.core.model.MangaTag +import org.koitharu.kotatsu.core.model.SortOrder + +data class MangaFilterConfig( + val sortOrders: List, + val tags: List, + val currentFilter: MangaFilter? +) \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/MangaGridHolder.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaGridHolder.kt similarity index 91% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/MangaGridHolder.kt rename to app/src/main/java/org/koitharu/kotatsu/list/ui/MangaGridHolder.kt index 45486b144..fa9f8b8ac 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/MangaGridHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaGridHolder.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.list +package org.koitharu.kotatsu.list.ui import android.view.ViewGroup import coil.ImageLoader @@ -6,9 +6,9 @@ import coil.request.Disposable import kotlinx.android.synthetic.main.item_manga_grid.* import org.koin.core.component.inject import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.list.BaseViewHolder import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaHistory -import org.koitharu.kotatsu.ui.base.list.BaseViewHolder import org.koitharu.kotatsu.utils.ext.enqueueWith import org.koitharu.kotatsu.utils.ext.newImageRequest diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/MangaListAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListAdapter.kt similarity index 81% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/MangaListAdapter.kt rename to app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListAdapter.kt index 0f8ad99b2..530730c9d 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/MangaListAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListAdapter.kt @@ -1,11 +1,11 @@ -package org.koitharu.kotatsu.ui.list +package org.koitharu.kotatsu.list.ui import android.view.ViewGroup +import org.koitharu.kotatsu.base.ui.list.BaseRecyclerAdapter +import org.koitharu.kotatsu.base.ui.list.OnRecyclerItemClickListener import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaHistory import org.koitharu.kotatsu.core.prefs.ListMode -import org.koitharu.kotatsu.ui.base.list.BaseRecyclerAdapter -import org.koitharu.kotatsu.ui.base.list.OnRecyclerItemClickListener class MangaListAdapter(onItemClickListener: OnRecyclerItemClickListener) : BaseRecyclerAdapter(onItemClickListener) { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/MangaListDetailsHolder.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListDetailsHolder.kt similarity index 94% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/MangaListDetailsHolder.kt rename to app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListDetailsHolder.kt index 3cf72c697..22fb4c3f8 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/MangaListDetailsHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListDetailsHolder.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.list +package org.koitharu.kotatsu.list.ui import android.annotation.SuppressLint import android.view.ViewGroup @@ -8,9 +8,9 @@ import coil.request.Disposable import kotlinx.android.synthetic.main.item_manga_list_details.* import org.koin.core.component.inject import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.list.BaseViewHolder import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaHistory -import org.koitharu.kotatsu.ui.base.list.BaseViewHolder import org.koitharu.kotatsu.utils.ext.enqueueWith import org.koitharu.kotatsu.utils.ext.newImageRequest import org.koitharu.kotatsu.utils.ext.textAndVisible diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/MangaListFragment.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListFragment.kt similarity index 77% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/MangaListFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListFragment.kt index 3a314f37d..d9bce800f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/MangaListFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListFragment.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.list +package org.koitharu.kotatsu.list.ui import android.content.SharedPreferences import android.os.Bundle @@ -13,32 +13,29 @@ import androidx.recyclerview.widget.* import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import com.google.android.material.snackbar.Snackbar import kotlinx.android.synthetic.main.fragment_list.* -import moxy.MvpDelegate import org.koin.android.ext.android.inject import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.BaseFragment +import org.koitharu.kotatsu.base.ui.list.OnRecyclerItemClickListener +import org.koitharu.kotatsu.base.ui.list.PaginationScrollListener +import org.koitharu.kotatsu.base.ui.list.ProgressBarAdapter +import org.koitharu.kotatsu.base.ui.list.decor.ItemTypeDividerDecoration +import org.koitharu.kotatsu.base.ui.list.decor.SectionItemDecoration +import org.koitharu.kotatsu.base.ui.list.decor.SpacingItemDecoration +import org.koitharu.kotatsu.browser.cloudflare.CloudFlareDialog import org.koitharu.kotatsu.core.exceptions.CloudFlareProtectedException import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaFilter -import org.koitharu.kotatsu.core.model.MangaTag -import org.koitharu.kotatsu.core.model.SortOrder import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.ListMode -import org.koitharu.kotatsu.ui.base.BaseFragment -import org.koitharu.kotatsu.ui.base.list.OnRecyclerItemClickListener -import org.koitharu.kotatsu.ui.base.list.PaginationScrollListener -import org.koitharu.kotatsu.ui.base.list.ProgressBarAdapter -import org.koitharu.kotatsu.ui.base.list.decor.ItemTypeDividerDecoration -import org.koitharu.kotatsu.ui.base.list.decor.SectionItemDecoration -import org.koitharu.kotatsu.ui.base.list.decor.SpacingItemDecoration -import org.koitharu.kotatsu.ui.details.MangaDetailsActivity -import org.koitharu.kotatsu.ui.list.filter.FilterAdapter -import org.koitharu.kotatsu.ui.list.filter.OnFilterChangedListener -import org.koitharu.kotatsu.ui.utils.cloudflare.CloudFlareDialog +import org.koitharu.kotatsu.details.ui.DetailsActivity +import org.koitharu.kotatsu.list.ui.filter.FilterAdapter +import org.koitharu.kotatsu.list.ui.filter.OnFilterChangedListener import org.koitharu.kotatsu.utils.UiUtils import org.koitharu.kotatsu.utils.ext.* -abstract class MangaListFragment : BaseFragment(R.layout.fragment_list), - MangaListView, PaginationScrollListener.Callback, OnRecyclerItemClickListener, +abstract class MangaListFragment : BaseFragment(R.layout.fragment_list), + PaginationScrollListener.Callback, OnRecyclerItemClickListener, SharedPreferences.OnSharedPreferenceChangeListener, OnFilterChangedListener, SectionItemDecoration.Callback, SwipeRefreshLayout.OnRefreshListener { @@ -53,6 +50,8 @@ abstract class MangaListFragment : BaseFragment(R.layout.fragment_list), private var paginationListener: PaginationScrollListener? = null protected var isSwipeRefreshEnabled = true + protected abstract val viewModel: MangaListViewModel + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setHasOptionsMenu(true) @@ -72,9 +71,13 @@ abstract class MangaListFragment : BaseFragment(R.layout.fragment_list), recyclerView_filter.addItemDecoration(ItemTypeDividerDecoration(view.context)) recyclerView_filter.addItemDecoration(SectionItemDecoration(false, this)) settings.subscribe(this) - if (savedInstanceState?.containsKey(MvpDelegate.MOXY_DELEGATE_TAGS_KEY) != true) { + if (savedInstanceState == null) { onRequestMoreItems(0) } + viewModel.content.observe(viewLifecycleOwner, ::onListChanged) + viewModel.filter.observe(viewLifecycleOwner, ::onInitFilter) + viewModel.onError.observe(viewLifecycleOwner, ::onError) + viewModel.isLoading.observe(viewLifecycleOwner, ::onLoadingStateChanged) } override fun onDestroyView() { @@ -109,7 +112,7 @@ abstract class MangaListFragment : BaseFragment(R.layout.fragment_list), } override fun onItemClick(item: Manga, position: Int, view: View) { - startActivity(MangaDetailsActivity.newIntent(context ?: return, item)) + startActivity(DetailsActivity.newIntent(context ?: return, item)) } override fun onItemLongClick(item: Manga, position: Int, view: View): Boolean { @@ -132,7 +135,7 @@ abstract class MangaListFragment : BaseFragment(R.layout.fragment_list), onRequestMoreItems(0) } - override fun onListChanged(list: List) { + private fun onListChanged(list: List) { paginationListener?.reset() adapter?.replaceData(list) if (list.isEmpty()) { @@ -145,29 +148,7 @@ abstract class MangaListFragment : BaseFragment(R.layout.fragment_list), recyclerView.callOnScrollListeners() } - override fun onListAppended(list: List) { - adapter?.appendData(list) - progressAdapter?.isProgressVisible = list.isNotEmpty() - if (list.isNotEmpty()) { - layout_holder.isVisible = false - } - recyclerView.callOnScrollListeners() - } - - @CallSuper - override fun onItemRemoved(item: Manga) { - adapter?.let { - it.removeItem(item) - if (it.itemCount == 0) { - setUpEmptyListHolder() - layout_holder.isVisible = true - } else { - layout_holder.isVisible = false - } - } - } - - override fun onListError(e: Throwable) { + private fun onError(e: Throwable) { if (e is CloudFlareProtectedException) { CloudFlareDialog.newInstance(e.url).show(childFragmentManager, CloudFlareDialog.TAG) } @@ -186,12 +167,8 @@ abstract class MangaListFragment : BaseFragment(R.layout.fragment_list), } } - override fun onError(e: Throwable) { - Snackbar.make(recyclerView, e.getDisplayMessage(resources), Snackbar.LENGTH_SHORT).show() - } - @CallSuper - override fun onLoadingStateChanged(isLoading: Boolean) { + protected open fun onLoadingStateChanged(isLoading: Boolean) { val hasItems = recyclerView.hasItems progressBar.isVisible = isLoading && !hasItems swipeRefreshLayout.isEnabled = isSwipeRefreshEnabled && !progressBar.isVisible @@ -213,20 +190,21 @@ abstract class MangaListFragment : BaseFragment(R.layout.fragment_list), } } - override fun onInitFilter( - sortOrders: List, - tags: List, - currentFilter: MangaFilter? - ) { - recyclerView_filter.adapter = FilterAdapter(sortOrders, tags, currentFilter, this) + protected fun onInitFilter(config: MangaFilterConfig) { + recyclerView_filter.adapter = FilterAdapter( + sortOrders = config.sortOrders, + tags = config.tags, + state = config.currentFilter, + listener = this + ) drawer?.setDrawerLockMode( - if (sortOrders.isEmpty() && tags.isEmpty()) { + if (config.sortOrders.isEmpty() && config.tags.isEmpty()) { DrawerLayout.LOCK_MODE_LOCKED_CLOSED } else { DrawerLayout.LOCK_MODE_UNLOCKED } ) ?: divider_filter?.let { - it.isGone = sortOrders.isEmpty() && tags.isEmpty() + it.isGone = config.sortOrders.isEmpty() && config.tags.isEmpty() recyclerView_filter.isVisible = it.isVisible } activity?.invalidateOptionsMenu() diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/MangaListHolder.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListHolder.kt similarity index 92% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/MangaListHolder.kt rename to app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListHolder.kt index 55ea6b8ab..8ebf6f91a 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/MangaListHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListHolder.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.list +package org.koitharu.kotatsu.list.ui import android.view.ViewGroup import coil.ImageLoader @@ -6,9 +6,9 @@ import coil.request.Disposable import kotlinx.android.synthetic.main.item_manga_list.* import org.koin.core.component.inject import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.list.BaseViewHolder import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaHistory -import org.koitharu.kotatsu.ui.base.list.BaseViewHolder import org.koitharu.kotatsu.utils.ext.enqueueWith import org.koitharu.kotatsu.utils.ext.newImageRequest import org.koitharu.kotatsu.utils.ext.textAndVisible diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/MangaListSheet.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListSheet.kt similarity index 76% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/MangaListSheet.kt rename to app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListSheet.kt index e2a932451..f4126ed4e 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/MangaListSheet.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListSheet.kt @@ -1,37 +1,31 @@ -package org.koitharu.kotatsu.ui.list +package org.koitharu.kotatsu.list.ui import android.content.SharedPreferences import android.os.Bundle import android.view.MenuItem import android.view.View import androidx.appcompat.widget.Toolbar -import androidx.core.view.isGone import androidx.core.view.isVisible import androidx.recyclerview.widget.* import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.snackbar.Snackbar import kotlinx.android.synthetic.main.sheet_list.* -import moxy.MvpDelegate import org.koin.android.ext.android.inject import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.BaseBottomSheet +import org.koitharu.kotatsu.base.ui.list.OnRecyclerItemClickListener +import org.koitharu.kotatsu.base.ui.list.PaginationScrollListener +import org.koitharu.kotatsu.base.ui.list.ProgressBarAdapter +import org.koitharu.kotatsu.base.ui.list.decor.SpacingItemDecoration import org.koitharu.kotatsu.core.model.Manga -import org.koitharu.kotatsu.core.model.MangaFilter -import org.koitharu.kotatsu.core.model.MangaTag -import org.koitharu.kotatsu.core.model.SortOrder import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.ListMode -import org.koitharu.kotatsu.ui.base.BaseBottomSheet -import org.koitharu.kotatsu.ui.base.list.OnRecyclerItemClickListener -import org.koitharu.kotatsu.ui.base.list.PaginationScrollListener -import org.koitharu.kotatsu.ui.base.list.ProgressBarAdapter -import org.koitharu.kotatsu.ui.base.list.decor.SpacingItemDecoration -import org.koitharu.kotatsu.ui.details.MangaDetailsActivity +import org.koitharu.kotatsu.details.ui.DetailsActivity import org.koitharu.kotatsu.utils.UiUtils import org.koitharu.kotatsu.utils.ext.* -abstract class MangaListSheet : BaseBottomSheet(R.layout.sheet_list), - MangaListView, +abstract class MangaListSheet : BaseBottomSheet(R.layout.sheet_list), PaginationScrollListener.Callback, OnRecyclerItemClickListener, SharedPreferences.OnSharedPreferenceChangeListener, Toolbar.OnMenuItemClickListener { @@ -44,6 +38,8 @@ abstract class MangaListSheet : BaseBottomSheet(R.layout.sheet_list), private var adapter: MangaListAdapter? = null private var progressAdapter: ProgressBarAdapter? = null + protected abstract val viewModel: MangaListViewModel + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) adapter = MangaListAdapter(this) @@ -62,9 +58,12 @@ abstract class MangaListSheet : BaseBottomSheet(R.layout.sheet_list), textView_title.isVisible = false appbar.elevation = resources.getDimension(R.dimen.elevation_large) } - if (savedInstanceState?.containsKey(MvpDelegate.MOXY_DELEGATE_TAGS_KEY) != true) { + if (savedInstanceState == null) { onRequestMoreItems(0) } + viewModel.content.observe(viewLifecycleOwner, ::onListChanged) + viewModel.onError.observe(viewLifecycleOwner, ::onError) + viewModel.isLoading.observe(viewLifecycleOwner, ::onLoadingStateChanged) } override fun onDestroyView() { @@ -122,49 +121,23 @@ abstract class MangaListSheet : BaseBottomSheet(R.layout.sheet_list), } override fun onItemClick(item: Manga, position: Int, view: View) { - startActivity(MangaDetailsActivity.newIntent(context ?: return, item)) + startActivity(DetailsActivity.newIntent(context ?: return, item)) } - override fun onListChanged(list: List) { + private fun onListChanged(list: List) { adapter?.replaceData(list) textView_holder.isVisible = list.isEmpty() progressAdapter?.isProgressVisible = list.isNotEmpty() recyclerView.callOnScrollListeners() } - override fun onListAppended(list: List) { - adapter?.appendData(list) - if (list.isNotEmpty()) { - textView_holder.isVisible = false - } - progressAdapter?.isProgressVisible = list.isNotEmpty() - recyclerView.callOnScrollListeners() - } - - override fun onListError(e: Throwable) { - Snackbar.make(recyclerView, e.getDisplayMessage(resources), Snackbar.LENGTH_SHORT).show() - } - override fun getItemsCount() = adapter?.itemCount ?: 0 - override fun onInitFilter( - sortOrders: List, - tags: List, - currentFilter: MangaFilter? - ) = Unit - - override fun onItemRemoved(item: Manga) { - adapter?.let { - it.removeItem(item) - textView_holder.isGone = it.hasItems - } - } - - override fun onError(e: Throwable) { + private fun onError(e: Throwable) { Snackbar.make(recyclerView, e.getDisplayMessage(resources), Snackbar.LENGTH_SHORT).show() } - override fun onLoadingStateChanged(isLoading: Boolean) { + private fun onLoadingStateChanged(isLoading: Boolean) { progressBar.isVisible = isLoading && !recyclerView.hasItems if (isLoading) { textView_holder.isVisible = false diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListViewModel.kt new file mode 100644 index 000000000..667909222 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListViewModel.kt @@ -0,0 +1,11 @@ +package org.koitharu.kotatsu.list.ui + +import androidx.lifecycle.MutableLiveData +import org.koitharu.kotatsu.base.ui.BaseViewModel +import org.koitharu.kotatsu.core.model.Manga + +abstract class MangaListViewModel : BaseViewModel() { + + val content = MutableLiveData>() + val filter = MutableLiveData() +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/filter/FilterAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterAdapter.kt similarity index 96% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/filter/FilterAdapter.kt rename to app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterAdapter.kt index da8de8fa4..cc8464f0e 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/filter/FilterAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterAdapter.kt @@ -1,11 +1,11 @@ -package org.koitharu.kotatsu.ui.list.filter +package org.koitharu.kotatsu.list.ui.filter import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView +import org.koitharu.kotatsu.base.ui.list.BaseViewHolder import org.koitharu.kotatsu.core.model.MangaFilter import org.koitharu.kotatsu.core.model.MangaTag import org.koitharu.kotatsu.core.model.SortOrder -import org.koitharu.kotatsu.ui.base.list.BaseViewHolder import java.util.* import kotlin.collections.ArrayList diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/filter/FilterSortHolder.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterSortHolder.kt similarity index 80% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/filter/FilterSortHolder.kt rename to app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterSortHolder.kt index 9b6d5e8c3..9abeab8eb 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/filter/FilterSortHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterSortHolder.kt @@ -1,10 +1,10 @@ -package org.koitharu.kotatsu.ui.list.filter +package org.koitharu.kotatsu.list.ui.filter import android.view.ViewGroup import kotlinx.android.synthetic.main.item_checkable_single.* import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.list.BaseViewHolder import org.koitharu.kotatsu.core.model.SortOrder -import org.koitharu.kotatsu.ui.base.list.BaseViewHolder class FilterSortHolder(parent: ViewGroup) : BaseViewHolder(parent, R.layout.item_checkable_single) { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/filter/FilterTagHolder.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterTagHolder.kt similarity index 81% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/filter/FilterTagHolder.kt rename to app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterTagHolder.kt index d1fcd95d4..ed8ef8489 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/filter/FilterTagHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/FilterTagHolder.kt @@ -1,10 +1,10 @@ -package org.koitharu.kotatsu.ui.list.filter +package org.koitharu.kotatsu.list.ui.filter import android.view.ViewGroup import kotlinx.android.synthetic.main.item_checkable_single.* import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.list.BaseViewHolder import org.koitharu.kotatsu.core.model.MangaTag -import org.koitharu.kotatsu.ui.base.list.BaseViewHolder class FilterTagHolder(parent: ViewGroup) : BaseViewHolder(parent, R.layout.item_checkable_single) { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/filter/OnFilterChangedListener.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/OnFilterChangedListener.kt similarity index 75% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/filter/OnFilterChangedListener.kt rename to app/src/main/java/org/koitharu/kotatsu/list/ui/filter/OnFilterChangedListener.kt index 8a2d93978..93a1b7db5 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/filter/OnFilterChangedListener.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/filter/OnFilterChangedListener.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.list.filter +package org.koitharu.kotatsu.list.ui.filter import org.koitharu.kotatsu.core.model.MangaFilter diff --git a/app/src/main/java/org/koitharu/kotatsu/local/LocalModule.kt b/app/src/main/java/org/koitharu/kotatsu/local/LocalModule.kt new file mode 100644 index 000000000..fddc72006 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/local/LocalModule.kt @@ -0,0 +1,17 @@ +package org.koitharu.kotatsu.local + +import org.koin.android.ext.koin.androidContext +import org.koin.android.viewmodel.dsl.viewModel +import org.koin.dsl.bind +import org.koin.dsl.module +import org.koitharu.kotatsu.core.parser.MangaRepository +import org.koitharu.kotatsu.local.domain.LocalMangaRepository +import org.koitharu.kotatsu.local.ui.LocalListViewModel + +val localModule + get() = module { + + single { LocalMangaRepository(androidContext()) } bind MangaRepository::class + + viewModel { LocalListViewModel(get(), get(), get(), androidContext()) } + } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/core/local/Cache.kt b/app/src/main/java/org/koitharu/kotatsu/local/data/Cache.kt similarity index 65% rename from app/src/main/java/org/koitharu/kotatsu/core/local/Cache.kt rename to app/src/main/java/org/koitharu/kotatsu/local/data/Cache.kt index 1a16d23fd..d675fbc2a 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/local/Cache.kt +++ b/app/src/main/java/org/koitharu/kotatsu/local/data/Cache.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.core.local +package org.koitharu.kotatsu.local.data enum class Cache(val dir: String) { diff --git a/app/src/main/java/org/koitharu/kotatsu/core/local/CbzFetcher.kt b/app/src/main/java/org/koitharu/kotatsu/local/data/CbzFetcher.kt similarity index 95% rename from app/src/main/java/org/koitharu/kotatsu/core/local/CbzFetcher.kt rename to app/src/main/java/org/koitharu/kotatsu/local/data/CbzFetcher.kt index a3bbb8cf2..f74c023e1 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/local/CbzFetcher.kt +++ b/app/src/main/java/org/koitharu/kotatsu/local/data/CbzFetcher.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.core.local +package org.koitharu.kotatsu.local.data import android.net.Uri import android.webkit.MimeTypeMap diff --git a/app/src/main/java/org/koitharu/kotatsu/core/local/CbzFilter.kt b/app/src/main/java/org/koitharu/kotatsu/local/data/CbzFilter.kt similarity index 87% rename from app/src/main/java/org/koitharu/kotatsu/core/local/CbzFilter.kt rename to app/src/main/java/org/koitharu/kotatsu/local/data/CbzFilter.kt index 3080f1fb9..98f4e73fc 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/local/CbzFilter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/local/data/CbzFilter.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.core.local +package org.koitharu.kotatsu.local.data import java.io.File import java.io.FilenameFilter diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/local/MangaIndex.kt b/app/src/main/java/org/koitharu/kotatsu/local/data/MangaIndex.kt similarity index 98% rename from app/src/main/java/org/koitharu/kotatsu/domain/local/MangaIndex.kt rename to app/src/main/java/org/koitharu/kotatsu/local/data/MangaIndex.kt index 4ce4dffd9..255c1a5c6 100644 --- a/app/src/main/java/org/koitharu/kotatsu/domain/local/MangaIndex.kt +++ b/app/src/main/java/org/koitharu/kotatsu/local/data/MangaIndex.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.domain.local +package org.koitharu.kotatsu.local.data import org.json.JSONArray import org.json.JSONObject diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/local/MangaZip.kt b/app/src/main/java/org/koitharu/kotatsu/local/data/MangaZip.kt similarity index 94% rename from app/src/main/java/org/koitharu/kotatsu/domain/local/MangaZip.kt rename to app/src/main/java/org/koitharu/kotatsu/local/data/MangaZip.kt index b6672aa31..2904910d6 100644 --- a/app/src/main/java/org/koitharu/kotatsu/domain/local/MangaZip.kt +++ b/app/src/main/java/org/koitharu/kotatsu/local/data/MangaZip.kt @@ -1,8 +1,7 @@ -package org.koitharu.kotatsu.domain.local +package org.koitharu.kotatsu.local.data import androidx.annotation.CheckResult import androidx.annotation.WorkerThread -import org.koitharu.kotatsu.core.local.WritableCbzFile import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaChapter import org.koitharu.kotatsu.utils.ext.takeIfReadable diff --git a/app/src/main/java/org/koitharu/kotatsu/core/local/PagesCache.kt b/app/src/main/java/org/koitharu/kotatsu/local/data/PagesCache.kt similarity index 83% rename from app/src/main/java/org/koitharu/kotatsu/core/local/PagesCache.kt rename to app/src/main/java/org/koitharu/kotatsu/local/data/PagesCache.kt index 63c842d2c..8630ed688 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/local/PagesCache.kt +++ b/app/src/main/java/org/koitharu/kotatsu/local/data/PagesCache.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.core.local +package org.koitharu.kotatsu.local.data import android.content.Context import com.tomclaw.cache.DiskLruCache @@ -12,7 +12,8 @@ import java.io.OutputStream class PagesCache(context: Context) { private val cacheDir = context.externalCacheDir ?: context.cacheDir - private val lruCache = DiskLruCache.create(cacheDir.sub(Cache.PAGES.dir), FileSizeUtils.mbToBytes(200)) + private val lruCache = + DiskLruCache.create(cacheDir.sub(Cache.PAGES.dir), FileSizeUtils.mbToBytes(200)) operator fun get(url: String): File? { return lruCache.get(url)?.takeIfReadable() diff --git a/app/src/main/java/org/koitharu/kotatsu/core/local/WritableCbzFile.kt b/app/src/main/java/org/koitharu/kotatsu/local/data/WritableCbzFile.kt similarity index 98% rename from app/src/main/java/org/koitharu/kotatsu/core/local/WritableCbzFile.kt rename to app/src/main/java/org/koitharu/kotatsu/local/data/WritableCbzFile.kt index 7ea9a2523..5a591740f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/local/WritableCbzFile.kt +++ b/app/src/main/java/org/koitharu/kotatsu/local/data/WritableCbzFile.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.core.local +package org.koitharu.kotatsu.local.data import androidx.annotation.CheckResult import kotlinx.coroutines.Dispatchers diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/LocalMangaRepository.kt b/app/src/main/java/org/koitharu/kotatsu/local/domain/LocalMangaRepository.kt similarity index 92% rename from app/src/main/java/org/koitharu/kotatsu/core/parser/LocalMangaRepository.kt rename to app/src/main/java/org/koitharu/kotatsu/local/domain/LocalMangaRepository.kt index 3f3fb0567..9fe679199 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/LocalMangaRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/local/domain/LocalMangaRepository.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.core.parser +package org.koitharu.kotatsu.local.domain import android.annotation.SuppressLint import android.content.Context @@ -7,10 +7,11 @@ import android.webkit.MimeTypeMap import androidx.collection.ArraySet import androidx.core.net.toFile import androidx.core.net.toUri -import org.koitharu.kotatsu.core.local.CbzFilter import org.koitharu.kotatsu.core.model.* -import org.koitharu.kotatsu.domain.local.MangaIndex -import org.koitharu.kotatsu.domain.local.MangaZip +import org.koitharu.kotatsu.core.parser.MangaRepository +import org.koitharu.kotatsu.local.data.CbzFilter +import org.koitharu.kotatsu.local.data.MangaIndex +import org.koitharu.kotatsu.local.data.MangaZip import org.koitharu.kotatsu.utils.AlphanumComparator import org.koitharu.kotatsu.utils.ext.longHashCode import org.koitharu.kotatsu.utils.ext.readText @@ -23,14 +24,19 @@ import java.util.zip.ZipFile class LocalMangaRepository(private val context: Context) : MangaRepository { + private val filenameFilter = CbzFilter() + override suspend fun getList( offset: Int, query: String?, sortOrder: SortOrder?, tag: MangaTag? ): List { + require(offset == 0) { + "LocalMangaRepository does not support pagination" + } val files = getAvailableStorageDirs(context) - .flatMap { x -> x.listFiles(CbzFilter())?.toList().orEmpty() } + .flatMap { x -> x.listFiles(filenameFilter)?.toList().orEmpty() } return files.mapNotNull { x -> safe { getFromFile(x) } } } diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/local/LocalListFragment.kt b/app/src/main/java/org/koitharu/kotatsu/local/ui/LocalListFragment.kt similarity index 79% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/local/LocalListFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/local/ui/LocalListFragment.kt index 85fac3dc3..fb153856b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/local/LocalListFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/local/ui/LocalListFragment.kt @@ -1,33 +1,41 @@ -package org.koitharu.kotatsu.ui.list.local +package org.koitharu.kotatsu.local.ui import android.content.ActivityNotFoundException import android.net.Uri +import android.os.Bundle import android.view.Menu import android.view.MenuInflater import android.view.MenuItem +import android.view.View import androidx.activity.result.ActivityResultCallback import androidx.activity.result.contract.ActivityResultContracts import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar import kotlinx.android.synthetic.main.fragment_list.* -import moxy.ktx.moxyPresenter +import org.koin.android.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.Manga -import org.koitharu.kotatsu.ui.list.MangaListFragment +import org.koitharu.kotatsu.list.ui.MangaListFragment import org.koitharu.kotatsu.utils.ext.ellipsize -import java.io.File -class LocalListFragment : MangaListFragment(), ActivityResultCallback { +class LocalListFragment : MangaListFragment(), ActivityResultCallback { - private val presenter by moxyPresenter(factory = ::LocalListPresenter) + override val viewModel by viewModel() private val importCall = registerForActivityResult( ActivityResultContracts.OpenDocument(), this ) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + viewModel.onMangaRemoved.observe(viewLifecycleOwner, ::onItemRemoved) + } + override fun onRequestMoreItems(offset: Int) { - presenter.loadList(offset) + if (offset == 0) { + viewModel.onRefresh() + } } override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { @@ -65,7 +73,7 @@ class LocalListFragment : MangaListFragment(), ActivityResultCallback override fun onActivityResult(result: Uri?) { if (result != null) { - presenter.importFile(context?.applicationContext ?: return, result) + viewModel.importFile(result) } } @@ -81,7 +89,7 @@ class LocalListFragment : MangaListFragment(), ActivityResultCallback .setTitle(R.string.delete_manga) .setMessage(getString(R.string.text_delete_local_manga, data.title)) .setPositiveButton(R.string.delete) { _, _ -> - presenter.delete(data) + viewModel.delete(data) } .setNegativeButton(android.R.string.cancel, null) .show() @@ -91,8 +99,7 @@ class LocalListFragment : MangaListFragment(), ActivityResultCallback } } - override fun onItemRemoved(item: Manga) { - super.onItemRemoved(item) + private fun onItemRemoved(item: Manga) { Snackbar.make( recyclerView, getString( R.string._s_deleted_from_local_storage, diff --git a/app/src/main/java/org/koitharu/kotatsu/local/ui/LocalListViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/local/ui/LocalListViewModel.kt new file mode 100644 index 000000000..ca94276f1 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/local/ui/LocalListViewModel.kt @@ -0,0 +1,84 @@ +package org.koitharu.kotatsu.local.ui + +import android.content.Context +import android.net.Uri +import android.os.Build +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.koitharu.kotatsu.core.exceptions.UnsupportedFileException +import org.koitharu.kotatsu.core.model.Manga +import org.koitharu.kotatsu.core.prefs.AppSettings +import org.koitharu.kotatsu.history.domain.HistoryRepository +import org.koitharu.kotatsu.list.ui.MangaListViewModel +import org.koitharu.kotatsu.local.domain.LocalMangaRepository +import org.koitharu.kotatsu.utils.MangaShortcut +import org.koitharu.kotatsu.utils.MediaStoreCompat +import org.koitharu.kotatsu.utils.SingleLiveEvent +import org.koitharu.kotatsu.utils.ext.safe +import org.koitharu.kotatsu.utils.ext.sub +import java.io.IOException + +class LocalListViewModel( + private val repository: LocalMangaRepository, + private val historyRepository: HistoryRepository, + private val settings: AppSettings, + private val context: Context +) : MangaListViewModel() { + + val onMangaRemoved = SingleLiveEvent() + + init { + loadList() + } + + fun onRefresh() { + loadList() + } + + fun importFile(uri: Uri) { + launchLoadingJob { + val contentResolver = context.contentResolver + val list = withContext(Dispatchers.Default) { + val name = MediaStoreCompat.getName(contentResolver, uri) + ?: throw IOException("Cannot fetch name from uri: $uri") + if (!LocalMangaRepository.isFileSupported(name)) { + throw UnsupportedFileException("Unsupported file on $uri") + } + val dest = settings.getStorageDir(context)?.sub(name) + ?: throw IOException("External files dir unavailable") + contentResolver.openInputStream(uri)?.use { source -> + dest.outputStream().use { output -> + source.copyTo(output) + } + } ?: throw IOException("Cannot open input stream: $uri") + repository.getList(0) + } + content.value = list + } + } + + fun delete(manga: Manga) { + launchJob { + withContext(Dispatchers.Default) { + val original = repository.getRemoteManga(manga) + repository.delete(manga) || throw IOException("Unable to delete file") + safe { + historyRepository.deleteOrSwap(manga, original) + } + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { + MangaShortcut(manga).removeAppShortcut(context) + } + onMangaRemoved.call(manga) + } + } + + private fun loadList() { + launchLoadingJob { + val list = withContext(Dispatchers.Default) { + repository.getList(0) + } + content.value = list + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/main/MainModule.kt b/app/src/main/java/org/koitharu/kotatsu/main/MainModule.kt new file mode 100644 index 000000000..53f0204ad --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/main/MainModule.kt @@ -0,0 +1,12 @@ +package org.koitharu.kotatsu.main + +import org.koin.android.viewmodel.dsl.viewModel +import org.koin.dsl.module +import org.koitharu.kotatsu.main.ui.MainViewModel +import org.koitharu.kotatsu.main.ui.protect.ProtectViewModel + +val mainModule + get() = module { + viewModel { MainViewModel(get()) } + viewModel { ProtectViewModel(get()) } + } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/MainActivity.kt b/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt similarity index 82% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/MainActivity.kt rename to app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt index a2396d703..1b0e62717 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/MainActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.list +package org.koitharu.kotatsu.main.ui import android.app.ActivityOptions import android.content.SharedPreferences @@ -17,34 +17,34 @@ import androidx.swiperefreshlayout.widget.CircularProgressDrawable import com.google.android.material.navigation.NavigationView import com.google.android.material.snackbar.Snackbar import kotlinx.android.synthetic.main.activity_main.* -import moxy.ktx.moxyPresenter import org.koin.android.ext.android.inject +import org.koin.android.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.domain.MangaProviderFactory +import org.koitharu.kotatsu.base.ui.BaseActivity import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.core.prefs.AppSection import org.koitharu.kotatsu.core.prefs.AppSettings -import org.koitharu.kotatsu.domain.MangaProviderFactory -import org.koitharu.kotatsu.ui.base.BaseActivity -import org.koitharu.kotatsu.ui.list.favourites.FavouritesContainerFragment -import org.koitharu.kotatsu.ui.list.feed.FeedFragment -import org.koitharu.kotatsu.ui.list.history.HistoryListFragment -import org.koitharu.kotatsu.ui.list.local.LocalListFragment -import org.koitharu.kotatsu.ui.list.remote.RemoteListFragment -import org.koitharu.kotatsu.ui.reader.ReaderActivity -import org.koitharu.kotatsu.ui.reader.ReaderState -import org.koitharu.kotatsu.ui.search.SearchHelper -import org.koitharu.kotatsu.ui.settings.AppUpdateChecker -import org.koitharu.kotatsu.ui.settings.SettingsActivity -import org.koitharu.kotatsu.ui.tracker.TrackWorker -import org.koitharu.kotatsu.ui.utils.protect.AppProtectHelper +import org.koitharu.kotatsu.favourites.ui.FavouritesContainerFragment +import org.koitharu.kotatsu.history.ui.HistoryListFragment +import org.koitharu.kotatsu.local.ui.LocalListFragment +import org.koitharu.kotatsu.main.ui.protect.AppProtectHelper +import org.koitharu.kotatsu.reader.ui.ReaderActivity +import org.koitharu.kotatsu.reader.ui.ReaderState +import org.koitharu.kotatsu.remotelist.ui.RemoteListFragment +import org.koitharu.kotatsu.search.ui.SearchHelper +import org.koitharu.kotatsu.settings.AppUpdateChecker +import org.koitharu.kotatsu.settings.SettingsActivity +import org.koitharu.kotatsu.tracker.ui.FeedFragment +import org.koitharu.kotatsu.tracker.work.TrackWorker import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.utils.ext.resolveDp import java.io.Closeable class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedListener, - SharedPreferences.OnSharedPreferenceChangeListener, MainView, View.OnClickListener { + SharedPreferences.OnSharedPreferenceChangeListener, View.OnClickListener { - private val presenter by moxyPresenter(factory = ::MainPresenter) + private val viewModel by viewModel() private val settings by inject() private lateinit var drawerToggle: ActionBarDrawerToggle @@ -77,6 +77,10 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList } TrackWorker.setup(applicationContext) AppUpdateChecker(this).launchIfNeeded() + + viewModel.onOpenReader.observe(this, ::onOpenReader) + viewModel.onError.observe(this, ::onError) + viewModel.isLoading.observe(this, ::onLoadingStateChanged) } override fun onDestroy() { @@ -121,7 +125,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList override fun onClick(v: View) { when (v.id) { - R.id.fab -> presenter.openLastReader() + R.id.fab -> viewModel.openLastReader() } } @@ -156,7 +160,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList return true } - override fun onOpenReader(state: ReaderState) { + private fun onOpenReader(state: ReaderState) { val options = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { ActivityOptions.makeClipRevealAnimation( fab, 0, 0, fab.measuredWidth, fab.measuredHeight @@ -169,11 +173,11 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList startActivity(ReaderActivity.newIntent(this, state), options?.toBundle()) } - override fun onError(e: Throwable) { + private fun onError(e: Throwable) { Snackbar.make(container, e.getDisplayMessage(resources), Snackbar.LENGTH_SHORT).show() } - override fun onLoadingStateChanged(isLoading: Boolean) { + private fun onLoadingStateChanged(isLoading: Boolean) { fab.isEnabled = !isLoading if (isLoading) { fab.setImageDrawable(CircularProgressDrawable(this).also { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/MainPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/main/ui/MainViewModel.kt similarity index 50% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/MainPresenter.kt rename to app/src/main/java/org/koitharu/kotatsu/main/ui/MainViewModel.kt index 4bcd8b9b6..6b4e8d799 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/MainPresenter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/main/ui/MainViewModel.kt @@ -1,16 +1,16 @@ -package org.koitharu.kotatsu.ui.list +package org.koitharu.kotatsu.main.ui -import moxy.InjectViewState -import org.koin.core.component.inject +import org.koitharu.kotatsu.base.ui.BaseViewModel import org.koitharu.kotatsu.core.exceptions.EmptyHistoryException -import org.koitharu.kotatsu.domain.history.HistoryRepository -import org.koitharu.kotatsu.ui.base.BasePresenter -import org.koitharu.kotatsu.ui.reader.ReaderState +import org.koitharu.kotatsu.history.domain.HistoryRepository +import org.koitharu.kotatsu.reader.ui.ReaderState +import org.koitharu.kotatsu.utils.SingleLiveEvent -@InjectViewState -class MainPresenter : BasePresenter() { +class MainViewModel( + private val historyRepository: HistoryRepository +) : BaseViewModel() { - private val historyRepository by inject() + val onOpenReader = SingleLiveEvent() fun openLastReader() { launchLoadingJob { @@ -21,7 +21,7 @@ class MainPresenter : BasePresenter() { manga.source.repository.getDetails(manga), history.chapterId, history.page, history.scroll ) - viewState.onOpenReader(state) + onOpenReader.call(state) } } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/utils/protect/AppProtectHelper.kt b/app/src/main/java/org/koitharu/kotatsu/main/ui/protect/AppProtectHelper.kt similarity index 89% rename from app/src/main/java/org/koitharu/kotatsu/ui/utils/protect/AppProtectHelper.kt rename to app/src/main/java/org/koitharu/kotatsu/main/ui/protect/AppProtectHelper.kt index 9b92cacb4..be8ba3cff 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/utils/protect/AppProtectHelper.kt +++ b/app/src/main/java/org/koitharu/kotatsu/main/ui/protect/AppProtectHelper.kt @@ -1,11 +1,11 @@ -package org.koitharu.kotatsu.ui.utils.protect +package org.koitharu.kotatsu.main.ui.protect import android.app.Activity import android.content.Intent import org.koin.core.component.KoinComponent import org.koin.core.component.inject import org.koitharu.kotatsu.core.prefs.AppSettings -import org.koitharu.kotatsu.ui.list.MainActivity +import org.koitharu.kotatsu.main.ui.MainActivity object AppProtectHelper : KoinComponent { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/utils/protect/ProtectActivity.kt b/app/src/main/java/org/koitharu/kotatsu/main/ui/protect/ProtectActivity.kt similarity index 70% rename from app/src/main/java/org/koitharu/kotatsu/ui/utils/protect/ProtectActivity.kt rename to app/src/main/java/org/koitharu/kotatsu/main/ui/protect/ProtectActivity.kt index 5fa104455..f98e013d1 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/utils/protect/ProtectActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/main/ui/protect/ProtectActivity.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.utils.protect +package org.koitharu.kotatsu.main.ui.protect import android.content.Context import android.content.Intent @@ -11,14 +11,14 @@ import android.view.MenuItem import android.view.inputmethod.EditorInfo import android.widget.TextView import kotlinx.android.synthetic.main.activity_protect.* -import moxy.ktx.moxyPresenter +import org.koin.android.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.ui.base.BaseActivity +import org.koitharu.kotatsu.base.ui.BaseActivity import org.koitharu.kotatsu.utils.ext.getDisplayMessage -class ProtectActivity : BaseActivity(), ProtectView, TextView.OnEditorActionListener, TextWatcher { +class ProtectActivity : BaseActivity(), TextView.OnEditorActionListener, TextWatcher { - private val presenter by moxyPresenter(factory = ::ProtectPresenter) + private val viewModel by viewModel() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -29,6 +29,10 @@ class ProtectActivity : BaseActivity(), ProtectView, TextView.OnEditorActionList setDisplayHomeAsUpEnabled(true) setHomeAsUpIndicator(R.drawable.ic_cross) } + + viewModel.onError.observe(this, this::onError) + viewModel.isLoading.observe(this, this::onLoadingStateChanged) + viewModel.onUnlockSuccess.observe(this, this::onUnlockSuccess) } override fun onCreateOptionsMenu(menu: Menu?): Boolean { @@ -38,7 +42,7 @@ class ProtectActivity : BaseActivity(), ProtectView, TextView.OnEditorActionList override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) { R.id.action_done -> { - presenter.tryUnlock(edit_password.text?.toString().orEmpty()) + viewModel.tryUnlock(edit_password.text?.toString().orEmpty()) true } else -> super.onOptionsItemSelected(item) @@ -46,7 +50,7 @@ class ProtectActivity : BaseActivity(), ProtectView, TextView.OnEditorActionList override fun onEditorAction(v: TextView?, actionId: Int, event: KeyEvent?): Boolean { return if (actionId == EditorInfo.IME_ACTION_DONE) { - presenter.tryUnlock(edit_password.text?.toString().orEmpty()) + viewModel.tryUnlock(edit_password.text?.toString().orEmpty()) true } else { false @@ -61,15 +65,15 @@ class ProtectActivity : BaseActivity(), ProtectView, TextView.OnEditorActionList layout_password.error = null } - override fun onUnlockSuccess() { + private fun onUnlockSuccess(unit: Unit) { AppProtectHelper.unlock(this) } - override fun onError(e: Throwable) { + private fun onError(e: Throwable) { layout_password.error = e.getDisplayMessage(resources) } - override fun onLoadingStateChanged(isLoading: Boolean) { + private fun onLoadingStateChanged(isLoading: Boolean) { layout_password.isEnabled = !isLoading } diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/utils/protect/ProtectPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/main/ui/protect/ProtectViewModel.kt similarity index 64% rename from app/src/main/java/org/koitharu/kotatsu/ui/utils/protect/ProtectPresenter.kt rename to app/src/main/java/org/koitharu/kotatsu/main/ui/protect/ProtectViewModel.kt index 51d404adb..3957fa797 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/utils/protect/ProtectPresenter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/main/ui/protect/ProtectViewModel.kt @@ -1,22 +1,24 @@ -package org.koitharu.kotatsu.ui.utils.protect +package org.koitharu.kotatsu.main.ui.protect import kotlinx.coroutines.delay -import org.koin.core.component.inject +import org.koitharu.kotatsu.base.ui.BaseViewModel import org.koitharu.kotatsu.core.exceptions.WrongPasswordException import org.koitharu.kotatsu.core.prefs.AppSettings -import org.koitharu.kotatsu.ui.base.BasePresenter +import org.koitharu.kotatsu.utils.SingleLiveEvent import org.koitharu.kotatsu.utils.ext.md5 -class ProtectPresenter : BasePresenter() { +class ProtectViewModel( + private val settings: AppSettings +) : BaseViewModel() { - private val settings by inject() + val onUnlockSuccess = SingleLiveEvent() fun tryUnlock(password: String) { launchLoadingJob { val passwordHash = password.md5() val appPasswordHash = settings.appPassword if (passwordHash == appPasswordHash) { - viewState.onUnlockSuccess() + onUnlockSuccess.call(Unit) } else { delay(PASSWORD_COMPARE_DELAY) throw WrongPasswordException() diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ReaderModule.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ReaderModule.kt new file mode 100644 index 000000000..e3b8b5eb1 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ReaderModule.kt @@ -0,0 +1,16 @@ +package org.koitharu.kotatsu.reader + +import org.koin.android.viewmodel.dsl.viewModel +import org.koin.dsl.module +import org.koitharu.kotatsu.base.domain.MangaDataRepository +import org.koitharu.kotatsu.local.data.PagesCache +import org.koitharu.kotatsu.reader.ui.ReaderViewModel + +val readerModule + get() = module { + + single { MangaDataRepository(get()) } + single { PagesCache(get()) } + + viewModel { ReaderViewModel(get(), get()) } + } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/ChaptersDialog.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ChaptersDialog.kt similarity index 91% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/ChaptersDialog.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/ChaptersDialog.kt index c99be2c1b..7aca1935d 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/ChaptersDialog.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ChaptersDialog.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.reader +package org.koitharu.kotatsu.reader.ui import android.os.Bundle import android.view.View @@ -9,10 +9,10 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import kotlinx.android.synthetic.main.dialog_chapters.* import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.AlertDialogFragment +import org.koitharu.kotatsu.base.ui.list.OnRecyclerItemClickListener import org.koitharu.kotatsu.core.model.MangaChapter -import org.koitharu.kotatsu.ui.base.AlertDialogFragment -import org.koitharu.kotatsu.ui.base.list.OnRecyclerItemClickListener -import org.koitharu.kotatsu.ui.details.ChaptersAdapter +import org.koitharu.kotatsu.details.ui.ChaptersAdapter import org.koitharu.kotatsu.utils.ext.withArgs class ChaptersDialog : AlertDialogFragment(R.layout.dialog_chapters), diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/PageLoader.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/PageLoader.kt similarity index 96% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/PageLoader.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/PageLoader.kt index d369c5618..7c42c05da 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/PageLoader.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/PageLoader.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.reader +package org.koitharu.kotatsu.reader.ui import android.graphics.Bitmap import android.graphics.BitmapFactory @@ -11,7 +11,7 @@ import okhttp3.OkHttpClient import okhttp3.Request import org.koin.core.component.KoinComponent import org.koin.core.component.inject -import org.koitharu.kotatsu.core.local.PagesCache +import org.koitharu.kotatsu.local.data.PagesCache import org.koitharu.kotatsu.utils.CacheUtils import org.koitharu.kotatsu.utils.ext.await import java.io.File diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderActivity.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt similarity index 91% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderActivity.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt index adce552bc..c313e88aa 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt @@ -1,7 +1,6 @@ -package org.koitharu.kotatsu.ui.reader +package org.koitharu.kotatsu.reader.ui import android.Manifest -import android.annotation.SuppressLint import android.content.Context import android.content.Intent import android.content.SharedPreferences @@ -26,23 +25,22 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch -import moxy.MvpDelegate -import moxy.ktx.moxyPresenter import org.koin.android.ext.android.inject +import org.koin.android.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.BaseFullscreenActivity import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaChapter import org.koitharu.kotatsu.core.model.MangaHistory import org.koitharu.kotatsu.core.model.MangaPage import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.ReaderMode -import org.koitharu.kotatsu.ui.base.BaseFullscreenActivity -import org.koitharu.kotatsu.ui.reader.base.AbstractReader -import org.koitharu.kotatsu.ui.reader.reversed.ReversedReaderFragment -import org.koitharu.kotatsu.ui.reader.standard.PagerReaderFragment -import org.koitharu.kotatsu.ui.reader.thumbnails.OnPageSelectListener -import org.koitharu.kotatsu.ui.reader.thumbnails.PagesThumbnailsSheet -import org.koitharu.kotatsu.ui.reader.wetoon.WebtoonReaderFragment +import org.koitharu.kotatsu.reader.ui.base.AbstractReader +import org.koitharu.kotatsu.reader.ui.reversed.ReversedReaderFragment +import org.koitharu.kotatsu.reader.ui.standard.PagerReaderFragment +import org.koitharu.kotatsu.reader.ui.thumbnails.OnPageSelectListener +import org.koitharu.kotatsu.reader.ui.thumbnails.PagesThumbnailsSheet +import org.koitharu.kotatsu.reader.ui.wetoon.WebtoonReaderFragment import org.koitharu.kotatsu.utils.GridTouchHelper import org.koitharu.kotatsu.utils.MangaShortcut import org.koitharu.kotatsu.utils.ScreenOrientationHelper @@ -50,12 +48,12 @@ import org.koitharu.kotatsu.utils.ShareHelper import org.koitharu.kotatsu.utils.anim.Motion import org.koitharu.kotatsu.utils.ext.* -class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnChapterChangeListener, +class ReaderActivity : BaseFullscreenActivity(), ChaptersDialog.OnChapterChangeListener, GridTouchHelper.OnGridTouchListener, OnPageSelectListener, ReaderConfigDialog.Callback, ReaderListener, SharedPreferences.OnSharedPreferenceChangeListener, ActivityResultCallback, OnApplyWindowInsetsListener { - private val presenter by moxyPresenter(factory = ::ReaderPresenter) + private val viewModel by viewModel() private val settings by inject() lateinit var state: ReaderState @@ -102,17 +100,21 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh toolbar_bottom.menu.findItem(R.id.action_screen_rotate).isVisible = !it }.launchIn(lifecycleScope) - if (savedInstanceState?.containsKey(MvpDelegate.MOXY_DELEGATE_TAGS_KEY) != true) { - presenter.init(state.manga) + if (savedInstanceState == null) { + viewModel.init(state.manga) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { GlobalScope.launch(Dispatchers.Main + IgnoreErrors) { MangaShortcut(state.manga).addAppShortcut(applicationContext) } } } + + viewModel.onError.observe(this, this::onError) + viewModel.reader.observe(this) { (manga, mode) -> onInitReader(manga, mode) } + viewModel.onPageSaved.observe(this, this::onPageSaved) } - override fun onInitReader(manga: Manga, mode: ReaderMode) { + private fun onInitReader(manga: Manga, mode: ReaderMode) { val currentReader = reader when (mode) { ReaderMode.WEBTOON -> if (currentReader !is WebtoonReaderFragment) { @@ -226,7 +228,7 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh override fun onActivityResult(result: Boolean) { if (result) { - presenter.savePage( + viewModel.savePage( resolver = contentResolver, page = reader?.currentPage ?: return ) @@ -235,7 +237,7 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh override fun saveState(chapterId: Long, page: Int, scroll: Int) { state = state.copy(chapterId = chapterId, page = page, scroll = scroll) - ReaderPresenter.saveState(state) + ReaderViewModel.saveState(state) } override fun onLoadingStateChanged(isLoading: Boolean) { @@ -343,11 +345,10 @@ class ReaderActivity : BaseFullscreenActivity(), ReaderView, ChaptersDialog.OnCh override fun onReaderModeChanged(mode: ReaderMode) { //TODO save state - presenter.setMode(state.manga, mode) + viewModel.setMode(state.manga, mode) } - @SuppressLint("ShowToast") - override fun onPageSaved(uri: Uri?) { + private fun onPageSaved(uri: Uri?) { if (uri != null) { Snackbar.make(container, R.string.page_saved, Snackbar.LENGTH_LONG) .setAnchorView(appbar_bottom) diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderConfigDialog.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderConfigDialog.kt similarity index 95% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderConfigDialog.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderConfigDialog.kt index d0c9f4265..2afd7ae54 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderConfigDialog.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderConfigDialog.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.reader +package org.koitharu.kotatsu.reader.ui import android.os.Bundle import android.view.View @@ -7,8 +7,8 @@ import androidx.fragment.app.FragmentManager import kotlinx.android.synthetic.main.dialog_list_mode.button_ok import kotlinx.android.synthetic.main.dialog_reader_config.* import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.AlertDialogFragment import org.koitharu.kotatsu.core.prefs.ReaderMode -import org.koitharu.kotatsu.ui.base.AlertDialogFragment import org.koitharu.kotatsu.utils.ext.withArgs class ReaderConfigDialog : AlertDialogFragment(R.layout.dialog_reader_config), diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderListener.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderListener.kt similarity index 52% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderListener.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderListener.kt index 6a98189fc..777bd8c48 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderListener.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderListener.kt @@ -1,11 +1,14 @@ -package org.koitharu.kotatsu.ui.reader +package org.koitharu.kotatsu.reader.ui import org.koitharu.kotatsu.core.model.MangaChapter -import org.koitharu.kotatsu.ui.base.BaseMvpView -interface ReaderListener : BaseMvpView { +interface ReaderListener { fun onPageChanged(chapter: MangaChapter, page: Int) fun saveState(chapterId: Long, page: Int, scroll: Int) + + fun onLoadingStateChanged(isLoading: Boolean) + + fun onError(error: Throwable) } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderState.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderState.kt similarity index 91% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderState.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderState.kt index fe7c1edaa..f3ebae266 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderState.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderState.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.reader +package org.koitharu.kotatsu.reader.ui import android.os.Parcelable import kotlinx.android.parcel.IgnoredOnParcel diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt new file mode 100644 index 000000000..4c24311b0 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderViewModel.kt @@ -0,0 +1,119 @@ +package org.koitharu.kotatsu.reader.ui + +import android.content.ContentResolver +import android.net.Uri +import android.webkit.URLUtil +import androidx.lifecycle.MutableLiveData +import kotlinx.coroutines.CancellationException +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import okhttp3.OkHttpClient +import okhttp3.Request +import org.koin.core.component.KoinComponent +import org.koin.core.component.get +import org.koitharu.kotatsu.base.domain.MangaDataRepository +import org.koitharu.kotatsu.base.domain.MangaUtils +import org.koitharu.kotatsu.base.ui.BaseViewModel +import org.koitharu.kotatsu.core.model.Manga +import org.koitharu.kotatsu.core.model.MangaPage +import org.koitharu.kotatsu.core.prefs.AppSettings +import org.koitharu.kotatsu.core.prefs.ReaderMode +import org.koitharu.kotatsu.history.domain.HistoryRepository +import org.koitharu.kotatsu.utils.MediaStoreCompat +import org.koitharu.kotatsu.utils.SingleLiveEvent +import org.koitharu.kotatsu.utils.ext.* + +class ReaderViewModel( + private val dataRepository: MangaDataRepository, + private val settings: AppSettings +) : BaseViewModel() { + + val reader = MutableLiveData>() + val onPageSaved = SingleLiveEvent() + + fun init(manga: Manga) { + launchLoadingJob { + val mode = withContext(Dispatchers.Default) { + val repo = manga.source.repository + val chapter = + (manga.chapters ?: throw RuntimeException("Chapters is null")).random() + var mode = dataRepository.getReaderMode(manga.id) + if (mode == null) { + val pages = repo.getPages(chapter) + val isWebtoon = MangaUtils.determineMangaIsWebtoon(pages) + mode = getReaderMode(isWebtoon) + if (isWebtoon != null) { + dataRepository.savePreferences( + manga = manga, + mode = mode + ) + } + } + mode + } + reader.value = manga to mode + } + } + + fun setMode(manga: Manga, mode: ReaderMode) { + launchJob { + dataRepository.savePreferences( + manga = manga, + mode = mode + ) + reader.value = manga to mode + } + } + + fun savePage(resolver: ContentResolver, page: MangaPage) { + launchJob { + withContext(Dispatchers.Default) { + try { + val repo = page.source.repository + val url = repo.getPageFullUrl(page) + val request = Request.Builder() + .url(url) + .get() + .build() + val uri = get().newCall(request).await().use { response -> + val fileName = + URLUtil.guessFileName( + url, + response.contentDisposition, + response.mimeType + ) + MediaStoreCompat.insertImage(resolver, fileName) { + response.body!!.byteStream().copyTo(it) + } + } + onPageSaved.postCall(uri) + } catch (e: CancellationException) { + } catch (e: Exception) { + onPageSaved.postCall(null) + } + } + } + } + + private fun getReaderMode(isWebtoon: Boolean?) = when { + isWebtoon == true -> ReaderMode.WEBTOON + settings.isPreferRtlReader -> ReaderMode.REVERSED + else -> ReaderMode.STANDARD + } + + companion object : KoinComponent { + + fun saveState(state: ReaderState) { + processLifecycleScope.launch(Dispatchers.Default + IgnoreErrors) { + get().addOrUpdate( + manga = state.manga, + chapterId = state.chapterId, + page = state.page, + scroll = state.scroll + ) + } + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/SimpleSettingsActivity.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/SimpleSettingsActivity.kt similarity index 77% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/SimpleSettingsActivity.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/SimpleSettingsActivity.kt index 1b832cd9f..ea02b4c0c 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/SimpleSettingsActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/SimpleSettingsActivity.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.reader +package org.koitharu.kotatsu.reader.ui import android.content.Context import android.content.Intent @@ -6,10 +6,10 @@ import android.os.Bundle import androidx.fragment.app.commit import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.ui.base.BaseActivity -import org.koitharu.kotatsu.ui.settings.MainSettingsFragment -import org.koitharu.kotatsu.ui.settings.NetworkSettingsFragment -import org.koitharu.kotatsu.ui.settings.ReaderSettingsFragment +import org.koitharu.kotatsu.base.ui.BaseActivity +import org.koitharu.kotatsu.settings.MainSettingsFragment +import org.koitharu.kotatsu.settings.NetworkSettingsFragment +import org.koitharu.kotatsu.settings.ReaderSettingsFragment class SimpleSettingsActivity : BaseActivity() { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/base/AbstractReader.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/base/AbstractReader.kt similarity index 96% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/base/AbstractReader.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/base/AbstractReader.kt index 1421b80ef..33678367a 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/base/AbstractReader.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/base/AbstractReader.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.reader.base +package org.koitharu.kotatsu.reader.ui.base import android.content.Context import android.os.Bundle @@ -10,13 +10,13 @@ import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import org.koitharu.kotatsu.base.ui.BaseFragment import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaChapter import org.koitharu.kotatsu.core.model.MangaPage -import org.koitharu.kotatsu.ui.base.BaseFragment -import org.koitharu.kotatsu.ui.reader.PageLoader -import org.koitharu.kotatsu.ui.reader.ReaderListener -import org.koitharu.kotatsu.ui.reader.ReaderState +import org.koitharu.kotatsu.reader.ui.PageLoader +import org.koitharu.kotatsu.reader.ui.ReaderListener +import org.koitharu.kotatsu.reader.ui.ReaderState import org.koitharu.kotatsu.utils.ext.associateByLong import org.koitharu.kotatsu.utils.ext.viewLifecycleScope diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/base/BaseReaderAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/base/BaseReaderAdapter.kt similarity index 92% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/base/BaseReaderAdapter.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/base/BaseReaderAdapter.kt index b90e752ca..67a54c62d 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/base/BaseReaderAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/base/BaseReaderAdapter.kt @@ -1,8 +1,8 @@ -package org.koitharu.kotatsu.ui.reader.base +package org.koitharu.kotatsu.reader.ui.base import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView -import org.koitharu.kotatsu.ui.base.list.BaseViewHolder +import org.koitharu.kotatsu.base.ui.list.BaseViewHolder abstract class BaseReaderAdapter(protected val pages: List) : RecyclerView.Adapter>() { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/base/OnBoundsScrollListener.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/base/OnBoundsScrollListener.kt similarity index 65% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/base/OnBoundsScrollListener.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/base/OnBoundsScrollListener.kt index 03054e3ef..44afcd6a2 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/base/OnBoundsScrollListener.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/base/OnBoundsScrollListener.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.reader.base +package org.koitharu.kotatsu.reader.ui.base interface OnBoundsScrollListener { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/base/PageHolderDelegate.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/base/PageHolderDelegate.kt similarity index 96% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/base/PageHolderDelegate.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/base/PageHolderDelegate.kt index 5d98f5abd..5c96fb65e 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/base/PageHolderDelegate.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/base/PageHolderDelegate.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.reader.base +package org.koitharu.kotatsu.reader.ui.base import android.net.Uri import androidx.core.net.toUri @@ -8,7 +8,7 @@ import org.koin.core.component.inject import org.koitharu.kotatsu.core.model.MangaPage import org.koitharu.kotatsu.core.model.ZoomMode import org.koitharu.kotatsu.core.prefs.AppSettings -import org.koitharu.kotatsu.ui.reader.PageLoader +import org.koitharu.kotatsu.reader.ui.PageLoader import org.koitharu.kotatsu.utils.ext.launchAfter import org.koitharu.kotatsu.utils.ext.launchInstead import java.io.File diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/base/ReaderPage.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/base/ReaderPage.kt similarity index 93% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/base/ReaderPage.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/base/ReaderPage.kt index 5f1807f68..b73387360 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/base/ReaderPage.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/base/ReaderPage.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.reader.base +package org.koitharu.kotatsu.reader.ui.base import android.os.Parcelable import kotlinx.android.parcel.Parcelize diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/reversed/ReversedPageAnimTransformer.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/reversed/ReversedPageAnimTransformer.kt similarity index 93% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/reversed/ReversedPageAnimTransformer.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/reversed/ReversedPageAnimTransformer.kt index 3404f0529..f572c4616 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/reversed/ReversedPageAnimTransformer.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/reversed/ReversedPageAnimTransformer.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.reader.reversed +package org.koitharu.kotatsu.reader.ui.reversed import android.view.View import androidx.viewpager2.widget.ViewPager2 diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/reversed/ReversedPageHolder.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/reversed/ReversedPageHolder.kt similarity index 89% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/reversed/ReversedPageHolder.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/reversed/ReversedPageHolder.kt index c21253cd2..233ab81ef 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/reversed/ReversedPageHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/reversed/ReversedPageHolder.kt @@ -1,12 +1,12 @@ -package org.koitharu.kotatsu.ui.reader.reversed +package org.koitharu.kotatsu.reader.ui.reversed import android.graphics.PointF import android.view.ViewGroup import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView import kotlinx.android.synthetic.main.item_page.* import org.koitharu.kotatsu.core.model.ZoomMode -import org.koitharu.kotatsu.ui.reader.PageLoader -import org.koitharu.kotatsu.ui.reader.standard.PageHolder +import org.koitharu.kotatsu.reader.ui.PageLoader +import org.koitharu.kotatsu.reader.ui.standard.PageHolder class ReversedPageHolder(parent: ViewGroup, loader: PageLoader) : PageHolder(parent, loader) { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/reversed/ReversedPagesAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/reversed/ReversedPagesAdapter.kt similarity index 78% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/reversed/ReversedPagesAdapter.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/reversed/ReversedPagesAdapter.kt index c4de634fd..620957714 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/reversed/ReversedPagesAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/reversed/ReversedPagesAdapter.kt @@ -1,10 +1,10 @@ -package org.koitharu.kotatsu.ui.reader.reversed +package org.koitharu.kotatsu.reader.ui.reversed import android.view.ViewGroup -import org.koitharu.kotatsu.ui.base.list.BaseViewHolder -import org.koitharu.kotatsu.ui.reader.PageLoader -import org.koitharu.kotatsu.ui.reader.base.BaseReaderAdapter -import org.koitharu.kotatsu.ui.reader.base.ReaderPage +import org.koitharu.kotatsu.base.ui.list.BaseViewHolder +import org.koitharu.kotatsu.reader.ui.PageLoader +import org.koitharu.kotatsu.reader.ui.base.BaseReaderAdapter +import org.koitharu.kotatsu.reader.ui.base.ReaderPage class ReversedPagesAdapter( pages: List, diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/reversed/ReversedReaderFragment.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/reversed/ReversedReaderFragment.kt similarity index 86% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/reversed/ReversedReaderFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/reversed/ReversedReaderFragment.kt index 2bed0925a..5fce5dd4c 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/reversed/ReversedReaderFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/reversed/ReversedReaderFragment.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.reader.reversed +package org.koitharu.kotatsu.reader.ui.reversed import android.content.Context import android.content.SharedPreferences @@ -8,12 +8,12 @@ import kotlinx.android.synthetic.main.fragment_reader_standard.* import org.koin.android.ext.android.inject import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.prefs.AppSettings -import org.koitharu.kotatsu.ui.reader.ReaderState -import org.koitharu.kotatsu.ui.reader.base.AbstractReader -import org.koitharu.kotatsu.ui.reader.base.BaseReaderAdapter -import org.koitharu.kotatsu.ui.reader.base.ReaderPage -import org.koitharu.kotatsu.ui.reader.standard.PageAnimTransformer -import org.koitharu.kotatsu.ui.reader.standard.PagerPaginationListener +import org.koitharu.kotatsu.reader.ui.ReaderState +import org.koitharu.kotatsu.reader.ui.base.AbstractReader +import org.koitharu.kotatsu.reader.ui.base.BaseReaderAdapter +import org.koitharu.kotatsu.reader.ui.base.ReaderPage +import org.koitharu.kotatsu.reader.ui.standard.PageAnimTransformer +import org.koitharu.kotatsu.reader.ui.standard.PagerPaginationListener import org.koitharu.kotatsu.utils.ext.doOnPageChanged import org.koitharu.kotatsu.utils.ext.swapAdapter import org.koitharu.kotatsu.utils.ext.withArgs diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/standard/PageAnimTransformer.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/standard/PageAnimTransformer.kt similarity index 93% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/standard/PageAnimTransformer.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/standard/PageAnimTransformer.kt index 584f7cf64..6b8405327 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/standard/PageAnimTransformer.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/standard/PageAnimTransformer.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.reader.standard +package org.koitharu.kotatsu.reader.ui.standard import android.view.View import androidx.viewpager2.widget.ViewPager2 diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/standard/PageHolder.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/standard/PageHolder.kt similarity index 90% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/standard/PageHolder.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/standard/PageHolder.kt index 4d127639c..75725a5b5 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/standard/PageHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/standard/PageHolder.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.reader.standard +package org.koitharu.kotatsu.reader.ui.standard import android.graphics.PointF import android.net.Uri @@ -9,11 +9,11 @@ import com.davemorrissey.labs.subscaleview.ImageSource import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView import kotlinx.android.synthetic.main.item_page.* import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.list.BaseViewHolder import org.koitharu.kotatsu.core.model.ZoomMode -import org.koitharu.kotatsu.ui.base.list.BaseViewHolder -import org.koitharu.kotatsu.ui.reader.PageLoader -import org.koitharu.kotatsu.ui.reader.base.PageHolderDelegate -import org.koitharu.kotatsu.ui.reader.base.ReaderPage +import org.koitharu.kotatsu.reader.ui.PageLoader +import org.koitharu.kotatsu.reader.ui.base.PageHolderDelegate +import org.koitharu.kotatsu.reader.ui.base.ReaderPage import org.koitharu.kotatsu.utils.ext.getDisplayMessage open class PageHolder(parent: ViewGroup, loader: PageLoader) : diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/standard/PagerPaginationListener.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/standard/PagerPaginationListener.kt similarity index 87% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/standard/PagerPaginationListener.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/standard/PagerPaginationListener.kt index 7bb129036..d8bad45b1 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/standard/PagerPaginationListener.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/standard/PagerPaginationListener.kt @@ -1,8 +1,8 @@ -package org.koitharu.kotatsu.ui.reader.standard +package org.koitharu.kotatsu.reader.ui.standard import androidx.recyclerview.widget.RecyclerView import androidx.viewpager2.widget.ViewPager2 -import org.koitharu.kotatsu.ui.reader.base.OnBoundsScrollListener +import org.koitharu.kotatsu.reader.ui.base.OnBoundsScrollListener class PagerPaginationListener( private val adapter: RecyclerView.Adapter<*>, diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/standard/PagerReaderFragment.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/standard/PagerReaderFragment.kt similarity index 89% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/standard/PagerReaderFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/standard/PagerReaderFragment.kt index b327bef84..2ce317e4b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/standard/PagerReaderFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/standard/PagerReaderFragment.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.reader.standard +package org.koitharu.kotatsu.reader.ui.standard import android.content.Context import android.content.SharedPreferences @@ -8,10 +8,10 @@ import kotlinx.android.synthetic.main.fragment_reader_standard.* import org.koin.android.ext.android.inject import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.prefs.AppSettings -import org.koitharu.kotatsu.ui.reader.ReaderState -import org.koitharu.kotatsu.ui.reader.base.AbstractReader -import org.koitharu.kotatsu.ui.reader.base.BaseReaderAdapter -import org.koitharu.kotatsu.ui.reader.base.ReaderPage +import org.koitharu.kotatsu.reader.ui.ReaderState +import org.koitharu.kotatsu.reader.ui.base.AbstractReader +import org.koitharu.kotatsu.reader.ui.base.BaseReaderAdapter +import org.koitharu.kotatsu.reader.ui.base.ReaderPage import org.koitharu.kotatsu.utils.ext.doOnPageChanged import org.koitharu.kotatsu.utils.ext.swapAdapter import org.koitharu.kotatsu.utils.ext.withArgs diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/standard/PagesAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/standard/PagesAdapter.kt similarity index 51% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/standard/PagesAdapter.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/standard/PagesAdapter.kt index 084f057c6..0ba2ec6bd 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/standard/PagesAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/standard/PagesAdapter.kt @@ -1,9 +1,9 @@ -package org.koitharu.kotatsu.ui.reader.standard +package org.koitharu.kotatsu.reader.ui.standard import android.view.ViewGroup -import org.koitharu.kotatsu.ui.reader.PageLoader -import org.koitharu.kotatsu.ui.reader.base.BaseReaderAdapter -import org.koitharu.kotatsu.ui.reader.base.ReaderPage +import org.koitharu.kotatsu.reader.ui.PageLoader +import org.koitharu.kotatsu.reader.ui.base.BaseReaderAdapter +import org.koitharu.kotatsu.reader.ui.base.ReaderPage class PagesAdapter( pages: List, diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/thumbnails/OnPageSelectListener.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/OnPageSelectListener.kt similarity index 71% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/thumbnails/OnPageSelectListener.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/OnPageSelectListener.kt index f99bf76bf..57eb3645c 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/thumbnails/OnPageSelectListener.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/OnPageSelectListener.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.reader.thumbnails +package org.koitharu.kotatsu.reader.ui.thumbnails import org.koitharu.kotatsu.core.model.MangaPage diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/thumbnails/PageThumbnailHolder.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PageThumbnailHolder.kt similarity index 91% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/thumbnails/PageThumbnailHolder.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PageThumbnailHolder.kt index 47f7a1527..71048d6f0 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/thumbnails/PageThumbnailHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PageThumbnailHolder.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.reader.thumbnails +package org.koitharu.kotatsu.reader.ui.thumbnails import android.view.ViewGroup import androidx.core.net.toUri @@ -10,9 +10,9 @@ import kotlinx.android.synthetic.main.item_page_thumb.* import kotlinx.coroutines.* import org.koin.core.component.inject import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.core.local.PagesCache +import org.koitharu.kotatsu.base.ui.list.BaseViewHolder import org.koitharu.kotatsu.core.model.MangaPage -import org.koitharu.kotatsu.ui.base.list.BaseViewHolder +import org.koitharu.kotatsu.local.data.PagesCache import org.koitharu.kotatsu.utils.ext.IgnoreErrors class PageThumbnailHolder(parent: ViewGroup, private val scope: CoroutineScope) : diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/thumbnails/PagesThumbnailsAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PagesThumbnailsAdapter.kt similarity index 80% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/thumbnails/PagesThumbnailsAdapter.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PagesThumbnailsAdapter.kt index ea488ba02..1d5f78c51 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/thumbnails/PagesThumbnailsAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PagesThumbnailsAdapter.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.reader.thumbnails +package org.koitharu.kotatsu.reader.ui.thumbnails import android.view.ViewGroup import kotlinx.coroutines.CoroutineScope @@ -6,10 +6,10 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.DisposableHandle import kotlinx.coroutines.SupervisorJob import org.koin.core.component.inject -import org.koitharu.kotatsu.core.local.PagesCache +import org.koitharu.kotatsu.base.ui.list.BaseRecyclerAdapter +import org.koitharu.kotatsu.base.ui.list.OnRecyclerItemClickListener import org.koitharu.kotatsu.core.model.MangaPage -import org.koitharu.kotatsu.ui.base.list.BaseRecyclerAdapter -import org.koitharu.kotatsu.ui.base.list.OnRecyclerItemClickListener +import org.koitharu.kotatsu.local.data.PagesCache import kotlin.coroutines.CoroutineContext class PagesThumbnailsAdapter(onItemClickListener: OnRecyclerItemClickListener?) : diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/thumbnails/PagesThumbnailsSheet.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PagesThumbnailsSheet.kt similarity index 93% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/thumbnails/PagesThumbnailsSheet.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PagesThumbnailsSheet.kt index f47d85fdc..49e4c4ef8 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/thumbnails/PagesThumbnailsSheet.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PagesThumbnailsSheet.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.reader.thumbnails +package org.koitharu.kotatsu.reader.ui.thumbnails import android.os.Bundle import android.view.View @@ -9,10 +9,10 @@ import com.google.android.material.bottomsheet.BottomSheetDialog import kotlinx.android.synthetic.main.sheet_pages.* import kotlinx.coroutines.DisposableHandle import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.BaseBottomSheet +import org.koitharu.kotatsu.base.ui.list.OnRecyclerItemClickListener +import org.koitharu.kotatsu.base.ui.list.decor.SpacingItemDecoration import org.koitharu.kotatsu.core.model.MangaPage -import org.koitharu.kotatsu.ui.base.BaseBottomSheet -import org.koitharu.kotatsu.ui.base.list.OnRecyclerItemClickListener -import org.koitharu.kotatsu.ui.base.list.decor.SpacingItemDecoration import org.koitharu.kotatsu.utils.UiUtils import org.koitharu.kotatsu.utils.ext.resolveDp import org.koitharu.kotatsu.utils.ext.withArgs diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/wetoon/ListPaginationListener.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/ListPaginationListener.kt similarity index 90% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/wetoon/ListPaginationListener.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/ListPaginationListener.kt index 23d5ed3d2..7c1daccf3 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/wetoon/ListPaginationListener.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/ListPaginationListener.kt @@ -1,8 +1,8 @@ -package org.koitharu.kotatsu.ui.reader.wetoon +package org.koitharu.kotatsu.reader.ui.wetoon import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import org.koitharu.kotatsu.ui.reader.base.OnBoundsScrollListener +import org.koitharu.kotatsu.reader.ui.base.OnBoundsScrollListener class ListPaginationListener( private val offset: Int, diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/wetoon/WebtoonAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonAdapter.kt similarity index 51% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/wetoon/WebtoonAdapter.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonAdapter.kt index 7972b9d8c..52d8efc7e 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/wetoon/WebtoonAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonAdapter.kt @@ -1,9 +1,9 @@ -package org.koitharu.kotatsu.ui.reader.wetoon +package org.koitharu.kotatsu.reader.ui.wetoon import android.view.ViewGroup -import org.koitharu.kotatsu.ui.reader.PageLoader -import org.koitharu.kotatsu.ui.reader.base.BaseReaderAdapter -import org.koitharu.kotatsu.ui.reader.base.ReaderPage +import org.koitharu.kotatsu.reader.ui.PageLoader +import org.koitharu.kotatsu.reader.ui.base.BaseReaderAdapter +import org.koitharu.kotatsu.reader.ui.base.ReaderPage class WebtoonAdapter( pages: List, diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/wetoon/WebtoonFrameLayout.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonFrameLayout.kt similarity index 92% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/wetoon/WebtoonFrameLayout.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonFrameLayout.kt index a6f1ec906..506fe322f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/wetoon/WebtoonFrameLayout.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonFrameLayout.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.reader.wetoon +package org.koitharu.kotatsu.reader.ui.wetoon import android.content.Context import android.util.AttributeSet diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/wetoon/WebtoonHolder.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonHolder.kt similarity index 88% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/wetoon/WebtoonHolder.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonHolder.kt index acbc8c4a5..98d4ebe0e 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/wetoon/WebtoonHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonHolder.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.reader.wetoon +package org.koitharu.kotatsu.reader.ui.wetoon import android.net.Uri import android.view.View @@ -8,11 +8,11 @@ import com.davemorrissey.labs.subscaleview.ImageSource import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView import kotlinx.android.synthetic.main.item_page_webtoon.* import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.list.BaseViewHolder import org.koitharu.kotatsu.core.model.ZoomMode -import org.koitharu.kotatsu.ui.base.list.BaseViewHolder -import org.koitharu.kotatsu.ui.reader.PageLoader -import org.koitharu.kotatsu.ui.reader.base.PageHolderDelegate -import org.koitharu.kotatsu.ui.reader.base.ReaderPage +import org.koitharu.kotatsu.reader.ui.PageLoader +import org.koitharu.kotatsu.reader.ui.base.PageHolderDelegate +import org.koitharu.kotatsu.reader.ui.base.ReaderPage import org.koitharu.kotatsu.utils.ext.getDisplayMessage diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/wetoon/WebtoonImageView.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonImageView.kt similarity index 96% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/wetoon/WebtoonImageView.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonImageView.kt index 9414818a6..fd8c21226 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/wetoon/WebtoonImageView.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonImageView.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.reader.wetoon +package org.koitharu.kotatsu.reader.ui.wetoon import android.content.Context import android.graphics.PointF diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/wetoon/WebtoonReaderFragment.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonReaderFragment.kt similarity index 89% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/wetoon/WebtoonReaderFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonReaderFragment.kt index bf5ba37d9..d78cf8fd9 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/wetoon/WebtoonReaderFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonReaderFragment.kt @@ -1,14 +1,14 @@ -package org.koitharu.kotatsu.ui.reader.wetoon +package org.koitharu.kotatsu.reader.ui.wetoon import android.os.Bundle import android.view.View import android.view.animation.AccelerateDecelerateInterpolator import kotlinx.android.synthetic.main.fragment_reader_webtoon.* import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.ui.reader.ReaderState -import org.koitharu.kotatsu.ui.reader.base.AbstractReader -import org.koitharu.kotatsu.ui.reader.base.BaseReaderAdapter -import org.koitharu.kotatsu.ui.reader.base.ReaderPage +import org.koitharu.kotatsu.reader.ui.ReaderState +import org.koitharu.kotatsu.reader.ui.base.AbstractReader +import org.koitharu.kotatsu.reader.ui.base.BaseReaderAdapter +import org.koitharu.kotatsu.reader.ui.base.ReaderPage import org.koitharu.kotatsu.utils.ext.doOnCurrentItemChanged import org.koitharu.kotatsu.utils.ext.findCenterViewPosition import org.koitharu.kotatsu.utils.ext.firstItem diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/wetoon/WebtoonRecyclerView.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonRecyclerView.kt similarity index 88% rename from app/src/main/java/org/koitharu/kotatsu/ui/reader/wetoon/WebtoonRecyclerView.kt rename to app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonRecyclerView.kt index e898f7637..1b9a42a29 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/wetoon/WebtoonRecyclerView.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/wetoon/WebtoonRecyclerView.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.reader.wetoon +package org.koitharu.kotatsu.reader.ui.wetoon import android.content.Context import android.util.AttributeSet @@ -48,7 +48,8 @@ class WebtoonRecyclerView @JvmOverloads constructor( if (consumedByChild < dy) { if (childCount > 1) { val nextChild = getChildAt(1) as WebtoonFrameLayout - val unconsumed = dy - consumedByChild - nextChild.top //will be consumed by scroll + val unconsumed = + dy - consumedByChild - nextChild.top //will be consumed by scroll if (unconsumed > 0) { consumedByChild += nextChild.dispatchVerticalScroll(unconsumed) } @@ -62,7 +63,8 @@ class WebtoonRecyclerView @JvmOverloads constructor( if (consumedByChild > dy) { if (childCount > 1) { val nextChild = getChildAt(childCount - 2) as WebtoonFrameLayout - val unconsumed = dy - consumedByChild + (height - nextChild.bottom) //will be consumed by scroll + val unconsumed = + dy - consumedByChild + (height - nextChild.bottom) //will be consumed by scroll if (unconsumed < 0) { consumedByChild += nextChild.dispatchVerticalScroll(unconsumed) } diff --git a/app/src/main/java/org/koitharu/kotatsu/remotelist/RemoteListModule.kt b/app/src/main/java/org/koitharu/kotatsu/remotelist/RemoteListModule.kt new file mode 100644 index 000000000..e806300e5 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/remotelist/RemoteListModule.kt @@ -0,0 +1,15 @@ +package org.koitharu.kotatsu.remotelist + +import org.koin.android.viewmodel.dsl.viewModel +import org.koin.core.qualifier.named +import org.koin.dsl.module +import org.koitharu.kotatsu.core.model.MangaSource +import org.koitharu.kotatsu.remotelist.ui.RemoteListViewModel + +val remoteListModule + get() = module { + + viewModel { (source: MangaSource) -> + RemoteListViewModel(get(named(source))) + } + } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/remote/RemoteListFragment.kt b/app/src/main/java/org/koitharu/kotatsu/remotelist/ui/RemoteListFragment.kt similarity index 73% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/remote/RemoteListFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/remotelist/ui/RemoteListFragment.kt index 698e5105a..5da26fa35 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/remote/RemoteListFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/remotelist/ui/RemoteListFragment.kt @@ -1,27 +1,28 @@ -package org.koitharu.kotatsu.ui.list.remote +package org.koitharu.kotatsu.remotelist.ui import android.view.Menu import android.view.MenuInflater import android.view.MenuItem -import moxy.ktx.moxyPresenter +import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.core.parameter.parametersOf import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.MangaFilter import org.koitharu.kotatsu.core.model.MangaSource -import org.koitharu.kotatsu.ui.list.MangaListFragment -import org.koitharu.kotatsu.ui.search.SearchActivity +import org.koitharu.kotatsu.list.ui.MangaListFragment +import org.koitharu.kotatsu.search.ui.SearchActivity import org.koitharu.kotatsu.utils.ext.parcelableArgument import org.koitharu.kotatsu.utils.ext.withArgs -class RemoteListFragment : MangaListFragment() { +class RemoteListFragment : MangaListFragment() { - private val presenter by moxyPresenter { - RemoteListPresenter(source) + override val viewModel by viewModel { + parametersOf(source) } private val source by parcelableArgument(ARG_SOURCE) override fun onRequestMoreItems(offset: Int) { - presenter.loadList(offset) + viewModel.loadList(offset) } override fun getTitle(): CharSequence? { @@ -29,7 +30,7 @@ class RemoteListFragment : MangaListFragment() { } override fun onFilterChanged(filter: MangaFilter) { - presenter.applyFilter(filter) + viewModel.applyFilter(filter) super.onFilterChanged(filter) } diff --git a/app/src/main/java/org/koitharu/kotatsu/remotelist/ui/RemoteListViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/remotelist/ui/RemoteListViewModel.kt new file mode 100644 index 000000000..474bfa280 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/remotelist/ui/RemoteListViewModel.kt @@ -0,0 +1,59 @@ +package org.koitharu.kotatsu.remotelist.ui + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.koitharu.kotatsu.BuildConfig +import org.koitharu.kotatsu.core.model.MangaFilter +import org.koitharu.kotatsu.core.parser.MangaRepository +import org.koitharu.kotatsu.list.ui.MangaFilterConfig +import org.koitharu.kotatsu.list.ui.MangaListViewModel + +class RemoteListViewModel( + private val repository: MangaRepository +) : MangaListViewModel() { + + private var appliedFilter: MangaFilter? = null + + init { + loadFilter() + } + + fun loadList(offset: Int) { + launchLoadingJob { + val list = withContext(Dispatchers.Default) { + repository.getList( + offset = offset, + sortOrder = appliedFilter?.sortOrder, + tag = appliedFilter?.tag + ) + } + if (offset == 0) { + content.value = list + } else { + content.value = content.value.orEmpty() + list + } + } + } + + fun applyFilter(newFilter: MangaFilter) { + appliedFilter = newFilter + content.value = emptyList() + loadList(0) + } + + private fun loadFilter() { + launchJob { + try { + val (sorts, tags) = withContext(Dispatchers.Default) { + repository.sortOrders.sortedBy { it.ordinal } to repository.getTags() + .sortedBy { it.title } + } + filter.value = MangaFilterConfig(sorts, tags, appliedFilter) + } catch (e: Exception) { + if (BuildConfig.DEBUG) { + e.printStackTrace() + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/search/SearchModule.kt b/app/src/main/java/org/koitharu/kotatsu/search/SearchModule.kt new file mode 100644 index 000000000..c8b764e34 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/search/SearchModule.kt @@ -0,0 +1,18 @@ +package org.koitharu.kotatsu.search + +import org.koin.android.viewmodel.dsl.viewModel +import org.koin.core.qualifier.named +import org.koin.dsl.module +import org.koitharu.kotatsu.core.model.MangaSource +import org.koitharu.kotatsu.search.domain.MangaSearchRepository +import org.koitharu.kotatsu.search.ui.SearchViewModel +import org.koitharu.kotatsu.search.ui.global.GlobalSearchViewModel + +val searchModule + get() = module { + + single { MangaSearchRepository() } + + viewModel { (source: MangaSource) -> SearchViewModel(get(named(source))) } + viewModel { GlobalSearchViewModel(get()) } + } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/MangaSearchRepository.kt b/app/src/main/java/org/koitharu/kotatsu/search/domain/MangaSearchRepository.kt similarity index 90% rename from app/src/main/java/org/koitharu/kotatsu/domain/MangaSearchRepository.kt rename to app/src/main/java/org/koitharu/kotatsu/search/domain/MangaSearchRepository.kt index 5e205c0e8..ad41053bb 100644 --- a/app/src/main/java/org/koitharu/kotatsu/domain/MangaSearchRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/domain/MangaSearchRepository.kt @@ -1,7 +1,8 @@ -package org.koitharu.kotatsu.domain +package org.koitharu.kotatsu.search.domain import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow +import org.koitharu.kotatsu.base.domain.MangaProviderFactory import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.core.model.SortOrder diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/search/MangaSearchSheet.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/MangaSearchSheet.kt similarity index 52% rename from app/src/main/java/org/koitharu/kotatsu/ui/search/MangaSearchSheet.kt rename to app/src/main/java/org/koitharu/kotatsu/search/ui/MangaSearchSheet.kt index e92821ebf..e227462e9 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/search/MangaSearchSheet.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/MangaSearchSheet.kt @@ -1,36 +1,35 @@ -package org.koitharu.kotatsu.ui.search +package org.koitharu.kotatsu.search.ui import android.os.Bundle import android.view.View import androidx.fragment.app.FragmentManager -import moxy.ktx.moxyPresenter +import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.core.parameter.parametersOf import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.MangaSource -import org.koitharu.kotatsu.ui.list.MangaListSheet +import org.koitharu.kotatsu.list.ui.MangaListSheet +import org.koitharu.kotatsu.utils.ext.parcelableArgument +import org.koitharu.kotatsu.utils.ext.stringArgument import org.koitharu.kotatsu.utils.ext.withArgs -class MangaSearchSheet : MangaListSheet() { +class MangaSearchSheet : MangaListSheet() { - private val presenter by moxyPresenter(factory = ::SearchPresenter) - - private lateinit var source: MangaSource - private lateinit var query: String - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - source = requireArguments().getParcelable(ARG_SOURCE)!! - query = requireArguments().getString(ARG_QUERY).orEmpty() + override val viewModel by viewModel { + parametersOf(source) } + private val query by stringArgument(ARG_QUERY) + private val source by parcelableArgument(ARG_SOURCE) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - setTitle(query) + setTitle(query.orEmpty()) setSubtitle(getString(R.string.search_results_on_s, source.title)) } override fun onRequestMoreItems(offset: Int) { - presenter.loadList(source, query, offset) + viewModel.loadList(query.orEmpty(), offset) } companion object { @@ -40,7 +39,7 @@ class MangaSearchSheet : MangaListSheet() { private const val TAG = "MangaSearchSheet" - fun show(fm: FragmentManager, source: MangaSource, query: String) { + fun show(fm: FragmentManager, source: MangaSource, query: String) { MangaSearchSheet().withArgs(2) { putParcelable(ARG_SOURCE, source) putString(ARG_QUERY, query) diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/search/MangaSuggestionsProvider.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/MangaSuggestionsProvider.kt similarity index 98% rename from app/src/main/java/org/koitharu/kotatsu/ui/search/MangaSuggestionsProvider.kt rename to app/src/main/java/org/koitharu/kotatsu/search/ui/MangaSuggestionsProvider.kt index 81627a063..2889a24cf 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/search/MangaSuggestionsProvider.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/MangaSuggestionsProvider.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.search +package org.koitharu.kotatsu.search.ui import android.app.SearchManager import android.content.ContentResolver diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/search/SearchActivity.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/SearchActivity.kt similarity index 95% rename from app/src/main/java/org/koitharu/kotatsu/ui/search/SearchActivity.kt rename to app/src/main/java/org/koitharu/kotatsu/search/ui/SearchActivity.kt index 89ea79c3d..33a19d383 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/search/SearchActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/SearchActivity.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.search +package org.koitharu.kotatsu.search.ui import android.content.Context import android.content.Intent @@ -7,8 +7,8 @@ import android.os.Parcelable import androidx.appcompat.widget.SearchView import kotlinx.android.synthetic.main.activity_search.* import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.BaseActivity import org.koitharu.kotatsu.core.model.MangaSource -import org.koitharu.kotatsu.ui.base.BaseActivity import org.koitharu.kotatsu.utils.ext.showKeyboard class SearchActivity : BaseActivity(), SearchView.OnQueryTextListener { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/search/SearchFragment.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/SearchFragment.kt similarity index 65% rename from app/src/main/java/org/koitharu/kotatsu/ui/search/SearchFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/search/ui/SearchFragment.kt index 1a796624f..29104078b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/search/SearchFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/SearchFragment.kt @@ -1,21 +1,24 @@ -package org.koitharu.kotatsu.ui.search +package org.koitharu.kotatsu.search.ui -import moxy.ktx.moxyPresenter +import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.core.parameter.parametersOf import org.koitharu.kotatsu.core.model.MangaSource -import org.koitharu.kotatsu.ui.list.MangaListFragment +import org.koitharu.kotatsu.list.ui.MangaListFragment import org.koitharu.kotatsu.utils.ext.parcelableArgument import org.koitharu.kotatsu.utils.ext.stringArgument import org.koitharu.kotatsu.utils.ext.withArgs -class SearchFragment : MangaListFragment() { +class SearchFragment : MangaListFragment() { - private val presenter by moxyPresenter(factory = ::SearchPresenter) + override val viewModel by viewModel { + parametersOf(source) + } private val query by stringArgument(ARG_QUERY) private val source by parcelableArgument(ARG_SOURCE) override fun onRequestMoreItems(offset: Int) { - presenter.loadList(source, query.orEmpty(), offset) + viewModel.loadList(query.orEmpty(), offset) } override fun getTitle(): CharSequence? { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/search/SearchHelper.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/SearchHelper.kt similarity index 94% rename from app/src/main/java/org/koitharu/kotatsu/ui/search/SearchHelper.kt rename to app/src/main/java/org/koitharu/kotatsu/search/ui/SearchHelper.kt index e408fdc7d..7cbdad906 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/search/SearchHelper.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/SearchHelper.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.search +package org.koitharu.kotatsu.search.ui import android.app.SearchManager import android.content.Context @@ -6,7 +6,7 @@ import android.database.Cursor import android.view.MenuItem import androidx.appcompat.widget.SearchView import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.ui.search.global.GlobalSearchActivity +import org.koitharu.kotatsu.search.ui.global.GlobalSearchActivity import org.koitharu.kotatsu.utils.ext.safe import java.io.Closeable diff --git a/app/src/main/java/org/koitharu/kotatsu/search/ui/SearchViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/SearchViewModel.kt new file mode 100644 index 000000000..ffa3e1436 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/SearchViewModel.kt @@ -0,0 +1,24 @@ +package org.koitharu.kotatsu.search.ui + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.koitharu.kotatsu.core.parser.MangaRepository +import org.koitharu.kotatsu.list.ui.MangaListViewModel + +class SearchViewModel( + private val repository: MangaRepository +) : MangaListViewModel() { + + fun loadList(query: String, offset: Int) { + launchLoadingJob { + val list = withContext(Dispatchers.Default) { + repository.getList(offset, query = query) + } + if (offset == 0) { + content.value = list + } else { + content.value = content.value.orEmpty() + list + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/search/global/GlobalSearchActivity.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/global/GlobalSearchActivity.kt similarity index 90% rename from app/src/main/java/org/koitharu/kotatsu/ui/search/global/GlobalSearchActivity.kt rename to app/src/main/java/org/koitharu/kotatsu/search/ui/global/GlobalSearchActivity.kt index 1adb63af6..acddcca71 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/search/global/GlobalSearchActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/global/GlobalSearchActivity.kt @@ -1,10 +1,10 @@ -package org.koitharu.kotatsu.ui.search.global +package org.koitharu.kotatsu.search.ui.global import android.content.Context import android.content.Intent import android.os.Bundle import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.ui.base.BaseActivity +import org.koitharu.kotatsu.base.ui.BaseActivity class GlobalSearchActivity : BaseActivity() { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/search/global/GlobalSearchFragment.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/global/GlobalSearchFragment.kt similarity index 59% rename from app/src/main/java/org/koitharu/kotatsu/ui/search/global/GlobalSearchFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/search/ui/global/GlobalSearchFragment.kt index bf05ceff3..ea54afbbc 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/search/global/GlobalSearchFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/global/GlobalSearchFragment.kt @@ -1,20 +1,20 @@ -package org.koitharu.kotatsu.ui.search.global +package org.koitharu.kotatsu.search.ui.global -import moxy.ktx.moxyPresenter -import org.koitharu.kotatsu.ui.list.MangaListFragment +import org.koin.android.viewmodel.ext.android.viewModel +import org.koitharu.kotatsu.list.ui.MangaListFragment import org.koitharu.kotatsu.utils.ext.stringArgument import org.koitharu.kotatsu.utils.ext.withArgs -class GlobalSearchFragment : MangaListFragment() { +class GlobalSearchFragment : MangaListFragment() { - private val presenter by moxyPresenter(factory = ::GlobalSearchPresenter) + override val viewModel by viewModel() private val query by stringArgument(ARG_QUERY) override fun onRequestMoreItems(offset: Int) { if (offset == 0) { - presenter.startSearch(query.orEmpty()) + viewModel.startSearch(query.orEmpty()) } } diff --git a/app/src/main/java/org/koitharu/kotatsu/search/ui/global/GlobalSearchViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/global/GlobalSearchViewModel.kt new file mode 100644 index 000000000..99154cfbf --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/global/GlobalSearchViewModel.kt @@ -0,0 +1,39 @@ +package org.koitharu.kotatsu.search.ui.global + +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.* +import org.koitharu.kotatsu.list.ui.MangaListViewModel +import org.koitharu.kotatsu.search.domain.MangaSearchRepository +import org.koitharu.kotatsu.utils.ext.onFirst +import java.io.IOException + +class GlobalSearchViewModel( + private val repository: MangaSearchRepository +) : MangaListViewModel() { + + private var searchJob: Job? = null + + fun startSearch(query: String) { + isLoading.value = true + searchJob?.cancel() + searchJob = repository.globalSearch(query) + .flowOn(Dispatchers.Default) + .catch { e -> + if (e is IOException) { + onError.call(e) + } + }.filterNot { x -> x.isEmpty() } + .onEmpty { + content.value = emptyList() + isLoading.value = false + }.onCompletion { + // TODO + }.onFirst { + isLoading.value = false + }.onEach { + content.value = content.value.orEmpty() + it + }.launchIn(viewModelScope) + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/AppUpdateChecker.kt b/app/src/main/java/org/koitharu/kotatsu/settings/AppUpdateChecker.kt similarity index 99% rename from app/src/main/java/org/koitharu/kotatsu/ui/settings/AppUpdateChecker.kt rename to app/src/main/java/org/koitharu/kotatsu/settings/AppUpdateChecker.kt index 1988467bf..dbc9f002b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/AppUpdateChecker.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/AppUpdateChecker.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.settings +package org.koitharu.kotatsu.settings import android.annotation.SuppressLint import android.content.Context diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/HistorySettingsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/settings/HistorySettingsFragment.kt similarity index 93% rename from app/src/main/java/org/koitharu/kotatsu/ui/settings/HistorySettingsFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/settings/HistorySettingsFragment.kt index 0343ac7e1..45abfe9d2 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/HistorySettingsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/HistorySettingsFragment.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.settings +package org.koitharu.kotatsu.settings import android.os.Bundle import android.view.View @@ -9,11 +9,11 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.koin.android.ext.android.inject import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.core.local.Cache +import org.koitharu.kotatsu.base.ui.BasePreferenceFragment import org.koitharu.kotatsu.core.prefs.AppSettings -import org.koitharu.kotatsu.domain.tracking.TrackingRepository -import org.koitharu.kotatsu.ui.base.BasePreferenceFragment -import org.koitharu.kotatsu.ui.search.MangaSuggestionsProvider +import org.koitharu.kotatsu.local.data.Cache +import org.koitharu.kotatsu.search.ui.MangaSuggestionsProvider +import org.koitharu.kotatsu.tracker.domain.TrackingRepository import org.koitharu.kotatsu.utils.CacheUtils import org.koitharu.kotatsu.utils.FileSizeUtils import org.koitharu.kotatsu.utils.ext.getDisplayMessage diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/MainSettingsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/settings/MainSettingsFragment.kt similarity index 95% rename from app/src/main/java/org/koitharu/kotatsu/ui/settings/MainSettingsFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/settings/MainSettingsFragment.kt index 1a298b532..a6c9ff146 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/MainSettingsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/MainSettingsFragment.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.settings +package org.koitharu.kotatsu.settings import android.content.DialogInterface import android.content.Intent @@ -15,16 +15,16 @@ import com.google.android.material.snackbar.Snackbar import kotlinx.coroutines.launch import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.BasePreferenceFragment +import org.koitharu.kotatsu.base.ui.dialog.StorageSelectDialog +import org.koitharu.kotatsu.base.ui.dialog.TextInputDialog import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.core.model.ZoomMode import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.ListMode -import org.koitharu.kotatsu.ui.base.BasePreferenceFragment -import org.koitharu.kotatsu.ui.base.dialog.StorageSelectDialog -import org.koitharu.kotatsu.ui.base.dialog.TextInputDialog -import org.koitharu.kotatsu.ui.list.ListModeSelectDialog -import org.koitharu.kotatsu.ui.settings.utils.MultiSummaryProvider -import org.koitharu.kotatsu.ui.tracker.TrackWorker +import org.koitharu.kotatsu.list.ui.ListModeSelectDialog +import org.koitharu.kotatsu.settings.utils.MultiSummaryProvider +import org.koitharu.kotatsu.tracker.work.TrackWorker import org.koitharu.kotatsu.utils.ext.getStorageName import org.koitharu.kotatsu.utils.ext.md5 import org.koitharu.kotatsu.utils.ext.names diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/NetworkSettingsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/settings/NetworkSettingsFragment.kt similarity index 74% rename from app/src/main/java/org/koitharu/kotatsu/ui/settings/NetworkSettingsFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/settings/NetworkSettingsFragment.kt index 435702315..8bfb2c3d6 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/NetworkSettingsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/NetworkSettingsFragment.kt @@ -1,8 +1,8 @@ -package org.koitharu.kotatsu.ui.settings +package org.koitharu.kotatsu.settings import android.os.Bundle import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.ui.base.BasePreferenceFragment +import org.koitharu.kotatsu.base.ui.BasePreferenceFragment class NetworkSettingsFragment : BasePreferenceFragment(R.string.settings) { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/NotificationSettingsLegacyFragment.kt b/app/src/main/java/org/koitharu/kotatsu/settings/NotificationSettingsLegacyFragment.kt similarity index 89% rename from app/src/main/java/org/koitharu/kotatsu/ui/settings/NotificationSettingsLegacyFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/settings/NotificationSettingsLegacyFragment.kt index 599c14fb0..8643fae82 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/NotificationSettingsLegacyFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/NotificationSettingsLegacyFragment.kt @@ -1,13 +1,13 @@ -package org.koitharu.kotatsu.ui.settings +package org.koitharu.kotatsu.settings import android.media.RingtoneManager import android.os.Bundle import android.view.View import androidx.preference.Preference import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.BasePreferenceFragment import org.koitharu.kotatsu.core.prefs.AppSettings -import org.koitharu.kotatsu.ui.base.BasePreferenceFragment -import org.koitharu.kotatsu.ui.settings.utils.RingtonePickContract +import org.koitharu.kotatsu.settings.utils.RingtonePickContract import org.koitharu.kotatsu.utils.ext.toUriOrNull class NotificationSettingsLegacyFragment : BasePreferenceFragment(R.string.notifications) { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/ReaderSettingsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/settings/ReaderSettingsFragment.kt similarity index 85% rename from app/src/main/java/org/koitharu/kotatsu/ui/settings/ReaderSettingsFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/settings/ReaderSettingsFragment.kt index 98d0e29ce..48d112540 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/ReaderSettingsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/ReaderSettingsFragment.kt @@ -1,14 +1,14 @@ -package org.koitharu.kotatsu.ui.settings +package org.koitharu.kotatsu.settings import android.os.Bundle import android.view.View import androidx.preference.ListPreference import androidx.preference.MultiSelectListPreference import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.BasePreferenceFragment import org.koitharu.kotatsu.core.model.ZoomMode import org.koitharu.kotatsu.core.prefs.AppSettings -import org.koitharu.kotatsu.ui.base.BasePreferenceFragment -import org.koitharu.kotatsu.ui.settings.utils.MultiSummaryProvider +import org.koitharu.kotatsu.settings.utils.MultiSummaryProvider import org.koitharu.kotatsu.utils.ext.names class ReaderSettingsFragment : BasePreferenceFragment(R.string.reader_settings) { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/SettingsActivity.kt b/app/src/main/java/org/koitharu/kotatsu/settings/SettingsActivity.kt similarity index 94% rename from app/src/main/java/org/koitharu/kotatsu/ui/settings/SettingsActivity.kt rename to app/src/main/java/org/koitharu/kotatsu/settings/SettingsActivity.kt index 8154fc47d..e052e4109 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/SettingsActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/SettingsActivity.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.settings +package org.koitharu.kotatsu.settings import android.content.Context import android.content.Intent @@ -8,8 +8,8 @@ import androidx.fragment.app.commit import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.BaseActivity import org.koitharu.kotatsu.core.model.MangaSource -import org.koitharu.kotatsu.ui.base.BaseActivity class SettingsActivity : BaseActivity(), PreferenceFragmentCompat.OnPreferenceStartFragmentCallback { diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/SettingsModule.kt b/app/src/main/java/org/koitharu/kotatsu/settings/SettingsModule.kt new file mode 100644 index 000000000..0a8b077f2 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/settings/SettingsModule.kt @@ -0,0 +1,22 @@ +package org.koitharu.kotatsu.settings + +import android.net.Uri +import org.koin.android.ext.koin.androidContext +import org.koin.android.viewmodel.dsl.viewModel +import org.koin.dsl.module +import org.koitharu.kotatsu.core.backup.BackupRepository +import org.koitharu.kotatsu.core.backup.RestoreRepository +import org.koitharu.kotatsu.core.prefs.AppSettings +import org.koitharu.kotatsu.settings.backup.BackupViewModel +import org.koitharu.kotatsu.settings.backup.RestoreViewModel + +val settingsModule + get() = module { + + single { BackupRepository(get()) } + single { RestoreRepository(get()) } + single { AppSettings(androidContext()) } + + viewModel { BackupViewModel(get(), androidContext()) } + viewModel { (uri: Uri?) -> RestoreViewModel(uri, get(), androidContext()) } + } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/SourceSettingsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/settings/SourceSettingsFragment.kt similarity index 93% rename from app/src/main/java/org/koitharu/kotatsu/ui/settings/SourceSettingsFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/settings/SourceSettingsFragment.kt index 0864b5170..a4fa0e443 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/SourceSettingsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/SourceSettingsFragment.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.settings +package org.koitharu.kotatsu.settings import android.os.Bundle import android.view.View @@ -8,7 +8,7 @@ import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.core.parser.RemoteMangaRepository import org.koitharu.kotatsu.core.prefs.SourceSettings -import org.koitharu.kotatsu.ui.settings.utils.EditTextSummaryProvider +import org.koitharu.kotatsu.settings.utils.EditTextSummaryProvider import org.koitharu.kotatsu.utils.ext.withArgs class SourceSettingsFragment : PreferenceFragmentCompat() { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/backup/BackupDialogFragment.kt b/app/src/main/java/org/koitharu/kotatsu/settings/backup/BackupDialogFragment.kt similarity index 70% rename from app/src/main/java/org/koitharu/kotatsu/ui/settings/backup/BackupDialogFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/settings/backup/BackupDialogFragment.kt index 9ee572019..3b1380a4b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/backup/BackupDialogFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/backup/BackupDialogFragment.kt @@ -1,30 +1,30 @@ -package org.koitharu.kotatsu.ui.settings.backup +package org.koitharu.kotatsu.settings.backup import android.os.Bundle import android.view.View import androidx.appcompat.app.AlertDialog import androidx.core.view.isVisible import kotlinx.android.synthetic.main.dialog_progress.* -import moxy.ktx.moxyPresenter -import org.koin.android.ext.android.get +import org.koin.android.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.ui.base.AlertDialogFragment +import org.koitharu.kotatsu.base.ui.AlertDialogFragment import org.koitharu.kotatsu.utils.ShareHelper import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.utils.progress.Progress import java.io.File -class BackupDialogFragment : AlertDialogFragment(R.layout.dialog_progress), BackupView { +class BackupDialogFragment : AlertDialogFragment(R.layout.dialog_progress) { - @Suppress("unused") - private val presenter by moxyPresenter { - BackupPresenter(get()) - } + private val viewModel by viewModel() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) textView_title.setText(R.string.create_backup) textView_subtitle.setText(R.string.processing_) + + viewModel.progress.observe(viewLifecycleOwner, this::onProgressChanged) + viewModel.onBackupDone.observe(viewLifecycleOwner, this::onBackupDone) + viewModel.onError.observe(viewLifecycleOwner, this::onError) } override fun onBuildDialog(builder: AlertDialog.Builder) { @@ -32,7 +32,7 @@ class BackupDialogFragment : AlertDialogFragment(R.layout.dialog_progress), Back .setNegativeButton(android.R.string.cancel, null) } - override fun onError(e: Throwable) { + private fun onError(e: Throwable) { AlertDialog.Builder(context ?: return) .setNegativeButton(R.string.close, null) .setTitle(R.string.error) @@ -41,9 +41,7 @@ class BackupDialogFragment : AlertDialogFragment(R.layout.dialog_progress), Back dismiss() } - override fun onLoadingStateChanged(isLoading: Boolean) = Unit - - override fun onProgressChanged(progress: Progress?) { + private fun onProgressChanged(progress: Progress?) { with(progressBar) { isVisible = true isIndeterminate = progress == null @@ -54,7 +52,7 @@ class BackupDialogFragment : AlertDialogFragment(R.layout.dialog_progress), Back } } - override fun onBackupDone(file: File) { + private fun onBackupDone(file: File) { ShareHelper.shareBackup(context ?: return, file) dismiss() } diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/backup/BackupSettingsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/settings/backup/BackupSettingsFragment.kt similarity index 93% rename from app/src/main/java/org/koitharu/kotatsu/ui/settings/backup/BackupSettingsFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/settings/backup/BackupSettingsFragment.kt index 02ebc35eb..b7cc6ec68 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/backup/BackupSettingsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/backup/BackupSettingsFragment.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.settings.backup +package org.koitharu.kotatsu.settings.backup import android.content.ActivityNotFoundException import android.net.Uri @@ -10,8 +10,8 @@ import com.google.android.material.snackbar.Snackbar import kotlinx.android.synthetic.main.fragment_list.* import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.BasePreferenceFragment import org.koitharu.kotatsu.core.prefs.AppSettings -import org.koitharu.kotatsu.ui.base.BasePreferenceFragment class BackupSettingsFragment : BasePreferenceFragment(R.string.backup_restore), ActivityResultCallback { diff --git a/app/src/main/java/org/koitharu/kotatsu/settings/backup/BackupViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/settings/backup/BackupViewModel.kt new file mode 100644 index 000000000..930a0a714 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/settings/backup/BackupViewModel.kt @@ -0,0 +1,41 @@ +package org.koitharu.kotatsu.settings.backup + +import android.content.Context +import androidx.lifecycle.MutableLiveData +import org.koitharu.kotatsu.base.ui.BaseViewModel +import org.koitharu.kotatsu.core.backup.BackupArchive +import org.koitharu.kotatsu.core.backup.BackupRepository +import org.koitharu.kotatsu.utils.SingleLiveEvent +import org.koitharu.kotatsu.utils.progress.Progress +import java.io.File + +class BackupViewModel( + private val repository: BackupRepository, + private val context: Context +) : BaseViewModel() { + + val progress = MutableLiveData(null) + val onBackupDone = SingleLiveEvent() + + init { + launchLoadingJob { + val backup = BackupArchive.createNew(context) + backup.put(repository.createIndex()) + + progress.value = Progress(0, 3) + backup.put(repository.dumpHistory()) + + progress.value = Progress(1, 3) + backup.put(repository.dumpCategories()) + + progress.value = Progress(2, 3) + backup.put(repository.dumpFavourites()) + + progress.value = Progress(3, 3) + backup.flush() + progress.value = null + backup.cleanup() + onBackupDone.call(backup.file) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/backup/RestoreDialogFragment.kt b/app/src/main/java/org/koitharu/kotatsu/settings/backup/RestoreDialogFragment.kt similarity index 74% rename from app/src/main/java/org/koitharu/kotatsu/ui/settings/backup/RestoreDialogFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/settings/backup/RestoreDialogFragment.kt index f31037539..84e85dd8f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/backup/RestoreDialogFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/backup/RestoreDialogFragment.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.settings.backup +package org.koitharu.kotatsu.settings.backup import android.net.Uri import android.os.Bundle @@ -6,34 +6,37 @@ import android.view.View import androidx.appcompat.app.AlertDialog import androidx.core.view.isVisible import kotlinx.android.synthetic.main.dialog_progress.* -import moxy.ktx.moxyPresenter -import org.koin.android.ext.android.get +import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.core.parameter.parametersOf import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.AlertDialogFragment import org.koitharu.kotatsu.core.backup.CompositeResult -import org.koitharu.kotatsu.ui.base.AlertDialogFragment import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.utils.ext.toUriOrNull import org.koitharu.kotatsu.utils.ext.withArgs import org.koitharu.kotatsu.utils.progress.Progress -class RestoreDialogFragment : AlertDialogFragment(R.layout.dialog_progress), RestoreView { +class RestoreDialogFragment : AlertDialogFragment(R.layout.dialog_progress) { - @Suppress("unused") - private val presenter by moxyPresenter { - RestorePresenter(arguments?.getString(ARG_FILE)?.toUriOrNull(), get()) + private val viewModel by viewModel { + parametersOf(arguments?.getString(ARG_FILE)?.toUriOrNull()) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) textView_title.setText(R.string.restore_backup) textView_subtitle.setText(R.string.preparing_) + + viewModel.progress.observe(viewLifecycleOwner, this::onProgressChanged) + viewModel.onRestoreDone.observe(viewLifecycleOwner, this::onRestoreDone) + viewModel.onError.observe(viewLifecycleOwner, this::onError) } override fun onBuildDialog(builder: AlertDialog.Builder) { builder.setCancelable(false) } - override fun onError(e: Throwable) { + private fun onError(e: Throwable) { AlertDialog.Builder(context ?: return) .setNegativeButton(R.string.close, null) .setTitle(R.string.error) @@ -42,9 +45,7 @@ class RestoreDialogFragment : AlertDialogFragment(R.layout.dialog_progress), Res dismiss() } - override fun onLoadingStateChanged(isLoading: Boolean) = Unit - - override fun onProgressChanged(progress: Progress?) { + private fun onProgressChanged(progress: Progress?) { with(progressBar) { isVisible = true isIndeterminate = progress == null @@ -55,7 +56,7 @@ class RestoreDialogFragment : AlertDialogFragment(R.layout.dialog_progress), Res } } - override fun onRestoreDone(result: CompositeResult) { + private fun onRestoreDone(result: CompositeResult) { val builder = AlertDialog.Builder(context ?: return) when { result.isAllSuccess -> builder.setTitle(R.string.data_restored) diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/backup/RestorePresenter.kt b/app/src/main/java/org/koitharu/kotatsu/settings/backup/RestoreViewModel.kt similarity index 67% rename from app/src/main/java/org/koitharu/kotatsu/ui/settings/backup/RestorePresenter.kt rename to app/src/main/java/org/koitharu/kotatsu/settings/backup/RestoreViewModel.kt index 3c9ce9d37..1948b6585 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/backup/RestorePresenter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/backup/RestoreViewModel.kt @@ -1,33 +1,36 @@ -package org.koitharu.kotatsu.ui.settings.backup +package org.koitharu.kotatsu.settings.backup import android.content.Context import android.net.Uri +import androidx.lifecycle.MutableLiveData import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.withContext -import org.koin.core.component.get +import org.koitharu.kotatsu.base.ui.BaseViewModel import org.koitharu.kotatsu.core.backup.BackupArchive import org.koitharu.kotatsu.core.backup.BackupEntry import org.koitharu.kotatsu.core.backup.CompositeResult import org.koitharu.kotatsu.core.backup.RestoreRepository -import org.koitharu.kotatsu.ui.base.BasePresenter +import org.koitharu.kotatsu.utils.SingleLiveEvent import org.koitharu.kotatsu.utils.progress.Progress import java.io.File import java.io.FileNotFoundException -class RestorePresenter( - private val uri: Uri?, - private val repository: RestoreRepository -) : BasePresenter() { +class RestoreViewModel( + uri: Uri?, + private val repository: RestoreRepository, + private val context: Context +) : BaseViewModel() { - override fun onFirstViewAttach() { - super.onFirstViewAttach() + val progress = MutableLiveData(null) + val onRestoreDone = SingleLiveEvent() + + init { launchLoadingJob { - viewState.onProgressChanged(null) if (uri == null) { throw FileNotFoundException() } - val contentResolver = get().contentResolver + val contentResolver = context.contentResolver @Suppress("BlockingMethodInNonBlockingContext") val backup = withContext(Dispatchers.IO) { @@ -44,17 +47,17 @@ class RestorePresenter( backup.unpack() val result = CompositeResult() - viewState.onProgressChanged(Progress(0, 3)) + progress.value = Progress(0, 3) result += repository.upsertHistory(backup.getEntry(BackupEntry.HISTORY)) - viewState.onProgressChanged(Progress(1, 3)) + progress.value = Progress(1, 3) result += repository.upsertCategories(backup.getEntry(BackupEntry.CATEGORIES)) - viewState.onProgressChanged(Progress(2, 3)) + progress.value = Progress(2, 3) result += repository.upsertFavourites(backup.getEntry(BackupEntry.FAVOURITES)) - viewState.onProgressChanged(Progress(3, 3)) - viewState.onRestoreDone(result) + progress.value = Progress(3, 3) + onRestoreDone.call(result) } finally { withContext(NonCancellable) { backup.cleanup() diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/sources/SourceViewHolder.kt b/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourceViewHolder.kt similarity index 80% rename from app/src/main/java/org/koitharu/kotatsu/ui/settings/sources/SourceViewHolder.kt rename to app/src/main/java/org/koitharu/kotatsu/settings/sources/SourceViewHolder.kt index dccb053b8..5039e1bc9 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/sources/SourceViewHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourceViewHolder.kt @@ -1,10 +1,10 @@ -package org.koitharu.kotatsu.ui.settings.sources +package org.koitharu.kotatsu.settings.sources import android.view.ViewGroup import kotlinx.android.synthetic.main.item_source_config.* import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.list.BaseViewHolder import org.koitharu.kotatsu.core.model.MangaSource -import org.koitharu.kotatsu.ui.base.list.BaseViewHolder class SourceViewHolder(parent: ViewGroup) : BaseViewHolder(parent, R.layout.item_source_config) { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/sources/SourcesAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesAdapter.kt similarity index 92% rename from app/src/main/java/org/koitharu/kotatsu/ui/settings/sources/SourcesAdapter.kt rename to app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesAdapter.kt index 9bf9c6fa0..298b9a0d5 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/sources/SourcesAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesAdapter.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.settings.sources +package org.koitharu.kotatsu.settings.sources import android.annotation.SuppressLint import android.view.MotionEvent @@ -7,10 +7,10 @@ import androidx.recyclerview.widget.RecyclerView import kotlinx.android.synthetic.main.item_source_config.* import org.koin.core.component.KoinComponent import org.koin.core.component.inject +import org.koitharu.kotatsu.base.domain.MangaProviderFactory +import org.koitharu.kotatsu.base.ui.list.OnRecyclerItemClickListener import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.core.prefs.AppSettings -import org.koitharu.kotatsu.domain.MangaProviderFactory -import org.koitharu.kotatsu.ui.base.list.OnRecyclerItemClickListener import org.koitharu.kotatsu.utils.ext.mapToSet import org.koitharu.kotatsu.utils.ext.safe diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/sources/SourcesReorderCallback.kt b/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesReorderCallback.kt similarity index 78% rename from app/src/main/java/org/koitharu/kotatsu/ui/settings/sources/SourcesReorderCallback.kt rename to app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesReorderCallback.kt index e6b2b8cbb..066a43a6f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/sources/SourcesReorderCallback.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesReorderCallback.kt @@ -1,9 +1,10 @@ -package org.koitharu.kotatsu.ui.settings.sources +package org.koitharu.kotatsu.settings.sources import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView -class SourcesReorderCallback : ItemTouchHelper.SimpleCallback(ItemTouchHelper.DOWN or ItemTouchHelper.UP, 0) { +class SourcesReorderCallback : + ItemTouchHelper.SimpleCallback(ItemTouchHelper.DOWN or ItemTouchHelper.UP, 0) { override fun onMove( recyclerView: RecyclerView, diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/sources/SourcesSettingsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesSettingsFragment.kt similarity index 87% rename from app/src/main/java/org/koitharu/kotatsu/ui/settings/sources/SourcesSettingsFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesSettingsFragment.kt index ba39fa748..0a3871867 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/sources/SourcesSettingsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/sources/SourcesSettingsFragment.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.settings.sources +package org.koitharu.kotatsu.settings.sources import android.os.Bundle import android.view.View @@ -7,10 +7,10 @@ import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView import kotlinx.android.synthetic.main.fragment_settings_sources.* import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.BaseFragment +import org.koitharu.kotatsu.base.ui.list.OnRecyclerItemClickListener import org.koitharu.kotatsu.core.model.MangaSource -import org.koitharu.kotatsu.ui.base.BaseFragment -import org.koitharu.kotatsu.ui.base.list.OnRecyclerItemClickListener -import org.koitharu.kotatsu.ui.settings.SettingsActivity +import org.koitharu.kotatsu.settings.SettingsActivity class SourcesSettingsFragment : BaseFragment(R.layout.fragment_settings_sources), OnRecyclerItemClickListener { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/utils/EditTextSummaryProvider.kt b/app/src/main/java/org/koitharu/kotatsu/settings/utils/EditTextSummaryProvider.kt similarity index 90% rename from app/src/main/java/org/koitharu/kotatsu/ui/settings/utils/EditTextSummaryProvider.kt rename to app/src/main/java/org/koitharu/kotatsu/settings/utils/EditTextSummaryProvider.kt index 847c46960..1e2976dc6 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/utils/EditTextSummaryProvider.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/utils/EditTextSummaryProvider.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.settings.utils +package org.koitharu.kotatsu.settings.utils import androidx.annotation.StringRes import androidx.preference.EditTextPreference diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/utils/MultiSummaryProvider.kt b/app/src/main/java/org/koitharu/kotatsu/settings/utils/MultiSummaryProvider.kt similarity index 92% rename from app/src/main/java/org/koitharu/kotatsu/ui/settings/utils/MultiSummaryProvider.kt rename to app/src/main/java/org/koitharu/kotatsu/settings/utils/MultiSummaryProvider.kt index 0705820e7..039dbbb37 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/utils/MultiSummaryProvider.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/utils/MultiSummaryProvider.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.settings.utils +package org.koitharu.kotatsu.settings.utils import androidx.annotation.StringRes import androidx.preference.MultiSelectListPreference diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/utils/RingtonePickContract.kt b/app/src/main/java/org/koitharu/kotatsu/settings/utils/RingtonePickContract.kt similarity index 95% rename from app/src/main/java/org/koitharu/kotatsu/ui/settings/utils/RingtonePickContract.kt rename to app/src/main/java/org/koitharu/kotatsu/settings/utils/RingtonePickContract.kt index 8d5b0d04f..1bf8b7856 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/utils/RingtonePickContract.kt +++ b/app/src/main/java/org/koitharu/kotatsu/settings/utils/RingtonePickContract.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.settings.utils +package org.koitharu.kotatsu.settings.utils import android.content.Context import android.content.Intent diff --git a/app/src/main/java/org/koitharu/kotatsu/tracker/TrackerModule.kt b/app/src/main/java/org/koitharu/kotatsu/tracker/TrackerModule.kt new file mode 100644 index 000000000..3fc8eee71 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/tracker/TrackerModule.kt @@ -0,0 +1,14 @@ +package org.koitharu.kotatsu.tracker + +import org.koin.android.viewmodel.dsl.viewModel +import org.koin.dsl.module +import org.koitharu.kotatsu.tracker.domain.TrackingRepository +import org.koitharu.kotatsu.tracker.ui.FeedViewModel + +val trackerModule + get() = module { + + single { TrackingRepository(get(), get()) } + + viewModel { FeedViewModel(get()) } + } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/tracking/TrackingRepository.kt b/app/src/main/java/org/koitharu/kotatsu/tracker/domain/TrackingRepository.kt similarity index 96% rename from app/src/main/java/org/koitharu/kotatsu/domain/tracking/TrackingRepository.kt rename to app/src/main/java/org/koitharu/kotatsu/tracker/domain/TrackingRepository.kt index 2b19a48dc..4ff9b74bb 100644 --- a/app/src/main/java/org/koitharu/kotatsu/domain/tracking/TrackingRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/tracker/domain/TrackingRepository.kt @@ -1,11 +1,11 @@ -package org.koitharu.kotatsu.domain.tracking +package org.koitharu.kotatsu.tracker.domain import androidx.room.withTransaction import org.koitharu.kotatsu.core.db.MangaDatabase import org.koitharu.kotatsu.core.db.entity.TrackEntity import org.koitharu.kotatsu.core.db.entity.TrackLogEntity import org.koitharu.kotatsu.core.model.* -import org.koitharu.kotatsu.core.parser.LocalMangaRepository +import org.koitharu.kotatsu.local.domain.LocalMangaRepository import java.util.* class TrackingRepository( diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/feed/FeedAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedAdapter.kt similarity index 69% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/feed/FeedAdapter.kt rename to app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedAdapter.kt index 35f5c2581..31f9486b0 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/feed/FeedAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedAdapter.kt @@ -1,10 +1,10 @@ -package org.koitharu.kotatsu.ui.list.feed +package org.koitharu.kotatsu.tracker.ui import android.view.ViewGroup +import org.koitharu.kotatsu.base.ui.list.BaseRecyclerAdapter +import org.koitharu.kotatsu.base.ui.list.BaseViewHolder +import org.koitharu.kotatsu.base.ui.list.OnRecyclerItemClickListener import org.koitharu.kotatsu.core.model.TrackingLogItem -import org.koitharu.kotatsu.ui.base.list.BaseRecyclerAdapter -import org.koitharu.kotatsu.ui.base.list.BaseViewHolder -import org.koitharu.kotatsu.ui.base.list.OnRecyclerItemClickListener class FeedAdapter(onItemClickListener: OnRecyclerItemClickListener? = null) : BaseRecyclerAdapter(onItemClickListener) { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/feed/FeedFragment.kt b/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedFragment.kt similarity index 70% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/feed/FeedFragment.kt rename to app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedFragment.kt index e9078831c..129a75a31 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/feed/FeedFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedFragment.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.list.feed +package org.koitharu.kotatsu.tracker.ui import android.os.Bundle import android.view.Menu @@ -8,24 +8,23 @@ import android.view.View import androidx.core.view.isVisible import com.google.android.material.snackbar.Snackbar import kotlinx.android.synthetic.main.fragment_tracklogs.* -import moxy.MvpDelegate -import moxy.ktx.moxyPresenter +import org.koin.android.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.BaseFragment +import org.koitharu.kotatsu.base.ui.list.OnRecyclerItemClickListener +import org.koitharu.kotatsu.base.ui.list.PaginationScrollListener +import org.koitharu.kotatsu.base.ui.list.decor.SpacingItemDecoration import org.koitharu.kotatsu.core.model.TrackingLogItem -import org.koitharu.kotatsu.ui.base.BaseFragment -import org.koitharu.kotatsu.ui.base.list.OnRecyclerItemClickListener -import org.koitharu.kotatsu.ui.base.list.PaginationScrollListener -import org.koitharu.kotatsu.ui.base.list.decor.SpacingItemDecoration -import org.koitharu.kotatsu.ui.details.MangaDetailsActivity -import org.koitharu.kotatsu.ui.tracker.TrackWorker +import org.koitharu.kotatsu.details.ui.DetailsActivity +import org.koitharu.kotatsu.tracker.work.TrackWorker import org.koitharu.kotatsu.utils.ext.callOnScrollListeners import org.koitharu.kotatsu.utils.ext.getDisplayMessage import org.koitharu.kotatsu.utils.ext.hasItems -class FeedFragment : BaseFragment(R.layout.fragment_tracklogs), FeedView, - PaginationScrollListener.Callback, OnRecyclerItemClickListener { +class FeedFragment : BaseFragment(R.layout.fragment_tracklogs), PaginationScrollListener.Callback, + OnRecyclerItemClickListener { - private val presenter by moxyPresenter(factory = ::FeedPresenter) + private val viewModel by viewModel() private var adapter: FeedAdapter? = null @@ -45,9 +44,13 @@ class FeedFragment : BaseFragment(R.layout.fragment_tracklogs), FeedView, ) recyclerView.setHasFixedSize(true) recyclerView.addOnScrollListener(PaginationScrollListener(4, this)) - if (savedInstanceState?.containsKey(MvpDelegate.MOXY_DELEGATE_TAGS_KEY) != true) { + if (savedInstanceState == null) { onRequestMoreItems(0) } + + viewModel.content.observe(viewLifecycleOwner, this::onListChanged) + viewModel.isLoading.observe(viewLifecycleOwner, this::onLoadingStateChanged) + viewModel.onError.observe(viewLifecycleOwner, this::onError) } override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { @@ -69,7 +72,7 @@ class FeedFragment : BaseFragment(R.layout.fragment_tracklogs), FeedView, super.onDestroyView() } - override fun onListChanged(list: List) { + private fun onListChanged(list: List) { adapter?.replaceData(list) if (list.isEmpty()) { setUpEmptyListHolder() @@ -80,12 +83,7 @@ class FeedFragment : BaseFragment(R.layout.fragment_tracklogs), FeedView, recyclerView.callOnScrollListeners() } - override fun onListAppended(list: List) { - adapter?.appendData(list) - recyclerView.callOnScrollListeners() - } - - override fun onListError(e: Throwable) { + private fun onError(e: Throwable) { if (recyclerView.hasItems) { Snackbar.make(recyclerView, e.getDisplayMessage(resources), Snackbar.LENGTH_SHORT) .show() @@ -101,11 +99,7 @@ class FeedFragment : BaseFragment(R.layout.fragment_tracklogs), FeedView, } } - override fun onError(e: Throwable) { - Snackbar.make(recyclerView, e.getDisplayMessage(resources), Snackbar.LENGTH_SHORT).show() - } - - override fun onLoadingStateChanged(isLoading: Boolean) { + private fun onLoadingStateChanged(isLoading: Boolean) { val hasItems = recyclerView.hasItems progressBar.isVisible = isLoading && !hasItems if (isLoading) { @@ -118,11 +112,11 @@ class FeedFragment : BaseFragment(R.layout.fragment_tracklogs), FeedView, } override fun onRequestMoreItems(offset: Int) { - presenter.loadList(offset) + viewModel.loadList(offset) } override fun onItemClick(item: TrackingLogItem, position: Int, view: View) { - startActivity(MangaDetailsActivity.newIntent(context ?: return, item.manga)) + startActivity(DetailsActivity.newIntent(context ?: return, item.manga)) } private fun setUpEmptyListHolder() { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/feed/FeedHolder.kt b/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedHolder.kt similarity index 93% rename from app/src/main/java/org/koitharu/kotatsu/ui/list/feed/FeedHolder.kt rename to app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedHolder.kt index 3ec2eb4c9..06e3dd934 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/feed/FeedHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedHolder.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.list.feed +package org.koitharu.kotatsu.tracker.ui import android.text.format.DateUtils import android.view.ViewGroup @@ -7,8 +7,8 @@ import coil.request.Disposable import kotlinx.android.synthetic.main.item_tracklog.* import org.koin.core.component.inject import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.list.BaseViewHolder import org.koitharu.kotatsu.core.model.TrackingLogItem -import org.koitharu.kotatsu.ui.base.list.BaseViewHolder import org.koitharu.kotatsu.utils.ext.enqueueWith import org.koitharu.kotatsu.utils.ext.formatRelative import org.koitharu.kotatsu.utils.ext.newImageRequest diff --git a/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedViewModel.kt b/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedViewModel.kt new file mode 100644 index 000000000..9056a4395 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/tracker/ui/FeedViewModel.kt @@ -0,0 +1,24 @@ +package org.koitharu.kotatsu.tracker.ui + +import androidx.lifecycle.MutableLiveData +import org.koitharu.kotatsu.base.ui.BaseViewModel +import org.koitharu.kotatsu.core.model.TrackingLogItem +import org.koitharu.kotatsu.tracker.domain.TrackingRepository + +class FeedViewModel( + private val repository: TrackingRepository +) : BaseViewModel() { + + val content = MutableLiveData>() + + fun loadList(offset: Int) { + launchLoadingJob { + val list = repository.getTrackingLog(offset, 20) + if (offset == 0) { + content.value = list + } else { + content.value = content.value.orEmpty() + list + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/tracker/TrackWorker.kt b/app/src/main/java/org/koitharu/kotatsu/tracker/work/TrackWorker.kt similarity index 97% rename from app/src/main/java/org/koitharu/kotatsu/ui/tracker/TrackWorker.kt rename to app/src/main/java/org/koitharu/kotatsu/tracker/work/TrackWorker.kt index 03b6a7dd5..9efae09da 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/tracker/TrackWorker.kt +++ b/app/src/main/java/org/koitharu/kotatsu/tracker/work/TrackWorker.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.tracker +package org.koitharu.kotatsu.tracker.work import android.app.NotificationChannel import android.app.NotificationManager @@ -19,8 +19,8 @@ import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaChapter import org.koitharu.kotatsu.core.prefs.AppSettings -import org.koitharu.kotatsu.domain.tracking.TrackingRepository -import org.koitharu.kotatsu.ui.details.MangaDetailsActivity +import org.koitharu.kotatsu.details.ui.DetailsActivity +import org.koitharu.kotatsu.tracker.domain.TrackingRepository import org.koitharu.kotatsu.utils.ext.safe import org.koitharu.kotatsu.utils.ext.toBitmapOrNull import org.koitharu.kotatsu.utils.ext.toUriOrNull @@ -162,7 +162,7 @@ class TrackWorker(context: Context, workerParams: WorkerParameters) : style.setSummaryText(manga.title) style.setBigContentTitle(summary) setStyle(style) - val intent = MangaDetailsActivity.newIntent(applicationContext, manga) + val intent = DetailsActivity.newIntent(applicationContext, manga) setContentIntent( PendingIntent.getActivity( applicationContext, id, diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/BaseMvpView.kt b/app/src/main/java/org/koitharu/kotatsu/ui/base/BaseMvpView.kt deleted file mode 100644 index da4a75439..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/BaseMvpView.kt +++ /dev/null @@ -1,14 +0,0 @@ -package org.koitharu.kotatsu.ui.base - -import moxy.MvpView -import moxy.viewstate.strategy.alias.AddToEndSingle -import moxy.viewstate.strategy.alias.OneExecution - -interface BaseMvpView : MvpView { - - @OneExecution - fun onError(e: Throwable) - - @AddToEndSingle - fun onLoadingStateChanged(isLoading: Boolean) -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/BasePresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/base/BasePresenter.kt deleted file mode 100644 index a267efd03..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/BasePresenter.kt +++ /dev/null @@ -1,44 +0,0 @@ -package org.koitharu.kotatsu.ui.base - -import kotlinx.coroutines.* -import moxy.MvpPresenter -import moxy.presenterScope -import org.koin.core.component.KoinComponent -import org.koitharu.kotatsu.BuildConfig -import kotlin.coroutines.CoroutineContext -import kotlin.coroutines.EmptyCoroutineContext - -abstract class BasePresenter : MvpPresenter(), KoinComponent { - - protected fun launchJob( - context: CoroutineContext = EmptyCoroutineContext, - start: CoroutineStart = CoroutineStart.DEFAULT, - block: suspend CoroutineScope.() -> Unit - ) { - presenterScope.launch(context + createErrorHandler(), start, block) - } - - protected fun launchLoadingJob( - context: CoroutineContext = EmptyCoroutineContext, - start: CoroutineStart = CoroutineStart.DEFAULT, - block: suspend CoroutineScope.() -> Unit - ) { - presenterScope.launch(context + createErrorHandler(), start) { - viewState.onLoadingStateChanged(isLoading = true) - try { - block() - } finally { - viewState.onLoadingStateChanged(isLoading = false) - } - } - } - - private fun createErrorHandler() = CoroutineExceptionHandler { _, throwable -> - if (BuildConfig.DEBUG) { - throwable.printStackTrace() - } - if (throwable !is CancellationException) { - viewState.onError(throwable) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/BaseService.kt b/app/src/main/java/org/koitharu/kotatsu/ui/base/BaseService.kt deleted file mode 100644 index b9ab215da..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/BaseService.kt +++ /dev/null @@ -1,24 +0,0 @@ -package org.koitharu.kotatsu.ui.base - -import android.app.Service -import android.content.Intent -import android.os.IBinder -import androidx.annotation.CallSuper -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.cancel - -abstract class BaseService : Service() { - - @Suppress("MemberVisibilityCanBePrivate") - val serviceScope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate) - - @CallSuper - override fun onDestroy() { - serviceScope.cancel() - super.onDestroy() - } - - override fun onBind(intent: Intent?): IBinder? = null -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/base/SharedPresenterHolder.kt b/app/src/main/java/org/koitharu/kotatsu/ui/base/SharedPresenterHolder.kt deleted file mode 100644 index 130008862..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/base/SharedPresenterHolder.kt +++ /dev/null @@ -1,25 +0,0 @@ -package org.koitharu.kotatsu.ui.base - -import android.util.ArrayMap -import moxy.MvpPresenter -import java.lang.ref.WeakReference - -abstract class SharedPresenterHolder> { - - private val cache = ArrayMap>(3) - - fun getInstance(key: Int): T { - var instance = cache[key]?.get() - if (instance == null) { - instance = onCreatePresenter(key) - cache[key] = WeakReference(instance) - } - return instance - } - - fun clear(key: Int) { - cache.remove(key) - } - - protected abstract fun onCreatePresenter(key: Int): T -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsPresenter.kt deleted file mode 100644 index 8e6aac244..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsPresenter.kt +++ /dev/null @@ -1,203 +0,0 @@ -package org.koitharu.kotatsu.ui.details - -import kotlinx.coroutines.CancellationException -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.* -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import moxy.InjectViewState -import moxy.presenterScope -import org.koin.core.component.get -import org.koin.core.component.inject -import org.koitharu.kotatsu.BuildConfig -import org.koitharu.kotatsu.core.exceptions.MangaNotFoundException -import org.koitharu.kotatsu.core.model.Manga -import org.koitharu.kotatsu.core.parser.LocalMangaRepository -import org.koitharu.kotatsu.domain.MangaDataRepository -import org.koitharu.kotatsu.domain.MangaSearchRepository -import org.koitharu.kotatsu.domain.favourites.FavouritesRepository -import org.koitharu.kotatsu.domain.favourites.OnFavouritesChangeListener -import org.koitharu.kotatsu.domain.history.HistoryRepository -import org.koitharu.kotatsu.domain.history.OnHistoryChangeListener -import org.koitharu.kotatsu.domain.tracking.TrackingRepository -import org.koitharu.kotatsu.ui.base.BasePresenter -import org.koitharu.kotatsu.ui.base.SharedPresenterHolder -import org.koitharu.kotatsu.utils.ext.safe -import java.io.IOException - -@InjectViewState -class MangaDetailsPresenter private constructor(private val key: Int) : - BasePresenter(), OnHistoryChangeListener, OnFavouritesChangeListener { - - private val historyRepository by inject() - private val favouritesRepository by inject() - private val trackingRepository by inject() - private val searchRepository by inject() - private val mangaDataRepository by inject() - - private var manga: Manga? = null - - override fun onFirstViewAttach() { - super.onFirstViewAttach() - HistoryRepository.subscribe(this) - FavouritesRepository.subscribe(this) - } - - fun findMangaById(id: Long) { - presenterScope.launch { - viewState.onLoadingStateChanged(true) - try { - val manga = withContext(Dispatchers.IO) { - mangaDataRepository.findMangaById(id) - } ?: throw MangaNotFoundException("Cannot find manga by id") - viewState.onMangaUpdated(manga) - loadDetails(manga, true) - } catch (_: CancellationException) { - } catch (e: Throwable) { - if (BuildConfig.DEBUG) { - e.printStackTrace() - } - viewState.onError(e) - } finally { - viewState.onLoadingStateChanged(false) - } - } - } - - fun loadDetails(manga: Manga, force: Boolean = false) { - if (!force && this.manga == manga) { - return - } - loadHistory(manga) - viewState.onMangaUpdated(manga) - loadFavourite(manga) - presenterScope.launch { - try { - viewState.onLoadingStateChanged(true) - val data = withContext(Dispatchers.Default) { - manga.source.repository.getDetails(manga) - } - viewState.onMangaUpdated(data) - this@MangaDetailsPresenter.manga = data - viewState.onNewChaptersChanged(trackingRepository.getNewChaptersCount(manga.id)) - } catch (_: CancellationException) { - } catch (e: Throwable) { - if (BuildConfig.DEBUG) { - e.printStackTrace() - } - viewState.onError(e) - } finally { - viewState.onLoadingStateChanged(false) - } - } - } - - fun deleteLocal(manga: Manga) { - presenterScope.launch { - viewState.onLoadingStateChanged(true) - try { - withContext(Dispatchers.IO) { - val repository = get() - val original = repository.getRemoteManga(manga) - repository.delete(manga) || throw IOException("Unable to delete file") - safe { - historyRepository.deleteOrSwap(manga, original) - } - } - viewState.onMangaRemoved(manga) - } catch (e: CancellationException) { - } catch (e: Exception) { - if (BuildConfig.DEBUG) { - e.printStackTrace() - } - viewState.onError(e) - } finally { - viewState.onLoadingStateChanged(false) - } - } - } - - private fun loadHistory(manga: Manga) { - presenterScope.launch { - try { - val history = withContext(Dispatchers.IO) { - historyRepository.getOne(manga) - } - viewState.onHistoryChanged(history) - } catch (e: Exception) { - if (BuildConfig.DEBUG) { - e.printStackTrace() - } - } - } - } - - private fun loadFavourite(manga: Manga) { - presenterScope.launch { - try { - val categories = withContext(Dispatchers.IO) { - favouritesRepository.getCategories(manga.id) - } - viewState.onFavouriteChanged(categories) - } catch (e: Exception) { - if (BuildConfig.DEBUG) { - e.printStackTrace() - } - } - } - } - - fun loadRelated() { - val manga = this.manga ?: return - presenterScope.launch { - viewState.onLoadingStateChanged(isLoading = true) - var isFirstCall = true - searchRepository.globalSearch(manga.title) - .map { list -> - list.filter { x -> x.id != manga.id } - }.filterNot { x -> x.isEmpty() } - .flowOn(Dispatchers.IO) - .catch { e -> - if (e is IOException) { - viewState.onError(e) - } - } - .onEmpty { - viewState.onListChanged(emptyList()) - viewState.onLoadingStateChanged(isLoading = false) - }.onCompletion { - viewState.onListAppended(emptyList()) - }.collect { - if (isFirstCall) { - isFirstCall = false - viewState.onListChanged(it) - viewState.onLoadingStateChanged(isLoading = false) - } else { - viewState.onListAppended(it) - } - } - } - } - - override fun onHistoryChanged() { - loadHistory(manga ?: return) - } - - override fun onFavouritesChanged(mangaId: Long) { - if (mangaId == manga?.id) { - loadFavourite(manga!!) - } - } - - override fun onDestroy() { - HistoryRepository.unsubscribe(this) - FavouritesRepository.unsubscribe(this) - clear(key) - super.onDestroy() - } - - companion object Holder : SharedPresenterHolder() { - - override fun onCreatePresenter(key: Int) = MangaDetailsPresenter(key) - } -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsView.kt b/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsView.kt deleted file mode 100644 index be9143067..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsView.kt +++ /dev/null @@ -1,38 +0,0 @@ -package org.koitharu.kotatsu.ui.details - -import moxy.viewstate.strategy.AddToEndSingleTagStrategy -import moxy.viewstate.strategy.AddToEndStrategy -import moxy.viewstate.strategy.StateStrategyType -import moxy.viewstate.strategy.alias.AddToEndSingle -import moxy.viewstate.strategy.alias.SingleState -import org.koitharu.kotatsu.core.model.FavouriteCategory -import org.koitharu.kotatsu.core.model.Manga -import org.koitharu.kotatsu.core.model.MangaHistory -import org.koitharu.kotatsu.ui.base.BaseMvpView - -interface MangaDetailsView : BaseMvpView { - - @AddToEndSingle - fun onMangaUpdated(manga: Manga) - - @AddToEndSingle - fun onHistoryChanged(history: MangaHistory?) - - @AddToEndSingle - fun onFavouriteChanged(categories: List) - - @SingleState - fun onMangaRemoved(manga: Manga) - - @AddToEndSingle - fun onNewChaptersChanged(newChapters: Int) - - @StateStrategyType(AddToEndSingleTagStrategy::class, tag = "content") - fun onListChanged(list: List) = Unit - - @StateStrategyType(AddToEndStrategy::class, tag = "content") - fun onListAppended(list: List) = Unit - - @StateStrategyType(AddToEndSingleTagStrategy::class, tag = "content") - fun onListError(e: Throwable) = Unit -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/details/RelatedMangaFragment.kt b/app/src/main/java/org/koitharu/kotatsu/ui/details/RelatedMangaFragment.kt deleted file mode 100644 index 1a5fddd9b..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/details/RelatedMangaFragment.kt +++ /dev/null @@ -1,43 +0,0 @@ -package org.koitharu.kotatsu.ui.details - -import android.os.Bundle -import android.view.View -import moxy.ktx.moxyPresenter -import org.koitharu.kotatsu.core.model.FavouriteCategory -import org.koitharu.kotatsu.core.model.Manga -import org.koitharu.kotatsu.core.model.MangaHistory -import org.koitharu.kotatsu.ui.list.MangaListFragment - -class RelatedMangaFragment : MangaListFragment(), MangaDetailsView { - - private val presenter by moxyPresenter { - MangaDetailsPresenter.getInstance(activity.hashCode()) - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - isSwipeRefreshEnabled = false - } - - override fun onRequestMoreItems(offset: Int) { - if (offset == 0) { - presenter.loadRelated() - } - } - - override fun onMangaUpdated(manga: Manga) = Unit - - override fun onHistoryChanged(history: MangaHistory?) = Unit - - override fun onFavouriteChanged(categories: List) = Unit - - override fun onMangaRemoved(manga: Manga) = Unit - - override fun onNewChaptersChanged(newChapters: Int) = Unit - - override fun onListChanged(list: List) = super.onListChanged(list) - - override fun onListAppended(list: List) = super.onListAppended(list) - - override fun onListError(e: Throwable) = super.onListError(e) -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/MainView.kt b/app/src/main/java/org/koitharu/kotatsu/ui/list/MainView.kt deleted file mode 100644 index f41fcd03f..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/MainView.kt +++ /dev/null @@ -1,11 +0,0 @@ -package org.koitharu.kotatsu.ui.list - -import moxy.viewstate.strategy.alias.OneExecution -import org.koitharu.kotatsu.ui.base.BaseMvpView -import org.koitharu.kotatsu.ui.reader.ReaderState - -interface MainView : BaseMvpView { - - @OneExecution - fun onOpenReader(state: ReaderState) -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/MangaListView.kt b/app/src/main/java/org/koitharu/kotatsu/ui/list/MangaListView.kt deleted file mode 100644 index 5954d9369..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/MangaListView.kt +++ /dev/null @@ -1,30 +0,0 @@ -package org.koitharu.kotatsu.ui.list - -import moxy.viewstate.strategy.AddToEndSingleTagStrategy -import moxy.viewstate.strategy.AddToEndStrategy -import moxy.viewstate.strategy.StateStrategyType -import moxy.viewstate.strategy.alias.AddToEnd -import moxy.viewstate.strategy.alias.AddToEndSingle -import org.koitharu.kotatsu.core.model.Manga -import org.koitharu.kotatsu.core.model.MangaFilter -import org.koitharu.kotatsu.core.model.MangaTag -import org.koitharu.kotatsu.core.model.SortOrder -import org.koitharu.kotatsu.ui.base.BaseMvpView - -interface MangaListView : BaseMvpView { - - @StateStrategyType(AddToEndSingleTagStrategy::class, tag = "content") - fun onListChanged(list: List) - - @StateStrategyType(AddToEndStrategy::class, tag = "content") - fun onListAppended(list: List) - - @StateStrategyType(AddToEndSingleTagStrategy::class, tag = "content") - fun onListError(e: Throwable) - - @AddToEndSingle - fun onInitFilter(sortOrders: List, tags: List, currentFilter: MangaFilter?) - - @AddToEnd - fun onItemRemoved(item: Manga) -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesListPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesListPresenter.kt deleted file mode 100644 index 1cc777a00..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/FavouritesListPresenter.kt +++ /dev/null @@ -1,59 +0,0 @@ -package org.koitharu.kotatsu.ui.list.favourites - -import kotlinx.coroutines.CancellationException -import kotlinx.coroutines.launch -import moxy.InjectViewState -import moxy.presenterScope -import org.koitharu.kotatsu.BuildConfig -import org.koitharu.kotatsu.core.model.Manga -import org.koitharu.kotatsu.domain.favourites.FavouritesRepository -import org.koitharu.kotatsu.ui.base.BasePresenter -import org.koitharu.kotatsu.ui.list.MangaListView - -@InjectViewState -class FavouritesListPresenter( - private val categoryId: Long, - private val repository: FavouritesRepository -) : BasePresenter>() { - - fun loadList(offset: Int) { - presenterScope.launch { - viewState.onLoadingStateChanged(true) - try { - val list = if (categoryId == 0L) { - repository.getAllManga(offset = offset) - } else { - repository.getManga(categoryId = categoryId, offset = offset) - } - if (offset == 0) { - viewState.onListChanged(list) - } else { - viewState.onListAppended(list) - } - } catch (e: CancellationException) { - } catch (e: Throwable) { - if (BuildConfig.DEBUG) { - e.printStackTrace() - } - if (offset == 0) { - viewState.onListError(e) - } else { - viewState.onError(e) - } - } finally { - viewState.onLoadingStateChanged(false) - } - } - } - - fun removeFromFavourites(manga: Manga) { - launchJob { - if (categoryId == 0L) { - repository.removeFromFavourites(manga) - } else { - repository.removeFromCategory(manga, categoryId) - } - viewState.onItemRemoved(manga) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/FavouriteCategoriesPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/FavouriteCategoriesPresenter.kt deleted file mode 100644 index 02a966f3d..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/FavouriteCategoriesPresenter.kt +++ /dev/null @@ -1,78 +0,0 @@ -package org.koitharu.kotatsu.ui.list.favourites.categories - -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock -import moxy.InjectViewState -import org.koin.core.component.get -import org.koitharu.kotatsu.core.model.Manga -import org.koitharu.kotatsu.domain.favourites.FavouritesRepository -import org.koitharu.kotatsu.ui.base.BasePresenter -import org.koitharu.kotatsu.utils.ext.mapToSet - -@InjectViewState -class FavouriteCategoriesPresenter : BasePresenter() { - - private val repository = get() - private val reorderMutex by lazy(LazyThreadSafetyMode.NONE) { Mutex() } - - override fun onFirstViewAttach() { - super.onFirstViewAttach() - loadAllCategories() - } - - fun loadAllCategories() { - launchJob { - val categories = repository.getAllCategories() - viewState.onCategoriesChanged(categories) - } - } - - fun loadMangaCategories(manga: Manga) { - launchJob { - val categories = repository.getCategories(manga.id) - viewState.onCheckedCategoriesChanged(categories.mapToSet { it.id.toInt() }) - } - } - - fun createCategory(name: String) { - launchJob { - repository.addCategory(name) - val categories = repository.getAllCategories() - viewState.onCategoriesChanged(categories) - } - } - - fun renameCategory(id: Long, name: String) { - launchJob { - repository.renameCategory(id, name) - } - } - - fun deleteCategory(id: Long) { - launchJob { - repository.removeCategory(id) - val categories = repository.getAllCategories() - viewState.onCategoriesChanged(categories) - } - } - - fun storeCategoriesOrder(orderedIds: List) { - launchJob { - reorderMutex.withLock { - repository.reorderCategories(orderedIds) - } - } - } - - fun addToCategory(manga: Manga, categoryId: Long) { - launchJob { - repository.addToCategory(manga, categoryId) - } - } - - fun removeFromCategory(manga: Manga, categoryId: Long) { - launchJob { - repository.removeFromCategory(manga, categoryId) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/FavouriteCategoriesView.kt b/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/FavouriteCategoriesView.kt deleted file mode 100644 index b4eb1de8f..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/favourites/categories/FavouriteCategoriesView.kt +++ /dev/null @@ -1,19 +0,0 @@ -package org.koitharu.kotatsu.ui.list.favourites.categories - -import moxy.viewstate.strategy.AddToEndSingleStrategy -import moxy.viewstate.strategy.StateStrategyType -import moxy.viewstate.strategy.alias.AddToEndSingle -import org.koitharu.kotatsu.core.model.FavouriteCategory -import org.koitharu.kotatsu.ui.base.BaseMvpView - -interface FavouriteCategoriesView : BaseMvpView { - - @StateStrategyType(AddToEndSingleStrategy::class) - fun onCategoriesChanged(categories: List) - - @StateStrategyType(AddToEndSingleStrategy::class) - fun onCheckedCategoriesChanged(checkedIds: Set) - - @AddToEndSingle - override fun onLoadingStateChanged(isLoading: Boolean) = Unit -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/feed/FeedPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/list/feed/FeedPresenter.kt deleted file mode 100644 index c9d7e5a34..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/feed/FeedPresenter.kt +++ /dev/null @@ -1,44 +0,0 @@ -package org.koitharu.kotatsu.ui.list.feed - -import kotlinx.coroutines.CancellationException -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import moxy.presenterScope -import org.koin.core.component.inject -import org.koitharu.kotatsu.BuildConfig -import org.koitharu.kotatsu.domain.tracking.TrackingRepository -import org.koitharu.kotatsu.ui.base.BasePresenter - -class FeedPresenter : BasePresenter() { - - private val repository by inject() - - fun loadList(offset: Int) { - presenterScope.launch { - viewState.onLoadingStateChanged(true) - try { - val list = withContext(Dispatchers.IO) { - repository.getTrackingLog(offset, 20) - } - if (offset == 0) { - viewState.onListChanged(list) - } else { - viewState.onListAppended(list) - } - } catch (e: CancellationException) { - } catch (e: Throwable) { - if (BuildConfig.DEBUG) { - e.printStackTrace() - } - if (offset == 0) { - viewState.onListError(e) - } else { - viewState.onError(e) - } - } finally { - viewState.onLoadingStateChanged(false) - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/feed/FeedView.kt b/app/src/main/java/org/koitharu/kotatsu/ui/list/feed/FeedView.kt deleted file mode 100644 index 8ff33007e..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/feed/FeedView.kt +++ /dev/null @@ -1,19 +0,0 @@ -package org.koitharu.kotatsu.ui.list.feed - -import moxy.viewstate.strategy.AddToEndSingleTagStrategy -import moxy.viewstate.strategy.AddToEndStrategy -import moxy.viewstate.strategy.StateStrategyType -import org.koitharu.kotatsu.core.model.TrackingLogItem -import org.koitharu.kotatsu.ui.base.BaseMvpView - -interface FeedView : BaseMvpView { - - @StateStrategyType(AddToEndSingleTagStrategy::class, tag = "content") - fun onListChanged(list: List) - - @StateStrategyType(AddToEndStrategy::class, tag = "content") - fun onListAppended(list: List) - - @StateStrategyType(AddToEndSingleTagStrategy::class, tag = "content") - fun onListError(e: Throwable) -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/history/HistoryListPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/list/history/HistoryListPresenter.kt deleted file mode 100644 index fa403185b..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/history/HistoryListPresenter.kt +++ /dev/null @@ -1,71 +0,0 @@ -package org.koitharu.kotatsu.ui.list.history - -import android.os.Build -import kotlinx.coroutines.CancellationException -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import moxy.InjectViewState -import moxy.presenterScope -import org.koin.core.component.get -import org.koitharu.kotatsu.BuildConfig -import org.koitharu.kotatsu.core.model.Manga -import org.koitharu.kotatsu.core.model.MangaHistory -import org.koitharu.kotatsu.domain.history.HistoryRepository -import org.koitharu.kotatsu.ui.base.BasePresenter -import org.koitharu.kotatsu.ui.list.MangaListView -import org.koitharu.kotatsu.utils.MangaShortcut - -@InjectViewState -class HistoryListPresenter : BasePresenter>() { - - private val repository = get() - - fun loadList(offset: Int) { - presenterScope.launch { - viewState.onLoadingStateChanged(true) - try { - val list = withContext(Dispatchers.IO) { - repository.getList(offset = offset) - } - if (offset == 0) { - viewState.onListChanged(list) - } else { - viewState.onListAppended(list) - } - } catch (_: CancellationException) { - } catch (e: Throwable) { - if (BuildConfig.DEBUG) { - e.printStackTrace() - } - if (offset == 0) { - viewState.onListError(e) - } else { - viewState.onError(e) - } - } finally { - viewState.onLoadingStateChanged(false) - } - } - } - - fun clearHistory() { - launchLoadingJob { - repository.clear() - viewState.onListChanged(emptyList()) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { - MangaShortcut.clearAppShortcuts(get()) - } - } - } - - fun removeFromHistory(manga: Manga) { - launchJob { - repository.delete(manga) - viewState.onItemRemoved(manga) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { - MangaShortcut(manga).removeAppShortcut(get()) - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/local/LocalListPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/list/local/LocalListPresenter.kt deleted file mode 100644 index 45f6d1ff2..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/local/LocalListPresenter.kt +++ /dev/null @@ -1,94 +0,0 @@ -package org.koitharu.kotatsu.ui.list.local - -import android.content.Context -import android.net.Uri -import android.os.Build -import kotlinx.coroutines.CancellationException -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import moxy.InjectViewState -import moxy.presenterScope -import org.koin.core.component.get -import org.koin.core.component.inject -import org.koitharu.kotatsu.BuildConfig -import org.koitharu.kotatsu.core.exceptions.UnsupportedFileException -import org.koitharu.kotatsu.core.model.Manga -import org.koitharu.kotatsu.core.parser.LocalMangaRepository -import org.koitharu.kotatsu.core.prefs.AppSettings -import org.koitharu.kotatsu.domain.history.HistoryRepository -import org.koitharu.kotatsu.ui.base.BasePresenter -import org.koitharu.kotatsu.ui.list.MangaListView -import org.koitharu.kotatsu.utils.MangaShortcut -import org.koitharu.kotatsu.utils.MediaStoreCompat -import org.koitharu.kotatsu.utils.ext.safe -import org.koitharu.kotatsu.utils.ext.sub -import java.io.File -import java.io.IOException - -@InjectViewState -class LocalListPresenter : BasePresenter>() { - - private val repository by inject() - - fun loadList(offset: Int) { - presenterScope.launch { - if (offset != 0) { - viewState.onListAppended(emptyList()) - return@launch - } - viewState.onLoadingStateChanged(true) - try { - val list = withContext(Dispatchers.IO) { - repository.getList(0) - } - viewState.onListChanged(list) - } catch (e: CancellationException) { - } catch (e: Throwable) { - if (BuildConfig.DEBUG) { - e.printStackTrace() - } - viewState.onListError(e) - } finally { - viewState.onLoadingStateChanged(false) - } - } - } - - fun importFile(context: Context, uri: Uri) { - launchJob { - val list = withContext(Dispatchers.IO) { - val name = MediaStoreCompat.getName(context, uri) - ?: throw IOException("Cannot fetch name from uri: $uri") - if (!LocalMangaRepository.isFileSupported(name)) { - throw UnsupportedFileException("Unsupported file on $uri") - } - val dest = get().getStorageDir(context)?.sub(name) - ?: throw IOException("External files dir unavailable") - context.contentResolver.openInputStream(uri)?.use { source -> - dest.outputStream().use { output -> - source.copyTo(output) - } - } ?: throw IOException("Cannot open input stream: $uri") - repository.getList(0) - } - viewState.onListChanged(list) - } - } - - fun delete(manga: Manga) { - launchJob { - withContext(Dispatchers.IO) { - val original = repository.getRemoteManga(manga) - repository.delete(manga) || throw IOException("Unable to delete file") - safe { - get().deleteOrSwap(manga, original) - } - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { - MangaShortcut(manga).removeAppShortcut(get()) - } - viewState.onItemRemoved(manga) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/list/remote/RemoteListPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/list/remote/RemoteListPresenter.kt deleted file mode 100644 index 6b90a9a52..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/list/remote/RemoteListPresenter.kt +++ /dev/null @@ -1,87 +0,0 @@ -package org.koitharu.kotatsu.ui.list.remote - -import kotlinx.coroutines.CancellationException -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import moxy.InjectViewState -import moxy.presenterScope -import org.koitharu.kotatsu.BuildConfig -import org.koitharu.kotatsu.core.model.MangaFilter -import org.koitharu.kotatsu.core.model.MangaSource -import org.koitharu.kotatsu.ui.base.BasePresenter -import org.koitharu.kotatsu.ui.list.MangaListView - -@InjectViewState -class RemoteListPresenter(source: MangaSource) : BasePresenter>() { - - private val repository by lazy(LazyThreadSafetyMode.PUBLICATION) { - source.repository - } - private var isFilterInitialized = false - private var filter: MangaFilter? = null - - override fun onFirstViewAttach() { - super.onFirstViewAttach() - loadFilter() - } - - fun loadList(offset: Int) { - presenterScope.launch { - viewState.onLoadingStateChanged(true) - try { - val list = withContext(Dispatchers.Default) { - repository.getList( - offset = offset, - sortOrder = filter?.sortOrder, - tag = filter?.tag - ) - } - if (offset == 0) { - viewState.onListChanged(list) - } else { - viewState.onListAppended(list) - } - } catch (_: CancellationException) { - } catch (e: Throwable) { - if (BuildConfig.DEBUG) { - e.printStackTrace() - } - if (offset == 0) { - viewState.onListError(e) - } else { - viewState.onError(e) - } - } finally { - viewState.onLoadingStateChanged(false) - } - } - if (!isFilterInitialized) { - loadFilter() - } - } - - fun applyFilter(filter: MangaFilter) { - this.filter = filter - viewState.onListChanged(emptyList()) - loadList(0) - } - - private fun loadFilter() { - isFilterInitialized = true - launchJob { - try { - val (sorts, tags) = withContext(Dispatchers.Default) { - repository.sortOrders.sortedBy { it.ordinal } to repository.getTags() - .sortedBy { it.title } - } - viewState.onInitFilter(sorts, tags, filter) - } catch (e: Exception) { - if (BuildConfig.DEBUG) { - e.printStackTrace() - } - isFilterInitialized = false - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderPresenter.kt deleted file mode 100644 index ebb9a8290..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderPresenter.kt +++ /dev/null @@ -1,127 +0,0 @@ -package org.koitharu.kotatsu.ui.reader - -import android.content.ContentResolver -import android.webkit.URLUtil -import kotlinx.coroutines.* -import moxy.InjectViewState -import moxy.presenterScope -import okhttp3.OkHttpClient -import okhttp3.Request -import org.koin.core.component.KoinComponent -import org.koin.core.component.get -import org.koin.core.component.inject -import org.koitharu.kotatsu.BuildConfig -import org.koitharu.kotatsu.core.model.Manga -import org.koitharu.kotatsu.core.model.MangaPage -import org.koitharu.kotatsu.core.prefs.AppSettings -import org.koitharu.kotatsu.core.prefs.ReaderMode -import org.koitharu.kotatsu.domain.MangaDataRepository -import org.koitharu.kotatsu.domain.MangaUtils -import org.koitharu.kotatsu.domain.history.HistoryRepository -import org.koitharu.kotatsu.ui.base.BasePresenter -import org.koitharu.kotatsu.utils.MediaStoreCompat -import org.koitharu.kotatsu.utils.ext.IgnoreErrors -import org.koitharu.kotatsu.utils.ext.await -import org.koitharu.kotatsu.utils.ext.contentDisposition -import org.koitharu.kotatsu.utils.ext.mimeType - -@InjectViewState -class ReaderPresenter : BasePresenter() { - - private val dataRepository by inject() - private val appSettings by inject() - - fun init(manga: Manga) { - presenterScope.launch { - viewState.onLoadingStateChanged(isLoading = true) - try { - val mode = withContext(Dispatchers.Default) { - val repo = manga.source.repository - val chapter = - (manga.chapters ?: throw RuntimeException("Chapters is null")).random() - var mode = dataRepository.getReaderMode(manga.id) - if (mode == null) { - val pages = repo.getPages(chapter) - val isWebtoon = MangaUtils.determineMangaIsWebtoon(pages) - mode = getReaderMode(isWebtoon) - if (isWebtoon != null) { - dataRepository.savePreferences( - manga = manga, - mode = mode - ) - } - } - mode - } - viewState.onInitReader(manga, mode) - } catch (_: CancellationException) { - } catch (e: Throwable) { - if (BuildConfig.DEBUG) { - e.printStackTrace() - } - viewState.onError(e) - } finally { - viewState.onLoadingStateChanged(isLoading = false) - } - } - } - - fun setMode(manga: Manga, mode: ReaderMode) { - presenterScope.launch { - dataRepository.savePreferences( - manga = manga, - mode = mode - ) - } - viewState.onInitReader(manga, mode) - } - - fun savePage(resolver: ContentResolver, page: MangaPage) { - presenterScope.launch(Dispatchers.IO) { - try { - val repo = page.source.repository - val url = repo.getPageFullUrl(page) - val request = Request.Builder() - .url(url) - .get() - .build() - val uri = get().newCall(request).await().use { response -> - val fileName = - URLUtil.guessFileName(url, response.contentDisposition, response.mimeType) - MediaStoreCompat.insertImage(resolver, fileName) { - response.body!!.byteStream().copyTo(it) - } - } - withContext(Dispatchers.Main) { - viewState.onPageSaved(uri) - } - } catch (e: CancellationException) { - } catch (e: Exception) { - withContext(Dispatchers.Main) { - viewState.onPageSaved(null) - } - } - } - } - - private fun getReaderMode(isWebtoon: Boolean?) = when { - isWebtoon == true -> ReaderMode.WEBTOON - appSettings.isPreferRtlReader -> ReaderMode.REVERSED - else -> ReaderMode.STANDARD - } - - companion object : KoinComponent { - - fun saveState(state: ReaderState) { - GlobalScope.launch(Dispatchers.Default + IgnoreErrors) { - get().addOrUpdate( - manga = state.manga, - chapterId = state.chapterId, - page = state.page, - scroll = state.scroll - ) - } - } - - } -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderView.kt b/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderView.kt deleted file mode 100644 index fb28407cb..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/reader/ReaderView.kt +++ /dev/null @@ -1,17 +0,0 @@ -package org.koitharu.kotatsu.ui.reader - -import android.net.Uri -import moxy.viewstate.strategy.alias.AddToEndSingle -import moxy.viewstate.strategy.alias.OneExecution -import org.koitharu.kotatsu.core.model.Manga -import org.koitharu.kotatsu.core.prefs.ReaderMode -import org.koitharu.kotatsu.ui.base.BaseMvpView - -interface ReaderView : BaseMvpView { - - @AddToEndSingle - fun onInitReader(manga: Manga, mode: ReaderMode) - - @OneExecution - fun onPageSaved(uri: Uri?) -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/search/SearchPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/search/SearchPresenter.kt deleted file mode 100644 index 713bb2bf1..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/search/SearchPresenter.kt +++ /dev/null @@ -1,25 +0,0 @@ -package org.koitharu.kotatsu.ui.search - -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import moxy.InjectViewState -import org.koitharu.kotatsu.core.model.MangaSource -import org.koitharu.kotatsu.ui.base.BasePresenter -import org.koitharu.kotatsu.ui.list.MangaListView - -@InjectViewState -class SearchPresenter : BasePresenter>() { - - fun loadList(source: MangaSource, query: String, offset: Int) { - launchLoadingJob { - val list = withContext(Dispatchers.Default) { - source.repository.getList(offset, query = query) - } - if (offset == 0) { - viewState.onListChanged(list) - } else { - viewState.onListAppended(list) - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/search/global/GlobalSearchPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/search/global/GlobalSearchPresenter.kt deleted file mode 100644 index 3addb3e3e..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/search/global/GlobalSearchPresenter.kt +++ /dev/null @@ -1,42 +0,0 @@ -package org.koitharu.kotatsu.ui.search.global - -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.* -import kotlinx.coroutines.plus -import moxy.presenterScope -import org.koin.core.component.get -import org.koitharu.kotatsu.domain.MangaSearchRepository -import org.koitharu.kotatsu.ui.base.BasePresenter -import org.koitharu.kotatsu.ui.list.MangaListView -import java.io.IOException - -class GlobalSearchPresenter : BasePresenter>() { - - private val repository = get() - - fun startSearch(query: String) { - viewState.onLoadingStateChanged(isLoading = true) - var isFirstCall = true - repository.globalSearch(query) - .catch { e -> - if (e is IOException) { - viewState.onError(e) - } - }.filterNot { x -> x.isEmpty() } - .onEmpty { - viewState.onListChanged(emptyList()) - viewState.onLoadingStateChanged(isLoading = false) - }.onCompletion { - viewState.onListAppended(emptyList()) - }.onEach { - if (isFirstCall) { - isFirstCall = false - viewState.onListChanged(it) - viewState.onLoadingStateChanged(isLoading = false) - } else { - viewState.onListAppended(it) - } - }.launchIn(presenterScope + Dispatchers.Default) - } - -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/backup/BackupPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/settings/backup/BackupPresenter.kt deleted file mode 100644 index 9f2854c38..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/backup/BackupPresenter.kt +++ /dev/null @@ -1,36 +0,0 @@ -package org.koitharu.kotatsu.ui.settings.backup - -import org.koin.core.component.get -import org.koitharu.kotatsu.core.backup.BackupArchive -import org.koitharu.kotatsu.core.backup.BackupRepository -import org.koitharu.kotatsu.ui.base.BasePresenter -import org.koitharu.kotatsu.utils.progress.Progress - -class BackupPresenter( - private val repository: BackupRepository -) : BasePresenter() { - - override fun onFirstViewAttach() { - super.onFirstViewAttach() - launchLoadingJob { - viewState.onProgressChanged(null) - val backup = BackupArchive.createNew(get()) - backup.put(repository.createIndex()) - - viewState.onProgressChanged(Progress(0, 3)) - backup.put(repository.dumpHistory()) - - viewState.onProgressChanged(Progress(1, 3)) - backup.put(repository.dumpCategories()) - - viewState.onProgressChanged(Progress(2, 3)) - backup.put(repository.dumpFavourites()) - - viewState.onProgressChanged(Progress(3, 3)) - backup.flush() - viewState.onProgressChanged(null) - backup.cleanup() - viewState.onBackupDone(backup.file) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/backup/BackupView.kt b/app/src/main/java/org/koitharu/kotatsu/ui/settings/backup/BackupView.kt deleted file mode 100644 index 180eef1ff..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/backup/BackupView.kt +++ /dev/null @@ -1,16 +0,0 @@ -package org.koitharu.kotatsu.ui.settings.backup - -import moxy.viewstate.strategy.alias.AddToEndSingle -import moxy.viewstate.strategy.alias.SingleState -import org.koitharu.kotatsu.ui.base.BaseMvpView -import org.koitharu.kotatsu.utils.progress.Progress -import java.io.File - -interface BackupView : BaseMvpView { - - @AddToEndSingle - fun onProgressChanged(progress: Progress?) - - @SingleState - fun onBackupDone(file: File) -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/settings/backup/RestoreView.kt b/app/src/main/java/org/koitharu/kotatsu/ui/settings/backup/RestoreView.kt deleted file mode 100644 index e81c411de..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/settings/backup/RestoreView.kt +++ /dev/null @@ -1,16 +0,0 @@ -package org.koitharu.kotatsu.ui.settings.backup - -import moxy.viewstate.strategy.alias.AddToEndSingle -import moxy.viewstate.strategy.alias.SingleState -import org.koitharu.kotatsu.core.backup.CompositeResult -import org.koitharu.kotatsu.ui.base.BaseMvpView -import org.koitharu.kotatsu.utils.progress.Progress - -interface RestoreView : BaseMvpView { - - @AddToEndSingle - fun onProgressChanged(progress: Progress?) - - @SingleState - fun onRestoreDone(result: CompositeResult) -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/utils/protect/ProtectView.kt b/app/src/main/java/org/koitharu/kotatsu/ui/utils/protect/ProtectView.kt deleted file mode 100644 index 8ab4781d1..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/ui/utils/protect/ProtectView.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.koitharu.kotatsu.ui.utils.protect - -import moxy.viewstate.strategy.alias.SingleState -import org.koitharu.kotatsu.ui.base.BaseMvpView - -interface ProtectView : BaseMvpView { - - @SingleState - fun onUnlockSuccess() -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/MangaShortcut.kt b/app/src/main/java/org/koitharu/kotatsu/utils/MangaShortcut.kt index b1d712b2e..7a5b0a308 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/MangaShortcut.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/MangaShortcut.kt @@ -17,9 +17,9 @@ import kotlinx.coroutines.withContext import org.koin.core.component.KoinComponent import org.koin.core.component.inject import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.domain.MangaDataRepository import org.koitharu.kotatsu.core.model.Manga -import org.koitharu.kotatsu.domain.MangaDataRepository -import org.koitharu.kotatsu.ui.details.MangaDetailsActivity +import org.koitharu.kotatsu.details.ui.DetailsActivity import org.koitharu.kotatsu.utils.ext.requireBitmap import org.koitharu.kotatsu.utils.ext.safe @@ -86,8 +86,8 @@ class MangaShortcut(private val manga: Manga) : KoinComponent { IconCompat.createWithAdaptiveBitmap(it) } ?: IconCompat.createWithResource(context, R.drawable.ic_shortcut_default)) .setIntent( - MangaDetailsActivity.newIntent(context, manga.id) - .setAction(MangaDetailsActivity.ACTION_MANGA_VIEW) + DetailsActivity.newIntent(context, manga.id) + .setAction(DetailsActivity.ACTION_MANGA_VIEW) ) } diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/MediaStoreCompat.kt b/app/src/main/java/org/koitharu/kotatsu/utils/MediaStoreCompat.kt index c21ef04f4..0d0127a03 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/MediaStoreCompat.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/MediaStoreCompat.kt @@ -2,7 +2,6 @@ package org.koitharu.kotatsu.utils import android.content.ContentResolver import android.content.ContentValues -import android.content.Context import android.net.Uri import android.os.Build import android.provider.MediaStore @@ -55,16 +54,16 @@ object MediaStoreCompat { return uri } - @JvmStatic - fun getName(context: Context, uri: Uri): String? = (if (uri.scheme == "content") { - context.contentResolver.query(uri, null, null, null, null)?.use { - if (it.moveToFirst()) { - it.getStringOrNull(it.getColumnIndex(OpenableColumns.DISPLAY_NAME)) - } else { - null + fun getName(contentResolver: ContentResolver, uri: Uri): String? = + (if (uri.scheme == "content") { + contentResolver.query(uri, null, null, null, null)?.use { + if (it.moveToFirst()) { + it.getStringOrNull(it.getColumnIndex(OpenableColumns.DISPLAY_NAME)) + } else { + null + } } - } - } else { - null - }) ?: uri.path?.substringAfterLast('/') + } else { + null + }) ?: uri.path?.substringAfterLast('/') } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/SingleLiveEvent.kt b/app/src/main/java/org/koitharu/kotatsu/utils/SingleLiveEvent.kt new file mode 100644 index 000000000..b8f982f33 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/utils/SingleLiveEvent.kt @@ -0,0 +1,36 @@ +package org.koitharu.kotatsu.utils + +import androidx.annotation.AnyThread +import androidx.annotation.MainThread +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.LiveData +import androidx.lifecycle.Observer +import java.util.concurrent.atomic.AtomicBoolean + +class SingleLiveEvent : LiveData() { + + private val pending = AtomicBoolean(false) + + override fun observe(owner: LifecycleOwner, observer: Observer) { + super.observe(owner) { + if (pending.compareAndSet(true, false)) { + observer.onChanged(it) + } + } + } + + override fun setValue(value: T) { + pending.set(true) + super.setValue(value) + } + + @MainThread + fun call(newValue: T) { + setValue(newValue) + } + + @AnyThread + fun postCall(newValue: T) { + postValue(newValue) + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/delegates/ParcelableArgumentDelegate.kt b/app/src/main/java/org/koitharu/kotatsu/utils/delegates/ParcelableArgumentDelegate.kt index 544b09119..113637107 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/delegates/ParcelableArgumentDelegate.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/delegates/ParcelableArgumentDelegate.kt @@ -5,7 +5,8 @@ import androidx.fragment.app.Fragment import kotlin.properties.ReadOnlyProperty import kotlin.reflect.KProperty -class ParcelableArgumentDelegate(private val name: String) : ReadOnlyProperty { +class ParcelableArgumentDelegate(private val name: String) : + ReadOnlyProperty { override fun getValue(thisRef: Fragment, property: KProperty<*>): T { return thisRef.requireArguments().getParcelable(name)!! diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/delegates/prefs/NullableStringPreferenceDelegate.kt b/app/src/main/java/org/koitharu/kotatsu/utils/delegates/prefs/NullableStringPreferenceDelegate.kt index e49dd1798..0b96447bc 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/delegates/prefs/NullableStringPreferenceDelegate.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/delegates/prefs/NullableStringPreferenceDelegate.kt @@ -5,7 +5,8 @@ import androidx.core.content.edit import kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty -class NullableStringPreferenceDelegate(private val key: String) : ReadWriteProperty { +class NullableStringPreferenceDelegate(private val key: String) : + ReadWriteProperty { override fun getValue(thisRef: SharedPreferences, property: KProperty<*>): String? { return thisRef.getString(key, null) diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/delegates/prefs/StringSetPreferenceDelegate.kt b/app/src/main/java/org/koitharu/kotatsu/utils/delegates/prefs/StringSetPreferenceDelegate.kt index 79adf259c..e1e0ed011 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/delegates/prefs/StringSetPreferenceDelegate.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/delegates/prefs/StringSetPreferenceDelegate.kt @@ -5,7 +5,10 @@ import androidx.core.content.edit import kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty -class StringSetPreferenceDelegate(private val key: String, private val defValue: Set = emptySet()) : +class StringSetPreferenceDelegate( + private val key: String, + private val defValue: Set = emptySet() +) : ReadWriteProperty> { override fun getValue(thisRef: SharedPreferences, property: KProperty<*>): Set { diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/CoroutineExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/CoroutineExt.kt index 50a29db9f..b1d147bde 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/CoroutineExt.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/CoroutineExt.kt @@ -1,5 +1,7 @@ package org.koitharu.kotatsu.utils.ext +import androidx.lifecycle.ProcessLifecycleOwner +import androidx.lifecycle.lifecycleScope import kotlinx.coroutines.* import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.onEach @@ -79,4 +81,7 @@ val IgnoreErrors if (BuildConfig.DEBUG) { e.printStackTrace() } - } \ No newline at end of file + } + +val processLifecycleScope: CoroutineScope + inline get() = ProcessLifecycleOwner.get().lifecycleScope \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/LiveDataExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/LiveDataExt.kt new file mode 100644 index 000000000..e19382be5 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/LiveDataExt.kt @@ -0,0 +1,13 @@ +package org.koitharu.kotatsu.utils.ext + +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.LiveData +import androidx.lifecycle.Observer + +fun LiveData.observeNotNull(owner: LifecycleOwner, observer: Observer) { + this.observe(owner) { + if (it != null) { + observer.onChanged(it) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/ViewExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/ViewExt.kt index 8f31764f8..f4e581995 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/ViewExt.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/ViewExt.kt @@ -22,7 +22,7 @@ import androidx.recyclerview.widget.RecyclerView import androidx.viewpager2.widget.ViewPager2 import com.google.android.material.chip.Chip import com.google.android.material.chip.ChipGroup -import org.koitharu.kotatsu.ui.base.ChipsFactory +import org.koitharu.kotatsu.core.ui.ChipsFactory fun View.hideKeyboard() { val imm = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/widget/WidgetUpdater.kt b/app/src/main/java/org/koitharu/kotatsu/widget/WidgetUpdater.kt similarity index 72% rename from app/src/main/java/org/koitharu/kotatsu/ui/widget/WidgetUpdater.kt rename to app/src/main/java/org/koitharu/kotatsu/widget/WidgetUpdater.kt index ac762dc3c..319e7a236 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/widget/WidgetUpdater.kt +++ b/app/src/main/java/org/koitharu/kotatsu/widget/WidgetUpdater.kt @@ -1,13 +1,13 @@ -package org.koitharu.kotatsu.ui.widget +package org.koitharu.kotatsu.widget import android.appwidget.AppWidgetManager import android.content.ComponentName import android.content.Context import android.content.Intent -import org.koitharu.kotatsu.domain.favourites.OnFavouritesChangeListener -import org.koitharu.kotatsu.domain.history.OnHistoryChangeListener -import org.koitharu.kotatsu.ui.widget.recent.RecentWidgetProvider -import org.koitharu.kotatsu.ui.widget.shelf.ShelfWidgetProvider +import org.koitharu.kotatsu.favourites.domain.OnFavouritesChangeListener +import org.koitharu.kotatsu.history.domain.OnHistoryChangeListener +import org.koitharu.kotatsu.widget.recent.RecentWidgetProvider +import org.koitharu.kotatsu.widget.shelf.ShelfWidgetProvider class WidgetUpdater(private val context: Context) : OnFavouritesChangeListener, OnHistoryChangeListener { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/widget/recent/RecentListFactory.kt b/app/src/main/java/org/koitharu/kotatsu/widget/recent/RecentListFactory.kt similarity index 87% rename from app/src/main/java/org/koitharu/kotatsu/ui/widget/recent/RecentListFactory.kt rename to app/src/main/java/org/koitharu/kotatsu/widget/recent/RecentListFactory.kt index 45ae59b7c..306cbdcfa 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/widget/recent/RecentListFactory.kt +++ b/app/src/main/java/org/koitharu/kotatsu/widget/recent/RecentListFactory.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.widget.recent +package org.koitharu.kotatsu.widget.recent import android.content.Context import android.content.Intent @@ -10,8 +10,8 @@ import coil.request.ImageRequest import kotlinx.coroutines.runBlocking import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.Manga -import org.koitharu.kotatsu.domain.history.HistoryRepository -import org.koitharu.kotatsu.ui.details.MangaDetailsActivity +import org.koitharu.kotatsu.details.ui.DetailsActivity +import org.koitharu.kotatsu.history.domain.HistoryRepository import org.koitharu.kotatsu.utils.ext.requireBitmap import java.io.IOException @@ -52,7 +52,7 @@ class RecentListFactory( views.setImageViewResource(R.id.imageView_cover, R.drawable.ic_placeholder) } val intent = Intent() - intent.putExtra(MangaDetailsActivity.EXTRA_MANGA_ID, item.id) + intent.putExtra(DetailsActivity.EXTRA_MANGA_ID, item.id) views.setOnClickFillInIntent(R.id.imageView_cover, intent) return views } diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/widget/recent/RecentWidgetProvider.kt b/app/src/main/java/org/koitharu/kotatsu/widget/recent/RecentWidgetProvider.kt similarity index 71% rename from app/src/main/java/org/koitharu/kotatsu/ui/widget/recent/RecentWidgetProvider.kt rename to app/src/main/java/org/koitharu/kotatsu/widget/recent/RecentWidgetProvider.kt index 25f2623e3..733885853 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/widget/recent/RecentWidgetProvider.kt +++ b/app/src/main/java/org/koitharu/kotatsu/widget/recent/RecentWidgetProvider.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.widget.recent +package org.koitharu.kotatsu.widget.recent import android.app.PendingIntent import android.appwidget.AppWidgetManager @@ -8,7 +8,7 @@ import android.content.Intent import android.net.Uri import android.widget.RemoteViews import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.ui.details.MangaDetailsActivity +import org.koitharu.kotatsu.details.ui.DetailsActivity class RecentWidgetProvider : AppWidgetProvider() { @@ -23,14 +23,16 @@ class RecentWidgetProvider : AppWidgetProvider() { adapter.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id) adapter.data = Uri.parse(adapter.toUri(Intent.URI_INTENT_SCHEME)) views.setRemoteAdapter(R.id.stackView, adapter) - val intent = Intent(context, MangaDetailsActivity::class.java) - intent.action = MangaDetailsActivity.ACTION_MANGA_VIEW - views.setPendingIntentTemplate(R.id.stackView, PendingIntent.getActivity( - context, - 0, - intent, - PendingIntent.FLAG_UPDATE_CURRENT - )) + val intent = Intent(context, DetailsActivity::class.java) + intent.action = DetailsActivity.ACTION_MANGA_VIEW + views.setPendingIntentTemplate( + R.id.stackView, PendingIntent.getActivity( + context, + 0, + intent, + PendingIntent.FLAG_UPDATE_CURRENT + ) + ) views.setEmptyView(R.id.stackView, R.id.textView_holder) appWidgetManager.updateAppWidget(id, views) } diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/widget/recent/RecentWidgetService.kt b/app/src/main/java/org/koitharu/kotatsu/widget/recent/RecentWidgetService.kt similarity index 85% rename from app/src/main/java/org/koitharu/kotatsu/ui/widget/recent/RecentWidgetService.kt rename to app/src/main/java/org/koitharu/kotatsu/widget/recent/RecentWidgetService.kt index 230c9e1f3..74e24e159 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/widget/recent/RecentWidgetService.kt +++ b/app/src/main/java/org/koitharu/kotatsu/widget/recent/RecentWidgetService.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.widget.recent +package org.koitharu.kotatsu.widget.recent import android.content.Intent import android.widget.RemoteViewsService diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/CategorySelectAdapter.kt b/app/src/main/java/org/koitharu/kotatsu/widget/shelf/CategorySelectAdapter.kt similarity index 82% rename from app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/CategorySelectAdapter.kt rename to app/src/main/java/org/koitharu/kotatsu/widget/shelf/CategorySelectAdapter.kt index f9b7dfcf1..98937d999 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/CategorySelectAdapter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/widget/shelf/CategorySelectAdapter.kt @@ -1,9 +1,9 @@ -package org.koitharu.kotatsu.ui.widget.shelf +package org.koitharu.kotatsu.widget.shelf import android.view.ViewGroup +import org.koitharu.kotatsu.base.ui.list.BaseRecyclerAdapter +import org.koitharu.kotatsu.base.ui.list.OnRecyclerItemClickListener import org.koitharu.kotatsu.core.model.FavouriteCategory -import org.koitharu.kotatsu.ui.base.list.BaseRecyclerAdapter -import org.koitharu.kotatsu.ui.base.list.OnRecyclerItemClickListener class CategorySelectAdapter(onItemClickListener: OnRecyclerItemClickListener? = null) : BaseRecyclerAdapter(onItemClickListener) { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/CategorySelectHolder.kt b/app/src/main/java/org/koitharu/kotatsu/widget/shelf/CategorySelectHolder.kt similarity index 82% rename from app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/CategorySelectHolder.kt rename to app/src/main/java/org/koitharu/kotatsu/widget/shelf/CategorySelectHolder.kt index 3e1871a5e..a36c7b4fc 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/CategorySelectHolder.kt +++ b/app/src/main/java/org/koitharu/kotatsu/widget/shelf/CategorySelectHolder.kt @@ -1,10 +1,10 @@ -package org.koitharu.kotatsu.ui.widget.shelf +package org.koitharu.kotatsu.widget.shelf import android.view.ViewGroup import kotlinx.android.synthetic.main.item_category_checkable.* import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.list.BaseViewHolder import org.koitharu.kotatsu.core.model.FavouriteCategory -import org.koitharu.kotatsu.ui.base.list.BaseViewHolder class CategorySelectHolder(parent: ViewGroup) : BaseViewHolder(parent, R.layout.item_category_checkable_single) { diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/ShelfConfigActivity.kt b/app/src/main/java/org/koitharu/kotatsu/widget/shelf/ShelfConfigActivity.kt similarity index 79% rename from app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/ShelfConfigActivity.kt rename to app/src/main/java/org/koitharu/kotatsu/widget/shelf/ShelfConfigActivity.kt index bd217cc04..97dbd0768 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/ShelfConfigActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/widget/shelf/ShelfConfigActivity.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.widget.shelf +package org.koitharu.kotatsu.widget.shelf import android.app.Activity import android.appwidget.AppWidgetManager @@ -14,22 +14,20 @@ import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.RecyclerView import com.google.android.material.snackbar.Snackbar import kotlinx.android.synthetic.main.activity_categories.* -import moxy.ktx.moxyPresenter +import org.koin.android.viewmodel.ext.android.viewModel import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.base.ui.BaseActivity +import org.koitharu.kotatsu.base.ui.list.OnRecyclerItemClickListener import org.koitharu.kotatsu.core.model.FavouriteCategory import org.koitharu.kotatsu.core.prefs.AppWidgetConfig -import org.koitharu.kotatsu.ui.base.BaseActivity -import org.koitharu.kotatsu.ui.base.list.OnRecyclerItemClickListener -import org.koitharu.kotatsu.ui.list.favourites.categories.FavouriteCategoriesPresenter -import org.koitharu.kotatsu.ui.list.favourites.categories.FavouriteCategoriesView +import org.koitharu.kotatsu.favourites.ui.categories.FavouritesCategoriesViewModel import org.koitharu.kotatsu.utils.ext.getDisplayMessage import java.util.* import kotlin.collections.ArrayList -class ShelfConfigActivity : BaseActivity(), FavouriteCategoriesView, - OnRecyclerItemClickListener { +class ShelfConfigActivity : BaseActivity(), OnRecyclerItemClickListener { - private val presenter by moxyPresenter(factory = ::FavouriteCategoriesPresenter) + private val viewModel by viewModel() private lateinit var adapter: CategorySelectAdapter private lateinit var config: AppWidgetConfig @@ -53,6 +51,9 @@ class ShelfConfigActivity : BaseActivity(), FavouriteCategoriesView, } config = AppWidgetConfig.getInstance(this, appWidgetId) adapter.setCheckedId(config.categoryId) + + viewModel.categories.observe(this, ::onCategoriesChanged) + viewModel.onError.observe(this, ::onError) } override fun onCreateOptionsMenu(menu: Menu?): Boolean { @@ -78,16 +79,14 @@ class ShelfConfigActivity : BaseActivity(), FavouriteCategoriesView, adapter.setCheckedId(item.id) } - override fun onCategoriesChanged(categories: List) { + private fun onCategoriesChanged(categories: List) { val data = ArrayList(categories.size + 1) data += FavouriteCategory(0L, getString(R.string.all_favourites), -1, Date()) data += categories adapter.replaceData(data) } - override fun onCheckedCategoriesChanged(checkedIds: Set) = Unit - - override fun onError(e: Throwable) { + private fun onError(e: Throwable) { Snackbar.make(recyclerView, e.getDisplayMessage(resources), Snackbar.LENGTH_LONG) .show() } diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/ShelfListFactory.kt b/app/src/main/java/org/koitharu/kotatsu/widget/shelf/ShelfListFactory.kt similarity index 89% rename from app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/ShelfListFactory.kt rename to app/src/main/java/org/koitharu/kotatsu/widget/shelf/ShelfListFactory.kt index f3b5b1e09..f32ce51a3 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/ShelfListFactory.kt +++ b/app/src/main/java/org/koitharu/kotatsu/widget/shelf/ShelfListFactory.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.widget.shelf +package org.koitharu.kotatsu.widget.shelf import android.content.Context import android.content.Intent @@ -11,8 +11,8 @@ import kotlinx.coroutines.runBlocking import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.prefs.AppWidgetConfig -import org.koitharu.kotatsu.domain.favourites.FavouritesRepository -import org.koitharu.kotatsu.ui.details.MangaDetailsActivity +import org.koitharu.kotatsu.details.ui.DetailsActivity +import org.koitharu.kotatsu.favourites.domain.FavouritesRepository import org.koitharu.kotatsu.utils.ext.requireBitmap import java.io.IOException @@ -63,7 +63,7 @@ class ShelfListFactory( views.setImageViewResource(R.id.imageView_cover, R.drawable.ic_placeholder) } val intent = Intent() - intent.putExtra(MangaDetailsActivity.EXTRA_MANGA_ID, item.id) + intent.putExtra(DetailsActivity.EXTRA_MANGA_ID, item.id) views.setOnClickFillInIntent(R.id.rootLayout, intent) return views } diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/ShelfWidgetProvider.kt b/app/src/main/java/org/koitharu/kotatsu/widget/shelf/ShelfWidgetProvider.kt similarity index 71% rename from app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/ShelfWidgetProvider.kt rename to app/src/main/java/org/koitharu/kotatsu/widget/shelf/ShelfWidgetProvider.kt index d84dcd882..5b92d7b8e 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/ShelfWidgetProvider.kt +++ b/app/src/main/java/org/koitharu/kotatsu/widget/shelf/ShelfWidgetProvider.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.widget.shelf +package org.koitharu.kotatsu.widget.shelf import android.app.PendingIntent import android.appwidget.AppWidgetManager @@ -8,7 +8,7 @@ import android.content.Intent import android.net.Uri import android.widget.RemoteViews import org.koitharu.kotatsu.R -import org.koitharu.kotatsu.ui.details.MangaDetailsActivity +import org.koitharu.kotatsu.details.ui.DetailsActivity class ShelfWidgetProvider : AppWidgetProvider() { @@ -23,14 +23,16 @@ class ShelfWidgetProvider : AppWidgetProvider() { adapter.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id) adapter.data = Uri.parse(adapter.toUri(Intent.URI_INTENT_SCHEME)) views.setRemoteAdapter(R.id.gridView, adapter) - val intent = Intent(context, MangaDetailsActivity::class.java) - intent.action = MangaDetailsActivity.ACTION_MANGA_VIEW - views.setPendingIntentTemplate(R.id.gridView, PendingIntent.getActivity( - context, - 0, - intent, - PendingIntent.FLAG_UPDATE_CURRENT - )) + val intent = Intent(context, DetailsActivity::class.java) + intent.action = DetailsActivity.ACTION_MANGA_VIEW + views.setPendingIntentTemplate( + R.id.gridView, PendingIntent.getActivity( + context, + 0, + intent, + PendingIntent.FLAG_UPDATE_CURRENT + ) + ) views.setEmptyView(R.id.gridView, R.id.textView_holder) appWidgetManager.updateAppWidget(id, views) } diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/ShelfWidgetService.kt b/app/src/main/java/org/koitharu/kotatsu/widget/shelf/ShelfWidgetService.kt similarity index 90% rename from app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/ShelfWidgetService.kt rename to app/src/main/java/org/koitharu/kotatsu/widget/shelf/ShelfWidgetService.kt index 1ad3032b5..3f590235a 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/widget/shelf/ShelfWidgetService.kt +++ b/app/src/main/java/org/koitharu/kotatsu/widget/shelf/ShelfWidgetService.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.ui.widget.shelf +package org.koitharu.kotatsu.widget.shelf import android.appwidget.AppWidgetManager import android.content.Intent diff --git a/app/src/main/res/layout/activity_details.xml b/app/src/main/res/layout/activity_details.xml index 52d7c02cb..7141a1c98 100644 --- a/app/src/main/res/layout/activity_details.xml +++ b/app/src/main/res/layout/activity_details.xml @@ -4,7 +4,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".ui.details.MangaDetailsActivity"> + tools:context=".details.ui.DetailsActivity"> - - - - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/item_source_config.xml b/app/src/main/res/layout/item_source_config.xml index 4d11f7735..b6a5b0e51 100644 --- a/app/src/main/res/layout/item_source_config.xml +++ b/app/src/main/res/layout/item_source_config.xml @@ -28,7 +28,7 @@ android:textColor="?android:attr/textColorPrimary" tools:text="@tools:sample/lorem[1]" /> - - @@ -124,7 +124,7 @@ app:iconSpaceReserved="false"> diff --git a/app/src/main/res/xml/widget_shelf.xml b/app/src/main/res/xml/widget_shelf.xml index 41c026cac..45c37262e 100644 --- a/app/src/main/res/xml/widget_shelf.xml +++ b/app/src/main/res/xml/widget_shelf.xml @@ -1,7 +1,7 @@