Verified Commit 0491c3ca authored by akwizgran's avatar akwizgran

Use a visitor to create ConversationItems.

parent 2e120f75
package org.briarproject.briar.android.contact; package org.briarproject.briar.android.contact;
import android.content.Intent; import android.content.Intent;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityCompat;
import android.support.v4.app.ActivityOptionsCompat; import android.support.v4.app.ActivityOptionsCompat;
...@@ -48,6 +47,7 @@ import java.util.logging.Logger; ...@@ -48,6 +47,7 @@ import java.util.logging.Logger;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import static android.os.Build.VERSION.SDK_INT;
import static android.support.v4.app.ActivityOptionsCompat.makeSceneTransitionAnimation; import static android.support.v4.app.ActivityOptionsCompat.makeSceneTransitionAnimation;
import static android.support.v4.view.ViewCompat.getTransitionName; import static android.support.v4.view.ViewCompat.getTransitionName;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
...@@ -113,7 +113,7 @@ public class ContactListFragment extends BaseFragment implements EventListener { ...@@ -113,7 +113,7 @@ public class ContactListFragment extends BaseFragment implements EventListener {
ContactId contactId = item.getContact().getId(); ContactId contactId = item.getContact().getId();
i.putExtra(CONTACT_ID, contactId.getInt()); i.putExtra(CONTACT_ID, contactId.getInt());
if (Build.VERSION.SDK_INT >= 23) { if (SDK_INT >= 23) {
ContactListItemViewHolder holder = ContactListItemViewHolder holder =
(ContactListItemViewHolder) list (ContactListItemViewHolder) list
.getRecyclerView() .getRecyclerView()
...@@ -256,8 +256,7 @@ public class ContactListFragment extends BaseFragment implements EventListener { ...@@ -256,8 +256,7 @@ public class ContactListFragment extends BaseFragment implements EventListener {
int position = adapter.findItemPosition(c); int position = adapter.findItemPosition(c);
ContactListItem item = adapter.getItemAt(position); ContactListItem item = adapter.getItemAt(position);
if (item != null) { if (item != null) {
ConversationItem i = ConversationItem.from(getContext(), "", h); item.addMessage(h);
item.addMessage(i);
adapter.updateItemAt(position, item); adapter.updateItemAt(position, item);
} }
}); });
......
...@@ -3,6 +3,7 @@ package org.briarproject.briar.android.contact; ...@@ -3,6 +3,7 @@ package org.briarproject.briar.android.contact;
import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.briar.api.client.MessageTracker.GroupCount; import org.briarproject.briar.api.client.MessageTracker.GroupCount;
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
import javax.annotation.concurrent.NotThreadSafe; import javax.annotation.concurrent.NotThreadSafe;
...@@ -22,11 +23,10 @@ public class ContactListItem extends ContactItem { ...@@ -22,11 +23,10 @@ public class ContactListItem extends ContactItem {
this.timestamp = count.getLatestMsgTime(); this.timestamp = count.getLatestMsgTime();
} }
void addMessage(ConversationItem message) { void addMessage(PrivateMessageHeader h) {
empty = false; empty = false;
if (message.getTime() > timestamp) timestamp = message.getTime(); if (h.getTimestamp() > timestamp) timestamp = h.getTimestamp();
if (!message.isRead()) if (!h.isRead()) unread++;
unread++;
} }
boolean isEmpty() { boolean isEmpty() {
......
...@@ -53,6 +53,7 @@ import org.briarproject.briar.android.activity.ActivityComponent; ...@@ -53,6 +53,7 @@ import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.activity.BriarActivity; import org.briarproject.briar.android.activity.BriarActivity;
import org.briarproject.briar.android.blog.BlogActivity; import org.briarproject.briar.android.blog.BlogActivity;
import org.briarproject.briar.android.contact.ConversationAdapter.ConversationListener; import org.briarproject.briar.android.contact.ConversationAdapter.ConversationListener;
import org.briarproject.briar.android.contact.ConversationVisitor.BodyCache;
import org.briarproject.briar.android.forum.ForumActivity; import org.briarproject.briar.android.forum.ForumActivity;
import org.briarproject.briar.android.introduction.IntroductionActivity; import org.briarproject.briar.android.introduction.IntroductionActivity;
import org.briarproject.briar.android.privategroup.conversation.GroupActivity; import org.briarproject.briar.android.privategroup.conversation.GroupActivity;
...@@ -111,7 +112,8 @@ import static uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt.S ...@@ -111,7 +112,8 @@ import static uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt.S
@MethodsNotNullByDefault @MethodsNotNullByDefault
@ParametersNotNullByDefault @ParametersNotNullByDefault
public class ConversationActivity extends BriarActivity public class ConversationActivity extends BriarActivity
implements EventListener, ConversationListener, TextInputListener { implements EventListener, ConversationListener, TextInputListener,
BodyCache {
public static final String CONTACT_ID = "briar.CONTACT_ID"; public static final String CONTACT_ID = "briar.CONTACT_ID";
...@@ -131,6 +133,7 @@ public class ConversationActivity extends BriarActivity ...@@ -131,6 +133,7 @@ public class ConversationActivity extends BriarActivity
private final Map<MessageId, String> bodyCache = new ConcurrentHashMap<>(); private final Map<MessageId, String> bodyCache = new ConcurrentHashMap<>();
private final MutableLiveData<String> contactName = new MutableLiveData<>(); private final MutableLiveData<String> contactName = new MutableLiveData<>();
private ConversationVisitor visitor;
private ConversationAdapter adapter; private ConversationAdapter adapter;
private Toolbar toolbar; private Toolbar toolbar;
private CircleImageView toolbarAvatar; private CircleImageView toolbarAvatar;
...@@ -191,6 +194,7 @@ public class ConversationActivity extends BriarActivity ...@@ -191,6 +194,7 @@ public class ConversationActivity extends BriarActivity
setTransitionName(toolbarAvatar, getAvatarTransitionName(contactId)); setTransitionName(toolbarAvatar, getAvatarTransitionName(contactId));
setTransitionName(toolbarStatus, getBulbTransitionName(contactId)); setTransitionName(toolbarStatus, getBulbTransitionName(contactId));
visitor = new ConversationVisitor(this, this, contactName);
adapter = new ConversationAdapter(this, this); adapter = new ConversationAdapter(this, this);
list = findViewById(R.id.conversationView); list = findViewById(R.id.conversationView);
list.setLayoutManager(new LinearLayoutManager(this)); list.setLayoutManager(new LinearLayoutManager(this));
...@@ -362,18 +366,7 @@ public class ConversationActivity extends BriarActivity ...@@ -362,18 +366,7 @@ public class ConversationActivity extends BriarActivity
private List<ConversationItem> createItems( private List<ConversationItem> createItems(
Collection<PrivateMessageHeader> headers) { Collection<PrivateMessageHeader> headers) {
List<ConversationItem> items = new ArrayList<>(headers.size()); List<ConversationItem> items = new ArrayList<>(headers.size());
for (PrivateMessageHeader h : headers) { for (PrivateMessageHeader h : headers) items.add(h.accept(visitor));
ConversationItem item;
if (h instanceof PrivateRequest || h instanceof PrivateResponse) {
item = ConversationItem.from(this, contactName.getValue(), h);
} else {
item = ConversationItem.from(h);
String body = bodyCache.get(h.getId());
if (body == null) loadMessageBody(h.getId());
else item.setBody(body);
}
items.add(item);
}
return items; return items;
} }
...@@ -467,27 +460,21 @@ public class ConversationActivity extends BriarActivity ...@@ -467,27 +460,21 @@ public class ConversationActivity extends BriarActivity
@Override @Override
public void onChanged(@Nullable String cName) { public void onChanged(@Nullable String cName) {
if (cName != null) { if (cName != null) {
onNewPrivateRequestOrResponse(h, cName); addConversationItem(h.accept(visitor));
contactName.removeObserver(this); contactName.removeObserver(this);
} }
} }
}); });
} else { } else {
onNewPrivateRequestOrResponse(h, cName); addConversationItem(h.accept(visitor));
} }
} else { } else {
addConversationItem(ConversationItem.from(h)); addConversationItem(h.accept(visitor));
loadMessageBody(h.getId()); loadMessageBody(h.getId());
} }
}); });
} }
@UiThread
private void onNewPrivateRequestOrResponse(PrivateMessageHeader h,
String cName) {
addConversationItem(ConversationItem.from(this, cName, h));
}
private void markMessages(Collection<MessageId> messageIds, boolean sent, private void markMessages(Collection<MessageId> messageIds, boolean sent,
boolean seen) { boolean seen) {
runOnUiThreadUnlessDestroyed(() -> { runOnUiThreadUnlessDestroyed(() -> {
...@@ -558,10 +545,8 @@ public class ConversationActivity extends BriarActivity ...@@ -558,10 +545,8 @@ public class ConversationActivity extends BriarActivity
PrivateMessageHeader h = new PrivateMessageHeader( PrivateMessageHeader h = new PrivateMessageHeader(
message.getId(), message.getGroupId(), message.getId(), message.getGroupId(),
message.getTimestamp(), true, false, false, false); message.getTimestamp(), true, false, false, false);
ConversationItem item = ConversationItem.from(h);
item.setBody(body);
bodyCache.put(message.getId(), body); bodyCache.put(message.getId(), body);
addConversationItem(item); addConversationItem(h.accept(visitor));
} catch (DbException e) { } catch (DbException e) {
logException(LOG, WARNING, e); logException(LOG, WARNING, e);
} }
...@@ -773,4 +758,12 @@ public class ConversationActivity extends BriarActivity ...@@ -773,4 +758,12 @@ public class ConversationActivity extends BriarActivity
throws DbException { throws DbException {
groupInvitationManager.respondToInvitation(contactId, id, accept); groupInvitationManager.respondToInvitation(contactId, id, accept);
} }
@Nullable
@Override
public String getBody(MessageId m) {
String body = bodyCache.get(m);
if (body == null) loadMessageBody(m);
return body;
}
} }
package org.briarproject.briar.android.contact; package org.briarproject.briar.android.contact;
import android.content.Context;
import android.support.annotation.LayoutRes; import android.support.annotation.LayoutRes;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
import org.briarproject.briar.api.messaging.PrivateRequest;
import org.briarproject.briar.api.messaging.PrivateResponse;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe; import javax.annotation.concurrent.NotThreadSafe;
...@@ -62,48 +58,4 @@ abstract class ConversationItem { ...@@ -62,48 +58,4 @@ abstract class ConversationItem {
@LayoutRes @LayoutRes
abstract public int getLayout(); abstract public int getLayout();
static ConversationItem from(PrivateMessageHeader h) {
if (h.isLocal()) {
return new ConversationMessageOutItem(h);
} else {
return new ConversationMessageInItem(h);
}
}
static ConversationItem from(Context ctx, String contactName,
PrivateMessageHeader h) {
if (h.isLocal()) {
return fromLocal(ctx, contactName, h);
} else {
return fromRemote(ctx, contactName, h);
}
}
private static ConversationItem fromLocal(Context ctx, String contactName,
PrivateMessageHeader h) {
if (h instanceof PrivateRequest) {
PrivateRequest r = (PrivateRequest) h;
return new ConversationNoticeOutItem(ctx, contactName, r);
} else if (h instanceof PrivateResponse) {
PrivateResponse r = (PrivateResponse) h;
return new ConversationNoticeOutItem(ctx, contactName, r);
} else {
return new ConversationMessageOutItem(h);
}
}
private static ConversationItem fromRemote(Context ctx, String contactName,
PrivateMessageHeader h) {
if (h instanceof PrivateRequest) {
PrivateRequest r = (PrivateRequest) h;
return new ConversationRequestItem(ctx, contactName, r);
} else if (h instanceof PrivateResponse) {
PrivateResponse r = (PrivateResponse) h;
return new ConversationNoticeInItem(ctx, contactName, r);
} else {
return new ConversationMessageInItem(h);
}
}
} }
package org.briarproject.briar.android.contact; package org.briarproject.briar.android.contact;
import android.content.Context;
import android.support.annotation.LayoutRes; import android.support.annotation.LayoutRes;
import android.support.annotation.StringRes;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.api.blog.BlogInvitationResponse;
import org.briarproject.briar.api.forum.ForumInvitationResponse;
import org.briarproject.briar.api.introduction.IntroductionResponse;
import org.briarproject.briar.api.messaging.PrivateResponse; import org.briarproject.briar.api.messaging.PrivateResponse;
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationResponse;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe; import javax.annotation.concurrent.NotThreadSafe;
...@@ -24,17 +18,14 @@ class ConversationNoticeInItem extends ConversationItem { ...@@ -24,17 +18,14 @@ class ConversationNoticeInItem extends ConversationItem {
@Nullable @Nullable
private final String msgText; private final String msgText;
ConversationNoticeInItem(MessageId id, GroupId groupId, ConversationNoticeInItem(MessageId id, GroupId groupId, String text,
String text, @Nullable String msgText, long time, @Nullable String msgText, long time, boolean read) {
boolean read) {
super(id, groupId, text, time, read); super(id, groupId, text, time, read);
this.msgText = msgText; this.msgText = msgText;
} }
public ConversationNoticeInItem(Context ctx, String contactName, ConversationNoticeInItem(String text, PrivateResponse r) {
PrivateResponse r) { super(r.getId(), r.getGroupId(), text, r.getTimestamp(), r.isRead());
super(r.getId(), r.getGroupId(), getText(ctx, contactName, r),
r.getTimestamp(), r.isRead());
this.msgText = null; this.msgText = null;
} }
...@@ -53,55 +44,4 @@ class ConversationNoticeInItem extends ConversationItem { ...@@ -53,55 +44,4 @@ class ConversationNoticeInItem extends ConversationItem {
public int getLayout() { public int getLayout() {
return R.layout.list_item_conversation_notice_in; return R.layout.list_item_conversation_notice_in;
} }
private static String getText(Context ctx, String contactName,
PrivateResponse r) {
if (r.wasAccepted()) {
if (r instanceof IntroductionResponse) {
IntroductionResponse ir = (IntroductionResponse) r;
return ctx.getString(
R.string.introduction_response_accepted_received,
contactName, ir.getIntroducedAuthor().getName());
} else if (r instanceof ForumInvitationResponse) {
return ctx.getString(
R.string.forum_invitation_response_accepted_received,
contactName);
} else if (r instanceof BlogInvitationResponse) {
return ctx.getString(
R.string.blogs_sharing_response_accepted_received,
contactName);
} else if (r instanceof GroupInvitationResponse) {
return ctx.getString(
R.string.groups_invitations_response_accepted_received,
contactName);
}
} else {
if (r instanceof IntroductionResponse) {
IntroductionResponse ir = (IntroductionResponse) r;
@StringRes int res;
if (ir.isIntroducer()) {
res = R.string.introduction_response_declined_received;
} else {
res =
R.string.introduction_response_declined_received_by_introducee;
}
return ctx.getString(res, contactName,
ir.getIntroducedAuthor().getName());
} else if (r instanceof ForumInvitationResponse) {
return ctx.getString(
R.string.forum_invitation_response_declined_received,
contactName);
} else if (r instanceof BlogInvitationResponse) {
return ctx.getString(
R.string.blogs_sharing_response_declined_received,
contactName);
} else if (r instanceof GroupInvitationResponse) {
return ctx.getString(
R.string.groups_invitations_response_declined_received,
contactName);
}
}
throw new IllegalArgumentException("Unknown PrivateResponse");
}
} }
package org.briarproject.briar.android.contact; package org.briarproject.briar.android.contact;
import android.content.Context;
import android.support.annotation.LayoutRes; import android.support.annotation.LayoutRes;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.api.blog.BlogInvitationRequest;
import org.briarproject.briar.api.blog.BlogInvitationResponse;
import org.briarproject.briar.api.forum.ForumInvitationRequest;
import org.briarproject.briar.api.forum.ForumInvitationResponse;
import org.briarproject.briar.api.introduction.IntroductionRequest;
import org.briarproject.briar.api.introduction.IntroductionResponse;
import org.briarproject.briar.api.messaging.PrivateRequest; import org.briarproject.briar.api.messaging.PrivateRequest;
import org.briarproject.briar.api.messaging.PrivateResponse; import org.briarproject.briar.api.messaging.PrivateResponse;
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationRequest;
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationResponse;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe; import javax.annotation.concurrent.NotThreadSafe;
...@@ -26,17 +17,15 @@ class ConversationNoticeOutItem extends ConversationOutItem { ...@@ -26,17 +17,15 @@ class ConversationNoticeOutItem extends ConversationOutItem {
@Nullable @Nullable
private final String msgText; private final String msgText;
ConversationNoticeOutItem(Context ctx, String contactName, ConversationNoticeOutItem(String text, PrivateRequest r) {
PrivateRequest r) { super(r.getId(), r.getGroupId(), text, r.getTimestamp(), r.isSent(),
super(r.getId(), r.getGroupId(), getText(ctx, contactName, r), r.isSeen());
r.getTimestamp(), r.isSent(), r.isSeen());
this.msgText = r.getMessage(); this.msgText = r.getMessage();
} }
ConversationNoticeOutItem(Context ctx, String contactName, ConversationNoticeOutItem(String text, PrivateResponse r) {
PrivateResponse r) { super(r.getId(), r.getGroupId(), text, r.getTimestamp(), r.isSent(),
super(r.getId(), r.getGroupId(), getText(ctx, contactName, r), r.isSeen());
r.getTimestamp(), r.isSent(), r.isSeen());
this.msgText = null; this.msgText = null;
} }
...@@ -50,58 +39,4 @@ class ConversationNoticeOutItem extends ConversationOutItem { ...@@ -50,58 +39,4 @@ class ConversationNoticeOutItem extends ConversationOutItem {
public int getLayout() { public int getLayout() {
return R.layout.list_item_conversation_notice_out; return R.layout.list_item_conversation_notice_out;
} }
private static String getText(Context ctx, String contactName,
PrivateRequest r) {
if (r instanceof IntroductionRequest) {
return ctx.getString(R.string.introduction_request_sent,
contactName, r.getName());
} else if (r instanceof ForumInvitationRequest) {
return ctx.getString(R.string.forum_invitation_sent,
r.getName(), contactName);
} else if (r instanceof BlogInvitationRequest) {
return ctx.getString(R.string.blogs_sharing_invitation_sent,
r.getName(), contactName);
} else if (r instanceof GroupInvitationRequest) {
return ctx.getString(R.string.groups_invitations_invitation_sent,
contactName, r.getName());
}
throw new IllegalArgumentException("Unknown PrivateRequest");
}
private static String getText(Context ctx, String contactName,
PrivateResponse r) {
if (r.wasAccepted()) {
if (r instanceof IntroductionResponse) {
String name = ((IntroductionResponse) r).getIntroducedAuthor()
.getName();
return ctx.getString(
R.string.introduction_response_accepted_sent,
name) + "\n\n" + ctx.getString(
R.string.introduction_response_accepted_sent_info,
name);
} else if (r instanceof ForumInvitationResponse) {
return ctx.getString(R.string.forum_invitation_response_accepted_sent, contactName);
} else if (r instanceof BlogInvitationResponse) {
return ctx.getString(R.string.blogs_sharing_response_accepted_sent, contactName);
} else if (r instanceof GroupInvitationResponse) {
return ctx.getString(R.string.groups_invitations_response_accepted_sent, contactName);
}
} else {
if (r instanceof IntroductionResponse) {
String name = ((IntroductionResponse) r).getIntroducedAuthor()
.getName();
return ctx.getString(
R.string.introduction_response_declined_sent, name);
} else if (r instanceof ForumInvitationResponse) {
return ctx.getString(R.string.forum_invitation_response_declined_sent, contactName);
} else if (r instanceof BlogInvitationResponse) {
return ctx.getString(R.string.blogs_sharing_response_declined_sent, contactName);
} else if (r instanceof GroupInvitationResponse) {
return ctx.getString(R.string.groups_invitations_response_declined_sent, contactName);
}
}
throw new IllegalArgumentException("Unknown PrivateResponse");
}
} }
package org.briarproject.briar.android.contact; package org.briarproject.briar.android.contact;
import android.content.Context;
import android.support.annotation.LayoutRes; import android.support.annotation.LayoutRes;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.bramble.api.sync.GroupId; import org.briarproject.bramble.api.sync.GroupId;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.api.blog.BlogInvitationRequest;
import org.briarproject.briar.api.client.SessionId; import org.briarproject.briar.api.client.SessionId;
import org.briarproject.briar.api.forum.ForumInvitationRequest;
import org.briarproject.briar.api.introduction.IntroductionRequest;
import org.briarproject.briar.api.messaging.PrivateRequest; import org.briarproject.briar.api.messaging.PrivateRequest;
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationRequest;
import org.briarproject.briar.api.sharing.InvitationRequest; import org.briarproject.briar.api.sharing.InvitationRequest;
import org.briarproject.briar.api.sharing.Shareable; import org.briarproject.briar.api.sharing.Shareable;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe; import javax.annotation.concurrent.NotThreadSafe;