diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/NotificationProfileDetailsFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/NotificationProfileDetailsFragment.kt index af59c2605f..785e8d9549 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/NotificationProfileDetailsFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/NotificationProfileDetailsFragment.kt @@ -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, isOn: Boolean): DSLConfiguration { + private fun getConfiguration(state: NotificationProfileDetailsViewModel.State.Valid): DSLConfiguration { + val (profile: NotificationProfile, recipients: List, 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( diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/NotificationProfileDetailsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/NotificationProfileDetailsViewModel.kt index 2a266066b9..38a7ced8c3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/NotificationProfileDetailsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/notifications/profiles/NotificationProfileDetailsViewModel.kt @@ -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 { - return repository.getProfiles() + private val store = Store(State.NotLoaded) + private val disposables = CompositeDisposable() + + val state: LiveData = 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 { @@ -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, - 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 { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 14e56c8130..28d3776595 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -4144,6 +4144,8 @@ Notify for all mentions Schedule + + See all Add a schedule