From 6e57d7bb4215d33536d4bc79c7bea8fd4043a22e Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Tue, 24 Nov 2020 16:03:00 -0300 Subject: [PATCH] Show avatars for contacts outside AuthorView --- .../briar/android/contact/ContactItem.java | 14 +++++-- .../contact/ContactItemViewHolder.java | 5 +-- .../android/contact/ContactListFragment.java | 11 +++++ .../android/contact/ContactListItem.java | 19 ++++----- .../android/contact/ContactListViewModel.java | 8 +++- .../ContactSelectorControllerImpl.java | 12 ++++-- .../SelectableContactItem.java | 10 +++-- .../conversation/AliasDialogFragment.java | 6 +-- .../conversation/ConversationActivity.java | 13 +++--- .../conversation/ConversationViewModel.java | 33 +++++++-------- .../introduction/ContactChooserFragment.java | 10 ++++- .../IntroductionMessageFragment.java | 40 ++++++++++++------- .../creation/CreateGroupControllerImpl.java | 7 ++-- .../reveal/RevealContactsControllerImpl.java | 12 ++++-- .../reveal/RevealableContactItem.java | 7 ++-- .../sharing/ShareBlogControllerImpl.java | 4 +- .../sharing/ShareForumControllerImpl.java | 4 +- .../sharing/SharingStatusActivity.java | 7 +++- .../briar/android/view/AuthorView.java | 32 ++++++++------- .../main/res/layout/introduction_message.xml | 4 +- briar-android/src/main/res/values/dimens.xml | 2 +- .../briar/api/identity/AuthorManager.java | 12 ++++++ .../briar/identity/AuthorManagerImpl.java | 11 +++++ 23 files changed, 189 insertions(+), 94 deletions(-) diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactItem.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactItem.java index 25d2f2806..803eb5d73 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactItem.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactItem.java @@ -2,6 +2,7 @@ package org.briarproject.briar.android.contact; import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.briar.api.identity.AuthorInfo; import javax.annotation.concurrent.Immutable; @@ -10,14 +11,17 @@ import javax.annotation.concurrent.Immutable; public class ContactItem { private final Contact contact; + private final AuthorInfo authorInfo; private final boolean connected; - public ContactItem(Contact contact) { - this(contact, false); + public ContactItem(Contact contact, AuthorInfo authorInfo) { + this(contact, authorInfo, false); } - public ContactItem(Contact contact, boolean connected) { + public ContactItem(Contact contact, AuthorInfo authorInfo, + boolean connected) { this.contact = contact; + this.authorInfo = authorInfo; this.connected = connected; } @@ -25,6 +29,10 @@ public class ContactItem { return contact; } + public AuthorInfo getAuthorInfo() { + return authorInfo; + } + boolean isConnected() { return connected; } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactItemViewHolder.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactItemViewHolder.java index 154287f47..4ac4db90f 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactItemViewHolder.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactItemViewHolder.java @@ -14,9 +14,9 @@ import javax.annotation.Nullable; import androidx.annotation.UiThread; import androidx.recyclerview.widget.RecyclerView; -import im.delight.android.identicons.IdenticonDrawable; import static org.briarproject.briar.android.util.UiUtils.getContactDisplayName; +import static org.briarproject.briar.android.view.AuthorView.setAvatar; @UiThread @NotNullByDefault @@ -41,8 +41,7 @@ public class ContactItemViewHolder protected void bind(I item, @Nullable OnContactClickListener listener) { Author author = item.getContact().getAuthor(); - avatar.setImageDrawable( - new IdenticonDrawable(author.getId().getBytes())); + setAvatar(avatar, author.getId(), item.getAuthorInfo()); name.setText(getContactDisplayName(item.getContact())); if (bulb != null) { diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java index 1a803c9a6..c0bdd447a 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java @@ -23,6 +23,17 @@ import org.briarproject.briar.android.fragment.BaseFragment; import org.briarproject.briar.android.keyagreement.ContactExchangeActivity; import org.briarproject.briar.android.util.BriarSnackbarBuilder; import org.briarproject.briar.android.view.BriarRecyclerView; +import org.briarproject.briar.api.android.AndroidNotificationManager; +import org.briarproject.briar.api.client.MessageTracker.GroupCount; +import org.briarproject.briar.api.conversation.ConversationManager; +import org.briarproject.briar.api.conversation.ConversationMessageHeader; +import org.briarproject.briar.api.conversation.event.ConversationMessageReceivedEvent; +import org.briarproject.briar.api.identity.AuthorInfo; +import org.briarproject.briar.api.identity.AuthorManager; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; import javax.annotation.Nullable; import javax.inject.Inject; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListItem.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListItem.java index d674f5295..0cad1f26c 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListItem.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListItem.java @@ -4,6 +4,7 @@ import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.briar.api.client.MessageTracker.GroupCount; import org.briarproject.briar.api.conversation.ConversationMessageHeader; +import org.briarproject.briar.api.identity.AuthorInfo; import javax.annotation.concurrent.Immutable; @@ -16,29 +17,29 @@ public class ContactListItem extends ContactItem private final long timestamp; private final int unread; - public ContactListItem(Contact contact, boolean connected, - GroupCount count) { - super(contact, connected); + public ContactListItem(Contact contact, AuthorInfo authorInfo, + boolean connected, GroupCount count) { + super(contact, authorInfo, connected); this.empty = count.getMsgCount() == 0; this.unread = count.getUnreadCount(); this.timestamp = count.getLatestMsgTime(); } - private ContactListItem(Contact contact, boolean connected, boolean empty, - int unread, long timestamp) { - super(contact, connected); + private ContactListItem(Contact contact, AuthorInfo authorInfo, + boolean connected, boolean empty, int unread, long timestamp) { + super(contact, authorInfo, connected); this.empty = empty; this.timestamp = timestamp; this.unread = unread; } ContactListItem(ContactListItem item, boolean connected) { - this(item.getContact(), connected, item.empty, item.unread, - item.timestamp); + this(item.getContact(), item.getAuthorInfo(), connected, item.empty, + item.unread, item.timestamp); } ContactListItem(ContactListItem item, ConversationMessageHeader h) { - this(item.getContact(), item.isConnected(), false, + this(item.getContact(), item.getAuthorInfo(), item.isConnected(), false, h.isRead() ? item.unread : item.unread + 1, Math.max(h.getTimestamp(), item.timestamp)); } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListViewModel.java index 729a4bdd8..28239d261 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListViewModel.java @@ -29,6 +29,8 @@ import org.briarproject.briar.api.client.MessageTracker; import org.briarproject.briar.api.conversation.ConversationManager; import org.briarproject.briar.api.conversation.ConversationMessageHeader; import org.briarproject.briar.api.conversation.event.ConversationMessageReceivedEvent; +import org.briarproject.briar.api.identity.AuthorInfo; +import org.briarproject.briar.api.identity.AuthorManager; import java.util.ArrayList; import java.util.Collections; @@ -55,6 +57,7 @@ class ContactListViewModel extends DbViewModel implements EventListener { getLogger(ContactListViewModel.class.getName()); private final ContactManager contactManager; + private final AuthorManager authorManager; private final ConversationManager conversationManager; private final ConnectionRegistry connectionRegistry; private final EventBus eventBus; @@ -71,11 +74,13 @@ class ContactListViewModel extends DbViewModel implements EventListener { @DatabaseExecutor Executor dbExecutor, LifecycleManager lifecycleManager, TransactionManager db, AndroidExecutor androidExecutor, ContactManager contactManager, + AuthorManager authorManager, ConversationManager conversationManager, ConnectionRegistry connectionRegistry, EventBus eventBus, AndroidNotificationManager notificationManager) { super(application, dbExecutor, lifecycleManager, db, androidExecutor); this.contactManager = contactManager; + this.authorManager = authorManager; this.conversationManager = conversationManager; this.connectionRegistry = connectionRegistry; this.eventBus = eventBus; @@ -99,10 +104,11 @@ class ContactListViewModel extends DbViewModel implements EventListener { List contacts = new ArrayList<>(); for (Contact c : contactManager.getContacts(txn)) { ContactId id = c.getId(); + AuthorInfo authorInfo = authorManager.getAuthorInfo(txn, c); MessageTracker.GroupCount count = conversationManager.getGroupCount(txn, id); boolean connected = connectionRegistry.isConnected(c.getId()); - contacts.add(new ContactListItem(c, connected, count)); + contacts.add(new ContactListItem(c, authorInfo, connected, count)); } Collections.sort(contacts); logDuration(LOG, "Full load", start); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contactselection/ContactSelectorControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/contactselection/ContactSelectorControllerImpl.java index 434d3b603..da25fbda3 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/contactselection/ContactSelectorControllerImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/contactselection/ContactSelectorControllerImpl.java @@ -10,6 +10,8 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.briar.android.controller.DbControllerImpl; import org.briarproject.briar.android.controller.handler.ResultExceptionHandler; +import org.briarproject.briar.api.identity.AuthorInfo; +import org.briarproject.briar.api.identity.AuthorManager; import java.util.ArrayList; import java.util.Collection; @@ -31,11 +33,14 @@ public abstract class ContactSelectorControllerImpl Logger.getLogger(ContactSelectorControllerImpl.class.getName()); private final ContactManager contactManager; + private final AuthorManager authorManager; public ContactSelectorControllerImpl(@DatabaseExecutor Executor dbExecutor, - LifecycleManager lifecycleManager, ContactManager contactManager) { + LifecycleManager lifecycleManager, ContactManager contactManager, + AuthorManager authorManager) { super(dbExecutor, lifecycleManager); this.contactManager = contactManager; + this.authorManager = authorManager; } @Override @@ -45,12 +50,13 @@ public abstract class ContactSelectorControllerImpl try { Collection contacts = new ArrayList<>(); for (Contact c : contactManager.getContacts()) { + AuthorInfo authorInfo = authorManager.getAuthorInfo(c); // was this contact already selected? boolean selected = selection.contains(c.getId()); // can this contact be selected? boolean disabled = isDisabled(g, c); - contacts.add(new SelectableContactItem(c, selected, - disabled)); + contacts.add(new SelectableContactItem(c, authorInfo, + selected, disabled)); } handler.onResult(contacts); } catch (DbException e) { diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contactselection/SelectableContactItem.java b/briar-android/src/main/java/org/briarproject/briar/android/contactselection/SelectableContactItem.java index d2a53a2a4..a3d09f8ce 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/contactselection/SelectableContactItem.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/contactselection/SelectableContactItem.java @@ -3,6 +3,7 @@ package org.briarproject.briar.android.contactselection; import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.briar.android.contact.ContactItem; +import org.briarproject.briar.api.identity.AuthorInfo; import javax.annotation.concurrent.NotThreadSafe; @@ -10,11 +11,12 @@ import javax.annotation.concurrent.NotThreadSafe; @NotNullByDefault public class SelectableContactItem extends ContactItem { - private boolean selected, disabled; + private boolean selected; + private final boolean disabled; - public SelectableContactItem(Contact contact, boolean selected, - boolean disabled) { - super(contact); + public SelectableContactItem(Contact contact, AuthorInfo authorInfo, + boolean selected, boolean disabled) { + super(contact, authorInfo); this.selected = selected; this.disabled = disabled; } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/conversation/AliasDialogFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/conversation/AliasDialogFragment.java index 4144ca31d..30df0ecad 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/conversation/AliasDialogFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/conversation/AliasDialogFragment.java @@ -21,7 +21,6 @@ import javax.inject.Inject; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatDialogFragment; import androidx.lifecycle.ViewModelProvider; -import androidx.lifecycle.ViewModelProviders; import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE; import static java.util.Objects.requireNonNull; @@ -59,7 +58,7 @@ public class AliasDialogFragment extends AppCompatDialogFragment { setStyle(STYLE_NO_TITLE, R.style.BriarDialogTheme); - viewModel = ViewModelProviders.of(requireActivity(), viewModelFactory) + viewModel = new ViewModelProvider(requireActivity(), viewModelFactory) .get(ConversationViewModel.class); } @@ -72,7 +71,8 @@ public class AliasDialogFragment extends AppCompatDialogFragment { aliasEditLayout = v.findViewById(R.id.aliasEditLayout); aliasEditText = v.findViewById(R.id.aliasEditText); - Contact contact = requireNonNull(viewModel.getContact().getValue()); + Contact contact = requireNonNull(viewModel.getContactItem().getValue()) + .getContact(); String alias = contact.getAlias(); aliasEditText.setText(alias); if (alias != null) aliasEditText.setSelection(alias.length()); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationActivity.java index 481aa7683..72faf405b 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationActivity.java @@ -31,6 +31,7 @@ import org.briarproject.bramble.api.db.NoSuchContactException; 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.identity.AuthorId; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.bramble.api.plugin.event.ContactConnectedEvent; @@ -106,7 +107,6 @@ import androidx.recyclerview.selection.StorageStrategy; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import de.hdodenhof.circleimageview.CircleImageView; -import im.delight.android.identicons.IdenticonDrawable; import uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt; import static android.os.Build.VERSION.SDK_INT; @@ -134,6 +134,7 @@ import static org.briarproject.briar.android.conversation.ImageActivity.DATE; import static org.briarproject.briar.android.conversation.ImageActivity.ITEM_ID; import static org.briarproject.briar.android.conversation.ImageActivity.NAME; import static org.briarproject.briar.android.util.UiUtils.observeOnce; +import static org.briarproject.briar.android.view.AuthorView.setAvatar; import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_ATTACHMENTS_PER_MESSAGE; import static org.briarproject.briar.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_TEXT_LENGTH; @@ -233,10 +234,10 @@ public class ConversationActivity extends BriarActivity toolbarStatus = toolbar.findViewById(R.id.contactStatus); toolbarTitle = toolbar.findViewById(R.id.contactName); - observeOnce(viewModel.getContactAuthorId(), this, authorId -> { - requireNonNull(authorId); - toolbarAvatar.setImageDrawable( - new IdenticonDrawable(authorId.getBytes())); + observeOnce(viewModel.getContactItem(), this, c -> { + requireNonNull(c); + AuthorId authorId = c.getContact().getAuthor().getId(); + setAvatar(toolbarAvatar, authorId, c.getAuthorInfo()); }); viewModel.getContactDisplayName().observe(this, contactName -> { requireNonNull(contactName); @@ -366,7 +367,7 @@ public class ConversationActivity extends BriarActivity } }); // enable alias action if available - observeOnce(viewModel.getContact(), this, contact -> + observeOnce(viewModel.getContactItem(), this, contact -> menu.findItem(R.id.action_set_alias).setEnabled(true)); return super.onCreateOptionsMenu(menu); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationViewModel.java index abcc55a40..47b0230b2 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/conversation/ConversationViewModel.java @@ -14,7 +14,6 @@ import org.briarproject.bramble.api.db.TransactionManager; 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.identity.AuthorId; import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.settings.Settings; @@ -27,10 +26,13 @@ import org.briarproject.briar.android.attachment.AttachmentCreator; import org.briarproject.briar.android.attachment.AttachmentManager; import org.briarproject.briar.android.attachment.AttachmentResult; import org.briarproject.briar.android.attachment.AttachmentRetriever; +import org.briarproject.briar.android.contact.ContactItem; import org.briarproject.briar.android.util.UiUtils; import org.briarproject.briar.android.viewmodel.DbViewModel; import org.briarproject.briar.android.viewmodel.LiveEvent; import org.briarproject.briar.android.viewmodel.MutableLiveEvent; +import org.briarproject.briar.api.identity.AuthorInfo; +import org.briarproject.briar.api.identity.AuthorManager; import org.briarproject.briar.api.media.AttachmentHeader; import org.briarproject.briar.api.messaging.MessagingManager; import org.briarproject.briar.api.messaging.PrivateMessage; @@ -49,8 +51,8 @@ import androidx.annotation.Nullable; import androidx.annotation.UiThread; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; -import androidx.lifecycle.Transformations; +import static androidx.lifecycle.Transformations.map; import static java.util.Objects.requireNonNull; import static java.util.logging.Level.WARNING; import static java.util.logging.Logger.getLogger; @@ -76,6 +78,7 @@ public class ConversationViewModel extends DbViewModel private final EventBus eventBus; private final MessagingManager messagingManager; private final ContactManager contactManager; + private final AuthorManager authorManager; private final SettingsManager settingsManager; private final PrivateMessageFactory privateMessageFactory; private final AttachmentRetriever attachmentRetriever; @@ -83,11 +86,10 @@ public class ConversationViewModel extends DbViewModel @Nullable private ContactId contactId = null; - private final MutableLiveData contact = new MutableLiveData<>(); - private final LiveData contactAuthorId = - Transformations.map(contact, c -> c.getAuthor().getId()); - private final LiveData contactName = - Transformations.map(contact, UiUtils::getContactDisplayName); + private final MutableLiveData contactItem = + new MutableLiveData<>(); + private final LiveData contactName = map(contactItem, c -> + UiUtils.getContactDisplayName(c.getContact())); private final LiveData messagingGroupId; private final MutableLiveData imageSupport = new MutableLiveData<>(); @@ -111,6 +113,7 @@ public class ConversationViewModel extends DbViewModel EventBus eventBus, MessagingManager messagingManager, ContactManager contactManager, + AuthorManager authorManager, SettingsManager settingsManager, PrivateMessageFactory privateMessageFactory, AttachmentRetriever attachmentRetriever, @@ -120,12 +123,13 @@ public class ConversationViewModel extends DbViewModel this.eventBus = eventBus; this.messagingManager = messagingManager; this.contactManager = contactManager; + this.authorManager = authorManager; this.settingsManager = settingsManager; this.privateMessageFactory = privateMessageFactory; this.attachmentRetriever = attachmentRetriever; this.attachmentCreator = attachmentCreator; - messagingGroupId = Transformations - .map(contact, c -> messagingManager.getContactGroup(c).getId()); + messagingGroupId = map(contactItem, c -> + messagingManager.getContactGroup(c.getContact()).getId()); contactDeleted.setValue(false); eventBus.addListener(this); @@ -168,7 +172,8 @@ public class ConversationViewModel extends DbViewModel try { long start = now(); Contact c = contactManager.getContact(contactId); - contact.postValue(c); + AuthorInfo authorInfo = authorManager.getAuthorInfo(c); + contactItem.postValue(new ContactItem(c, authorInfo)); logDuration(LOG, "Loading contact", start); start = now(); checkFeaturesAndOnboarding(contactId); @@ -319,12 +324,8 @@ public class ConversationViewModel extends DbViewModel return attachmentRetriever; } - LiveData getContact() { - return contact; - } - - LiveData getContactAuthorId() { - return contactAuthorId; + LiveData getContactItem() { + return contactItem; } LiveData getContactDisplayName() { diff --git a/briar-android/src/main/java/org/briarproject/briar/android/introduction/ContactChooserFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/introduction/ContactChooserFragment.java index 49e274c97..7a655f2af 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/introduction/ContactChooserFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/introduction/ContactChooserFragment.java @@ -21,6 +21,8 @@ import org.briarproject.briar.android.fragment.BaseFragment; import org.briarproject.briar.android.view.BriarRecyclerView; import org.briarproject.briar.api.client.MessageTracker.GroupCount; import org.briarproject.briar.api.conversation.ConversationManager; +import org.briarproject.briar.api.identity.AuthorInfo; +import org.briarproject.briar.api.identity.AuthorManager; import java.util.ArrayList; import java.util.List; @@ -49,10 +51,12 @@ public class ContactChooserFragment extends BaseFragment { private ContactId contactId; // Fields that are accessed from background threads must be volatile - volatile Contact c1; + private volatile Contact c1; @Inject volatile ContactManager contactManager; @Inject + volatile AuthorManager authorManager; + @Inject volatile ConversationManager conversationManager; @Inject volatile ConnectionRegistry connectionRegistry; @@ -123,12 +127,14 @@ public class ContactChooserFragment extends BaseFragment { if (c.getId().equals(contactId)) { c1 = c; } else { + AuthorInfo authorInfo = authorManager.getAuthorInfo(c); ContactId id = c.getId(); GroupCount count = conversationManager.getGroupCount(id); boolean connected = connectionRegistry.isConnected(c.getId()); - contacts.add(new ContactListItem(c, connected, count)); + contacts.add(new ContactListItem(c, authorInfo, + connected, count)); } } displayContacts(contacts); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/introduction/IntroductionMessageFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/introduction/IntroductionMessageFragment.java index 6321dde14..ad7a0de79 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/introduction/IntroductionMessageFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/introduction/IntroductionMessageFragment.java @@ -18,10 +18,13 @@ import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.briar.R; import org.briarproject.briar.android.activity.ActivityComponent; +import org.briarproject.briar.android.contact.ContactItem; import org.briarproject.briar.android.fragment.BaseFragment; import org.briarproject.briar.android.view.TextInputView; import org.briarproject.briar.android.view.TextSendController; import org.briarproject.briar.android.view.TextSendController.SendListener; +import org.briarproject.briar.api.identity.AuthorInfo; +import org.briarproject.briar.api.identity.AuthorManager; import org.briarproject.briar.api.introduction.IntroductionManager; import org.briarproject.briar.api.media.AttachmentHeader; @@ -33,7 +36,6 @@ import javax.inject.Inject; import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; import de.hdodenhof.circleimageview.CircleImageView; -import im.delight.android.identicons.IdenticonDrawable; import static android.app.Activity.RESULT_OK; import static android.view.View.GONE; @@ -43,6 +45,7 @@ import static java.util.logging.Level.WARNING; import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.briar.android.util.UiUtils.getContactDisplayName; import static org.briarproject.briar.android.util.UiUtils.hideSoftKeyboard; +import static org.briarproject.briar.android.view.AuthorView.setAvatar; import static org.briarproject.briar.api.introduction.IntroductionConstants.MAX_INTRODUCTION_TEXT_LENGTH; @MethodsNotNullByDefault @@ -65,6 +68,8 @@ public class IntroductionMessageFragment extends BaseFragment @Inject protected volatile ContactManager contactManager; @Inject + protected volatile AuthorManager authorManager; + @Inject protected volatile IntroductionManager introductionManager; public static IntroductionMessageFragment newInstance(int contactId1, @@ -137,11 +142,16 @@ public class IntroductionMessageFragment extends BaseFragment private void prepareToSetUpViews(int contactId1, int contactId2) { introductionActivity.runOnDbThread(() -> { try { - Contact c1 = contactManager.getContact( - new ContactId(contactId1)); - Contact c2 = contactManager.getContact( - new ContactId(contactId2)); - boolean possible = introductionManager.canIntroduce(c1, c2); + Contact contact1 = + contactManager.getContact(new ContactId(contactId1)); + Contact contact2 = + contactManager.getContact(new ContactId(contactId2)); + AuthorInfo a1 = authorManager.getAuthorInfo(contact1); + AuthorInfo a2 = authorManager.getAuthorInfo(contact2); + boolean possible = + introductionManager.canIntroduce(contact1, contact2); + ContactItem c1 = new ContactItem(contact1, a1); + ContactItem c2 = new ContactItem(contact2, a2); setUpViews(c1, c2, possible); } catch (DbException e) { logException(LOG, WARNING, e); @@ -149,20 +159,20 @@ public class IntroductionMessageFragment extends BaseFragment }); } - private void setUpViews(Contact c1, Contact c2, boolean possible) { + private void setUpViews(ContactItem c1, ContactItem c2, boolean possible) { introductionActivity.runOnUiThreadUnlessDestroyed(() -> { - contact1 = c1; - contact2 = c2; + contact1 = c1.getContact(); + contact2 = c2.getContact(); // set avatars - ui.avatar1.setImageDrawable(new IdenticonDrawable( - c1.getAuthor().getId().getBytes())); - ui.avatar2.setImageDrawable(new IdenticonDrawable( - c2.getAuthor().getId().getBytes())); + setAvatar(ui.avatar1, c1.getContact().getAuthor().getId(), + c1.getAuthorInfo()); + setAvatar(ui.avatar2, c2.getContact().getAuthor().getId(), + c2.getAuthorInfo()); // set contact names - ui.contactName1.setText(getContactDisplayName(c1)); - ui.contactName2.setText(getContactDisplayName(c2)); + ui.contactName1.setText(getContactDisplayName(c1.getContact())); + ui.contactName2.setText(getContactDisplayName(c2.getContact())); // hide progress bar ui.progressBar.setVisibility(GONE); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/creation/CreateGroupControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/creation/CreateGroupControllerImpl.java index 88355a63b..809f224e6 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/creation/CreateGroupControllerImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/creation/CreateGroupControllerImpl.java @@ -15,6 +15,7 @@ import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.system.Clock; import org.briarproject.briar.android.contactselection.ContactSelectorControllerImpl; import org.briarproject.briar.android.controller.handler.ResultExceptionHandler; +import org.briarproject.briar.api.identity.AuthorManager; import org.briarproject.briar.api.privategroup.GroupMessage; import org.briarproject.briar.api.privategroup.GroupMessageFactory; import org.briarproject.briar.api.privategroup.PrivateGroup; @@ -59,12 +60,13 @@ class CreateGroupControllerImpl extends ContactSelectorControllerImpl CreateGroupControllerImpl(@DatabaseExecutor Executor dbExecutor, @CryptoExecutor Executor cryptoExecutor, LifecycleManager lifecycleManager, ContactManager contactManager, - IdentityManager identityManager, PrivateGroupFactory groupFactory, + AuthorManager authorManager, IdentityManager identityManager, + PrivateGroupFactory groupFactory, GroupMessageFactory groupMessageFactory, PrivateGroupManager groupManager, GroupInvitationFactory groupInvitationFactory, GroupInvitationManager groupInvitationManager, Clock clock) { - super(dbExecutor, lifecycleManager, contactManager); + super(dbExecutor, lifecycleManager, contactManager, authorManager); this.cryptoExecutor = cryptoExecutor; this.contactManager = contactManager; this.identityManager = identityManager; @@ -176,7 +178,6 @@ class CreateGroupControllerImpl extends ContactSelectorControllerImpl // Continue } } - //noinspection ConstantConditions handler.onResult(null); } catch (DbException e) { logException(LOG, WARNING, e); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/reveal/RevealContactsControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/reveal/RevealContactsControllerImpl.java index f8c1fe1d7..edf50600c 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/reveal/RevealContactsControllerImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/reveal/RevealContactsControllerImpl.java @@ -14,6 +14,8 @@ import org.briarproject.briar.android.controller.DbControllerImpl; import org.briarproject.briar.android.controller.handler.ExceptionHandler; import org.briarproject.briar.android.controller.handler.ResultExceptionHandler; import org.briarproject.briar.api.client.ProtocolStateException; +import org.briarproject.briar.api.identity.AuthorInfo; +import org.briarproject.briar.api.identity.AuthorManager; import org.briarproject.briar.api.privategroup.GroupMember; import org.briarproject.briar.api.privategroup.PrivateGroupManager; import org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager; @@ -45,17 +47,20 @@ class RevealContactsControllerImpl extends DbControllerImpl private final PrivateGroupManager groupManager; private final GroupInvitationManager groupInvitationManager; private final ContactManager contactManager; + private final AuthorManager authorManager; private final SettingsManager settingsManager; @Inject RevealContactsControllerImpl(@DatabaseExecutor Executor dbExecutor, LifecycleManager lifecycleManager, PrivateGroupManager groupManager, GroupInvitationManager groupInvitationManager, - ContactManager contactManager, SettingsManager settingsManager) { + ContactManager contactManager, AuthorManager authorManager, + SettingsManager settingsManager) { super(dbExecutor, lifecycleManager); this.groupManager = groupManager; this.groupInvitationManager = groupInvitationManager; this.contactManager = contactManager; + this.authorManager = authorManager; this.settingsManager = settingsManager; } @@ -82,11 +87,12 @@ class RevealContactsControllerImpl extends DbControllerImpl for (GroupMember m : members) { for (Contact c : contacts) { if (m.getAuthor().equals(c.getAuthor())) { + AuthorInfo authorInfo = authorManager.getAuthorInfo(c); boolean disabled = m.getVisibility() != INVISIBLE; boolean selected = disabled || selection.contains(c.getId()); - items.add(new RevealableContactItem(c, selected, disabled, - m.getVisibility())); + items.add(new RevealableContactItem(c, authorInfo, selected, + disabled, m.getVisibility())); } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/reveal/RevealableContactItem.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/reveal/RevealableContactItem.java index 48ae57ecd..57f84947f 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/reveal/RevealableContactItem.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/reveal/RevealableContactItem.java @@ -3,6 +3,7 @@ package org.briarproject.briar.android.privategroup.reveal; import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.briar.android.contactselection.SelectableContactItem; +import org.briarproject.briar.api.identity.AuthorInfo; import org.briarproject.briar.api.privategroup.Visibility; import javax.annotation.concurrent.NotThreadSafe; @@ -13,9 +14,9 @@ class RevealableContactItem extends SelectableContactItem { private final Visibility visibility; - RevealableContactItem(Contact contact, boolean selected, - boolean disabled, Visibility visibility) { - super(contact, selected, disabled); + RevealableContactItem(Contact contact, AuthorInfo authorInfo, + boolean selected, boolean disabled, Visibility visibility) { + super(contact, authorInfo, selected, disabled); this.visibility = visibility; } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/ShareBlogControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/ShareBlogControllerImpl.java index 26af4b3ca..abff0f41d 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/ShareBlogControllerImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/ShareBlogControllerImpl.java @@ -15,6 +15,7 @@ import org.briarproject.briar.android.contactselection.ContactSelectorController import org.briarproject.briar.android.controller.handler.ExceptionHandler; import org.briarproject.briar.api.blog.BlogSharingManager; import org.briarproject.briar.api.conversation.ConversationManager; +import org.briarproject.briar.api.identity.AuthorManager; import java.util.Collection; import java.util.concurrent.Executor; @@ -42,9 +43,10 @@ class ShareBlogControllerImpl extends ContactSelectorControllerImpl @Inject ShareBlogControllerImpl(@DatabaseExecutor Executor dbExecutor, LifecycleManager lifecycleManager, ContactManager contactManager, + AuthorManager authorManager, ConversationManager conversationManager, BlogSharingManager blogSharingManager, Clock clock) { - super(dbExecutor, lifecycleManager, contactManager); + super(dbExecutor, lifecycleManager, contactManager, authorManager); this.conversationManager = conversationManager; this.blogSharingManager = blogSharingManager; this.clock = clock; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/ShareForumControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/ShareForumControllerImpl.java index 9bbc6d3e7..1ab210d2e 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/ShareForumControllerImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/ShareForumControllerImpl.java @@ -15,6 +15,7 @@ import org.briarproject.briar.android.contactselection.ContactSelectorController import org.briarproject.briar.android.controller.handler.ExceptionHandler; import org.briarproject.briar.api.conversation.ConversationManager; import org.briarproject.briar.api.forum.ForumSharingManager; +import org.briarproject.briar.api.identity.AuthorManager; import java.util.Collection; import java.util.concurrent.Executor; @@ -42,9 +43,10 @@ class ShareForumControllerImpl extends ContactSelectorControllerImpl @Inject ShareForumControllerImpl(@DatabaseExecutor Executor dbExecutor, LifecycleManager lifecycleManager, ContactManager contactManager, + AuthorManager authorManager, ConversationManager conversationManager, ForumSharingManager forumSharingManager, Clock clock) { - super(dbExecutor, lifecycleManager, contactManager); + super(dbExecutor, lifecycleManager, contactManager, authorManager); this.conversationManager = conversationManager; this.forumSharingManager = forumSharingManager; this.clock = clock; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/sharing/SharingStatusActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/sharing/SharingStatusActivity.java index ab8e0e1ae..6f7521d58 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/sharing/SharingStatusActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/sharing/SharingStatusActivity.java @@ -20,6 +20,8 @@ import org.briarproject.briar.R; import org.briarproject.briar.android.activity.BriarActivity; import org.briarproject.briar.android.contact.ContactItem; import org.briarproject.briar.android.view.BriarRecyclerView; +import org.briarproject.briar.api.identity.AuthorInfo; +import org.briarproject.briar.api.identity.AuthorManager; import org.briarproject.briar.api.sharing.event.ContactLeftShareableEvent; import java.util.ArrayList; @@ -42,6 +44,8 @@ import static org.briarproject.bramble.util.LogUtils.logException; abstract class SharingStatusActivity extends BriarActivity implements EventListener { + @Inject + AuthorManager authorManager; @Inject ConnectionRegistry connectionRegistry; @Inject @@ -134,8 +138,9 @@ abstract class SharingStatusActivity extends BriarActivity try { List contactItems = new ArrayList<>(); for (Contact c : getSharedWith()) { + AuthorInfo authorInfo = authorManager.getAuthorInfo(c); boolean online = connectionRegistry.isConnected(c.getId()); - ContactItem item = new ContactItem(c, online); + ContactItem item = new ContactItem(c, authorInfo, online); contactItems.add(item); } displaySharedWith(contactItems); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/view/AuthorView.java b/briar-android/src/main/java/org/briarproject/briar/android/view/AuthorView.java index 9650dcf64..e1cc4aac2 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/view/AuthorView.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/view/AuthorView.java @@ -11,6 +11,7 @@ import android.widget.TextView; import com.bumptech.glide.load.engine.DiskCacheStrategy; import org.briarproject.bramble.api.identity.Author; +import org.briarproject.bramble.api.identity.AuthorId; import org.briarproject.briar.R; import org.briarproject.briar.android.conversation.glide.GlideApp; import org.briarproject.briar.android.util.UiUtils; @@ -27,7 +28,6 @@ import im.delight.android.identicons.IdenticonDrawable; import static android.content.Context.LAYOUT_INFLATER_SERVICE; import static android.graphics.Typeface.BOLD; import static android.util.TypedValue.COMPLEX_UNIT_PX; -import static com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions.withCrossFade; import static org.briarproject.briar.android.util.UiUtils.getContactDisplayName; import static org.briarproject.briar.android.util.UiUtils.resolveAttribute; import static org.briarproject.briar.api.identity.AuthorInfo.Status.NONE; @@ -78,19 +78,7 @@ public class AuthorView extends ConstraintLayout { public void setAuthor(Author author, AuthorInfo authorInfo) { authorName .setText(getContactDisplayName(author, authorInfo.getAlias())); - IdenticonDrawable identicon = - new IdenticonDrawable(author.getId().getBytes()); - if (authorInfo.getAvatarHeader() == null) { - avatar.setImageDrawable(identicon); - } else { - GlideApp.with(avatar) - .load(authorInfo.getAvatarHeader()) - .diskCacheStrategy(DiskCacheStrategy.NONE) - .error(identicon) - .transition(withCrossFade()) - .into(avatar) - .waitForLayout(); - } + setAvatar(avatar, author.getId(), authorInfo); if (authorInfo.getStatus() != NONE) { trustIndicator.setTrustLevel(authorInfo.getStatus()); @@ -109,6 +97,22 @@ public class AuthorView extends ConstraintLayout { requestLayout(); } + public static void setAvatar(ImageView v, AuthorId id, AuthorInfo info) { + IdenticonDrawable identicon = new IdenticonDrawable(id.getBytes()); + if (info.getAvatarHeader() == null) { + GlideApp.with(v) + .clear(v); + v.setImageDrawable(identicon); + } else { + GlideApp.with(v) + .load(info.getAvatarHeader()) + .diskCacheStrategy(DiskCacheStrategy.NONE) + .error(identicon) + .into(v) + .waitForLayout(); + } + } + public void setDate(long date) { this.date.setText(UiUtils.formatDate(getContext(), date)); diff --git a/briar-android/src/main/res/layout/introduction_message.xml b/briar-android/src/main/res/layout/introduction_message.xml index 99a2e980a..518fa2f91 100644 --- a/briar-android/src/main/res/layout/introduction_message.xml +++ b/briar-android/src/main/res/layout/introduction_message.xml @@ -14,7 +14,7 @@ android:id="@+id/avatarContact1" style="@style/BriarAvatar" android:layout_width="42dp" - android:layout_height="wrap_content" + android:layout_height="42dp" android:layout_margin="@dimen/margin_large" app:layout_constraintEnd_toStartOf="@+id/introductionIcon" app:layout_constraintStart_toStartOf="parent" @@ -55,7 +55,7 @@ android:id="@+id/avatarContact2" style="@style/BriarAvatar" android:layout_width="42dp" - android:layout_height="wrap_content" + android:layout_height="42dp" android:layout_margin="@dimen/margin_large" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/introductionIcon" diff --git a/briar-android/src/main/res/values/dimens.xml b/briar-android/src/main/res/values/dimens.xml index 0b8e5f2c8..cc74b7be3 100644 --- a/briar-android/src/main/res/values/dimens.xml +++ b/briar-android/src/main/res/values/dimens.xml @@ -30,7 +30,7 @@ 40dp 40dp 48dp - 2dp + 1dp 30sp 48dp diff --git a/briar-api/src/main/java/org/briarproject/briar/api/identity/AuthorManager.java b/briar-api/src/main/java/org/briarproject/briar/api/identity/AuthorManager.java index a07fbb8d1..46381a3c0 100644 --- a/briar-api/src/main/java/org/briarproject/briar/api/identity/AuthorManager.java +++ b/briar-api/src/main/java/org/briarproject/briar/api/identity/AuthorManager.java @@ -1,5 +1,6 @@ package org.briarproject.briar.api.identity; +import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Transaction; import org.briarproject.bramble.api.identity.AuthorId; @@ -19,6 +20,17 @@ public interface AuthorManager { */ AuthorInfo getAuthorInfo(Transaction txn, AuthorId a) throws DbException; + /** + * Returns the {@link AuthorInfo} for the given contact. + */ + AuthorInfo getAuthorInfo(Contact c) throws DbException; + + /** + * Returns the {@link AuthorInfo} for the given contact. + */ + AuthorInfo getAuthorInfo(Transaction txn, Contact c) + throws DbException; + /** * Returns the {@link AuthorInfo} for the {@link LocalAuthor}. */ diff --git a/briar-core/src/main/java/org/briarproject/briar/identity/AuthorManagerImpl.java b/briar-core/src/main/java/org/briarproject/briar/identity/AuthorManagerImpl.java index 479803113..b0fd4fc59 100644 --- a/briar-core/src/main/java/org/briarproject/briar/identity/AuthorManagerImpl.java +++ b/briar-core/src/main/java/org/briarproject/briar/identity/AuthorManagerImpl.java @@ -53,6 +53,17 @@ class AuthorManagerImpl implements AuthorManager { if (contacts.isEmpty()) return new AuthorInfo(UNKNOWN); if (contacts.size() > 1) throw new AssertionError(); Contact c = contacts.iterator().next(); + return getAuthorInfo(txn, c); + } + + @Override + public AuthorInfo getAuthorInfo(Contact c) throws DbException { + return db.transactionWithResult(true, txn -> getAuthorInfo(txn, c)); + } + + @Override + public AuthorInfo getAuthorInfo(Transaction txn, Contact c) + throws DbException { AttachmentHeader avatar = avatarManager.getAvatarHeader(txn, c); if (c.isVerified()) return new AuthorInfo(VERIFIED, c.getAlias(), avatar);