mirror of
https://github.com/oxen-io/session-android.git
synced 2025-10-26 11:21:55 +00:00
Theme Support
1) Broke out the UI elements of the major Activites into stylable attributes. 2) Created a 'light' and 'dark' theme for the newly stylable attrs. 3) Touched up some of the UI spacing. 4) Implemented dynamic theme switching support.
This commit is contained in:
@@ -38,8 +38,10 @@ import org.thoughtcrime.securesms.crypto.IdentityKeyUtil;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecretUtil;
|
||||
import org.thoughtcrime.securesms.util.Dialogs;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.MemoryCleaner;
|
||||
import org.thoughtcrime.securesms.util.Trimmer;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
import com.actionbarsherlock.view.MenuItem;
|
||||
|
||||
@@ -52,7 +54,9 @@ import java.util.List;
|
||||
*
|
||||
*/
|
||||
|
||||
public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPreferenceActivity {
|
||||
public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPreferenceActivity
|
||||
implements SharedPreferences.OnSharedPreferenceChangeListener
|
||||
{
|
||||
|
||||
private static final int PICK_IDENTITY_CONTACT = 1;
|
||||
|
||||
@@ -67,6 +71,7 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr
|
||||
public static final String PASSPHRASE_TIMEOUT_INTERVAL_PREF = "pref_timeout_interval";
|
||||
public static final String PASSPHRASE_TIMEOUT_PREF = "pref_timeout_passphrase";
|
||||
public static final String AUTO_KEY_EXCHANGE_PREF = "pref_auto_complete_key_exchange";
|
||||
public static final String THEME_PREF = "pref_theme";
|
||||
|
||||
private static final String DISPLAY_CATEGORY_PREF = "pref_display_category";
|
||||
|
||||
@@ -93,8 +98,11 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr
|
||||
public static final String REGISTERED_GCM_PREF = "pref_gcm_registered";
|
||||
public static final String GCM_PASSWORD_PREF = "pref_gcm_password";
|
||||
|
||||
private final DynamicTheme dynamicTheme = new DynamicTheme();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle icicle) {
|
||||
dynamicTheme.onCreate(this);
|
||||
super.onCreate(icicle);
|
||||
|
||||
this.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
@@ -116,6 +124,24 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr
|
||||
.setOnPreferenceChangeListener(new TrimLengthValidationListener());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
dynamicTheme.onResume(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
MemoryCleaner.clean((MasterSecret) getIntent().getParcelableExtra("master_secret"));
|
||||
@@ -203,6 +229,13 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
if (key.equals(THEME_PREF)) {
|
||||
dynamicTheme.onResume(this);
|
||||
}
|
||||
}
|
||||
|
||||
private class IdentityPreferenceClickListener implements Preference.OnPreferenceClickListener {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
@@ -328,4 +361,5 @@ public class ApplicationPreferencesActivity extends PassphraseRequiredSherlockPr
|
||||
((PreferenceScreen)preference).getDialog().getWindow().getDecorView().setBackgroundDrawable(this.getWindow().getDecorView().getBackground().getConstantState().newDrawable());
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
|
||||
import org.thoughtcrime.securesms.recipients.Recipients;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
|
||||
import com.actionbarsherlock.app.ActionBar;
|
||||
import com.actionbarsherlock.app.ActionBar.Tab;
|
||||
@@ -41,6 +42,8 @@ import com.actionbarsherlock.view.MenuItem;
|
||||
*/
|
||||
public class ContactSelectionActivity extends PassphraseRequiredSherlockFragmentActivity {
|
||||
|
||||
private final DynamicTheme dynamicTheme = new DynamicTheme();
|
||||
|
||||
private ContactSelectionListFragment contactsFragment;
|
||||
private ContactSelectionGroupsFragment groupsFragment;
|
||||
private ContactSelectionRecentFragment recentFragment;
|
||||
@@ -49,6 +52,7 @@ public class ContactSelectionActivity extends PassphraseRequiredSherlockFragment
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle icicle) {
|
||||
dynamicTheme.onCreate(this);
|
||||
super.onCreate(icicle);
|
||||
|
||||
ActionBar actionBar = this.getSupportActionBar();
|
||||
@@ -62,6 +66,12 @@ public class ContactSelectionActivity extends PassphraseRequiredSherlockFragment
|
||||
setupRecentTab();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
dynamicTheme.onResume(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = this.getSupportMenuInflater();
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.TypedArray;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
@@ -75,6 +76,7 @@ import org.thoughtcrime.securesms.sms.OutgoingEncryptedMessage;
|
||||
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
||||
import org.thoughtcrime.securesms.util.BitmapDecodingException;
|
||||
import org.thoughtcrime.securesms.util.CharacterCalculator;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.EncryptedCharacterCalculator;
|
||||
import org.thoughtcrime.securesms.util.InvalidMessageException;
|
||||
import org.thoughtcrime.securesms.util.MemoryCleaner;
|
||||
@@ -129,9 +131,11 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
|
||||
private boolean isMmsEnabled = true;
|
||||
|
||||
private CharacterCalculator characterCalculator = new CharacterCalculator();
|
||||
private DynamicTheme dynamicTheme = new DynamicTheme();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle state) {
|
||||
dynamicTheme.onCreate(this);
|
||||
super.onCreate(state);
|
||||
|
||||
setContentView(R.layout.conversation_activity);
|
||||
@@ -154,6 +158,8 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
dynamicTheme.onResume(this);
|
||||
|
||||
initializeSecurity();
|
||||
initializeTitleBar();
|
||||
initializeMmsEnabledCheck();
|
||||
@@ -513,21 +519,26 @@ public class ConversationActivity extends PassphraseRequiredSherlockFragmentActi
|
||||
}
|
||||
|
||||
private void initializeSecurity() {
|
||||
int attributes[] = new int[]{R.attr.conversation_send_button,
|
||||
R.attr.conversation_send_secure_button};
|
||||
TypedArray drawables = obtainStyledAttributes(attributes);
|
||||
|
||||
if (isSingleConversation() &&
|
||||
KeyUtil.isSessionFor(this, getRecipients().getPrimaryRecipient()))
|
||||
{
|
||||
sendButton.setImageResource(R.drawable.ic_send_encrypted_holo_light);
|
||||
sendButton.setImageDrawable(drawables.getDrawable(1));
|
||||
this.isEncryptedConversation = true;
|
||||
this.isAuthenticatedConversation = KeyUtil.isIdentityKeyFor(this, masterSecret, getRecipients().getPrimaryRecipient());
|
||||
this.characterCalculator = new EncryptedCharacterCalculator();
|
||||
} else {
|
||||
sendButton.setImageResource(R.drawable.ic_send_holo_light);
|
||||
sendButton.setImageDrawable(drawables.getDrawable(0));
|
||||
this.isEncryptedConversation = false;
|
||||
this.isAuthenticatedConversation = false;
|
||||
this.characterCalculator = new CharacterCalculator();
|
||||
}
|
||||
|
||||
calculateCharactersRemaining();
|
||||
drawables.recycle();
|
||||
}
|
||||
|
||||
private void initializeMmsEnabledCheck() {
|
||||
|
||||
@@ -84,6 +84,7 @@ public class ConversationItem extends LinearLayout {
|
||||
private ImageView contactPhoto;
|
||||
private ImageView deliveredImage;
|
||||
|
||||
private View mmsContainer;
|
||||
private ImageView mmsThumbnail;
|
||||
private Button mmsDownloadButton;
|
||||
private TextView mmsDownloadingLabel;
|
||||
@@ -115,6 +116,7 @@ public class ConversationItem extends LinearLayout {
|
||||
this.secureImage = (ImageView)findViewById(R.id.sms_secure_indicator);
|
||||
this.failedImage = (ImageView)findViewById(R.id.sms_failed_indicator);
|
||||
this.keyImage = (ImageView)findViewById(R.id.key_exchange_indicator);
|
||||
this.mmsContainer = (View) findViewById(R.id.mms_view);
|
||||
this.mmsThumbnail = (ImageView)findViewById(R.id.image_view);
|
||||
this.mmsDownloadButton = (Button) findViewById(R.id.mms_download_button);
|
||||
this.mmsDownloadingLabel = (TextView) findViewById(R.id.mms_label_downloading);
|
||||
@@ -237,9 +239,11 @@ public class ConversationItem extends LinearLayout {
|
||||
private void setMediaMmsAttributes(MediaMmsMessageRecord messageRecord) {
|
||||
if (messageRecord.getPartCount() > 0) {
|
||||
mmsThumbnail.setVisibility(View.VISIBLE);
|
||||
mmsContainer.setVisibility(View.VISIBLE);
|
||||
mmsThumbnail.setImageDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
} else {
|
||||
mmsThumbnail.setVisibility(View.GONE);
|
||||
mmsContainer.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
slideDeck = messageRecord.getSlideDeck();
|
||||
|
||||
@@ -21,18 +21,22 @@ 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.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.MemoryCleaner;
|
||||
|
||||
public class ConversationListActivity extends PassphraseRequiredSherlockFragmentActivity
|
||||
implements ConversationListFragment.ConversationSelectedListener
|
||||
{
|
||||
private final DynamicTheme dynamicTheme = new DynamicTheme();
|
||||
|
||||
private ConversationListFragment fragment;
|
||||
private MasterSecret masterSecret;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
dynamicTheme.onCreate(this);
|
||||
super.onCreate(icicle);
|
||||
|
||||
setContentView(R.layout.conversation_list_activity);
|
||||
getSupportActionBar().setTitle("TextSecure");
|
||||
|
||||
@@ -41,6 +45,12 @@ public class ConversationListActivity extends PassphraseRequiredSherlockFragment
|
||||
initializeContactUpdatesReceiver();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
dynamicTheme.onResume(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
Log.w("ConversationListActivity", "onDestroy...");
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.thoughtcrime.securesms;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.net.Uri;
|
||||
@@ -148,13 +149,21 @@ public class ConversationListItem extends RelativeLayout
|
||||
}
|
||||
|
||||
private void setBackground(boolean read, boolean batch) {
|
||||
int[] attributes = new int[]{R.attr.conversation_list_item_background_selected,
|
||||
R.attr.conversation_list_item_background_read,
|
||||
R.attr.conversation_list_item_background_unread};
|
||||
|
||||
TypedArray drawables = context.obtainStyledAttributes(attributes);
|
||||
|
||||
if (batch && selectedThreads.contains(threadId)) {
|
||||
setBackgroundResource(R.drawable.list_selected_holo_light);
|
||||
setBackgroundDrawable(drawables.getDrawable(0));
|
||||
} else if (read) {
|
||||
setBackgroundResource(R.drawable.conversation_list_item_background_read);
|
||||
setBackgroundDrawable(drawables.getDrawable(1));
|
||||
} else {
|
||||
setBackgroundResource(R.drawable.conversation_list_item_background_unread);
|
||||
setBackgroundDrawable(drawables.getDrawable(2));
|
||||
}
|
||||
|
||||
drawables.recycle();
|
||||
}
|
||||
|
||||
private boolean isBadgeEnabled() {
|
||||
@@ -162,12 +171,15 @@ public class ConversationListItem extends RelativeLayout
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
String fromString = from.toShortString();
|
||||
SpannableStringBuilder builder = new SpannableStringBuilder(fromString);
|
||||
|
||||
if (count > 0) {
|
||||
builder.append(" " + count);
|
||||
builder.setSpan(new ForegroundColorSpan(Color.parseColor("#66333333")),
|
||||
builder.setSpan(new ForegroundColorSpan(colors.getColor(0,0)),
|
||||
fromString.length(), builder.length(),
|
||||
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
@@ -177,6 +189,7 @@ public class ConversationListItem extends RelativeLayout
|
||||
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
}
|
||||
|
||||
colors.recycle();
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.actionbarsherlock.app.SherlockFragmentActivity;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
|
||||
public class CountrySelectionActivity extends SherlockFragmentActivity
|
||||
implements CountrySelectionFragment.CountrySelectedListener
|
||||
|
||||
@@ -17,11 +17,13 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.thoughtcrime.securesms.crypto.SerializableKey;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.thoughtcrime.securesms.util.Dialogs;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
|
||||
import com.actionbarsherlock.view.Menu;
|
||||
import com.actionbarsherlock.view.MenuInflater;
|
||||
@@ -36,6 +38,20 @@ import com.google.zxing.integration.android.IntentResult;
|
||||
*/
|
||||
public abstract class KeyScanningActivity extends PassphraseRequiredSherlockActivity {
|
||||
|
||||
private final DynamicTheme dynamicTheme = new DynamicTheme();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle bundle) {
|
||||
dynamicTheme.onCreate(this);
|
||||
super.onCreate(bundle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
dynamicTheme.onResume(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareOptionsMenu(Menu menu) {
|
||||
super.onPrepareOptionsMenu(menu);
|
||||
|
||||
@@ -20,14 +20,26 @@ import android.os.Bundle;
|
||||
|
||||
import com.actionbarsherlock.app.SherlockFragmentActivity;
|
||||
import com.actionbarsherlock.view.MenuItem;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
|
||||
public class ReviewIdentitiesActivity extends SherlockFragmentActivity {
|
||||
|
||||
private final DynamicTheme dynamicTheme = new DynamicTheme();
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle bundle) {
|
||||
dynamicTheme.onCreate(this);
|
||||
super.onCreate(bundle);
|
||||
setContentView(R.layout.review_identities);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
dynamicTheme.onResume(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.thoughtcrime.securesms.components;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
@@ -45,19 +46,24 @@ public class ImageDivet extends ImageView {
|
||||
}
|
||||
|
||||
private void setDrawable() {
|
||||
Resources r = getContext().getResources();
|
||||
int attributes[] = new int[] {R.attr.conversation_avatar_divet_left,
|
||||
R.attr.conversation_avatar_divet_right};
|
||||
|
||||
TypedArray drawables = getContext().obtainStyledAttributes(attributes);
|
||||
|
||||
switch (position) {
|
||||
case 0:
|
||||
drawable = r.getDrawable(R.drawable.divet_right);
|
||||
drawable = drawables.getDrawable(1);
|
||||
break;
|
||||
case 1:
|
||||
drawable = r.getDrawable(R.drawable.divet_left);
|
||||
drawable = drawables.getDrawable(0);
|
||||
break;
|
||||
}
|
||||
|
||||
drawableIntrinsicWidth = drawable.getIntrinsicWidth();
|
||||
drawableIntrinsicHeight = drawable.getIntrinsicHeight();
|
||||
|
||||
drawables.recycle();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -103,6 +103,9 @@ public class ImageSlide extends Slide {
|
||||
|
||||
imageView.setImageDrawable(temporaryDrawable);
|
||||
|
||||
if (maxWidth == 0 || maxHeight == 0)
|
||||
return;
|
||||
|
||||
MmsDatabase.slideResolver.execute(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
61
src/org/thoughtcrime/securesms/util/DynamicTheme.java
Normal file
61
src/org/thoughtcrime/securesms/util/DynamicTheme.java
Normal file
@@ -0,0 +1,61 @@
|
||||
package org.thoughtcrime.securesms.util;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
import org.thoughtcrime.securesms.ApplicationPreferencesActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
|
||||
public class DynamicTheme {
|
||||
|
||||
private int currentTheme;
|
||||
|
||||
public void onCreate(Activity activity) {
|
||||
currentTheme = getSelectedTheme(activity);
|
||||
activity.setTheme(currentTheme);
|
||||
}
|
||||
|
||||
public void onResume(Activity activity) {
|
||||
if (currentTheme != getSelectedTheme(activity)) {
|
||||
Intent intent = activity.getIntent();
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
|
||||
|
||||
activity.startActivity(intent);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
|
||||
OverridePendingTransition.invoke(activity);
|
||||
}
|
||||
|
||||
activity.finish();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
|
||||
OverridePendingTransition.invoke(activity);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static int getSelectedTheme(Context context) {
|
||||
String theme = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
.getString(ApplicationPreferencesActivity.THEME_PREF, "light");
|
||||
|
||||
return getSelectedTheme(theme);
|
||||
}
|
||||
|
||||
public static int getSelectedTheme(String theme) {
|
||||
if (theme.equals("light")) {
|
||||
return R.style.TextSecure_LightTheme;
|
||||
} else if (theme.equals("dark")) {
|
||||
return R.style.TextSecure_DarkTheme;
|
||||
}
|
||||
|
||||
return R.style.TextSecure_LightTheme;
|
||||
}
|
||||
|
||||
private static final class OverridePendingTransition {
|
||||
static void invoke(Activity activity) {
|
||||
activity.overridePendingTransition(0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -184,7 +184,6 @@ public class Util {
|
||||
return new String(bout.toByteArray());
|
||||
}
|
||||
|
||||
|
||||
// public static Bitmap loadScaledBitmap(InputStream src, int targetWidth, int targetHeight) {
|
||||
// return BitmapFactory.decodeStream(src);
|
||||
//// BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
|
||||
Reference in New Issue
Block a user