kopia lustrzana https://github.com/ryukoposting/Signal-Android
192 wiersze
7.6 KiB
Java
192 wiersze
7.6 KiB
Java
package org.thoughtcrime.securesms.mediasend;
|
|
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.os.Bundle;
|
|
import android.text.TextUtils;
|
|
import android.view.LayoutInflater;
|
|
import android.view.Menu;
|
|
import android.view.MenuItem;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.widget.Toast;
|
|
|
|
import androidx.annotation.NonNull;
|
|
import androidx.annotation.Nullable;
|
|
import androidx.appcompat.app.AppCompatActivity;
|
|
import androidx.appcompat.widget.SearchView;
|
|
import androidx.appcompat.widget.Toolbar;
|
|
import androidx.constraintlayout.widget.Group;
|
|
import androidx.fragment.app.Fragment;
|
|
import androidx.lifecycle.ViewModelProvider;
|
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
import androidx.recyclerview.widget.RecyclerView;
|
|
|
|
import org.thoughtcrime.securesms.InviteActivity;
|
|
import org.thoughtcrime.securesms.LoggingFragment;
|
|
import org.thoughtcrime.securesms.R;
|
|
import org.thoughtcrime.securesms.mms.GlideApp;
|
|
import org.thoughtcrime.securesms.recipients.Recipient;
|
|
import org.thoughtcrime.securesms.util.DynamicTheme;
|
|
import org.thoughtcrime.securesms.util.ThemeUtil;
|
|
|
|
import java.util.List;
|
|
|
|
/**
|
|
* Fragment that selects Signal contacts. Intended to be used in the camera-first capture flow.
|
|
*/
|
|
public class CameraContactSelectionFragment extends LoggingFragment implements CameraContactAdapter.CameraContactListener {
|
|
|
|
private Controller controller;
|
|
private CameraContactSelectionViewModel contactViewModel;
|
|
private RecyclerView contactList;
|
|
private CameraContactAdapter contactAdapter;
|
|
private RecyclerView selectionList;
|
|
private CameraContactSelectionAdapter selectionAdapter;
|
|
private Toolbar toolbar;
|
|
private View sendButton;
|
|
private Group selectionFooterGroup;
|
|
private ViewGroup cameraContactsEmpty;
|
|
private View inviteButton;
|
|
|
|
public static Fragment newInstance() {
|
|
return new CameraContactSelectionFragment();
|
|
}
|
|
|
|
|
|
@Override
|
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
setHasOptionsMenu(true);
|
|
|
|
CameraContactSelectionViewModel.Factory factory = new CameraContactSelectionViewModel.Factory(new CameraContactsRepository(requireContext()));
|
|
|
|
this.contactViewModel = new ViewModelProvider(requireActivity(), factory).get(CameraContactSelectionViewModel.class);
|
|
}
|
|
|
|
@Override
|
|
public void onAttach(@NonNull Context context) {
|
|
super.onAttach(context);
|
|
if (!(getActivity() instanceof Controller)) {
|
|
throw new IllegalStateException("Parent activity must implement controller interface.");
|
|
}
|
|
controller = (Controller) getActivity();
|
|
}
|
|
|
|
@Override
|
|
public @Nullable View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
|
int theme = DynamicTheme.isDarkTheme(inflater.getContext()) ? R.style.TextSecure_DarkTheme
|
|
: R.style.TextSecure_LightTheme;
|
|
return ThemeUtil.getThemedInflater(inflater.getContext(), inflater, theme)
|
|
.inflate(R.layout.camera_contact_selection_fragment, container, false);
|
|
}
|
|
|
|
@Override
|
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
|
this.contactList = view.findViewById(R.id.camera_contacts_list);
|
|
this.selectionList = view.findViewById(R.id.camera_contacts_selected_list);
|
|
this.toolbar = view.findViewById(R.id.camera_contacts_toolbar);
|
|
this.sendButton = view.findViewById(R.id.camera_contacts_send_button);
|
|
this.selectionFooterGroup = view.findViewById(R.id.camera_contacts_footer_group);
|
|
this.cameraContactsEmpty = view.findViewById(R.id.camera_contacts_empty);
|
|
this.inviteButton = view.findViewById(R.id.camera_contacts_invite_button);
|
|
this.contactAdapter = new CameraContactAdapter(GlideApp.with(this), this);
|
|
this.selectionAdapter = new CameraContactSelectionAdapter();
|
|
|
|
contactList.setLayoutManager(new LinearLayoutManager(requireContext()));
|
|
contactList.setAdapter(contactAdapter);
|
|
|
|
selectionList.setLayoutManager(new LinearLayoutManager(requireContext(), LinearLayoutManager.HORIZONTAL, false));
|
|
selectionList.setAdapter(selectionAdapter);
|
|
|
|
((AppCompatActivity) requireActivity()).setSupportActionBar(toolbar);
|
|
((AppCompatActivity) requireActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
|
toolbar.setNavigationOnClickListener(v -> requireActivity().onBackPressed());
|
|
|
|
inviteButton.setOnClickListener(v -> onInviteContactsClicked());
|
|
|
|
initViewModel();
|
|
}
|
|
|
|
@Override
|
|
public void onPrepareOptionsMenu(@NonNull Menu menu) {
|
|
requireActivity().getMenuInflater().inflate(R.menu.camera_contacts, menu);
|
|
|
|
MenuItem searchViewItem = menu.findItem(R.id.menu_search);
|
|
SearchView searchView = (SearchView) searchViewItem.getActionView();
|
|
SearchView.OnQueryTextListener queryListener = new SearchView.OnQueryTextListener() {
|
|
@Override
|
|
public boolean onQueryTextSubmit(String query) {
|
|
contactViewModel.onQueryUpdated(query);
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean onQueryTextChange(String query) {
|
|
contactViewModel.onQueryUpdated(query);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
searchViewItem.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
|
|
@Override
|
|
public boolean onMenuItemActionExpand(MenuItem item) {
|
|
searchView.setOnQueryTextListener(queryListener);
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean onMenuItemActionCollapse(MenuItem item) {
|
|
searchView.setOnQueryTextListener(null);
|
|
contactViewModel.onSearchClosed();
|
|
return true;
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public void onContactClicked(@NonNull Recipient recipient) {
|
|
contactViewModel.onContactClicked(recipient);
|
|
}
|
|
|
|
@Override
|
|
public void onInviteContactsClicked() {
|
|
startActivity(new Intent(requireContext(), InviteActivity.class));
|
|
}
|
|
|
|
private void initViewModel() {
|
|
contactViewModel.getContacts().observe(getViewLifecycleOwner(), contactState -> {
|
|
if (contactState == null) return;
|
|
|
|
if (contactState.getContacts().isEmpty() && TextUtils.isEmpty(contactState.getQuery())) {
|
|
cameraContactsEmpty.setVisibility(View.VISIBLE);
|
|
contactList.setVisibility(View.GONE);
|
|
selectionFooterGroup.setVisibility(View.GONE);
|
|
} else {
|
|
cameraContactsEmpty.setVisibility(View.GONE);
|
|
contactList.setVisibility(View.VISIBLE);
|
|
|
|
sendButton.setOnClickListener(v -> controller.onCameraContactsSendClicked(contactState.getSelected()));
|
|
|
|
contactAdapter.setContacts(contactState.getContacts(), contactState.getSelected());
|
|
selectionAdapter.setRecipients(contactState.getSelected());
|
|
|
|
selectionFooterGroup.setVisibility(contactState.getSelected().isEmpty() ? View.GONE : View.VISIBLE);
|
|
}
|
|
});
|
|
|
|
contactViewModel.getError().observe(getViewLifecycleOwner(), error -> {
|
|
if (error == null) return;
|
|
|
|
if (error == CameraContactSelectionViewModel.Error.MAX_SELECTION) {
|
|
String message = getString(R.string.CameraContacts_you_can_share_with_a_maximum_of_n_conversations, CameraContactSelectionViewModel.MAX_SELECTION_COUNT);
|
|
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show();
|
|
}
|
|
});
|
|
}
|
|
|
|
public interface Controller {
|
|
void onCameraContactsSendClicked(@NonNull List<Recipient> recipients);
|
|
}
|
|
}
|