Improve user subscription UX flow when latency is high (#11735)

* Improve user subscription UX flow when latency is high

* Extract subscribeBtn into const, add margin-bottom to logged-in-text
This commit is contained in:
Vaidehi Joshi 2020-12-03 12:25:32 -08:00 committed by GitHub
parent 8d3a13bc7d
commit d9011f4b59
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 13 deletions

View file

@ -8,16 +8,20 @@ class UserSubscriptionTag < LiquidTagBase
].freeze
SCRIPT = <<~JAVASCRIPT.freeze
const subscribeBtn = document.getElementById('subscribe-btn');
function isUserSignedIn() {
return document.head.querySelector('meta[name="user-signed-in"][content="true"]') !== null;
}
// Hiding/showing elements
// If clearSubscribeButton is false, we will not clear out the subscription-signed-in area,
// which will allow users to re-submit their subscription if they see any error messages.
// ***************************************
function clearSubscriptionArea() {
const subscriptionSignedIn = document.getElementById('subscription-signed-in');
if (subscriptionSignedIn) {
subscriptionSignedIn.classList.add("hidden");
function clearSubscriptionArea({ clearSubscribeButton = true } = {}) {
if (!clearSubscribeButton) {
// Allow users to try submitting again if they see an error.
hideSubscriptionSignedIn();
}
const subscriptionSignedOut = document.getElementById('subscription-signed-out');
@ -25,10 +29,7 @@ class UserSubscriptionTag < LiquidTagBase
subscriptionSignedOut.classList.add("hidden");
}
const responseMessage = document.getElementById('response-message');
if (responseMessage) {
responseMessage.classList.add("hidden");
}
hideResponseMessage();
const subscriberAppleAuth = document.getElementById('subscriber-apple-auth');
if (subscriberAppleAuth) {
@ -38,6 +39,15 @@ class UserSubscriptionTag < LiquidTagBase
hideConfirmationModal();
}
// Hides the response message (which displays success/error messages) if it exists.
// ***************************************
function hideResponseMessage() {
const responseMessage = document.getElementById('response-message');
if (responseMessage) {
responseMessage.classList.add("hidden");
}
}
function showSignedIn() {
clearSubscriptionArea();
const subscriptionSignedIn = document.getElementById('subscription-signed-in');
@ -73,12 +83,19 @@ class UserSubscriptionTag < LiquidTagBase
}
function showResponseMessage(noticeType, msg) {
clearSubscriptionArea();
clearSubscriptionArea(clearSubscribeButton = false);
const responseMessage = document.getElementById('response-message');
if (responseMessage) {
responseMessage.classList.remove("hidden");
responseMessage.classList.add(`crayons-notice--${noticeType}`);
responseMessage.textContent = msg;
if (noticeType === 'danger') {
// Allow users to try resubscribing if they see an error message.
subscribeBtn.textContent = "Submit";
subscribeBtn.disabled = false;
}
}
}
@ -96,6 +113,7 @@ class UserSubscriptionTag < LiquidTagBase
}
function showSubscribed() {
hideSubscriptionSignedIn();
updateSubscriberData();
const authorUsername = document.getElementById('user-subscription-tag')?.dataset.authorUsername;
const alreadySubscribedMsg = `You are already subscribed.`;
@ -144,6 +162,13 @@ class UserSubscriptionTag < LiquidTagBase
});
}
function hideSubscriptionSignedIn() {
const subscriptionSignedIn = document.getElementById('subscription-signed-in');
if (subscriptionSignedIn) {
subscriptionSignedIn.classList.add("hidden");
}
}
// Adding event listeners for 'click'
// ***************************************
function addSignInClickHandler() {
@ -158,7 +183,6 @@ class UserSubscriptionTag < LiquidTagBase
}
function addConfirmationModalClickHandlers() {
const subscribeBtn = document.getElementById('subscribe-btn');
if (subscribeBtn) {
subscribeBtn.addEventListener('click', function(e) {
showConfirmationModal();
@ -190,6 +214,12 @@ class UserSubscriptionTag < LiquidTagBase
// API calls
// ***************************************
function submitSubscription() {
// Hide any error messages previously rendered.
hideResponseMessage();
subscribeBtn.textContent = "Submitting...";
subscribeBtn.disabled = true;
const headers = {
Accept: 'application/json',
'X-CSRF-Token': window.csrfToken,
@ -251,12 +281,15 @@ class UserSubscriptionTag < LiquidTagBase
// Handle API responses
// ***************************************
function handleSubscription() {
hideConfirmationModal(); // Close the modal once the user has confirmed.
submitSubscription().then(function(response) {
if (response.success) {
const userSubscriptionTag = document.getElementById('user-subscription-tag');
const authorUsername = (userSubscriptionTag ? userSubscriptionTag.dataset.authorUsername : null);
const successMsg = `You are now subscribed and may receive emails from ${authorUsername}`;
showResponseMessage('success', successMsg);
hideSubscriptionSignedIn();
} else {
showResponseMessage('danger', response.error);
}

View file

@ -33,7 +33,7 @@
<button class="crayons-btn mb-4" id="subscribe-btn">
Subscribe
</button>
<div class="fs-s" id="logged-in-text">
<div class="fs-s mb-3" id="logged-in-text">
You'll subscribe with
<span class="ltag__user-subscription-tag__subscriber-email"></span>
the email address associated with your DEV account. To use a

View file

@ -63,7 +63,7 @@ RSpec.describe UserSubscriptionTag, type: :liquid_tag do
expect(page).to have_css("#user-subscription-confirmation-modal", visible: :visible)
end
it "displays a sucess mesage when a subscription is created" do
it "displays a sucess message when a subscription is created" do
expect(page).to have_css("#subscription-signed-out", visible: :hidden)
expect(page).to have_css("#subscriber-apple-auth", visible: :hidden)
expect(page).to have_css("#response-message", visible: :hidden)
@ -94,7 +94,9 @@ RSpec.describe UserSubscriptionTag, type: :liquid_tag do
expect(page).to have_css("#subscription-signed-in", visible: :visible)
click_button("Subscribe", id: "subscribe-btn")
click_button("Confirm subscription", id: "confirmation-btn")
expect(page).to have_css("#subscription-signed-in", visible: :hidden)
# User should be able see the error and should be able to resubscribe.
expect(page).to have_css("#subscription-signed-in", visible: :visible)
expect(page).to have_css("#response-message.crayons-notice--danger", visible: :visible)
within "#response-message" do