Merge branch 'develop' into musicians_page

This commit is contained in:
Jonathan Kolyer 2013-10-26 16:03:47 -05:00
commit fd04b3a7b5
135 changed files with 3004 additions and 1251 deletions

View File

@ -73,3 +73,4 @@ crash_dumps.sql
crash_dumps_idx.sql
music_sessions_user_history_add_session_removed_at.sql
user_progress_tracking.sql
whats_next.sql

1
db/up/whats_next.sql Normal file
View File

@ -0,0 +1 @@
ALTER TABLE users ADD COLUMN show_whats_next boolean DEFAULT TRUE;

View File

@ -124,6 +124,7 @@ module JamRuby
validates :terms_of_service, :acceptance => {:accept => true, :on => :create, :allow_nil => false }
validates :subscribe_email, :inclusion => {:in => [nil, true, false]}
validates :musician, :inclusion => {:in => [true, false]}
validates :show_whats_next, :inclusion => {:in => [nil, true, false]}
# custom validators
validate :validate_musician_instruments
@ -651,7 +652,7 @@ module JamRuby
# throws ActiveRecord::RecordNotFound if instrument is invalid
# throws an email delivery error if unable to connect out to SMTP
def self.signup(first_name, last_name, email, password, password_confirmation, terms_of_service, subscribe_email,
def self.signup(first_name, last_name, email, password, password_confirmation, terms_of_service,
location, instruments, birth_date, musician, photo_url, invited_user, signup_confirm_url)
user = User.new
@ -659,7 +660,7 @@ module JamRuby
user.first_name = first_name
user.last_name = last_name
user.email = email
user.subscribe_email = subscribe_email
user.subscribe_email = true
user.terms_of_service = terms_of_service
user.musician = musician

View File

@ -88,14 +88,13 @@ end
gem 'capybara-screenshot'
gem 'cucumber-rails', :require => false #, '1.3.0', :require => false
gem 'factory_girl_rails', '4.1.0'
gem 'database_cleaner', '0.7.0'
gem 'guard-spork', '0.3.2'
gem 'spork', '0.9.0'
gem 'launchy', '2.1.0'
gem 'rack-test'
# gem 'rb-fsevent', '0.9.1', :require => false
# gem 'growl', '1.0.3'
gem 'poltergeist' , '1.4.1' # can't go to 1.4.0 until this is fixed https://github.com/jonleighton/poltergeist/issues/385
gem 'poltergeist'
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 808 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 744 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 486 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@ -91,12 +91,12 @@
function navToEditIdentity() {
resetForm()
window.location = '#/account/identity'
window.location = '/client#/account/identity'
}
function navToEditProfile() {
resetForm()
window.location = '#/account/profile'
window.location = '/client#/account/profile'
}
function navToEditSubscriptions() {
@ -109,7 +109,7 @@
function navToEditAudio() {
resetForm()
window.location = "#/account/audio"
window.location = "/client#/account/audio"
}
// handle update avatar event

View File

@ -74,7 +74,7 @@
function navToAccount() {
resetForm();
window.location = '#/account';
window.location = '/client#/account';
}
function handleUpdateEmail() {

View File

@ -38,7 +38,8 @@
last_name: userDetail.last_name,
user_instruments: userDetail.instruments,
birth_date : userDetail.birth_date,
gender: userDetail.gender
gender: userDetail.gender,
subscribe_email: userDetail.subscribe_email ? "checked=checked" : ""
});
var content_root = $('#account-profile-content-scroller')
@ -263,12 +264,12 @@
function navToAccount() {
resetForm();
window.location = '#/account';
window.location = '/client#/account';
}
function navToAvatar() {
resetForm();
window.location = '#/account/profile/avatar';
window.location = '/client#/account/profile/avatar';
}
function handleUpdateProfile() {
@ -280,11 +281,12 @@
var city = getCityElement().val();
var firstName = getFirstNameElement().val();
var lastName = getLastNameElement().val();
var gender = getGenderElement().val()
var gender = getGenderElement().val();
var subscribeEmail = getSubscribeEmail().is(':checked');
var birthDate = getBirthDate();
var instruments = getInstrumentsValue();
postUpdateProfile({
api.updateUser({
country: country,
state: region,
city: city,
@ -292,25 +294,13 @@
last_name: lastName,
gender: gender,
birth_date: birthDate,
instruments: instruments
instruments: instruments,
subscribe_email: subscribeEmail
})
.done(postUpdateProfileSuccess)
.fail(postUpdateProfileFailure)
}
function postUpdateProfile(options) {
var url = "/api/users/" + context.JK.currentUserId;
return $.ajax({
type: "POST",
dataType: "json",
contentType: 'application/json',
url: url,
data: JSON.stringify(options),
processData: false
});
}
function postUpdateProfileSuccess(response) {
app.notify(
{ title: "Profile Changed",
@ -332,6 +322,7 @@
var city = context.JK.format_errors("city", errors);
var birth_date = context.JK.format_errors("birth_date", errors);
var gender = context.JK.format_errors("birth_date", errors);
var subscribeEmail = context.JK.format_errors("subscribe_email", errors);
var instruments = context.JK.format_errors("musician_instruments", errors)
if(first_name != null) {
@ -358,6 +349,10 @@
getYearElement().closest('div.field').addClass('error').end().after(birth_date);
}
if(subscribeEmail != null) {
getSubscribeEmail().closest('div.field').addClass('error').end().after(subscribeEmail);
}
if(gender != null) {
getGenderElement().closest('div.field').addClass('error').end().after(gender);
}
@ -480,6 +475,10 @@
return $('#account-profile-content-scroller select#user_birth_date_1i');
}
function getSubscribeEmail() {
return $('#account-profile-content-scroller input[name=subscribe_email]');
}
function getInstrumentsElement() {
return $('#account-profile-content-scroller .instrument_selector');
}

View File

@ -15,6 +15,7 @@
var selection = null;
var targetCropSize = 88;
var updatingAvatar = false;
var userDropdown;
function beforeShow(data) {
userId = data.id;
@ -92,7 +93,7 @@
function deleteAvatarSuccess(response) {
renderAvatar(null, null);
JK.Header.loadMe();
userDropdown.loadMe();
rest.getUserDetail()
.done(function(userDetail) {
@ -139,7 +140,7 @@
function navToEditProfile() {
resetForm();
window.location = '#/account/profile'
window.location = '/client#/account/profile'
}
function renderAvatarSpinner() {
@ -306,8 +307,9 @@
quality: 90,
policy: filepickerPolicy.policy,
signature: filepickerPolicy.signature
}, { path: createStorePath(self.userDetail) + 'cropped.jpg', access: 'public' },
}, { path: createStorePath(self.userDetail) + 'cropped-' + new Date().getTime() + '.jpg', access: 'public' },
function(cropped) {
logger.debug("converting cropped");
rest.getFilepickerPolicy({handle: cropped.url, convert: true})
.done(function(filepickerPolicy) {
filepicker.convert(cropped, {
@ -320,6 +322,7 @@
signature: filepickerPolicy.signature
}, { path: createStorePath(self.userDetail), access: 'public' },
function(scaled) {
logger.debug("converted and scaled final image %o", scaled);
rest.updateAvatar({
original_fpfile: determineCurrentFpfile(),
cropped_fpfile: scaled,
@ -361,7 +364,7 @@
self.userDetail = response;
// notify any listeners that the avatar changed
JK.Header.loadMe();
userDropdown.loadMe();
// $('.avatar_large img').trigger('avatar_changed', [self.userDetail.photo_url]);
app.notify(
@ -414,13 +417,15 @@
return $.cookie('original_fpfile') == null ? userDetail.crop_selection : null;
}
function initialize() {
function initialize(userDropdownInstance) {
var screenBindings = {
'beforeShow': beforeShow,
'afterShow': afterShow
};
app.bindScreen('account/profile/avatar', screenBindings);
events();
userDropdown = userDropdownInstance;
}
this.initialize = initialize;

View File

@ -14,7 +14,6 @@
// ON TOP OF OTHER DIALOGS. ANY OTHER DIALOGS THAT
// USE THIS NEED TO BE ADDED TO THE FOLLOWING LIST.
// NEED TO FIGURE OUT A CLEANER WAY TO HANDLE THIS.
app.layout.closeDialog('add-track');
app.layout.closeDialog('configure-audio');
});

View File

@ -12,10 +12,10 @@
//
//= require jquery
//= require jquery_ujs
//= require jquery.icheck
//= require jquery.color
//= require jquery.cookie
//= require jquery.Jcrop
//= require jquery.naturalsize
//= require jquery.queryparams
//= require bootstrap
//= require_directory .

View File

@ -41,17 +41,17 @@
var originalVoiceChat;
var configure_audio_instructions = {
"Win32": "Choose the audio profile you would like to use for this session. If needed, use arrow buttons to assign audio inputs " +
"Win32": "Choose the audio device you would like to use for this session. If needed, use arrow buttons to assign audio inputs " +
"to your tracks, to indicate what instrument you are playing on each track, and to assign audio outputs for listening. " +
"If you want to use a new audio device you have not tested/certified for latency using JamKazam, click the Add New Audio " +
"Gear button to test that device.",
"MacOSX": "Choose the audio profile you would like to use for this session. If needed, use arrow buttons to assign audio inputs " +
"MacOSX": "Choose the audio device you would like to use for this session. If needed, use arrow buttons to assign audio inputs " +
"to your tracks, to indicate what instrument you are playing on each track, and to assign audio outputs for listening. " +
"If you want to use a new audio device you have not tested/certified for latency using JamKazam, click the Add New Audio " +
"Gear button to test that device.",
"Unix": "Choose the audio profile you would like to use for this session. If needed, use arrow buttons to assign audio inputs " +
"Unix": "Choose the audio device you would like to use for this session. If needed, use arrow buttons to assign audio inputs " +
"to your tracks, to indicate what instrument you are playing on each track, and to assign audio outputs for listening. " +
"If you want to use a new audio device you have not tested/certified for latency using JamKazam, click the Add New Audio " +
"Gear button to test that device."
@ -61,25 +61,6 @@
"for both music and chat. Otherwise, choose a device to use for voice chat, and use arrow buttons to " +
"select an input on that device.";
function toggleTrack2ConfigDetails(visible) {
if (visible) {
$('#track2-details').show();
$('#track2-input-buttons').show();
$('#track1-input').height('92px');
$('#track1-instrument').height('92px');
$('#track1-input-buttons').addClass('mt30');
$('#track1-input-buttons').removeClass('mt65');
}
else {
$('#track2-details').hide();
$('#track2-input-buttons').hide();
$('#track1-input').height('195px');
$('#track1-instrument').height('195px');
$('#track1-input-buttons').addClass('mt65');
$('#track1-input-buttons').removeClass('mt30');
}
}
function events() {
// Music Audio Tab
@ -425,15 +406,12 @@
context.JK.loadOptions($('#template-option').html(), $('#track1-instrument'), instrument_array, "id", "description", current_instrument);
// load Track 2 config details if necessary
if (myTrackCount > 1) {
// load Track 2 Input(s)
context.JK.loadOptions($('#template-option').html(), $('#track2-input'), track2AudioInputChannels, "id", "name", -1);
// load Track 2 Input(s)
context.JK.loadOptions($('#template-option').html(), $('#track2-input'), track2AudioInputChannels, "id", "name", -1);
// load Track 2 Instrument
current_instrument = context.jamClient.TrackGetInstrument(ASSIGNMENT.TRACK2);
context.JK.loadOptions($('#template-option').html(), $('#track2-instrument'), instrument_array, "id", "description", current_instrument);
}
// load Track 2 Instrument
current_instrument = context.jamClient.TrackGetInstrument(ASSIGNMENT.TRACK2);
context.JK.loadOptions($('#template-option').html(), $('#track2-instrument'), instrument_array, "id", "description", current_instrument);
// load Unused Outputs
context.JK.loadOptions($('#template-option').html(), $('#audio-output-unused'), outputUnassignedList, "id", "name", -1);
@ -614,29 +592,52 @@
context.jamClient.TrackSetInstrument(ASSIGNMENT.TRACK1, instrumentVal);
// UPDATE SERVER
//logger.debug("Updating track " + myTracks[0].trackId + " with instrument " + instrumentText);
logger.debug("Updating track " + myTracks[0].trackId + " with instrument " + instrumentText);
var data = {};
data.instrument_id = instrumentText;
sessionModel.updateTrack(sessionId, myTracks[0].trackId, data);
if (myTrackCount > 1) {
// TRACK 2 INPUTS
$('#track2-input > option').each(function() {
logger.debug("Saving track 2 input = " + this.value);
context.jamClient.TrackSetAssignment(this.value, true, ASSIGNMENT.TRACK2);
});
// TRACK 2 INPUTS
var track2Selected = false;
$('#track2-input > option').each(function() {
track2Selected = true;
logger.debug("Saving track 2 input = " + this.value);
context.jamClient.TrackSetAssignment(this.value, true, ASSIGNMENT.TRACK2);
});
if (track2Selected) {
// TRACK 2 INSTRUMENT
instrumentVal = $('#track2-instrument').val();
instrumentText = $('#track2-instrument > option:selected').text().toLowerCase();
// track 2 new - add
if (myTrackCount === 1) {
data = {};
// use the first track's connection_id (not sure why we need this on the track data model)
logger.debug("myTracks[0].connection_id=" + myTracks[0].connection_id);
data.connection_id = myTracks[0].connection_id;
data.instrument_id = instrumentText;
data.sound = "stereo";
sessionModel.addTrack(sessionId, data);
}
// track 2 exists - update
else if (myTrackCount === 2) {
// UPDATE SERVER
logger.debug("Updating track " + myTracks[1].trackId + " with instrument " + instrumentText);
data = {};
data.instrument_id = instrumentText;
sessionModel.updateTrack(sessionId, myTracks[1].trackId, data);
}
logger.debug("Saving track 2 instrument = " + instrumentVal);
context.jamClient.TrackSetInstrument(ASSIGNMENT.TRACK2, instrumentVal);
// UPDATE SERVER
//logger.debug("Updating track " + myTracks[1].trackId + " with instrument " + instrumentText);
data.instrument_id = instrumentText;
sessionModel.updateTrack(sessionId, myTracks[1].trackId, data);
}
else {
// track 2 was removed
if (myTrackCount === 2) {
logger.debug("Deleting track " + myTracks[1].trackId);
sessionModel.deleteTrack(sessionId, myTracks[1].trackId);
}
}
// UNASSIGNED OUTPUTS
@ -695,7 +696,7 @@
function validateAudioSettings(allowEmptyInput) {
var isValid = true;
var noTrackErrMsg = 'You must assign at least one input port to each of your tracks. Please update your settings to correct this. If you want to delete a track, please return to the session screen and delete the track by clicking the "x" box in the upper right-hand corner of the track.';
var noTrackErrMsg = 'You must assign at least one input port to each of your tracks. Please update your settings to correct this.';
var noInstrumentErrMsg = 'You must specify what instrument is being played for each track. Please update your settings to correct this.';
var outputErrMsg = 'You must assign two output ports for stereo session audio to hear music. Please update your settings to correct this.';
@ -723,8 +724,8 @@
logger.debug("validateAudioSettings:myTrackCount=" + myTrackCount);
// if Track 2 exists, verify Input and Instrument exist
if (isValid && myTrackCount > 1) {
if ($('#track2-input > option').size() === 0 || $('#track2-input > option').size() > 2) {
if (isValid) {
if ($('#track2-input > option').size() > 2) {
errMsg = noTrackErrMsg;
isValid = false;
}
@ -834,7 +835,6 @@
_init();
myTrackCount = myTracks.length;
logger.debug("initialize:myTrackCount=" + myTrackCount);
toggleTrack2ConfigDetails(myTrackCount > 1);
};
this.showMusicAudioPanel = showMusicAudioPanel;

View File

@ -7,7 +7,7 @@
var logger = context.JK.logger;
var realtimeMessaging = context.JK.JamServer;
var friendSelectorDialog = new context.JK.FriendSelectorDialog(app, friendSelectorCallback);
var invitationDialog = new context.JK.InvitationDialog(app);
var invitationDialog = null;
var autoComplete = null;
var userNames = [];
var userIds = [];
@ -100,7 +100,7 @@
}
function resetForm() {
$('#intellectual-property').attr('checked', false);
$('#intellectual-property').iCheck('uncheck').attr('checked', false);
var $form = $('#create-session-form');
var description = sessionSettings.hasOwnProperty('description') ? sessionSettings.description : '';
@ -114,7 +114,7 @@
if (musician_access) {
var approval_required = sessionSettings.hasOwnProperty('approval_required') ? sessionSettings.approval_required : false;
$('#musician-access-option-' + approval_required).attr('checked', 'checked');
$('#musician-access-option-' + approval_required).iCheck('check').attr('checked', 'checked');
}
var fan_access = sessionSettings.hasOwnProperty('fan_access') ? sessionSettings.fan_access : true;
@ -123,7 +123,7 @@
if (fan_access) {
var fan_chat = sessionSettings.hasOwnProperty('fan_chat') ? sessionSettings.fan_chat : false;
$('#fan-chat-option-' + fan_chat).attr('checked', 'checked');
$('#fan-chat-option-' + fan_chat).iCheck('check').attr('checked', 'checked');
}
// Should easily be able to grab other items out of sessionSettings and put them into the appropriate ui elements.
}
@ -293,7 +293,7 @@
friendSelectorDialog.showDialog(selectedFriendIds);
});
$('.btn-email-invitation').click(function() {
$('div[layout-id="createSession"] .btn-email-invitation').click(function() {
invitationDialog.showEmailDialog();
});
@ -374,6 +374,15 @@
resetForm();
}
// this exists solely due to a bug in Windows QTWebkit: https://bugreports.qt-project.org/browse/QTBUG-30072
function initializeButtons() {
$('div[layout-id="createSession"] .icheckbuttons input').iCheck({
checkboxClass: 'icheckbox_minimal',
radioClass: 'iradio_minimal',
inheritClass: true
});
}
function searchFriends(query) {
if (query.length < 2) {
$('#friend-search-results').empty();
@ -403,12 +412,13 @@
});
}
function initialize() {
function initialize(invitationDialogInstance) {
friendSelectorDialog.initialize();
invitationDialog.initialize();
invitationDialog = invitationDialogInstance;
events();
loadBands();
loadSessionSettings();
initializeButtons();
var screenBindings = { 'beforeShow': beforeShow, 'afterShow': afterShow };
app.bindScreen('createSession', screenBindings);
}

View File

@ -1,7 +1,7 @@
(function(context,$) {
/**
* Javascript for managing the header (account dropdown) as well
* Javascript for managing the header as well
* as any dialogs reachable from there. Account settings dialog.
*/
@ -17,8 +17,7 @@
var instrumentIds = [];
var instrumentNames = [];
var instrumentPopularities = {}; // id -> popularity
var invitationDialog = new context.JK.InvitationDialog(app);
var rest = new JK.Rest();
function loadInstruments() {
// TODO: This won't work in the long-term. We'll need to provide
@ -98,45 +97,10 @@
context.location = '#/home';
});
$('.userinfo').on('click', function() {
$('ul.shortcuts', this).toggle();
});
$('.userinfo .invite-friends .menuheader').on('click', function(e) {
$(this).closest('li').css('height', 'auto').find('ul').toggle();
e.stopPropagation();
return false;
});
/**
$('.userinfo .sign-out a').on('click', function(e) {
e.stopPropagation();
/** rest.signout()
.done(function() {
})
}); */
$('.invite-friends .google-invite a').on('click', function(e) {
invitationDialog.showGoogleDialog();
});
$('.invite-friends .email-invite a').on('click', function(e) {
invitationDialog.showEmailDialog();
})
$('#account-identity-form').submit(handleIdentitySubmit);
$('#account-profile-form').submit(handleProfileSubmit);
// Remove added instruments when 'X' is clicked
$('#added-profile-instruments').on("click", ".instrument span", removeInvitation);
$('#header-avatar').on('avatar_changed', function(event, newAvatarUrl) {
updateAvatar(newAvatarUrl);
event.preventDefault();
return false;
})
}
function handleIdentitySubmit(evt) {
@ -194,52 +158,12 @@
return false;
}
function loadMe() {
$.ajax({
url: '/api/users/' + context.JK.currentUserId
}).done(function(r) {
userMe = r;
// TODO - Setting global variable for local user.
context.JK.userMe = r;
updateHeader();
}).fail(app.ajaxError);
}
function updateHeader() {
$('#user').html(userMe.name);
showAvatar();
}
// initially show avatar
function showAvatar() {
var photoUrl = context.JK.resolveAvatarUrl(userMe.photo_url);
$('#header-avatar').attr('src', photoUrl);
}
// handle update avatar event
function updateAvatar(avatar_url) {
var photoUrl = context.JK.resolveAvatarUrl(avatar_url);
var avatar = $(new Image());
avatar.attr('src', photoUrl + '?cache_bust=' + new Date().getTime());
avatar.attr('alt', "Avatar");
avatar.attr('id', 'header-avatar');
$('#header-avatar').replaceWith(avatar);
}
this.initialize = function() {
events();
loadInstruments();
loadMe();
invitationDialog.initialize();
//searcher = new context.JK.Searcher(app);
//searcher.initialize();
};
this.loadMe = loadMe;
};
})(window,jQuery);

View File

@ -8,17 +8,6 @@
var isFtueComplete = false;
function beforeShow(data) {
refreshDeviceState();
}
function refreshDeviceState() {
isFtueComplete = checkDeviceState();
updateTiles();
}
function checkDeviceState() {
var devices = context.jamClient.TrackGetDevices();
return Object.keys(devices).length > 0;
}
function mouseenterTile() {
@ -49,19 +38,7 @@
}
function userHasDevices() {
var $createSession = $('div[type="createSession"]');
var $findSession = $('div[type="findSession"]');
$createSession.attr('layout-link', 'createSession');
$findSession.attr('layout-link', 'findSession');
// undo any earlier disabling
$('h2', $createSession).removeClass('disabled');
$('h2', $findSession).removeClass('disabled');
$createSession.removeClass('createsession-disabled');
$createSession.addClass('createsession');
$findSession.removeClass('findsession-disabled');
$findSession.addClass('findsession');
// and enable features
$($createSession).on('mouseenter', mouseenterTile);
@ -97,36 +74,22 @@
// used to initialize things that do not have to be touched up in the same UI sessiion
function events() {
// initialize profile, feed and account tiles normally
$('.homecard.profile, .homecard.feed, .homecard.account').on('mouseenter', mouseenterTile);
$('.homecard.profile, .homecard.feed, .homecard.account').on('mouseleave', mouseleaveTile);
$('div[layout-id=ftue]').on("ftue_success", refreshDeviceState);
$('.homecard').on('mouseenter', mouseenterTile);
$('.homecard').on('mouseleave', mouseleaveTile);
if(gon.allow_force_native_client) {
$('body').on('keyup', switchClientMode);
}
}
function updateTiles() {
logger.debug("isFtueComplete=" + isFtueComplete);
if(isFtueComplete) {
userHasDevices();
}
else {
userHasNoDevices();
}
$('.profile').on('click', function() {
context.location = '#/profile/' + context.JK.currentUserId;
});
}
this.initialize = function() {
var screenBindings = { 'beforeShow': beforeShow };
app.bindScreen('home', screenBindings);
events();
$('.profile').on('click', function() {
context.location = '#/profile/' + context.JK.currentUserId;
});
};
this.beforeShow = beforeShow;

View File

@ -106,7 +106,6 @@
$('#btn-send-invitation').show();
$('#btn-next-invitation').hide();
clearTextFields();
app.layout.showDialog('inviteUsers')
}

View File

@ -293,6 +293,21 @@
});
}
function updateUser(options) {
var id = getId(options);
delete options['id'];
return $.ajax({
type: "POST",
dataType: "json",
contentType: 'application/json',
url: "/api/users/" + id,
data: JSON.stringify(options),
processData: false
});
}
function initialize() {
return self;
}
@ -322,6 +337,7 @@
this.userSocialPromoted = userSocialPromoted;
this.createJoinRequest = createJoinRequest;
this.updateJoinRequest = updateJoinRequest;
this.updateUser = updateUser;
return this;
};

View File

@ -28,7 +28,10 @@
var heartbeatAckCheckInterval = null;
var opts = {
layoutOpts: {}
inClient: true, // specify false if you want the app object but none of the client-oriented features
layoutOpts: {
layoutFooter: true // specify false if you want footer to be left alone
}
};
/**
@ -89,7 +92,6 @@
function loggedIn(header, payload) {
app.clientId = payload.client_id;
$.cookie('client_id', payload.client_id);
// $.cookie('remember_token', payload.token); // removed per vrfs-273/403
heartbeatMS = payload.heartbeat_interval * 1000;
logger.debug("jamkazam.js.loggedIn(): clientId now " + app.clientId + "; Setting up heartbeat every " + heartbeatMS + " MS");
@ -279,14 +281,17 @@
this.opts = $.extend(opts, inOpts);
this.layout = new context.JK.Layout();
this.layout.initialize(this.opts.layoutOpts);
registerLoginAck();
registerHeartbeatAck();
registerBadStateRecovered();
registerBadStateError();
registerSocketClosed();
events();
context.JK.FaderHelpers.initialize();
context.window.onunload = this.unloadFunction;
if(opts.inClient) {
registerLoginAck();
registerHeartbeatAck();
registerBadStateRecovered();
registerBadStateError();
registerSocketClosed();
context.JK.FaderHelpers.initialize();
context.window.onunload = this.unloadFunction;
}
};

View File

@ -1,106 +1,115 @@
/**
* hoverIntent is similar to jQuery's built-in "hover" function except that
* instead of firing the onMouseOver event immediately, hoverIntent checks
* to see if the user's mouse has slowed down (beneath the sensitivity
* threshold) before firing the onMouseOver event.
*
* hoverIntent r6 // 2011.02.26 // jQuery 1.5.1+
* <http://cherne.net/brian/resources/jquery.hoverIntent.html>
*
* hoverIntent is currently available for use in all personal or commercial
* projects under both MIT and GPL licenses. This means that you can choose
* the license that best suits your project, and use it accordingly.
*
* // basic usage (just like .hover) receives onMouseOver and onMouseOut functions
* $("ul li").hoverIntent( showNav , hideNav );
*
* // advanced usage receives configuration object only
* $("ul li").hoverIntent({
* sensitivity: 7, // number = sensitivity threshold (must be 1 or higher)
* interval: 100, // number = milliseconds of polling interval
* over: showNav, // function = onMouseOver callback (required)
* timeout: 0, // number = milliseconds delay before onMouseOut function call
* out: hideNav // function = onMouseOut callback (required)
* });
*
* @param f onMouseOver function || An object with configuration options
* @param g onMouseOut function || Nothing (use configuration options object)
* @author Brian Cherne brian(at)cherne(dot)net
*/
/*!
* hoverIntent r7 // 2013.03.11 // jQuery 1.9.1+
* http://cherne.net/brian/resources/jquery.hoverIntent.html
*
* You may use hoverIntent under the terms of the MIT license. Basically that
* means you are free to use hoverIntent as long as this header is left intact.
* Copyright 2007, 2013 Brian Cherne
*/
/* hoverIntent is similar to jQuery's built-in "hover" method except that
* instead of firing the handlerIn function immediately, hoverIntent checks
* to see if the user's mouse has slowed down (beneath the sensitivity
* threshold) before firing the event. The handlerOut function is only
* called after a matching handlerIn.
*
* // basic usage ... just like .hover()
* .hoverIntent( handlerIn, handlerOut )
* .hoverIntent( handlerInOut )
*
* // basic usage ... with event delegation!
* .hoverIntent( handlerIn, handlerOut, selector )
* .hoverIntent( handlerInOut, selector )
*
* // using a basic configuration object
* .hoverIntent( config )
*
* @param handlerIn function OR configuration object
* @param handlerOut function OR selector for delegation OR undefined
* @param selector selector OR undefined
* @author Brian Cherne <brian(at)cherne(dot)net>
*/
(function($) {
$.fn.hoverIntent = function(f,g) {
// default configuration options
var cfg = {
sensitivity: 7,
interval: 100,
timeout: 0
};
// override configuration options with user supplied object
cfg = $.extend(cfg, g ? { over: f, out: g } : f );
$.fn.hoverIntent = function(handlerIn,handlerOut,selector) {
// instantiate variables
// cX, cY = current X and Y position of mouse, updated by mousemove event
// pX, pY = previous X and Y position of mouse, set by mouseover and polling interval
var cX, cY, pX, pY;
// default configuration values
var cfg = {
interval: 100,
sensitivity: 7,
timeout: 0
};
// A private function for getting mouse position
var track = function(ev) {
cX = ev.pageX;
cY = ev.pageY;
};
if ( typeof handlerIn === "object" ) {
cfg = $.extend(cfg, handlerIn );
} else if ($.isFunction(handlerOut)) {
cfg = $.extend(cfg, { over: handlerIn, out: handlerOut, selector: selector } );
} else {
cfg = $.extend(cfg, { over: handlerIn, out: handlerIn, selector: handlerOut } );
}
// A private function for comparing current and previous mouse position
var compare = function(ev,ob) {
ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
// compare mouse positions to see if they've crossed the threshold
if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) {
$(ob).unbind("mousemove",track);
// set hoverIntent state to true (so mouseOut can be called)
ob.hoverIntent_s = 1;
return cfg.over.apply(ob,[ev]);
} else {
// set previous coordinates for next time
pX = cX; pY = cY;
// use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval );
}
};
// instantiate variables
// cX, cY = current X and Y position of mouse, updated by mousemove event
// pX, pY = previous X and Y position of mouse, set by mouseover and polling interval
var cX, cY, pX, pY;
// A private function for delaying the mouseOut function
var delay = function(ev,ob) {
ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
ob.hoverIntent_s = 0;
return cfg.out.apply(ob,[ev]);
};
// A private function for getting mouse position
var track = function(ev) {
cX = ev.pageX;
cY = ev.pageY;
};
// A private function for handling mouse 'hovering'
var handleHover = function(e) {
// copy objects to be passed into t (required for event object to be passed in IE)
var ev = jQuery.extend({},e);
var ob = this;
// A private function for comparing current and previous mouse position
var compare = function(ev,ob) {
ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
// compare mouse positions to see if they've crossed the threshold
if ( ( Math.abs(pX-cX) + Math.abs(pY-cY) ) < cfg.sensitivity ) {
$(ob).off("mousemove.hoverIntent",track);
// set hoverIntent state to true (so mouseOut can be called)
ob.hoverIntent_s = 1;
return cfg.over.apply(ob,[ev]);
} else {
// set previous coordinates for next time
pX = cX; pY = cY;
// use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
ob.hoverIntent_t = setTimeout( function(){compare(ev, ob);} , cfg.interval );
}
};
// cancel hoverIntent timer if it exists
if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); }
// A private function for delaying the mouseOut function
var delay = function(ev,ob) {
ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
ob.hoverIntent_s = 0;
return cfg.out.apply(ob,[ev]);
};
// if e.type == "mouseenter"
if (e.type == "mouseenter") {
// set "previous" X and Y position based on initial entry point
pX = ev.pageX; pY = ev.pageY;
// update "current" X and Y position based on mousemove
$(ob).bind("mousemove",track);
// start polling interval (self-calling timeout) to compare mouse coordinates over time
if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );}
// A private function for handling mouse 'hovering'
var handleHover = function(e) {
// copy objects to be passed into t (required for event object to be passed in IE)
var ev = jQuery.extend({},e);
var ob = this;
// else e.type == "mouseleave"
} else {
// unbind expensive mousemove event
$(ob).unbind("mousemove",track);
// if hoverIntent state is true, then call the mouseOut function after the specified delay
if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );}
}
};
// cancel hoverIntent timer if it exists
if (ob.hoverIntent_t) { ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t); }
// bind the function to the two event listeners
return this.bind('mouseenter',handleHover).bind('mouseleave',handleHover);
};
// if e.type == "mouseenter"
if (e.type == "mouseenter") {
// set "previous" X and Y position based on initial entry point
pX = ev.pageX; pY = ev.pageY;
// update "current" X and Y position based on mousemove
$(ob).on("mousemove.hoverIntent",track);
// start polling interval (self-calling timeout) to compare mouse coordinates over time
if (ob.hoverIntent_s != 1) { ob.hoverIntent_t = setTimeout( function(){compare(ev,ob);} , cfg.interval );}
// else e.type == "mouseleave"
} else {
// unbind expensive mousemove event
$(ob).off("mousemove.hoverIntent",track);
// if hoverIntent state is true, then call the mouseOut function after the specified delay
if (ob.hoverIntent_s == 1) { ob.hoverIntent_t = setTimeout( function(){delay(ev,ob);} , cfg.timeout );}
}
};
// listen for mouseenter and mouseleave
return this.on({'mouseenter.hoverIntent':handleHover,'mouseleave.hoverIntent':handleHover}, cfg.selector);
};
})(jQuery);

View File

@ -1,74 +0,0 @@
(function(context,$) {
"use strict";
context.JK = context.JK || {};
var downloads = {};
function listClients() {
var rest = context.JK.Rest();
var currentOS = context.JK.detectOS();
var downloads = $('.downloads');
rest.getClientDownloads()
.done(function(data) {
downloads.removeClass('spinner-large');
var count = 0;
for ( var property in data ) count++;
if(count == 0) {
alert("Currently unable to list client software downloads.");
}
else {
$.each(data, function(key, item) {
// if the currentOS we detect from browser is found within the product of an available client
// we flag it with this boolean
var matchesUserOS = currentOS != null && key.toLowerCase().indexOf(currentOS.toLowerCase()) > -1;
var platform = key.substring('JamClient/'.length);
var options = {
emphasis: matchesUserOS ? "currentOS" : "",
uri: item.uri,
platform: platform
}
var download = $(context._.template($('#client-download-link').html(), options, { variable: 'data' }));
download.find('a').data('platform', platform).click(function() {
var clicked = $(this);
rest.userDownloadedClient().always(function() {
$('body').append('<iframe class="downloading" src="' + clicked.attr('href') + '" style="display:none"/>')
})
context.JK.GA.trackDownload($(this).data('platform'));
return false;
});
if(matchesUserOS) {
// make sure the current user OS is at the top
downloads.prepend(download);
}
else {
downloads.append(download)
}
});
}
})
.fail(function() {
downloads.removeClass('spinner-large');
alert("Currently unable to list client software downloads due to error.");
})
}
downloads.listClients = listClients;
context.JK.Downloads = downloads;
})(window, jQuery)

View File

@ -7,6 +7,4 @@
//= require ga
//= require jam_rest
//= require landing/init
//= require landing/signup
//= require landing/downloads
//= require landing/congratulations
//= require landing/signup

View File

@ -56,6 +56,8 @@
var dialogBindings = {};
var wizardShowFunctions = {};
var openDialogs = []; // FIFO stack
function setup() {
requiredStyles();
hideAll();
@ -281,7 +283,10 @@
}
function layoutFooter(screenWidth, screenHeight) {
if(!opts.layoutFooter) { return; }
var $footer = $('#footer');
$footer.show();
var nHeight = $footer.height();
var footerStyle = {
top: (screenHeight - 80) + 'px'
@ -291,17 +296,7 @@
$footer.animate({ "left" : opts.gutter, "width" : width, "top": (screenHeight - 78) + "px"}, opts.animationDuration);
}
function requiredStyles() {
var bodyStyle = {
margin: '0px',
padding: '0px',
overflow: 'hidden'
};
if (opts.allowBodyOverflow) {
delete bodyStyle.overflow;
}
$('body').css(bodyStyle);
function requiredLayoutStyles() {
var layoutStyle = {
position: 'absolute',
margin: '0px',
@ -321,6 +316,21 @@
$('[layout-grid]').children().css({
position: "absolute"
});
}
function requiredStyles() {
var bodyStyle = {
margin: '0px',
padding: '0px',
overflow: 'hidden'
};
if (opts.allowBodyOverflow) {
delete bodyStyle.overflow;
}
$('body').css(bodyStyle);
requiredLayoutStyles();
var curtainStyle = {
position: "absolute",
margin: '0px',
@ -399,9 +409,11 @@
}
function closeDialog(dialog) {
console.log("closing dialog: " + dialog);
var $dialog = $('[layout-id="' + dialog + '"]');
dialogEvent(dialog, 'beforeHide');
$('.dialog-overlay').hide();
var $overlay = $('.dialog-overlay');
unstackDialogs($overlay);
$dialog.hide();
dialogEvent(dialog, 'afterHide');
}
@ -456,11 +468,47 @@
}
}
/**
* Responsible for keeping N dialogs in correct stacked order,
* also moves the .dialog-overlay such that it hides/obscures all dialogs except the highest one
*/
function stackDialogs($dialog, $overlay) {
console.log("pushing dialog: " + $dialog.attr('layout-id'))
openDialogs.push($dialog);
var zIndex = 1000;
for(var i in openDialogs) {
var $dialog = openDialogs[i];
$dialog.css('zIndex', zIndex);
zIndex++;
}
$overlay.css('zIndex', zIndex - 1);
}
function unstackDialogs($overlay) {
if(openDialogs.length > 0) {
var removed = openDialogs.pop();
console.log("removed dialog : " + removed.attr('layout-id'));
}
else {
console.log("no dialog removed because nothing was on the stack");
}
var zIndex = 1000 + openDialogs.length;
$overlay.css('zIndex', zIndex - 1);
if(openDialogs.length == 0) {
$overlay.hide();
}
}
function showDialog(dialog) {
dialogEvent(dialog, 'beforeShow');
$('.dialog-overlay').show();
var $overlay = $('.dialog-overlay')
$overlay.show();
centerDialog(dialog);
$('[layout-id="' + dialog + '"]').show();
var $dialog = $('[layout-id="' + dialog + '"]');
stackDialogs($dialog, $overlay);
$dialog.show();
dialogEvent(dialog, 'afterShow');
}
@ -540,7 +588,7 @@
this.notify = function(message, descriptor) {
var $notify = $('[layout="notify"]');
if (notifyQueue.length === 0) {
firstNotification = true;
setNotificationInfo(message, descriptor);

View File

@ -12,7 +12,6 @@
var mixers = [];
var configureTrackDialog;
var addTrackDialog;
var addNewGearDialog;
var screenActive = false;
@ -212,7 +211,6 @@
function _initDialogs() {
configureTrackDialog.initialize();
addTrackDialog.initialize();
addNewGearDialog.initialize();
}
@ -426,8 +424,6 @@
// Show settings icons only for my tracks
if (myTrack) {
var $trackSettings = $('div[mixer-id="' + mixer.id + '"].track-icon-settings');
$trackSettings.show();
myTracks.push(trackData);
}
// TODO: UNCOMMENT THIS WHEN TESTING LOCALLY IN BROWSER
@ -436,22 +432,7 @@
});
configureTrackDialog = new context.JK.ConfigureTrackDialog(app, myTracks, sessionId, sessionModel);
addTrackDialog = new context.JK.AddTrackDialog(app, myTracks, sessionId, sessionModel);
addNewGearDialog = new context.JK.AddNewGearDialog(app, ftueCallback);
// # NO LONGER HIDING ADD TRACK even when there are 2 tracks (VRFS-537)
$('#div-add-track').click(function() {
if (myTracks.length === 2) {
$('#btn-error-ok').click(function() {
app.layout.closeDialog('error-dialog');
});
context.JK.showErrorDialog(app, "You can only have a maximum of 2 personal tracks per session.", "max # of tracks");
}
else {
app.layout.showDialog('add-track');
addTrackDialog.showDialog();
}
});
}
function ftueCallback() {
@ -505,7 +486,6 @@
connectTrackToMixer(trackSelector, key, mixer.id, gainPercent);
var $track = $('div.track[client-id="' + key + '"]');
$track.find('.track-icon-mute').attr('mixer-id', mixer.id);
$track.find('.track-icon-settings').attr('mixer-id', mixer.id);
// Set mute state
_toggleVisualMuteControl($track.find('.track-icon-mute'), mixer.mute);
}
@ -577,13 +557,6 @@
$closeButton.click(deleteTrack);
}
var $trackSettings = $('div[mixer-id="' + trackData.mixerId + '"].track-icon-settings');
$trackSettings.click(function() {
// call this to initialize Voice Chat tab
configureTrackDialog.showVoiceChatPanel(true);
configureTrackDialog.showMusicAudioPanel(true);
});
tracks[trackData.trackId] = new context.JK.SessionTrack(trackData.clientId);
}
@ -809,10 +782,9 @@
$('#session-contents').on("click", '[action="delete"]', deleteSession);
$('#tracks').on('click', 'div[control="mute"]', toggleMute);
$('.voicechat-settings').click(function() {
// call this to initialize Music Audio tab
configureTrackDialog.showMusicAudioPanel(true);
$('#track-settings').click(function() {
configureTrackDialog.showVoiceChatPanel(true);
configureTrackDialog.showMusicAudioPanel(true);
});
}

View File

@ -6,8 +6,8 @@
context.JK.Sidebar = function(app) {
var logger = context.JK.logger;
var friends = [];
var invitationDialog = new context.JK.InvitationDialog(app);
var rest = context.JK.Rest();
var invitationDialog = null;
function initializeFriendsPanel() {
@ -423,10 +423,12 @@
// watch for Invite More Users events
$('#sidebar-div .btn-email-invitation').click(function() {
invitationDialog.showEmailDialog();
return false;
});
$('#sidebar-div .btn-gmail-invitation').click(function() {
invitationDialog.showGoogleDialog();
return false;
});
}
@ -661,11 +663,12 @@
});
}
this.initialize = function() {
this.initialize = function(invitationDialogInstance) {
events();
initializeFriendsPanel();
initializeChatPanel();
initializeNotificationsPanel();
invitationDialog = invitationDialogInstance;
};
};
})(window,jQuery);

