Skip to content

Commit

Permalink
Improve scrobbling selection
Browse files Browse the repository at this point in the history
  • Loading branch information
Koitharu committed Jan 17, 2024
1 parent 18e573b commit 48808f8
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 22 deletions.
11 changes: 11 additions & 0 deletions app/src/main/kotlin/org/koitharu/kotatsu/core/util/ext/View.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ import androidx.core.view.descendants
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import androidx.swiperefreshlayout.widget.CircularProgressDrawable
import androidx.viewpager2.widget.ViewPager2
import com.google.android.material.button.MaterialButton
import com.google.android.material.progressindicator.BaseProgressIndicator
import com.google.android.material.slider.Slider
import com.google.android.material.tabs.TabLayout
Expand Down Expand Up @@ -161,3 +163,12 @@ val Toolbar.menuView: ActionMenuView?
menu // to call ensureMenu()
return children.firstNotNullOfOrNull { it as? ActionMenuView }
}

fun MaterialButton.setProgressIcon() {
val progressDrawable = CircularProgressDrawable(context)
progressDrawable.strokeWidth = resources.resolveDp(2f)
progressDrawable.setColorSchemeColors(currentTextColor)
progressDrawable.setTintList(textColors)
icon = progressDrawable
progressDrawable.start()
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package org.koitharu.kotatsu.explore.ui.adapter

import android.graphics.Color
import android.view.View
import androidx.lifecycle.LifecycleOwner
import androidx.swiperefreshlayout.widget.CircularProgressDrawable
import coil.ImageLoader
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
import org.koitharu.kotatsu.R
Expand All @@ -15,10 +13,9 @@ import org.koitharu.kotatsu.core.ui.image.TrimTransformation
import org.koitharu.kotatsu.core.ui.list.AdapterDelegateClickListenerAdapter
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
import org.koitharu.kotatsu.core.util.ext.enqueueWith
import org.koitharu.kotatsu.core.util.ext.getThemeColor
import org.koitharu.kotatsu.core.util.ext.newImageRequest
import org.koitharu.kotatsu.core.util.ext.resolveDp
import org.koitharu.kotatsu.core.util.ext.setOnContextClickListenerCompat
import org.koitharu.kotatsu.core.util.ext.setProgressIcon
import org.koitharu.kotatsu.core.util.ext.source
import org.koitharu.kotatsu.core.util.ext.textAndVisible
import org.koitharu.kotatsu.databinding.ItemExploreButtonsBinding
Expand All @@ -30,7 +27,6 @@ import org.koitharu.kotatsu.explore.ui.model.MangaSourceItem
import org.koitharu.kotatsu.explore.ui.model.RecommendationsItem
import org.koitharu.kotatsu.list.ui.model.ListModel
import org.koitharu.kotatsu.parsers.model.Manga
import com.google.android.material.R as materialR

fun exploreButtonsAD(
clickListener: View.OnClickListener,
Expand All @@ -45,16 +41,7 @@ fun exploreButtonsAD(

bind {
if (item.isRandomLoading) {
val icon = CircularProgressDrawable(context)
icon.strokeWidth = context.resources.resolveDp(2f)
icon.setColorSchemeColors(
context.getThemeColor(
materialR.attr.colorPrimary,
Color.DKGRAY,
),
)
binding.buttonRandom.icon = icon
icon.start()
binding.buttonRandom.setProgressIcon()
} else {
binding.buttonRandom.setIconResource(R.drawable.ic_dice)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.koitharu.kotatsu.scrobbling.common.domain

import androidx.annotation.FloatRange
import androidx.collection.LongSparseArray
import androidx.collection.getOrElse
import androidx.core.text.parseAsHtml
Expand All @@ -11,23 +12,24 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map
import org.koitharu.kotatsu.core.db.MangaDatabase
import org.koitharu.kotatsu.core.util.ext.findKeyByValue
import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
import org.koitharu.kotatsu.core.util.ext.sanitize
import org.koitharu.kotatsu.parsers.model.MangaChapter
import org.koitharu.kotatsu.parsers.util.runCatchingCancellable
import org.koitharu.kotatsu.scrobbling.common.data.ScrobblerRepository
import org.koitharu.kotatsu.scrobbling.common.data.ScrobblingEntity
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerManga
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerMangaInfo
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerService
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerUser
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblingInfo
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblingStatus
import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
import java.util.EnumMap

abstract class Scrobbler(
protected val db: MangaDatabase,
val scrobblerService: ScrobblerService,
private val repository: org.koitharu.kotatsu.scrobbling.common.data.ScrobblerRepository,
private val repository: ScrobblerRepository,
) {

private val infoCache = LongSparseArray<ScrobblerMangaInfo>()
Expand Down Expand Up @@ -76,7 +78,12 @@ abstract class Scrobbler(
return entity.toScrobblingInfo()
}

abstract suspend fun updateScrobblingInfo(mangaId: Long, rating: Float, status: ScrobblingStatus?, comment: String?)
abstract suspend fun updateScrobblingInfo(
mangaId: Long,
@FloatRange(from = 0.0, to = 1.0) rating: Float,
status: ScrobblingStatus?,
comment: String?,
)

fun observeScrobblingInfo(mangaId: Long): Flow<ScrobblingInfo?> {
return db.getScrobblingDao().observe(scrobblerService.id, mangaId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import org.koitharu.kotatsu.core.util.ext.firstVisibleItemPosition
import org.koitharu.kotatsu.core.util.ext.getDisplayMessage
import org.koitharu.kotatsu.core.util.ext.observe
import org.koitharu.kotatsu.core.util.ext.observeEvent
import org.koitharu.kotatsu.core.util.ext.setProgressIcon
import org.koitharu.kotatsu.core.util.ext.setTabsEnabled
import org.koitharu.kotatsu.core.util.ext.withArgs
import org.koitharu.kotatsu.databinding.SheetScrobblingSelectorBinding
import org.koitharu.kotatsu.list.ui.adapter.ListStateHolderListener
Expand Down Expand Up @@ -80,6 +82,15 @@ class ScrobblingSelectorSheet :
viewModel.onClose.observeEvent(viewLifecycleOwner) {
dismiss()
}
viewModel.isLoading.observe(viewLifecycleOwner) { isLoading ->
binding.buttonDone.isEnabled = !isLoading
if (isLoading) {
binding.buttonDone.setProgressIcon()
} else {
binding.buttonDone.icon = null
}
binding.tabs.setTabsEnabled(!isLoading)
}
viewModel.selectedScrobblerIndex.observe(viewLifecycleOwner) { index ->
val tab = binding.tabs.getTabAt(index)
if (tab != null && !tab.isSelected) {
Expand All @@ -100,7 +111,7 @@ class ScrobblingSelectorSheet :
}

override fun onItemClick(item: ScrobblerManga, view: View) {
viewModel.selectedItemId.value = item.id
viewModel.selectItem(item.id)
}

override fun onRetryClick(error: Throwable) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,33 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.plus
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.model.findById
import org.koitharu.kotatsu.core.model.parcelable.ParcelableManga
import org.koitharu.kotatsu.core.parser.MangaIntent
import org.koitharu.kotatsu.core.parser.MangaRepository
import org.koitharu.kotatsu.core.ui.BaseViewModel
import org.koitharu.kotatsu.core.util.ext.MutableEventFlow
import org.koitharu.kotatsu.core.util.ext.call
import org.koitharu.kotatsu.core.util.ext.printStackTraceDebug
import org.koitharu.kotatsu.core.util.ext.require
import org.koitharu.kotatsu.core.util.ext.requireValue
import org.koitharu.kotatsu.history.data.HistoryRepository
import org.koitharu.kotatsu.list.ui.model.ListModel
import org.koitharu.kotatsu.list.ui.model.LoadingFooter
import org.koitharu.kotatsu.list.ui.model.LoadingState
import org.koitharu.kotatsu.parsers.util.runCatchingCancellable
import org.koitharu.kotatsu.scrobbling.common.domain.Scrobbler
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblerManga
import org.koitharu.kotatsu.scrobbling.common.domain.model.ScrobblingStatus
import org.koitharu.kotatsu.scrobbling.common.ui.selector.model.ScrobblerHint
import javax.inject.Inject

@HiltViewModel
class ScrobblingSelectorViewModel @Inject constructor(
savedStateHandle: SavedStateHandle,
scrobblers: Set<@JvmSuppressWildcards Scrobbler>,
private val historyRepository: HistoryRepository,
private val mangaRepositoryFactory: MangaRepository.Factory,
) : BaseViewModel() {

val manga = savedStateHandle.require<ParcelableManga>(MangaIntent.KEY_MANGA).manga
Expand Down Expand Up @@ -92,6 +98,13 @@ class ScrobblingSelectorViewModel @Inject constructor(
loadList(append = false)
}

fun selectItem(id: Long) {
if (doneJob?.isActive == true) {
return
}
selectedItemId.value = id
}

fun loadNextPage() {
if (scrobblerMangaList.value.isNotEmpty() && hasNextPage.value) {
loadList(append = true)
Expand All @@ -109,7 +122,7 @@ class ScrobblingSelectorViewModel @Inject constructor(
if (loadingJob?.isActive == true) {
return
}
loadingJob = launchLoadingJob(Dispatchers.Default) {
loadingJob = launchJob(Dispatchers.Default) {
listError.value = null
val offset = if (append) scrobblerMangaList.value.size else 0
runCatchingCancellable {
Expand All @@ -136,8 +149,31 @@ class ScrobblingSelectorViewModel @Inject constructor(
if (targetId == NO_ID) {
onClose.call(Unit)
}
doneJob = launchJob(Dispatchers.Default) {
doneJob = launchLoadingJob(Dispatchers.Default) {
val prevInfo = currentScrobbler.getScrobblingInfoOrNull(manga.id)
currentScrobbler.linkManga(manga.id, targetId)
val history = historyRepository.getOne(manga)
currentScrobbler.updateScrobblingInfo(
mangaId = manga.id,
rating = prevInfo?.rating ?: manga.rating,
status = prevInfo?.status ?: if (history == null) {
ScrobblingStatus.PLANNED
} else {
ScrobblingStatus.READING
},
comment = prevInfo?.comment,
)
if (history != null) {
val chapter = mangaRepositoryFactory.create(manga.source)
.getDetails(manga)
.chapters?.findById(history.chapterId)
if (chapter != null) {
currentScrobbler.scrobble(
mangaId = manga.id,
chapter = chapter,
)
}
}
onClose.call(Unit)
}
}
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/layout/sheet_scrobbling_selector.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
app:tabMode="scrollable"
tools:ignore="UnusedAttribute" />

<Button
<com.google.android.material.button.MaterialButton
android:id="@+id/button_done"
style="@style/Widget.Material3.Button.UnelevatedButton"
android:layout_width="wrap_content"
Expand Down

0 comments on commit 48808f8

Please sign in to comment.