Skip to content

Commit

Permalink
Toggling following in settings (#259)
Browse files Browse the repository at this point in the history
  • Loading branch information
eoji committed Jun 7, 2018
1 parent bd7d98f commit e857094
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 7 deletions.
1 change: 1 addition & 0 deletions app/src/main/java/com/kickstarter/services/ApiClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,7 @@ public ApiClient(final @NonNull ApiService service, final @NonNull Gson gson) {
.gamesNewsletter(isTrue(user.gamesNewsletter()) ? 1 : 0)
.happeningNewsletter(isTrue(user.happeningNewsletter()) ? 1 : 0)
.promoNewsletter(isTrue(user.promoNewsletter()) ? 1 : 0)
.social(isTrue(user.social()) ? 1 : 0)
.weeklyNewsletter(isTrue(user.weeklyNewsletter()) ? 1 : 0)
.build())
.lift(apiErrorOperator())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public abstract class SettingsBody {
public abstract boolean notifyOfFriendActivity();
public abstract boolean notifyOfMessages();
public abstract boolean notifyOfUpdates();
public abstract int social();
public abstract int gamesNewsletter();
public abstract int happeningNewsletter();
public abstract int promoNewsletter();
Expand All @@ -32,6 +33,7 @@ public abstract static class Builder {
public abstract Builder notifyOfFriendActivity(boolean __);
public abstract Builder notifyOfMessages(boolean __);
public abstract Builder notifyOfUpdates(boolean __);
public abstract Builder social(int __);
public abstract Builder gamesNewsletter(int __);
public abstract Builder happeningNewsletter(int __);
public abstract Builder promoNewsletter(int __);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@

@RequiresActivityViewModel(SettingsViewModel.ViewModel.class)
public final class SettingsActivity extends BaseActivity<SettingsViewModel.ViewModel> {
protected @Bind(R.id.following_switch) SwitchCompat followingSwitch;
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) ImageButton friendActivityMailImageButton;
Expand All @@ -65,6 +66,9 @@ public final class SettingsActivity extends BaseActivity<SettingsViewModel.ViewM
protected @BindColor(R.color.ksr_green_700) int green;
protected @BindColor(R.color.ksr_dark_grey_400) int gray;

protected @BindString(R.string.Cancel) String cancelString;
protected @BindString(R.string.Following) String followingString;
protected @BindString(R.string.When_following_is_on_you_can_follow_the_acticity_of_others) String followingInfoString;
protected @BindString(R.string.Got_it) String gotItString;
protected @BindString(R.string.profile_settings_newsletter_games) String gamesNewsletterString;
protected @BindString(R.string.profile_settings_newsletter_happening) String happeningNewsletterString;
Expand All @@ -82,8 +86,9 @@ public final class SettingsActivity extends BaseActivity<SettingsViewModel.ViewM
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;
protected @BindString(R.string.Recommendations) String recommendations;
protected @BindString(R.string.Recommendations) String recommendationsString;
protected @BindString(R.string.We_use_your_activity_internally_to_make_recommendations_for_you) String recommendationsInfo;
protected @BindString(R.string.Yes_turn_off) String yesTurnOffString;

private CurrentUserType currentUser;
private Build build;
Expand All @@ -98,6 +103,8 @@ public final class SettingsActivity extends BaseActivity<SettingsViewModel.ViewM
private boolean notifyOfFriendActivity;
private boolean notifyOfMessages;
private boolean notifyOfUpdates;
private AlertDialog followingConfirmationDialog;
private AlertDialog followingInfoDialog;
private AlertDialog logoutConfirmationDialog;
private AlertDialog recommendationsInfoDialog;

Expand Down Expand Up @@ -129,6 +136,25 @@ protected void onCreate(final @Nullable Bundle savedInstanceState) {
.observeOn(AndroidSchedulers.mainThread())
.subscribe(__ -> ViewUtils.showToast(this, this.unableToSaveString));

RxView.clicks(this.followingSwitch)
.compose(bindToLifecycle())
.subscribe(__ -> this.viewModel.inputs.optIntoFollowing(this.followingSwitch.isChecked()));

this.viewModel.outputs.hideConfirmFollowingOptOutPrompt()
.compose(bindToLifecycle())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(__ -> SwitchCompatUtils.setCheckedWithoutAnimation(this.followingSwitch, true));

this.viewModel.outputs.showConfirmFollowingOptOutPrompt()
.compose(bindToLifecycle())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(__ -> lazyFollowingOptOutConfirmationDialog().show());

this.viewModel.outputs.showFollowingInfo()
.compose(bindToLifecycle())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(__ -> lazyFollowingInfoDialog().show());

RxView.clicks(this.gamesNewsletterSwitch)
.compose(bindToLifecycle())
.subscribe(__ -> this.viewModel.inputs.sendGamesNewsletter(this.gamesNewsletterSwitch.isChecked()));
Expand Down Expand Up @@ -186,6 +212,11 @@ public void cookiePolicyClick() {
startHelpActivity(HelpActivity.CookiePolicy.class);
}

@OnClick(R.id.following_info)
public void followingInfoClick() {
this.viewModel.inputs.followingInfoClicked();
}

@OnClick(R.id.help_center)
public void helpCenterClick() {
final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(Secrets.HelpCenter.ENDPOINT));
Expand Down Expand Up @@ -213,6 +244,11 @@ public void privacyPolicyClick() {
startHelpActivity(HelpActivity.Privacy.class);
}

@OnClick(R.id.recommendations_info)
public void recommendationsInfoClick() {
this.viewModel.inputs.recommendationsInfoClicked();
}

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);
Expand Down Expand Up @@ -258,11 +294,6 @@ public void toggleNotifyMobileOfUpdates() {
this.viewModel.inputs.notifyMobileOfUpdates(!this.notifyMobileOfUpdates);
}

@OnClick(R.id.recommendations_info)
public void recommendationsInfoClick() {
this.viewModel.inputs.recommendationsInfoClicked();
}

@OnClick(R.id.terms_of_use)
public void termsOfUseClick() {
startHelpActivity(HelpActivity.Terms.class);
Expand Down Expand Up @@ -330,13 +361,40 @@ private void displayPreferences(final @NonNull User user) {
toggleImageButtonIconColor(this.projectUpdatesMailImageButton, false, this.notifyOfUpdates);
toggleTextViewIconColor(this.projectUpdatesPhoneIconTextView, true, this.notifyMobileOfUpdates);

SwitchCompatUtils.setCheckedWithoutAnimation(this.followingSwitch, isTrue(user.social()));
SwitchCompatUtils.setCheckedWithoutAnimation(this.gamesNewsletterSwitch, isTrue(user.gamesNewsletter()));
SwitchCompatUtils.setCheckedWithoutAnimation(this.recommendationsSwitch, isFalse(user.optedOutOfRecommendations()));
SwitchCompatUtils.setCheckedWithoutAnimation(this.happeningNewsletterSwitch, isTrue(user.happeningNewsletter()));
SwitchCompatUtils.setCheckedWithoutAnimation(this.promoNewsletterSwitch, isTrue(user.promoNewsletter()));
SwitchCompatUtils.setCheckedWithoutAnimation(this.weeklyNewsletterSwitch, isTrue(user.weeklyNewsletter()));
}

private @NonNull AlertDialog lazyFollowingInfoDialog() {
if (this.followingInfoDialog == null) {
final String capitalizedGotIt = this.gotItString.toUpperCase(Locale.getDefault());
this.followingInfoDialog = new AlertDialog.Builder(this)
.setTitle(this.followingString)
.setMessage(this.followingInfoString)
.setPositiveButton(capitalizedGotIt, (__, ___) -> this.followingInfoDialog.dismiss())
.setCancelable(true)
.create();
}
return this.followingInfoDialog;
}

private @NonNull AlertDialog lazyFollowingOptOutConfirmationDialog() {
if (this.followingConfirmationDialog == null) {
this.followingConfirmationDialog = new AlertDialog.Builder(this)
.setCancelable(false)
.setTitle(getString(R.string.Are_you_sure))
.setMessage(getString(R.string.If_you_turn_following_off))
.setNegativeButton(this.cancelString, (__, ___) -> this.viewModel.inputs.optOutOfFollowing(false))
.setPositiveButton(this.yesTurnOffString, (__, ___) -> this.viewModel.inputs.optOutOfFollowing(true))
.create();
}
return this.followingConfirmationDialog;
}

/**
* Lazily creates a logout confirmation dialog and stores it in an instance variable.
*/
Expand All @@ -357,7 +415,7 @@ private void displayPreferences(final @NonNull User user) {
if (this.recommendationsInfoDialog == null) {
final String capitalizedGotIt = this.gotItString.toUpperCase(Locale.getDefault());
this.recommendationsInfoDialog = new AlertDialog.Builder(this)
.setTitle(this.recommendations)
.setTitle(this.recommendationsString)
.setMessage(this.recommendationsInfo)
.setPositiveButton(capitalizedGotIt, (__, ___) -> this.recommendationsInfoDialog.dismiss())
.setCancelable(true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ interface Inputs {
/** Call when the user clicks on contact email. */
void contactEmailClicked();

/** Call when the user clicks the Follwing info icon. */
void followingInfoClicked();

/** Call when the user taps the logout button. */
void logoutClicked();

Expand Down Expand Up @@ -60,6 +63,12 @@ interface Inputs {
/** Call when the notify of project updates toggle changes. */
void notifyOfUpdates(boolean checked);

/** Call when the user toggles the Following switch. */
void optIntoFollowing(boolean checked);

/** Call when the user confirms or cancels opting out of Following. */
void optOutOfFollowing(boolean optOut);

/** Call when the user toggles the Recommendations switch. */
void optedOutOfRecommendations(boolean checked);

Expand All @@ -83,9 +92,18 @@ interface Outputs {
/** Emits when its time to log the user out. */
Observable<Void> logout();

/** Emits when Following switch should be turned back on after user cancels opting out. */
Observable<Void> hideConfirmFollowingOptOutPrompt();

/** Emits when user should be shown the Following confirmation dialog. */
Observable<Void> showConfirmFollowingOptOutPrompt();

/** Emits a boolean that determines if the logout confirmation should be displayed. */
Observable<Boolean> showConfirmLogoutPrompt();

/** Emits when user should be shown the Following info dialog. */
Observable<Void> showFollowingInfo();

/** Show a dialog to inform the user that their newsletter subscription must be confirmed via email. */
Observable<Newsletter> showOptInPrompt();

Expand Down Expand Up @@ -161,6 +179,26 @@ public ViewModel(final @NonNull Environment environment) {
this.logout.onNext(null);
});

this.optIntoFollowing
.compose(bindToLifecycle())
.filter(checked -> checked)
.subscribe(__ -> this.userInput.onNext(this.userOutput.getValue().toBuilder().social(true).build()));

this.optIntoFollowing
.compose(bindToLifecycle())
.filter(checked -> !checked)
.subscribe(__ -> this.showConfirmFollowingOptOutPrompt.onNext(null));

this.optOutOfFollowing
.compose(bindToLifecycle())
.filter(optOut -> optOut)
.subscribe(__ -> this.userInput.onNext(this.userOutput.getValue().toBuilder().social(false).build()));

this.optOutOfFollowing
.compose(bindToLifecycle())
.filter(optOut -> !optOut)
.subscribe(__ -> this.hideConfirmFollowingOptOutPrompt.onNext(null));

this.koala.trackSettingsView();
}

Expand All @@ -182,10 +220,15 @@ private void success(final @NonNull User user) {
private final PublishSubject<Void> contactEmailClicked = PublishSubject.create();
private final PublishSubject<Boolean> optedOutOfRecommendations = PublishSubject.create();
private final PublishSubject<Pair<Boolean, Newsletter>> newsletterInput = PublishSubject.create();
private final PublishSubject<Boolean> optIntoFollowing = PublishSubject.create();
private final PublishSubject<Boolean> optOutOfFollowing = PublishSubject.create();
private final PublishSubject<User> userInput = PublishSubject.create();

private final BehaviorSubject<Void> hideConfirmFollowingOptOutPrompt = BehaviorSubject.create();
private final BehaviorSubject<Void> logout = BehaviorSubject.create();
private final BehaviorSubject<Void> showConfirmFollowingOptOutPrompt = BehaviorSubject.create();
private final BehaviorSubject<Boolean> showConfirmLogoutPrompt = BehaviorSubject.create();
private final BehaviorSubject<Void> showFollowingInfo = BehaviorSubject.create();
private final PublishSubject<Newsletter> showOptInPrompt = PublishSubject.create();
private final PublishSubject<Void> showRecommendationsInfo = PublishSubject.create();
private final PublishSubject<Void> updateSuccess = PublishSubject.create();
Expand All @@ -206,6 +249,9 @@ private void success(final @NonNull User user) {
@Override public void contactEmailClicked() {
this.contactEmailClicked.onNext(null);
}
@Override public void followingInfoClicked() {
this.showFollowingInfo.onNext(null);
}
@Override
public void optedOutOfRecommendations(final boolean checked) {
this.userInput.onNext(this.userOutput.getValue().toBuilder().optedOutOfRecommendations(!checked).build());
Expand Down Expand Up @@ -241,6 +287,12 @@ public void optedOutOfRecommendations(final boolean checked) {
@Override public void notifyOfUpdates(final boolean b) {
this.userInput.onNext(this.userOutput.getValue().toBuilder().notifyOfUpdates(b).build());
}
@Override public void optIntoFollowing(final boolean checked) {
this.optIntoFollowing.onNext(checked);
}
@Override public void optOutOfFollowing(final boolean optOut) {
this.optOutOfFollowing.onNext(optOut);
}
@Override public void sendGamesNewsletter(final boolean checked) {
this.userInput.onNext(this.userOutput.getValue().toBuilder().gamesNewsletter(checked).build());
this.newsletterInput.onNext(new Pair<>(checked, Newsletter.GAMES));
Expand All @@ -261,9 +313,18 @@ public void optedOutOfRecommendations(final boolean checked) {
@Override public @NonNull Observable<Void> logout() {
return this.logout;
}
@Override public @NonNull Observable<Void> hideConfirmFollowingOptOutPrompt() {
return this.hideConfirmFollowingOptOutPrompt;
}
@Override public @NonNull Observable<Boolean> showConfirmLogoutPrompt() {
return this.showConfirmLogoutPrompt;
}
@Override public @NonNull Observable<Void> showConfirmFollowingOptOutPrompt() {
return this.showConfirmFollowingOptOutPrompt;
}
@Override public @NonNull Observable<Void> showFollowingInfo() {
return this.showFollowingInfo;
}
@Override public @NonNull Observable<Newsletter> showOptInPrompt() {
return this.showOptInPrompt;
}
Expand Down
20 changes: 20 additions & 0 deletions app/src/main/res/layout/settings_layout.xml
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,26 @@
style="@style/EndSettingsWidget" />
</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/grid_10"
android:gravity="center_vertical"
android:orientation="horizontal">

<TextView
style="@style/SettingsSectionLabel"
android:text="@string/Following" />

<ImageButton
android:id="@+id/following_info"
android:contentDescription="@string/Following_More_Info"
style="@style/SettingsInfoIcon" />

<android.support.v7.widget.SwitchCompat
android:id="@+id/following_switch"
style="@style/EndSettingsWidget" />
</LinearLayout>

</LinearLayout>

</ScrollView>
Expand Down
Loading

0 comments on commit e857094

Please sign in to comment.