View File

@ -0,0 +1,94 @@
(function(context,$) {
/** Javascript for managing the (account dropdown) */
"use strict";
context.JK = context.JK || {};
context.JK.UserDropdown = function(app) {
var logger = context.JK.logger;
var rest = new JK.Rest();
var userMe = null;
var invitationDialog = null;
function menuHoverIn() {
$('ul.shortcuts', this).show();
}
function menuHoverOut() {
$('ul.shortcuts', this).hide();
}
function events() {
$('.userinfo').hoverIntent(menuHoverIn, menuHoverOut);
$('.userinfo .invite-friends .menuheader').on('click', function(e) {
$(this).closest('li').css('height', 'auto').find('ul').toggle();
e.stopPropagation();
return false;
});
$('.invite-friends .google-invite a').on('click', function(e) {
invitationDialog.showGoogleDialog();
});
$('.invite-friends .email-invite a').on('click', function(e) {
invitationDialog.showEmailDialog();
});
$('#header-avatar').on('avatar_changed', function(event, newAvatarUrl) {
updateAvatar(newAvatarUrl);
event.preventDefault();
return false;
})
}
function loadMe() {
$.ajax({
url: '/api/users/' + context.JK.currentUserId
}).done(function(r) {
userMe = r;
// TODO - Setting global variable for local user.
context.JK.userMe = r;
updateHeader();
handleWhatsNext(userMe);
}).fail(app.ajaxError);
}
function updateHeader() {
$('#user').html(userMe.name);
showAvatar();
}
function handleWhatsNext(userProfile) {
if(gon.isNativeClient && userProfile.show_whats_next) {
app.layout.showDialog('whatsNext');
}
}
// initially show avatar
function showAvatar() {
var photoUrl = context.JK.resolveAvatarUrl(userMe.photo_url);
$('#header-avatar').attr('src', photoUrl);
}
// handle update avatar event
function updateAvatar(avatar_url) {
var photoUrl = context.JK.resolveAvatarUrl(avatar_url);
var avatar = $(new Image());
avatar.attr('src', photoUrl + '?cache_bust=' + new Date().getTime());
avatar.attr('alt', "Avatar");
avatar.attr('id', 'header-avatar');
$('#header-avatar').replaceWith(avatar);
}
this.initialize = function(invitationDialogInstance) {
events();
invitationDialog = invitationDialogInstance;
loadMe();
}
this.loadMe = loadMe;
}
})(window,jQuery);

View File

@ -297,7 +297,7 @@
context.JK.popExternalLinks = function() {
// Allow any a link with a rel="external" attribute to launch
// the link in the default browser, using jamClient:
$('a[rel="external"]').click(function(evt) {
$('body').on('click', 'a[rel="external"]', function(evt) {
if(!context.jamClient) {
return;

View File

@ -6,7 +6,7 @@
congratulations.initialize = function initialize(musician, registrationType) {
if(musician) {
context.JK.Downloads.listClients();
context.JK.Downloads.listClients(true);
}
if(registrationType) {

View File

@ -0,0 +1,138 @@
(function(context,$) {
"use strict";
context.JK = context.JK || {};
var downloads = {};
var isCongratulations;
var downloadUris = {}; // map of platform > uri
var rest = context.JK.Rest();
function selectPlatform(selectedPlatform) {
var platformName; // mac, windows, linux
var platformDisplay; // Mac, Windows, Linux
var platform = selectedPlatform; //MacOSX, Win32, Unix
var platformName1, platformName2, platform1, platform2;
var uri = downloadUris[selectedPlatform];
// prepare template varaibles
if (selectedPlatform == "Unix") {
platformName = "linux";
platformDisplay = "Linux"
platformName1 = "mac";
platformName2 = "windows";
platform1 = "MacOSX";
platform2 = "Win32"
} else if(selectedPlatform == "Win32") {
platformName = "windows";
platformDisplay = "Windows";
platformName1 = "mac";
platformName2 = "linux"
platform1 = "MacOSX";
platform2 = "Unix";
} else if(selectedPlatform == "MacOSX") {
platformName = "mac";
platformDisplay = "Mac";
platformName1 = "windows";
platformName2 = "linux";
platform1 = "Win32";
platform2 = "Unix";
}
else {
alert("unknown platform: " + selectedPlatform);
}
var options = {
platform : platform,
platformName : platformName,
platformDisplay : platformDisplay,
platformName1 : platformName1,
platformName2 : platformName2,
platform1: platform1,
platform2: platform2,
uri : uri ? uri : '#',
isCongratulations : isCongratulations
};
var blurb = $(context._.template($('#client-download-blurb-contents').html(), options, { variable: 'data' }));
// isolate active image for blurb
$('div.hidden-images img[data-purpose=' + platformName + ']', blurb).remove().appendTo($('a.current-os-download', blurb));
var selectOthers = $(context._.template($('#client-download-select-others').html(), options, { variable: 'data' }));
// isolate active images for selectOthers
$('div.hidden-images img[data-purpose=' + platformName1 + ']', selectOthers).remove().appendTo($('a[data-order=1]', selectOthers));
$('div.hidden-images img[data-purpose=' + platformName2 + ']', selectOthers).remove().appendTo($('a[data-order=2]', selectOthers));
// install click handler for change selection
$('a', selectOthers).click(function() {
var platform = $(this).attr('data-platform');
selectPlatform(platform);
return false;
});
$('a', blurb).click(function() {
var clicked = $(this);
var href = clicked.attr('href');
if(href != "#") {
rest.userDownloadedClient().always(function() {
$('body').append('<iframe class="downloading" src="' + clicked.attr('href') + '" style="display:none"/>')
});
}
else {
context.JK.GA.trackDownload(clicked.attr('data-platform'));
// if there is no download available, apologize to the user
alert("Sorry, this download is not currently available.");
return false;
}
return false;
});
// update blurb
$('body.web .downloads-blurb').empty().append(blurb);
// update the 'download other platforms' buttons
$('body.web .downloads-container').empty().append(selectOthers);
// update system requirements
$('body.web .system-requirements ul').hide();
$('body.web .system-requirements ul.' + platformName + '-requirements').show();
$('body.web .system-requirements').show();
}
function removeSpinner() {
$('body.web .spinner-large').remove();
}
function listClients(congratulations) {
isCongratulations = congratulations;
var rest = context.JK.Rest();
var currentOS = context.JK.detectOS();
var downloads = $('.downloads');
rest.getClientDownloads()
.done(function(data) {
removeSpinner();
$.each(data, function(key, item) {
var platform = key.substring('JamClient/'.length);
downloadUris[platform] = item.uri;
});
})
.fail(function() {
removeSpinner();
alert("Currently unable to list client software downloads due to error.");
})
.always(function() {
selectPlatform(currentOS == null ? 'Win32' : currentOS);
});
}
downloads.listClients = listClients;
context.JK.Downloads = downloads;
})(window, jQuery)

View File

@ -0,0 +1,18 @@
//= require jquery
//= require jquery_ujs
//= require jquery.queryparams
//= require jquery.hoverIntent
//= require AAA_Log
//= require AAC_underscore
//= require globals
//= require invitationDialog
//= require layout
//= require user_dropdown
//= require jamkazam
//= require utils
//= require ga
//= require jam_rest
//= require landing/init
//= require landing/signup
//= require web/downloads
//= require web/congratulations

View File

@ -0,0 +1,55 @@
(function(context,$) {
"use strict";
context.JK = context.JK || {};
context.JK.WhatsNextDialog = function(app) {
var logger = context.JK.logger;
var rest = context.JK.Rest();
var invitationDialog = null;
function registerEvents() {
$('#whatsnext-dialog a.facebook-invite').on('click', function(e) {
alert("This feature not yet implemented");
});
$('#whatsnext-dialog a.google-invite').on('click', function(e) {
invitationDialog.showGoogleDialog();
});
$('#whatsnext-dialog a.email-invite').on('click', function(e) {
invitationDialog.showEmailDialog();
});
}
function beforeShow() {
}
function beforeHide() {
var $dontShowWhatsNext = $('#show_whats_next');
if($dontShowWhatsNext.is(':checked')) {
rest.updateUser( {show_whats_next:false})
}
}
function initialize(invitationDialogInstance) {
var dialogBindings = {
'beforeShow' : beforeShow,
'beforeHide': beforeHide
};
app.bindDialog('whatsNext', dialogBindings);
registerEvents();
invitationDialog = invitationDialogInstance;
};
this.initialize = initialize;
}
return this;
})(window,jQuery);

View File

@ -41,12 +41,14 @@
min-width: 165px;
width: 20%;
}
.account-left h2 {
color: #FFFFFF;
font-size: 23px;
font-weight: 400;
margin-bottom: 8px;
}
.account-mid {
float: left;
line-height: 150%;
@ -54,6 +56,29 @@
width: 50%;
}
.account-profile {
padding-top:25px;
h2 {
margin-bottom:15px;
}
.location {
position:relative;
}
#account-change-avatar {
position:absolute;
top:-27px;
right:72px;
height:13px;
}
.birth_date {
margin-left:40px;
}
}
.audio .audio-profiles-short{
white-space: normal;
}

View File

@ -14,6 +14,7 @@
*= require ./content
*= require ./faders
*= require ./header
#= require ./user_dropdown
*= require ./footer
*= require ./screen_common
*= require ./notify
@ -34,4 +35,5 @@
*= require ./banner
*= require ./clientUpdate
*= require jquery.Jcrop
*= require icheck/minimal/minimal
*/

View File

@ -338,8 +338,15 @@ ul.shortcuts {
}
}
}
.tagline {
font-size:30px;
margin-top:35px;
color:#ed3718;
font-weight:300;
width:345px;
clear:left;
white-space:normal;
}

View File

@ -29,6 +29,7 @@
.radio-text {
font-size:13px;
line-height:17px;
}
.friendbox {
@ -111,4 +112,20 @@ div.friendbox input[type=text] {
padding:10px;
border-bottom:solid 1px #999;
cursor:pointer;
}
}
div[layout-id="createSession"] .icheckbuttons {
margin-top:5px;
div.iradio_minimal {
float:left;
}
label {
float:left;
margin:0 10px 0 3px;
}
}

View File

@ -9,6 +9,7 @@
padding-top: 10px;
border-top:solid 1px #444;
height:13px;
display:none;
}
#copyright {

View File

@ -299,6 +299,50 @@ div[layout-id="ftue3"] {
border: 1px solid #ed3618;
}
.ftue-overlay.tall {
top:75px;
}
.ftue-overlay.tall .ftue-inner {
padding:5px;
}
#whatsnext-dialog {
height:auto;
.ftue-inner h2 {
font-weight:normal;
color:#ed3618;
margin-bottom:6px;
font-size:1.7em;
}
.ftue-inner table td.whatsnext {
font-size:12px;
padding:10px;
width:50%;
font-weight:300;
}
.ftue-inner table td.whatsnext {
font-size:12px;
padding:10px;
width:50%;
font-weight:300;
}
.ftue-inner table a {
text-decoration:none;
}
.ftue-inner table {
border-collapse:separate;
border-spacing: 20px;
}
}
.ftue-inner {
width:750px;
padding:25px;

View File

@ -1,6 +1,5 @@
@charset "UTF-8";
@import "compass/utilities/text/replacement";
@import "client/common.css.scss";
.header {
height: 55px;
@ -15,123 +14,3 @@ div[layout="header"] h1 {
@include replace-text(image-url("header/logo.png"));
float:left;
}
#logo {
float:left;
width:247px;
}
#profile {
width:auto;
float:right;
height:54px;
}
.avatar_large {
float:left;
padding:2px;
width:54px;
height:54px;
background-color: $ColorScreenPrimary;
-webkit-border-radius:28px;
-moz-border-radius:28px;
border-radius:28px;
}
.avatar_large img {
width:54px;
height:54px;
-webkit-border-radius:26px;
-moz-border-radius:26px;
border-radius:26px;
}
#user {
margin:18px 0px 0px 10px;
font-size:20px;
font-weight:200;
color:#ccc;
float:left;
}
.arrow-down {
float:left;
cursor:pointer;
margin-left:16px;
margin-top:26px;
width: 0;
height: 0;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-top: 8px solid #fff;
}
.userinfo {
cursor:pointer;
}
.userinfo ul {
clear:both;
background: scale-lightness($ColorUIBackground, 10%);
display:none;
}
.userinfo li {
display:block;
margin: 2px;
padding: 2px;
background: scale-lightness($ColorUIBackground, 20%);
}
/*
div[layout="header"] h1 {
width: 252px;
height:47px;
@include replace-text(image-url("logo.png"));
}
*/
/*.header h1 {*/
/*margin:22px;*/
/*font-size:300%;*/
/*font-family: 'LatoLight', Arial, sans-serif;*/
/*}*/
/*
.userinfo {
position:absolute;
right:0px;
top:0px;
width: 266px;
z-index:5;
}
.userinfo img.avatar {
float:left;
}
.userinfo .username {
float:left;
margin-top: 18px;
cursor: pointer;
}
.userinfo h2 {
font-size:120%;
font-weight: bold;
float:left;
margin-right:4px;
}
.userinfo .profile-toggle {
display:inline-block;
}
.userinfo ul {
clear:both;
background: $color7;
display:none;
}
.userinfo li {
display:block;
margin: 2px;
padding: 2px;
background: scale-lightness($color7, 10%);
}
*/

View File

@ -131,6 +131,10 @@ input[type="button"] {
font-size:11px;
}
.orange {
color: $ColorScreenPrimary !important;
}
.curtain {
background-color: $ColorScreenBackground;
position:absolute;
@ -433,6 +437,9 @@ input[type="text"], input[type="password"]{
width:100%;
}
.f20 {
font-size: 20px !important;
}
/* TODO - we need a separate stylesheet(s) for signin/signup screens */
/* Following is a style adjustment for the sign-in table spacing */
#sign-in td { padding: 4px; }

View File

@ -480,7 +480,7 @@ table.vu td {
.voicechat {
margin-top:10px;
width:152px;
width:130px;
height:25px;
background-color:#242323;
position:absolute;

View File

@ -0,0 +1,75 @@
@import "client/common.css.scss";
#logo {
float:left;
width:247px;
}
#profile {
width:auto;
float:right;
height:64px;
.signin {
position:relative;
margin-top:40px;
}
}
.avatar_large {
float:left;
padding:2px;
width:54px;
height:54px;
background-color: $ColorScreenPrimary;
-webkit-border-radius:28px;
-moz-border-radius:28px;
border-radius:28px;
}
.avatar_large img {
width:54px;
height:54px;
-webkit-border-radius:26px;
-moz-border-radius:26px;
border-radius:26px;
}
#user {
margin:18px 0px 0px 10px;
font-size:20px;
font-weight:200;
color:#ccc;
float:left;
}
.arrow-down {
float:left;
cursor:pointer;
margin-left:16px;
margin-top:26px;
width: 0;
height: 0;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-top: 8px solid #fff;
}
.userinfo {
cursor:pointer;
}
.userinfo ul {
clear:both;
background: scale-lightness($ColorUIBackground, 10%);
display:none;
position:relative;
}
.userinfo li {
display:block;
margin: 2px;
padding: 2px;
background: scale-lightness($ColorUIBackground, 20%);
}

View File

@ -175,76 +175,3 @@ strong {
display:block;
}
}
// all custom CSS for the register page goes here
.register-page {
.register-container {
padding:10px;
}
input.register-musician {
}
.error {
padding: 5px 12px 5px 5px;
margin-left:-5px;
margin-right:-12px;
}
input.register-fan {
margin-left:20px;
}
input[type=text], input[type=password] {
margin-top:1px;
width:100%;
}
select {
width:100%;
}
.right-side {
margin-left:25px;
}
.ftue-left {
margin-bottom:30px;
select {
width:104%;
}
div.field {
margin-top:31px;
width:43%;
float:left;
}
}
.ftue-right {
table {
border-collapse:separate;
border-spacing:6px;
}
label.instruments {
margin-bottom:2px;
}
div.field {
margin-top:15px;
}
a.tos {
text-decoration: underline;
}
input[type=submit] {
margin-top:20px;
}
}
}

