aboutsummaryrefslogtreecommitdiff
path: root/WordPress/src/main/java/org/wordpress/android/ui/prefs/notifications/NotificationsSettingsFragment.java
diff options
context:
space:
mode:
Diffstat (limited to 'WordPress/src/main/java/org/wordpress/android/ui/prefs/notifications/NotificationsSettingsFragment.java')
-rw-r--r--WordPress/src/main/java/org/wordpress/android/ui/prefs/notifications/NotificationsSettingsFragment.java451
1 files changed, 451 insertions, 0 deletions
diff --git a/WordPress/src/main/java/org/wordpress/android/ui/prefs/notifications/NotificationsSettingsFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/prefs/notifications/NotificationsSettingsFragment.java
new file mode 100644
index 000000000..a0b47e7ac
--- /dev/null
+++ b/WordPress/src/main/java/org/wordpress/android/ui/prefs/notifications/NotificationsSettingsFragment.java
@@ -0,0 +1,451 @@
+package org.wordpress.android.ui.prefs.notifications;
+
+import android.app.Dialog;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.net.Uri;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceFragment;
+import android.preference.PreferenceManager;
+import android.preference.PreferenceScreen;
+import android.provider.Settings;
+import android.support.annotation.NonNull;
+import android.support.v4.view.MenuItemCompat;
+import android.support.v7.widget.SearchView;
+import android.text.TextUtils;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+
+import com.android.volley.VolleyError;
+import com.wordpress.rest.RestRequest;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.wordpress.android.R;
+import org.wordpress.android.WordPress;
+import org.wordpress.android.WordPressDB;
+import org.wordpress.android.analytics.AnalyticsTracker;
+import org.wordpress.android.models.NotificationsSettings;
+import org.wordpress.android.models.NotificationsSettings.Channel;
+import org.wordpress.android.models.NotificationsSettings.Type;
+import org.wordpress.android.ui.notifications.NotificationEvents;
+import org.wordpress.android.ui.notifications.utils.NotificationsUtils;
+import org.wordpress.android.util.AppLog;
+import org.wordpress.android.util.AppLog.T;
+import org.wordpress.android.util.MapUtils;
+import org.wordpress.android.util.UrlUtils;
+import org.wordpress.android.util.WPActivityUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import de.greenrobot.event.EventBus;
+
+public class NotificationsSettingsFragment extends PreferenceFragment {
+
+ private static final String KEY_SEARCH_QUERY = "search_query";
+ private static final int SITE_SEARCH_VISIBILITY_COUNT = 15;
+ // The number of notification types we support (e.g. timeline, email, mobile)
+ private static final int TYPE_COUNT = 3;
+
+ private NotificationsSettings mNotificationsSettings;
+ private SearchView mSearchView;
+ private MenuItem mSearchMenuItem;
+
+ private String mDeviceId;
+ private String mRestoredQuery;
+ private boolean mNotificationsEnabled;
+ private int mSiteCount;
+
+ private final List<PreferenceCategory> mTypePreferenceCategories = new ArrayList<>();
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ addPreferencesFromResource(R.xml.notifications_settings);
+ setHasOptionsMenu(true);
+
+ // Bump Analytics
+ if (savedInstanceState == null) {
+ AnalyticsTracker.track(AnalyticsTracker.Stat.NOTIFICATION_SETTINGS_LIST_OPENED);
+ }
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getActivity());
+ mDeviceId = settings.getString(NotificationsUtils.WPCOM_PUSH_DEVICE_SERVER_ID, "");
+
+ if (hasNotificationsSettings()) {
+ loadNotificationsAndUpdateUI(true);
+ }
+
+ if (savedInstanceState != null && savedInstanceState.containsKey(KEY_SEARCH_QUERY)) {
+ mRestoredQuery = savedInstanceState.getString(KEY_SEARCH_QUERY);
+ }
+ }
+
+
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ mNotificationsEnabled = NotificationsUtils.isNotificationsEnabled(getActivity());
+
+ refreshSettings();
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ inflater.inflate(R.menu.notifications_settings, menu);
+
+ mSearchMenuItem = menu.findItem(R.id.menu_notifications_settings_search);
+ mSearchView = (SearchView) MenuItemCompat.getActionView(mSearchMenuItem);
+ mSearchView.setQueryHint(getString(R.string.search_sites));
+
+ mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
+ @Override
+ public boolean onQueryTextSubmit(String query) {
+ configureBlogsSettings();
+ return true;
+ }
+
+ @Override
+ public boolean onQueryTextChange(String newText) {
+ configureBlogsSettings();
+ return true;
+ }
+ });
+
+ updateSearchMenuVisibility();
+
+ // Check for a restored search query (if device was rotated, etc)
+ if (!TextUtils.isEmpty(mRestoredQuery)) {
+ mSearchMenuItem.expandActionView();
+ mSearchView.setQuery(mRestoredQuery, true);
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState(Bundle outState) {
+ if (mSearchView != null && !TextUtils.isEmpty(mSearchView.getQuery())) {
+ outState.putString(KEY_SEARCH_QUERY, mSearchView.getQuery().toString());
+ }
+
+ super.onSaveInstanceState(outState);
+ }
+
+ private void refreshSettings() {
+ if (!hasNotificationsSettings()) {
+ EventBus.getDefault().post(new NotificationEvents.NotificationsSettingsStatusChanged(getString(R.string.loading)));
+ }
+
+ if (hasNotificationsSettings()) {
+ updateUIForNotificationsEnabledState();
+ }
+
+ NotificationsUtils.getPushNotificationSettings(getActivity(), new RestRequest.Listener() {
+ @Override
+ public void onResponse(JSONObject response) {
+ AppLog.d(T.NOTIFS, "Get settings action succeeded");
+ if (!isAdded()) return;
+
+ boolean settingsExisted = hasNotificationsSettings();
+ if (!settingsExisted) {
+ EventBus.getDefault().post(new NotificationEvents.NotificationsSettingsStatusChanged(null));
+ }
+
+ SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getActivity());
+ SharedPreferences.Editor editor = settings.edit();
+ editor.putString(NotificationsUtils.WPCOM_PUSH_DEVICE_NOTIFICATION_SETTINGS, response.toString());
+ editor.apply();
+
+ loadNotificationsAndUpdateUI(!settingsExisted);
+ updateUIForNotificationsEnabledState();
+ }
+ }, new RestRequest.ErrorListener() {
+ @Override
+ public void onErrorResponse(VolleyError error) {
+ if (!isAdded()) return;
+ AppLog.e(T.NOTIFS, "Get settings action failed", error);
+
+ if (!hasNotificationsSettings()) {
+ EventBus.getDefault().post(new NotificationEvents.NotificationsSettingsStatusChanged(getString(R.string.error_loading_notifications)));
+ }
+ }
+ });
+ }
+
+ private void loadNotificationsAndUpdateUI(boolean shouldUpdateUI) {
+ JSONObject settingsJson;
+ try {
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
+ settingsJson = new JSONObject(
+ sharedPreferences.getString(NotificationsUtils.WPCOM_PUSH_DEVICE_NOTIFICATION_SETTINGS, "")
+ );
+ } catch (JSONException e) {
+ AppLog.e(T.NOTIFS, "Could not parse notifications settings JSON");
+ return;
+ }
+
+ if (mNotificationsSettings == null) {
+ mNotificationsSettings = new NotificationsSettings(settingsJson);
+ } else {
+ mNotificationsSettings.updateJson(settingsJson);
+ }
+
+ if (shouldUpdateUI) {
+ configureBlogsSettings();
+ configureOtherSettings();
+ configureDotcomSettings();
+ }
+ }
+
+ private boolean hasNotificationsSettings() {
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
+
+ return sharedPreferences.contains(NotificationsUtils.WPCOM_PUSH_DEVICE_NOTIFICATION_SETTINGS);
+ }
+
+ // Updates the UI for preference screens based on if notifications are enabled or not
+ private void updateUIForNotificationsEnabledState() {
+ if (mTypePreferenceCategories == null || mTypePreferenceCategories.size() == 0) {
+ return;
+ }
+
+ for (final PreferenceCategory category : mTypePreferenceCategories) {
+ if (mNotificationsEnabled && category.getPreferenceCount() > TYPE_COUNT) {
+ category.removePreference(category.getPreference(TYPE_COUNT));
+ } else if (!mNotificationsEnabled && category.getPreferenceCount() == TYPE_COUNT) {
+ Preference disabledMessage = new Preference(getActivity());
+ disabledMessage.setSummary(R.string.notifications_disabled);
+ disabledMessage.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ Intent intent = new Intent();
+ intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+ Uri uri = Uri.fromParts("package", getActivity().getApplicationContext().getPackageName(), null);
+ intent.setData(uri);
+
+ startActivity(intent);
+ return true;
+ }
+ });
+
+ category.addPreference(disabledMessage);
+ }
+
+ if (category.getPreferenceCount() >= TYPE_COUNT &&
+ category.getPreference(TYPE_COUNT - 1) != null) {
+ category.getPreference(TYPE_COUNT - 1).setEnabled(mNotificationsEnabled);
+ }
+ }
+
+ }
+
+ private void configureBlogsSettings() {
+ if (!isAdded()) return;
+ // Retrieve blogs (including jetpack sites) originally retrieved through FetchBlogListWPCom
+ // They will have an empty (but encrypted) password
+ String args = "password='" + WordPressDB.encryptPassword("") + "'";
+
+ // Check if user has typed in a search query
+ String trimmedQuery = null;
+ if (mSearchView != null && !TextUtils.isEmpty(mSearchView.getQuery())) {
+ trimmedQuery = mSearchView.getQuery().toString().trim();
+ args += " AND (url LIKE '%" + trimmedQuery + "%' OR blogName LIKE '%" + trimmedQuery + "%')";
+ }
+
+ List<Map<String, Object>> blogs = WordPress.wpDB.getBlogsBy(args, null, 0, false);
+ mSiteCount = blogs.size();
+
+ Context context = getActivity();
+
+ PreferenceCategory blogsCategory = (PreferenceCategory) findPreference(
+ getString(R.string.pref_notification_blogs));
+ blogsCategory.removeAll();
+
+ for (Map blog : blogs) {
+ if (context == null) return;
+
+ String siteUrl = MapUtils.getMapStr(blog, "url");
+ String title = MapUtils.getMapStr(blog, "blogName");
+ long blogId = MapUtils.getMapLong(blog, "blogId");
+
+ PreferenceScreen prefScreen = getPreferenceManager().createPreferenceScreen(context);
+ prefScreen.setTitle(title);
+ prefScreen.setSummary(UrlUtils.getHost(siteUrl));
+
+ addPreferencesForPreferenceScreen(prefScreen, Channel.BLOGS, blogId);
+ blogsCategory.addPreference(prefScreen);
+ }
+
+ // Add a message in a preference if there are no matching search results
+ if (mSiteCount == 0 && !TextUtils.isEmpty(trimmedQuery)) {
+ Preference searchResultsPref = new Preference(context);
+ searchResultsPref.setSummary(String.format(getString(R.string.notifications_no_search_results), trimmedQuery));
+ blogsCategory.addPreference(searchResultsPref);
+ }
+
+ updateSearchMenuVisibility();
+ }
+
+ private void updateSearchMenuVisibility() {
+ // Show the search menu item in the toolbar if we have enough sites
+ if (mSearchMenuItem != null) {
+ mSearchMenuItem.setVisible(mSiteCount > SITE_SEARCH_VISIBILITY_COUNT);
+ }
+ }
+
+ private void configureOtherSettings() {
+ PreferenceScreen otherBlogsScreen = (PreferenceScreen) findPreference(
+ getString(R.string.pref_notification_other_blogs));
+ addPreferencesForPreferenceScreen(otherBlogsScreen, Channel.OTHER, 0);
+ }
+
+ private void configureDotcomSettings() {
+ PreferenceCategory otherPreferenceCategory = (PreferenceCategory) findPreference(
+ getString(R.string.pref_notification_other_category));
+ NotificationsSettingsDialogPreference devicePreference = new NotificationsSettingsDialogPreference(
+ getActivity(), null, Channel.DOTCOM, NotificationsSettings.Type.DEVICE, 0, mNotificationsSettings, mOnSettingsChangedListener
+ );
+ devicePreference.setTitle(R.string.notifications_account_emails);
+ devicePreference.setDialogTitle(R.string.notifications_account_emails);
+ devicePreference.setSummary(R.string.notifications_account_emails_summary);
+ otherPreferenceCategory.addPreference(devicePreference);
+ }
+
+ private void addPreferencesForPreferenceScreen(PreferenceScreen preferenceScreen, Channel channel, long blogId) {
+ Context context = getActivity();
+ if (context == null) return;
+
+ PreferenceCategory rootCategory = new PreferenceCategory(context);
+ rootCategory.setTitle(R.string.notification_types);
+ preferenceScreen.addPreference(rootCategory);
+
+ NotificationsSettingsDialogPreference timelinePreference = new NotificationsSettingsDialogPreference(
+ context, null, channel, NotificationsSettings.Type.TIMELINE, blogId, mNotificationsSettings, mOnSettingsChangedListener
+ );
+ timelinePreference.setIcon(R.drawable.ic_bell_grey);
+ timelinePreference.setTitle(R.string.notifications_tab);
+ timelinePreference.setDialogTitle(R.string.notifications_tab);
+ timelinePreference.setSummary(R.string.notifications_tab_summary);
+ rootCategory.addPreference(timelinePreference);
+
+ NotificationsSettingsDialogPreference emailPreference = new NotificationsSettingsDialogPreference(
+ context, null, channel, NotificationsSettings.Type.EMAIL, blogId, mNotificationsSettings, mOnSettingsChangedListener
+ );
+ emailPreference.setIcon(R.drawable.ic_email_grey);
+ emailPreference.setTitle(R.string.email);
+ emailPreference.setDialogTitle(R.string.email);
+ emailPreference.setSummary(R.string.notifications_email_summary);
+ rootCategory.addPreference(emailPreference);
+
+ SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
+ String deviceID = settings.getString(NotificationsUtils.WPCOM_PUSH_DEVICE_SERVER_ID, null);
+ if (!TextUtils.isEmpty(deviceID)) {
+ NotificationsSettingsDialogPreference devicePreference = new NotificationsSettingsDialogPreference(
+ context, null, channel, NotificationsSettings.Type.DEVICE, blogId, mNotificationsSettings, mOnSettingsChangedListener
+ );
+ devicePreference.setIcon(R.drawable.ic_phone_grey);
+ devicePreference.setTitle(R.string.app_notifications);
+ devicePreference.setDialogTitle(R.string.app_notifications);
+ devicePreference.setSummary(R.string.notifications_push_summary);
+ devicePreference.setEnabled(mNotificationsEnabled);
+ rootCategory.addPreference(devicePreference);
+ }
+
+ mTypePreferenceCategories.add(rootCategory);
+ }
+
+ private final NotificationsSettingsDialogPreference.OnNotificationsSettingsChangedListener mOnSettingsChangedListener =
+ new NotificationsSettingsDialogPreference.OnNotificationsSettingsChangedListener() {
+ @SuppressWarnings("unchecked")
+ @Override
+ public void onSettingsChanged(Channel channel, NotificationsSettings.Type type, long blogId, JSONObject newValues) {
+ if (!isAdded()) return;
+
+ // Construct a new settings JSONObject to send back to WP.com
+ JSONObject settingsObject = new JSONObject();
+ switch (channel) {
+ case BLOGS:
+ try {
+ JSONObject blogObject = new JSONObject();
+ blogObject.put(NotificationsSettings.KEY_BLOG_ID, blogId);
+
+ JSONArray blogsArray = new JSONArray();
+ if (type == Type.DEVICE) {
+ newValues.put(NotificationsSettings.KEY_DEVICE_ID, Long.parseLong(mDeviceId));
+ JSONArray devicesArray = new JSONArray();
+ devicesArray.put(newValues);
+ blogObject.put(NotificationsSettings.KEY_DEVICES, devicesArray);
+ blogsArray.put(blogObject);
+ } else {
+ blogObject.put(type.toString(), newValues);
+ blogsArray.put(blogObject);
+ }
+
+ settingsObject.put(NotificationsSettings.KEY_BLOGS, blogsArray);
+ } catch (JSONException e) {
+ AppLog.e(T.NOTIFS, "Could not build notification settings object");
+ }
+ break;
+ case OTHER:
+ try {
+ JSONObject otherObject = new JSONObject();
+ if (type == Type.DEVICE) {
+ newValues.put(NotificationsSettings.KEY_DEVICE_ID, Long.parseLong(mDeviceId));
+ JSONArray devicesArray = new JSONArray();
+ devicesArray.put(newValues);
+ otherObject.put(NotificationsSettings.KEY_DEVICES, devicesArray);
+ } else {
+ otherObject.put(type.toString(), newValues);
+ }
+
+ settingsObject.put(NotificationsSettings.KEY_OTHER, otherObject);
+ } catch (JSONException e) {
+ AppLog.e(T.NOTIFS, "Could not build notification settings object");
+ }
+ break;
+ case DOTCOM:
+ try {
+ settingsObject.put(NotificationsSettings.KEY_DOTCOM, newValues);
+ } catch (JSONException e) {
+ AppLog.e(T.NOTIFS, "Could not build notification settings object");
+ }
+ break;
+ }
+
+ if (settingsObject.length() > 0) {
+ WordPress.getRestClientUtilsV1_1().post("/me/notifications/settings", settingsObject, null, null, null);
+ }
+ }
+ };
+
+ @Override
+ public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, @NonNull Preference preference) {
+ super.onPreferenceTreeClick(preferenceScreen, preference);
+
+ if (preference instanceof PreferenceScreen) {
+ Dialog prefDialog = ((PreferenceScreen) preference).getDialog();
+ if (prefDialog != null) {
+ String title = String.valueOf(preference.getTitle());
+ WPActivityUtils.addToolbarToDialog(this, prefDialog, title);
+ }
+ AnalyticsTracker.track(AnalyticsTracker.Stat.NOTIFICATION_SETTINGS_STREAMS_OPENED);
+ } else {
+ AnalyticsTracker.track(AnalyticsTracker.Stat.NOTIFICATION_SETTINGS_DETAILS_OPENED);
+ }
+
+ return false;
+ }
+}