Navigation drawer (squashed and rebased).

This commit is contained in:
Ernir Erlingsson
2016-01-13 21:25:01 +01:00
committed by akwizgran
parent d33dbca25a
commit dae29eecce
26 changed files with 1260 additions and 637 deletions

View File

@@ -1,18 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
<manifest
package="org.briarproject"
xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="11"
android:versionName="0.11" >
android:versionName="0.11">
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="22"
xmlns:tools="http://schemas.android.com/tools"
tools:overrideLibrary="android.support.v14.preference"
/>
android:minSdkVersion="9"
<uses-feature android:name="android.hardware.bluetooth" />
android:targetSdkVersion="22"
tools:overrideLibrary="android.support.v14.preference"
/>
<uses-feature android:name="android.hardware.bluetooth"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
@@ -23,183 +24,160 @@
<!-- Since API 23, this is needed to add contacts via Bluetooth -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- FIXME: Only needed for alpha and beta builds -->
<uses-permission android:name="android.permission.READ_LOGS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_LOGS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:name=".android.BriarApplication"
android:theme="@style/BriarTheme"
android:allowBackup="false"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:logo="@drawable/logo"
android:allowBackup="false" >
android:theme="@style/BriarTheme">
<service
android:name=".android.BriarService"
android:exported="false" >
android:exported="false">
<intent-filter>
<action android:name="org.briarproject.android.BriarService" />
<action android:name="org.briarproject.android.BriarService"/>
</intent-filter>
</service>
<activity
android:name=".android.CrashReportActivity"
android:label="@string/crash_report_title"
android:taskAffinity="org.briarproject.android.CrashHandler"
android:excludeFromRecents="true"
android:exported="false"
android:label="@string/crash_report_title"
android:launchMode="singleInstance"
android:process=":briar_error_handler"
android:exported="false" >
android:taskAffinity="org.briarproject.android.CrashHandler">
<intent-filter>
<action android:name="org.briarproject.REPORT_CRASH" />
<category android:name="android.intent.category.DEFAULT" />
<action android:name="org.briarproject.REPORT_CRASH"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity
android:name=".android.DashboardActivity"
android:label="@string/app_name" >
</activity>
<activity
android:name=".android.ExpiredActivity"
android:label="@string/app_name" >
android:label="@string/app_name">
</activity>
<activity
android:name=".android.PasswordActivity"
android:label="@string/app_name"
android:windowSoftInputMode="stateVisible" >
</activity>
<activity
android:name=".android.SettingsActivity"
android:label="@string/settings_title"
android:parentActivityName=".android.DashboardActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.DashboardActivity"
/>
android:windowSoftInputMode="stateVisible">
</activity>
<activity
android:name=".android.SetupActivity"
android:label="@string/setup_title" >
android:label="@string/setup_title">
</activity>
<activity
android:name=".android.SplashScreenActivity"
android:label="@string/app_name" >
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name=".android.TestingActivity"
android:label="@string/app_name" >
android:label="@string/app_name">
</activity>
<activity
android:name=".android.contact.ContactListActivity"
android:label="@string/contact_list_title"
android:parentActivityName=".android.DashboardActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.DashboardActivity"
android:name=".android.NavDrawerActivity"
android:theme="@style/BriarThemeNoActionBar.Default"
android:launchMode="singleTop"
/>
</activity>
<activity
android:name=".android.contact.ConversationActivity"
android:label="@string/app_name"
android:windowSoftInputMode="stateHidden"
android:parentActivityName=".android.contact.ContactListActivity" >
android:parentActivityName=".android.NavDrawerActivity"
android:windowSoftInputMode="stateHidden">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.contact.ContactListActivity"
/>
android:value=".android.NavDrawerActivity"
/>
</activity>
<activity
android:name=".android.forum.AvailableForumsActivity"
android:label="@string/available_forums_title"
android:parentActivityName=".android.forum.ForumListActivity" >
android:parentActivityName=".android.NavDrawerActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.forum.ForumListActivity"
/>
android:value=".android.NavDrawerActivity"
/>
</activity>
<activity
android:name=".android.forum.CreateForumActivity"
android:label="@string/create_forum_title"
android:windowSoftInputMode="stateVisible"
android:parentActivityName=".android.forum.ForumListActivity" >
android:parentActivityName=".android.NavDrawerActivity"
android:windowSoftInputMode="stateVisible">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.forum.ForumListActivity"
/>
android:value=".android.NavDrawerActivity"
/>
</activity>
<activity
android:name=".android.forum.ForumActivity"
android:label="@string/app_name"
android:parentActivityName=".android.forum.ForumListActivity" >
android:parentActivityName=".android.NavDrawerActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.forum.ForumListActivity"
/>
</activity>
<activity
android:name=".android.forum.ForumListActivity"
android:label="@string/forums_title"
android:parentActivityName=".android.DashboardActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.DashboardActivity"
/>
android:value=".android.NavDrawerActivity"
/>
</activity>
<activity
android:name=".android.forum.ReadForumPostActivity"
android:label="@string/app_name"
android:parentActivityName=".android.forum.ForumListActivity" >
android:parentActivityName=".android.NavDrawerActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.forum.ForumListActivity"
/>
android:value=".android.NavDrawerActivity"
/>
</activity>
<activity
android:name=".android.forum.ShareForumActivity"
android:label="@string/app_name"
android:parentActivityName=".android.forum.ForumListActivity" >
android:parentActivityName=".android.NavDrawerActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.forum.ForumListActivity"
/>
android:value=".android.NavDrawerActivity"
/>
</activity>
<activity
android:name=".android.forum.WriteForumPostActivity"
android:label="@string/app_name"
android:windowSoftInputMode="stateVisible"
android:parentActivityName=".android.forum.ForumListActivity" >
android:parentActivityName=".android.NavDrawerActivity"
android:windowSoftInputMode="stateVisible">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.forum.ForumListActivity"
/>
android:value=".android.NavDrawerActivity"
/>
</activity>
<activity
android:name=".android.identity.CreateIdentityActivity"
android:label="@string/new_identity_title"
android:windowSoftInputMode="stateVisible" >
android:windowSoftInputMode="stateVisible">
</activity>
<activity
android:name=".android.invitation.AddContactActivity"
android:label="@string/add_contact_title"
android:parentActivityName=".android.contact.ContactListActivity" >
android:parentActivityName=".android.NavDrawerActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.contact.ContactListActivity"
/>
android:value=".android.NavDrawerActivity"
/>
</activity>
<activity
android:name=".android.StartupFailureActivity"
android:label="@string/startup_failed_activity_title" >
android:label="@string/startup_failed_activity_title">
</activity>
<activity
android:name=".android.panic.PanicPreferencesActivity"
android:label="@string/panic_setting" >
android:label="@string/panic_setting">
<intent-filter>
<action android:name="info.guardianproject.panic.action.CONNECT" />
<action android:name="info.guardianproject.panic.action.DISCONNECT" />
<category android:name="android.intent.category.DEFAULT" />
<action android:name="info.guardianproject.panic.action.CONNECT"/>
<action android:name="info.guardianproject.panic.action.DISCONNECT"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity
@@ -208,12 +186,12 @@
android:theme="@android:style/Theme.NoDisplay">
<!-- this can never have launchMode singleTask or singleInstance! -->
<intent-filter>
<action android:name="info.guardianproject.panic.action.TRIGGER" />
<category android:name="android.intent.category.DEFAULT" />
<action android:name="info.guardianproject.panic.action.TRIGGER"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity
android:name=".android.panic.ExitActivity"
android:theme="@android:style/Theme.NoDisplay" />
android:theme="@android:style/Theme.NoDisplay"/>
</application>
</manifest>

View File

@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The first child(root) is the content view -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
style="@style/BriarToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/content_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/default_background"/>
<RelativeLayout
android:id="@+id/container_progress"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="@color/default_background"
android:visibility="invisible"
tools:visibility="visible">
<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleLargeInverse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
<TextView
android:id="@+id/title_progress_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/progress_bar"
android:gravity="center"
android:paddingTop="@dimen/margin_large"
tools:text="progress bar title"
/>
</RelativeLayout>
</FrameLayout>
</LinearLayout>
<!-- The second child is the menu -->
<include
android:id="@+id/navigation_menu_drawer"
layout="@layout/navigation_menu"
android:layout_width="@dimen/nav_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"/>
</android.support.v4.widget.DrawerLayout>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/dashboard_background"
>
</RelativeLayout>

View File