View File

@ -0,0 +1,41 @@
@charset "UTF-8";
#footer-container {
position:relative;
margin:0 6%;
top:100px;
height:13px;
}
#footer {
padding-top: 10px;
border-top:solid 1px #444;
}
#copyright {
float:left;
font-size:11px;
color:#ccc;
}
#footer-links {
float:right;
font-size:11px;
color:#ccc;
}
#footer-links a {
color:#ccc;
text-decoration:none;
}
#footer-links a:hover {
color:#fff;
text-decoration:underline;
}
#version {
font-size:11px;
color:#ccc;
text-align: center;
}

View File

@ -0,0 +1,366 @@
html {
height:100%;
}
body.web {
background-repeat: repeat-x;
margin:0 !important;
padding:0 !important;
position:relative !important;
overflow: visible !important;
width:auto !important;
#web-container {
padding:3% 0;
}
div.wrapper {
white-space: nowrap;
p, ul {
color:#999;
line-height:160%;
margin-bottom:20px;
width:90%;
white-space:normal;
font-size:16px;
}
h2 {
font-weight:300;
}
.content-wrapper {
border-bottom: medium none;
padding: 0;
}
.black-bar{
position:relative;
width:100%;
min-height: 366px;
background-color:black;
padding-top:20px;
}
.black-bar-inner {
width:1100px;
margin: 0 auto;
position:relative;
// all custom CSS for the register page goes here
.register-page {
.register-container {
padding:10px;
}
input.register-musician {
}
.actions {
margin-top:20px;
a.button-grey {
line-height:15px; // WHY is this not universal
}
}
.error {
padding: 5px 12px 5px 5px;
margin-left:-5px;
margin-right:-12px;
}
input.register-fan {
margin-left:20px;
}
input[type=text], input[type=password] {
margin-top:1px;
width:100%;
}
select {
width:100%;
}
.right-side {
margin-left:25px;
}
.register-left {
select {
width:104%;
}
div.field {
margin-top:31px;
width:43%;
float:left;
}
}
.register-right {
margin-top:40px;
table {
border-collapse:separate;
border-spacing:6px;
}
label.instruments {
margin-bottom:2px;
}
div.field {
margin-top:15px;
}
a.tos {
text-decoration: underline;
}
.ftue-instrumentlist {
width:100%;
}
}
}
}
.after-black-bar {
position:relative;
background-color:#262626;
width:1100px;
margin:0 auto;
.after-black-bar-inner {
background-color:#262626;
position:absolute;
left:0;
right:0;
}
}
}
.header {
width:1100px;
margin:0 auto;
.logo-home {
width: 298px;
margin-top: 30px;
display: inline-block;
float:left;
}
}
#profile {
position:absolute;
top:-80px;
right:0;
ul {
margin-bottom:0;
}
}
ul {
list-style: none outside none;
}
h3 {
font-size:20px;
font-weight:normal;
}
.download-box {
padding:15px;
color:#fff;
text-align:center;
font-size:20px;
-webkit-border-radius: 8px;
border-radius: 8px;
background:#383838;
margin-top:100px;
}
.system-requirements {
margin-top:35px;
display:none;
ul {
display:none;
list-style:disc outside none;
padding-left:40px;
}
}
div.proceed {
margin:40px 0 250px 5px;
}
.downloads {
ul {
list-style:disc outside none;
padding-left:40px;
}
}
}
#landing-container {
padding: 3% 0;
position:relative;
text-align: center;
}
.signin-overlay {
position:relative;
top:0;
}
strong {
font-weight: 600;
}
.logo-message {
display: block;
margin: 0 auto;
width: 247px;
}
.message-wrapper {
margin: 0 auto;
width: 480px;
}
.message-wrapper .left {
display: block;
overflow: visible;
}
.message {
display: block;
float: left;
margin-left: 20px;
overflow: visible;
width: 320px;
}
.message h2 {
border-bottom: 1px solid #FFFFFF;
color: #FFFFFF;
display: block;
font-weight: 200;
margin-bottom: 10px;
font-size:21px;
}
.spinner-large {
vertical-align:middle;
text-align: center;
margin: 125px auto;
}
.client-download {
margin-bottom:20px;
}
.currentOS {
span.platform {
font-size:18px;
}
}
// all custom CSS for the sign-in page goes here
.signin-page {
.ftue-inner {
line-height:18px;
}
.ftue-left, .ftue-right {
}
fieldset[name=text-input]{
float:right;
margin-right:18px;
}
fieldset[name=signin-options] {
float:left;
margin:10px 0 0 10px;
small {
float:left;
}
}
fieldset[name=actions] {
float:right;
margin: 10px 19px 0 0;
}
.field {
right:0;
}
.email {
float:left;
margin-right:10px;
}
.password {
float:left;
}
label {
margin:27px 0 10px;
}
.already-member {
}
.keep-logged-in {
}
.forgot-password {
font-size:11px;
float:right;
margin:15px 19px 0 0;
a {
text-decoration: underline;
}
}
.login-error {
background-color: #330000;
border: 1px solid #990000;
padding:4px;
}
.login-error-msg {
display:none;
margin-top:10px;
text-align:center;
color:#F00;
font-size:11px;
}
fieldset.login-error .login-error-msg {
display:block;
}
}

View File

@ -0,0 +1,12 @@
/**
*= require client/ie
*= require client/jamkazam
*= require client/screen_common
*= require client/content
*= require client/ftue
*= require client/user_dropdown
*= require client/dialog
*= require client/invitationDialog
*= require web/main
*= require web/footer
*/

View File

@ -27,8 +27,7 @@ class ApiJoinRequestsController < ApiController
if @join_request.errors.any?
response.status = :unprocessable_entity
respond_with "You cannot join the session at this time."
# respond_with @join_request
respond_with @join_request
else
# send notification
Notification.send_join_request(music_session, @join_request, text)

View File

@ -14,14 +14,12 @@ class ApiUsersController < ApiController
respond_to :json
def index
# don't return users that aren't yet confirmed
@users = User.where('email_confirmed=TRUE').paginate(page: params[:page])
@users = User.paginate(page: params[:page])
respond_with @users, responder: ApiResponder, :status => 200
end
def show
# don't return users that aren't yet confirmed
@user = User.where('email_confirmed=TRUE').find(params[:id])
@user = User.find(params[:id])
respond_with @user, responder: ApiResponder, :status => 200
end
@ -65,6 +63,8 @@ class ApiUsersController < ApiController
@user.country = params[:country] if params.has_key?(:country)
@user.musician = params[:musician] if params.has_key?(:musician)
@user.update_instruments(params[:instruments].nil? ? [] : params[:instruments]) if params.has_key?(:instruments)
@user.show_whats_next = params[:show_whats_next] if params.has_key?(:show_whats_next)
@user.subscribe_email = params[:subscribe_email] if params.has_key?(:subscribe_email)
@user.save

View File

@ -3,6 +3,14 @@ class ClientsController < ApplicationController
include UsersHelper
def index
# we want to enforce that /client is always the client view prefix
# this is a side effect of setting root path to '/'; soon we can remove this when we implement the new home page
if request.path == '/'
redirect_to client_url
return
end
# use gon to pass variables into javascript
gon.websocket_gateway_uri = Rails.application.config.websocket_gateway_uri
gon.check_for_client_updates = Rails.application.config.check_for_client_updates
@ -21,6 +29,9 @@ class ClientsController < ApplicationController
end
end
# let javascript have access to the server's opinion if this is a native client
gon.isNativeClient = @nativeClient
if current_user
render :layout => 'client'
else

View File

