mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 18:59:06 +01:00
[android] finalize list of pending contacts and add test code
This commit is contained in:
@@ -85,7 +85,7 @@ public interface ContactManager {
|
||||
* Removes a {@link PendingContact} that is in state
|
||||
* {@link PendingContactState FAILED}.
|
||||
*/
|
||||
void removePendingContact(PendingContact pendingContact);
|
||||
void removePendingContact(PendingContact pendingContact) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the contact with the given ID.
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.contact.ContactManager;
|
||||
import org.briarproject.bramble.api.contact.PendingContact;
|
||||
import org.briarproject.bramble.api.contact.PendingContactId;
|
||||
import org.briarproject.bramble.api.contact.event.ContactAddedRemotelyEvent;
|
||||
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent;
|
||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
@@ -19,6 +20,7 @@ import org.briarproject.bramble.api.identity.AuthorInfo;
|
||||
import org.briarproject.bramble.api.identity.IdentityManager;
|
||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.bramble.api.system.Scheduler;
|
||||
import org.briarproject.bramble.api.transport.KeyManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -27,12 +29,18 @@ import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.ThreadSafe;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static java.lang.System.currentTimeMillis;
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.bramble.api.contact.PendingContactState.ADDING_CONTACT;
|
||||
import static org.briarproject.bramble.api.contact.PendingContactState.CONNECTED;
|
||||
import static org.briarproject.bramble.api.contact.PendingContactState.FAILED;
|
||||
import static org.briarproject.bramble.api.contact.PendingContactState.WAITING_FOR_CONNECTION;
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
@@ -48,10 +56,12 @@ class ContactManagerImpl implements ContactManager {
|
||||
|
||||
private static final String REMOTE_CONTACT_LINK =
|
||||
"briar://" + getRandomBase32String(LINK_LENGTH);
|
||||
// TODO remove
|
||||
// TODO replace with real implementation
|
||||
private final List<PendingContact> pendingContacts = new ArrayList<>();
|
||||
@DatabaseExecutor
|
||||
private final Executor dbExecutor;
|
||||
@Scheduler
|
||||
private final ScheduledExecutorService scheduler;
|
||||
|
||||
private final DatabaseComponent db;
|
||||
private final KeyManager keyManager;
|
||||
@@ -61,11 +71,13 @@ class ContactManagerImpl implements ContactManager {
|
||||
@Inject
|
||||
ContactManagerImpl(DatabaseComponent db,
|
||||
@DatabaseExecutor Executor dbExecutor, KeyManager keyManager,
|
||||
IdentityManager identityManager) {
|
||||
IdentityManager identityManager, @Scheduler
|
||||
ScheduledExecutorService scheduler) {
|
||||
this.db = db;
|
||||
this.dbExecutor = dbExecutor;
|
||||
this.keyManager = keyManager;
|
||||
this.identityManager = identityManager;
|
||||
this.scheduler = scheduler;
|
||||
hooks = new CopyOnWriteArrayList<>();
|
||||
}
|
||||
|
||||
@@ -113,7 +125,7 @@ class ContactManagerImpl implements ContactManager {
|
||||
return REMOTE_CONTACT_LINK;
|
||||
}
|
||||
|
||||
// TODO remove
|
||||
// TODO replace with real implementation
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
private static String getRandomBase32String(int length) {
|
||||
Random random = new Random();
|
||||
@@ -134,23 +146,78 @@ class ContactManagerImpl implements ContactManager {
|
||||
@Override
|
||||
public void addRemoteContactRequest(String link, String alias) {
|
||||
// TODO replace with real implementation
|
||||
PendingContactId id = new PendingContactId(
|
||||
link.substring(0, PendingContactId.LENGTH).getBytes());
|
||||
PendingContact pendingContact =
|
||||
new PendingContact(id, new byte[MAX_PUBLIC_KEY_LENGTH],
|
||||
alias, WAITING_FOR_CONNECTION, currentTimeMillis());
|
||||
dbExecutor.execute(() -> {
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
Thread.sleep(1500);
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
PendingContactId id = new PendingContactId(link.getBytes());
|
||||
PendingContact pendingContact =
|
||||
new PendingContact(id, new byte[MAX_PUBLIC_KEY_LENGTH],
|
||||
alias, WAITING_FOR_CONNECTION, currentTimeMillis());
|
||||
pendingContacts.add(pendingContact);
|
||||
Event e = new PendingContactStateChangedEvent(id,
|
||||
WAITING_FOR_CONNECTION);
|
||||
try {
|
||||
getLogger("TMP").warning("WAITING_FOR_CONNECTION");
|
||||
pendingContacts.add(pendingContact);
|
||||
Event e = new PendingContactStateChangedEvent(id,
|
||||
WAITING_FOR_CONNECTION);
|
||||
db.transaction(true, txn -> txn.attach(e));
|
||||
} catch (DbException ignored) {
|
||||
}
|
||||
});
|
||||
|
||||
scheduler.schedule(() -> dbExecutor.execute(() -> {
|
||||
getLogger("TMP").warning("CONNECTED");
|
||||
pendingContacts.remove(pendingContact);
|
||||
PendingContact updated = new PendingContact(id,
|
||||
pendingContact.getPublicKey(), alias, CONNECTED,
|
||||
pendingContact.getTimestamp());
|
||||
pendingContacts.add(updated);
|
||||
Event e = new PendingContactStateChangedEvent(id, CONNECTED);
|
||||
try {
|
||||
db.transaction(true, txn -> txn.attach(e));
|
||||
} catch (DbException ignored) {
|
||||
}
|
||||
}), 20, SECONDS);
|
||||
|
||||
scheduler.schedule(() -> dbExecutor.execute(() -> {
|
||||
getLogger("TMP").warning("ADDING_CONTACT");
|
||||
pendingContacts.remove(pendingContact);
|
||||
PendingContact updated = new PendingContact(id,
|
||||
pendingContact.getPublicKey(), alias, ADDING_CONTACT,
|
||||
pendingContact.getTimestamp());
|
||||
pendingContacts.add(updated);
|
||||
Event e =
|
||||
new PendingContactStateChangedEvent(id, ADDING_CONTACT);
|
||||
try {
|
||||
db.transaction(true, txn -> txn.attach(e));
|
||||
} catch (DbException ignored) {
|
||||
}
|
||||
}), 40, SECONDS);
|
||||
|
||||
scheduler.schedule(() -> dbExecutor.execute(() -> {
|
||||
pendingContacts.remove(pendingContact);
|
||||
Event e;
|
||||
try {
|
||||
if (true || new Random().nextBoolean()) {
|
||||
getLogger("TMP").warning("FAILED");
|
||||
e = new PendingContactStateChangedEvent(id, FAILED);
|
||||
PendingContact updated = new PendingContact(id,
|
||||
pendingContact.getPublicKey(), alias, FAILED,
|
||||
pendingContact.getTimestamp());
|
||||
pendingContacts.add(updated);
|
||||
} else {
|
||||
getLogger("TMP").warning("ADDED");
|
||||
ContactId cid = new ContactId(Integer.MAX_VALUE);
|
||||
AuthorId aid = identityManager.getLocalAuthor().getId();
|
||||
Contact c = new Contact(cid, null, aid, alias,
|
||||
new byte[MAX_PUBLIC_KEY_LENGTH], true);
|
||||
e = new ContactAddedRemotelyEvent(c);
|
||||
}
|
||||
db.transaction(true, txn -> txn.attach(e));
|
||||
} catch (DbException ignored) {
|
||||
}
|
||||
}), 60, SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.junit.Test;
|
||||
import java.util.Collection;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.singletonList;
|
||||
@@ -59,8 +60,10 @@ public class ContactManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
public ContactManagerImplTest() {
|
||||
Executor dbExecutor = new ImmediateExecutor();
|
||||
ScheduledExecutorService scheduler =
|
||||
context.mock(ScheduledExecutorService.class);
|
||||
contactManager = new ContactManagerImpl(db, dbExecutor, keyManager,
|
||||
identityManager);
|
||||
identityManager, scheduler);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -13,17 +13,12 @@ import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
|
||||
@NotNullByDefault
|
||||
public class AddContactViewModel extends AndroidViewModel {
|
||||
|
||||
private static Logger LOG = getLogger(AddContactViewModel.class.getName());
|
||||
|
||||
private final ContactManager contactManager;
|
||||
@DatabaseExecutor
|
||||
private final Executor dbExecutor;
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.briarproject.briar.android.contact.add.remote;
|
||||
|
||||
import org.briarproject.bramble.api.contact.PendingContact;
|
||||
|
||||
interface PendingContactListener {
|
||||
|
||||
void onFailedPendingContactRemoved(PendingContact pendingContact);
|
||||
|
||||
}
|
||||
@@ -1,18 +1,13 @@
|
||||
package org.briarproject.briar.android.contact.add.remote;
|
||||
|
||||
import android.arch.lifecycle.ViewModelProvider;
|
||||
import android.arch.lifecycle.ViewModelProviders;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import org.briarproject.bramble.api.contact.Contact;
|
||||
import org.briarproject.bramble.api.contact.ContactManager;
|
||||
import org.briarproject.bramble.api.contact.PendingContact;
|
||||
import org.briarproject.bramble.api.contact.event.ContactAddedEvent;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.event.EventListener;
|
||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||
import org.briarproject.briar.R;
|
||||
@@ -28,13 +23,12 @@ import javax.inject.Inject;
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
public class PendingRequestsActivity extends BriarActivity
|
||||
implements EventListener {
|
||||
implements PendingContactListener {
|
||||
|
||||
@Inject
|
||||
ContactManager contactManager;
|
||||
@Inject
|
||||
EventBus eventBus;
|
||||
ViewModelProvider.Factory viewModelFactory;
|
||||
|
||||
private PendingRequestsViewModel viewModel;
|
||||
private PendingRequestsAdapter adapter;
|
||||
private BriarRecyclerView list;
|
||||
|
||||
@@ -54,33 +48,29 @@ public class PendingRequestsActivity extends BriarActivity
|
||||
ab.setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
adapter = new PendingRequestsAdapter(this, PendingContact.class);
|
||||
viewModel = ViewModelProviders.of(this, viewModelFactory)
|
||||
.get(PendingRequestsViewModel.class);
|
||||
viewModel.getPendingContacts()
|
||||
.observe(this, this::onPendingContactsChanged);
|
||||
|
||||
adapter = new PendingRequestsAdapter(this, this, PendingContact.class);
|
||||
list = findViewById(R.id.list);
|
||||
list.setEmptyText(R.string.no_pending_contacts);
|
||||
list.setLayoutManager(new LinearLayoutManager(this));
|
||||
list.setAdapter(adapter);
|
||||
list.showProgressBar();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
eventBus.addListener(this);
|
||||
list.startPeriodicUpdate();
|
||||
runOnDbThread(() -> {
|
||||
try {
|
||||
Collection<PendingContact> contacts =
|
||||
contactManager.getPendingContacts();
|
||||
addPendingContacts(contacts);
|
||||
} catch (DbException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
list.stopPeriodicUpdate();
|
||||
adapter.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -95,31 +85,23 @@ public class PendingRequestsActivity extends BriarActivity
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eventOccurred(Event e) {
|
||||
if (e instanceof ContactAddedEvent) {
|
||||
runOnDbThread(() -> {
|
||||
try {
|
||||
Contact contact = contactManager
|
||||
.getContact(((ContactAddedEvent) e).getContactId());
|
||||
runOnUiThreadUnlessDestroyed(() -> {
|
||||
adapter.remove(contact);
|
||||
if (adapter.isEmpty()) finish();
|
||||
});
|
||||
} catch (DbException e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
});
|
||||
public void onFailedPendingContactRemoved(PendingContact pendingContact) {
|
||||
adapter.remove(pendingContact);
|
||||
viewModel.removePendingContact(pendingContact);
|
||||
}
|
||||
|
||||
private void onPendingContactsChanged(Collection<PendingContact> contacts) {
|
||||
if (contacts.isEmpty()) {
|
||||
if (!adapter.isEmpty()) {
|
||||
// all previous contacts have been removed, so we can finish
|
||||
supportFinishAfterTransition();
|
||||
} else {
|
||||
adapter.clear();
|
||||
list.showData();
|
||||
}
|
||||
} else {
|
||||
adapter.setItems(contacts);
|
||||
}
|
||||
}
|
||||
|
||||
private void addPendingContacts(Collection<PendingContact> contacts) {
|
||||
runOnUiThreadUnlessDestroyed(() -> {
|
||||
if (contacts.isEmpty()) {
|
||||
list.showData();
|
||||
} else {
|
||||
adapter.addAll(contacts);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import org.briarproject.bramble.api.contact.Contact;
|
||||
import org.briarproject.bramble.api.contact.PendingContact;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.briar.R;
|
||||
@@ -15,8 +14,12 @@ import org.briarproject.briar.android.util.BriarAdapter;
|
||||
public class PendingRequestsAdapter extends
|
||||
BriarAdapter<PendingContact, PendingRequestsViewHolder> {
|
||||
|
||||
public PendingRequestsAdapter(Context ctx, Class<PendingContact> c) {
|
||||
private final PendingContactListener listener;
|
||||
|
||||
public PendingRequestsAdapter(Context ctx, PendingContactListener listener,
|
||||
Class<PendingContact> c) {
|
||||
super(ctx, c);
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -24,7 +27,7 @@ public class PendingRequestsAdapter extends
|
||||
ViewGroup viewGroup, int i) {
|
||||
View v = LayoutInflater.from(viewGroup.getContext()).inflate(
|
||||
R.layout.list_item_pending_contact, viewGroup, false);
|
||||
return new PendingRequestsViewHolder(v);
|
||||
return new PendingRequestsViewHolder(v, listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -52,14 +55,4 @@ public class PendingRequestsAdapter extends
|
||||
item1.getTimestamp() == item2.getTimestamp();
|
||||
}
|
||||
|
||||
// TODO use PendingContactId
|
||||
public void remove(Contact contact) {
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
if (items.get(i).getAlias().equals(contact.getAuthor().getName())) {
|
||||
items.removeItemAt(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.briarproject.briar.android.contact.add.remote;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.widget.RecyclerView.ViewHolder;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.briarproject.bramble.api.contact.PendingContact;
|
||||
@@ -10,33 +11,41 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.view.TextAvatarView;
|
||||
|
||||
import static org.briarproject.bramble.util.StringUtils.toUtf8;
|
||||
import static android.view.View.GONE;
|
||||
import static android.view.View.VISIBLE;
|
||||
import static org.briarproject.briar.android.util.UiUtils.formatDate;
|
||||
|
||||
@NotNullByDefault
|
||||
public class PendingRequestsViewHolder extends ViewHolder {
|
||||
|
||||
private final PendingContactListener listener;
|
||||
private final TextAvatarView avatar;
|
||||
private final TextView name;
|
||||
private final TextView time;
|
||||
private final TextView status;
|
||||
private final Button button;
|
||||
|
||||
public PendingRequestsViewHolder(View v) {
|
||||
public PendingRequestsViewHolder(View v, PendingContactListener listener) {
|
||||
super(v);
|
||||
avatar = v.findViewById(R.id.avatar);
|
||||
name = v.findViewById(R.id.name);
|
||||
time = v.findViewById(R.id.time);
|
||||
status = v.findViewById(R.id.status);
|
||||
button = v.findViewById(R.id.button);
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public void bind(PendingContact item) {
|
||||
avatar.setText(item.getAlias());
|
||||
avatar.setBackgroundBytes(toUtf8(item.getAlias() + item.getTimestamp()));
|
||||
avatar.setBackgroundBytes(item.getId().getBytes());
|
||||
name.setText(item.getAlias());
|
||||
time.setText(formatDate(time.getContext(), item.getTimestamp()));
|
||||
button.setOnClickListener(
|
||||
v -> listener.onFailedPendingContactRemoved(item));
|
||||
|
||||
int color = ContextCompat
|
||||
.getColor(status.getContext(), R.color.briar_green);
|
||||
int buttonVisibility = GONE;
|
||||
switch (item.getState()) {
|
||||
case WAITING_FOR_CONNECTION:
|
||||
color = ContextCompat
|
||||
@@ -50,15 +59,16 @@ public class PendingRequestsViewHolder extends ViewHolder {
|
||||
status.setText(R.string.adding_contact);
|
||||
break;
|
||||
case FAILED:
|
||||
// TODO add remove button
|
||||
color = ContextCompat
|
||||
.getColor(status.getContext(), R.color.briar_red);
|
||||
status.setText(R.string.adding_contact_failed);
|
||||
buttonVisibility = VISIBLE;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
status.setTextColor(color);
|
||||
button.setVisibility(buttonVisibility);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
package org.briarproject.briar.android.contact.add.remote;
|
||||
|
||||
import android.app.Application;
|
||||
import android.arch.lifecycle.AndroidViewModel;
|
||||
import android.arch.lifecycle.LiveData;
|
||||
import android.arch.lifecycle.MutableLiveData;
|
||||
|
||||
import org.briarproject.bramble.api.contact.ContactManager;
|
||||
import org.briarproject.bramble.api.contact.PendingContact;
|
||||
import org.briarproject.bramble.api.contact.event.ContactAddedRemotelyEvent;
|
||||
import org.briarproject.bramble.api.contact.event.PendingContactStateChangedEvent;
|
||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||
import org.briarproject.bramble.api.db.DbException;
|
||||
import org.briarproject.bramble.api.event.Event;
|
||||
import org.briarproject.bramble.api.event.EventBus;
|
||||
import org.briarproject.bramble.api.event.EventListener;
|
||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static java.util.logging.Logger.getLogger;
|
||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||
|
||||
@NotNullByDefault
|
||||
public class PendingRequestsViewModel extends AndroidViewModel
|
||||
implements EventListener {
|
||||
|
||||
private final Logger LOG =
|
||||
getLogger(PendingRequestsViewModel.class.getName());
|
||||
|
||||
@DatabaseExecutor
|
||||
private final Executor dbExecutor;
|
||||
private final ContactManager contactManager;
|
||||
private final EventBus eventBus;
|
||||
|
||||
private final MutableLiveData<Collection<PendingContact>> pendingContacts =
|
||||
new MutableLiveData<>();
|
||||
|
||||
@Inject
|
||||
public PendingRequestsViewModel(Application application,
|
||||
@DatabaseExecutor Executor dbExecutor,
|
||||
ContactManager contactManager, EventBus eventBus) {
|
||||
super(application);
|
||||
this.dbExecutor = dbExecutor;
|
||||
this.contactManager = contactManager;
|
||||
this.eventBus = eventBus;
|
||||
this.eventBus.addListener(this);
|
||||
loadPendingContacts();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCleared() {
|
||||
super.onCleared();
|
||||
eventBus.removeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eventOccurred(Event e) {
|
||||
if (e instanceof ContactAddedRemotelyEvent ||
|
||||
e instanceof PendingContactStateChangedEvent) {
|
||||
loadPendingContacts();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadPendingContacts() {
|
||||
dbExecutor.execute(() -> {
|
||||
try {
|
||||
pendingContacts.postValue(contactManager.getPendingContacts());
|
||||
} catch (DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
LiveData<Collection<PendingContact>> getPendingContacts() {
|
||||
return pendingContacts;
|
||||
}
|
||||
|
||||
void removePendingContact(PendingContact pendingContact) {
|
||||
dbExecutor.execute(() -> {
|
||||
try {
|
||||
contactManager.removePendingContact(pendingContact);
|
||||
} catch (DbException e) {
|
||||
logException(LOG, WARNING, e);
|
||||
}
|
||||
});
|
||||
loadPendingContacts();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import android.arch.lifecycle.ViewModel;
|
||||
import android.arch.lifecycle.ViewModelProvider;
|
||||
|
||||
import org.briarproject.briar.android.contact.add.remote.AddContactViewModel;
|
||||
import org.briarproject.briar.android.contact.add.remote.PendingRequestsViewModel;
|
||||
import org.briarproject.briar.android.conversation.ConversationViewModel;
|
||||
import org.briarproject.briar.android.conversation.ImageViewModel;
|
||||
|
||||
@@ -34,6 +35,12 @@ public abstract class ViewModelModule {
|
||||
abstract ViewModel bindAddContactViewModel(
|
||||
AddContactViewModel addContactViewModel);
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ViewModelKey(PendingRequestsViewModel.class)
|
||||
abstract ViewModel bindPendingRequestsViewModel(
|
||||
PendingRequestsViewModel pendingRequestsViewModel);
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
abstract ViewModelProvider.Factory bindViewModelFactory(
|
||||
|
||||
@@ -147,6 +147,7 @@
|
||||
android:text="@string/share_button"
|
||||
app:layout_constraintBottom_toBottomOf="@id/copyButton"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="1.0"
|
||||
app:layout_constraintStart_toEndOf="@id/copyButton"
|
||||
app:layout_constraintTop_toTopOf="@id/copyButton"/>
|
||||
|
||||
|
||||
@@ -11,11 +11,10 @@
|
||||
android:id="@+id/avatar"
|
||||
android:layout_width="@dimen/listitem_picture_frame_size"
|
||||
android:layout_height="@dimen/listitem_picture_frame_size"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginBottom="@dimen/listitem_horizontal_margin"
|
||||
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
|
||||
android:layout_marginStart="@dimen/listitem_horizontal_margin"
|
||||
android:layout_marginTop="8dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/divider"
|
||||
android:layout_marginTop="@dimen/listitem_horizontal_margin"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
@@ -47,37 +46,49 @@
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/waiting_for_contact_to_come_online"
|
||||
android:text="@string/adding_contact_failed"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintBottom_toTopOf="@+id/divider"
|
||||
app:layout_constraintEnd_toStartOf="@+id/time"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toStartOf="@+id/name"
|
||||
app:layout_constraintTop_toBottomOf="@+id/name"/>
|
||||
app:layout_constraintTop_toBottomOf="@+id/name"
|
||||
tools:textColor="@color/briar_red"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/time"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/margin_large"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="@dimen/text_size_small"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/status"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/name"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/name"
|
||||
tools:text="Dec 24"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/button"
|
||||
style="@style/BriarButtonFlat.Negative"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/groups_remove"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="@+id/time"
|
||||
app:layout_constraintHorizontal_bias="1.0"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/status"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
style="@style/Divider.ContactList"
|
||||
android:layout_width="0dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/avatar"/>
|
||||
app:layout_constraintStart_toEndOf="@+id/avatar"
|
||||
app:layout_constraintTop_toBottomOf="@+id/button"
|
||||
app:layout_goneMarginTop="@dimen/margin_large"/>
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
|
||||
@@ -192,11 +192,12 @@
|
||||
<string name="link_copied_toast">Link copied</string>
|
||||
<string name="pending_contact_requests_snackbar">"There are pending contact requests"</string>
|
||||
<string name="pending_contact_requests">Pending contact requests</string>
|
||||
<string name="no_pending_contacts">No pending contacts</string>
|
||||
<string name="add_contact_remote_connecting">Connecting…</string>
|
||||
<string name="scan_qr_code_title">Scan QR Code</string>
|
||||
<string name="show_qr_code_title">Your QR Code</string>
|
||||
<string name="camera_error_toast">Camera Error</string>
|
||||
<string name="waiting_for_contact_to_come_online">Waiting for contact to come online…</string>
|
||||
<string name="waiting_for_contact_to_come_online">Waiting for contact to come online…\n\nDid they enter your link already?</string>
|
||||
<string name="connecting">Connecting…</string>
|
||||
<string name="adding_contact">Adding contact…</string>
|
||||
<string name="adding_contact_failed">Adding contact has failed</string>
|
||||
|
||||
Reference in New Issue
Block a user