mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-18 21:59:54 +01:00
Show connection indicator and last connection time in contact list.
This commit is contained in:
@@ -6,6 +6,8 @@
|
|||||||
<string name="contact_list_button">Contacts</string>
|
<string name="contact_list_button">Contacts</string>
|
||||||
<string name="quit_button">Quit</string>
|
<string name="quit_button">Quit</string>
|
||||||
<string name="contact_list_title">Contacts</string>
|
<string name="contact_list_title">Contacts</string>
|
||||||
|
<string name="contact_connected">Connected</string>
|
||||||
|
<string name="contact_last_connected">Last connected <br /> %s</string>
|
||||||
<string name="add_contact_button">Add a contact</string>
|
<string name="add_contact_button">Add a contact</string>
|
||||||
<string name="add_contact_title">Add a Contact</string>
|
<string name="add_contact_title">Add a Contact</string>
|
||||||
<string name="same_network">Briar can add contacts via Wi-Fi or Bluetooth. For security reasons, you must be face-to-face to add someone as a contact. To use Wi-Fi you must both be connected to the same network.</string>
|
<string name="same_network">Briar can add contacts via Wi-Fi or Bluetooth. For security reasons, you must be face-to-face to add someone as a contact. To use Wi-Fi you must both be connected to the same network.</string>
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ import android.view.View;
|
|||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.LinearLayout.LayoutParams;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.RelativeLayout.LayoutParams;
|
|
||||||
|
|
||||||
public class HomeScreenActivity extends BriarActivity
|
public class HomeScreenActivity extends BriarActivity
|
||||||
implements OnClickListener {
|
implements OnClickListener {
|
||||||
|
|||||||
@@ -7,9 +7,7 @@ import static android.widget.LinearLayout.VERTICAL;
|
|||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@@ -25,6 +23,7 @@ import net.sf.briar.api.db.DatabaseComponent;
|
|||||||
import net.sf.briar.api.db.DatabaseExecutor;
|
import net.sf.briar.api.db.DatabaseExecutor;
|
||||||
import net.sf.briar.api.db.DbException;
|
import net.sf.briar.api.db.DbException;
|
||||||
import net.sf.briar.api.db.event.ContactAddedEvent;
|
import net.sf.briar.api.db.event.ContactAddedEvent;
|
||||||
|
import net.sf.briar.api.db.event.ContactRemovedEvent;
|
||||||
import net.sf.briar.api.db.event.DatabaseEvent;
|
import net.sf.briar.api.db.event.DatabaseEvent;
|
||||||
import net.sf.briar.api.db.event.DatabaseListener;
|
import net.sf.briar.api.db.event.DatabaseListener;
|
||||||
import net.sf.briar.api.transport.ConnectionListener;
|
import net.sf.briar.api.transport.ConnectionListener;
|
||||||
@@ -37,8 +36,8 @@ import android.view.View.OnClickListener;
|
|||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.LinearLayout.LayoutParams;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
import android.widget.RelativeLayout.LayoutParams;
|
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
@@ -47,7 +46,6 @@ implements OnClickListener, DatabaseListener, ConnectionListener {
|
|||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(ContactListActivity.class.getName());
|
Logger.getLogger(ContactListActivity.class.getName());
|
||||||
private static final ItemComparator COMPARATOR = new ItemComparator();
|
|
||||||
|
|
||||||
private final BriarServiceConnection serviceConnection =
|
private final BriarServiceConnection serviceConnection =
|
||||||
new BriarServiceConnection();
|
new BriarServiceConnection();
|
||||||
@@ -67,10 +65,10 @@ implements OnClickListener, DatabaseListener, ConnectionListener {
|
|||||||
layout.setOrientation(VERTICAL);
|
layout.setOrientation(VERTICAL);
|
||||||
layout.setGravity(CENTER_HORIZONTAL);
|
layout.setGravity(CENTER_HORIZONTAL);
|
||||||
|
|
||||||
adapter = new ArrayAdapter<ContactListItem>(this,
|
adapter = new ContactListAdapter(this);
|
||||||
android.R.layout.simple_expandable_list_item_1,
|
|
||||||
new ArrayList<ContactListItem>());
|
|
||||||
ListView listView = new ListView(this);
|
ListView listView = new ListView(this);
|
||||||
|
listView.setLayoutParams(new LayoutParams(MATCH_PARENT, WRAP_CONTENT,
|
||||||
|
1f));
|
||||||
listView.setAdapter(adapter);
|
listView.setAdapter(adapter);
|
||||||
layout.addView(listView);
|
layout.addView(listView);
|
||||||
|
|
||||||
@@ -85,14 +83,13 @@ implements OnClickListener, DatabaseListener, ConnectionListener {
|
|||||||
|
|
||||||
setContentView(layout);
|
setContentView(layout);
|
||||||
|
|
||||||
// Listen for database events and connection events
|
// Listen for contacts being added or removed
|
||||||
db.addListener(this);
|
db.addListener(this);
|
||||||
|
// Listen for contacts connecting or disconnecting
|
||||||
connectionRegistry.addListener(this);
|
connectionRegistry.addListener(this);
|
||||||
|
// Bind to the service so we can wait for the DB to be opened
|
||||||
// Bind to the service
|
|
||||||
bindService(new Intent(BriarService.class.getName()),
|
bindService(new Intent(BriarService.class.getName()),
|
||||||
serviceConnection, 0);
|
serviceConnection, 0);
|
||||||
|
|
||||||
// Load the contact list from the DB
|
// Load the contact list from the DB
|
||||||
reloadContactList();
|
reloadContactList();
|
||||||
|
|
||||||
@@ -105,9 +102,12 @@ implements OnClickListener, DatabaseListener, ConnectionListener {
|
|||||||
IBinder binder = serviceConnection.waitForBinder();
|
IBinder binder = serviceConnection.waitForBinder();
|
||||||
((BriarBinder) binder).getService().waitForStartup();
|
((BriarBinder) binder).getService().waitForStartup();
|
||||||
if(LOG.isLoggable(INFO)) LOG.info("Service started");
|
if(LOG.isLoggable(INFO)) LOG.info("Service started");
|
||||||
// Insert a couple of fake contacts
|
Collection<Contact> contacts = db.getContacts();
|
||||||
db.addContact("Alice");
|
if(contacts.isEmpty()) {
|
||||||
db.addContact("Bob");
|
// Insert a couple of fake contacts
|
||||||
|
db.addContact("Alice");
|
||||||
|
db.addContact("Bob");
|
||||||
|
}
|
||||||
} 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);
|
||||||
@@ -134,6 +134,7 @@ implements OnClickListener, DatabaseListener, ConnectionListener {
|
|||||||
|
|
||||||
public void eventOccurred(DatabaseEvent e) {
|
public void eventOccurred(DatabaseEvent e) {
|
||||||
if(e instanceof ContactAddedEvent) reloadContactList();
|
if(e instanceof ContactAddedEvent) reloadContactList();
|
||||||
|
else if(e instanceof ContactRemovedEvent) reloadContactList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reloadContactList() {
|
private void reloadContactList() {
|
||||||
@@ -148,11 +149,7 @@ implements OnClickListener, DatabaseListener, ConnectionListener {
|
|||||||
if(LOG.isLoggable(INFO))
|
if(LOG.isLoggable(INFO))
|
||||||
LOG.info("Loaded " + contacts.size() + " contacts");
|
LOG.info("Loaded " + contacts.size() + " contacts");
|
||||||
// Update the contact list
|
// Update the contact list
|
||||||
runOnUiThread(new Runnable() {
|
updateContactList(contacts);
|
||||||
public void run() {
|
|
||||||
updateContactList(contacts);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} 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);
|
||||||
@@ -165,14 +162,17 @@ implements OnClickListener, DatabaseListener, ConnectionListener {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// UI thread
|
private void updateContactList(final Collection<Contact> contacts) {
|
||||||
private void updateContactList(Collection<Contact> contacts) {
|
runOnUiThread(new Runnable() {
|
||||||
adapter.clear();
|
public void run() {
|
||||||
for(Contact c : contacts) {
|
adapter.clear();
|
||||||
boolean connected = connectionRegistry.isConnected(c.getId());
|
for(Contact c : contacts) {
|
||||||
adapter.add(new ContactListItem(c, connected));
|
boolean conn = connectionRegistry.isConnected(c.getId());
|
||||||
}
|
adapter.add(new ContactListItem(c, conn));
|
||||||
adapter.sort(COMPARATOR);
|
}
|
||||||
|
adapter.sort(ContactListItem.COMPARATOR);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void contactConnected(final ContactId c) {
|
public void contactConnected(final ContactId c) {
|
||||||
@@ -189,37 +189,12 @@ implements OnClickListener, DatabaseListener, ConnectionListener {
|
|||||||
int count = adapter.getCount();
|
int count = adapter.getCount();
|
||||||
for(int i = 0; i < count; i++) {
|
for(int i = 0; i < count; i++) {
|
||||||
ContactListItem item = adapter.getItem(i);
|
ContactListItem item = adapter.getItem(i);
|
||||||
if(item.contact.getId().equals(c)) {
|
if(item.getContactId().equals(c)) {
|
||||||
item.connected = connected;
|
item.setConnected(connected);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ItemComparator implements Comparator<ContactListItem> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compare(ContactListItem a, ContactListItem b) {
|
|
||||||
return String.CASE_INSENSITIVE_ORDER.compare(a.contact.getName(),
|
|
||||||
b.contact.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ContactListItem {
|
|
||||||
|
|
||||||
private final Contact contact;
|
|
||||||
private boolean connected; // UI thread
|
|
||||||
|
|
||||||
private ContactListItem(Contact contact, boolean connected) {
|
|
||||||
this.contact = contact;
|
|
||||||
this.connected = connected;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return contact.getName() + " (" + connected + ")";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package net.sf.briar.android.contact;
|
||||||
|
|
||||||
|
import static android.view.Gravity.CENTER;
|
||||||
|
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||||
|
import static android.widget.LinearLayout.HORIZONTAL;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import net.sf.briar.R;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.Html;
|
||||||
|
import android.text.format.DateUtils;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.LinearLayout.LayoutParams;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
public class ContactListAdapter extends ArrayAdapter<ContactListItem> {
|
||||||
|
|
||||||
|
public ContactListAdapter(Context context) {
|
||||||
|
super(context, android.R.layout.simple_expandable_list_item_1,
|
||||||
|
new ArrayList<ContactListItem>());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
|
ContactListItem item = getItem(position);
|
||||||
|
Context ctx = getContext();
|
||||||
|
LinearLayout layout = new LinearLayout(ctx);
|
||||||
|
layout.setOrientation(HORIZONTAL);
|
||||||
|
layout.setGravity(CENTER);
|
||||||
|
|
||||||
|
ImageView bulb = new ImageView(ctx);
|
||||||
|
if(item.getConnected()) bulb.setImageResource(R.drawable.green_bulb);
|
||||||
|
else bulb.setImageResource(R.drawable.grey_bulb);
|
||||||
|
bulb.setPadding(5, 0, 5, 0);
|
||||||
|
layout.addView(bulb);
|
||||||
|
|
||||||
|
TextView name = new TextView(ctx);
|
||||||
|
name.setLayoutParams(new LayoutParams(WRAP_CONTENT, WRAP_CONTENT, 1f));
|
||||||
|
name.setTextSize(18);
|
||||||
|
name.setText(item.getName());
|
||||||
|
layout.addView(name);
|
||||||
|
|
||||||
|
TextView connected = new TextView(ctx);
|
||||||
|
connected.setTextSize(12);
|
||||||
|
connected.setPadding(5, 0, 5, 0);
|
||||||
|
if(item.getConnected()) {
|
||||||
|
connected.setText(R.string.contact_connected);
|
||||||
|
} else {
|
||||||
|
String format = ctx.getResources().getString(
|
||||||
|
R.string.contact_last_connected);
|
||||||
|
long then = item.getLastConnected();
|
||||||
|
CharSequence ago = DateUtils.getRelativeTimeSpanString(then);
|
||||||
|
connected.setText(Html.fromHtml(String.format(format, ago)));
|
||||||
|
}
|
||||||
|
layout.addView(connected);
|
||||||
|
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package net.sf.briar.android.contact;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
import net.sf.briar.api.Contact;
|
||||||
|
import net.sf.briar.api.ContactId;
|
||||||
|
|
||||||
|
// This class is not thread-safe
|
||||||
|
class ContactListItem {
|
||||||
|
|
||||||
|
static Comparator<ContactListItem> COMPARATOR = new ItemComparator();
|
||||||
|
|
||||||
|
private final Contact contact;
|
||||||
|
private boolean connected;
|
||||||
|
|
||||||
|
ContactListItem(Contact contact, boolean connected) {
|
||||||
|
this.contact = contact;
|
||||||
|
this.connected = connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
ContactId getContactId() {
|
||||||
|
return contact.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
String getName() {
|
||||||
|
return contact.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
long getLastConnected() {
|
||||||
|
return contact.getLastConnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean getConnected() {
|
||||||
|
return connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setConnected(boolean connected) {
|
||||||
|
this.connected = connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ItemComparator implements Comparator<ContactListItem> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(ContactListItem a, ContactListItem b) {
|
||||||
|
return String.CASE_INSENSITIVE_ORDER.compare(a.contact.getName(),
|
||||||
|
b.contact.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user