@ -22,6 +22,11 @@ class UsersController < ApplicationController
end
def new
if current_user
redirect_to :root
return
end
@invited_user = load_invited_user(params)
if !@invited_user.nil? && @invited_user.accepted
@ -41,10 +46,14 @@ class UsersController < ApplicationController
@user.email = @invited_user.email
end
render :layout => 'landing'
render :layout => 'web'
end
def create
if current_user
redirect_to :root
return
end
@invited_user = load_invited_user(params)
@signup_postback = load_postback(@invited_user)
@ -53,7 +62,7 @@ class UsersController < ApplicationController
# check recaptcha; if any errors seen, contribute it to the model
unless verify_recaptcha(:model => @user, :message => "recaptcha")
render 'new', :layout => 'landing'
render 'new', :layout => 'web'
return
end
@ -62,7 +71,6 @@ class UsersController < ApplicationController
birth_date = fixup_birthday(params[:jam_ruby_user]["birth_date(2i)"], params[:jam_ruby_user]["birth_date(3i)"], params[:jam_ruby_user]["birth_date(1i)"])
location = { :country => params[:jam_ruby_user][:country], :state => params[:jam_ruby_user][:state], :city => params[:jam_ruby_user][:city]}
terms_of_service = params[:jam_ruby_user][:terms_of_service].nil? ? false : true
subscribe_email = params[:jam_ruby_user][:subscribe_email].nil? ? false : true
musician = params[:jam_ruby_user][:musician]
@ -73,7 +81,6 @@ class UsersController < ApplicationController
params[:jam_ruby_user][:password],
params[:jam_ruby_user][:password_confirmation],
terms_of_service,
subscribe_email,
instruments,
birth_date,
location,
@ -88,7 +95,7 @@ class UsersController < ApplicationController
load_location(request.remote_ip, location)
gon.signup_errors = true
gon.musician_instruments = instruments
render 'new', :layout => 'landing'
render 'new', :layout => 'web'
else
sign_in @user
@ -102,15 +109,15 @@ class UsersController < ApplicationController
end
def congratulations_fan
render :layout => "landing"
render :layout => "web"
end
def congratulations_musician
render :layout => "landing"
render :layout => "web"
end
def downloads
render :layout => "landing"
render :layout => "web"
end
def signup_confirm

View File

@ -4,7 +4,7 @@ attributes :id, :first_name, :last_name, :name, :city, :state, :country, :locati
# give back more info if the user being fetched is yourself
if @user == current_user
attributes :email, :original_fpfile, :cropped_fpfile, :crop_selection, :session_settings
attributes :email, :original_fpfile, :cropped_fpfile, :crop_selection, :session_settings, :show_whats_next, :subscribe_email
end
unless @user.friends.nil? || @user.friends.size == 0

View File

@ -22,100 +22,86 @@
<script type="text/template" id="template-account-profile">
<!-- content wrapper -->
<div class="content-wrapper account-profile">
<br />
<form id="account-edit-profile-form">
<table width="100%" cellpadding="0" cellspacing="0">
<tr>
<td valign="top" width="33%"> <!-- TODO -->
<div class="right mr30"><!--<a href="#" class="avatar_large ml10"><img src="images/shared/avatar_jonathon.png" width="246" height="246" /></a>--><br clear="left" />
<a href="#" class="small" id="account-change-avatar">Change Avatar</a></div>
<h2>profile:</h2>
<h2>profile:</h2>
</td>
<div class="location w30 left">
<a href="#" class="small" id="account-change-avatar">Change Avatar</a>
<div class="field">
<label>Country:</label>
<select name='country' class="w80">
<option value='{country}' selected="selected">{country}</option>
</select>
</div>
<div class="field">
<label>State/Province:</label>
<select name='region' class="w80" disabled='disabled'>
<option value="{region}" selected="selected">{region}</option>
</select>
</div>
<div class="field">
<label>City:</label>
<select name='city' class="w80" disabled='disabled'>
<option value="{city}" selected="selected">{city}</option>
</select>
</div>
</div>
<div class="right-side right w70">
<div class="field left w45">
<label>First Name:</label>
<input type="text" name="first_name" value="{first_name}" class="w80"><br/>
</div>
<div class="field right w45">
<label>Last Name:</label>
<input type="text" name="last_name" value="{last_name}" class="w80">
</div>
<br class="clearall"/>
<div class="field left">
<label>Gender:</label>
<select name="gender" data-value="{gender}" class="w80">
<option value='M'>Male</option>
<option value='F'>Female</option>
<option>-</option>
</select>
</div>
<div class="field left birth_date">
<label>Birth Date:</label>
<%= date_select("user", "birth_date", :use_short_month => true, :start_year => 1900, :end_year => Time.now.year - 18, :order => [:month, :day, :year], :default => -25.years.from_now) %>
</div>
<br class="clearall"/>
<td valign="top" width="33%">
<div class="field">
First Name:<br />
<input type="text" name="first_name" value="{first_name}" class="w80"><br />
</div>
</td>
<td valign="top" width="33%">
<div class="field">
Last Name:<br />
<div class="field">
What instruments can you play?
<div class="profile-instrumentlist w90">
<table class="instrument_selector" width="100%" cellpadding="0" cellspacing="6">
<input type="text" name="last_name" value="{last_name}" class="w80">
</div>
</td>
</tr>
<tr>
<td valign="top">
<div class="field">
Country:<br />
<select name='country' class="w80"><option value='{country}' selected="selected">{country}</option></select><br /><br />
</div>
</td>
<td valign="top">
<div class="field">
Gender:<br />
<select name="gender" data-value="{gender}" class="w80"><option value='M'>Male</option><option value='F'>Female</option><option >-</option></select><br />
<br />
</div>
</td>
<td valign="top">
<div class="field">
Birth Date:<br />
<%= date_select("user", "birth_date", :use_short_month => true, :start_year => 1900, :end_year => Time.now.year - 18, :order => [:month, :day, :year], :default => -25.years.from_now ) %>
</div>
</td>
</tr>
<tr>
<td valign="top">
<div class="field">
State/Province:<br />
<select name='region' class="w80" disabled='disabled'><option value="{region}" selected="selected">{region}</option></select><br /><br />
</div>
</td>
<td rowspan=3 colspan=2 valign="top">
<div class="field">
What instruments can you play?
<div class="profile-instrumentlist w90">
<table class="instrument_selector" width="100%" cellpadding="0" cellspacing="6">
</table>
</div>
</div>
</td>
</tr>
<tr>
<td valign="top">
<div class="field">
City:<br />
<select name='city' class="w80" disabled='disabled'><option value="{city}" selected="selected">{city}</option></select><br /><br />
</div>
</td>
</tr>
</table>
</table>
</div>
</div>
<div class="field">
<input type="checkbox" name="subscribe_email" {subscribe_email} /> I will accept email from JamKazam about this service.
</div>
<div class="right actions">
<a id="account-edit-profile-cancel" href="#" class="button-grey">CANCEL</a>&nbsp;&nbsp;<a id="account-edit-profile-submit" href="#" class="button-orange">UPDATE PROFILE</a>
</div>
</div>
</form>
<br clear="all" />
<div class="right"><a id="account-edit-profile-cancel" href="#" class="button-grey">CANCEL</a>&nbsp;&nbsp;<a id="account-edit-profile-submit" href="#" class="button-orange">UPDATE PROFILE</a></div>
<br clear="all"/>
</div>
<!-- end content wrapper -->
@ -125,6 +111,10 @@
<script type="text/template" id="account-profile-instrument">
<tr data-instrument-id='{id}'>
<td><input type="checkbox" {checked} />{description}</td>
<td align="right" width="50%"><select name="proficiency" class='proficiency_selector'><option value="1">Beginner</option><option value="2">Intermediate</option><option value="3">Expert</option></select></td>
<td align="right" width="50%"><select name="proficiency" class='proficiency_selector'>
<option value="1">Beginner</option>
<option value="2">Intermediate</option>
<option value="3">Expert</option>
</select></td>
</tr>
</script>

View File

@ -22,10 +22,10 @@
<div class="left mt35">
<div class="left w5 ml10 mr10">
<div>
<img id="img-add-track2-input-add" style="cursor:pointer;" src="assets/content/arrow_right_24.png" width="24" height="24" />
<img id="img-add-track2-input-add" style="cursor:pointer;" src="/assets/content/arrow_right_24.png" width="24" height="24" />
</div>
<div class="mt10">
<img id="img-add-track2-input-remove" style="cursor:pointer;" src="assets/content/arrow_left_24.png" width="24" height="24" />
<img id="img-add-track2-input-remove" style="cursor:pointer;" src="/assets/content/arrow_left_24.png" width="24" height="24" />
</div>
</div>
</div>

View File

@ -44,21 +44,21 @@
</div>
</div>
<div class="left">
<div id="track1-input-buttons" class="left w5 ml10 mr10">
<div id="track1-input-buttons" class="left w5 ml10 mr10 mt30">
<div>
<img id="img-track1-input-add" style="cursor:pointer;" src="assets/content/arrow_right_24.png" width="24" height="24" />
<img id="img-track1-input-add" style="cursor:pointer;" src="/assets/content/arrow_right_24.png" width="24" height="24" />
</div>
<div class="mt10">
<img id="img-track1-input-remove" style="cursor:pointer;" src="assets/content/arrow_left_24.png" width="24" height="24" />
<img id="img-track1-input-remove" style="cursor:pointer;" src="/assets/content/arrow_left_24.png" width="24" height="24" />
</div>
</div>
<div class="clearall"></div>
<div id="track2-input-buttons" class="left w5 ml10 mr10 mt45">
<div>
<img id="img-track2-input-add" style="cursor:pointer;" src="assets/content/arrow_right_24.png" width="24" height="24" />
<img id="img-track2-input-add" style="cursor:pointer;" src="/assets/content/arrow_right_24.png" width="24" height="24" />
</div>
<div class="mt10">
<img id="img-track2-input-remove" style="cursor:pointer;" src="assets/content/arrow_left_24.png" width="24" height="24" />
<img id="img-track2-input-remove" style="cursor:pointer;" src="/assets/content/arrow_left_24.png" width="24" height="24" />
</div>
</div>
</div>
@ -68,20 +68,20 @@
<div class="left">Track 1 Input:</div>
<div class="clearall"></div>
<div class="left w100">
<select id="track1-input" class="w100" multiple="multiple" style="height:100%"></select>
<select id="track1-input" class="w100" multiple="multiple" style="height:92px"></select>
</div>
</div>
<div class="left w45 ml20">
<div class="left">Track 1 Instrument:</div>
<div class="clearall"></div>
<div class="left w100">
<select id="track1-instrument" class="w100" multiple="multiple" style="height:100%"></select>
<select id="track1-instrument" class="w100" multiple="multiple" style="height:92px"></select>
</div>
</div>
<div class="clearall"></div>
<div id="track2-details" class="left mt5 w100">
<div class="left mt5 w100">
<div class="left w45">
<div class="left">Track 2 Input:</div>
<div class="clearall"></div>
@ -114,10 +114,10 @@
</div>
<div class="left ml10 mr10 mt25">
<div>
<img id="img-audio-output-add" style="cursor:pointer;" src="assets/content/arrow_right_24.png" width="24" height="24" />
<img id="img-audio-output-add" style="cursor:pointer;" src="/assets/content/arrow_right_24.png" width="24" height="24" />
</div>
<div class="mt10">
<img id="img-audio-output-remove" style="cursor:pointer;" src="assets/content/arrow_left_24.png" width="24" height="24" />
<img id="img-audio-output-remove" style="cursor:pointer;" src="/assets/content/arrow_left_24.png" width="24" height="24" />
</div>
</div>
<div class="left w27">
@ -154,10 +154,10 @@
<div class="left mt55">
<div class="left ml10 mr10">
<div>
<img id="img-voice-input-add" style="cursor:pointer;" src="assets/content/arrow_right_24.png" width="24" height="24" />
<img id="img-voice-input-add" style="cursor:pointer;" src="/assets/content/arrow_right_24.png" width="24" height="24" />
</div>
<div class="mt10">
<img id="img-voice-input-remove" style="cursor:pointer;" src="assets/content/arrow_left_24.png" width="24" height="24" />
<img id="img-voice-input-remove" style="cursor:pointer;" src="/assets/content/arrow_left_24.png" width="24" height="24" />
</div>
</div>
</div>

View File

@ -56,9 +56,9 @@
</select>
</div>
<div class="left">
<input type="radio" name="musician-access-option" id="musician-access-option-false" checked="checked" value="false" />&nbsp;<span class="radio-text">Open</span>&nbsp;&nbsp;
<input type="radio" name="musician-access-option" id="musician-access-option-true" value="true" />&nbsp;<span class="radio-text">By Approval</span>
<div class="left icheckbuttons">
<input type="radio" name="musician-access-option" id="musician-access-option-false" checked="checked" value="false" class="musician-access-false" /><label for="musician-access-option-false" class="radio-text">Open</label>
<input type="radio" name="musician-access-option" id="musician-access-option-true" value="true" class="musician-access-true" /><label for="musician-access-option-true" class="radio-text">By Approval</label>
</div>
</div>
@ -73,9 +73,9 @@
</select>
</div>
<div class="left op50">
<input type="radio" name="fan-chat-option" id="fan-chat-option-true" value="true" disabled="disabled" />&nbsp;<span class="radio-text">Chat</span>&nbsp;&nbsp;
<input type="radio" name="fan-chat-option" id="fan-chat-option-false" checked="checked" value="false" disabled="disabled" />&nbsp;<span class="radio-text">No Fan Chat</span>
<div class="left icheckbuttons">
<input type="radio" name="fan-chat-option" id="fan-chat-option-true" value="true" class="fan-chat-option-true" disabled="disabled" /><label for="fan-chat-option-true" class="radio-text">Chat</label>
<input type="radio" name="fan-chat-option" id="fan-chat-option-false" checked="checked" class="fan-chat-option-false" value="false" disabled="disabled" /><label for="fan-chat-option-false" class="radio-text">No Fan Chat</label>
</div>
</div>
</div>
@ -108,7 +108,7 @@
</div>
<div style="width:78%">
<div class="left mr20">
<div class="left" layout-link="inviteUsers">
<div class="left">
<a class="btn-email-invitation">
<%= image_tag("content/icon_gmail.png", :size => "24x24", :align => "absmiddle") %>
</a>
@ -134,7 +134,7 @@
<div class="right mt5 ml5">Twitter</div>
</div> -->
<div class="left left">
<div class="left" layout-link="inviteUsers">
<div class="left">
<a class="btn-gmail-invitation">
<%= image_tag("content/icon_google.png", :size => "24x24", :align => "absmiddle") %>
</a>
@ -146,8 +146,8 @@
<br clear="all"/>
<!-- terms -->
<div id="divIntellectualProperty">
<div class="terms-checkbox">
<input type="checkbox" id="intellectual-property" />
<div class="terms-checkbox icheckbuttons">
<input type="checkbox" id="intellectual-property" class="intellectual-property" />
</div>
<div id="divTerms" class="terms ml25">
I agree that intellectual property ownership of any musical works created during this session shall be governed by the terms of the <a href="http://creativecommons.org/licenses/by-nc-sa/3.0/" target="_blank">Creative Commons CC BY-NC-SA license</a> in accordance with the <a rel="external" href="http://www.jamkazam.com/corp/terms" target="_blank">JamKazam Terms of Service</a>.

View File

@ -8,40 +8,8 @@
<a onclick="jamClient.FTUESetStatus(true);">No FTUE</a> |
<a layout-link="session-settings">SS</a>
-->
<!-- profile area -->
<div id="profile" class="userinfo">
<!-- avatar -->
<div class="avatar_large">
<img id="header-avatar" />
</div>
<!-- user name -->
<div id="user"></div>
<div class="arrow-down"></div>
<ul class="shortcuts">
<!-- <li><a layout-link="account">Profile</a></li> -->
<li class="account-home"><%= link_to "Account Home", '#/account' %></li>
<li class="identity"><%= link_to "Identity", '#/account/identity' %></li>
<li class="profile"><%= link_to "Profile", '#/account/profile' %></li>
<!--<li class="subscriptions"><%= link_to "Subscriptions", '#/account/subscriptions' %></li> -->
<!-- <li class="payments"><%= link_to "Payments", '#/account/payments' %></li> -->
<li class="audio"><%= link_to "Audio Gear", '#/account/audio' %></li>
<li class="invite-friends"><span class='menuheader'><span class="arrow-right"></span><%= link_to "Invite Friends", '#' %></span>
<ul class="shortcuts-submenu">
<li class="google-invite"><%= link_to "Google", '#' %></li>
<li class="email-invite"><%= link_to "Email", '#' %></li>
</ul>
</li>
<li class="download-app"><%= link_to "Download App", downloads_path, :rel => "external" %></li>
<li class="get-help"><%= link_to "Get Help", 'https://jamkazam.desk.com/', :rel => "external" %></li>
<li class="sign-out"><%= link_to "Sign Out", signout_path, method: "delete" %></li>
</ul>
</div>
<!-- end profile area -->
<%= render "users/user_dropdown" %>
<!-- Templates -->
<script type="text/template" id="template-search-section">

View File

@ -2,32 +2,44 @@
<!-- Grid is the count of the smallest spaces, then
individual spells span those spaces -->
<% if @nativeClient %>
<div layout-grid="2x4" class="grid">
<div type="createSession" layout-grid-position="0,0" layout-grid-rows="1" layout-grid-columns="2"
<div layout-grid="2x12" class="grid">
<div type="createSession" layout-grid-position="0,0" layout-grid-rows="1" layout-grid-columns="4"
layout-link="createSession" class="homecard createsession">
<h2>create session</h2>
<div class="homebox-info"><!-- 4 friends online, 2 currently in sessions --></div>
</div>
<div type="findSession" layout-grid-position="2,0" layout-grid-rows="1" layout-grid-columns="2"
<div type="findSession" layout-grid-position="4,0" layout-grid-rows="1" layout-grid-columns="4"
layout-link="findSession" class="homecard findsession">
<h2>find session</h2>
<div class="homebox-info"><!-- 1 session invitation, 19 public sessions active --></div>
</div>
<div layout-grid-position="0,1" layout-grid-rows="1" layout-grid-columns="1"
<div layout-grid-position="8,0" layout-grid-rows="1" layout-grid-columns="4"
layout-link="feed" class="homecard feed">
<h2>feed</h2>
<div class="homebox-info"><!-- 4 friends online, 2 currently in sessions --></div>
</div>
<div layout-grid-position="0,1" layout-grid-rows="1" layout-grid-columns="3"
layout-link="musicians" class="homecard musicians">
<h2>musicians</h2>
<div class="homebox-info"><!-- 5 followers, 3 following --></div>
</div>
<div layout-grid-position="3,1" layout-grid-rows="1" layout-grid-columns="3"
layout-link="bands" class="homecard bands">
<h2>bands</h2>
<div class="homebox-info"><!-- 1 session invitation, 19 public sessions active --></div>
</div>
<div layout-grid-position="6,1" layout-grid-rows="1" layout-grid-columns="3"
class="homecard profile">
<h2>profile</h2>
<div class="homebox-info"><!-- 5 followers, 3 following --></div>
</div>
<div layout-grid-position="1,1" layout-grid-rows="1" layout-grid-columns="2"
layout-link="feed" class="homecard feed">
<h2>feed</h2>
<div class="homebox-info"><!-- 38 new recordings, 19 sessions open to fans --></div>
</div>
<div layout-grid-position="3,1" layout-grid-rows="1" layout-grid-columns="1"
<div layout-grid-position="9,1" layout-grid-rows="1" layout-grid-columns="3"
layout-link="account" class="homecard account">
<h2>account</h2>

View File

@ -52,10 +52,8 @@
<!-- my tracks -->
<div class="session-mytracks">
<h2>my tracks</h2>
<div id="div-add-track" class="session-add" style="display:block;" mixer-id="{mixerId}">
<a>
<%= image_tag "content/icon_add.png", {:width => 19, :height => 19, :align => "texttop"} %>&nbsp;&nbsp;Add Track
</a>
<div id="track-settings" class="session-add" style="display:block;" layout-link="configure-audio">
<%= image_tag "content/icon_settings_lg.png", {:width => 18, :height => 18} %>&nbsp;&nbsp;Settings
</div>
<div class="session-tracks-scroller">
@ -64,9 +62,6 @@
<div class="voicechat-label">CHAT</div>
<div class="voicechat-gain"></div>
<div class="voicechat-mute enabled" control="mute" mixer-id=""></div>
<div class="voicechat-settings" layout-link="configure-audio">
<%= image_tag "content/icon_settings_lg.png", {:width => 18, :height => 18} %>
</div>
</div>
</div>
</div>
@ -162,9 +157,6 @@
-->
<div class="track-icon-mute {muteClass}" control="mute" mixer-id="{mixerId}">
</div>
<div class="track-icon-settings" layout-link="configure-audio" style="display:none;" mixer-id="{mixerId}">
<%= image_tag "content/icon_settings_lg.png", {:width => 18, :height => 18} %>
</div>
<!-- TODO - connection class from curly param -->
<div mixer-id="{mixerId}_connection" class="track-connection green">CONNECTION</div>
</div>

View File

@ -60,7 +60,7 @@
<br clear="all"/>
<div class="invitation-button-holder">
<div class="left mr20">
<div class="left" layout-link="inviteUsers">
<div class="left">
<a class="btn-email-invitation">
<%= image_tag("content/icon_gmail.png", :size => "24x24", :align => "absmiddle") %>
</a>
@ -68,7 +68,7 @@
<div class="right mt5 ml5">E-mail</div>
</div>
<div class="left left">
<div class="left" layout-link="inviteUsers">
<div class="left">
<a class="btn-gmail-invitation">
<%= image_tag("content/icon_google.png", :size => "24x24", :align => "absmiddle") %>
</a>

View File

@ -0,0 +1,70 @@
<!-- Invitation Dialog -->
<div class="dialog whatsnext-overlay ftue-overlay tall" layout="dialog" layout-id="whatsNext" id="whatsnext-dialog">
<div class="content-head">
<h1>what's next?</h1>
</div>
<div class="ftue-inner">
<div align="center">
<table width="790" cellspacing="20">
<tbody>
<tr>
<td valign="top" bgcolor="#000" class="whatsnext">
<h2>INVITE YOUR FRIENDS</h2>
JamKazam is a very new service, so we don't have a bunch of users yet. This will make it
harder to jump into existing sessions with others for a while. So invite other musicians you
know to join using the buttons below, and then schedule a time to meet up (online) and play!<br><br>
<a href="#" class="facebook-invite"><%= image_tag "content/icon_facebook.png", {:align=>"absmiddle", :height => 24, :width => 24} %>&nbsp;Facebook</a>&nbsp;&nbsp;&nbsp;&nbsp;
<a href="#" class="email-invite"><%= image_tag "content/icon_gmail.png", {:align=>"absmiddle", :height => 24, :width => 24} %>&nbsp;E-mail</a>&nbsp;&nbsp;&nbsp;&nbsp;
<a href="#" class="google-invite"><%= image_tag "content/icon_google.png", {:align=>"absmiddle", :height => 26, :width => 26 } %>&nbsp;Google+</a>
</td>
<td valign="top" bgcolor="#000" class="whatsnext">
<h2>FIND MUSICIANS</h2>
<div class="left mr10">
<%= image_tag "content/ftue_whatsnext_musicians.png", {:height => 115, :width => 107 } %>
</div>
Click the Musicians tile on the home screen to find other musicians in your area. Use the
Message button to say hello, or the Connect button to request a friend connection. Then get
a session set up with each other.
</td>
</tr>
<tr>
<td valign="top" bgcolor="#000" class="whatsnext">
<h2>FIND OR CREATE A SESSION</h2>
Click the Find Session tile on the home screen to see if there are any active public
sessions in your area that you can join. If there aren't, use the Create Session tile to
make your own session.<br><br>
<%= image_tag "content/ftue_whatsnext_create.png", {:height => 67, :width => 313 } %>
</td>
<td valign="top" bgcolor="#000" class="whatsnext">
<h2>WATCH VIDEOS</h2>
Watch tuturial videos on YouTube to learn how to use the key features of the JamKazam
service.
<br><br>
<div class="left f20"><br>
<a purpose="youtube-tutorials" rel="external" href="http://www.youtube.com/channel/UC38nc9MMZgExJAd7ca3rkUA" class="orange">See a List of<br>
Videos »</a></div>
<div class="right mr20">
<a purpose="youtube-tutorials" rel="external" href="http://www.youtube.com/channel/UC38nc9MMZgExJAd7ca3rkUA">
<%= image_tag "content/ftue_whatsnext_videos.png", {:height => 90, :width => 152 } %>
</a>
</div>
</td>
</tr>
</tbody>
</table>
<input type="checkbox" id="show_whats_next"> Don't show this again
&nbsp;&nbsp;&nbsp;
<a href="#" class="button-orange" layout-action="close">CLOSE</a><br>
<br>
</div>
</div>
</div>
</div>

View File

