210 lines
7.8 KiB
Java
210 lines
7.8 KiB
Java
package org.mercury_im.messenger.android.ui.contacts.detail;
|
|
|
|
import android.app.AlertDialog;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.os.Bundle;
|
|
import android.util.Log;
|
|
import android.view.LayoutInflater;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.widget.Button;
|
|
import android.widget.EditText;
|
|
import android.widget.ImageView;
|
|
import android.widget.TextView;
|
|
|
|
import androidx.annotation.NonNull;
|
|
import androidx.annotation.Nullable;
|
|
import androidx.fragment.app.Fragment;
|
|
import androidx.lifecycle.ViewModelProvider;
|
|
import androidx.lifecycle.ViewModelStoreOwner;
|
|
import androidx.recyclerview.widget.RecyclerView;
|
|
|
|
import com.google.android.material.card.MaterialCardView;
|
|
import com.google.android.material.chip.Chip;
|
|
import com.google.android.material.chip.ChipGroup;
|
|
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton;
|
|
|
|
import org.mercury_im.messenger.android.ui.openpgp.OpenPgpV4FingerprintFormatter;
|
|
import org.mercury_im.messenger.android.ui.openpgp.ToggleableFingerprintsAdapter;
|
|
import org.mercury_im.messenger.core.Messenger;
|
|
import org.mercury_im.messenger.R;
|
|
import org.mercury_im.messenger.android.ui.chat.ChatActivity;
|
|
import org.mercury_im.messenger.android.util.ColorUtil;
|
|
import org.mercury_im.messenger.core.util.Optional;
|
|
import org.mercury_im.messenger.core.viewmodel.openpgp.FingerprintViewItem;
|
|
|
|
import java.util.Arrays;
|
|
import java.util.List;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
|
|
import butterknife.BindView;
|
|
import butterknife.ButterKnife;
|
|
import io.reactivex.Completable;
|
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
|
import io.reactivex.schedulers.Schedulers;
|
|
|
|
public class ContactDetailFragment extends Fragment {
|
|
|
|
private static final Logger LOGGER = Logger.getLogger(ContactDetailFragment.class.getName());
|
|
|
|
@BindView(R.id.contact_avatar)
|
|
ImageView contactAvatar;
|
|
|
|
@BindView(R.id.contact_status_badge)
|
|
ImageView contactStatusBadge;
|
|
|
|
@BindView(R.id.contact_name)
|
|
TextView contactName;
|
|
|
|
@BindView(R.id.contact_address)
|
|
TextView contactAddress;
|
|
|
|
@BindView(R.id.contact_presence)
|
|
TextView contactPresence;
|
|
|
|
@BindView(R.id.contact_account)
|
|
TextView contactAccount;
|
|
|
|
@BindView(R.id.contact_groups)
|
|
ChipGroup contactGroups;
|
|
|
|
@BindView(R.id.fab)
|
|
ExtendedFloatingActionButton fab;
|
|
|
|
@BindView(R.id.button_add_to_group)
|
|
Button button;
|
|
|
|
@BindView(R.id.fingerprint_list)
|
|
RecyclerView fingerprintRecyclerView;
|
|
|
|
@BindView(R.id.card_contact_fingerprints)
|
|
MaterialCardView fingerprintsLayout;
|
|
|
|
private ContactDetailViewModel viewModel;
|
|
@BindView(R.id.card_ikey_fingerprint)
|
|
MaterialCardView ikeyLayout;
|
|
|
|
@BindView(R.id.fingerprint)
|
|
TextView ikeyFingerprint;
|
|
|
|
private ToggleableFingerprintsAdapter fingerprintsAdapter;
|
|
|
|
@Nullable
|
|
@Override
|
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
|
View view = inflater.inflate(R.layout.fragment_contact_details, container, false);
|
|
ButterKnife.bind(this, view);
|
|
|
|
if (fab != null) {
|
|
fab.setOnClickListener(v -> {
|
|
Intent intent = new Intent(getContext(), ChatActivity.class);
|
|
intent.putExtra(ChatActivity.EXTRA_CHAT_ID, viewModel.getOrCreateChat().blockingGet().toString());
|
|
startActivity(intent);
|
|
});
|
|
}
|
|
|
|
contactName.setOnClickListener(v -> displayChangeContactNameDialog());
|
|
|
|
button.setOnClickListener(new View.OnClickListener() {
|
|
@Override
|
|
public void onClick(View v) {
|
|
viewModel.addContactToRosterGroup().subscribeOn(Schedulers.io())
|
|
.observeOn(AndroidSchedulers.mainThread())
|
|
.subscribe();
|
|
}
|
|
});
|
|
|
|
fingerprintsAdapter = new ToggleableFingerprintsAdapter(
|
|
(fingerprint, checked) -> viewModel.markFingerprintTrusted(fingerprint, checked));
|
|
fingerprintRecyclerView.setAdapter(fingerprintsAdapter);
|
|
|
|
return view;
|
|
}
|
|
|
|
private void displayChangeContactNameDialog() {
|
|
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
|
builder.setTitle("Edit Contact Name");
|
|
final EditText editText = new EditText(getContext());
|
|
editText.setText(contactName.getText());
|
|
builder.setView(editText)
|
|
.setPositiveButton("Save", (dialog, which) -> {
|
|
Completable.fromAction(() -> viewModel.changeContactName(editText.getText().toString())).subscribeOn(Schedulers.io())
|
|
.observeOn(AndroidSchedulers.mainThread())
|
|
.subscribe(() -> {}, e -> Log.e(Messenger.TAG, "Error changing contact name", e));
|
|
})
|
|
.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel());
|
|
|
|
builder.show();
|
|
}
|
|
|
|
@Override
|
|
public void onAttach(Context context) {
|
|
super.onAttach(context);
|
|
viewModel = new ViewModelProvider((ViewModelStoreOwner) context).get(ContactDetailViewModel.class);
|
|
|
|
observeViewModel();
|
|
}
|
|
|
|
private void observeViewModel() {
|
|
viewModel.getContactAvatar().observe(this, drawable -> contactAvatar.setImageDrawable(drawable));
|
|
viewModel.getContactPresenceMode().observe(this, mode -> {
|
|
int color = 0;
|
|
switch (mode) {
|
|
case chat:
|
|
case available:
|
|
color = ColorUtil.rgb(0, 255, 0);
|
|
break;
|
|
case away:
|
|
case xa:
|
|
color = ColorUtil.rgb(255, 128, 0);
|
|
break;
|
|
case dnd:
|
|
color = ColorUtil.rgb(255, 0, 0);
|
|
break;
|
|
}
|
|
contactStatusBadge.setColorFilter(color);
|
|
});
|
|
viewModel.getContactName().observe(this, name -> contactName.setText(name));
|
|
viewModel.getContactAddress().observe(this, address -> contactAddress.setText(address));
|
|
viewModel.getContactPresenceStatus().observe(this, presenceText -> contactPresence.setText(presenceText));
|
|
viewModel.getContactAccountAddress().observe(this, address -> contactAccount.setText(address));
|
|
viewModel.getContactGroups().observe(this, this::setRosterGroups);
|
|
viewModel.getContactFingerprints().observe(this, this::setFingerprints);
|
|
}
|
|
|
|
private void setRosterGroups(List<String> groups) {
|
|
contactGroups.removeAllViews();
|
|
for (String group : groups) {
|
|
Chip chip = new Chip(contactGroups.getContext());
|
|
chip.setText(group);
|
|
chip.setOnLongClickListener(new View.OnLongClickListener() {
|
|
@Override
|
|
public boolean onLongClick(View v) {
|
|
viewModel.removeContactFromRosterGroup(group)
|
|
.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
|
|
.subscribe();
|
|
return true;
|
|
}
|
|
});
|
|
contactGroups.addView(chip);
|
|
}
|
|
}
|
|
|
|
private void setIkeyFingerprint(Optional<FingerprintViewItem> fingerprintViewItemOptional) {
|
|
if (fingerprintViewItemOptional.isPresent()) {
|
|
ikeyLayout.setVisibility(View.VISIBLE);
|
|
ikeyFingerprint.setText(OpenPgpV4FingerprintFormatter.formatOpenPgpV4Fingerprint(fingerprintViewItemOptional.getItem().getFingerprint()));
|
|
} else {
|
|
ikeyLayout.setVisibility(View.GONE);
|
|
}
|
|
}
|
|
|
|
private void setFingerprints(List<FingerprintViewItem> fingerprints) {
|
|
LOGGER.log(Level.INFO, "Display fingerprints: " + Arrays.asList(fingerprints.toArray()));
|
|
fingerprintsLayout.setVisibility(fingerprints.isEmpty() ? View.GONE : View.VISIBLE);
|
|
fingerprintsAdapter.setItems(fingerprints);
|
|
}
|
|
}
|