reformat
This commit is contained in:
parent
1df528c0dc
commit
afa960c808
171 changed files with 3458 additions and 1915 deletions
|
@ -8,5 +8,5 @@ data class Manga(
|
|||
var selectedChapter: String? = null,
|
||||
var chapters: MutableMap<String, MangaChapter>? = null,
|
||||
var slug: String? = null,
|
||||
var author: Author?=null,
|
||||
var author: Author? = null,
|
||||
) : Serializable
|
|
@ -10,7 +10,6 @@ import android.os.Build
|
|||
import android.os.Environment
|
||||
import android.provider.MediaStore
|
||||
import android.util.LruCache
|
||||
import android.widget.Toast
|
||||
import ani.dantotsu.logger
|
||||
import ani.dantotsu.snackString
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
|
@ -23,8 +22,12 @@ import java.io.FileOutputStream
|
|||
data class ImageData(
|
||||
val page: Page,
|
||||
val source: HttpSource
|
||||
){
|
||||
suspend fun fetchAndProcessImage(page: Page, httpSource: HttpSource, context: Context): Bitmap? {
|
||||
) {
|
||||
suspend fun fetchAndProcessImage(
|
||||
page: Page,
|
||||
httpSource: HttpSource,
|
||||
context: Context
|
||||
): Bitmap? {
|
||||
return withContext(Dispatchers.IO) {
|
||||
try {
|
||||
// Fetch the image
|
||||
|
@ -52,16 +55,26 @@ data class ImageData(
|
|||
}
|
||||
}
|
||||
|
||||
fun saveImage(bitmap: Bitmap, contentResolver: ContentResolver, filename: String, format: Bitmap.CompressFormat, quality: Int) {
|
||||
fun saveImage(
|
||||
bitmap: Bitmap,
|
||||
contentResolver: ContentResolver,
|
||||
filename: String,
|
||||
format: Bitmap.CompressFormat,
|
||||
quality: Int
|
||||
) {
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
val contentValues = ContentValues().apply {
|
||||
put(MediaStore.MediaColumns.DISPLAY_NAME, filename)
|
||||
put(MediaStore.MediaColumns.MIME_TYPE, "image/${format.name.lowercase()}")
|
||||
put(MediaStore.MediaColumns.RELATIVE_PATH, "${Environment.DIRECTORY_DOWNLOADS}/Dantotsu/Manga")
|
||||
put(
|
||||
MediaStore.MediaColumns.RELATIVE_PATH,
|
||||
"${Environment.DIRECTORY_DOWNLOADS}/Dantotsu/Manga"
|
||||
)
|
||||
}
|
||||
|
||||
val uri: Uri? = contentResolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues)
|
||||
val uri: Uri? =
|
||||
contentResolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, contentValues)
|
||||
|
||||
uri?.let {
|
||||
contentResolver.openOutputStream(it)?.use { os ->
|
||||
|
@ -69,7 +82,8 @@ fun saveImage(bitmap: Bitmap, contentResolver: ContentResolver, filename: String
|
|||
}
|
||||
}
|
||||
} else {
|
||||
val directory = File("${Environment.getExternalStorageDirectory()}${File.separator}Dantotsu${File.separator}Manga")
|
||||
val directory =
|
||||
File("${Environment.getExternalStorageDirectory()}${File.separator}Dantotsu${File.separator}Manga")
|
||||
if (!directory.exists()) {
|
||||
directory.mkdirs()
|
||||
}
|
||||
|
@ -85,7 +99,7 @@ fun saveImage(bitmap: Bitmap, contentResolver: ContentResolver, filename: String
|
|||
}
|
||||
}
|
||||
|
||||
class MangaCache() {
|
||||
class MangaCache {
|
||||
private val maxMemory = (Runtime.getRuntime().maxMemory() / 1024 / 2).toInt()
|
||||
private val cache = LruCache<String, ImageData>(maxMemory)
|
||||
|
||||
|
|
|
@ -15,7 +15,14 @@ data class MangaChapter(
|
|||
val scanlator: String? = null,
|
||||
var progress: String? = ""
|
||||
) : Serializable {
|
||||
constructor(chapter: MangaChapter) : this(chapter.number, chapter.link, chapter.title, chapter.description, chapter.sChapter, chapter.scanlator)
|
||||
constructor(chapter: MangaChapter) : this(
|
||||
chapter.number,
|
||||
chapter.link,
|
||||
chapter.title,
|
||||
chapter.description,
|
||||
chapter.sChapter,
|
||||
chapter.scanlator
|
||||
)
|
||||
|
||||
private val images = mutableListOf<MangaImage>()
|
||||
fun images(): List<MangaImage> = images
|
||||
|
|
|
@ -5,16 +5,15 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.animation.LinearInterpolator
|
||||
import androidx.core.content.ContentProviderCompat.requireContext
|
||||
import androidx.lifecycle.coroutineScope
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import ani.dantotsu.R
|
||||
import ani.dantotsu.connections.updateProgress
|
||||
import ani.dantotsu.currContext
|
||||
import ani.dantotsu.databinding.ItemChapterListBinding
|
||||
import ani.dantotsu.databinding.ItemEpisodeCompactBinding
|
||||
import ani.dantotsu.media.Media
|
||||
import ani.dantotsu.setAnimation
|
||||
import ani.dantotsu.connections.updateProgress
|
||||
import ani.dantotsu.currContext
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
@ -124,7 +123,7 @@ class MangaChapterAdapter(
|
|||
if (progress != null) {
|
||||
binding.itemChapterTitle.visibility = View.VISIBLE
|
||||
binding.itemChapterTitle.text = "$progress"
|
||||
}else{
|
||||
} else {
|
||||
binding.itemChapterTitle.visibility = View.GONE
|
||||
binding.itemChapterTitle.text = ""
|
||||
}
|
||||
|
@ -154,9 +153,10 @@ class MangaChapterAdapter(
|
|||
// Add chapter number to active coroutines set
|
||||
activeCoroutines.add(chapterNumber)
|
||||
while (activeDownloads.contains(chapterNumber)) {
|
||||
binding.itemDownload.animate().rotationBy(360f).setDuration(1000).setInterpolator(
|
||||
LinearInterpolator()
|
||||
).start()
|
||||
binding.itemDownload.animate().rotationBy(360f).setDuration(1000)
|
||||
.setInterpolator(
|
||||
LinearInterpolator()
|
||||
).start()
|
||||
delay(1000)
|
||||
}
|
||||
// Remove chapter number from active coroutines set
|
||||
|
@ -171,8 +171,16 @@ class MangaChapterAdapter(
|
|||
|
||||
init {
|
||||
val theme = currContext()?.theme
|
||||
theme?.resolveAttribute(com.google.android.material.R.attr.colorError, typedValue1, true)
|
||||
theme?.resolveAttribute(com.google.android.material.R.attr.colorPrimary, typedValue2, true)
|
||||
theme?.resolveAttribute(
|
||||
com.google.android.material.R.attr.colorError,
|
||||
typedValue1,
|
||||
true
|
||||
)
|
||||
theme?.resolveAttribute(
|
||||
com.google.android.material.R.attr.colorPrimary,
|
||||
typedValue2,
|
||||
true
|
||||
)
|
||||
itemView.setOnClickListener {
|
||||
if (0 <= bindingAdapterPosition && bindingAdapterPosition < arr.size)
|
||||
fragment.onMangaChapterClick(arr[bindingAdapterPosition].number)
|
||||
|
|
|
@ -13,15 +13,12 @@ import androidx.core.content.ContextCompat
|
|||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import ani.dantotsu.*
|
||||
import ani.dantotsu.App.Companion.context
|
||||
import ani.dantotsu.media.anime.handleProgress
|
||||
import ani.dantotsu.databinding.ItemAnimeWatchBinding
|
||||
import ani.dantotsu.databinding.ItemChipBinding
|
||||
import ani.dantotsu.media.Media
|
||||
import ani.dantotsu.media.MediaDetailsActivity
|
||||
import ani.dantotsu.media.SourceSearchDialogFragment
|
||||
import ani.dantotsu.parsers.AnimeSources
|
||||
import ani.dantotsu.parsers.DynamicAnimeParser
|
||||
import ani.dantotsu.media.anime.handleProgress
|
||||
import ani.dantotsu.parsers.DynamicMangaParser
|
||||
import ani.dantotsu.parsers.MangaReadSources
|
||||
import ani.dantotsu.parsers.MangaSources
|
||||
|
@ -30,7 +27,6 @@ import ani.dantotsu.subcriptions.Subscription.Companion.getChannelId
|
|||
import com.google.android.material.chip.Chip
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.launch
|
||||
import java.lang.IndexOutOfBoundsException
|
||||
|
||||
class MangaReadAdapter(
|
||||
private val media: Media,
|
||||
|
@ -57,12 +53,16 @@ class MangaReadAdapter(
|
|||
|
||||
//Wrong Title
|
||||
binding.animeSourceSearch.setOnClickListener {
|
||||
SourceSearchDialogFragment().show(fragment.requireActivity().supportFragmentManager, null)
|
||||
SourceSearchDialogFragment().show(
|
||||
fragment.requireActivity().supportFragmentManager,
|
||||
null
|
||||
)
|
||||
}
|
||||
|
||||
//Source Selection
|
||||
var source = media.selected!!.sourceIndex.let { if (it >= mangaReadSources.names.size) 0 else it }
|
||||
setLanguageList(media.selected!!.langIndex,source)
|
||||
var source =
|
||||
media.selected!!.sourceIndex.let { if (it >= mangaReadSources.names.size) 0 else it }
|
||||
setLanguageList(media.selected!!.langIndex, source)
|
||||
if (mangaReadSources.names.isNotEmpty() && source in 0 until mangaReadSources.names.size) {
|
||||
binding.animeSource.setText(mangaReadSources.names[source])
|
||||
mangaReadSources[source].apply {
|
||||
|
@ -70,14 +70,20 @@ class MangaReadAdapter(
|
|||
showUserTextListener = { MainScope().launch { binding.animeSourceTitle.text = it } }
|
||||
}
|
||||
}
|
||||
binding.animeSource.setAdapter(ArrayAdapter(fragment.requireContext(), R.layout.item_dropdown, mangaReadSources.names))
|
||||
binding.animeSource.setAdapter(
|
||||
ArrayAdapter(
|
||||
fragment.requireContext(),
|
||||
R.layout.item_dropdown,
|
||||
mangaReadSources.names
|
||||
)
|
||||
)
|
||||
binding.animeSourceTitle.isSelected = true
|
||||
binding.animeSource.setOnItemClickListener { _, _, i, _ ->
|
||||
fragment.onSourceChange(i).apply {
|
||||
binding.animeSourceTitle.text = showUserText
|
||||
showUserTextListener = { MainScope().launch { binding.animeSourceTitle.text = it } }
|
||||
source = i
|
||||
setLanguageList(0,i)
|
||||
setLanguageList(0, i)
|
||||
}
|
||||
subscribeButton(false)
|
||||
//invalidate if it's the last source
|
||||
|
@ -92,7 +98,8 @@ class MangaReadAdapter(
|
|||
fragment.onLangChange(i)
|
||||
fragment.onSourceChange(media.selected!!.sourceIndex).apply {
|
||||
binding.animeSourceTitle.text = showUserText
|
||||
showUserTextListener = { MainScope().launch { binding.animeSourceTitle.text = it } }
|
||||
showUserTextListener =
|
||||
{ MainScope().launch { binding.animeSourceTitle.text = it } }
|
||||
setLanguageList(i, source)
|
||||
}
|
||||
subscribeButton(false)
|
||||
|
@ -139,7 +146,8 @@ class MangaReadAdapter(
|
|||
}
|
||||
|
||||
binding.animeScanlatorTop.setOnClickListener {
|
||||
val dialogView = LayoutInflater.from(currContext()).inflate(R.layout.custom_dialog_layout, null)
|
||||
val dialogView =
|
||||
LayoutInflater.from(currContext()).inflate(R.layout.custom_dialog_layout, null)
|
||||
val checkboxContainer = dialogView.findViewById<LinearLayout>(R.id.checkboxContainer)
|
||||
|
||||
// Dynamically add checkboxes
|
||||
|
@ -149,10 +157,10 @@ class MangaReadAdapter(
|
|||
text = option
|
||||
}
|
||||
//set checked if it's already selected
|
||||
if(media.selected!!.scanlators != null){
|
||||
if (media.selected!!.scanlators != null) {
|
||||
checkBox.isChecked = media.selected!!.scanlators?.contains(option) != true
|
||||
scanlatorSelectionListener?.onScanlatorsSelected()
|
||||
}else{
|
||||
} else {
|
||||
checkBox.isChecked = true
|
||||
}
|
||||
checkboxContainer.addView(checkBox)
|
||||
|
@ -178,8 +186,8 @@ class MangaReadAdapter(
|
|||
}
|
||||
|
||||
var selected = when (style) {
|
||||
0 -> binding.animeSourceList
|
||||
1 -> binding.animeSourceCompact
|
||||
0 -> binding.animeSourceList
|
||||
1 -> binding.animeSourceCompact
|
||||
else -> binding.animeSourceList
|
||||
}
|
||||
selected.alpha = 1f
|
||||
|
@ -217,14 +225,26 @@ class MangaReadAdapter(
|
|||
for (position in arr.indices) {
|
||||
val last = if (position + 1 == arr.size) names.size else (limit * (position + 1))
|
||||
val chip =
|
||||
ItemChipBinding.inflate(LayoutInflater.from(fragment.context), binding.animeSourceChipGroup, false).root
|
||||
ItemChipBinding.inflate(
|
||||
LayoutInflater.from(fragment.context),
|
||||
binding.animeSourceChipGroup,
|
||||
false
|
||||
).root
|
||||
chip.isCheckable = true
|
||||
fun selected() {
|
||||
chip.isChecked = true
|
||||
binding.animeWatchChipScroll.smoothScrollTo((chip.left - screenWidth / 2) + (chip.width / 2), 0)
|
||||
binding.animeWatchChipScroll.smoothScrollTo(
|
||||
(chip.left - screenWidth / 2) + (chip.width / 2),
|
||||
0
|
||||
)
|
||||
}
|
||||
chip.text = "${names[limit * (position)]} - ${names[last - 1]}"
|
||||
chip.setTextColor(ContextCompat.getColorStateList(fragment.requireContext(), R.color.chip_text_color))
|
||||
chip.setTextColor(
|
||||
ContextCompat.getColorStateList(
|
||||
fragment.requireContext(),
|
||||
R.color.chip_text_color
|
||||
)
|
||||
)
|
||||
|
||||
chip.setOnClickListener {
|
||||
selected()
|
||||
|
@ -237,7 +257,14 @@ class MangaReadAdapter(
|
|||
}
|
||||
}
|
||||
if (select != null)
|
||||
binding.animeWatchChipScroll.apply { post { scrollTo((select.left - screenWidth / 2) + (select.width / 2), 0) } }
|
||||
binding.animeWatchChipScroll.apply {
|
||||
post {
|
||||
scrollTo(
|
||||
(select.left - screenWidth / 2) + (select.width / 2),
|
||||
0
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -259,7 +286,9 @@ class MangaReadAdapter(
|
|||
val chapter = media.manga.chapters!![chapterKey]!!
|
||||
chapter.scanlator !in hiddenScanlators
|
||||
}
|
||||
val formattedChapters = filteredChapters.map { MangaNameAdapter.findChapterNumber(it)?.toInt()?.toString() }
|
||||
val formattedChapters = filteredChapters.map {
|
||||
MangaNameAdapter.findChapterNumber(it)?.toInt()?.toString()
|
||||
}
|
||||
if (formattedChapters.contains(continueEp)) {
|
||||
continueEp = chapters[formattedChapters.indexOf(continueEp)]
|
||||
binding.animeSourceContinue.visibility = View.VISIBLE
|
||||
|
@ -317,10 +346,17 @@ class MangaReadAdapter(
|
|||
}
|
||||
try {
|
||||
binding?.animeSourceLanguage?.setText(parser.extension.sources[lang].lang)
|
||||
}catch (e: IndexOutOfBoundsException) {
|
||||
binding?.animeSourceLanguage?.setText(parser.extension.sources.firstOrNull()?.lang ?: "Unknown")
|
||||
} catch (e: IndexOutOfBoundsException) {
|
||||
binding?.animeSourceLanguage?.setText(
|
||||
parser.extension.sources.firstOrNull()?.lang ?: "Unknown"
|
||||
)
|
||||
}
|
||||
binding?.animeSourceLanguage?.setAdapter(ArrayAdapter(fragment.requireContext(), R.layout.item_dropdown, parser.extension.sources.map { it.lang }))
|
||||
binding?.animeSourceLanguage?.setAdapter(
|
||||
ArrayAdapter(
|
||||
fragment.requireContext(),
|
||||
R.layout.item_dropdown,
|
||||
parser.extension.sources.map { it.lang })
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -328,7 +364,8 @@ class MangaReadAdapter(
|
|||
|
||||
override fun getItemCount(): Int = 1
|
||||
|
||||
inner class ViewHolder(val binding: ItemAnimeWatchBinding) : RecyclerView.ViewHolder(binding.root)
|
||||
inner class ViewHolder(val binding: ItemAnimeWatchBinding) :
|
||||
RecyclerView.ViewHolder(binding.root)
|
||||
}
|
||||
|
||||
interface ScanlatorSelectionListener {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package ani.dantotsu.media.manga
|
||||
|
||||
import android.Manifest
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.AlertDialog
|
||||
import android.content.BroadcastReceiver
|
||||
|
@ -16,6 +17,7 @@ import android.view.ViewGroup
|
|||
import android.widget.FrameLayout
|
||||
import android.widget.Toast
|
||||
import androidx.cardview.widget.CardView
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.math.MathUtils.clamp
|
||||
import androidx.core.view.updatePadding
|
||||
|
@ -31,10 +33,10 @@ import ani.dantotsu.download.Download
|
|||
import ani.dantotsu.download.DownloadsManager
|
||||
import ani.dantotsu.download.manga.MangaDownloaderService
|
||||
import ani.dantotsu.download.manga.MangaServiceDataSingleton
|
||||
import ani.dantotsu.media.manga.mangareader.ChapterLoaderDialog
|
||||
import ani.dantotsu.media.Media
|
||||
import ani.dantotsu.media.MediaDetailsActivity
|
||||
import ani.dantotsu.media.MediaDetailsViewModel
|
||||
import ani.dantotsu.media.manga.mangareader.ChapterLoaderDialog
|
||||
import ani.dantotsu.parsers.DynamicMangaParser
|
||||
import ani.dantotsu.parsers.HMangaSources
|
||||
import ani.dantotsu.parsers.MangaParser
|
||||
|
@ -59,10 +61,8 @@ import uy.kohesive.injekt.api.get
|
|||
import kotlin.math.ceil
|
||||
import kotlin.math.max
|
||||
import kotlin.math.roundToInt
|
||||
import android.Manifest
|
||||
import androidx.core.app.ActivityCompat
|
||||
|
||||
open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
|
||||
open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
|
||||
private var _binding: FragmentAnimeWatchBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
private val model: MediaDetailsViewModel by activityViewModels()
|
||||
|
@ -85,7 +85,8 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
|
|||
var continueEp: Boolean = false
|
||||
var loaded = false
|
||||
|
||||
val uiSettings = loadData("ui_settings", toast = false) ?: UserInterfaceSettings().apply { saveData("ui_settings", this) }
|
||||
val uiSettings = loadData("ui_settings", toast = false)
|
||||
?: UserInterfaceSettings().apply { saveData("ui_settings", this) }
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
|
@ -105,7 +106,12 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
|
|||
addAction(ACTION_DOWNLOAD_PROGRESS)
|
||||
}
|
||||
|
||||
ContextCompat.registerReceiver(requireContext(), downloadStatusReceiver, intentFilter, ContextCompat.RECEIVER_EXPORTED)
|
||||
ContextCompat.registerReceiver(
|
||||
requireContext(),
|
||||
downloadStatusReceiver,
|
||||
intentFilter,
|
||||
ContextCompat.RECEIVER_EXPORTED
|
||||
)
|
||||
|
||||
binding.animeSourceRecycler.updatePadding(bottom = binding.animeSourceRecycler.paddingBottom + navBarHeight)
|
||||
screenWidth = resources.displayMetrics.widthPixels.dp
|
||||
|
@ -120,10 +126,10 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
|
|||
val style = chapterAdapter.getItemViewType(position)
|
||||
|
||||
return when (position) {
|
||||
0 -> maxGridSize
|
||||
0 -> maxGridSize
|
||||
else -> when (style) {
|
||||
0 -> maxGridSize
|
||||
1 -> 1
|
||||
0 -> maxGridSize
|
||||
1 -> 1
|
||||
else -> maxGridSize
|
||||
}
|
||||
}
|
||||
|
@ -146,7 +152,8 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
|
|||
if (media.format == "MANGA" || media.format == "ONE SHOT") {
|
||||
media.selected = model.loadSelected(media)
|
||||
|
||||
subscribed = SubscriptionHelper.getSubscriptions(requireContext()).containsKey(media.id)
|
||||
subscribed =
|
||||
SubscriptionHelper.getSubscriptions(requireContext()).containsKey(media.id)
|
||||
|
||||
style = media.selected!!.recyclerStyle
|
||||
reverse = media.selected!!.recyclerReversed
|
||||
|
@ -156,13 +163,15 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
|
|||
|
||||
headerAdapter = MangaReadAdapter(it, this, model.mangaReadSources!!)
|
||||
headerAdapter.scanlatorSelectionListener = this
|
||||
chapterAdapter = MangaChapterAdapter(style ?: uiSettings.mangaDefaultView, media, this)
|
||||
chapterAdapter =
|
||||
MangaChapterAdapter(style ?: uiSettings.mangaDefaultView, media, this)
|
||||
|
||||
for (download in downloadManager.mangaDownloads){
|
||||
for (download in downloadManager.mangaDownloads) {
|
||||
chapterAdapter.stopDownload(download.chapter)
|
||||
}
|
||||
|
||||
binding.animeSourceRecycler.adapter = ConcatAdapter(headerAdapter, chapterAdapter)
|
||||
binding.animeSourceRecycler.adapter =
|
||||
ConcatAdapter(headerAdapter, chapterAdapter)
|
||||
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
model.loadMangaChapters(media, media.selected!!.sourceIndex)
|
||||
|
@ -173,7 +182,8 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
|
|||
}
|
||||
} else {
|
||||
binding.animeNotSupported.visibility = View.VISIBLE
|
||||
binding.animeNotSupported.text = getString(R.string.not_supported, media.format ?: "")
|
||||
binding.animeNotSupported.text =
|
||||
getString(R.string.not_supported, media.format ?: "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -207,7 +217,7 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
|
|||
val limit = when {
|
||||
(divisions < 25) -> 25
|
||||
(divisions < 50) -> 50
|
||||
else -> 100
|
||||
else -> 100
|
||||
}
|
||||
headerAdapter.clearChips()
|
||||
if (total > limit) {
|
||||
|
@ -302,7 +312,7 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
|
|||
)
|
||||
}
|
||||
|
||||
fun openSettings(pkg: MangaExtension.Installed){
|
||||
fun openSettings(pkg: MangaExtension.Installed) {
|
||||
val changeUIVisibility: (Boolean) -> Unit = { show ->
|
||||
val activity = requireActivity() as MediaDetailsActivity
|
||||
val visibility = if (show) View.VISIBLE else View.GONE
|
||||
|
@ -310,9 +320,9 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
|
|||
activity.findViewById<ViewPager2>(R.id.mediaViewPager).visibility = visibility
|
||||
activity.findViewById<CardView>(R.id.mediaCover).visibility = visibility
|
||||
activity.findViewById<CardView>(R.id.mediaClose).visibility = visibility
|
||||
try{
|
||||
try {
|
||||
activity.findViewById<CustomBottomNavBar>(R.id.mediaTab).visibility = visibility
|
||||
}catch (e: ClassCastException){
|
||||
} catch (e: ClassCastException) {
|
||||
activity.findViewById<NavigationRailView>(R.id.mediaTab).visibility = visibility
|
||||
}
|
||||
activity.findViewById<FrameLayout>(R.id.fragmentExtensionsContainer).visibility =
|
||||
|
@ -335,7 +345,7 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
|
|||
|
||||
// Move the fragment transaction here
|
||||
val fragment =
|
||||
MangaSourcePreferencesFragment().getInstance(selectedSetting.id){
|
||||
MangaSourcePreferencesFragment().getInstance(selectedSetting.id) {
|
||||
changeUIVisibility(true)
|
||||
loadChapters(media.selected!!.sourceIndex, true)
|
||||
}
|
||||
|
@ -353,7 +363,7 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
|
|||
.show()
|
||||
} else {
|
||||
// If there's only one setting, proceed with the fragment transaction
|
||||
val fragment = MangaSourcePreferencesFragment().getInstance(selectedSetting.id){
|
||||
val fragment = MangaSourcePreferencesFragment().getInstance(selectedSetting.id) {
|
||||
changeUIVisibility(true)
|
||||
loadChapters(media.selected!!.sourceIndex, true)
|
||||
}
|
||||
|
@ -376,7 +386,8 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
|
|||
media.manga?.chapters?.get(i)?.let {
|
||||
media.manga?.selectedChapter = i
|
||||
model.saveSelected(media.id, media.selected!!, requireActivity())
|
||||
ChapterLoaderDialog.newInstance(it, true).show(requireActivity().supportFragmentManager, "dialog")
|
||||
ChapterLoaderDialog.newInstance(it, true)
|
||||
.show(requireActivity().supportFragmentManager, "dialog")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -393,7 +404,8 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
|
|||
|
||||
model.continueMedia = false
|
||||
media.manga?.chapters?.get(i)?.let { chapter ->
|
||||
val parser = model.mangaReadSources?.get(media.selected!!.sourceIndex) as? DynamicMangaParser
|
||||
val parser =
|
||||
model.mangaReadSources?.get(media.selected!!.sourceIndex) as? DynamicMangaParser
|
||||
parser?.let {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
val images = parser.imageList("", chapter.sChapter)
|
||||
|
@ -439,10 +451,17 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
|
|||
}
|
||||
|
||||
|
||||
fun onMangaChapterRemoveDownloadClick(i: String){
|
||||
downloadManager.removeDownload(Download(media.nameMAL?:media.nameRomaji, i, Download.Type.MANGA))
|
||||
fun onMangaChapterRemoveDownloadClick(i: String) {
|
||||
downloadManager.removeDownload(
|
||||
Download(
|
||||
media.nameMAL ?: media.nameRomaji,
|
||||
i,
|
||||
Download.Type.MANGA
|
||||
)
|
||||
)
|
||||
chapterAdapter.deleteDownload(i)
|
||||
}
|
||||
|
||||
fun onMangaChapterStopDownloadClick(i: String) {
|
||||
val cancelIntent = Intent().apply {
|
||||
action = MangaDownloaderService.ACTION_CANCEL_DOWNLOAD
|
||||
|
@ -451,12 +470,19 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
|
|||
requireContext().sendBroadcast(cancelIntent)
|
||||
|
||||
// Remove the download from the manager and update the UI
|
||||
downloadManager.removeDownload(Download(media.nameMAL?:media.nameRomaji, i, Download.Type.MANGA))
|
||||
downloadManager.removeDownload(
|
||||
Download(
|
||||
media.nameMAL ?: media.nameRomaji,
|
||||
i,
|
||||
Download.Type.MANGA
|
||||
)
|
||||
)
|
||||
chapterAdapter.purgeDownload(i)
|
||||
}
|
||||
|
||||
private val downloadStatusReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
if(!this@MangaReadFragment::chapterAdapter.isInitialized) return
|
||||
if (!this@MangaReadFragment::chapterAdapter.isInitialized) return
|
||||
when (intent.action) {
|
||||
ACTION_DOWNLOAD_STARTED -> {
|
||||
val chapterNumber = intent.getStringExtra(EXTRA_CHAPTER_NUMBER)
|
||||
|
@ -492,8 +518,10 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
|
|||
val selected = model.loadSelected(media)
|
||||
|
||||
//Find latest chapter for subscription
|
||||
selected.latest = media.manga?.chapters?.values?.maxOfOrNull { it.number.toFloatOrNull() ?: 0f } ?: 0f
|
||||
selected.latest = media.userProgress?.toFloat()?.takeIf { selected.latest < it } ?: selected.latest
|
||||
selected.latest =
|
||||
media.manga?.chapters?.values?.maxOfOrNull { it.number.toFloatOrNull() ?: 0f } ?: 0f
|
||||
selected.latest =
|
||||
media.userProgress?.toFloat()?.takeIf { selected.latest < it } ?: selected.latest
|
||||
|
||||
model.saveSelected(media.id, selected, requireActivity())
|
||||
headerAdapter.handleChapters()
|
||||
|
@ -502,7 +530,8 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
|
|||
if (media.manga!!.chapters != null) {
|
||||
val end = if (end != null && end!! < media.manga!!.chapters!!.size) end else null
|
||||
arr.addAll(
|
||||
media.manga!!.chapters!!.values.toList().slice(start..(end ?: (media.manga!!.chapters!!.size - 1)))
|
||||
media.manga!!.chapters!!.values.toList()
|
||||
.slice(start..(end ?: (media.manga!!.chapters!!.size - 1)))
|
||||
)
|
||||
if (reverse)
|
||||
arr = (arr.reversed() as? ArrayList<MangaChapter>) ?: arr
|
||||
|
|
|
@ -14,8 +14,8 @@ import androidx.core.view.updateLayoutParams
|
|||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import ani.dantotsu.*
|
||||
import ani.dantotsu.media.manga.MangaCache
|
||||
import ani.dantotsu.media.manga.MangaChapter
|
||||
import ani.dantotsu.parsers.DynamicMangaParser
|
||||
import ani.dantotsu.settings.CurrentReaderSettings
|
||||
import com.alexvasilkov.gestures.views.GestureFrameLayout
|
||||
import com.bumptech.glide.Glide
|
||||
|
@ -23,12 +23,9 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy
|
|||
import com.bumptech.glide.load.model.GlideUrl
|
||||
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import ani.dantotsu.media.manga.MangaCache
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.io.File
|
||||
|
||||
|
@ -118,7 +115,10 @@ abstract class BaseImageAdapter(
|
|||
abstract suspend fun loadImage(position: Int, parent: View): Boolean
|
||||
|
||||
companion object {
|
||||
suspend fun Context.loadBitmap_old(link: FileUrl, transforms: List<BitmapTransformation>): Bitmap? { //still used in some places
|
||||
suspend fun Context.loadBitmap_old(
|
||||
link: FileUrl,
|
||||
transforms: List<BitmapTransformation>
|
||||
): Bitmap? { //still used in some places
|
||||
return tryWithSuspend {
|
||||
withContext(Dispatchers.IO) {
|
||||
Glide.with(this@loadBitmap_old)
|
||||
|
@ -135,8 +135,7 @@ abstract class BaseImageAdapter(
|
|||
.let {
|
||||
if (transforms.isNotEmpty()) {
|
||||
it.transform(*transforms.toTypedArray())
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
|
@ -146,7 +145,10 @@ abstract class BaseImageAdapter(
|
|||
}
|
||||
}
|
||||
|
||||
suspend fun Context.loadBitmap(link: FileUrl, transforms: List<BitmapTransformation>): Bitmap? {
|
||||
suspend fun Context.loadBitmap(
|
||||
link: FileUrl,
|
||||
transforms: List<BitmapTransformation>
|
||||
): Bitmap? {
|
||||
return tryWithSuspend {
|
||||
val mangaCache = uy.kohesive.injekt.Injekt.get<MangaCache>()
|
||||
withContext(Dispatchers.IO) {
|
||||
|
@ -161,7 +163,11 @@ abstract class BaseImageAdapter(
|
|||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
} else {
|
||||
mangaCache.get(link.url)?.let { imageData ->
|
||||
val bitmap = imageData.fetchAndProcessImage(imageData.page, imageData.source, context = this@loadBitmap)
|
||||
val bitmap = imageData.fetchAndProcessImage(
|
||||
imageData.page,
|
||||
imageData.source,
|
||||
context = this@loadBitmap
|
||||
)
|
||||
it.load(bitmap)
|
||||
.skipMemoryCache(true)
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
|
|
|
@ -14,9 +14,9 @@ import ani.dantotsu.BottomSheetDialogFragment
|
|||
import ani.dantotsu.R
|
||||
import ani.dantotsu.currActivity
|
||||
import ani.dantotsu.databinding.BottomSheetSelectorBinding
|
||||
import ani.dantotsu.media.manga.MangaChapter
|
||||
import ani.dantotsu.media.MediaDetailsViewModel
|
||||
import ani.dantotsu.media.MediaSingleton
|
||||
import ani.dantotsu.media.manga.MangaChapter
|
||||
import ani.dantotsu.others.getSerialized
|
||||
import ani.dantotsu.tryWith
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
@ -29,8 +29,8 @@ class ChapterLoaderDialog : BottomSheetDialogFragment() {
|
|||
|
||||
val model: MediaDetailsViewModel by activityViewModels()
|
||||
|
||||
private val launch : Boolean by lazy { arguments?.getBoolean("launch", false) ?: false }
|
||||
private val chp : MangaChapter by lazy { arguments?.getSerialized("next")!! }
|
||||
private val launch: Boolean by lazy { arguments?.getBoolean("launch", false) ?: false }
|
||||
private val chp: MangaChapter by lazy { arguments?.getSerialized("next")!! }
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
var loaded = false
|
||||
|
@ -47,13 +47,21 @@ class ChapterLoaderDialog : BottomSheetDialogFragment() {
|
|||
loaded = true
|
||||
binding.selectorAutoText.text = chp.title
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
if(model.loadMangaChapterImages(chp, m.selected!!, m.nameMAL?:m.nameRomaji)) {
|
||||
if (model.loadMangaChapterImages(
|
||||
chp,
|
||||
m.selected!!,
|
||||
m.nameMAL ?: m.nameRomaji
|
||||
)
|
||||
) {
|
||||
val activity = currActivity()
|
||||
activity?.runOnUiThread {
|
||||
tryWith { dismiss() }
|
||||
if(launch) {
|
||||
if (launch) {
|
||||
MediaSingleton.media = m
|
||||
val intent = Intent(activity, MangaReaderActivity::class.java)//.apply { putExtra("media", m) }
|
||||
val intent = Intent(
|
||||
activity,
|
||||
MangaReaderActivity::class.java
|
||||
)//.apply { putExtra("media", m) }
|
||||
activity.startActivity(intent)
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +71,11 @@ class ChapterLoaderDialog : BottomSheetDialogFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = BottomSheetSelectorBinding.inflate(inflater, container, false)
|
||||
val window = dialog?.window
|
||||
window?.statusBarColor = Color.TRANSPARENT
|
||||
|
|
|
@ -30,15 +30,15 @@ open class ImageAdapter(
|
|||
|
||||
inner class ImageViewHolder(binding: ItemImageBinding) : RecyclerView.ViewHolder(binding.root)
|
||||
|
||||
open suspend fun loadBitmap(position: Int, parent: View) : Bitmap? {
|
||||
open suspend fun loadBitmap(position: Int, parent: View): Bitmap? {
|
||||
val link = images.getOrNull(position)?.url ?: return null
|
||||
if (link.url.isEmpty()) return null
|
||||
|
||||
val transforms = mutableListOf<BitmapTransformation>()
|
||||
val parserTransformation = activity.getTransformation(images[position])
|
||||
|
||||
if(parserTransformation!=null) transforms.add(parserTransformation)
|
||||
if(settings.cropBorders) {
|
||||
if (parserTransformation != null) transforms.add(parserTransformation)
|
||||
if (settings.cropBorders) {
|
||||
transforms.add(RemoveBordersTransformation(true, settings.cropBorderThreshold))
|
||||
transforms.add(RemoveBordersTransformation(false, settings.cropBorderThreshold))
|
||||
}
|
||||
|
@ -47,7 +47,8 @@ open class ImageAdapter(
|
|||
}
|
||||
|
||||
override suspend fun loadImage(position: Int, parent: View): Boolean {
|
||||
val imageView = parent.findViewById<SubsamplingScaleImageView>(R.id.imgProgImageNoGestures) ?: return false
|
||||
val imageView = parent.findViewById<SubsamplingScaleImageView>(R.id.imgProgImageNoGestures)
|
||||
?: return false
|
||||
val progress = parent.findViewById<View>(R.id.imgProgProgress) ?: return false
|
||||
imageView.recycle()
|
||||
imageView.visibility = View.GONE
|
||||
|
@ -60,10 +61,12 @@ open class ImageAdapter(
|
|||
if (settings.layout != PAGED)
|
||||
parent.updateLayoutParams {
|
||||
if (settings.direction != LEFT_TO_RIGHT && settings.direction != RIGHT_TO_LEFT) {
|
||||
sHeight = if (settings.wrapImages) bitmap.height else (sWidth * bitmap.height * 1f / bitmap.width).toInt()
|
||||
sHeight =
|
||||
if (settings.wrapImages) bitmap.height else (sWidth * bitmap.height * 1f / bitmap.width).toInt()
|
||||
height = sHeight
|
||||
} else {
|
||||
sWidth = if (settings.wrapImages) bitmap.width else (sHeight * bitmap.width * 1f / bitmap.height).toInt()
|
||||
sWidth =
|
||||
if (settings.wrapImages) bitmap.width else (sHeight * bitmap.width * 1f / bitmap.height).toInt()
|
||||
width = sWidth
|
||||
}
|
||||
}
|
||||
|
@ -73,7 +76,8 @@ open class ImageAdapter(
|
|||
|
||||
val parentArea = sWidth * sHeight * 1f
|
||||
val bitmapArea = bitmap.width * bitmap.height * 1f
|
||||
val scale = if (parentArea < bitmapArea) (bitmapArea / parentArea) else (parentArea / bitmapArea)
|
||||
val scale =
|
||||
if (parentArea < bitmapArea) (bitmapArea / parentArea) else (parentArea / bitmapArea)
|
||||
|
||||
imageView.maxScale = scale * 1.1f
|
||||
imageView.minScale = scale
|
||||
|
|
|
@ -34,12 +34,11 @@ import ani.dantotsu.databinding.ActivityMangaReaderBinding
|
|||
import ani.dantotsu.media.Media
|
||||
import ani.dantotsu.media.MediaDetailsViewModel
|
||||
import ani.dantotsu.media.MediaSingleton
|
||||
import ani.dantotsu.media.anime.ExoplayerView
|
||||
import ani.dantotsu.media.manga.MangaCache
|
||||
import ani.dantotsu.media.manga.MangaChapter
|
||||
import ani.dantotsu.media.manga.MangaNameAdapter
|
||||
import ani.dantotsu.others.ImageViewDialog
|
||||
import ani.dantotsu.others.getSerialized
|
||||
import ani.dantotsu.others.LangSet
|
||||
import ani.dantotsu.parsers.HMangaSources
|
||||
import ani.dantotsu.parsers.MangaImage
|
||||
import ani.dantotsu.parsers.MangaSources
|
||||
|
@ -50,7 +49,6 @@ import ani.dantotsu.settings.CurrentReaderSettings.Layouts.*
|
|||
import ani.dantotsu.settings.ReaderSettings
|
||||
import ani.dantotsu.settings.UserInterfaceSettings
|
||||
import ani.dantotsu.themes.ThemeManager
|
||||
import ani.dantotsu.others.LangSet
|
||||
import com.alexvasilkov.gestures.views.GestureFrameLayout
|
||||
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
|
||||
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
|
||||
|
@ -58,8 +56,6 @@ import com.google.firebase.crashlytics.ktx.crashlytics
|
|||
import com.google.firebase.ktx.Firebase
|
||||
import eu.kanade.tachiyomi.extension.manga.MangaExtensionManager
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
@ -262,16 +258,16 @@ class MangaReaderActivity : AppCompatActivity() {
|
|||
if (showProgressDialog && Anilist.userid != null && if (media.isAdult) settings.updateForH else true)
|
||||
AlertDialog.Builder(this, R.style.MyPopup)
|
||||
.setTitle(getString(R.string.title_update_progress)).apply {
|
||||
setMultiChoiceItems(
|
||||
arrayOf(getString(R.string.dont_ask_again, media.userPreferredName)),
|
||||
booleanArrayOf(false)
|
||||
) { _, _, isChecked ->
|
||||
if (isChecked) progressDialog = null
|
||||
saveData("${media.id}_progressDialog", isChecked)
|
||||
showProgressDialog = isChecked
|
||||
setMultiChoiceItems(
|
||||
arrayOf(getString(R.string.dont_ask_again, media.userPreferredName)),
|
||||
booleanArrayOf(false)
|
||||
) { _, _, isChecked ->
|
||||
if (isChecked) progressDialog = null
|
||||
saveData("${media.id}_progressDialog", isChecked)
|
||||
showProgressDialog = isChecked
|
||||
}
|
||||
setOnCancelListener { hideBars() }
|
||||
}
|
||||
setOnCancelListener { hideBars() }
|
||||
}
|
||||
else null
|
||||
|
||||
//Chapter Change
|
||||
|
|
|
@ -10,14 +10,15 @@ import kotlin.math.max
|
|||
|
||||
class PreloadLinearLayoutManager(context: Context, orientation: Int, reverseLayout: Boolean) :
|
||||
LinearLayoutManager(context, orientation, reverseLayout) {
|
||||
private val mOrientationHelper: OrientationHelper = OrientationHelper.createOrientationHelper(this, orientation)
|
||||
private val mOrientationHelper: OrientationHelper =
|
||||
OrientationHelper.createOrientationHelper(this, orientation)
|
||||
|
||||
/**
|
||||
* As [LinearLayoutManager.collectAdjacentPrefetchPositions] will prefetch one view for us,
|
||||
* we only need to prefetch additional ones.
|
||||
*/
|
||||
var preloadItemCount = 1
|
||||
set(count){
|
||||
set(count) {
|
||||
require(count >= 1) { "preloadItemCount must not be smaller than 1!" }
|
||||
field = count - 1
|
||||
}
|
||||
|
@ -37,7 +38,8 @@ class PreloadLinearLayoutManager(context: Context, orientation: Int, reverseLayo
|
|||
val currentPosition: Int = getPosition(child ?: return) + layoutDirection
|
||||
|
||||
if (layoutDirection == 1) {
|
||||
val scrollingOffset = (mOrientationHelper.getDecoratedEnd(child) - mOrientationHelper.endAfterPadding)
|
||||
val scrollingOffset =
|
||||
(mOrientationHelper.getDecoratedEnd(child) - mOrientationHelper.endAfterPadding)
|
||||
((currentPosition + 1) until (currentPosition + preloadItemCount + 1)).forEach {
|
||||
if (it >= 0 && it < state.itemCount) {
|
||||
layoutPrefetchRegistry.addPosition(it, max(0, scrollingOffset))
|
||||
|
|
|
@ -14,7 +14,11 @@ class ReaderSettingsDialogFragment : BottomSheetDialogFragment() {
|
|||
private var _binding: BottomSheetCurrentReaderSettingsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = BottomSheetCurrentReaderSettingsBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
@ -24,11 +28,14 @@ class ReaderSettingsDialogFragment : BottomSheetDialogFragment() {
|
|||
val activity = requireActivity() as MangaReaderActivity
|
||||
val settings = activity.settings.default
|
||||
|
||||
binding.readerDirectionText.text = resources.getStringArray(R.array.manga_directions)[settings.direction.ordinal]
|
||||
binding.readerDirectionText.text =
|
||||
resources.getStringArray(R.array.manga_directions)[settings.direction.ordinal]
|
||||
binding.readerDirection.rotation = 90f * (settings.direction.ordinal)
|
||||
binding.readerDirection.setOnClickListener {
|
||||
settings.direction = Directions[settings.direction.ordinal + 1] ?: Directions.TOP_TO_BOTTOM
|
||||
binding.readerDirectionText.text = resources.getStringArray(R.array.manga_directions)[settings.direction.ordinal]
|
||||
settings.direction =
|
||||
Directions[settings.direction.ordinal + 1] ?: Directions.TOP_TO_BOTTOM
|
||||
binding.readerDirectionText.text =
|
||||
resources.getStringArray(R.array.manga_directions)[settings.direction.ordinal]
|
||||
binding.readerDirection.rotation = 90f * (settings.direction.ordinal)
|
||||
activity.applySettings()
|
||||
}
|
||||
|
@ -39,36 +46,39 @@ class ReaderSettingsDialogFragment : BottomSheetDialogFragment() {
|
|||
binding.readerContinuous
|
||||
)
|
||||
|
||||
binding.readerPadding.isEnabled = settings.layout.ordinal!=0
|
||||
fun paddingAvailable(enable:Boolean){
|
||||
binding.readerPadding.isEnabled = settings.layout.ordinal != 0
|
||||
fun paddingAvailable(enable: Boolean) {
|
||||
binding.readerPadding.isEnabled = enable
|
||||
}
|
||||
|
||||
binding.readerPadding.isChecked = settings.padding
|
||||
binding.readerPadding.setOnCheckedChangeListener { _,isChecked ->
|
||||
binding.readerPadding.setOnCheckedChangeListener { _, isChecked ->
|
||||
settings.padding = isChecked
|
||||
activity.applySettings()
|
||||
}
|
||||
|
||||
binding.readerCropBorders.isChecked = settings.cropBorders
|
||||
binding.readerCropBorders.setOnCheckedChangeListener { _,isChecked ->
|
||||
binding.readerCropBorders.setOnCheckedChangeListener { _, isChecked ->
|
||||
settings.cropBorders = isChecked
|
||||
activity.applySettings()
|
||||
}
|
||||
|
||||
binding.readerLayoutText.text = resources.getStringArray(R.array.manga_layouts)[settings.layout.ordinal]
|
||||
binding.readerLayoutText.text =
|
||||
resources.getStringArray(R.array.manga_layouts)[settings.layout.ordinal]
|
||||
var selected = list[settings.layout.ordinal]
|
||||
selected.alpha = 1f
|
||||
|
||||
list.forEachIndexed { index , imageButton ->
|
||||
list.forEachIndexed { index, imageButton ->
|
||||
imageButton.setOnClickListener {
|
||||
selected.alpha = 0.33f
|
||||
selected = imageButton
|
||||
selected.alpha = 1f
|
||||
settings.layout = CurrentReaderSettings.Layouts[index]?:CurrentReaderSettings.Layouts.CONTINUOUS
|
||||
binding.readerLayoutText.text = resources.getStringArray(R.array.manga_layouts)[settings.layout.ordinal]
|
||||
settings.layout =
|
||||
CurrentReaderSettings.Layouts[index] ?: CurrentReaderSettings.Layouts.CONTINUOUS
|
||||
binding.readerLayoutText.text =
|
||||
resources.getStringArray(R.array.manga_layouts)[settings.layout.ordinal]
|
||||
activity.applySettings()
|
||||
paddingAvailable(settings.layout.ordinal!=0)
|
||||
paddingAvailable(settings.layout.ordinal != 0)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,7 +97,8 @@ class ReaderSettingsDialogFragment : BottomSheetDialogFragment() {
|
|||
selectedDual.alpha = 0.33f
|
||||
selectedDual = imageButton
|
||||
selectedDual.alpha = 1f
|
||||
settings.dualPageMode = CurrentReaderSettings.DualPageModes[index] ?: CurrentReaderSettings.DualPageModes.Automatic
|
||||
settings.dualPageMode = CurrentReaderSettings.DualPageModes[index]
|
||||
?: CurrentReaderSettings.DualPageModes.Automatic
|
||||
binding.readerDualPageText.text = settings.dualPageMode.toString()
|
||||
activity.applySettings()
|
||||
}
|
||||
|
@ -111,37 +122,37 @@ class ReaderSettingsDialogFragment : BottomSheetDialogFragment() {
|
|||
}
|
||||
|
||||
binding.readerKeepScreenOn.isChecked = settings.keepScreenOn
|
||||
binding.readerKeepScreenOn.setOnCheckedChangeListener { _,isChecked ->
|
||||
binding.readerKeepScreenOn.setOnCheckedChangeListener { _, isChecked ->
|
||||
settings.keepScreenOn = isChecked
|
||||
activity.applySettings()
|
||||
}
|
||||
|
||||
binding.readerHidePageNumbers.isChecked = settings.hidePageNumbers
|
||||
binding.readerHidePageNumbers.setOnCheckedChangeListener { _,isChecked ->
|
||||
binding.readerHidePageNumbers.setOnCheckedChangeListener { _, isChecked ->
|
||||
settings.hidePageNumbers = isChecked
|
||||
activity.applySettings()
|
||||
}
|
||||
|
||||
binding.readerOverscroll.isChecked = settings.overScrollMode
|
||||
binding.readerOverscroll.setOnCheckedChangeListener { _,isChecked ->
|
||||
binding.readerOverscroll.setOnCheckedChangeListener { _, isChecked ->
|
||||
settings.overScrollMode = isChecked
|
||||
activity.applySettings()
|
||||
}
|
||||
|
||||
binding.readerVolumeButton.isChecked = settings.volumeButtons
|
||||
binding.readerVolumeButton.setOnCheckedChangeListener { _,isChecked ->
|
||||
binding.readerVolumeButton.setOnCheckedChangeListener { _, isChecked ->
|
||||
settings.volumeButtons = isChecked
|
||||
activity.applySettings()
|
||||
}
|
||||
|
||||
binding.readerWrapImage.isChecked = settings.wrapImages
|
||||
binding.readerWrapImage.setOnCheckedChangeListener { _,isChecked ->
|
||||
binding.readerWrapImage.setOnCheckedChangeListener { _, isChecked ->
|
||||
settings.wrapImages = isChecked
|
||||
activity.applySettings()
|
||||
}
|
||||
|
||||
binding.readerLongClickImage.isChecked = settings.longClickImage
|
||||
binding.readerLongClickImage.setOnCheckedChangeListener { _,isChecked ->
|
||||
binding.readerLongClickImage.setOnCheckedChangeListener { _, isChecked ->
|
||||
settings.longClickImage = isChecked
|
||||
activity.applySettings()
|
||||
}
|
||||
|
@ -152,7 +163,7 @@ class ReaderSettingsDialogFragment : BottomSheetDialogFragment() {
|
|||
super.onDestroy()
|
||||
}
|
||||
|
||||
companion object{
|
||||
companion object {
|
||||
fun newInstance() = ReaderSettingsDialogFragment()
|
||||
}
|
||||
}
|
|
@ -6,7 +6,8 @@ import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
|
|||
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
|
||||
import java.security.MessageDigest
|
||||
|
||||
class RemoveBordersTransformation(private val white:Boolean, private val threshHold:Int) : BitmapTransformation() {
|
||||
class RemoveBordersTransformation(private val white: Boolean, private val threshHold: Int) :
|
||||
BitmapTransformation() {
|
||||
|
||||
override fun transform(
|
||||
pool: BitmapPool,
|
||||
|
@ -95,6 +96,6 @@ class RemoveBordersTransformation(private val white:Boolean, private val threshH
|
|||
|
||||
private fun isPixelNotWhite(pixel: Int): Boolean {
|
||||
val brightness = Color.red(pixel) + Color.green(pixel) + Color.blue(pixel)
|
||||
return if(white) brightness < (255-threshHold) else brightness > threshHold
|
||||
return if (white) brightness < (255 - threshHold) else brightness > threshHold
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ class Swipy @JvmOverloads constructor(
|
|||
context: Context, attrs: AttributeSet? = null
|
||||
) : FrameLayout(context, attrs) {
|
||||
|
||||
var dragDivider : Int = 5
|
||||
var dragDivider: Int = 5
|
||||
var vertical = true
|
||||
|
||||
//public, in case a different sub child needs to be considered
|
||||
|
@ -100,7 +100,7 @@ class Swipy @JvmOverloads constructor(
|
|||
}
|
||||
|
||||
when (action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
activePointerId = ev.getPointerId(0)
|
||||
isBeingDragged = false
|
||||
pointerIndex = ev.findPointerIndex(activePointerId)
|
||||
|
@ -109,7 +109,8 @@ class Swipy @JvmOverloads constructor(
|
|||
}
|
||||
initialDown = if (vertical) ev.getY(pointerIndex) else ev.getX(pointerIndex)
|
||||
}
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
if (activePointerId == INVALID_POINTER) {
|
||||
//("Got ACTION_MOVE event but don't have an active pointer id.")
|
||||
return false
|
||||
|
@ -121,7 +122,8 @@ class Swipy @JvmOverloads constructor(
|
|||
val pos = if (vertical) ev.getY(pointerIndex) else ev.getX(pointerIndex)
|
||||
startDragging(pos)
|
||||
}
|
||||
MotionEvent.ACTION_POINTER_UP -> onSecondaryPointerUp(ev)
|
||||
|
||||
MotionEvent.ACTION_POINTER_UP -> onSecondaryPointerUp(ev)
|
||||
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
|
||||
isBeingDragged = false
|
||||
activePointerId = INVALID_POINTER
|
||||
|
@ -138,11 +140,12 @@ class Swipy @JvmOverloads constructor(
|
|||
return false
|
||||
}
|
||||
when (action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
activePointerId = ev.getPointerId(0)
|
||||
isBeingDragged = false
|
||||
}
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
pointerIndex = ev.findPointerIndex(activePointerId)
|
||||
if (pointerIndex < 0) {
|
||||
//("Got ACTION_MOVE event but have an invalid active pointer id.")
|
||||
|
@ -160,16 +163,16 @@ class Swipy @JvmOverloads constructor(
|
|||
|
||||
if (overscroll > 0) {
|
||||
parent.requestDisallowInterceptTouchEvent(true)
|
||||
if (vertical){
|
||||
val totalDragDistance = Resources.getSystem().displayMetrics.heightPixels / dragDivider
|
||||
if (vertical) {
|
||||
val totalDragDistance =
|
||||
Resources.getSystem().displayMetrics.heightPixels / dragDivider
|
||||
if (verticalPos == VerticalPosition.Top)
|
||||
topBeingSwiped.invoke(overscroll / totalDragDistance)
|
||||
else
|
||||
bottomBeingSwiped.invoke(overscroll / totalDragDistance)
|
||||
}
|
||||
|
||||
else {
|
||||
val totalDragDistance = Resources.getSystem().displayMetrics.widthPixels / dragDivider
|
||||
} else {
|
||||
val totalDragDistance =
|
||||
Resources.getSystem().displayMetrics.widthPixels / dragDivider
|
||||
if (horizontalPos == HorizontalPosition.Left)
|
||||
leftBeingSwiped.invoke(overscroll / totalDragDistance)
|
||||
else
|
||||
|
@ -180,6 +183,7 @@ class Swipy @JvmOverloads constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
MotionEvent.ACTION_POINTER_DOWN -> {
|
||||
pointerIndex = ev.actionIndex
|
||||
if (pointerIndex < 0) {
|
||||
|
@ -188,8 +192,9 @@ class Swipy @JvmOverloads constructor(
|
|||
}
|
||||
activePointerId = ev.getPointerId(pointerIndex)
|
||||
}
|
||||
MotionEvent.ACTION_POINTER_UP -> onSecondaryPointerUp(ev)
|
||||
MotionEvent.ACTION_UP -> {
|
||||
|
||||
MotionEvent.ACTION_POINTER_UP -> onSecondaryPointerUp(ev)
|
||||
MotionEvent.ACTION_UP -> {
|
||||
if (vertical) {
|
||||
topBeingSwiped.invoke(0f)
|
||||
bottomBeingSwiped.invoke(0f)
|
||||
|
@ -216,7 +221,8 @@ class Swipy @JvmOverloads constructor(
|
|||
activePointerId = INVALID_POINTER
|
||||
return false
|
||||
}
|
||||
MotionEvent.ACTION_CANCEL -> return false
|
||||
|
||||
MotionEvent.ACTION_CANCEL -> return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -235,21 +241,20 @@ class Swipy @JvmOverloads constructor(
|
|||
|
||||
private fun finishSpinner(overscrollDistance: Float) {
|
||||
|
||||
if (vertical) {
|
||||
val totalDragDistance = Resources.getSystem().displayMetrics.heightPixels / dragDivider
|
||||
if (overscrollDistance > totalDragDistance)
|
||||
if (verticalPos == VerticalPosition.Top)
|
||||
onTopSwiped.invoke()
|
||||
else
|
||||
onBottomSwiped.invoke()
|
||||
}
|
||||
else {
|
||||
val totalDragDistance = Resources.getSystem().displayMetrics.widthPixels / dragDivider
|
||||
if (overscrollDistance > totalDragDistance)
|
||||
if (vertical) {
|
||||
val totalDragDistance = Resources.getSystem().displayMetrics.heightPixels / dragDivider
|
||||
if (overscrollDistance > totalDragDistance)
|
||||
if (verticalPos == VerticalPosition.Top)
|
||||
onTopSwiped.invoke()
|
||||
else
|
||||
onBottomSwiped.invoke()
|
||||
} else {
|
||||
val totalDragDistance = Resources.getSystem().displayMetrics.widthPixels / dragDivider
|
||||
if (overscrollDistance > totalDragDistance)
|
||||
if (horizontalPos == HorizontalPosition.Left)
|
||||
onLeftSwiped.invoke()
|
||||
else
|
||||
onRightSwiped.invoke()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue