diff --git a/app/assets/javascripts/initializers/initializeBodyData.js b/app/assets/javascripts/initializers/initializeBodyData.js index 945c7f28e..fabbb4906 100644 --- a/app/assets/javascripts/initializers/initializeBodyData.js +++ b/app/assets/javascripts/initializers/initializeBodyData.js @@ -12,46 +12,60 @@ function removeExistingCSRF() { function fetchBaseData() { fetch('/async_info/base_data') .then((response) => response.json()) - .then(({ token, param, broadcast, user, creator }) => { - if (token) { - removeExistingCSRF(); - } + .then( + ({ + token, + param, + broadcast, + user, + creator, + client_geolocation, + default_email_optin_allowed, + }) => { + if (token) { + removeExistingCSRF(); + } - const newCsrfParamMeta = document.createElement('meta'); - newCsrfParamMeta.name = 'csrf-param'; - newCsrfParamMeta.content = param; - document.head.appendChild(newCsrfParamMeta); + const newCsrfParamMeta = document.createElement('meta'); + newCsrfParamMeta.name = 'csrf-param'; + newCsrfParamMeta.content = param; + document.head.appendChild(newCsrfParamMeta); - const newCsrfTokenMeta = document.createElement('meta'); - newCsrfTokenMeta.name = 'csrf-token'; - newCsrfTokenMeta.content = token; - document.head.appendChild(newCsrfTokenMeta); - document.body.dataset.loaded = 'true'; + const newCsrfTokenMeta = document.createElement('meta'); + newCsrfTokenMeta.name = 'csrf-token'; + newCsrfTokenMeta.content = token; + document.head.appendChild(newCsrfTokenMeta); + document.body.dataset.loaded = 'true'; - if (broadcast) { - document.body.dataset.broadcast = broadcast; - } + if (broadcast) { + document.body.dataset.broadcast = broadcast; + } - if (checkUserLoggedIn()) { - document.body.dataset.user = user; - document.body.dataset.creator = creator; - browserStoreCache('set', user); + if (checkUserLoggedIn()) { + document.body.dataset.user = user; + document.body.dataset.creator = creator; + document.body.dataset.clientGeolocation = + JSON.stringify(client_geolocation); + document.body.dataset.default_email_optin_allowed = + default_email_optin_allowed; + browserStoreCache('set', user); - setTimeout(() => { - if (typeof ga === 'function') { - ga('set', 'userId', JSON.parse(user).id); - } - if (typeof gtag === 'function') { - gtag('set', 'user_Id', JSON.parse(user).id); - } - }, 400); - } else { - // Ensure user data is not exposed if no one is logged in - delete document.body.dataset.user; - delete document.body.dataset.creator; - browserStoreCache('remove'); - } - }); + setTimeout(() => { + if (typeof ga === 'function') { + ga('set', 'userId', JSON.parse(user).id); + } + if (typeof gtag === 'function') { + gtag('set', 'user_Id', JSON.parse(user).id); + } + }, 400); + } else { + // Ensure user data is not exposed if no one is logged in + delete document.body.dataset.user; + delete document.body.dataset.creator; + browserStoreCache('remove'); + } + }, + ); } function initializeBodyData() { diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index bdc1139d9..73f087fb0 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -278,6 +278,15 @@ class ApplicationController < ActionController::Base end helper_method :client_geolocation + def default_email_optin_allowed? + return false if Settings::General.geos_with_allowed_default_email_opt_in.blank? + + Settings::General.geos_with_allowed_default_email_opt_in.any? do |geo| + client_geolocation.to_s.starts_with?(geo) + end + end + helper_method :default_email_optin_allowed? + def forward_to_app_config_domain # Let's only redirect get requests for this purpose. return unless request.get? && diff --git a/app/controllers/async_info_controller.rb b/app/controllers/async_info_controller.rb index 99664d401..513c15bf7 100644 --- a/app/controllers/async_info_controller.rb +++ b/app/controllers/async_info_controller.rb @@ -14,6 +14,8 @@ class AsyncInfoController < ApplicationController param: request_forgery_protection_token, token: form_authenticity_token, user: user_data, + client_geolocation: client_geolocation, + default_email_optin_allowed: default_email_optin_allowed?, creator: user_is_a_creator } end diff --git a/app/javascript/onboarding/components/FollowTags.jsx b/app/javascript/onboarding/components/FollowTags.jsx index ecef1592d..2e29e8a7f 100644 --- a/app/javascript/onboarding/components/FollowTags.jsx +++ b/app/javascript/onboarding/components/FollowTags.jsx @@ -12,10 +12,13 @@ export class FollowTags extends Component { this.handleClick = this.handleClick.bind(this); this.handleComplete = this.handleComplete.bind(this); + const emailState = + document.body.dataset.defaultEmailOptinAllowed === 'true'; + this.state = { allTags: [], selectedTags: [], - email_digest_periodic: false, + email_digest_periodic: emailState, }; } diff --git a/app/javascript/onboarding/components/__tests__/FollowTags.test.jsx b/app/javascript/onboarding/components/__tests__/FollowTags.test.jsx index 4568f1c0f..fa1558b21 100644 --- a/app/javascript/onboarding/components/__tests__/FollowTags.test.jsx +++ b/app/javascript/onboarding/components/__tests__/FollowTags.test.jsx @@ -231,4 +231,28 @@ describe('FollowTags', () => { expect(lastFetchUri).toEqual('/onboarding/notifications'); }); }); + + describe('emailDigestPeriodic state initialization', () => { + it('should initialize email_digest_periodic to true when data-default-email-optin-allowed is true', async () => { + // Simulate setting data-default-email-optin-allowed to true + document.body.dataset.defaultEmailOptinAllowed = 'true'; + + const { container } = renderFollowTags(); + const checkbox = container.querySelector('#email_digest_periodic'); + + // Assert that the checkbox is checked, indicating email_digest_periodic state is true + expect(checkbox.checked).toBeTruthy(); + }); + + it('should initialize email_digest_periodic to false when data-default-email-optin-allowed is false', async () => { + // Simulate setting data-default-email-optin-allowed to false + document.body.dataset.defaultEmailOptinAllowed = 'false'; + + const { container } = renderFollowTags(); + const checkbox = container.querySelector('#email_digest_periodic'); + + // Assert that the checkbox is not checked, indicating email_digest_periodic state is false + expect(checkbox.checked).toBeFalsy(); + }); + }); }); diff --git a/app/lib/constants/settings/general.rb b/app/lib/constants/settings/general.rb index 658fb51c9..275e50015 100644 --- a/app/lib/constants/settings/general.rb +++ b/app/lib/constants/settings/general.rb @@ -109,6 +109,10 @@ module Constants description: I18n.t("lib.constants.settings.general.onboarding_newsletter_opt_in_subhead.description"), placeholder: I18n.t("lib.constants.settings.general.onboarding_newsletter_opt_in_subhead.placeholder") }, + geos_with_allowed_default_email_opt_in: { + description: I18n.t("lib.constants.settings.general.geos_with_allowed_default_email_opt_in.description"), + placeholder: I18n.t("lib.constants.settings.general.geos_with_allowed_default_email_opt_in.placeholder") + }, payment_pointer: { description: I18n.t("lib.constants.settings.general.payment.description"), placeholder: "$pay.somethinglikethis.co/value" diff --git a/app/models/settings/general.rb b/app/models/settings/general.rb index f47ebd699..71e2a5dc1 100644 --- a/app/models/settings/general.rb +++ b/app/models/settings/general.rb @@ -139,6 +139,8 @@ module Settings setting :onboarding_newsletter_opt_in_head setting :onboarding_newsletter_opt_in_subhead + setting :geos_with_allowed_default_email_opt_in, type: :array, default: %w[] + setting :default_content_language, type: :string, default: "en", validates: { inclusion: Languages::Detection.codes } diff --git a/app/views/admin/settings/forms/_onboarding.html.erb b/app/views/admin/settings/forms/_onboarding.html.erb index 735f0ae8e..3394504fb 100644 --- a/app/views/admin/settings/forms/_onboarding.html.erb +++ b/app/views/admin/settings/forms/_onboarding.html.erb @@ -36,6 +36,13 @@ class: "crayons-textfield", value: Settings::General.onboarding_newsletter_opt_in_subhead, placeholder: Constants::Settings::General.details[:onboarding_newsletter_opt_in_subhead][:placeholder] %> + <% if FeatureFlag.enabled?(Geolocation::FEATURE_FLAG) %> + <%= admin_config_label Constants::Settings::General.details[:geos_with_allowed_default_email_opt_in][:description] %> + <%= f.text_field :geos_with_allowed_default_email_opt_in, + class: "crayons-textfield", + value: Settings::General.geos_with_allowed_default_email_opt_in, + placeholder: Constants::Settings::General.details[:geos_with_allowed_default_email_opt_in][:placeholder] %> + <% end %> diff --git a/app/views/onboardings/_newsletter.html.erb b/app/views/onboardings/_newsletter.html.erb index d1300c154..0a3bd163c 100644 --- a/app/views/onboardings/_newsletter.html.erb +++ b/app/views/onboardings/_newsletter.html.erb @@ -6,7 +6,7 @@