diff --git a/libs/android-support-v4.jar b/libs/android-support-v4.jar index 6080877d4a..428bdbc02a 100644 Binary files a/libs/android-support-v4.jar and b/libs/android-support-v4.jar differ diff --git a/res/drawable-hdpi/contacts_identities_dark.png b/res/drawable-hdpi/contacts_identities_dark.png new file mode 100644 index 0000000000..dbf88a85bc Binary files /dev/null and b/res/drawable-hdpi/contacts_identities_dark.png differ diff --git a/res/drawable-hdpi/contacts_identities_light.png b/res/drawable-hdpi/contacts_identities_light.png new file mode 100644 index 0000000000..bb05720467 Binary files /dev/null and b/res/drawable-hdpi/contacts_identities_light.png differ diff --git a/res/drawable-hdpi/drawer_shadow_dark.9.png b/res/drawable-hdpi/drawer_shadow_dark.9.png new file mode 100644 index 0000000000..224cc4ff43 Binary files /dev/null and b/res/drawable-hdpi/drawer_shadow_dark.9.png differ diff --git a/res/drawable-hdpi/drawer_shadow_light.9.png b/res/drawable-hdpi/drawer_shadow_light.9.png new file mode 100644 index 0000000000..224cc4ff43 Binary files /dev/null and b/res/drawable-hdpi/drawer_shadow_light.9.png differ diff --git a/res/drawable-hdpi/ic_drawer.png b/res/drawable-hdpi/ic_drawer.png new file mode 100644 index 0000000000..ff7b1def9a Binary files /dev/null and b/res/drawable-hdpi/ic_drawer.png differ diff --git a/res/drawable-hdpi/import_export_dark.png b/res/drawable-hdpi/import_export_dark.png new file mode 100644 index 0000000000..160a2b8fe3 Binary files /dev/null and b/res/drawable-hdpi/import_export_dark.png differ diff --git a/res/drawable-hdpi/import_export_light.png b/res/drawable-hdpi/import_export_light.png new file mode 100644 index 0000000000..cf7e761bad Binary files /dev/null and b/res/drawable-hdpi/import_export_light.png differ diff --git a/res/drawable-hdpi/my_identity_dark.png b/res/drawable-hdpi/my_identity_dark.png new file mode 100644 index 0000000000..0997e31dd9 Binary files /dev/null and b/res/drawable-hdpi/my_identity_dark.png differ diff --git a/res/drawable-hdpi/my_identity_light.png b/res/drawable-hdpi/my_identity_light.png new file mode 100644 index 0000000000..7b64886f7d Binary files /dev/null and b/res/drawable-hdpi/my_identity_light.png differ diff --git a/res/drawable-mdpi/contacts_identities_dark.png b/res/drawable-mdpi/contacts_identities_dark.png new file mode 100644 index 0000000000..a19796c36a Binary files /dev/null and b/res/drawable-mdpi/contacts_identities_dark.png differ diff --git a/res/drawable-mdpi/contacts_identities_light.png b/res/drawable-mdpi/contacts_identities_light.png new file mode 100644 index 0000000000..af80d47686 Binary files /dev/null and b/res/drawable-mdpi/contacts_identities_light.png differ diff --git a/res/drawable-mdpi/drawer_shadow_dark.9.png b/res/drawable-mdpi/drawer_shadow_dark.9.png new file mode 100644 index 0000000000..3797f99c0e Binary files /dev/null and b/res/drawable-mdpi/drawer_shadow_dark.9.png differ diff --git a/res/drawable-mdpi/drawer_shadow_light.9.png b/res/drawable-mdpi/drawer_shadow_light.9.png new file mode 100644 index 0000000000..3797f99c0e Binary files /dev/null and b/res/drawable-mdpi/drawer_shadow_light.9.png differ diff --git a/res/drawable-mdpi/ic_drawer.png b/res/drawable-mdpi/ic_drawer.png new file mode 100644 index 0000000000..fb681ba263 Binary files /dev/null and b/res/drawable-mdpi/ic_drawer.png differ diff --git a/res/drawable-mdpi/import_export_dark.png b/res/drawable-mdpi/import_export_dark.png new file mode 100644 index 0000000000..a74fe67943 Binary files /dev/null and b/res/drawable-mdpi/import_export_dark.png differ diff --git a/res/drawable-mdpi/import_export_light.png b/res/drawable-mdpi/import_export_light.png new file mode 100644 index 0000000000..f481a04aab Binary files /dev/null and b/res/drawable-mdpi/import_export_light.png differ diff --git a/res/drawable-mdpi/my_identity_dark.png b/res/drawable-mdpi/my_identity_dark.png new file mode 100644 index 0000000000..b1f8be1b3f Binary files /dev/null and b/res/drawable-mdpi/my_identity_dark.png differ diff --git a/res/drawable-mdpi/my_identity_light.png b/res/drawable-mdpi/my_identity_light.png new file mode 100644 index 0000000000..35e67efb8b Binary files /dev/null and b/res/drawable-mdpi/my_identity_light.png differ diff --git a/res/drawable-xhdpi/contacts_identities_dark.png b/res/drawable-xhdpi/contacts_identities_dark.png new file mode 100644 index 0000000000..32d24d2c33 Binary files /dev/null and b/res/drawable-xhdpi/contacts_identities_dark.png differ diff --git a/res/drawable-xhdpi/contacts_identities_light.png b/res/drawable-xhdpi/contacts_identities_light.png new file mode 100644 index 0000000000..5b4ebc08af Binary files /dev/null and b/res/drawable-xhdpi/contacts_identities_light.png differ diff --git a/res/drawable-xhdpi/drawer_shadow_dark.9.png b/res/drawable-xhdpi/drawer_shadow_dark.9.png new file mode 100644 index 0000000000..fa3d853e90 Binary files /dev/null and b/res/drawable-xhdpi/drawer_shadow_dark.9.png differ diff --git a/res/drawable-xhdpi/drawer_shadow_light.9.png b/res/drawable-xhdpi/drawer_shadow_light.9.png new file mode 100644 index 0000000000..fa3d853e90 Binary files /dev/null and b/res/drawable-xhdpi/drawer_shadow_light.9.png differ diff --git a/res/drawable-xhdpi/ic_drawer.png b/res/drawable-xhdpi/ic_drawer.png new file mode 100644 index 0000000000..b9bc3d70f1 Binary files /dev/null and b/res/drawable-xhdpi/ic_drawer.png differ diff --git a/res/drawable-xhdpi/import_export_dark.png b/res/drawable-xhdpi/import_export_dark.png new file mode 100644 index 0000000000..6161b58e6d Binary files /dev/null and b/res/drawable-xhdpi/import_export_dark.png differ diff --git a/res/drawable-xhdpi/import_export_light.png b/res/drawable-xhdpi/import_export_light.png new file mode 100644 index 0000000000..7c1c1d718d Binary files /dev/null and b/res/drawable-xhdpi/import_export_light.png differ diff --git a/res/drawable-xhdpi/my_identity_dark.png b/res/drawable-xhdpi/my_identity_dark.png new file mode 100644 index 0000000000..46ef148de1 Binary files /dev/null and b/res/drawable-xhdpi/my_identity_dark.png differ diff --git a/res/drawable-xhdpi/my_identity_light.png b/res/drawable-xhdpi/my_identity_light.png new file mode 100644 index 0000000000..357229b80d Binary files /dev/null and b/res/drawable-xhdpi/my_identity_light.png differ diff --git a/res/layout/conversation_list_activity.xml b/res/layout/conversation_list_activity.xml index fd34417503..73fbafc8bf 100644 --- a/res/layout/conversation_list_activity.xml +++ b/res/layout/conversation_list_activity.xml @@ -1,13 +1,21 @@ - + + android:id="@+id/fragment_content" + android:name="org.thoughtcrime.securesms.ConversationListFragment" + android:layout_width="match_parent" + android:layout_height="match_parent"/> - \ No newline at end of file + + \ No newline at end of file diff --git a/res/layout/navigation_drawer_item.xml b/res/layout/navigation_drawer_item.xml new file mode 100644 index 0000000000..2623b88364 --- /dev/null +++ b/res/layout/navigation_drawer_item.xml @@ -0,0 +1,23 @@ + + + + + + + + \ No newline at end of file diff --git a/res/values/arrays.xml b/res/values/arrays.xml index a24008290e..63a17e0788 100644 --- a/res/values/arrays.xml +++ b/res/values/arrays.xml @@ -41,12 +41,35 @@ @string/preferences__slow @string/preferences__custom - + + 300,300 500,2000 3000,3000 custom - + + + @string/arrays__import_export + @string/arrays__my_identity_key + @string/arrays__contact_keys + + + + import_export + my_identity_key + contact_identity_keys + + + + @drawable/import_export_light + @drawable/my_identity_light + @drawable/contacts_identities_light + + + + @drawable/import_export_dark + @drawable/my_identity_dark + @drawable/contacts_identities_dark + \ No newline at end of file diff --git a/res/values/attrs.xml b/res/values/attrs.xml index 5097450f27..b662e79d12 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -16,4 +16,9 @@ + + + + + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index 14298b8443..bc83efa01c 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -84,7 +84,7 @@ Invalid recipient! Calls Not Supported This device does not appear to support dial actions. - + Message details Sender: %1$s\nTransport: %2$s\nSent/Received:%3$s @@ -379,7 +379,12 @@ Manage Identity Keys Complete Key Exchange Verify Imported Identity - + + + Import / Export + My Identity Key + Contact Keys + General Use Settings @@ -459,6 +464,8 @@ Scan through all conversation threads and enforce conversation length limits Light Theme Dark Theme + Appearance + Theme @@ -528,8 +535,6 @@ Verified - Appearance - Theme diff --git a/res/values/themes.xml b/res/values/themes.xml index 3e29c835b4..eda774b4b5 100644 --- a/res/values/themes.xml +++ b/res/values/themes.xml @@ -19,6 +19,15 @@ @drawable/ic_sms_mms_delivered_light + + + + \ No newline at end of file diff --git a/src/org/thoughtcrime/securesms/ConversationListActivity.java b/src/org/thoughtcrime/securesms/ConversationListActivity.java index f43ec1edc1..f7926ff652 100644 --- a/src/org/thoughtcrime/securesms/ConversationListActivity.java +++ b/src/org/thoughtcrime/securesms/ConversationListActivity.java @@ -1,18 +1,26 @@ package org.thoughtcrime.securesms; import android.content.Intent; +import android.content.res.TypedArray; import android.database.ContentObserver; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.provider.ContactsContract; +import android.support.v4.view.GravityCompat; +import android.support.v4.widget.DrawerLayout; import android.util.Log; +import android.view.View; import android.view.WindowManager; +import android.widget.AdapterView; +import android.widget.ListView; +import android.widget.SimpleAdapter; import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.MenuInflater; import com.actionbarsherlock.view.MenuItem; import org.thoughtcrime.securesms.ApplicationExportManager.ApplicationExportListener; +import org.thoughtcrime.securesms.crypto.IdentityKeyUtil; import org.thoughtcrime.securesms.crypto.MasterSecret; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.ThreadDatabase; @@ -24,13 +32,20 @@ import org.thoughtcrime.securesms.service.SendReceiveService; import org.thoughtcrime.securesms.util.DynamicTheme; import org.thoughtcrime.securesms.util.MemoryCleaner; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + public class ConversationListActivity extends PassphraseRequiredSherlockFragmentActivity - implements ConversationListFragment.ConversationSelectedListener + implements ConversationListFragment.ConversationSelectedListener, + ListView.OnItemClickListener { private final DynamicTheme dynamicTheme = new DynamicTheme(); private ConversationListFragment fragment; private MasterSecret masterSecret; + private DrawerLayout drawerLayout; + private ListView drawerList; @Override public void onCreate(Bundle icicle) { @@ -40,6 +55,7 @@ public class ConversationListActivity extends PassphraseRequiredSherlockFragment setContentView(R.layout.conversation_list_activity); getSupportActionBar().setTitle("TextSecure"); + initializeNavigationDrawer(); initializeSenderReceiverService(); initializeResources(); initializeContactUpdatesReceiver(); @@ -76,6 +92,31 @@ public class ConversationListActivity extends PassphraseRequiredSherlockFragment return true; } + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + String[] values = getResources().getStringArray(R.array.navigation_drawer_values); + String selected = values[position]; + + Intent intent; + + if (selected.equals("import_export")) { + intent = new Intent(); + } else if (selected.equals("my_identity_key")) { + intent = new Intent(this, ViewIdentityActivity.class); + intent.putExtra("identity_key", IdentityKeyUtil.getIdentityKey(this)); + intent.putExtra("title", getString(R.string.ApplicationPreferencesActivity_my) + " " + + getString(R.string.ViewIdentityActivity_identity_fingerprint)); + } else if (selected.equals("contact_identity_keys")) { + intent = new Intent(this, ReviewIdentitiesActivity.class); + intent.putExtra("master_secret", masterSecret); + } else { + return; + } + + drawerLayout.closeDrawers(); + startActivity(intent); + } + @Override public boolean onOptionsItemSelected(MenuItem item) { super.onOptionsItemSelected(item); @@ -89,6 +130,7 @@ public class ConversationListActivity extends PassphraseRequiredSherlockFragment case R.id.menu_import: handleImportDatabase(); return true; case R.id.menu_clear_passphrase: handleClearPassphrase(); return true; case R.id.menu_mark_all_read: handleMarkAllRead(); return true; + case android.R.id.home: handleNavigationDrawerToggle(); return true; } return false; @@ -109,6 +151,14 @@ public class ConversationListActivity extends PassphraseRequiredSherlockFragment startActivity(intent); } + private void handleNavigationDrawerToggle() { + if (drawerLayout.isDrawerOpen(drawerList)) { + drawerLayout.closeDrawer(drawerList); + } else { + drawerLayout.openDrawer(drawerList); + } + } + private void handleDisplaySettings() { Intent preferencesIntent = new Intent(this, ApplicationPreferencesActivity.class); preferencesIntent.putExtra("master_secret", masterSecret); @@ -151,6 +201,40 @@ public class ConversationListActivity extends PassphraseRequiredSherlockFragment }.execute(); } + private void initializeNavigationDrawer() { + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setHomeButtonEnabled(true); + + int[] attributes = new int[] {R.attr.navigation_drawer_icons, R.attr.navigation_drawer_shadow}; + String[] from = new String[]{"navigation_icon", "navigation_text" }; + int[] to = new int[] {R.id.navigation_icon, R.id.navigation_text}; + + TypedArray iconArray = obtainStyledAttributes(attributes); + int iconArrayResource = iconArray.getResourceId(0, -1); + TypedArray icons = getResources().obtainTypedArray(iconArrayResource); + String[] text = getResources().getStringArray(R.array.navigation_drawer_text); + + List> items = new ArrayList>(); + + for(int i = 0; i < text.length; i++){ + HashMap item = new HashMap(); + item.put("navigation_icon", Integer.toString(icons.getResourceId(i, -1))); + item.put("navigation_text", text[i]); + items.add(item); + } + + DrawerLayout drawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout); + ListView drawer = (ListView)findViewById(R.id.left_drawer); + SimpleAdapter adapter = new SimpleAdapter(this, items, R.layout.navigation_drawer_item, from, to); + + drawerLayout.setDrawerShadow(iconArray.getDrawable(1), GravityCompat.START); + drawer.setAdapter(adapter); + drawer.setOnItemClickListener(this); + + iconArray.recycle(); + icons.recycle(); + } + private void initializeContactUpdatesReceiver() { ContentObserver observer = new ContentObserver(null) { @Override @@ -179,6 +263,8 @@ public class ConversationListActivity extends PassphraseRequiredSherlockFragment WindowManager.LayoutParams.FLAG_SECURE); } + this.drawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout); + this.drawerList = (ListView)findViewById(R.id.left_drawer); this.masterSecret = (MasterSecret)getIntent().getParcelableExtra("master_secret"); this.fragment = (ConversationListFragment)this.getSupportFragmentManager() @@ -186,4 +272,5 @@ public class ConversationListActivity extends PassphraseRequiredSherlockFragment this.fragment.setMasterSecret(masterSecret); } -} + + } diff --git a/src/org/thoughtcrime/securesms/util/DynamicTheme.java b/src/org/thoughtcrime/securesms/util/DynamicTheme.java index 183b1403f9..85a6999db5 100644 --- a/src/org/thoughtcrime/securesms/util/DynamicTheme.java +++ b/src/org/thoughtcrime/securesms/util/DynamicTheme.java @@ -1,12 +1,12 @@ 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.ConversationListActivity; import org.thoughtcrime.securesms.R; public class DynamicTheme { @@ -36,18 +36,16 @@ public class DynamicTheme { } } - public static int getSelectedTheme(Context context) { - String theme = PreferenceManager.getDefaultSharedPreferences(context) + private static int getSelectedTheme(Activity activity) { + String theme = PreferenceManager.getDefaultSharedPreferences(activity) .getString(ApplicationPreferencesActivity.THEME_PREF, "light"); - return getSelectedTheme(theme); - } - - public static int getSelectedTheme(String theme) { if (theme.equals("light")) { - return R.style.TextSecure_LightTheme; + if (activity instanceof ConversationListActivity) return R.style.TextSecure_LightTheme_NavigationDrawer; + else return R.style.TextSecure_LightTheme; } else if (theme.equals("dark")) { - return R.style.TextSecure_DarkTheme; + if (activity instanceof ConversationListActivity) return R.style.TextSecure_DarkTheme_NavigationDrawer; + else return R.style.TextSecure_DarkTheme; } return R.style.TextSecure_LightTheme;