@@ -0,0 +1,110 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="@dimen/nav_drawer_width"
android:layout_height="match_parent"
android:background="@color/menu_background"
android:orientation="vertical">
<TextView
android:id="@+id/nav_menu_header"
style="@style/BriarTextTitleInverted"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/briar_primary"
android:paddingBottom="@dimen/margin_large"
android:paddingLeft="@dimen/margin_large"
android:paddingTop="@dimen/margin_xlarge"
android:textStyle="bold"
tools:text="Username"
/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fadingEdge="none"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.AppCompatButton
android:id="@+id/nav_btn_contacts"
style="@style/NavMenuButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/social_person"
android:onClick="onNavigationClick"
android:text="@string/contact_list_button"/>
<View
style="@style/Divider"
android:layout_width="match_parent"
android:layout_height="@dimen/nav_seperator_height"
android:layout_marginLeft="@dimen/margin_large"/>
<android.support.v7.widget.AppCompatButton
android:id="@+id/nav_btn_forums"
style="@style/NavMenuButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/social_chat"
android:onClick="onNavigationClick"
android:text="@string/forums_button"/>
<View
style="@style/Divider"
android:layout_width="match_parent"
android:layout_height="@dimen/margin_seperator"
android:layout_marginLeft="@dimen/margin_large"/>
<android.support.v7.widget.AppCompatButton
android:id="@+id/nav_btn_settings"
style="@style/NavMenuButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/action_settings"
android:onClick="onNavigationClick"
android:text="@string/settings_button"/>
<View
style="@style/Divider"
android:layout_width="match_parent"
android:layout_height="@dimen/margin_seperator"
android:layout_marginLeft="@dimen/margin_large"/>
<android.support.v7.widget.AppCompatButton
android:id="@+id/nav_btn_signout"
style="@style/NavMenuButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/device_access_accounts"
android:onClick="onNavigationClick"
android:text="@string/sign_out_button"/>
<View
style="@style/Divider"
android:layout_width="match_parent"
android:layout_height="@dimen/margin_seperator"
android:layout_marginLeft="@dimen/margin_large"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.0"/>
<include
layout="@layout/transports_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
</ScrollView>
</LinearLayout>

View File

@@ -26,4 +26,8 @@
<!-- this is needed as preference_category_material layout uses this color as the text color -->
<color name="preference_fallback_accent_color">@color/briar_accent</color>
<color name="default_background">#ffffff</color>
<color name="default_seperator">#000000</color>
<color name="default_seperator_inverted">#ffffff</color>
<color name="menu_background">#FFFFFF</color>
</resources>

View File

@@ -17,5 +17,7 @@
<dimen name="text_size_medium">16sp</dimen>
<dimen name="text_size_large">20sp</dimen>
<dimen name="text_size_xlarge">34sp</dimen>
<dimen name="nav_drawer_width">300dp</dimen>
<dimen name="nav_seperator_height">1dp</dimen>
</resources>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="nav_drawer_open_description">Open the navigation drawer</string>
<string name="nav_drawer_close_description">Close the navigation drawer</string>
<string name="app_name">Briar</string>
<string name="crash_report_title">Briar Crash Report</string>
<string name="ongoing_notification_title">Signed into Briar</string>
@@ -141,4 +141,15 @@
<string name="dialog_message_delete_contact">Are you sure that you want to remove this contact and all messages exchanged with this contact?</string>
<string name="dialog_title_connect_panic_app">Confirm Panic App</string>
<string name="dialog_message_connect_panic_app">Are you sure that you want to allow %1$s to trigger destructive panic button actions?</string>
<string name="dialog_title_welcome">Welcome to Briar</string>
<string name="dialog_welcome_message">Add a contact to start communicating securely or press the icon in the upper left corner of the screen for more options.</string>
<string name="dialog_button_ok">OK</string>
<!-- Toolbar headers -->
<string name="dashboard_toolbar_header">Briar</string>
<string name="settings_toolbar_header">Settings</string>
<string name="contacts_toolbar_header">Contacts</string>
<string name="forums_toolbar_header">Forums</string>
<!-- Progress titles -->
<string name="progress_title_logout">Signing out of Briar..</string>
<string name="progress_title_please_wait">Please wait..</string>
</resources>

View File

@@ -12,6 +12,36 @@
<item name="android:textColorLink">@color/briar_text_link</item>
</style>
<style name="BriarThemeNoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
<item name="toolbarStyle">@style/BriarToolbar</item>
<item name="colorPrimary">@color/briar_primary</item>
<item name="colorPrimaryDark">@color/briar_primary_dark</item>
<item name="colorAccent">@color/briar_primary</item>
<item name="android:textColorPrimary">@color/briar_text_primary</item>
<item name="android:textColorPrimaryInverse">@color/briar_text_primary_inverse</item>
<item name="android:textColorSecondary">@color/briar_text_primary</item>
<item name="android:textColorLink">@color/briar_text_link</item>
</style>
<style name="BriarThemeNoActionBar.Default" />
<style name="BriarToolbar" parent="Widget.AppCompat.Toolbar">
<item name="android:background">?colorPrimary</item>
<item name="android:textColorPrimary">@color/briar_text_primary_inverse</item>
<item name="android:textSize">@dimen/text_size_medium</item>
<item name="colorPrimary">@color/briar_primary</item>
<item name="titleTextAppearance">@style/BriarToolbarTextAppearance</item>
<item name="android:theme">@style/BriarToolbarTheme</item>
</style>
<style name="BriarToolbarTheme">
<item name="colorControlNormal">@color/briar_text_primary_inverse</item>
</style>
<style name="BriarToolbarTextAppearance" parent="TextAppearance.Widget.AppCompat.Toolbar.Title">
<item name="android:textColor">@color/briar_text_primary_inverse</item>
</style>
<style name="BriarTheme" parent="BriarBaseTheme">
<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
<item name="android:listSeparatorTextViewStyle">@style/BriarTheme.ListSeparatorTextView</item>
@@ -33,6 +63,10 @@
<item name="android:textColor">@android:color/primary_text_light</item>
</style>
<style name="BriarTextTitleInverted" parent="BriarTextTitle">
<item name="android:textColor">@android:color/primary_text_dark</item>
</style>
<style name="BriarTextBody">
<item name="android:textSize">@dimen/text_size_small</item>
<item name="android:textColor">@android:color/primary_text_light</item>
@@ -47,6 +81,17 @@
<item name="android:layout_height">1px</item>
</style>
<style name="NavMenuButton" parent="Widget.AppCompat.Button.Borderless.Colored">
<item name="android:textSize">@dimen/text_size_medium</item>
<item name="android:textColor">@android:color/tertiary_text_light</item>
<item name="android:paddingTop">@dimen/margin_large</item>
<item name="android:paddingBottom">@dimen/margin_large</item>
<item name="android:drawablePadding">@dimen/margin_xlarge</item>
<item name="android:gravity">left|center_vertical</item>
<item name="android:layout_margin">0dp</item>
<item name="android:paddingLeft">@dimen/margin_large</item>
</style>
<!-- This fixes a UI bug in the support preference library -->
<style name="BriarTheme.ListSeparatorTextView">
<item name="android:textSize">14sp</item>

View File

@@ -9,10 +9,8 @@ import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import org.briarproject.R;
import org.briarproject.android.contact.ContactListActivity;
import org.briarproject.android.contact.ConversationActivity;
import org.briarproject.android.forum.ForumActivity;
import org.briarproject.android.forum.ForumListActivity;
import org.briarproject.api.Settings;
import org.briarproject.api.android.AndroidExecutor;
import org.briarproject.api.android.AndroidNotificationManager;
@@ -205,10 +203,11 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
t.addNextIntent(i);
b.setContentIntent(t.getPendingIntent(nextRequestId++, 0));
} else {
Intent i = new Intent(appContext, ContactListActivity.class);
Intent i = new Intent(appContext, NavDrawerActivity.class);
i.putExtra(NavDrawerActivity.INTENT_CONTACTS, true);
i.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP);
TaskStackBuilder t = TaskStackBuilder.create(appContext);
t.addParentStack(ContactListActivity.class);
t.addParentStack(NavDrawerActivity.class);
t.addNextIntent(i);
b.setContentIntent(t.getPendingIntent(nextRequestId++, 0));
}
@@ -283,10 +282,11 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
t.addNextIntent(i);
b.setContentIntent(t.getPendingIntent(nextRequestId++, 0));
} else {
Intent i = new Intent(appContext, ForumListActivity.class);
Intent i = new Intent(appContext, NavDrawerActivity.class);
i.putExtra(NavDrawerActivity.INTENT_FORUMS, true);
i.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP);
TaskStackBuilder t = TaskStackBuilder.create(appContext);
t.addParentStack(ForumListActivity.class);
t.addParentStack(NavDrawerActivity.class);
t.addNextIntent(i);
b.setContentIntent(t.getPendingIntent(nextRequestId++, 0));
}

View File

