package org.mercury_im.messenger.android.ui.account.detail; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.card.MaterialCardView; import org.mercury_im.messenger.R; import org.mercury_im.messenger.android.MercuryImApplication; import org.mercury_im.messenger.android.ui.ikey.IkeyBackupCreationFragment; import org.mercury_im.messenger.android.ui.openpgp.ToggleableFingerprintsAdapter; import org.mercury_im.messenger.android.ui.openpgp.OpenPgpV4FingerprintFormatter; import org.mercury_im.messenger.core.util.Optional; import org.mercury_im.messenger.core.viewmodel.openpgp.FingerprintViewItem; import org.pgpainless.key.OpenPgpV4Fingerprint; import java.util.List; import java.util.UUID; import butterknife.BindView; import butterknife.ButterKnife; import de.hdodenhof.circleimageview.CircleImageView; public class AccountDetailsFragment extends Fragment { @BindView(R.id.avatar) CircleImageView avatar; @BindView(R.id.jid) TextView jid; @BindView(R.id.btn_share) Button localFingerprintShareButton; @BindView(R.id.btn_share_ikey) Button ikeyFingerprintShareButton; @BindView(R.id.btn_backup_ikey) Button ikeyCreateBackupButton; @BindView(R.id.ikey_fingerprint) TextView ikeyFingerprint; @BindView(R.id.local_fingerprint) TextView localFingerprint; @BindView(R.id.fingerprint_list) RecyclerView externalFingerprintRecyclerView; @BindView(R.id.other_fingerprints_card) MaterialCardView otherFingerprintsLayout; @BindView(R.id.layout_ikey) MaterialCardView ikeyLayout; private final UUID accountId; private ToggleableFingerprintsAdapter otherFingerprintsAdapter; private AndroidAccountDetailsViewModel viewModel; public AccountDetailsFragment(UUID accountId) { this.accountId = accountId; } @Override public void onAttach(@NonNull Context context) { super.onAttach(context); AndroidAccountDetailsViewModel.AndroidAccountDetailsViewModelFactory factory = new AndroidAccountDetailsViewModel.AndroidAccountDetailsViewModelFactory(MercuryImApplication.getApplication(), accountId); viewModel = new ViewModelProvider(this, factory) .get(AndroidAccountDetailsViewModel.class); this.otherFingerprintsAdapter = new ToggleableFingerprintsAdapter( (fingerprint, checked) -> viewModel.markFingerprintTrusted(fingerprint, checked)); this.otherFingerprintsAdapter.setItemLongClickListener(fingerprint -> viewModel.unpublishPublicKey(fingerprint)); } @Override public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { inflater.inflate(R.menu.menu_account_details, menu); super.onCreateOptionsMenu(menu, inflater); } @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case R.id.action_generate_ikey: viewModel.onGenerateIkey(); return true; case R.id.action_delete_ikey: viewModel.onDeleteIkey(); return true; case R.id.action_restore_ikey_backup: viewModel.onRestoreIkeyBackup(); return true; } return super.onOptionsItemSelected(item); } @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_account_details, container, false); ButterKnife.bind(this, view); setHasOptionsMenu(true); externalFingerprintRecyclerView.setAdapter(otherFingerprintsAdapter); observeViewModel(); return view; } private void observeViewModel() { viewModel.getIkeyFingerprint().observe(getViewLifecycleOwner(), this::displayIkeyFingerprint); viewModel.getLocalFingerprint().observe(getViewLifecycleOwner(), this::displayLocalOxFingerprint); viewModel.getRemoteFingerprints().observe(getViewLifecycleOwner(), this::displayOtherOxFingerprints); viewModel.getJid().observe(getViewLifecycleOwner(), accountJid -> jid.setText(accountJid.toString())); localFingerprintShareButton.setOnClickListener(v -> { OpenPgpV4Fingerprint fingerprint = viewModel.getLocalFingerprint().getValue(); startShareFingerprintIntent(fingerprint); }); ikeyFingerprintShareButton.setOnClickListener(v -> { Optional fingerprint = viewModel.getIkeyFingerprint().getValue(); if (fingerprint == null || !fingerprint.isPresent()) { return; } startShareFingerprintIntent(fingerprint.getItem()); }); ikeyCreateBackupButton.setOnClickListener(v -> { getParentFragmentManager().beginTransaction() .replace(R.id.fragment, IkeyBackupCreationFragment.newInstance(accountId)).commit(); }); } private void startShareFingerprintIntent(OpenPgpV4Fingerprint fingerprint) { Intent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_TEXT, "openpgp4fpr:" + fingerprint); sendIntent.setType("text/plain"); Intent shareIntent = Intent.createChooser(sendIntent, "Share OpenPGP Fingerprint"); startActivity(shareIntent); } private void displayIkeyFingerprint(Optional fingerprint) { if (fingerprint.isPresent()) { ikeyLayout.setVisibility(View.VISIBLE); ikeyFingerprint.setText(OpenPgpV4FingerprintFormatter.formatOpenPgpV4Fingerprint(fingerprint.getItem())); } else { ikeyLayout.setVisibility(View.GONE); ikeyFingerprint.setText(null); } } private void displayLocalOxFingerprint(OpenPgpV4Fingerprint fingerprint) { if (fingerprint != null) { localFingerprint.setText(OpenPgpV4FingerprintFormatter.formatOpenPgpV4Fingerprint(fingerprint)); } else { localFingerprint.setText(null); } } private void displayOtherOxFingerprints(List fingerprints) { otherFingerprintsAdapter.setItems(fingerprints); if (fingerprints.isEmpty()) { otherFingerprintsLayout.setVisibility(View.GONE); } else { otherFingerprintsLayout.setVisibility(View.VISIBLE); } } }