Convert channel group dialogs to bottom sheets

This commit is contained in:
Bnyro 2023-05-08 17:59:55 +02:00
parent dcb10883f4
commit 8cf4f76d4e
9 changed files with 147 additions and 82 deletions

View File

@ -7,7 +7,7 @@ import androidx.recyclerview.widget.RecyclerView
import com.github.libretube.databinding.SubscriptionGroupRowBinding import com.github.libretube.databinding.SubscriptionGroupRowBinding
import com.github.libretube.db.DatabaseHolder import com.github.libretube.db.DatabaseHolder
import com.github.libretube.db.obj.SubscriptionGroup import com.github.libretube.db.obj.SubscriptionGroup
import com.github.libretube.ui.dialogs.EditChannelGroupDialog import com.github.libretube.ui.sheets.EditChannelGroupSheet
import com.github.libretube.ui.viewholders.SubscriptionGroupsViewHolder import com.github.libretube.ui.viewholders.SubscriptionGroupsViewHolder
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
@ -44,7 +44,7 @@ class SubscriptionGroupsAdapter(
notifyItemRangeChanged(position, itemCount) notifyItemRangeChanged(position, itemCount)
} }
editGroup.setOnClickListener { editGroup.setOnClickListener {
EditChannelGroupDialog(subscriptionGroup) { EditChannelGroupSheet(subscriptionGroup) {
groups[position] = it groups[position] = it
runBlocking(Dispatchers.IO) { runBlocking(Dispatchers.IO) {
// delete the old one as it might have a different name // delete the old one as it might have a different name

View File

@ -1,47 +0,0 @@
package com.github.libretube.ui.dialogs
import android.app.Dialog
import android.os.Bundle
import androidx.fragment.app.DialogFragment
import androidx.recyclerview.widget.LinearLayoutManager
import com.github.libretube.R
import com.github.libretube.databinding.DialogSubscriptionGroupsBinding
import com.github.libretube.db.DatabaseHolder
import com.github.libretube.db.obj.SubscriptionGroup
import com.github.libretube.ui.adapters.SubscriptionGroupsAdapter
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
class ChannelGroupsDialog(
private val groups: MutableList<SubscriptionGroup>,
private val onGroupsChanged: (List<SubscriptionGroup>) -> Unit
) : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val binding = DialogSubscriptionGroupsBinding.inflate(layoutInflater)
binding.groupsRV.layoutManager = LinearLayoutManager(context)
val adapter = SubscriptionGroupsAdapter(
groups.toMutableList(),
parentFragmentManager,
onGroupsChanged
)
binding.groupsRV.adapter = adapter
return MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.channel_groups)
.setView(binding.root)
.setPositiveButton(R.string.okay, null)
.setNeutralButton(R.string.new_group) { _, _ ->
EditChannelGroupDialog(SubscriptionGroup("", mutableListOf())) {
runBlocking(Dispatchers.IO) {
DatabaseHolder.Database.subscriptionGroupsDao().createGroup(it)
}
groups.add(it)
adapter.insertItem(it)
onGroupsChanged(groups)
}.show(parentFragmentManager, null)
}
.create()
}
}

View File

@ -25,9 +25,9 @@ import com.github.libretube.helpers.PreferenceHelper
import com.github.libretube.ui.adapters.LegacySubscriptionAdapter import com.github.libretube.ui.adapters.LegacySubscriptionAdapter
import com.github.libretube.ui.adapters.SubscriptionChannelAdapter import com.github.libretube.ui.adapters.SubscriptionChannelAdapter
import com.github.libretube.ui.adapters.VideosAdapter import com.github.libretube.ui.adapters.VideosAdapter
import com.github.libretube.ui.dialogs.ChannelGroupsDialog
import com.github.libretube.ui.models.SubscriptionsViewModel import com.github.libretube.ui.models.SubscriptionsViewModel
import com.github.libretube.ui.sheets.BaseBottomSheet import com.github.libretube.ui.sheets.BaseBottomSheet
import com.github.libretube.ui.sheets.ChannelGroupsSheet
import com.google.android.material.chip.Chip import com.google.android.material.chip.Chip
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -197,7 +197,7 @@ class SubscriptionsFragment : Fragment() {
} }
binding.editGroups.setOnClickListener { binding.editGroups.setOnClickListener {
ChannelGroupsDialog(channelGroups.toMutableList()) { ChannelGroupsSheet(channelGroups.toMutableList()) {
lifecycleScope.launch { initChannelGroups() } lifecycleScope.launch { initChannelGroups() }
}.show(childFragmentManager, null) }.show(childFragmentManager, null)
} }

View File

@ -0,0 +1,51 @@
package com.github.libretube.ui.sheets
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import com.github.libretube.databinding.DialogSubscriptionGroupsBinding
import com.github.libretube.db.DatabaseHolder
import com.github.libretube.db.obj.SubscriptionGroup
import com.github.libretube.ui.adapters.SubscriptionGroupsAdapter
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
class ChannelGroupsSheet(
private val groups: MutableList<SubscriptionGroup>,
private val onGroupsChanged: (List<SubscriptionGroup>) -> Unit
) : ExpandedBottomSheet() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val binding = DialogSubscriptionGroupsBinding.inflate(layoutInflater)
binding.groupsRV.layoutManager = LinearLayoutManager(context)
val adapter = SubscriptionGroupsAdapter(
groups.toMutableList(),
parentFragmentManager,
onGroupsChanged
)
binding.groupsRV.adapter = adapter
binding.newGroup.setOnClickListener {
EditChannelGroupSheet(SubscriptionGroup("", mutableListOf())) {
runBlocking(Dispatchers.IO) {
DatabaseHolder.Database.subscriptionGroupsDao().createGroup(it)
}
groups.add(it)
adapter.insertItem(it)
onGroupsChanged(groups)
}.show(parentFragmentManager, null)
}
binding.confirm.setOnClickListener {
dismiss()
}
return binding.root
}
}