@@ -14,6 +14,7 @@ import org.briarproject.api.db.DatabaseExecutor;
import org.briarproject.api.lifecycle.LifecycleManager;
import java.util.concurrent.Executor;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.inject.Inject;
@@ -22,7 +23,10 @@ import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
@SuppressLint("Registered")
public class BriarActivity extends BaseActivity {
public abstract class BriarActivity extends BaseActivity {
public static final String KEY_LOCAL_AUTHOR_HANDLE = "briar.LOCAL_AUTHOR_HANDLE";
public static final String KEY_STARTUP_FAILED = "briar.STARTUP_FAILED";
public static final int REQUEST_PASSWORD = 1;
@@ -125,7 +129,7 @@ public class BriarActivity extends BaseActivity {
});
}
protected void runOnDbThread(final Runnable task) {
public void runOnDbThread(final Runnable task) {
dbExecutor.execute(new Runnable() {
public void run() {
try {

View File

@@ -0,0 +1,102 @@
package org.briarproject.android;
import android.app.AlertDialog;
import android.support.annotation.AnimRes;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBar;
import org.briarproject.R;
import org.briarproject.android.fragment.BaseFragment;
import org.briarproject.android.contact.ContactListFragment;
import org.briarproject.android.fragment.DashboardFragment;
import org.briarproject.android.forum.ForumListFragment;
import org.briarproject.android.fragment.SettingsFragment;
/**
* This class should be extended by classes that wish to utilise fragments in
* Briar, it encapsulates all fragment related code.
*/
public abstract class BriarFragmentActivity extends BriarActivity {
private void updateToolbarTitle(String fragmentTag) {
ActionBar actionBar = getSupportActionBar();
if (actionBar == null)
return;
if (fragmentTag.equals(DashboardFragment.TAG)) {
actionBar.setTitle(R.string.dashboard_toolbar_header);
} else if (fragmentTag.equals(SettingsFragment.TAG)) {
actionBar.setTitle(R.string.settings_toolbar_header);
} else if (fragmentTag.equals(ContactListFragment.TAG)) {
actionBar.setTitle(R.string.contacts_toolbar_header);
} else if (fragmentTag.equals(ForumListFragment.TAG)) {
actionBar.setTitle(R.string.forums_toolbar_header);
}
}
protected void clearBackStack() {
getSupportFragmentManager()
.popBackStackImmediate(
null,
FragmentManager.POP_BACK_STACK_INCLUSIVE
);
}
@Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() == 0 &&
getSupportFragmentManager()
.findFragmentByTag(ContactListFragment.TAG) == null) {
/*
This Makes sure that the first fragment (ContactListFragment) the
user sees is the same as the last fragment the user sees before
exiting. This models the typical Google navigation behaviour such
as in Gmail/Inbox.
*/
startFragment(ContactListFragment.newInstance());
} else {
super.onBackPressed();
}
}
protected void startFragment(BaseFragment fragment) {
if (getSupportFragmentManager().getBackStackEntryCount() == 0)
this.startFragment(fragment, false);
else
this.startFragment(fragment, true);
}
protected void showMessageDialog(int titleStringId, int msgStringId) {
// TODO replace with custom dialog fragment ?
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(titleStringId);
builder.setMessage(msgStringId);
builder.setPositiveButton(R.string.dialog_button_ok, null);
AlertDialog dialog = builder.create();
dialog.show();
}
protected void startFragment(BaseFragment fragment,
boolean isAddedToBackStack) {
this.startFragment(fragment, 0, 0, isAddedToBackStack);
}
protected void startFragment(BaseFragment fragment,
@AnimRes int inAnimation, @AnimRes int outAnimation,
boolean isAddedToBackStack) {
FragmentTransaction trans =
getSupportFragmentManager().beginTransaction();
if (inAnimation != 0 && outAnimation != 0) {
trans.setCustomAnimations(inAnimation, 0, 0, outAnimation);
}
trans.replace(R.id.content_fragment, fragment, fragment.getUniqueTag());
if (isAddedToBackStack) {
trans.addToBackStack(fragment.getUniqueTag());
}
trans.commit();
updateToolbarTitle(fragment.getUniqueTag());
}
}

View File

@@ -70,7 +70,7 @@ public class BriarService extends RoboService {
b.setContentText(getText(R.string.ongoing_notification_text));
b.setWhen(0); // Don't show the time
b.setOngoing(true);
Intent i = new Intent(this, DashboardActivity.class);
Intent i = new Intent(this, NavDrawerActivity.class);
i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP |
FLAG_ACTIVITY_SINGLE_TOP);
b.setContentIntent(PendingIntent.getActivity(this, 0, i, 0));
@@ -117,7 +117,7 @@ public class BriarService extends RoboService {
NotificationManager nm = (NotificationManager) o;
nm.notify(FAILURE_NOTIFICATION_ID, b.build());
// Bring the dashboard to the front to clear the back stack
i = new Intent(BriarService.this, DashboardActivity.class);
i = new Intent(BriarService.this, NavDrawerActivity.class);
i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP);
i.putExtra("briar.STARTUP_FAILED", true);
startActivity(i);

View File

@@ -1,381 +0,0 @@
package org.briarproject.android;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import org.briarproject.R;
import org.briarproject.android.contact.ContactListActivity;
import org.briarproject.android.forum.ForumListActivity;
import org.briarproject.android.util.LayoutUtils;
import org.briarproject.api.TransportId;
import org.briarproject.api.android.ReferenceManager;
import org.briarproject.api.db.DbException;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.TransportDisabledEvent;
import org.briarproject.api.event.TransportEnabledEvent;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.plugins.Plugin;
import org.briarproject.api.plugins.PluginManager;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import javax.inject.Inject;
import static android.view.Gravity.CENTER;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.android.util.CommonLayoutParams.MATCH_MATCH;
public class DashboardActivity extends BriarActivity implements EventListener {
private static final Logger LOG =
Logger.getLogger(DashboardActivity.class.getName());
private List<Transport> transports;
private BaseAdapter transportsAdapter;
@Inject private ReferenceManager referenceManager;
@Inject private PluginManager pluginManager;
// Fields that are accessed from background threads must be volatile
@Inject private volatile IdentityManager identityManager;
@Inject private volatile EventBus eventBus;
@Override
public void onCreate(Bundle state) {
super.onCreate(state);
handleIntent(getIntent());
}
@Override
public void onResume() {
super.onResume();
updateTransports();
eventBus.addListener(this);
}
@Override
public void onPause() {
super.onPause();
eventBus.removeListener(this);
}
@Override
public void onNewIntent(Intent i) {
super.onNewIntent(i);
handleIntent(i);
}
@Override
public void eventOccurred(Event e) {
if (e instanceof TransportEnabledEvent) {
TransportId id = ((TransportEnabledEvent) e).getTransportId();
if (LOG.isLoggable(INFO)) {
LOG.info("TransportEnabledEvent: " + id.getString());
}
setTransport(id, true);
} else if (e instanceof TransportDisabledEvent) {
TransportId id = ((TransportDisabledEvent) e).getTransportId();
if (LOG.isLoggable(INFO)) {
LOG.info("TransportDisabledEvent: " + id.getString());
}
setTransport(id, false);
}
}
private void handleIntent(Intent i) {
boolean failed = i.getBooleanExtra("briar.STARTUP_FAILED", false);
long handle = i.getLongExtra("briar.LOCAL_AUTHOR_HANDLE", -1);
if (failed) {
finish();
LOG.info("Exiting");
System.exit(0);
} else if (handle == -1) {
// The activity has been launched before
showButtons();
} else {
// The activity was launched from the setup wizard
LocalAuthor a = referenceManager.removeReference(handle,
LocalAuthor.class);
// The reference may be null if the activity has been recreated,
// for example due to screen rotation
if (a == null) {
showButtons();
} else {
showSpinner();
storeLocalAuthor(a);
}
}
}
private void showButtons() {
ListView.LayoutParams matchMatch =
new ListView.LayoutParams(MATCH_PARENT, MATCH_PARENT);
final List<Button> buttons = new ArrayList<Button>();
Button contactsButton = new Button(this);
contactsButton.setLayoutParams(matchMatch);
contactsButton.setBackgroundResource(0);
contactsButton.setCompoundDrawablesWithIntrinsicBounds(0,
R.drawable.social_person, 0, 0);
contactsButton.setText(R.string.contact_list_button);
contactsButton.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
startActivity(new Intent(DashboardActivity.this,
ContactListActivity.class));
}
});
buttons.add(contactsButton);
Button forumsButton = new Button(this);
forumsButton.setLayoutParams(matchMatch);
forumsButton.setBackgroundResource(0);
forumsButton.setCompoundDrawablesWithIntrinsicBounds(0,
R.drawable.social_chat, 0, 0);
forumsButton.setText(R.string.forums_button);
forumsButton.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
startActivity(new Intent(DashboardActivity.this,
ForumListActivity.class));
}
});
buttons.add(forumsButton);
Button settingsButton = new Button(this);
settingsButton.setLayoutParams(matchMatch);
settingsButton.setBackgroundResource(0);
settingsButton.setCompoundDrawablesWithIntrinsicBounds(0,
R.drawable.action_settings, 0, 0);
settingsButton.setText(R.string.settings_button);
settingsButton.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
startActivity(new Intent(DashboardActivity.this,
SettingsActivity.class));
}
});
buttons.add(settingsButton);
Button signOutButton = new Button(this);
signOutButton.setLayoutParams(matchMatch);
signOutButton.setBackgroundResource(0);
signOutButton.setCompoundDrawablesWithIntrinsicBounds(0,
R.drawable.device_access_accounts, 0, 0);
signOutButton.setText(R.string.sign_out_button);
signOutButton.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
showSpinner();
signOut();
}
});
buttons.add(signOutButton);
int pad = LayoutUtils.getPadding(this);
LinearLayout layout = new LinearLayout(this);
layout.setLayoutParams(MATCH_MATCH);
layout.setOrientation(LinearLayout.VERTICAL);
GridView grid = new GridView(this);
LinearLayout.LayoutParams params =
new LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT, 1f);
grid.setLayoutParams(params);
grid.setGravity(CENTER);
grid.setPadding(pad, pad, pad, pad);
Resources res = getResources();
grid.setBackgroundColor(res.getColor(R.color.dashboard_background));
grid.setNumColumns(2);
grid.setAdapter(new BaseAdapter() {
public int getCount() {
return buttons.size();
}
public Object getItem(int position) {
return buttons.get(position);
}
public long getItemId(int position) {
return 0;
}
public View getView(int position, View convertView,
ViewGroup parent) {
return buttons.get(position);
}
});
layout.addView(grid);
// inflate transports layout
LayoutInflater inflater = (LayoutInflater) getSystemService
(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup transportsLayout = (ViewGroup) inflater.
inflate(R.layout.transports_list, layout);
initializeTransports();
GridView transportsView = (GridView) transportsLayout.findViewById(
R.id.transportsView);
transportsView.setAdapter(transportsAdapter);
setContentView(layout);
}
private void showSpinner() {
LinearLayout layout = new LinearLayout(this);
layout.setLayoutParams(MATCH_MATCH);
layout.setGravity(CENTER);
ProgressBar progress = new ProgressBar(this);
progress.setIndeterminate(true);
layout.addView(progress);
setContentView(layout);
}
private void storeLocalAuthor(final LocalAuthor a) {
runOnDbThread(new Runnable() {
public void run() {
try {
long now = System.currentTimeMillis();
identityManager.addLocalAuthor(a);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Storing author took " + duration + " ms");
runOnUiThread(new Runnable() {
public void run() {
showButtons();
}
});
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
}
});
}
private void initializeTransports() {
transports = new ArrayList<Transport>(3);
Transport tor = new Transport();
tor.id = new TransportId("tor");
Plugin torPlugin = pluginManager.getPlugin(tor.id);
tor.enabled = torPlugin != null && torPlugin.isRunning();
tor.iconId = R.drawable.transport_tor;
tor.textId = R.string.transport_tor;
transports.add(tor);
Transport bt = new Transport();
bt.id = new TransportId("bt");
Plugin btPlugin = pluginManager.getPlugin(bt.id);
bt.enabled = btPlugin != null && btPlugin.isRunning();
bt.iconId = R.drawable.transport_bt;
bt.textId = R.string.transport_bt;
transports.add(bt);
Transport lan = new Transport();
lan.id = new TransportId("lan");
Plugin lanPlugin = pluginManager.getPlugin(lan.id);
lan.enabled = lanPlugin != null && lanPlugin.isRunning();
lan.iconId = R.drawable.transport_lan;
lan.textId = R.string.transport_lan;
transports.add(lan);
transportsAdapter = new BaseAdapter() {
@Override
public int getCount() {
return transports.size();
}
@Override
public Transport getItem(int position) {
return transports.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView,
ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
ViewGroup view = (ViewGroup) inflater
.inflate(R.layout.list_item_transport, parent, false);
Transport t = getItem(position);
Resources r = getResources();
int c;
if (t.enabled) {
c = r.getColor(R.color.briar_green_light);
} else {
c = r.getColor(android.R.color.tertiary_text_light);
}
ImageView icon = (ImageView) view.findViewById(R.id.imageView);
icon.setImageDrawable(r.getDrawable(t.iconId));
icon.setColorFilter(c);
TextView text = (TextView) view.findViewById(R.id.textView);
text.setText(getString(t.textId));
return view;
}
};
}
private void setTransport(final TransportId id, final boolean enabled) {
runOnUiThread(new Runnable() {
public void run() {
if (transports == null || transportsAdapter == null) return;
for (Transport t : transports) {
if (t.id.equals(id)) {
t.enabled = enabled;
transportsAdapter.notifyDataSetChanged();
break;
}
}
}
});
}
private void updateTransports() {
if (transports == null || transportsAdapter == null) return;
for (Transport t : transports) {
Plugin plugin = pluginManager.getPlugin(t.id);
t.enabled = plugin != null && plugin.isRunning();
}
transportsAdapter.notifyDataSetChanged();
}
private static class Transport {
TransportId id;
boolean enabled;
int iconId;
int textId;
}
}

View File

@@ -0,0 +1,407 @@
package org.briarproject.android;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.AppCompatButton;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import org.briarproject.R;
import org.briarproject.android.fragment.BaseFragment;
import org.briarproject.android.contact.ContactListFragment;
import org.briarproject.android.forum.ForumListFragment;
import org.briarproject.android.fragment.SettingsFragment;
import org.briarproject.android.util.CustomAnimations;
import org.briarproject.api.TransportId;
import org.briarproject.api.android.ReferenceManager;
import org.briarproject.api.db.DbException;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.TransportDisabledEvent;
import org.briarproject.api.event.TransportEnabledEvent;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.plugins.Plugin;
import org.briarproject.api.plugins.PluginManager;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import javax.inject.Inject;
import roboguice.RoboGuice;
import roboguice.inject.InjectView;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
public class NavDrawerActivity extends BriarFragmentActivity implements
BaseFragment.BaseFragmentListener, EventListener {
public static final String INTENT_CONTACTS = "intent_contacts";
public static final String INTENT_FORUMS = "intent_forums";
private static final Logger LOG =
Logger.getLogger(NavDrawerActivity.class.getName());
private final static String PREFS_USER_SETTINGS = "prefs_user_settings";
private final static String KEY_SEEN_WELCOME_MESSAGE = "welcome_message";
private ActionBarDrawerToggle drawerToggle;
@Inject
private ReferenceManager referenceManager;
// Fields that are accessed from background threads must be volatile
@Inject
private volatile IdentityManager identityManager;
@Inject
private PluginManager pluginManager;
@Inject
protected volatile EventBus eventBus;
@InjectView(R.id.toolbar)
private Toolbar toolbar;
@InjectView(R.id.drawer_layout)
private DrawerLayout drawerLayout;
@InjectView(R.id.nav_btn_contacts)
private AppCompatButton contactButton;
@InjectView(R.id.nav_btn_contacts)
private AppCompatButton forumsButton;
@InjectView(R.id.nav_btn_contacts)
private AppCompatButton settingsButton;
@InjectView(R.id.nav_menu_header)
private TextView menuHeader;
@InjectView(R.id.title_progress_bar)
private TextView progressTitle;
@InjectView(R.id.container_progress)
ViewGroup progressViewGroup;
@InjectView(R.id.transportsView)
private GridView transportsView;
private List<Transport> transports;
private BaseAdapter transportsAdapter;
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (!isStartupFailed(intent)) {
checkAuthorHandle(intent);
clearBackStack();
if (intent.getBooleanExtra(INTENT_FORUMS, false))
startFragment(ForumListFragment.newInstance());
else if (intent.getBooleanExtra(INTENT_CONTACTS, false))
startFragment(ContactListFragment.newInstance());
}
}
@SuppressWarnings("ConstantConditions")
@Override
public void onCreate(Bundle state) {
super.onCreate(state);
if (isStartupFailed(getIntent()))
return;
// TODO inflate and inject with @ContentView with RoboGuice 3.0 and later
setContentView(R.layout.activity_nav_drawer);
RoboGuice.getInjector(this).injectViewMembers(this);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar,
R.string.nav_drawer_open_description,
R.string.nav_drawer_close_description
) {
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
}
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
}
};
drawerLayout.setDrawerListener(drawerToggle);
startFragment(ContactListFragment.newInstance());
checkAuthorHandle(getIntent());
initializeTransports(getLayoutInflater());
transportsView.setAdapter(transportsAdapter);
welcomeMessageCheck();
}
private void welcomeMessageCheck() {
SharedPreferences prefs = getSharedPreferences(PREFS_USER_SETTINGS,
Context.MODE_PRIVATE);
if (!prefs.getBoolean(KEY_SEEN_WELCOME_MESSAGE, false)) {
showMessageDialog(R.string.dialog_title_welcome,
R.string.dialog_welcome_message);
prefs.edit().putBoolean(KEY_SEEN_WELCOME_MESSAGE, true).apply();
}
}
@Override
public void onResume() {
super.onResume();
eventBus.addListener(this);
updateTransports();
}
@Override
protected void onPause() {
super.onPause();
eventBus.removeListener(this);
}
private void checkAuthorHandle(Intent intent) {
long handle = intent.getLongExtra(KEY_LOCAL_AUTHOR_HANDLE, -1);
if (handle != -1) {
// The activity was launched from the setup wizard
LocalAuthor a = referenceManager.removeReference(handle,
LocalAuthor.class);
if (a != null) {
showLoadingScreen(true, R.string.progress_title_please_wait);
storeLocalAuthor(a);
}
}
}
private boolean isStartupFailed(Intent intent) {
if (intent.getBooleanExtra(KEY_STARTUP_FAILED, false)) {
finish();
LOG.info("Exiting");
System.exit(0);
return true;
}
return false;
}
private void storeLocalAuthor(final LocalAuthor a) {
runOnDbThread(new Runnable() {
public void run() {
try {
long now = System.currentTimeMillis();
identityManager.addLocalAuthor(a);
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Storing author took " + duration + " ms");
runOnUiThread(new Runnable() {
public void run() {
hideLoadingScreen();
}
});
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
}
});
}
public void onNavigationClick(View view) {
drawerLayout.closeDrawer(GravityCompat.START);
clearBackStack();
switch (view.getId()) {
case R.id.nav_btn_contacts:
startFragment(ContactListFragment.newInstance());
break;
case R.id.nav_btn_forums:
startFragment(ForumListFragment.newInstance());
break;
case R.id.nav_btn_settings:
startFragment(SettingsFragment.newInstance());
break;
case R.id.nav_btn_signout:
signOut();
break;
}
}
@Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() == 0
&& drawerLayout.isDrawerOpen(GravityCompat.START)) {
drawerLayout.closeDrawer(GravityCompat.START);
return;
}
super.onBackPressed();
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
drawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
drawerToggle.onConfigurationChanged(newConfig);
}
@Override
protected void signOut() {
showLoadingScreen(true, R.string.progress_title_logout);
super.signOut();
}
@Override
public void showLoadingScreen(boolean isBlocking, int stringId) {
if (isBlocking) {
// Disable navigation drawer slide to open
drawerLayout
.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
CustomAnimations.animateHeight(toolbar, false, 250);
}
progressTitle.setText(stringId);
progressViewGroup.setVisibility(View.VISIBLE);
}
@Override
public void hideLoadingScreen() {
drawerLayout
.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
CustomAnimations.animateHeight(toolbar, true, 250);
progressViewGroup.setVisibility(View.INVISIBLE);
}
private void initializeTransports(final LayoutInflater inflater) {
transports = new ArrayList<Transport>(3);
Transport tor = new Transport();
tor.id = new TransportId("tor");
Plugin torPlugin = pluginManager.getPlugin(tor.id);
tor.enabled = torPlugin != null && torPlugin.isRunning();
tor.iconId = R.drawable.transport_tor;
tor.textId = R.string.transport_tor;
transports.add(tor);
Transport bt = new Transport();
bt.id = new TransportId("bt");
Plugin btPlugin = pluginManager.getPlugin(bt.id);
bt.enabled = btPlugin != null && btPlugin.isRunning();
bt.iconId = R.drawable.transport_bt;
bt.textId = R.string.transport_bt;
transports.add(bt);
Transport lan = new Transport();
lan.id = new TransportId("lan");
Plugin lanPlugin = pluginManager.getPlugin(lan.id);
lan.enabled = lanPlugin != null && lanPlugin.isRunning();
lan.iconId = R.drawable.transport_lan;
lan.textId = R.string.transport_lan;
transports.add(lan);
transportsAdapter = new BaseAdapter() {
@Override
public int getCount() {
return transports.size();
}
@Override
public Transport getItem(int position) {
return transports.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView,
ViewGroup parent) {
ViewGroup view = (ViewGroup) inflater
.inflate(R.layout.list_item_transport, parent, false);
Transport t = getItem(position);
Resources r = getResources();
int c;
if (t.enabled) {
c = r.getColor(R.color.briar_green_light);
} else {
c = r.getColor(android.R.color.tertiary_text_light);
}
ImageView icon = (ImageView) view.findViewById(R.id.imageView);
icon.setImageDrawable(r.getDrawable(t.iconId));
icon.setColorFilter(c);
TextView text = (TextView) view.findViewById(R.id.textView);
text.setText(getString(t.textId));
return view;
}
};
}
private void setTransport(final TransportId id, final boolean enabled) {
runOnUiThread(new Runnable() {
public void run() {
if (transports == null || transportsAdapter == null) return;
for (Transport t : transports) {
if (t.id.equals(id)) {
t.enabled = enabled;
transportsAdapter.notifyDataSetChanged();
break;
}
}
}
});
}
private void updateTransports() {
if (transports == null || transportsAdapter == null) return;
for (Transport t : transports) {
Plugin plugin = pluginManager.getPlugin(t.id);
t.enabled = plugin != null && plugin.isRunning();
}
transportsAdapter.notifyDataSetChanged();
}
@Override
public void eventOccurred(Event e) {
if (e instanceof TransportEnabledEvent) {
TransportId id = ((TransportEnabledEvent) e).getTransportId();
if (LOG.isLoggable(INFO)) {
LOG.info("TransportEnabledEvent: " + id.getString());
}
setTransport(id, true);
} else if (e instanceof TransportDisabledEvent) {
TransportId id = ((TransportDisabledEvent) e).getTransportId();
if (LOG.isLoggable(INFO)) {
LOG.info("TransportDisabledEvent: " + id.getString());
}
setTransport(id, false);
}
}
private static class Transport {
TransportId id;
boolean enabled;
int iconId;
int textId;
}
}

View File

@@ -176,8 +176,8 @@ public class SetupActivity extends BaseActivity implements OnClickListener,
runOnUiThread(new Runnable() {
public void run() {
Intent i = new Intent(SetupActivity.this,
DashboardActivity.class);
i.putExtra("briar.LOCAL_AUTHOR_HANDLE", handle);
NavDrawerActivity.class);
i.putExtra(BriarActivity.KEY_LOCAL_AUTHOR_HANDLE, handle);
i.setFlags(FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
finish();

View File

@@ -84,7 +84,7 @@ public class SplashScreenActivity extends RoboSplashActivity {
Injector i = RoboGuice.getBaseApplicationInjector(getApplication());
DatabaseConfig databaseConfig = i.getInstance(DatabaseConfig.class);
if (hex != null && databaseConfig.databaseExists()) {
startActivity(new Intent(this, DashboardActivity.class));
startActivity(new Intent(this, NavDrawerActivity.class));
} else {
prefs.edit().clear().apply();
FileUtils.deleteFileOrDir(

View File

@@ -5,7 +5,7 @@ import static java.util.logging.Level.OFF;
import java.util.logging.Level;
interface TestingConstants {
public interface TestingConstants {
/**
* Whether this is an alpha or beta build. This should be set to false for
@@ -25,7 +25,7 @@ interface TestingConstants {
boolean PREVENT_SCREENSHOTS = TESTING ? false : true;
/**
* Whether to allow TestingActivity to be launched from SettingsActivity.
* Whether to allow TestingActivity to be launched from SettingsFragment.
*/
boolean SHOW_TESTING_ACTIVITY = TESTING ? true : false;

View File

@@ -2,12 +2,15 @@ package org.briarproject.android.contact;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.widget.LinearLayoutManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.briarproject.R;
import org.briarproject.android.BriarActivity;
import org.briarproject.android.fragment.BaseEventFragment;
import org.briarproject.android.invitation.AddContactActivity;
import org.briarproject.android.util.BriarRecyclerView;
import org.briarproject.api.contact.Contact;
@@ -21,7 +24,6 @@ import org.briarproject.api.event.ContactDisconnectedEvent;
import org.briarproject.api.event.ContactRemovedEvent;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.MessageValidatedEvent;
import org.briarproject.api.messaging.MessagingManager;
import org.briarproject.api.messaging.PrivateMessageHeader;
@@ -39,63 +41,82 @@ import javax.inject.Inject;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
public class ContactListActivity extends BriarActivity
implements EventListener {
public class ContactListFragment extends BaseEventFragment {
private static final Logger LOG =
Logger.getLogger(ContactListActivity.class.getName());
Logger.getLogger(ContactListFragment.class.getName());
@Inject private ConnectionRegistry connectionRegistry;
public final static String TAG = "ContactListFragment";
public static ContactListFragment newInstance() {
Bundle args = new Bundle();
ContactListFragment fragment = new ContactListFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public String getUniqueTag() {
return TAG;
}
@Inject
private ConnectionRegistry connectionRegistry;
private ContactListAdapter adapter = null;
private BriarRecyclerView list = null;
// Fields that are accessed from background threads must be volatile
@Inject private volatile ContactManager contactManager;
@Inject private volatile MessagingManager messagingManager;
@Inject private volatile EventBus eventBus;
@Inject
private volatile ContactManager contactManager;
@Inject
private volatile MessagingManager messagingManager;
@Inject
private volatile EventBus eventBus;
@Nullable
@Override
public void onCreate(Bundle state) {
super.onCreate(state);
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View contentView =
inflater.inflate(R.layout.activity_contact_list, container,
false);
setContentView(R.layout.activity_contact_list);
adapter = new ContactListAdapter(this);
list = (BriarRecyclerView) findViewById(R.id.contactList);
list.setLayoutManager(new LinearLayoutManager(this));
adapter = new ContactListAdapter(getContext());
list = (BriarRecyclerView) contentView.findViewById(R.id.contactList);
list.setLayoutManager(new LinearLayoutManager(getContext()));
list.setAdapter(adapter);
list.setEmptyText(getString(R.string.no_contacts));
// Show a floating action button
FloatingActionButton fab = (FloatingActionButton) findViewById(
R.id.addContactFAB);
FloatingActionButton fab =
(FloatingActionButton) contentView.findViewById(
R.id.addContactFAB);
// handle FAB click
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(ContactListActivity.this,
startActivity(new Intent(getContext(),
AddContactActivity.class));
}
});
return contentView;
}
@Override
public void onPause() {
super.onPause();
eventBus.removeListener(this);
}
@Override
public void onResume() {
super.onResume();
eventBus.addListener(this);
loadContacts();
}
private void loadContacts() {
runOnDbThread(new Runnable() {
listener.runOnDbThread(new Runnable() {
public void run() {
try {
long now = System.currentTimeMillis();
@@ -113,7 +134,7 @@ public class ContactListActivity extends BriarActivity
contacts.add(new ContactListItem(c, connected,
groupId, headers));
} catch (NoSuchContactException e) {
LOG.info("Contact removed");
// Continue
}
}
displayContacts(contacts);
@@ -129,7 +150,7 @@ public class ContactListActivity extends BriarActivity
}
private void displayContacts(final List<ContactListItem> contacts) {
runOnUiThread(new Runnable() {
listener.runOnUiThread(new Runnable() {
public void run() {
adapter.clear();
if (contacts.size() == 0) list.showData();
@@ -160,7 +181,7 @@ public class ContactListActivity extends BriarActivity
}
private void reloadConversation(final GroupId g) {
runOnDbThread(new Runnable() {
listener.runOnDbThread(new Runnable() {
public void run() {
try {
long now = System.currentTimeMillis();
@@ -183,7 +204,7 @@ public class ContactListActivity extends BriarActivity
private void updateItem(final ContactId c,
final Collection<PrivateMessageHeader> headers) {
runOnUiThread(new Runnable() {
listener.runOnUiThread(new Runnable() {
public void run() {
int position = adapter.findItemPosition(c);
ContactListItem item = adapter.getItem(position);
@@ -196,7 +217,7 @@ public class ContactListActivity extends BriarActivity
}
private void removeItem(final ContactId c) {
runOnUiThread(new Runnable() {
listener.runOnUiThread(new Runnable() {
public void run() {
int position = adapter.findItemPosition(c);
ContactListItem item = adapter.getItem(position);
@@ -206,7 +227,7 @@ public class ContactListActivity extends BriarActivity
}
private void setConnected(final ContactId c, final boolean connected) {
runOnUiThread(new Runnable() {
listener.runOnUiThread(new Runnable() {
public void run() {
int position = adapter.findItemPosition(c);
ContactListItem item = adapter.getItem(position);

View File

@@ -18,11 +18,11 @@ import static android.text.TextUtils.TruncateAt.END;
import static android.widget.LinearLayout.HORIZONTAL;
import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP_1;
class ForumListAdapter extends ArrayAdapter<ForumListItem> {
public class ForumListAdapter extends ArrayAdapter<ForumListItem> {
private final int pad;
ForumListAdapter(Context ctx) {
public ForumListAdapter(Context ctx) {
super(ctx, android.R.layout.simple_expandable_list_item_1,
new ArrayList<ForumListItem>());
pad = LayoutUtils.getPadding(ctx);

View File

@@ -3,15 +3,15 @@ package org.briarproject.android.forum;
import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnCreateContextMenuListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ListView;
@@ -19,15 +19,13 @@ import android.widget.TextView;
import android.widget.Toast;
import org.briarproject.R;
import org.briarproject.android.BriarActivity;
import org.briarproject.android.fragment.BaseEventFragment;
import org.briarproject.android.util.HorizontalBorder;
import org.briarproject.android.util.LayoutUtils;
import org.briarproject.android.util.ListLoadingProgressBar;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.NoSuchSubscriptionException;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.MessageValidatedEvent;
import org.briarproject.api.event.RemoteSubscriptionsUpdatedEvent;
import org.briarproject.api.event.SubscriptionAddedEvent;
@@ -58,13 +56,24 @@ import static org.briarproject.android.util.CommonLayoutParams.MATCH_MATCH;
import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP;
import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP_1;
public class ForumListActivity extends BriarActivity
implements EventListener, OnClickListener, OnItemClickListener,
OnCreateContextMenuListener {
public class ForumListFragment extends BaseEventFragment implements
AdapterView.OnItemClickListener, View.OnClickListener {
public final static String TAG = "ForumListFragment";
private static final Logger LOG =
Logger.getLogger(ForumListFragment.class.getName());
public static ForumListFragment newInstance() {
Bundle args = new Bundle();
ForumListFragment fragment = new ForumListFragment();
fragment.setArguments(args);
return fragment;
}
private static final int MENU_ITEM_UNSUBSCRIBE = 1;
private static final Logger LOG =
Logger.getLogger(ForumListActivity.class.getName());
private TextView empty = null;
private ForumListAdapter adapter = null;
@@ -74,20 +83,21 @@ public class ForumListActivity extends BriarActivity
private ImageButton newForumButton = null;
// Fields that are accessed from background threads must be volatile
@Inject private volatile ForumManager forumManager;
@Inject private volatile EventBus eventBus;
@Inject
private volatile ForumManager forumManager;
@Nullable
@Override
public void onCreate(Bundle state) {
super.onCreate(state);
LinearLayout layout = new LinearLayout(this);
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LinearLayout layout = new LinearLayout(getContext());
layout.setLayoutParams(MATCH_MATCH);
layout.setOrientation(VERTICAL);
layout.setGravity(CENTER_HORIZONTAL);
int pad = LayoutUtils.getPadding(this);
int pad = LayoutUtils.getPadding(getContext());
empty = new TextView(this);
empty = new TextView(getContext());
empty.setLayoutParams(MATCH_WRAP_1);
empty.setGravity(CENTER);
empty.setTextSize(18);
@@ -95,8 +105,8 @@ public class ForumListActivity extends BriarActivity
empty.setVisibility(GONE);
layout.addView(empty);
adapter = new ForumListAdapter(this);
list = new ListView(this);
adapter = new ForumListAdapter(getContext());
list = new ListView(getContext());
list.setLayoutParams(MATCH_WRAP_1);
list.setAdapter(adapter);
list.setOnItemClickListener(this);
@@ -105,10 +115,10 @@ public class ForumListActivity extends BriarActivity
layout.addView(list);
// Show a progress bar while the list is loading
loading = new ListLoadingProgressBar(this);
loading = new ListLoadingProgressBar(getContext());
layout.addView(loading);
available = new TextView(this);
available = new TextView(getContext());
available.setLayoutParams(MATCH_WRAP);
available.setGravity(CENTER);
available.setTextSize(18);
@@ -120,33 +130,37 @@ public class ForumListActivity extends BriarActivity
available.setVisibility(GONE);
layout.addView(available);
layout.addView(new HorizontalBorder(this));
layout.addView(new HorizontalBorder(getContext()));
LinearLayout footer = new LinearLayout(this);
LinearLayout footer = new LinearLayout(getContext());
footer.setLayoutParams(MATCH_WRAP);
footer.setOrientation(HORIZONTAL);
footer.setGravity(CENTER);
footer.setBackgroundColor(res.getColor(R.color.button_bar_background));
newForumButton = new ImageButton(this);
newForumButton = new ImageButton(getContext());
newForumButton.setBackgroundResource(0);
newForumButton.setImageResource(R.drawable.social_new_chat);
newForumButton.setOnClickListener(this);
footer.addView(newForumButton);
layout.addView(footer);
setContentView(layout);
return layout;
}
@Override
public String getUniqueTag() {
return TAG;
}
@Override
public void onResume() {
super.onResume();
eventBus.addListener(this);
loadHeaders();
}
private void loadHeaders() {
clearHeaders();
runOnDbThread(new Runnable() {
listener.runOnDbThread(new Runnable() {
public void run() {
try {
long now = System.currentTimeMillis();
@@ -173,7 +187,7 @@ public class ForumListActivity extends BriarActivity
}
private void clearHeaders() {
runOnUiThread(new Runnable() {
listener.runOnUiThread(new Runnable() {
public void run() {
empty.setVisibility(GONE);
list.setVisibility(GONE);
@@ -186,7 +200,7 @@ public class ForumListActivity extends BriarActivity
private void displayHeaders(final Forum f,
final Collection<ForumPostHeader> headers) {
runOnUiThread(new Runnable() {
listener.runOnUiThread(new Runnable() {
public void run() {
list.setVisibility(VISIBLE);
loading.setVisibility(GONE);
@@ -202,7 +216,7 @@ public class ForumListActivity extends BriarActivity
}
private void displayAvailable(final int availableCount) {
runOnUiThread(new Runnable() {
listener.runOnUiThread(new Runnable() {
public void run() {
if (adapter.isEmpty()) empty.setVisibility(VISIBLE);
loading.setVisibility(GONE);
@@ -239,12 +253,6 @@ public class ForumListActivity extends BriarActivity
else list.setSelection(firstUnread);
}
@Override
public void onPause() {
super.onPause();
eventBus.removeListener(this);
}
public void eventOccurred(Event e) {
if (e instanceof MessageValidatedEvent) {
MessageValidatedEvent m = (MessageValidatedEvent) e;
@@ -269,7 +277,7 @@ public class ForumListActivity extends BriarActivity
}
private void loadHeaders(final GroupId g) {
runOnDbThread(new Runnable() {
listener.runOnDbThread(new Runnable() {
public void run() {
try {
long now = System.currentTimeMillis();
@@ -291,7 +299,7 @@ public class ForumListActivity extends BriarActivity
}
private void removeForum(final GroupId g) {
runOnUiThread(new Runnable() {
listener.runOnUiThread(new Runnable() {
public void run() {
ForumListItem item = findForum(g);
if (item != null) {
@@ -308,7 +316,7 @@ public class ForumListActivity extends BriarActivity
}
private void loadAvailable() {
runOnDbThread(new Runnable() {
listener.runOnDbThread(new Runnable() {
public void run() {
try {
long now = System.currentTimeMillis();
@@ -327,15 +335,16 @@ public class ForumListActivity extends BriarActivity
public void onClick(View view) {
if (view == available) {
startActivity(new Intent(this, AvailableForumsActivity.class));
startActivity(new Intent(getContext(),
AvailableForumsActivity.class));
} else if (view == newForumButton) {
startActivity(new Intent(this, CreateForumActivity.class));
startActivity(new Intent(getContext(), CreateForumActivity.class));
}
}
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Intent i = new Intent(this, ForumActivity.class);
Intent i = new Intent(getContext(), ForumActivity.class);
Forum f = adapter.getItem(position).getForum();
i.putExtra("briar.GROUP_ID", f.getId().getBytes());
i.putExtra("briar.FORUM_NAME", f.getName());
@@ -344,7 +353,7 @@ public class ForumListActivity extends BriarActivity
@Override
public void onCreateContextMenu(ContextMenu menu, View view,
ContextMenu.ContextMenuInfo info) {
ContextMenuInfo info) {
String delete = getString(R.string.unsubscribe);
menu.add(NONE, MENU_ITEM_UNSUBSCRIBE, NONE, delete);
}
@@ -357,13 +366,13 @@ public class ForumListActivity extends BriarActivity
ForumListItem item = adapter.getItem(position);
removeSubscription(item.getForum());
String unsubscribed = getString(R.string.unsubscribed_toast);
Toast.makeText(this, unsubscribed, LENGTH_SHORT).show();
Toast.makeText(getContext(), unsubscribed, LENGTH_SHORT).show();
}
return true;
}
private void removeSubscription(final Forum f) {
runOnDbThread(new Runnable() {
listener.runOnDbThread(new Runnable() {
public void run() {
try {
long now = System.currentTimeMillis();
@@ -378,4 +387,4 @@ public class ForumListActivity extends BriarActivity
}
});
}
}
}

View File

@@ -2,9 +2,9 @@ package org.briarproject.android.forum;
import java.util.Comparator;
class ForumListItemComparator implements Comparator<ForumListItem> {
public class ForumListItemComparator implements Comparator<ForumListItem> {
static final ForumListItemComparator INSTANCE =
public static final ForumListItemComparator INSTANCE =
new ForumListItemComparator();
public int compare(ForumListItem a, ForumListItem b) {

View File

@@ -0,0 +1,28 @@
package org.briarproject.android.fragment;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.EventListener;
import javax.inject.Inject;
/**
* Created by Ernir Erlingsson (ernir@ymirmobile.com) on 8.1.2016.
*/
public abstract class BaseEventFragment extends BaseFragment implements
EventListener {
@Inject
protected volatile EventBus eventBus;
@Override
public void onResume() {
super.onResume();
eventBus.addListener(this);
}
@Override
public void onPause() {
super.onPause();
eventBus.removeListener(this);
}
}

View File

@@ -0,0 +1,35 @@
package org.briarproject.android.fragment;
import android.content.Context;
import org.briarproject.android.BriarActivity;
import roboguice.fragment.RoboFragment;
public abstract class BaseFragment extends RoboFragment {
public abstract String getUniqueTag();
protected BaseFragmentListener listener;
protected BriarActivity briarActivity;
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
listener = (BaseFragmentListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(
"Using class must implement BaseFragmentListener");
}
}
public interface BaseFragmentListener {
void showLoadingScreen(boolean isBlocking, int stringId);
void hideLoadingScreen();
void runOnUiThread(Runnable runnable);
void runOnDbThread(Runnable runnable);
}
}

View File

@@ -0,0 +1,66 @@
package org.briarproject.android.fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.GridView;
import org.briarproject.R;
import org.briarproject.api.event.Event;
import org.briarproject.api.plugins.PluginManager;
import java.util.logging.Logger;
import javax.inject.Inject;
import roboguice.inject.InjectView;
public class DashboardFragment extends BaseEventFragment {
public final static String TAG = "DashboardFragment";
private static final Logger LOG =
Logger.getLogger(DashboardFragment.class.getName());
@Inject
private PluginManager pluginManager;
@InjectView(R.id.transportsView)
private GridView transportsView;
public static DashboardFragment newInstance() {
Bundle args = new Bundle();
DashboardFragment fragment = new DashboardFragment();
fragment.setArguments(args);
return fragment;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View contentView =
inflater.inflate(R.layout.fragment_dashboard, container, false);
return contentView;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
@Override
public String getUniqueTag() {
return TAG;
}
@Override
public void eventOccurred(Event e) {
}
}

View File

@@ -1,4 +1,4 @@
package org.briarproject.android;
package org.briarproject.android.fragment;
import android.bluetooth.BluetoothAdapter;
import android.content.Intent;
@@ -7,8 +7,10 @@ import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageButton;
import android.widget.LinearLayout;
@@ -16,6 +18,7 @@ import android.widget.ScrollView;
import android.widget.TextView;
import org.briarproject.R;
import org.briarproject.android.TestingActivity;
import org.briarproject.android.panic.PanicPreferencesActivity;
import org.briarproject.android.util.AndroidUtils;
import org.briarproject.android.util.FixedVerticalSpace;
@@ -27,7 +30,6 @@ import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.SettingsUpdatedEvent;
import org.briarproject.api.settings.SettingsManager;
import org.briarproject.util.StringUtils;
@@ -53,16 +55,19 @@ import static android.widget.LinearLayout.VERTICAL;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.android.TestingConstants.SHOW_TESTING_ACTIVITY;
import static android.app.Activity.RESULT_OK;
import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP;
import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP_1;
public class SettingsActivity extends BriarActivity implements EventListener,
OnClickListener {
public class SettingsFragment extends BaseFragment implements
View.OnClickListener {
public final static String TAG = "SettingsFragment";
public static final int REQUEST_RINGTONE = 2;
private static final Logger LOG =
Logger.getLogger(SettingsActivity.class.getName());
Logger.getLogger(SettingsFragment.class.getName());
private ScrollView scroll = null;
private TextView enableBluetooth = null, enableBluetoothHint = null;
@@ -81,21 +86,36 @@ OnClickListener {
private volatile Settings settings;
private volatile boolean bluetoothSetting = true, torSetting = false;
@Override
public void onCreate(Bundle state) {
super.onCreate(state);
public static SettingsFragment newInstance() {
LinearLayout layout = new LinearLayout(this);
Bundle args = new Bundle();
SettingsFragment fragment = new SettingsFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public String getUniqueTag() {
return TAG;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LinearLayout layout = new LinearLayout(getContext());
layout.setOrientation(VERTICAL);
scroll = new ScrollView(this);
scroll = new ScrollView(getContext());
LinearLayout settings = new LinearLayout(this);
LinearLayout settings = new LinearLayout(getContext());
settings.setOrientation(VERTICAL);
int pad = LayoutUtils.getPadding(this);
int pad = LayoutUtils.getPadding(getContext());
settings.setPadding(pad, pad, pad, pad);
TextView bluetoothTitle = new TextView(this);
TextView bluetoothTitle = new TextView(getContext());
bluetoothTitle.setPadding(pad, 0, pad, 0);
bluetoothTitle.setTypeface(DEFAULT_BOLD);
Resources res = getResources();
@@ -104,143 +124,143 @@ OnClickListener {
bluetoothTitle.setText(R.string.bluetooth_setting_title);
settings.addView(bluetoothTitle);
HorizontalBorder underline = new HorizontalBorder(this);
HorizontalBorder underline = new HorizontalBorder(getContext());
int titleUnderline = res.getColor(R.color.settings_title_underline);
underline.setBackgroundColor(titleUnderline);
settings.addView(underline);
enableBluetooth = new TextView(this);
enableBluetooth = new TextView(getContext());
enableBluetooth.setPadding(pad, pad, pad, 0);
enableBluetooth.setTextSize(18);
enableBluetooth.setText(R.string.bluetooth_setting);
enableBluetooth.setOnClickListener(this);
settings.addView(enableBluetooth);
enableBluetoothHint = new TextView(this);
enableBluetoothHint = new TextView(getContext());
enableBluetoothHint.setPadding(pad, 0, pad, pad);
enableBluetoothHint.setOnClickListener(this);
settings.addView(enableBluetoothHint);
TextView torTitle = new TextView(this);
TextView torTitle = new TextView(getContext());
torTitle.setPadding(pad, 0, pad, 0);
torTitle.setTypeface(DEFAULT_BOLD);
torTitle.setTextColor(titleText);
torTitle.setText(R.string.tor_wifi_setting_title);
settings.addView(torTitle);
underline = new HorizontalBorder(this);
underline = new HorizontalBorder(getContext());
underline.setBackgroundColor(titleUnderline);
settings.addView(underline);
torOverWifi = new TextView(this);
torOverWifi = new TextView(getContext());
torOverWifi.setPadding(pad, pad, pad, 0);
torOverWifi.setTextSize(18);
torOverWifi.setText(R.string.tor_wifi_setting);
torOverWifi.setOnClickListener(this);
settings.addView(torOverWifi);
torOverWifiHint = new TextView(this);
torOverWifiHint = new TextView(getContext());
torOverWifiHint.setPadding(pad, 0, pad, pad);
torOverWifiHint.setOnClickListener(this);
settings.addView(torOverWifiHint);
TextView panicTitle = new TextView(this);
TextView panicTitle = new TextView(getContext());
panicTitle.setPadding(pad, 0, pad, 0);
panicTitle.setTypeface(DEFAULT_BOLD);
panicTitle.setTextColor(titleText);
panicTitle.setText(R.string.panic_setting_title);
settings.addView(panicTitle);
underline = new HorizontalBorder(this);
underline = new HorizontalBorder(getContext());
underline.setBackgroundColor(titleUnderline);
settings.addView(underline);
panicSettings = new TextView(this);
panicSettings = new TextView(getContext());
panicSettings.setPadding(pad, pad, pad, 0);
panicSettings.setTextSize(18);
panicSettings.setText(R.string.panic_setting);
panicSettings.setOnClickListener(this);
settings.addView(panicSettings);
panicSettingsHint = new TextView(this);
panicSettingsHint = new TextView(getContext());
panicSettingsHint.setText(R.string.panic_setting_hint);
panicSettingsHint.setPadding(pad, 0, pad, pad);
panicSettingsHint.setOnClickListener(this);
settings.addView(panicSettingsHint);
TextView notificationsTitle = new TextView(this);
TextView notificationsTitle = new TextView(getContext());
notificationsTitle.setPadding(pad, 0, pad, 0);
notificationsTitle.setTypeface(DEFAULT_BOLD);
notificationsTitle.setTextColor(titleText);
notificationsTitle.setText(R.string.notification_settings_title);
settings.addView(notificationsTitle);
underline = new HorizontalBorder(this);
underline = new HorizontalBorder(getContext());
underline.setBackgroundColor(titleUnderline);
settings.addView(underline);
settings.addView(new FixedVerticalSpace(this));
settings.addView(new FixedVerticalSpace(getContext()));
notifyPrivateMessages = new CheckBox(this);
notifyPrivateMessages = new CheckBox(getContext());
notifyPrivateMessages.setTextSize(18);
notifyPrivateMessages.setText(R.string.notify_private_messages_setting);
notifyPrivateMessages.setOnClickListener(this);
settings.addView(notifyPrivateMessages);
settings.addView(new FixedVerticalSpace(this));
settings.addView(new HorizontalBorder(this));
settings.addView(new FixedVerticalSpace(this));
settings.addView(new FixedVerticalSpace(getContext()));
settings.addView(new HorizontalBorder(getContext()));
settings.addView(new FixedVerticalSpace(getContext()));
notifyForumPosts = new CheckBox(this);
notifyForumPosts = new CheckBox(getContext());
notifyForumPosts.setTextSize(18);
notifyForumPosts.setText(R.string.notify_forum_posts_setting);
notifyForumPosts.setOnClickListener(this);
settings.addView(notifyForumPosts);
settings.addView(new FixedVerticalSpace(this));
settings.addView(new HorizontalBorder(this));
settings.addView(new FixedVerticalSpace(this));
settings.addView(new FixedVerticalSpace(getContext()));
settings.addView(new HorizontalBorder(getContext()));
settings.addView(new FixedVerticalSpace(getContext()));
notifyVibration = new CheckBox(this);
notifyVibration = new CheckBox(getContext());
notifyVibration.setTextSize(18);
notifyVibration.setText(R.string.notify_vibration_setting);
notifyVibration.setOnClickListener(this);
settings.addView(notifyVibration);
settings.addView(new FixedVerticalSpace(this));
settings.addView(new HorizontalBorder(this));
settings.addView(new FixedVerticalSpace(getContext()));
settings.addView(new HorizontalBorder(getContext()));
notifySound = new TextView(this);
notifySound = new TextView(getContext());
notifySound.setPadding(pad, pad, pad, 0);
notifySound.setTextSize(18);
notifySound.setText(R.string.notify_sound_setting);
notifySound.setOnClickListener(this);
settings.addView(notifySound);
notifySoundHint = new TextView(this);
notifySoundHint = new TextView(getContext());
notifySoundHint.setPadding(pad, 0, pad, pad);
notifySoundHint.setOnClickListener(this);
settings.addView(notifySoundHint);
settings.addView(new HorizontalBorder(this));
settings.addView(new HorizontalBorder(getContext()));
scroll.addView(settings);
scroll.setLayoutParams(MATCH_WRAP_1);
scroll.setVisibility(GONE);
layout.addView(scroll);
progress = new ListLoadingProgressBar(this);
progress = new ListLoadingProgressBar(getContext());
layout.addView(progress);
layout.addView(new HorizontalBorder(this));
layout.addView(new HorizontalBorder(getContext()));
if (SHOW_TESTING_ACTIVITY) {
LinearLayout footer = new LinearLayout(this);
LinearLayout footer = new LinearLayout(getContext());
footer.setLayoutParams(MATCH_WRAP);
footer.setGravity(CENTER);
int background = res.getColor(R.color.button_bar_background);
footer.setBackgroundColor(background);
testingButton = new ImageButton(this);
testingButton = new ImageButton(getContext());
testingButton.setBackgroundResource(0);
testingButton.setImageResource(R.drawable.action_about);
testingButton.setOnClickListener(this);
@@ -248,18 +268,17 @@ OnClickListener {
layout.addView(footer);
}
setContentView(layout);
return layout;
}
@Override
public void onResume() {
super.onResume();
eventBus.addListener(this);
loadSettings();
}
private void loadSettings() {
runOnDbThread(new Runnable() {
listener.runOnDbThread(new Runnable() {
public void run() {
try {
long now = System.currentTimeMillis();
@@ -281,13 +300,14 @@ OnClickListener {
}
private void displaySettings() {
runOnUiThread(new Runnable() {
listener.runOnUiThread(new Runnable() {
public void run() {
scroll.setVisibility(VISIBLE);
progress.setVisibility(GONE);
int resId;
if (bluetoothSetting) resId = R.string.bluetooth_setting_enabled;
if (bluetoothSetting)
resId = R.string.bluetooth_setting_enabled;
else resId = R.string.bluetooth_setting_disabled;
enableBluetoothHint.setText(resId);
@@ -318,16 +338,10 @@ OnClickListener {
});
}
@Override
public void onPause() {
super.onPause();
eventBus.removeListener(this);
}
public void onClick(View view) {
if (progress == null) return; // Not created yet
if (view == testingButton) {
startActivity(new Intent(this, TestingActivity.class));
startActivity(new Intent(getActivity(), TestingActivity.class));
} else if (view == enableBluetooth || view == enableBluetoothHint) {
bluetoothSetting = !bluetoothSetting;
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
@@ -346,7 +360,7 @@ OnClickListener {
notifyPrivateMessages.isChecked());
storeSettings(s);
} else if (view == panicSettings || view == panicSettingsHint) {
startActivity(new Intent(this, PanicPreferencesActivity.class));
startActivity(new Intent(getActivity(), PanicPreferencesActivity.class));
} else if (view == notifyForumPosts) {
Settings s = new Settings();
s.putBoolean("notifyForumPosts", notifyForumPosts.isChecked());
@@ -375,7 +389,7 @@ OnClickListener {
}
private void storeTorSettings() {
runOnDbThread(new Runnable() {
listener.runOnDbThread(new Runnable() {
public void run() {
try {
Settings s = new Settings();
@@ -394,7 +408,7 @@ OnClickListener {
}
private void storeBluetoothSettings() {
runOnDbThread(new Runnable() {
listener.runOnDbThread(new Runnable() {
public void run() {
try {
Settings s = new Settings();
@@ -413,11 +427,12 @@ OnClickListener {
}
private void storeSettings(final Settings settings) {
runOnDbThread(new Runnable() {
listener.runOnDbThread(new Runnable() {
public void run() {
try {
long now = System.currentTimeMillis();
settingsManager.mergeSettings(settings, "settings-activity");
settingsManager
.mergeSettings(settings, "settings-activity");
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Merging settings took " + duration + " ms");
@@ -449,8 +464,8 @@ OnClickListener {
s.put("notifyRingtoneUri", "");
} else {
// The user chose a ringtone other than the default
Ringtone r = RingtoneManager.getRingtone(this, uri);
String name = r.getTitle(this);
Ringtone r = RingtoneManager.getRingtone(getContext(), uri);
String name = r.getTitle(getContext());
notifySoundHint.setText(name);
s.putBoolean("notifySound", true);
s.put("notifyRingtoneName", name);

View File

@@ -0,0 +1,84 @@
package org.briarproject.android.util;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.os.Build;
import android.view.View;
import android.view.ViewGroup;
public class CustomAnimations {
public static void animateHeight(
final ViewGroup viewGroup, final boolean isExtending,
int duration) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
animateHeightPostGingerbread(viewGroup, isExtending, duration);
} else {
animateHeightGingerbread(viewGroup, isExtending, duration);
}
}
private static void animateHeightGingerbread(final ViewGroup viewGroup,
final boolean isExtending, int duration) {
// No animations for Gingerbread
if (isExtending) {
viewGroup.setVisibility(View.VISIBLE);
} else {
viewGroup.setVisibility(View.GONE);
}
}
@SuppressLint("NewApi")
private static void animateHeightPostGingerbread(
final ViewGroup viewGroup,
final boolean isExtending,
int duration) {
ValueAnimator anim;
if (isExtending) {
viewGroup.setVisibility(View.VISIBLE);
viewGroup.measure(View.MeasureSpec.UNSPECIFIED,
View.MeasureSpec.UNSPECIFIED);
anim = ValueAnimator.ofInt(0, viewGroup.getMeasuredHeight());
} else {
anim = ValueAnimator.ofInt(viewGroup.getHeight(), 0);
}
anim.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
if (!isExtending) {
viewGroup.setVisibility(View.GONE);
}
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int val = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams =
viewGroup.getLayoutParams();
layoutParams.height = val;
viewGroup.setLayoutParams(layoutParams);
}
});
anim.setDuration(duration);
anim.start();
}
}