From 4d7ff5f6cc270891b386f3a854d13401cec103f6 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Thu, 11 Apr 2024 10:19:32 +0300 Subject: [PATCH] Tracker debug info --- app/build.gradle | 6 +- app/src/debug/AndroidManifest.xml | 12 +++ .../kotatsu/tracker/ui/debug/TrackDebugAD.kt | 73 +++++++++++++++++++ .../tracker/ui/debug/TrackDebugItem.kt | 19 +++++ .../tracker/ui/debug/TrackerDebugActivity.kt | 57 +++++++++++++++ .../tracker/ui/debug/TrackerDebugViewModel.kt | 36 +++++++++ .../res/layout/activity_tracker_debug.xml | 44 +++++++++++ app/src/debug/res/layout/item_track_debug.xml | 56 ++++++++++++++ app/src/debug/res/menu/opt_settings.xml | 7 +- .../kotatsu/settings/SettingsActivity.kt | 7 ++ .../kotatsu/tracker/data/TracksDao.kt | 4 + .../kotatsu/tracker/work/TrackWorker.kt | 8 +- app/src/main/res/values/ids.xml | 1 + 13 files changed, 323 insertions(+), 7 deletions(-) create mode 100644 app/src/debug/AndroidManifest.xml create mode 100644 app/src/debug/kotlin/org/koitharu/kotatsu/tracker/ui/debug/TrackDebugAD.kt create mode 100644 app/src/debug/kotlin/org/koitharu/kotatsu/tracker/ui/debug/TrackDebugItem.kt create mode 100644 app/src/debug/kotlin/org/koitharu/kotatsu/tracker/ui/debug/TrackerDebugActivity.kt create mode 100644 app/src/debug/kotlin/org/koitharu/kotatsu/tracker/ui/debug/TrackerDebugViewModel.kt create mode 100644 app/src/debug/res/layout/activity_tracker_debug.xml create mode 100644 app/src/debug/res/layout/item_track_debug.xml diff --git a/app/build.gradle b/app/build.gradle index a414ebf4b..22cc5695f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,8 +16,8 @@ android { applicationId 'org.koitharu.kotatsu' minSdk = 21 targetSdk = 34 - versionCode = 633 - versionName = '6.8.3' + versionCode = 634 + versionName = '7.0-a1' generatedDensities = [] testInstrumentationRunner 'org.koitharu.kotatsu.HiltTestRunner' ksp { @@ -104,7 +104,7 @@ dependencies { implementation 'androidx.viewpager2:viewpager2:1.1.0-beta02' implementation 'androidx.preference:preference-ktx:1.2.1' implementation 'androidx.biometric:biometric-ktx:1.2.0-alpha05' - implementation 'com.google.android.material:material:1.12.0-beta01' + implementation 'com.google.android.material:material:1.12.0-rc01' implementation 'androidx.lifecycle:lifecycle-common-java8:2.7.0' implementation 'androidx.webkit:webkit:1.10.0' diff --git a/app/src/debug/AndroidManifest.xml b/app/src/debug/AndroidManifest.xml new file mode 100644 index 000000000..5b4f937ef --- /dev/null +++ b/app/src/debug/AndroidManifest.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/app/src/debug/kotlin/org/koitharu/kotatsu/tracker/ui/debug/TrackDebugAD.kt b/app/src/debug/kotlin/org/koitharu/kotatsu/tracker/ui/debug/TrackDebugAD.kt new file mode 100644 index 000000000..596669443 --- /dev/null +++ b/app/src/debug/kotlin/org/koitharu/kotatsu/tracker/ui/debug/TrackDebugAD.kt @@ -0,0 +1,73 @@ +package org.koitharu.kotatsu.tracker.ui.debug + +import android.graphics.Color +import android.text.format.DateUtils +import androidx.core.content.ContextCompat +import androidx.core.text.bold +import androidx.core.text.buildSpannedString +import androidx.core.text.color +import androidx.lifecycle.LifecycleOwner +import coil.ImageLoader +import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding +import org.koitharu.kotatsu.R +import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener +import org.koitharu.kotatsu.core.util.ext.drawableStart +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.source +import org.koitharu.kotatsu.databinding.ItemTrackDebugBinding +import org.koitharu.kotatsu.tracker.data.TrackEntity +import com.google.android.material.R as materialR + +fun trackDebugAD( + lifecycleOwner: LifecycleOwner, + coil: ImageLoader, + clickListener: OnListItemClickListener, +) = adapterDelegateViewBinding( + { layoutInflater, parent -> ItemTrackDebugBinding.inflate(layoutInflater, parent, false) }, +) { + val indicatorNew = ContextCompat.getDrawable(context, R.drawable.ic_new) + + itemView.setOnClickListener { v -> + clickListener.onItemClick(item, v) + } + + bind { + binding.imageViewCover.newImageRequest(lifecycleOwner, item.manga.coverUrl)?.run { + placeholder(R.drawable.ic_placeholder) + fallback(R.drawable.ic_placeholder) + error(R.drawable.ic_error_placeholder) + allowRgb565(true) + source(item.manga.source) + enqueueWith(coil) + } + binding.textViewTitle.text = item.manga.title + binding.textViewSummary.text = buildSpannedString { + item.lastCheckTime?.let { + append( + DateUtils.getRelativeDateTimeString( + context, + it.toEpochMilli(), + DateUtils.MINUTE_IN_MILLIS, + DateUtils.WEEK_IN_MILLIS, + 0, + ), + ) + } + if (item.lastResult == TrackEntity.RESULT_FAILED) { + append(" - ") + bold { + color(context.getThemeColor(materialR.attr.colorError, Color.RED)) { + append(getString(R.string.error)) + } + } + } + } + binding.textViewTitle.drawableStart = if (item.newChapters > 0) { + indicatorNew + } else { + null + } + } +} diff --git a/app/src/debug/kotlin/org/koitharu/kotatsu/tracker/ui/debug/TrackDebugItem.kt b/app/src/debug/kotlin/org/koitharu/kotatsu/tracker/ui/debug/TrackDebugItem.kt new file mode 100644 index 000000000..0e59c15ef --- /dev/null +++ b/app/src/debug/kotlin/org/koitharu/kotatsu/tracker/ui/debug/TrackDebugItem.kt @@ -0,0 +1,19 @@ +package org.koitharu.kotatsu.tracker.ui.debug + +import org.koitharu.kotatsu.list.ui.model.ListModel +import org.koitharu.kotatsu.parsers.model.Manga +import java.time.Instant + +data class TrackDebugItem( + val manga: Manga, + val lastChapterId: Long, + val newChapters: Int, + val lastCheckTime: Instant?, + val lastChapterDate: Instant?, + val lastResult: Int, +) : ListModel { + + override fun areItemsTheSame(other: ListModel): Boolean { + return other is TrackDebugItem && other.manga.id == manga.id + } +} diff --git a/app/src/debug/kotlin/org/koitharu/kotatsu/tracker/ui/debug/TrackerDebugActivity.kt b/app/src/debug/kotlin/org/koitharu/kotatsu/tracker/ui/debug/TrackerDebugActivity.kt new file mode 100644 index 000000000..bcd0c59a0 --- /dev/null +++ b/app/src/debug/kotlin/org/koitharu/kotatsu/tracker/ui/debug/TrackerDebugActivity.kt @@ -0,0 +1,57 @@ +package org.koitharu.kotatsu.tracker.ui.debug + +import android.os.Bundle +import android.view.View +import androidx.activity.viewModels +import androidx.core.graphics.Insets +import androidx.core.view.updatePadding +import coil.ImageLoader +import dagger.hilt.android.AndroidEntryPoint +import org.koitharu.kotatsu.core.ui.BaseActivity +import org.koitharu.kotatsu.core.ui.BaseListAdapter +import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener +import org.koitharu.kotatsu.core.util.ext.observe +import org.koitharu.kotatsu.databinding.ActivityTrackerDebugBinding +import org.koitharu.kotatsu.details.ui.DetailsActivity +import org.koitharu.kotatsu.list.ui.adapter.ListItemType +import org.koitharu.kotatsu.list.ui.adapter.TypedListSpacingDecoration +import javax.inject.Inject + +@AndroidEntryPoint +class TrackerDebugActivity : BaseActivity(), OnListItemClickListener { + + @Inject + lateinit var coil: ImageLoader + + private val viewModel by viewModels() + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(ActivityTrackerDebugBinding.inflate(layoutInflater)) + supportActionBar?.setDisplayHomeAsUpEnabled(true) + val tracksAdapter = BaseListAdapter() + .addDelegate(ListItemType.FEED, trackDebugAD(this, coil, this)) + with(viewBinding.recyclerView) { + adapter = tracksAdapter + addItemDecoration(TypedListSpacingDecoration(context, false)) + } + viewModel.content.observe(this, tracksAdapter) + } + + override fun onWindowInsetsChanged(insets: Insets) { + val rv = viewBinding.recyclerView + rv.updatePadding( + left = insets.left + rv.paddingTop, + right = insets.right + rv.paddingTop, + bottom = insets.bottom, + ) + viewBinding.toolbar.updatePadding( + left = insets.left, + right = insets.right, + ) + } + + override fun onItemClick(item: TrackDebugItem, view: View) { + startActivity(DetailsActivity.newIntent(this, item.manga)) + } +} diff --git a/app/src/debug/kotlin/org/koitharu/kotatsu/tracker/ui/debug/TrackerDebugViewModel.kt b/app/src/debug/kotlin/org/koitharu/kotatsu/tracker/ui/debug/TrackerDebugViewModel.kt new file mode 100644 index 000000000..942741882 --- /dev/null +++ b/app/src/debug/kotlin/org/koitharu/kotatsu/tracker/ui/debug/TrackerDebugViewModel.kt @@ -0,0 +1,36 @@ +package org.koitharu.kotatsu.tracker.ui.debug + +import androidx.lifecycle.viewModelScope +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.plus +import org.koitharu.kotatsu.core.db.MangaDatabase +import org.koitharu.kotatsu.core.db.entity.toManga +import org.koitharu.kotatsu.core.ui.BaseViewModel +import org.koitharu.kotatsu.core.util.ext.toInstantOrNull +import org.koitharu.kotatsu.tracker.data.TrackWithManga +import javax.inject.Inject + +@HiltViewModel +class TrackerDebugViewModel @Inject constructor( + private val db: MangaDatabase +) : BaseViewModel() { + + val content = db.getTracksDao().observeAll() + .map { it.toUiList() } + .stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Eagerly, emptyList()) + + private fun List.toUiList(): List = map { + TrackDebugItem( + manga = it.manga.toManga(emptySet()), + lastChapterId = it.track.lastChapterId, + newChapters = it.track.newChapters, + lastCheckTime = it.track.lastCheckTime.toInstantOrNull(), + lastChapterDate = it.track.lastChapterDate.toInstantOrNull(), + lastResult = it.track.lastResult, + ) + } +} diff --git a/app/src/debug/res/layout/activity_tracker_debug.xml b/app/src/debug/res/layout/activity_tracker_debug.xml new file mode 100644 index 000000000..0ba8c74e9 --- /dev/null +++ b/app/src/debug/res/layout/activity_tracker_debug.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/debug/res/layout/item_track_debug.xml b/app/src/debug/res/layout/item_track_debug.xml new file mode 100644 index 000000000..e9f7702d9 --- /dev/null +++ b/app/src/debug/res/layout/item_track_debug.xml @@ -0,0 +1,56 @@ + + + + + + + + + + diff --git a/app/src/debug/res/menu/opt_settings.xml b/app/src/debug/res/menu/opt_settings.xml index f54e09cc0..b8bc2c309 100644 --- a/app/src/debug/res/menu/opt_settings.xml +++ b/app/src/debug/res/menu/opt_settings.xml @@ -8,4 +8,9 @@ android:title="@string/leak_canary_display_activity_label" app:showAsAction="never" /> - \ No newline at end of file + + + diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/settings/SettingsActivity.kt b/app/src/main/kotlin/org/koitharu/kotatsu/settings/SettingsActivity.kt index 0d85d8b05..b04cc0655 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/settings/SettingsActivity.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/settings/SettingsActivity.kt @@ -96,6 +96,13 @@ class SettingsActivity : true } + R.id.action_tracker -> { + val intent = Intent() + intent.component = ComponentName(this, "org.koitharu.kotatsu.tracker.ui.debug.TrackerDebugActivity") + startActivity(intent) + true + } + else -> super.onOptionsItemSelected(item) } diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/tracker/data/TracksDao.kt b/app/src/main/kotlin/org/koitharu/kotatsu/tracker/data/TracksDao.kt index e05053655..937f3514b 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/tracker/data/TracksDao.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/tracker/data/TracksDao.kt @@ -18,6 +18,10 @@ abstract class TracksDao { @Query("SELECT * FROM tracks ORDER BY last_check_time ASC LIMIT :limit OFFSET :offset") abstract suspend fun findAll(offset: Int, limit: Int): List + @Transaction + @Query("SELECT * FROM tracks ORDER BY last_check_time DESC") + abstract fun observeAll(): Flow> + @Query("SELECT manga_id FROM tracks") abstract suspend fun findAllIds(): LongArray diff --git a/app/src/main/kotlin/org/koitharu/kotatsu/tracker/work/TrackWorker.kt b/app/src/main/kotlin/org/koitharu/kotatsu/tracker/work/TrackWorker.kt index d3060499b..3d6d46fee 100644 --- a/app/src/main/kotlin/org/koitharu/kotatsu/tracker/work/TrackWorker.kt +++ b/app/src/main/kotlin/org/koitharu/kotatsu/tracker/work/TrackWorker.kt @@ -42,6 +42,7 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Semaphore import kotlinx.coroutines.sync.withPermit import kotlinx.coroutines.withContext +import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.R import org.koitharu.kotatsu.browser.cloudflare.CaptchaNotifier import org.koitharu.kotatsu.core.db.MangaDatabase @@ -337,8 +338,9 @@ class TrackWorker @AssistedInject constructor( } fun startNow() { - val constraints = - Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build() + val constraints = Constraints.Builder() + .setRequiredNetworkType(NetworkType.CONNECTED) + .build() val request = OneTimeWorkRequestBuilder() .setConstraints(constraints) .addTag(TAG_ONESHOT) @@ -370,6 +372,6 @@ class TrackWorker @AssistedInject constructor( const val MAX_ATTEMPTS = 3 const val DATA_KEY_SUCCESS = "success" const val DATA_KEY_FAILED = "failed" - const val BATCH_SIZE = 20 + val BATCH_SIZE = if (BuildConfig.DEBUG) 20 else 46 } } diff --git a/app/src/main/res/values/ids.xml b/app/src/main/res/values/ids.xml index 5991f6498..0a060ced1 100644 --- a/app/src/main/res/values/ids.xml +++ b/app/src/main/res/values/ids.xml @@ -3,6 +3,7 @@ +