Merge branch 'master' of bitbucket.org:jamkazam/jam-web
This commit is contained in:
commit
d125ffb0b8
1
Gemfile
1
Gemfile
|
|
@ -42,6 +42,7 @@ gem 'sendgrid', '1.1.0'
|
|||
gem 'recaptcha', '0.3.4'
|
||||
gem 'filepicker-rails', '0.0.2'
|
||||
gem 'aws-sdk', '1.8.0'
|
||||
gem 'aasm', '3.0.16'
|
||||
|
||||
#group :libv8 do
|
||||
# gem 'libv8', "~> 3.11.8"
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 2.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 8.8 KiB |
|
|
@ -94,14 +94,21 @@
|
|||
};
|
||||
|
||||
server.send = function(message) {
|
||||
var jsMessage = JSON.stringify(message);
|
||||
logger.log("server.send(" + jsMessage + ")");
|
||||
if (server !== undefined && server.socket !== undefined && server.socket.send !== undefined) {
|
||||
server.socket.send(jsMessage);
|
||||
} else {
|
||||
logger.log("Dropped message because server connection is closed.");
|
||||
}
|
||||
|
||||
var jsMessage = JSON.stringify(message);
|
||||
|
||||
// make sure we're connected before sending
|
||||
if (context.jamClient.connected === true) {
|
||||
logger.log("server.send(" + jsMessage + ")");
|
||||
if (server !== undefined && server.socket !== undefined && server.socket.send !== undefined) {
|
||||
server.socket.send(jsMessage);
|
||||
} else {
|
||||
logger.log("Dropped message because server connection is closed.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
logger.log("Could not send " + jsMessage + " since we're not connected yet.");
|
||||
}
|
||||
};
|
||||
|
||||
server.loginSession = function(sessionId) {
|
||||
|
|
@ -164,4 +171,5 @@
|
|||
context.jamClient.SendP2PMessage.connect(server.sendP2PMessage);
|
||||
}
|
||||
|
||||
|
||||
})(window, jQuery);
|
||||
|
|
@ -58,7 +58,7 @@
|
|||
function StopRecording(map) { dbg('StopRecording' + JSON.stringify(arguments)); }
|
||||
function TestASIOLatency(s) { dbg('TestASIOLatency' + JSON.stringify(arguments)); }
|
||||
|
||||
function TestLatency(clientID, callbackFunctionName) {
|
||||
function TestLatency(clientID, callbackFunctionName, timeoutCallbackName) {
|
||||
logger.debug("Fake JamClient: TestLatency called with client, " + clientID + " and callback function name: " + callbackFunctionName);
|
||||
var response = {
|
||||
clientID: clientID,
|
||||
|
|
@ -108,8 +108,8 @@
|
|||
range_low: -80,
|
||||
record: true,
|
||||
stereo: true,
|
||||
volume_left: 20,
|
||||
volume_right:20
|
||||
volume_left: -40,
|
||||
volume_right:-40
|
||||
});
|
||||
}
|
||||
return response;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
INVITATION : {index: 0, id: "table#sessions-invitations"},
|
||||
FRIEND : {index: 1, id: "table#sessions-friends"},
|
||||
OTHER : {index: 2, id: "table#sessions-other"}
|
||||
};
|
||||
};
|
||||
|
||||
var logger = context.JK.logger;
|
||||
var sessionLatency;
|
||||
|
|
@ -117,7 +117,7 @@
|
|||
if (!priorVisible) {
|
||||
$(OTHER).removeClass('mt35');
|
||||
}
|
||||
|
||||
|
||||
if (sessionCounts[CATEGORY.OTHER.index] == 0) {
|
||||
$(OTHER).hide();
|
||||
}
|
||||
|
|
@ -197,7 +197,7 @@
|
|||
* of the renderSession method without having to do
|
||||
* as much heavy setup.
|
||||
*/
|
||||
function setSession(session) {
|
||||
function setSession(session) {
|
||||
invitationSessionGroup[session.id] = session;
|
||||
}
|
||||
|
||||
|
|
@ -264,7 +264,7 @@
|
|||
// if (boxHeight == "20px") {
|
||||
// $('#musician-list').css({height: "auto"});
|
||||
// $('#musician-list-arrow').removeClass("arrow-down").addClass("arrow-up");
|
||||
|
||||
|
||||
// }
|
||||
// else {
|
||||
// $('#musician-list').css({height: "20px"});
|
||||
|
|
@ -283,18 +283,6 @@
|
|||
$('table#sessions-friends').children(':not(:first-child)').remove();
|
||||
$('table#sessions-other').children(':not(:first-child)').remove();
|
||||
|
||||
// sessions = null;
|
||||
// sessions = {};
|
||||
|
||||
// invitationSessionGroup = null;
|
||||
// invitationSessionGroup = {};
|
||||
|
||||
// friendSessionGroup = null;
|
||||
// friendSessionGroup = {};
|
||||
|
||||
// otherSessionGroup = null;
|
||||
// otherSessionGroup = {};
|
||||
|
||||
sessionCounts = [0, 0, 0];
|
||||
}
|
||||
|
||||
|
|
@ -324,6 +312,12 @@
|
|||
* Initialize, providing an instance of the SessionLatency class.
|
||||
*/
|
||||
function initialize(latency) {
|
||||
|
||||
var screenBindings = {
|
||||
'afterShow': afterShow
|
||||
};
|
||||
app.bindScreen('findSession', screenBindings);
|
||||
|
||||
genreSelector.initialize('Any genre', 0, $('#find-session-form'));
|
||||
|
||||
if (latency) {
|
||||
|
|
@ -335,10 +329,6 @@
|
|||
|
||||
sessionList = new context.JK.SessionList(app);
|
||||
|
||||
var screenBindings = {
|
||||
'afterShow': afterShow
|
||||
};
|
||||
app.bindScreen('findSession', screenBindings);
|
||||
events();
|
||||
}
|
||||
|
||||
|
|
@ -347,7 +337,7 @@
|
|||
this.afterShow = afterShow;
|
||||
|
||||
// Following exposed for easier testing.
|
||||
this.setSession = setSession;
|
||||
this.setSession = setSession;
|
||||
this.clearResults = clearResults;
|
||||
this.getCategoryEnum = getCategoryEnum;
|
||||
this.getGenreSelector = getGenreSelector;
|
||||
|
|
|
|||
|
|
@ -156,7 +156,11 @@
|
|||
function updateHeader() {
|
||||
|
||||
$('#user').html(userMe.name);
|
||||
$('#header-avatar').attr('src', userMe.photo_url);
|
||||
var photoUrl = userMe.photo_url;
|
||||
if (!(photoUrl)) {
|
||||
photoUrl = "/assets/shared/avatar_default.jpg";
|
||||
}
|
||||
$('#header-avatar').attr('src', photoUrl);
|
||||
}
|
||||
|
||||
function updateAccountForms() {
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@
|
|||
|
||||
function loggedIn(header, payload) {
|
||||
app.clientId = payload.client_id;
|
||||
logger.debug("jamkazam.js: loggedIn. clientId now " + app.clientId);
|
||||
}
|
||||
|
||||
function registerLoginAck() {
|
||||
|
|
@ -161,27 +162,32 @@
|
|||
});
|
||||
}
|
||||
|
||||
// Due to timing of initialization, this must be called externally
|
||||
// after all screens have been given a chance to initialize.
|
||||
// It is called from index.html.erb after connecting, and initialization
|
||||
// of other screens.
|
||||
function initialRouting() {
|
||||
routing();
|
||||
|
||||
var hash = context.location.hash;
|
||||
var url = '#/ftue1';
|
||||
if (hash) {
|
||||
url = hash;
|
||||
}
|
||||
logger.debug("Changing screen to " + url);
|
||||
context.location = url;
|
||||
}
|
||||
|
||||
this.initialize = function(inOpts) {
|
||||
var url, hash;
|
||||
app = this;
|
||||
this.opts = $.extend(opts, inOpts);
|
||||
this.layout = new context.JK.Layout();
|
||||
this.layout.initialize(this.opts.layoutOpts);
|
||||
routing();
|
||||
registerMessages();
|
||||
registerLoginAck();
|
||||
|
||||
events();
|
||||
|
||||
// Set the frequency at which we get VU updates
|
||||
context.jamClient.SetVURefreshRate(100);
|
||||
|
||||
hash = context.location.hash;
|
||||
url = '#/ftue1';
|
||||
if (hash) {
|
||||
url = hash;
|
||||
}
|
||||
context.location = url;
|
||||
events();
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -189,6 +195,7 @@
|
|||
* Will be set upon LOGIN_ACK
|
||||
*/
|
||||
this.clientId = null;
|
||||
this.initialRouting = initialRouting;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -63,7 +63,6 @@
|
|||
$('[layout="sidebar"]').show();
|
||||
$('[layout="panel"]').show();
|
||||
layout();
|
||||
context.JK.hideCurtain(opts.animationDuration);
|
||||
}
|
||||
|
||||
function setInitialExpandedSidebarPanel() {
|
||||
|
|
@ -172,7 +171,8 @@
|
|||
var $screen = $('[layout-id="' + currentScreen + '"]');
|
||||
$screen.animate({
|
||||
top: top,
|
||||
left: left
|
||||
left: left,
|
||||
overflow: 'auto'
|
||||
}, duration);
|
||||
}
|
||||
|
||||
|
|
@ -362,7 +362,7 @@
|
|||
}
|
||||
|
||||
function screenEvent(screen, evtName, data) {
|
||||
if (screen in screenBindings) {
|
||||
if (screen && screen in screenBindings) {
|
||||
if (evtName in screenBindings[screen]) {
|
||||
screenBindings[screen][evtName].call(me, data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@
|
|||
var currentMixerRangeMax = null;
|
||||
|
||||
var defaultParticipant = {
|
||||
tracks: [{
|
||||
instrument_id: "unknown"
|
||||
}],
|
||||
user: {
|
||||
first_name: 'Unknown',
|
||||
last_name: 'User',
|
||||
|
|
@ -91,10 +94,15 @@
|
|||
$.ajax({
|
||||
type: "GET",
|
||||
url: "/api/sessions/" + sessionId,
|
||||
success: updateSession
|
||||
success: updateSession,
|
||||
error: fetchSessionError
|
||||
});
|
||||
}
|
||||
|
||||
function fetchSessionError() {
|
||||
context.location = '#/home';
|
||||
}
|
||||
|
||||
function beforeHide(data) {
|
||||
// Move joinSession function to this file for ease of finding it?
|
||||
context.JK.leaveMusicSession(sessionId);
|
||||
|
|
@ -198,10 +206,26 @@
|
|||
});
|
||||
}
|
||||
|
||||
var instrumentIcons = {
|
||||
"keyboard": "content/icon_instrument_keyboard45.png",
|
||||
"electric guitar": "content/icon_instrument_guitar45.png",
|
||||
"bass guitar": "content/icon_instrument_guitar45.png",
|
||||
"voice": "content/icon_instrument_vocal45.png"
|
||||
};
|
||||
|
||||
function _instrumentIconFromId(id) {
|
||||
if (id in instrumentIcons) {
|
||||
return instrumentIcons[id];
|
||||
}
|
||||
// return default instrument for any unknowns
|
||||
return "content/icon_instrument_default45.png";
|
||||
}
|
||||
|
||||
function _renderTracks() {
|
||||
$.each(mixers, function(index, mixer) {
|
||||
// Only handle local music input and peer music here.
|
||||
if (mixer.group_id === 2 || mixer.group_id === 7) {
|
||||
var myTrack = (mixer.group_id === 2);
|
||||
var participant = _participantForClientId(mixer.client_id);
|
||||
if (!(participant)) {
|
||||
participant = defaultParticipant;
|
||||
|
|
@ -210,18 +234,32 @@
|
|||
if (!(name)) {
|
||||
name = participant.user.first_name + ' ' + participant.user.last_name;
|
||||
}
|
||||
var instrumentIcon = _instrumentIconFromId(participant.tracks[0].instrument_id);
|
||||
var photoUrl = participant.user.photo_url;
|
||||
if (!(photoUrl)) {
|
||||
photoUrl = "/assets/shared/avatar_default.jpg";
|
||||
}
|
||||
var gainPercent = percentFromMixerValue(
|
||||
mixer.range_low, mixer.range_high, mixer.volume_left);
|
||||
var muteClass = "enabled";
|
||||
if (mixer.mute) {
|
||||
muteClass = "muted";
|
||||
}
|
||||
var trackData = {
|
||||
clientId: mixer.client_id,
|
||||
name: name,
|
||||
part: "Keyboard", // TODO - need this
|
||||
avatar: participant.user.photo_url,
|
||||
instrumentIcon: instrumentIcon,
|
||||
avatar: photoUrl,
|
||||
latency: "good",
|
||||
vu: 0.0,
|
||||
gain: 0.5,
|
||||
mute: false,
|
||||
gainPercent: gainPercent,
|
||||
muteClass: muteClass,
|
||||
mixerId: mixer.id
|
||||
};
|
||||
_addTrack(trackData);
|
||||
// Show settings icons only for my tracks
|
||||
if (myTrack) {
|
||||
$('div[mixer-id="' + mixer.id + '"].track-icon-settings').show();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -339,17 +377,16 @@
|
|||
}
|
||||
|
||||
function toggleMute(evt) {
|
||||
logger.debug('toggleMute');
|
||||
var $control = $(evt.currentTarget);
|
||||
var mixerId = $control.attr('mixer-id');
|
||||
currentMixerId = mixerId;
|
||||
fillTrackVolumeObject(currentMixerId);
|
||||
var muting = ($control.hasClass('enabled'));
|
||||
_toggleVisualMuteControl($control, muting);
|
||||
_toggleAudioMute(mixerId, muting);
|
||||
}
|
||||
|
||||
// TODO rename to getVerticalFaderPercent
|
||||
function getFaderPercent(eventY, $fader) {
|
||||
function getVerticalFaderPercent(eventY, $fader) {
|
||||
var faderPosition = $fader.offset();
|
||||
var faderHeight = $fader.height();
|
||||
var handleValue = faderHeight - (eventY - faderPosition.top);
|
||||
|
|
@ -363,7 +400,6 @@
|
|||
return faderPct;
|
||||
}
|
||||
|
||||
// TODO rename to getHorizontalFaderPercent
|
||||
function getHorizontalFaderPercent(eventX, $fader) {
|
||||
var faderPosition = $fader.offset();
|
||||
var faderWidth = $fader.width();
|
||||
|
|
@ -399,8 +435,32 @@
|
|||
}
|
||||
}
|
||||
|
||||
// Given a mixer's min/max and current value, return it as
|
||||
// a percent from 0-100. Return an integer.
|
||||
function percentFromMixerValue(min, max, value) {
|
||||
var range = Math.abs(max - min);
|
||||
var magnitude = value - min;
|
||||
var percent = Math.round(100*(magnitude/range));
|
||||
return percent;
|
||||
}
|
||||
|
||||
// Given a volumne percent (0-100), set the underlying
|
||||
// Given a mixer's min/max and a percent value, return it as
|
||||
// the mixer's value. Returns an integer.
|
||||
function percentToMixerValue(min, max, percent) {
|
||||
var range = Math.abs(max - min);
|
||||
var multiplier = percent/100; // Change 85 into 0.85
|
||||
var value = min + (multiplier * range);
|
||||
// Protect against percents < 0 and > 100
|
||||
if (value < min) {
|
||||
value = min;
|
||||
}
|
||||
if (value > max) {
|
||||
value = max;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
// Given a volume percent (0-100), set the underlying
|
||||
// audio volume level of the passed mixerId to the correct
|
||||
// value.
|
||||
function setMixerVolume(mixerId, volumePercent) {
|
||||
|
|
@ -410,9 +470,8 @@
|
|||
// All that needs doing is to translate the incoming percent
|
||||
// into the real value ont the sliders range. Set Left/Right
|
||||
// volumes on trackVolumeObject, and call SetControlState to stick.
|
||||
var sliderRange = currentMixerRangeMax - currentMixerRangeMin;
|
||||
volumePercent = volumePercent/100;
|
||||
var sliderValue = currentMixerRangeMin + (volumePercent * sliderRange);
|
||||
var sliderValue = percentToMixerValue(
|
||||
currentMixerRangeMin, currentMixerRangeMax, volumePercent);
|
||||
context.trackVolumeObject.volL = sliderValue;
|
||||
context.trackVolumeObject.volR = sliderValue;
|
||||
context.jamClient.SessionSetControlState(mixerId);
|
||||
|
|
@ -486,7 +545,7 @@
|
|||
return false;
|
||||
}
|
||||
evt.stopPropagation();
|
||||
var faderPct = getFaderPercent(evt.clientY, $draggingFader);
|
||||
var faderPct = getVerticalFaderPercent(evt.clientY, $draggingFader);
|
||||
setMixerVolume(currentMixerId, faderPct);
|
||||
if (faderPct > 90) { faderPct = 90; } // Visual limit
|
||||
$draggingFaderHandle.css('bottom', faderPct + '%');
|
||||
|
|
@ -531,7 +590,7 @@
|
|||
}
|
||||
var $fader = $(evt.currentTarget);
|
||||
var $handle = $fader.find('div[control="fader-handle"]');
|
||||
var faderPct = getFaderPercent(evt.clientY, $fader);
|
||||
var faderPct = getVerticalFaderPercent(evt.clientY, $fader);
|
||||
var mixerId = $fader.closest('[mixer-id]').attr('mixer-id');
|
||||
fillTrackVolumeObject(mixerId);
|
||||
setMixerVolume(mixerId, faderPct);
|
||||
|
|
@ -575,8 +634,6 @@
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function events() {
|
||||
$('#session-contents').on("click", '[action="delete"]', deleteSession);
|
||||
$('#tracks').on('click', 'div[control="mute"]', toggleMute);
|
||||
|
|
@ -592,7 +649,6 @@
|
|||
|
||||
// Go ahead and wire up voice-chat events, although it won't be visible
|
||||
// (and can't fire events) unless the user has a voice chat mixer
|
||||
$('#voice-chat').on('click', 'div[control="mute"]', toggleMute);
|
||||
$('#voice-chat').on('click', 'div[control="fader"]', voiceChatClick);
|
||||
$('#voice-chat').on('mousedown', 'div[control="fader-handle"]', chatHandleDown);
|
||||
$('#voice-chat').on('mousemove', chatMouseMove);
|
||||
|
|
|
|||
|
|
@ -57,11 +57,17 @@
|
|||
}
|
||||
sessionPingsOut[session.id]++;
|
||||
var jsFunction = "JK.Callbacks.clientPingResponse";
|
||||
jamClient.TestLatency(clientID, jsFunction);
|
||||
var timeoutFunction = "JK.Callbacks.clientPingTimeout";
|
||||
|
||||
logger.log('jamClient.connected = ' + jamClient.connected);
|
||||
logger.log('Testing latency for ' + clientID);
|
||||
jamClient.TestLatency(clientID, jsFunction, timeoutFunction);
|
||||
});
|
||||
}
|
||||
|
||||
function clientPingResponse(response) {
|
||||
logger.debug("clientPingResponse");
|
||||
logger.debug(response);
|
||||
var sessionId = clientsToSessions[response.clientID];
|
||||
sessionPingsOut[sessionId]--;
|
||||
updateSessionLatency(sessionId, response);
|
||||
|
|
@ -72,6 +78,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
function clientPingTimeout(clientId) {
|
||||
logger.warn("TIMEOUT during client ping:" + clientId);
|
||||
logger.warn("calling clientPingResponse directly with 1,000 MS latency");
|
||||
var response = { clientID: clientId, latency: 1000 };
|
||||
clientPingResponse(response);
|
||||
}
|
||||
|
||||
function updateSessionLatency(sessionId, latencyResponse) {
|
||||
ensureSessionLatencyEntry(sessionId);
|
||||
var sl = sessionLatency[sessionId];
|
||||
|
|
@ -116,10 +129,12 @@
|
|||
this.getSortScore = getSortScore;
|
||||
this.subscribe = subscribe;
|
||||
this.clientPingResponse = clientPingResponse;
|
||||
this.clientPingTimeout = clientPingTimeout;
|
||||
|
||||
// Register clientPingResponse on this instance as a static function
|
||||
// so that the JavascriptBridge native code can invoke it with a string.
|
||||
context.JK.Callbacks.makeStatic("clientPingResponse", this.clientPingResponse, this);
|
||||
context.JK.Callbacks.makeStatic("clientPingTimeout", this.clientPingTimeout, this);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
context.JK = context.JK || {};
|
||||
context.JK.SessionList = function(app) {
|
||||
var logger = context.JK.logger;
|
||||
var LATENCY = {
|
||||
GOOD : {description: "GOOD", min: 0.0, max: 100.0},
|
||||
MEDIUM : {description: "MEDIUM", min: 100.0, max: 200.0},
|
||||
|
|
@ -15,6 +16,8 @@
|
|||
MUSICIANS_ONLY:"Musicians Only"
|
||||
};
|
||||
|
||||
// JW: TODO - I'm building a similar map in session.js
|
||||
// At somepoint, we should refactor to somewhere we can share.
|
||||
var instrument_logo_map = { "accordion": '',
|
||||
"acoustic guitar": '',
|
||||
"banjo": '',
|
||||
|
|
@ -39,10 +42,9 @@
|
|||
"viola": '',
|
||||
"violin": '',
|
||||
"voice": '../assets/content/icon_instrument_vocal24.png'
|
||||
}
|
||||
};
|
||||
|
||||
var _logger = context.JK.logger;
|
||||
var _sessionLatency;
|
||||
|
||||
/**
|
||||
* Render a single session line into the table.
|
||||
|
|
@ -91,12 +93,13 @@
|
|||
|
||||
var id = participant.user.id;
|
||||
var name = participant.user.name;
|
||||
var photoUrl = participant.user.photo_url ? participant.user.photo_url : "/assets/shared/avatar_default.jpg";
|
||||
var musicianVals = {
|
||||
avatar_url: participant.user.photo_url,
|
||||
avatar_url: photoUrl,
|
||||
profile_url: "users/" + id,
|
||||
musician_name: name,
|
||||
instruments: instrumentLogoHtml
|
||||
}
|
||||
};
|
||||
|
||||
var musician = {};
|
||||
musician.id = id;
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@
|
|||
color:#ccc;
|
||||
border-bottom: dotted 1px #444;
|
||||
overflow-x:hidden;
|
||||
white-space:nowrap;
|
||||
}
|
||||
|
||||
.create-session-left {
|
||||
|
|
@ -97,12 +98,13 @@
|
|||
font-size:24px;
|
||||
}
|
||||
|
||||
.content-wrapper select, .content-wrapper textarea, .content-wrapper input[type=text], div.friendbox, .ftue-inner input[type=text], .ftue-inner input[type=password] {
|
||||
.content-wrapper select, .content-wrapper textarea, .content-wrapper input[type=text], div.friendbox, .ftue-inner input[type=text], .ftue-inner input[type=password], .dialog-inner textarea, .dialog-inner input[type=text] {
|
||||
font-family:"Raleway", arial, sans-serif;
|
||||
background-color:#c5c5c5;
|
||||
border:none;
|
||||
-webkit-box-shadow: inset 2px 2px 3px 0px #888;
|
||||
box-shadow: inset 2px 2px 3px 0px #888;
|
||||
color:#333;
|
||||
color:#666;
|
||||
}
|
||||
|
||||
.create-session-description {
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
font-size:11px;
|
||||
width:auto;
|
||||
display:block;
|
||||
white-space:normal;
|
||||
}
|
||||
|
||||
div.friendbox {
|
||||
|
|
|
|||
|
|
@ -121,8 +121,24 @@ input[type="button"] {
|
|||
}
|
||||
|
||||
.curtain {
|
||||
background-color: shade($color7, 10%);
|
||||
background-color: $ColorScreenBackground;
|
||||
position:absolute;
|
||||
top:0px;
|
||||
left:0px;
|
||||
}
|
||||
.curtain .splash {
|
||||
position:absolute;
|
||||
left:50%;
|
||||
top:50%;
|
||||
margin-top:-100px;
|
||||
margin-left:-125px;
|
||||
}
|
||||
.curtain .splash img {}
|
||||
.curtain .splash p {
|
||||
width: 100%;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.dialog-overlay {
|
||||
background-color: #000;
|
||||
@include opacity(0.8);
|
||||
|
|
|
|||
|
|
@ -40,6 +40,11 @@
|
|||
color:#666;
|
||||
}
|
||||
|
||||
#tracks {
|
||||
margin-top:12px;
|
||||
overflow:auto;
|
||||
}
|
||||
|
||||
.track-empty a {
|
||||
color:#aaa;
|
||||
}
|
||||
|
|
@ -78,6 +83,7 @@ table.vu td {
|
|||
|
||||
.track-label {
|
||||
position: absolute;
|
||||
text-align:center;
|
||||
width: 55px;
|
||||
max-width: 55px;
|
||||
white-space:normal;
|
||||
|
|
@ -104,14 +110,14 @@ table.vu td {
|
|||
.master-volume-label {
|
||||
font-size:12px;
|
||||
position:absolute;
|
||||
left: 210px;
|
||||
top: 15px;
|
||||
left: 226px;
|
||||
top: 16px;
|
||||
}
|
||||
|
||||
#volume {
|
||||
position:absolute;
|
||||
top: 15px;
|
||||
left: 264px;
|
||||
left: 284px;
|
||||
width: 60px;
|
||||
height: 24px;
|
||||
font-size:12px;
|
||||
|
|
@ -174,6 +180,10 @@ table.vu td {
|
|||
text-decoration: none;
|
||||
}
|
||||
|
||||
.session-add a img {
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.session-recording-name-wrapper {
|
||||
position:relative;
|
||||
white-space:nowrap;
|
||||
|
|
@ -499,6 +509,14 @@ table.vu td {
|
|||
background-repeat:no-repeat;
|
||||
}
|
||||
|
||||
.voicechat-mute.muted {
|
||||
background-position: 0px 0px;
|
||||
}
|
||||
.voicechat-mute.enabled {
|
||||
background-position: -20px 0px;
|
||||
}
|
||||
|
||||
|
||||
.voicechat-settings {
|
||||
position:absolute;
|
||||
top:4px;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
object @connection
|
||||
|
||||
attributes :ip_address, :client_id
|
||||
attribute :aasm_state => :connection_state
|
||||
|
||||
node(:user_id, :if => lambda { |connection| connection.user.friends?(current_user) }) do |connection|
|
||||
connection.user_id
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ child(:connections => :participants) {
|
|||
attributes :ip_address, :client_id
|
||||
|
||||
node :user do |connection|
|
||||
{ :id => connection.user.id, :photo_url => connection.user.photo_url, :name => connection.user.name, :is_friend => connection.user.friends?(current_user) }
|
||||
{ :id => connection.user.id, :photo_url => connection.user.photo_url, :name => connection.user.name, :is_friend => connection.user.friends?(current_user), :connection_state => connection.aasm_state }
|
||||
end
|
||||
|
||||
child(:tracks => :tracks) {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
SETTINGS
|
||||
</a>
|
||||
<a class="button-grey left" href="#">
|
||||
<%= image_tag "content/icon_share.png", {:align => "texttop"} %>
|
||||
<%= image_tag "content/icon_share.png", {:align => "texttop", :height => 12, :width => 12} %>
|
||||
SHARE
|
||||
</a>
|
||||
<div class="master-volume-label">VOLUME</div>
|
||||
|
|
@ -140,26 +140,25 @@
|
|||
</div>
|
||||
<!-- TODO - use user's avatar as curly param -->
|
||||
<div class="avatar-med">
|
||||
<%= image_tag "shared/avatar_jonathon.png", {:width => 246, :height => 246} %>
|
||||
<img src="{avatar}"/>
|
||||
</div>
|
||||
<!-- TODO - use track instrument as curly param -->
|
||||
<div class="track-instrument">
|
||||
<%= image_tag "content/icon_instrument_guitar45.png",
|
||||
{:width => 45, :height => 45} %>
|
||||
<img src="/assets/{instrumentIcon}" width="45" height="45"/>
|
||||
</div>
|
||||
<div class="track-gain" mixer-id="{mixerId}">
|
||||
<div class="track-gain-wrapper" control="fader">
|
||||
<div class="track-gain-slider" style="bottom:0%;" control="fader-handle">
|
||||
<div class="track-gain-slider" style="bottom:{gainPercent}%;" control="fader-handle">
|
||||
<%= image_tag "content/slider_gain_vertical.png",
|
||||
{:width => 28, :height => 11} %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="track-icon-mute enabled"
|
||||
<div class="track-icon-mute {muteClass}"
|
||||
control="mute"
|
||||
mixer-id="{mixerId}">
|
||||
</div>
|
||||
<div class="track-icon-settings">
|
||||
<div class="track-icon-settings" style="display:none;" mixer-id="{mixerId}">
|
||||
<%= image_tag "content/icon_settings_lg.png",
|
||||
{:width => 18, :height => 18} %>
|
||||
</div>
|
||||
|
|
@ -211,38 +210,3 @@
|
|||
</tr>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-voicechat">
|
||||
<!-- voice chat box -->
|
||||
<div class="voicechat">
|
||||
<div class="voicechat-label">CHAT</div>
|
||||
<!-- voice chat gain -->
|
||||
<div class="voicechat-gain">
|
||||
<div class="voicechat-gain-wrapper">
|
||||
<!-- voice chat gain slider -->
|
||||
<div class="voicechat-gain-slider">
|
||||
<%= image_tag "content/slider_gain_horiz.png", {:width => 10, :height => 18} %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- mute icon -->
|
||||
<div class="voicechat-mute">
|
||||
<%= image_tag "content/icon_mute.png", {:width => 20, :height => 18} %>
|
||||
</div>
|
||||
<!-- settings icon -->
|
||||
<div class="voicechat-settings">
|
||||
<%= image_tag "content/sicon_settings_lg.png", {:width => 18, :height => 18} %>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end voice chat -->
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="template-makerecording">
|
||||
<!-- make a recording -->
|
||||
<div class="recording">
|
||||
<a href="#">
|
||||
<img src="images/content/recordbutton-off.png" width="20" height="20" align="absmiddle" /> Make a Recording</a>
|
||||
|
||||
|
||||
</div>
|
||||
<!-- end make a recording -->
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
<div class="curtain" style="width:100%; height:100%; z-index:9999; background-color:#ffffff;"></div>
|
||||
<div class="curtain" style="width:100%; height:100%; z-index:9999;">
|
||||
<div class="splash">
|
||||
<img src="assets/header/logo.png"/>
|
||||
<p>Connecting...</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dialog-overlay" style="display:none; width:100%; height:100%; z-index:99;"></div>
|
||||
|
||||
<%= render "footer" %>
|
||||
|
|
@ -30,7 +35,7 @@
|
|||
// but in any other mode, just trust the config coming through gon
|
||||
JK.websocket_gateway_uri = gon.websocket_gateway_uri
|
||||
<% end %>
|
||||
console.debug("websocket_gateway_uri:" + JK.websocket_gateway_uri);
|
||||
if (console) { console.debug("websocket_gateway_uri:" + JK.websocket_gateway_uri); }
|
||||
|
||||
// If no jamClient (when not running in native client)
|
||||
// create a fake one.
|
||||
|
|
@ -60,42 +65,59 @@
|
|||
JK.currentUserId = null;
|
||||
<% end %>
|
||||
|
||||
if (JK.currentUserId) {
|
||||
// Some things can't be initialized until we're connected. Put them here.
|
||||
function _initAfterConnect() {
|
||||
|
||||
var jk = JK.JamKazam();
|
||||
jk.initialize();
|
||||
|
||||
var jam_server = JK.JamServer;
|
||||
jam_server.connect();
|
||||
|
||||
var header = new JK.Header(jk);
|
||||
var header = new JK.Header(JK.app);
|
||||
header.initialize();
|
||||
|
||||
var homeScreen = new JK.HomeScreen(jk);
|
||||
var homeScreen = new JK.HomeScreen(JK.app);
|
||||
homeScreen.initialize();
|
||||
|
||||
var createSessionScreen = new JK.CreateSessionScreen(jk);
|
||||
var createSessionScreen = new JK.CreateSessionScreen(JK.app);
|
||||
createSessionScreen.initialize();
|
||||
|
||||
var findSessionScreen = new JK.FindSessionScreen(jk);
|
||||
var findSessionScreen = new JK.FindSessionScreen(JK.app);
|
||||
var sessionLatency = null;
|
||||
if ("jamClient" in window) {
|
||||
sessionLatency = new JK.SessionLatency(window.jamClient);
|
||||
}
|
||||
findSessionScreen.initialize(sessionLatency);
|
||||
|
||||
var sessionScreen = new JK.SessionScreen(jk);
|
||||
var sessionScreen = new JK.SessionScreen(JK.app);
|
||||
sessionScreen.initialize();
|
||||
|
||||
var ftueAudioSelectionScreen = new JK.FtueAudioSelectionScreen(jk);
|
||||
var ftueAudioSelectionScreen = new JK.FtueAudioSelectionScreen(JK.app);
|
||||
ftueAudioSelectionScreen.initialize();
|
||||
|
||||
var ftueAudioTestingScreen = new JK.FtueAudioTestingScreen(jk);
|
||||
var ftueAudioTestingScreen = new JK.FtueAudioTestingScreen(JK.app);
|
||||
ftueAudioTestingScreen.initialize();
|
||||
|
||||
var testBridgeScreen = new JK.TestBridgeScreen(jk);
|
||||
var testBridgeScreen = new JK.TestBridgeScreen(JK.app);
|
||||
testBridgeScreen.initialize();
|
||||
|
||||
JK.app.initialRouting();
|
||||
JK.hideCurtain(300);
|
||||
|
||||
}
|
||||
|
||||
// Let's get things rolling...
|
||||
if (JK.currentUserId) {
|
||||
JK.JamServer.connect(); // singleton here defined in JamServer.js
|
||||
JK.app = JK.JamKazam();
|
||||
JK.app.initialize();
|
||||
|
||||
// Run a check to see if we're logged in yet. Only after that should
|
||||
// we initialize the other screens.
|
||||
function testConnected() {
|
||||
if (JK.clientId) {
|
||||
_initAfterConnect();
|
||||
} else {
|
||||
window.setTimeout(testConnected, 100);
|
||||
}
|
||||
}
|
||||
testConnected();
|
||||
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -88,7 +88,8 @@ module SampleApp
|
|||
|
||||
# Websocket-gateway embedded configs
|
||||
config.websocket_gateway_enable = false
|
||||
config.websocket_gateway_max_stale_connection_time = 1800
|
||||
config.websocket_gateway_connect_time_stale = 30
|
||||
config.websocket_gateway_connect_time_expire = 180
|
||||
config.websocket_gateway_internal_debug = false
|
||||
config.websocket_gateway_port = 6767
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,8 @@ SampleApp::Application.configure do
|
|||
|
||||
# Websocket-gateway embedded configs
|
||||
config.websocket_gateway_enable = true
|
||||
config.websocket_gateway_max_stale_connection_time = 30
|
||||
config.websocket_gateway_connect_time_stale = 30
|
||||
config.websocket_gateway_connect_time_expire = 180
|
||||
config.websocket_gateway_internal_debug = false
|
||||
config.websocket_gateway_port = 6777
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ module JamWebEventMachine
|
|||
end
|
||||
|
||||
def self.die_gracefully_on_signal
|
||||
Rails.logger.debug("*** die_gracefully_on_signal")
|
||||
Signal.trap("INT") { EM.stop }
|
||||
Signal.trap("TERM") { EM.stop }
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,5 +2,6 @@ if Rails.application.config.websocket_gateway_enable
|
|||
|
||||
JamWebsockets::Server.new.run :port => Rails.application.config.websocket_gateway_port,
|
||||
:emwebsocket_debug => Rails.application.config.websocket_gateway_internal_debug,
|
||||
:max_stale_connection_time => Rails.application.config.websocket_gateway_max_stale_connection_time
|
||||
end
|
||||
:connect_time_stale => Rails.application.config.websocket_gateway_connect_time_stale,
|
||||
:connect_time_expire => Rails.application.config.websocket_gateway_connect_time_expire
|
||||
end
|
||||
|
|
|
|||
|
|
@ -14,6 +14,11 @@ module LoginHelper
|
|||
context.fill_in 'Password', :with => user.password
|
||||
context.click_button 'SIGN IN'
|
||||
|
||||
# There are delays in the main app due to us waiting until we're connected to
|
||||
# the websocket gateway. Tough to test, but adding a sleep to see if this
|
||||
# gets us past it.
|
||||
sleep 4
|
||||
|
||||
# verify that the client page is showing
|
||||
context.find("h1:contains('Audio Gear Setup')").should be_visible
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue