Restyle conversation list view.
1. New look for quick contact badges. 2. No more unread indicator, replace with bolded text. 3. Style message count with color rather than parens. 4. Remove "New Message" item, add as item in action bar instead.
|
@ -13,6 +13,7 @@
|
|||
<activity android:name=".SecureSMS"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTask"
|
||||
android:uiOptions="splitActionBarWhenNarrow"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout"
|
||||
>
|
||||
<intent-filter>
|
||||
|
|
BIN
res/drawable-hdpi/ic_menu_msg_compose_holo_dark.png
Normal file
After Width: | Height: | Size: 844 B |
BIN
res/drawable-hdpi/ic_menu_search_holo_dark.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
res/drawable-hdpi/ic_menu_trash_holo_dark.png
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
res/drawable-mdpi/ic_menu_msg_compose_holo_dark.png
Normal file
After Width: | Height: | Size: 669 B |
BIN
res/drawable-mdpi/ic_menu_search_holo_dark.png
Normal file
After Width: | Height: | Size: 881 B |
BIN
res/drawable-mdpi/ic_menu_trash_holo_dark.png
Normal file
After Width: | Height: | Size: 790 B |
BIN
res/drawable-xhdpi/ic_menu_msg_compose_holo_dark.png
Normal file
After Width: | Height: | Size: 961 B |
BIN
res/drawable-xhdpi/ic_menu_search_holo_dark.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
res/drawable-xhdpi/ic_menu_trash_holo_dark.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 265 B |
|
@ -5,21 +5,10 @@
|
|||
android:paddingRight="10dip"
|
||||
>
|
||||
|
||||
<ImageView android:id="@+id/unread_indicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:visibility="invisible"
|
||||
android:src="@drawable/ic_sms_unread_msg_indicator" />
|
||||
|
||||
<QuickContactBadge android:id="@+id/contact_photo"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:cropToPadding="true"
|
||||
android:scaleType="centerCrop"
|
||||
android:layout_toRightOf="@id/unread_indicator"
|
||||
android:visibility="gone" />
|
||||
|
||||
style="?android:attr/quickContactBadgeStyleWindowLarge"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_alignParentLeft="true" />
|
||||
|
||||
<ImageView android:id="@+id/key_indicator"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -43,7 +32,7 @@
|
|||
android:layout_marginTop="6dip"
|
||||
android:layout_marginRight="5dip"
|
||||
android:layout_marginLeft="5dip"
|
||||
android:layout_alignTop="@id/unread_indicator"
|
||||
android:layout_alignTop="@id/contact_photo"
|
||||
android:layout_toRightOf="@id/contact_photo"
|
||||
android:layout_toLeftOf="@id/checkbox"
|
||||
android:layout_alignWithParentIfMissing="true"
|
||||
|
@ -87,7 +76,7 @@
|
|||
android:singleLine="true"
|
||||
android:layout_marginBottom="10dip"
|
||||
android:layout_marginLeft="5dip"
|
||||
android:layout_alignBottom="@id/unread_indicator"
|
||||
android:layout_alignBottom="@id/contact_photo"
|
||||
android:layout_toRightOf="@id/contact_photo"
|
||||
android:layout_toLeftOf="@id/date"
|
||||
android:ellipsize="end" />
|
||||
|
|
|
@ -17,8 +17,12 @@
|
|||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.format.DateUtils;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.text.style.StyleSpan;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
|
@ -43,16 +47,13 @@ import java.util.Set;
|
|||
|
||||
public class ConversationHeaderView extends RelativeLayout {
|
||||
|
||||
private final Context context;
|
||||
private Set<Long> selectedThreads;
|
||||
|
||||
private Set<Long> selectedThreads;
|
||||
private Recipients recipients;
|
||||
private long threadId;
|
||||
private boolean first;
|
||||
private TextView subjectView;
|
||||
private TextView fromView;
|
||||
private TextView dateView;
|
||||
private View unreadIndicator;
|
||||
private View keyIndicator;
|
||||
private CheckBox checkbox;
|
||||
private QuickContactBadge contactPhoto;
|
||||
|
@ -70,12 +71,10 @@ public class ConversationHeaderView extends RelativeLayout {
|
|||
LayoutInflater li = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
li.inflate(R.layout.conversation_header_view, this, true);
|
||||
|
||||
this.context = context;
|
||||
this.selectedThreads = selectedThreads;
|
||||
this.subjectView = (TextView)findViewById(R.id.subject);
|
||||
this.fromView = (TextView)findViewById(R.id.from);
|
||||
this.dateView = (TextView)findViewById(R.id.date);
|
||||
this.unreadIndicator = findViewById(R.id.unread_indicator);
|
||||
this.keyIndicator = findViewById(R.id.key_indicator);
|
||||
this.contactPhoto = (QuickContactBadge)findViewById(R.id.contact_photo);
|
||||
this.checkbox = (CheckBox)findViewById(R.id.checkbox);
|
||||
|
@ -85,13 +84,12 @@ public class ConversationHeaderView extends RelativeLayout {
|
|||
|
||||
public ConversationHeaderView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public void set(MessageRecord message, boolean batchMode) {
|
||||
this.recipients = message.getRecipients();
|
||||
this.threadId = message.getThreadId();
|
||||
this.fromView.setText(formatFrom(recipients, message.getCount()));
|
||||
this.fromView.setText(formatFrom(recipients, message.getCount(), message.getRead()));
|
||||
|
||||
if (message.isKeyExchange())
|
||||
this.subjectView.setText("Key exchange message...", TextView.BufferType.SPANNABLE);
|
||||
|
@ -108,7 +106,7 @@ public class ConversationHeaderView extends RelativeLayout {
|
|||
this.checkbox.setChecked(selectedThreads.contains(threadId));
|
||||
|
||||
clearIndicators();
|
||||
setIndicators(message.getRead(), message.isKeyExchange());
|
||||
setIndicators(message.isKeyExchange());
|
||||
|
||||
if (!first) {
|
||||
if (batchMode) checkbox.setVisibility(View.VISIBLE);
|
||||
|
@ -126,16 +124,28 @@ public class ConversationHeaderView extends RelativeLayout {
|
|||
|
||||
private void clearIndicators() {
|
||||
this.keyIndicator.setVisibility(View.INVISIBLE);
|
||||
this.unreadIndicator.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
private void setIndicators(boolean read, boolean key) {
|
||||
if (!read && key) this.keyIndicator.setVisibility(View.VISIBLE);
|
||||
else if (!read) this.unreadIndicator.setVisibility(View.VISIBLE);
|
||||
private void setIndicators(boolean key) {
|
||||
if (key) this.keyIndicator.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private String formatFrom(Recipients from, long count) {
|
||||
return from.toShortString() + (count > 0 ? " (" + count + ")" : "");
|
||||
private CharSequence formatFrom(Recipients from, long count, boolean read) {
|
||||
SpannableStringBuilder builder = new SpannableStringBuilder(from.toShortString());
|
||||
|
||||
if (count > 0) {
|
||||
builder.append(" " + count);
|
||||
builder.setSpan(new ForegroundColorSpan(Color.parseColor("#66333333")),
|
||||
from.toShortString().length(), builder.length(),
|
||||
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
|
||||
if (!read) {
|
||||
builder.setSpan(new StyleSpan(Typeface.BOLD), 0, builder.length(),
|
||||
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
public Recipients getRecipients() {
|
||||
|
|
|
@ -61,7 +61,6 @@ import org.thoughtcrime.securesms.crypto.MasterSecret;
|
|||
import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
|
||||
import org.thoughtcrime.securesms.database.ApplicationExporter;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.MessageRecord;
|
||||
import org.thoughtcrime.securesms.database.NoExternalStorageException;
|
||||
import org.thoughtcrime.securesms.database.SmsMigrator;
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase;
|
||||
|
@ -75,7 +74,6 @@ import org.thoughtcrime.securesms.util.Eula;
|
|||
import org.thoughtcrime.securesms.util.MemoryCleaner;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -89,6 +87,7 @@ import java.util.Set;
|
|||
|
||||
public class SecureSMS extends SherlockListActivity {
|
||||
|
||||
private static final int MENU_NEW_MESSAGE = 0;
|
||||
private static final int MENU_SEND_KEY = 1;
|
||||
private static final int MENU_PASSPHRASE_KEY = 2;
|
||||
private static final int MENU_PREFERENCES_KEY = 3;
|
||||
|
@ -187,30 +186,54 @@ public class SecureSMS extends SherlockListActivity {
|
|||
}
|
||||
|
||||
private void prepareNormalMenu(Menu menu) {
|
||||
menu.add(0, MENU_BATCH_MODE, Menu.NONE, "Batch Mode").setIcon(android.R.drawable.ic_menu_share);
|
||||
menu.add(0, MENU_BATCH_MODE, Menu.NONE, "Batch Mode")
|
||||
.setIcon(android.R.drawable.ic_menu_share);
|
||||
|
||||
if (masterSecret != null) menu.add(0, MENU_SEND_KEY, Menu.NONE, "Secure Session").setIcon(R.drawable.ic_lock_message_sms);
|
||||
else menu.add(0, MENU_PASSPHRASE_KEY, Menu.NONE, "Enter passphrase").setIcon(R.drawable.ic_lock_message_sms);
|
||||
if (masterSecret != null) {
|
||||
menu.add(0, MENU_SEND_KEY, Menu.NONE, "Secure Session")
|
||||
.setIcon(R.drawable.ic_lock_message_sms);
|
||||
} else {
|
||||
menu.add(0, MENU_PASSPHRASE_KEY, Menu.NONE, "Enter passphrase")
|
||||
.setIcon(R.drawable.ic_lock_message_sms);
|
||||
}
|
||||
|
||||
menu.add(0, MENU_SEARCH, Menu.NONE, "Search").setIcon(android.R.drawable.ic_menu_search);
|
||||
menu.add(0, MENU_PREFERENCES_KEY, Menu.NONE, "Settings").setIcon(android.R.drawable.ic_menu_preferences);
|
||||
menu.add(0, MENU_NEW_MESSAGE, Menu.NONE, "New Message")
|
||||
.setIcon(R.drawable.ic_menu_msg_compose_holo_dark)
|
||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
|
||||
|
||||
SubMenu importExportMenu = menu.addSubMenu("Import/Export").setIcon(android.R.drawable.ic_menu_save);
|
||||
importExportMenu.add(0, MENU_EXPORT, Menu.NONE, "Export To SD Card").setIcon(android.R.drawable.ic_menu_save);
|
||||
importExportMenu.add(0, MENU_IMPORT, Menu.NONE, "Import From SD Card").setIcon(android.R.drawable.ic_menu_revert);
|
||||
menu.add(0, MENU_SEARCH, Menu.NONE, "Search")
|
||||
.setIcon(R.drawable.ic_menu_search_holo_dark)
|
||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
|
||||
|
||||
SubMenu moreMenu = menu.addSubMenu("More").setIcon(android.R.drawable.ic_menu_more);
|
||||
menu.add(0, MENU_PREFERENCES_KEY, Menu.NONE, "Settings")
|
||||
.setIcon(android.R.drawable.ic_menu_preferences);
|
||||
|
||||
if (masterSecret != null)
|
||||
moreMenu.add(0, MENU_CLEAR_PASSPHRASE, Menu.NONE, "Clear Passphrase").setIcon(android.R.drawable.ic_menu_close_clear_cancel);
|
||||
SubMenu importExportMenu = menu.addSubMenu("Import/Export")
|
||||
.setIcon(android.R.drawable.ic_menu_save);
|
||||
importExportMenu.add(0, MENU_EXPORT, Menu.NONE, "Export To SD Card")
|
||||
.setIcon(android.R.drawable.ic_menu_save);
|
||||
importExportMenu.add(0, MENU_IMPORT, Menu.NONE, "Import From SD Card")
|
||||
.setIcon(android.R.drawable.ic_menu_revert);
|
||||
|
||||
if (masterSecret != null) {
|
||||
menu.add(0, MENU_CLEAR_PASSPHRASE, Menu.NONE, "Clear Passphrase")
|
||||
.setIcon(android.R.drawable.ic_menu_close_clear_cancel);
|
||||
}
|
||||
}
|
||||
|
||||
private void prepareBatchModeMenu(Menu menu) {
|
||||
menu.add(0, MENU_EXIT_BATCH, Menu.NONE, "Normal Mode").setIcon(android.R.drawable.ic_menu_set_as);
|
||||
menu.add(0, MENU_DELETE_SELECTED_THREADS, Menu.NONE, "Delete Selected").setIcon(android.R.drawable.ic_menu_delete);
|
||||
menu.add(0, MENU_SELECT_ALL_THREADS, Menu.NONE, "Select All").setIcon(android.R.drawable.ic_menu_add);
|
||||
menu.add(0, MENU_CLEAR_SELECTION, Menu.NONE, "Unselect All").setIcon(android.R.drawable.ic_menu_revert);
|
||||
menu.add(0, MENU_EXIT_BATCH, Menu.NONE, "Normal Mode")
|
||||
.setIcon(android.R.drawable.ic_menu_set_as);
|
||||
|
||||
menu.add(0, MENU_DELETE_SELECTED_THREADS, Menu.NONE, "Delete Selected")
|
||||
.setIcon(R.drawable.ic_menu_trash_holo_dark)
|
||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
|
||||
|
||||
menu.add(0, MENU_SELECT_ALL_THREADS, Menu.NONE, "Select All")
|
||||
.setIcon(android.R.drawable.ic_menu_add);
|
||||
|
||||
menu.add(0, MENU_CLEAR_SELECTION, Menu.NONE, "Unselect All")
|
||||
.setIcon(android.R.drawable.ic_menu_revert);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -218,6 +241,9 @@ public class SecureSMS extends SherlockListActivity {
|
|||
super.onOptionsItemSelected(item);
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case MENU_NEW_MESSAGE:
|
||||
createConversation(-1, null);
|
||||
return true;
|
||||
case MENU_SEND_KEY:
|
||||
Intent intent = new Intent(this, SendKeyActivity.class);
|
||||
intent.putExtra("master_secret", masterSecret);
|
||||
|
@ -435,7 +461,6 @@ public class SecureSMS extends SherlockListActivity {
|
|||
else DecryptingQueue.schedulePendingDecrypts(this, masterSecret);
|
||||
}
|
||||
|
||||
addNewMessageItem();
|
||||
addConversationItems();
|
||||
createConversationIfNecessary(this.getIntent());
|
||||
}
|
||||
|
@ -465,9 +490,7 @@ public class SecureSMS extends SherlockListActivity {
|
|||
|
||||
@Override
|
||||
protected void onListItemClick(ListView l, View v, int position, long id) {
|
||||
if (position == 0) {
|
||||
createConversation(-1, null);
|
||||
} else if (v instanceof ConversationHeaderView) {
|
||||
if (v instanceof ConversationHeaderView) {
|
||||
ConversationHeaderView headerView = (ConversationHeaderView) v;
|
||||
createConversation(headerView.getThreadId(), headerView.getRecipients());
|
||||
}
|
||||
|
@ -509,23 +532,6 @@ public class SecureSMS extends SherlockListActivity {
|
|||
startActivity(intent);
|
||||
}
|
||||
|
||||
private void addNewMessageItem() {
|
||||
ListView listView = getListView();
|
||||
if (listView.getHeaderViewsCount() > 0) return;
|
||||
|
||||
ArrayList<Recipient> dummyList = new ArrayList<Recipient>();
|
||||
dummyList.add(new Recipient("New Message", null, null));
|
||||
|
||||
Recipients recipients = new Recipients(dummyList);
|
||||
headerView = new ConversationHeaderView(this, true);
|
||||
MessageRecord messageRecord = new MessageRecord(-1, recipients, 0, 0, true, -1);
|
||||
messageRecord.setBody("Compose new message.");
|
||||
headerView.set(messageRecord, false);
|
||||
// headerView.setBackgroundColor(Color.TRANSPARENT);
|
||||
|
||||
listView.addHeaderView(headerView, null, true);
|
||||
}
|
||||
|
||||
private void addConversationItems() {
|
||||
Cursor cursor = DatabaseFactory.getThreadDatabase(this).getConversationList();
|
||||
startManagingCursor(cursor);
|
||||
|
|