Merge branch 'develop' of bitbucket.org:jamkazam/jam-cloud into develop

This commit is contained in:
Seth Call 2024-11-11 18:40:42 -06:00
commit 8979d732f2
21 changed files with 243 additions and 92 deletions

View File

@ -17,7 +17,7 @@ const JKMusicSessionsHistory = () => {
const sessions = useSelector(state => state.sessionsHistory.sessions);
const loadingStatus = useSelector(state => state.sessionsHistory.status);
const [offset, setOffset] = useState(0);
const LIMIT = 10;
const LIMIT = 50;
useEffect(() => {
const options = {
@ -27,6 +27,10 @@ const JKMusicSessionsHistory = () => {
dispatch(fetchSessionsHistory(options));
}, [offset]);
const handleNextPage = () => {
setOffset(offset + LIMIT);
};
return (
<Card>
<FalconCardHeader title={t('history.page_title', { ns: 'sessions' })} titleClass="font-weight-bold" />
@ -38,12 +42,16 @@ const JKMusicSessionsHistory = () => {
{greaterThan.sm ? (
<Row className="mb-3 justify-content-between d-none d-md-block">
<div className="table-responsive-xl px-2">
<JKSessionsHistoryList sessions={sessions} />
<JKSessionsHistoryList
sessions={sessions}
onNextPage={handleNextPage}
isLoading={loadingStatus === 'loading'}
/>
</div>
</Row>
) : (
<Row className="swiper-container d-block d-md-none" data-testid="sessionsSwiper">
<JKSessionsHistorySwiper sessions={sessions} />
<JKSessionsHistorySwiper sessions={sessions} onNextPage={handleNextPage} />
</Row>
)}
</>

View File

@ -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;

View File

@ -6,33 +6,54 @@ import JKInstrumentIcon from '../profile/JKInstrumentIcon';
import JKSessionUser from './JKSessionUser';
import JKUserLatencyBadge from '../profile/JKUserLatencyBadge';
import { useTranslation } from 'react-i18next';
import { useAuth } from '../../context/UserAuth';
import { fetchUserLatencies } from '../../store/features/latencySlice';
const JKSessionsHistoryItem = ({ session_id, sessionGroup }) => {
const { greaterThan } = useResponsive();
const { sessionDescription, sessionDateTime } = useSessionHelper(sessionGroup[0]);
const [participants, setParticipants] = useState([]);
const { t } = useTranslation();
const { currentUser } = useAuth();
useEffect(() => {
console.log('sessionGroup', sessionGroup);
setParticipants(
sessionGroup.map(history => ({
id: history.user_id,
user: {
sessionGroup.map(history => {
const participant = {
id: history.user_id,
photo_url: history.photo_url,
first_name: history.first_name,
last_name: history.last_name,
name: `${history.first_name} ${history.last_name}`
},
tracks: history.instruments.split('|').map((instrument, index) => ({
id: index,
instrument_id: instrument,
instrument: instrument
}))
}))
user: {
id: history.user_id,
photo_url: history.photo_url,
first_name: history.first_name,
last_name: history.last_name,
name: `${history.first_name} ${history.last_name}`
}
};
if (history.instrments) {
participant.tracks = history.instrments.split('|').map((instrument, index) => ({
id: index,
instrument_id: instrument,
instrument: instrument
}));
}
return participant;
})
);
}, [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 d = new Date(date);
// return d.toLocaleDateString('en-us', {
@ -73,7 +94,7 @@ const JKSessionsHistoryItem = ({ session_id, sessionGroup }) => {
))}
</td>
<td className="text-center">
{participants.map(participant => (
{participants.filter(p => p.user.id !== currentUser.id).map(participant => (
<Row key={participant.id} style={musicianRowStyle}>
<Col>
<JKUserLatencyBadge key={participant.id} user={participant.user} showBadgeOnly={true} />
@ -85,7 +106,7 @@ const JKSessionsHistoryItem = ({ session_id, sessionGroup }) => {
{participants.map(participant => (
<Row style={musicianRowStyle} key={participant.id} data-testid={`Participant${participant.id}Tracks`}>
<Col>
{participant.tracks.map(track => (
{participant.tracks && participant.tracks.map(track => (
<span key={track.id} className="mr-1 mb-1" title={track.instrment}>
<a
id={`Participant${participant.id}Track${track.id}Instrument`}

View File

@ -1,10 +1,11 @@
import React from 'react';
import PropTypes from 'prop-types';
import { groupByKey } from '../../helpers/utils';
import { Table } from 'reactstrap';
import { Table, Button } from 'reactstrap';
import JKSessionsHistoryItem from './JKSessionsHistoryItem';
import { useTranslation } from 'react-i18next';
const JKSessionsHistoryList = ({ sessions }) => {
const JKSessionsHistoryList = ({ sessions, onNextPage, isLoading }) => {
const sessionsById = groupByKey(sessions, 'session_id');
const { t } = useTranslation();
@ -31,8 +32,23 @@ const JKSessionsHistoryList = ({ sessions }) => {
))}
</tbody>
</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;

View File

@ -20,7 +20,7 @@ import { Card, CardBody, CardHeader } from 'reactstrap';
SwiperCore.use([Navigation, Pagination, Scrollbar, A11y]);
const JKSessionsHistorySwiper = ({ sessions }) => {
const JKSessionsHistorySwiper = ({ sessions, onNextPage }) => {
const sessionsById = groupByKey(sessions, 'session_id');
const { t } = useTranslation();
@ -32,7 +32,7 @@ const JKSessionsHistorySwiper = ({ sessions }) => {
//onSlideChange={() => console.log('slide change')}
onSlideNextTransitionEnd={swiper => {
if(swiper.isEnd){
//goNextPage()
onNextPage()
}
}}
pagination={{
@ -68,6 +68,7 @@ const JKSessionsHistorySwiper = ({ sessions }) => {
JKSessionsHistorySwiper.propTypes = {
sessions: PropTypes.arrayOf(PropTypes.instanceOf(Object)).isRequired,
onNextPage: PropTypes.func.isRequired
};
export default JKSessionsHistorySwiper;

View File

@ -18,13 +18,17 @@ const useSessionHelper = (session) => {
const sessionDateTime = session => {
const date = new Date(session.created_at);
const d = new Date(date);
return d.toLocaleDateString('en-us', {
weekday: 'long',
year: 'numeric',
month: 'short',
day: 'numeric',
timeZoneName: 'short'
});
// return d.toLocaleDateString('en-us', {
// weekday: 'long',
// year: 'numeric',
// month: 'short',
// day: 'numeric',
// timeZoneName: 'short'
// });
return new Intl.DateTimeFormat('en-US', {
dateStyle: 'full',
timeStyle: 'long',
}).format(date);
};
return {

View File

@ -11,6 +11,7 @@ export const fetchUserLatencies = createAsyncThunk(
'latency/fetchUserLatencies',
async (options, thunkAPI) => {
const { currentUserId, otherUserIds } = options
console.log('X_DEBUG_ fetchUserLatencies', currentUserId, otherUserIds)
const response = await getLatencyToUsers(currentUserId, otherUserIds)
return response.json()
}

View File

@ -31,9 +31,9 @@ module JamRuby
sendgrid_recipients([user.email])
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.html
format.html { render layout: "user_mailer_beta" }
end
end

View File

@ -1,9 +1,34 @@
<% provide(:title, 'Welcome to JamKazam!') %>
<p>Were delighted you have joined our community of <%= APP_CONFIG.musician_count %> musicians. Wed 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 arent 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/>
Team JamKazam
<p>
<%= 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>

View File

@ -0,0 +1,9 @@
<% provide(:title, 'Welcome to JamKazam!') %>
<p>Were delighted you have joined our community of <%= APP_CONFIG.musician_count %> musicians. Wed 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 arent 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>

View File

@ -1,8 +1,8 @@
Welcome to JamKazam!
<%= I18n.t 'user_mailer.confirm_email.paragraph1' -%>
Were delighted you have joined our community of <%= APP_CONFIG.musician_count %> musicians. Wed 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 arent 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,
Team JamKazam
<%= I18n.t 'user_mailer.confirm_email.best_wishes' -%>
<%= I18n.t 'user_mailer.confirm_email.signature' -%>

View File

@ -0,0 +1,8 @@
Welcome to JamKazam!
Were delighted you have joined our community of <%= APP_CONFIG.musician_count %> musicians. Wed 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 arent 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

View File

@ -2,7 +2,7 @@
Hi <%= @user.first_name %>,
<% 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 | -%>
@ -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 }
-%>
<%= 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 -%>
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 -%>
<% musician.musician_instruments.each do |mi| -%>
<%= mi.description %> (<%= @instrument_proficiencies[mi.proficiency_level.to_s.to_sym] %>)
<% end -%>
View Profile: <%= APP_CONFIG.spa_origin -%>/friends?id=<%= musician.id %>&open=details
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.view_profile' -%>: <%= APP_CONFIG.spa_origin -%>/friends?id=<%= musician.id %>&open=details
<%= I18n.t 'user_mailer.new_musicians_match.send_message' -%>: <%= APP_CONFIG.spa_origin -%>/friends?id=<%= musician.id %>&open=message
<%= I18n.t 'user_mailer.new_musicians_match.send_friend_request' -%>: <%= APP_CONFIG.spa_origin -%>/friends?id=<%= musician.id %>&open=connect
<% 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

View File

@ -18,45 +18,47 @@
"
>
<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>
<%= yield %>
</div>
<footer style="text-align: center; margin: 0px auto; padding: 0px auto;">
<p>
This email was sent to you because you have an account at JamKazam. <a
href=""
style="
color: #2c7be5;
text-decoration: none;
border-bottom: 1px solid #2c7be5;
"
>Unsubscribe</a>
</p>
<div style="text-align: center; margin: 1em 0;">
<a href="https://www.facebook.com" target="_blank">
<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;">
</a>
<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 href="https://www.tiktok.com" target="_blank">
<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 href="https://www.youtube.com" target="_blank">
<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 href="https://www.x.com" target="_blank">
<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>
</div>
<p>
Copyright © 2024 JamKazam, Inc. All rights reserved.
</p>
</footer>
<% if @user && @user.unsubscribe_token -%>
<p>
<%= I18n.t "mailer_layout.footer.paragraph1" -%> <a href="https://www.jamkazam.com" target="_blank">JamKazam</a>. <a
href="https://www.jamkazam.com/unsubscribe/<%= @user.unsubscribe_token %>"
style="
color: #2c7be5;
text-decoration: none;
border-bottom: 1px solid #2c7be5;
"
><%= I18n.t "mailer_layout.footer.unsubscribe" -%></a>
</p>
<% end -%>
<div style="text-align: center; margin: 1em 0;">
<a href="https://www.facebook.com" target="_blank" style="text-decoration: none;">
<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>
<a href="https://www.instagram.com" target="_blank" style="text-decoration: none;">
<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;">
</a>
<a href="https://www.tiktok.com" target="_blank" style="text-decoration: none;">
<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;">
</a>
<a href="https://www.youtube.com" target="_blank" style="text-decoration: none;">
<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;">
</a>
<a href="https://www.x.com" target="_blank" style="text-decoration: none;">
<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;">
</a>
</div>
<p>
<%= I18n.t "mailer_layout.footer.copyright" -%>
</p>
</footer>
</div>
</body>

View File

@ -6,10 +6,10 @@ module JamRuby
JOINED_WITHIN_DAYS = 7
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
"New musicians with good Internet connections to you have joined JamKazam!"
I18n.t 'user_mailer.new_musicians_match.subject'
end
def self.send_new_musicians
@ -33,7 +33,6 @@ module JamRuby
end
begin
recipients = User.where("users.subscribe_email = ? AND
users.subscribe_email_for_user_match = ?
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(',')}')
THEN 0 ELSE 1 END, last_active_at DESC").select("users.*,
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,
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
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
matched_musician_data = []

View File

@ -23,6 +23,7 @@ describe EmailNewMusicianMatch do
ActionMailer::Base.deliveries = []
User.delete_all
allow(JamRuby::MusicianFilter).to receive(:filter).and_return(search_result)
Rails.application.config.send_user_match_mail_only_to_jamkazam_team = false
end
after(:each) do
@ -46,6 +47,14 @@ describe EmailNewMusicianMatch do
JamRuby::EmailNewMusicianMatch.send_new_musicians
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
JamRuby::EmailNewMusicianMatch.send_new_musicians
raise ActionMailer::Base.deliveries.map{|d| d['to'].to_s }.inspect #.include?("seth@example.com").should be_truthy

View File

@ -159,7 +159,7 @@ gem 'logging', '1.7.2'
gem 'rack-cors', '~> 1.0', '>= 1.0.6'
gem 'mailcatcher'
#gem 'mailcatcher'
if ENV['FASTER_PATH'] == '1'

View File

@ -518,5 +518,6 @@ if defined?(Bundler)
config.manual_override_installer_ends_with = "JamKazam-1.0.3776.dmg"
config.spa_origin = "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
end
end

View File

@ -26,8 +26,8 @@ SampleApp::Application.configure do
# Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = false
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.delivery_method = :smtp
#config.action_mailer.smtp_settings = { address: '127.0.0.1', port: 1025, domain: '127.0.0.1' }
# Print deprecation notices to the Rails logger
config.active_support.deprecation = :log
@ -123,6 +123,8 @@ SampleApp::Application.configure do
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.send_user_match_mail_only_to_jamkazam_team = false
end

View File

@ -6,8 +6,22 @@ en:
attributes:
user:
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:
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 arent 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:
subject: "New musicians with good Internet connections to you have joined JamKazam!"
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."
latency_to_you: "Latency to You"

View File

@ -6,7 +6,29 @@ en:
attributes:
user:
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:
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 arent 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:
subject: "New musicians with good Internet connections to you have joined JamKazam!"
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"