diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index b1be5710434..2464ffa4865 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -200,6 +200,11 @@
android:launchMode="singleTask"
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
+
+
+
+
+
+
+
+
+
diff --git a/build.gradle b/build.gradle
index 4c709a33012..2010b65e793 100644
--- a/build.gradle
+++ b/build.gradle
@@ -58,7 +58,7 @@ dependencies {
compile 'com.soundcloud.android:android-crop:0.9.10@aar'
compile 'com.android.support:appcompat-v7:22.1.1'
compile 'com.android.support:recyclerview-v7:21.0.3'
- compile 'com.melnykov:floatingactionbutton:1.1.0'
+ compile 'com.melnykov:floatingactionbutton:1.3.0'
compile 'com.google.zxing:android-integration:3.1.0'
compile ('com.android.support:support-v4-preferencefragment:1.0.0@aar'){
exclude module: 'support-v4'
@@ -80,6 +80,7 @@ dependencies {
compile 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
compile 'org.whispersystems:textsecure-android:1.8.1'
compile 'com.h6ah4i.android.compat:mulsellistprefcompat:1.0.0'
+ compile 'me.relex:circleindicator:1.0.0@aar'
testCompile 'junit:junit:4.12'
testCompile 'org.assertj:assertj-core:1.7.1'
@@ -118,7 +119,7 @@ dependencyVerification {
'com.soundcloud.android:android-crop:ffd4b973cf6e97f7d64118a0dc088df50e9066fd5634fe6911dd0c0c5d346177',
'com.android.support:appcompat-v7:9a2355537c2f01cf0b95523605c18606b8d824017e6e94a05c77b0cfc8f21c96',
'com.android.support:recyclerview-v7:e525ad3f33c84bb12b73d2dc975b55364a53f0f2d0697e043efba59ba73e22d2',
- 'com.melnykov:floatingactionbutton:0679ad9f7d61eb7aeab91e8dc56358cdedd5b1c1b9c48464499ffa05c40d3985',
+ 'com.melnykov:floatingactionbutton:15d58d4fac0f7a288d0e5301bbaf501a146f5b3f5921277811bf99bd3b397263',
'com.google.zxing:android-integration:89e56aadf1164bd71e57949163c53abf90af368b51669c0d4a47a163335f95c4',
'com.android.support:support-v4-preferencefragment:5470f5872514a6226fa1fc6f4e000991f38805691c534cf0bd2778911fc773ad',
'com.android.support:gridlayout-v7:a9b770cffca2c7c5cd83cba4dd12503365de5e8d9c79c479165adf18ab3bc25b',
@@ -129,6 +130,7 @@ dependencyVerification {
'org.whispersystems:libpastelog:550d33c565380d90f4c671e7b8ed5f3a6da55a9fda468373177106b2eb5220b2',
'com.amulyakhare:com.amulyakhare.textdrawable:54c92b5fba38cfd316a07e5a30528068f45ce8515a6890f1297df4c401af5dcb',
'com.h6ah4i.android.compat:mulsellistprefcompat:47167c5cb796de1a854788e9ff318358e36c8fb88123baaa6e38fb78511dfabe',
+ 'me.relex:circleindicator:996766d3dad51401331515e742948f2a10982d17c626edd976a246b9bf046aac',
'com.nineoldandroids:library:68025a14e3e7673d6ad2f95e4b46d78d7d068343aa99256b686fe59de1b3163a',
'javax.inject:javax.inject:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
'com.madgag.spongycastle:core:8d6240b974b0aca4d3da9c7dd44d42339d8a374358aca5fc98e50a995764511f',
diff --git a/res/drawable-xxhdpi/splash_logo.png b/res/drawable-xxhdpi/splash_logo.png
new file mode 100644
index 00000000000..f6f777644db
Binary files /dev/null and b/res/drawable-xxhdpi/splash_logo.png differ
diff --git a/res/drawable-xxxhdpi/ic_arrow_forward_white_24dp.png b/res/drawable-xxxhdpi/ic_arrow_forward_white_24dp.png
new file mode 100644
index 00000000000..3aebc05370c
Binary files /dev/null and b/res/drawable-xxxhdpi/ic_arrow_forward_white_24dp.png differ
diff --git a/res/layout/color_fragment.xml b/res/layout/color_fragment.xml
new file mode 100644
index 00000000000..9cfebe7e426
--- /dev/null
+++ b/res/layout/color_fragment.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/res/layout/experience_upgrade_activity.xml b/res/layout/experience_upgrade_activity.xml
new file mode 100644
index 00000000000..5f118087dd0
--- /dev/null
+++ b/res/layout/experience_upgrade_activity.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index b71862b4221..bcf175759ff 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -1,9 +1,12 @@
- #ff2090ea
- #ff1c7ac5
+ #ff2090ea
+ #ff1c7ac5
+ #552090ea
- #552090ea
+ @color/signal_primary
+ @color/signal_primary_dark
+ @color/signal_primary_alpha33
#ffffffff
#ff000000
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 8349dacfecd..5fd2cdc83bd 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -55,4 +55,8 @@
holding the phone, *before* moving it up to your face and having
the prox sensor kick in.) -->
20dp
+
+ 35dp
+ 20dp
+ 140dp
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f749215e28a..1a1b6054d0d 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -187,6 +187,12 @@
Share with
+
+ Welcome to Signal.
+ TextSecure and RedPhone are now one private messenger, for every situation: Signal.
+ Welcome to Signal!
+ TextSecure is now Signal.
+ TextSecure and RedPhone are now one app: Signal. Tap to explore.
Export
Export plaintext to SD card?
diff --git a/src/org/thoughtcrime/securesms/BasicIntroFragment.java b/src/org/thoughtcrime/securesms/BasicIntroFragment.java
new file mode 100644
index 00000000000..db1520ad613
--- /dev/null
+++ b/src/org/thoughtcrime/securesms/BasicIntroFragment.java
@@ -0,0 +1,54 @@
+package org.thoughtcrime.securesms;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+public class BasicIntroFragment extends Fragment {
+
+ private static final String ARG_DRAWABLE = "drawable";
+ private static final String ARG_TEXT = "text";
+ private static final String ARG_SUBTEXT = "subtext";
+
+ private int drawable;
+ private int text;
+ private int subtext;
+
+ public static BasicIntroFragment newInstance(int drawable, int text, int subtext) {
+ BasicIntroFragment fragment = new BasicIntroFragment();
+ Bundle args = new Bundle();
+ args.putInt(ARG_DRAWABLE, drawable);
+ args.putInt(ARG_TEXT, text);
+ args.putInt(ARG_SUBTEXT, subtext);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ public BasicIntroFragment() {}
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (getArguments() != null) {
+ drawable = getArguments().getInt(ARG_DRAWABLE);
+ text = getArguments().getInt(ARG_TEXT );
+ subtext = getArguments().getInt(ARG_SUBTEXT );
+ }
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View v = inflater.inflate(R.layout.color_fragment, container, false);
+
+ ((ImageView)v.findViewById(R.id.watermark)).setImageResource(drawable);
+ ((TextView)v.findViewById(R.id.blurb)).setText(text);
+ ((TextView)v.findViewById(R.id.subblurb)).setText(subtext);
+
+ return v;
+ }
+}
diff --git a/src/org/thoughtcrime/securesms/ExperienceUpgradeActivity.java b/src/org/thoughtcrime/securesms/ExperienceUpgradeActivity.java
new file mode 100644
index 00000000000..a7c5b5b22ab
--- /dev/null
+++ b/src/org/thoughtcrime/securesms/ExperienceUpgradeActivity.java
@@ -0,0 +1,224 @@
+package org.thoughtcrime.securesms;
+
+import android.annotation.TargetApi;
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.drawable.ColorDrawable;
+import android.os.Build;
+import android.os.Build.VERSION_CODES;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.annotation.StringRes;
+import android.support.v4.app.NotificationCompat;
+import android.support.v4.view.ViewPager;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+
+import com.melnykov.fab.FloatingActionButton;
+import com.nineoldandroids.animation.ArgbEvaluator;
+
+import org.thoughtcrime.securesms.IntroPagerAdapter.IntroPage;
+import org.thoughtcrime.securesms.util.ServiceUtil;
+import org.thoughtcrime.securesms.util.TextSecurePreferences;
+import org.thoughtcrime.securesms.util.Util;
+import org.thoughtcrime.securesms.util.ViewUtil;
+import org.whispersystems.libaxolotl.util.guava.Optional;
+
+import java.util.Collections;
+import java.util.List;
+
+import me.relex.circleindicator.CircleIndicator;
+
+public class ExperienceUpgradeActivity extends BaseActionBarActivity {
+ private static final String TAG = ExperienceUpgradeActivity.class.getSimpleName();
+ private static final int NOTIFICATION_ID = 1339;
+
+ private enum ExperienceUpgrade {
+ SIGNAL_REBRANDING(155,
+ new IntroPage(0xFF2090EA,
+ BasicIntroFragment.newInstance(R.drawable.splash_logo,
+ R.string.ExperienceUpgradeActivity_welcome_to_signal_dgaf,
+ R.string.ExperienceUpgradeActivity_textsecure_is_now_called_signal)),
+ R.string.ExperienceUpgradeActivity_welcome_to_signal_excited,
+ R.string.ExperienceUpgradeActivity_textsecure_is_now_signal,
+ R.string.ExperienceUpgradeActivity_textsecure_is_now_signal_long);
+
+ private int version;
+ private List pages;
+ private @StringRes int notificationTitle;
+ private @StringRes int notificationText;
+ private @StringRes int notificationBigText;
+
+ ExperienceUpgrade(int version,
+ @NonNull List pages,
+ @StringRes int notificationTitle,
+ @StringRes int notificationText,
+ @StringRes int notificationBigText)
+ {
+ this.version = version;
+ this.pages = pages;
+ this.notificationTitle = notificationTitle;
+ this.notificationText = notificationText;
+ this.notificationBigText = notificationBigText;
+ }
+
+ ExperienceUpgrade(int version,
+ @NonNull IntroPage page,
+ @StringRes int notificationTitle,
+ @StringRes int notificationText,
+ @StringRes int notificationBigText)
+ {
+ this(version, Collections.singletonList(page), notificationTitle, notificationText, notificationBigText);
+ }
+
+ public int getVersion() {
+ return version;
+ }
+
+ public List getPages() {
+ return pages;
+ }
+
+ public IntroPage getPage(int i) {
+ return pages.get(i);
+ }
+
+ public int getNotificationTitle() {
+ return notificationTitle;
+ }
+
+ public int getNotificationText() {
+ return notificationText;
+ }
+
+ public int getNotificationBigText() {
+ return notificationBigText;
+ }
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setStatusBarColor(getResources().getColor(R.color.signal_primary_dark));
+
+ Optional upgrade = getExperienceUpgrade(this);
+ if (!upgrade.isPresent()) {
+ onContinue();
+ return;
+ }
+
+ setContentView(R.layout.experience_upgrade_activity);
+ final ViewPager pager = ViewUtil.findById(this, R.id.pager);
+ final CircleIndicator indicator = ViewUtil.findById(this, R.id.indicator);
+ final FloatingActionButton fab = ViewUtil.findById(this, R.id.fab);
+
+ pager.setAdapter(new IntroPagerAdapter(getSupportFragmentManager(), upgrade.get().getPages()));
+
+ if (upgrade.get().getPages().size() > 1) {
+ indicator.setViewPager(pager);
+ indicator.setOnPageChangeListener(new OnPageChangeListener(upgrade.get()));
+ } else {
+ indicator.setVisibility(View.GONE);
+ }
+
+ fab.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ onContinue();
+ }
+ });
+
+ getWindow().setBackgroundDrawable(new ColorDrawable(upgrade.get().getPage(0).backgroundColor));
+ ServiceUtil.getNotificationManager(this).cancel(NOTIFICATION_ID);
+ }
+
+ @TargetApi(VERSION_CODES.LOLLIPOP)
+ private void setStatusBarColor(int color) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ getWindow().setStatusBarColor(color);
+ }
+ }
+
+ private void onContinue() {
+ TextSecurePreferences.setLastExperienceVersionCode(this, Util.getCurrentApkReleaseVersion(this));
+ startActivity((Intent)getIntent().getParcelableExtra("next_intent"));
+ finish();
+ }
+
+ public static boolean isUpdate(Context context) {
+ return getExperienceUpgrade(context).isPresent();
+ }
+
+ public static Optional getExperienceUpgrade(Context context) {
+ final int currentVersionCode = Util.getCurrentApkReleaseVersion(context);
+ final int lastSeenVersion = TextSecurePreferences.getLastExperienceVersionCode(context);
+ Log.w(TAG, "getExperienceUpgrade(" + lastSeenVersion + ")");
+
+ if (lastSeenVersion >= currentVersionCode || lastSeenVersion == 0) {
+ TextSecurePreferences.setLastExperienceVersionCode(context, currentVersionCode);
+ return Optional.absent();
+ }
+
+ Optional eligibleUpgrade = Optional.absent();
+ for (ExperienceUpgrade upgrade : ExperienceUpgrade.values()) {
+ if (lastSeenVersion < upgrade.getVersion()) eligibleUpgrade = Optional.of(upgrade);
+ }
+
+ return eligibleUpgrade;
+ }
+
+ private final class OnPageChangeListener implements ViewPager.OnPageChangeListener {
+ private final ArgbEvaluator evaluator = new ArgbEvaluator();
+ private final ExperienceUpgrade upgrade;
+
+ public OnPageChangeListener(ExperienceUpgrade upgrade) {
+ this.upgrade = upgrade;
+ }
+
+ @Override
+ public void onPageSelected(int position) {}
+
+ @Override
+ public void onPageScrollStateChanged(int state) {}
+
+ @Override
+ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+ final int nextPosition = (position + 1) % upgrade.getPages().size();
+
+ final int color = (Integer)evaluator.evaluate(positionOffset,
+ upgrade.getPage(position).backgroundColor,
+ upgrade.getPage(nextPosition).backgroundColor);
+ getWindow().setBackgroundDrawable(new ColorDrawable(color));
+ }
+ }
+
+ public static class AppUpgradeReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if(Intent.ACTION_PACKAGE_REPLACED.equals(intent.getAction()) &&
+ intent.getData().getSchemeSpecificPart().equals(context.getPackageName()))
+ {
+ Optional experienceUpgrade = getExperienceUpgrade(context);
+ if (!experienceUpgrade.isPresent()) return;
+
+ Intent targetIntent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
+ Notification notification = new NotificationCompat.Builder(context)
+ .setSmallIcon(R.drawable.icon_notification)
+ .setColor(context.getResources().getColor(R.color.signal_primary))
+ .setContentTitle(context.getString(experienceUpgrade.get().getNotificationTitle()))
+ .setContentText(context.getString(experienceUpgrade.get().getNotificationText()))
+ .setStyle(new NotificationCompat.BigTextStyle().bigText(context.getString(experienceUpgrade.get().getNotificationBigText())))
+ .setAutoCancel(true)
+ .setContentIntent(PendingIntent.getActivity(context, 0,
+ targetIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT))
+ .build();
+ ServiceUtil.getNotificationManager(context).notify(NOTIFICATION_ID, notification);
+ }
+ }
+ }
+}
diff --git a/src/org/thoughtcrime/securesms/IntroPagerAdapter.java b/src/org/thoughtcrime/securesms/IntroPagerAdapter.java
new file mode 100644
index 00000000000..e10cc8fb407
--- /dev/null
+++ b/src/org/thoughtcrime/securesms/IntroPagerAdapter.java
@@ -0,0 +1,38 @@
+package org.thoughtcrime.securesms;
+
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentStatePagerAdapter;
+
+import java.util.List;
+
+public class IntroPagerAdapter extends FragmentStatePagerAdapter {
+
+ public static class IntroPage {
+ final int backgroundColor;
+ final Fragment fragment;
+
+ public IntroPage(int backgroundColor, Fragment fragment) {
+ this.backgroundColor = backgroundColor;
+ this.fragment = fragment;
+ }
+ }
+
+ private List pages;
+
+ public IntroPagerAdapter(FragmentManager fm, List pages) {
+ super(fm);
+ this.pages = pages;
+ }
+
+ @Override
+ public Fragment getItem(int i) {
+ IntroPage page = pages.get(i);
+ return page.fragment;
+ }
+
+ @Override
+ public int getCount() {
+ return pages.size();
+ }
+}
diff --git a/src/org/thoughtcrime/securesms/PassphraseRequiredActionBarActivity.java b/src/org/thoughtcrime/securesms/PassphraseRequiredActionBarActivity.java
index fcb6751de18..188be38ebc3 100644
--- a/src/org/thoughtcrime/securesms/PassphraseRequiredActionBarActivity.java
+++ b/src/org/thoughtcrime/securesms/PassphraseRequiredActionBarActivity.java
@@ -31,6 +31,7 @@ public abstract class PassphraseRequiredActionBarActivity extends BaseActionBarA
private static final int STATE_PROMPT_PASSPHRASE = 2;
private static final int STATE_UPGRADE_DATABASE = 3;
private static final int STATE_PROMPT_PUSH_REGISTRATION = 4;
+ private static final int STATE_EXPERIENCE_UPGRADE = 5;
private BroadcastReceiver clearKeyReceiver;
private boolean isVisible;
@@ -128,17 +129,20 @@ private Intent getIntentForState(MasterSecret masterSecret, int state) {
Log.w(TAG, "routeApplicationState(), state: " + state);
switch (state) {
- case STATE_CREATE_PASSPHRASE: return getCreatePassphraseIntent();
- case STATE_PROMPT_PASSPHRASE: return getPromptPassphraseIntent();
- case STATE_UPGRADE_DATABASE: return getUpgradeDatabaseIntent(masterSecret);
- case STATE_PROMPT_PUSH_REGISTRATION: return getPushRegistrationIntent(masterSecret);
- default: return null;
+ case STATE_CREATE_PASSPHRASE: return getCreatePassphraseIntent();
+ case STATE_PROMPT_PASSPHRASE: return getPromptPassphraseIntent();
+ case STATE_UPGRADE_DATABASE: return getUpgradeDatabaseIntent(masterSecret);
+ case STATE_PROMPT_PUSH_REGISTRATION: return getPushRegistrationIntent(masterSecret);
+ case STATE_EXPERIENCE_UPGRADE: return getExperienceUpgradeIntent();
+ default: return null;
}
}
private int getApplicationState(MasterSecret masterSecret) {
if (!MasterSecretUtil.isPassphraseInitialized(this)) {
return STATE_CREATE_PASSPHRASE;
+ } else if (ExperienceUpgradeActivity.isUpdate(this)) {
+ return STATE_EXPERIENCE_UPGRADE;
} else if (masterSecret == null) {
return STATE_PROMPT_PASSPHRASE;
} else if (DatabaseUpgradeActivity.isUpdate(this)) {
@@ -166,6 +170,10 @@ private Intent getUpgradeDatabaseIntent(MasterSecret masterSecret) {
masterSecret);
}
+ private Intent getExperienceUpgradeIntent() {
+ return getRoutedIntent(ExperienceUpgradeActivity.class, getIntent(), null);
+ }
+
private Intent getPushRegistrationIntent(MasterSecret masterSecret) {
return getRoutedIntent(RegistrationActivity.class, getConversationListIntent(), masterSecret);
}
diff --git a/src/org/thoughtcrime/securesms/util/ServiceUtil.java b/src/org/thoughtcrime/securesms/util/ServiceUtil.java
index d1cfdae7a89..d9fd80c794c 100644
--- a/src/org/thoughtcrime/securesms/util/ServiceUtil.java
+++ b/src/org/thoughtcrime/securesms/util/ServiceUtil.java
@@ -1,6 +1,7 @@
package org.thoughtcrime.securesms.util;
import android.app.Activity;
+import android.app.NotificationManager;
import android.content.Context;
import android.net.ConnectivityManager;
import android.view.WindowManager;
@@ -18,4 +19,8 @@ public static WindowManager getWindowManager(Context context) {
public static ConnectivityManager getConnectivityManager(Context context) {
return (ConnectivityManager) context.getSystemService(Activity.CONNECTIVITY_SERVICE);
}
+
+ public static NotificationManager getNotificationManager(Context context) {
+ return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+ }
}
diff --git a/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java b/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java
index 154d8d695ea..7d4d62b01bb 100644
--- a/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java
+++ b/src/org/thoughtcrime/securesms/util/TextSecurePreferences.java
@@ -44,6 +44,7 @@ public class TextSecurePreferences {
public static final String ENABLE_MANUAL_MMS_PREF = "pref_enable_manual_mms";
private static final String LAST_VERSION_CODE_PREF = "last_version_code";
+ private static final String LAST_EXPERIENCE_VERSION_PREF = "last_experience_version_code";
public static final String RINGTONE_PREF = "pref_key_ringtone";
private static final String VIBRATE_PREF = "pref_key_vibrate";
private static final String NOTIFICATION_PREF = "pref_key_enable_notifications";
@@ -342,7 +343,15 @@ public static void setLastVersionCode(Context context, int versionCode) throws I
if (!setIntegerPrefrenceBlocking(context, LAST_VERSION_CODE_PREF, versionCode)) {
throw new IOException("couldn't write version code to sharedpreferences");
}
- }
+ }
+
+ public static int getLastExperienceVersionCode(Context context) {
+ return getIntegerPreference(context, LAST_EXPERIENCE_VERSION_PREF, 0);
+ }
+
+ public static void setLastExperienceVersionCode(Context context, int versionCode) {
+ setIntegerPrefrence(context, LAST_EXPERIENCE_VERSION_PREF, versionCode);
+ }
public static String getTheme(Context context) {
return getStringPreference(context, THEME_PREF, "light");
diff --git a/src/org/thoughtcrime/securesms/util/ViewUtil.java b/src/org/thoughtcrime/securesms/util/ViewUtil.java
index 0a20a243817..9cd4af625e0 100644
--- a/src/org/thoughtcrime/securesms/util/ViewUtil.java
+++ b/src/org/thoughtcrime/securesms/util/ViewUtil.java
@@ -16,7 +16,7 @@
*/
package org.thoughtcrime.securesms.util;
-import android.content.Context;
+import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
@@ -72,6 +72,11 @@ public static T findById(@NonNull View parent, @IdRes int resId
return (T) parent.findViewById(resId);
}
+ @SuppressWarnings("unchecked")
+ public static T findById(@NonNull Activity parent, @IdRes int resId) {
+ return (T) parent.findViewById(resId);
+ }
+
private static Animation getAlphaAnimation(float from, float to, int duration) {
final Animation anim = new AlphaAnimation(from, to);
anim.setInterpolator(new FastOutSlowInInterpolator());