diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/MangaDao.kt b/app/src/main/java/org/koitharu/kotatsu/core/db/MangaDao.kt index 9a320b86d..e50a3a557 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/db/MangaDao.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/db/MangaDao.kt @@ -3,13 +3,15 @@ package org.koitharu.kotatsu.core.db import androidx.room.* import org.koitharu.kotatsu.core.db.entity.MangaEntity import org.koitharu.kotatsu.core.db.entity.MangaTagsEntity +import org.koitharu.kotatsu.core.db.entity.MangaWithTags import org.koitharu.kotatsu.core.db.entity.TagEntity @Dao abstract class MangaDao { - @Query("SELECT * FROM manga") - abstract suspend fun getAllManga(): List + @Transaction + @Query("SELECT * FROM manga WHERE manga_id = :id") + abstract suspend fun find(id: Long): MangaWithTags? @Insert(onConflict = OnConflictStrategy.IGNORE) abstract suspend fun insert(manga: MangaEntity): Long diff --git a/app/src/main/java/org/koitharu/kotatsu/core/db/entity/MangaWithTags.kt b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/MangaWithTags.kt new file mode 100644 index 000000000..922b0949a --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/core/db/entity/MangaWithTags.kt @@ -0,0 +1,20 @@ +package org.koitharu.kotatsu.core.db.entity + +import androidx.room.Embedded +import androidx.room.Junction +import androidx.room.Relation + +data class MangaWithTags( + @Embedded val manga: MangaEntity, + @Relation( + parentColumn = "manga_id", + entityColumn = "tag_id", + associateBy = Junction(MangaTagsEntity::class) + ) + val tags: List +) { + + fun toManga() = manga.toManga(tags.map { + it.toMangaTag() + }.toSet()) +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/core/exceptions/MangaNotFoundException.kt b/app/src/main/java/org/koitharu/kotatsu/core/exceptions/MangaNotFoundException.kt new file mode 100644 index 000000000..be892ea64 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/core/exceptions/MangaNotFoundException.kt @@ -0,0 +1,5 @@ +package org.koitharu.kotatsu.core.exceptions + +import java.lang.NullPointerException + +class MangaNotFoundException(s: String? = null) : RuntimeException(s) \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/domain/MangaPreferencesRepository.kt b/app/src/main/java/org/koitharu/kotatsu/domain/MangaDataRepository.kt similarity index 52% rename from app/src/main/java/org/koitharu/kotatsu/domain/MangaPreferencesRepository.kt rename to app/src/main/java/org/koitharu/kotatsu/domain/MangaDataRepository.kt index 72c261080..360aac965 100644 --- a/app/src/main/java/org/koitharu/kotatsu/domain/MangaPreferencesRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/domain/MangaDataRepository.kt @@ -3,14 +3,17 @@ package org.koitharu.kotatsu.domain import org.koin.core.KoinComponent import org.koin.core.inject import org.koitharu.kotatsu.core.db.MangaDatabase +import org.koitharu.kotatsu.core.db.entity.MangaEntity import org.koitharu.kotatsu.core.db.entity.MangaPrefsEntity +import org.koitharu.kotatsu.core.db.entity.TagEntity +import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.prefs.ReaderMode -class MangaPreferencesRepository : KoinComponent { +class MangaDataRepository : KoinComponent { private val db: MangaDatabase by inject() - suspend fun saveData(mangaId: Long, mode: ReaderMode) { + suspend fun savePreferences(mangaId: Long, mode: ReaderMode) { db.preferencesDao().upsert( MangaPrefsEntity( mangaId = mangaId, @@ -22,4 +25,12 @@ class MangaPreferencesRepository : KoinComponent { suspend fun getReaderMode(mangaId: Long): ReaderMode? { return db.preferencesDao().find(mangaId)?.let { ReaderMode.valueOf(it.mode) } } + + suspend fun findMangaById(mangaId: Long): Manga? { + return db.mangaDao().find(mangaId)?.toManga() + } + + suspend fun storeManga(manga: Manga) { + db.mangaDao().upsert(MangaEntity.from(manga), manga.tags.map(TagEntity.Companion::fromMangaTag)) + } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsActivity.kt b/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsActivity.kt index 378488cd6..7e9616e97 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsActivity.kt @@ -40,12 +40,13 @@ class MangaDetailsActivity : BaseActivity(), MangaDetailsView { supportActionBar?.setDisplayHomeAsUpEnabled(true) pager.adapter = MangaDetailsAdapter(resources, supportFragmentManager) tabs.setupWithViewPager(pager) - intent?.getParcelableExtra(EXTRA_MANGA)?.let { - presenter.loadDetails( - manga = it, - force = savedInstanceState?.containsKey(MvpDelegate.MOXY_DELEGATE_TAGS_KEY) != true - ) - } ?: finish() + if (savedInstanceState?.containsKey(MvpDelegate.MOXY_DELEGATE_TAGS_KEY) != true) { + intent?.getParcelableExtra(EXTRA_MANGA)?.let { + presenter.loadDetails(it, true) + } ?: intent?.getLongExtra(EXTRA_MANGA_ID, 0)?.takeUnless { it == 0L }?.let { + presenter.findMangaById(it) + } ?: finish() + } } override fun onMangaUpdated(manga: Manga) { @@ -69,7 +70,12 @@ class MangaDetailsActivity : BaseActivity(), MangaDetailsView { } override fun onError(e: Throwable) { - Snackbar.make(pager, e.getDisplayMessage(resources), Snackbar.LENGTH_LONG).show() + if (manga == null) { + Toast.makeText(this, e.getDisplayMessage(resources), Toast.LENGTH_LONG).show() + finish() + } else { + Snackbar.make(pager, e.getDisplayMessage(resources), Snackbar.LENGTH_LONG).show() + } } override fun onCreateOptionsMenu(menu: Menu?): Boolean { @@ -82,8 +88,8 @@ class MangaDetailsActivity : BaseActivity(), MangaDetailsView { manga?.source != null && manga?.source != MangaSource.LOCAL menu.findItem(R.id.action_delete).isVisible = manga?.source == MangaSource.LOCAL - menu.findItem(R.id.action_shortcut).isVisible = BuildConfig.DEBUG && - ShortcutManagerCompat.isRequestPinShortcutSupported(this) + menu.findItem(R.id.action_shortcut).isVisible = + ShortcutManagerCompat.isRequestPinShortcutSupported(this) return super.onPrepareOptionsMenu(menu) } @@ -142,11 +148,16 @@ class MangaDetailsActivity : BaseActivity(), MangaDetailsView { companion object { private const val EXTRA_MANGA = "manga" + private const val EXTRA_MANGA_ID = "manga_id" const val ACTION_MANGA_VIEW = "${BuildConfig.APPLICATION_ID}.action.VIEW_MANGA" fun newIntent(context: Context, manga: Manga) = Intent(context, MangaDetailsActivity::class.java) .putExtra(EXTRA_MANGA, manga) + + fun newIntent(context: Context, mangaId: Long) = + Intent(context, MangaDetailsActivity::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/MangaDetailsPresenter.kt b/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsPresenter.kt index 3376c25dd..bae4c74a6 100644 --- a/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsPresenter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/ui/details/MangaDetailsPresenter.kt @@ -7,9 +7,11 @@ import kotlinx.coroutines.withContext import moxy.InjectViewState import moxy.presenterScope import org.koitharu.kotatsu.BuildConfig +import org.koitharu.kotatsu.core.exceptions.MangaNotFoundException import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.core.parser.LocalMangaRepository +import org.koitharu.kotatsu.domain.MangaDataRepository import org.koitharu.kotatsu.domain.MangaProviderFactory import org.koitharu.kotatsu.domain.favourites.FavouritesRepository import org.koitharu.kotatsu.domain.favourites.OnFavouritesChangeListener @@ -37,6 +39,27 @@ class MangaDetailsPresenter private constructor() : BasePresenter() { ?: throw RuntimeException("Chapter ${chapterId} not found") val pages = repo.getPages(chapter) if (!isInitialized) { - val prefs = MangaPreferencesRepository() + val prefs = MangaDataRepository() var mode = prefs.getReaderMode(manga.id) if (mode == null) { mode = MangaUtils.determineReaderMode(pages) if (mode != null) { - prefs.saveData( + prefs.savePreferences( mangaId = manga.id, mode = mode ) @@ -84,7 +84,7 @@ class ReaderPresenter : BasePresenter() { page = state.page ) if (mode != null) { - MangaPreferencesRepository().saveData( + MangaDataRepository().savePreferences( mangaId = state.manga.id, mode = mode ) diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ShortcutUtils.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ShortcutUtils.kt index dae106504..19ac3ffd6 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ShortcutUtils.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ShortcutUtils.kt @@ -12,6 +12,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.koitharu.kotatsu.R import org.koitharu.kotatsu.core.model.Manga +import org.koitharu.kotatsu.domain.MangaDataRepository import org.koitharu.kotatsu.ui.details.MangaDetailsActivity import org.koitharu.kotatsu.utils.ext.safe @@ -27,6 +28,7 @@ object ShortcutUtils { }.toBitmap() } } + MangaDataRepository().storeManga(manga) return ShortcutInfoCompat.Builder(context, manga.id.toString()) .setShortLabel(manga.title) .setLongLabel(manga.title) @@ -34,7 +36,7 @@ object ShortcutUtils { IconCompat.createWithBitmap(it) } ?: IconCompat.createWithResource(context, R.drawable.ic_launcher_foreground)) .setIntent( - MangaDetailsActivity.newIntent(context, manga.copy(chapters = null)) + MangaDetailsActivity.newIntent(context, manga.id) .setAction(MangaDetailsActivity.ACTION_MANGA_VIEW) ) .build()