Android UI for writing private messages (text only for now).

This commit is contained in:
akwizgran
2013-03-05 01:57:15 +00:00
parent 666499337c
commit f549b6d818
9 changed files with 189 additions and 74 deletions

View File

@@ -52,5 +52,9 @@
android:name=".android.messages.ReadMessageActivity"
android:label="@string/messages_title" >
</activity>
<activity
android:name=".android.messages.WriteMessageActivity"
android:label="@string/compose_title" >
</activity>
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -43,4 +43,5 @@
<string name="done_button">Done</string>
<string name="messages_title">Messages</string>
<string name="compose_button">New Message</string>
<string name="compose_title">New Message</string>
</resources>

View File

@@ -165,13 +165,17 @@ implements DatabaseListener, OnClickListener, OnItemClickListener {
}
public void onClick(View view) {
// FIXME: Hook this button up to an activity
Intent i = new Intent(this, WriteMessageActivity.class);
i.putExtra("net.sf.briar.CONTACT_ID", contactId.getInt());
i.putExtra("net.sf.briar.CONTACT_NAME", contactName);
startActivity(i);
}
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
PrivateMessageHeader item = adapter.getItem(position);
Intent i = new Intent(this, ReadMessageActivity.class);
i.putExtra("net.sf.briar.CONTACT_ID", contactId.getInt());
i.putExtra("net.sf.briar.CONTACT_NAME", contactName);
i.putExtra("net.sf.briar.MESSAGE_ID", item.getId().getBytes());
i.putExtra("net.sf.briar.CONTENT_TYPE", item.getContentType());

View File

@@ -1,67 +0,0 @@
package net.sf.briar.android.messages;
import net.sf.briar.api.db.PrivateMessageHeader;
import net.sf.briar.api.messaging.MessageId;
class ConversationItem {
private final PrivateMessageHeader header;
private final byte[] body;
private final boolean expanded;
ConversationItem(PrivateMessageHeader header) {
this.header = header;
body = null;
expanded = false;
}
// Collapse an existing item
ConversationItem(ConversationItem item) {
this.header = item.header;
body = null;
expanded = false;
}
// Expand an existing item
ConversationItem(ConversationItem item, byte[] body) {
this.header = item.header;
this.body = body;
expanded = true;
}
MessageId getId() {
return header.getId();
}
String getContentType() {
return header.getContentType();
}
String getSubject() {
return header.getSubject();
}
long getTimestamp() {
return header.getTimestamp();
}
boolean isRead() {
return header.isRead();
}
boolean isStarred() {
return header.isStarred();
}
boolean isIncoming() {
return header.isIncoming();
}
byte[] getBody() {
return body;
}
boolean isExpanded() {
return expanded;
}
}

View File

