mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-17 13:19:52 +01:00
Updated group conversation view to resemble private conversation view.
This commit is contained in:
@@ -50,7 +50,7 @@ import android.widget.ListView;
|
|||||||
public class ConversationActivity extends BriarActivity
|
public class ConversationActivity extends BriarActivity
|
||||||
implements EventListener, OnClickListener, OnItemClickListener {
|
implements EventListener, OnClickListener, OnItemClickListener {
|
||||||
|
|
||||||
private static final int REQUEST_READ_MESSAGE = 2;
|
private static final int REQUEST_READ = 2;
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(ConversationActivity.class.getName());
|
Logger.getLogger(ConversationActivity.class.getName());
|
||||||
|
|
||||||
@@ -239,7 +239,7 @@ implements EventListener, OnClickListener, OnItemClickListener {
|
|||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int request, int result, Intent data) {
|
protected void onActivityResult(int request, int result, Intent data) {
|
||||||
super.onActivityResult(request, result, data);
|
super.onActivityResult(request, result, data);
|
||||||
if(request == REQUEST_READ_MESSAGE && result == RESULT_PREV_NEXT) {
|
if(request == REQUEST_READ && result == RESULT_PREV_NEXT) {
|
||||||
int position = data.getIntExtra("briar.POSITION", -1);
|
int position = data.getIntExtra("briar.POSITION", -1);
|
||||||
if(position >= 0 && position < adapter.getCount())
|
if(position >= 0 && position < adapter.getCount())
|
||||||
displayMessage(position);
|
displayMessage(position);
|
||||||
@@ -296,6 +296,6 @@ implements EventListener, OnClickListener, OnItemClickListener {
|
|||||||
i.putExtra("briar.CONTENT_TYPE", header.getContentType());
|
i.putExtra("briar.CONTENT_TYPE", header.getContentType());
|
||||||
i.putExtra("briar.TIMESTAMP", header.getTimestamp());
|
i.putExtra("briar.TIMESTAMP", header.getTimestamp());
|
||||||
i.putExtra("briar.POSITION", position);
|
i.putExtra("briar.POSITION", position);
|
||||||
startActivityForResult(i, REQUEST_READ_MESSAGE);
|
startActivityForResult(i, REQUEST_READ);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ class ConversationAdapter extends ArrayAdapter<ConversationItem> {
|
|||||||
authorView.init(header.getAuthor().getName(), VERIFIED);
|
authorView.init(header.getAuthor().getName(), VERIFIED);
|
||||||
headerLayout.addView(authorView);
|
headerLayout.addView(authorView);
|
||||||
|
|
||||||
|
// FIXME: Factor this out into a TimestampView
|
||||||
TextView date = new TextView(ctx);
|
TextView date = new TextView(ctx);
|
||||||
date.setTextSize(14);
|
date.setTextSize(14);
|
||||||
date.setPadding(0, pad, pad, pad);
|
date.setPadding(0, pad, pad, pad);
|
||||||
|
|||||||
@@ -2,10 +2,9 @@ package org.briarproject.android.contact;
|
|||||||
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
||||||
public class ConversationItemComparator
|
class ConversationItemComparator implements Comparator<ConversationItem> {
|
||||||
implements Comparator<ConversationItem> {
|
|
||||||
|
|
||||||
public static final ConversationItemComparator INSTANCE =
|
static final ConversationItemComparator INSTANCE =
|
||||||
new ConversationItemComparator();
|
new ConversationItemComparator();
|
||||||
|
|
||||||
public int compare(ConversationItem a, ConversationItem b) {
|
public int compare(ConversationItem a, ConversationItem b) {
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import java.util.logging.Logger;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import org.briarproject.R;
|
import org.briarproject.R;
|
||||||
import org.briarproject.android.AscendingHeaderComparator;
|
|
||||||
import org.briarproject.android.BriarActivity;
|
import org.briarproject.android.BriarActivity;
|
||||||
import org.briarproject.android.util.HorizontalBorder;
|
import org.briarproject.android.util.HorizontalBorder;
|
||||||
import org.briarproject.android.util.ListLoadingProgressBar;
|
import org.briarproject.android.util.ListLoadingProgressBar;
|
||||||
@@ -26,6 +25,7 @@ import org.briarproject.api.android.DatabaseUiExecutor;
|
|||||||
import org.briarproject.api.db.DatabaseComponent;
|
import org.briarproject.api.db.DatabaseComponent;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
import org.briarproject.api.db.MessageHeader;
|
import org.briarproject.api.db.MessageHeader;
|
||||||
|
import org.briarproject.api.db.NoSuchMessageException;
|
||||||
import org.briarproject.api.db.NoSuchSubscriptionException;
|
import org.briarproject.api.db.NoSuchSubscriptionException;
|
||||||
import org.briarproject.api.event.Event;
|
import org.briarproject.api.event.Event;
|
||||||
import org.briarproject.api.event.EventListener;
|
import org.briarproject.api.event.EventListener;
|
||||||
@@ -34,6 +34,7 @@ import org.briarproject.api.event.MessageExpiredEvent;
|
|||||||
import org.briarproject.api.event.SubscriptionRemovedEvent;
|
import org.briarproject.api.event.SubscriptionRemovedEvent;
|
||||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||||
import org.briarproject.api.messaging.GroupId;
|
import org.briarproject.api.messaging.GroupId;
|
||||||
|
import org.briarproject.api.messaging.MessageId;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -48,7 +49,7 @@ import android.widget.ListView;
|
|||||||
public class GroupActivity extends BriarActivity implements EventListener,
|
public class GroupActivity extends BriarActivity implements EventListener,
|
||||||
OnClickListener, OnItemClickListener {
|
OnClickListener, OnItemClickListener {
|
||||||
|
|
||||||
private static final int REQUEST_READ_POST = 2;
|
private static final int REQUEST_READ = 2;
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(GroupActivity.class.getName());
|
Logger.getLogger(GroupActivity.class.getName());
|
||||||
|
|
||||||
@@ -125,11 +126,7 @@ OnClickListener, OnItemClickListener {
|
|||||||
displayHeaders(headers);
|
displayHeaders(headers);
|
||||||
} catch(NoSuchSubscriptionException e) {
|
} catch(NoSuchSubscriptionException e) {
|
||||||
if(LOG.isLoggable(INFO)) LOG.info("Subscription removed");
|
if(LOG.isLoggable(INFO)) LOG.info("Subscription removed");
|
||||||
runOnUiThread(new Runnable() {
|
finishOnUiThread();
|
||||||
public void run() {
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch(DbException e) {
|
} catch(DbException e) {
|
||||||
if(LOG.isLoggable(WARNING))
|
if(LOG.isLoggable(WARNING))
|
||||||
LOG.log(WARNING, e.toString(), e);
|
LOG.log(WARNING, e.toString(), e);
|
||||||
@@ -148,30 +145,91 @@ OnClickListener, OnItemClickListener {
|
|||||||
list.setVisibility(VISIBLE);
|
list.setVisibility(VISIBLE);
|
||||||
loading.setVisibility(GONE);
|
loading.setVisibility(GONE);
|
||||||
adapter.clear();
|
adapter.clear();
|
||||||
for(MessageHeader h : headers) adapter.add(h);
|
for(MessageHeader h : headers) adapter.add(new GroupItem(h));
|
||||||
adapter.sort(AscendingHeaderComparator.INSTANCE);
|
adapter.sort(GroupItemComparator.INSTANCE);
|
||||||
adapter.notifyDataSetChanged();
|
adapter.notifyDataSetChanged();
|
||||||
selectFirstUnread();
|
expandMessages();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void selectFirstUnread() {
|
private void expandMessages() {
|
||||||
int firstUnread = -1, count = adapter.getCount();
|
// Expand unread messages and the last three messages
|
||||||
|
int firstExpanded = -1, count = adapter.getCount();
|
||||||
|
if(count == 0) return;
|
||||||
for(int i = 0; i < count; i++) {
|
for(int i = 0; i < count; i++) {
|
||||||
if(!adapter.getItem(i).isRead()) {
|
GroupItem item = adapter.getItem(i);
|
||||||
firstUnread = i;
|
if(!item.getHeader().isRead() || i >= count - 3) {
|
||||||
break;
|
if(firstExpanded == -1) firstExpanded = i;
|
||||||
|
item.setExpanded(true);
|
||||||
|
loadMessage(item.getHeader());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(firstUnread == -1) list.setSelection(count - 1);
|
// Scroll to the first expanded message
|
||||||
else list.setSelection(firstUnread);
|
list.setSelection(firstExpanded);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadMessage(final MessageHeader h) {
|
||||||
|
dbUiExecutor.execute(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
lifecycleManager.waitForDatabase();
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
byte[] body = db.getMessageBody(h.getId());
|
||||||
|
long duration = System.currentTimeMillis() - now;
|
||||||
|
if(LOG.isLoggable(INFO))
|
||||||
|
LOG.info("Loading message took " + duration + " ms");
|
||||||
|
displayMessage(h.getId(), body);
|
||||||
|
if(!h.isRead()) {
|
||||||
|
now = System.currentTimeMillis();
|
||||||
|
db.setReadFlag(h.getId(), true);
|
||||||
|
duration = System.currentTimeMillis() - now;
|
||||||
|
if(LOG.isLoggable(INFO))
|
||||||
|
LOG.info("Setting read took " + duration + " ms");
|
||||||
|
}
|
||||||
|
} catch(NoSuchMessageException e) {
|
||||||
|
if(LOG.isLoggable(INFO)) LOG.info("Message expired");
|
||||||
|
// The item will be removed when we get the event
|
||||||
|
} catch(DbException e) {
|
||||||
|
if(LOG.isLoggable(WARNING))
|
||||||
|
LOG.log(WARNING, e.toString(), e);
|
||||||
|
} catch(InterruptedException e) {
|
||||||
|
if(LOG.isLoggable(INFO))
|
||||||
|
LOG.info("Interrupted while waiting for database");
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void displayMessage(final MessageId m, final byte[] body) {
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
int count = adapter.getCount();
|
||||||
|
for(int i = 0; i < count; i++) {
|
||||||
|
GroupItem item = adapter.getItem(i);
|
||||||
|
if(item.getHeader().getId().equals(m)) {
|
||||||
|
item.setBody(body);
|
||||||
|
adapter.notifyDataSetChanged();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void finishOnUiThread() {
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int request, int result, Intent data) {
|
protected void onActivityResult(int request, int result, Intent data) {
|
||||||
super.onActivityResult(request, result, data);
|
super.onActivityResult(request, result, data);
|
||||||
if(request == REQUEST_READ_POST && result == RESULT_PREV_NEXT) {
|
if(request == REQUEST_READ && result == RESULT_PREV_NEXT) {
|
||||||
int position = data.getIntExtra("briar.POSITION", -1);
|
int position = data.getIntExtra("briar.POSITION", -1);
|
||||||
if(position >= 0 && position < adapter.getCount())
|
if(position >= 0 && position < adapter.getCount())
|
||||||
displayMessage(position);
|
displayMessage(position);
|
||||||
@@ -197,11 +255,7 @@ OnClickListener, OnItemClickListener {
|
|||||||
SubscriptionRemovedEvent s = (SubscriptionRemovedEvent) e;
|
SubscriptionRemovedEvent s = (SubscriptionRemovedEvent) e;
|
||||||
if(s.getGroup().getId().equals(groupId)) {
|
if(s.getGroup().getId().equals(groupId)) {
|
||||||
if(LOG.isLoggable(INFO)) LOG.info("Subscription removed");
|
if(LOG.isLoggable(INFO)) LOG.info("Subscription removed");
|
||||||
runOnUiThread(new Runnable() {
|
finishOnUiThread();
|
||||||
public void run() {
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -218,7 +272,7 @@ OnClickListener, OnItemClickListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void displayMessage(int position) {
|
private void displayMessage(int position) {
|
||||||
MessageHeader item = adapter.getItem(position);
|
MessageHeader item = adapter.getItem(position).getHeader();
|
||||||
Intent i = new Intent(this, ReadGroupPostActivity.class);
|
Intent i = new Intent(this, ReadGroupPostActivity.class);
|
||||||
i.putExtra("briar.GROUP_ID", groupId.getBytes());
|
i.putExtra("briar.GROUP_ID", groupId.getBytes());
|
||||||
i.putExtra("briar.GROUP_NAME", groupName);
|
i.putExtra("briar.GROUP_NAME", groupName);
|
||||||
@@ -229,6 +283,6 @@ OnClickListener, OnItemClickListener {
|
|||||||
i.putExtra("briar.CONTENT_TYPE", item.getContentType());
|
i.putExtra("briar.CONTENT_TYPE", item.getContentType());
|
||||||
i.putExtra("briar.TIMESTAMP", item.getTimestamp());
|
i.putExtra("briar.TIMESTAMP", item.getTimestamp());
|
||||||
i.putExtra("briar.POSITION", position);
|
i.putExtra("briar.POSITION", position);
|
||||||
startActivityForResult(i, REQUEST_READ_POST);
|
startActivityForResult(i, REQUEST_READ);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package org.briarproject.android.groups;
|
package org.briarproject.android.groups;
|
||||||
|
|
||||||
|
import static android.view.Gravity.CENTER_HORIZONTAL;
|
||||||
import static android.view.Gravity.CENTER_VERTICAL;
|
import static android.view.Gravity.CENTER_VERTICAL;
|
||||||
import static android.widget.LinearLayout.HORIZONTAL;
|
import static android.widget.LinearLayout.HORIZONTAL;
|
||||||
|
import static android.widget.LinearLayout.VERTICAL;
|
||||||
import static java.text.DateFormat.SHORT;
|
import static java.text.DateFormat.SHORT;
|
||||||
import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP_1;
|
import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP_1;
|
||||||
|
|
||||||
@@ -12,6 +14,7 @@ import org.briarproject.android.util.AuthorView;
|
|||||||
import org.briarproject.android.util.LayoutUtils;
|
import org.briarproject.android.util.LayoutUtils;
|
||||||
import org.briarproject.api.Author;
|
import org.briarproject.api.Author;
|
||||||
import org.briarproject.api.db.MessageHeader;
|
import org.briarproject.api.db.MessageHeader;
|
||||||
|
import org.briarproject.util.StringUtils;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
@@ -20,45 +23,71 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
class GroupAdapter extends ArrayAdapter<MessageHeader> {
|
class GroupAdapter extends ArrayAdapter<GroupItem> {
|
||||||
|
|
||||||
private final int pad;
|
private final int pad;
|
||||||
|
|
||||||
GroupAdapter(Context ctx) {
|
GroupAdapter(Context ctx) {
|
||||||
super(ctx, android.R.layout.simple_expandable_list_item_1,
|
super(ctx, android.R.layout.simple_expandable_list_item_1,
|
||||||
new ArrayList<MessageHeader>());
|
new ArrayList<GroupItem>());
|
||||||
pad = LayoutUtils.getPadding(ctx);
|
pad = LayoutUtils.getPadding(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
MessageHeader header = getItem(position);
|
GroupItem item = getItem(position);
|
||||||
|
MessageHeader header = item.getHeader();
|
||||||
Context ctx = getContext();
|
Context ctx = getContext();
|
||||||
|
Resources res = ctx.getResources();
|
||||||
|
|
||||||
LinearLayout layout = new LinearLayout(ctx);
|
LinearLayout headerLayout = new LinearLayout(ctx);
|
||||||
layout.setOrientation(HORIZONTAL);
|
headerLayout.setOrientation(HORIZONTAL);
|
||||||
layout.setGravity(CENTER_VERTICAL);
|
headerLayout.setGravity(CENTER_VERTICAL);
|
||||||
if(!header.isRead()) {
|
int background;
|
||||||
Resources res = ctx.getResources();
|
if(header.isRead()) background = res.getColor(R.color.read_background);
|
||||||
layout.setBackgroundColor(res.getColor(R.color.unread_background));
|
else background = res.getColor(R.color.unread_background);
|
||||||
}
|
headerLayout.setBackgroundColor(background);
|
||||||
|
|
||||||
AuthorView authorView = new AuthorView(ctx);
|
AuthorView authorView = new AuthorView(ctx);
|
||||||
authorView.setLayoutParams(WRAP_WRAP_1);
|
authorView.setLayoutParams(WRAP_WRAP_1);
|
||||||
Author author = header.getAuthor();
|
Author author = header.getAuthor();
|
||||||
if(author == null) authorView.init(null, header.getAuthorStatus());
|
if(author == null) authorView.init(null, header.getAuthorStatus());
|
||||||
else authorView.init(author.getName(), header.getAuthorStatus());
|
else authorView.init(author.getName(), header.getAuthorStatus());
|
||||||
layout.addView(authorView);
|
headerLayout.addView(authorView);
|
||||||
|
|
||||||
|
// FIXME: Factor this out into a TimestampView
|
||||||
TextView date = new TextView(ctx);
|
TextView date = new TextView(ctx);
|
||||||
date.setTextSize(14);
|
date.setTextSize(14);
|
||||||
date.setPadding(0, pad, pad, pad);
|
date.setPadding(0, pad, pad, pad);
|
||||||
long then = header.getTimestamp(), now = System.currentTimeMillis();
|
long then = header.getTimestamp(), now = System.currentTimeMillis();
|
||||||
date.setText(DateUtils.formatSameDayTime(then, now, SHORT, SHORT));
|
date.setText(DateUtils.formatSameDayTime(then, now, SHORT, SHORT));
|
||||||
layout.addView(date);
|
headerLayout.addView(date);
|
||||||
|
|
||||||
return layout;
|
if(!item.isExpanded()) return headerLayout;
|
||||||
|
|
||||||
|
LinearLayout expanded = new LinearLayout(ctx);
|
||||||
|
expanded.setOrientation(VERTICAL);
|
||||||
|
expanded.setGravity(CENTER_HORIZONTAL);
|
||||||
|
expanded.setBackgroundColor(background);
|
||||||
|
expanded.addView(headerLayout);
|
||||||
|
|
||||||
|
byte[] body = item.getBody();
|
||||||
|
if(body == null) {
|
||||||
|
ProgressBar progress = new ProgressBar(ctx);
|
||||||
|
progress.setPadding(pad, 0, pad, pad);
|
||||||
|
progress.setIndeterminate(true);
|
||||||
|
expanded.addView(progress);
|
||||||
|
} else if(header.getContentType().equals("text/plain")) {
|
||||||
|
TextView text = new TextView(ctx);
|
||||||
|
text.setPadding(pad, 0, pad, pad);
|
||||||
|
text.setBackgroundColor(background);
|
||||||
|
text.setText(StringUtils.fromUtf8(body));
|
||||||
|
expanded.addView(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
return expanded;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package org.briarproject.android.groups;
|
||||||
|
|
||||||
|
import org.briarproject.api.db.MessageHeader;
|
||||||
|
|
||||||
|
// This class is not thread-safe
|
||||||
|
class GroupItem {
|
||||||
|
|
||||||
|
private final MessageHeader header;
|
||||||
|
private boolean expanded;
|
||||||
|
private byte[] body;
|
||||||
|
|
||||||
|
GroupItem(MessageHeader header) {
|
||||||
|
this.header = header;
|
||||||
|
expanded = false;
|
||||||
|
body = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageHeader getHeader() {
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isExpanded() {
|
||||||
|
return expanded;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setExpanded(boolean expanded) {
|
||||||
|
this.expanded = expanded;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] getBody() {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBody(byte[] body) {
|
||||||
|
this.body = body;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package org.briarproject.android.groups;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
class GroupItemComparator implements Comparator<GroupItem> {
|
||||||
|
|
||||||
|
static final GroupItemComparator INSTANCE = new GroupItemComparator();
|
||||||
|
|
||||||
|
public int compare(GroupItem a, GroupItem b) {
|
||||||
|
// The oldest message comes first
|
||||||
|
long aTime = a.getHeader().getTimestamp();
|
||||||
|
long bTime = b.getHeader().getTimestamp();
|
||||||
|
if(aTime < bTime) return -1;
|
||||||
|
if(aTime > bTime) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user