Merge branch 'develop' into seth/obs-download
This commit is contained in:
commit
a64873d7a6
|
|
@ -4,7 +4,7 @@ import { Link } from 'react-router-dom';
|
|||
import FalconCardHeader from '../common/FalconCardHeader';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { fetchSessions } from '../../store/features/sessionsSlice';
|
||||
import { fetchSessions, fetchFriendsSessions, fetchPublicSessions, fetchInactiveSessions } from '../../store/features/sessionsSlice';
|
||||
import { isIterableArray } from '../../helpers/utils';
|
||||
import { useResponsive } from '@farfetch/react-context-responsive';
|
||||
import JKModalDialog from '../common/JKModalDialog';
|
||||
|
|
@ -23,7 +23,10 @@ function JKMusicSessions() {
|
|||
const { nativeAppUnavailable, setNativeAppUnavailable } = useNativeApp();
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(fetchSessions());
|
||||
// dispatch(fetchSessions());
|
||||
dispatch(fetchFriendsSessions());
|
||||
dispatch(fetchPublicSessions());
|
||||
//dispatch(fetchInactiveSessions());
|
||||
}, []);
|
||||
|
||||
const toggleAppUnavilableModel = () => {
|
||||
|
|
@ -37,7 +40,7 @@ function JKMusicSessions() {
|
|||
<CardBody className="pt-0">
|
||||
{loadingStatus === 'loading' && sessions.length === 0 ? (
|
||||
<Loader />
|
||||
) : isIterableArray(sessions) ? (
|
||||
) : loadingStatus === "succeeded" && sessions.length > 0 ? (
|
||||
<>
|
||||
{greaterThan.sm ? (
|
||||
<Row className="mb-3 justify-content-between d-none d-md-block">
|
||||
|
|
@ -51,7 +54,7 @@ function JKMusicSessions() {
|
|||
</Row>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
) : loadingStatus === "succeeded" && sessions.length <= 0 ? (
|
||||
<Row className="p-card">
|
||||
<Col>
|
||||
{t('list.no_records_1', { ns: 'sessions' })}
|
||||
|
|
@ -59,7 +62,13 @@ function JKMusicSessions() {
|
|||
{t('list.no_records_2', { ns: 'sessions' })}
|
||||
</Col>
|
||||
</Row>
|
||||
)}
|
||||
) : loadingStatus === "failed" ? (
|
||||
<Row className="p-card">
|
||||
<Col>
|
||||
{t('list.error', { ns: 'sessions' })}
|
||||
</Col>
|
||||
</Row>
|
||||
) : null }
|
||||
</CardBody>
|
||||
</Card>
|
||||
<JKModalDialog
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ const JKDownloads = () => {
|
|||
</p>
|
||||
<div className='mt-2 d-flex flex-column flex-md-row'>
|
||||
<div style={ { flexGrow: 0, flexShrink: 0, flexBasis: '25%' } }>
|
||||
<a href={downloadLink} target='_blank'>
|
||||
<a href={downloadLink} target='_blank' style={{ cursor: 'pointer' }}>
|
||||
<img src={downloadImageUrl} alt="Download JamKazam" />
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -72,8 +72,9 @@ const JKDownloadsLegacy = () => {
|
|||
|
||||
const downloadLink = React.useMemo(() => {
|
||||
if (!currentOS) return null
|
||||
return downloads[`JamClient/${currentOS}`]
|
||||
}, [currentOS]);
|
||||
if (!selectedPlatform) return null
|
||||
return downloads[`JamClient/${selectedPlatform}`]
|
||||
}, [currentOS, selectedPlatform]);
|
||||
|
||||
const selectPlatform = (platform) => {
|
||||
setSelectedPlatform(platform)
|
||||
|
|
@ -126,7 +127,7 @@ const JKDownloadsLegacy = () => {
|
|||
</p>
|
||||
<div className='mt-2 d-flex flex-column flex-md-row'>
|
||||
<div style={ { flexGrow: 0, flexShrink: 0, flexBasis: '25%' } }>
|
||||
<a href={downloadLink} target='_blank'>
|
||||
<a href={downloadLink} target='_blank' style={ { cursor: 'pointer' } }>
|
||||
<img src={downloadImageUrl} alt="Download JamKazam" />
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ function JKSession({ session }) {
|
|||
|
||||
|
||||
useEffect(() => {
|
||||
const otherUserIds = session.participants.map(p => p.user.id);
|
||||
const otherUserIds = session.active_music_session ? session.active_music_session.participants.map(p => p.user.id) : [];
|
||||
const options = { currentUserId: currentUser.id, otherUserIds };
|
||||
dispatch(fetchUserLatencies(options));
|
||||
}, [session.id]);
|
||||
|
|
@ -40,7 +40,7 @@ function JKSession({ session }) {
|
|||
};
|
||||
|
||||
const hasFriendNote = session => {
|
||||
if (session.participants.find(p => p.user.is_friend)) {
|
||||
if (session.active_music_session && session.active_music_session.participants.find(p => p.user.is_friend)) {
|
||||
return t('list.notes.has_friend', { ns: 'sessions' });
|
||||
}
|
||||
};
|
||||
|
|
@ -71,26 +71,38 @@ function JKSession({ session }) {
|
|||
</div>
|
||||
<div>{sessionDescription}</div>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{session.participants.map(participant => (
|
||||
{session.active_music_session && session.active_music_session.participants.length > 0 && (
|
||||
<>
|
||||
{session.active_music_session.participants.map(participant => (
|
||||
<Row style={musicianRowStyle} key={participant.id}>
|
||||
<Col>
|
||||
<JKSessionUser user={participant.user} />
|
||||
</Col>
|
||||
</Row>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
|
||||
</td>
|
||||
<td className="text-center">
|
||||
{session.participants.map(participant => (
|
||||
{session.active_music_session && session.active_music_session.participants.length > 0 && (
|
||||
<>
|
||||
{session.active_music_session.participants.map(participant => (
|
||||
<Row key={participant.id} style={musicianRowStyle}>
|
||||
<Col>
|
||||
<JKUserLatencyBadge key={participant.id} user={participant.user} showBadgeOnly={true} />
|
||||
</Col>
|
||||
</Row>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</td>
|
||||
<td>
|
||||
{session.participants.map(participant => (
|
||||
{session.active_music_session && session.active_music_session.participants.length > 0 && (
|
||||
<>
|
||||
{session.active_music_session.participants.map(participant => (
|
||||
<Row style={musicianRowStyle} key={participant.id} data-testid={`Participant${participant.id}Tracks`}>
|
||||
<Col>
|
||||
{participant.tracks.map(track => (
|
||||
|
|
@ -113,6 +125,8 @@ function JKSession({ session }) {
|
|||
</Col>
|
||||
</Row>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</td>
|
||||
<td className="text-center">
|
||||
<JoinSessionButton session={session} />
|
||||
|
|
@ -142,11 +156,13 @@ function JKSession({ session }) {
|
|||
<strong>{t('list.header.latency', { ns: 'sessions' })}</strong>
|
||||
</div>
|
||||
</div>
|
||||
{session.active_music_session && session.active_music_session.participants.length > 0 && (
|
||||
<div>
|
||||
{session.participants.map(participant => (
|
||||
{session.active_music_session.participants.map(participant => (
|
||||
<JKSessionUser key={participant.id} user={participant.user} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<div className="mt-4 d-flex flex-row justify-content-center">
|
||||
<JoinSessionButton session={session} />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -213,6 +213,30 @@ export const getSessions = () => {
|
|||
});
|
||||
};
|
||||
|
||||
export const getFriendsSessions = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
apiFetch(`/sessions/friends`)
|
||||
.then(response => resolve(response))
|
||||
.catch(error => reject(error));
|
||||
});
|
||||
};
|
||||
|
||||
export const getPublicSessions = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
apiFetch(`/sessions/public`)
|
||||
.then(response => resolve(response))
|
||||
.catch(error => reject(error));
|
||||
});
|
||||
};
|
||||
|
||||
export const getInactiveSessions = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
apiFetch(`/sessions/inactive`)
|
||||
.then(response => resolve(response))
|
||||
.catch(error => reject(error));
|
||||
});
|
||||
};
|
||||
|
||||
export const getSessionsHistory = (options = {}) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
apiFetch(`/sessions/history?${new URLSearchParams(options)}`)
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@
|
|||
},
|
||||
"no_records_1": "There are no public, open sessions currently available for you to join. We suggest you ",
|
||||
"create_session": "create a session",
|
||||
"no_records_2": " that others can join now, or wait a bit and then refresh this page in your browser to see if new public sessions have been started."
|
||||
"no_records_2": " that others can join now, or wait a bit and then refresh this page in your browser to see if new public sessions have been started.",
|
||||
"error": "There was an error retrieving the session list. Please try again."
|
||||
},
|
||||
"lobby": {
|
||||
"page_title": "Lobby",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
|
||||
import { getSessions, getPersonById } from '../../helpers/rest'
|
||||
import { getSessions, getFriendsSessions, getPublicSessions, getInactiveSessions, getPersonById } from '../../helpers/rest'
|
||||
|
||||
const initialState = {
|
||||
sessions: [],
|
||||
|
|
@ -14,7 +14,30 @@ export const fetchSessions = createAsyncThunk(
|
|||
const response = await getSessions();
|
||||
return response.json();
|
||||
}
|
||||
)
|
||||
|
||||
export const fetchFriendsSessions = createAsyncThunk(
|
||||
"session/fetchFriendsSessions",
|
||||
async (options, thunkAPI) => {
|
||||
const response = await getFriendsSessions(options);
|
||||
return response.json();
|
||||
}
|
||||
)
|
||||
|
||||
export const fetchPublicSessions = createAsyncThunk(
|
||||
"session/fetchPublicSessions",
|
||||
async (options, thunkAPI) => {
|
||||
const response = await getPublicSessions(options);
|
||||
return response.json();
|
||||
}
|
||||
)
|
||||
|
||||
export const fetchInactiveSessions = createAsyncThunk(
|
||||
"session/fetchInactiveSessions",
|
||||
async (options, thunkAPI) => {
|
||||
const response = await getInactiveSessions(options);
|
||||
return response.json();
|
||||
}
|
||||
)
|
||||
|
||||
export const fetchPerson = createAsyncThunk(
|
||||
|
|
@ -51,14 +74,54 @@ export const SessionSlice = createSlice({
|
|||
state.status = "loading";
|
||||
})
|
||||
.addCase(fetchSessions.fulfilled, (state, action) => {
|
||||
console.log(action.payload);
|
||||
// add unique sessions to the array
|
||||
const records = new Set([...state.sessions, ...action.payload]);
|
||||
const unique = [];
|
||||
records.map(x => unique.filter(p => p.id === x.id).length > 0 ? null : unique.push(x))
|
||||
state.sessions = unique;
|
||||
state.error = null;
|
||||
state.status = "succeeded";
|
||||
state.sessions = action.payload;
|
||||
})
|
||||
.addCase(fetchSessions.rejected, (state, action) => {
|
||||
state.status = 'failed'
|
||||
state.error = action.error.message
|
||||
})
|
||||
.addCase(fetchFriendsSessions.pending, (state, action) => {
|
||||
state.status = "loading";
|
||||
})
|
||||
.addCase(fetchFriendsSessions.fulfilled, (state, action) => {
|
||||
// add unique sessions to the array
|
||||
const records = new Set([...state.sessions, ...action.payload.sessions]);
|
||||
const unique = [];
|
||||
records.map(x => unique.filter(p => p.id === x.id).length > 0 ? null : unique.push(x))
|
||||
state.sessions = unique;
|
||||
state.error = null;
|
||||
state.status = "succeeded";
|
||||
})
|
||||
.addCase(fetchPublicSessions.pending, (state, action) => {
|
||||
state.status = "loading";
|
||||
})
|
||||
.addCase(fetchPublicSessions.fulfilled, (state, action) => {
|
||||
// add unique sessions to the array
|
||||
const records = new Set([...state.sessions, ...action.payload.sessions]);
|
||||
const unique = [];
|
||||
records.map(x => unique.filter(p => p.id === x.id).length > 0 ? null : unique.push(x))
|
||||
state.sessions = unique;
|
||||
state.error = null;
|
||||
state.status = "succeeded";
|
||||
})
|
||||
.addCase(fetchInactiveSessions.pending, (state, action) => {
|
||||
state.status = "loading";
|
||||
})
|
||||
.addCase(fetchInactiveSessions.fulfilled, (state, action) => {
|
||||
// add unique sessions to the array
|
||||
const records = new Set([...state.sessions, ...action.payload.sessions]);
|
||||
const unique = [];
|
||||
records.map(x => unique.filter(p => p.id === x.id).length > 0 ? null : unique.push(x))
|
||||
state.sessions = unique;
|
||||
state.error = null;
|
||||
state.status = "succeeded";
|
||||
})
|
||||
.addCase(fetchPerson.fulfilled, (state, action) => {
|
||||
const person = state.people.find(person => person.id === action.payload.id)
|
||||
if (person) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
class AddProfileCompleteColumnsToUsers < ActiveRecord::Migration
|
||||
def self.up
|
||||
execute "ALTER TABLE users ADD COLUMN profile_completed_at TIMESTAMP"
|
||||
#add index on profile_completed_at
|
||||
execute "CREATE INDEX index_users_on_profile_completed_at ON users USING btree (profile_completed_at)"
|
||||
execute "ALTER TABLE users ADD COLUMN profile_complete_reminder1_sent_at TIMESTAMP"
|
||||
execute "ALTER TABLE users ADD COLUMN profile_complete_reminder2_sent_at TIMESTAMP"
|
||||
execute "ALTER TABLE users ADD COLUMN profile_complete_reminder3_sent_at TIMESTAMP"
|
||||
|
||||
User.find_each(batch_size:100) do |user|
|
||||
User.where(id:user.id).update_all(profile_completed_at: Time.now)
|
||||
end
|
||||
#User.where('users.id IN (SELECT player_id FROM musicians_instruments) OR users.id IN (SELECT player_id FROM genre_players)').update_all(profile_completed_at: Time.now)
|
||||
end
|
||||
def self.down
|
||||
execute "ALTER TABLE users DROP COLUMN profile_completed_at"
|
||||
execute "ALTER TABLE users DROP COLUMN profile_complete_reminder1_sent_at"
|
||||
execute "ALTER TABLE users DROP COLUMN profile_complete_reminder2_sent_at"
|
||||
execute "ALTER TABLE users DROP COLUMN profile_complete_reminder3_sent_at"
|
||||
end
|
||||
end
|
||||
=begin
|
||||
ALTER TABLE users ADD COLUMN profile_completed_at TIMESTAMP;
|
||||
CREATE INDEX index_users_on_profile_completed_at ON users USING btree (profile_completed_at);
|
||||
ALTER TABLE users ADD COLUMN profile_complete_reminder1_sent_at TIMESTAMP;
|
||||
ALTER TABLE users ADD COLUMN profile_complete_reminder2_sent_at TIMESTAMP;
|
||||
ALTER TABLE users ADD COLUMN profile_complete_reminder3_sent_at TIMESTAMP;
|
||||
UPDATE users set profile_completed_at=NOW() WHERE users.id IN (SELECT player_id FROM musicians_instruments) OR users.id IN (SELECT player_id FROM genre_players);
|
||||
end
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
class AddGearSetupReminderColumnsToUsers < ActiveRecord::Migration
|
||||
def self.up
|
||||
execute "ALTER TABLE users ADD COLUMN gear_setup_reminder1_sent_at TIMESTAMP"
|
||||
execute "ALTER TABLE users ADD COLUMN gear_setup_reminder2_sent_at TIMESTAMP"
|
||||
execute "ALTER TABLE users ADD COLUMN gear_setup_reminder3_sent_at TIMESTAMP"
|
||||
end
|
||||
|
||||
def self.down
|
||||
execute "ALTER TABLE users DROP COLUMN gear_setup_reminder1_sent_at"
|
||||
execute "ALTER TABLE users DROP COLUMN gear_setup_reminder2_sent_at"
|
||||
execute "ALTER TABLE users DROP COLUMN gear_setup_reminder3_sent_at"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
=begin
|
||||
ALTER TABLE users ADD COLUMN gear_setup_reminder1_sent_at TIMESTAMP;
|
||||
ALTER TABLE users ADD COLUMN gear_setup_reminder2_sent_at TIMESTAMP;
|
||||
ALTER TABLE users ADD COLUMN gear_setup_reminder3_sent_at TIMESTAMP;
|
||||
end
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
class AddSignupSurveySentAtToUsers < ActiveRecord::Migration
|
||||
def self.up
|
||||
execute "ALTER TABLE users ADD COLUMN signup_survey_sent_at TIMESTAMP"
|
||||
User.find_each(batch_size:100) do |user|
|
||||
User.where(id:user.id).update_all(signup_survey_sent_at: Time.now)
|
||||
end
|
||||
end
|
||||
def self.down
|
||||
execute "ALTER TABLE users DROP COLUMN signup_survey_sent_at"
|
||||
end
|
||||
end
|
||||
=begin
|
||||
ALTER TABLE users ADD COLUMN signup_survey_sent_at TIMESTAMP;
|
||||
CREATE INDEX index_users_on_signup_survey_sent_at ON users USING btree (signup_survey_sent_at);
|
||||
|
||||
User.find_each(batch_size:100) do |user|
|
||||
User.where(id:user.id).update_all(signup_survey_sent_at: Time.now)
|
||||
end
|
||||
=end
|
||||
|
|
@ -120,6 +120,9 @@ require "jam_ruby/lib/subscription_message"
|
|||
require "jam_ruby/lib/stats.rb"
|
||||
require "jam_ruby/lib/email_new_musician_match"
|
||||
require "jam_ruby/lib/musician_filter"
|
||||
require "jam_ruby/lib/email_profile_reminder"
|
||||
require "jam_ruby/lib/email_signup_survey"
|
||||
require "jam_ruby/lib/gear_setup_reminder"
|
||||
require "jam_ruby/amqp/amqp_connection_manager"
|
||||
require "jam_ruby/database"
|
||||
require "jam_ruby/message_factory"
|
||||
|
|
|
|||
|
|
@ -418,6 +418,78 @@ module JamRuby
|
|||
end
|
||||
end
|
||||
|
||||
def profile_complete_reminder1(user)
|
||||
@user = user
|
||||
sendgrid_recipients([user.email])
|
||||
sendgrid_substitute('@USERID', [user.id])
|
||||
sendgrid_unique_args :type => "profile_complete_reminder1"
|
||||
|
||||
mail(:to => user.email, :subject => I18n.t('user_mailer.profile_complete_reminder1.subject')) do |format|
|
||||
format.text
|
||||
format.html { render layout: "user_mailer_beta" }
|
||||
end
|
||||
end
|
||||
|
||||
def profile_complete_reminder2(user)
|
||||
@user = user
|
||||
sendgrid_recipients([user.email])
|
||||
sendgrid_substitute('@USERID', [user.id])
|
||||
sendgrid_unique_args :type => "profile_complete_reminder2"
|
||||
|
||||
mail(:to => user.email, :subject => "Take 2 minutes to fill out your JamKazam profile now") do |format|
|
||||
format.text
|
||||
format.html { render layout: "user_mailer_beta" }
|
||||
end
|
||||
end
|
||||
|
||||
def profile_complete_reminder3(user)
|
||||
@user = user
|
||||
sendgrid_recipients([user.email])
|
||||
sendgrid_substitute('@USERID', [user.id])
|
||||
sendgrid_unique_args :type => "profile_complete_reminder3"
|
||||
|
||||
mail(:to => user.email, :subject => "Last reminder to update your JamKazam profile") do |format|
|
||||
format.text
|
||||
format.html { render layout: "user_mailer_beta" }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#################################### GEAR SETUP REMINDER EMAILS ####################################
|
||||
def gear_setup_reminder1(user)
|
||||
@user = user
|
||||
mail(:to => user.email, :subject => I18n.t('user_mailer.gear_setup_reminder1.subject')) do |format|
|
||||
format.text
|
||||
format.html { render layout: "user_mailer_beta" }
|
||||
end
|
||||
end
|
||||
|
||||
def gear_setup_reminder2(user)
|
||||
@user = user
|
||||
mail(:to => user.email, :subject => I18n.t('user_mailer.gear_setup_reminder2.subject')) do |format|
|
||||
format.text
|
||||
format.html { render layout: "user_mailer_beta" }
|
||||
end
|
||||
end
|
||||
|
||||
def gear_setup_reminder3(user)
|
||||
@user = user
|
||||
mail(:to => user.email, :subject => I18n.t('user_mailer.gear_setup_reminder3.subject')) do |format|
|
||||
format.text
|
||||
format.html { render layout: "user_mailer_beta" }
|
||||
end
|
||||
end
|
||||
|
||||
def signup_survey(user)
|
||||
@user = user
|
||||
@subject = I18n.t('user_mailer.signup_survey.subject')
|
||||
@survey_url = Rails.application.config.signup_survey_url
|
||||
mail(:to => user.email, :subject => @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
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
<p><%=I18n.t('user_mailer.gear_setup_reminder1.greeting') -%> <%= @user.first_name -%> -</p>
|
||||
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder1.paragraph1').html_safe -%>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder1.paragraph2').html_safe -%>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder1.paragraph3').html_safe -%>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder1.paragraph4').html_safe -%>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder1.regards') -%>,<br />
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder1.signature') -%>
|
||||
</p>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<%=I18n.t('user_mailer.gear_setup_reminder1.greeting') -%> <%= @user.first_name -%>
|
||||
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder1.paragraph1') -%>
|
||||
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder1.paragraph2') -%>
|
||||
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder1.paragraph3') -%>
|
||||
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder1.paragraph4') -%>
|
||||
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder1.regards') -%>,
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder1.signature') -%>
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<p><%=I18n.t('user_mailer.gear_setup_reminder2.greeting') -%> <%= @user.first_name -%> -</p>
|
||||
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder2.paragraph1').html_safe -%>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder2.paragraph2').html_safe -%>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder2.paragraph3').html_safe -%>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder2.paragraph4').html_safe -%>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder2.paragraph5').html_safe -%>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder2.regards') -%>,<br />
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder2.signature') -%>
|
||||
</p>
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<%=I18n.t('user_mailer.gear_setup_reminder2.greeting') -%> <%= @user.first_name -%>
|
||||
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder2.paragraph1') -%>
|
||||
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder2.paragraph2') -%>
|
||||
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder2.paragraph3') -%>
|
||||
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder2.paragraph4') -%>
|
||||
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder2.paragraph5') -%>
|
||||
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder2.regards') -%>,
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder2.signature') -%>
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<p><%=I18n.t('user_mailer.gear_setup_reminder3.greeting') -%> <%= @user.first_name -%> -</p>
|
||||
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder3.paragraph1').html_safe -%>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder3.paragraph2').html_safe -%>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder3.paragraph3').html_safe -%>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder3.paragraph4').html_safe -%>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder3.paragraph5').html_safe -%>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder3.regards') -%>,<br />
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder3.signature') -%>
|
||||
</p>
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<%=I18n.t('user_mailer.gear_setup_reminder3.greeting') -%> <%= @user.first_name -%>
|
||||
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder3.paragraph1') -%>
|
||||
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder3.paragraph2') -%>
|
||||
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder3.paragraph3') -%>
|
||||
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder3.paragraph4') -%>
|
||||
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder3.paragraph5') -%>
|
||||
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder3.regards') -%>,
|
||||
<%=I18n.t('user_mailer.gear_setup_reminder3.signature') -%>
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
<p><%=I18n.t('user_mailer.profile_complete_reminder1.greeting') -%> <%= @user.first_name -%> -</p>
|
||||
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder1.paragraph1') -%>
|
||||
</p>
|
||||
|
||||
<p style="text-align:center">
|
||||
<a href="<%= APP_CONFIG.spa_origin_url %>/profile" style="color: #fff;
|
||||
text-decoration: none;
|
||||
background-color: #2c7be5;
|
||||
border-color: #2c7be5;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.3125rem 1rem;
|
||||
line-height: 2.5;
|
||||
font-size: 1em;
|
||||
border-radius: 0.25rem;
|
||||
transition: color 0.15s ease-in-out,
|
||||
background-color 0.15s ease-in-out, border-color 0.15s ease-in-out,
|
||||
box-shadow 0.15s ease-in-out;">
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder1.update_profile') -%>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder1.paragraph2') -%>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder1.paragraph3') -%>
|
||||
</p>
|
||||
|
||||
<p style="text-align:center">
|
||||
<a href="<%= APP_CONFIG.external_root_url %>/downloads" style="color: #fff;
|
||||
text-decoration: none;
|
||||
background-color: #2c7be5;
|
||||
border-color: #2c7be5;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.3125rem 1rem;
|
||||
margin-right: 1rem;
|
||||
line-height: 2.5;
|
||||
font-size: 1em;
|
||||
border-radius: 0.25rem;
|
||||
transition: color 0.15s ease-in-out,
|
||||
background-color 0.15s ease-in-out, border-color 0.15s ease-in-out,
|
||||
box-shadow 0.15s ease-in-out;">
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder1.download_app') -%>
|
||||
</a>
|
||||
<a href="<%= APP_CONFIG.external_root_url %>/downloads" style="color: #fff;
|
||||
text-decoration: none;
|
||||
background-color: #2c7be5;
|
||||
border-color: #2c7be5;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.3125rem 1rem;
|
||||
line-height: 2.5;
|
||||
font-size: 1em;
|
||||
border-radius: 0.25rem;
|
||||
transition: color 0.15s ease-in-out,
|
||||
background-color 0.15s ease-in-out, border-color 0.15s ease-in-out,
|
||||
box-shadow 0.15s ease-in-out;">
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder1.download_legacy_app') -%>
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder1.paragraph4') -%>
|
||||
</p>
|
||||
|
||||
<div>
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder1.regards') -%>
|
||||
<br />
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder1.signature') -%>
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<%=I18n.t('user_mailer.profile_complete_reminder1.greeting') -%> <%= @user.first_name -%> -
|
||||
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder1.paragraph1') -%>
|
||||
|
||||
<%= APP_CONFIG.spa_origin_url %>/profile
|
||||
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder1.paragraph2') -%>
|
||||
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder1.paragraph3') -%>
|
||||
|
||||
<%= APP_CONFIG.external_root_url %>/downloads
|
||||
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder1.paragraph4') -%>
|
||||
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder1.regards') -%>
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder1.signature') -%>
|
||||
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<p><%=I18n.t('user_mailer.profile_complete_reminder2.greeting') -%> <%= @user.first_name -%> -</p>
|
||||
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder2.paragraph1') -%>
|
||||
</p>
|
||||
|
||||
<p style="text-align:center">
|
||||
<a href="<%= APP_CONFIG.spa_origin_url %>/profile" style="color: #fff;
|
||||
text-decoration: none;
|
||||
background-color: #2c7be5;
|
||||
border-color: #2c7be5;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.3125rem 1rem;
|
||||
line-height: 2.5;
|
||||
font-size: 1em;
|
||||
border-radius: 0.25rem;
|
||||
transition: color 0.15s ease-in-out,
|
||||
background-color 0.15s ease-in-out, border-color 0.15s ease-in-out,
|
||||
box-shadow 0.15s ease-in-out;">
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder2.update_profile') -%>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder2.paragraph2') -%>
|
||||
</p>
|
||||
|
||||
<div>
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder2.regards') -%>
|
||||
<br />
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder2.signature') -%>
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<%=I18n.t('user_mailer.profile_complete_reminder2.greeting') -%> <%= @user.first_name -%> -
|
||||
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder2.paragraph1') -%>
|
||||
|
||||
<%= APP_CONFIG.spa_origin_url %>/profile
|
||||
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder2.paragraph2') -%>
|
||||
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder2.regards') -%>
|
||||
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder2.signature') -%>
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<p><%=I18n.t('user_mailer.profile_complete_reminder3.greeting') -%> <%= @user.first_name -%> -</p>
|
||||
|
||||
<p><%=I18n.t('user_mailer.profile_complete_reminder3.paragraph1') -%>
|
||||
</p>
|
||||
|
||||
<p style="text-align:center">
|
||||
<a href="<%= APP_CONFIG.spa_origin_url %>/profile" style="color: #fff;
|
||||
text-decoration: none;
|
||||
background-color: #2c7be5;
|
||||
border-color: #2c7be5;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.3125rem 1rem;
|
||||
line-height: 2.5;
|
||||
font-size: 1em;
|
||||
border-radius: 0.25rem;
|
||||
transition: color 0.15s ease-in-out,
|
||||
background-color 0.15s ease-in-out, border-color 0.15s ease-in-out,
|
||||
box-shadow 0.15s ease-in-out;">
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder3.update_profile') -%>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<div>
|
||||
<p>
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder3.regards') -%>
|
||||
<br />
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder3.signature') -%>
|
||||
</p>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<%=I18n.t('user_mailer.profile_complete_reminder3.greeting') -%><%= @user.first_name -%> -
|
||||
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder3.paragraph1') -%>
|
||||
|
||||
<%= APP_CONFIG.spa_origin_url %>/profile
|
||||
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder3.regards') -%>
|
||||
|
||||
<%=I18n.t('user_mailer.profile_complete_reminder3.signature') -%>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<p><%= I18n.t 'user_mailer.signup_survey.greeting' -%> <%= @user.first_name -%> -</p>
|
||||
|
||||
<p>
|
||||
<%= I18n.t 'user_mailer.signup_survey.paragraph1' -%>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%= @survey_url %>
|
||||
</p>
|
||||
<p>
|
||||
<%= I18n.t 'user_mailer.signup_survey.ps' -%>
|
||||
<%= I18n.t 'user_mailer.signup_survey.ps_text' -%>
|
||||
</p>
|
||||
|
||||
|
||||
<p><%= I18n.t 'user_mailer.signup_survey.regards' -%><br/>
|
||||
<%= I18n.t 'user_mailer.signup_survey.signature' -%>
|
||||
</p>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<%= I18n.t 'user_mailer.signup_survey.greeting' -%> <%= @user.first_name -%> -
|
||||
|
||||
<%= I18n.t 'user_mailer.signup_survey.paragraph1' -%>
|
||||
|
||||
<%= @survey_url %>
|
||||
|
||||
<%= I18n.t 'user_mailer.signup_survey.ps' -%>
|
||||
<%= I18n.t 'user_mailer.signup_survey.ps_text' -%>
|
||||
|
||||
<%= I18n.t 'user_mailer.signup_survey.regards' -%>,
|
||||
<%= I18n.t 'user_mailer.signup_survey.signature' -%>
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
module JamRuby
|
||||
class EmailProfileReminder
|
||||
@@log = Logging.logger[EmailProfileReminder]
|
||||
|
||||
def self.send_reminders
|
||||
begin
|
||||
#If the user has not updated their profile 1 day after signup, then send reminder email1
|
||||
reminder1_users.find_each do |user|
|
||||
UserMailer.profile_complete_reminder1(user).deliver_now
|
||||
User.where(id: user.id).update_all(profile_complete_reminder1_sent_at: Time.now)
|
||||
end
|
||||
|
||||
#If the user has not updated their profile 3 days after signup, then send reminder email2
|
||||
reminder2_users.find_each do |user|
|
||||
UserMailer.profile_complete_reminder2(user).deliver_now
|
||||
User.where(id: user.id).update_all(profile_complete_reminder2_sent_at: Time.now)
|
||||
end
|
||||
|
||||
#If the user has not updated their profile 5 days after signup, then send reminder email3
|
||||
reminder3_users.find_each do |user|
|
||||
UserMailer.profile_complete_reminder3(user).deliver_now
|
||||
User.where(id: user.id).update_all(profile_complete_reminder3_sent_at: Time.now)
|
||||
end
|
||||
rescue Exception => e
|
||||
@@log.error("unable to send profile reminder email=#{e}")
|
||||
puts "unable to send profile reminder email=#{e}"
|
||||
end
|
||||
end
|
||||
|
||||
def self.prospect_users
|
||||
User.where("users.profile_completed_at IS NULL AND users.subscribe_email = ?", true)
|
||||
end
|
||||
|
||||
def self.reminder1_users
|
||||
EmailProfileReminder.prospect_users.where("users.created_at < ? AND users.profile_complete_reminder1_sent_at IS NULL", 1.day.ago)
|
||||
end
|
||||
|
||||
def self.reminder2_users
|
||||
EmailProfileReminder.prospect_users.where("users.created_at < ? AND users.profile_complete_reminder1_sent_at IS NOT NULL AND users.profile_complete_reminder2_sent_at IS NULL", 3.days.ago)
|
||||
end
|
||||
|
||||
def self.reminder3_users
|
||||
EmailProfileReminder.prospect_users.where("users.created_at < ? AND users.profile_complete_reminder2_sent_at IS NOT NULL AND users.profile_complete_reminder3_sent_at IS NULL", 5.days.ago)
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
module JamRuby
|
||||
class EmailSignupSurvey
|
||||
@@log = Logging.logger[EmailSignupSurvey]
|
||||
|
||||
def self.send_survey
|
||||
begin
|
||||
# if signup survey email has not been sent to this user, then send it
|
||||
survey_users.find_each do |user|
|
||||
UserMailer.signup_survey(user).deliver_now
|
||||
User.where(id: user.id).update_all(signup_survey_sent_at: Time.now)
|
||||
end
|
||||
rescue Exception => e
|
||||
@@log.error("unable to send surevy email e=#{e}")
|
||||
puts "unable to send surevy email e=#{e}"
|
||||
end
|
||||
end
|
||||
|
||||
def self.survey_users
|
||||
cutoff_date = Date.parse(Rails.application.config.signup_survey_cutoff_date) # Define a cutoff date for the survey/gear setup emails
|
||||
User.where("users.signup_survey_sent_at IS NULL AND users.created_at < ? AND users.created_at > ?", 1.days.ago, cutoff_date)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
module JamRuby
|
||||
class GearSetupReminder
|
||||
|
||||
@@log = Logging.logger[GearSetupReminder]
|
||||
|
||||
def self.send_reminders
|
||||
begin
|
||||
cutoff_date = Date.parse(Rails.application.config.signup_survey_cutoff_date) # Define a cutoff date for the survey/gear setup emails
|
||||
|
||||
reminder1_users(cutoff_date).find_each do |user|
|
||||
UserMailer.gear_setup_reminder1(user).deliver_now
|
||||
User.where(id: user.id).update_all(gear_setup_reminder1_sent_at: Time.now)
|
||||
end
|
||||
|
||||
reminder2_users(cutoff_date).find_each do |user|
|
||||
UserMailer.gear_setup_reminder2(user).deliver_now
|
||||
User.where(id: user.id).update_all(gear_setup_reminder2_sent_at: Time.now)
|
||||
end
|
||||
|
||||
reminder3_users(cutoff_date).find_each do |user|
|
||||
UserMailer.gear_setup_reminder3(user).deliver_now
|
||||
User.where(id: user.id).update_all(gear_setup_reminder3_sent_at: Time.now)
|
||||
end
|
||||
rescue Exception => e
|
||||
@@log.error("unable to send gear setup reminder email #{e}")
|
||||
puts "unable to send gear setup reminder email #{e}"
|
||||
end
|
||||
end
|
||||
|
||||
def self.prospect_users
|
||||
User.where("users.first_certified_gear_at IS NULL")
|
||||
end
|
||||
|
||||
def self.reminder1_users(cutoff_date)
|
||||
GearSetupReminder.prospect_users.where("users.created_at < ? AND users.created_at > ? AND users.gear_setup_reminder1_sent_at IS NULL", 1.day.ago, cutoff_date)
|
||||
end
|
||||
|
||||
def self.reminder2_users(cutoff_date)
|
||||
GearSetupReminder.prospect_users.where("users.created_at < ? AND users.created_at > ? AND users.gear_setup_reminder1_sent_at IS NOT NULL AND users.gear_setup_reminder2_sent_at IS NULL", 3.days.ago, cutoff_date)
|
||||
end
|
||||
|
||||
def self.reminder3_users(cutoff_date)
|
||||
GearSetupReminder.prospect_users.where("users.created_at < ? AND users.created_at > ? AND users.gear_setup_reminder2_sent_at IS NOT NULL AND users.gear_setup_reminder3_sent_at IS NULL", 5.days.ago, cutoff_date)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -863,6 +863,10 @@ module JamRuby
|
|||
self.save!(:validate => false)
|
||||
end
|
||||
|
||||
def in_session?(user)
|
||||
self.users.exists?(user.id)
|
||||
end
|
||||
|
||||
def connected_participant_count
|
||||
Connection.where(:music_session_id => self.id,
|
||||
:aasm_state => Connection::CONNECT_STATE.to_s,
|
||||
|
|
|
|||
|
|
@ -75,6 +75,11 @@ module JamRuby
|
|||
has_stream_mix
|
||||
end
|
||||
|
||||
def can_stop?(user)
|
||||
# only allow the starting-user to create (ideally, perhaps, only the client that did it)
|
||||
user == owner
|
||||
end
|
||||
|
||||
# this should be a has-one relationship. until this, this is easiest way to get from recording > mix
|
||||
def mix
|
||||
self.mixes[0] if self.mixes.length > 0
|
||||
|
|
@ -214,7 +219,7 @@ module JamRuby
|
|||
def has_access?(user)
|
||||
return false if user.nil?
|
||||
|
||||
users.exists?(user.id) || attached_with_lesson(user) #|| plays.where("player_id=?", user).count != 0
|
||||
users.exists?(user.id) || attached_with_lesson(user) || (music_session && music_session.in_session?(user))
|
||||
end
|
||||
|
||||
def attached_with_lesson(user)
|
||||
|
|
|
|||
|
|
@ -420,6 +420,12 @@ module JamRuby
|
|||
|
||||
User.where(id: self.id).update_all(updates)
|
||||
end
|
||||
|
||||
# check if the profile looks complete
|
||||
if musician_instruments.length > 0 || genre_players.length > 0
|
||||
User.where(id: self.id).update_all(profile_completed_at: Time.now)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def self.hourly_check
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ module JamRuby
|
|||
#TeacherPayment.hourly_check
|
||||
User.hourly_check
|
||||
AffiliatePartner.tally_up(Date.today)
|
||||
EmailProfileReminder.send_reminders
|
||||
EmailSignupSurvey.send_survey
|
||||
GearSetupReminder.send_reminders
|
||||
ConnectionManager.new.cleanup_dangling
|
||||
|
||||
@@log.info("done")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
module JamRuby
|
||||
class ProfileReminderEmailer
|
||||
extend Resque::Plugins::JamLonelyJob
|
||||
|
||||
@queue = :scheduled_profile_reminder_emailer
|
||||
@@log = Logging.logger[ProfileReminderEmailer]
|
||||
|
||||
def self.perform
|
||||
@@log.debug("waking up")
|
||||
EmailProfileReminder.send_reminders
|
||||
@@log.debug("done")
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -14,6 +14,7 @@
|
|||
//= require react-components/actions/VideoActions
|
||||
//= require client_init
|
||||
//= require utils
|
||||
//= require subscription_utils
|
||||
//= require jamkazam
|
||||
//= require modern/JamServer_copy
|
||||
|
||||
|
|
|
|||
|
|
@ -187,6 +187,11 @@ class ApiRecordingsController < ApiController
|
|||
|
||||
def stop
|
||||
|
||||
# only allow the creator to stop the recording
|
||||
if @recording.can_stop?(current_user) == false
|
||||
raise JamPermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR
|
||||
end
|
||||
|
||||
@recording.stop
|
||||
|
||||
if @recording.errors.any?
|
||||
|
|
|
|||
|
|
@ -386,6 +386,7 @@ if defined?(Bundler)
|
|||
config.video_available = "full"
|
||||
config.alerts_api_enabled = true
|
||||
|
||||
config.show_recording_debug_status = false
|
||||
config.gear_check_ignore_high_latency = false
|
||||
config.remove_whitespace_credit_card = false
|
||||
config.estimate_taxes = true
|
||||
|
|
@ -519,6 +520,8 @@ if defined?(Bundler)
|
|||
config.spa_origin_url = "http://beta.jamkazam.local:4000"
|
||||
config.user_match_monitoring_email = "user_match_monitoring_email@jamkazam.com"
|
||||
config.send_user_match_mail_only_to_jamkazam_team = true
|
||||
config.signup_survey_url = "https://www.surveymonkey.com/r/WVBKLYL"
|
||||
config.signup_survey_cutoff_date = "2025-06-10"
|
||||
config.action_mailer.asset_host = config.action_controller.asset_host
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -126,4 +126,6 @@ SampleApp::Application.configure do
|
|||
config.action_controller.asset_host = 'http://www.jamkazam.local:3000'
|
||||
|
||||
config.send_user_match_mail_only_to_jamkazam_team = false
|
||||
config.signup_survey_url = "https://www.surveymonkey.com/r/WVBKLYL"
|
||||
config.signup_survey_cutoff_date = "2025-06-10"
|
||||
end
|
||||
|
|
|
|||
|
|
@ -31,5 +31,6 @@ Gon.global.braintree_token = Rails.application.config.braintree_token
|
|||
Gon.global.paypal_admin_only = Rails.application.config.paypal_admin_only
|
||||
Gon.global.use_video_conferencing_server = Rails.application.config.use_video_conferencing_server
|
||||
Gon.global.manual_override_installer_ends_with = Rails.application.config.manual_override_installer_ends_with
|
||||
Gon.global.show_recording_debug_status = Rails.application.config.show_recording_debug_status
|
||||
Gon.global.env = Rails.env
|
||||
Gon.global.version = ::JamWeb::VERSION
|
||||
|
|
|
|||
|
|
@ -71,3 +71,83 @@ en:
|
|||
paragraph2: "Your account was imported for you, so you'll need to set a password. Click the button below to set a password for your JamKazam account."
|
||||
paragraph3: "Thanks for joining JamKazam!"
|
||||
signature: "The JamKazam Team"
|
||||
profile_complete_reminder1:
|
||||
subject: "Update your JamKazam profile now & get connected to other musicians"
|
||||
greeting: "Hello"
|
||||
paragraph1: "If you may be interested in playing music live online with other musicians, the first thing you should do is fill out your JamKazam profile. The information in your profile lets other musicians with similar interests find, message, and connect with you, and also lets JamKazam’s matchmaking features give you recommendations for great musical connections. Click the button below to update your profile now. It only takes 2 minutes to complete your profile."
|
||||
update_profile: "Update Profile"
|
||||
paragraph2: "After you have updated your profile, the next thing you should do is download, install, and run the JamKazam app. You’ll need this app to play online with others, and the app also gives you access to more advanced JamTracks features if you signed up to use our huge catalog of backing tracks. After you download and install the app, we recommend you open the app and then leave the app running for about 10-15 minutes on your computer. The app will use this time to quietly collect Internet data that we use to figure out which other musicians on JamKazam you’ll have the best connections with – i.e. the lowest latency (or lag) when playing together"
|
||||
paragraph3: "Click a button below to go to the JamKazam app download page. (Most users should click the Download App button, but 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.) After you download it, double click the downloaded installer, and follow the on-screen instructions to install the app, then start the app and leave it running for about 15 minutes."
|
||||
download_app: "Download App"
|
||||
download_legacy_app: "Download Legacy App"
|
||||
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"
|
||||
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 connect. Click the button below to update your profile now, before it’s shared with others!"
|
||||
update_profile: "Update Profile"
|
||||
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"
|
||||
paragraph1: "Your profile is your key to connecting with other musicians on JamKazam. It lets others know what instruments you play at what level of proficiency and what kinds of music you like to play. This lets our existing community find and reach out to you to connect and play, and this information also powers our automated matchmaking features that make recommendations to you. If you think you might want to play music live online on JamKazam, please click the button below now to fill out your profile!"
|
||||
update_profile: "Update Profile"
|
||||
regards: "Best Regards,"
|
||||
signature: "JamKazam Team"
|
||||
|
||||
gear_setup_reminder1:
|
||||
subject: "Set up audio gear in JamKazam now so you can get in your first session"
|
||||
greeting: "Hello"
|
||||
paragraph1: "The next thing you should do with JamKazam is set up your audio gear and test it in a solo session by yourself."
|
||||
paragraph2: |
|
||||
If you already have an audio interface and the ability to connect your computer to your home router using an Ethernet cable, you are ready to set up your gear. You can find all of our gear setup articles <a href="https://jamkazam.freshdesk.com/support/solutions/66000073844">here</a>. We recommend you use our articles on setting up your audio interface <a href="https://jamkazam.freshdesk.com/support/solutions/folders/66000108387">for Mac</a> or <a href="https://jamkazam.freshdesk.com/support/solutions/folders/66000108430">for Windows</a> to make sure you get this critical step done properly, and that you use our article on <a href="https://jamkazam.freshdesk.com/support/solutions/articles/66000124756">connecting your computer via Ethernet</a>, which is the other critical setup step.
|
||||
paragraph3: |
|
||||
If you’re not sure what gear you need, we recommend you start by reading <a href="https://jamkazam.freshdesk.com/support/solutions/articles/66000122533-what-gear-do-i-need-to-play-on-jamkazam-">this article</a> that explains this topic in general terms. Next, <a href="https://jamkazam.freshdesk.com/support/solutions/folders/66000108418">check this list of articles</a> to find the one that best describes you. You need to use an audio interface rather than relying on the built-in mic on your computer, and you need to connect your computer to your Internet router using an Ethernet cable rather than using WiFi. <a href="https://jamkazam.freshdesk.com/support/solutions/folders/66000108419">See this list of articles</a> for recommendations on gear. If you’re worried about spending money on gear without knowing how well JamKazam will work for you, you can buy gear on Amazon, try it for a week, and return it for a refund if you’re not happy for a risk-free trial experience.
|
||||
paragraph4: |
|
||||
If you have any trouble or feel confused about gear setup, you can email us for help at <a href="mailto:support@jamkazam.com">support@jamkazam.com</a>. You can also visit with a JamKazam support team member in our <a href="https://us02web.zoom.us/j/5967470315?pwd=eHZZL2hmVW1haUU5aTZTUUJobjFIdz09">weekly Zoom office hours</a>, which is offered every Wednesday from 11am to 12pm US Central Time.
|
||||
regards: "Best Regards,"
|
||||
signature: "JamKazam Team"
|
||||
|
||||
gear_setup_reminder2:
|
||||
subject: "Set up your gear in JamKazam now to 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 set up your gear in the JamKazam app."
|
||||
paragraph3: |
|
||||
If you already have an audio interface and the ability to connect your computer to your home router using an Ethernet cable, you are ready to set up your gear. You can find all of our gear setup articles <a href="https://jamkazam.freshdesk.com/support/solutions/66000073844">here</a>. We recommend you use our articles on setting up your audio interface <a href="https://jamkazam.freshdesk.com/support/solutions/folders/66000108387">for Mac</a> or <a href="https://jamkazam.freshdesk.com/support/solutions/folders/66000108430">for Windows</a> to make sure you get this critical step done properly, and that you use our article on <a href="https://jamkazam.freshdesk.com/support/solutions/articles/66000124756">connecting your computer via Ethernet</a>, which is the other critical setup step.
|
||||
paragraph4: |
|
||||
If you’re not sure what gear you need, we recommend you start by reading <a href="https://jamkazam.freshdesk.com/support/solutions/articles/66000122533-what-gear-do-i-need-to-play-on-jamkazam-">this article</a> that explains this topic in general terms. Next, <a href="https://jamkazam.freshdesk.com/support/solutions/folders/66000108418">check this list of articles</a> to find the one that best describes you. You need to use an audio interface rather than relying on the built-in mic on your computer, and you need to connect your computer to your Internet router using an Ethernet cable rather than using WiFi. <a href="https://jamkazam.freshdesk.com/support/solutions/folders/66000108419">See this list of articles</a> for recommendations on gear. If you’re worried about spending money on gear without knowing how well JamKazam will work for you, you can buy gear on Amazon, try it for a week, and return it for a refund if you’re not happy for a risk-free trial experience.
|
||||
paragraph5: |
|
||||
If you have any trouble or feel confused about gear setup, you can email us for help at <a href="mailto:support@jamkazam.com">support@jamkazam.com</a>. You can also visit with a JamKazam support team member in our <a href="https://us02web.zoom.us/j/5967470315?pwd=eHZZL2hmVW1haUU5aTZTUUJobjFIdz09">weekly Zoom office hours</a>, which is offered every Wednesday from 11am to 12pm US Central Time.
|
||||
regards: "Best Regards,"
|
||||
signature: "JamKazam Team"
|
||||
|
||||
gear_setup_reminder3:
|
||||
subject: Don’t waste your free 30-day premium gold plan - set up your gear 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! Set up your gear in the JamKazam app now, and get started.
|
||||
paragraph3: |
|
||||
If you already have an audio interface and the ability to connect your computer to your home router using an Ethernet cable, you are ready to set up your gear. You can find all of our gear setup articles <a href="https://jamkazam.freshdesk.com/support/solutions/66000073844">here</a>. We recommend you use our articles on setting up your audio interface <a href="https://jamkazam.freshdesk.com/support/solutions/folders/66000108387">for Mac</a> or <a href="https://jamkazam.freshdesk.com/support/solutions/folders/66000108430">for Windows</a> to make sure you get this critical step done properly, and that you use our article on <a href="https://jamkazam.freshdesk.com/support/solutions/articles/66000124756">connecting your computer via Ethernet</a>, which is the other critical setup step.
|
||||
paragraph4: |
|
||||
If you’re not sure what gear you need, we recommend you start by reading <a href="https://jamkazam.freshdesk.com/support/solutions/articles/66000122533-what-gear-do-i-need-to-play-on-jamkazam-">this article</a> that explains this topic in general terms. Next, <a href="https://jamkazam.freshdesk.com/support/solutions/folders/66000108418">check this list of articles</a> to find the one that best describes you. You need to use an audio interface rather than relying on the built-in mic on your computer, and you need to connect your computer to your Internet router using an Ethernet cable rather than using WiFi. <a href="https://jamkazam.freshdesk.com/support/solutions/folders/66000108419">See this list of articles</a> for recommendations on gear. If you’re worried about spending money on gear without knowing how well JamKazam will work for you, you can buy gear on Amazon, try it for a week, and return it for a refund if you’re not happy for a risk-free trial experience.
|
||||
paragraph5: |
|
||||
If you have any trouble or feel confused about gear setup, you can email us for help at <a href="mailto:support@jamkazam.com">support@jamkazam.com</a>. You can also visit with a JamKazam support team member in our <a href="https://us02web.zoom.us/j/5967470315?pwd=eHZZL2hmVW1haUU5aTZTUUJobjFIdz09">weekly Zoom office hours</a>, which is offered every Wednesday from 11am to 12pm US Central Time.
|
||||
regards: "Best Regards,"
|
||||
signature: "JamKazam Team"
|
||||
signup_survey:
|
||||
subject: "Let us help you to be successful on JamKazam"
|
||||
greeting: "Hi"
|
||||
paragraph1: "Thanks for signing up to join our community of musicians! Please click the link below and take 2 minutes to let us know a little more about your goals. Our support team will use this information to provide tailored, individual help to you to make it faster and easier for you to be successful."
|
||||
ps: "p.s."
|
||||
ps_text: "If we can help in any way, please always feel free to contact us at"
|
||||
regards: "Best Regards,"
|
||||
signature: "JamKazam Team"
|
||||
Loading…
Reference in New Issue