First semi working version of account details fragment
This commit is contained in:
parent
b0ee219721
commit
4e1585a4bb
|
@ -67,7 +67,7 @@ public class MercuryImApplication extends Application {
|
||||||
/**
|
/**
|
||||||
* Create the Dependency Injection graph.
|
* Create the Dependency Injection graph.
|
||||||
*/
|
*/
|
||||||
public AppComponent createAppComponent() {
|
private AppComponent createAppComponent() {
|
||||||
AppComponent appComponent = DaggerAppComponent.builder()
|
AppComponent appComponent = DaggerAppComponent.builder()
|
||||||
.appModule(new AppModule(this))
|
.appModule(new AppModule(this))
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -3,10 +3,12 @@ package org.mercury_im.messenger.android.di.component;
|
||||||
import org.mercury_im.messenger.android.MercuryImApplication;
|
import org.mercury_im.messenger.android.MercuryImApplication;
|
||||||
import org.mercury_im.messenger.android.di.module.AndroidDatabaseModule;
|
import org.mercury_im.messenger.android.di.module.AndroidDatabaseModule;
|
||||||
import org.mercury_im.messenger.android.di.module.AndroidSchedulersModule;
|
import org.mercury_im.messenger.android.di.module.AndroidSchedulersModule;
|
||||||
|
import org.mercury_im.messenger.android.ui.account.AndroidAccountDetailsViewModel;
|
||||||
import org.mercury_im.messenger.android.ui.ox.AndroidOxSecretKeyBackupRestoreViewModel;
|
import org.mercury_im.messenger.android.ui.ox.AndroidOxSecretKeyBackupRestoreViewModel;
|
||||||
import org.mercury_im.messenger.core.di.module.RxMercuryMessageStoreFactoryModule;
|
import org.mercury_im.messenger.core.di.module.RxMercuryMessageStoreFactoryModule;
|
||||||
import org.mercury_im.messenger.core.di.module.RxMercuryRosterStoreFactoryModule;
|
import org.mercury_im.messenger.core.di.module.RxMercuryRosterStoreFactoryModule;
|
||||||
import org.mercury_im.messenger.core.di.module.XmppTcpConnectionFactoryModule;
|
import org.mercury_im.messenger.core.di.module.XmppTcpConnectionFactoryModule;
|
||||||
|
import org.mercury_im.messenger.core.viewmodel.accounts.AccountDetailsViewModel;
|
||||||
import org.mercury_im.messenger.data.di.RepositoryModule;
|
import org.mercury_im.messenger.data.di.RepositoryModule;
|
||||||
import org.mercury_im.messenger.android.di.module.AppModule;
|
import org.mercury_im.messenger.android.di.module.AppModule;
|
||||||
import org.mercury_im.messenger.core.di.module.ViewModelModule;
|
import org.mercury_im.messenger.core.di.module.ViewModelModule;
|
||||||
|
@ -81,6 +83,10 @@ public interface AppComponent {
|
||||||
|
|
||||||
void inject(ContactDetailViewModel contactDetailViewModel);
|
void inject(ContactDetailViewModel contactDetailViewModel);
|
||||||
|
|
||||||
|
void inject(AccountDetailsViewModel accountDetailsViewModel);
|
||||||
|
|
||||||
|
void inject(AndroidAccountDetailsViewModel accountDetailsViewModel);
|
||||||
|
|
||||||
//void inject(AndroidOxSecretKeyBackupRestoreViewModel viewModel);
|
//void inject(AndroidOxSecretKeyBackupRestoreViewModel viewModel);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ public class MainActivity extends AppCompatActivity
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAccountListItemClick(Account item) {
|
public void onAccountListItemClick(Account item) {
|
||||||
getSupportFragmentManager().beginTransaction().replace(R.id.fragment, new AccountDetailsFragment()).commit();
|
getSupportFragmentManager().beginTransaction().replace(R.id.fragment, new AccountDetailsFragment(item.getId())).commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,18 +1,32 @@
|
||||||
package org.mercury_im.messenger.android.ui.account;
|
package org.mercury_im.messenger.android.ui.account;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.ListView;
|
import android.widget.Switch;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import org.mercury_im.messenger.R;
|
import org.mercury_im.messenger.R;
|
||||||
|
import org.mercury_im.messenger.android.MercuryImApplication;
|
||||||
|
import org.mercury_im.messenger.android.util.OpenPgpFingerprintColorizer;
|
||||||
|
import org.mercury_im.messenger.core.viewmodel.accounts.AccountFingerprintViewItem;
|
||||||
|
import org.pgpainless.key.OpenPgpV4Fingerprint;
|
||||||
|
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
|
@ -29,17 +43,132 @@ public class AccountDetailsFragment extends Fragment {
|
||||||
@BindView(R.id.btn_share)
|
@BindView(R.id.btn_share)
|
||||||
Button localFingerprintShareButton;
|
Button localFingerprintShareButton;
|
||||||
|
|
||||||
@BindView(R.id.fingerprint)
|
@BindView(R.id.local_fingerprint)
|
||||||
TextView localFingerprint;
|
TextView localFingerprint;
|
||||||
|
|
||||||
@BindView(R.id.fingerprint_list)
|
@BindView(R.id.fingerprint_list)
|
||||||
ListView externalFingerprintList;
|
RecyclerView externalFingerprintList;
|
||||||
|
|
||||||
|
private final UUID accountId;
|
||||||
|
private ToggleableFingerprintsAdapter adapter;
|
||||||
|
|
||||||
|
private AndroidAccountDetailsViewModel viewModel;
|
||||||
|
|
||||||
|
private static final DateFormat dateFormat = SimpleDateFormat.getDateInstance();
|
||||||
|
|
||||||
|
|
||||||
|
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.adapter = new ToggleableFingerprintsAdapter(viewModel);
|
||||||
|
observe();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void observe() {
|
||||||
|
viewModel.getLocalFingerprint().observe(this,
|
||||||
|
f -> localFingerprint.setText(OpenPgpFingerprintColorizer.formatOpenPgpV4Fingerprint(f)));
|
||||||
|
|
||||||
|
viewModel.getRemoteFingerprints().observe(this, adapter::setItems);
|
||||||
|
|
||||||
|
//viewModel.getJid().observe(this, jid::setText);
|
||||||
|
|
||||||
|
/*
|
||||||
|
localFingerprintShareButton.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Intent sendIntent = new Intent();
|
||||||
|
sendIntent.setAction(Intent.ACTION_SEND);
|
||||||
|
sendIntent.putExtra(Intent.EXTRA_TEXT, viewModel.getLocalFingerprint().getValue());
|
||||||
|
sendIntent.setType("text/plain");
|
||||||
|
|
||||||
|
Intent shareIntent = Intent.createChooser(sendIntent, null);
|
||||||
|
startActivity(shareIntent);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.fragment_account_details, container, false);
|
View view = inflater.inflate(R.layout.fragment_account_details, container, false);
|
||||||
ButterKnife.bind(this, view);
|
ButterKnife.bind(this, view);
|
||||||
|
|
||||||
|
externalFingerprintList.setAdapter(adapter);
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class ToggleableFingerprintsAdapter extends RecyclerView.Adapter<ToggleableFingerprintsAdapter.ViewHolder> {
|
||||||
|
|
||||||
|
private final List<AccountFingerprintViewItem> fingerprints = new ArrayList<>();
|
||||||
|
private final AndroidAccountDetailsViewModel viewModel;
|
||||||
|
|
||||||
|
public ToggleableFingerprintsAdapter(AndroidAccountDetailsViewModel viewModel) {
|
||||||
|
this.viewModel = viewModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setItems(List<AccountFingerprintViewItem> fingerprints) {
|
||||||
|
synchronized (this.fingerprints) {
|
||||||
|
this.fingerprints.clear();
|
||||||
|
this.fingerprints.addAll(fingerprints);
|
||||||
|
this.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
View view = LayoutInflater.from(parent.getContext())
|
||||||
|
.inflate(R.layout.view_fingerprint_toggleable, parent, false);
|
||||||
|
return new ViewHolder(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||||
|
synchronized (fingerprints) {
|
||||||
|
AccountFingerprintViewItem f = fingerprints.get(position);
|
||||||
|
|
||||||
|
final OpenPgpV4Fingerprint fingerprint = f.getFingerprint();
|
||||||
|
|
||||||
|
holder.fingerprint.setText(OpenPgpFingerprintColorizer.formatOpenPgpV4Fingerprint(fingerprint));
|
||||||
|
holder.fingerprintTimestamp.setText(dateFormat.format(f.getAnnouncementDate()));
|
||||||
|
|
||||||
|
holder.trustSwitch.setChecked(f.isTrusted());
|
||||||
|
holder.trustSwitch.setOnCheckedChangeListener(
|
||||||
|
(buttonView, isChecked) -> viewModel.markFingerprintTrusted(fingerprint, isChecked));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return fingerprints.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
|
private final Switch trustSwitch;
|
||||||
|
private final TextView fingerprintTimestamp;
|
||||||
|
private final TextView fingerprint;
|
||||||
|
|
||||||
|
public ViewHolder(@NonNull View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
this.fingerprint = itemView.findViewById(R.id.fingerprint);
|
||||||
|
this.trustSwitch = itemView.findViewById(R.id.fingerprint_toggle);
|
||||||
|
this.fingerprintTimestamp = itemView.findViewById(R.id.fingerprint_timestamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
package org.mercury_im.messenger.android.ui.account;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.lifecycle.AndroidViewModel;
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
|
import org.jxmpp.jid.EntityBareJid;
|
||||||
|
import org.mercury_im.messenger.android.MercuryImApplication;
|
||||||
|
import org.mercury_im.messenger.android.ui.MercuryAndroidViewModel;
|
||||||
|
import org.mercury_im.messenger.core.SchedulersFacade;
|
||||||
|
import org.mercury_im.messenger.core.util.Optional;
|
||||||
|
import org.mercury_im.messenger.core.viewmodel.accounts.AccountDetailsViewModel;
|
||||||
|
import org.mercury_im.messenger.core.viewmodel.accounts.AccountFingerprintViewItem;
|
||||||
|
import org.pgpainless.key.OpenPgpV4Fingerprint;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
public class AndroidAccountDetailsViewModel extends AndroidViewModel implements MercuryAndroidViewModel<AccountDetailsViewModel> {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
SchedulersFacade schedulers;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
AccountDetailsViewModel commonViewModel;
|
||||||
|
|
||||||
|
private final UUID accountId;
|
||||||
|
private MutableLiveData<OpenPgpV4Fingerprint> localFingerprint = new MutableLiveData<>();
|
||||||
|
private MutableLiveData<List<AccountFingerprintViewItem>> remoteFingerprints = new MutableLiveData<>(new ArrayList<>());
|
||||||
|
private MutableLiveData<EntityBareJid> jid;
|
||||||
|
|
||||||
|
public AndroidAccountDetailsViewModel(@NonNull Application application, UUID accountId) {
|
||||||
|
super(application);
|
||||||
|
this.accountId = accountId;
|
||||||
|
|
||||||
|
((MercuryImApplication) application).getAppComponent().inject(this);
|
||||||
|
|
||||||
|
addDisposable(getCommonViewModel().observeLocalFingerprint(accountId)
|
||||||
|
.compose(schedulers.executeUiSafeObservable())
|
||||||
|
.filter(Optional::isPresent)
|
||||||
|
.map(Optional::getItem)
|
||||||
|
.subscribe(localFingerprint::setValue));
|
||||||
|
|
||||||
|
addDisposable(getCommonViewModel().observeRemoteFingerprints(accountId)
|
||||||
|
.compose(schedulers.executeUiSafeObservable())
|
||||||
|
.subscribe(list -> remoteFingerprints.setValue(list)));
|
||||||
|
|
||||||
|
//addDisposable(getCommonViewModel().getJid(accountId).subscribe(jid::setValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AccountDetailsViewModel getCommonViewModel() {
|
||||||
|
return commonViewModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<EntityBareJid> getJid() {
|
||||||
|
return jid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void markFingerprintTrusted(OpenPgpV4Fingerprint fingerprint, boolean trusted) {
|
||||||
|
getCommonViewModel().markFingerprintTrusted(accountId, fingerprint, trusted);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<OpenPgpV4Fingerprint> getLocalFingerprint() {
|
||||||
|
return localFingerprint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<List<AccountFingerprintViewItem>> getRemoteFingerprints() {
|
||||||
|
return remoteFingerprints;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class AndroidAccountDetailsViewModelFactory implements ViewModelProvider.Factory {
|
||||||
|
|
||||||
|
private final Application application;
|
||||||
|
private final UUID accountId;
|
||||||
|
|
||||||
|
public AndroidAccountDetailsViewModelFactory(Application application, UUID accountId) {
|
||||||
|
this.application = application;
|
||||||
|
this.accountId = accountId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
|
||||||
|
return (T) new AndroidAccountDetailsViewModel(application, accountId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,7 +27,7 @@ public class ChatInputFragment extends Fragment implements View.OnClickListener
|
||||||
EditText textInput;
|
EditText textInput;
|
||||||
|
|
||||||
@BindView(R.id.btn_media)
|
@BindView(R.id.btn_media)
|
||||||
ImageButton addAttachement;
|
ImageButton addAttachment;
|
||||||
|
|
||||||
@BindView(R.id.btn_send)
|
@BindView(R.id.btn_send)
|
||||||
ImageButton buttonSend;
|
ImageButton buttonSend;
|
||||||
|
|
|
@ -4,8 +4,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical">
|
||||||
android:padding="12dp">
|
|
||||||
|
|
||||||
<de.hdodenhof.circleimageview.CircleImageView
|
<de.hdodenhof.circleimageview.CircleImageView
|
||||||
android:id="@+id/avatar"
|
android:id="@+id/avatar"
|
||||||
|
@ -35,6 +34,8 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="12dp"
|
android:layout_marginTop="12dp"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
|
android:padding="12dp"
|
||||||
|
android:clipToPadding="false"
|
||||||
app:layout_constraintTop_toBottomOf="@id/jid">
|
app:layout_constraintTop_toBottomOf="@id/jid">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
@ -44,13 +45,13 @@
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.SearchResult.Title"
|
android:textAppearance="@style/TextAppearance.AppCompat.SearchResult.Title"
|
||||||
android:text="Encryption Keys" />
|
android:text="Encryption Keys" />
|
||||||
|
|
||||||
<include layout="@layout/fragment_fingerprint_card"
|
<include layout="@layout/view_fingerprint_card"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:layout_marginBottom="8dp"/>
|
android:layout_marginBottom="8dp"/>
|
||||||
|
|
||||||
<include layout="@layout/fragment_toggleable_fingerprints_card"
|
<include layout="@layout/view_fingerprints_card_toggleable"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/fingerprint"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:textSize="18sp"
|
android:textSize="18sp"
|
||||||
android:typeface="monospace"
|
android:typeface="monospace"
|
||||||
tools:text="1357 B018 65B2 503C 1845\n3D20 8CAC 2A96 7854 8E35" />
|
android:text="@string/test_fingerprint"
|
||||||
|
tools:text="@string/test_fingerprint" />
|
|
@ -23,8 +23,9 @@
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
|
||||||
<include
|
<include
|
||||||
android:id="@+id/fingerprint"
|
android:id="@+id/local_fingerprint"
|
||||||
layout="@layout/view_fingerprint"
|
layout="@layout/view_fingerprint"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -41,7 +42,7 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="share"
|
android:text="share"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/fingerprint" />
|
app:layout_constraintTop_toBottomOf="@+id/local_fingerprint" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
|
@ -2,35 +2,45 @@
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<include
|
<include
|
||||||
android:id="@+id/include"
|
android:id="@+id/fingerprint"
|
||||||
layout="@layout/view_fingerprint"
|
layout="@layout/view_fingerprint"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_marginVertical="4dp"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:layout_marginTop="4dp"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
android:id="@+id/toggle"
|
android:id="@+id/fingerprint_toggle"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:layout_marginStart="12dp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintBottom_toTopOf="@+id/divider"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintStart_toEndOf="@+id/fingerprint"
|
||||||
android:layout_marginEnd="4dp"/>
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/fingerprint_timestamp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:text="2018-03-01T15:26:12Z"
|
||||||
|
app:layout_constraintStart_toStartOf="@id/fingerprint"
|
||||||
|
app:layout_constraintEnd_toEndOf="@id/fingerprint"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/fingerprint"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent" />
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/divider"
|
android:id="@+id/divider"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="1dp"
|
android:layout_height="1dp"
|
||||||
android:background="?android:attr/listDivider"
|
android:background="?android:attr/listDivider"
|
||||||
app:layout_constraintBottom_toBottomOf="parent" />
|
app:layout_constraintTop_toBottomOf="@id/fingerprint" />
|
||||||
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -4,13 +4,13 @@
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
app:cardCornerRadius="4dp"
|
app:cardCornerRadius="4dp"
|
||||||
app:cardElevation="4dp">
|
app:cardElevation="4dp">
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:paddingStart="12dp"
|
android:paddingStart="12dp"
|
||||||
android:paddingEnd="12dp"
|
android:paddingEnd="12dp"
|
||||||
|
@ -24,11 +24,11 @@
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<ListView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/fingerprint_list"
|
android:id="@+id/fingerprint_list"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
tools:listitem="@layout/view_toggleable_fingerprint"
|
tools:listitem="@layout/view_fingerprint_toggleable"
|
||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
|
@ -142,4 +142,6 @@
|
||||||
<string name="error_uknown_error">Unknown error</string>
|
<string name="error_uknown_error">Unknown error</string>
|
||||||
<string name="content_description_avatar_image">Avatar Image</string>
|
<string name="content_description_avatar_image">Avatar Image</string>
|
||||||
<string name="button_delete">Delete</string>
|
<string name="button_delete">Delete</string>
|
||||||
|
|
||||||
|
<string name="test_fingerprint">1357 B018 65B2 503C 1845\n3D20 8CAC 2A96 7854 8E35</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -89,8 +89,8 @@ public class RepositoryModule {
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
static OpenPgpRepository provideOpenPgpRepository(
|
static OpenPgpRepository provideOpenPgpRepository(
|
||||||
ReactiveEntityStore<Persistable> data) {
|
ReactiveEntityStore<Persistable> data, AccountRepository accountRepository) {
|
||||||
return new RxOpenPgpRepository(data);
|
return new RxOpenPgpRepository(data, accountRepository);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
|
|
@ -6,7 +6,9 @@ import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
|
||||||
import org.jivesoftware.smackx.ox.store.definition.OpenPgpTrustStore;
|
import org.jivesoftware.smackx.ox.store.definition.OpenPgpTrustStore;
|
||||||
import org.jxmpp.jid.EntityBareJid;
|
import org.jxmpp.jid.EntityBareJid;
|
||||||
import org.jxmpp.jid.impl.JidCreate;
|
import org.jxmpp.jid.impl.JidCreate;
|
||||||
|
import org.mercury_im.messenger.core.data.repository.AccountRepository;
|
||||||
import org.mercury_im.messenger.core.data.repository.OpenPgpRepository;
|
import org.mercury_im.messenger.core.data.repository.OpenPgpRepository;
|
||||||
|
import org.mercury_im.messenger.core.util.Optional;
|
||||||
import org.mercury_im.messenger.data.model.AnnouncedOpenPgpContactKey;
|
import org.mercury_im.messenger.data.model.AnnouncedOpenPgpContactKey;
|
||||||
import org.mercury_im.messenger.data.model.OpenPgpKeyFetchDate;
|
import org.mercury_im.messenger.data.model.OpenPgpKeyFetchDate;
|
||||||
import org.mercury_im.messenger.data.model.OpenPgpKeyTrust;
|
import org.mercury_im.messenger.data.model.OpenPgpKeyTrust;
|
||||||
|
@ -27,6 +29,7 @@ import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
@ -43,9 +46,12 @@ public class RxOpenPgpRepository implements OpenPgpRepository {
|
||||||
|
|
||||||
private final ReactiveEntityStore<Persistable> data;
|
private final ReactiveEntityStore<Persistable> data;
|
||||||
|
|
||||||
|
private final AccountRepository accountRepository;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public RxOpenPgpRepository(ReactiveEntityStore<Persistable> data) {
|
public RxOpenPgpRepository(ReactiveEntityStore<Persistable> data, AccountRepository accountRepository) {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
|
this.accountRepository = accountRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -158,6 +164,24 @@ public class RxOpenPgpRepository implements OpenPgpRepository {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Single<Date> loadAnnouncementDate(UUID accountId, EntityBareJid owner, OpenPgpV4Fingerprint fingerprint) {
|
||||||
|
return data.select(AnnouncedOpenPgpContactKey.class)
|
||||||
|
.where(AnnouncedOpenPgpContactKey.ACCOUNT_ID.eq(accountId)
|
||||||
|
.and(AnnouncedOpenPgpContactKey.OWNER.eq(owner))
|
||||||
|
.and(AnnouncedOpenPgpContactKey.FINGERPRINT.eq(fingerprint)))
|
||||||
|
.get().observableResult()
|
||||||
|
.map(ResultDelegate::first)
|
||||||
|
.map(AnnouncedOpenPgpContactKey::getModificationDate)
|
||||||
|
.singleOrError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Single<Date> loadAnnouncementDate(UUID accountId, OpenPgpV4Fingerprint fingerprint) {
|
||||||
|
return accountRepository.getAccount(accountId).toSingle()
|
||||||
|
.flatMap(account -> loadAnnouncementDate(accountId, account.getJid(), fingerprint));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Single<OpenPgpTrustStore.Trust> loadTrust(UUID accountId, EntityBareJid owner, OpenPgpV4Fingerprint fingerprint) {
|
public Single<OpenPgpTrustStore.Trust> loadTrust(UUID accountId, EntityBareJid owner, OpenPgpV4Fingerprint fingerprint) {
|
||||||
return data.select(OpenPgpKeyTrust.class)
|
return data.select(OpenPgpKeyTrust.class)
|
||||||
|
@ -171,6 +195,12 @@ public class RxOpenPgpRepository implements OpenPgpRepository {
|
||||||
.map(entity -> entity.getTrust() != null ? entity.getTrust() : OpenPgpTrustStore.Trust.undecided);
|
.map(entity -> entity.getTrust() != null ? entity.getTrust() : OpenPgpTrustStore.Trust.undecided);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Single<OpenPgpTrustStore.Trust> loadTrust(UUID accountId, OpenPgpV4Fingerprint fingerprint) {
|
||||||
|
return accountRepository.getAccount(accountId).toSingle()
|
||||||
|
.flatMap(account -> loadTrust(accountId, account.getJid(), fingerprint));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Completable storeTrust(UUID accountId, EntityBareJid owner, OpenPgpV4Fingerprint fingerprint, OpenPgpTrustStore.Trust trust) {
|
public Completable storeTrust(UUID accountId, EntityBareJid owner, OpenPgpV4Fingerprint fingerprint, OpenPgpTrustStore.Trust trust) {
|
||||||
OpenPgpKeyTrust entity = new OpenPgpKeyTrust();
|
OpenPgpKeyTrust entity = new OpenPgpKeyTrust();
|
||||||
|
@ -181,6 +211,12 @@ public class RxOpenPgpRepository implements OpenPgpRepository {
|
||||||
return data.upsert(entity).ignoreElement();
|
return data.upsert(entity).ignoreElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Completable storeTrust(UUID accountId, OpenPgpV4Fingerprint fingerprint, OpenPgpTrustStore.Trust trust) {
|
||||||
|
return accountRepository.getAccount(accountId).toSingle()
|
||||||
|
.flatMapCompletable(account -> storeTrust(accountId, account.getJid(), fingerprint, trust));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Observable<List<OpenPgpV4Fingerprint>> observeFingerprintsOf(UUID accountId, String peerAddress) {
|
public Observable<List<OpenPgpV4Fingerprint>> observeFingerprintsOf(UUID accountId, String peerAddress) {
|
||||||
return data.select(OpenPgpPublicKeyRing.class)
|
return data.select(OpenPgpPublicKeyRing.class)
|
||||||
|
@ -201,6 +237,50 @@ public class RxOpenPgpRepository implements OpenPgpRepository {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Observable<Optional<OpenPgpV4Fingerprint>> observeLocalFingerprintOf(UUID accountId) {
|
||||||
|
return data.select(OpenPgpSecretKeyRing.class)
|
||||||
|
.where(OpenPgpSecretKeyRing.ACCOUNT_ID.eq(accountId))
|
||||||
|
.get().observableResult()
|
||||||
|
.map(result -> {
|
||||||
|
OpenPgpSecretKeyRing ring = new ResultDelegate<>(result).firstOrNull();
|
||||||
|
if (ring == null) {
|
||||||
|
return new Optional<>();
|
||||||
|
} else {
|
||||||
|
return new Optional<>(new OpenPgpV4Fingerprint(
|
||||||
|
PGPainless.readKeyRing().secretKeyRing(ring.getBytes()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Observable<List<OpenPgpV4Fingerprint>> observeRemoteFingerprintsOfAccount(UUID accountId) {
|
||||||
|
return observeLocalFingerprintOf(accountId)
|
||||||
|
.flatMap(localFingerprint -> data.select(OpenPgpPublicKeyRing.class)
|
||||||
|
.where(OpenPgpPublicKeyRing.ACCOUNT_ID.eq(accountId))
|
||||||
|
.get().observableResult()
|
||||||
|
.map(result -> {
|
||||||
|
OpenPgpPublicKeyRing ring = new ResultDelegate<>(result).firstOrNull();
|
||||||
|
if (ring == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
} else {
|
||||||
|
Iterator<PGPPublicKeyRing> iterator = PGPainless.readKeyRing().publicKeyRingCollection(ring.getBytes()).iterator();
|
||||||
|
List<OpenPgpV4Fingerprint> fingerprints = new ArrayList<>();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
PGPPublicKeyRing r = iterator.next();
|
||||||
|
OpenPgpV4Fingerprint f = new OpenPgpV4Fingerprint(r);
|
||||||
|
fingerprints.add(f);
|
||||||
|
}
|
||||||
|
if (localFingerprint.isPresent()) {
|
||||||
|
fingerprints.remove(localFingerprint.getItem());
|
||||||
|
}
|
||||||
|
return fingerprints;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Single<Map<OpenPgpV4Fingerprint, Date>> loadPublicKeyFetchDates(UUID accountId, EntityBareJid owner) {
|
public Single<Map<OpenPgpV4Fingerprint, Date>> loadPublicKeyFetchDates(UUID accountId, EntityBareJid owner) {
|
||||||
List<OpenPgpKeyFetchDate> fetchDates =
|
List<OpenPgpKeyFetchDate> fetchDates =
|
||||||
|
|
|
@ -4,6 +4,8 @@ import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
|
||||||
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
|
import org.bouncycastle.openpgp.PGPSecretKeyRingCollection;
|
||||||
import org.jivesoftware.smackx.ox.store.definition.OpenPgpTrustStore;
|
import org.jivesoftware.smackx.ox.store.definition.OpenPgpTrustStore;
|
||||||
import org.jxmpp.jid.EntityBareJid;
|
import org.jxmpp.jid.EntityBareJid;
|
||||||
|
import org.mercury_im.messenger.core.util.Optional;
|
||||||
|
import org.mercury_im.messenger.entity.Account;
|
||||||
import org.pgpainless.key.OpenPgpV4Fingerprint;
|
import org.pgpainless.key.OpenPgpV4Fingerprint;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -37,9 +39,21 @@ public interface OpenPgpRepository {
|
||||||
|
|
||||||
Single<Map<OpenPgpV4Fingerprint, Date>> loadAnnouncedFingerprints(UUID accountId, EntityBareJid contact);
|
Single<Map<OpenPgpV4Fingerprint, Date>> loadAnnouncedFingerprints(UUID accountId, EntityBareJid contact);
|
||||||
|
|
||||||
|
Single<Date> loadAnnouncementDate(UUID accountId, EntityBareJid owner, OpenPgpV4Fingerprint fingerprint);
|
||||||
|
|
||||||
|
Single<Date> loadAnnouncementDate(UUID accountId, OpenPgpV4Fingerprint fingerprint);
|
||||||
|
|
||||||
Single<OpenPgpTrustStore.Trust> loadTrust(UUID accountId, EntityBareJid owner, OpenPgpV4Fingerprint fingerprint);
|
Single<OpenPgpTrustStore.Trust> loadTrust(UUID accountId, EntityBareJid owner, OpenPgpV4Fingerprint fingerprint);
|
||||||
|
|
||||||
|
Single<OpenPgpTrustStore.Trust> loadTrust(UUID accountId, OpenPgpV4Fingerprint fingerprint);
|
||||||
|
|
||||||
Completable storeTrust(UUID accountId, EntityBareJid owner, OpenPgpV4Fingerprint fingerprint, OpenPgpTrustStore.Trust trust);
|
Completable storeTrust(UUID accountId, EntityBareJid owner, OpenPgpV4Fingerprint fingerprint, OpenPgpTrustStore.Trust trust);
|
||||||
|
|
||||||
|
Completable storeTrust(UUID accountId, OpenPgpV4Fingerprint fingerprint, OpenPgpTrustStore.Trust trust);
|
||||||
|
|
||||||
Observable<List<OpenPgpV4Fingerprint>> observeFingerprintsOf(UUID accountId, String peerAddress);
|
Observable<List<OpenPgpV4Fingerprint>> observeFingerprintsOf(UUID accountId, String peerAddress);
|
||||||
|
|
||||||
|
Observable<Optional<OpenPgpV4Fingerprint>> observeLocalFingerprintOf(UUID accountId);
|
||||||
|
|
||||||
|
Observable<List<OpenPgpV4Fingerprint>> observeRemoteFingerprintsOfAccount(UUID accountId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package org.mercury_im.messenger.core.di.module;
|
||||||
import org.mercury_im.messenger.core.SchedulersFacade;
|
import org.mercury_im.messenger.core.SchedulersFacade;
|
||||||
import org.mercury_im.messenger.core.data.repository.AccountRepository;
|
import org.mercury_im.messenger.core.data.repository.AccountRepository;
|
||||||
import org.mercury_im.messenger.core.data.repository.OpenPgpRepository;
|
import org.mercury_im.messenger.core.data.repository.OpenPgpRepository;
|
||||||
|
import org.mercury_im.messenger.core.viewmodel.accounts.AccountDetailsViewModel;
|
||||||
import org.mercury_im.messenger.core.viewmodel.accounts.AccountsViewModel;
|
import org.mercury_im.messenger.core.viewmodel.accounts.AccountsViewModel;
|
||||||
import org.mercury_im.messenger.core.viewmodel.accounts.LoginViewModel;
|
import org.mercury_im.messenger.core.viewmodel.accounts.LoginViewModel;
|
||||||
import org.mercury_im.messenger.core.xmpp.MercuryConnectionManager;
|
import org.mercury_im.messenger.core.xmpp.MercuryConnectionManager;
|
||||||
|
@ -32,6 +33,14 @@ public class ViewModelModule {
|
||||||
return new AccountsViewModel(connectionManager, accountRepository, openPgpRepository, schedulers);
|
return new AccountsViewModel(connectionManager, accountRepository, openPgpRepository, schedulers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
static AccountDetailsViewModel provideAccountDetailsViewModel(OpenPgpRepository openPgpRepository,
|
||||||
|
AccountRepository accountRepository,
|
||||||
|
SchedulersFacade schedulers) {
|
||||||
|
return new AccountDetailsViewModel(openPgpRepository, accountRepository, schedulers);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
package org.mercury_im.messenger.core.viewmodel.accounts;
|
||||||
|
|
||||||
|
import org.jivesoftware.smackx.ox.store.definition.OpenPgpTrustStore;
|
||||||
|
import org.jxmpp.jid.EntityBareJid;
|
||||||
|
import org.mercury_im.messenger.core.SchedulersFacade;
|
||||||
|
import org.mercury_im.messenger.core.data.repository.AccountRepository;
|
||||||
|
import org.mercury_im.messenger.core.data.repository.OpenPgpRepository;
|
||||||
|
import org.mercury_im.messenger.core.util.Optional;
|
||||||
|
import org.mercury_im.messenger.core.viewmodel.MercuryViewModel;
|
||||||
|
import org.mercury_im.messenger.entity.Account;
|
||||||
|
import org.pgpainless.key.OpenPgpV4Fingerprint;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import io.reactivex.Observable;
|
||||||
|
import io.reactivex.Single;
|
||||||
|
|
||||||
|
public class AccountDetailsViewModel implements MercuryViewModel {
|
||||||
|
|
||||||
|
private final OpenPgpRepository openPgpRepository;
|
||||||
|
private final AccountRepository accountRepository;
|
||||||
|
private final SchedulersFacade schedulers;
|
||||||
|
|
||||||
|
public AccountDetailsViewModel(OpenPgpRepository openPgpRepository, AccountRepository accountRepository, SchedulersFacade schedulers) {
|
||||||
|
this.openPgpRepository = openPgpRepository;
|
||||||
|
this.accountRepository = accountRepository;
|
||||||
|
this.schedulers = schedulers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void markFingerprintTrusted(UUID accountId, OpenPgpV4Fingerprint fingerprint, boolean trusted) {
|
||||||
|
addDisposable(openPgpRepository.storeTrust(accountId, fingerprint, trusted ? OpenPgpTrustStore.Trust.trusted : OpenPgpTrustStore.Trust.untrusted)
|
||||||
|
.compose(schedulers.executeUiSafeCompletable())
|
||||||
|
.subscribe());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Single<EntityBareJid> getJid(UUID accountId) {
|
||||||
|
return accountRepository.getAccount(accountId).toSingle()
|
||||||
|
.compose(schedulers.executeUiSafeSingle())
|
||||||
|
.map(Account::getJid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Observable<Optional<OpenPgpV4Fingerprint>> observeLocalFingerprint(UUID accountId) {
|
||||||
|
return openPgpRepository.observeLocalFingerprintOf(accountId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Observable<List<AccountFingerprintViewItem>> observeRemoteFingerprints(UUID accountId) {
|
||||||
|
return openPgpRepository.observeRemoteFingerprintsOfAccount(accountId)
|
||||||
|
.map(list -> {
|
||||||
|
List<AccountFingerprintViewItem> viewItems = new ArrayList<>(list.size());
|
||||||
|
for (OpenPgpV4Fingerprint fingerprint : list) {
|
||||||
|
OpenPgpTrustStore.Trust trust = openPgpRepository.loadTrust(accountId, fingerprint).blockingGet();
|
||||||
|
Date announcementDate = openPgpRepository.loadAnnouncementDate(accountId, fingerprint).blockingGet();
|
||||||
|
viewItems.add(new AccountFingerprintViewItem(fingerprint, announcementDate, trust == OpenPgpTrustStore.Trust.trusted));
|
||||||
|
}
|
||||||
|
return viewItems;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package org.mercury_im.messenger.core.viewmodel.accounts;
|
||||||
|
|
||||||
|
import org.pgpainless.key.OpenPgpV4Fingerprint;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class AccountFingerprintViewItem {
|
||||||
|
OpenPgpV4Fingerprint fingerprint;
|
||||||
|
Date announcementDate;
|
||||||
|
boolean trusted;
|
||||||
|
}
|
Loading…
Reference in New Issue