From 033e4f205d27cd8f65abf30dd0baeec9a647ea10 Mon Sep 17 00:00:00 2001 From: Jay Date: Sat, 8 Feb 2020 06:04:56 -0800 Subject: [PATCH] Fixed library sorting not updating while library updating in progress --- .../data/database/queries/MangaQueries.kt | 18 +++++++++++- .../data/database/queries/RawQueries.kt | 21 ++++++++++++++ .../data/library/LibraryUpdateService.kt | 15 +++++----- .../tachiyomi/ui/library/LibraryController.kt | 4 +-- .../tachiyomi/ui/library/LibraryPresenter.kt | 28 ++++++++----------- .../ui/library/filter/FilterBottomSheet.kt | 22 ++++++++++++--- .../kanade/tachiyomi/ui/main/MainActivity.kt | 15 +++++----- .../res/drawable/bg_bottom_sheet_primary.xml | 8 ++++++ .../main/res/layout/filter_bottom_sheet.xml | 5 ++-- .../main/res/layout/library_controller.xml | 2 +- app/src/main/res/menu/library_selection.xml | 6 ++-- 11 files changed, 97 insertions(+), 47 deletions(-) create mode 100644 app/src/main/res/drawable/bg_bottom_sheet_primary.xml diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/MangaQueries.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/MangaQueries.kt index 22d21cafc4..58cda2fe1e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/MangaQueries.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/MangaQueries.kt @@ -6,7 +6,14 @@ import com.pushtorefresh.storio.sqlite.queries.RawQuery import eu.kanade.tachiyomi.data.database.DbProvider import eu.kanade.tachiyomi.data.database.models.LibraryManga import eu.kanade.tachiyomi.data.database.models.Manga -import eu.kanade.tachiyomi.data.database.resolvers.* +import eu.kanade.tachiyomi.data.database.resolvers.LibraryMangaGetResolver +import eu.kanade.tachiyomi.data.database.resolvers.MangaFavoritePutResolver +import eu.kanade.tachiyomi.data.database.resolvers.MangaFlagsPutResolver +import eu.kanade.tachiyomi.data.database.resolvers.MangaHideTitlePutResolver +import eu.kanade.tachiyomi.data.database.resolvers.MangaInfoPutResolver +import eu.kanade.tachiyomi.data.database.resolvers.MangaLastUpdatedPutResolver +import eu.kanade.tachiyomi.data.database.resolvers.MangaTitlePutResolver +import eu.kanade.tachiyomi.data.database.resolvers.MangaViewerPutResolver import eu.kanade.tachiyomi.data.database.tables.CategoryTable import eu.kanade.tachiyomi.data.database.tables.ChapterTable import eu.kanade.tachiyomi.data.database.tables.MangaCategoryTable @@ -30,6 +37,15 @@ interface MangaQueries : DbProvider { .withGetResolver(LibraryMangaGetResolver.INSTANCE) .prepare() + fun getLibraryManga(id: Long) = db.get() + .`object`(LibraryManga::class.java) + .withQuery(RawQuery.builder() + .query(getLibraryMangaQuery(id)) + .observesTables(MangaTable.TABLE, ChapterTable.TABLE, MangaCategoryTable.TABLE, CategoryTable.TABLE) + .build()) + .withGetResolver(LibraryMangaGetResolver.INSTANCE) + .prepare() + fun getFavoriteMangas() = db.get() .listOfObjects(Manga::class.java) .withQuery(Query.builder() diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/RawQueries.kt b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/RawQueries.kt index 1c532948f3..ac63517686 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/RawQueries.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/database/queries/RawQueries.kt @@ -30,6 +30,27 @@ val libraryQuery = """ ON MC.${MangaCategory.COL_MANGA_ID} = M.${Manga.COL_ID} """ +fun getLibraryMangaQuery(id: Long) = """ + SELECT M.*, COALESCE(MC.${MangaCategory.COL_CATEGORY_ID}, 0) AS ${Manga.COL_CATEGORY} + FROM ( + SELECT ${Manga.TABLE}.*, COALESCE(C.unread, 0) AS ${Manga.COL_UNREAD} + FROM ${Manga.TABLE} + LEFT JOIN ( + SELECT ${Chapter.COL_MANGA_ID}, COUNT(*) AS unread + FROM ${Chapter.TABLE} + WHERE ${Chapter.COL_READ} = 0 + GROUP BY ${Chapter.COL_MANGA_ID} + ) AS C + ON ${Manga.COL_ID} = C.${Chapter.COL_MANGA_ID} + WHERE ${Manga.COL_FAVORITE} = 1 AND ${Manga.COL_ID} = $id + GROUP BY ${Manga.COL_ID} + ORDER BY ${Manga.COL_TITLE} + ) AS M + LEFT JOIN ( + SELECT * FROM ${MangaCategory.TABLE}) AS MC + ON MC.${MangaCategory.COL_MANGA_ID} = M.${Manga.COL_ID} +""" + /** * Query to get the recent chapters of manga from the library up to a date. */ diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt index 439c1ebebe..418e47ea35 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt @@ -22,7 +22,6 @@ import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.MangaImpl import eu.kanade.tachiyomi.data.download.DownloadManager import eu.kanade.tachiyomi.data.download.DownloadService -import eu.kanade.tachiyomi.data.download.DownloadServiceListener import eu.kanade.tachiyomi.data.glide.GlideApp import eu.kanade.tachiyomi.data.library.LibraryUpdateRanker.rankingScheme import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Companion.start @@ -53,7 +52,6 @@ import rx.schedulers.Schedulers import timber.log.Timber import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get -import uy.kohesive.injekt.injectLazy import java.util.ArrayList import java.util.Date import java.util.concurrent.TimeUnit @@ -368,15 +366,16 @@ class LibraryUpdateService( emptyList() } if (fetchedChapters.isNotEmpty()) { - val newChapters = syncChaptersWithSource(db, fetchedChapters, manga, source).first - listener?.updatedManga(manga) - if (newChapters.isNotEmpty()) { + val newChapters = syncChaptersWithSource(db, fetchedChapters, manga, source) + if (newChapters.first.isNotEmpty()) { if (downloadNew && (categoriesToDownload.isEmpty() || manga.category in categoriesToDownload)) { - downloadChapters(manga, newChapters.sortedBy { it.chapter_number }) + downloadChapters(manga, newChapters.first.sortedBy { it.chapter_number }) hasDownloads = true } - newUpdates.add(manga to newChapters.sortedBy { it.chapter_number }.toTypedArray()) + newUpdates.add(manga to newChapters.first.sortedBy { it.chapter_number }.toTypedArray()) } + if (newChapters.first.size + newChapters.second.size > 0) + listener?.onUpdateManga(manga) } } if (newUpdates.isNotEmpty()) { @@ -609,5 +608,5 @@ class LibraryUpdateService( } interface LibraryServiceListener { - fun updatedManga(manga: LibraryManga) + fun onUpdateManga(manga: LibraryManga) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt index b5c71b6083..e41110683c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt @@ -222,7 +222,7 @@ class LibraryController( if (MainActivity.bottomNav) { bottom_sheet.onCreate(pager_layout) - bottom_sheet?.onGroupClicked = { + bottom_sheet.onGroupClicked = { when (it) { FilterBottomSheet.ACTION_REFRESH -> onRefresh() FilterBottomSheet.ACTION_FILTER -> onFilterChanged() @@ -304,7 +304,7 @@ class LibraryController( } } - override fun updatedManga(manga: LibraryManga) { + override fun onUpdateManga(manga: LibraryManga) { presenter.updateManga(manga) } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt index 8a096ff91a..68aa97e292 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt @@ -1,7 +1,6 @@ package eu.kanade.tachiyomi.ui.library import android.os.Bundle -import com.jakewharton.rxrelay.BehaviorRelay import eu.kanade.tachiyomi.data.cache.CoverCache import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.models.Category @@ -30,8 +29,6 @@ import eu.kanade.tachiyomi.ui.base.presenter.BasePresenter import eu.kanade.tachiyomi.ui.main.MainActivity import eu.kanade.tachiyomi.ui.migration.MigrationFlags import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource -import eu.kanade.tachiyomi.util.lang.combineLatest -import eu.kanade.tachiyomi.util.lang.isNullOrUnsubscribed import eu.kanade.tachiyomi.util.lang.removeArticles import eu.kanade.tachiyomi.util.system.launchUI import eu.kanade.tachiyomi.widget.ExtendedNavigationView.Item.TriStateGroup.Companion.STATE_EXCLUDE @@ -44,7 +41,6 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import rx.Observable -import rx.Subscription import rx.android.schedulers.AndroidSchedulers import rx.schedulers.Schedulers import uy.kohesive.injekt.Injekt @@ -600,19 +596,17 @@ class LibraryPresenter( GlobalScope.launch(Dispatchers.IO, CoroutineStart.DEFAULT) { val rawMap = rawMangaMap ?: return@launch val currentMap = currentMangaMap ?: return@launch - rawMap.apply { - forEach { - it.value.forEach { item -> - if (item.manga.id == manga.id) - item.manga.unread = manga.unread - } - } - } - currentMap.apply { - forEach { - it.value.forEach { item -> - if (item.manga.id == manga.id) - item.manga.unread = manga.unread + val id = manga.id ?: return@launch + val dbManga = db.getLibraryManga(id).executeAsBlocking() ?: return@launch + arrayOf(rawMap, currentMap).forEach { map -> + map.apply { + forEach { entry -> + entry.value.forEach { item -> + if (item.manga.id == dbManga.id) { + item.manga.last_update = dbManga.last_update + item.manga.unread = dbManga.unread + } + } } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/filter/FilterBottomSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/filter/FilterBottomSheet.kt index e3febf841f..4361b3a289 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/filter/FilterBottomSheet.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/filter/FilterBottomSheet.kt @@ -112,13 +112,14 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri pager = pagerView updateTitle() - val shadow:View = (pagerView.parent as ViewGroup).findViewById(R.id.shadow2) + val shadow2:View = (pagerView.parent as ViewGroup).findViewById(R.id.shadow2) + val shadow:View = (pagerView.parent as ViewGroup).findViewById(R.id.shadow) val coordLayout:View = (pagerView.parent as ViewGroup).findViewById(R.id.snackbar_layout) sheetBehavior?.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() { override fun onSlide(bottomSheet: View, progress: Float) { updateRootPadding(progress) topbar.alpha = 1 - progress - shadow.alpha = (1 - progress) * 0.25f + shadow2.alpha = (1 - progress) * 0.25f } override fun onStateChanged(p0: View, state: Int) { @@ -129,10 +130,23 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri } }) topbar.viewTreeObserver.addOnGlobalLayoutListener { - sheetBehavior?.peekHeight = topbar.height + val phoneLandscape = (context.resources.configuration?.orientation == + Configuration.ORIENTATION_LANDSCAPE && !isTablet()) + sheetBehavior?.peekHeight = if (phoneLandscape) { + if (shadow2.visibility != View.GONE) { + shadow.gone() + shadow2.gone() + } + 0 + } + else if (!sortText.text.isNullOrBlank()) { + topbar.height + } + else 0 if (sheetBehavior?.state == BottomSheetBehavior.STATE_COLLAPSED) { val height = context.resources.getDimensionPixelSize(R.dimen.rounder_radius) - pager?.setPadding(0, 0, 0, topbar.height - height) + pager?.setPadding(0, 0, 0, if (phoneLandscape) 0 else + (topbar.height - height)) coordLayout.setPadding(0, 0, 0, topbar.height) } else { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt index 0bce943dab..507d9c569f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt @@ -20,7 +20,6 @@ import androidx.appcompat.graphics.drawable.DrawerArrowDrawable import androidx.biometric.BiometricManager import androidx.core.graphics.ColorUtils import androidx.core.view.GravityCompat -import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat import com.bluelinelabs.conductor.Conductor import com.bluelinelabs.conductor.Controller import com.bluelinelabs.conductor.ControllerChangeHandler @@ -28,7 +27,6 @@ import com.bluelinelabs.conductor.Router import com.bluelinelabs.conductor.RouterTransaction import com.bluelinelabs.conductor.changehandler.FadeChangeHandler import com.bluelinelabs.conductor.changehandler.SimpleSwapChangeHandler -import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.snackbar.Snackbar import eu.kanade.tachiyomi.Migrations import eu.kanade.tachiyomi.R @@ -53,7 +51,6 @@ import eu.kanade.tachiyomi.ui.library.LibraryController import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.recent_updates.RecentChaptersController import eu.kanade.tachiyomi.ui.recently_read.RecentlyReadController -import eu.kanade.tachiyomi.ui.setting.SettingsDownloadController import eu.kanade.tachiyomi.ui.setting.SettingsMainController import eu.kanade.tachiyomi.util.system.getResourceColor import eu.kanade.tachiyomi.util.system.launchUI @@ -338,18 +335,20 @@ open class MainActivity : BaseActivity(), DownloadServiceListener { } override fun startSupportActionMode(callback: androidx.appcompat.view.ActionMode.Callback): androidx.appcompat.view.ActionMode? { - window?.statusBarColor = getResourceColor(R.attr.colorPrimary) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ) + window?.statusBarColor = getResourceColor(R.attr.colorPrimary) return super.startSupportActionMode(callback) } override fun onSupportActionModeFinished(mode: androidx.appcompat.view.ActionMode) { - launchUI { - val scale = Settings.Global.getFloat(contentResolver, Settings.Global - .ANIMATOR_DURATION_SCALE, 1.0f) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) launchUI { + val scale = Settings.Global.getFloat( + contentResolver, Settings.Global.ANIMATOR_DURATION_SCALE, 1.0f + ) val duration = resources.getInteger(android.R.integer.config_mediumAnimTime) * scale delay(duration.toLong()) delay(100) - window?.statusBarColor = Color.TRANSPARENT + window?.statusBarColor = getResourceColor(android.R.attr.statusBarColor) } super.onSupportActionModeFinished(mode) } diff --git a/app/src/main/res/drawable/bg_bottom_sheet_primary.xml b/app/src/main/res/drawable/bg_bottom_sheet_primary.xml new file mode 100644 index 0000000000..76060c00a3 --- /dev/null +++ b/app/src/main/res/drawable/bg_bottom_sheet_primary.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/filter_bottom_sheet.xml b/app/src/main/res/layout/filter_bottom_sheet.xml index 201338b95d..0675449787 100644 --- a/app/src/main/res/layout/filter_bottom_sheet.xml +++ b/app/src/main/res/layout/filter_bottom_sheet.xml @@ -4,6 +4,7 @@ android:id="@+id/bottom_sheet" style="@style/BottomSheetDialogTheme" android:layout_width="match_parent" + app:behavior_peekHeight="0dp" android:layout_height="wrap_content" android:background="@drawable/bg_bottom_sheet_dialog_fragment" android:clickable="true" @@ -187,8 +188,7 @@ android:id="@+id/topbar" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@drawable/bg_bottom_sheet_dialog_fragment" - android:backgroundTint="?android:attr/colorPrimary" + android:background="@drawable/bg_bottom_sheet_primary" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> @@ -212,7 +212,6 @@ android:layout_marginTop="15dp" android:layout_marginEnd="8dp" android:layout_marginBottom="15dp" - android:text="Filter & Sort" android:textAlignment="textStart" android:textAppearance="@style/TextAppearance.MaterialComponents.Body1" android:textColor="?attr/actionBarTintColor" diff --git a/app/src/main/res/layout/library_controller.xml b/app/src/main/res/layout/library_controller.xml index 54ec27a15e..277a95d24b 100644 --- a/app/src/main/res/layout/library_controller.xml +++ b/app/src/main/res/layout/library_controller.xml @@ -37,7 +37,7 @@ app:layout_anchorGravity="top" app:layout_anchor="@id/bottom_sheet" /> - + + android:title="@string/action_remove" + android:icon="@drawable/ic_delete_white_24dp" + app:showAsAction="ifRoom"/>