Light novel support
This commit is contained in:
parent
32f918450a
commit
c7bc1ffe9e
39 changed files with 2537 additions and 91 deletions
|
@ -30,7 +30,7 @@ import ani.dantotsu.databinding.FragmentAnimeWatchBinding
|
|||
import ani.dantotsu.download.Download
|
||||
import ani.dantotsu.download.DownloadsManager
|
||||
import ani.dantotsu.download.manga.MangaDownloaderService
|
||||
import ani.dantotsu.download.manga.ServiceDataSingleton
|
||||
import ani.dantotsu.download.manga.MangaServiceDataSingleton
|
||||
import ani.dantotsu.media.manga.mangareader.ChapterLoaderDialog
|
||||
import ani.dantotsu.media.Media
|
||||
import ani.dantotsu.media.MediaDetailsActivity
|
||||
|
@ -408,15 +408,15 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
|
|||
simultaneousDownloads = 2
|
||||
)
|
||||
|
||||
ServiceDataSingleton.downloadQueue.offer(downloadTask)
|
||||
MangaServiceDataSingleton.downloadQueue.offer(downloadTask)
|
||||
|
||||
// If the service is not already running, start it
|
||||
if (!ServiceDataSingleton.isServiceRunning) {
|
||||
if (!MangaServiceDataSingleton.isServiceRunning) {
|
||||
val intent = Intent(context, MangaDownloaderService::class.java)
|
||||
withContext(Dispatchers.Main) {
|
||||
ContextCompat.startForegroundService(requireContext(), intent)
|
||||
}
|
||||
ServiceDataSingleton.isServiceRunning = true
|
||||
MangaServiceDataSingleton.isServiceRunning = true
|
||||
}
|
||||
|
||||
// Inform the adapter that the download has started
|
||||
|
@ -456,6 +456,7 @@ open class MangaReadFragment : Fragment(), ScanlatorSelectionListener {
|
|||
}
|
||||
private val downloadStatusReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
if(!this@MangaReadFragment::chapterAdapter.isInitialized) return
|
||||
when (intent.action) {
|
||||
ACTION_DOWNLOAD_STARTED -> {
|
||||
val chapterNumber = intent.getStringExtra(EXTRA_CHAPTER_NUMBER)
|
||||
|
|
|
@ -29,6 +29,14 @@ class BookDialog : BottomSheetDialogFragment() {
|
|||
private lateinit var novel: ShowResponse
|
||||
private var source:Int = 0
|
||||
|
||||
interface Callback {
|
||||
fun onDownloadTriggered(link: String)
|
||||
}
|
||||
private var callback: Callback? = null
|
||||
fun setCallback(callback: Callback) {
|
||||
this.callback = callback
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
arguments?.let {
|
||||
novelName = it.getString("novelName")!!
|
||||
|
@ -51,7 +59,7 @@ class BookDialog : BottomSheetDialogFragment() {
|
|||
binding.itemBookTitle.text = it.name
|
||||
binding.itemBookDesc.text = it.description
|
||||
binding.itemBookImage.loadImage(it.img)
|
||||
binding.bookRecyclerView.adapter = UrlAdapter(it.links, it, novelName)
|
||||
binding.bookRecyclerView.adapter = UrlAdapter(it.links, it, novelName, callback)
|
||||
}
|
||||
}
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
|
|
|
@ -64,7 +64,7 @@ class NovelReadAdapter(
|
|||
binding.searchBar.setEndIconOnClickListener { search() }
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = 0
|
||||
override fun getItemCount(): Int = 1
|
||||
|
||||
inner class ViewHolder(val binding: ItemNovelHeaderBinding) : RecyclerView.ViewHolder(binding.root)
|
||||
}
|
|
@ -1,12 +1,20 @@
|
|||
package ani.dantotsu.media.novel
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.Parcelable
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
|
@ -14,16 +22,29 @@ import androidx.lifecycle.lifecycleScope
|
|||
import androidx.recyclerview.widget.ConcatAdapter
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import ani.dantotsu.databinding.FragmentAnimeWatchBinding
|
||||
import ani.dantotsu.download.Download
|
||||
import ani.dantotsu.download.DownloadsManager
|
||||
import ani.dantotsu.download.novel.NovelDownloaderService
|
||||
import ani.dantotsu.download.novel.NovelServiceDataSingleton
|
||||
import ani.dantotsu.loadData
|
||||
import ani.dantotsu.media.Media
|
||||
import ani.dantotsu.media.MediaDetailsViewModel
|
||||
import ani.dantotsu.media.novel.novelreader.NovelReaderActivity
|
||||
import ani.dantotsu.navBarHeight
|
||||
import ani.dantotsu.parsers.ShowResponse
|
||||
import ani.dantotsu.saveData
|
||||
import ani.dantotsu.settings.UserInterfaceSettings
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.io.File
|
||||
|
||||
class NovelReadFragment : Fragment() {
|
||||
class NovelReadFragment : Fragment(),
|
||||
DownloadTriggerCallback,
|
||||
DownloadedCheckCallback {
|
||||
|
||||
private var _binding: FragmentAnimeWatchBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
@ -42,9 +63,104 @@ class NovelReadFragment : Fragment() {
|
|||
|
||||
val uiSettings = loadData("ui_settings", toast = false) ?: UserInterfaceSettings().apply { saveData("ui_settings", this) }
|
||||
|
||||
override fun downloadTrigger(novelDownloadPackage: NovelDownloadPackage) {
|
||||
Log.e("downloadTrigger", novelDownloadPackage.link)
|
||||
val downloadTask = NovelDownloaderService.DownloadTask(
|
||||
title = media.nameMAL ?: media.nameRomaji,
|
||||
chapter = novelDownloadPackage.novelName,
|
||||
downloadLink = novelDownloadPackage.link,
|
||||
originalLink = novelDownloadPackage.originalLink,
|
||||
sourceMedia = media,
|
||||
coverUrl = novelDownloadPackage.coverUrl,
|
||||
retries = 2,
|
||||
)
|
||||
NovelServiceDataSingleton.downloadQueue.offer(downloadTask)
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
|
||||
if (!NovelServiceDataSingleton.isServiceRunning) {
|
||||
val intent = Intent(context, NovelDownloaderService::class.java)
|
||||
withContext(Dispatchers.Main) {
|
||||
ContextCompat.startForegroundService(requireContext(), intent)
|
||||
}
|
||||
NovelServiceDataSingleton.isServiceRunning = true
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun downloadedCheckWithStart(novel: ShowResponse): Boolean {
|
||||
val downloadsManager = Injekt.get<DownloadsManager>()
|
||||
if(downloadsManager.queryDownload(Download(media.nameMAL ?: media.nameRomaji, novel.name, Download.Type.NOVEL))) {
|
||||
val file = File(context?.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "${DownloadsManager.novelLocation}/${media.nameMAL ?: media.nameRomaji}/${novel.name}/0.epub")
|
||||
if (!file.exists()) return false
|
||||
val fileUri = FileProvider.getUriForFile(requireContext(), "${requireContext().packageName}.provider", file)
|
||||
val intent = Intent(context, NovelReaderActivity::class.java).apply {
|
||||
action = Intent.ACTION_VIEW
|
||||
setDataAndType(fileUri, "application/epub+zip")
|
||||
flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
}
|
||||
startActivity(intent)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
override fun downloadedCheck(novel: ShowResponse): Boolean {
|
||||
val downloadsManager = Injekt.get<DownloadsManager>()
|
||||
return downloadsManager.queryDownload(Download(media.nameMAL ?: media.nameRomaji, novel.name, Download.Type.NOVEL))
|
||||
}
|
||||
|
||||
override fun deleteDownload(novel: ShowResponse) {
|
||||
val downloadsManager = Injekt.get<DownloadsManager>()
|
||||
downloadsManager.removeDownload(Download(media.nameMAL ?: media.nameRomaji, novel.name, Download.Type.NOVEL))
|
||||
}
|
||||
|
||||
private val downloadStatusReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
if (!this@NovelReadFragment::novelResponseAdapter.isInitialized) return
|
||||
when (intent.action) {
|
||||
ACTION_DOWNLOAD_STARTED -> {
|
||||
val link = intent.getStringExtra(EXTRA_NOVEL_LINK)
|
||||
link?.let {
|
||||
novelResponseAdapter.startDownload(it)
|
||||
}
|
||||
}
|
||||
ACTION_DOWNLOAD_FINISHED -> {
|
||||
val link = intent.getStringExtra(EXTRA_NOVEL_LINK)
|
||||
link?.let {
|
||||
novelResponseAdapter.stopDownload(it)
|
||||
}
|
||||
}
|
||||
ACTION_DOWNLOAD_FAILED -> {
|
||||
val link = intent.getStringExtra(EXTRA_NOVEL_LINK)
|
||||
link?.let {
|
||||
novelResponseAdapter.purgeDownload(it)
|
||||
}
|
||||
}
|
||||
ACTION_DOWNLOAD_PROGRESS -> {
|
||||
val link = intent.getStringExtra(EXTRA_NOVEL_LINK)
|
||||
val progress = intent.getIntExtra("progress", 0)
|
||||
link?.let {
|
||||
novelResponseAdapter.updateDownloadProgress(it, progress)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var response: List<ShowResponse>? = null
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val intentFilter = IntentFilter().apply {
|
||||
addAction(ACTION_DOWNLOAD_STARTED)
|
||||
addAction(ACTION_DOWNLOAD_FINISHED)
|
||||
addAction(ACTION_DOWNLOAD_FAILED)
|
||||
addAction(ACTION_DOWNLOAD_PROGRESS)
|
||||
}
|
||||
|
||||
ContextCompat.registerReceiver(requireContext(), downloadStatusReceiver, intentFilter ,ContextCompat.RECEIVER_EXPORTED)
|
||||
|
||||
binding.animeSourceRecycler.updatePadding(bottom = binding.animeSourceRecycler.paddingBottom + navBarHeight)
|
||||
|
||||
binding.animeSourceRecycler.layoutManager = LinearLayoutManager(requireContext())
|
||||
|
@ -63,7 +179,7 @@ class NovelReadFragment : Fragment() {
|
|||
val sel = media.selected
|
||||
searchQuery = sel?.server ?: media.name ?: media.nameRomaji
|
||||
headerAdapter = NovelReadAdapter(media, this, model.novelSources)
|
||||
novelResponseAdapter = NovelResponseAdapter(this)
|
||||
novelResponseAdapter = NovelResponseAdapter(this, this, this) // probably a better way to do this but it works
|
||||
binding.animeSourceRecycler.adapter = ConcatAdapter(headerAdapter, novelResponseAdapter)
|
||||
loaded = true
|
||||
Handler(Looper.getMainLooper()).postDelayed({
|
||||
|
@ -74,6 +190,7 @@ class NovelReadFragment : Fragment() {
|
|||
}
|
||||
model.novelResponses.observe(viewLifecycleOwner) {
|
||||
if (it != null) {
|
||||
response = it
|
||||
searching = false
|
||||
novelResponseAdapter.submitList(it)
|
||||
headerAdapter.progress?.visibility = View.GONE
|
||||
|
@ -121,6 +238,7 @@ class NovelReadFragment : Fragment() {
|
|||
|
||||
override fun onDestroy() {
|
||||
model.mangaReadSources?.flushText()
|
||||
requireContext().unregisterReceiver(downloadStatusReceiver)
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
|
@ -135,4 +253,22 @@ class NovelReadFragment : Fragment() {
|
|||
super.onPause()
|
||||
state = binding.animeSourceRecycler.layoutManager?.onSaveInstanceState()
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val ACTION_DOWNLOAD_STARTED = "ani.dantotsu.ACTION_DOWNLOAD_STARTED"
|
||||
const val ACTION_DOWNLOAD_FINISHED = "ani.dantotsu.ACTION_DOWNLOAD_FINISHED"
|
||||
const val ACTION_DOWNLOAD_FAILED = "ani.dantotsu.ACTION_DOWNLOAD_FAILED"
|
||||
const val ACTION_DOWNLOAD_PROGRESS = "ani.dantotsu.ACTION_DOWNLOAD_PROGRESS"
|
||||
const val EXTRA_NOVEL_LINK = "extra_novel_link"
|
||||
}
|
||||
}
|
||||
|
||||
interface DownloadTriggerCallback {
|
||||
fun downloadTrigger(novelDownloadPackage: NovelDownloadPackage)
|
||||
}
|
||||
|
||||
interface DownloadedCheckCallback {
|
||||
fun downloadedCheck(novel: ShowResponse): Boolean
|
||||
fun downloadedCheckWithStart(novel: ShowResponse): Boolean
|
||||
fun deleteDownload(novel: ShowResponse)
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package ani.dantotsu.media.novel
|
||||
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
|
@ -7,16 +8,23 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import ani.dantotsu.databinding.ItemNovelResponseBinding
|
||||
import ani.dantotsu.parsers.ShowResponse
|
||||
import ani.dantotsu.setAnimation
|
||||
import ani.dantotsu.snackString
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.model.GlideUrl
|
||||
|
||||
class NovelResponseAdapter(val fragment: NovelReadFragment) : RecyclerView.Adapter<NovelResponseAdapter.ViewHolder>() {
|
||||
class NovelResponseAdapter(
|
||||
val fragment: NovelReadFragment,
|
||||
val downloadTriggerCallback: DownloadTriggerCallback,
|
||||
val downloadedCheckCallback: DownloadedCheckCallback
|
||||
) : RecyclerView.Adapter<NovelResponseAdapter.ViewHolder>() {
|
||||
val list: MutableList<ShowResponse> = mutableListOf()
|
||||
|
||||
inner class ViewHolder(val binding: ItemNovelResponseBinding) : RecyclerView.ViewHolder(binding.root)
|
||||
inner class ViewHolder(val binding: ItemNovelResponseBinding) :
|
||||
RecyclerView.ViewHolder(binding.root)
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val bind = ItemNovelResponseBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
val bind =
|
||||
ItemNovelResponseBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
return ViewHolder(bind)
|
||||
}
|
||||
|
||||
|
@ -27,19 +35,128 @@ class NovelResponseAdapter(val fragment: NovelReadFragment) : RecyclerView.Adapt
|
|||
val novel = list[position]
|
||||
setAnimation(fragment.requireContext(), holder.binding.root, fragment.uiSettings)
|
||||
|
||||
val cover = GlideUrl(novel.coverUrl.url){ novel.coverUrl.headers }
|
||||
Glide.with(binding.itemEpisodeImage).load(cover).override(400,0).into(binding.itemEpisodeImage)
|
||||
val cover = GlideUrl(novel.coverUrl.url) { novel.coverUrl.headers }
|
||||
Glide.with(binding.itemEpisodeImage).load(cover).override(400, 0)
|
||||
.into(binding.itemEpisodeImage)
|
||||
|
||||
binding.itemEpisodeTitle.text = novel.name
|
||||
binding.itemEpisodeFiller.text = novel.extra?.get("0") ?: ""
|
||||
binding.itemEpisodeFiller.text =
|
||||
if (downloadedCheckCallback.downloadedCheck(novel)) {
|
||||
"Downloaded"
|
||||
} else {
|
||||
novel.extra?.get("0") ?: ""
|
||||
}
|
||||
if (binding.itemEpisodeFiller.text.contains("Downloading")) {
|
||||
binding.itemEpisodeFiller.setTextColor(
|
||||
fragment.requireContext().getColor(android.R.color.holo_blue_light)
|
||||
)
|
||||
} else if (binding.itemEpisodeFiller.text.contains("Downloaded")) {
|
||||
binding.itemEpisodeFiller.setTextColor(
|
||||
fragment.requireContext().getColor(android.R.color.holo_green_light)
|
||||
)
|
||||
} else {
|
||||
binding.itemEpisodeFiller.setTextColor(
|
||||
fragment.requireContext().getColor(android.R.color.white)
|
||||
)
|
||||
}
|
||||
binding.itemEpisodeDesc2.text = novel.extra?.get("1") ?: ""
|
||||
val desc = novel.extra?.get("2")
|
||||
binding.itemEpisodeDesc.visibility = if (desc != null && desc.trim(' ') != "") View.VISIBLE else View.GONE
|
||||
binding.itemEpisodeDesc.visibility =
|
||||
if (desc != null && desc.trim(' ') != "") View.VISIBLE else View.GONE
|
||||
binding.itemEpisodeDesc.text = desc ?: ""
|
||||
|
||||
binding.root.setOnClickListener {
|
||||
BookDialog.newInstance(fragment.novelName, novel, fragment.source)
|
||||
.show(fragment.parentFragmentManager, "dialog")
|
||||
//make sure the file is not downloading
|
||||
if (activeDownloads.contains(novel.link)) {
|
||||
return@setOnClickListener
|
||||
}
|
||||
if (downloadedCheckCallback.downloadedCheckWithStart(novel)) {
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
val bookDialog = BookDialog.newInstance(fragment.novelName, novel, fragment.source)
|
||||
|
||||
bookDialog.setCallback(object : BookDialog.Callback {
|
||||
override fun onDownloadTriggered(link: String) {
|
||||
downloadTriggerCallback.downloadTrigger(
|
||||
NovelDownloadPackage(
|
||||
link,
|
||||
novel.coverUrl.url,
|
||||
novel.name,
|
||||
novel.link
|
||||
)
|
||||
)
|
||||
bookDialog.dismiss()
|
||||
}
|
||||
})
|
||||
bookDialog.show(fragment.parentFragmentManager, "dialog")
|
||||
|
||||
}
|
||||
|
||||
binding.root.setOnLongClickListener {
|
||||
downloadedCheckCallback.deleteDownload(novel)
|
||||
deleteDownload(novel.link)
|
||||
snackString("Deleted ${novel.name}")
|
||||
if (binding.itemEpisodeFiller.text.toString().contains("Download", ignoreCase = true)) {
|
||||
binding.itemEpisodeFiller.text = ""
|
||||
}
|
||||
notifyItemChanged(position)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
private val activeDownloads = mutableSetOf<String>()
|
||||
private val downloadedChapters = mutableSetOf<String>()
|
||||
|
||||
fun startDownload(link: String) {
|
||||
activeDownloads.add(link)
|
||||
val position = list.indexOfFirst { it.link == link }
|
||||
if (position != -1) {
|
||||
list[position].extra?.remove("0")
|
||||
list[position].extra?.set("0", "Downloading: 0%")
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun stopDownload(link: String) {
|
||||
activeDownloads.remove(link)
|
||||
downloadedChapters.add(link)
|
||||
val position = list.indexOfFirst { it.link == link }
|
||||
if (position != -1) {
|
||||
list[position].extra?.remove("0")
|
||||
list[position].extra?.set("0", "Downloaded")
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
}
|
||||
|
||||
fun deleteDownload(link: String) { //TODO:
|
||||
downloadedChapters.remove(link)
|
||||
val position = list.indexOfFirst { it.link == link }
|
||||
if (position != -1) {
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
}
|
||||
|
||||
fun purgeDownload(link: String) {
|
||||
activeDownloads.remove(link)
|
||||
downloadedChapters.remove(link)
|
||||
val position = list.indexOfFirst { it.link == link }
|
||||
if (position != -1) {
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateDownloadProgress(link: String, progress: Int) {
|
||||
if (!activeDownloads.contains(link)) {
|
||||
activeDownloads.add(link)
|
||||
}
|
||||
val position = list.indexOfFirst { it.link == link }
|
||||
if (position != -1) {
|
||||
list[position].extra?.remove("0")
|
||||
list[position].extra?.set("0", "Downloading: $progress%")
|
||||
Log.d("NovelResponseAdapter", "updateDownloadProgress: $progress, position: $position")
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,4 +171,11 @@ class NovelResponseAdapter(val fragment: NovelReadFragment) : RecyclerView.Adapt
|
|||
list.clear()
|
||||
notifyItemRangeRemoved(0, size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class NovelDownloadPackage(
|
||||
val link: String,
|
||||
val coverUrl: String,
|
||||
val novelName: String,
|
||||
val originalLink: String
|
||||
)
|
|
@ -9,12 +9,11 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import ani.dantotsu.FileUrl
|
||||
import ani.dantotsu.copyToClipboard
|
||||
import ani.dantotsu.databinding.ItemUrlBinding
|
||||
import ani.dantotsu.others.Download.download
|
||||
import ani.dantotsu.parsers.Book
|
||||
import ani.dantotsu.setSafeOnClickListener
|
||||
import ani.dantotsu.tryWith
|
||||
|
||||
class UrlAdapter(private val urls: List<FileUrl>, val book: Book, val novel: String) :
|
||||
class UrlAdapter(private val urls: List<FileUrl>, val book: Book, val novel: String, val callback: BookDialog.Callback?) :
|
||||
RecyclerView.Adapter<UrlAdapter.UrlViewHolder>() {
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UrlViewHolder {
|
||||
|
@ -26,6 +25,7 @@ class UrlAdapter(private val urls: List<FileUrl>, val book: Book, val novel: Str
|
|||
val binding = holder.binding
|
||||
val url = urls[position]
|
||||
binding.urlQuality.text = url.url
|
||||
binding.urlQuality.maxLines = 4
|
||||
binding.urlDownload.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
|
@ -36,12 +36,14 @@ class UrlAdapter(private val urls: List<FileUrl>, val book: Book, val novel: Str
|
|||
itemView.setSafeOnClickListener {
|
||||
tryWith(true) {
|
||||
binding.urlDownload.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS)
|
||||
download(
|
||||
callback?.onDownloadTriggered(book.links[bindingAdapterPosition].url)
|
||||
/*download(
|
||||
itemView.context,
|
||||
book,
|
||||
bindingAdapterPosition,
|
||||
novel
|
||||
)
|
||||
)*/
|
||||
|
||||
}
|
||||
}
|
||||
itemView.setOnLongClickListener {
|
||||
|
|
|
@ -138,7 +138,7 @@ class NovelReaderActivity : AppCompatActivity(), EbookReaderEventListener {
|
|||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
LangSet.setLocale(this)
|
||||
ThemeManager(this).applyTheme()
|
||||
ThemeManager(this).applyTheme()
|
||||
binding = ActivityNovelReaderBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue