From 598cd26d604b6ee27c4573e04609e739ee24ec5f Mon Sep 17 00:00:00 2001 From: Nuwan Date: Sun, 11 May 2025 11:59:07 +0530 Subject: [PATCH] Download App prompts & reminders reminds the newly joined users to download the jamkazam app using modal popup and emails. --- jam-ui/src/components/page/JKEditProfile.js | 88 ++++++++++++++++++- .../profile/JKDownloadAppReminderModal.js | 72 +++++++++++++++ .../components/profile/JKUnsavedDataModal.js | 48 ++++++++++ jam-ui/src/i18n/locales/en/profile.json | 18 ++++ ..._tracking_totals_to_affiliate_partners.rb} | 0 ..._app_download_reminder_columns_to_users.rb | 12 +++ ruby/lib/jam_ruby/app/mailers/user_mailer.rb | 33 +++++++ .../app_download_reminder1.html.erb | 62 +++++++++++++ .../app_download_reminder1.text.erb | 19 ++++ .../app_download_reminder2.html.erb | 66 ++++++++++++++ .../app_download_reminder2.text.erb | 21 +++++ .../app_download_reminder3.html.erb | 62 +++++++++++++ .../app_download_reminder3.text.erb | 18 ++++ .../lib/jam_ruby/lib/app_download_reminder.rb | 43 +++++++++ .../jam_ruby/resque/scheduled/hourly_job.rb | 1 + web/app/views/api_users/profile_show.rabl | 2 +- web/config/locales/en.yml | 44 +++++++++- 17 files changed, 602 insertions(+), 7 deletions(-) create mode 100644 jam-ui/src/components/profile/JKDownloadAppReminderModal.js create mode 100644 jam-ui/src/components/profile/JKUnsavedDataModal.js rename ruby/db/migrate/{20250322000000_affiliate_tracking_totals.rb => 20250322000000_add_tracking_totals_to_affiliate_partners.rb} (100%) create mode 100644 ruby/db/migrate/20250505101117_add_app_download_reminder_columns_to_users.rb create mode 100644 ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/app_download_reminder1.html.erb create mode 100644 ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/app_download_reminder1.text.erb create mode 100644 ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/app_download_reminder2.html.erb create mode 100644 ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/app_download_reminder2.text.erb create mode 100644 ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/app_download_reminder3.html.erb create mode 100644 ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/app_download_reminder3.text.erb create mode 100644 ruby/lib/jam_ruby/lib/app_download_reminder.rb diff --git a/jam-ui/src/components/page/JKEditProfile.js b/jam-ui/src/components/page/JKEditProfile.js index 77f639a14..fcd43ed2c 100644 --- a/jam-ui/src/components/page/JKEditProfile.js +++ b/jam-ui/src/components/page/JKEditProfile.js @@ -5,20 +5,28 @@ import FalconCardHeader from '../common/FalconCardHeader'; import { useTranslation } from 'react-i18next'; import JKProfileAvatar from '../profile/JKProfileAvatar'; import { useAuth } from '../../context/UserAuth'; -import { useForm, Controller } from 'react-hook-form'; +import { useForm, Controller, set } from 'react-hook-form'; import { getInstruments, getGenres, updateUser, getCountries, getRegions, getCities } from '../../helpers/rest'; import JKProfileAvatarUpload from '../profile/JKProfileAvatarUpload'; +import JKDownloadAppReminderModal from '../profile/JKDownloadAppReminderModal'; +import JKUnsavedDataModal from '../profile/JKUnsavedDataModal'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { Prompt } from 'react-router'; +// import { Prompt } from 'react-router'; +import { useHistory } from 'react-router-dom'; import { useAppData } from '../../context/AppDataContext'; function JKEditProfile() { const { t } = useTranslation('profile'); const { currentUser } = useAuth(); + const history = useHistory(); const [musicInstruments, setMusicInstruments] = useState([]); const [userMusicInstruments, setUserMusicInstruments] = useState([]); const [userMusicInstrumentsReceived, setUserMusicInstrumentsReceived] = useState(false); + const [showDownloadAppReminder, setShowDownloadAppReminder] = useState(false); + const [showUnsavedDataModal, setShowUnsavedDataModal] = useState(false); + const hasDownloadedApp = React.useRef(false); + const [nextLocation, setNextLocation] = useState(null); const [genres, setGenres] = useState([]); const [userGenres, setUserGenres] = useState([]); @@ -32,6 +40,9 @@ function JKEditProfile() { const [cities, setCities] = useState([]); const [showAvatarUpload, setShowAvatarUpload] = useState(false); const [updating, setUpdating] = useState(false); + const [isBlocking, setIsBlocking] = useState(false); + + let unblock = null; // const { userProfile, photoUrl } = useUserProfile(currentUser); const { appData } = useAppData(); @@ -73,6 +84,11 @@ function JKEditProfile() { setUserGenresReceived(true); setUserMusicInstruments(userProfile.instruments); setUserMusicInstrumentsReceived(true); + hasDownloadedApp.current = !!userProfile.first_downloaded_client_at + if(!hasDownloadedApp.current){ + setIsBlocking(true); + } + }, [userProfile]); useLayoutEffect(() => { @@ -81,6 +97,7 @@ function JKEditProfile() { fetchCountries(); }, []); + const updateFormData = data => { setValue('firstName', data.first_name); setValue('lastName', data.last_name); @@ -390,7 +407,19 @@ function JKEditProfile() { useEffect(() => { function beforeUnload(e) { - if (updating) e.preventDefault(); + + if (updating) { + e.preventDefault(); + setShowUnsavedDataModal(true); + return false; // prevent navigation + } + + if (!hasDownloadedApp.current && (!!localStorage.getItem('downloadAppReminded') === false || localStorage.getItem('downloadAppReminded') !== 'true')) { + e.preventDefault(); + setShowDownloadAppReminder(true); + return false; // prevent navigation + } + } window.addEventListener('beforeunload', beforeUnload); @@ -400,13 +429,59 @@ function JKEditProfile() { }; }, [updating]); + + useEffect(() => { + if (isBlocking) { + unblock = history.block((tx) => { + console.log('Blocking navigation', tx, updating); + setNextLocation(tx); + + if (updating) { + setShowUnsavedDataModal(true); + return false; // prevent navigation + } + + if (!hasDownloadedApp.current && (!!localStorage.getItem('downloadAppReminded') === false || localStorage.getItem('downloadAppReminded') !== 'true')) { + setShowDownloadAppReminder(true); + return false; // prevent navigation + } + + }); + } else { + if (unblock) { + unblock(); // remove blocker if not blocking anymore + } + } + return () => { + if (unblock) unblock(); + }; + }, [isBlocking, history, updating]); + const toggleAvatarUpload = () => { setShowAvatarUpload(!showAvatarUpload); }; + const onLeaveUnsavedData = () => { + if(nextLocation && nextLocation.pathname) { + history.push(nextLocation.pathname); + }else{ + history.push('/'); + } + setShowUnsavedDataModal(false); + } + + const onCancelAppReminder = () => { + if(nextLocation && nextLocation.pathname) { + history.push(nextLocation.pathname); + } else { + history.push('/'); + } + setShowDownloadAppReminder(false); + } + return ( <> - + {/* */} {updating && ( @@ -762,6 +837,11 @@ function JKEditProfile() { + + ); } diff --git a/jam-ui/src/components/profile/JKDownloadAppReminderModal.js b/jam-ui/src/components/profile/JKDownloadAppReminderModal.js new file mode 100644 index 000000000..3091a6462 --- /dev/null +++ b/jam-ui/src/components/profile/JKDownloadAppReminderModal.js @@ -0,0 +1,72 @@ +import React, { useState, useEffect } from 'react'; +import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; +import { useTranslation } from 'react-i18next'; +import PropTypes from 'prop-types'; +import { useHistory } from 'react-router-dom'; + + +const JKDownloadAppReminderModal = ({ show, onCancel }) => { + const [modal, setModal] = useState(false); + const { t } = useTranslation("profile"); + const history = useHistory(); + + const toggle = () => { + setModal(!modal); + } + + useEffect(() => { + if(show){ + localStorage.setItem('downloadAppReminded', 'true'); + } + setModal(show); + }, [show]); + + const onDownloadAppClick = () => { + history.push('/public/downloads'); + setModal(false); + } + + const onDownloadLegacyAppClick = () => { + history.push('/public/downloads-legacy'); + setModal(false); + } + + return ( + + {t('app_download_reminder.next_step')} + +