@ -1,10 +1,10 @@
<div class="curtain" style="width:100%; height:100%; z-index:9999;">
<div class="splash">
<img src="assets/header/logo.png"/>
<img src="/assets/header/logo.png"/>
<p>Connecting...</p>
</div>
</div>
<div class="dialog-overlay op70" style="display:none; width:100%; height:100%; z-index:99;"></div>
<div class="dialog-overlay op70" style="display:none; width:100%; height:100%; z-index:99;"></div>
<%= render "header" %>
<%= render "home" %>
@ -30,6 +30,7 @@
<%= render "account_profile_avatar" %>
<%= render "account_audio_profile" %>
<%= render "invitationDialog" %>
<%= render "whatsNextDialog" %>
<%= render "notify" %>
<%= render "client_update" %>
<%= render "banner" %>
@ -86,12 +87,19 @@
// Some things can't be initialized until we're connected. Put them here.
function _initAfterConnect() {
var invitationDialog = new JK.InvitationDialog(JK.app);
invitationDialog.initialize();
var userDropdown = new JK.UserDropdown(JK.app);
JK.UserDropdown = userDropdown;
userDropdown.initialize(invitationDialog);
var header = new JK.Header(JK.app);
JK.Header = header;
header.initialize();
var sidebar = new JK.Sidebar(JK.app);
sidebar.initialize();
sidebar.initialize(invitationDialog);
var homeScreen = new JK.HomeScreen(JK.app);
homeScreen.initialize();
@ -109,7 +117,7 @@
accountProfileScreen.initialize();
var accountProfileAvatarScreen = new JK.AccountProfileAvatarScreen(JK.app);
accountProfileAvatarScreen.initialize();
accountProfileAvatarScreen.initialize(userDropdown);
var accountAudioProfile = new JK.AccountAudioProfile(JK.app);
accountAudioProfile.initialize();
@ -122,7 +130,7 @@
JK.Banner.initialize();
var createSessionScreen = new JK.CreateSessionScreen(JK.app);
createSessionScreen.initialize();
createSessionScreen.initialize(invitationDialog);
var findSessionScreen = new JK.FindSessionScreen(JK.app);
var sessionLatency = null;
@ -136,6 +144,10 @@
var sessionSettingsDialog = new JK.SessionSettingsDialog(JK.app, sessionScreen);
sessionSettingsDialog.initialize();
var whatsNextDialog = new JK.WhatsNextDialog(JK.app);
whatsNextDialog.initialize(invitationDialog);
var ftueWizard = new JK.FtueWizard(JK.app);
ftueWizard.initialize();

View File

@ -9,6 +9,7 @@
<!-- THIS NEEDS TO BE IN FRONT OF ANY OTHER JAVASCRIPT INCLUDES ACCORDING TO BUGSNAG -->
<script src="//d2wy8f7a9ursnm.cloudfront.net/bugsnag-1.0.9.min.js" data-apikey="<%= Rails.application.config.bugsnag_key %>"></script>
<% end %>
<%= include_gon(:init => true) %>
<%= javascript_include_tag "corp/corporate" %>
<%= csrf_meta_tags %>
</head>

View File

@ -12,7 +12,7 @@
<!-- THIS NEEDS TO BE IN FRONT OF ANY OTHER JAVASCRIPT INCLUDES ACCORDING TO BUGSNAG -->
<script src="//d2wy8f7a9ursnm.cloudfront.net/bugsnag-1.0.9.min.js" data-apikey="<%= Rails.application.config.bugsnag_key %>"></script>
<% end %>
<%= include_gon %>
<%= include_gon(:init => true) %>
<%= csrf_meta_tags %>
</head>
<body>

View File

@ -0,0 +1,83 @@
<!DOCTYPE html>
<html>
<head>
<title><%= full_title(yield(:title)) %></title>
<!--[if IE]>
<link rel="stylesheet" type="text/css" href="css/ie.css" media="screen, projection"/>
<![endif]-->
<link href='http://fonts.googleapis.com/css?family=Raleway:100,200,300,400,500,600,700' rel='stylesheet' type='text/css'>
<%= stylesheet_link_tag "web/web", media: "all" %>
<% if bugsnag? %>
<!-- THIS NEEDS TO BE IN FRONT OF ANY OTHER JAVASCRIPT INCLUDES ACCORDING TO BUGSNAG -->
<script src="//d2wy8f7a9ursnm.cloudfront.net/bugsnag-1.0.9.min.js" data-apikey="<%= Rails.application.config.bugsnag_key %>"></script>
<% end %>
<%= include_gon(:init => true) %>
<%= csrf_meta_tags %>
</head>
<body class="web">
<%= javascript_include_tag "web/web" %>
<div class="dialog-overlay op70" style="display:none; width:100%; height:100%; z-index:99;"></div>
<div id="web-container">
<div class="wrapper">
<div class="header">
<div class="logo-home">
<%= link_to root_path do %>
<%= image_tag("web/logo_home.png", :alt => "JamKazam logo", :size => "298x54") %>
<% end %>
</div>
</div>
<br clear="all">
<div class="black-bar">
<div class="black-bar-inner">
<%= render "users/user_dropdown" %>
<%= yield %>
</div>
</div>
<div class="after-black-bar">
<%= yield(:after_black_bar) %>
</div>
<div id="footer-container">
<%= render "clients/footer" %>
</div>
</div>
<%= render "clients/invitationDialog" %>
<script type="text/javascript">
$(function () {
JK = JK || {};
<% if current_user %>
JK.currentUserId = '<%= current_user.id %>';
<% else %>
JK.currentUserId = null;
<% end %>
if (JK.currentUserId) {
JK.app = JK.JamKazam();
JK.app.initialize({inClient: false, layoutOpts: {layoutFooter: false}});
var invitationDialog = new JK.InvitationDialog(JK.app);
invitationDialog.initialize();
var userDropdown = new JK.UserDropdown(JK.app);
userDropdown.initialize(invitationDialog);
}
})
</script>
</div>
<%= render "shared/ga" %>
<!-- version info: <%= version %> -->
</body>
</html>

View File

@ -66,7 +66,7 @@
<br>
<div align="center"><span class="white"><strong>Not a member?</strong></span> Join JamKazam for free:<br>
<br>
<a href="/signup" class="button-orange">REGISTER NOW</a>
<a href="/signup" rel="external" class="button-orange">REGISTER NOW</a>
</div>
<!-- end right column -->

View File

@ -1,3 +1,46 @@
<script type="text/template" id="client-download-link">
<div align="center" class="client-download {{data.emphasis}}"><a href="{{data.uri}}" class="button-orange m0">DOWNLOAD JAMKAZAM SOFTWARE<br/><span class="platform" platform="{{data.platform}}">{{data.platform}}</span></a></div>
<script type="text/template" id="client-download-blurb-contents">
<div class="downloads">
{% if(data.isCongratulations) { %}
<div class="tagline">Congratulations!</div>
<br>
<p>You have successfully registered as a JamKazam musician. To get started playing with others, use the button below to download the JamKazam application through your browser. When the download is complete, open the downloaded file, and follow the on-screen instructions to install the application on your computer.</p>
<br>
{% } else { %}
<div class="tagline">JamKazam for {{data.platformDisplay}}</div><br>
<p>Here are a few of the great things you can do with JamKazam:</p>
<ul>
<li>Play with other musicians from your homes across the Internet as if you were in the same room</li>
<li>Record performances from your online sessions and share them over Facebook, Twitter, email, and more</li>
<li>Live broadcast your sessions so that family, friends, and fans can listen from anywhere</li>
</ul>
<br>
{% } %}
<a href="{{data.uri}}" class="current-os-download" data-platform="{{data.platform}}"></a>
<div class="hidden hidden-images">
<%= image_tag("content/button_download_mac.png", :alt => "download mac", :size => "348x92", "data-purpose" => "mac") %>
<%= image_tag("content/button_download_windows.png", :alt => "download windows", :size => "348x92", "data-purpose" => "windows") %>
<%= image_tag("content/button_download_linux.png", :alt => "download linux", :size => "348x92", "data-purpose" => "linux") %>
</div>
</div>
</script>
<script type="text/template" id="client-download-select-others">
<div class="download-box">
NEED A DIFFERENT VERSION?
<br><br>
<div class="download-others">
<a href="#" data-order="1" data-platform="{{data.platform1}}"></a><br><br>
<a href="#" data-order="2" data-platform="{{data.platform2}}"></a>
</div>
<div class="hidden hidden-images">
<%= image_tag("content/button_download_other_mac.png", :alt => "show download for mac", :size => "300x79", "data-purpose" => "mac") %>
<%= image_tag("content/button_download_other_windows.png", :alt => "show download for windows", :size => "300x79", "data-purpose" => "windows") %>
<%= image_tag("content/button_download_other_linux.png", :alt => "show download for linux", :size => "300x79", "data-purpose" => "linux" ) %>
</div>
</div>
</script>

View File

@ -0,0 +1,43 @@
<!-- used by congrats_musician, and downloads -->
<div class="w100 ">
<div class="spinner-large"></div>
<div class="w70 left downloads-blurb">
<
</div>
</div>
<div class="w30 left downloads-container">
</div>
<br clear="all">
<% content_for :after_black_bar do %>
<div class="system-requirements w100">
<h3>SYSTEM REQUIREMENTS:</h3><br>
<p>A short summary of requirements follows. For a more detailed explanation of system requirements, please review our <a href="https://jamkazam.desk.com/customer/portal/articles/1288274-minimum-system-requirements">Minimum System Requirements</a> knowledgebase article.</p>
<ul class="windows-requirements">
<li>Windows 64-bit operating system (Win 7 &amp; 8 tested, Win XP and Vista like to work but not officially supported</li>
<li>Dual-core processor or higher</li>
<li>Ethernet port for Internet (we strongly advise that you not use Wi-Fi)</li>
<li>74MB hard disk space for app, plus any space needed for recordings</li>
<li>Audio interface (best to use an audio interface device that gets your music into your computer, else can use built-in mic &amp; headphones on your computer to get started)</li>
<li>Broadband Internet service with 1Mbps uplink bandwidth</li>
</ul>
<ul class="mac-requirements">
<li>Mac OS X 64-bit operating system 10.7 or higher</li>
<li>Dual-core processor or higher</li>
<li>Ethernet port for Internet (we strongly advise that you not use Wi-Fi)</li>
<li>74MB hard disk space for app, plus any space needed for recordings</li>
<li>Audio interface (best to use an audio interface device that gets your music into your computer, else can use built-in mic &amp; headphones on your computer to get started)</li>
<li>Broadband Internet service with 1Mbps uplink bandwidth</li>
</ul>
<ul class="linux-requirements">
<li>Linux is not yet supported</li>
</ul>
</div>
<%end%>
<%= render "users/download_templates" %>

View File

@ -0,0 +1,39 @@
<div id="profile" class="userinfo">
<% if signed_in? %>
<!-- profile area -->
<!-- avatar -->
<div class="avatar_large">
<img id="header-avatar" />
</div>
<!-- user name -->
<div id="user"></div>
<div class="arrow-down"></div>
<ul class="shortcuts">
<!-- <li><a layout-link="account">Profile</a></li> -->
<li class="account-home"><%= link_to "Account Home", '/client#/account' %></li>
<li class="identity"><%= link_to "Identity", '/client#/account/identity' %></li>
<li class="profile"><%= link_to "Profile", '/client#/account/profile' %></li>
<!--<li class="subscriptions"><%= link_to "Subscriptions", '/client#/account/subscriptions' %></li> -->
<!-- <li class="payments"><%= link_to "Payments", '/client#/account/payments' %></li> -->
<li class="audio"><%= link_to "Audio Gear", '/client#/account/audio' %></li>
<li class="invite-friends"><span class='menuheader'><span class="arrow-right"></span><%= link_to "Invite Friends", '#' %></span>
<ul class="shortcuts-submenu">
<li class="google-invite"><%= link_to "Google", '#' %></li>
<li class="email-invite"><%= link_to "Email", '#' %></li>
</ul>
</li>
<li class="download-app"><%= link_to "Download App", downloads_path, :rel => "external" %></li>
<li class="get-help"><%= link_to "Get Help", 'https://jamkazam.desk.com/', :rel => "external" %></li>
<li class="sign-out"><%= link_to "Sign Out", signout_path, method: "delete" %></li>
</ul>
<!-- end profile area -->
<% else %>
<a class="signin" href="/signin">Sign In</a>
<% end %>
</div>

View File

@ -1,23 +1,10 @@
<% provide(:title, 'Congratulations') %>
<div class="overlay-small">
<!-- header -->
<div class="content-head">
<h1>congratulations</h1>
</div>
<div class="tagline">Congratulations!</div>
<!-- inner wrapper -->
<div class="overlay-inner">
<p>You have successfully registered as a JamKazam fan.</p>
You have successfully registered as a JamKazam fan.
<br />
<br />
<div align="center"><%= link_to "PROCEED TO JAMKAZAM SITE", root_path, :class =>"button-orange m0" %></div>
</div>
<!-- end inner -->
</div>
<div class="proceed"><%= link_to "PROCEED TO JAMKAZAM SITE", root_path, :class =>"button-orange m0" %></div>
<script type="text/javascript">
window.congratulations.initialize(false, jQuery.QueryString["type"]);

View File

@ -1,30 +1,7 @@
<% provide(:title, 'Congratulations') %>
<div class="overlay-small">
<!-- header -->
<div class="content-head">
<h1>congratulations</h1>
</div>
<!-- inner wrapper -->
<div class="overlay-inner">
You have successfully registered as a JamKazam musician.
To get started playing with others, use the button below to download the JamKazam software, then click to open the download and follow the on-screen instructions to install the application on your computer.<br />
<br />
<div align="center" class="downloads spinner-large">
</div>
</div>
<!-- end inner -->
</div>
<%= render "users/downloads" %>
<script type="text/javascript">
window.congratulations.initialize(true, jQuery.QueryString["type"]);
</script>
<%= render "users/download_templates" %>

View File

@ -1,28 +1,7 @@
<% provide(:title, 'Downloads') %>
<div class="overlay-small">
<!-- header -->
<div class="content-head">
<h1>Downloads</h1>
</div>
<!-- inner wrapper -->
<div class="overlay-inner">
To get started playing with others, use the button below to download the JamKazam software, then click to open the download and follow the on-screen instructions to install the application on your computer.<br />
<br />
<div align="center" class="downloads spinner-large">
</div>
</div>
<!-- end inner -->
</div>
<%= render "users/download_templates" %>
<%= render "users/downloads" %>
<script type="text/javascript">
window.JK.Downloads.listClients();
window.JK.Downloads.listClients(false);
</script>

Some files were not shown because too many files have changed in this diff Show More