Merge branch 'develop' of bitbucket.org:jamkazam/jam-cloud into develop
This commit is contained in:
commit
8979d732f2
|
|
@ -17,7 +17,7 @@ const JKMusicSessionsHistory = () => {
|
||||||
const sessions = useSelector(state => state.sessionsHistory.sessions);
|
const sessions = useSelector(state => state.sessionsHistory.sessions);
|
||||||
const loadingStatus = useSelector(state => state.sessionsHistory.status);
|
const loadingStatus = useSelector(state => state.sessionsHistory.status);
|
||||||
const [offset, setOffset] = useState(0);
|
const [offset, setOffset] = useState(0);
|
||||||
const LIMIT = 10;
|
const LIMIT = 50;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const options = {
|
const options = {
|
||||||
|
|
@ -27,6 +27,10 @@ const JKMusicSessionsHistory = () => {
|
||||||
dispatch(fetchSessionsHistory(options));
|
dispatch(fetchSessionsHistory(options));
|
||||||
}, [offset]);
|
}, [offset]);
|
||||||
|
|
||||||
|
const handleNextPage = () => {
|
||||||
|
setOffset(offset + LIMIT);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<FalconCardHeader title={t('history.page_title', { ns: 'sessions' })} titleClass="font-weight-bold" />
|
<FalconCardHeader title={t('history.page_title', { ns: 'sessions' })} titleClass="font-weight-bold" />
|
||||||
|
|
@ -38,12 +42,16 @@ const JKMusicSessionsHistory = () => {
|
||||||
{greaterThan.sm ? (
|
{greaterThan.sm ? (
|
||||||
<Row className="mb-3 justify-content-between d-none d-md-block">
|
<Row className="mb-3 justify-content-between d-none d-md-block">
|
||||||
<div className="table-responsive-xl px-2">
|
<div className="table-responsive-xl px-2">
|
||||||
<JKSessionsHistoryList sessions={sessions} />
|
<JKSessionsHistoryList
|
||||||
|
sessions={sessions}
|
||||||
|
onNextPage={handleNextPage}
|
||||||
|
isLoading={loadingStatus === 'loading'}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Row>
|
</Row>
|
||||||
) : (
|
) : (
|
||||||
<Row className="swiper-container d-block d-md-none" data-testid="sessionsSwiper">
|
<Row className="swiper-container d-block d-md-none" data-testid="sessionsSwiper">
|
||||||
<JKSessionsHistorySwiper sessions={sessions} />
|
<JKSessionsHistorySwiper sessions={sessions} onNextPage={handleNextPage} />
|
||||||
</Row>
|
</Row>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,10 @@ const JKUserLatency = ({user, showAll, showBadgeOnly}) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
JKUserLatency.propTypes = { user: PropTypes.object.isRequired };
|
JKUserLatency.propTypes = {
|
||||||
|
user: PropTypes.object.isRequired,
|
||||||
|
showAll: PropTypes.bool,
|
||||||
|
showBadgeOnly: PropTypes.bool
|
||||||
|
};
|
||||||
|
|
||||||
export default JKUserLatency;
|
export default JKUserLatency;
|
||||||
|
|
|
||||||
|
|
@ -6,33 +6,54 @@ import JKInstrumentIcon from '../profile/JKInstrumentIcon';
|
||||||
import JKSessionUser from './JKSessionUser';
|
import JKSessionUser from './JKSessionUser';
|
||||||
import JKUserLatencyBadge from '../profile/JKUserLatencyBadge';
|
import JKUserLatencyBadge from '../profile/JKUserLatencyBadge';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { useAuth } from '../../context/UserAuth';
|
||||||
|
import { fetchUserLatencies } from '../../store/features/latencySlice';
|
||||||
|
|
||||||
const JKSessionsHistoryItem = ({ session_id, sessionGroup }) => {
|
const JKSessionsHistoryItem = ({ session_id, sessionGroup }) => {
|
||||||
const { greaterThan } = useResponsive();
|
const { greaterThan } = useResponsive();
|
||||||
const { sessionDescription, sessionDateTime } = useSessionHelper(sessionGroup[0]);
|
const { sessionDescription, sessionDateTime } = useSessionHelper(sessionGroup[0]);
|
||||||
const [participants, setParticipants] = useState([]);
|
const [participants, setParticipants] = useState([]);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const { currentUser } = useAuth();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
console.log('sessionGroup', sessionGroup);
|
||||||
setParticipants(
|
setParticipants(
|
||||||
sessionGroup.map(history => ({
|
sessionGroup.map(history => {
|
||||||
id: history.user_id,
|
const participant = {
|
||||||
user: {
|
|
||||||
id: history.user_id,
|
id: history.user_id,
|
||||||
photo_url: history.photo_url,
|
user: {
|
||||||
first_name: history.first_name,
|
id: history.user_id,
|
||||||
last_name: history.last_name,
|
photo_url: history.photo_url,
|
||||||
name: `${history.first_name} ${history.last_name}`
|
first_name: history.first_name,
|
||||||
},
|
last_name: history.last_name,
|
||||||
tracks: history.instruments.split('|').map((instrument, index) => ({
|
name: `${history.first_name} ${history.last_name}`
|
||||||
id: index,
|
}
|
||||||
instrument_id: instrument,
|
};
|
||||||
instrument: instrument
|
if (history.instrments) {
|
||||||
}))
|
participant.tracks = history.instrments.split('|').map((instrument, index) => ({
|
||||||
}))
|
id: index,
|
||||||
|
instrument_id: instrument,
|
||||||
|
instrument: instrument
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
return participant;
|
||||||
|
})
|
||||||
);
|
);
|
||||||
}, [sessionGroup]);
|
}, [sessionGroup]);
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
|
||||||
|
if (participants.length > 0 && currentUser) {
|
||||||
|
const currentUserId = currentUser.id;
|
||||||
|
const otherUserIds = participants.filter(p => p.id !== currentUserId).map(p => p.id);
|
||||||
|
console.log('X_DEBUG_ JKSessionsHistoryItem', currentUserId, otherUserIds);
|
||||||
|
fetchUserLatencies({ currentUserId, otherUserIds});
|
||||||
|
}
|
||||||
|
}, [participants]);
|
||||||
|
|
||||||
// const formattedDate = date => {
|
// const formattedDate = date => {
|
||||||
// const d = new Date(date);
|
// const d = new Date(date);
|
||||||
// return d.toLocaleDateString('en-us', {
|
// return d.toLocaleDateString('en-us', {
|
||||||
|
|
@ -73,7 +94,7 @@ const JKSessionsHistoryItem = ({ session_id, sessionGroup }) => {
|
||||||
))}
|
))}
|
||||||
</td>
|
</td>
|
||||||
<td className="text-center">
|
<td className="text-center">
|
||||||
{participants.map(participant => (
|
{participants.filter(p => p.user.id !== currentUser.id).map(participant => (
|
||||||
<Row key={participant.id} style={musicianRowStyle}>
|
<Row key={participant.id} style={musicianRowStyle}>
|
||||||
<Col>
|
<Col>
|
||||||
<JKUserLatencyBadge key={participant.id} user={participant.user} showBadgeOnly={true} />
|
<JKUserLatencyBadge key={participant.id} user={participant.user} showBadgeOnly={true} />
|
||||||
|
|
@ -85,7 +106,7 @@ const JKSessionsHistoryItem = ({ session_id, sessionGroup }) => {
|
||||||
{participants.map(participant => (
|
{participants.map(participant => (
|
||||||
<Row style={musicianRowStyle} key={participant.id} data-testid={`Participant${participant.id}Tracks`}>
|
<Row style={musicianRowStyle} key={participant.id} data-testid={`Participant${participant.id}Tracks`}>
|
||||||
<Col>
|
<Col>
|
||||||
{participant.tracks.map(track => (
|
{participant.tracks && participant.tracks.map(track => (
|
||||||
<span key={track.id} className="mr-1 mb-1" title={track.instrment}>
|
<span key={track.id} className="mr-1 mb-1" title={track.instrment}>
|
||||||
<a
|
<a
|
||||||
id={`Participant${participant.id}Track${track.id}Instrument`}
|
id={`Participant${participant.id}Track${track.id}Instrument`}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
import { groupByKey } from '../../helpers/utils';
|
import { groupByKey } from '../../helpers/utils';
|
||||||
import { Table } from 'reactstrap';
|
import { Table, Button } from 'reactstrap';
|
||||||
import JKSessionsHistoryItem from './JKSessionsHistoryItem';
|
import JKSessionsHistoryItem from './JKSessionsHistoryItem';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
const JKSessionsHistoryList = ({ sessions }) => {
|
const JKSessionsHistoryList = ({ sessions, onNextPage, isLoading }) => {
|
||||||
const sessionsById = groupByKey(sessions, 'session_id');
|
const sessionsById = groupByKey(sessions, 'session_id');
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
|
@ -31,8 +32,23 @@ const JKSessionsHistoryList = ({ sessions }) => {
|
||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
</Table>
|
</Table>
|
||||||
|
<Button
|
||||||
|
color="primary"
|
||||||
|
outline={true}
|
||||||
|
onClick={() =>onNextPage()}
|
||||||
|
disabled={isLoading}
|
||||||
|
data-testid="paginate-next-page"
|
||||||
|
>
|
||||||
|
{isLoading ? <span>Loading...</span> : <span>Load More</span>}
|
||||||
|
</Button>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
JKSessionsHistoryList.propTypes = {
|
||||||
|
sessions: PropTypes.array.isRequired,
|
||||||
|
onNextPage: PropTypes.func.isRequired,
|
||||||
|
isLoading: PropTypes.bool
|
||||||
|
};
|
||||||
|
|
||||||
export default JKSessionsHistoryList;
|
export default JKSessionsHistoryList;
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ import { Card, CardBody, CardHeader } from 'reactstrap';
|
||||||
|
|
||||||
SwiperCore.use([Navigation, Pagination, Scrollbar, A11y]);
|
SwiperCore.use([Navigation, Pagination, Scrollbar, A11y]);
|
||||||
|
|
||||||
const JKSessionsHistorySwiper = ({ sessions }) => {
|
const JKSessionsHistorySwiper = ({ sessions, onNextPage }) => {
|
||||||
const sessionsById = groupByKey(sessions, 'session_id');
|
const sessionsById = groupByKey(sessions, 'session_id');
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
|
@ -32,7 +32,7 @@ const JKSessionsHistorySwiper = ({ sessions }) => {
|
||||||
//onSlideChange={() => console.log('slide change')}
|
//onSlideChange={() => console.log('slide change')}
|
||||||
onSlideNextTransitionEnd={swiper => {
|
onSlideNextTransitionEnd={swiper => {
|
||||||
if(swiper.isEnd){
|
if(swiper.isEnd){
|
||||||
//goNextPage()
|
onNextPage()
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
pagination={{
|
pagination={{
|
||||||
|
|
@ -68,6 +68,7 @@ const JKSessionsHistorySwiper = ({ sessions }) => {
|
||||||
|
|
||||||
JKSessionsHistorySwiper.propTypes = {
|
JKSessionsHistorySwiper.propTypes = {
|
||||||
sessions: PropTypes.arrayOf(PropTypes.instanceOf(Object)).isRequired,
|
sessions: PropTypes.arrayOf(PropTypes.instanceOf(Object)).isRequired,
|
||||||
|
onNextPage: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export default JKSessionsHistorySwiper;
|
export default JKSessionsHistorySwiper;
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,17 @@ const useSessionHelper = (session) => {
|
||||||
const sessionDateTime = session => {
|
const sessionDateTime = session => {
|
||||||
const date = new Date(session.created_at);
|
const date = new Date(session.created_at);
|
||||||
const d = new Date(date);
|
const d = new Date(date);
|
||||||
return d.toLocaleDateString('en-us', {
|
// return d.toLocaleDateString('en-us', {
|
||||||
weekday: 'long',
|
// weekday: 'long',
|
||||||
year: 'numeric',
|
// year: 'numeric',
|
||||||
month: 'short',
|
// month: 'short',
|
||||||
day: 'numeric',
|
// day: 'numeric',
|
||||||
timeZoneName: 'short'
|
// timeZoneName: 'short'
|
||||||
});
|
// });
|
||||||
|
return new Intl.DateTimeFormat('en-US', {
|
||||||
|
dateStyle: 'full',
|
||||||
|
timeStyle: 'long',
|
||||||
|
}).format(date);
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ export const fetchUserLatencies = createAsyncThunk(
|
||||||
'latency/fetchUserLatencies',
|
'latency/fetchUserLatencies',
|
||||||
async (options, thunkAPI) => {
|
async (options, thunkAPI) => {
|
||||||
const { currentUserId, otherUserIds } = options
|
const { currentUserId, otherUserIds } = options
|
||||||
|
console.log('X_DEBUG_ fetchUserLatencies', currentUserId, otherUserIds)
|
||||||
const response = await getLatencyToUsers(currentUserId, otherUserIds)
|
const response = await getLatencyToUsers(currentUserId, otherUserIds)
|
||||||
return response.json()
|
return response.json()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,9 @@ module JamRuby
|
||||||
sendgrid_recipients([user.email])
|
sendgrid_recipients([user.email])
|
||||||
sendgrid_substitute('@USERID', [user.id])
|
sendgrid_substitute('@USERID', [user.id])
|
||||||
|
|
||||||
mail(:to => user.email, :subject => "Please confirm your JamKazam email") do |format|
|
mail(:to => user.email, :subject => "Please confirm your JamKazam email address") do |format|
|
||||||
format.text
|
format.text
|
||||||
format.html
|
format.html { render layout: "user_mailer_beta" }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,34 @@
|
||||||
<% provide(:title, 'Welcome to JamKazam!') %>
|
<% provide(:title, 'Welcome to JamKazam!') %>
|
||||||
|
|
||||||
<p>We’re delighted you have joined our community of <%= APP_CONFIG.musician_count %> musicians. We’d like to send you an orientation email with information and resource links that will help you get the most out of JamKazam. Please <a style="color: #ffcc00;" href="<%= @signup_confirm_url %>">click here to confirm this email</a> has reached you successfully and we will then send the orientation email.</p>
|
<p>
|
||||||
|
<%= I18n.t 'user_mailer.confirm_email.paragraph1' -%>
|
||||||
|
</p>
|
||||||
|
|
||||||
<p>If you have received this email but aren’t familiar with JamKazam or JamTracks, then someone has registered at our website using your email address, and you can just ignore and delete this email.</p>
|
<div style="text-align: center">
|
||||||
|
<a
|
||||||
|
href="<%= @signup_confirm_url %>"
|
||||||
|
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.confirm_email.confirm_email' -%></a
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
|
||||||
<p>Best Regards,<br/>
|
<p>
|
||||||
Team JamKazam
|
<%= I18n.t 'user_mailer.confirm_email.paragraph2' -%>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p><%= I18n.t 'user_mailer.confirm_email.best_wishes' -%><br/>
|
||||||
|
<%= I18n.t 'user_mailer.confirm_email.signature' -%>
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
<% provide(:title, 'Welcome to JamKazam!') %>
|
||||||
|
|
||||||
|
<p>We’re delighted you have joined our community of <%= APP_CONFIG.musician_count %> musicians. We’d like to send you an orientation email with information and resource links that will help you get the most out of JamKazam. Please <a style="color: #ffcc00;" href="<%= @signup_confirm_url %>">click here to confirm this email</a> has reached you successfully and we will then send the orientation email.</p>
|
||||||
|
|
||||||
|
<p>If you have received this email but aren’t familiar with JamKazam or JamTracks, then someone has registered at our website using your email address, and you can just ignore and delete this email.</p>
|
||||||
|
|
||||||
|
<p>Best Regards,<br/>
|
||||||
|
Team JamKazam
|
||||||
|
</p>
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
Welcome to JamKazam!
|
<%= I18n.t 'user_mailer.confirm_email.paragraph1' -%>
|
||||||
|
|
||||||
We’re delighted you have joined our community of <%= APP_CONFIG.musician_count %> musicians. We’d like to send you an orientation email with information and resource links that will help you get the most out of JamKazam. Please click <%= @signup_confirm_url %> to confirm this email has reached you successfully and we will then send the orientation email.
|
<%= @signup_confirm_url %>
|
||||||
|
|
||||||
If you have received this email but aren’t familiar with JamKazam or JamTracks, then someone has registered at our website using your email address, and you can just ignore and delete this email.
|
<%= I18n.t 'user_mailer.confirm_email.paragraph2' -%>
|
||||||
|
|
||||||
Best Regards,
|
<%= I18n.t 'user_mailer.confirm_email.best_wishes' -%>
|
||||||
Team JamKazam
|
<%= I18n.t 'user_mailer.confirm_email.signature' -%>
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
Welcome to JamKazam!
|
||||||
|
|
||||||
|
We’re delighted you have joined our community of <%= APP_CONFIG.musician_count %> musicians. We’d like to send you an orientation email with information and resource links that will help you get the most out of JamKazam. Please click <%= @signup_confirm_url %> to confirm this email has reached you successfully and we will then send the orientation email.
|
||||||
|
|
||||||
|
If you have received this email but aren’t familiar with JamKazam or JamTracks, then someone has registered at our website using your email address, and you can just ignore and delete this email.
|
||||||
|
|
||||||
|
Best Regards,
|
||||||
|
Team JamKazam
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
Hi <%= @user.first_name %>,
|
Hi <%= @user.first_name %>,
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
The following musicians have joined JamKazam within the last week and have low internet latency to you that will support enjoyable sessions. If you'd like to make more musical connections, we encourage you to use the links below to send these new users a welcome message and perhaps arrange a session to play together.
|
<%= I18n.t 'user_mailer.new_musicians_match.paragraph1' -%>
|
||||||
|
|
||||||
<%
|
<%
|
||||||
@musicians_data.each do | data | -%>
|
@musicians_data.each do | data | -%>
|
||||||
|
|
@ -13,20 +13,20 @@ The following musicians have joined JamKazam within the last week and have low i
|
||||||
latency = latencies.find{|l| l[:user_id] == musician.id }
|
latency = latencies.find{|l| l[:user_id] == musician.id }
|
||||||
-%>
|
-%>
|
||||||
<%= musician.first_name %> <%= musician.last_name %>
|
<%= musician.first_name %> <%= musician.last_name %>
|
||||||
Latency To You: <%= latency_info(latency) %>
|
<%= I18n.t 'user_mailer.new_musicians_match.latency_to_you' -%>: <%= latency_info(latency) %>
|
||||||
<% if musician.last_active_timestamp -%>
|
<% if musician.last_active_timestamp -%>
|
||||||
Last Active On: <%= time_ago_in_words(Time.at(musician.last_active_timestamp)) %> ago
|
<%= I18n.t 'user_mailer.new_musicians_match.last_active' -%>: <%= time_ago_in_words(Time.at(musician.last_active_timestamp)) %> ago
|
||||||
<% end -%>
|
<% end -%>
|
||||||
<% musician.musician_instruments.each do |mi| -%>
|
<% musician.musician_instruments.each do |mi| -%>
|
||||||
<%= mi.description %> (<%= @instrument_proficiencies[mi.proficiency_level.to_s.to_sym] %>)
|
<%= mi.description %> (<%= @instrument_proficiencies[mi.proficiency_level.to_s.to_sym] %>)
|
||||||
<% end -%>
|
<% end -%>
|
||||||
View Profile: <%= APP_CONFIG.spa_origin -%>/friends?id=<%= musician.id %>&open=details
|
<%= I18n.t 'user_mailer.new_musicians_match.view_profile' -%>: <%= APP_CONFIG.spa_origin -%>/friends?id=<%= musician.id %>&open=details
|
||||||
Send Message: <%= APP_CONFIG.spa_origin -%>/friends?id=<%= musician.id %>&open=message
|
<%= I18n.t 'user_mailer.new_musicians_match.send_message' -%>: <%= APP_CONFIG.spa_origin -%>/friends?id=<%= musician.id %>&open=message
|
||||||
Send Friend Request: <%= APP_CONFIG.spa_origin -%>/friends?id=<%= musician.id %>&open=connect
|
<%= I18n.t 'user_mailer.new_musicians_match.send_friend_request' -%>: <%= APP_CONFIG.spa_origin -%>/friends?id=<%= musician.id %>&open=connect
|
||||||
|
|
||||||
<% end -%>
|
<% end -%>
|
||||||
<% end -%>
|
<% end -%>
|
||||||
|
|
||||||
To find great musical matches across the entire JamKazam commiunity and make new connections, use the link below to access our musician search feature. This let you filter JamKazammers by latency, instruments, skill level, genre interests, last active day and more.
|
<%= I18n.t 'user_mailer.new_musicians_match.paragraph2' -%>
|
||||||
|
|
||||||
Search JamKazam Musicians: <%= APP_CONFIG.spa_origin -%>/friends
|
<%= I18n.t 'user_mailer.new_musicians_match.search_musicians' -%>: <%= APP_CONFIG.spa_origin -%>/friends
|
||||||
|
|
@ -18,45 +18,47 @@
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div style="text-align: center">
|
<div style="text-align: center">
|
||||||
<img src="<%= image_url("JK_Logo_blue-2021.png", host: APP_CONFIG.action_mailer.assets_host ) -%>" alt="JamKazam" />
|
<img src="<%= asset_url("JK_Logo_blue-2021.png", host: APP_CONFIG.action_mailer.asset_host ) -%>" alt="JamKazam" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<%= yield %>
|
<%= yield %>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<footer style="text-align: center; margin: 0px auto; padding: 0px auto;">
|
<footer style="text-align: center; margin: 0px auto; padding: 0px auto;">
|
||||||
<p>
|
<% if @user && @user.unsubscribe_token -%>
|
||||||
This email was sent to you because you have an account at JamKazam. <a
|
<p>
|
||||||
href=""
|
<%= I18n.t "mailer_layout.footer.paragraph1" -%> <a href="https://www.jamkazam.com" target="_blank">JamKazam</a>. <a
|
||||||
style="
|
href="https://www.jamkazam.com/unsubscribe/<%= @user.unsubscribe_token %>"
|
||||||
color: #2c7be5;
|
style="
|
||||||
text-decoration: none;
|
color: #2c7be5;
|
||||||
border-bottom: 1px solid #2c7be5;
|
text-decoration: none;
|
||||||
"
|
border-bottom: 1px solid #2c7be5;
|
||||||
>Unsubscribe</a>
|
"
|
||||||
</p>
|
><%= I18n.t "mailer_layout.footer.unsubscribe" -%></a>
|
||||||
<div style="text-align: center; margin: 1em 0;">
|
</p>
|
||||||
<a href="https://www.facebook.com" target="_blank">
|
<% end -%>
|
||||||
<img src="<%= image_url("/email/fb-icon.svg", host: APP_CONFIG.action_mailer.assets_host ) -%>" alt="Facebook" style="width: 24px; height: 24px; margin: 0 5px;">
|
<div style="text-align: center; margin: 1em 0;">
|
||||||
|
<a href="https://www.facebook.com" target="_blank" style="text-decoration: none;">
|
||||||
</a>
|
<img src="<%= asset_url("/email/fb-icon.svg", host: APP_CONFIG.action_mailer.asset_host ) -%>" alt="Facebook" style="width: 24px; height: 24px; margin: 0 5px;">
|
||||||
<a href="https://www.instagram.com" target="_blank">
|
|
||||||
<img src="<%= image_url("/email/instagram-icon.svg", host: APP_CONFIG.action_mailer.assets_host ) -%>" alt="Instagram" style="width: 24px; height: 24px; margin: 0 5px;">
|
</a>
|
||||||
</a>
|
<a href="https://www.instagram.com" target="_blank" style="text-decoration: none;">
|
||||||
<a href="https://www.tiktok.com" target="_blank">
|
<img src="<%= asset_url("/email/instagram-icon.svg", host: APP_CONFIG.action_mailer.asset_host ) -%>" alt="Instagram" style="width: 24px; height: 24px; margin: 0 5px;">
|
||||||
<img src="<%= image_url("/email/tiktok-icon.svg", host: APP_CONFIG.action_mailer.assets_host ) -%>" alt="TikTok" style="width: 24px; height: 24px; margin: 0 5px;">
|
</a>
|
||||||
</a>
|
<a href="https://www.tiktok.com" target="_blank" style="text-decoration: none;">
|
||||||
<a href="https://www.youtube.com" target="_blank">
|
<img src="<%= asset_url("/email/tiktok-icon.svg", host: APP_CONFIG.action_mailer.asset_host ) -%>" alt="TikTok" style="width: 24px; height: 24px; margin: 0 5px;">
|
||||||
<img src="<%= image_url("/email/youtube-icon.svg", host: APP_CONFIG.action_mailer.assets_host ) -%>" alt="YouTube" style="width: 24px; height: 24px; margin: 0 5px;">
|
</a>
|
||||||
</a>
|
<a href="https://www.youtube.com" target="_blank" style="text-decoration: none;">
|
||||||
<a href="https://www.x.com" target="_blank">
|
<img src="<%= asset_url("/email/youtube-icon.svg", host: APP_CONFIG.action_mailer.asset_host ) -%>" alt="YouTube" style="width: 24px; height: 24px; margin: 0 5px;">
|
||||||
<img src=<%= image_url("/email/twitter-x-icon.svg", host: APP_CONFIG.action_mailer.assets_host ) -%>" alt="X.com" style="width: 24px; height: 24px; margin: 0 5px;">
|
</a>
|
||||||
</a>
|
<a href="https://www.x.com" target="_blank" style="text-decoration: none;">
|
||||||
</div>
|
<img src=<%= asset_url("/email/twitter-x-icon.svg", host: APP_CONFIG.action_mailer.asset_host ) -%>" alt="X.com" style="width: 24px; height: 24px; margin: 0 5px;">
|
||||||
<p>
|
</a>
|
||||||
Copyright © 2024 JamKazam, Inc. All rights reserved.
|
</div>
|
||||||
</p>
|
<p>
|
||||||
</footer>
|
<%= I18n.t "mailer_layout.footer.copyright" -%>
|
||||||
|
</p>
|
||||||
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,10 @@ module JamRuby
|
||||||
JOINED_WITHIN_DAYS = 7
|
JOINED_WITHIN_DAYS = 7
|
||||||
ACTIVE_WITHIN_DAYS = 30
|
ACTIVE_WITHIN_DAYS = 30
|
||||||
|
|
||||||
PRIORITY_RECIPIENTS = %w(seth@jamkazam.com david@jamkazam.com peter@jamkazam.com nuwan@jamkazam.com).freeze
|
PRIORITY_RECIPIENTS = %w(seth@jamkazam.com david@jamkazam.com peter@jamkazam.com nuwan@jamkazam.com murali@jamkazam.com bob@jamkazam.com jorge@jamkazam.com).freeze
|
||||||
|
|
||||||
def self.subject
|
def self.subject
|
||||||
"New musicians with good Internet connections to you have joined JamKazam!"
|
I18n.t 'user_mailer.new_musicians_match.subject'
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.send_new_musicians
|
def self.send_new_musicians
|
||||||
|
|
@ -33,7 +33,6 @@ module JamRuby
|
||||||
end
|
end
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
recipients = User.where("users.subscribe_email = ? AND
|
recipients = User.where("users.subscribe_email = ? AND
|
||||||
users.subscribe_email_for_user_match = ?
|
users.subscribe_email_for_user_match = ?
|
||||||
AND NOT COALESCE(users.user_match_email_sent_at, ?) > ?",
|
AND NOT COALESCE(users.user_match_email_sent_at, ?) > ?",
|
||||||
|
|
@ -41,12 +40,17 @@ module JamRuby
|
||||||
CASE WHEN users.email IN ('#{PRIORITY_RECIPIENTS.map {|str| "\"#{str}\""}.join(',')}')
|
CASE WHEN users.email IN ('#{PRIORITY_RECIPIENTS.map {|str| "\"#{str}\""}.join(',')}')
|
||||||
THEN 0 ELSE 1 END, last_active_at DESC").select("users.*,
|
THEN 0 ELSE 1 END, last_active_at DESC").select("users.*,
|
||||||
GREATEST(updated_at, last_jam_updated_at) AS last_active_at").limit(LIMIT)
|
GREATEST(updated_at, last_jam_updated_at) AS last_active_at").limit(LIMIT)
|
||||||
|
|
||||||
|
# If the flag is set to send user match email only to jamkazam team
|
||||||
|
if Rails.application.config.send_user_match_mail_only_to_jamkazam_team
|
||||||
|
recipients = recipients.where(email: PRIORITY_RECIPIENTS)
|
||||||
|
end
|
||||||
|
|
||||||
AdminMailer.ugly({to: APP_CONFIG.user_match_monitoring_email,
|
AdminMailer.ugly({to: APP_CONFIG.user_match_monitoring_email,
|
||||||
subject:"Weekly user match email sending job started.",
|
subject:"Weekly user match email sending job started.",
|
||||||
body: "#{email_sending.sent_user_ids.any?? "This job is resuming. It was originally started at #{email_sending.created_at} and has been sent to #{email_sending.sent_user_ids.size} user(s) so far." : "This job was started at #{email_sending.created_at}" }. It will send to total of #{ recipients.size } users."}).deliver_now
|
body: "#{email_sending.sent_user_ids.any?? "This job is resuming. It was originally started at #{email_sending.created_at} and has been sent to #{email_sending.sent_user_ids.size} user(s) so far." : "This job was started at #{email_sending.created_at}" }. It will send to total of #{ recipients.size } users."}).deliver_now
|
||||||
|
|
||||||
recipients.find_each do |user|
|
recipients.find_each do |user|
|
||||||
|
|
||||||
ip_address = user.last_jam_addr.blank?? '127.0.0.1' : IPAddr.new(user.last_jam_addr, Socket::AF_INET).to_s
|
ip_address = user.last_jam_addr.blank?? '127.0.0.1' : IPAddr.new(user.last_jam_addr, Socket::AF_INET).to_s
|
||||||
matched_musician_data = []
|
matched_musician_data = []
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ describe EmailNewMusicianMatch do
|
||||||
ActionMailer::Base.deliveries = []
|
ActionMailer::Base.deliveries = []
|
||||||
User.delete_all
|
User.delete_all
|
||||||
allow(JamRuby::MusicianFilter).to receive(:filter).and_return(search_result)
|
allow(JamRuby::MusicianFilter).to receive(:filter).and_return(search_result)
|
||||||
|
Rails.application.config.send_user_match_mail_only_to_jamkazam_team = false
|
||||||
end
|
end
|
||||||
|
|
||||||
after(:each) do
|
after(:each) do
|
||||||
|
|
@ -46,6 +47,14 @@ describe EmailNewMusicianMatch do
|
||||||
JamRuby::EmailNewMusicianMatch.send_new_musicians
|
JamRuby::EmailNewMusicianMatch.send_new_musicians
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "delivers only to priority recipients" do
|
||||||
|
Rails.application.config.send_user_match_mail_only_to_jamkazam_team = true
|
||||||
|
allow(UserMailer).to receive(:new_musicians_match).and_return(mail)
|
||||||
|
expect(mail).to receive(:deliver_now).exactly(1).times #only to the priority user seth@jamkazam
|
||||||
|
JamRuby::EmailNewMusicianMatch.send_new_musicians
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
xit "delivers to priority recipients first" do
|
xit "delivers to priority recipients first" do
|
||||||
JamRuby::EmailNewMusicianMatch.send_new_musicians
|
JamRuby::EmailNewMusicianMatch.send_new_musicians
|
||||||
raise ActionMailer::Base.deliveries.map{|d| d['to'].to_s }.inspect #.include?("seth@example.com").should be_truthy
|
raise ActionMailer::Base.deliveries.map{|d| d['to'].to_s }.inspect #.include?("seth@example.com").should be_truthy
|
||||||
|
|
|
||||||
|
|
@ -159,7 +159,7 @@ gem 'logging', '1.7.2'
|
||||||
|
|
||||||
gem 'rack-cors', '~> 1.0', '>= 1.0.6'
|
gem 'rack-cors', '~> 1.0', '>= 1.0.6'
|
||||||
|
|
||||||
gem 'mailcatcher'
|
#gem 'mailcatcher'
|
||||||
|
|
||||||
|
|
||||||
if ENV['FASTER_PATH'] == '1'
|
if ENV['FASTER_PATH'] == '1'
|
||||||
|
|
|
||||||
|
|
@ -518,5 +518,6 @@ if defined?(Bundler)
|
||||||
config.manual_override_installer_ends_with = "JamKazam-1.0.3776.dmg"
|
config.manual_override_installer_ends_with = "JamKazam-1.0.3776.dmg"
|
||||||
config.spa_origin = "http://beta.jamkazam.local:4000"
|
config.spa_origin = "http://beta.jamkazam.local:4000"
|
||||||
config.user_match_monitoring_email = "user_match_monitoring_email@jamkazam.com"
|
config.user_match_monitoring_email = "user_match_monitoring_email@jamkazam.com"
|
||||||
|
config.send_user_match_mail_only_to_jamkazam_team = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,8 @@ SampleApp::Application.configure do
|
||||||
|
|
||||||
# Don't care if the mailer can't send
|
# Don't care if the mailer can't send
|
||||||
config.action_mailer.raise_delivery_errors = false
|
config.action_mailer.raise_delivery_errors = false
|
||||||
config.action_mailer.delivery_method = :smtp
|
#config.action_mailer.delivery_method = :smtp
|
||||||
config.action_mailer.smtp_settings = { address: '127.0.0.1', port: 1025, domain: '127.0.0.1' }
|
#config.action_mailer.smtp_settings = { address: '127.0.0.1', port: 1025, domain: '127.0.0.1' }
|
||||||
|
|
||||||
# Print deprecation notices to the Rails logger
|
# Print deprecation notices to the Rails logger
|
||||||
config.active_support.deprecation = :log
|
config.active_support.deprecation = :log
|
||||||
|
|
@ -123,6 +123,8 @@ SampleApp::Application.configure do
|
||||||
|
|
||||||
config.session_cookie_domain = ".jamkazam.local"
|
config.session_cookie_domain = ".jamkazam.local"
|
||||||
|
|
||||||
config.action_controller.asset_host = 'http://localhost:3000'
|
config.action_controller.asset_host = 'http://www.jamkazam.local:3000/assets'
|
||||||
config.action_mailer.asset_host = config.action_controller.asset_host
|
config.action_mailer.asset_host = config.action_controller.asset_host
|
||||||
|
|
||||||
|
config.send_user_match_mail_only_to_jamkazam_team = false
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,22 @@ en:
|
||||||
attributes:
|
attributes:
|
||||||
user:
|
user:
|
||||||
password_digest: "Password"
|
password_digest: "Password"
|
||||||
|
mailer_layout:
|
||||||
|
footer:
|
||||||
|
paragraph1: "This email was sent to you because you have an account at"
|
||||||
|
unsubscribe: "Unsubscribe"
|
||||||
|
copyright: "Copyright © 2024 JamKazam, Inc. All rights reserved."
|
||||||
user_mailer:
|
user_mailer:
|
||||||
|
confirm_email:
|
||||||
|
subject: "Please confirm your JamKazam email address"
|
||||||
|
paragraph1: "Thanks for signing up with JamKazam! Please click the button below to confirm your email for use with JamKazam. We do not sell or share our users’ emails. We only use your email to send you information and updates about the JamKazam service."
|
||||||
|
confirm_email: "Confirm Email Address"
|
||||||
|
paragraph2: " If you have received this email but aren’t familiar with JamKazam, someone has registered at our website using your email address, and you can use the unsubscribe link below to stop receiving emails from us."
|
||||||
|
best_wishes: "Best Regards,"
|
||||||
|
signature: "Team JamKazam"
|
||||||
|
|
||||||
new_musicians_match:
|
new_musicians_match:
|
||||||
|
subject: "New musicians with good Internet connections to you have joined JamKazam!"
|
||||||
greeting: "Hi"
|
greeting: "Hi"
|
||||||
paragraph1: "The following musicians have joined JamKazam within the last week and have low internet latency to you that will support enjoyable sessions. If you'd like to make more musical connections, we encourage you to use the links below to send these new users a welcome message and perhaps arrange a session to play together."
|
paragraph1: "The following musicians have joined JamKazam within the last week and have low internet latency to you that will support enjoyable sessions. If you'd like to make more musical connections, we encourage you to use the links below to send these new users a welcome message and perhaps arrange a session to play together."
|
||||||
latency_to_you: "Latency to You"
|
latency_to_you: "Latency to You"
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,29 @@ en:
|
||||||
attributes:
|
attributes:
|
||||||
user:
|
user:
|
||||||
password_digest: "Password"
|
password_digest: "Password"
|
||||||
|
mailer_layout:
|
||||||
|
footer:
|
||||||
|
paragraph1: "This email was sent to you because you have an account at"
|
||||||
|
unsubscribe: "Unsubscribe"
|
||||||
|
copyright: "Copyright © 2024 JamKazam, Inc. All rights reserved."
|
||||||
user_mailer:
|
user_mailer:
|
||||||
|
confirm_email:
|
||||||
|
subject: "Please confirm your JamKazam email address"
|
||||||
|
paragraph1: "Thanks for signing up with JamKazam! Please click the button below to confirm your email for use with JamKazam. We do not sell or share our users’ emails. We only use your email to send you information and updates about the JamKazam service."
|
||||||
|
confirm_email: "Confirm Email Address"
|
||||||
|
paragraph2: " If you have received this email but aren’t familiar with JamKazam, someone has registered at our website using your email address, and you can use the unsubscribe link below to stop receiving emails from us."
|
||||||
|
best_wishes: "Best Regards,"
|
||||||
|
signature: "Team JamKazam"
|
||||||
|
|
||||||
new_musicians_match:
|
new_musicians_match:
|
||||||
|
subject: "New musicians with good Internet connections to you have joined JamKazam!"
|
||||||
greeting: "Hola"
|
greeting: "Hola"
|
||||||
view_profile: "Ver Perfil"
|
paragraph1: "The following musicians have joined JamKazam within the last week and have low internet latency to you that will support enjoyable sessions. If you'd like to make more musical connections, we encourage you to use the links below to send these new users a welcome message and perhaps arrange a session to play together."
|
||||||
|
latency_to_you: "Latency to You"
|
||||||
|
last_active: "Last Active"
|
||||||
|
ago: "ago"
|
||||||
|
view_profile: "View Profile"
|
||||||
|
send_message: "Send Message"
|
||||||
|
send_friend_request: "Send Friend Request"
|
||||||
|
paragraph2: "To find great musical matches across the entire JamKazam commiunity and make new connections, use the button below to access our musician search feature. This let you filter JamKazammers by latency, instruments, skill level, genre interests, last active day and more."
|
||||||
|
search_musicians: "Search JamKazam Musicians"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue