package org.tm.archive.mediasend; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModelProvider; import org.signal.core.util.ThreadUtil; import org.tm.archive.recipients.Recipient; import org.tm.archive.util.SingleLiveEvent; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; class CameraContactSelectionViewModel extends ViewModel { static final int MAX_SELECTION_COUNT = 16; private final CameraContactsRepository repository; private final MutableLiveData contacts; private final SingleLiveEvent error; private final Set selected; private String currentQuery; private CameraContactSelectionViewModel(@NonNull CameraContactsRepository repository) { this.repository = repository; this.contacts = new MutableLiveData<>(); this.error = new SingleLiveEvent<>(); this.selected = new LinkedHashSet<>(); repository.getCameraContacts(cameraContacts -> { ThreadUtil.runOnMain(() -> { contacts.postValue(new ContactState(cameraContacts, new ArrayList<>(selected), currentQuery)); }); }); } LiveData getContacts() { return contacts; } LiveData getError() { return error; } void onSearchClosed() { onQueryUpdated(""); } void onQueryUpdated(String query) { this.currentQuery = query; repository.getCameraContacts(query, cameraContacts -> { ThreadUtil.runOnMain(() -> { contacts.postValue(new ContactState(cameraContacts, new ArrayList<>(selected), query)); }); }); } void onRefresh() { repository.getCameraContacts(cameraContacts -> { ThreadUtil.runOnMain(() -> { contacts.postValue(new ContactState(cameraContacts, new ArrayList<>(selected), currentQuery)); }); }); } void onContactClicked(@NonNull Recipient recipient) { if (selected.contains(recipient)) { selected.remove(recipient); } else if (selected.size() < MAX_SELECTION_COUNT) { selected.add(recipient); } else { error.postValue(Error.MAX_SELECTION); } ContactState currentState = contacts.getValue(); if (currentState != null) { contacts.setValue(new ContactState(currentState.getContacts(), new ArrayList<>(selected), currentQuery)); } } static class ContactState { private final CameraContacts contacts; private final List selected; private final String query; ContactState(@NonNull CameraContacts contacts, @NonNull List selected, @Nullable String query) { this.contacts = contacts; this.selected = selected; this.query = query; } public CameraContacts getContacts() { return contacts; } public List getSelected() { return selected; } public @Nullable String getQuery() { return query; } } enum Error { MAX_SELECTION } static class Factory extends ViewModelProvider.NewInstanceFactory { private final CameraContactsRepository repository; Factory(CameraContactsRepository repository) { this.repository = repository; } @Override public @NonNull T create(@NonNull Class modelClass) { //noinspection ConstantConditions return modelClass.cast(new CameraContactSelectionViewModel(repository)); } } }