Fixes
This commit is contained in:
@@ -14,8 +14,8 @@ android {
|
|||||||
applicationId 'org.koitharu.kotatsu'
|
applicationId 'org.koitharu.kotatsu'
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 32
|
targetSdkVersion 32
|
||||||
versionCode 426
|
versionCode 427
|
||||||
versionName '3.4.14'
|
versionName '3.4.15'
|
||||||
generatedDensities = []
|
generatedDensities = []
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import androidx.core.view.MenuProvider
|
|||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.core.view.updatePadding
|
import androidx.core.view.updatePadding
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
|
import kotlin.math.roundToInt
|
||||||
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.base.ui.BaseFragment
|
import org.koitharu.kotatsu.base.ui.BaseFragment
|
||||||
@@ -29,7 +30,6 @@ import org.koitharu.kotatsu.reader.ui.ReaderActivity
|
|||||||
import org.koitharu.kotatsu.reader.ui.ReaderState
|
import org.koitharu.kotatsu.reader.ui.ReaderState
|
||||||
import org.koitharu.kotatsu.utils.RecyclerViewScrollCallback
|
import org.koitharu.kotatsu.utils.RecyclerViewScrollCallback
|
||||||
import org.koitharu.kotatsu.utils.ext.addMenuProvider
|
import org.koitharu.kotatsu.utils.ext.addMenuProvider
|
||||||
import kotlin.math.roundToInt
|
|
||||||
|
|
||||||
class ChaptersFragment :
|
class ChaptersFragment :
|
||||||
BaseFragment<FragmentChaptersBinding>(),
|
BaseFragment<FragmentChaptersBinding>(),
|
||||||
@@ -46,7 +46,7 @@ class ChaptersFragment :
|
|||||||
|
|
||||||
override fun onInflateView(
|
override fun onInflateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?
|
container: ViewGroup?,
|
||||||
) = FragmentChaptersBinding.inflate(inflater, container, false)
|
) = FragmentChaptersBinding.inflate(inflater, container, false)
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
@@ -98,7 +98,7 @@ class ChaptersFragment :
|
|||||||
manga = viewModel.manga.value ?: return,
|
manga = viewModel.manga.value ?: return,
|
||||||
state = ReaderState(item.chapter.id, 0, 0),
|
state = ReaderState(item.chapter.id, 0, 0),
|
||||||
),
|
),
|
||||||
options.toBundle()
|
options.toBundle(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +128,7 @@ class ChaptersFragment :
|
|||||||
Snackbar.make(
|
Snackbar.make(
|
||||||
binding.recyclerViewChapters,
|
binding.recyclerViewChapters,
|
||||||
R.string.chapters_will_removed_background,
|
R.string.chapters_will_removed_background,
|
||||||
Snackbar.LENGTH_LONG
|
Snackbar.LENGTH_LONG,
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -271,8 +271,8 @@ class ChaptersFragment :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onPrepareMenu(menu: Menu) {
|
override fun onPrepareMenu(menu: Menu) {
|
||||||
menu.findItem(R.id.action_reversed).isChecked = viewModel.isChaptersReversed.value == true
|
menu.findItem(R.id.action_reversed)?.isChecked = viewModel.isChaptersReversed.value == true
|
||||||
menu.findItem(R.id.action_search).isVisible = viewModel.isChaptersEmpty.value == false
|
menu.findItem(R.id.action_search)?.isVisible = viewModel.isChaptersEmpty.value == false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMenuItemSelected(menuItem: MenuItem): Boolean = when (menuItem.itemId) {
|
override fun onMenuItemSelected(menuItem: MenuItem): Boolean = when (menuItem.itemId) {
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ class DownloadManager(
|
|||||||
}
|
}
|
||||||
outState.value = DownloadState.PostProcessing(startId, data, cover)
|
outState.value = DownloadState.PostProcessing(startId, data, cover)
|
||||||
output.mergeWithExisting()
|
output.mergeWithExisting()
|
||||||
output.finalize()
|
output.finish()
|
||||||
val localManga = localMangaRepository.getFromFile(output.file)
|
val localManga = localMangaRepository.getFromFile(output.file)
|
||||||
outState.value = DownloadState.Done(startId, data, cover, localManga)
|
outState.value = DownloadState.Done(startId, data, cover, localManga)
|
||||||
} catch (e: CancellationException) {
|
} catch (e: CancellationException) {
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import android.view.Menu
|
|||||||
import android.view.MenuInflater
|
import android.view.MenuInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import androidx.core.view.MenuProvider
|
import androidx.core.view.MenuProvider
|
||||||
|
import com.google.android.material.R as materialR
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import com.google.android.material.R as materialR
|
|
||||||
|
|
||||||
class HistoryListMenuProvider(
|
class HistoryListMenuProvider(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
@@ -38,6 +38,6 @@ class HistoryListMenuProvider(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onPrepareMenu(menu: Menu) {
|
override fun onPrepareMenu(menu: Menu) {
|
||||||
menu.findItem(R.id.action_history_grouping).isChecked = viewModel.isGroupingEnabled.value == true
|
menu.findItem(R.id.action_history_grouping)?.isChecked = viewModel.isGroupingEnabled.value == true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,13 +1,16 @@
|
|||||||
@file:SuppressLint("UnsafeOptInUsageError")
|
@file:SuppressLint("UnsafeOptInUsageError")
|
||||||
|
|
||||||
package org.koitharu.kotatsu.list.ui.adapter
|
package org.koitharu.kotatsu.list.ui.adapter
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import androidx.annotation.CheckResult
|
||||||
import androidx.core.view.doOnNextLayout
|
import androidx.core.view.doOnNextLayout
|
||||||
import com.google.android.material.badge.BadgeDrawable
|
import com.google.android.material.badge.BadgeDrawable
|
||||||
import com.google.android.material.badge.BadgeUtils
|
import com.google.android.material.badge.BadgeUtils
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
|
|
||||||
|
@CheckResult
|
||||||
fun View.bindBadge(badge: BadgeDrawable?, counter: Int): BadgeDrawable? {
|
fun View.bindBadge(badge: BadgeDrawable?, counter: Int): BadgeDrawable? {
|
||||||
return if (counter > 0) {
|
return if (counter > 0) {
|
||||||
val badgeDrawable = badge ?: initBadge(this)
|
val badgeDrawable = badge ?: initBadge(this)
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ fun mangaListDetailedItemAD(
|
|||||||
}
|
}
|
||||||
binding.textViewRating.textAndVisible = item.rating
|
binding.textViewRating.textAndVisible = item.rating
|
||||||
binding.textViewTags.text = item.tags
|
binding.textViewTags.text = item.tags
|
||||||
itemView.bindBadge(badge, item.counter)
|
badge = itemView.bindBadge(badge, item.counter)
|
||||||
}
|
}
|
||||||
|
|
||||||
onViewRecycled {
|
onViewRecycled {
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ fun mangaListItemAD(
|
|||||||
lifecycle(lifecycleOwner)
|
lifecycle(lifecycleOwner)
|
||||||
enqueueWith(coil)
|
enqueueWith(coil)
|
||||||
}
|
}
|
||||||
itemView.bindBadge(badge, item.counter)
|
badge = itemView.bindBadge(badge, item.counter)
|
||||||
}
|
}
|
||||||
|
|
||||||
onViewRecycled {
|
onViewRecycled {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package org.koitharu.kotatsu.local.domain
|
package org.koitharu.kotatsu.local.domain
|
||||||
|
|
||||||
import androidx.annotation.WorkerThread
|
import androidx.annotation.WorkerThread
|
||||||
|
import java.io.File
|
||||||
|
import java.util.zip.ZipFile
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.runInterruptible
|
import kotlinx.coroutines.runInterruptible
|
||||||
import okio.Closeable
|
import okio.Closeable
|
||||||
@@ -11,8 +13,6 @@ import org.koitharu.kotatsu.parsers.model.MangaChapter
|
|||||||
import org.koitharu.kotatsu.parsers.util.toFileNameSafe
|
import org.koitharu.kotatsu.parsers.util.toFileNameSafe
|
||||||
import org.koitharu.kotatsu.utils.ext.deleteAwait
|
import org.koitharu.kotatsu.utils.ext.deleteAwait
|
||||||
import org.koitharu.kotatsu.utils.ext.readText
|
import org.koitharu.kotatsu.utils.ext.readText
|
||||||
import java.io.File
|
|
||||||
import java.util.zip.ZipFile
|
|
||||||
|
|
||||||
class CbzMangaOutput(
|
class CbzMangaOutput(
|
||||||
val file: File,
|
val file: File,
|
||||||
@@ -62,7 +62,7 @@ class CbzMangaOutput(
|
|||||||
index.addChapter(chapter)
|
index.addChapter(chapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun finalize() {
|
suspend fun finish() {
|
||||||
runInterruptible(Dispatchers.IO) {
|
runInterruptible(Dispatchers.IO) {
|
||||||
output.put(ENTRY_NAME_INDEX, index.toString())
|
output.put(ENTRY_NAME_INDEX, index.toString())
|
||||||
output.finish()
|
output.finish()
|
||||||
@@ -89,7 +89,7 @@ class CbzMangaOutput(
|
|||||||
otherIndex = MangaIndex(
|
otherIndex = MangaIndex(
|
||||||
zip.getInputStream(entry).use {
|
zip.getInputStream(entry).use {
|
||||||
it.reader().readText()
|
it.reader().readText()
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
output.copyEntryFrom(zip, entry)
|
output.copyEntryFrom(zip, entry)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.utils.ext
|
|||||||
|
|
||||||
import android.content.ActivityNotFoundException
|
import android.content.ActivityNotFoundException
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
|
import androidx.collection.arraySetOf
|
||||||
import java.net.SocketTimeoutException
|
import java.net.SocketTimeoutException
|
||||||
import okio.FileNotFoundException
|
import okio.FileNotFoundException
|
||||||
import org.acra.ktx.sendWithAcra
|
import org.acra.ktx.sendWithAcra
|
||||||
@@ -30,14 +31,19 @@ fun Throwable.getDisplayMessage(resources: Resources): String = when (this) {
|
|||||||
} ?: resources.getString(R.string.error_occurred)
|
} ?: resources.getString(R.string.error_occurred)
|
||||||
|
|
||||||
fun Throwable.isReportable(): Boolean {
|
fun Throwable.isReportable(): Boolean {
|
||||||
if (this !is Exception) {
|
return this is Error || this.javaClass in reportableExceptions
|
||||||
return true
|
|
||||||
}
|
|
||||||
return this is ParseException || this is IllegalArgumentException ||
|
|
||||||
this is IllegalStateException || this.javaClass == RuntimeException::class.java
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Throwable.report(message: String?) {
|
fun Throwable.report(message: String?) {
|
||||||
val exception = CaughtException(this, message)
|
val exception = CaughtException(this, message)
|
||||||
exception.sendWithAcra()
|
exception.sendWithAcra()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val reportableExceptions = arraySetOf<Class<*>>(
|
||||||
|
ParseException::class.java,
|
||||||
|
RuntimeException::class.java,
|
||||||
|
IllegalStateException::class.java,
|
||||||
|
IllegalArgumentException::class.java,
|
||||||
|
ConcurrentModificationException::class.java,
|
||||||
|
UnsupportedOperationException::class.java,
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user