*wip
This commit is contained in:
parent
a2bf56beac
commit
dff3fa4870
|
|
@ -29,9 +29,12 @@ module JamRuby
|
|||
# websocket gateway got a client with the same client_id as an already-connected client
|
||||
DUPLICATE_CLIENT = 'DUPLICATE_CLIENT'
|
||||
|
||||
# info about how the test went
|
||||
NETWORK_TEST_RESULT = 'NETWORK_TEST_RESULT'
|
||||
|
||||
DIAGNOSTIC_TYPES = [NO_HEARTBEAT_ACK, WEBSOCKET_CLOSED_REMOTELY, EXPIRED_STALE_CONNECTION,
|
||||
MISSING_CLIENT_STATE, UNKNOWN_MESSAGE_TYPE, MISSING_ROUTE_TO,
|
||||
DUPLICATE_CLIENT, WEBSOCKET_CLOSED_LOCALLY]
|
||||
DUPLICATE_CLIENT, WEBSOCKET_CLOSED_LOCALLY, NETWORK_TEST_RESULT]
|
||||
|
||||
# creator types #
|
||||
CLIENT = 'client'
|
||||
|
|
|
|||
|
|
@ -3,9 +3,16 @@ module JamRuby
|
|||
|
||||
belongs_to :connection, class_name: 'JamRuby::Connection', foreign_key: :client_id, primary_key: :client_id
|
||||
|
||||
def heartbeat_interval_client
|
||||
nil
|
||||
end
|
||||
|
||||
def connection_expire_time_client
|
||||
nil
|
||||
end
|
||||
|
||||
def self.select_latency_tester
|
||||
LatencyTester.joins(:connection).first
|
||||
LatencyTester.joins(:connection).first!
|
||||
end
|
||||
|
||||
# we need to find that latency_tester with the specified connection (and reconnect it)
|
||||
|
|
|
|||
|
|
@ -132,6 +132,7 @@
|
|||
if (!(context.JK.hasOneConfiguredDevice())) {
|
||||
app.afterFtue = function() { submitForm(evt); };
|
||||
app.layout.startNewFtue();
|
||||
alert("dere")
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -444,7 +444,7 @@
|
|||
function SessionStartRecording() {}
|
||||
function SessionStopPlay() {}
|
||||
function SessionStopRecording() {}
|
||||
function SessionAddPlayTrack() {}
|
||||
function SessionAddPlayTrack() {return true;}
|
||||
function SessionRemoveAllPlayTracks(){}
|
||||
function isSessionTrackPlaying() { return false; }
|
||||
function SessionCurrrentPlayPosMs() { return 0; }
|
||||
|
|
@ -675,17 +675,39 @@
|
|||
fakeJamClientRecordings = fakeRecordingsImpl;
|
||||
}
|
||||
|
||||
function OnLoggedIn(userId, sessionToken) {
|
||||
|
||||
}
|
||||
|
||||
function OnLoggedOut() {
|
||||
|
||||
}
|
||||
|
||||
function UserAttention(option) {
|
||||
function TestNetworkPktBwRate(targetClientId, successCallback, timeoutCallback, testType, duration, numClients, payloadSize) {
|
||||
var progress = {progress:true,
|
||||
upthroughput:.95,
|
||||
downthroughput:.95,
|
||||
upjitter: 2.3,
|
||||
downjitter: 2.3
|
||||
}
|
||||
var count = 0;
|
||||
var interval = setInterval(function() {
|
||||
|
||||
eval(successCallback + "(" + JSON.stringify(progress) + ");");
|
||||
|
||||
if(progress.upthroughput < 1) {
|
||||
progress.upthroughput += .05;
|
||||
}
|
||||
if(progress.downthroughput < 1) {
|
||||
progress.downthroughput += .05;
|
||||
}
|
||||
|
||||
count++;
|
||||
if(count == duration) {
|
||||
clearInterval(interval);
|
||||
|
||||
delete progress['progress']
|
||||
progress.pass = true;
|
||||
eval(successCallback + "(" + JSON.stringify(progress) + ");");
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
function StopNetworkTest(targetClientId) {}
|
||||
function OnLoggedIn(userId, sessionToken) {}
|
||||
function OnLoggedOut() {}
|
||||
function UserAttention(option) {}
|
||||
|
||||
function log(level, message) {
|
||||
console.log("beep : " + message)
|
||||
|
|
@ -902,6 +924,9 @@
|
|||
this.RegisterP2PMessageCallbacks = RegisterP2PMessageCallbacks;
|
||||
this.SetFakeRecordingImpl = SetFakeRecordingImpl;
|
||||
|
||||
// network test
|
||||
this.TestNetworkPktBwRate = TestNetworkPktBwRate;
|
||||
this.StopNetworkTest = StopNetworkTest;
|
||||
this.log = log;
|
||||
this.getOperatingMode = getOperatingMode;
|
||||
this.clientID = "devtester";
|
||||
|
|
|
|||
|
|
@ -89,6 +89,8 @@
|
|||
register : "Register",
|
||||
download : "DownloadClient",
|
||||
audioTest : "AudioTest",
|
||||
trackConfig : "AudioTrackConfig",
|
||||
networkTest : "NetworkTest",
|
||||
sessionCount : "SessionCount",
|
||||
sessionMusicians : "SessionMusicians",
|
||||
sessionQuality : "SessionQuality",
|
||||
|
|
@ -281,6 +283,23 @@
|
|||
context.ga('send', 'event', category, target, data);
|
||||
}
|
||||
|
||||
function trackNetworkTest(platform, numUsers) {
|
||||
var normalizedPlatform = translatePlatformForGA(platform);
|
||||
|
||||
context.ga('send', 'event', categories.networkTest, 'Passed', normalizedPlatform, numUsers);
|
||||
}
|
||||
|
||||
function trackAudioTestCompletion(platform) {
|
||||
var normalizedPlatform = translatePlatformForGA(platform);
|
||||
|
||||
context.ga('send', 'event', categories.audioTest, 'Passed', normalizedPlatform);
|
||||
}
|
||||
|
||||
function trackConfigureTracksCompletion(platform) {
|
||||
var normalizedPlatform = translatePlatformForGA(platform);
|
||||
|
||||
context.ga('send', 'event', categories.trackConfig, 'Passed', normalizedPlatform);
|
||||
}
|
||||
|
||||
var GA = {};
|
||||
GA.Categories = categories;
|
||||
|
|
@ -294,6 +313,9 @@
|
|||
GA.trackRegister = trackRegister;
|
||||
GA.trackDownload = trackDownload;
|
||||
GA.trackFTUECompletion = trackFTUECompletion;
|
||||
GA.trackNetworkTest = trackNetworkTest;
|
||||
GA.trackAudioTestCompletion = trackAudioTestCompletion;
|
||||
GA.trackConfigureTracksCompletion = trackConfigureTracksCompletion;
|
||||
GA.trackSessionCount = trackSessionCount;
|
||||
GA.trackSessionMusicians = trackSessionMusicians;
|
||||
GA.trackSessionQuality = trackSessionQuality;
|
||||
|
|
|
|||
|
|
@ -103,6 +103,27 @@
|
|||
}
|
||||
|
||||
|
||||
function onCanceled() {
|
||||
if (app.cancelFtue) {
|
||||
app.cancelFtue();
|
||||
app.afterFtue = null;
|
||||
app.cancelFtue = null;
|
||||
}
|
||||
|
||||
return closeDialog();
|
||||
}
|
||||
|
||||
function onClosed() {
|
||||
if (app.afterFtue) {
|
||||
// If there's a function to invoke, invoke it.
|
||||
app.afterFtue();
|
||||
app.afterFtue = null;
|
||||
app.cancelFtue = null;
|
||||
}
|
||||
|
||||
return closeDialog();
|
||||
}
|
||||
|
||||
function closeDialog() {
|
||||
wizard.onCloseDialog();
|
||||
app.layout.closeDialog('gear-wizard');
|
||||
|
|
@ -111,8 +132,8 @@
|
|||
|
||||
function events() {
|
||||
$(wizard).on('step_changed', onStepChanged);
|
||||
$(wizard).on('wizard_cancel', closeDialog);
|
||||
$(wizard).on('wizard_close', closeDialog);
|
||||
$(wizard).on('wizard_cancel', onCanceled);
|
||||
$(wizard).on('wizard_close', onClosed);
|
||||
}
|
||||
|
||||
function setNextState(enabled) {
|
||||
|
|
|
|||
|
|
@ -179,7 +179,13 @@
|
|||
return false;
|
||||
}
|
||||
|
||||
return save(tracks);
|
||||
var saved = save(tracks);
|
||||
|
||||
if(saved) {
|
||||
context.JK.GA.trackConfigureTracksCompletion(context.JK.detectOS());
|
||||
}
|
||||
|
||||
return saved;
|
||||
}
|
||||
|
||||
function beforeShow() {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,18 @@
|
|||
context.JK = context.JK || {};
|
||||
context.JK.StepNetworkTest = function (app, $dialog) {
|
||||
|
||||
var NETWORK_TEST_TYPES = {
|
||||
RestPhase : 0,
|
||||
PktTest100NormalLatency : 1,
|
||||
PktTest200MediumLatency : 2,
|
||||
PktTest400LowLatency : 3,
|
||||
PktTestRateSweep : 4,
|
||||
RcvOnly : 5
|
||||
}
|
||||
var STARTING_NUM_CLIENTS = 4;
|
||||
var PAYLOAD_SIZE = 100;
|
||||
var MINIMUM_ACCEPTABLE_SESSION_SIZE = 2;
|
||||
|
||||
var rest = context.JK.Rest();
|
||||
var logger = context.JK.logger;
|
||||
var $step = null;
|
||||
|
|
@ -16,64 +28,355 @@
|
|||
var $testScore = null;
|
||||
var $testText = null;
|
||||
var testedSuccessfully = false;
|
||||
var serverClientId = null;
|
||||
var $scoringBar = null;
|
||||
var $goodMarker = null;
|
||||
var $goodLine = null;
|
||||
var $currentScore = null;
|
||||
var $scoredClients = null;
|
||||
var $subscore = null;
|
||||
|
||||
var serverClientId = '';
|
||||
var isScoring = false;
|
||||
var numClientsToTest = STARTING_NUM_CLIENTS;
|
||||
var testSummary = {attempts : [], final:null}
|
||||
|
||||
var scoringZoneWidth = 100;//px
|
||||
|
||||
|
||||
function reset() {
|
||||
serverClientId = '';
|
||||
isScoring = false;
|
||||
numClientsToTest = STARTING_NUM_CLIENTS;
|
||||
testSummary = {attempts : []};
|
||||
}
|
||||
|
||||
function renderStartTest() {
|
||||
$scoredClients.empty();
|
||||
$testResults.removeClass('good acceptable bad').addClass('testing');
|
||||
$testText.empty();
|
||||
$subscore.empty();
|
||||
updateControlsState();
|
||||
$currentScore.width(0);
|
||||
$goodLine.css('left', (gon.ftue_packet_rate_treshold * 100) + '%');
|
||||
$goodMarker.css('left', (gon.ftue_packet_rate_treshold * 100) + '%');
|
||||
}
|
||||
|
||||
function renderStopTest(score, text) {
|
||||
$scoredClients.html(score);
|
||||
$testText.html(text);
|
||||
$testResults.removeClass('testing');
|
||||
}
|
||||
|
||||
function postDiagnostic() {
|
||||
rest.createDiagnostic({
|
||||
type: 'NETWORK_TEST_RESULT',
|
||||
data: {client_type: context.JK.clientType(), client_id: context.JK.JamServer.clientID, summary:testSummary}
|
||||
});
|
||||
}
|
||||
|
||||
function testFinished() {
|
||||
var attempt = getCurrentAttempt();
|
||||
|
||||
if(!attempt.final) {
|
||||
attempt.final = {reason : attempt.reason};
|
||||
}
|
||||
|
||||
var reason = attempt.final.reason;
|
||||
|
||||
if(reason == "success") {
|
||||
renderStopTest(attempt.num_clients, "Your router and Internet service will support sessions of up to " + attempt.num_clients + " JamKazam musicians.")
|
||||
testedSuccessfully = true;
|
||||
if(!attempt.final.num_clients) {
|
||||
attempt.final.num_clients = attempt.num_clients;
|
||||
}
|
||||
context.JK.GA.trackNetworkTest(context.JK.detectOS(), attempt.final.num_clients);
|
||||
//context.jamClient.updateLatencyTestScore(attempt.num_clients);
|
||||
if(attempt.final.num_clients == 2) {
|
||||
$testResults.addClass('acceptable');
|
||||
}
|
||||
else {
|
||||
$testResults.addClass('good');
|
||||
}
|
||||
}
|
||||
else if(reason == "minimum_client_threshold") {
|
||||
renderStopTest('', "We're sorry, but your router and Internet service will not effectively support JamKazam sessions. Please click the HELP button for more information.")
|
||||
}
|
||||
else if(reason == "unreachable") {
|
||||
renderStopTest('', "We're sorry, but your router will not support JamKazam in its current configuration. Please click the HELP button for more information.");
|
||||
}
|
||||
else if(reason == "internal_error") {
|
||||
context.JK.alertSupportedNeeded("The JamKazam client software had an unexpected problem while scoring your Internet connection.");
|
||||
renderStopTest('', '');
|
||||
}
|
||||
else if(reason == "remote_peer_cant_test") {
|
||||
context.JK.alertSupportedNeeded("JamKazam is experiencing technical difficulties.");
|
||||
renderStopTest('', '');
|
||||
}
|
||||
else if(reason == "invalid_response") {
|
||||
context.JK.alertSupportedNeeded("The JamKazam client software had an unexpected problem while scoring your Internet connection. Reason=" + attempt.backend_data.reason + '.');
|
||||
renderStopTest('', '');
|
||||
}
|
||||
else if(reason == 'no_servers') {
|
||||
context.JK.alertSupportedNeeded("No network test servers are available. You can skip this step for now.");
|
||||
renderStopTest('', '');
|
||||
testedSuccessfully = true;
|
||||
}
|
||||
else if(reason == 'no_network') {
|
||||
context.JK.Banner.showAlert("Please try again later. Your network appears down.");
|
||||
renderStopTest('', '');
|
||||
}
|
||||
else if(reason == "rest_api_error") {
|
||||
context.JK.alertSupportedNeeded("Unable to network test servers are available. You can skip this step for now.");
|
||||
testedSuccessfully = true;
|
||||
renderStopTest('', '');
|
||||
}
|
||||
else if(reason == "timeout") {
|
||||
context.JK.alertSupportedNeeded("Unable to network test servers timed out. You can skip this step for now.");
|
||||
testedSuccessfully = true;
|
||||
renderStopTest('', '');
|
||||
}
|
||||
else {
|
||||
context.JK.alertSupportedNeeded("The JamKazam client software had a logic error while scoring your Internet connection.");
|
||||
renderStopTest('', '');
|
||||
}
|
||||
|
||||
numClientsToTest = STARTING_NUM_CLIENTS;
|
||||
isScoring = false;
|
||||
updateControlsState();
|
||||
postDiagnostic();
|
||||
}
|
||||
|
||||
function getCurrentAttempt() {
|
||||
return testSummary.attempts[testSummary.attempts.length - 1];
|
||||
}
|
||||
|
||||
|
||||
function attemptTestPass() {
|
||||
|
||||
var attempt = {};
|
||||
attempt.payload_size = PAYLOAD_SIZE;
|
||||
attempt.duration = gon.ftue_network_test_duration;
|
||||
attempt.test_type = 'PktTest400LowLatency';
|
||||
attempt.num_clients = numClientsToTest;
|
||||
attempt.server_client_id = serverClientId;
|
||||
attempt.received_progress = false;
|
||||
testSummary.attempts.push(attempt);
|
||||
|
||||
//context.jamClient.StopNetworkTest('');
|
||||
|
||||
$testText.text("Simulating the network traffic of a " + numClientsToTest + "-person session.");
|
||||
|
||||
updateProgress(0, false);
|
||||
|
||||
$currentScore.css
|
||||
context.jamClient.TestNetworkPktBwRate(serverClientId, TEST_SUCCESS_CALLBACK, TEST_TIMEOUT_CALLBACK,
|
||||
NETWORK_TEST_TYPES.PktTest400LowLatency,
|
||||
gon.ftue_network_test_duration,
|
||||
numClientsToTest,
|
||||
PAYLOAD_SIZE);
|
||||
}
|
||||
|
||||
|
||||
function startNetworkTest() {
|
||||
isScoring = true;
|
||||
numClientsToTest = STARTING_NUM_CLIENTS;
|
||||
renderStartTest();
|
||||
rest.getLatencyTester()
|
||||
.done(function(response) {
|
||||
// ensure there are no tests ongoing
|
||||
|
||||
serverClientId = response.client_id;
|
||||
|
||||
logger.info("beginning network test against client_id: " + clientId);
|
||||
logger.info("beginning network test against client_id: " + serverClientId);
|
||||
|
||||
context.jamClient.TestNetworkPktBwRate(serverClientId, TEST_SUCCESS_CALLBACK, TEST_TIMEOUT_CALLBACK);
|
||||
attemptTestPass();
|
||||
})
|
||||
.fail(function() {
|
||||
isScoring = false;
|
||||
logger.error("arguments:", arguments);
|
||||
|
||||
if(context.JK.isNetworkError(arguments)) {
|
||||
context.JK.Banner.showAlert("Please try again latery. Your network appears down.");
|
||||
.fail(function(jqXHR) {
|
||||
if(jqXHR.status == 404) {
|
||||
// means there are no network testers available.
|
||||
// we have to skip this part of the UI
|
||||
testSummary.final = {reason: 'no_servers'}
|
||||
}
|
||||
else {
|
||||
logger.error("unable to get latency tester from server");
|
||||
if(context.JK.isNetworkError(arguments)) {
|
||||
testSummary.final = {reason: 'no_network'}
|
||||
}
|
||||
else {
|
||||
testSummary.final = {reason: 'rest_api_error'}
|
||||
}
|
||||
}
|
||||
testFinished();
|
||||
})
|
||||
logger.info("starting network test");
|
||||
return false;
|
||||
}
|
||||
|
||||
function networkTestSuccess() {
|
||||
console.log("success arguments: ", arguments);
|
||||
context.jamClient.StopNetworkTest(serverClientId);
|
||||
function updateProgress(throughput, showSubscore) {
|
||||
var width = throughput * 100;
|
||||
|
||||
$currentScore.stop().data('showSubscore', showSubscore);
|
||||
|
||||
if(!showSubscore) {
|
||||
$subscore.text('');
|
||||
}
|
||||
|
||||
$currentScore.animate({
|
||||
duration: 1000,
|
||||
width: width + '%'
|
||||
}, {
|
||||
step: function (now, fx) {
|
||||
if(showSubscore) {
|
||||
var newWidth = ( 100 * parseFloat($currentScore.css('width')) / parseFloat($currentScore.parent().css('width')) );
|
||||
$subscore.text((Math.round(newWidth * 10) / 10) + '%');
|
||||
}
|
||||
}
|
||||
}).css('overflow', 'visible');
|
||||
;
|
||||
}
|
||||
|
||||
function networkTestTimeout() {
|
||||
console.log("timeout arguments:", arguments);
|
||||
context.jamClient.StopNetworkTest(serverClientId);
|
||||
function networkTestSuccess(data) {
|
||||
var attempt = getCurrentAttempt();
|
||||
|
||||
function refineTest(up) {
|
||||
if(up) {
|
||||
if(numClientsToTest == gon.ftue_network_test_max_clients) {
|
||||
attempt.reason = "success";
|
||||
testFinished();
|
||||
}
|
||||
else {
|
||||
numClientsToTest++;
|
||||
logger.debug("increasing number of clients to " + numClientsToTest);
|
||||
setTimeout(attemptTestPass, 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// reduce numclients if we can
|
||||
if(numClientsToTest == MINIMUM_ACCEPTABLE_SESSION_SIZE) {
|
||||
// we are too low already. fail the user
|
||||
attempt.reason = "minimum_client_threshold";
|
||||
testFinished();
|
||||
}
|
||||
else if(numClientsToTest > STARTING_NUM_CLIENTS) {
|
||||
// this means we've gone up before... so don't go back down (i.e., creating a loop)
|
||||
attempt.reason = "success";
|
||||
attempt.final = { reason:'success', num_clients: numClientsToTest - 1 }
|
||||
testFinished();
|
||||
}
|
||||
else {
|
||||
numClientsToTest--;
|
||||
logger.debug("reducing number of clients to " + numClientsToTest);
|
||||
setTimeout(attemptTestPass, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
attempt.backend_data = data;
|
||||
|
||||
if(data.progress === true) {
|
||||
|
||||
var animate = true;
|
||||
if(data.downthroughput && data.upthroughput) {
|
||||
|
||||
if(data.downthroughput > 0 || data.upthroughput > 0) {
|
||||
attempt.received_progress = true;
|
||||
animate = true;
|
||||
}
|
||||
|
||||
if(attempt.received_progress) {
|
||||
// take the lower
|
||||
var throughput= data.downthroughput < data.upthroughput ? data.downthroughput : data.upthroughput;
|
||||
|
||||
updateProgress(throughput, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
logger.debug("network test pass success. data: ", data);
|
||||
|
||||
if(data.reason == "unreachable") {
|
||||
// STUN
|
||||
logger.debug("network test: unreachable (STUN issue or similar)");
|
||||
attempt.reason = data.reason;
|
||||
testFinished();
|
||||
}
|
||||
else if(data.reason == "internal_error") {
|
||||
// oops
|
||||
logger.debug("network test: internal_error (client had a unexpected problem)");
|
||||
attempt.reason = data.reason;
|
||||
testFinished();
|
||||
}
|
||||
else if(data.reason == "remote_peer_cant_test") {
|
||||
// old client
|
||||
logger.debug("network test: remote_peer_cant_test (old client)")
|
||||
attempt.reason = data.reason;
|
||||
testFinished();
|
||||
}
|
||||
else {
|
||||
if(!data.downthroughput || !data.upthroughput) {
|
||||
// we have to assume this is bad. just not a reason we know about in code
|
||||
logger.debug("network test: no test data (unknown issue? " + data.reason + ")")
|
||||
attempt.reason = "invalid_response";
|
||||
testFinished();
|
||||
}
|
||||
else {
|
||||
// success... but we still have to verify if this data is within threshold
|
||||
if(data.downthroughput < gon.ftue_packet_rate_treshold) {
|
||||
logger.debug("network test: downthroughput too low. downthroughput: " + data.downthroughput + ", threshold: " + gon.ftue_packet_rate_treshold);
|
||||
refineTest(false);
|
||||
}
|
||||
else if(data.upthroughput < gon.ftue_packet_rate_treshold) {
|
||||
logger.debug("network test: upthroughput too low. upthroughput: " + data.upthroughput + ", threshold: " + gon.ftue_packet_rate_treshold);
|
||||
refineTest(false);
|
||||
}
|
||||
else {
|
||||
// true success. we can accept this score
|
||||
logger.debug("network test: success")
|
||||
refineTest(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// VRFS-1742
|
||||
// context.jamClient.StopNetworkTest(serverClientId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function networkTestTimeout(data) {
|
||||
logger.warn("network timeout when testing latency test: " + data);
|
||||
|
||||
var attempt = getCurrentAttempt();
|
||||
attempt.reason = 'timeout';
|
||||
attempt.backend_data = data;
|
||||
testFinished();
|
||||
}
|
||||
|
||||
function hasScoredNetworkSuccessfully() {
|
||||
return testedSuccessfully;
|
||||
}
|
||||
|
||||
function updateControlsState() {
|
||||
initializeNextButtonState();
|
||||
initializeBackButtonState();
|
||||
}
|
||||
|
||||
function initializeNextButtonState() {
|
||||
$dialog.setNextState(hasScoredNetworkSuccessfully());
|
||||
$dialog.setNextState(hasScoredNetworkSuccessfully() && !isScoring);
|
||||
}
|
||||
|
||||
function initializeBackButtonState() {
|
||||
$dialog.setNextState();
|
||||
$dialog.setBackState(!isScoring);
|
||||
}
|
||||
|
||||
function newSession() {
|
||||
isScoring = false;
|
||||
// XXX context.jamClient.stopNetworkTest();
|
||||
reset();
|
||||
//context.jamClient.StopNetworkTest('');
|
||||
}
|
||||
|
||||
function beforeShow() {
|
||||
initializeNextButtonState();
|
||||
reset();
|
||||
updateControlsState();
|
||||
}
|
||||
|
||||
function initialize(_$step) {
|
||||
|
|
@ -83,7 +386,12 @@
|
|||
$testResults = $step.find('.network-test-results');
|
||||
$testScore = $step.find('.network-test-score');
|
||||
$testText = $step.find('.network-test-text');
|
||||
|
||||
$scoringBar = $step.find('.scoring-bar');
|
||||
$goodMarker = $step.find('.good-marker');
|
||||
$goodLine =$step.find('.good-line');
|
||||
$currentScore = $step.find('.current-score');
|
||||
$scoredClients= $step.find('.scored-clients');
|
||||
$subscore = $step.find('.subscore');
|
||||
$startNetworkTestBtn.on('click', startNetworkTest);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -932,9 +932,15 @@
|
|||
// lie for now until IO questions finalize
|
||||
validIOScore = true;
|
||||
|
||||
onSuccessfulScore();
|
||||
|
||||
renderScoringStopped();
|
||||
}
|
||||
|
||||
function onSuccessfulScore() {
|
||||
|
||||
}
|
||||
|
||||
// refocused affects how IO testing occurs.
|
||||
// on refocus=true:
|
||||
// * reuse IO score if it was good/acceptable
|
||||
|
|
@ -1049,7 +1055,9 @@
|
|||
return false;
|
||||
}
|
||||
else {
|
||||
//XXX rename profile
|
||||
context.jamClient.FTUESave(true);
|
||||
context.JK.GA.trackAudioTestCompletion(context.JK.detectOS());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
var $wizardSteps = null;
|
||||
var $currentWizardStep = null;
|
||||
var $wizardButtons = null;
|
||||
var $btnHelp = null;
|
||||
var $btnNext = null;
|
||||
var $btnBack = null;
|
||||
var $btnClose = null;
|
||||
|
|
@ -21,7 +22,7 @@
|
|||
var $self = $(this);
|
||||
|
||||
function totalSteps() {
|
||||
return STEPS.length;
|
||||
return context.JK.dkeys(STEPS).length;
|
||||
}
|
||||
|
||||
function beforeHideStep() {
|
||||
|
|
@ -62,7 +63,7 @@
|
|||
var stepInfo = STEPS[step];
|
||||
if(stepInfo.handleNext) {
|
||||
var result = stepInfo.handleNext.call(stepInfo);
|
||||
if(!result) {return false;}
|
||||
if(result === false) {return false;}
|
||||
}
|
||||
|
||||
previousStep = step;
|
||||
|
|
@ -81,25 +82,32 @@
|
|||
|
||||
$currentWizardStep = $nextWizardStep;
|
||||
|
||||
context.JK.GA.virtualPageView(location.pathname + location.search + location.hash, $currentWizardStep.attr('dialog-title'));
|
||||
|
||||
$self.triggerHandler('step_changed', {step:step});
|
||||
|
||||
// update buttons
|
||||
var $wizardButtonsContent = $(context._.template($templateButtons.html(), {}, {variable: 'data'}));
|
||||
|
||||
$btnHelp = $wizardButtonsContent.find('.btn-help');
|
||||
$btnBack = $wizardButtonsContent.find('.btn-back');
|
||||
$btnNext = $wizardButtonsContent.find('.btn-next');
|
||||
$btnClose = $wizardButtonsContent.find('.btn-close');
|
||||
$btnCancel = $wizardButtonsContent.find('.btn-cancel');
|
||||
|
||||
// hide help button if on last step
|
||||
if (step == totalSteps() - 1) {
|
||||
$btnHelp.hide();
|
||||
}
|
||||
// hide back button if 1st step or last step
|
||||
if (step == 0 && step == totalSteps() - 1) {
|
||||
if (step == 0 || step == totalSteps() - 1) {
|
||||
$btnBack.hide();
|
||||
}
|
||||
// hide next button if not on last step
|
||||
// hide next button if on last step
|
||||
if (step == totalSteps() - 1) {
|
||||
$btnNext.hide();
|
||||
}
|
||||
// hide close if on last step
|
||||
// hide close if not on last step
|
||||
if (step != totalSteps() - 1) {
|
||||
$btnClose.hide();
|
||||
}
|
||||
|
|
@ -130,7 +138,7 @@
|
|||
|
||||
previousStep = null;
|
||||
|
||||
step = args.d1;
|
||||
step = args != null ? args.d1 : 0;
|
||||
if (!step) step = 0;
|
||||
step = parseInt(step);
|
||||
moveToStep();
|
||||
|
|
@ -177,7 +185,6 @@
|
|||
}
|
||||
|
||||
function initialize(_$dialog, _$wizardSteps, _STEPS) {
|
||||
|
||||
$dialog = _$dialog;
|
||||
$wizardSteps = _$wizardSteps;
|
||||
STEPS = _STEPS;
|
||||
|
|
|
|||
|
|
@ -678,9 +678,9 @@
|
|||
|
||||
function startNewFtue() {
|
||||
var step = 0;
|
||||
setWizardStep(step);
|
||||
wizardShowFunctions[step]();
|
||||
showDialog('ftue');
|
||||
//setWizardStep(step);
|
||||
//wizardShowFunctions[step]();
|
||||
showDialog('gear-wizard');
|
||||
}
|
||||
|
||||
function setWizardStep(targetStepId) {
|
||||
|
|
|
|||
|
|
@ -46,7 +46,13 @@
|
|||
for (i=0; i < localMusicTracks.length; i++) {
|
||||
var track = {};
|
||||
track.client_track_id = localMusicTracks[i].id;
|
||||
track.instrument_id = context.JK.client_to_server_instrument_map[localMusicTracks[i].instrument_id].server_id;
|
||||
|
||||
if(localMusicTracks[i].instrument_id === 0) {
|
||||
track.instrument_id = context.JK.server_to_client_instrument_map["Other"].server_id;
|
||||
}
|
||||
else {
|
||||
track.instrument_id = context.JK.client_to_server_instrument_map[localMusicTracks[i].instrument_id].server_id;
|
||||
}
|
||||
if (localMusicTracks[i].stereo) {
|
||||
track.sound = "stereo";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@
|
|||
margin-top:20px;
|
||||
}
|
||||
|
||||
.ftue-buttons {
|
||||
.wizard-buttons {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width:100%;
|
||||
|
|
@ -67,7 +67,7 @@
|
|||
|
||||
}
|
||||
|
||||
.ftue-buttons-holder {
|
||||
.wizard-buttons-holder {
|
||||
float:right;
|
||||
}
|
||||
|
||||
|
|
@ -151,6 +151,9 @@
|
|||
width:25%;
|
||||
}
|
||||
|
||||
.watch-video {
|
||||
margin-top:29px;
|
||||
}
|
||||
.select-audio-input-device {
|
||||
margin-bottom:20px;
|
||||
}
|
||||
|
|
@ -378,6 +381,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
.watch-video {
|
||||
margin-top:45px;
|
||||
}
|
||||
|
||||
.icon-instrument-select {
|
||||
padding:3px 0; // to combine 24 of .current-instrument + 3x on either side
|
||||
margin:0 auto 15px; // 15 margin-bottom to match tracks on the left
|
||||
|
|
@ -478,13 +485,21 @@
|
|||
|
||||
&[track-count="2"] {
|
||||
.ftue-input {
|
||||
width:50%;
|
||||
width:49%;
|
||||
display:inline-block;
|
||||
|
||||
&:nth-of-type(1) {
|
||||
float:left;
|
||||
&:after {
|
||||
float:left;
|
||||
content: ',';
|
||||
padding-right:3px;
|
||||
}
|
||||
}
|
||||
&:nth-of-type(2) {
|
||||
float:right;
|
||||
}
|
||||
}
|
||||
/**.ftue-input:nth-child(1)::before {
|
||||
content: ',';
|
||||
padding-right:3px;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -499,6 +514,9 @@
|
|||
}
|
||||
}
|
||||
|
||||
.watch-video {
|
||||
margin-top:97px;
|
||||
}
|
||||
|
||||
.voicechat-option {
|
||||
|
||||
|
|
@ -625,6 +643,10 @@
|
|||
margin-top:22px;
|
||||
}
|
||||
|
||||
.watch-video {
|
||||
margin-top:90px;
|
||||
}
|
||||
|
||||
a.start-network-test {
|
||||
margin-top:20px;
|
||||
}
|
||||
|
|
@ -635,6 +657,8 @@
|
|||
color:white;
|
||||
font-size:20px;
|
||||
background-color:#222;
|
||||
text-align:center;
|
||||
margin-bottom:20px;
|
||||
|
||||
&.good {
|
||||
background-color: #72a43b;
|
||||
|
|
@ -647,6 +671,63 @@
|
|||
}
|
||||
}
|
||||
|
||||
.scoring-bar {
|
||||
width:100%;
|
||||
height:20px;
|
||||
left:0;
|
||||
position:relative;
|
||||
//display:inline-block;
|
||||
display:none;
|
||||
|
||||
.current-score {
|
||||
background-color:gray;
|
||||
border-right:1px solid white;
|
||||
border-top:1px solid #ccc;
|
||||
border-bottom:1px solid #ccc;
|
||||
border-left:1px solid #ccc;
|
||||
height:20px;
|
||||
display:inline-block;
|
||||
position:relative;
|
||||
left:0;
|
||||
min-width:55px;
|
||||
text-align:left;
|
||||
padding-left:5px;
|
||||
@include border_box_sizing;
|
||||
font-size:12px;
|
||||
color:white;
|
||||
|
||||
.subscore {
|
||||
font-size:10px;
|
||||
color:white;
|
||||
bottom:-15px;
|
||||
right:-16px;
|
||||
position:absolute;
|
||||
}
|
||||
}
|
||||
|
||||
.good-marker {
|
||||
position:absolute;
|
||||
text-align:center;
|
||||
left:95%;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 5px solid transparent;
|
||||
border-right: 5px solid transparent;
|
||||
border-top: 5px solid #72a43b;
|
||||
margin-left:-5px;
|
||||
top:-7px;
|
||||
}
|
||||
|
||||
.good-line {
|
||||
position:absolute;
|
||||
height:100%;
|
||||
left:95%;
|
||||
width:1px;
|
||||
background-color: #72a43b;
|
||||
margin-left:-0.5px;
|
||||
top:0;
|
||||
}
|
||||
}
|
||||
.network-test-text {
|
||||
|
||||
}
|
||||
|
|
@ -655,16 +736,41 @@
|
|||
height: 248px ! important;
|
||||
@include border_box_sizing;
|
||||
&.testing {
|
||||
|
||||
text-align:left;
|
||||
.network-test-score {
|
||||
font-size:16px;
|
||||
display:none;
|
||||
}
|
||||
|
||||
.scoring-bar {
|
||||
display:inline-block;
|
||||
margin-bottom:10px;
|
||||
}
|
||||
|
||||
.network-test-text {
|
||||
background-image: url('/assets/shared/spinner.gif');
|
||||
background-repeat:no-repeat;
|
||||
background-position:center;
|
||||
//background-image: url('/assets/shared/spinner.gif');
|
||||
//background-repeat:no-repeat;
|
||||
//background-position:center;
|
||||
//width:128px;
|
||||
height:128px;
|
||||
//height:128px;
|
||||
}
|
||||
}
|
||||
|
||||
&.good {
|
||||
.network-test-score {
|
||||
background-color: #72a43b;
|
||||
}
|
||||
}
|
||||
|
||||
&.acceptable {
|
||||
.network-test-score {
|
||||
background-color: #D6A800;
|
||||
}
|
||||
}
|
||||
|
||||
&.bad {
|
||||
.network-test-score {
|
||||
background-color: #7B0C00;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -674,10 +780,15 @@
|
|||
.wizard-step-content .wizard-step-column {
|
||||
&:nth-of-type(1) {
|
||||
width:50%;
|
||||
height:350px;
|
||||
}
|
||||
&:nth-of-type(2) {
|
||||
width:50%;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-bottom:20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,9 @@ class ClientsController < ApplicationController
|
|||
gon.fp_upload_dir = Rails.application.config.filepicker_upload_dir
|
||||
gon.allow_force_native_client = Rails.application.config.allow_force_native_client
|
||||
gon.ftue_io_wait_time = Rails.application.config.ftue_io_wait_time
|
||||
gon.ftue_packet_rate_treshold = Rails.application.config.ftue_packet_rate_treshold
|
||||
gon.ftue_network_test_duration = Rails.application.config.ftue_network_test_duration
|
||||
gon.ftue_network_test_max_clients = Rails.application.config.ftue_network_test_max_clients
|
||||
|
||||
# is this the native client or browser?
|
||||
@nativeClient = is_native_client?
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
- total_steps = 7
|
||||
|
||||
.ftue-buttons
|
||||
.ftue-buttons-holder
|
||||
%a.button-grey{href: '#'} HELP
|
||||
.wizard-buttons
|
||||
.wizard-buttons-holder
|
||||
%a.button-grey.btn-help{href: '#'} HELP
|
||||
- if step > 0 && step != total_steps
|
||||
%a.button-orange.btn-back{href:'#'} BACK
|
||||
- if step != total_steps
|
||||
|
|
|
|||
|
|
@ -217,10 +217,10 @@
|
|||
.wizard-step-column
|
||||
%h2 Instructions
|
||||
.ftue-box.instructions
|
||||
Find the Direct Monitoring control on your audio interface.<br>
|
||||
%ul
|
||||
%li If a button, push it into its off position
|
||||
%li If a knob, turn it so that 100% of audio is from your computer, and 0% is from the direct monitor
|
||||
%li Check that computer is connected to router using Ethernet cable.
|
||||
%li Click Start Network Test button.
|
||||
%li View test results.
|
||||
.center
|
||||
%a.button-orange.watch-video{href:'#'} WATCH VIDEO
|
||||
.wizard-step-column
|
||||
|
|
@ -232,7 +232,14 @@
|
|||
.wizard-step-column
|
||||
%h2 Test Results
|
||||
.network-test-results.ftue-box
|
||||
.scoring-bar
|
||||
.current-score
|
||||
testing...
|
||||
.subscore
|
||||
.good-marker
|
||||
.good-line
|
||||
.network-test-score
|
||||
.scored-clients
|
||||
.network-test-text
|
||||
|
||||
|
||||
|
|
@ -246,28 +253,26 @@
|
|||
%p Have fun and thanks for joining us!
|
||||
%p — Team JamKazam
|
||||
.wizard-step-column
|
||||
%h2
|
||||
Tutorial Videos
|
||||
%ul
|
||||
%li
|
||||
%a Creating a Session
|
||||
%li
|
||||
%a Finding a Session
|
||||
%li
|
||||
%a Playing in a Session
|
||||
%li
|
||||
%a Connecting with Other Musicians
|
||||
%li
|
||||
%a Making and Sharing Recordings
|
||||
%li
|
||||
%a Broadcasting Your Sessions
|
||||
%h2
|
||||
Other Valuable Resource Links
|
||||
%ul
|
||||
%li
|
||||
%a JamKazam Support Center
|
||||
%li
|
||||
%a JamKazam Community Forum
|
||||
%h2 Tutorial Videos
|
||||
%ul
|
||||
%li
|
||||
%a Creating a Session
|
||||
%li
|
||||
%a Finding a Session
|
||||
%li
|
||||
%a Playing in a Session
|
||||
%li
|
||||
%a Connecting with Other Musicians
|
||||
%li
|
||||
%a Making and Sharing Recordings
|
||||
%li
|
||||
%a Broadcasting Your Sessions
|
||||
%h2 Other Valuable Resource Links
|
||||
%ul
|
||||
%li
|
||||
%a JamKazam Support Center
|
||||
%li
|
||||
%a JamKazam Community Forum
|
||||
.wizard-buttons
|
||||
|
||||
%script{type: 'text/template', id: 'template-ftuesteps'}
|
||||
|
|
@ -289,9 +294,9 @@
|
|||
|
||||
|
||||
%script{type: 'text/template', id: 'template-wizard-buttons'}
|
||||
.ftue-buttons-holder
|
||||
.wizard-buttons-holder
|
||||
%a.button-grey.btn-cancel{href:'#', 'layout-action' => 'close'} CANCEL
|
||||
%a.button-grey{href: '#'} HELP
|
||||
%a.button-grey.btn-help{href: '#'} HELP
|
||||
%a.button-orange.btn-back{href:'#'} BACK
|
||||
%a.button-orange.btn-next{href:'#'} NEXT
|
||||
%a.button-orange.btn-close{href:'#', 'layout-action' => 'close'} CLOSE
|
||||
|
|
|
|||
|
|
@ -235,5 +235,11 @@ if defined?(Bundler)
|
|||
|
||||
# how long should the frontend wait for the IO to stabilize before asking for a IO score?
|
||||
config.ftue_io_wait_time = 10
|
||||
# what should the threshold be for us to say, 'this person can't play at this rate' during the network test
|
||||
config.ftue_packet_rate_treshold = 0.95
|
||||
# how long to test at each network test step
|
||||
config.ftue_network_test_duration = 10
|
||||
# max number of people to test
|
||||
config.ftue_network_test_max_clients = 8
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,7 +1,20 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe ApiFeedsController do
|
||||
describe ApiLatencyTestersController do
|
||||
render_views
|
||||
|
||||
|
||||
before(:each) do
|
||||
LatencyTester.delete_all
|
||||
end
|
||||
|
||||
describe "match" do
|
||||
it "insists on login" do
|
||||
get :match
|
||||
response.status.should == 403
|
||||
end
|
||||
|
||||
it "throws 404 if no latency testers"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -480,10 +480,10 @@ module JamWebsockets
|
|||
default_expire = @connect_time_expire_client
|
||||
end
|
||||
|
||||
heartbeat_interval = user.try(:heartbeat_interval_client) || default_heartbeat
|
||||
heartbeat_interval = (user && user.heartbeat_interval_client) || default_heartbeat
|
||||
heartbeat_interval = heartbeat_interval.to_i
|
||||
heartbeat_interval = default_heartbeat if heartbeat_interval == 0 # protect against bad config
|
||||
connection_expire_time = user.try(:connection_expire_time_client) || default_expire
|
||||
connection_expire_time = (user && user.connection_expire_time_client) || default_expire
|
||||
connection_expire_time = connection_expire_time.to_i
|
||||
connection_expire_time = default_expire if connection_expire_time == 0 # protect against bad config
|
||||
connection_stale_time = default_stale # no user override exists for this; not a very meaningful time right now
|
||||
|
|
@ -825,7 +825,7 @@ module JamWebsockets
|
|||
# by not catching any exception here, a PermissionError will be thrown if this isn't valid
|
||||
# if for some reason the client is trying to send to a client that it doesn't
|
||||
# belong to
|
||||
access_p2p(to_client_id, context.user, client_msg)
|
||||
#access_p2p(to_client_id, context.user, client_msg)
|
||||
|
||||
if to_client_id.nil? || to_client_id == 'undefined' # javascript translates to 'undefined' in many cases
|
||||
raise SessionError, "empty client_id specified in peer-to-peer message"
|
||||
|
|
|
|||
Loading…
Reference in New Issue