diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Preferences.java b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Preferences.java index de4766d09..e5836e53a 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Preferences.java +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/models/user/Preferences.java @@ -11,7 +11,7 @@ public class Preferences extends RealmObject implements AvatarPreferences { @PrimaryKey private String userId; - public Hair hair; + private Hair hair; SuppressedModals suppressModals; User user; private boolean costume, toolbarCollapsed, advancedCollapsed, tagsCollapsed, newTaskEdit, disableClasses, stickyHeader, sleep, hideHeader, dailyDueDefaultView, automaticAllocation; diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/BasePreferencesFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/BasePreferencesFragment.kt index eabe1b180..1f7543b06 100644 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/BasePreferencesFragment.kt +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/BasePreferencesFragment.kt @@ -12,6 +12,7 @@ import com.habitrpg.android.habitica.helpers.RxErrorHandler import com.habitrpg.android.habitica.models.user.User import com.habitrpg.android.habitica.modules.AppModule import rx.functions.Action1 +import rx.subscriptions.CompositeSubscription import java.util.* import javax.inject.Inject import javax.inject.Named @@ -25,6 +26,8 @@ abstract class BasePreferencesFragment : PreferenceFragmentCompat() { internal open var user: User? = null + internal val compositeSubscription = CompositeSubscription() + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -35,6 +38,7 @@ abstract class BasePreferencesFragment : PreferenceFragmentCompat() { override fun onDestroy() { userRepository.close() + compositeSubscription.unsubscribe() super.onDestroy() } diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PreferencesFragment.java b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PreferencesFragment.java deleted file mode 100644 index 98f706884..000000000 --- a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PreferencesFragment.java +++ /dev/null @@ -1,279 +0,0 @@ -package com.habitrpg.android.habitica.ui.fragments.preferences; - -import android.app.ProgressDialog; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.Configuration; -import android.os.Build; -import android.os.Bundle; -import android.support.v7.app.AlertDialog; -import android.support.v7.preference.Preference; -import android.support.v7.preference.PreferenceScreen; - -import com.habitrpg.android.habitica.HabiticaApplication; -import com.habitrpg.android.habitica.HabiticaBaseApplication; -import com.habitrpg.android.habitica.R; -import com.habitrpg.android.habitica.data.InventoryRepository; -import com.habitrpg.android.habitica.data.UserRepository; -import com.habitrpg.android.habitica.helpers.LanguageHelper; -import com.habitrpg.android.habitica.helpers.RxErrorHandler; -import com.habitrpg.android.habitica.helpers.SoundManager; -import com.habitrpg.android.habitica.helpers.TaskAlarmManager; -import com.habitrpg.android.habitica.helpers.notifications.PushNotificationManager; -import com.habitrpg.android.habitica.models.user.User; -import com.habitrpg.android.habitica.prefs.TimePreference; -import com.habitrpg.android.habitica.ui.activities.ClassSelectionActivity; -import com.habitrpg.android.habitica.ui.activities.FixCharacterValuesActivity; -import com.habitrpg.android.habitica.ui.activities.MainActivity; - -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; - -import javax.inject.Inject; - -import rx.Subscription; - -import static com.habitrpg.android.habitica.ui.activities.MainActivity.SELECT_CLASS_RESULT; - -public class PreferencesFragment extends BasePreferencesFragment implements - SharedPreferences.OnSharedPreferenceChangeListener { - - @Inject - public InventoryRepository inventoryRepository; - @Inject - public SoundManager soundManager; - @Inject - UserRepository userRepository; - private Context context; - private TimePreference timePreference; - private PreferenceScreen pushNotificationsPreference; - private Preference classSelectionPreference; - private User user; - @Inject - PushNotificationManager pushNotificationManager; - private Subscription subscription; - - @Override - public void onCreate(Bundle savedInstanceState) { - HabiticaBaseApplication.getComponent().inject(this); - super.onCreate(savedInstanceState); - - context = getActivity(); - - String userID = getPreferenceManager().getSharedPreferences().getString(context.getString(R.string.SP_userID), null); - if (userID != null) { - subscription = userRepository.getUser(userID).subscribe(PreferencesFragment.this::setUser, RxErrorHandler.handleEmptyError()); - } - } - - @Override - public void onDestroy() { - userRepository.close(); - if (subscription != null) { - subscription.unsubscribe(); - } - super.onDestroy(); - } - - @Override - protected void setupPreferences() { - timePreference = (TimePreference) findPreference("reminder_time"); - boolean useReminder = getPreferenceManager().getSharedPreferences().getBoolean("use_reminder", false); - timePreference.setEnabled(useReminder); - - - pushNotificationsPreference = (PreferenceScreen) findPreference("pushNotifications"); - boolean userPushNotifications = getPreferenceManager().getSharedPreferences().getBoolean("usePushNotifications", true); - pushNotificationsPreference.setEnabled(userPushNotifications); - - - classSelectionPreference = findPreference("choose_class"); - classSelectionPreference.setVisible(false); - } - - @Override - public void onResume() { - super.onResume(); - getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this); - - } - - @Override - public void onPause() { - getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this); - super.onPause(); - } - - @Override - public boolean onPreferenceTreeClick(Preference preference) { - if (preference.getKey().equals("logout")) { - HabiticaApplication.logout(context); - getActivity().finish(); - } else if (preference.getKey().equals("choose_class")) { - Bundle bundle = new Bundle(); - bundle.putString("size", user.getPreferences().getSize()); - bundle.putString("skin", user.getPreferences().getSkin()); - bundle.putString("shirt", user.getPreferences().getShirt()); - bundle.putInt("hairBangs", user.getPreferences().getHair().getBangs()); - bundle.putInt("hairBase", user.getPreferences().getHair().getBase()); - bundle.putString("hairColor", user.getPreferences().getHair().getColor()); - bundle.putInt("hairMustache", user.getPreferences().getHair().getMustache()); - bundle.putInt("hairBeard", user.getPreferences().getHair().getBeard()); - if (!user.getFlags().getClassSelected()) { - bundle.putBoolean("isInitialSelection", true); - } else { - bundle.putBoolean("isInitialSelection", false); - } - - Intent intent = new Intent(getActivity(), ClassSelectionActivity.class); - intent.putExtras(bundle); - - if (user.getFlags().getClassSelected() && !user.getPreferences().getDisableClasses()) { - AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()) - .setMessage(getString(R.string.change_class_confirmation)) - .setNegativeButton(getString(R.string.dialog_go_back), (dialog, which) -> dialog.dismiss()) - .setPositiveButton(getString(R.string.change_class), (dialog, which) -> startActivityForResult(intent, MainActivity.SELECT_CLASS_RESULT)); - AlertDialog alert = builder.create(); - alert.show(); - } else { - startActivityForResult(intent, MainActivity.SELECT_CLASS_RESULT); - } - return true; - } else if (preference.getKey().equals("reload_content")) { - ProgressDialog dialog = ProgressDialog.show(context, context.getString(R.string.reloading_content), null, true); - inventoryRepository.retrieveContent(true).subscribe(contentResult -> { - if (dialog.isShowing()) { - dialog.dismiss(); - } - }, throwable -> { - if (dialog.isShowing()) { - dialog.dismiss(); - } - RxErrorHandler.reportError(throwable); - }); - } else if (preference.getKey().equals("fixCharacterValues")) { - Intent intent = new Intent(getActivity(), FixCharacterValuesActivity.class); - getActivity().startActivity(intent); - } - return super.onPreferenceTreeClick(preference); - } - - - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - switch (key) { - case "use_reminder": - boolean use_reminder = sharedPreferences.getBoolean(key, false); - timePreference.setEnabled(use_reminder); - if (use_reminder) { - TaskAlarmManager.scheduleDailyReminder(context); - } else { - TaskAlarmManager.removeDailyReminder(context); - } - break; - case "reminder_time": - TaskAlarmManager.removeDailyReminder(context); - TaskAlarmManager.scheduleDailyReminder(context); - break; - case "usePushNotifications": - boolean userPushNotifications = sharedPreferences.getBoolean(key, false); - pushNotificationsPreference.setEnabled(userPushNotifications); - if (userPushNotifications) { - pushNotificationManager.addPushDeviceUsingStoredToken(); - } else { - pushNotificationManager.removePushDeviceUsingStoredToken(); - } - break; - case "cds_time": - String timeval = sharedPreferences.getString("cds_time", "00:00"); - String[] pieces = timeval.split(":"); - int hour = Integer.parseInt(pieces[0]); - userRepository.changeCustomDayStart(hour).subscribe(user -> {}, RxErrorHandler.handleEmptyError()); - break; - case "language": { - LanguageHelper languageHelper = new LanguageHelper(sharedPreferences.getString(key, "en")); - - Locale.setDefault(languageHelper.getLocale()); - Configuration configuration = new Configuration(); - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) { - configuration.locale = languageHelper.getLocale(); - } else { - configuration.setLocale(languageHelper.getLocale()); - } - getActivity().getResources().updateConfiguration(configuration, getActivity().getResources().getDisplayMetrics()); - userRepository.updateLanguage(user, languageHelper.getLanguageCode()) - .flatMap(user1 -> inventoryRepository.retrieveContent(true)) - .subscribe(contentResult -> {}, RxErrorHandler.handleEmptyError()); - - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { - Intent intent = new Intent(getActivity(), MainActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - startActivity(intent); - } else { - Intent intent = new Intent(getActivity(), MainActivity.class); - this.startActivity(intent); - getActivity().finishAffinity(); - } - break; - } - case "audioTheme": { - String newAudioTheme = sharedPreferences.getString(key, "off"); - userRepository.updateUser(user, "preferences.sound", newAudioTheme) - .subscribe(habitRPGUser -> {}, RxErrorHandler.handleEmptyError()); - soundManager.setSoundTheme(newAudioTheme); - soundManager.preloadAllFiles(); - break; - } - case "dailyDueDefaultView": - userRepository.updateUser(user, "preferences.dailyDueDefaultView", sharedPreferences.getBoolean(key, false)) - .subscribe(habitRPGUser -> {}, RxErrorHandler.handleEmptyError()); - break; - } - } - - @Override - public void onDisplayPreferenceDialog(Preference preference) { - if (preference instanceof TimePreference) { - if (preference.getKey().equals("cds_time")) { - if (getFragmentManager().findFragmentByTag(DayStartPreferenceDialogFragment.TAG) == null) { - DayStartPreferenceDialogFragment.newInstance(this, preference.getKey()) - .show(getFragmentManager(), DayStartPreferenceDialogFragment.TAG); - } - } else { - if (getFragmentManager().findFragmentByTag(TimePreferenceDialogFragment.TAG) == null) { - TimePreferenceDialogFragment.newInstance(this, preference.getKey()) - .show(getFragmentManager(), TimePreferenceDialogFragment.TAG); - } - } - } else { - super.onDisplayPreferenceDialog(preference); - } - } - - public void setUser(User user) { - this.user = user; - if (user != null && user.getFlags() != null && user.getStats() != null) { - if (user.getStats().getLvl() >= 10) { - if (user.getFlags().getClassSelected()) { - if (user.getPreferences().getDisableClasses()) { - classSelectionPreference.setTitle(getString(R.string.enable_class)); - } else { - classSelectionPreference.setTitle(getString(R.string.change_class)); - classSelectionPreference.setSummary(getString(R.string.change_class_description)); - } - classSelectionPreference.setVisible(true); - } else { - classSelectionPreference.setTitle(getString(R.string.enable_class)); - classSelectionPreference.setVisible(true); - } - } - } - if (user != null && user.getPreferences() != null) { - TimePreference cdsTimePreference = (TimePreference) findPreference("cds_time"); - cdsTimePreference.setText(user.getPreferences().getDayStart() + ":00"); - findPreference("dailyDueDefaultView").setDefaultValue(user.getPreferences().getDailyDueDefaultView()); - } - } -} diff --git a/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PreferencesFragment.kt b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PreferencesFragment.kt new file mode 100644 index 000000000..f591c7fa0 --- /dev/null +++ b/Habitica/src/main/java/com/habitrpg/android/habitica/ui/fragments/preferences/PreferencesFragment.kt @@ -0,0 +1,245 @@ +package com.habitrpg.android.habitica.ui.fragments.preferences + +import android.app.ProgressDialog +import android.content.Intent +import android.content.SharedPreferences +import android.content.res.Configuration +import android.os.Build +import android.os.Bundle +import android.support.v7.app.AlertDialog +import android.support.v7.preference.Preference +import android.support.v7.preference.PreferenceScreen +import com.habitrpg.android.habitica.HabiticaApplication +import com.habitrpg.android.habitica.HabiticaBaseApplication +import com.habitrpg.android.habitica.R +import com.habitrpg.android.habitica.data.InventoryRepository +import com.habitrpg.android.habitica.helpers.LanguageHelper +import com.habitrpg.android.habitica.helpers.RxErrorHandler +import com.habitrpg.android.habitica.helpers.SoundManager +import com.habitrpg.android.habitica.helpers.TaskAlarmManager +import com.habitrpg.android.habitica.helpers.notifications.PushNotificationManager +import com.habitrpg.android.habitica.models.ContentResult +import com.habitrpg.android.habitica.models.user.User +import com.habitrpg.android.habitica.prefs.TimePreference +import com.habitrpg.android.habitica.ui.activities.ClassSelectionActivity +import com.habitrpg.android.habitica.ui.activities.FixCharacterValuesActivity +import com.habitrpg.android.habitica.ui.activities.MainActivity +import rx.functions.Action1 +import java.util.* +import javax.inject.Inject + +class PreferencesFragment : BasePreferencesFragment(), SharedPreferences.OnSharedPreferenceChangeListener { + + @Inject + lateinit var inventoryRepository: InventoryRepository + @Inject + lateinit var soundManager: SoundManager + @Inject + lateinit var pushNotificationManager: PushNotificationManager + + private var timePreference: TimePreference? = null + private var pushNotificationsPreference: PreferenceScreen? = null + private var classSelectionPreference: Preference? = null + + override fun onCreate(savedInstanceState: Bundle?) { + HabiticaBaseApplication.getComponent().inject(this) + super.onCreate(savedInstanceState) + + val userID = preferenceManager.sharedPreferences.getString(context?.getString(R.string.SP_userID), null) + if (userID != null) { + compositeSubscription.add(userRepository.getUser(userID).subscribe(Action1 { this@PreferencesFragment.setUser(it) }, RxErrorHandler.handleEmptyError())) + } + } + + override fun setupPreferences() { + timePreference = findPreference("reminder_time") as TimePreference + val useReminder = preferenceManager.sharedPreferences.getBoolean("use_reminder", false) + timePreference?.isEnabled = useReminder + + + pushNotificationsPreference = findPreference("pushNotifications") as PreferenceScreen + val userPushNotifications = preferenceManager.sharedPreferences.getBoolean("usePushNotifications", true) + pushNotificationsPreference?.isEnabled = userPushNotifications + + + classSelectionPreference = findPreference("choose_class") + classSelectionPreference?.isVisible = false + } + + override fun onResume() { + super.onResume() + preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(this) + + } + + override fun onPause() { + preferenceManager.sharedPreferences.unregisterOnSharedPreferenceChangeListener(this) + super.onPause() + } + + override fun onPreferenceTreeClick(preference: Preference): Boolean { + when(preference.key) { + "logout" -> { + HabiticaApplication.logout(context) + activity?.finish() + } + "choose_class" -> { + val bundle = Bundle() + bundle.putString("size", user?.preferences?.size) + bundle.putString("skin", user?.preferences?.skin) + bundle.putString("shirt", user?.preferences?.shirt) + bundle.putInt("hairBangs", user?.preferences?.hair?.bangs ?: 0) + bundle.putInt("hairBase", user?.preferences?.hair?.base ?: 0) + bundle.putString("hairColor", user?.preferences?.hair?.color) + bundle.putInt("hairMustache", user?.preferences?.hair?.mustache ?: 0) + bundle.putInt("hairBeard", user?.preferences?.hair?.beard ?: 0) + bundle.putBoolean("isInitialSelection", user?.flags?.classSelected == false) + + val intent = Intent(activity, ClassSelectionActivity::class.java) + intent.putExtras(bundle) + + if (user?.flags?.classSelected == true && user?.preferences?.disableClasses == false) { + val context = context + if (context != null) { + val builder = AlertDialog.Builder(context) + .setMessage(getString(R.string.change_class_confirmation)) + .setNegativeButton(getString(R.string.dialog_go_back)) { dialog, _ -> dialog.dismiss() } + .setPositiveButton(getString(R.string.change_class)) { _, _ -> startActivityForResult(intent, MainActivity.SELECT_CLASS_RESULT) } + val alert = builder.create() + alert.show() + } + } else { + startActivityForResult(intent, MainActivity.SELECT_CLASS_RESULT) + } + return true + } + "reload_content" -> { + val dialog = ProgressDialog.show(context, context?.getString(R.string.reloading_content), null, true) + inventoryRepository.retrieveContent(true).subscribe({ + if (dialog.isShowing) { + dialog.dismiss() + } + }) { throwable -> + if (dialog.isShowing) { + dialog.dismiss() + } + RxErrorHandler.reportError(throwable) + } + } + "fixCharacterValues" -> { + val intent = Intent(activity, FixCharacterValuesActivity::class.java) + activity?.startActivity(intent) + } + } + return super.onPreferenceTreeClick(preference) + } + + + override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { + when (key) { + "use_reminder" -> { + val useReminder = sharedPreferences.getBoolean(key, false) + timePreference?.isEnabled = useReminder + if (useReminder) { + TaskAlarmManager.scheduleDailyReminder(context) + } else { + TaskAlarmManager.removeDailyReminder(context) + } + } + "reminder_time" -> { + TaskAlarmManager.removeDailyReminder(context) + TaskAlarmManager.scheduleDailyReminder(context) + } + "usePushNotifications" -> { + val userPushNotifications = sharedPreferences.getBoolean(key, false) + pushNotificationsPreference?.isEnabled = userPushNotifications + if (userPushNotifications) { + pushNotificationManager.addPushDeviceUsingStoredToken() + } else { + pushNotificationManager.removePushDeviceUsingStoredToken() + } + } + "cds_time" -> { + val timeval = sharedPreferences.getString("cds_time", "00:00") + val pieces = timeval?.split(":".toRegex())?.dropLastWhile { it.isEmpty() }?.toTypedArray() + if (pieces != null) { + val hour = Integer.parseInt(pieces[0]) + userRepository.changeCustomDayStart(hour).subscribe(Action1 { }, RxErrorHandler.handleEmptyError()) + } + } + "language" -> { + val languageHelper = LanguageHelper(sharedPreferences.getString(key, "en")) + + Locale.setDefault(languageHelper.locale) + val configuration = Configuration() + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) { + configuration.locale = languageHelper.locale + } else { + configuration.setLocale(languageHelper.locale) + } + activity?.resources?.updateConfiguration(configuration, activity?.resources?.displayMetrics) + userRepository.updateLanguage(user, languageHelper.languageCode) + .flatMap { inventoryRepository.retrieveContent(true) } + .subscribe(Action1 { }, RxErrorHandler.handleEmptyError()) + + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { + val intent = Intent(activity, MainActivity::class.java) + intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP + startActivity(intent) + } else { + val intent = Intent(activity, MainActivity::class.java) + this.startActivity(intent) + activity?.finishAffinity() + } + } + "audioTheme" -> { + val newAudioTheme = sharedPreferences.getString(key, "off") + userRepository.updateUser(user, "preferences.sound", newAudioTheme) + .subscribe(Action1 { }, RxErrorHandler.handleEmptyError()) + soundManager.setSoundTheme(newAudioTheme) + soundManager.preloadAllFiles() + } + "dailyDueDefaultView" -> userRepository.updateUser(user, "preferences.dailyDueDefaultView", sharedPreferences.getBoolean(key, false)) + .subscribe(Action1 { }, RxErrorHandler.handleEmptyError()) + } + } + + override fun onDisplayPreferenceDialog(preference: Preference) { + if (preference is TimePreference) { + if (preference.getKey() == "cds_time") { + if (fragmentManager?.findFragmentByTag(DayStartPreferenceDialogFragment.TAG) == null) { + DayStartPreferenceDialogFragment.newInstance(this, preference.getKey()) + .show(fragmentManager, DayStartPreferenceDialogFragment.TAG) + } + } else { + if (fragmentManager?.findFragmentByTag(TimePreferenceDialogFragment.TAG) == null) { + TimePreferenceDialogFragment.newInstance(this, preference.getKey()) + .show(fragmentManager, TimePreferenceDialogFragment.TAG) + } + } + } else { + super.onDisplayPreferenceDialog(preference) + } + } + + fun setUser(user: User?) { + this.user = user + if (10 <= user?.stats?.getLvl() ?: 0) { + if (user?.flags?.classSelected == true) { + if (user.preferences.disableClasses) { + classSelectionPreference?.title = getString(R.string.enable_class) + } else { + classSelectionPreference?.title = getString(R.string.change_class) + classSelectionPreference?.summary = getString(R.string.change_class_description) + } + classSelectionPreference?.isVisible = true + } else { + classSelectionPreference?.title = getString(R.string.enable_class) + classSelectionPreference?.isVisible = true + } + } + val cdsTimePreference = findPreference("cds_time") as TimePreference + cdsTimePreference.text = user?.preferences?.dayStart.toString() + ":00" + findPreference("dailyDueDefaultView").setDefaultValue(user?.preferences?.dailyDueDefaultView) + } +}