+ {t('app_download_reminder.paragraph1')} +

+

+ {t('app_download_reminder.paragraph2')} +

    +
  • {t('app_download_reminder.paragraph2_list_item1')}
  • +
  • {t('app_download_reminder.paragraph2_list_item2')}
  • +
+

+

+ {t('app_download_reminder.paragraph3')} +

+
+ + {' '} + {' '} + + +
+ ) +} + +JKDownloadAppReminderModal.propTypes = { + show: PropTypes.bool, + onCancel: PropTypes.func, +}; + +export default JKDownloadAppReminderModal \ No newline at end of file diff --git a/jam-ui/src/components/profile/JKUnsavedDataModal.js b/jam-ui/src/components/profile/JKUnsavedDataModal.js new file mode 100644 index 000000000..fefa2f622 --- /dev/null +++ b/jam-ui/src/components/profile/JKUnsavedDataModal.js @@ -0,0 +1,48 @@ +import React, { useState, useEffect } from 'react'; +import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; +import { useTranslation } from 'react-i18next'; +import PropTypes from 'prop-types'; + +const JKUnsavedDataModal = ({ show, onLeave }) => { + const [modal, setModal] = useState(false); + const { t } = useTranslation("profile"); + + const toggle = () => { + setModal(!modal); + } + + const onCancel = () => { + setModal(false); + } + + useEffect(() => { + setModal(show); + } + , [show]); + + return ( + + {t('unsaved_data_warning.title')} + +

+ {t('unsaved_data_warning.message')} +

+
+ + {' '} + + +
+ ) +} + +JKUnsavedDataModal.propTypes = { + show: PropTypes.bool, + onLeave: PropTypes.func, +}; + +export default JKUnsavedDataModal \ No newline at end of file diff --git a/jam-ui/src/i18n/locales/en/profile.json b/jam-ui/src/i18n/locales/en/profile.json index ab1d871fc..88b60b31e 100644 --- a/jam-ui/src/i18n/locales/en/profile.json +++ b/jam-ui/src/i18n/locales/en/profile.json @@ -26,5 +26,23 @@ "delete": "Delete Photo", "cacel": "Cancel", "save": "Save" + }, + "app_download_reminder": { + "next_step": "Next Step: Download Jamkazam App", + "paragraph1": "The next thing you should do with JamKazam is download and install our free app for Windows or Mac. You’ll need this app to play music online with others, and the app also gives you access to more advanced JamTracks features if you’re interested in using our huge catalog of backing tracks.", + "paragraph2": "To go to the app download page, most users should click the Download App button below, with these exceptions:", + "paragraph2_list_item1": "If you’re on a Mac that can’t run MacOS 10.15 or later, click the Download Legacy App button, as that version of the app supports older MacOS versions back to 10.7.", + "paragraph2_list_item2": "If you’re on Windows 7, click the Download Legacy App button, as that version of the app supports Windows 7 computers.", + "download_app": "Download App", + "download_legacy_app": "Download Legacy App", + "not_now": "Not Now", + "paragraph3": "After downloading, double click the downloaded installer, and then follow the on-screen instructions to install the app.", + "paragraph4": "For next steps after downloading and installing the app, don’t forget you can always refer back to the Welcome email we sent you when you signed up. And if you run into any problems or get stuck, please send us email at support@jamkazam.com. We’re always happy to help!" + }, + "unsaved_data_warning": { + "title": "Unsaved Data", + "message": "You have unsaved data. Are you sure you want to leave this page?", + "cancel": "Cancel", + "leave": "Leave" } } diff --git a/ruby/db/migrate/20250322000000_affiliate_tracking_totals.rb b/ruby/db/migrate/20250322000000_add_tracking_totals_to_affiliate_partners.rb similarity index 100% rename from ruby/db/migrate/20250322000000_affiliate_tracking_totals.rb rename to ruby/db/migrate/20250322000000_add_tracking_totals_to_affiliate_partners.rb diff --git a/ruby/db/migrate/20250505101117_add_app_download_reminder_columns_to_users.rb b/ruby/db/migrate/20250505101117_add_app_download_reminder_columns_to_users.rb new file mode 100644 index 000000000..f59225593 --- /dev/null +++ b/ruby/db/migrate/20250505101117_add_app_download_reminder_columns_to_users.rb @@ -0,0 +1,12 @@ + class AddAppDownloadReminderColumnsToUsers < ActiveRecord::Migration + def self.up + execute "ALTER TABLE users ADD COLUMN app_download_reminder1_sent_at TIMESTAMP" + execute "ALTER TABLE users ADD COLUMN app_download_reminder2_sent_at TIMESTAMP" + execute "ALTER TABLE users ADD COLUMN app_download_reminder3_sent_at TIMESTAMP" + end + def self.down + execute "ALTER TABLE users DROP COLUMN app_download_reminder1_sent_at" + execute "ALTER TABLE users DROP COLUMN app_download_reminder2_sent_at" + execute "ALTER TABLE users DROP COLUMN app_download_reminder3_sent_at" + end + end diff --git a/ruby/lib/jam_ruby/app/mailers/user_mailer.rb b/ruby/lib/jam_ruby/app/mailers/user_mailer.rb index 193402404..d157fac63 100644 --- a/ruby/lib/jam_ruby/app/mailers/user_mailer.rb +++ b/ruby/lib/jam_ruby/app/mailers/user_mailer.rb @@ -454,6 +454,39 @@ module JamRuby end end + def app_download_reminder1(user) + @user = user + sendgrid_recipients([user.email]) + sendgrid_substitute('@USERID', [user.id]) + sendgrid_unique_args :type => "app_download_reminder1" + mail(:to => user.email, :subject => I18n.t('user_mailer.app_download_reminder1.subject')) do |format| + format.text + format.html { render layout: "user_mailer_beta" } + end + end + + def app_download_reminder2(user) + @user = user + sendgrid_recipients([user.email]) + sendgrid_substitute('@USERID', [user.id]) + sendgrid_unique_args :type => "app_download_reminder2" + mail(:to => user.email, :subject => I18n.t('user_mailer.app_download_reminder2.subject')) do |format| + format.text + format.html { render layout: "user_mailer_beta" } + end + end + + def app_download_reminder3(user) + @user = user + sendgrid_recipients([user.email]) + sendgrid_substitute('@USERID', [user.id]) + sendgrid_unique_args :type => "app_download_reminder3" + mail(:to => user.email, :subject => I18n.t('user_mailer.app_download_reminder3.subject')) do |format| + format.text + format.html { render layout: "user_mailer_beta" } + end + end + #################################### NOTIFICATION EMAILS #################################### def friend_request(user, msg, friend_request_id) return if !user.subscribe_email diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/app_download_reminder1.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/app_download_reminder1.html.erb new file mode 100644 index 000000000..8b766563e --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/app_download_reminder1.html.erb @@ -0,0 +1,62 @@ +

