Merge with develop
This commit is contained in:
commit
aedcbde1f3
|
|
@ -49,7 +49,7 @@ gem 'unf', '0.1.3' #optional fog dependency
|
||||||
gem 'country-select'
|
gem 'country-select'
|
||||||
gem 'aasm', '3.0.16'
|
gem 'aasm', '3.0.16'
|
||||||
gem 'postgres-copy', '0.6.0'
|
gem 'postgres-copy', '0.6.0'
|
||||||
gem 'aws-sdk' #, '1.29.1'
|
gem 'aws-sdk', '~> 1'
|
||||||
gem 'bugsnag'
|
gem 'bugsnag'
|
||||||
gem 'gon'
|
gem 'gon'
|
||||||
gem 'cocoon'
|
gem 'cocoon'
|
||||||
|
|
|
||||||
|
|
@ -250,3 +250,4 @@ user_model_about_changes.sql
|
||||||
performance_samples.sql
|
performance_samples.sql
|
||||||
user_presences.sql
|
user_presences.sql
|
||||||
recorded_backing_tracks_add_filename.sql
|
recorded_backing_tracks_add_filename.sql
|
||||||
|
discard_scores_optimized.sql
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
DROP FUNCTION IF EXISTS discard_scores();
|
||||||
|
|
||||||
|
CREATE FUNCTION discard_scores (keep INTEGER) RETURNS VOID AS $$
|
||||||
|
BEGIN
|
||||||
|
|
||||||
|
DELETE FROM scores WHERE score_dt <
|
||||||
|
(SELECT score_dt FROM scores s WHERE s.alocidispid = scores.alocidispid AND s.blocidispid = scores.blocidispid ORDER BY score_dt DESC LIMIT 1 OFFSET (keep - 1));
|
||||||
|
|
||||||
|
RETURN;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION update_current_network_scores(aloc BIGINT, bloc BIGINT) RETURNS VOID
|
||||||
|
STRICT VOLATILE AS $$
|
||||||
|
DECLARE
|
||||||
|
newscore INTEGER;
|
||||||
|
newscore_dt TIMESTAMP;
|
||||||
|
newscore_limited BOOL;
|
||||||
|
sum INTEGER;
|
||||||
|
kount INTEGER;
|
||||||
|
r RECORD;
|
||||||
|
avgscore INTEGER;
|
||||||
|
maxscore INTEGER;
|
||||||
|
minscore INTEGER;
|
||||||
|
BEGIN
|
||||||
|
-- find the 6 most recent scores
|
||||||
|
-- (supposedly newscore is the first...)
|
||||||
|
-- hybrid scheme: compute the average of some recent scores, then limit newscore to be between 4/5 and 6/5 of the average
|
||||||
|
newscore := NULL;
|
||||||
|
newscore_dt := NULL;
|
||||||
|
newscore_limited := FALSE;
|
||||||
|
sum := 0;
|
||||||
|
kount := 0;
|
||||||
|
FOR r IN SELECT score, score_dt FROM scores WHERE alocidispid = aloc AND blocidispid = bloc ORDER BY score_dt DESC LIMIT 6 LOOP
|
||||||
|
IF newscore IS NULL THEN
|
||||||
|
newscore := r.score;
|
||||||
|
newscore_dt := r.score_dt;
|
||||||
|
ELSE
|
||||||
|
sum := sum + r.score;
|
||||||
|
kount := kount + 1;
|
||||||
|
END IF;
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
-- if no scores in query at all, then delete any current entry
|
||||||
|
IF newscore IS NULL THEN
|
||||||
|
DELETE FROM current_network_scores WHERE alocidispid = aloc AND blocidispid = bloc;
|
||||||
|
IF aloc != bloc THEN
|
||||||
|
DELETE FROM current_network_scores WHERE alocidispid = bloc AND blocidispid = aloc;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- if there are scores older than newscore, then use their average to limit the range of newscore
|
||||||
|
IF kount > 0 THEN
|
||||||
|
avgscore := sum / kount;
|
||||||
|
maxscore := avgscore*6/5;
|
||||||
|
minscore := avgscore*4/5;
|
||||||
|
-- the score newscore will be inserted as the current value in current_network_scores, but we will limit it
|
||||||
|
-- to be no greater than 120% of the average and no less than 80% of the average. this will dampen wild
|
||||||
|
-- swings in the scores.
|
||||||
|
IF newscore > maxscore THEN
|
||||||
|
newscore := maxscore;
|
||||||
|
newscore_limited := TRUE;
|
||||||
|
ELSEIF newscore < minscore THEN
|
||||||
|
newscore := minscore;
|
||||||
|
newscore_limited := TRUE;
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
UPDATE current_network_scores SET score = newscore, limited = newscore_limited, score_dt = newscore_dt WHERE alocidispid = aloc AND blocidispid = bloc;
|
||||||
|
IF NOT FOUND THEN
|
||||||
|
INSERT INTO current_network_scores (alocidispid, blocidispid, score, limited, score_dt) VALUES (aloc, bloc, newscore, newscore_limited, newscore_dt);
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF aloc != bloc THEN
|
||||||
|
UPDATE current_network_scores SET score = newscore, limited = newscore_limited, score_dt = newscore_dt WHERE alocidispid = bloc AND blocidispid = aloc;
|
||||||
|
IF NOT FOUND THEN
|
||||||
|
INSERT INTO current_network_scores (alocidispid, blocidispid, score, limited, score_dt) VALUES (bloc, aloc, newscore, newscore_limited, newscore_dt);
|
||||||
|
END IF;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- keep the scores table clean, meaning only up to the most 5 recent scores per group & direction (scorer)
|
||||||
|
DELETE FROM scores WHERE alocidispid = aloc AND blocidispid = bloc AND scorer = 0 AND score_dt <
|
||||||
|
(SELECT score_dt FROM scores s WHERE s.alocidispid = aloc AND s.blocidispid = bloc AND s.scorer = 0 ORDER BY score_dt DESC LIMIT 1 OFFSET 4);
|
||||||
|
DELETE FROM scores WHERE alocidispid = bloc AND blocidispid = aloc AND scorer = 1 AND score_dt <
|
||||||
|
(SELECT score_dt FROM scores s WHERE s.alocidispid = bloc AND s.blocidispid = aloc AND s.scorer = 1 ORDER BY score_dt DESC LIMIT 1 OFFSET 4);
|
||||||
|
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
@ -50,6 +50,7 @@ describe "Deployed site at #{www}", :js => true, :type => :feature, :capybara_fe
|
||||||
end
|
end
|
||||||
|
|
||||||
it "is possible for #{user3} to sign in and not get disconnected within 30 seconds" do
|
it "is possible for #{user3} to sign in and not get disconnected within 30 seconds" do
|
||||||
|
pending "continual failures - need to debug - try using Selenium instead of PhantomJS"
|
||||||
as_monitor(user3) do
|
as_monitor(user3) do
|
||||||
sign_in_poltergeist(user3)
|
sign_in_poltergeist(user3)
|
||||||
repeat_for(30.seconds) do
|
repeat_for(30.seconds) do
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ gem 'amqp', '1.0.2'
|
||||||
gem 'will_paginate'
|
gem 'will_paginate'
|
||||||
gem 'actionmailer', '3.2.13'
|
gem 'actionmailer', '3.2.13'
|
||||||
gem 'sendgrid', '1.2.0'
|
gem 'sendgrid', '1.2.0'
|
||||||
gem 'aws-sdk' #, '1.29.1'
|
gem 'aws-sdk', '~> 1'
|
||||||
gem 'carrierwave', '0.9.0'
|
gem 'carrierwave', '0.9.0'
|
||||||
gem 'aasm', '3.0.16'
|
gem 'aasm', '3.0.16'
|
||||||
gem 'devise', '3.3.0' # 3.4.0 causes: uninitialized constant ActionController::Metal (NameError)
|
gem 'devise', '3.3.0' # 3.4.0 causes: uninitialized constant ActionController::Metal (NameError)
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ require "jam_ruby/resque/resque_hooks"
|
||||||
require "jam_ruby/resque/audiomixer"
|
require "jam_ruby/resque/audiomixer"
|
||||||
require "jam_ruby/resque/quick_mixer"
|
require "jam_ruby/resque/quick_mixer"
|
||||||
require "jam_ruby/resque/icecast_config_writer"
|
require "jam_ruby/resque/icecast_config_writer"
|
||||||
|
require "jam_ruby/resque/stress_job"
|
||||||
require "jam_ruby/resque/scheduled/audiomixer_retry"
|
require "jam_ruby/resque/scheduled/audiomixer_retry"
|
||||||
require "jam_ruby/resque/scheduled/icecast_config_retry"
|
require "jam_ruby/resque/scheduled/icecast_config_retry"
|
||||||
require "jam_ruby/resque/scheduled/icecast_source_check"
|
require "jam_ruby/resque/scheduled/icecast_source_check"
|
||||||
|
|
|
||||||
|
|
@ -1,45 +1,64 @@
|
||||||
<% provide(:title, 'Welcome to JamKazam!') %>
|
<% provide(:title, 'Welcome to JamKazam!') %>
|
||||||
|
|
||||||
|
|
||||||
<p>Hello <%= EmailBatchProgression::VAR_FIRST_NAME %> --
|
<p>Hello <%= EmailBatchProgression::VAR_FIRST_NAME %> --
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
<p> We're delighted that you have decided to try the JamKazam service,
|
<p> We're delighted that you have decided to try the JamKazam service,
|
||||||
and we hope that you will enjoy using JamKazam to play music with others.
|
and we hope that you will enjoy using JamKazam to play
|
||||||
Following are links to some resources that can help to get you up and running quickly.
|
music with others.
|
||||||
|
Following are some resources that can help you get oriented and get the most out of JamKazam.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
|
<p><b style="color: white;">Getting Started</b><br/>
|
||||||
|
There are basically three kinds of setups you can use to play on JamKazam.<br/>
|
||||||
|
<ul>
|
||||||
|
<li><b style="color: white;">Built-In Audio on Your Computer</b> - You can use a Windows or Mac computer, and just use the built-in mic and headphone jack to
|
||||||
|
handle your audio. This is cheap and easy, but your audio quality will suffer, and it will also process audio very slowly,
|
||||||
|
creating problems with latency, or lag, in your sessions. Still, you can at least start experimenting with JamKazam in this way.</li>
|
||||||
|
<li><b style="color: white;">Computer with External Audio Interface</b> - You can use a Windows or Mac computer with an external audio interface that you
|
||||||
|
already own and use for recording, if you happen to have one already. If you are going to do this, or use the built-in mic/headphones on your computer, please refer
|
||||||
|
to our <a style="color: #ffcc00;" href="https://jamkazam.desk.com/customer/portal/articles/1288274-minimum-system-requirements">Minimum System Requirements</a>
|
||||||
|
to make sure your computer will work. These requirements were on the download page for the app, but you may have sped by them. Also, we'd recommend watching our
|
||||||
|
<a style="color: #ffcc00;" href="https://www.youtube.com/watch?v=DBo--aj_P1w">Getting Started Video</a> to learn more about your options here.</li>
|
||||||
|
<li><b style="color: white;">The JamBlaster</b> - JamKazam has designed a new product from the ground up to be the best way to play music online in real time. It's called the JamBlaster.
|
||||||
|
It processes audio faster than any of the thousands of combinations of computers and interfaces in use on JamKazam today, which means you can play with musicians
|
||||||
|
who are farther away from you, and closer sessions will feel/sound tighter. The JamBlaster is both a computer and an audio interface, so it also eliminates the
|
||||||
|
system requirements worries, and it "just works" so you don't have to be an audio and computer genius to get it working. This is a great product - available only
|
||||||
|
through a Kickstarter program running during a 30-day window during parts of February and March 2015. You can watch the
|
||||||
|
<a style="color: #ffcc00;" href="https://www.youtube.com/watch?v=gAJAIHMyois">JamBlaster Video</a> to learn more about this amazing new product.</li>
|
||||||
|
</ul>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p><b style="color: white;">JamKazam Features</b><br/>
|
||||||
|
JamKazam offers a very robust and exciting set of features for playing online and sharing your performances with others. Here are some videos you can watch
|
||||||
|
to easily get up to speed on some of the things you can do with JamKazam:<br/>
|
||||||
|
<ul>
|
||||||
|
<li><a style="color: #ffcc00;" href="https://www.youtube.com/watch?v=EZZuGcDUoWk">Creating a Session</a></li>
|
||||||
|
<li><a style="color: #ffcc00;" href="https://www.youtube.com/watch?v=xWponSJo-GU">Finding a Session</a></li>
|
||||||
|
<li><a style="color: #ffcc00;" href="https://www.youtube.com/watch?v=zJ68hA8-fLA">Playing in a Session</a></li>
|
||||||
|
<li><a style="color: #ffcc00;" href="https://www.youtube.com/watch?v=4KWklSZZxRc">Connecting with Other Musicians</a></li>
|
||||||
|
<li><a style="color: #ffcc00;" href="https://www.youtube.com/watch?v=Gn-dOqnNLoY">Working with Recordings</a></li>
|
||||||
|
</ul>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p><b style="color: white;">Getting Help</b><br/>
|
||||||
|
If you run into trouble and need help, please reach out to us. We will be glad to do everything we can to answer your questions and get you up and running.
|
||||||
|
You can visit our
|
||||||
|
<a style="color: #ffcc00;" href="https://jamkazam.desk.com/">Support Portal</a>
|
||||||
|
to find knowledge base articles and post questions that have
|
||||||
|
not already been answered. You can email us at support@jamkazam.com. And if you just want to chat, share tips and war stories, and hang out with fellow JamKazamers,
|
||||||
|
you can visit our <a style="color: #ffcc00;" href="http://forums.jamkazam.com/">Community Forum</a>
|
||||||
|
.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Getting Started Video<br/>
|
Again, welcome to JamKazam, and we look forward to seeing – and hearing – you online soon!
|
||||||
We recommend watching this video before you jump into the service just to get oriented. It will really help you hit the ground running:
|
|
||||||
<a style="color: #ffcc00;" href="https://www.youtube.com/watch?v=DBo--aj_P1w">https://www.youtube.com/watch?v=DBo--aj_P1w</a>
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>Best Regards,<br/>
|
||||||
Other Great Tutorial Videos<br />
|
Team JamKazam</p>
|
||||||
There are several other very great videos that will help you understand how to find and connect with other musicians on the service, create your own sessions or find and join other musicians’ sessions, play in sessions, record and share your performances, and even live broadcast your sessions to family, friends, and fans. Check these helpful videos out here:
|
|
||||||
<a style="color: #ffcc00;" href="https://jamkazam.desk.com/customer/portal/topics/673198-tutorials-on-major-features/articles">https://jamkazam.desk.com/customer/portal/topics/673198-tutorials-on-major-features/articles</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Knowledge Base Articles<br />
|
|
||||||
You can find Getting Started knowledge base articles on things like frequently asked questions (FAQ), minimum system requirements for your Windows or Mac computer, how to troubleshoot audio problems in sessions, and more here:
|
|
||||||
<a style="color: #ffcc00;" href="https://jamkazam.desk.com/customer/portal/topics/564807-getting-started/articles">https://jamkazam.desk.com/customer/portal/topics/564807-getting-started/articles</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
JamKazam Support Portal<br />
|
|
||||||
If you run into trouble and need help, please reach out to us. We will be glad to do everything we can to get you up and running. You can find our support portal here:
|
|
||||||
<a style="color: #ffcc00;" href="https://jamkazam.desk.com/">https://jamkazam.desk.com/</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
JamKazam Community Forum<br />
|
|
||||||
And if you just want to chat, share tips and war stories, and hang out with fellow JamKazamers, you can visit our community forum here:
|
|
||||||
<a style="color: #ffcc00;" href="http://forums.jamkazam.com/">http://forums.jamkazam.com/</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Please take a moment to like or follow us by clicking the icons below, and we look forward to seeing – and hearing – you online soon!
|
|
||||||
</p>
|
|
||||||
|
|
||||||
-- Team JamKazam
|
|
||||||
|
|
@ -1,27 +1,43 @@
|
||||||
Hello <%= EmailBatchProgression::VAR_FIRST_NAME %> --
|
Hello <%= EmailBatchProgression::VAR_FIRST_NAME %> --
|
||||||
|
|
||||||
We're delighted that you have decided to try the JamKazam service, and we hope that you will enjoy using JamKazam to play music with others. Following are links to some resources that can help to get you up and running quickly.
|
We're delighted that you have decided to try the JamKazam service, and we hope that you will enjoy using JamKazam to play music with others. Following are some resources that can help you get oriented and get the most out of JamKazam.
|
||||||
|
|
||||||
Getting Started Video
|
|
||||||
We recommend watching this video before you jump into the service just to get oriented. It will really help you hit the ground running:
|
|
||||||
https://www.youtube.com/watch?v=DBo--aj_P1w
|
|
||||||
|
|
||||||
Other Great Tutorial Videos
|
Getting Started
|
||||||
There are several other very great videos that will help you understand how to find and connect with other musicians on the service, create your own sessions or find and join other musicians’ sessions, play in sessions, record and share your performances, and even live broadcast your sessions to family, friends, and fans. Check these helpful videos out here:
|
---------------
|
||||||
https://jamkazam.desk.com/customer/portal/topics/673198-tutorials-on-major-features/articles
|
|
||||||
|
|
||||||
Knowledge Base Articles
|
There are basically three kinds of setups you can use to play on JamKazam.
|
||||||
You can find Getting Started knowledge base articles on things like frequently asked questions (FAQ), minimum system requirements for your Windows or Mac computer, how to troubleshoot audio problems in sessions, and more here:
|
|
||||||
https://jamkazam.desk.com/customer/portal/topics/564807-getting-started/articles
|
|
||||||
|
|
||||||
JamKazam Support Portal
|
* Built-In Audio on Your Computer - You can use a Windows or Mac computer, and just use the built-in mic and headphone jack to handle your audio. This is cheap and easy, but your audio quality will suffer, and it will also process audio very slowly, creating problems with latency, or lag, in your sessions. Still, you can at least start experimenting with JamKazam in this way.
|
||||||
If you run into trouble and need help, please reach out to us. We will be glad to do everything we can to get you up and running. You can find our support portal here:
|
|
||||||
https://jamkazam.desk.com
|
|
||||||
|
|
||||||
JamKazam Community Forum
|
* Computer with External Audio Interface - - You can use a Windows or Mac computer with an external audio interface that you already own and use for recording, if you happen to have one already. If you are going to do this, or use the built-in mic/headphones on your computer, please refer to our Minimum System Requirements at https://jamkazam.desk.com/customer/portal/articles/1288274-minimum-system-requirements to make sure your computer will work. These requirements were on the download page for the app, but you may have sped by them. Also, we'd recommend watching our Getting Started Video at https://www.youtube.com/watch?v=DBo--aj_P1w to learn more about your options here.
|
||||||
And if you just want to chat, share tips and war stories, and hang out with fellow JamKazamers, you can visit our community forum here:
|
|
||||||
http://forums.jamkazam.com
|
|
||||||
|
|
||||||
Please take a moment to like or follow us by clicking the icons below, and we look forward to seeing – and hearing – you online soon!
|
* The JamBlaster - JamKazam has designed a new product from the ground up to be the best way to play music online in real time. It's called the JamBlaster. It processes audio faster than any of the thousands of combinations of computers and interfaces in use on JamKazam today, which means you can play with musicians who are farther away from you, and closer sessions will feel/sound tighter. The JamBlaster is both a computer and an audio interface, so it also eliminates the system requirements worries, and it "just works" so you don't have to be an audio and computer genius to get it working. This is a great product - available only through a Kickstarter program running during a 30-day window during parts of February and March 2015. You can watch the JamBlaster Video at https://www.youtube.com/watch?v=gAJAIHMyois to learn more about this amazing new product.
|
||||||
|
|
||||||
|
|
||||||
|
JamKazam Features
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
JamKazam offers a very robust and exciting set of features for playing online and sharing your performances with others. Here are some videos you can watch to easily get up to speed on some of the things you can do with JamKazam:
|
||||||
|
|
||||||
|
* Creating a Session - https://www.youtube.com/watch?v=EZZuGcDUoWk
|
||||||
|
|
||||||
|
* Finding a Session - https://www.youtube.com/watch?v=xWponSJo-GU
|
||||||
|
|
||||||
|
* Playing in a Session - https://www.youtube.com/watch?v=zJ68hA8-fLA
|
||||||
|
|
||||||
|
* Connecting with Other Musicians - https://www.youtube.com/watch?v=4KWklSZZxRc
|
||||||
|
|
||||||
|
* Working with Recordings - https://www.youtube.com/watch?v=Gn-dOqnNLoY
|
||||||
|
|
||||||
|
|
||||||
|
Getting Help
|
||||||
|
------------
|
||||||
|
|
||||||
|
If you run into trouble and need help, please reach out to us. We will be glad to do everything we can to answer your questions and get you up and running. You can visit our Support Portal at https://jamkazam.desk.com/ to find knowledge base articles and post questions that have not already been answered. You can email us at support@jamkazam.com. And if you just want to chat, share tips and war stories, and hang out with fellow JamKazamers, you can visit our Community Forum at http://forums.jamkazam.com/.
|
||||||
|
|
||||||
|
Again, welcome to JamKazam, and we look forward to seeing – and hearing – you online soon!
|
||||||
|
|
||||||
|
Best Regards,
|
||||||
|
Team JamKazam
|
||||||
|
|
||||||
-- Team JamKazam
|
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@ Resque.before_first_fork do
|
||||||
end
|
end
|
||||||
|
|
||||||
JamRuby::Stats.init(config)
|
JamRuby::Stats.init(config)
|
||||||
|
|
||||||
end
|
end
|
||||||
# https://devcenter.heroku.com/articles/forked-pg-connections
|
# https://devcenter.heroku.com/articles/forked-pg-connections
|
||||||
Resque.before_fork do
|
Resque.before_fork do
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
require 'resque'
|
||||||
|
|
||||||
|
module JamRuby
|
||||||
|
|
||||||
|
# this job exists as a way to manually test a bunch of jobs firing at once. It's not a real job.
|
||||||
|
class StressJob
|
||||||
|
extend JamRuby::ResqueStats
|
||||||
|
|
||||||
|
@queue = :stress_job
|
||||||
|
|
||||||
|
@@log = Logging.logger[StressJob]
|
||||||
|
|
||||||
|
|
||||||
|
def self.perform
|
||||||
|
|
||||||
|
@@log.debug("STARTING")
|
||||||
|
100.times do
|
||||||
|
user = User.first.id
|
||||||
|
diagnostic = Diagnostic.first.user_id
|
||||||
|
count = Diagnostic.all.count
|
||||||
|
end
|
||||||
|
@@log.debug("ENDING")
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -522,29 +522,30 @@ describe Score do
|
||||||
it "works" do
|
it "works" do
|
||||||
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
|
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
|
||||||
Score.count.should == 2
|
Score.count.should == 2
|
||||||
Score.connection.execute("SELECT discard_scores()").check
|
Score.connection.execute("SELECT discard_scores(5)").check
|
||||||
Score.count.should == 2
|
Score.count.should == 2
|
||||||
end
|
end
|
||||||
|
|
||||||
it "discards over 5 items" do
|
it "discards over 5 items" do
|
||||||
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
|
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, 6.days.ago)
|
||||||
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
|
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, 5.days.ago)
|
||||||
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
|
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, 4.days.ago)
|
||||||
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
|
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, 3.days.ago)
|
||||||
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
|
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, 2.days.ago)
|
||||||
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, nil)
|
|
||||||
|
|
||||||
Score.count.should == 12
|
Score.count.should == 10
|
||||||
Score.connection.execute("SELECT discard_scores()").check
|
|
||||||
Score.count.should == 12
|
|
||||||
|
|
||||||
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 26, nil)
|
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 20, 1.days.ago)
|
||||||
Score.connection.execute("UPDATE scores set created_at = TIMESTAMP '#{2.days.ago}' WHERE score = 26").cmdtuples.should == 2
|
|
||||||
Score.connection.execute("SELECT discard_scores()").check
|
Score.count.should == 10
|
||||||
Score.count.should == 12
|
|
||||||
Score.connection.execute("SELECT * FROM scores WHERE score = 20").ntuples.should == 12
|
# make a score older than all the rest; it should get whacked
|
||||||
Score.connection.execute("SELECT * FROM scores WHERE scorer = 0").ntuples.should == 6
|
Score.createx(LOCA, NODEA, ADDRA, LOCB, NODEB, ADDRB, 26, 7.days.ago)
|
||||||
Score.connection.execute("SELECT * FROM scores WHERE scorer = 1").ntuples.should == 6
|
|
||||||
|
Score.count.should == 10
|
||||||
|
Score.connection.execute("SELECT * FROM scores WHERE score = 20").ntuples.should == 10
|
||||||
|
Score.connection.execute("SELECT * FROM scores WHERE scorer = 0").ntuples.should == 5
|
||||||
|
Score.connection.execute("SELECT * FROM scores WHERE scorer = 1").ntuples.should == 5
|
||||||
|
|
||||||
|
|
||||||
Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil)
|
Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil)
|
||||||
|
|
@ -554,18 +555,35 @@ describe Score do
|
||||||
Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil)
|
Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil)
|
||||||
Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil)
|
Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 22, nil)
|
||||||
|
|
||||||
Score.count.should == 24
|
Score.count.should == 20
|
||||||
Score.connection.execute("SELECT discard_scores()").check
|
|
||||||
Score.count.should == 24
|
|
||||||
|
|
||||||
Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 36, nil)
|
Score.connection.execute("SELECT * FROM scores WHERE score = 22").ntuples.should == 10
|
||||||
Score.connection.execute("UPDATE scores set created_at = TIMESTAMP '#{2.days.ago}' WHERE score = 36").cmdtuples.should == 2
|
Score.connection.execute("SELECT * FROM scores WHERE score = 20").ntuples.should == 10
|
||||||
Score.connection.execute("SELECT discard_scores()").check
|
Score.connection.execute("SELECT * FROM scores WHERE scorer = 0").ntuples.should == 10
|
||||||
Score.count.should == 24
|
Score.connection.execute("SELECT * FROM scores WHERE scorer = 1").ntuples.should == 10
|
||||||
Score.connection.execute("SELECT * FROM scores WHERE score = 22").ntuples.should == 12
|
|
||||||
Score.connection.execute("SELECT * FROM scores WHERE score = 22 AND scorer = 0").ntuples.should == 6
|
|
||||||
Score.connection.execute("SELECT * FROM scores WHERE score = 22 AND scorer = 1").ntuples.should == 6
|
|
||||||
|
|
||||||
|
Score.createx(LOCB, NODEB, ADDRB, LOCA, NODEA, ADDRA, 36, 7.days.ago)
|
||||||
|
Score.count.should == 20
|
||||||
|
Score.connection.execute("SELECT * FROM scores WHERE score = 22").ntuples.should == 10
|
||||||
|
Score.connection.execute("SELECT * FROM scores WHERE score = 20").ntuples.should == 10
|
||||||
|
Score.connection.execute("SELECT * FROM scores WHERE scorer = 0").ntuples.should == 10
|
||||||
|
Score.connection.execute("SELECT * FROM scores WHERE scorer = 1").ntuples.should == 10
|
||||||
|
|
||||||
|
# let's create scores between a new location, and make sure they don't distrurb the data we have now
|
||||||
|
Score.createx(LOCC, NODEC, ADDRC, LOCA, NODEA, ADDRA, 10, nil)
|
||||||
|
|
||||||
|
Score.count.should == 22
|
||||||
|
|
||||||
|
Score.createx(LOCC, NODEC, ADDRC, LOCA, NODEA, ADDRA, 10, nil)
|
||||||
|
Score.createx(LOCC, NODEC, ADDRC, LOCA, NODEA, ADDRA, 10, nil)
|
||||||
|
Score.createx(LOCC, NODEC, ADDRC, LOCA, NODEA, ADDRA, 10, nil)
|
||||||
|
Score.createx(LOCC, NODEC, ADDRC, LOCA, NODEA, ADDRA, 10, nil)
|
||||||
|
|
||||||
|
Score.count.should == 30
|
||||||
|
|
||||||
|
Score.connection.execute("SELECT * FROM scores WHERE score = 20").ntuples.should == 10
|
||||||
|
Score.connection.execute("SELECT * FROM scores WHERE score = 22").ntuples.should == 10
|
||||||
|
Score.connection.execute("SELECT * FROM scores WHERE score = 10").ntuples.should == 10
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ gem 'twitter'
|
||||||
gem 'fb_graph', '2.5.9'
|
gem 'fb_graph', '2.5.9'
|
||||||
gem 'sendgrid', '1.2.0'
|
gem 'sendgrid', '1.2.0'
|
||||||
gem 'filepicker-rails', '0.1.0'
|
gem 'filepicker-rails', '0.1.0'
|
||||||
gem 'aws-sdk' #, '1.29.1'
|
gem 'aws-sdk', '~> 1'
|
||||||
gem 'aasm', '3.0.16'
|
gem 'aasm', '3.0.16'
|
||||||
gem 'carrierwave', '0.9.0'
|
gem 'carrierwave', '0.9.0'
|
||||||
gem 'carrierwave_direct'
|
gem 'carrierwave_direct'
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 198 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 126 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 205 KiB |
|
|
@ -355,7 +355,7 @@
|
||||||
context._.each(tracks.tracks, function(track) {
|
context._.each(tracks.tracks, function(track) {
|
||||||
if(!track.instrument_id) {
|
if(!track.instrument_id) {
|
||||||
logger.debug("ConfigureTracks validation error: all tracks with ports assigned must specify an instrument.");
|
logger.debug("ConfigureTracks validation error: all tracks with ports assigned must specify an instrument.");
|
||||||
context.JK.Banner.showAlert('All tracks with ports assigned must specify an instrument.');
|
context.JK.Banner.showAlert('Please use the instrument icons to choose what you plan to play on each track.');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1539,6 +1539,14 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function validateUrlSite(url, sitetype) {
|
||||||
|
return $.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: '/api/data_validation?sitetype='+sitetype+'&data=' + encodeURIComponent(url),
|
||||||
|
contentType: 'application/json'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function initialize() {
|
function initialize() {
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
@ -1675,6 +1683,7 @@
|
||||||
this.resendBandInvitation = resendBandInvitation;
|
this.resendBandInvitation = resendBandInvitation;
|
||||||
this.getMount = getMount;
|
this.getMount = getMount;
|
||||||
this.createSourceChange = createSourceChange;
|
this.createSourceChange = createSourceChange;
|
||||||
|
this.validateUrlSite = validateUrlSite;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -215,6 +215,14 @@
|
||||||
top: childLayout.top,
|
top: childLayout.top,
|
||||||
left: childLayout.left
|
left: childLayout.left
|
||||||
}, opts.animationDuration);
|
}, opts.animationDuration);
|
||||||
|
|
||||||
|
if($(this).is('.feed')) {
|
||||||
|
$('#jamblaster-notice').animate({
|
||||||
|
width: childLayout.width,
|
||||||
|
bottom: '102%',
|
||||||
|
left: childLayout.left
|
||||||
|
}, opts.animationDuration)
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -221,9 +221,9 @@
|
||||||
$.each(response, function(index, val) {
|
$.each(response, function(index, val) {
|
||||||
|
|
||||||
// this means the session no longer exists
|
// this means the session no longer exists
|
||||||
if (response.fan_access == null && response.musician_access == null) {
|
//if (response.fan_access == null && response.musician_access == null) {
|
||||||
return;
|
// return;
|
||||||
}
|
//}
|
||||||
|
|
||||||
if(val.description == context.JK.MessageType.TEXT_MESSAGE) {
|
if(val.description == context.JK.MessageType.TEXT_MESSAGE) {
|
||||||
val.formatted_msg = textMessageDialog.formatTextMessage(val.message.substring(0, 200), val.source_user_id, val.source_user.name, val.message.length > 200).html();
|
val.formatted_msg = textMessageDialog.formatTextMessage(val.message.substring(0, 200), val.source_user_id, val.source_user.name, val.message.length > 200).html();
|
||||||
|
|
|
||||||
|
|
@ -226,27 +226,9 @@
|
||||||
if (showJoinLink) {
|
if (showJoinLink) {
|
||||||
// wire up the Join Link to the T&Cs dialog
|
// wire up the Join Link to the T&Cs dialog
|
||||||
$('.join-link', $parentRow).click(function(evt) {
|
$('.join-link', $parentRow).click(function(evt) {
|
||||||
if(!context.JK.guardAgainstBrowser(app)) {
|
sessionUtils.ensureValidClient(app, gearUtils, function() {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!context.JK.JamServer.connected) {
|
|
||||||
app.notifyAlert("Not Connected", 'To create or join a session, you must be connected to the server.');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
gearUtils.guardAgainstInvalidConfiguration(app)
|
|
||||||
.fail(function() {
|
|
||||||
app.notify(
|
|
||||||
{ title: "Unable to Join Session",
|
|
||||||
text: "You can only join a session once you have working audio gear and a tested internet connection."
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.done(function(){
|
|
||||||
sessionUtils.joinSession(session.id);
|
sessionUtils.joinSession(session.id);
|
||||||
})
|
});
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -368,7 +350,7 @@
|
||||||
$('a.more.rsvps', $parentRow).click(toggleRsvps);
|
$('a.more.rsvps', $parentRow).click(toggleRsvps);
|
||||||
|
|
||||||
var showRsvpLink = true;
|
var showRsvpLink = true;
|
||||||
var noLinkText = '';
|
var sessionLinkText = '';
|
||||||
$('.rsvp-link-text', $parentRow).hide();
|
$('.rsvp-link-text', $parentRow).hide();
|
||||||
|
|
||||||
function showStartSessionButton(scheduledStart) {
|
function showStartSessionButton(scheduledStart) {
|
||||||
|
|
@ -380,8 +362,8 @@
|
||||||
|
|
||||||
if (session.creator.id === context.JK.currentUserId) {
|
if (session.creator.id === context.JK.currentUserId) {
|
||||||
showRsvpLink = false;
|
showRsvpLink = false;
|
||||||
noLinkText = $('<span class="text"><a class="start" style="color: #fc0">Start session now?</a></span>');
|
sessionLinkText = $('<span class="text"><a class="start" style="color: #fc0">Start session now?</a></span>');
|
||||||
noLinkText.find('a').click(function() {
|
sessionLinkText.find('a').click(function() {
|
||||||
ui.launchSessionStartDialog(session);
|
ui.launchSessionStartDialog(session);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
@ -390,18 +372,18 @@
|
||||||
showRsvpLink = false;
|
showRsvpLink = false;
|
||||||
|
|
||||||
if (session.scheduled_start && showStartSessionButton(session.scheduled_start)) {
|
if (session.scheduled_start && showStartSessionButton(session.scheduled_start)) {
|
||||||
noLinkText = $('<span class="text"><a class="start" style="color: #fc0">Start session now?</a> | <a class="cancel" style="color: #fc0">Cancel RSVP</a></span>');
|
sessionLinkText = $('<span class="text"><a class="start" style="color: #fc0">Start session now?</a> | <a class="cancel" style="color: #fc0">Cancel RSVP</a></span>');
|
||||||
noLinkText.find('a.start').click(function() {
|
sessionLinkText.find('a.start').click(function() {
|
||||||
ui.launchSessionStartDialog(session);
|
ui.launchSessionStartDialog(session);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
noLinkText = $('<span class="text"><a class="cancel" style="color: #fc0">Cancel RSVP</a></span>');
|
sessionLinkText = $('<span class="text"><a class="cancel" style="color: #fc0">Cancel RSVP</a></span>');
|
||||||
}
|
}
|
||||||
|
|
||||||
// wire cancel link
|
// wire cancel link
|
||||||
noLinkText.find('a.cancel').click(function() {
|
sessionLinkText.find('a.cancel').click(function() {
|
||||||
ui.launchRsvpCancelDialog(session.id, approvedRsvpId)
|
ui.launchRsvpCancelDialog(session.id, approvedRsvpId)
|
||||||
.one(EVENTS.RSVP_CANCELED, function() {
|
.one(EVENTS.RSVP_CANCELED, function() {
|
||||||
rest.getSessionHistory(session.id)
|
rest.getSessionHistory(session.id)
|
||||||
|
|
@ -419,8 +401,8 @@
|
||||||
showRsvpLink = false;
|
showRsvpLink = false;
|
||||||
|
|
||||||
if (session.scheduled_start && showStartSessionButton(session.scheduled_start)) {
|
if (session.scheduled_start && showStartSessionButton(session.scheduled_start)) {
|
||||||
noLinkText = $('<span class="text"><a class="start" style="color: #fc0">Start session now?</a></span>');
|
sessionLinkText = $('<span class="text"><a class="start" style="color: #fc0">Start session now?</a></span>');
|
||||||
noLinkText.find('a').click(function() {
|
sessionLinkText.find('a').click(function() {
|
||||||
ui.launchSessionStartDialog(session);
|
ui.launchSessionStartDialog(session);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
@ -428,8 +410,8 @@
|
||||||
}
|
}
|
||||||
else if (pendingRsvpId) {
|
else if (pendingRsvpId) {
|
||||||
showRsvpLink = false;
|
showRsvpLink = false;
|
||||||
noLinkText = $('<span class="text"><a class="cancel" style="color: #fc0">Cancel RSVP</a></span>');
|
sessionLinkText = $('<span class="text"><a class="cancel" style="color: #fc0">Cancel RSVP</a></span>');
|
||||||
noLinkText.find('a').click(function() {
|
sessionLinkText.find('a').click(function() {
|
||||||
ui.launchRsvpCancelDialog(session.id, pendingRsvpId)
|
ui.launchRsvpCancelDialog(session.id, pendingRsvpId)
|
||||||
.one(EVENTS.RSVP_CANCELED, function() {
|
.one(EVENTS.RSVP_CANCELED, function() {
|
||||||
rest.getSessionHistory(session.id)
|
rest.getSessionHistory(session.id)
|
||||||
|
|
@ -445,11 +427,11 @@
|
||||||
}
|
}
|
||||||
else if (!openSlots) {
|
else if (!openSlots) {
|
||||||
showRsvpLink = false;
|
showRsvpLink = false;
|
||||||
noLinkText = '<span class="text">No more openings in this session.</span>';
|
sessionLinkText = '<span class="text">No more openings in this session.</span>';
|
||||||
}
|
}
|
||||||
else if (!openRsvps && !hasInvitation) {
|
else if (!openRsvps && !hasInvitation) {
|
||||||
showRsvpLink = false;
|
showRsvpLink = false;
|
||||||
noLinkText = '<span class="text">You need an invitation to RSVP to this session.</span>';
|
sessionLinkText = '<span class="text">You need an invitation to RSVP to this session.</span>';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (showRsvpLink) {
|
if (showRsvpLink) {
|
||||||
|
|
@ -472,7 +454,7 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$('.rsvp-msg', $parentRow).html(noLinkText).show();
|
$('.rsvp-msg', $parentRow).html(sessionLinkText).show();
|
||||||
$('.rsvp-link', $parentRow).hide();
|
$('.rsvp-link', $parentRow).hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,33 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sessionUtils.ensureValidClient = function(app, gearUtils, successCallback) {
|
||||||
|
|
||||||
|
if(!context.JK.guardAgainstBrowser(app)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!context.JK.JamServer.connected) {
|
||||||
|
app.notifyAlert("Not Connected", 'To create or join a session, you must be connected to the server.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
gearUtils.guardAgainstInvalidConfiguration(app)
|
||||||
|
.fail(function() {
|
||||||
|
app.notify(
|
||||||
|
{ title: "Unable to Join Session",
|
||||||
|
text: "You can only join a session once you have working audio gear and a tested internet connection."
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.done(function() {
|
||||||
|
if (successCallback) {
|
||||||
|
successCallback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
sessionUtils.joinSession = function(sessionId) {
|
sessionUtils.joinSession = function(sessionId) {
|
||||||
|
|
||||||
var hasInvitation = false;
|
var hasInvitation = false;
|
||||||
var session = null;
|
var session = null;
|
||||||
// we need to do a real-time check of the session in case the settings have
|
// we need to do a real-time check of the session in case the settings have
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,84 @@
|
||||||
|
$ = jQuery
|
||||||
|
context = window
|
||||||
|
context.JK ||= {};
|
||||||
|
|
||||||
|
context.JK.SiteValidator = class SiteValidator
|
||||||
|
|
||||||
|
constructor: (site_type) ->
|
||||||
|
@EVENTS = context.JK.EVENTS
|
||||||
|
@rest = context.JK.Rest()
|
||||||
|
@site_type = site_type
|
||||||
|
@input_div = $(".site_validator#"+site_type+"_validator")
|
||||||
|
@data_input = @input_div.find('input')
|
||||||
|
@logger = context.JK.logger
|
||||||
|
@site_status = null
|
||||||
|
@spinner = @input_div.find('span.spinner-small')
|
||||||
|
@checkmark = @input_div.find('.validate-checkmark')
|
||||||
|
this.show_format_status()
|
||||||
|
|
||||||
|
init: () =>
|
||||||
|
this.renderErrors({})
|
||||||
|
@spinner.hide()
|
||||||
|
validator = this
|
||||||
|
@data_input.on 'blur', ->
|
||||||
|
validator.did_blur()
|
||||||
|
@data_input.on 'focus', ->
|
||||||
|
validator.show_format_status()
|
||||||
|
|
||||||
|
data_to_validate: () =>
|
||||||
|
url = @data_input.val()
|
||||||
|
if 0 < url.length
|
||||||
|
url.substring(0,2000)
|
||||||
|
else
|
||||||
|
null
|
||||||
|
|
||||||
|
show_format_status: () =>
|
||||||
|
data = this.data_to_validate()
|
||||||
|
yn = true
|
||||||
|
if data && 'url' == @site_type
|
||||||
|
regexp = /(http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/
|
||||||
|
yn = regexp.test(this.data_to_validate())
|
||||||
|
if yn
|
||||||
|
@checkmark.show()
|
||||||
|
else
|
||||||
|
@checkmark.hide()
|
||||||
|
yn
|
||||||
|
|
||||||
|
did_blur: () =>
|
||||||
|
if this.show_format_status()
|
||||||
|
this.validate_site()
|
||||||
|
|
||||||
|
validate_site: () =>
|
||||||
|
@site_status = null
|
||||||
|
@spinner.show()
|
||||||
|
@checkmark.hide()
|
||||||
|
@rest.validateUrlSite(this.data_to_validate(), @site_type)
|
||||||
|
.done(this.processSiteCheck)
|
||||||
|
.fail(this.processSiteCheckFail)
|
||||||
|
|
||||||
|
processSiteCheck: (response) =>
|
||||||
|
@spinner.hide()
|
||||||
|
if 'Valid Site' == response.message
|
||||||
|
@site_status = 'valid'
|
||||||
|
this.renderErrors({})
|
||||||
|
else
|
||||||
|
@site_status = 'invalid'
|
||||||
|
this.renderErrors(response)
|
||||||
|
@logger.debug("site_status = "+@site_status)
|
||||||
|
|
||||||
|
processSiteCheckFail: (response) =>
|
||||||
|
@spinner.hide()
|
||||||
|
@checkmark.hide()
|
||||||
|
@logger.error("site check error")
|
||||||
|
@site_status = 'invalid'
|
||||||
|
|
||||||
|
renderErrors: (errors) =>
|
||||||
|
errdiv = @input_div.find('.error')
|
||||||
|
if errmsg = context.JK.format_errors("site", errors)
|
||||||
|
@checkmark.hide()
|
||||||
|
errdiv.show()
|
||||||
|
errdiv.html(errmsg)
|
||||||
|
else
|
||||||
|
@checkmark.show()
|
||||||
|
errdiv.hide()
|
||||||
|
errdiv.html('')
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
context.JK.UIHelper = function(app) {
|
context.JK.UIHelper = function(app) {
|
||||||
var logger = context.JK.logger;
|
var logger = context.JK.logger;
|
||||||
var rest = new context.JK.Rest();
|
var rest = new context.JK.Rest();
|
||||||
|
var sessionUtils = context.JK.SessionUtils;
|
||||||
|
|
||||||
function addSessionLike(sessionId, userId, $likeCountSelector, $likeButtonSelector) {
|
function addSessionLike(sessionId, userId, $likeCountSelector, $likeButtonSelector) {
|
||||||
rest.addSessionLike(sessionId, userId)
|
rest.addSessionLike(sessionId, userId)
|
||||||
|
|
@ -54,9 +55,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function launchSessionStartDialog(session) {
|
function launchSessionStartDialog(session) {
|
||||||
|
sessionUtils.ensureValidClient(app, context.JK.GearUtils, function() {
|
||||||
var sessionStartDialog = new JK.SessionStartDialog(JK.app, session);
|
var sessionStartDialog = new JK.SessionStartDialog(JK.app, session);
|
||||||
sessionStartDialog.initialize();
|
sessionStartDialog.initialize();
|
||||||
return sessionStartDialog.showDialog();
|
return sessionStartDialog.showDialog();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.addSessionLike = addSessionLike;
|
this.addSessionLike = addSessionLike;
|
||||||
|
|
|
||||||
|
|
@ -593,5 +593,16 @@ body.jam .icheckbox_minimal {
|
||||||
display:inline-block;
|
display:inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#jamblaster-notice {
|
||||||
|
position:absolute;
|
||||||
|
width:100%;
|
||||||
|
bottom:105%;
|
||||||
|
border-color:#ED3618;
|
||||||
|
border-style:solid;
|
||||||
|
border-width:1px;
|
||||||
|
padding:10px;
|
||||||
|
text-align:center;
|
||||||
|
@include border_box_sizing;
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
@import "client/common";
|
||||||
|
|
||||||
|
.site_validator {
|
||||||
|
input {
|
||||||
|
width: 100%;
|
||||||
|
padding: 5px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.validate-checkmark {
|
||||||
|
background-image: url('/assets/content/icon_checkmark_circle.png');
|
||||||
|
background-repeat:no-repeat;
|
||||||
|
background-position:center;
|
||||||
|
width:32px;
|
||||||
|
height:32px;
|
||||||
|
background-size: 50% 50%;
|
||||||
|
display:inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
position: absolute;
|
||||||
|
margin-top: 0px;
|
||||||
|
margin-left: 520px;
|
||||||
|
position: absolute;
|
||||||
|
left: 0px;
|
||||||
|
}
|
||||||
|
.error {
|
||||||
|
}
|
||||||
|
span.spinner-small {
|
||||||
|
display:inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
position: absolute;
|
||||||
|
margin-top: 0px;
|
||||||
|
margin-left: 520px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,9 +10,42 @@ body.web.landing_page {
|
||||||
}
|
}
|
||||||
|
|
||||||
&.wo_1 {
|
&.wo_1 {
|
||||||
.landing-content h1 {
|
|
||||||
margin-left:45px;
|
.landing-tag {
|
||||||
|
left: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cta-container {
|
||||||
|
width:75%;
|
||||||
|
text-align:center;
|
||||||
|
margin-left:0% !important;
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin-left:0px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.column:nth-child(1) {
|
||||||
|
width:50% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column:nth-child(2) {
|
||||||
|
width:50% !important;
|
||||||
|
h1 {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin-bottom:30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-container a {
|
||||||
|
|
||||||
|
margin-bottom:8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
&.wo_3 {
|
&.wo_3 {
|
||||||
.landing-content h1 {
|
.landing-content h1 {
|
||||||
|
|
|
||||||
|
|
@ -64,10 +64,16 @@ body.web {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.register {
|
||||||
|
.landing-content {
|
||||||
|
min-height:460px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.landing-content {
|
.landing-content {
|
||||||
background-color:black;
|
background-color:black;
|
||||||
width:100%;
|
width:100%;
|
||||||
min-height: 460px;
|
min-height: 366px;
|
||||||
position:relative;
|
position:relative;
|
||||||
padding-bottom:30px;
|
padding-bottom:30px;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,15 @@ body.web {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.jamfest {
|
||||||
|
top:-70px;
|
||||||
|
position:relative;
|
||||||
|
|
||||||
|
.jamblaster {
|
||||||
|
font-weight:bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.follow-links {
|
.follow-links {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
require 'sanitize'
|
require 'sanitize'
|
||||||
class ApiUsersController < ApiController
|
class ApiUsersController < ApiController
|
||||||
|
|
||||||
before_filter :api_signed_in_user, :except => [:create, :show, :signup_confirm, :auth_session_create, :complete, :finalize_update_email, :isp_scoring, :add_play, :crash_dump]
|
before_filter :api_signed_in_user, :except => [:create, :show, :signup_confirm, :auth_session_create, :complete, :finalize_update_email, :isp_scoring, :add_play, :crash_dump, :validate_data]
|
||||||
before_filter :auth_user, :only => [:session_settings_show, :session_history_index, :session_user_history_index, :update, :delete,
|
before_filter :auth_user, :only => [:session_settings_show, :session_history_index, :session_user_history_index, :update, :delete,
|
||||||
:liking_create, :liking_destroy, # likes
|
:liking_create, :liking_destroy, # likes
|
||||||
:following_create, :following_show, :following_destroy, # followings
|
:following_create, :following_show, :following_destroy, # followings
|
||||||
|
|
@ -699,6 +699,28 @@ class ApiUsersController < ApiController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def validate_data
|
||||||
|
unless (data = params[:data]).present?
|
||||||
|
render(json: { message: "blank data #{data}" }, status: :unprocessable_entity) && return
|
||||||
|
end
|
||||||
|
url = nil
|
||||||
|
site = params[:sitetype]
|
||||||
|
if site.blank? || 'url'==site
|
||||||
|
url = data
|
||||||
|
else
|
||||||
|
url = Utils.username_url(data, site)
|
||||||
|
end
|
||||||
|
unless url.blank?
|
||||||
|
if errmsg = Utils.site_validator(url, site)
|
||||||
|
render json: { message: 'Invalid Site', errors: { site: [errmsg] } }, status: 200
|
||||||
|
else
|
||||||
|
render json: { message: 'Valid Site' }, status: 200
|
||||||
|
end
|
||||||
|
else
|
||||||
|
render json: { message: "unknown validation for data '#{params[:data]}', site '#{params[:site]}'" }, status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
###################### RECORDINGS #######################
|
###################### RECORDINGS #######################
|
||||||
# def recording_index
|
# def recording_index
|
||||||
# @recordings = User.recording_index(current_user, params[:id])
|
# @recordings = User.recording_index(current_user, params[:id])
|
||||||
|
|
|
||||||
|
|
@ -37,4 +37,9 @@ class SpikesController < ApplicationController
|
||||||
Notification.send_subscription_message('test', '2', '{"msg": "oh hai 2"}')
|
Notification.send_subscription_message('test', '2', '{"msg": "oh hai 2"}')
|
||||||
render text: 'oh hai'
|
render text: 'oh hai'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def site_validate
|
||||||
|
render :layout => 'web'
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -190,12 +190,12 @@ class UsersController < ApplicationController
|
||||||
def welcome
|
def welcome
|
||||||
|
|
||||||
@slides = [
|
@slides = [
|
||||||
Slide.new("JamKazam Overview", "web/carousel_musicians.jpg", "http://www.youtube.com/embed/ylYcvTY9CVo?autoplay=1"),
|
Slide.new("JamKazam Overview", "web/carousel_overview.png", "http://www.youtube.com/embed/ylYcvTY9CVo?autoplay=1"),
|
||||||
Slide.new("Getting Started", "web/carousel_fans.jpg", "http://www.youtube.com/embed/DBo--aj_P1w?autoplay=1"),
|
Slide.new("The Revolutionary New JamBlaster!", "web/carousel_jamblaster.png", "http://www.youtube.com/embed/gAJAIHMyois?autoplay=1"),
|
||||||
Slide.new("Playing in a Session", "web/carousel_bands.jpg", "http://www.youtube.com/embed/zJ68hA8-fLA?autoplay=1"),
|
Slide.new("Kudos From Our Community", "web/carousel_community.png", "http://www.youtube.com/embed/_7qj5RXyHCo?autoplay=1"),
|
||||||
Slide.new("JamKazam Overview", "web/carousel_musicians.jpg", "http://www.youtube.com/embed/ylYcvTY9CVo?autoplay=1"),
|
Slide.new("JamKazam Overview", "web/carousel_overview.png", "http://www.youtube.com/embed/ylYcvTY9CVo?autoplay=1"),
|
||||||
Slide.new("Getting Started", "web/carousel_fans.jpg", "http://www.youtube.com/embed/DBo--aj_P1w?autoplay=1"),
|
Slide.new("The Revolutionary New JamBlaster!", "web/carousel_fans.jpg", "http://www.youtube.com/embed/gAJAIHMyois?autoplay=1"),
|
||||||
Slide.new("Playing in a Session", "web/carousel_bands.jpg", "http://www.youtube.com/embed/zJ68hA8-fLA?autoplay=1")
|
Slide.new("Kudos From Our Community", "web/carousel_community.png", "http://www.youtube.com/embed/_7qj5RXyHCo?autoplay=1")
|
||||||
]
|
]
|
||||||
|
|
||||||
@promo_buzz = PromoBuzz.active
|
@promo_buzz = PromoBuzz.active
|
||||||
|
|
@ -207,8 +207,8 @@ class UsersController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
# temporary--will go away soon
|
# temporary--will go away soon
|
||||||
@jamfest_2014 = Event.find_by_id('80bb6acf-3ddc-4305-9442-75e6ec047c27') # production ID
|
#@jamfest_2014 = Event.find_by_id('80bb6acf-3ddc-4305-9442-75e6ec047c27') # production ID
|
||||||
@jamfest_2014 = Event.find_by_id('a2dfbd26-9b17-4446-8c61-b67a542ea6ee') unless @jamfest_2014 # development ID
|
#@jamfest_2014 = Event.find_by_id('a2dfbd26-9b17-4446-8c61-b67a542ea6ee') unless @jamfest_2014 # development ID
|
||||||
# temporary--end
|
# temporary--end
|
||||||
|
|
||||||
@welcome_page = true
|
@welcome_page = true
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
.screen layout="screen" layout-id="home"
|
.screen layout="screen" layout-id="home"
|
||||||
|
-if Rails.configuration.show_jamblaster_notice
|
||||||
|
#jamblaster-notice
|
||||||
|
a href='https://www.youtube.com/watch?v=gAJAIHMyois' rel="external"
|
||||||
|
span Check out the amazing new JamBlaster, and learn how it can improve your sessions!
|
||||||
/ Layout is different if jam_tracks tile available:
|
/ Layout is different if jam_tracks tile available:
|
||||||
-jamtracks=Rails.configuration.jam_tracks_available
|
-jamtracks=Rails.configuration.jam_tracks_available
|
||||||
-if (jamtracks)
|
-if (jamtracks)
|
||||||
|
|
|
||||||
|
|
@ -210,7 +210,7 @@
|
||||||
|
|
||||||
<!-- Notification panel template -->
|
<!-- Notification panel template -->
|
||||||
<script type="text/template" id="template-notification-panel">
|
<script type="text/template" id="template-notification-panel">
|
||||||
<li session-id="{sessionId}" notification-id="{notificationId}">
|
<li class="notification-entry" session-id="{sessionId}" notification-id="{notificationId}">
|
||||||
<div class="avatar-small" user-id="{userId}" hoveraction="musician"><img src="{avatar_url}" /></div>
|
<div class="avatar-small" user-id="{userId}" hoveraction="musician"><img src="{avatar_url}" /></div>
|
||||||
<div session-id="{sessionId}" hoveraction="hoveraction" class="note-text">
|
<div session-id="{sessionId}" hoveraction="hoveraction" class="note-text">
|
||||||
{text}<br/>
|
{text}<br/>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
div class="site_validator" id="#{site_type}_validator"
|
||||||
|
span class="validate-checkmark"
|
||||||
|
span class="spinner-small upload-spinner"
|
||||||
|
input type='text' id="validate_input_#{site_type}" maxlength="2000"
|
||||||
|
br
|
||||||
|
div class="error"
|
||||||
|
|
@ -7,11 +7,20 @@
|
||||||
iframe src="//www.youtube.com/embed/ylYcvTY9CVo" frameborder="0" allowfullscreen
|
iframe src="//www.youtube.com/embed/ylYcvTY9CVo" frameborder="0" allowfullscreen
|
||||||
.cta-container
|
.cta-container
|
||||||
h2 It's FREE! Ready to Go?
|
h2 It's FREE! Ready to Go?
|
||||||
= link_to image_tag("web/cta_button.png", :alt => "Sign up now for your free account!"), signup_path, class: "signup", id: "signup"
|
= link_to image_tag("web/cta_button.png", :alt => "Sign up now for your free account!"), signup_path, class: "signup", id: "signup", rel: "external"
|
||||||
.column
|
.column
|
||||||
= render :partial => "users/buzz", locals: {header: 'From Our Community'}
|
h1
|
||||||
.more-container
|
| Learn About the Revolutionary New
|
||||||
h2 Need to Know More?
|
b JamBlaster
|
||||||
= link_to 'Watch 6 Bands Play Using JamKazam', landing_wo_path(p: 2), class: 'landing_wb'
|
.video-wrapper
|
||||||
|
.video-container
|
||||||
|
iframe src="//www.youtube.com/embed/gAJAIHMyois" frameborder="0" allowfullscreen
|
||||||
|
.cta-container
|
||||||
|
h2 More Resources:
|
||||||
|
a href="https://www.youtube.com/watch?v=_7qj5RXyHCo" rel="external"
|
||||||
|
| See kudos and endorsements from JamKazam users
|
||||||
|
a href="https://www.kickstarter.com/projects/jamkazam/jamblaster-play-music-in-real-time-with-others-fro" rel="external"
|
||||||
|
| Visit the JamBlaster page on KickStarter
|
||||||
|
|
||||||
|
|
||||||
br clear="all"
|
br clear="all"
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
= javascript_include_tag "site_validator"
|
||||||
|
div style="width:50%"
|
||||||
|
= render "clients/site_validator", site_type: params[:site_type] || 'url'
|
||||||
|
= stylesheet_link_tag "client/site_validator"
|
||||||
|
<br />
|
||||||
|
= select_tag "site_type", options_for_select(Utils::SITE_TYPES, params[:site_type] || 'url')
|
||||||
|
|
||||||
|
javascript:
|
||||||
|
var initialized = false;
|
||||||
|
$(document).on('JAMKAZAM_READY', function(e, data) {
|
||||||
|
setTimeout(function() {
|
||||||
|
window.site_validator = new JK.SiteValidator('#{params[:site_type] || 'url'}');
|
||||||
|
site_validator.init();
|
||||||
|
$('#validate_input_'+'#{params[:site_type] || 'url'}').val('jonathankolyer');
|
||||||
|
}, 1)
|
||||||
|
});
|
||||||
|
$('#site_type').change(function(){
|
||||||
|
location.href = 'site_validate?site_type='+$(this).val();
|
||||||
|
});
|
||||||
|
|
@ -9,11 +9,14 @@
|
||||||
= link_to "Already have an account?", signin_path, class: "signin", id: "signin"
|
= link_to "Already have an account?", signin_path, class: "signin", id: "signin"
|
||||||
|
|
||||||
- content_for :after_black_bar do
|
- content_for :after_black_bar do
|
||||||
= render :partial => 'users/follow_links'
|
//= render :partial => 'users/follow_links'
|
||||||
- if @jamfest_2014
|
- if Rails.application.config.show_jamblaster_kickstarter_link
|
||||||
.jamfest{style: 'top:-70px;position:relative'}
|
.jamfest
|
||||||
%a{ href: event_path(@jamfest_2014.slug), style: 'font-size:20px;margin-top:11px' }
|
%a{ href: 'https://www.kickstarter.com/projects/jamkazam/jamblaster-play-music-in-real-time-with-others-fro', style: 'font-size:20px;margin-top:11px' }
|
||||||
Listen to the terrific band performances from Virtual Jam Fest 2014!
|
= "Check out our new "
|
||||||
|
%span.jamblaster JamBlaster
|
||||||
|
= " on "
|
||||||
|
%span Kickstarter, the fastest way to play!
|
||||||
%div{style: "padding-top:20px;"}
|
%div{style: "padding-top:20px;"}
|
||||||
.right
|
.right
|
||||||
= render :partial => "buzz"
|
= render :partial => "buzz"
|
||||||
|
|
|
||||||
|
|
@ -309,5 +309,8 @@ if defined?(Bundler)
|
||||||
config.influxdb_hosts = ["localhost"]
|
config.influxdb_hosts = ["localhost"]
|
||||||
config.influxdb_port = 8086
|
config.influxdb_port = 8086
|
||||||
config.influxdb_ignored_environments = ENV["INFLUXDB_ENABLED"] == '1' ? ['test', 'cucumber'] : ['test', 'cucumber', 'development']
|
config.influxdb_ignored_environments = ENV["INFLUXDB_ENABLED"] == '1' ? ['test', 'cucumber'] : ['test', 'cucumber', 'development']
|
||||||
|
|
||||||
|
config.show_jamblaster_notice = true
|
||||||
|
config.show_jamblaster_kickstarter_link = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,8 @@ SampleApp::Application.routes.draw do
|
||||||
match '/launch_app', to: 'spikes#launch_app'
|
match '/launch_app', to: 'spikes#launch_app'
|
||||||
match '/websocket', to: 'spikes#websocket'
|
match '/websocket', to: 'spikes#websocket'
|
||||||
match '/test_subscription', to: 'spikes#subscription'
|
match '/test_subscription', to: 'spikes#subscription'
|
||||||
|
match '/site_validate', to: 'spikes#site_validate'
|
||||||
|
match '/username_validate', to: 'spikes#username_validate'
|
||||||
|
|
||||||
# junk pages
|
# junk pages
|
||||||
match '/help', to: 'static_pages#help'
|
match '/help', to: 'static_pages#help'
|
||||||
|
|
@ -237,6 +239,9 @@ SampleApp::Application.routes.draw do
|
||||||
# users
|
# users
|
||||||
match '/users/isp_scoring' => 'api_users#isp_scoring', :via => :post , :as => 'isp_scoring'
|
match '/users/isp_scoring' => 'api_users#isp_scoring', :via => :post , :as => 'isp_scoring'
|
||||||
|
|
||||||
|
# validation
|
||||||
|
match '/data_validation' => 'api_users#validate_data', :via => :get
|
||||||
|
|
||||||
match '/users' => 'api_users#index', :via => :get
|
match '/users' => 'api_users#index', :via => :get
|
||||||
match '/users/:id' => 'api_users#show', :via => :get, :as => 'api_user_detail'
|
match '/users/:id' => 'api_users#show', :via => :get, :as => 'api_user_detail'
|
||||||
#match '/users' => 'api_users#create', :via => :post
|
#match '/users' => 'api_users#create', :via => :post
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
namespace :gear do
|
||||||
|
|
||||||
|
task analyze: :environment do
|
||||||
|
|
||||||
|
successful = {types: {}}
|
||||||
|
|
||||||
|
Diagnostic.where("type = 'GEAR_SELECTION'").each do |diagnostic|
|
||||||
|
|
||||||
|
data = JSON.parse(diagnostic.data)
|
||||||
|
|
||||||
|
os = data["summary"]["os"] # MacOSX or Win32
|
||||||
|
success = data["summary"]["success"] # bool
|
||||||
|
|
||||||
|
if success
|
||||||
|
latency = data["summary"]["score"]["latencyScore"]["latency"]
|
||||||
|
id = data["summary"]["selectedDevice"]["input"]["info"]["id"]
|
||||||
|
displayName = data["summary"]["selectedDevice"]["input"]["info"]["displayName"]
|
||||||
|
type = data["summary"]["selectedDevice"]["input"]["info"]["type"]
|
||||||
|
|
||||||
|
store = successful[:types][type]
|
||||||
|
|
||||||
|
if !store
|
||||||
|
store = {}
|
||||||
|
successful[:types][type] = store
|
||||||
|
end
|
||||||
|
|
||||||
|
deviceData = store[id + ':' + latency.to_i.to_s]
|
||||||
|
|
||||||
|
if !deviceData
|
||||||
|
deviceData = {id: id, displayName: displayName, type: type, latency: latency, count: 0}
|
||||||
|
store[id + ':' + latency.to_i.to_s] = deviceData
|
||||||
|
end
|
||||||
|
|
||||||
|
deviceData[:count] = deviceData[:count] + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "TYPES:"
|
||||||
|
successful[:types].each do|type, hits|
|
||||||
|
puts "#{type}"
|
||||||
|
end
|
||||||
|
puts ""
|
||||||
|
puts ""
|
||||||
|
|
||||||
|
successful[:types].each do |type, hits|
|
||||||
|
results = hits.sort_by do |id_latency, deviceData|
|
||||||
|
deviceData[:latency]
|
||||||
|
end
|
||||||
|
|
||||||
|
puts "--------------- #{type} -----------------"
|
||||||
|
|
||||||
|
results.each do |result|
|
||||||
|
puts "#{result[1][:latency].to_i.to_s.rjust(2)} #{result[1][:displayName]}"
|
||||||
|
end
|
||||||
|
puts ""
|
||||||
|
puts ""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
task :stress_resque do
|
||||||
|
Rake::Task['environment'].invoke
|
||||||
|
|
||||||
|
10.times do
|
||||||
|
Resque.enqueue(StressJob)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,62 @@
|
||||||
|
class Utils
|
||||||
|
|
||||||
|
USERNAME_SITES = %W{youtube facebook soundcloud bandcamp fandalism twitter reverbnation}
|
||||||
|
SITE_TYPES = ['url'].concat(USERNAME_SITES)
|
||||||
|
|
||||||
|
def self.username_url(username, site)
|
||||||
|
case site
|
||||||
|
when 'youtube'
|
||||||
|
"https://www.youtube.com/c/#{username}"
|
||||||
|
when 'facebook'
|
||||||
|
"https://www.facebook.com/#{username}"
|
||||||
|
when 'soundcloud'
|
||||||
|
"https://soundcloud.com/#{username}"
|
||||||
|
when 'bandcamp'
|
||||||
|
"http://#{username}.bandcamp.com"
|
||||||
|
when 'bandcamp-fan'
|
||||||
|
"http://bandcamp.com/#{username}"
|
||||||
|
when 'fandalism'
|
||||||
|
"http://fandalism.com/#{username}"
|
||||||
|
when 'twitter'
|
||||||
|
"https://twitter.com/#{username}"
|
||||||
|
when 'reverbnation'
|
||||||
|
"http://www.reverbnation.com/#{username}"
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.site_validator(url, site=nil)
|
||||||
|
uagent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.1 Safari/537.36"
|
||||||
|
curl_args = "-A '#{uagent}' --silent --head --fail --show-error "
|
||||||
|
case site
|
||||||
|
when 'bandcamp'
|
||||||
|
cmd = "curl #{curl_args} '#{url}' 2>&1"
|
||||||
|
result = `#{cmd}`.chomp
|
||||||
|
if $?.success?
|
||||||
|
if /^HTTP\/\d+\.\d+ 2\d\d OK/ =~ result.lines[0]
|
||||||
|
return nil
|
||||||
|
else
|
||||||
|
if /http:\/\/(.*)\.bandcamp.com/ =~ url
|
||||||
|
return self.site_validator(self.username_url($1, 'bandcamp-fan'), 'bandcamp-fan')
|
||||||
|
end
|
||||||
|
return "Unrecognized url (#{url})"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
result =~ /curl: \(\d+\) (.*)/
|
||||||
|
return "#{$1} (#{url})"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
curl_args << "-L --output /dev/null "
|
||||||
|
cmd = "curl #{curl_args} '#{url}' 2>&1"
|
||||||
|
result = `#{cmd}`.chomp
|
||||||
|
end
|
||||||
|
if $?.success?
|
||||||
|
return nil
|
||||||
|
else
|
||||||
|
result =~ /curl: \(\d+\) (.*)/
|
||||||
|
return "#{$1} (#{url})"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
@ -34,6 +34,45 @@ describe ApiUsersController do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'site validation' do
|
||||||
|
|
||||||
|
it 'checks valid and invalid site types' do
|
||||||
|
site_types = Utils::SITE_TYPES.clone << 'bandcamp-fan'
|
||||||
|
site_types.each do |sitetype|
|
||||||
|
case sitetype
|
||||||
|
when 'url'
|
||||||
|
valid, invalid = 'http://jamkazam.com', 'http://jamkazamxxx.com'
|
||||||
|
when 'youtube'
|
||||||
|
valid, invalid = 'jonathankolyer', 'jonathankolyerxxx'
|
||||||
|
when 'facebook'
|
||||||
|
valid, invalid = 'jamkazam', 'jamkazamxxxx'
|
||||||
|
when 'twitter'
|
||||||
|
valid, invalid = 'jamkazam', 'jamkazamxxxx'
|
||||||
|
when 'soundcloud'
|
||||||
|
valid, invalid = 'zedisdead', 'zedisdeadxxxx'
|
||||||
|
when 'reverbnation'
|
||||||
|
valid, invalid = 'jessicabrown', 'jessicabrownasdf'
|
||||||
|
when 'bandcamp'
|
||||||
|
valid, invalid = 'hucci', 'huccixxxxxx'
|
||||||
|
when 'bandcamp-fan'
|
||||||
|
valid, invalid = 'iguanaden', 'iguanadenxxxxxx'
|
||||||
|
when 'fandalism'
|
||||||
|
valid, invalid = 'pud', 'pudxxxx'
|
||||||
|
else
|
||||||
|
valid, invalid = '', ''
|
||||||
|
end
|
||||||
|
next if valid.blank?
|
||||||
|
2.times do |nn|
|
||||||
|
get :validate_data, sitetype:sitetype, data: 0==nn ? valid : invalid
|
||||||
|
response.should be_success
|
||||||
|
json = JSON.parse(response.body)
|
||||||
|
expect(json['message']).to eq(0==nn ? 'Valid Site' : 'Invalid Site')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
describe "audio_latency" do
|
describe "audio_latency" do
|
||||||
it "updates both connection and user" do
|
it "updates both connection and user" do
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,21 +11,18 @@ describe "Alternate Landing Pages", :js => true, :type => :feature, :capybara_fe
|
||||||
find('h1', text: 'See How JamKazam Works')
|
find('h1', text: 'See How JamKazam Works')
|
||||||
find('a.landing_wb', text: 'Watch a Video to See How to Get Started').trigger(:click)
|
find('a.landing_wb', text: 'Watch a Video to See How to Get Started').trigger(:click)
|
||||||
find('h1', text: 'See How to Get Started')
|
find('h1', text: 'See How to Get Started')
|
||||||
find('div.fb-like')
|
#find('div.fb-like')
|
||||||
find('a.twitter-follow-button')
|
#find('a.twitter-follow-button')
|
||||||
find('.g-follow-btn iframe')
|
#find('.g-follow-btn iframe')
|
||||||
end
|
end
|
||||||
|
|
||||||
it "landing-page watch-overview" do
|
it "landing-page watch-overview" do
|
||||||
visit landing_wo_path
|
visit landing_wo_path
|
||||||
find('h1', text: 'Watch Video to See How JamKazam Works')
|
find('h1', text: 'Watch Video to See How JamKazam Works')
|
||||||
find('a.landing_wb', text: 'Watch 6 Bands Play Using JamKazam').trigger(:click)
|
find('h1', text: 'Learn About the Revolutionary New JamBlaster')
|
||||||
find('h1', text: 'Watch 6 Bands Play Together from Different Locations')
|
#find('div.fb-like')
|
||||||
find('a.landing_wb', text: 'See How to Get Started Using JamKazam').trigger(:click)
|
#find('a.twitter-follow-button')
|
||||||
find('h1', text: 'See How to Get Started Using JamKazam')
|
#find('.g-follow-btn iframe')
|
||||||
find('div.fb-like')
|
|
||||||
find('a.twitter-follow-button')
|
|
||||||
find('.g-follow-btn iframe')
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "landing-page-tight watch-bands" do
|
it "landing-page-tight watch-bands" do
|
||||||
|
|
@ -33,9 +30,9 @@ describe "Alternate Landing Pages", :js => true, :type => :feature, :capybara_fe
|
||||||
find('h1', text: 'Watch 6 Bands Play Together from Different Locations')
|
find('h1', text: 'Watch 6 Bands Play Together from Different Locations')
|
||||||
find('h2', text: "It's FREE! Ready to Go?")
|
find('h2', text: "It's FREE! Ready to Go?")
|
||||||
find('h2', text: 'Not a Good Time to Sign Up?')
|
find('h2', text: 'Not a Good Time to Sign Up?')
|
||||||
find('div.fb-like')
|
#find('div.fb-like')
|
||||||
find('a.twitter-follow-button')
|
#find('a.twitter-follow-button')
|
||||||
find('.g-follow-btn iframe')
|
#find('.g-follow-btn iframe')
|
||||||
end
|
end
|
||||||
|
|
||||||
it "landing-page-tight watch-overview" do
|
it "landing-page-tight watch-overview" do
|
||||||
|
|
@ -43,9 +40,9 @@ describe "Alternate Landing Pages", :js => true, :type => :feature, :capybara_fe
|
||||||
find('h1', text: 'Watch Overview Video to See How JamKazam Works')
|
find('h1', text: 'Watch Overview Video to See How JamKazam Works')
|
||||||
find('h2', text: "It's FREE! Ready to Go?")
|
find('h2', text: "It's FREE! Ready to Go?")
|
||||||
find('h2', text: 'Not a Good Time to Sign Up?')
|
find('h2', text: 'Not a Good Time to Sign Up?')
|
||||||
find('div.fb-like')
|
#find('div.fb-like')
|
||||||
find('a.twitter-follow-button')
|
#find('a.twitter-follow-button')
|
||||||
find('.g-follow-btn iframe')
|
#find('.g-follow-btn iframe')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -158,8 +158,16 @@ describe "Bands", :js => true, :type => :feature, :capybara_feature => true do
|
||||||
expect(page).to have_selector('.result-name', text: band_musician.name)
|
expect(page).to have_selector('.result-name', text: band_musician.name)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "displays photo, name, location, instruments played"
|
it "displays photo, name, location for member" do
|
||||||
it "displays a hover bubble containing more info on musician"
|
sign_in_poltergeist fan
|
||||||
|
visit "/client#/bandProfile/#{band_musician.bands.first.id}"
|
||||||
|
find('#band-profile-members-link').trigger(:click)
|
||||||
|
within "div.band-profile-members" do
|
||||||
|
find(".avatar-small img")
|
||||||
|
find(".result-name", text: band_musician.name)
|
||||||
|
find(".result-location", text: "#{band_musician.city}, #{band_musician.state}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
it "displays any pending band invitations when viewed by current band member" do
|
it "displays any pending band invitations when viewed by current band member" do
|
||||||
friend = user
|
friend = user
|
||||||
|
|
|
||||||
|
|
@ -203,4 +203,30 @@ describe "Feed", :js => true, :type => :feature, :capybara_feature => true do
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "session participants behavior (VRFS-2193)" do
|
||||||
|
let(:creator) { FactoryGirl.create(:user) }
|
||||||
|
let(:finder_1) { FactoryGirl.create(:user) }
|
||||||
|
let(:finder_2) { FactoryGirl.create(:user) }
|
||||||
|
|
||||||
|
specify "after session ends all participants are shown in Feed" do
|
||||||
|
creator, description = create_join_session creator, finder_1
|
||||||
|
# feed shows user, finder_1
|
||||||
|
formal_leave_by(finder_1)
|
||||||
|
# feed shows user
|
||||||
|
join_session(finder_2, description: description)
|
||||||
|
# feed shows user, finder_2
|
||||||
|
formal_leave_by(finder_2)
|
||||||
|
formal_leave_by(creator)
|
||||||
|
|
||||||
|
in_client(creator) { verify_feed_shows_users creator, finder_1, finder_2 }
|
||||||
|
end
|
||||||
|
|
||||||
|
specify "during session only current participants are shown in Feed" do
|
||||||
|
creator, description = create_join_session creator, finder_1
|
||||||
|
formal_leave_by(finder_1)
|
||||||
|
join_session(finder_2, description: description)
|
||||||
|
|
||||||
|
in_client(finder_1) { verify_feed_shows_users finder_2, creator }
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ describe "In a Session", :js => true, :type => :feature, :capybara_feature => tr
|
||||||
description = "Public or private, I cant decide!"
|
description = "Public or private, I cant decide!"
|
||||||
create_session(creator: user, description: description)
|
create_session(creator: user, description: description)
|
||||||
in_client(user) do
|
in_client(user) do
|
||||||
set_session_as_private
|
set_session_access :private
|
||||||
end
|
end
|
||||||
in_client(finder) do
|
in_client(finder) do
|
||||||
emulate_client
|
emulate_client
|
||||||
|
|
@ -31,7 +31,7 @@ describe "In a Session", :js => true, :type => :feature, :capybara_feature => tr
|
||||||
sign_out_poltergeist(validate: true)
|
sign_out_poltergeist(validate: true)
|
||||||
end
|
end
|
||||||
in_client(user) do
|
in_client(user) do
|
||||||
set_session_as_public
|
set_session_access :public
|
||||||
end
|
end
|
||||||
join_session(finder, description: description) # verify the public session is able to be joined
|
join_session(finder, description: description) # verify the public session is able to be joined
|
||||||
end
|
end
|
||||||
|
|
@ -84,15 +84,61 @@ describe "In a Session", :js => true, :type => :feature, :capybara_feature => tr
|
||||||
end
|
end
|
||||||
|
|
||||||
it "can rejoin private session as creator" do
|
it "can rejoin private session as creator" do
|
||||||
pending
|
#pending
|
||||||
creator, description = create_join_session(user, [finder])
|
creator, description = create_join_session(user, [finder])
|
||||||
|
|
||||||
in_client(user) do
|
in_client(user) do
|
||||||
set_session_as_private
|
set_session_access :private
|
||||||
formal_leave_by user
|
formal_leave_by user
|
||||||
sign_out_poltergeist user
|
sign_out_poltergeist user
|
||||||
end
|
end
|
||||||
|
|
||||||
join_session(user, description: description)
|
join_session(user, description: description)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
specify "creator should receive join requests after changing session to 'by approval' (VRFS-2266)" do
|
||||||
|
creator, description = create_session
|
||||||
|
in_client(creator) do
|
||||||
|
set_session_access :by_approval
|
||||||
|
end
|
||||||
|
|
||||||
|
request_to_join_session(finder, description: description)
|
||||||
|
|
||||||
|
in_client(creator) do
|
||||||
|
expand_sidebar :notifications
|
||||||
|
expect(page).to have_content "#{finder.name} has requested to join your session."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
specify "invitee receives notification when creator invites musician" do
|
||||||
|
pending "blocked on testing this via front-end - fakeJamClient doesn't support invite UX"
|
||||||
|
user = FactoryGirl.create(:user)
|
||||||
|
invitee = FactoryGirl.create(:user)
|
||||||
|
FactoryGirl.create(:friendship, :user => user, :friend => invitee)
|
||||||
|
in_client(user) do
|
||||||
|
create_session
|
||||||
|
find('#session-invite-musicians').trigger(:click)
|
||||||
|
find('#btn-choose-friends-update').trigger(:click)
|
||||||
|
within('#friend-selector-list') { find("tr[user-id='#{invitee.id}']").trigger(:click) }
|
||||||
|
find('#btn-save-friends').trigger(:click)
|
||||||
|
find('#btn-save-invites').trigger(:click)
|
||||||
|
end
|
||||||
|
|
||||||
|
in_client(invitee) do
|
||||||
|
fast_signin(invitee, "/client#/home")
|
||||||
|
expand_sidebar :notifications
|
||||||
|
expect(page).to have_content "invited you"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
specify "user is able to see recording in 'Open Recording' modal" do
|
||||||
|
recording = FactoryGirl.create(:recording, owner: user)
|
||||||
|
in_client(user) do
|
||||||
|
create_session
|
||||||
|
find('#open-a-recording').trigger(:click)
|
||||||
|
within('table.local-recordings') do
|
||||||
|
expect(page).to have_content recording.name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe "Notification Subpanel", :js => true, :type => :feature, :capybara_feature => true do
|
||||||
|
|
||||||
|
subject { page }
|
||||||
|
|
||||||
|
|
||||||
|
let(:user) { FactoryGirl.create(:user, last_jam_locidispid: 1) }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
describe "user with no notifications" do
|
||||||
|
before(:each) do
|
||||||
|
fast_signin(user, "/client")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "lists no notifications" do
|
||||||
|
open_notifications
|
||||||
|
expect(page).to have_selector("#{NOTIFICATION_PANEL} li.notification-entry", count: 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "user with 1 notification" do
|
||||||
|
|
||||||
|
let!(:other) { FactoryGirl.create(:user, last_jam_locidispid: 1) }
|
||||||
|
let!(:msg1) {FactoryGirl.create(:notification_text_message, source_user: other, target_user: user) }
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
fast_signin(user, "/client")
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
it "lists 1 notifications" do
|
||||||
|
open_notifications
|
||||||
|
expect(page).to have_selector("#{NOTIFICATION_PANEL} li.notification-entry", count: 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
= stylesheet_link_tag "site_validator"
|
||||||
|
div style="width:50%"
|
||||||
|
= render "clients/site_validator", site_type: 'url'
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
describe "SiteValidator", ->
|
||||||
|
|
||||||
|
fixture.preload("siteValidator.html")
|
||||||
|
|
||||||
|
beforeEach ->
|
||||||
|
this.server = sinon.fakeServer.create();
|
||||||
|
window.jamClient = sinon.stub()
|
||||||
|
@fixtures = fixture.load("siteValidator.html", true)
|
||||||
|
# $('body').append(@fixtures[0])
|
||||||
|
window.gon = {}
|
||||||
|
window.gon.isNativeClient = true
|
||||||
|
|
||||||
|
afterEach ->
|
||||||
|
this.server.restore();
|
||||||
|
|
||||||
|
it "displays validator widget", ->
|
||||||
|
site_validator = new JK.SiteValidator('url')
|
||||||
|
site_validator.init()
|
||||||
|
|
||||||
|
site_validator.data_input.val('http://www.jamkazam.com')
|
||||||
|
site_validator.did_blur() # focus not working in the test
|
||||||
|
# expect(site_validator.checkmark).toBeVisible()
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
//= require client/site_validator
|
||||||
|
|
@ -464,6 +464,12 @@ def join_session(joiner, options)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def request_to_join_session(joiner, options)
|
||||||
|
join_session(joiner, options.merge(no_verify: true))
|
||||||
|
find('#btn-alert-ok').trigger(:click)
|
||||||
|
# page.should have_no_selector('h1', text: 'Alert')
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def emulate_client
|
def emulate_client
|
||||||
|
|
@ -475,7 +481,7 @@ def create_join_session(creator, joiners=[], options={})
|
||||||
creator, unique_session_desc = create_session(options)
|
creator, unique_session_desc = create_session(options)
|
||||||
|
|
||||||
# find session in second client
|
# find session in second client
|
||||||
joiners.each do |joiner|
|
[*joiners].each do |joiner|
|
||||||
join_session(joiner, description: unique_session_desc)
|
join_session(joiner, description: unique_session_desc)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -490,6 +496,21 @@ def formal_leave_by user
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def verify_feed_shows_users *users
|
||||||
|
users = [*users]
|
||||||
|
visit "/client#/feed"
|
||||||
|
find('.feed-details a.details').trigger(:click)
|
||||||
|
within 'div.music-session-history-entry' do
|
||||||
|
users.each do |user|
|
||||||
|
# confirm user avatar exists
|
||||||
|
find("a.avatar-tiny[user-id=\"#{user.id}\"][hoveraction=\"musician\"] img")
|
||||||
|
|
||||||
|
# confirm user name exists
|
||||||
|
find("a.musician-name[user-id=\"#{user.id}\"][hoveraction=\"musician\"]", text: user.name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def start_recording_with(creator, joiners=[], genre=nil)
|
def start_recording_with(creator, joiners=[], genre=nil)
|
||||||
create_join_session(creator, joiners, {genre: genre})
|
create_join_session(creator, joiners, {genre: genre})
|
||||||
in_client(creator) do
|
in_client(creator) do
|
||||||
|
|
@ -529,22 +550,21 @@ def claim_recording(name, description)
|
||||||
page.should have_no_selector('h1', text: 'recording finished')
|
page.should have_no_selector('h1', text: 'recording finished')
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_session_as_private()
|
def set_session_access access_type
|
||||||
find('#session-settings-button').trigger(:click)
|
case access_type
|
||||||
within('#session-settings-dialog') do
|
when :only_rsvp, :private
|
||||||
jk_select("Only RSVP musicians may join", '#session-settings-dialog #session-settings-musician-access')
|
access_level = "Only RSVP musicians may join"
|
||||||
#select('Private', :from => 'session-settings-musician-access')
|
when :by_approval
|
||||||
find('#session-settings-dialog-submit').trigger(:click)
|
access_level = "Musicians may join by approval"
|
||||||
end
|
when :at_will, :public, :open
|
||||||
# verify it's dismissed
|
access_level = "Musicians may join at will"
|
||||||
page.should have_no_selector('h1', text: 'update session settings')
|
else
|
||||||
|
access_level = "Musicians may join at will"
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_session_as_public()
|
|
||||||
find('#session-settings-button').trigger(:click)
|
find('#session-settings-button').trigger(:click)
|
||||||
within('#session-settings-dialog') do
|
within('#session-settings-dialog') do
|
||||||
jk_select("Musicians may join at will", '#session-settings-dialog #session-settings-musician-access')
|
jk_select(access_level, '#session-settings-dialog #session-settings-musician-access')
|
||||||
# select('Public', :from => 'session-settings-musician-access')
|
|
||||||
find('#session-settings-dialog-submit').trigger(:click)
|
find('#session-settings-dialog-submit').trigger(:click)
|
||||||
end
|
end
|
||||||
# verify it's dismissed
|
# verify it's dismissed
|
||||||
|
|
@ -649,6 +669,12 @@ def sidebar_search_for string, category
|
||||||
wait_for_ajax
|
wait_for_ajax
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def expand_sidebar header_name
|
||||||
|
#search, friends, chat, notifications
|
||||||
|
panel_id = "panel#{header_name.to_s.capitalize}"
|
||||||
|
within("div[layout-id='#{panel_id}']") { find('div.panel-header').trigger(:click) }
|
||||||
|
end
|
||||||
|
|
||||||
def show_user_menu
|
def show_user_menu
|
||||||
page.execute_script("$('ul.shortcuts').show()")
|
page.execute_script("$('ul.shortcuts').show()")
|
||||||
#page.execute_script("JK.UserDropdown.menuHoverIn()")
|
#page.execute_script("JK.UserDropdown.menuHoverIn()")
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ gem 'carrierwave'
|
||||||
gem 'fog'
|
gem 'fog'
|
||||||
gem 'devise', '3.3.0' # 3.4.0 causes uninitialized constant ActionController::Metal (NameError)
|
gem 'devise', '3.3.0' # 3.4.0 causes uninitialized constant ActionController::Metal (NameError)
|
||||||
gem 'postgres-copy'
|
gem 'postgres-copy'
|
||||||
gem 'aws-sdk' #, '1.29.1'
|
gem 'aws-sdk', '~> 1'
|
||||||
gem 'bugsnag'
|
gem 'bugsnag'
|
||||||
gem 'postgres_ext'
|
gem 'postgres_ext'
|
||||||
gem 'resque'
|
gem 'resque'
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue