Tracker fixes

This commit is contained in:
Koitharu
2020-06-03 18:52:00 +03:00
parent e01b74ee3d
commit 680fc66f21
16 changed files with 97 additions and 81 deletions

View File

@@ -3,6 +3,7 @@ package org.koitharu.kotatsu.domain
import android.graphics.BitmapFactory
import android.net.Uri
import android.util.Size
import androidx.annotation.WorkerThread
import okhttp3.OkHttpClient
import okhttp3.Request
import org.koin.core.KoinComponent
@@ -21,6 +22,8 @@ object MangaUtils : KoinComponent {
* Automatic determine type of manga by page size
* @return ReaderMode.WEBTOON if page is wide
*/
@WorkerThread
@Suppress("BlockingMethodInNonBlockingContext")
suspend fun determineReaderMode(pages: List<MangaPage>): ReaderMode? {
try {
val page = pages.medianOrNull() ?: return null

View File

@@ -49,7 +49,7 @@ class TrackingRepository : KoinComponent {
knownChaptersCount: Int,
lastChapterId: Long,
newChapters: List<MangaChapter>,
lastNotifiedChapterId: Long
previousTrackChapterId: Long
) {
db.withTransaction {
val entity = TrackEntity(
@@ -58,13 +58,15 @@ class TrackingRepository : KoinComponent {
lastCheck = System.currentTimeMillis(),
lastChapterId = lastChapterId,
totalChapters = knownChaptersCount,
lastNotifiedChapterId = lastNotifiedChapterId
lastNotifiedChapterId = newChapters.lastOrNull()?.id ?: previousTrackChapterId
)
db.tracksDao.upsert(entity)
if (newChapters.isNotEmpty()) {
val logEntity = TrackLogEntity(
mangaId = mangaId,
chapters = newChapters.joinToString("\n") { x -> x.name },
chapters = newChapters
.takeLastWhile { x -> x.id != previousTrackChapterId }
.joinToString("\n") { x -> x.name },
createdAt = System.currentTimeMillis()
)
db.trackLogsDao.insert(logEntity)

View File

@@ -87,16 +87,23 @@ abstract class BaseRecyclerAdapter<T, E>(private val onItemClickListener: OnRecy
final override fun getItemCount() = dataSet.size
final override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder<T, E> {
return onCreateViewHolder(parent).setOnItemClickListener(onItemClickListener)
.also(this::onViewHolderCreated)
return onCreateViewHolder(parent)
}
override fun onViewDetachedFromWindow(holder: BaseViewHolder<T, E>) {
holder.setOnItemClickListener(null)
super.onViewDetachedFromWindow(holder)
}
override fun onViewAttachedToWindow(holder: BaseViewHolder<T, E>) {
super.onViewAttachedToWindow(holder)
holder.setOnItemClickListener(onItemClickListener)
}
protected open fun onDataSetChanged() = Unit
protected abstract fun getExtra(item: T, position: Int): E
protected open fun onViewHolderCreated(holder: BaseViewHolder<T, E>) = Unit
protected abstract fun onCreateViewHolder(parent: ViewGroup): BaseViewHolder<T, E>
protected abstract fun onGetItemId(item: T): Long

View File

@@ -1,6 +1,5 @@
package org.koitharu.kotatsu.ui.common.list
import android.os.Build
import android.view.View
import android.view.ViewGroup
import androidx.annotation.LayoutRes
@@ -27,26 +26,29 @@ abstract class BaseViewHolder<T, E> protected constructor(view: View) :
onBind(data, extra)
}
fun requireData() = boundData ?: throw IllegalStateException("Calling requireData() before bind()")
fun requireData(): T {
return boundData ?: throw IllegalStateException("Calling requireData() before bind()")
}
fun setOnItemClickListener(listener: OnRecyclerItemClickListener<T>?): BaseViewHolder<T, E> {
if (listener != null) {
itemView.setOnClickListener {
listener.onItemClick(boundData ?: return@setOnClickListener, bindingAdapterPosition, it)
}
itemView.setOnLongClickListener {
listener.onItemLongClick(boundData ?: return@setOnLongClickListener false, bindingAdapterPosition, it)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
itemView.setOnContextClickListener {
listener.onItemLongClick(boundData ?: return@setOnContextClickListener false, bindingAdapterPosition, it)
}
}
}
return this
fun setOnItemClickListener(listener: OnRecyclerItemClickListener<T>?) {
val listenersAdapter = listener?.let { HolderListenersAdapter(it) }
itemView.setOnClickListener(listenersAdapter)
itemView.setOnLongClickListener(listenersAdapter)
}
open fun onRecycled() = Unit
abstract fun onBind(data: T, extra: E)
private inner class HolderListenersAdapter(private val listener: OnRecyclerItemClickListener<T>) :
View.OnClickListener, View.OnLongClickListener {
override fun onClick(v: View) {
listener.onItemClick(boundData ?: return, bindingAdapterPosition, v)
}
override fun onLongClick(v: View): Boolean {
return listener.onItemLongClick(boundData ?: return false, bindingAdapterPosition, v)
}
}
}

View File

@@ -19,7 +19,7 @@ class CategoriesAdapter(private val onItemClickListener: OnRecyclerItemClickList
override fun getExtra(item: FavouriteCategory, position: Int) = Unit
@SuppressLint("ClickableViewAccessibility")
override fun onViewHolderCreated(holder: BaseViewHolder<FavouriteCategory, Unit>) {
override fun onViewAttachedToWindow(holder: BaseViewHolder<FavouriteCategory, Unit>) {
holder.imageView_more.setOnClickListener { v ->
onItemClickListener.onItemClick(holder.requireData(), holder.bindingAdapterPosition, v)
}
@@ -32,6 +32,11 @@ class CategoriesAdapter(private val onItemClickListener: OnRecyclerItemClickList
}
}
override fun onViewDetachedFromWindow(holder: BaseViewHolder<FavouriteCategory, Unit>) {
holder.imageView_more.setOnClickListener(null)
holder.imageView_handle.setOnTouchListener(null)
}
fun moveItem(oldPos: Int, newPos: Int) {
val item = dataSet.removeAt(oldPos)
dataSet.add(newPos, item)

View File

@@ -31,8 +31,11 @@ class CategoriesSelectAdapter(private val listener: OnCategoryCheckListener) :
override fun onGetItemId(item: FavouriteCategory) = item.id
override fun onViewHolderCreated(holder: BaseViewHolder<FavouriteCategory, Boolean>) {
super.onViewHolderCreated(holder)
override fun onViewDetachedFromWindow(holder: BaseViewHolder<FavouriteCategory, Boolean>) {
holder.itemView.setOnClickListener(null)
}
override fun onViewAttachedToWindow(holder: BaseViewHolder<FavouriteCategory, Boolean>) {
holder.itemView.setOnClickListener {
if (it !is Checkable) return@setOnClickListener
it.toggle()

View File

@@ -55,7 +55,7 @@ class TrackWorker(context: Context, workerParams: WorkerParameters) :
mangaId = track.manga.id,
knownChaptersCount = chapters.size,
lastChapterId = chapters.lastOrNull()?.id ?: 0L,
lastNotifiedChapterId = 0L,
previousTrackChapterId = 0L,
newChapters = emptyList()
)
}
@@ -64,7 +64,7 @@ class TrackWorker(context: Context, workerParams: WorkerParameters) :
mangaId = track.manga.id,
knownChaptersCount = track.knownChaptersCount,
lastChapterId = 0L,
lastNotifiedChapterId = chapters.lastOrNull()?.id ?: 0L,
previousTrackChapterId = track.lastNotifiedChapterId,
newChapters = chapters
)
showNotification(track.manga, chapters)
@@ -82,7 +82,7 @@ class TrackWorker(context: Context, workerParams: WorkerParameters) :
mangaId = track.manga.id,
knownChaptersCount = chapters.size,
lastChapterId = chapters.lastOrNull()?.id ?: 0L,
lastNotifiedChapterId = chapters.lastOrNull()?.id ?: 0L,
previousTrackChapterId = track.lastNotifiedChapterId,
newChapters = emptyList()
)
} else {
@@ -91,12 +91,13 @@ class TrackWorker(context: Context, workerParams: WorkerParameters) :
mangaId = track.manga.id,
knownChaptersCount = knownChapter + 1,
lastChapterId = track.lastChapterId,
lastNotifiedChapterId = chapters.lastOrNull()?.id ?: 0L,
previousTrackChapterId = track.lastNotifiedChapterId,
newChapters = newChapters
)
if (chapters.lastOrNull()?.id != track.lastNotifiedChapterId) {
showNotification(track.manga, newChapters)
}
showNotification(
track.manga,
newChapters.takeLastWhile { x -> x.id != track.lastNotifiedChapterId }
)
}
}
}
@@ -106,12 +107,13 @@ class TrackWorker(context: Context, workerParams: WorkerParameters) :
mangaId = track.manga.id,
knownChaptersCount = track.knownChaptersCount,
lastChapterId = track.lastChapterId,
lastNotifiedChapterId = chapters.lastOrNull()?.id ?: 0L,
previousTrackChapterId = track.lastNotifiedChapterId,
newChapters = newChapters
)
if (chapters.lastOrNull()?.id != track.lastNotifiedChapterId) {
showNotification(track.manga, newChapters)
}
showNotification(
track.manga,
newChapters.takeLastWhile { x -> x.id != track.lastNotifiedChapterId }
)
}
}
success++
@@ -130,15 +132,21 @@ class TrackWorker(context: Context, workerParams: WorkerParameters) :
val id = manga.url.hashCode()
val colorPrimary = ContextCompat.getColor(applicationContext, R.color.blue_primary)
val builder = NotificationCompat.Builder(applicationContext, CHANNEL_ID)
val summary = applicationContext.resources.getQuantityString(R.plurals.new_chapters,
newChapters.size, newChapters.size)
val summary = applicationContext.resources.getQuantityString(
R.plurals.new_chapters,
newChapters.size, newChapters.size
)
with(builder) {
setContentText(summary)
setContentTitle(manga.title)
setNumber(newChapters.size)
setLargeIcon(Coil.execute(GetRequestBuilder(applicationContext)
.data(manga.coverUrl)
.build()).toBitmapOrNull())
setLargeIcon(
Coil.execute(
GetRequestBuilder(applicationContext)
.data(manga.coverUrl)
.build()
).toBitmapOrNull()
)
setSmallIcon(R.drawable.ic_stat_book_plus)
val style = NotificationCompat.InboxStyle(this)
for (chapter in newChapters) {
@@ -148,8 +156,12 @@ class TrackWorker(context: Context, workerParams: WorkerParameters) :
style.setBigContentTitle(summary)
setStyle(style)
val intent = MangaDetailsActivity.newIntent(applicationContext, manga)
setContentIntent(PendingIntent.getActivity(applicationContext, id,
intent, PendingIntent.FLAG_UPDATE_CURRENT))
setContentIntent(
PendingIntent.getActivity(
applicationContext, id,
intent, PendingIntent.FLAG_UPDATE_CURRENT
)
)
setAutoCancel(true)
color = colorPrimary
setShortcutId(manga.id.toString())
@@ -182,9 +194,11 @@ class TrackWorker(context: Context, workerParams: WorkerParameters) :
val manager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (manager.getNotificationChannel(CHANNEL_ID) == null) {
val channel = NotificationChannel(CHANNEL_ID,
val channel = NotificationChannel(
CHANNEL_ID,
context.getString(R.string.new_chapters),
NotificationManager.IMPORTANCE_DEFAULT)
NotificationManager.IMPORTANCE_DEFAULT
)
channel.setShowBadge(true)
channel.lightColor = ContextCompat.getColor(context, R.color.blue_primary)
channel.enableLights(true)

View File

@@ -40,12 +40,12 @@
android:layout_width="match_parent"
android:layout_height="?android:listPreferredItemHeightSmall"
android:background="?android:selectableItemBackground"
android:drawableEnd="@drawable/ic_add"
android:gravity="start|center_vertical"
android:paddingStart="?android:listPreferredItemPaddingStart"
android:paddingEnd="?android:listPreferredItemPaddingEnd"
android:text="@string/add_new_category"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
android:textColor="?android:textColorPrimary" />
android:textColor="?android:textColorPrimary"
app:drawableEndCompat="@drawable/ic_add" />
</LinearLayout>

View File

@@ -6,7 +6,8 @@
android:layout_height="?android:listPreferredItemHeightSmall"
android:background="?android:windowBackground"
android:gravity="center_vertical"
android:orientation="horizontal">
android:orientation="horizontal"
tools:ignore="Overdraw">
<ImageView
android:id="@+id/imageView_handle"

View File

@@ -89,10 +89,10 @@
android:id="@+id/textView_rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableStart="@drawable/ic_star_rating"
android:drawablePadding="4dp"
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
tools:text="10/10" />
tools:text="10/10"
app:drawableStartCompat="@drawable/ic_star_rating" />
</LinearLayout>

View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:background="?android:windowBackground"
android:layout_width="match_parent"
@@ -33,11 +34,11 @@
android:id="@+id/textView_error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableTop="@drawable/ic_error_large"
android:drawablePadding="12dp"
android:gravity="center_horizontal"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
tools:text="@tools:sample/lorem[6]" />
tools:text="@tools:sample/lorem[6]"
app:drawableTopCompat="@drawable/ic_error_large" />
<com.google.android.material.button.MaterialButton
android:id="@+id/button_retry"

View File

@@ -36,11 +36,11 @@
android:id="@+id/textView_error"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableTop="@drawable/ic_error_large"
android:drawablePadding="12dp"
android:gravity="center_horizontal"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
tools:text="@tools:sample/lorem[6]" />
tools:text="@tools:sample/lorem[6]"
app:drawableTopCompat="@drawable/ic_error_large" />
<com.google.android.material.button.MaterialButton
android:id="@+id/button_retry"

View File

@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="?listPreferredItemHeightSmall"
android:background="?selectableItemBackground"
android:drawableStart="@drawable/ic_history"
android:drawablePadding="20dp"
android:gravity="center_vertical"
android:paddingStart="?listPreferredItemPaddingStart"
@@ -13,4 +13,5 @@
android:textAppearance="?textAppearanceListItemSmall"
android:textColor="?android:textColorPrimary"
android:theme="@style/AppPopupTheme"
tools:text="@tools:sample/full_names" />
tools:text="@tools:sample/full_names"
app:drawableStartCompat="@drawable/ic_history" />

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_save_this"
android:title="@string/save_this_chapter" />
<item
android:id="@+id/action_save_this_next"
android:title="@string/save_this_chapter_and_next" />
<item
android:id="@+id/action_save_this_prev"
android:title="@string/save_this_chapter_and_prev" />
</menu>

View File

@@ -38,9 +38,6 @@
<string name="processing_">Обработка…</string>
<string name="download_complete">Загрузка завершена</string>
<string name="downloads">Загрузки</string>
<string name="save_this_chapter_and_prev">Сохранить предыдущие главы</string>
<string name="save_this_chapter_and_next">Сохранить следующие главы</string>
<string name="save_this_chapter">Сохранить эту главу</string>
<string name="by_name">По имени</string>
<string name="popular">Популярная</string>
<string name="updated">Обновлённая</string>

View File

@@ -39,9 +39,6 @@
<string name="processing_">Processing…</string>
<string name="download_complete">Download complete</string>
<string name="downloads">Downloads</string>
<string name="save_this_chapter_and_prev">Save this chapter and prev.</string>
<string name="save_this_chapter_and_next">Save this chapter and next</string>
<string name="save_this_chapter">Save this chapter</string>
<string name="by_name">By name</string>
<string name="popular">Popular</string>
<string name="updated">Updated</string>