<%=I18n.t('user_mailer.app_download_reminder1.greeting') -%> <%= @user.first_name -%> -

+ +

+ <%=I18n.t('user_mailer.app_download_reminder1.paragraph1') -%> +

+ +

+ <%=I18n.t('user_mailer.app_download_reminder1.paragraph2') -%> +

    +
  • <%=I18n.t('user_mailer.app_download_reminder1.paragraph2_list_item1') -%>
  • +
  • <%=I18n.t('user_mailer.app_download_reminder1.paragraph2_list_item2') -%>
  • +
+

+ +

+ + <%=I18n.t('user_mailer.app_download_reminder1.download_app') -%> + + + + <%=I18n.t('user_mailer.app_download_reminder1.download_legacy_app') -%> + +

+ +

+ <%=I18n.t('user_mailer.app_download_reminder1.paragraph3') -%> +

+ +

+ <%=I18n.t('user_mailer.app_download_reminder1.paragraph4') -%> +

+ +
+

+ <%=I18n.t('user_mailer.app_download_reminder1.regards') -%> +
+ <%=I18n.t('user_mailer.app_download_reminder1.signature') -%> +

+
\ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/app_download_reminder1.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/app_download_reminder1.text.erb new file mode 100644 index 000000000..6d4d68071 --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/app_download_reminder1.text.erb @@ -0,0 +1,19 @@ +<%=I18n.t('user_mailer.app_download_reminder1.greeting') -%> <%= @user.first_name -%> + +<%=I18n.t('user_mailer.app_download_reminder1.paragraph1') -%> + +<%=I18n.t('user_mailer.app_download_reminder1.paragraph2') -%> +<%=I18n.t('user_mailer.app_download_reminder1.paragraph2_list_item1') -%> +<%=I18n.t('user_mailer.app_download_reminder1.paragraph2_list_item2') -%> + +<%= APP_CONFIG.spa_origin_url %>/public/downloads + +<%= APP_CONFIG.spa_origin_url %>/public/downloads-legacy + +<%=I18n.t('user_mailer.app_download_reminder1.paragraph3') -%> + +<%=I18n.t('user_mailer.app_download_reminder1.paragraph4') -%> + +<%=I18n.t('user_mailer.app_download_reminder1.regards') -%> + +<%=I18n.t('user_mailer.app_download_reminder1.signature') -%> \ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/app_download_reminder2.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/app_download_reminder2.html.erb new file mode 100644 index 000000000..7e80262b8 --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/app_download_reminder2.html.erb @@ -0,0 +1,66 @@ +

<%=I18n.t('user_mailer.app_download_reminder2.greeting') -%> <%= @user.first_name -%> -

+ +

+ <%=I18n.t('user_mailer.app_download_reminder2.paragraph1') -%> +

+ +

+ <%=I18n.t('user_mailer.app_download_reminder2.paragraph2') -%> +

+ +

+ <%=I18n.t('user_mailer.app_download_reminder2.paragraph3') -%> +

    +
  • <%=I18n.t('user_mailer.app_download_reminder2.paragraph3_list_item1') -%>
  • +
  • <%=I18n.t('user_mailer.app_download_reminder2.paragraph3_list_item2') -%>
  • +
+

+ +

+ + <%=I18n.t('user_mailer.app_download_reminder2.download_app') -%> + + + + <%=I18n.t('user_mailer.app_download_reminder2.download_legacy_app') -%> + +

+ +

+ <%=I18n.t('user_mailer.app_download_reminder2.paragraph4') -%> +

+ +

+ <%=I18n.t('user_mailer.app_download_reminder2.paragraph5') -%> +

+ +
+

+ <%=I18n.t('user_mailer.app_download_reminder2.regards') -%> +
+ <%=I18n.t('user_mailer.app_download_reminder2.signature') -%> +

+
\ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/app_download_reminder2.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/app_download_reminder2.text.erb new file mode 100644 index 000000000..1afcfc62b --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/app_download_reminder2.text.erb @@ -0,0 +1,21 @@ +<%=I18n.t('user_mailer.app_download_reminder2.greeting') -%> <%= @user.first_name -%> + +<%=I18n.t('user_mailer.app_download_reminder2.paragraph1') -%> + +<%=I18n.t('user_mailer.app_download_reminder2.paragraph2') -%> + +<%=I18n.t('user_mailer.app_download_reminder2.paragraph3') -%> +<%=I18n.t('user_mailer.app_download_reminder2.paragraph3_list_item1') -%> +<%=I18n.t('user_mailer.app_download_reminder2.paragraph3_list_item2') -%> + +<%= APP_CONFIG.spa_origin_url %>/public/downloads + +<%= APP_CONFIG.spa_origin_url %>/public/downloads-legacy + +<%=I18n.t('user_mailer.app_download_reminder2.paragraph4') -%> + +<%=I18n.t('user_mailer.app_download_reminder2.paragraph5') -%> + +<%=I18n.t('user_mailer.app_download_reminder2.regards') -%> + +<%=I18n.t('user_mailer.app_download_reminder2.signature') -%> \ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/app_download_reminder3.html.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/app_download_reminder3.html.erb new file mode 100644 index 000000000..efd348edc --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/app_download_reminder3.html.erb @@ -0,0 +1,62 @@ +

<%=I18n.t('user_mailer.app_download_reminder3.greeting') -%> <%= @user.first_name -%> -

+ +

+ <%=I18n.t('user_mailer.app_download_reminder3.paragraph1') -%> +

+ +

+ <%=I18n.t('user_mailer.app_download_reminder3.paragraph2') -%> +

    +
  • <%=I18n.t('user_mailer.app_download_reminder3.paragraph2_list_item1') -%>
  • +
  • <%=I18n.t('user_mailer.app_download_reminder3.paragraph2_list_item2') -%>
  • +
+

+ +

+ + <%=I18n.t('user_mailer.app_download_reminder3.download_app') -%> + + + + <%=I18n.t('user_mailer.app_download_reminder3.download_legacy_app') -%> + +

+ +

+ <%=I18n.t('user_mailer.app_download_reminder3.paragraph3') -%> +

+ +

+ <%=I18n.t('user_mailer.app_download_reminder3.paragraph4') -%> +

+ +
+

+ <%=I18n.t('user_mailer.app_download_reminder3.regards') -%> +
+ <%=I18n.t('user_mailer.app_download_reminder3.signature') -%> +

+
\ No newline at end of file diff --git a/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/app_download_reminder3.text.erb b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/app_download_reminder3.text.erb new file mode 100644 index 000000000..db6e93f01 --- /dev/null +++ b/ruby/lib/jam_ruby/app/views/jam_ruby/user_mailer/app_download_reminder3.text.erb @@ -0,0 +1,18 @@ +<%=I18n.t('user_mailer.app_download_reminder3.greeting') -%> <%= @user.first_name -%> + +<%=I18n.t('user_mailer.app_download_reminder3.paragraph1') -%> + +<%=I18n.t('user_mailer.app_download_reminder3.paragraph2') -%> +<%=I18n.t('user_mailer.app_download_reminder3.paragraph2_list_item1') -%> +<%=I18n.t('user_mailer.app_download_reminder3.paragraph2_list_item2') -%> + +<%= APP_CONFIG.spa_origin_url %>/public/downloads +<%= APP_CONFIG.spa_origin_url %>/public/downloads-legacy + +<%=I18n.t('user_mailer.app_download_reminder3.paragraph3') -%> + +<%=I18n.t('user_mailer.app_download_reminder3.paragraph4') -%> + +<%=I18n.t('user_mailer.app_download_reminder3.regards') -%> + +<%=I18n.t('user_mailer.app_download_reminder3.signature') -%> \ No newline at end of file diff --git a/ruby/lib/jam_ruby/lib/app_download_reminder.rb b/ruby/lib/jam_ruby/lib/app_download_reminder.rb new file mode 100644 index 000000000..a35124129 --- /dev/null +++ b/ruby/lib/jam_ruby/lib/app_download_reminder.rb @@ -0,0 +1,43 @@ +module JamRuby + class AppDownloadReminder + + def self.send_reminders + #If the user has not downloaded the app 2 days after signup, then send reminder email 1 + reminder1_users.each do |user| + UserMailer.app_download_reminder1(user).deliver_now + user.update(app_download_reminder1_sent_at: Time.now) + end + + #If the user has not downloaded the app 4 days after signup, then send reminder email2 + reminder2_users.each do |user| + UserMailer.app_download_reminder2(user).deliver_now + user.update(app_download_reminder2_sent_at: Time.now) + end + + #If the user has not downloaded the app 6 days after signup, then send reminder email3 + reminder3_users.each do |user| + UserMailer.app_download_reminder3(user).deliver_now + user.update(app_download_reminder3_sent_at: Time.now) + end + + end + + def self.prospect_users + User.where("users.first_downloaded_client_at IS NULL") + end + + def self.reminder1_users + AppDownloadReminder.prospect_users.where("users.created_at > ? AND users.app_download_reminder1_sent_at IS NULL", 2.day.ago) + end + + def self.reminder2_users + AppDownloadReminder.prospect_users.where("users.created_at > ? AND users.app_download_reminder1_sent_at IS NOT NULL AND users.app_download_reminder2_sent_at IS NULL", 4.days.ago) + end + + def self.reminder3_users + AppDownloadReminder.prospect_users.where("users.created_at > ? AND users.app_download_reminder2_sent_at IS NOT NULL AND users.app_download_reminder3_sent_at IS NULL", 6.days.ago) + end + + end +end +# == Schema Information \ No newline at end of file diff --git a/ruby/lib/jam_ruby/resque/scheduled/hourly_job.rb b/ruby/lib/jam_ruby/resque/scheduled/hourly_job.rb index a73b813b9..71cd9e290 100644 --- a/ruby/lib/jam_ruby/resque/scheduled/hourly_job.rb +++ b/ruby/lib/jam_ruby/resque/scheduled/hourly_job.rb @@ -14,6 +14,7 @@ module JamRuby User.hourly_check AffiliatePartner.tally_up(Date.today) EmailProfileReminder.send_reminders + AppDownloadReminder.send_reminders ConnectionManager.new.cleanup_dangling @@log.info("done") diff --git a/web/app/views/api_users/profile_show.rabl b/web/app/views/api_users/profile_show.rabl index 0a1d169ed..792e551a6 100644 --- a/web/app/views/api_users/profile_show.rabl +++ b/web/app/views/api_users/profile_show.rabl @@ -1,7 +1,7 @@ object @profile attributes :id, :first_name, :last_name, :name, :city, :state, :country, :location, :online, :photo_url, :musician, :gender, :birth_date, :internet_service_provider, :friend_count, :liker_count, :like_count, :follower_count, :following_count, :recording_count, :session_count, :biography, :favorite_count, :audio_latency, :upcoming_session_count, :age, :website, :skill_level, :concert_count, :studio_session_count, :virtual_band, :virtual_band_commitment, :traditional_band, :traditional_band_commitment, :traditional_band_touring, :paid_sessions, :paid_sessions_hourly_rate, -:paid_sessions_daily_rate, :free_sessions, :cowriting, :cowriting_purpose, :subscribe_email, :is_a_teacher, :is_a_student, :last_active_timestamp, :v2_photo_url, :v2_photo_uploaded +:paid_sessions_daily_rate, :free_sessions, :cowriting, :cowriting_purpose, :subscribe_email, :is_a_teacher, :is_a_student, :last_active_timestamp, :v2_photo_url, :v2_photo_uploaded, :first_downloaded_client_at child :online_presences => :online_presences do attributes :id, :service_type, :username diff --git a/web/config/locales/en.yml b/web/config/locales/en.yml index 92778cd01..6b09d9067 100644 --- a/web/config/locales/en.yml +++ b/web/config/locales/en.yml @@ -83,7 +83,6 @@ en: paragraph4: "For next steps, don’t forget you can always refer back to the Welcome email we sent you when you signed up. And if you run into any problems or get stuck, please send us email at support@jamkazam.com. We’re always happy to help" regards: "Best Regards," signature: "JamKazam Team" - profile_complete_reminder2: subject: "Complete your JamKazam profile" greeting: "Hello" @@ -92,7 +91,6 @@ en: paragraph2: "For next steps after your profile, don’t forget you can always refer back to the Welcome email we sent you when you signed up. And if you run into any problems or get stuck, please send us email at support@jamkazam.com. We’re always happy to help!" regards: "Best Regards," signature: "JamKazam Team" - profile_complete_reminder3: subject: "Complete your JamKazam profile" greeting: "Hello" @@ -100,3 +98,45 @@ en: update_profile: "Update Profile" regards: "Best Regards," signature: "JamKazam Team" + app_download_reminder1: + subject: "Download the free JamKazam app now – it’s your next step" + next_step: "Next Step: Download Jamkazam App" + greeting: "Hello" + paragraph1: "The next thing you should do with JamKazam is download and install our free app for Windows or Mac. You’ll need this app to play music online with others, and the app also gives you access to more advanced JamTracks features if you’re interested in using our huge catalog of backing tracks." + paragraph2: "To go to the app download page, most users should click the Download App button below, with these exceptions:" + paragraph2_list_item1: "If you’re on a Mac that can’t run MacOS 10.15 or later, click the Download Legacy App button, as that version of the app supports older MacOS versions back to 10.7." + paragraph2_list_item2: "If you’re on Windows 7, click the Download Legacy App button, as that version of the app supports Windows 7 computers." + download_app: "Download App" + download_legacy_app: "Download Legacy App" + not_now: "Not Now" + paragraph3: "After downloading, double click the downloaded installer, and then follow the on-screen instructions to install the app." + paragraph4: "For next steps after downloading and installing the app, don’t forget you can always refer back to the Welcome email we sent you when you signed up. And if you run into any problems or get stuck, please send us email at support@jamkazam.com. We’re always happy to help!" + regards: "Best Regards," + signature: "JamKazam Team" + app_download_reminder2: + subject: "Take 2 minutes to get the free JamKazam app now & connect with other musicians" + greeting: "Hello" + paragraph1: "We share your profile with JamKazam members who may be a good fit to play music with you during your first week on the platform via an automated email feature. Don’t miss this opportunity to get connected!" + paragraph2: "One of the critical pieces of information in getting you connected is your latency to other musicians on JamKazam (this is the amount of time it takes to get your audio to them). To get this information, you need to download and install the JamKazam app, and then open it and let it run for about 15 minutes. During this time, the app will run Internet tests that measure your latency to other musicians on our platform." + paragraph3: "To go to the app download page, most users should click the Download App button below, with these exceptions:" + paragraph3_list_item1: "If you’re on a Mac that can’t run MacOS 10.15 or later, click the Download Legacy App button, as that version of the app supports older MacOS versions back to 10.7." + paragraph3_list_item2: "If you’re on Windows 7, click the Download Legacy App button, as that version of the app supports Windows 7 computers." + download_app: "Download App" + download_legacy_app: "Download Legacy App" + paragraph4: "After downloading, double click the downloaded installer, and then follow the on-screen instructions to install the app." + paragraph5: "For next steps after downloading and installing the app, don’t forget you can always refer back to the Welcome email we sent you when you signed up. And if you run into any problems or get stuck, please send us email at support@jamkazam.com. We’re always happy to help!" + regards: "Best Regards," + signature: "JamKazam Team" + app_download_reminder3: + subject: "Don’t waste your free 30-day premium gold plan, get the JamKazam app now!" + greeting: "Hello" + paragraph1: "When you sign up for JamKazam, we give you a free 30-day premium gold plan so you can fully experience how amazing our online sessions are and how JamKazam can help you play more music with more people to bring more musical joy to your life." + paragraph2: "Don’t waste your 30-day window! Get the free JamKazam app now and get started. To go to the app download page, most users should click the Download App button below, with these exceptions:" + paragraph2_list_item1: "If you’re on a Mac that can’t run MacOS 10.15 or later, click the Download Legacy App button, as that version of the app supports older MacOS versions back to 10.7." + paragraph2_list_item2: "If you’re on Windows 7, click the Download Legacy App button, as that version of the app supports Windows 7 computers." + download_app: "Download App" + download_legacy_app: "Download Legacy App" + paragraph3: "After downloading, double click the downloaded installer, and then follow the on-screen instructions to install the app." + paragraph4: "For next steps after downloading and installing the app, don’t forget you can always refer back to the Welcome email we sent you when you signed up. And if you run into any problems or get stuck, please send us email at support@jamkazam.com. We’re always happy to help!" + regards: "Best Regards," + signature: "JamKazam Team" \ No newline at end of file