add resetting and deleting an account

This commit is contained in:
Phillip Thelen 2017-08-25 01:11:44 +02:00
parent 3048e5ca5b
commit cc08fa3b14
8 changed files with 116 additions and 2 deletions

View file

@ -644,4 +644,14 @@
<string name="per_abbrv">Per:</string>
<string name="int_abbrv">Int:</string>
<string name="con_abbrv">Con:</string>
<string name="reset_account">Reset Account</string>
<string name="reset_account_description">WARNING! This resets many parts of your account. This is highly discouraged, but some people find it useful in the beginning after playing with the site for a short time.\n\nYou will lose all your levels, gold, and experience points. All your tasks (except those from challenges) will be deleted permanently and you will lose all of their historical data. You will lose all your equipment but you will be able to buy it all back, including all limited edition equipment or subscriber Mystery items that you already own (you will need to be in the correct class to re-buy class-specific gear). You will keep your current class and your pets and mounts. You might prefer to use an Orb of Rebirth instead, which is a much safer option and which will preserve your tasks and equipment.</string>
<string name="delete_account">Delete Account</string>
<string name="delete_account_description">Are you sure? This will delete your account forever, and it can never be restored! You will need to register a new account to use Habitica again. Banked or spent Gems will not be refunded. If you\'re absolutely certain, type your password into the text box below.</string>
<string name="reset_account_confirmation">reset my account</string>
<string name="delete_account_confirmation">delete my account</string>
<string name="danger_zone">Danger Zone</string>
<string name="nevermind">Nevermind</string>
<string name="resetting_account">Resetting Account</string>
<string name="deleting_account">Deleting Account</string>
</resources>

View file

@ -60,7 +60,12 @@
android:persistent="false"
android:shouldDisableView="false"/>
</PreferenceCategory>
<PreferenceCategory android:title="@string/danger_zone">
<Preference android:title="@string/reset_account"
android:key="reset_account" />
<Preference android:title="@string/delete_account"
android:key="delete_account" />
</PreferenceCategory>
</PreferenceScreen>
<Preference

View file

@ -37,6 +37,7 @@ import java.util.Map;
import retrofit2.http.Body;
import retrofit2.http.DELETE;
import retrofit2.http.GET;
import retrofit2.http.HTTP;
import retrofit2.http.Header;
import retrofit2.http.POST;
import retrofit2.http.PUT;
@ -325,4 +326,10 @@ public interface ApiService {
@POST("cron")
Observable<HabitResponse<Void>> runCron();
@POST("user/reset")
Observable<HabitResponse<Void>> resetAccount();
@HTTP(method = "DELETE", path = "user", hasBody = true)
Observable<HabitResponse<Void>> deleteAccount(@Body Map<String, String> body);
}

View file

@ -234,5 +234,6 @@ public interface ApiClient {
Observable<Void> runCron();
Observable<Void> resetAccount();
Observable<Void> deleteAccount(String password);
}

View file

@ -57,4 +57,7 @@ public interface UserRepository extends BaseRepository {
Observable<User> changeCustomDayStart(int dayStartTime);
Observable<User> updateLanguage(User user, String languageCode);
Observable<User> resetAccount();
Observable<Void> deleteAccount(String password);
}

View file

@ -104,6 +104,7 @@ import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -857,4 +858,16 @@ public class ApiClientImpl implements Action1<Throwable>, ApiClient {
public Observable<Void> runCron() {
return apiService.runCron().compose(configureApiCallObserver());
}
@Override
public Observable<Void> resetAccount() {
return apiService.resetAccount().compose(configureApiCallObserver());
}
@Override
public Observable<Void> deleteAccount(String password) {
Map<String, String> updateObject = new HashMap<>();
updateObject.put("password", password);
return apiService.deleteAccount(updateObject).compose(configureApiCallObserver());
}
}

View file

