diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 73fddfea2f..2d2906dd26 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -9,8 +9,8 @@
-
+ android:protectionLevel="signature" />
+
@@ -39,14 +39,14 @@
-
+
@@ -54,7 +54,7 @@
-
+
@@ -63,7 +63,7 @@
-
+
@@ -71,7 +71,7 @@
-
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable/conversation_item_received_triangle_shape.xml b/res/drawable/conversation_item_received_triangle_shape.xml
new file mode 100644
index 0000000000..90ecd5653f
--- /dev/null
+++ b/res/drawable/conversation_item_received_triangle_shape.xml
@@ -0,0 +1,16 @@
+
+
+ -
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable/conversation_item_sent_shape.xml b/res/drawable/conversation_item_sent_shape.xml
new file mode 100644
index 0000000000..6f3b22fca0
--- /dev/null
+++ b/res/drawable/conversation_item_sent_shape.xml
@@ -0,0 +1,19 @@
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable/conversation_item_sent_triangle_shape.xml b/res/drawable/conversation_item_sent_triangle_shape.xml
new file mode 100644
index 0000000000..d957fbd96d
--- /dev/null
+++ b/res/drawable/conversation_item_sent_triangle_shape.xml
@@ -0,0 +1,16 @@
+
+
+ -
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/conversation_activity.xml b/res/layout/conversation_activity.xml
index fcfdd132f0..d030d48e00 100644
--- a/res/layout/conversation_activity.xml
+++ b/res/layout/conversation_activity.xml
@@ -120,16 +120,15 @@
android:clickable="false"
android:enabled="false" />
-
-
diff --git a/res/layout/conversation_fragment.xml b/res/layout/conversation_fragment.xml
index 0df83e5e1d..165cb71ab5 100644
--- a/res/layout/conversation_fragment.xml
+++ b/res/layout/conversation_fragment.xml
@@ -16,6 +16,8 @@
android:scrollbarStyle="insideOverlay"
android:stackFromBottom="true"
android:fadingEdge="none"
+ android:divider="@android:color/transparent"
+ android:dividerHeight="0dp"
android:layout_marginBottom="1dip"/>
\ No newline at end of file
diff --git a/res/layout/conversation_fragment_cab.xml b/res/layout/conversation_fragment_cab.xml
index 63ed906569..f116ed697d 100644
--- a/res/layout/conversation_fragment_cab.xml
+++ b/res/layout/conversation_fragment_cab.xml
@@ -13,6 +13,7 @@
android:singleLine="true"
android:layout_gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceMediumInverse"
+ android:textColor="?textColorPrimary"
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
diff --git a/res/layout/conversation_item_received.xml b/res/layout/conversation_item_received.xml
index 526bc39efd..5a408fc6ec 100644
--- a/res/layout/conversation_item_received.xml
+++ b/res/layout/conversation_item_received.xml
@@ -5,46 +5,73 @@
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingRight="10dip"
- android:orientation="horizontal">
+ android:orientation="horizontal"
+ android:background="?conversation_background">
+ android:layout_marginTop="6dp"
+ android:layout_marginLeft="10dp"
+ android:layout_marginBottom="6dp"
+ android:layout_marginRight="0dp">
-
+ android:scaleType="centerCrop"
+ android:layout_marginRight="10dp"
+ />
+
+
+ android:layout_toRightOf="@id/triangle_tick"
+ android:background="@drawable/conversation_item_received_shape"
+ android:orientation="vertical">
-
+
+
+
+
+
+
+
-
+ android:gravity="left"
+ android:paddingTop="2dip"
+ android:paddingLeft="8dp"
+ android:paddingRight="5dp"
+ android:paddingBottom="5dp" >
-
+
+ android:paddingTop="1dip"/>
+
+
-
-
+ android:textColor="?conversation_received_text_secondary_color"
+ android:fontFamily="sans-serif-light"
+ android:paddingTop="1dip" />
+
+
-
-
+ android:orientation="horizontal"
+ android:background="?conversation_background">
-
+ android:layout_marginTop="6dp"
+ android:layout_marginLeft="6dp"
+ android:layout_marginBottom="6dp"
+ android:layout_marginRight="0dp">
-
-
-
-
+ android:gravity="right"
+ android:layout_alignParentRight="true"
+ android:visibility="gone">
+ android:paddingLeft="10dip"
+ android:layout_marginRight="12dp"
+ android:orientation="vertical">
-
+
+
+
+
+
+
-
+ android:paddingTop="0dip"
+ android:layout_gravity="right">
-
+
-
+
-
+ android:fontFamily="sans-serif-light"
+ android:textColor="?conversation_sent_text_secondary_color"
+ android:paddingTop="1dip"
+ android:paddingBottom="5dp" />
+
+
+
-
-
+
-
+
+
-
+ android:scaleType="centerCrop"
+ android:visibility="gone" />
diff --git a/res/layout/conversation_list_item_view.xml b/res/layout/conversation_list_item_view.xml
index 3553eb773f..c182010f81 100644
--- a/res/layout/conversation_list_item_view.xml
+++ b/res/layout/conversation_list_item_view.xml
@@ -9,19 +9,17 @@
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
+ android:padding="8dp"
android:visibility="visible">
-
-
+ android:contentDescription="Contact Photo Image"
+ android:layout_marginLeft="3dp" />
@@ -35,29 +33,31 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textColor="?attr/conversation_list_item_contact_color"
android:singleLine="true"
- android:layout_marginTop="6dip"
+ android:layout_marginTop="12dip"
android:layout_marginRight="5dip"
- android:layout_marginLeft="10dip"
+ android:layout_marginLeft="4dip"
android:layout_marginBottom="10dip"
android:layout_alignTop="@id/contact_photo_frame"
android:layout_toRightOf="@id/contact_photo_frame"
android:layout_alignWithParentIfMissing="true"
- android:ellipsize="marquee"/>
+ android:ellipsize="marquee" />
-
+ android:layout_alignTop="@id/contact_photo_frame"
+ android:layout_alignParentRight="true" />
+ android:contentDescription="Error Alert" />
+ android:contentDescription="Attachment Indicator" />
-
diff --git a/res/menu/conversation_insecure.xml b/res/menu/conversation_insecure.xml
index a0f006bf00..afbc14111c 100644
--- a/res/menu/conversation_insecure.xml
+++ b/res/menu/conversation_insecure.xml
@@ -2,7 +2,7 @@
diff --git a/res/menu/conversation_list.xml b/res/menu/conversation_list.xml
index 4bd788c63b..cdea06f8c5 100644
--- a/res/menu/conversation_list.xml
+++ b/res/menu/conversation_list.xml
@@ -3,7 +3,7 @@
diff --git a/res/menu/conversation_list_batch.xml b/res/menu/conversation_list_batch.xml
index a207d46d98..5df9605326 100644
--- a/res/menu/conversation_list_batch.xml
+++ b/res/menu/conversation_list_batch.xml
@@ -3,11 +3,11 @@
+ android:icon="?menu_selectall_icon" />
\ No newline at end of file
diff --git a/res/menu/conversation_secure_identity.xml b/res/menu/conversation_secure_identity.xml
index ae3e9eadde..3c6987f804 100644
--- a/res/menu/conversation_secure_identity.xml
+++ b/res/menu/conversation_secure_identity.xml
@@ -2,7 +2,7 @@
-
-
-
-
+ android:icon="?attr/menu_new_conversation_icon"
+ android:showAsAction="always" />
+
+
+
+
+
+
+
+
+
+
+
-
-
-
@@ -23,4 +31,13 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 4578c05d79..2f4f37ab47 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -1,4 +1,6 @@
64dip
+ 3dp
+ 2dp
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 3ef7f885c8..c467194aec 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -52,8 +52,8 @@
Initiate Secure Session?
Initiate secure session with %s?
- Abort Secure Session Confirmation
- Are you sure that you want to abort this secure session?
+ End Secure Session Confirmation
+ Are you sure that you want to end this secure session?
Delete Thread Confirmation
Are you sure that you want to permanently delete this conversation?
Add attachment
@@ -691,7 +691,7 @@
Security
No Identity Available
Verify Recipient
- Abort Secure Session
+ End Secure Session
Add attachment
diff --git a/res/values/themes.xml b/res/values/themes.xml
index be30650a88..e033afe110 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -1,15 +1,21 @@
-
-
\ No newline at end of file
diff --git a/src/org/thoughtcrime/securesms/ApplicationPreferencesActivity.java b/src/org/thoughtcrime/securesms/ApplicationPreferencesActivity.java
index 4a0938b83c..fc9787a674 100644
--- a/src/org/thoughtcrime/securesms/ApplicationPreferencesActivity.java
+++ b/src/org/thoughtcrime/securesms/ApplicationPreferencesActivity.java
@@ -51,6 +51,7 @@ import org.thoughtcrime.securesms.contacts.ContactIdentityManager;
import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
import org.thoughtcrime.securesms.push.PushServiceSocketFactory;
import org.thoughtcrime.securesms.service.KeyCachingService;
+import org.thoughtcrime.securesms.util.ActionBarUtil;
import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.MemoryCleaner;
@@ -93,6 +94,7 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr
super.onCreate(icicle);
this.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ ActionBarUtil.initializeDefaultActionBar(this, getSupportActionBar());
addPreferencesFromResource(R.xml.preferences);
diff --git a/src/org/thoughtcrime/securesms/ContactSelectionActivity.java b/src/org/thoughtcrime/securesms/ContactSelectionActivity.java
index aa9456d877..834b06c1f3 100644
--- a/src/org/thoughtcrime/securesms/ContactSelectionActivity.java
+++ b/src/org/thoughtcrime/securesms/ContactSelectionActivity.java
@@ -25,6 +25,7 @@ import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import org.thoughtcrime.securesms.recipients.Recipients;
+import org.thoughtcrime.securesms.util.ActionBarUtil;
import org.thoughtcrime.securesms.util.DynamicTheme;
import com.actionbarsherlock.app.ActionBar;
@@ -58,7 +59,8 @@ public class ContactSelectionActivity extends PassphraseRequiredSherlockFragment
dynamicTheme.onCreate(this);
super.onCreate(icicle);
- ActionBar actionBar = this.getSupportActionBar();
+ final ActionBar actionBar = this.getSupportActionBar();
+ ActionBarUtil.initializeDefaultActionBar(this, getSupportActionBar());
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
actionBar.setDisplayHomeAsUpEnabled(true);
diff --git a/src/org/thoughtcrime/securesms/ConversationActivity.java b/src/org/thoughtcrime/securesms/ConversationActivity.java
index c13e926781..bd0feec0c8 100644
--- a/src/org/thoughtcrime/securesms/ConversationActivity.java
+++ b/src/org/thoughtcrime/securesms/ConversationActivity.java
@@ -36,6 +36,7 @@ import android.text.InputType;
import android.text.TextWatcher;
import android.util.Log;
import android.view.ContextMenu;
+import android.view.ContextThemeWrapper;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
@@ -78,6 +79,7 @@ import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.sms.MessageSender;
import org.thoughtcrime.securesms.sms.OutgoingEncryptedMessage;
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
+import org.thoughtcrime.securesms.util.ActionBarUtil;
import org.thoughtcrime.securesms.util.BitmapDecodingException;
import org.thoughtcrime.securesms.util.CharacterCalculator;
import org.thoughtcrime.securesms.util.DynamicLanguage;
@@ -154,6 +156,7 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
setContentView(R.layout.conversation_activity);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ ActionBarUtil.initializeDefaultActionBar(this, getSupportActionBar());
initializeReceivers();
initializeResources();
@@ -465,7 +468,7 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
private void handleAddAttachment() {
if (this.isMmsEnabled) {
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(this, R.style.TextSecure_Light_Dialog));
builder.setIcon(R.drawable.ic_dialog_attach);
builder.setTitle(R.string.ConversationActivity_add_attachment);
builder.setAdapter(attachmentAdapter, new AttachmentTypeListener());
@@ -508,7 +511,7 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
this.getSupportActionBar().setTitle(title);
- if (subtitle != null)
+ if (subtitle != null && !Util.isEmpty(subtitle))
this.getSupportActionBar().setSubtitle(PhoneNumberUtils.formatNumber(subtitle));
this.invalidateOptionsMenu();
@@ -612,6 +615,10 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
emojiDrawer = (EmojiDrawer)findViewById(R.id.emoji_drawer);
emojiToggle = (EmojiToggle)findViewById(R.id.emoji_toggle);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+ emojiToggle.setVisibility(View.GONE);
+ }
+
attachmentAdapter = new AttachmentTypeSelectorAdapter(this);
attachmentManager = new AttachmentManager(this);
@@ -811,6 +818,11 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
private void calculateCharactersRemaining() {
int charactersSpent = composeText.getText().toString().length();
CharacterCalculator.CharacterState characterState = characterCalculator.calculateCharacters(charactersSpent);
+ if (characterState.charactersRemaining <= 15 && charactersLeft.getVisibility() != View.VISIBLE) {
+ charactersLeft.setVisibility(View.VISIBLE);
+ } else if (characterState.charactersRemaining > 15 && charactersLeft.getVisibility() != View.GONE) {
+ charactersLeft.setVisibility(View.GONE);
+ }
charactersLeft.setText(characterState.charactersRemaining + "/" + characterState.maxMessageSize + " (" + characterState.messagesSpent + ")");
}
diff --git a/src/org/thoughtcrime/securesms/ConversationItem.java b/src/org/thoughtcrime/securesms/ConversationItem.java
index 94de626921..a4e3f95ad8 100644
--- a/src/org/thoughtcrime/securesms/ConversationItem.java
+++ b/src/org/thoughtcrime/securesms/ConversationItem.java
@@ -21,7 +21,13 @@ import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.media.MediaScannerConnection;
import android.net.Uri;
@@ -30,7 +36,7 @@ import android.os.Handler;
import android.os.Message;
import android.provider.Contacts.Intents;
import android.provider.ContactsContract.QuickContact;
-import android.text.format.DateUtils;
+import org.thoughtcrime.securesms.util.DateUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
@@ -52,6 +58,7 @@ import org.thoughtcrime.securesms.mms.Slide;
import org.thoughtcrime.securesms.mms.SlideDeck;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.service.SendReceiveService;
+import org.thoughtcrime.securesms.util.BitmapUtil;
import org.thoughtcrime.securesms.util.Emoji;
import org.whispersystems.textsecure.util.FutureTaskListener;
import org.whispersystems.textsecure.util.ListenableFutureTask;
@@ -173,9 +180,7 @@ public class ConversationItem extends LinearLayout {
}
private void setContactPhoto(MessageRecord messageRecord) {
- if (messageRecord.isOutgoing()) {
- setContactPhotoForUserIdentity();
- } else {
+ if (! messageRecord.isOutgoing()) {
setContactPhotoForRecipient(messageRecord.getIndividualRecipient());
}
}
@@ -190,13 +195,17 @@ public class ConversationItem extends LinearLayout {
mmsDownloadButton.setVisibility(View.GONE);
mmsDownloadingLabel.setVisibility(View.GONE);
- if (messageRecord.isFailed()) dateText.setText(R.string.ConversationItem_error_sending_message);
- else if (messageRecord.isPending()) dateText.setText(R.string.ConversationItem_sending);
- else dateText.setText(DateUtils.getRelativeTimeSpanString(getContext(),
- (messageRecord.isOutgoing() ?
- messageRecord.getDateSent() :
- messageRecord.getDateReceived()),
- false));
+ if (messageRecord.isFailed()) {
+ dateText.setText(R.string.ConversationItem_error_sending_message);
+ } else if (messageRecord.isPending()) {
+ dateText.setText(R.string.ConversationItem_sending);
+ } else {
+ final long timestamp = (messageRecord.isOutgoing() ?
+ messageRecord.getDateSent() :
+ messageRecord.getDateReceived());
+
+ dateText.setText(DateUtils.getBetterRelativeTimeSpanString(getContext(), timestamp));
+ }
}
private void setEvents(MessageRecord messageRecord) {
@@ -317,7 +326,7 @@ public class ConversationItem extends LinearLayout {
}
private void setContactPhotoForRecipient(final Recipient recipient) {
- contactPhoto.setImageBitmap(recipient.getContactPhoto());
+ contactPhoto.setImageBitmap(BitmapUtil.getCroppedBitmap(recipient.getContactPhoto()));
contactPhoto.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
diff --git a/src/org/thoughtcrime/securesms/ConversationListActivity.java b/src/org/thoughtcrime/securesms/ConversationListActivity.java
index 030983e607..4661b0bdb5 100644
--- a/src/org/thoughtcrime/securesms/ConversationListActivity.java
+++ b/src/org/thoughtcrime/securesms/ConversationListActivity.java
@@ -6,7 +6,6 @@ import android.database.ContentObserver;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
-import android.preference.PreferenceManager;
import android.provider.ContactsContract;
import android.provider.Telephony;
import android.support.v4.view.GravityCompat;
@@ -22,7 +21,6 @@ import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
-import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
import org.thoughtcrime.securesms.service.DirectoryRefreshListener;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.database.ThreadDatabase;
@@ -31,6 +29,7 @@ import org.thoughtcrime.securesms.recipients.RecipientFactory;
import org.thoughtcrime.securesms.recipients.Recipients;
import org.thoughtcrime.securesms.service.KeyCachingService;
import org.thoughtcrime.securesms.service.SendReceiveService;
+import org.thoughtcrime.securesms.util.ActionBarUtil;
import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.MemoryCleaner;
@@ -61,7 +60,8 @@ public class ConversationListActivity extends PassphraseRequiredSherlockFragment
super.onCreate(icicle);
setContentView(R.layout.conversation_list_activity);
- getSupportActionBar().setTitle("TextSecure");
+
+ ActionBarUtil.initializeDefaultActionBar(this, getSupportActionBar(), "TextSecure");
initializeNavigationDrawer();
initializeSenderReceiverService();
@@ -267,16 +267,11 @@ public class ConversationListActivity extends PassphraseRequiredSherlockFragment
}
private void initializeDefaultMessengerCheck() {
- if (!Util.isDefaultSmsProvider(this) &&
- !(PreferenceManager.getDefaultSharedPreferences(this)
- .getBoolean("pref_prompted_default_sms", false)))
- {
- PreferenceManager.getDefaultSharedPreferences(this).edit()
- .putBoolean("pref_prompted_default_sms", true).commit();
+ if (!TextSecurePreferences.hasPromptedDefaultSmsProvider(this) && !Util.isDefaultSmsProvider(this)) {
+ TextSecurePreferences.setPromptedDefaultSmsProvider(this, true);
Intent intent = new Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT);
intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, getPackageName());
startActivity(intent);
}
}
-
}
diff --git a/src/org/thoughtcrime/securesms/ConversationListItem.java b/src/org/thoughtcrime/securesms/ConversationListItem.java
index 331f4cf179..ee9755ed3f 100644
--- a/src/org/thoughtcrime/securesms/ConversationListItem.java
+++ b/src/org/thoughtcrime/securesms/ConversationListItem.java
@@ -21,14 +21,11 @@ import android.content.Intent;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.net.Uri;
-import android.os.Build;
import android.os.Handler;
import android.provider.Contacts.Intents;
import android.provider.ContactsContract.QuickContact;
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.View;
@@ -40,6 +37,8 @@ import android.widget.TextView;
import org.thoughtcrime.securesms.database.model.ThreadRecord;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.Recipients;
+import org.thoughtcrime.securesms.util.BitmapUtil;
+import org.thoughtcrime.securesms.util.DateUtils;
import org.thoughtcrime.securesms.util.Emoji;
import java.util.Set;
@@ -105,10 +104,10 @@ public class ConversationListItem extends RelativeLayout
this.fromView.setText(formatFrom(recipients, count, read));
this.subjectView.setText(Emoji.getInstance(context).emojify(thread.getDisplayBody(),
Emoji.EMOJI_SMALL),
- TextView.BufferType.SPANNABLE);
+ TextView.BufferType.SPANNABLE);
if (thread.getDate() > 0)
- this.dateView.setText(DateUtils.getRelativeTimeSpanString(getContext(), thread.getDate(), false));
+ this.dateView.setText(DateUtils.getBetterRelativeTimeSpanString(getContext(), thread.getDate()));
setBackground(read, batchMode);
setContactPhoto(this.recipients.getPrimaryRecipient());
@@ -120,35 +119,24 @@ public class ConversationListItem extends RelativeLayout
}
private void initializeContactWidgetVisibility() {
- if (isBadgeEnabled()) {
- contactPhotoBadge.setVisibility(View.VISIBLE);
- contactPhotoImage.setVisibility(View.GONE);
- } else {
- contactPhotoBadge.setVisibility(View.GONE);
- contactPhotoImage.setVisibility(View.VISIBLE);
- }
+ contactPhotoImage.setVisibility(View.VISIBLE);
}
private void setContactPhoto(final Recipient recipient) {
if (recipient == null) return;
- if (isBadgeEnabled()) {
- contactPhotoBadge.setImageBitmap(recipient.getContactPhoto());
- contactPhotoBadge.assignContactFromPhone(recipient.getNumber(), true);
- } else {
- contactPhotoImage.setImageBitmap(recipient.getContactPhoto());
- contactPhotoImage.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (recipient.getContactUri() != null) {
- QuickContact.showQuickContact(context, contactPhotoImage, recipient.getContactUri(), QuickContact.MODE_LARGE, null);
- } else {
- Intent intent = new Intent(Intents.SHOW_OR_CREATE_CONTACT, Uri.fromParts("tel", recipient.getNumber(), null));
- context.startActivity(intent);
- }
+ contactPhotoImage.setImageBitmap(BitmapUtil.getCroppedBitmap(recipient.getContactPhoto()));
+ contactPhotoImage.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (recipient.getContactUri() != null) {
+ QuickContact.showQuickContact(context, contactPhotoImage, recipient.getContactUri(), QuickContact.MODE_LARGE, null);
+ } else {
+ Intent intent = new Intent(Intents.SHOW_OR_CREATE_CONTACT, Uri.fromParts("tel", recipient.getNumber(), null));
+ context.startActivity(intent);
}
- });
- }
+ }
+ });
}
private void setBackground(boolean read, boolean batch) {
@@ -169,10 +157,6 @@ public class ConversationListItem extends RelativeLayout
drawables.recycle();
}
- private boolean isBadgeEnabled() {
- return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;
- }
-
private CharSequence formatFrom(Recipients from, long count, boolean read) {
int attributes[] = new int[] {R.attr.conversation_list_item_count_color};
TypedArray colors = context.obtainStyledAttributes(attributes);
@@ -180,13 +164,6 @@ public class ConversationListItem extends RelativeLayout
String fromString = from.toShortString();
SpannableStringBuilder builder = new SpannableStringBuilder(fromString);
- if (count > 0) {
- builder.append(" " + count);
- builder.setSpan(new ForegroundColorSpan(colors.getColor(0,0)),
- fromString.length(), builder.length(),
- Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
- }
-
if (!read) {
builder.setSpan(new StyleSpan(Typeface.BOLD), 0, builder.length(),
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
diff --git a/src/org/thoughtcrime/securesms/ImportExportActivity.java b/src/org/thoughtcrime/securesms/ImportExportActivity.java
index e14f3d8531..f91749861b 100644
--- a/src/org/thoughtcrime/securesms/ImportExportActivity.java
+++ b/src/org/thoughtcrime/securesms/ImportExportActivity.java
@@ -9,6 +9,8 @@ import android.support.v4.view.ViewPager;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.view.MenuItem;
+
+import org.thoughtcrime.securesms.util.ActionBarUtil;
import org.whispersystems.textsecure.crypto.MasterSecret;
@@ -23,6 +25,7 @@ public class ImportExportActivity extends PassphraseRequiredSherlockFragmentActi
super.onCreate(savedInstanceState);
setContentView(R.layout.import_export_activity);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ ActionBarUtil.initializeDefaultActionBar(this, getSupportActionBar());
initializeResources();
initializeViewPager();
diff --git a/src/org/thoughtcrime/securesms/MmsPreferencesActivity.java b/src/org/thoughtcrime/securesms/MmsPreferencesActivity.java
index db6dc555a2..b8e8d65545 100644
--- a/src/org/thoughtcrime/securesms/MmsPreferencesActivity.java
+++ b/src/org/thoughtcrime/securesms/MmsPreferencesActivity.java
@@ -26,6 +26,7 @@ import android.widget.Toast;
import com.actionbarsherlock.view.MenuItem;
import org.thoughtcrime.securesms.mms.MmsDownloadHelper;
import org.thoughtcrime.securesms.service.SendReceiveService;
+import org.thoughtcrime.securesms.util.ActionBarUtil;
import org.thoughtcrime.securesms.util.DynamicLanguage;
import org.thoughtcrime.securesms.util.DynamicTheme;
import org.thoughtcrime.securesms.util.MemoryCleaner;
@@ -46,6 +47,7 @@ public class MmsPreferencesActivity extends PassphraseRequiredSherlockPreference
super.onCreate(icicle);
this.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ ActionBarUtil.initializeDefaultActionBar(this, getSupportActionBar());
initializePreferences();
masterSecret = getIntent().getParcelableExtra("master_secret");
diff --git a/src/org/thoughtcrime/securesms/RegistrationActivity.java b/src/org/thoughtcrime/securesms/RegistrationActivity.java
index 4dc9888a28..d90b49b019 100644
--- a/src/org/thoughtcrime/securesms/RegistrationActivity.java
+++ b/src/org/thoughtcrime/securesms/RegistrationActivity.java
@@ -24,6 +24,8 @@ import com.google.i18n.phonenumbers.AsYouTypeFormatter;
import com.google.i18n.phonenumbers.NumberParseException;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber;
+
+import org.thoughtcrime.securesms.util.ActionBarUtil;
import org.whispersystems.textsecure.crypto.MasterSecret;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.whispersystems.textsecure.util.PhoneNumberFormatter;
@@ -55,8 +57,7 @@ public class RegistrationActivity extends SherlockActivity {
super.onCreate(icicle);
setContentView(R.layout.registration_activity);
- ActionBar actionBar = this.getSupportActionBar();
- actionBar.setTitle(getString(R.string.RegistrationActivity_connect_with_textsecure));
+ ActionBarUtil.initializeDefaultActionBar(this, getSupportActionBar(), getString(R.string.RegistrationActivity_connect_with_textsecure));
initializeResources();
initializeSpinner();
diff --git a/src/org/thoughtcrime/securesms/RegistrationProgressActivity.java b/src/org/thoughtcrime/securesms/RegistrationProgressActivity.java
index 2a51044ff8..5c45b886f8 100644
--- a/src/org/thoughtcrime/securesms/RegistrationProgressActivity.java
+++ b/src/org/thoughtcrime/securesms/RegistrationProgressActivity.java
@@ -32,6 +32,7 @@ import com.actionbarsherlock.app.SherlockActivity;
import org.thoughtcrime.securesms.push.PushServiceSocketFactory;
import org.thoughtcrime.securesms.service.RegistrationService;
+import org.thoughtcrime.securesms.util.ActionBarUtil;
import org.whispersystems.textsecure.crypto.MasterSecret;
import org.whispersystems.textsecure.push.PushServiceSocket;
import org.whispersystems.textsecure.push.RateLimitException;
@@ -89,7 +90,7 @@ public class RegistrationProgressActivity extends SherlockActivity {
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
- this.getSupportActionBar().setTitle(getString(R.string.RegistrationProgressActivity_verifying_number));
+ ActionBarUtil.initializeDefaultActionBar(this, getSupportActionBar(), getString(R.string.RegistrationProgressActivity_verifying_number));
setContentView(R.layout.registration_progress_activity);
initializeResources();
diff --git a/src/org/thoughtcrime/securesms/ReviewIdentitiesActivity.java b/src/org/thoughtcrime/securesms/ReviewIdentitiesActivity.java
index 4611c75fc0..d9d7428329 100644
--- a/src/org/thoughtcrime/securesms/ReviewIdentitiesActivity.java
+++ b/src/org/thoughtcrime/securesms/ReviewIdentitiesActivity.java
@@ -20,6 +20,8 @@ import android.os.Bundle;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.MenuItem;
+
+import org.thoughtcrime.securesms.util.ActionBarUtil;
import org.thoughtcrime.securesms.util.DynamicTheme;
public class ReviewIdentitiesActivity extends SherlockFragmentActivity {
@@ -32,6 +34,7 @@ public class ReviewIdentitiesActivity extends SherlockFragmentActivity {
super.onCreate(bundle);
setContentView(R.layout.review_identities);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ ActionBarUtil.initializeDefaultActionBar(this, getSupportActionBar());
}
@Override
diff --git a/src/org/thoughtcrime/securesms/VerifyIdentityActivity.java b/src/org/thoughtcrime/securesms/VerifyIdentityActivity.java
index 3af573dd82..e2ff224034 100644
--- a/src/org/thoughtcrime/securesms/VerifyIdentityActivity.java
+++ b/src/org/thoughtcrime/securesms/VerifyIdentityActivity.java
@@ -23,6 +23,7 @@ import android.widget.Toast;
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
import org.thoughtcrime.securesms.recipients.Recipient;
+import org.thoughtcrime.securesms.util.ActionBarUtil;
import org.thoughtcrime.securesms.util.MemoryCleaner;
import org.whispersystems.textsecure.crypto.IdentityKey;
import org.whispersystems.textsecure.crypto.MasterSecret;
@@ -49,6 +50,7 @@ public class VerifyIdentityActivity extends KeyScanningActivity {
public void onCreate(Bundle state) {
super.onCreate(state);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
+ ActionBarUtil.initializeDefaultActionBar(this, getSupportActionBar());
setContentView(R.layout.verify_identity_activity);
initializeResources();
diff --git a/src/org/thoughtcrime/securesms/database/model/MessageRecord.java b/src/org/thoughtcrime/securesms/database/model/MessageRecord.java
index db8f6611f0..be07a43698 100644
--- a/src/org/thoughtcrime/securesms/database/model/MessageRecord.java
+++ b/src/org/thoughtcrime/securesms/database/model/MessageRecord.java
@@ -17,10 +17,12 @@
package org.thoughtcrime.securesms.database.model;
import android.content.Context;
+import android.graphics.Color;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan;
+import android.text.style.TextAppearanceSpan;
import org.thoughtcrime.securesms.database.MmsSmsColumns;
import org.thoughtcrime.securesms.database.SmsDatabase;
@@ -125,7 +127,7 @@ public abstract class MessageRecord extends DisplayRecord {
protected SpannableString emphasisAdded(String sequence) {
SpannableString spannable = new SpannableString(sequence);
- spannable.setSpan(new ForegroundColorSpan(context.getResources().getColor(android.R.color.darker_gray)), 0, sequence.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ spannable.setSpan(new TextAppearanceSpan(context, android.R.style.TextAppearance_Small), 0, sequence.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
spannable.setSpan(new StyleSpan(android.graphics.Typeface.ITALIC), 0, sequence.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return spannable;
diff --git a/src/org/thoughtcrime/securesms/database/model/SmsMessageRecord.java b/src/org/thoughtcrime/securesms/database/model/SmsMessageRecord.java
index 3347b02ebc..5fa9eaec98 100644
--- a/src/org/thoughtcrime/securesms/database/model/SmsMessageRecord.java
+++ b/src/org/thoughtcrime/securesms/database/model/SmsMessageRecord.java
@@ -53,7 +53,7 @@ public class SmsMessageRecord extends MessageRecord {
@Override
public SpannableString getDisplayBody() {
if (isProcessedKeyExchange()) {
- return emphasisAdded(context.getString(R.string.ConversationItem_received_and_processed_key_exchange_message));
+ return new SpannableString("");
} else if (isStaleKeyExchange()) {
return emphasisAdded(context.getString(R.string.ConversationItem_error_received_stale_key_exchange_message));
} else if (isCorruptedKeyExchange()) {
@@ -63,7 +63,7 @@ public class SmsMessageRecord extends MessageRecord {
} else if (isBundleKeyExchange()) {
return emphasisAdded(context.getString(R.string.SmsMessageRecord_received_message_with_unknown_identity_key_click_to_process));
} else if (isKeyExchange() && isOutgoing()) {
- return emphasisAdded(context.getString(R.string.ConversationListAdapter_key_exchange_message));
+ return new SpannableString("");
} else if (isKeyExchange() && !isOutgoing()) {
return emphasisAdded(context.getString(R.string.ConversationItem_received_key_exchange_message_click_to_process));
} else if (SmsDatabase.Types.isFailedDecryptType(type)) {
diff --git a/src/org/thoughtcrime/securesms/util/ActionBarUtil.java b/src/org/thoughtcrime/securesms/util/ActionBarUtil.java
new file mode 100644
index 0000000000..bdb08c3982
--- /dev/null
+++ b/src/org/thoughtcrime/securesms/util/ActionBarUtil.java
@@ -0,0 +1,25 @@
+package org.thoughtcrime.securesms.util;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.util.TypedValue;
+
+import com.actionbarsherlock.app.ActionBar;
+
+import org.thoughtcrime.securesms.R;
+
+public class ActionBarUtil {
+ public static void initializeDefaultActionBar(final Context c, final ActionBar actionBar, final String title) {
+ actionBar.setTitle(title);
+ initializeDefaultActionBar(c, actionBar);
+ }
+
+ public static void initializeDefaultActionBar(final Context c, final ActionBar actionBar) {
+ TypedValue iconResValue = new TypedValue();
+ c.getTheme().resolveAttribute(R.attr.actionbar_icon, iconResValue, true);
+ int attributeResourceId = iconResValue.resourceId;
+ Drawable icon = c.getResources().getDrawable(attributeResourceId);
+ actionBar.setIcon(icon);
+ }
+
+}
diff --git a/src/org/thoughtcrime/securesms/util/BitmapUtil.java b/src/org/thoughtcrime/securesms/util/BitmapUtil.java
index 0d786da20e..d0f6e1d31d 100644
--- a/src/org/thoughtcrime/securesms/util/BitmapUtil.java
+++ b/src/org/thoughtcrime/securesms/util/BitmapUtil.java
@@ -3,6 +3,11 @@ package org.thoughtcrime.securesms.util;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.Rect;
import android.net.Uri;
import android.util.Log;
@@ -98,5 +103,23 @@ public class BitmapUtil {
return options;
}
+ public static Bitmap getCroppedBitmap(Bitmap bitmap) {
+ Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
+ bitmap.getHeight(), Bitmap.Config.ARGB_8888);
+ Canvas canvas = new Canvas(output);
+
+ final int color = 0xff424242;
+ final Paint paint = new Paint();
+ final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
+
+ paint.setAntiAlias(true);
+ canvas.drawARGB(0, 0, 0, 0);
+ paint.setColor(color);
+ canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2,
+ bitmap.getWidth() / 2, paint);
+ paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
+ canvas.drawBitmap(bitmap, rect, rect, paint);
+ return output;
+ }
}
diff --git a/src/org/thoughtcrime/securesms/util/DateUtils.java b/src/org/thoughtcrime/securesms/util/DateUtils.java
new file mode 100644
index 0000000000..690db6f5f4
--- /dev/null
+++ b/src/org/thoughtcrime/securesms/util/DateUtils.java
@@ -0,0 +1,40 @@
+package org.thoughtcrime.securesms.util;
+
+import android.content.Context;
+
+import java.util.Calendar;
+
+/**
+ * Created by kaonashi on 1/6/14.
+ */
+public class DateUtils extends android.text.format.DateUtils {
+
+ private final static long DAY_IN_MILLIS = 86400000L;
+ private final static long WEEK_IN_MILLIS = 7 * DAY_IN_MILLIS;
+ private final static long YEAR_IN_MILLIS = (long)(52.1775 * WEEK_IN_MILLIS);
+
+ private static boolean isWithinWeek(final long millis) {
+ return System.currentTimeMillis() - millis <= (WEEK_IN_MILLIS - DAY_IN_MILLIS);
+ }
+
+ private static boolean isWithinYear(final long millis) {
+ return System.currentTimeMillis() - millis <= YEAR_IN_MILLIS;
+ }
+
+ public static String getBetterRelativeTimeSpanString(final Context c, final long millis) {
+ final String prettyDate;
+ if (isToday(millis)) {
+ prettyDate = DateUtils.formatDateTime(c, millis, DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_ABBREV_TIME);
+ } else if (isWithinWeek(millis)) {
+ prettyDate = DateUtils.formatDateTime(c, millis,
+ DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_ABBREV_WEEKDAY);
+ } else if (isWithinYear(millis)) {
+ prettyDate = DateUtils.formatDateTime(c, millis,
+ DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_NO_YEAR | DateUtils.FORMAT_ABBREV_ALL);
+ } else {
+ prettyDate = DateUtils.formatDateTime(c, millis,
+ DateUtils.FORMAT_NUMERIC_DATE);
+ }
+ return prettyDate;
+ }
+}
diff --git a/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java b/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java
index 59c20f7e0e..021788dc41 100644
--- a/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java
+++ b/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java
@@ -38,6 +38,7 @@ public class TextSecurePreferences {
private static final String REGISTERED_GCM_PREF = "pref_gcm_registered";
private static final String GCM_PASSWORD_PREF = "pref_gcm_password";
private static final String PROMPTED_PUSH_REGISTRATION_PREF = "pref_prompted_push_registration";
+ private static final String PROMPTED_DEFAULT_SMS_PREF = "pref_prompted_default_sms";
private static final String SIGNALING_KEY_PREF = "pref_signaling_key";
private static final String DIRECTORY_FRESH_TIME_PREF = "pref_directory_refresh_time";
private static final String IN_THREAD_NOTIFICATION_PREF = "pref_key_inthread_notifications";
@@ -175,6 +176,14 @@ public class TextSecurePreferences {
setBooleanPreference(context, PROMPTED_PUSH_REGISTRATION_PREF, value);
}
+ public static boolean hasPromptedDefaultSmsProvider(Context context) {
+ return getBooleanPreference(context, PROMPTED_DEFAULT_SMS_PREF, false);
+ }
+
+ public static void setPromptedDefaultSmsProvider(Context context, boolean value) {
+ setBooleanPreference(context, PROMPTED_DEFAULT_SMS_PREF, value);
+ }
+
public static boolean isInterceptAllMmsEnabled(Context context) {
return getBooleanPreference(context, ALL_MMS_PREF, true);
}