/**
* Wire
* Copyright (C) 2016 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.waz.zclient.pages.main.profile.preferences;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v7.preference.Preference;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import com.waz.zclient.BaseActivity;
import com.waz.zclient.R;
import com.waz.zclient.controllers.accentcolor.AccentColorObserver;
import com.waz.zclient.controllers.tracking.events.profile.ResetPassword;
import com.waz.zclient.controllers.tracking.events.profile.SignOut;
import com.waz.zclient.core.controllers.tracking.events.session.LoggedOutEvent;
import com.waz.zclient.core.controllers.tracking.events.settings.EditedUsernameEvent;
import com.waz.zclient.core.stores.profile.ProfileStoreObserver;
import com.waz.zclient.pages.BasePreferenceFragment;
import com.waz.zclient.pages.main.profile.ZetaPreferencesActivity;
import com.waz.zclient.pages.main.profile.camera.CameraContext;
import com.waz.zclient.pages.main.profile.preferences.dialogs.AccentColorPreferenceDialogFragment;
import com.waz.zclient.pages.main.profile.preferences.dialogs.AddEmailAndPasswordPreferenceDialogFragment;
import com.waz.zclient.pages.main.profile.preferences.dialogs.AddPhoneNumberPreferenceDialogFragment;
import com.waz.zclient.pages.main.profile.preferences.dialogs.ChangeEmailPreferenceDialogFragment;
import com.waz.zclient.pages.main.profile.preferences.dialogs.ChangeUsernamePreferenceDialogFragment;
import com.waz.zclient.pages.main.profile.preferences.dialogs.VerifyEmailPreferenceFragment;
import com.waz.zclient.pages.main.profile.preferences.dialogs.VerifyPhoneNumberPreferenceFragment;
import com.waz.zclient.tracking.GlobalTrackingController;
import com.waz.zclient.ui.utils.TextViewUtils;
import com.waz.zclient.utils.StringUtils;
import com.waz.zclient.utils.ViewUtils;
import net.xpece.android.support.preference.EditTextPreference;
public class AccountPreferences extends BasePreferenceFragment<AccountPreferences.Container> implements ProfileStoreObserver,
SharedPreferences.OnSharedPreferenceChangeListener,
VerifyPhoneNumberPreferenceFragment.Container,
VerifyEmailPreferenceFragment.Container,
AddEmailAndPasswordPreferenceDialogFragment.Container,
ChangeEmailPreferenceDialogFragment.Container,
AddPhoneNumberPreferenceDialogFragment.Container,
ChangeUsernamePreferenceDialogFragment.Container,
AccentColorObserver {
public static final String TAG = AccountPreferences.class.getName();
private EditTextPreference namePreference;
private Preference usernamePreference;
private Preference phonePreference;
private Preference emailPreference;
private Preference signOutPreference;
private Preference deletePreference;
private Preference resetPasswordPreference;
private PicturePreference picturePreference;
private ColorPreference colorPreference;
public static AccountPreferences newInstance(String rootKey, Bundle extras) {
AccountPreferences f = new AccountPreferences();
Bundle args = new Bundle(extras);
args.putString(ARG_PREFERENCE_ROOT, rootKey);
f.setArguments(args);
return f;
}
@Override
public void onCreatePreferences2(Bundle savedInstanceState, String rootKey) {
super.onCreatePreferences2(savedInstanceState, rootKey);
addPreferencesFromResource(R.xml.preferences_account);
boolean shouldShowUsernameEdit = getArguments().getBoolean(ZetaPreferencesActivity.SHOW_USERNAME_EDIT);
namePreference = (EditTextPreference) findPreference(getString(R.string.pref_account_name_key));
namePreference.setOnEditTextCreatedListener(new EditTextPreference.OnEditTextCreatedListener() {
@Override
public void onEditTextCreated(final EditText edit) {
//Having it directly on the xml doesn't seem to work for EditTextPreference
edit.setSingleLine(true);
edit.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean b) {
edit.setSelection(edit.getText().length());
}
});
}
});
namePreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final String newName = ((String) newValue).trim();
if (TextUtils.getTrimmedLength(newName) < getResources().getInteger(R.integer.account_preferences__min_name_length)) {
ViewUtils.showAlertDialog(getActivity(),
null,
getString(R.string.pref_account_edit_name_empty_warning),
getString(R.string.pref_account_edit_name_empty_verify),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
},
false);
return false;
}
getStoreFactory().getProfileStore().setMyName(newName);
return false;
}
});
usernamePreference = findPreference(getString(R.string.pref_account_username_key));
usernamePreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
if (getStoreFactory() == null || getStoreFactory().isTornDown() || getStoreFactory().getProfileStore().getSelfUser() == null) {
return false;
}
String username = getStoreFactory().getProfileStore().getSelfUser().getUsername();
changeUsername(username, true);
return true;
}
});
phonePreference = findPreference(getString(R.string.pref_account_phone_key));
phonePreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
final CharSequence phoneNumber = preference.getTitle();
if (TextUtils.isEmpty(phoneNumber) || phoneNumber.equals(getString(R.string.pref_account_add_phone_title))) {
addPhoneNumber();
} else {
changePhoneNumber(String.valueOf(phoneNumber));
}
return true;
}
});
emailPreference = findPreference(getString(R.string.pref_account_email_key));
emailPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
final CharSequence email = preference.getTitle();
if (TextUtils.isEmpty(email) || email.equals(getString(R.string.pref_account_add_email_title))) {
addEmailAndPassword();
} else {
changeEmail(String.valueOf(email));
}
return true;
}
});
resetPasswordPreference = findPreference(getString(R.string.pref_account_password_key));
signOutPreference = findPreference(getString(R.string.pref_account_sign_out_key));
signOutPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
signOut();
return true;
}
});
deletePreference = findPreference(getString(R.string.pref_account_delete_key));
deletePreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
deleteAccount();
return true;
}
});
resetPasswordPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
((BaseActivity) getActivity()).injectJava(GlobalTrackingController.class).tagEvent(new ResetPassword(ResetPassword.Location.FROM_PROFILE));
return false;
}
});
picturePreference = (PicturePreference) findPreference(getString(R.string.pref_account_picture_key));
picturePreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
getControllerFactory().getCameraController().openCamera(CameraContext.SETTINGS);
return true;
}
});
colorPreference = (ColorPreference) findPreference(getString(R.string.pref_account_color_key));
colorPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
getChildFragmentManager().beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.add(AccentColorPreferenceDialogFragment.newInstance(getStoreFactory().getProfileStore().getAccentColor()),
AccentColorPreferenceDialogFragment.TAG)
.addToBackStack(AccentColorPreferenceDialogFragment.TAG)
.commit();
return true;
}
});
if (shouldShowUsernameEdit) {
changeUsername(getControllerFactory().getUsernameController().getGeneratedUsername(), false);
}
}
@Override
public void onStart() {
super.onStart();
getControllerFactory().getAccentColorController().addAccentColorObserver(this);
getStoreFactory().getProfileStore().addProfileStoreAndUpdateObserver(this);
}
@Override
public void onStop() {
getControllerFactory().getAccentColorController().removeAccentColorObserver(this);
getStoreFactory().getProfileStore().removeProfileStoreObserver(this);
super.onStop();
}
@Override
public void onDestroyView() {
if (namePreference != null) {
namePreference.setOnPreferenceChangeListener(null);
namePreference = null;
}
phonePreference = null;
emailPreference = null;
if (signOutPreference != null) {
signOutPreference.setOnPreferenceClickListener(null);
signOutPreference = null;
}
if (resetPasswordPreference != null) {
resetPasswordPreference.setOnPreferenceClickListener(null);
resetPasswordPreference = null;
}
super.onDestroyView();
}
@Override
public void onAccentColorChangedRemotely(Object sender, int color) {
}
@Override
public void onMyNameHasChanged(Object sender, String myName) {
if (namePreference == null) {
return;
}
namePreference.setTitle(myName);
namePreference.setText(myName);
namePreference.setSummary(getString(R.string.pref_account_name_title));
}
@Override
public void onMyEmailHasChanged(String myEmail, boolean isVerified) {
if (emailPreference == null) {
return;
}
if (TextUtils.isEmpty(myEmail)) {
emailPreference.setTitle(R.string.pref_account_add_email_title);
emailPreference.setSummary("");
} else {
if (isVerified) {
getChildFragmentManager().popBackStack(VerifyEmailPreferenceFragment.TAG,
FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
emailPreference.setTitle(myEmail);
emailPreference.setSummary(R.string.pref_account_email_title);
}
}
@Override
public void onMyPhoneHasChanged(String myPhone, boolean isVerified) {
if (phonePreference == null) {
return;
}
if (TextUtils.isEmpty(myPhone)) {
phonePreference.setTitle(R.string.pref_account_add_phone_title);
phonePreference.setSummary("");
} else {
phonePreference.setTitle(myPhone);
phonePreference.setSummary(R.string.pref_account_phone_title);
}
}
@Override
public void onPhoneUpdateFailed(String myPhone, int errorCode, String message, String label) {}
@Override
public void onMyEmailAndPasswordHasChanged(String myEmail) {
onMyEmailHasChanged(myEmail, getStoreFactory().getProfileStore().isEmailVerified());
}
@Override
public void onVerifyEmail(String email) {
getChildFragmentManager().popBackStack(AddEmailAndPasswordPreferenceDialogFragment.TAG,
FragmentManager.POP_BACK_STACK_INCLUSIVE);
getChildFragmentManager().popBackStack(ChangeEmailPreferenceDialogFragment.TAG,
FragmentManager.POP_BACK_STACK_INCLUSIVE);
verifyEmail(email);
}
@Override
public void onEmailCleared() {
getChildFragmentManager().popBackStack(ChangeEmailPreferenceDialogFragment.TAG,
FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
@Override
public void onVerifyPhone(String phoneNumber) {
getChildFragmentManager().popBackStack(AddPhoneNumberPreferenceDialogFragment.TAG,
FragmentManager.POP_BACK_STACK_INCLUSIVE);
verifyPhoneNumber(phoneNumber);
}
@Override
public void onPhoneNumberCleared() {
getChildFragmentManager().popBackStack(AddPhoneNumberPreferenceDialogFragment.TAG,
FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
private void signOut() {
ViewUtils.showAlertDialog(getActivity(),
null,
getString(R.string.pref_account_sign_out_warning_message),
getString(R.string.pref_account_sign_out_warning_verify),
getString(R.string.pref_account_sign_out_warning_cancel),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO: Remove old SignOut event https://wearezeta.atlassian.net/browse/AN-4232
((BaseActivity) getActivity()).injectJava(GlobalTrackingController.class).tagEvent(new SignOut());
((BaseActivity) getActivity()).injectJava(GlobalTrackingController.class).tagEvent(new LoggedOutEvent());
getControllerFactory().getUsernameController().logout();
getStoreFactory().getZMessagingApiStore().logout();
}
},
null);
}
private void deleteAccount() {
final String email = (String) emailPreference.getTitle();
final String phone = (String) phonePreference.getTitle();
final String message;
if (getString(R.string.pref_account_add_email_title).equals(email)) {
message = getString(R.string.pref_account_delete_warning_message_sms, phone);
} else {
message = getString(R.string.pref_account_delete_warning_message_email, email);
}
ViewUtils.showAlertDialog(getActivity(),
getString(R.string.pref_account_delete_warning_title),
TextViewUtils.getBoldText(getActivity(), message),
getString(R.string.pref_account_delete_warning_verify),
getString(R.string.pref_account_delete_warning_cancel),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
getStoreFactory().getZMessagingApiStore().delete();
}
},
null);
}
private void verifyPhoneNumber(String phoneNumber) {
getChildFragmentManager().beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.add(VerifyPhoneNumberPreferenceFragment.newInstance(phoneNumber),
VerifyPhoneNumberPreferenceFragment.TAG)
.addToBackStack(VerifyPhoneNumberPreferenceFragment.TAG)
.commit();
}
private void verifyEmail(String email) {
getChildFragmentManager().beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.add(VerifyEmailPreferenceFragment.newInstance(email),
VerifyEmailPreferenceFragment.TAG)
.addToBackStack(VerifyEmailPreferenceFragment.TAG)
.commit();
}
private void addPhoneNumber() {
getChildFragmentManager().beginTransaction()
.add(AddPhoneNumberPreferenceDialogFragment.newInstance(),
AddPhoneNumberPreferenceDialogFragment.TAG)
.addToBackStack(AddPhoneNumberPreferenceDialogFragment.TAG)
.commit();
}
@Override
public void changePhoneNumber(String phoneNumber) {
getChildFragmentManager().beginTransaction()
.add(AddPhoneNumberPreferenceDialogFragment.newInstance(phoneNumber),
AddPhoneNumberPreferenceDialogFragment.TAG)
.addToBackStack(AddPhoneNumberPreferenceDialogFragment.TAG)
.commit();
}
@Override
public void changeEmail(String email) {
getChildFragmentManager().beginTransaction()
.add(ChangeEmailPreferenceDialogFragment.newInstance(email),
ChangeEmailPreferenceDialogFragment.TAG)
.addToBackStack(ChangeEmailPreferenceDialogFragment.TAG)
.commit();
}
private void addEmailAndPassword() {
getChildFragmentManager().beginTransaction()
.add(AddEmailAndPasswordPreferenceDialogFragment.newInstance(),
AddEmailAndPasswordPreferenceDialogFragment.TAG)
.addToBackStack(AddEmailAndPasswordPreferenceDialogFragment.TAG)
.commit();
}
private void changeUsername(String currentUsername, boolean cancellable) {
((BaseActivity) getActivity()).injectJava(GlobalTrackingController.class).tagEvent(new EditedUsernameEvent());
getChildFragmentManager().beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.add(ChangeUsernamePreferenceDialogFragment.newInstance(currentUsername, cancellable),
ChangeUsernamePreferenceDialogFragment.TAG)
.addToBackStack(ChangeUsernamePreferenceDialogFragment.TAG)
.commit();
}
@Override
public void onAccentColorHasChanged(Object sender, int color) {
colorPreference.setAccentColor(color);
}
@Override
public void onMyUsernameHasChanged(String myUsername) {
if (usernamePreference == null) {
return;
}
if (TextUtils.isEmpty(myUsername)) {
usernamePreference.setTitle(getString(R.string.pref_account_username_empty_title));
usernamePreference.setSummary("");
} else {
usernamePreference.setTitle(StringUtils.formatHandle(myUsername));
usernamePreference.setSummary(getString(R.string.pref_account_username_title));
}
}
@Override
public void onUsernameChanged(String username) {
onMyUsernameHasChanged(username);
}
public interface Container {
}
}