mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 18:59:06 +01:00
Improved ConversationActivity (bug #32), but it's still not quite there.
GroupActivity needs to receive a similar treatment.
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
<color name="home_screen_background">#FFFFFF</color>
|
||||
<color name="content_background">#FFFFFF</color>
|
||||
<color name="unread_background">#FFFFFF</color>
|
||||
<color name="read_background">#EEEEEE</color>
|
||||
<color name="horizontal_border">#CCCCCC</color>
|
||||
<color name="no_posts">#AAAAAA</color>
|
||||
<color name="no_messages">#AAAAAA</color>
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.briarproject.api.db.DatabaseComponent;
|
||||
import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.db.MessageHeader;
|
||||
import org.briarproject.api.db.NoSuchContactException;
|
||||
import org.briarproject.api.db.NoSuchMessageException;
|
||||
import org.briarproject.api.event.ContactRemovedEvent;
|
||||
import org.briarproject.api.event.Event;
|
||||
import org.briarproject.api.event.EventListener;
|
||||
@@ -34,6 +35,7 @@ import org.briarproject.api.event.MessageAddedEvent;
|
||||
import org.briarproject.api.event.MessageExpiredEvent;
|
||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.api.messaging.GroupId;
|
||||
import org.briarproject.api.messaging.MessageId;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
@@ -131,15 +133,11 @@ implements EventListener, OnClickListener, OnItemClickListener {
|
||||
db.getInboxMessageHeaders(contactId);
|
||||
long duration = System.currentTimeMillis() - now;
|
||||
if(LOG.isLoggable(INFO))
|
||||
LOG.info("Load took " + duration + " ms");
|
||||
LOG.info("Loading headers took " + duration + " ms");
|
||||
displayHeaders(headers);
|
||||
} catch(NoSuchContactException e) {
|
||||
if(LOG.isLoggable(INFO)) LOG.info("Contact removed");
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
finishOnUiThread();
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
@@ -163,21 +161,83 @@ implements EventListener, OnClickListener, OnItemClickListener {
|
||||
adapter.add(new ConversationItem(h));
|
||||
adapter.sort(ConversationItemComparator.INSTANCE);
|
||||
adapter.notifyDataSetChanged();
|
||||
selectFirstUnread();
|
||||
expandMessages();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void selectFirstUnread() {
|
||||
int firstUnread = -1, count = adapter.getCount();
|
||||
private void expandMessages() {
|
||||
// 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++) {
|
||||
if(!adapter.getItem(i).getHeader().isRead()) {
|
||||
firstUnread = i;
|
||||
break;
|
||||
ConversationItem item = adapter.getItem(i);
|
||||
if(!item.getHeader().isRead() || i >= count - 3) {
|
||||
if(firstExpanded == -1) firstExpanded = i;
|
||||
item.setExpanded(true);
|
||||
loadMessage(item.getHeader());
|
||||
}
|
||||
}
|
||||
if(firstUnread == -1) list.setSelection(count - 1);
|
||||
else list.setSelection(firstUnread);
|
||||
// Scroll to the first expanded message
|
||||
if(firstExpanded == -1) list.setSelection(count - 1);
|
||||
else 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++) {
|
||||
ConversationItem 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
|
||||
@@ -201,11 +261,7 @@ implements EventListener, OnClickListener, OnItemClickListener {
|
||||
ContactRemovedEvent c = (ContactRemovedEvent) e;
|
||||
if(c.getContactId().equals(contactId)) {
|
||||
if(LOG.isLoggable(INFO)) LOG.info("Contact removed");
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
finishOnUiThread();
|
||||
}
|
||||
} else if(e instanceof MessageAddedEvent) {
|
||||
GroupId g = ((MessageAddedEvent) e).getGroup().getId();
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package org.briarproject.android.contact;
|
||||
|
||||
import static android.view.Gravity.CENTER_HORIZONTAL;
|
||||
import static android.view.Gravity.CENTER_VERTICAL;
|
||||
import static android.widget.LinearLayout.HORIZONTAL;
|
||||
import static android.widget.LinearLayout.VERTICAL;
|
||||
import static java.text.DateFormat.SHORT;
|
||||
import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP_1;
|
||||
import static org.briarproject.api.Author.Status.VERIFIED;
|
||||
@@ -12,6 +14,7 @@ import org.briarproject.R;
|
||||
import org.briarproject.android.util.AuthorView;
|
||||
import org.briarproject.android.util.LayoutUtils;
|
||||
import org.briarproject.api.db.MessageHeader;
|
||||
import org.briarproject.util.StringUtils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
@@ -20,6 +23,7 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
class ConversationAdapter extends ArrayAdapter<ConversationItem> {
|
||||
@@ -34,29 +38,53 @@ class ConversationAdapter extends ArrayAdapter<ConversationItem> {
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
MessageHeader header = getItem(position).getHeader();
|
||||
ConversationItem item = getItem(position);
|
||||
MessageHeader header = item.getHeader();
|
||||
Context ctx = getContext();
|
||||
Resources res = ctx.getResources();
|
||||
|
||||
LinearLayout layout = new LinearLayout(ctx);
|
||||
layout.setOrientation(HORIZONTAL);
|
||||
layout.setGravity(CENTER_VERTICAL);
|
||||
if(!header.isRead()) {
|
||||
Resources res = ctx.getResources();
|
||||
layout.setBackgroundColor(res.getColor(R.color.unread_background));
|
||||
}
|
||||
LinearLayout headerLayout = new LinearLayout(ctx);
|
||||
headerLayout.setOrientation(HORIZONTAL);
|
||||
headerLayout.setGravity(CENTER_VERTICAL);
|
||||
int background;
|
||||
if(header.isRead()) background = res.getColor(R.color.read_background);
|
||||
else background = res.getColor(R.color.unread_background);
|
||||
headerLayout.setBackgroundColor(background);
|
||||
|
||||
AuthorView authorView = new AuthorView(ctx);
|
||||
authorView.setLayoutParams(WRAP_WRAP_1);
|
||||
authorView.init(header.getAuthor().getName(), VERIFIED);
|
||||
layout.addView(authorView);
|
||||
headerLayout.addView(authorView);
|
||||
|
||||
TextView date = new TextView(ctx);
|
||||
date.setTextSize(14);
|
||||
date.setPadding(0, pad, pad, pad);
|
||||
long then = header.getTimestamp(), now = System.currentTimeMillis();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,6 @@ import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP_1;
|
||||
import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP_1;
|
||||
import static org.briarproject.api.Author.Status.VERIFIED;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -32,6 +31,7 @@ import org.briarproject.api.db.NoSuchMessageException;
|
||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.api.messaging.GroupId;
|
||||
import org.briarproject.api.messaging.MessageId;
|
||||
import org.briarproject.util.StringUtils;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
@@ -227,7 +227,7 @@ implements OnClickListener {
|
||||
long duration = System.currentTimeMillis() - now;
|
||||
if(LOG.isLoggable(INFO))
|
||||
LOG.info("Loading message took " + duration + " ms");
|
||||
final String text = new String(body, "UTF-8");
|
||||
final String text = StringUtils.fromUtf8(body);
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
content.setText(text);
|
||||
@@ -247,8 +247,6 @@ implements OnClickListener {
|
||||
if(LOG.isLoggable(INFO))
|
||||
LOG.info("Interrupted while waiting for database");
|
||||
Thread.currentThread().interrupt();
|
||||
} catch(UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -14,7 +14,6 @@ import static java.util.logging.Level.WARNING;
|
||||
import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.logging.Logger;
|
||||
@@ -39,6 +38,7 @@ import org.briarproject.api.messaging.GroupId;
|
||||
import org.briarproject.api.messaging.Message;
|
||||
import org.briarproject.api.messaging.MessageFactory;
|
||||
import org.briarproject.api.messaging.MessageId;
|
||||
import org.briarproject.util.StringUtils;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
@@ -194,11 +194,7 @@ implements OnClickListener {
|
||||
|
||||
public void onClick(View view) {
|
||||
if(localAuthor == null) throw new IllegalStateException();
|
||||
try {
|
||||
createMessage(content.getText().toString().getBytes("UTF-8"));
|
||||
} catch(UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
createMessage(StringUtils.toUtf8(content.getText().toString()));
|
||||
Toast.makeText(this, R.string.message_sent_toast, LENGTH_LONG).show();
|
||||
finish();
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import static org.briarproject.android.util.CommonLayoutParams.MATCH_MATCH;
|
||||
import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP;
|
||||
import static org.briarproject.api.messaging.MessagingConstants.MAX_GROUP_NAME_LENGTH;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.Executor;
|
||||
@@ -35,6 +34,7 @@ import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.api.messaging.Group;
|
||||
import org.briarproject.api.messaging.GroupFactory;
|
||||
import org.briarproject.util.StringUtils;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
@@ -245,12 +245,8 @@ SelectContactsDialog.Listener {
|
||||
|
||||
private boolean validateName() {
|
||||
if(nameEntry.getText().length() == 0) return false;
|
||||
try {
|
||||
byte[] b = nameEntry.getText().toString().getBytes("UTF-8");
|
||||
if(b.length > MAX_GROUP_NAME_LENGTH) return false;
|
||||
} catch(UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
byte[] b = StringUtils.toUtf8(nameEntry.getText().toString());
|
||||
if(b.length > MAX_GROUP_NAME_LENGTH) return false;
|
||||
// Hide the soft keyboard
|
||||
Object o = getSystemService(INPUT_METHOD_SERVICE);
|
||||
((InputMethodManager) o).toggleSoftInput(HIDE_IMPLICIT_ONLY, 0);
|
||||
|
||||
@@ -11,7 +11,6 @@ import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP;
|
||||
import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP_1;
|
||||
import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP_1;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -31,6 +30,7 @@ import org.briarproject.api.db.NoSuchMessageException;
|
||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.api.messaging.GroupId;
|
||||
import org.briarproject.api.messaging.MessageId;
|
||||
import org.briarproject.util.StringUtils;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
@@ -223,7 +223,7 @@ implements OnClickListener {
|
||||
long duration = System.currentTimeMillis() - now;
|
||||
if(LOG.isLoggable(INFO))
|
||||
LOG.info("Loading message took " + duration + " ms");
|
||||
final String text = new String(body, "UTF-8");
|
||||
final String text = StringUtils.fromUtf8(body);
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
content.setText(text);
|
||||
@@ -243,8 +243,6 @@ implements OnClickListener {
|
||||
if(LOG.isLoggable(INFO))
|
||||
LOG.info("Interrupted while waiting for database");
|
||||
Thread.currentThread().interrupt();
|
||||
} catch(UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -15,7 +15,6 @@ import static java.util.logging.Level.WARNING;
|
||||
import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.Executor;
|
||||
@@ -46,6 +45,7 @@ import org.briarproject.api.messaging.GroupId;
|
||||
import org.briarproject.api.messaging.Message;
|
||||
import org.briarproject.api.messaging.MessageFactory;
|
||||
import org.briarproject.api.messaging.MessageId;
|
||||
import org.briarproject.util.StringUtils;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
@@ -269,11 +269,7 @@ implements OnItemSelectedListener, OnClickListener {
|
||||
|
||||
public void onClick(View view) {
|
||||
if(group == null) throw new IllegalStateException();
|
||||
try {
|
||||
createMessage(content.getText().toString().getBytes("UTF-8"));
|
||||
} catch(UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
createMessage(StringUtils.toUtf8(content.getText().toString()));
|
||||
Toast.makeText(this, R.string.post_sent_toast, LENGTH_LONG).show();
|
||||
finish();
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import static org.briarproject.android.util.CommonLayoutParams.MATCH_MATCH;
|
||||
import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP;
|
||||
import static org.briarproject.api.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -32,6 +31,7 @@ import org.briarproject.api.crypto.KeyPair;
|
||||
import org.briarproject.api.db.DatabaseComponent;
|
||||
import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.util.StringUtils;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
@@ -138,12 +138,8 @@ implements OnEditorActionListener, OnClickListener {
|
||||
|
||||
private boolean validateNickname() {
|
||||
if(nicknameEntry.getText().length() == 0) return false;
|
||||
try {
|
||||
byte[] b = nicknameEntry.getText().toString().getBytes("UTF-8");
|
||||
if(b.length > MAX_AUTHOR_NAME_LENGTH) return false;
|
||||
} catch(UnsupportedEncodingException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
byte[] b = StringUtils.toUtf8(nicknameEntry.getText().toString());
|
||||
if(b.length > MAX_AUTHOR_NAME_LENGTH) return false;
|
||||
// Hide the soft keyboard
|
||||
Object o = getSystemService(INPUT_METHOD_SERVICE);
|
||||
((InputMethodManager) o).toggleSoftInput(HIDE_IMPLICIT_ONLY, 0);
|
||||
|
||||
Reference in New Issue
Block a user