diff --git a/app/src/main/java/ani/dantotsu/settings/SubscriptionItem.kt b/app/src/main/java/ani/dantotsu/settings/SubscriptionItem.kt index bb8c0396..bb60cd4e 100644 --- a/app/src/main/java/ani/dantotsu/settings/SubscriptionItem.kt +++ b/app/src/main/java/ani/dantotsu/settings/SubscriptionItem.kt @@ -9,31 +9,25 @@ import ani.dantotsu.loadImage import ani.dantotsu.media.MediaDetailsActivity import ani.dantotsu.notifications.subscription.SubscriptionHelper import com.xwray.groupie.GroupieAdapter -import com.xwray.groupie.Item import com.xwray.groupie.viewbinding.BindableItem class SubscriptionItem( val id: Int, private val media: SubscriptionHelper.Companion.SubscribeMedia, - private val adapter: GroupieAdapter + private val adapter: GroupieAdapter, + private val onItemRemoved: (Int) -> Unit ) : BindableItem() { private lateinit var binding: ItemSubscriptionBinding - override fun bind(p0: ItemSubscriptionBinding, p1: Int) { - val context = p0.root.context - binding = p0 - val parserName = if (media.isAnime) - SubscriptionHelper.getAnimeParser(media.id).name - else - SubscriptionHelper.getMangaParser(media.id).name - val mediaName = media.name - val showName = "$mediaName ($parserName)" - binding.subscriptionName.text = showName + + override fun bind(viewBinding: ItemSubscriptionBinding, position: Int) { + binding = viewBinding + val context = binding.root.context + + binding.subscriptionName.text = media.name binding.root.setOnClickListener { ContextCompat.startActivity( context, - Intent(context, MediaDetailsActivity::class.java).putExtra( - "mediaId", media.id - ), + Intent(context, MediaDetailsActivity::class.java).putExtra("mediaId", media.id), null ) } @@ -41,14 +35,11 @@ class SubscriptionItem( binding.deleteSubscription.setOnClickListener { SubscriptionHelper.deleteSubscription(id, true) adapter.remove(this) + onItemRemoved(id) } } - override fun getLayout(): Int { - return R.layout.item_subscription - } + override fun getLayout(): Int = R.layout.item_subscription - override fun initializeViewBinding(p0: View): ItemSubscriptionBinding { - return ItemSubscriptionBinding.bind(p0) - } + override fun initializeViewBinding(view: View): ItemSubscriptionBinding = ItemSubscriptionBinding.bind(view) } \ No newline at end of file diff --git a/app/src/main/java/ani/dantotsu/settings/SubscriptionSource.kt b/app/src/main/java/ani/dantotsu/settings/SubscriptionSource.kt new file mode 100644 index 00000000..80975159 --- /dev/null +++ b/app/src/main/java/ani/dantotsu/settings/SubscriptionSource.kt @@ -0,0 +1,113 @@ +package ani.dantotsu.settings + +import android.app.AlertDialog +import android.content.Context +import android.graphics.drawable.Drawable +import android.view.View +import android.view.ViewGroup +import ani.dantotsu.R +import ani.dantotsu.databinding.ItemExtensionBinding +import ani.dantotsu.notifications.subscription.SubscriptionHelper +import com.xwray.groupie.GroupieAdapter +import com.xwray.groupie.viewbinding.BindableItem + +class SubscriptionSource( + private val parserName: String, + private val subscriptions: MutableList, + private val adapter: GroupieAdapter, + private var parserIcon: Drawable? = null, + private val onGroupRemoved: (SubscriptionSource) -> Unit +) : BindableItem() { + private lateinit var binding: ItemExtensionBinding + private var isExpanded = false + + override fun bind(viewBinding: ItemExtensionBinding, position: Int) { + binding = viewBinding + binding.extensionNameTextView.text = parserName + updateSubscriptionCount() + binding.extensionSubscriptions.visibility = View.VISIBLE + + binding.extensionSubscriptions.setOnClickListener(null) + binding.root.setOnClickListener { + isExpanded = !isExpanded + toggleSubscriptions() + } + binding.subscriptionCount.setOnClickListener { + showRemoveAllSubscriptionsDialog(it.context) + } + binding.extensionIconImageView.visibility = View.VISIBLE + val layoutParams = binding.extensionIconImageView.layoutParams as ViewGroup.MarginLayoutParams + layoutParams.leftMargin = 28 + binding.extensionIconImageView.layoutParams = layoutParams + + parserIcon?.let { + binding.extensionIconImageView.setImageDrawable(it) + } ?: run { + binding.extensionIconImageView.setImageResource(R.drawable.control_background_40dp) + } + + binding.extensionPinImageView.visibility = View.GONE + binding.extensionVersionTextView.visibility = View.GONE + binding.closeTextView.visibility = View.GONE + binding.settingsImageView.visibility = View.GONE + } + + private fun updateSubscriptionCount() { + binding.subscriptionCount.text = subscriptions.size.toString() + binding.subscriptionCount.visibility = if (subscriptions.isEmpty()) View.GONE else View.VISIBLE + } + + private fun showRemoveAllSubscriptionsDialog(context: Context) { + AlertDialog.Builder(context, R.style.MyPopup) + .setTitle(R.string.remove_all_subscriptions) + .setMessage(context.getString(R.string.remove_all_subscriptions_desc, parserName)) + .setPositiveButton(R.string.apply) { _, _ -> + removeAllSubscriptions() + } + .setNegativeButton(R.string.cancel, null) + .show() + } + + private fun removeAllSubscriptions() { + subscriptions.forEach { subscription -> + SubscriptionHelper.deleteSubscription(subscription.id, false) + } + if (isExpanded) { + val startPosition = adapter.getAdapterPosition(this) + 1 + repeat(subscriptions.size) { + adapter.removeGroupAtAdapterPosition(startPosition) + } + } + subscriptions.clear() + onGroupRemoved(this) + } + + private fun removeSubscription(id: Any?) { + subscriptions.removeAll { it.id == id } + updateSubscriptionCount() + if (subscriptions.isEmpty()) { + onGroupRemoved(this) + } else { + adapter.notifyItemChanged(adapter.getAdapterPosition(this)) + } + } + + private fun toggleSubscriptions() { + val startPosition = adapter.getAdapterPosition(this) + 1 + if (isExpanded) { + subscriptions.forEachIndexed { index, subscribeMedia -> + adapter.add(startPosition + index, SubscriptionItem(subscribeMedia.id, subscribeMedia, adapter) { removedId -> + removeSubscription(removedId) + }) + } + } else { + repeat(subscriptions.size) { + adapter.removeGroupAtAdapterPosition(startPosition) + } + } + } + + override fun getLayout(): Int = R.layout.item_extension + + override fun initializeViewBinding(view: View): ItemExtensionBinding = ItemExtensionBinding.bind(view) +} \ No newline at end of file diff --git a/app/src/main/java/ani/dantotsu/settings/SubscriptionsBottomDialog.kt b/app/src/main/java/ani/dantotsu/settings/SubscriptionsBottomDialog.kt index 2b833114..93fd58db 100644 --- a/app/src/main/java/ani/dantotsu/settings/SubscriptionsBottomDialog.kt +++ b/app/src/main/java/ani/dantotsu/settings/SubscriptionsBottomDialog.kt @@ -1,5 +1,6 @@ package ani.dantotsu.settings +import android.graphics.drawable.Drawable import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -9,13 +10,21 @@ import ani.dantotsu.BottomSheetDialogFragment import ani.dantotsu.R import ani.dantotsu.databinding.BottomSheetRecyclerBinding import ani.dantotsu.notifications.subscription.SubscriptionHelper +import ani.dantotsu.parsers.novel.NovelExtensionManager import com.xwray.groupie.GroupieAdapter +import eu.kanade.tachiyomi.extension.anime.AnimeExtensionManager +import eu.kanade.tachiyomi.extension.manga.MangaExtensionManager +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get class SubscriptionsBottomDialog : BottomSheetDialogFragment() { private var _binding: BottomSheetRecyclerBinding? = null private val binding get() = _binding!! private val adapter: GroupieAdapter = GroupieAdapter() private var subscriptions: Map = mapOf() + private val animeExtension: AnimeExtensionManager = Injekt.get() + private val mangaExtensions: MangaExtensionManager = Injekt.get() + private val novelExtensions: NovelExtensionManager = Injekt.get() override fun onCreateView( inflater: LayoutInflater, @@ -36,8 +45,33 @@ class SubscriptionsBottomDialog : BottomSheetDialogFragment() { val context = requireContext() binding.title.text = context.getString(R.string.subscriptions) binding.replyButton.visibility = View.GONE - subscriptions.forEach { (id, media) -> - adapter.add(SubscriptionItem(id, media, adapter)) + + val groupedSubscriptions = subscriptions.values.groupBy { + if (it.isAnime) SubscriptionHelper.getAnimeParser(it.id).name + else SubscriptionHelper.getMangaParser(it.id).name + } + + groupedSubscriptions.forEach { (parserName, mediaList) -> + adapter.add(SubscriptionSource( + parserName, + mediaList.toMutableList(), + adapter, + getParserIcon(parserName) + ) { group -> + adapter.remove(group) + }) + } + } + + private fun getParserIcon(parserName: String): Drawable? { + return when { + animeExtension.installedExtensionsFlow.value.any { it.name == parserName } -> + animeExtension.installedExtensionsFlow.value.find { it.name == parserName }?.icon + mangaExtensions.installedExtensionsFlow.value.any { it.name == parserName } -> + mangaExtensions.installedExtensionsFlow.value.find { it.name == parserName }?.icon + novelExtensions.installedExtensionsFlow.value.any { it.name == parserName } -> + novelExtensions.installedExtensionsFlow.value.find { it.name == parserName }?.icon + else -> null } } diff --git a/app/src/main/res/layout/item_extension.xml b/app/src/main/res/layout/item_extension.xml index b32b6ef5..6fd255b0 100644 --- a/app/src/main/res/layout/item_extension.xml +++ b/app/src/main/res/layout/item_extension.xml @@ -25,7 +25,7 @@ android:layout_width="40dp" android:layout_height="40dp" android:layout_gravity="center_vertical" - android:layout_marginEnd="3dp" + android:layout_marginEnd="9dp" tools:ignore="ContentDescription" /> + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index befeed04..d64f5f37 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -417,6 +417,8 @@ Use Alarm Manager for reliable Notifications Using Alarm Manger can help fight against battery optimization, but may consume more battery. It also requires the Alarm Manager permission. Use + Remove All Subscriptions + Are you sure you want to remove all subscriptions for %1$s? Notification for Checking Subscriptions Subscriptions Update Frequency : %1$s Subscriptions Update Frequency