Only initially show up to 5 members on profile details.

fork-5.53.8
Cody Henthorne 2021-12-09 14:04:30 -05:00
rodzic 3b9cfc8e5a
commit 3d77ce0d57
3 zmienionych plików z 90 dodań i 24 usunięć

Wyświetl plik

@ -23,6 +23,7 @@ import org.thoughtcrime.securesms.components.settings.app.notifications.profiles
import org.thoughtcrime.securesms.components.settings.app.notifications.profiles.models.NotificationProfilePreference
import org.thoughtcrime.securesms.components.settings.app.notifications.profiles.models.NotificationProfileRecipient
import org.thoughtcrime.securesms.components.settings.configure
import org.thoughtcrime.securesms.components.settings.conversation.preferences.LargeIconClickPreference
import org.thoughtcrime.securesms.components.settings.conversation.preferences.RecipientPreference
import org.thoughtcrime.securesms.notifications.profiles.NotificationProfile
import org.thoughtcrime.securesms.notifications.profiles.NotificationProfileSchedule
@ -37,6 +38,8 @@ import java.time.DayOfWeek
import java.time.format.TextStyle
import java.util.Locale
private const val MEMBER_COUNT_TO_SHOW_EXPAND: Int = 5
class NotificationProfileDetailsFragment : DSLSettingsFragment() {
private val viewModel: NotificationProfileDetailsViewModel by viewModels(factoryProducer = this::createFactory)
@ -66,30 +69,31 @@ class NotificationProfileDetailsFragment : DSLSettingsFragment() {
NotificationProfilePreference.register(adapter)
NotificationProfileAddMembers.register(adapter)
NotificationProfileRecipient.register(adapter)
LargeIconClickPreference.register(adapter)
lifecycleDisposable += viewModel.getProfile()
.subscribeBy(
onNext = { state ->
when (state) {
is NotificationProfileDetailsViewModel.State.Valid -> {
toolbar?.title = state.profile.name
toolbar?.setOnMenuItemClickListener { item ->
if (item.itemId == R.id.action_edit) {
findNavController().navigate(NotificationProfileDetailsFragmentDirections.actionNotificationProfileDetailsFragmentToEditNotificationProfileFragment().setProfileId(state.profile.id))
true
} else {
false
}
}
adapter.submitList(getConfiguration(state.profile, state.recipients, state.isOn).toMappingModelList())
viewModel.state.observe(viewLifecycleOwner) { state ->
when (state) {
is NotificationProfileDetailsViewModel.State.Valid -> {
toolbar?.title = state.profile.name
toolbar?.setOnMenuItemClickListener { item ->
if (item.itemId == R.id.action_edit) {
findNavController().navigate(NotificationProfileDetailsFragmentDirections.actionNotificationProfileDetailsFragmentToEditNotificationProfileFragment().setProfileId(state.profile.id))
true
} else {
false
}
NotificationProfileDetailsViewModel.State.Invalid -> findNavController().navigateUp()
}
adapter.submitList(getConfiguration(state).toMappingModelList())
}
)
NotificationProfileDetailsViewModel.State.NotLoaded -> Unit
NotificationProfileDetailsViewModel.State.Invalid -> findNavController().navigateUp()
}
}
}
private fun getConfiguration(profile: NotificationProfile, recipients: List<Recipient>, isOn: Boolean): DSLConfiguration {
private fun getConfiguration(state: NotificationProfileDetailsViewModel.State.Valid): DSLConfiguration {
val (profile: NotificationProfile, recipients: List<Recipient>, isOn: Boolean, expanded: Boolean) = state
return configure {
customPref(
@ -122,7 +126,14 @@ class NotificationProfileDetailsFragment : DSLSettingsFragment() {
currentSelection = profile.allowedMembers
)
)
for (member in recipients) {
val membersToShow = if (expanded || recipients.size <= MEMBER_COUNT_TO_SHOW_EXPAND) {
recipients
} else {
recipients.slice(0 until MEMBER_COUNT_TO_SHOW_EXPAND)
}
for (member in membersToShow) {
customPref(
NotificationProfileRecipient.Model(
recipientModel = RecipientPreference.Model(
@ -146,6 +157,16 @@ class NotificationProfileDetailsFragment : DSLSettingsFragment() {
)
}
if (!expanded && membersToShow != recipients) {
customPref(
LargeIconClickPreference.Model(
title = DSLSettingsText.from(R.string.NotificationProfileDetails__see_all),
icon = DSLSettingsIcon.from(R.drawable.show_more, NO_TINT),
onClick = viewModel::showAllMembers
)
)
}
dividerPref()
sectionHeaderPref(R.string.NotificationProfileDetails__schedule)
clickPref(

Wyświetl plik

@ -1,21 +1,30 @@
package org.thoughtcrime.securesms.components.settings.app.notifications.profiles
import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.kotlin.plusAssign
import io.reactivex.rxjava3.kotlin.subscribeBy
import org.thoughtcrime.securesms.database.NotificationProfileDatabase
import org.thoughtcrime.securesms.notifications.profiles.NotificationProfile
import org.thoughtcrime.securesms.notifications.profiles.NotificationProfiles
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.util.livedata.Store
class NotificationProfileDetailsViewModel(private val profileId: Long, private val repository: NotificationProfilesRepository) : ViewModel() {
fun getProfile(): Observable<State> {
return repository.getProfiles()
private val store = Store<State>(State.NotLoaded)
private val disposables = CompositeDisposable()
val state: LiveData<State> = store.stateLiveData
init {
disposables += repository.getProfiles()
.map { profiles ->
val profile = profiles.firstOrNull { it.id == profileId }
if (profile == null) {
@ -28,7 +37,29 @@ class NotificationProfileDetailsViewModel(private val profileId: Long, private v
)
}
}
.observeOn(AndroidSchedulers.mainThread())
.subscribeBy(
onNext = { newState ->
when (newState) {
State.NotLoaded -> Unit
State.Invalid -> store.update { newState }
is State.Valid -> updateWithValidState(newState)
}
}
)
}
private fun updateWithValidState(newState: State.Valid) {
store.update { oldState: State ->
if (oldState is State.Valid) {
oldState.copy(profile = newState.profile, recipients = newState.recipients, isOn = newState.isOn)
} else {
newState
}
}
}
override fun onCleared() {
disposables.clear()
}
fun addMember(id: RecipientId): Single<NotificationProfile> {
@ -70,13 +101,25 @@ class NotificationProfileDetailsViewModel(private val profileId: Long, private v
.observeOn(AndroidSchedulers.mainThread())
}
fun showAllMembers() {
store.update { s ->
if (s is State.Valid) {
s.copy(expanded = true)
} else {
s
}
}
}
sealed class State {
data class Valid(
val profile: NotificationProfile,
val recipients: List<Recipient>,
val isOn: Boolean
val isOn: Boolean,
val expanded: Boolean = false
) : State()
object Invalid : State()
object NotLoaded : State()
}
class Factory(private val profileId: Long) : ViewModelProvider.Factory {

Wyświetl plik

@ -4144,6 +4144,8 @@
<string name="NotificationProfileDetails__notify_for_all_mentions">Notify for all mentions</string>
<!-- Section header for showing schedule information -->
<string name="NotificationProfileDetails__schedule">Schedule</string>
<!-- If member list is long, will truncate the list and show an option to then see all when tapped -->
<string name="NotificationProfileDetails__see_all">See all</string>
<!-- Title for add schedule to profile in create flow -->
<string name="EditNotificationProfileSchedule__add_a_schedule">Add a schedule</string>