@@ -18,6 +18,7 @@ import net.sf.briar.R;
import net.sf.briar.android.BriarActivity;
import net.sf.briar.android.BriarService;
import net.sf.briar.android.BriarService.BriarServiceConnection;
import net.sf.briar.api.ContactId;
import net.sf.briar.api.db.DatabaseComponent;
import net.sf.briar.api.db.DatabaseExecutor;
import net.sf.briar.api.db.DbException;
@@ -47,6 +48,8 @@ implements OnClickListener {
@Inject private DatabaseComponent db;
@Inject @DatabaseExecutor private Executor dbExecutor;
private ContactId contactId = null;
private String contactName = null;
private MessageId messageId = null;
private boolean starred = false;
private ImageButton starButton = null, replyButton = null;
@@ -57,12 +60,15 @@ implements OnClickListener {
super.onCreate(null);
Intent i = getIntent();
String contactName = i.getStringExtra("net.sf.briar.CONTACT_NAME");
int cid = i.getIntExtra("net.sf.briar.CONTACT_ID", -1);
if(cid == -1) throw new IllegalStateException();
contactId = new ContactId(cid);
contactName = i.getStringExtra("net.sf.briar.CONTACT_NAME");
if(contactName == null) throw new IllegalStateException();
setTitle(contactName);
byte[] id = i.getByteArrayExtra("net.sf.briar.MESSAGE_ID");
if(id == null) throw new IllegalStateException();
messageId = new MessageId(id);
byte[] mid = i.getByteArrayExtra("net.sf.briar.MESSAGE_ID");
if(mid == null) throw new IllegalStateException();
messageId = new MessageId(mid);
String contentType = i.getStringExtra("net.sf.briar.CONTENT_TYPE");
if(contentType == null) throw new IllegalStateException();
long timestamp = i.getLongExtra("net.sf.briar.TIMESTAMP", -1);
@@ -181,7 +187,6 @@ implements OnClickListener {
unbindService(serviceConnection);
}
@Override
public void onClick(View view) {
if(view == starButton) {
final MessageId id = messageId;
@@ -201,7 +206,11 @@ implements OnClickListener {
starButton.setImageResource(R.drawable.rating_important);
else starButton.setImageResource(R.drawable.rating_not_important);
} else if(view == replyButton) {
// FIXME: Hook this up to an activity
Intent i = new Intent(this, WriteMessageActivity.class);
i.putExtra("net.sf.briar.CONTACT_ID", contactId.getInt());
i.putExtra("net.sf.briar.CONTACT_NAME", contactName);
i.putExtra("net.sf.briar.PARENT_ID", messageId.getBytes());
startActivity(i);
}
}
}

View File

@@ -0,0 +1,164 @@
package net.sf.briar.android.messages;
import static android.view.Gravity.CENTER_VERTICAL;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static android.widget.LinearLayout.HORIZONTAL;
import static android.widget.LinearLayout.VERTICAL;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
import net.sf.briar.R;
import net.sf.briar.android.BriarActivity;
import net.sf.briar.android.BriarService;
import net.sf.briar.android.BriarService.BriarServiceConnection;
import net.sf.briar.api.ContactId;
import net.sf.briar.api.android.BundleEncrypter;
import net.sf.briar.api.db.DatabaseComponent;
import net.sf.briar.api.db.DatabaseExecutor;
import net.sf.briar.api.db.DbException;
import net.sf.briar.api.messaging.Message;
import net.sf.briar.api.messaging.MessageFactory;
import net.sf.briar.api.messaging.MessageId;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.ScrollView;
import com.google.inject.Inject;
public class WriteMessageActivity extends BriarActivity
implements OnClickListener {
private static final Logger LOG =
Logger.getLogger(WriteMessageActivity.class.getName());
private final BriarServiceConnection serviceConnection =
new BriarServiceConnection();
@Inject private BundleEncrypter bundleEncrypter;
@Inject private DatabaseComponent db;
@Inject @DatabaseExecutor private Executor dbExecutor;
@Inject private MessageFactory messageFactory;
private ContactId contactId = null;
private String contactName = null;
private MessageId parentId = null;
private ImageButton cancelButton = null, sendButton = null;
private EditText content = null;
@Override
public void onCreate(Bundle state) {
super.onCreate(null);
Intent i = getIntent();
int cid = i.getIntExtra("net.sf.briar.CONTACT_ID", -1);
if(cid == -1) throw new IllegalStateException();
contactId = new ContactId(cid);
contactName = i.getStringExtra("net.sf.briar.CONTACT_NAME");
if(contactName == null) throw new IllegalStateException();
byte[] pid = i.getByteArrayExtra("net.sf.briar.MESSAGE_ID");
if(pid != null) parentId = new MessageId(pid);
LinearLayout layout = new LinearLayout(this);
layout.setLayoutParams(new LayoutParams(MATCH_PARENT, WRAP_CONTENT));
layout.setOrientation(VERTICAL);
LinearLayout header = new LinearLayout(this);
header.setLayoutParams(new LayoutParams(MATCH_PARENT, WRAP_CONTENT));
header.setOrientation(HORIZONTAL);
header.setGravity(CENTER_VERTICAL);
cancelButton = new ImageButton(this);
cancelButton.setPadding(5, 5, 5, 5);
cancelButton.setBackgroundResource(0);
cancelButton.setImageResource(R.drawable.navigation_cancel);
cancelButton.setOnClickListener(this);
header.addView(cancelButton);
sendButton = new ImageButton(this);
sendButton.setPadding(5, 5, 5, 5);
sendButton.setBackgroundResource(0);
sendButton.setImageResource(R.drawable.social_send_now);
sendButton.setOnClickListener(this);
header.addView(sendButton);
layout.addView(header);
ScrollView scrollView = new ScrollView(this);
content = new EditText(this);
content.setPadding(10, 10, 10, 10);
if(state != null && bundleEncrypter.decrypt(state)) {
Parcelable p = state.getParcelable("net.sf.briar.CONTENT");
if(p != null) content.onRestoreInstanceState(p);
}
scrollView.addView(content);
layout.addView(scrollView);
setContentView(layout);
// Bind to the service so we can wait for the DB to be opened
bindService(new Intent(BriarService.class.getName()),
serviceConnection, 0);
}
@Override
public void onSaveInstanceState(Bundle state) {
Parcelable p = content.onSaveInstanceState();
state.putParcelable("net.sf.briar.CONTENT", p);
bundleEncrypter.encrypt(state);
}
@Override
public void onDestroy() {
super.onDestroy();
unbindService(serviceConnection);
}
public void onClick(View view) {
if(view == cancelButton) {
finish();
} else if(view == sendButton) {
final Message m;
try {
byte[] body = content.getText().toString().getBytes("UTF-8");
m = messageFactory.createPrivateMessage(parentId,
"text/plain", body);
} catch(UnsupportedEncodingException e) {
throw new RuntimeException(e);
} catch(IOException e) {
throw new RuntimeException(e);
} catch(GeneralSecurityException e) {
throw new RuntimeException(e);
}
final ContactId contactId = this.contactId;
dbExecutor.execute(new Runnable() {
public void run() {
try {
serviceConnection.waitForStartup();
db.addLocalPrivateMessage(m, contactId);
} 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 service");
Thread.currentThread().interrupt();
}
}
});
finish();
}
}
}