manga "working" :D
This commit is contained in:
parent
57a584a820
commit
41b90e3a39
32 changed files with 1179 additions and 409 deletions
|
@ -21,14 +21,21 @@ import androidx.core.app.ActivityCompat
|
|||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||
import androidx.viewpager2.widget.ViewPager2
|
||||
import ani.dantotsu.*
|
||||
import eu.kanade.tachiyomi.extension.anime.AnimeExtensionManager
|
||||
import eu.kanade.tachiyomi.extension.anime.model.AnimeExtension
|
||||
import ani.dantotsu.databinding.ActivityExtensionsBinding
|
||||
import ani.dantotsu.home.AnimeFragment
|
||||
import ani.dantotsu.home.MangaFragment
|
||||
import com.bumptech.glide.Glide
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
@ -36,7 +43,10 @@ import kotlinx.coroutines.flow.combine
|
|||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
class ExtensionsActivity : AppCompatActivity() {
|
||||
|
@ -44,52 +54,10 @@ class ExtensionsActivity : AppCompatActivity() {
|
|||
override fun handleOnBackPressed() = startMainActivity(this@ExtensionsActivity)
|
||||
}
|
||||
lateinit var binding: ActivityExtensionsBinding
|
||||
private lateinit var extensionsRecyclerView: RecyclerView
|
||||
private lateinit var allextenstionsRecyclerView: RecyclerView
|
||||
private val animeExtensionManager: AnimeExtensionManager by injectLazy()
|
||||
private val extensionsAdapter = ExtensionsAdapter { pkgName ->
|
||||
animeExtensionManager.uninstallExtension(pkgName)
|
||||
}
|
||||
private val allExtensionsAdapter = AllExtensionsAdapter(lifecycleScope) { pkgName ->
|
||||
|
||||
val notificationManager =
|
||||
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
|
||||
// Start the installation process
|
||||
animeExtensionManager.installExtension(pkgName)
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{ installStep ->
|
||||
val builder = NotificationCompat.Builder(this,
|
||||
Notifications.CHANNEL_DOWNLOADER_PROGRESS
|
||||
)
|
||||
.setSmallIcon(R.drawable.ic_round_sync_24)
|
||||
.setContentTitle("Installing extension")
|
||||
.setContentText("Step: $installStep")
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
notificationManager.notify(1, builder.build())
|
||||
},
|
||||
{ error ->
|
||||
val builder = NotificationCompat.Builder(this,
|
||||
Notifications.CHANNEL_DOWNLOADER_ERROR
|
||||
)
|
||||
.setSmallIcon(R.drawable.ic_round_info_24)
|
||||
.setContentTitle("Installation failed")
|
||||
.setContentText("Error: ${error.message}")
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
notificationManager.notify(1, builder.build())
|
||||
},
|
||||
{
|
||||
val builder = NotificationCompat.Builder(this,
|
||||
Notifications.CHANNEL_DOWNLOADER_PROGRESS)
|
||||
.setSmallIcon(androidx.media3.ui.R.drawable.exo_ic_check)
|
||||
.setContentTitle("Installation complete")
|
||||
.setContentText("The extension has been successfully installed.")
|
||||
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||
notificationManager.notify(1, builder.build())
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
|
@ -98,35 +66,33 @@ class ExtensionsActivity : AppCompatActivity() {
|
|||
binding = ActivityExtensionsBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
extensionsRecyclerView = findViewById(R.id.extensionsRecyclerView)
|
||||
extensionsRecyclerView.layoutManager = LinearLayoutManager(this)
|
||||
extensionsRecyclerView.adapter = extensionsAdapter
|
||||
|
||||
allextenstionsRecyclerView = findViewById(R.id.allExtensionsRecyclerView)
|
||||
allextenstionsRecyclerView.layoutManager = LinearLayoutManager(this)
|
||||
allextenstionsRecyclerView.adapter = allExtensionsAdapter
|
||||
val tabLayout = findViewById<TabLayout>(R.id.tabLayout)
|
||||
val viewPager = findViewById<ViewPager2>(R.id.viewPager)
|
||||
|
||||
lifecycleScope.launch {
|
||||
animeExtensionManager.installedExtensionsFlow.collect { extensions ->
|
||||
extensionsAdapter.updateData(extensions)
|
||||
viewPager.adapter = object : FragmentStateAdapter(this) {
|
||||
override fun getItemCount(): Int = 2
|
||||
|
||||
override fun createFragment(position: Int): Fragment {
|
||||
return when (position) {
|
||||
0 -> AnimeExtensionsFragment()
|
||||
1 -> MangaExtensionsFragment()
|
||||
else -> AnimeExtensionsFragment()
|
||||
}
|
||||
}
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
combine(
|
||||
animeExtensionManager.availableExtensionsFlow,
|
||||
animeExtensionManager.installedExtensionsFlow
|
||||
) { availableExtensions, installedExtensions ->
|
||||
// Pair of available and installed extensions
|
||||
Pair(availableExtensions, installedExtensions)
|
||||
}.collect { pair ->
|
||||
val (availableExtensions, installedExtensions) = pair
|
||||
allExtensionsAdapter.updateData(availableExtensions, installedExtensions)
|
||||
|
||||
TabLayoutMediator(tabLayout, viewPager) { tab, position ->
|
||||
tab.text = when (position) {
|
||||
0 -> "Anime" // Your tab title
|
||||
1 -> "Manga" // Your tab title
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}.attach()
|
||||
|
||||
|
||||
val searchView: SearchView = findViewById(R.id.searchView)
|
||||
val extensionsRecyclerView: RecyclerView = findViewById(R.id.extensionsRecyclerView)
|
||||
|
||||
val extensionsHeader: LinearLayout = findViewById(R.id.extensionsHeader)
|
||||
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||
override fun onQueryTextSubmit(query: String?): Boolean {
|
||||
|
@ -134,17 +100,11 @@ class ExtensionsActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
override fun onQueryTextChange(newText: String?): Boolean {
|
||||
if (newText.isNullOrEmpty()) {
|
||||
allExtensionsAdapter.filter("") // Reset the filter
|
||||
allextenstionsRecyclerView.visibility = View.VISIBLE
|
||||
extensionsHeader.visibility = View.VISIBLE
|
||||
extensionsRecyclerView.visibility = View.VISIBLE
|
||||
} else {
|
||||
allExtensionsAdapter.filter(newText)
|
||||
allextenstionsRecyclerView.visibility = View.VISIBLE
|
||||
extensionsRecyclerView.visibility = View.GONE
|
||||
extensionsHeader.visibility = View.GONE
|
||||
val currentFragment = supportFragmentManager.findFragmentByTag("f${viewPager.currentItem}")
|
||||
if (currentFragment is SearchQueryHandler) {
|
||||
currentFragment.updateContentBasedOnQuery(newText)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
})
|
||||
|
@ -168,104 +128,8 @@ class ExtensionsActivity : AppCompatActivity() {
|
|||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private class ExtensionsAdapter(private val onUninstallClicked: (String) -> Unit) : RecyclerView.Adapter<ExtensionsAdapter.ViewHolder>() {
|
||||
|
||||
private var extensions: List<AnimeExtension.Installed> = emptyList()
|
||||
|
||||
fun updateData(newExtensions: List<AnimeExtension.Installed>) {
|
||||
extensions = newExtensions
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val view = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.item_extension, parent, false)
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val extension = extensions[position]
|
||||
holder.extensionNameTextView.text = extension.name
|
||||
holder.extensionIconImageView.setImageDrawable(extension.icon)
|
||||
holder.closeTextView.text = "Uninstall"
|
||||
holder.closeTextView.setOnClickListener {
|
||||
onUninstallClicked(extension.pkgName)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = extensions.size
|
||||
|
||||
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
val extensionNameTextView: TextView = view.findViewById(R.id.extensionNameTextView)
|
||||
val extensionIconImageView: ImageView = view.findViewById(R.id.extensionIconImageView)
|
||||
val closeTextView: TextView = view.findViewById(R.id.closeTextView)
|
||||
}
|
||||
}
|
||||
|
||||
private class AllExtensionsAdapter(private val coroutineScope: CoroutineScope,
|
||||
private val onButtonClicked: (AnimeExtension.Available) -> Unit) : RecyclerView.Adapter<AllExtensionsAdapter.ViewHolder>() {
|
||||
private var extensions: List<AnimeExtension.Available> = emptyList()
|
||||
|
||||
fun updateData(newExtensions: List<AnimeExtension.Available>, installedExtensions: List<AnimeExtension.Installed> = emptyList()) {
|
||||
val installedPkgNames = installedExtensions.map { it.pkgName }.toSet()
|
||||
extensions = newExtensions.filter { it.pkgName !in installedPkgNames }
|
||||
filteredExtensions = extensions
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AllExtensionsAdapter.ViewHolder {
|
||||
val view = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.item_extension_all, parent, false)
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val extension = filteredExtensions[position]
|
||||
holder.extensionNameTextView.text = extension.name
|
||||
coroutineScope.launch {
|
||||
val drawable = urlToDrawable(holder.itemView.context, extension.iconUrl)
|
||||
holder.extensionIconImageView.setImageDrawable(drawable)
|
||||
}
|
||||
holder.closeTextView.text = "Install"
|
||||
holder.closeTextView.setOnClickListener {
|
||||
onButtonClicked(extension)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = filteredExtensions.size
|
||||
|
||||
private var filteredExtensions: List<AnimeExtension.Available> = emptyList()
|
||||
|
||||
fun filter(query: String) {
|
||||
filteredExtensions = if (query.isEmpty()) {
|
||||
extensions
|
||||
} else {
|
||||
extensions.filter { it.name.contains(query, ignoreCase = true) }
|
||||
}
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
val extensionNameTextView: TextView = view.findViewById(R.id.extensionNameTextView)
|
||||
val extensionIconImageView: ImageView = view.findViewById(R.id.extensionIconImageView)
|
||||
val closeTextView: TextView = view.findViewById(R.id.closeTextView)
|
||||
}
|
||||
|
||||
suspend fun urlToDrawable(context: Context, url: String): Drawable? {
|
||||
return withContext(Dispatchers.IO) {
|
||||
try {
|
||||
return@withContext Glide.with(context)
|
||||
.load(url)
|
||||
.submit()
|
||||
.get()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
return@withContext null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface SearchQueryHandler {
|
||||
fun updateContentBasedOnQuery(query: String?)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue