Skip to content

Commit b6488fe

Browse files
authored
Merge pull request TeamNewPipe#8841 from Isira-Seneviratne/Notification_mode_ListAdapter
Use ListAdapter in NotificationModeConfigAdapter.
2 parents cd0e585 + b1d9080 commit b6488fe

2 files changed

Lines changed: 77 additions & 117 deletions

File tree

Lines changed: 41 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
package org.schabi.newpipe.settings.notifications
22

33
import android.view.LayoutInflater
4-
import android.view.View
54
import android.view.ViewGroup
6-
import android.widget.CheckedTextView
7-
import androidx.recyclerview.widget.AsyncListDiffer
85
import androidx.recyclerview.widget.DiffUtil
6+
import androidx.recyclerview.widget.ListAdapter
97
import androidx.recyclerview.widget.RecyclerView
10-
import org.schabi.newpipe.R
118
import org.schabi.newpipe.database.subscription.NotificationMode
129
import org.schabi.newpipe.database.subscription.SubscriptionEntity
10+
import org.schabi.newpipe.databinding.ItemNotificationConfigBinding
1311
import org.schabi.newpipe.settings.notifications.NotificationModeConfigAdapter.SubscriptionHolder
1412

1513
/**
@@ -19,85 +17,46 @@ import org.schabi.newpipe.settings.notifications.NotificationModeConfigAdapter.S
1917
*/
2018
class NotificationModeConfigAdapter(
2119
private val listener: ModeToggleListener
22-
) : RecyclerView.Adapter<SubscriptionHolder>() {
23-
24-
private val differ = AsyncListDiffer(this, DiffCallback())
25-
26-
init {
27-
setHasStableIds(true)
28-
}
29-
30-
override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): SubscriptionHolder {
31-
val view = LayoutInflater.from(viewGroup.context)
32-
.inflate(R.layout.item_notification_config, viewGroup, false)
33-
return SubscriptionHolder(view, listener)
34-
}
35-
36-
override fun onBindViewHolder(subscriptionHolder: SubscriptionHolder, i: Int) {
37-
subscriptionHolder.bind(differ.currentList[i])
20+
) : ListAdapter<SubscriptionItem, SubscriptionHolder>(DiffCallback) {
21+
override fun onCreateViewHolder(parent: ViewGroup, i: Int): SubscriptionHolder {
22+
return SubscriptionHolder(
23+
ItemNotificationConfigBinding
24+
.inflate(LayoutInflater.from(parent.context), parent, false)
25+
)
3826
}
3927

40-
fun getItem(position: Int): SubscriptionItem = differ.currentList[position]
41-
42-
override fun getItemCount() = differ.currentList.size
43-
44-
override fun getItemId(position: Int): Long {
45-
return differ.currentList[position].id
28+
override fun onBindViewHolder(holder: SubscriptionHolder, position: Int) {
29+
holder.bind(currentList[position])
4630
}
4731

48-
fun getCurrentList(): List<SubscriptionItem> = differ.currentList
49-
5032
fun update(newData: List<SubscriptionEntity>) {
51-
differ.submitList(
52-
newData.map {
53-
SubscriptionItem(
54-
id = it.uid,
55-
title = it.name,
56-
notificationMode = it.notificationMode,
57-
serviceId = it.serviceId,
58-
url = it.url
59-
)
60-
}
61-
)
33+
val items = newData.map {
34+
SubscriptionItem(it.uid, it.name, it.notificationMode, it.serviceId, it.url)
35+
}
36+
submitList(items)
6237
}
6338

64-
data class SubscriptionItem(
65-
val id: Long,
66-
val title: String,
67-
@NotificationMode
68-
val notificationMode: Int,
69-
val serviceId: Int,
70-
val url: String
71-
)
72-
73-
class SubscriptionHolder(
74-
itemView: View,
75-
private val listener: ModeToggleListener
76-
) : RecyclerView.ViewHolder(itemView), View.OnClickListener {
77-
78-
private val checkedTextView = itemView as CheckedTextView
79-
39+
inner class SubscriptionHolder(
40+
private val itemBinding: ItemNotificationConfigBinding
41+
) : RecyclerView.ViewHolder(itemBinding.root) {
8042
init {
81-
itemView.setOnClickListener(this)
43+
itemView.setOnClickListener {
44+
val mode = if (itemBinding.root.isChecked) {
45+
NotificationMode.DISABLED
46+
} else {
47+
NotificationMode.ENABLED
48+
}
49+
listener.onModeChange(bindingAdapterPosition, mode)
50+
}
8251
}
8352

8453
fun bind(data: SubscriptionItem) {
85-
checkedTextView.text = data.title
86-
checkedTextView.isChecked = data.notificationMode != NotificationMode.DISABLED
87-
}
88-
89-
override fun onClick(v: View) {
90-
val mode = if (checkedTextView.isChecked) {
91-
NotificationMode.DISABLED
92-
} else {
93-
NotificationMode.ENABLED
94-
}
95-
listener.onModeChange(bindingAdapterPosition, mode)
54+
itemBinding.root.text = data.title
55+
itemBinding.root.isChecked = data.notificationMode != NotificationMode.DISABLED
9656
}
9757
}
9858

99-
private class DiffCallback : DiffUtil.ItemCallback<SubscriptionItem>() {
100-
59+
private object DiffCallback : DiffUtil.ItemCallback<SubscriptionItem>() {
10160
override fun areItemsTheSame(oldItem: SubscriptionItem, newItem: SubscriptionItem): Boolean {
10261
return oldItem.id == newItem.id
10362
}
@@ -107,18 +66,27 @@ class NotificationModeConfigAdapter(
10766
}
10867

10968
override fun getChangePayload(oldItem: SubscriptionItem, newItem: SubscriptionItem): Any? {
110-
if (oldItem.notificationMode != newItem.notificationMode) {
111-
return newItem.notificationMode
69+
return if (oldItem.notificationMode != newItem.notificationMode) {
70+
newItem.notificationMode
11271
} else {
113-
return super.getChangePayload(oldItem, newItem)
72+
super.getChangePayload(oldItem, newItem)
11473
}
11574
}
11675
}
11776

118-
interface ModeToggleListener {
77+
fun interface ModeToggleListener {
11978
/**
12079
* Triggered when the UI representation of a notification mode is changed.
12180
*/
12281
fun onModeChange(position: Int, @NotificationMode mode: Int)
12382
}
12483
}
84+
85+
data class SubscriptionItem(
86+
val id: Long,
87+
val title: String,
88+
@NotificationMode
89+
val notificationMode: Int,
90+
val serviceId: Int,
91+
val url: String
92+
)
Lines changed: 36 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.schabi.newpipe.settings.notifications
22

3+
import android.content.Context
34
import android.os.Bundle
45
import android.view.LayoutInflater
56
import android.view.Menu
@@ -8,59 +9,71 @@ import android.view.MenuItem
89
import android.view.View
910
import android.view.ViewGroup
1011
import androidx.fragment.app.Fragment
11-
import androidx.recyclerview.widget.RecyclerView
1212
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
1313
import io.reactivex.rxjava3.disposables.CompositeDisposable
1414
import io.reactivex.rxjava3.disposables.Disposable
1515
import io.reactivex.rxjava3.schedulers.Schedulers
1616
import org.schabi.newpipe.R
1717
import org.schabi.newpipe.database.subscription.NotificationMode
18+
import org.schabi.newpipe.databinding.FragmentChannelsNotificationsBinding
1819
import org.schabi.newpipe.local.subscription.SubscriptionManager
19-
import org.schabi.newpipe.settings.notifications.NotificationModeConfigAdapter.ModeToggleListener
2020

2121
/**
2222
* [NotificationModeConfigFragment] is a settings fragment
2323
* which allows changing the [NotificationMode] of all subscribed channels.
2424
* The [NotificationMode] can either be changed one by one or toggled for all channels.
2525
*/
26-
class NotificationModeConfigFragment : Fragment(), ModeToggleListener {
26+
class NotificationModeConfigFragment : Fragment() {
27+
private var _binding: FragmentChannelsNotificationsBinding? = null
28+
private val binding get() = _binding!!
2729

28-
private lateinit var updaters: CompositeDisposable
30+
private val disposables = CompositeDisposable()
2931
private var loader: Disposable? = null
30-
private var adapter: NotificationModeConfigAdapter? = null
32+
private lateinit var adapter: NotificationModeConfigAdapter
33+
private lateinit var subscriptionManager: SubscriptionManager
34+
35+
override fun onAttach(context: Context) {
36+
super.onAttach(context)
37+
subscriptionManager = SubscriptionManager(context)
38+
}
3139

3240
override fun onCreate(savedInstanceState: Bundle?) {
3341
super.onCreate(savedInstanceState)
34-
updaters = CompositeDisposable()
3542
setHasOptionsMenu(true)
3643
}
3744

3845
override fun onCreateView(
3946
inflater: LayoutInflater,
4047
container: ViewGroup?,
4148
savedInstanceState: Bundle?,
42-
): View = inflater.inflate(R.layout.fragment_channels_notifications, container, false)
49+
): View {
50+
_binding = FragmentChannelsNotificationsBinding.inflate(inflater, container, false)
51+
return binding.root
52+
}
4353

4454
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
4555
super.onViewCreated(view, savedInstanceState)
46-
val recyclerView: RecyclerView = view.findViewById(R.id.recycler_view)
47-
adapter = NotificationModeConfigAdapter(this)
48-
recyclerView.adapter = adapter
56+
adapter = NotificationModeConfigAdapter { position, mode ->
57+
// Notification mode has been changed via the UI.
58+
// Now change it in the database.
59+
updateNotificationMode(adapter.currentList[position], mode)
60+
}
61+
binding.recyclerView.adapter = adapter
4962
loader?.dispose()
50-
loader = SubscriptionManager(requireContext())
51-
.subscriptions()
63+
loader = subscriptionManager.subscriptions()
5264
.observeOn(AndroidSchedulers.mainThread())
53-
.subscribe { newData -> adapter?.update(newData) }
65+
.subscribe(adapter::update)
5466
}
5567

5668
override fun onDestroyView() {
5769
loader?.dispose()
5870
loader = null
71+
_binding = null
5972
super.onDestroyView()
6073
}
6174

6275
override fun onDestroy() {
63-
updaters.dispose()
76+
disposables.dispose()
6477
super.onDestroy()
6578
}
6679

@@ -79,41 +92,20 @@ class NotificationModeConfigFragment : Fragment(), ModeToggleListener {
7992
}
8093
}
8194

82-
override fun onModeChange(position: Int, @NotificationMode mode: Int) {
83-
// Notification mode has been changed via the UI.
84-
// Now change it in the database.
85-
val subscription = adapter?.getItem(position) ?: return
86-
updaters.add(
87-
SubscriptionManager(requireContext())
88-
.updateNotificationMode(
89-
subscription.serviceId,
90-
subscription.url,
91-
mode
92-
)
93-
.subscribeOn(Schedulers.io())
94-
.subscribe()
95-
)
96-
}
97-
9895
private fun toggleAll() {
99-
val subscriptions = adapter?.getCurrentList() ?: return
100-
val mode = subscriptions.firstOrNull()?.notificationMode ?: return
96+
val mode = adapter.currentList.firstOrNull()?.notificationMode ?: return
10197
val newMode = when (mode) {
10298
NotificationMode.DISABLED -> NotificationMode.ENABLED
10399
else -> NotificationMode.DISABLED
104100
}
105-
val subscriptionManager = SubscriptionManager(requireContext())
106-
updaters.add(
107-
CompositeDisposable(
108-
subscriptions.map { item ->
109-
subscriptionManager.updateNotificationMode(
110-
serviceId = item.serviceId,
111-
url = item.url,
112-
mode = newMode
113-
).subscribeOn(Schedulers.io())
114-
.subscribe()
115-
}
116-
)
101+
adapter.currentList.forEach { updateNotificationMode(it, newMode) }
102+
}
103+
104+
private fun updateNotificationMode(item: SubscriptionItem, @NotificationMode mode: Int) {
105+
disposables.add(
106+
subscriptionManager.updateNotificationMode(item.serviceId, item.url, mode)
107+
.subscribeOn(Schedulers.io())
108+
.subscribe()
117109
)
118110
}
119111
}

0 commit comments

Comments
 (0)