package com.kickstarter.ui.activities; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v7.app.AlertDialog; import android.support.v7.widget.SwitchCompat; import android.text.TextUtils; import android.widget.TextView; import com.jakewharton.rxbinding.view.RxView; import com.kickstarter.KSApplication; import com.kickstarter.R; import com.kickstarter.libs.BaseActivity; import com.kickstarter.libs.Build; import com.kickstarter.libs.CurrentUserType; import com.kickstarter.libs.KSString; import com.kickstarter.libs.Logout; import com.kickstarter.libs.qualifiers.RequiresActivityViewModel; import com.kickstarter.libs.utils.ApplicationUtils; import com.kickstarter.libs.utils.SwitchCompatUtils; import com.kickstarter.libs.utils.ViewUtils; import com.kickstarter.models.User; import com.kickstarter.ui.data.Newsletter; import com.kickstarter.ui.views.IconTextView; import com.kickstarter.viewmodels.SettingsViewModel; import java.util.Arrays; import java.util.List; import javax.inject.Inject; import butterknife.Bind; import butterknife.BindColor; import butterknife.BindString; import butterknife.ButterKnife; import butterknife.OnClick; import rx.android.schedulers.AndroidSchedulers; import static com.kickstarter.libs.utils.BooleanUtils.isTrue; import static com.kickstarter.libs.utils.IntegerUtils.intValueOrZero; @RequiresActivityViewModel(SettingsViewModel.class) public final class SettingsActivity extends BaseActivity<SettingsViewModel> { protected @Bind(R.id.games_switch) SwitchCompat gamesNewsletterSwitch; protected @Bind(R.id.happening_now_switch) SwitchCompat happeningNewsletterSwitch; protected @Bind(R.id.friend_activity_mail_icon) IconTextView friendActivityMailIconTextView; protected @Bind(R.id.friend_activity_phone_icon) IconTextView friendActivityPhoneIconTextView; protected @Bind(R.id.new_followers_mail_icon) IconTextView newFollowersMailIconTextView; protected @Bind(R.id.new_followers_phone_icon) IconTextView newFollowersPhoneIconTextView; protected @Bind(R.id.project_notifications_count) TextView projectNotificationsCountTextView; protected @Bind(R.id.project_updates_mail_icon) IconTextView projectUpdatesMailIconTextView; protected @Bind(R.id.project_updates_phone_icon) IconTextView projectUpdatesPhoneIconTextView; protected @Bind(R.id.kickstarter_news_and_events_switch) SwitchCompat promoNewsletterSwitch; protected @Bind(R.id.projects_we_love_switch) SwitchCompat weeklyNewsletterSwitch; protected @BindColor(R.color.green) int green; protected @BindColor(R.color.gray) int gray; protected @BindString(R.string.profile_settings_newsletter_games) String gamesNewsletterString; protected @BindString(R.string.profile_settings_newsletter_happening) String happeningNewsletterString; protected @BindString(R.string.mailto) String mailtoString; protected @BindString(R.string.Logged_Out) String loggedOutString; protected @BindString(R.string.profile_settings_newsletter_weekly) String weeklyNewsletterString; protected @BindString(R.string.profile_settings_newsletter_promo) String promoNewsletterString; protected @BindString(R.string.profile_settings_newsletter_opt_in_message) String optInMessageString; protected @BindString(R.string.profile_settings_newsletter_opt_in_title) String optInTitleString; protected @BindString(R.string.profile_settings_accessibility_subscribe_mobile_notifications) String subscribeMobileString; protected @BindString(R.string.profile_settings_accessibility_subscribe_notifications) String subscribeString; protected @BindString(R.string.support_email_body) String supportEmailBodyString; protected @BindString(R.string.support_email_subject) String supportEmailSubjectString; protected @BindString(R.string.support_email_to_android) String supportEmailString; protected @BindString(R.string.profile_settings_error) String unableToSaveString; protected @BindString(R.string.profile_settings_accessibility_unsubscribe_mobile_notifications) String unsubscribeMobileString; protected @BindString(R.string.profile_settings_accessibility_unsubscribe_notifications) String unsubscribeString; @Inject CurrentUserType currentUser; @Inject KSString ksString; @Inject Logout logout; @Inject Build build; private boolean notifyMobileOfFollower; private boolean notifyMobileOfFriendActivity; private boolean notifyMobileOfUpdates; private boolean notifyOfFollower; private boolean notifyOfFriendActivity; private boolean notifyOfUpdates; private AlertDialog logoutConfirmationDialog; @Override protected void onCreate(final @Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.settings_layout); ButterKnife.bind(this); ((KSApplication) getApplication()).component().inject(this); viewModel.outputs.user() .compose(bindToLifecycle()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(this::displayPreferences); viewModel.outputs.showOptInPrompt() .compose(bindToLifecycle()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(this::showOptInPrompt); viewModel.errors.unableToSavePreferenceError() .compose(bindToLifecycle()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(__ -> ViewUtils.showToast(this, unableToSaveString)); RxView.clicks(gamesNewsletterSwitch) .compose(bindToLifecycle()) .subscribe(__ -> viewModel.inputs.sendGamesNewsletter(gamesNewsletterSwitch.isChecked())); RxView.clicks(happeningNewsletterSwitch) .compose(bindToLifecycle()) .subscribe(__ -> viewModel.inputs.sendHappeningNewsletter(happeningNewsletterSwitch.isChecked())); RxView.clicks(promoNewsletterSwitch) .compose(bindToLifecycle()) .subscribe(__ -> viewModel.inputs.sendPromoNewsletter(promoNewsletterSwitch.isChecked())); RxView.clicks(weeklyNewsletterSwitch) .compose(bindToLifecycle()) .subscribe(__ -> viewModel.inputs.sendWeeklyNewsletter(weeklyNewsletterSwitch.isChecked())); viewModel.outputs.showConfirmLogoutPrompt() .compose(bindToLifecycle()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(show -> { if (show) { lazyLogoutConfirmationDialog().show(); } else { lazyLogoutConfirmationDialog().dismiss(); } }); viewModel.outputs.logout() .compose(bindToLifecycle()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(__ -> logout()); } @OnClick(R.id.contact) public void contactClick() { viewModel.inputs.contactEmailClicked(); currentUser.observable() .take(1) .observeOn(AndroidSchedulers.mainThread()) .subscribe(this::composeContactEmail); } @OnClick(R.id.cookie_policy) public void cookiePolicyClick() { startHelpActivity(HelpActivity.CookiePolicy.class); } @OnClick(R.id.faq) public void faqClick() { startHelpActivity(HelpActivity.Faq.class); } @OnClick(R.id.how_kickstarter_works) public void howKickstarterWorksClick() { startHelpActivity(HelpActivity.HowItWorks.class); } @OnClick(R.id.log_out_button) public void logoutClick() { viewModel.inputs.logoutClicked(); } @OnClick(R.id.manage_project_notifications) public void manageProjectNotifications() { final Intent intent = new Intent(this, ProjectNotificationSettingsActivity.class); startActivityWithTransition(intent, R.anim.slide_in_right, R.anim.fade_out_slide_out_left); } @OnClick(R.id.privacy_policy) public void privacyPolicyClick() { startHelpActivity(HelpActivity.Privacy.class); } public void startHelpActivity(final @NonNull Class<? extends HelpActivity> helpClass) { final Intent intent = new Intent(this, helpClass); startActivityWithTransition(intent, R.anim.slide_in_right, R.anim.fade_out_slide_out_left); } @OnClick(R.id.friend_activity_mail_icon) public void toggleNotifyOfFriendActivity() { viewModel.inputs.notifyOfFriendActivity(!notifyOfFriendActivity); } @OnClick(R.id.friend_activity_phone_icon) public void toggleNotifyMobileOfFriendActivity() { viewModel.inputs.notifyMobileOfFriendActivity(!notifyMobileOfFriendActivity); } @OnClick(R.id.new_followers_mail_icon) public void toggleNotifyOfNewFollowers() { viewModel.inputs.notifyOfFollower(!notifyOfFollower); } @OnClick(R.id.new_followers_phone_icon) public void toggleNotifyMobileOfNewFollowers() { viewModel.inputs.notifyMobileOfFollower(!notifyMobileOfFollower); } @OnClick(R.id.project_updates_mail_icon) public void toggleNotifyOfUpdates() { viewModel.inputs.notifyOfUpdates(!notifyOfUpdates); } @OnClick(R.id.project_updates_phone_icon) public void toggleNotifyMobileOfUpdates() { viewModel.inputs.notifyMobileOfUpdates(!notifyMobileOfUpdates); } @OnClick(R.id.terms_of_use) public void termsOfUseClick() { startHelpActivity(HelpActivity.Terms.class); } @OnClick(R.id.settings_rate_us) public void rateUsClick() { ViewUtils.openStoreRating(this, getPackageName()); } private void composeContactEmail(final @Nullable User user) { final List<String> debugInfo = Arrays.asList( user != null ? String.valueOf(user.id()) : loggedOutString, build.versionName(), android.os.Build.VERSION.RELEASE + " (SDK " + Integer.toString(android.os.Build.VERSION.SDK_INT) + ")", android.os.Build.MANUFACTURER + " " + android.os.Build.MODEL ); final String body = new StringBuilder() .append(supportEmailBodyString) .append(TextUtils.join(" | ", debugInfo)) .toString(); final Intent intent = new Intent(Intent.ACTION_SENDTO) .setData(Uri.parse(mailtoString)) .putExtra(Intent.EXTRA_SUBJECT, "[Android] " + supportEmailSubjectString) .putExtra(Intent.EXTRA_TEXT, body) .putExtra(Intent.EXTRA_EMAIL, new String[]{supportEmailString}); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(Intent.createChooser(intent, getString(R.string.support_email_chooser))); } } private void displayPreferences(final @NonNull User user) { projectNotificationsCountTextView.setText(String.valueOf(intValueOrZero(user.backedProjectsCount()))); notifyMobileOfFriendActivity = isTrue(user.notifyMobileOfFriendActivity()); notifyOfFriendActivity = isTrue(user.notifyOfFriendActivity()); notifyMobileOfFollower = isTrue(user.notifyMobileOfFollower()); notifyOfFollower = isTrue(user.notifyOfFollower()); notifyMobileOfUpdates = isTrue(user.notifyMobileOfUpdates()); notifyOfUpdates = isTrue(user.notifyOfUpdates()); toggleIconColor(friendActivityMailIconTextView, false, notifyOfFriendActivity); toggleIconColor(friendActivityPhoneIconTextView, true, notifyMobileOfFriendActivity); toggleIconColor(newFollowersMailIconTextView, false, notifyOfFollower); toggleIconColor(newFollowersPhoneIconTextView, true, notifyMobileOfFollower); toggleIconColor(projectUpdatesMailIconTextView, false, notifyOfUpdates); toggleIconColor(projectUpdatesPhoneIconTextView, true, notifyMobileOfUpdates); SwitchCompatUtils.setCheckedWithoutAnimation(gamesNewsletterSwitch, isTrue(user.gamesNewsletter())); SwitchCompatUtils.setCheckedWithoutAnimation(happeningNewsletterSwitch, isTrue(user.happeningNewsletter())); SwitchCompatUtils.setCheckedWithoutAnimation(promoNewsletterSwitch, isTrue(user.promoNewsletter())); SwitchCompatUtils.setCheckedWithoutAnimation(weeklyNewsletterSwitch, isTrue(user.weeklyNewsletter())); } /** * Lazily creates a logout confirmation dialog and stores it in an instance variable. */ private @NonNull AlertDialog lazyLogoutConfirmationDialog() { if (logoutConfirmationDialog == null) { logoutConfirmationDialog = new AlertDialog.Builder(this) .setTitle(getString(R.string.profile_settings_logout_alert_title)) .setMessage(getString(R.string.profile_settings_logout_alert_message)) .setPositiveButton(getString(R.string.profile_settings_logout_alert_confirm_button), (__, ___) -> { viewModel.inputs.confirmLogoutClicked(); }) .setNegativeButton(getString(R.string.profile_settings_logout_alert_cancel_button), (__, ___) -> { viewModel.inputs.closeLogoutConfirmationClicked(); }) .setOnCancelListener(__ -> viewModel.inputs.closeLogoutConfirmationClicked()) .create(); } return logoutConfirmationDialog; } private void logout() { logout.execute(); ApplicationUtils.startNewDiscoveryActivity(this); } private @Nullable String newsletterString(final @NonNull Newsletter newsletter) { switch (newsletter) { case GAMES: return gamesNewsletterString; case HAPPENING: return happeningNewsletterString; case PROMO: return promoNewsletterString; case WEEKLY: return weeklyNewsletterString; default: return null; } } private void showOptInPrompt(final @NonNull Newsletter newsletter) { final String string = newsletterString(newsletter); if (string == null) { return; } final String optInDialogMessageString = ksString.format(optInMessageString, "newsletter", string); ViewUtils.showDialog(this, optInTitleString, optInDialogMessageString); } private void toggleIconColor(final @NonNull TextView iconTextView, final boolean typeMobile, final boolean enabled) { final int color = enabled ? green : gray; iconTextView.setTextColor(color); String contentDescription = ""; if (typeMobile && enabled) { contentDescription = unsubscribeMobileString; } if (typeMobile && !enabled) { contentDescription = subscribeMobileString; } if (!typeMobile && enabled) { contentDescription = unsubscribeString; } if (!typeMobile && !enabled) { contentDescription = subscribeString; } iconTextView.setContentDescription(contentDescription); } }