session-android/src/org/thoughtcrime/securesms/ConversationFragment.java
Moxie Marlinspike b377fe84df New design for Conversation Activity.
1) Move to Fragments for the list view.
2) Switch to CursorLoader from my jankey self-managed cursor.
3) Add session security logic to the ActionBar.
4) Fix colors to be less ugly.
2012-07-19 14:22:03 -07:00

176 lines
6.3 KiB
Java

package org.thoughtcrime.securesms;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.text.ClipboardManager;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import com.actionbarsherlock.app.SherlockListFragment;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.MessageRecord;
import org.thoughtcrime.securesms.database.loaders.ConversationLoader;
import org.thoughtcrime.securesms.recipients.Recipients;
import java.sql.Date;
import java.text.SimpleDateFormat;
public class ConversationFragment extends SherlockListFragment
implements LoaderManager.LoaderCallbacks<Cursor>
{
private MasterSecret masterSecret;
private Recipients recipients;
private long threadId;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
return inflater.inflate(R.layout.conversation_fragment, container, false);
}
@Override
public void onActivityCreated(Bundle bundle) {
super.onActivityCreated(bundle);
initializeResources();
initializeListAdapter();
registerForContextMenu(getListView());
getLoaderManager().initLoader(0, null, this);
}
@Override
public void onCreateContextMenu (ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
android.view.MenuInflater inflater = this.getSherlockActivity().getMenuInflater();
menu.clear();
inflater.inflate(R.menu.conversation_context, menu);
}
@Override
public boolean onContextItemSelected(android.view.MenuItem item) {
Cursor cursor = ((CursorAdapter)getListAdapter()).getCursor();
ConversationItem conversationItem = (ConversationItem)(((ConversationAdapter)getListAdapter()).newView(getActivity(), cursor, null));
MessageRecord messageRecord = conversationItem.getMessageRecord();
switch(item.getItemId()) {
case R.id.menu_context_copy: handleCopyMessage(messageRecord); return true;
case R.id.menu_context_delete_message: handleDeleteMessage(messageRecord); return true;
case R.id.menu_context_details: handleDisplayDetails(messageRecord); return true;
case R.id.menu_context_forward: handleForwardMessage(messageRecord); return true;
}
return false;
}
private void handleCopyMessage(MessageRecord message) {
String body = message.getBody();
if (body == null) return;
ClipboardManager clipboard = (ClipboardManager)getActivity()
.getSystemService(Context.CLIPBOARD_SERVICE);
clipboard.setText(body);
}
private void handleDeleteMessage(MessageRecord message) {
final long messageId = message.getId();
final String transport = message.isMms() ? "mms" : "sms";
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Delete Message Confirmation");
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setCancelable(true);
builder.setMessage("Are you sure that you want to permanently delete this message?");
builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (transport.equals("mms")) {
DatabaseFactory.getMmsDatabase(getActivity()).delete(messageId);
} else {
DatabaseFactory.getSmsDatabase(getActivity()).deleteMessage(messageId);
}
}
});
builder.setNegativeButton(R.string.no, null);
builder.show();
}
private void handleDisplayDetails(MessageRecord message) {
String sender = message.getRecipients().getPrimaryRecipient().getNumber();
String transport = message.isMms() ? "mms" : "sms";
long date = message.getDate();
SimpleDateFormat dateFormatter = new SimpleDateFormat("EEE MMM d, yyyy 'at' hh:mm:ss a zzz");
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Message Details");
builder.setIcon(android.R.drawable.ic_dialog_info);
builder.setCancelable(false);
builder.setMessage("Sender: " + sender + "\nTransport: " + transport.toUpperCase() +
"\nSent/Received: " + dateFormatter.format(new Date(date)));
builder.setPositiveButton("Ok", null);
builder.show();
}
private void handleForwardMessage(MessageRecord message) {
Intent composeIntent = new Intent(getActivity(), ConversationActivity.class);
composeIntent.putExtra("forwarded_message", message.getBody());
composeIntent.putExtra("master_secret", masterSecret);
startActivity(composeIntent);
}
private void initializeResources() {
this.masterSecret = (MasterSecret)this.getActivity().getIntent()
.getParcelableExtra("master_secret");
this.recipients = this.getActivity().getIntent().getParcelableExtra("recipients");
this.threadId = this.getActivity().getIntent().getLongExtra("thread_id", -1);
}
private void initializeListAdapter() {
if (this.recipients != null && this.threadId != -1) {
this.setListAdapter(new ConversationAdapter(recipients, threadId, getActivity(), masterSecret, new FailedIconClickHandler()));
}
}
@Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
if (this.threadId != -1) {
return new ConversationLoader(getActivity(), threadId);
} else {
return null;
}
}
@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor cursor) {
((CursorAdapter)getListAdapter()).changeCursor(cursor);
}
@Override
public void onLoaderReset(Loader<Cursor> arg0) {
((CursorAdapter)getListAdapter()).changeCursor(null);
}
private class FailedIconClickHandler extends Handler {
@Override
public void handleMessage(android.os.Message message) {
assert(false);
// String failedMessageText = (String)message.obj;
// ConversationActivity.this.composeText.setText(failedMessageText);
}
}
}