View File

@ -1,34 +1,37 @@
package com.github.libretube.ui.dialogs package com.github.libretube.ui.sheets
import android.app.Dialog
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.widget.addTextChangedListener import androidx.core.widget.addTextChangedListener
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.github.libretube.R
import com.github.libretube.api.SubscriptionHelper import com.github.libretube.api.SubscriptionHelper
import com.github.libretube.api.obj.Subscription import com.github.libretube.api.obj.Subscription
import com.github.libretube.databinding.DialogEditChannelGroupBinding import com.github.libretube.databinding.DialogEditChannelGroupBinding
import com.github.libretube.db.obj.SubscriptionGroup import com.github.libretube.db.obj.SubscriptionGroup
import com.github.libretube.ui.adapters.SubscriptionGroupChannelsAdapter import com.github.libretube.ui.adapters.SubscriptionGroupChannelsAdapter
import com.github.libretube.ui.models.SubscriptionsViewModel import com.github.libretube.ui.models.SubscriptionsViewModel
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
class EditChannelGroupDialog( class EditChannelGroupSheet(
private var group: SubscriptionGroup, private var group: SubscriptionGroup,
private val onGroupChanged: (SubscriptionGroup) -> Unit private val onGroupChanged: (SubscriptionGroup) -> Unit
) : DialogFragment() { ) : ExpandedBottomSheet() {
private val subscriptionsModel: SubscriptionsViewModel by activityViewModels() private val subscriptionsModel: SubscriptionsViewModel by activityViewModels()
private lateinit var binding: DialogEditChannelGroupBinding private lateinit var binding: DialogEditChannelGroupBinding
private var channels: List<Subscription> = listOf() private var channels: List<Subscription> = listOf()
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DialogEditChannelGroupBinding.inflate(layoutInflater) binding = DialogEditChannelGroupBinding.inflate(layoutInflater)
binding.groupName.setText(group.name) binding.groupName.setText(group.name)
@ -39,16 +42,18 @@ class EditChannelGroupDialog(
showChannels(channels, it?.toString()) showChannels(channels, it?.toString())
} }
return MaterialAlertDialogBuilder(requireContext()) binding.cancel.setOnClickListener {
.setTitle(R.string.edit_group) dismiss()
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(R.string.okay) { _, _ ->
group.name = binding.groupName.text.toString()
if (group.name.isBlank()) return@setPositiveButton
onGroupChanged(group)
} }
.setView(binding.root)
.create() binding.confirm.setOnClickListener {
group.name = binding.groupName.text.toString()
if (group.name.isBlank()) return@setOnClickListener
onGroupChanged(group)
dismiss()
}
return binding.root
} }
private fun fetchSubscriptions() { private fun fetchSubscriptions() {

View File

@ -47,6 +47,29 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="10dp"/> android:layout_marginTop="10dp"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_gravity="end"
android:paddingVertical="10dp"
android:layout_height="wrap_content">
<com.google.android.material.button.MaterialButton
android:id="@+id/cancel"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="wrap_content"
android:text="@string/cancel"
android:layout_height="wrap_content"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/confirm"
style="@style/Widget.Material3.Button.ElevatedButton"
android:layout_width="wrap_content"
android:text="@string/okay"
android:layout_marginHorizontal="16dp"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
<ProgressBar <ProgressBar
@ -54,6 +77,6 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_marginVertical="200dp" /> android:layout_marginVertical="20dp"/>
</LinearLayout> </LinearLayout>

View File

@ -1,7 +1,17 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:text="@string/channel_groups"
android:textStyle="bold"
android:textSize="24sp"
android:layout_marginTop="18dp"
android:layout_marginStart="18dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/groupsRV" android:id="@+id/groupsRV"
@ -9,4 +19,27 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="20dp"/> android:layout_marginTop="20dp"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_gravity="end"
android:paddingVertical="10dp"
android:layout_height="wrap_content">
<com.google.android.material.button.MaterialButton
android:id="@+id/new_group"
android:layout_width="wrap_content"
android:text="@string/new_group"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_height="wrap_content"/>
<com.google.android.material.button.MaterialButton
android:id="@+id/confirm"
style="@style/Widget.Material3.Button.ElevatedButton"
android:layout_width="wrap_content"
android:text="@string/okay"
android:layout_marginHorizontal="16dp"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout> </LinearLayout>

View File

@ -5,7 +5,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground" android:background="?android:attr/selectableItemBackground"
android:paddingHorizontal="20dp" > android:paddingHorizontal="10dp" >
<com.google.android.material.imageview.ShapeableImageView <com.google.android.material.imageview.ShapeableImageView
android:id="@+id/subscription_channel_image" android:id="@+id/subscription_channel_image"

View File

@ -3,7 +3,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:orientation="horizontal"
android:paddingHorizontal="25dp" android:paddingHorizontal="5dp"
android:paddingVertical="10dp"> android:paddingVertical="10dp">
<TextView <TextView