kopia lustrzana https://github.com/ryukoposting/Signal-Android
Add error toasts to multiforward sheet.
rodzic
40c52a31c9
commit
b57b160660
|
@ -0,0 +1,7 @@
|
||||||
|
package org.thoughtcrime.securesms.contacts.paged
|
||||||
|
|
||||||
|
enum class ContactSearchError {
|
||||||
|
CONTACT_NOT_SELECTABLE,
|
||||||
|
RECOMMENDED_LIMIT_REACHED,
|
||||||
|
HARD_LIMIT_REACHED
|
||||||
|
}
|
|
@ -7,6 +7,8 @@ import androidx.lifecycle.LiveData
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
|
||||||
|
import io.reactivex.rxjava3.core.Observable
|
||||||
import org.thoughtcrime.securesms.R
|
import org.thoughtcrime.securesms.R
|
||||||
import org.thoughtcrime.securesms.groups.SelectionLimits
|
import org.thoughtcrime.securesms.groups.SelectionLimits
|
||||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||||
|
@ -82,6 +84,10 @@ class ContactSearchMediator(
|
||||||
return viewModel.selectionState
|
return viewModel.selectionState
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getErrorEvents(): Observable<ContactSearchError> {
|
||||||
|
return viewModel.errorEventsStream.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
}
|
||||||
|
|
||||||
fun addToVisibleGroupStories(groupStories: Set<ContactSearchKey.RecipientSearchKey.Story>) {
|
fun addToVisibleGroupStories(groupStories: Set<ContactSearchKey.RecipientSearchKey.Story>) {
|
||||||
viewModel.addToVisibleGroupStories(groupStories)
|
viewModel.addToVisibleGroupStories(groupStories)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,10 @@ import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.Transformations
|
import androidx.lifecycle.Transformations
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import io.reactivex.rxjava3.core.Observable
|
||||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||||
import io.reactivex.rxjava3.kotlin.plusAssign
|
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||||
|
import io.reactivex.rxjava3.subjects.PublishSubject
|
||||||
import org.signal.paging.LivePagedData
|
import org.signal.paging.LivePagedData
|
||||||
import org.signal.paging.PagedData
|
import org.signal.paging.PagedData
|
||||||
import org.signal.paging.PagingConfig
|
import org.signal.paging.PagingConfig
|
||||||
|
@ -38,11 +40,13 @@ class ContactSearchViewModel(
|
||||||
private val pagedData = MutableLiveData<LivePagedData<ContactSearchKey, ContactSearchData>>()
|
private val pagedData = MutableLiveData<LivePagedData<ContactSearchKey, ContactSearchData>>()
|
||||||
private val configurationStore = Store(ContactSearchState())
|
private val configurationStore = Store(ContactSearchState())
|
||||||
private val selectionStore = Store<Set<ContactSearchKey>>(emptySet())
|
private val selectionStore = Store<Set<ContactSearchKey>>(emptySet())
|
||||||
|
private val errorEvents = PublishSubject.create<ContactSearchError>()
|
||||||
|
|
||||||
val controller: LiveData<PagingController<ContactSearchKey>> = Transformations.map(pagedData) { it.controller }
|
val controller: LiveData<PagingController<ContactSearchKey>> = Transformations.map(pagedData) { it.controller }
|
||||||
val data: LiveData<List<ContactSearchData>> = Transformations.switchMap(pagedData) { it.data }
|
val data: LiveData<List<ContactSearchData>> = Transformations.switchMap(pagedData) { it.data }
|
||||||
val configurationState: LiveData<ContactSearchState> = configurationStore.stateLiveData
|
val configurationState: LiveData<ContactSearchState> = configurationStore.stateLiveData
|
||||||
val selectionState: LiveData<Set<ContactSearchKey>> = selectionStore.stateLiveData
|
val selectionState: LiveData<Set<ContactSearchKey>> = selectionStore.stateLiveData
|
||||||
|
val errorEventsStream: Observable<ContactSearchError> = errorEvents
|
||||||
|
|
||||||
override fun onCleared() {
|
override fun onCleared() {
|
||||||
disposables.clear()
|
disposables.clear()
|
||||||
|
@ -64,7 +68,7 @@ class ContactSearchViewModel(
|
||||||
fun setKeysSelected(contactSearchKeys: Set<ContactSearchKey>) {
|
fun setKeysSelected(contactSearchKeys: Set<ContactSearchKey>) {
|
||||||
disposables += contactSearchRepository.filterOutUnselectableContactSearchKeys(contactSearchKeys).subscribe { results ->
|
disposables += contactSearchRepository.filterOutUnselectableContactSearchKeys(contactSearchKeys).subscribe { results ->
|
||||||
if (results.any { !it.isSelectable }) {
|
if (results.any { !it.isSelectable }) {
|
||||||
// TODO [alex] -- Pop an error.
|
errorEvents.onNext(ContactSearchError.CONTACT_NOT_SELECTABLE)
|
||||||
return@subscribe
|
return@subscribe
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,9 +76,9 @@ class ContactSearchViewModel(
|
||||||
val newSelectionSize = newSelectionEntries.size + getSelectedContacts().size
|
val newSelectionSize = newSelectionEntries.size + getSelectedContacts().size
|
||||||
|
|
||||||
if (selectionLimits.hasRecommendedLimit() && getSelectedContacts().size < selectionLimits.recommendedLimit && newSelectionSize >= selectionLimits.recommendedLimit) {
|
if (selectionLimits.hasRecommendedLimit() && getSelectedContacts().size < selectionLimits.recommendedLimit && newSelectionSize >= selectionLimits.recommendedLimit) {
|
||||||
// Pop a warning
|
errorEvents.onNext(ContactSearchError.RECOMMENDED_LIMIT_REACHED)
|
||||||
} else if (selectionLimits.hasHardLimit() && newSelectionSize > selectionLimits.hardLimit) {
|
} else if (selectionLimits.hasHardLimit() && newSelectionSize > selectionLimits.hardLimit) {
|
||||||
// Pop an error
|
errorEvents.onNext(ContactSearchError.HARD_LIMIT_REACHED)
|
||||||
return@subscribe
|
return@subscribe
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ import org.thoughtcrime.securesms.components.ContactFilterView
|
||||||
import org.thoughtcrime.securesms.components.TooltipPopup
|
import org.thoughtcrime.securesms.components.TooltipPopup
|
||||||
import org.thoughtcrime.securesms.components.WrapperDialogFragment
|
import org.thoughtcrime.securesms.components.WrapperDialogFragment
|
||||||
import org.thoughtcrime.securesms.contacts.paged.ContactSearchConfiguration
|
import org.thoughtcrime.securesms.contacts.paged.ContactSearchConfiguration
|
||||||
|
import org.thoughtcrime.securesms.contacts.paged.ContactSearchError
|
||||||
import org.thoughtcrime.securesms.contacts.paged.ContactSearchKey
|
import org.thoughtcrime.securesms.contacts.paged.ContactSearchKey
|
||||||
import org.thoughtcrime.securesms.contacts.paged.ContactSearchMediator
|
import org.thoughtcrime.securesms.contacts.paged.ContactSearchMediator
|
||||||
import org.thoughtcrime.securesms.contacts.paged.ContactSearchState
|
import org.thoughtcrime.securesms.contacts.paged.ContactSearchState
|
||||||
|
@ -197,6 +198,19 @@ class MultiselectForwardFragment :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
disposables += contactSearchMediator
|
||||||
|
.getErrorEvents()
|
||||||
|
.subscribe {
|
||||||
|
@Suppress("WHEN_ENUM_CAN_BE_NULL_IN_JAVA")
|
||||||
|
val message: Int = when (it) {
|
||||||
|
ContactSearchError.CONTACT_NOT_SELECTABLE -> R.string.MultiselectForwardFragment__only_admins_can_send_messages_to_this_group
|
||||||
|
ContactSearchError.RECOMMENDED_LIMIT_REACHED -> R.string.ContactSelectionListFragment_recommended_member_limit_reached
|
||||||
|
ContactSearchError.HARD_LIMIT_REACHED -> R.string.MultiselectForwardFragment__limit_reached
|
||||||
|
}
|
||||||
|
|
||||||
|
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
|
||||||
viewModel.state.observe(viewLifecycleOwner) {
|
viewModel.state.observe(viewLifecycleOwner) {
|
||||||
when (it.stage) {
|
when (it.stage) {
|
||||||
MultiselectForwardState.Stage.Selection -> {}
|
MultiselectForwardState.Stage.Selection -> {}
|
||||||
|
|
|
@ -4190,6 +4190,8 @@
|
||||||
<item quantity="one">Couldn\'t forward message because it\'s no longer available.</item>
|
<item quantity="one">Couldn\'t forward message because it\'s no longer available.</item>
|
||||||
<item quantity="other">Couldn\'t forward messages because they\'re no longer available.</item>
|
<item quantity="other">Couldn\'t forward messages because they\'re no longer available.</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
<!-- Error message shown when attempting to select a group to forward/share but it's announcement only and you are not an admin -->
|
||||||
|
<string name="MultiselectForwardFragment__only_admins_can_send_messages_to_this_group">Only admins can send messages to this group.</string>
|
||||||
<string name="MultiselectForwardFragment__limit_reached">Limit reached</string>
|
<string name="MultiselectForwardFragment__limit_reached">Limit reached</string>
|
||||||
|
|
||||||
<!-- Media V2 -->
|
<!-- Media V2 -->
|
||||||
|
|
Ładowanie…
Reference in New Issue