@ -233,6 +233,17 @@ public class UserRepositoryImpl extends BaseRepositoryImpl<UserLocalRepository>
.doOnNext(user1 -> apiClient.setLanguageCode(languageCode));
}
@Override
public Observable<User> resetAccount() {
return apiClient.resetAccount()
.flatMap(aVoid -> retrieveUser(true, true));
}
@Override
public Observable<Void> deleteAccount(String password) {
return apiClient.deleteAccount(password);
}
@Override
public void runCron(List<Task> tasks) {
Observable<List<TaskScoringResult>> observable;

View file

@ -1,13 +1,19 @@
package com.habitrpg.android.habitica.ui.fragments.preferences;
import android.app.ProgressDialog;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.preference.Preference;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.habitrpg.android.habitica.HabiticaApplication;
import com.habitrpg.android.habitica.HabiticaBaseApplication;
import com.habitrpg.android.habitica.R;
import com.habitrpg.android.habitica.data.UserRepository;
@ -16,6 +22,7 @@ import com.habitrpg.android.habitica.helpers.QrCodeManager;
import com.habitrpg.android.habitica.helpers.RxErrorHandler;
import com.habitrpg.android.habitica.models.user.User;
import com.habitrpg.android.habitica.models.user.SubscriptionPlan;
import com.habitrpg.android.habitica.ui.activities.MainActivity;
import com.habitrpg.android.habitica.ui.views.subscriptions.SubscriptionDetailsView;
import org.greenrobot.eventbus.EventBus;
@ -86,6 +93,10 @@ public class AccountDetailsFragment extends BasePreferencesFragment {
}
}
EventBus.getDefault().post(new OpenGemPurchaseFragmentCommand());
} else if ("reset_account".equals(preference.getKey())) {
showAccountResetConfirmation();
} else if ("delete_account".equals(preference.getKey())) {
showAccountDeleteConfirmation();
} else {
ClipboardManager clipMan = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
clipMan.setPrimaryClip(ClipData.newPlainText(preference.getKey(), preference.getSummary()));
@ -94,6 +105,59 @@ public class AccountDetailsFragment extends BasePreferencesFragment {
return super.onPreferenceTreeClick(preference);
}
private void showAccountDeleteConfirmation() {
final EditText input = new EditText(getContext());
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
input.setLayoutParams(lp);
AlertDialog dialog = new AlertDialog.Builder(getContext())
.setTitle(R.string.delete_account)
.setMessage(R.string.delete_account_description)
.setPositiveButton(R.string.delete_account_confirmation, ((thisDialog, which) -> {
thisDialog.dismiss();
deleteAccount(input.getText().toString());
}))
.setNegativeButton(R.string.nevermind, ((thisDialog, which) -> thisDialog.dismiss()))
.create();
dialog.setOnShowListener(arg0 -> dialog.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(ContextCompat.getColor(getContext(), R.color.worse_10)));
dialog.setView(input);
dialog.show();
}
private void deleteAccount(String password) {
ProgressDialog dialog = ProgressDialog.show(getContext(), getContext().getString(R.string.deleting_account), null, true);
userRepository.deleteAccount(password).subscribe(user -> {
HabiticaApplication.logout(getContext());
getActivity().finish();
}, throwable -> {
dialog.dismiss();
RxErrorHandler.reportError(throwable);
});
}
private void showAccountResetConfirmation() {
AlertDialog dialog = new AlertDialog.Builder(getContext())
.setTitle(R.string.reset_account)
.setMessage(R.string.reset_account_description)
.setPositiveButton(R.string.reset_account_confirmation, ((thisDialog, which) -> {
thisDialog.dismiss();
resetAccount();
}))
.setNegativeButton(R.string.nevermind, ((thisDialog, which) -> thisDialog.dismiss()))
.create();
dialog.setOnShowListener(arg0 -> dialog.getButton(DialogInterface.BUTTON_POSITIVE).setTextColor(ContextCompat.getColor(getContext(), R.color.worse_10)));
dialog.show();
}
private void resetAccount() {
ProgressDialog dialog = ProgressDialog.show(getContext(), getContext().getString(R.string.resetting_account), null, true);
userRepository.resetAccount().subscribe(user -> dialog.dismiss(), throwable -> {
dialog.dismiss();
RxErrorHandler.reportError(throwable);
});
}
private void showSubscriptionStatusDialog() {
SubscriptionDetailsView view = new SubscriptionDetailsView(getContext());
view.setPlan(user.getPurchased().getPlan());