| package org.wordpress.android.ui.prefs; |
| |
| import android.app.Activity; |
| import android.app.AlertDialog; |
| import android.app.Dialog; |
| import android.app.DialogFragment; |
| import android.app.ProgressDialog; |
| import android.content.Context; |
| import android.content.DialogInterface; |
| import android.content.Intent; |
| import android.content.res.Resources; |
| import android.os.Bundle; |
| import android.os.Handler; |
| import android.preference.EditTextPreference; |
| import android.preference.Preference; |
| import android.preference.PreferenceFragment; |
| import android.preference.PreferenceScreen; |
| import android.support.annotation.NonNull; |
| import android.support.design.widget.Snackbar; |
| import android.support.v7.widget.LinearLayoutManager; |
| import android.text.TextUtils; |
| import android.util.Pair; |
| import android.util.SparseBooleanArray; |
| import android.view.ActionMode; |
| import android.view.ContextThemeWrapper; |
| import android.view.HapticFeedbackConstants; |
| import android.view.LayoutInflater; |
| import android.view.Menu; |
| import android.view.MenuInflater; |
| import android.view.MenuItem; |
| import android.view.View; |
| import android.view.ViewGroup; |
| import android.view.Window; |
| import android.view.WindowManager.LayoutParams; |
| import android.widget.AdapterView; |
| import android.widget.Button; |
| import android.widget.EditText; |
| import android.widget.ListAdapter; |
| import android.widget.ListView; |
| import android.widget.NumberPicker.Formatter; |
| import android.widget.TextView; |
| |
| 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.analytics.AnalyticsTracker; |
| import org.wordpress.android.models.AccountHelper; |
| import org.wordpress.android.models.Blog; |
| import org.wordpress.android.ui.WPWebViewActivity; |
| import org.wordpress.android.ui.stats.StatsWidgetProvider; |
| import org.wordpress.android.ui.stats.datasets.StatsTable; |
| import org.wordpress.android.util.AnalyticsUtils; |
| import org.wordpress.android.util.AppLog; |
| import org.wordpress.android.util.CoreEvents; |
| import org.wordpress.android.util.HelpshiftHelper; |
| import org.wordpress.android.util.NetworkUtils; |
| import org.wordpress.android.util.StringUtils; |
| import org.wordpress.android.util.ToastUtils; |
| import org.wordpress.android.util.UrlUtils; |
| import org.wordpress.android.util.WPActivityUtils; |
| import org.wordpress.android.util.WPPrefUtils; |
| |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import de.greenrobot.event.EventBus; |
| |
| /** |
| * Allows interfacing with WordPress site settings. Works with WP.com and WP.org v4.5+ (pending). |
| * |
| * Settings are synced automatically when local changes are made. |
| */ |
| |
| public class SiteSettingsFragment extends PreferenceFragment |
| implements Preference.OnPreferenceChangeListener, |
| Preference.OnPreferenceClickListener, |
| AdapterView.OnItemLongClickListener, |
| ViewGroup.OnHierarchyChangeListener, |
| Dialog.OnDismissListener, |
| SiteSettingsInterface.SiteSettingsListener { |
| |
| /** |
| * Use this argument to pass the {@link Integer} local blog ID to this fragment. |
| */ |
| public static final String ARG_LOCAL_BLOG_ID = "local_blog_id"; |
| |
| /** |
| * When the user removes a site (by selecting Delete Site) the parent {@link Activity} result |
| * is set to this value and {@link Activity#finish()} is invoked. |
| */ |
| public static final int RESULT_BLOG_REMOVED = Activity.RESULT_FIRST_USER; |
| |
| /** |
| * Provides the regex to identify domain HTTP(S) protocol and/or 'www' sub-domain. |
| * |
| * Used to format user-facing {@link String}'s in certain preferences. |
| */ |
| public static final String ADDRESS_FORMAT_REGEX = "^(https?://(w{3})?|www\\.)"; |
| |
| /** |
| * url that points to wordpress.com purchases |
| */ |
| public static final String WORDPRESS_PURCHASES_URL = "https://wordpress.com/purchases"; |
| |
| /** |
| * Used to move the Uncategorized category to the beginning of the category list. |
| */ |
| private static final int UNCATEGORIZED_CATEGORY_ID = 1; |
| |
| /** |
| * Request code used when creating the {@link RelatedPostsDialog}. |
| */ |
| private static final int RELATED_POSTS_REQUEST_CODE = 1; |
| private static final int THREADING_REQUEST_CODE = 2; |
| private static final int PAGING_REQUEST_CODE = 3; |
| private static final int CLOSE_AFTER_REQUEST_CODE = 4; |
| private static final int MULTIPLE_LINKS_REQUEST_CODE = 5; |
| private static final int DELETE_SITE_REQUEST_CODE = 6; |
| private static final String DELETE_SITE_TAG = "delete-site"; |
| private static final String PURCHASE_ORIGINAL_RESPONSE_KEY = "originalResponse"; |
| private static final String PURCHASE_ACTIVE_KEY = "active"; |
| private static final String ANALYTICS_ERROR_PROPERTY_KEY = "error"; |
| |
| private static final long FETCH_DELAY = 1000; |
| |
| // Reference to blog obtained from passed ID (ARG_LOCAL_BLOG_ID) |
| private Blog mBlog; |
| |
| // Can interface with WP.com or WP.org |
| private SiteSettingsInterface mSiteSettings; |
| |
| // Reference to the list of items being edited in the current list editor |
| private List<String> mEditingList; |
| |
| // Used to ensure that settings are only fetched once throughout the lifecycle of the fragment |
| private boolean mShouldFetch; |
| |
| // General settings |
| private EditTextPreference mTitlePref; |
| private EditTextPreference mTaglinePref; |
| private EditTextPreference mAddressPref; |
| private DetailListPreference mPrivacyPref; |
| private DetailListPreference mLanguagePref; |
| |
| // Account settings (NOTE: only for WP.org) |
| private EditTextPreference mUsernamePref; |
| private EditTextPreference mPasswordPref; |
| |
| // Writing settings |
| private WPSwitchPreference mLocationPref; |
| private DetailListPreference mCategoryPref; |
| private DetailListPreference mFormatPref; |
| private Preference mRelatedPostsPref; |
| |
| // Discussion settings preview |
| private WPSwitchPreference mAllowCommentsPref; |
| private WPSwitchPreference mSendPingbacksPref; |
| private WPSwitchPreference mReceivePingbacksPref; |
| |
| // Discussion settings -> Defaults for New Posts |
| private WPSwitchPreference mAllowCommentsNested; |
| private WPSwitchPreference mSendPingbacksNested; |
| private WPSwitchPreference mReceivePingbacksNested; |
| private PreferenceScreen mMorePreference; |
| |
| // Discussion settings -> Comments |
| private WPSwitchPreference mIdentityRequiredPreference; |
| private WPSwitchPreference mUserAccountRequiredPref; |
| private Preference mCloseAfterPref; |
| private DetailListPreference mSortByPref; |
| private Preference mThreadingPref; |
| private Preference mPagingPref; |
| private DetailListPreference mWhitelistPref; |
| private Preference mMultipleLinksPref; |
| private Preference mModerationHoldPref; |
| private Preference mBlacklistPref; |
| |
| // This Device settings |
| private DetailListPreference mImageWidthPref; |
| private WPSwitchPreference mUploadAndLinkPref; |
| |
| // Advanced settings |
| private Preference mStartOverPref; |
| private Preference mExportSitePref; |
| private Preference mDeleteSitePref; |
| |
| private boolean mEditingEnabled = true; |
| |
| // Reference to the state of the fragment |
| private boolean mIsFragmentPaused = false; |
| |
| // Hold for Moderation and Blacklist settings |
| private Dialog mDialog; |
| private ActionMode mActionMode; |
| private MultiSelectRecyclerViewAdapter mAdapter; |
| |
| @Override |
| public void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| |
| Activity activity = getActivity(); |
| |
| // make sure we have local site data and a network connection, otherwise finish activity |
| mBlog = WordPress.getBlog(getArguments().getInt(ARG_LOCAL_BLOG_ID, -1)); |
| if (mBlog == null || !NetworkUtils.checkConnection(activity)) { |
| getActivity().finish(); |
| return; |
| } |
| |
| // track successful settings screen access |
| AnalyticsUtils.trackWithCurrentBlogDetails( |
| AnalyticsTracker.Stat.SITE_SETTINGS_ACCESSED); |
| |
| // setup state to fetch remote settings |
| mShouldFetch = true; |
| |
| // initialize the appropriate settings interface (WP.com or WP.org) |
| mSiteSettings = SiteSettingsInterface.getInterface(activity, mBlog, this); |
| |
| setRetainInstance(true); |
| addPreferencesFromResource(R.xml.site_settings); |
| |
| // toggle which preferences are shown and set references |
| initPreferences(); |
| } |
| |
| @Override |
| public void onPause() { |
| super.onPause(); |
| WordPress.wpDB.saveBlog(mBlog); |
| mIsFragmentPaused = true; |
| } |
| |
| @Override |
| public void onResume() { |
| super.onResume(); |
| |
| // Fragment#onResume() is called after FragmentActivity#onPostResume(). |
| // The latter is the most secure way of keeping track of the activity's state, and avoid calls to commitAllowingStateLoss. |
| mIsFragmentPaused = false; |
| |
| // always load cached settings |
| mSiteSettings.init(false); |
| |
| if (mShouldFetch) { |
| new Handler().postDelayed(new Runnable() { |
| @Override |
| public void run() { |
| // initialize settings with locally cached values, fetch remote on first pass |
| mSiteSettings.init(true); |
| } |
| }, FETCH_DELAY); |
| // stop future calls from fetching remote settings |
| mShouldFetch = false; |
| } |
| } |
| |
| @Override |
| public void onDestroyView() { |
| removeMoreScreenToolbar(); |
| super.onDestroyView(); |
| } |
| |
| @Override |
| public void onActivityResult(int requestCode, int resultCode, Intent data) { |
| if (data != null) { |
| switch (requestCode) { |
| case RELATED_POSTS_REQUEST_CODE: |
| // data is null if user cancelled editing Related Posts settings |
| mSiteSettings.setShowRelatedPosts(data.getBooleanExtra( |
| RelatedPostsDialog.SHOW_RELATED_POSTS_KEY, false)); |
| mSiteSettings.setShowRelatedPostHeader(data.getBooleanExtra( |
| RelatedPostsDialog.SHOW_HEADER_KEY, false)); |
| mSiteSettings.setShowRelatedPostImages(data.getBooleanExtra( |
| RelatedPostsDialog.SHOW_IMAGES_KEY, false)); |
| onPreferenceChange(mRelatedPostsPref, mSiteSettings.getRelatedPostsDescription()); |
| break; |
| case THREADING_REQUEST_CODE: |
| int levels = data.getIntExtra(NumberPickerDialog.CUR_VALUE_KEY, -1); |
| mSiteSettings.setShouldThreadComments(levels > 1 && data.getBooleanExtra |
| (NumberPickerDialog.SWITCH_ENABLED_KEY, false)); |
| onPreferenceChange(mThreadingPref, levels); |
| break; |
| case PAGING_REQUEST_CODE: |
| mSiteSettings.setShouldPageComments(data.getBooleanExtra |
| (NumberPickerDialog.SWITCH_ENABLED_KEY, false)); |
| onPreferenceChange(mPagingPref, data.getIntExtra( |
| NumberPickerDialog.CUR_VALUE_KEY, -1)); |
| break; |
| case CLOSE_AFTER_REQUEST_CODE: |
| mSiteSettings.setShouldCloseAfter(data.getBooleanExtra |
| (NumberPickerDialog.SWITCH_ENABLED_KEY, false)); |
| onPreferenceChange(mCloseAfterPref, data.getIntExtra( |
| NumberPickerDialog.CUR_VALUE_KEY, -1)); |
| break; |
| case MULTIPLE_LINKS_REQUEST_CODE: |
| int numLinks = data.getIntExtra(NumberPickerDialog.CUR_VALUE_KEY, -1); |
| if (numLinks < 0 || numLinks == mSiteSettings.getMultipleLinks()) return; |
| onPreferenceChange(mMultipleLinksPref, numLinks); |
| break; |
| } |
| } else { |
| switch (requestCode) { |
| case DELETE_SITE_REQUEST_CODE: |
| deleteSite(); |
| break; |
| } |
| } |
| |
| super.onActivityResult(requestCode, resultCode, data); |
| } |
| |
| @Override |
| public View onCreateView(@NonNull LayoutInflater inflater, |
| ViewGroup container, |
| Bundle savedInstanceState) { |
| // use a wrapper to apply the Calypso theme |
| Context themer = new ContextThemeWrapper(getActivity(), R.style.Calypso_SiteSettingsTheme); |
| LayoutInflater localInflater = inflater.cloneInContext(themer); |
| View view = super.onCreateView(localInflater, container, savedInstanceState); |
| |
| if (view != null) { |
| setupPreferenceList((ListView) view.findViewById(android.R.id.list), getResources()); |
| } |
| |
| return view; |
| } |
| |
| @Override |
| public void onSaveInstanceState(Bundle outState) { |
| removeMoreScreenToolbar(); |
| super.onSaveInstanceState(outState); |
| setupMorePreferenceScreen(); |
| } |
| |
| @Override |
| public void onActivityCreated(Bundle savedInstanceState) { |
| super.onActivityCreated(savedInstanceState); |
| if (savedInstanceState != null) setupMorePreferenceScreen(); |
| } |
| |
| @Override |
| public void onChildViewAdded(View parent, View child) { |
| if (child.getId() == android.R.id.title && child instanceof TextView) { |
| // style preference category title views |
| TextView title = (TextView) child; |
| WPPrefUtils.layoutAsBody2(title); |
| } else { |
| // style preference title views |
| TextView title = (TextView) child.findViewById(android.R.id.title); |
| if (title != null) WPPrefUtils.layoutAsSubhead(title); |
| } |
| } |
| |
| @Override |
| public void onChildViewRemoved(View parent, View child) { |
| // NOP |
| } |
| |
| @Override |
| public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) { |
| super.onPreferenceTreeClick(screen, preference); |
| |
| // More preference selected, style the Discussion screen |
| if (preference == mMorePreference) { |
| // track user accessing the full Discussion settings screen |
| AnalyticsUtils.trackWithCurrentBlogDetails( |
| AnalyticsTracker.Stat.SITE_SETTINGS_ACCESSED_MORE_SETTINGS); |
| |
| return setupMorePreferenceScreen(); |
| } else if (preference == findPreference(getString(R.string.pref_key_site_start_over_screen))) { |
| Dialog dialog = ((PreferenceScreen) preference).getDialog(); |
| if (dialog == null) return false; |
| |
| AnalyticsUtils.trackWithCurrentBlogDetails( |
| AnalyticsTracker.Stat.SITE_SETTINGS_START_OVER_ACCESSED); |
| |
| setupPreferenceList((ListView) dialog.findViewById(android.R.id.list), getResources()); |
| String title = getString(R.string.start_over); |
| WPActivityUtils.addToolbarToDialog(this, dialog, title); |
| } |
| |
| return false; |
| } |
| |
| @Override |
| public boolean onPreferenceClick(Preference preference) { |
| if (preference == mRelatedPostsPref) { |
| showRelatedPostsDialog(); |
| } else if (preference == mMultipleLinksPref) { |
| showMultipleLinksDialog(); |
| } else if (preference == mModerationHoldPref) { |
| mEditingList = mSiteSettings.getModerationKeys(); |
| showListEditorDialog(R.string.site_settings_moderation_hold_title, |
| R.string.site_settings_hold_for_moderation_description); |
| } else if (preference == mBlacklistPref) { |
| mEditingList = mSiteSettings.getBlacklistKeys(); |
| showListEditorDialog(R.string.site_settings_blacklist_title, |
| R.string.site_settings_blacklist_description); |
| } else if (preference == mStartOverPref) { |
| AnalyticsUtils.trackWithCurrentBlogDetails( |
| AnalyticsTracker.Stat.SITE_SETTINGS_START_OVER_CONTACT_SUPPORT_CLICKED); |
| HelpshiftHelper.getInstance().showConversation(getActivity(), HelpshiftHelper.Tag.ORIGIN_START_OVER); |
| } else if (preference == mCloseAfterPref) { |
| showCloseAfterDialog(); |
| } else if (preference == mPagingPref) { |
| showPagingDialog(); |
| } else if (preference == mThreadingPref) { |
| showThreadingDialog(); |
| } else if (preference == mCategoryPref || preference == mFormatPref) { |
| return !shouldShowListPreference((DetailListPreference) preference); |
| } else if (preference == mExportSitePref) { |
| showExportContentDialog(); |
| } else if (preference == mDeleteSitePref) { |
| AnalyticsUtils.trackWithCurrentBlogDetails( |
| AnalyticsTracker.Stat.SITE_SETTINGS_DELETE_SITE_ACCESSED); |
| requestPurchasesForDeletionCheck(); |
| } else { |
| return false; |
| } |
| |
| return true; |
| } |
| |
| @Override |
| public boolean onPreferenceChange(Preference preference, Object newValue) { |
| if (newValue == null || !mEditingEnabled) return false; |
| |
| if (preference == mTitlePref) { |
| mSiteSettings.setTitle(newValue.toString()); |
| changeEditTextPreferenceValue(mTitlePref, mSiteSettings.getTitle()); |
| } else if (preference == mTaglinePref) { |
| mSiteSettings.setTagline(newValue.toString()); |
| changeEditTextPreferenceValue(mTaglinePref, mSiteSettings.getTagline()); |
| } else if (preference == mAddressPref) { |
| mSiteSettings.setAddress(newValue.toString()); |
| changeEditTextPreferenceValue(mAddressPref, mSiteSettings.getAddress()); |
| } else if (preference == mLanguagePref) { |
| if (!mSiteSettings.setLanguageCode(newValue.toString())) { |
| AppLog.w(AppLog.T.SETTINGS, "Unknown language code " + newValue.toString() + " selected in Site Settings."); |
| ToastUtils.showToast(getActivity(), R.string.site_settings_unknown_language_code_error); |
| } |
| changeLanguageValue(mSiteSettings.getLanguageCode()); |
| } else if (preference == mPrivacyPref) { |
| mSiteSettings.setPrivacy(Integer.parseInt(newValue.toString())); |
| setDetailListPreferenceValue(mPrivacyPref, |
| String.valueOf(mSiteSettings.getPrivacy()), |
| mSiteSettings.getPrivacyDescription()); |
| } else if (preference == mAllowCommentsPref || preference == mAllowCommentsNested) { |
| setAllowComments((Boolean) newValue); |
| } else if (preference == mSendPingbacksPref || preference == mSendPingbacksNested) { |
| setSendPingbacks((Boolean) newValue); |
| } else if (preference == mReceivePingbacksPref || preference == mReceivePingbacksNested) { |
| setReceivePingbacks((Boolean) newValue); |
| } else if (preference == mCloseAfterPref) { |
| mSiteSettings.setCloseAfter(Integer.parseInt(newValue.toString())); |
| mCloseAfterPref.setSummary(mSiteSettings.getCloseAfterDescription()); |
| } else if (preference == mSortByPref) { |
| mSiteSettings.setCommentSorting(Integer.parseInt(newValue.toString())); |
| setDetailListPreferenceValue(mSortByPref, |
| newValue.toString(), |
| mSiteSettings.getSortingDescription()); |
| } else if (preference == mThreadingPref) { |
| mSiteSettings.setThreadingLevels(Integer.parseInt(newValue.toString())); |
| mThreadingPref.setSummary(mSiteSettings.getThreadingDescription()); |
| } else if (preference == mPagingPref) { |
| mSiteSettings.setPagingCount(Integer.parseInt(newValue.toString())); |
| mPagingPref.setSummary(mSiteSettings.getPagingDescription()); |
| } else if (preference == mIdentityRequiredPreference) { |
| mSiteSettings.setIdentityRequired((Boolean) newValue); |
| } else if (preference == mUserAccountRequiredPref) { |
| mSiteSettings.setUserAccountRequired((Boolean) newValue); |
| } else if (preference == mWhitelistPref) { |
| updateWhitelistSettings(Integer.parseInt(newValue.toString())); |
| } else if (preference == mMultipleLinksPref) { |
| mSiteSettings.setMultipleLinks(Integer.parseInt(newValue.toString())); |
| String s = StringUtils.getQuantityString(getActivity(), R.string.site_settings_multiple_links_summary_zero, |
| R.string.site_settings_multiple_links_summary_one, |
| R.string.site_settings_multiple_links_summary_other, mSiteSettings.getMultipleLinks()); |
| mMultipleLinksPref.setSummary(s); |
| } else if (preference == mUsernamePref) { |
| mSiteSettings.setUsername(newValue.toString()); |
| changeEditTextPreferenceValue(mUsernamePref, mSiteSettings.getUsername()); |
| } else if (preference == mPasswordPref) { |
| mSiteSettings.setPassword(newValue.toString()); |
| changeEditTextPreferenceValue(mPasswordPref, mSiteSettings.getPassword()); |
| } else if (preference == mLocationPref) { |
| mSiteSettings.setLocation((Boolean) newValue); |
| } else if (preference == mCategoryPref) { |
| mSiteSettings.setDefaultCategory(Integer.parseInt(newValue.toString())); |
| setDetailListPreferenceValue(mCategoryPref, |
| newValue.toString(), |
| mSiteSettings.getDefaultCategoryForDisplay()); |
| } else if (preference == mFormatPref) { |
| mSiteSettings.setDefaultFormat(newValue.toString()); |
| setDetailListPreferenceValue(mFormatPref, |
| newValue.toString(), |
| mSiteSettings.getDefaultPostFormatDisplay()); |
| } else if (preference == mImageWidthPref) { |
| mBlog.setMaxImageWidth(newValue.toString()); |
| setDetailListPreferenceValue(mImageWidthPref, |
| mBlog.getMaxImageWidth(), |
| mBlog.getMaxImageWidth()); |
| } else if (preference == mUploadAndLinkPref) { |
| mBlog.setFullSizeImage(Boolean.valueOf(newValue.toString())); |
| } else if (preference == mRelatedPostsPref) { |
| mRelatedPostsPref.setSummary(newValue.toString()); |
| } else if (preference == mModerationHoldPref) { |
| mModerationHoldPref.setSummary(mSiteSettings.getModerationHoldDescription()); |
| } else if (preference == mBlacklistPref) { |
| mBlacklistPref.setSummary(mSiteSettings.getBlacklistDescription()); |
| } else { |
| return false; |
| } |
| |
| mSiteSettings.saveSettings(); |
| |
| return true; |
| } |
| |
| @Override |
| public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { |
| ListView listView = (ListView) parent; |
| ListAdapter listAdapter = listView.getAdapter(); |
| Object obj = listAdapter.getItem(position); |
| |
| if (obj != null) { |
| if (obj instanceof View.OnLongClickListener) { |
| View.OnLongClickListener longListener = (View.OnLongClickListener) obj; |
| return longListener.onLongClick(view); |
| } else if (obj instanceof PreferenceHint) { |
| PreferenceHint hintObj = (PreferenceHint) obj; |
| if (hintObj.hasHint()) { |
| HashMap<String, Object> properties = new HashMap<>(); |
| properties.put("hint_shown", hintObj.getHint()); |
| AnalyticsUtils.trackWithCurrentBlogDetails( |
| AnalyticsTracker.Stat.SITE_SETTINGS_HINT_TOAST_SHOWN, properties); |
| ToastUtils.showToast(getActivity(), hintObj.getHint(), ToastUtils.Duration.SHORT); |
| } |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| @Override |
| public void onDismiss(DialogInterface dialog) { |
| if (mEditingList == mSiteSettings.getModerationKeys()) { |
| onPreferenceChange(mModerationHoldPref, mEditingList.size()); |
| } else if (mEditingList == mSiteSettings.getBlacklistKeys()) { |
| onPreferenceChange(mBlacklistPref, mEditingList.size()); |
| } |
| mEditingList = null; |
| } |
| |
| @Override |
| public void onSettingsUpdated(Exception error) { |
| if (error != null) { |
| ToastUtils.showToast(getActivity(), R.string.error_fetch_remote_site_settings); |
| getActivity().finish(); |
| return; |
| } |
| |
| if (isAdded()) setPreferencesFromSiteSettings(); |
| } |
| |
| @Override |
| public void onSettingsSaved(Exception error) { |
| if (error != null) { |
| ToastUtils.showToast(WordPress.getContext(), R.string.error_post_remote_site_settings); |
| return; |
| } |
| mBlog.setBlogName(mSiteSettings.getTitle()); |
| WordPress.wpDB.saveBlog(mBlog); |
| |
| // update the global current Blog so WordPress.getCurrentBlog() callers will get the updated object |
| WordPress.setCurrentBlog(mBlog.getLocalTableBlogId()); |
| |
| EventBus.getDefault().post(new CoreEvents.BlogListChanged()); |
| } |
| |
| @Override |
| public void onCredentialsValidated(Exception error) { |
| if (error != null) { |
| ToastUtils.showToast(WordPress.getContext(), R.string.username_or_password_incorrect); |
| } |
| } |
| |
| private void setupPreferenceList(ListView prefList, Resources res) { |
| if (prefList == null || res == null) return; |
| |
| // customize list dividers |
| //noinspection deprecation |
| prefList.setDivider(res.getDrawable(R.drawable.preferences_divider)); |
| prefList.setDividerHeight(res.getDimensionPixelSize(R.dimen.site_settings_divider_height)); |
| // handle long clicks on preferences to display hints |
| prefList.setOnItemLongClickListener(this); |
| // required to customize (Calypso) preference views |
| prefList.setOnHierarchyChangeListener(this); |
| // remove footer divider bar |
| prefList.setFooterDividersEnabled(false); |
| //noinspection deprecation |
| prefList.setOverscrollFooter(res.getDrawable(R.color.transparent)); |
| } |
| |
| /** |
| * Helper method to retrieve {@link Preference} references and initialize any data. |
| */ |
| private void initPreferences() { |
| mTitlePref = (EditTextPreference) getChangePref(R.string.pref_key_site_title); |
| mTaglinePref = (EditTextPreference) getChangePref(R.string.pref_key_site_tagline); |
| mAddressPref = (EditTextPreference) getChangePref(R.string.pref_key_site_address); |
| mPrivacyPref = (DetailListPreference) getChangePref(R.string.pref_key_site_visibility); |
| mLanguagePref = (DetailListPreference) getChangePref(R.string.pref_key_site_language); |
| mUsernamePref = (EditTextPreference) getChangePref(R.string.pref_key_site_username); |
| mPasswordPref = (EditTextPreference) getChangePref(R.string.pref_key_site_password); |
| mLocationPref = (WPSwitchPreference) getChangePref(R.string.pref_key_site_location); |
| mCategoryPref = (DetailListPreference) getChangePref(R.string.pref_key_site_category); |
| mFormatPref = (DetailListPreference) getChangePref(R.string.pref_key_site_format); |
| mAllowCommentsPref = (WPSwitchPreference) getChangePref(R.string.pref_key_site_allow_comments); |
| mAllowCommentsNested = (WPSwitchPreference) getChangePref(R.string.pref_key_site_allow_comments_nested); |
| mSendPingbacksPref = (WPSwitchPreference) getChangePref(R.string.pref_key_site_send_pingbacks); |
| mSendPingbacksNested = (WPSwitchPreference) getChangePref(R.string.pref_key_site_send_pingbacks_nested); |
| mReceivePingbacksPref = (WPSwitchPreference) getChangePref(R.string.pref_key_site_receive_pingbacks); |
| mReceivePingbacksNested = (WPSwitchPreference) getChangePref(R.string.pref_key_site_receive_pingbacks_nested); |
| mIdentityRequiredPreference = (WPSwitchPreference) getChangePref(R.string.pref_key_site_identity_required); |
| mUserAccountRequiredPref = (WPSwitchPreference) getChangePref(R.string.pref_key_site_user_account_required); |
| mSortByPref = (DetailListPreference) getChangePref(R.string.pref_key_site_sort_by); |
| mWhitelistPref = (DetailListPreference) getChangePref(R.string.pref_key_site_whitelist); |
| mMorePreference = (PreferenceScreen) getClickPref(R.string.pref_key_site_more_discussion); |
| mRelatedPostsPref = getClickPref(R.string.pref_key_site_related_posts); |
| mCloseAfterPref = getClickPref(R.string.pref_key_site_close_after); |
| mPagingPref = getClickPref(R.string.pref_key_site_paging); |
| mThreadingPref = getClickPref(R.string.pref_key_site_threading); |
| mMultipleLinksPref = getClickPref(R.string.pref_key_site_multiple_links); |
| mModerationHoldPref = getClickPref(R.string.pref_key_site_moderation_hold); |
| mBlacklistPref = getClickPref(R.string.pref_key_site_blacklist); |
| mImageWidthPref = (DetailListPreference) getChangePref(R.string.pref_key_site_image_width); |
| mUploadAndLinkPref = (WPSwitchPreference) getChangePref(R.string.pref_key_site_upload_and_link_image); |
| mStartOverPref = getClickPref(R.string.pref_key_site_start_over); |
| mExportSitePref = getClickPref(R.string.pref_key_site_export_site); |
| mDeleteSitePref = getClickPref(R.string.pref_key_site_delete_site); |
| |
| sortLanguages(); |
| |
| // .com sites hide the Account category, self-hosted sites hide the Related Posts preference |
| if (mBlog.isDotcomFlag()) { |
| removeSelfHostedOnlyPreferences(); |
| } else { |
| removeDotComOnlyPreferences(); |
| } |
| |
| // hide all options except for Delete site and Enable Location if user is not admin |
| if (!mBlog.isAdmin()) hideAdminRequiredPreferences(); |
| } |
| |
| public void setEditingEnabled(boolean enabled) { |
| // excludes mAddressPref, mMorePreference |
| final Preference[] editablePreference = { |
| mTitlePref , mTaglinePref, mPrivacyPref, mLanguagePref, mUsernamePref, |
| mPasswordPref, mLocationPref, mCategoryPref, mFormatPref, mAllowCommentsPref, |
| mAllowCommentsNested, mSendPingbacksPref, mSendPingbacksNested, mReceivePingbacksPref, |
| mReceivePingbacksNested, mIdentityRequiredPreference, mUserAccountRequiredPref, |
| mSortByPref, mWhitelistPref, mRelatedPostsPref, mCloseAfterPref, mPagingPref, |
| mThreadingPref, mMultipleLinksPref, mModerationHoldPref, mBlacklistPref, |
| mImageWidthPref, mUploadAndLinkPref, mDeleteSitePref |
| }; |
| |
| for(Preference preference : editablePreference) { |
| if(preference!=null) preference.setEnabled(enabled); |
| } |
| |
| mEditingEnabled = enabled; |
| } |
| |
| private void showRelatedPostsDialog() { |
| DialogFragment relatedPosts = new RelatedPostsDialog(); |
| Bundle args = new Bundle(); |
| args.putBoolean(RelatedPostsDialog.SHOW_RELATED_POSTS_KEY, mSiteSettings.getShowRelatedPosts()); |
| args.putBoolean(RelatedPostsDialog.SHOW_HEADER_KEY, mSiteSettings.getShowRelatedPostHeader()); |
| args.putBoolean(RelatedPostsDialog.SHOW_IMAGES_KEY, mSiteSettings.getShowRelatedPostImages()); |
| relatedPosts.setArguments(args); |
| relatedPosts.setTargetFragment(this, RELATED_POSTS_REQUEST_CODE); |
| relatedPosts.show(getFragmentManager(), "related-posts"); |
| } |
| |
| private void showNumberPickerDialog(Bundle args, int requestCode, String tag) { |
| showNumberPickerDialog(args, requestCode, tag, null); |
| } |
| |
| private void showNumberPickerDialog(Bundle args, int requestCode, String tag, Formatter format) { |
| NumberPickerDialog dialog = new NumberPickerDialog(); |
| dialog.setNumberFormat(format); |
| dialog.setArguments(args); |
| dialog.setTargetFragment(this, requestCode); |
| dialog.show(getFragmentManager(), tag); |
| } |
| |
| private void showPagingDialog() { |
| Bundle args = new Bundle(); |
| args.putBoolean(NumberPickerDialog.SHOW_SWITCH_KEY, true); |
| args.putBoolean(NumberPickerDialog.SWITCH_ENABLED_KEY, mSiteSettings.getShouldPageComments()); |
| args.putString(NumberPickerDialog.SWITCH_TITLE_KEY, getString(R.string.site_settings_paging_title)); |
| args.putString(NumberPickerDialog.SWITCH_DESC_KEY, getString(R.string.site_settings_paging_dialog_description)); |
| args.putString(NumberPickerDialog.TITLE_KEY, getString(R.string.site_settings_paging_title)); |
| args.putString(NumberPickerDialog.HEADER_TEXT_KEY, getString(R.string.site_settings_paging_dialog_header)); |
| args.putInt(NumberPickerDialog.MIN_VALUE_KEY, 1); |
| args.putInt(NumberPickerDialog.MAX_VALUE_KEY, getResources().getInteger(R.integer.paging_limit)); |
| args.putInt(NumberPickerDialog.CUR_VALUE_KEY, mSiteSettings.getPagingCount()); |
| showNumberPickerDialog(args, PAGING_REQUEST_CODE, "paging-dialog"); |
| } |
| |
| private void showThreadingDialog() { |
| Bundle args = new Bundle(); |
| args.putBoolean(NumberPickerDialog.SHOW_SWITCH_KEY, true); |
| args.putBoolean(NumberPickerDialog.SWITCH_ENABLED_KEY, mSiteSettings.getShouldThreadComments()); |
| args.putString(NumberPickerDialog.SWITCH_TITLE_KEY, getString(R.string.site_settings_threading_title)); |
| args.putString(NumberPickerDialog.SWITCH_DESC_KEY, getString(R.string.site_settings_threading_dialog_description)); |
| args.putString(NumberPickerDialog.TITLE_KEY, getString(R.string.site_settings_threading_title)); |
| args.putString(NumberPickerDialog.HEADER_TEXT_KEY, getString(R.string.site_settings_threading_dialog_header)); |
| args.putInt(NumberPickerDialog.MIN_VALUE_KEY, 2); |
| args.putInt(NumberPickerDialog.MAX_VALUE_KEY, getResources().getInteger(R.integer.threading_limit)); |
| args.putInt(NumberPickerDialog.CUR_VALUE_KEY, mSiteSettings.getThreadingLevels()); |
| showNumberPickerDialog(args, THREADING_REQUEST_CODE, "threading-dialog", new Formatter() { |
| @Override |
| public String format(int value) { |
| return mSiteSettings.getThreadingDescriptionForLevel(value); |
| } |
| }); |
| } |
| |
| private void showExportContentDialog() { |
| AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
| builder.setTitle(R.string.export_your_content); |
| String email = AccountHelper.getDefaultAccount().getEmail(); |
| builder.setMessage(getString(R.string.export_your_content_message, email)); |
| builder.setPositiveButton(R.string.site_settings_export_content_title, new DialogInterface.OnClickListener() { |
| @Override |
| public void onClick(DialogInterface dialog, int which) { |
| AnalyticsUtils.trackWithCurrentBlogDetails( |
| AnalyticsTracker.Stat.SITE_SETTINGS_EXPORT_SITE_REQUESTED); |
| exportSite(); |
| } |
| }); |
| builder.setNegativeButton(R.string.cancel, null); |
| |
| builder.show(); |
| AnalyticsUtils.trackWithCurrentBlogDetails( |
| AnalyticsTracker.Stat.SITE_SETTINGS_EXPORT_SITE_ACCESSED); |
| } |
| |
| private void dismissProgressDialog(ProgressDialog progressDialog) { |
| if (progressDialog != null && progressDialog.isShowing()) { |
| try { |
| progressDialog.dismiss(); |
| } catch (IllegalArgumentException e) { |
| // dialog doesn't exist |
| } |
| } |
| } |
| |
| private void requestPurchasesForDeletionCheck() { |
| final Blog currentBlog = WordPress.getCurrentBlog(); |
| final ProgressDialog progressDialog = ProgressDialog.show(getActivity(), "", getString(R.string.checking_purchases), true, false); |
| AnalyticsUtils.trackWithCurrentBlogDetails( |
| AnalyticsTracker.Stat.SITE_SETTINGS_DELETE_SITE_PURCHASES_REQUESTED); |
| WordPress.getRestClientUtils().getSitePurchases(currentBlog.getDotComBlogId(), new RestRequest.Listener() { |
| @Override |
| public void onResponse(JSONObject response) { |
| dismissProgressDialog(progressDialog); |
| if (isAdded()) { |
| showPurchasesOrDeleteSiteDialog(response, currentBlog); |
| } |
| } |
| }, new RestRequest.ErrorListener() { |
| @Override |
| public void onErrorResponse(VolleyError error) { |
| dismissProgressDialog(progressDialog); |
| if (isAdded()) { |
| ToastUtils.showToast(getActivity(), getString(R.string.purchases_request_error)); |
| AppLog.e(AppLog.T.API, "Error occurred while requesting purchases for deletion check: " + error.toString()); |
| } |
| } |
| }); |
| } |
| |
| private void showPurchasesOrDeleteSiteDialog(JSONObject response, final Blog currentBlog) { |
| try { |
| JSONArray purchases = response.getJSONArray(PURCHASE_ORIGINAL_RESPONSE_KEY); |
| if (hasActivePurchases(purchases)) { |
| showPurchasesDialog(currentBlog); |
| } else { |
| showDeleteSiteDialog(); |
| } |
| } catch (JSONException e) { |
| AppLog.e(AppLog.T.API, "Error occurred while trying to delete site: " + e.toString()); |
| } |
| } |
| |
| private void showPurchasesDialog(final Blog currentBlog) { |
| AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
| builder.setTitle(R.string.premium_upgrades_title); |
| builder.setMessage(R.string.premium_upgrades_message); |
| builder.setPositiveButton(R.string.show_purchases, new DialogInterface.OnClickListener() { |
| @Override |
| public void onClick(DialogInterface dialog, int which) { |
| AnalyticsUtils.trackWithCurrentBlogDetails( |
| AnalyticsTracker.Stat.SITE_SETTINGS_DELETE_SITE_PURCHASES_SHOW_CLICKED); |
| WPWebViewActivity.openUrlByUsingWPCOMCredentials(getActivity(), WORDPRESS_PURCHASES_URL, AccountHelper.getCurrentUsernameForBlog(currentBlog)); |
| } |
| }); |
| builder.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() { |
| @Override |
| public void onClick(DialogInterface dialog, int which) { |
| dialog.dismiss(); |
| } |
| }); |
| builder.show(); |
| AnalyticsUtils.trackWithCurrentBlogDetails( |
| AnalyticsTracker.Stat.SITE_SETTINGS_DELETE_SITE_PURCHASES_SHOWN); |
| } |
| |
| private boolean hasActivePurchases(JSONArray purchases) throws JSONException { |
| for (int i = 0; i < purchases.length(); i++) { |
| JSONObject purchase = purchases.getJSONObject(i); |
| int active = purchase.getInt(PURCHASE_ACTIVE_KEY); |
| |
| if (active == 1) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| private void showDeleteSiteDialog() { |
| if (mIsFragmentPaused) return; // Do not show the DeleteSiteDialogFragment if the fragment was paused. |
| // DialogFragment internally uses commit(), and not commitAllowingStateLoss, crashing the app in case like that. |
| Bundle args = new Bundle(); |
| args.putString(DeleteSiteDialogFragment.SITE_DOMAIN_KEY, UrlUtils.getHost(mBlog.getHomeURL())); |
| DeleteSiteDialogFragment deleteSiteDialogFragment = new DeleteSiteDialogFragment(); |
| deleteSiteDialogFragment.setArguments(args); |
| deleteSiteDialogFragment.setTargetFragment(this, DELETE_SITE_REQUEST_CODE); |
| deleteSiteDialogFragment.show(getFragmentManager(), DELETE_SITE_TAG); |
| } |
| |
| private void showCloseAfterDialog() { |
| Bundle args = new Bundle(); |
| args.putBoolean(NumberPickerDialog.SHOW_SWITCH_KEY, true); |
| args.putBoolean(NumberPickerDialog.SWITCH_ENABLED_KEY, mSiteSettings.getShouldCloseAfter()); |
| args.putString(NumberPickerDialog.SWITCH_TITLE_KEY, getString(R.string.site_settings_close_after_dialog_switch_text)); |
| args.putString(NumberPickerDialog.SWITCH_DESC_KEY, getString(R.string.site_settings_close_after_dialog_description)); |
| args.putString(NumberPickerDialog.TITLE_KEY, getString(R.string.site_settings_close_after_dialog_title)); |
| args.putString(NumberPickerDialog.HEADER_TEXT_KEY, getString(R.string.site_settings_close_after_dialog_header)); |
| args.putInt(NumberPickerDialog.MIN_VALUE_KEY, 1); |
| args.putInt(NumberPickerDialog.MAX_VALUE_KEY, getResources().getInteger(R.integer.close_after_limit)); |
| args.putInt(NumberPickerDialog.CUR_VALUE_KEY, mSiteSettings.getCloseAfter()); |
| showNumberPickerDialog(args, CLOSE_AFTER_REQUEST_CODE, "close-after-dialog"); |
| } |
| |
| private void showMultipleLinksDialog() { |
| Bundle args = new Bundle(); |
| args.putBoolean(NumberPickerDialog.SHOW_SWITCH_KEY, false); |
| args.putString(NumberPickerDialog.TITLE_KEY, getString(R.string.site_settings_multiple_links_title)); |
| args.putInt(NumberPickerDialog.MIN_VALUE_KEY, 0); |
| args.putInt(NumberPickerDialog.MAX_VALUE_KEY, getResources().getInteger(R.integer.max_links_limit)); |
| args.putInt(NumberPickerDialog.CUR_VALUE_KEY, mSiteSettings.getMultipleLinks()); |
| showNumberPickerDialog(args, MULTIPLE_LINKS_REQUEST_CODE, "multiple-links-dialog"); |
| } |
| |
| private void setPreferencesFromSiteSettings() { |
| mLocationPref.setChecked(mSiteSettings.getLocation()); |
| changeEditTextPreferenceValue(mTitlePref, mSiteSettings.getTitle()); |
| changeEditTextPreferenceValue(mTaglinePref, mSiteSettings.getTagline()); |
| changeEditTextPreferenceValue(mAddressPref, mSiteSettings.getAddress()); |
| changeEditTextPreferenceValue(mUsernamePref, mSiteSettings.getUsername()); |
| changeEditTextPreferenceValue(mPasswordPref, mSiteSettings.getPassword()); |
| changeLanguageValue(mSiteSettings.getLanguageCode()); |
| setDetailListPreferenceValue(mPrivacyPref, |
| String.valueOf(mSiteSettings.getPrivacy()), |
| mSiteSettings.getPrivacyDescription()); |
| setDetailListPreferenceValue(mImageWidthPref, |
| mBlog.getMaxImageWidth(), |
| mBlog.getMaxImageWidth()); |
| setCategories(); |
| setPostFormats(); |
| setAllowComments(mSiteSettings.getAllowComments()); |
| setSendPingbacks(mSiteSettings.getSendPingbacks()); |
| setReceivePingbacks(mSiteSettings.getReceivePingbacks()); |
| setDetailListPreferenceValue(mSortByPref, |
| String.valueOf(mSiteSettings.getCommentSorting()), |
| mSiteSettings.getSortingDescription()); |
| int approval = mSiteSettings.getManualApproval() ? |
| mSiteSettings.getUseCommentWhitelist() ? 0 |
| : -1 : 1; |
| setDetailListPreferenceValue(mWhitelistPref, String.valueOf(approval), getWhitelistSummary(approval)); |
| String s = StringUtils.getQuantityString(getActivity(), R.string.site_settings_multiple_links_summary_zero, |
| R.string.site_settings_multiple_links_summary_one, |
| R.string.site_settings_multiple_links_summary_other, mSiteSettings.getMultipleLinks()); |
| mMultipleLinksPref.setSummary(s); |
| mUploadAndLinkPref.setChecked(mBlog.isFullSizeImage()); |
| mIdentityRequiredPreference.setChecked(mSiteSettings.getIdentityRequired()); |
| mUserAccountRequiredPref.setChecked(mSiteSettings.getUserAccountRequired()); |
| mThreadingPref.setSummary(mSiteSettings.getThreadingDescription()); |
| mCloseAfterPref.setSummary(mSiteSettings.getCloseAfterDescriptionForPeriod()); |
| mPagingPref.setSummary(mSiteSettings.getPagingDescription()); |
| mRelatedPostsPref.setSummary(mSiteSettings.getRelatedPostsDescription()); |
| mModerationHoldPref.setSummary(mSiteSettings.getModerationHoldDescription()); |
| mBlacklistPref.setSummary(mSiteSettings.getBlacklistDescription()); |
| } |
| |
| private void setCategories() { |
| // Ignore if there are no changes |
| if (mSiteSettings.isSameCategoryList(mCategoryPref.getEntryValues())) { |
| mCategoryPref.setValue(String.valueOf(mSiteSettings.getDefaultCategory())); |
| mCategoryPref.setSummary(mSiteSettings.getDefaultCategoryForDisplay()); |
| return; |
| } |
| |
| Map<Integer, String> categories = mSiteSettings.getCategoryNames(); |
| CharSequence[] entries = new CharSequence[categories.size()]; |
| CharSequence[] values = new CharSequence[categories.size()]; |
| int i = 0; |
| for (Integer key : categories.keySet()) { |
| entries[i] = categories.get(key); |
| values[i] = String.valueOf(key); |
| if (key == UNCATEGORIZED_CATEGORY_ID) { |
| CharSequence temp = entries[0]; |
| entries[0] = entries[i]; |
| entries[i] = temp; |
| temp = values[0]; |
| values[0] = values[i]; |
| values[i] = temp; |
| } |
| ++i; |
| } |
| |
| mCategoryPref.setEntries(entries); |
| mCategoryPref.setEntryValues(values); |
| mCategoryPref.setValue(String.valueOf(mSiteSettings.getDefaultCategory())); |
| mCategoryPref.setSummary(mSiteSettings.getDefaultCategoryForDisplay()); |
| } |
| |
| private void setPostFormats() { |
| // Ignore if there are no changes |
| if (mSiteSettings.isSameFormatList(mFormatPref.getEntryValues())) { |
| mFormatPref.setValue(String.valueOf(mSiteSettings.getDefaultPostFormat())); |
| mFormatPref.setSummary(mSiteSettings.getDefaultPostFormatDisplay()); |
| return; |
| } |
| |
| // clone the post formats map |
| final Map<String, String> postFormats = new HashMap<>(mSiteSettings.getFormats()); |
| |
| // transform the keys and values into arrays and set the ListPreference's data |
| mFormatPref.setEntries(postFormats.values().toArray(new String[0])); |
| mFormatPref.setEntryValues(postFormats.keySet().toArray(new String[0])); |
| mFormatPref.setValue(String.valueOf(mSiteSettings.getDefaultPostFormat())); |
| mFormatPref.setSummary(mSiteSettings.getDefaultPostFormatDisplay()); |
| } |
| |
| private void setAllowComments(boolean newValue) { |
| mSiteSettings.setAllowComments(newValue); |
| mAllowCommentsPref.setChecked(newValue); |
| mAllowCommentsNested.setChecked(newValue); |
| } |
| |
| private void setSendPingbacks(boolean newValue) { |
| mSiteSettings.setSendPingbacks(newValue); |
| mSendPingbacksPref.setChecked(newValue); |
| mSendPingbacksNested.setChecked(newValue); |
| } |
| |
| private void setReceivePingbacks(boolean newValue) { |
| mSiteSettings.setReceivePingbacks(newValue); |
| mReceivePingbacksPref.setChecked(newValue); |
| mReceivePingbacksNested.setChecked(newValue); |
| } |
| |
| private void setDetailListPreferenceValue(DetailListPreference pref, String value, String summary) { |
| pref.setValue(value); |
| pref.setSummary(summary); |
| pref.refreshAdapter(); |
| } |
| |
| /** |
| * Helper method to perform validation and set multiple properties on an EditTextPreference. |
| * If newValue is equal to the current preference text no action will be taken. |
| */ |
| private void changeEditTextPreferenceValue(EditTextPreference pref, String newValue) { |
| if (newValue == null || pref == null || pref.getEditText().isInEditMode()) return; |
| |
| if (!newValue.equals(pref.getSummary())) { |
| String formattedValue = StringUtils.unescapeHTML(newValue.replaceFirst(ADDRESS_FORMAT_REGEX, "")); |
| |
| pref.setText(formattedValue); |
| pref.setSummary(formattedValue); |
| } |
| } |
| |
| /** |
| * Detail strings for the dialog are generated in the selected language. |
| * |
| * @param newValue |
| * languageCode |
| */ |
| private void changeLanguageValue(String newValue) { |
| if (mLanguagePref == null || newValue == null) return; |
| |
| if (TextUtils.isEmpty(mLanguagePref.getSummary()) || |
| !newValue.equals(mLanguagePref.getValue())) { |
| mLanguagePref.setValue(newValue); |
| String summary = WPPrefUtils.getLanguageString(newValue, WPPrefUtils.languageLocale(newValue)); |
| mLanguagePref.setSummary(summary); |
| mLanguagePref.refreshAdapter(); |
| } |
| } |
| |
| private void sortLanguages() { |
| if (mLanguagePref == null) return; |
| |
| Pair<String[], String[]> pair = WPPrefUtils.createSortedLanguageDisplayStrings(mLanguagePref.getEntryValues(), WPPrefUtils.languageLocale(null)); |
| if (pair != null) { |
| String[] sortedEntries = pair.first; |
| String[] sortedValues = pair.second; |
| |
| mLanguagePref.setEntries(sortedEntries); |
| mLanguagePref.setEntryValues(sortedValues); |
| mLanguagePref.setDetails(WPPrefUtils.createLanguageDetailDisplayStrings(sortedValues)); |
| } |
| } |
| |
| private String getWhitelistSummary(int value) { |
| if (isAdded()) { |
| switch (value) { |
| case -1: |
| return getString(R.string.site_settings_whitelist_none_summary); |
| case 0: |
| return getString(R.string.site_settings_whitelist_known_summary); |
| case 1: |
| return getString(R.string.site_settings_whitelist_all_summary); |
| } |
| } |
| return ""; |
| } |
| |
| private void updateWhitelistSettings(int val) { |
| mSiteSettings.setManualApproval(val == -1); |
| mSiteSettings.setUseCommentWhitelist(val == 0); |
| setDetailListPreferenceValue(mWhitelistPref, |
| String.valueOf(val), |
| getWhitelistSummary(val)); |
| } |
| |
| private void showListEditorDialog(int titleRes, int headerRes) { |
| mDialog = new Dialog(getActivity(), R.style.Calypso_SiteSettingsTheme); |
| mDialog.setOnDismissListener(this); |
| mDialog.setContentView(getListEditorView(getString(headerRes))); |
| mDialog.show(); |
| WPActivityUtils.addToolbarToDialog(this, mDialog, getString(titleRes)); |
| } |
| |
| private View getListEditorView(String headerText) { |
| Context themer = new ContextThemeWrapper(getActivity(), R.style.Calypso_SiteSettingsTheme); |
| View view = View.inflate(themer, R.layout.list_editor, null); |
| ((TextView) view.findViewById(R.id.list_editor_header_text)).setText(headerText); |
| |
| mAdapter = null; |
| final EmptyViewRecyclerView list = (EmptyViewRecyclerView) view.findViewById(android.R.id.list); |
| list.setLayoutManager( |
| new SmoothScrollLinearLayoutManager( |
| getActivity(), |
| LinearLayoutManager.VERTICAL, |
| false, |
| getResources().getInteger(android.R.integer.config_mediumAnimTime) |
| ) |
| ); |
| list.setAdapter(getAdapter()); |
| list.setEmptyView(view.findViewById(R.id.empty_view)); |
| list.addOnItemTouchListener( |
| new RecyclerViewItemClickListener( |
| getActivity(), |
| list, |
| new RecyclerViewItemClickListener.OnItemClickListener() { |
| @Override |
| public void onItemClick(View view, int position) { |
| if (mActionMode != null) { |
| getAdapter().toggleItemSelected(position); |
| mActionMode.invalidate(); |
| |
| if (getAdapter().getItemsSelected().size() <= 0) { |
| mActionMode.finish(); |
| } |
| } |
| } |
| |
| @Override |
| public void onLongItemClick(View view, int position) { |
| if (mActionMode == null) { |
| if (view.isHapticFeedbackEnabled()) { |
| view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); |
| } |
| |
| mDialog.getWindow().getDecorView().startActionMode(new ActionModeCallback()); |
| getAdapter().setItemSelected(position); |
| mActionMode.invalidate(); |
| } |
| } |
| } |
| ) |
| ); |
| view.findViewById(R.id.fab_button).setOnClickListener(new View.OnClickListener() { |
| @Override |
| public void onClick(View v) { |
| AlertDialog.Builder builder = |
| new AlertDialog.Builder(getActivity(), R.style.Calypso_AlertDialog); |
| final EditText input = new EditText(getActivity()); |
| WPPrefUtils.layoutAsInput(input); |
| input.setWidth(getResources().getDimensionPixelSize(R.dimen.list_editor_input_max_width)); |
| input.setHint(R.string.site_settings_list_editor_input_hint); |
| builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { |
| @Override |
| public void onClick(DialogInterface dialog, int which) { |
| String entry = input.getText().toString(); |
| if (!TextUtils.isEmpty(entry) && !mEditingList.contains(entry)) { |
| mEditingList.add(entry); |
| getAdapter().notifyItemInserted(getAdapter().getItemCount() - 1); |
| list.post( |
| new Runnable() { |
| @Override |
| public void run() { |
| list.smoothScrollToPosition(getAdapter().getItemCount() - 1); |
| } |
| } |
| ); |
| mSiteSettings.saveSettings(); |
| AnalyticsUtils.trackWithCurrentBlogDetails( |
| AnalyticsTracker.Stat.SITE_SETTINGS_ADDED_LIST_ITEM); |
| } |
| } |
| }); |
| builder.setNegativeButton(R.string.cancel, null); |
| final AlertDialog alertDialog = builder.create(); |
| int spacing = getResources().getDimensionPixelSize(R.dimen.dlp_padding_start); |
| alertDialog.setView(input, spacing, spacing, spacing, 0); |
| alertDialog.requestWindowFeature(Window.FEATURE_NO_TITLE); |
| alertDialog.getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE); |
| alertDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { |
| @Override |
| public void onDismiss(DialogInterface dialog) { |
| alertDialog.getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_HIDDEN); |
| } |
| }); |
| alertDialog.show(); |
| Button positive = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE); |
| Button negative = alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE); |
| if (positive != null) WPPrefUtils.layoutAsFlatButton(positive); |
| if (negative != null) WPPrefUtils.layoutAsFlatButton(negative); |
| } |
| }); |
| |
| return view; |
| } |
| |
| private void removeBlog() { |
| if (WordPress.wpDB.deleteBlog(getActivity(), mBlog.getLocalTableBlogId())) { |
| StatsTable.deleteStatsForBlog(getActivity(), mBlog.getLocalTableBlogId()); // Remove stats data |
| AnalyticsUtils.refreshMetadata(); |
| ToastUtils.showToast(getActivity(), R.string.blog_removed_successfully); |
| WordPress.wpDB.deleteLastBlogId(); |
| WordPress.currentBlog = null; |
| getActivity().setResult(RESULT_BLOG_REMOVED); |
| |
| // If the last blog is removed and the user is not signed in wpcom, broadcast a UserSignedOut event |
| if (!AccountHelper.isSignedIn()) { |
| EventBus.getDefault().post(new CoreEvents.UserSignedOutCompletely()); |
| } |
| |
| // Checks for stats widgets that were synched with a blog that could be gone now. |
| StatsWidgetProvider.updateWidgetsOnLogout(getActivity()); |
| |
| getActivity().finish(); |
| } else { |
| AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getActivity()); |
| dialogBuilder.setTitle(getResources().getText(R.string.error)); |
| dialogBuilder.setMessage(getResources().getText(R.string.could_not_remove_account)); |
| dialogBuilder.setPositiveButton(R.string.ok, null); |
| dialogBuilder.setCancelable(true); |
| dialogBuilder.create().show(); |
| } |
| } |
| |
| private boolean shouldShowListPreference(DetailListPreference preference) { |
| return preference != null && preference.getEntries() != null && preference.getEntries().length > 0; |
| } |
| |
| private boolean setupMorePreferenceScreen() { |
| if (mMorePreference == null || !isAdded()) return false; |
| String title = getString(R.string.site_settings_discussion_title); |
| Dialog dialog = mMorePreference.getDialog(); |
| if (dialog != null) { |
| setupPreferenceList((ListView) dialog.findViewById(android.R.id.list), getResources()); |
| WPActivityUtils.addToolbarToDialog(this, dialog, title); |
| return true; |
| } |
| return false; |
| } |
| |
| private void removeMoreScreenToolbar() { |
| if (mMorePreference == null || !isAdded()) return; |
| Dialog moreDialog = mMorePreference.getDialog(); |
| WPActivityUtils.removeToolbarFromDialog(this, moreDialog); |
| } |
| |
| private void hideAdminRequiredPreferences() { |
| WPPrefUtils.removePreference(this, R.string.pref_key_site_screen, R.string.pref_key_site_general); |
| WPPrefUtils.removePreference(this, R.string.pref_key_site_screen, R.string.pref_key_site_account); |
| WPPrefUtils.removePreference(this, R.string.pref_key_site_screen, R.string.pref_key_site_discussion); |
| WPPrefUtils.removePreference(this, R.string.pref_key_site_writing, R.string.pref_key_site_category); |
| WPPrefUtils.removePreference(this, R.string.pref_key_site_writing, R.string.pref_key_site_format); |
| WPPrefUtils.removePreference(this, R.string.pref_key_site_writing, R.string.pref_key_site_related_posts); |
| } |
| |
| private void removeDotComOnlyPreferences() { |
| WPPrefUtils.removePreference(this, R.string.pref_key_site_general, R.string.pref_key_site_language); |
| WPPrefUtils.removePreference(this, R.string.pref_key_site_writing, R.string.pref_key_site_related_posts); |
| } |
| |
| private void removeSelfHostedOnlyPreferences() { |
| WPPrefUtils.removePreference(this, R.string.pref_key_site_screen, R.string.pref_key_site_account); |
| WPPrefUtils.removePreference(this, R.string.pref_key_site_screen, R.string.pref_key_site_delete_site_screen); |
| } |
| |
| private Preference getChangePref(int id) { |
| return WPPrefUtils.getPrefAndSetChangeListener(this, id, this); |
| } |
| |
| private Preference getClickPref(int id) { |
| return WPPrefUtils.getPrefAndSetClickListener(this, id, this); |
| } |
| |
| private void handleDeleteSiteError() { |
| AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); |
| builder.setTitle(R.string.error_deleting_site); |
| builder.setMessage(R.string.error_deleting_site_summary); |
| builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { |
| @Override |
| public void onClick(DialogInterface dialog, int which) { |
| dialog.dismiss(); |
| } |
| }); |
| builder.setPositiveButton(R.string.contact_support, new DialogInterface.OnClickListener() { |
| @Override |
| public void onClick(DialogInterface dialog, int which) { |
| HelpshiftHelper.getInstance().showConversation(getActivity(), HelpshiftHelper.Tag.ORIGIN_DELETE_SITE); |
| } |
| }); |
| builder.show(); |
| } |
| |
| private void exportSite() { |
| final Blog currentBlog = WordPress.getCurrentBlog(); |
| if (currentBlog.isDotcomFlag()) { |
| final ProgressDialog progressDialog = ProgressDialog.show(getActivity(), "", getActivity().getString(R.string.exporting_content_progress), true, true); |
| WordPress.getRestClientUtils().exportContentAll(currentBlog.getDotComBlogId(), new RestRequest.Listener() { |
| @Override |
| public void onResponse(JSONObject response) { |
| if (isAdded()) { |
| AnalyticsUtils.trackWithCurrentBlogDetails( |
| AnalyticsTracker.Stat.SITE_SETTINGS_EXPORT_SITE_RESPONSE_OK); |
| dismissProgressDialog(progressDialog); |
| Snackbar.make(getView(), R.string.export_email_sent, Snackbar.LENGTH_LONG).show(); |
| } |
| } |
| }, new RestRequest.ErrorListener() { |
| @Override |
| public void onErrorResponse(VolleyError error) { |
| if (isAdded()) { |
| HashMap<String, Object> errorProperty = new HashMap<>(); |
| errorProperty.put(ANALYTICS_ERROR_PROPERTY_KEY, error.getMessage()); |
| AnalyticsUtils.trackWithCurrentBlogDetails( |
| AnalyticsTracker.Stat.SITE_SETTINGS_EXPORT_SITE_RESPONSE_ERROR, errorProperty); |
| dismissProgressDialog(progressDialog); |
| } |
| } |
| }); |
| } |
| } |
| |
| private void deleteSite() { |
| final Blog currentBlog = WordPress.getCurrentBlog(); |
| if (currentBlog.isDotcomFlag()) { |
| final ProgressDialog progressDialog = ProgressDialog.show(getActivity(), "", getString(R.string.delete_site_progress), true, false); |
| AnalyticsUtils.trackWithCurrentBlogDetails( |
| AnalyticsTracker.Stat.SITE_SETTINGS_DELETE_SITE_REQUESTED); |
| WordPress.getRestClientUtils().deleteSite(currentBlog.getDotComBlogId(), new RestRequest.Listener() { |
| @Override |
| public void onResponse(JSONObject response) { |
| AnalyticsUtils.trackWithCurrentBlogDetails( |
| AnalyticsTracker.Stat.SITE_SETTINGS_DELETE_SITE_RESPONSE_OK); |
| progressDialog.dismiss(); |
| removeBlog(); |
| } |
| }, new RestRequest.ErrorListener() { |
| @Override |
| public void onErrorResponse(VolleyError error) { |
| HashMap<String, Object> errorProperty = new HashMap<>(); |
| errorProperty.put(ANALYTICS_ERROR_PROPERTY_KEY, error.getMessage()); |
| AnalyticsUtils.trackWithCurrentBlogDetails( |
| AnalyticsTracker.Stat.SITE_SETTINGS_DELETE_SITE_RESPONSE_ERROR, errorProperty); |
| dismissProgressDialog(progressDialog); |
| handleDeleteSiteError(); |
| } |
| }); |
| } |
| } |
| |
| private MultiSelectRecyclerViewAdapter getAdapter() { |
| if (mAdapter == null) { |
| mAdapter = new MultiSelectRecyclerViewAdapter(getActivity(), mEditingList); |
| } |
| |
| return mAdapter; |
| } |
| |
| private final class ActionModeCallback implements ActionMode.Callback { |
| @Override |
| public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) { |
| switch (menuItem.getItemId()) { |
| case R.id.menu_delete: |
| SparseBooleanArray checkedItems = getAdapter().getItemsSelected(); |
| |
| HashMap<String, Object> properties = new HashMap<>(); |
| properties.put("num_items_deleted", checkedItems.size()); |
| AnalyticsUtils.trackWithCurrentBlogDetails(AnalyticsTracker.Stat.SITE_SETTINGS_DELETED_LIST_ITEMS, properties); |
| |
| for (int i = checkedItems.size() - 1; i >= 0; i--) { |
| final int index = checkedItems.keyAt(i); |
| |
| if (checkedItems.get(index)) { |
| mEditingList.remove(index); |
| } |
| } |
| |
| mSiteSettings.saveSettings(); |
| mActionMode.finish(); |
| return true; |
| case R.id.menu_select_all: |
| for (int i = 0; i < getAdapter().getItemCount(); i++) { |
| getAdapter().setItemSelected(i); |
| } |
| |
| mActionMode.invalidate(); |
| return true; |
| default: |
| return false; |
| } |
| } |
| |
| @Override |
| public boolean onCreateActionMode(ActionMode actionMode, Menu menu) { |
| WPActivityUtils.setStatusBarColor(mDialog.getWindow(), R.color.action_mode_status_bar_tint); |
| mActionMode = actionMode; |
| MenuInflater inflater = actionMode.getMenuInflater(); |
| inflater.inflate(R.menu.list_editor, menu); |
| return true; |
| } |
| |
| @Override |
| public void onDestroyActionMode(ActionMode mode) { |
| WPActivityUtils.setStatusBarColor(mDialog.getWindow(), R.color.status_bar_tint); |
| getAdapter().removeItemsSelected(); |
| mActionMode = null; |
| } |
| |
| @Override |
| public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) { |
| actionMode.setTitle(getString( |
| R.string.site_settings_list_editor_action_mode_title, |
| getAdapter().getItemsSelected().size()) |
| ); |
| return true; |
| } |
| } |
| } |