Merge commit 'dcbaf4d329fac3870b64925a8b89a40ff8ec1843'
|
|
@ -79,7 +79,7 @@ end
|
|||
# gem 'capistrano'
|
||||
|
||||
# To use debugger
|
||||
# gem 'debugger'
|
||||
gem 'debugger'
|
||||
|
||||
group :development, :test do
|
||||
gem 'capybara'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
ActiveAdmin.register JamRuby::IspScoreBatch, :as => 'Isp Score Data' do
|
||||
|
||||
config.sort_order = 'created_at_desc'
|
||||
|
||||
end
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
ActiveAdmin.register JamRuby::ArtifactUpdate do
|
||||
ActiveAdmin.register JamRuby::ArtifactUpdate, :as => 'Artifacts' do
|
||||
menu :label => 'Artifacts'
|
||||
|
||||
config.sort_order = 'product,environment'
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ActiveAdmin.register JamRuby::InvitedUser do
|
||||
ActiveAdmin.register JamRuby::InvitedUser, :as => 'Invited Users' do
|
||||
menu :label => 'Invite Users'
|
||||
|
||||
config.sort_order = 'created_at'
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ActiveAdmin.register JamRuby::User do
|
||||
ActiveAdmin.register JamRuby::User, :as => 'Users' do
|
||||
|
||||
menu :label => 'Jam User'
|
||||
|
||||
|
|
|
|||
|
|
@ -6,15 +6,24 @@ ActiveAdmin.register JamRuby::MusicSessionHistory, :as => 'Music Session History
|
|||
|
||||
controller do
|
||||
def scoped_collection
|
||||
@music_session_histories ||= end_of_association_chain
|
||||
.includes([:user, :band])
|
||||
.order('created_at DESC')
|
||||
if params['admin'].blank? || '1' == params['admin']
|
||||
@music_session_histories ||= end_of_association_chain
|
||||
.includes([:user, :band])
|
||||
.order('created_at DESC')
|
||||
else
|
||||
@music_session_histories ||= end_of_association_chain
|
||||
.joins('INNER JOIN users AS uu ON uu.id = music_sessions_history.user_id')
|
||||
.where(['uu.admin = ?','f'])
|
||||
.includes([:user, :band])
|
||||
.order('created_at DESC')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
index :as => :block do |msh|
|
||||
div :for => msh do
|
||||
h3 "Session ##{msh.music_session_id}: #{msh.created_at.strftime('%b %d %Y, %H:%M')}"
|
||||
h4 "(append URL with ?admin=0 to hide admin sessions)"
|
||||
columns do
|
||||
column do
|
||||
panel 'Session Details' do
|
||||
|
|
|
|||
|
|
@ -11,25 +11,25 @@ describe "Artifact Update" do
|
|||
before { sign_in user }
|
||||
|
||||
describe "crud" do
|
||||
before { visit admin_jam_ruby_artifact_updates_path }
|
||||
it { should have_selector('h2', text: "Jam Ruby Artifact Updates") }
|
||||
before { visit admin_artifacts_path }
|
||||
it { should have_selector('h2', text: "Artifacts") }
|
||||
|
||||
describe "upload artifact" do
|
||||
|
||||
in_directory_with_file(ARTIFACT_FILE)
|
||||
|
||||
before do
|
||||
visit new_admin_jam_ruby_artifact_update_path
|
||||
fill_in "jam_ruby_artifact_update_version", with: "1"
|
||||
fill_in "jam_ruby_artifact_update_environment", with: "public"
|
||||
select('JamClient/Win32', from: "jam_ruby_artifact_update_product")
|
||||
fill_in "jam_ruby_artifact_update_environment", with: "public"
|
||||
attach_file("jam_ruby_artifact_update_uri", ARTIFACT_FILE)
|
||||
visit new_admin_artifact_path
|
||||
fill_in "artifacts_version", with: "1"
|
||||
fill_in "artifacts_environment", with: "public"
|
||||
select('JamClient/Win32', from: "artifacts_product")
|
||||
fill_in "artifacts_environment", with: "public"
|
||||
attach_file("artifacts_uri", ARTIFACT_FILE)
|
||||
click_button "Create Artifact update"
|
||||
end
|
||||
|
||||
it {
|
||||
should have_selector('#main_content .panel:first-child h3', text: "Jam Ruby Artifact Update Details" ) }
|
||||
should have_selector('#main_content .panel:first-child h3', text: "Artifacts Details" ) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ describe InvitedUser do
|
|||
describe "enduser management" do
|
||||
|
||||
# let's go the management page for users
|
||||
before { visit admin_jam_ruby_invited_users_path }
|
||||
it { should have_selector('h2', text: "Jam Ruby Invited Users") }
|
||||
before { visit admin_invited_users_path }
|
||||
it { should have_selector('h2', text: "Invited Users") }
|
||||
|
||||
describe "create service invite" do
|
||||
|
||||
|
|
@ -21,15 +21,13 @@ describe InvitedUser do
|
|||
|
||||
# create a new user
|
||||
UserMailer.deliveries.clear
|
||||
visit new_admin_jam_ruby_invited_user_path
|
||||
fill_in "jam_ruby_invited_user_email", with: "some_silly_guy@jamkazam.com"
|
||||
#fill_in "jam_ruby_invited_user_sender_id", with: "some_silly_guy@jamkazam.com"
|
||||
#fill_in "jam_ruby_invited_user_autofriend", with: "some_silly_guy@jamkazam.com"
|
||||
visit new_admin_invited_user_path
|
||||
fill_in "invited_users_email", with: "some_silly_guy@jamkazam.com"
|
||||
click_button "Create Invited user"
|
||||
|
||||
end
|
||||
|
||||
it { should have_selector('#main_content .panel:first-child h3', text: "Jam Ruby Invited User Details" ); }
|
||||
it { should have_selector('#main_content .panel:first-child h3', text: "Invited Users Details" ); }
|
||||
it { UserMailer.deliveries.length.should == 1 }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE users ADD COLUMN show_whats_next boolean DEFAULT TRUE;
|
||||
|
|
@ -28,6 +28,8 @@ message ClientMessage {
|
|||
MUSICIAN_SESSION_FRESH = 115;
|
||||
MUSICIAN_SESSION_STALE = 116;
|
||||
HEARTBEAT_ACK = 117;
|
||||
JOIN_REQUEST_APPROVED = 118;
|
||||
JOIN_REQUEST_REJECTED = 119;
|
||||
|
||||
TEST_SESSION_MESSAGE = 200;
|
||||
|
||||
|
|
@ -72,6 +74,8 @@ message ClientMessage {
|
|||
optional MusicianSessionFresh musician_session_fresh = 115;
|
||||
optional MusicianSessionStale musician_session_stale = 116;
|
||||
optional HeartbeatAck heartbeat_ack = 117;
|
||||
optional JoinRequestApproved join_request_approved = 118;
|
||||
optional JoinRequestRejected join_request_rejected = 119;
|
||||
|
||||
// Client-Session messages (to/from)
|
||||
optional TestSessionMessage test_session_message = 200;
|
||||
|
|
@ -195,8 +199,32 @@ message MusicianSessionStale {
|
|||
|
||||
message JoinRequest {
|
||||
optional string join_request_id = 1;
|
||||
optional string username = 2;
|
||||
optional string text = 3;
|
||||
optional string session_id = 2;
|
||||
optional string username = 3;
|
||||
optional string photo_url = 4;
|
||||
optional string msg = 5;
|
||||
optional string notification_id = 6;
|
||||
optional string created_at = 7;
|
||||
}
|
||||
|
||||
message JoinRequestApproved {
|
||||
optional string join_request_id = 1;
|
||||
optional string session_id = 2;
|
||||
optional string username = 3;
|
||||
optional string photo_url = 4;
|
||||
optional string msg = 5;
|
||||
optional string notification_id = 6;
|
||||
optional string created_at = 7;
|
||||
}
|
||||
|
||||
message JoinRequestRejected {
|
||||
optional string join_request_id = 1;
|
||||
optional string session_id = 2;
|
||||
optional string username = 3;
|
||||
optional string photo_url = 4;
|
||||
optional string msg = 5;
|
||||
optional string notification_id = 6;
|
||||
optional string created_at = 7;
|
||||
}
|
||||
|
||||
// route_to: session
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ require "will_paginate/active_record"
|
|||
require "action_mailer"
|
||||
require "devise"
|
||||
require "sendgrid"
|
||||
require 'postgres-copy'
|
||||
require "postgres-copy"
|
||||
require "jam_ruby/lib/module_overrides"
|
||||
require "jam_ruby/constants/limits"
|
||||
require "jam_ruby/constants/notification_types"
|
||||
require "jam_ruby/constants/validation_messages"
|
||||
|
|
@ -75,9 +76,10 @@ require "jam_ruby/models/recorded_track"
|
|||
require "jam_ruby/models/mix"
|
||||
require "jam_ruby/models/claimed_recording"
|
||||
require "jam_ruby/models/crash_dump"
|
||||
require "jam_ruby/models/isp_score_batch"
|
||||
|
||||
include Jampb
|
||||
|
||||
module JamRuby
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -9,6 +9,9 @@ module NotificationTypes
|
|||
# session notifications
|
||||
SESSION_INVITATION = "SESSION_INVITATION"
|
||||
SESSION_ENDED = "SESSION_ENDED" # used to remove session-related notification from sidebar
|
||||
JOIN_REQUEST = "JOIN_REQUEST"
|
||||
JOIN_REQUEST_APPROVED = "JOIN_REQUEST_APPROVED"
|
||||
JOIN_REQUEST_REJECTED = "JOIN_REQUEST_REJECTED"
|
||||
|
||||
# musician notifications
|
||||
MUSICIAN_SESSION_JOIN = "MUSICIAN_SESSION_JOIN"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
require 'json'
|
||||
|
||||
class String
|
||||
def is_json?
|
||||
begin
|
||||
!!JSON.parse(self)
|
||||
rescue
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -124,11 +124,22 @@
|
|||
return Jampb::ClientMessage.new(:type => ClientMessage::Type::MUSICIAN_SESSION_STALE, :route_to => CLIENT_TARGET, :musician_session_stale => stale)
|
||||
end
|
||||
|
||||
# create a join request session message
|
||||
def join_request(join_request_id, session_id, username, photo_url, msg, notification_id, created_at)
|
||||
req = Jampb::JoinRequest.new(:join_request_id => join_request_id, :session_id => session_id, :username => username, :photo_url => photo_url, :msg => msg, :notification_id => notification_id, :created_at => created_at)
|
||||
return Jampb::ClientMessage.new(:type => ClientMessage::Type::JOIN_REQUEST, :route_to => SESSION_TARGET_PREFIX + session_id, :join_request => req)
|
||||
end
|
||||
|
||||
# create a user-joined session message
|
||||
def join_request(session_id, join_request_id, username, text)
|
||||
join_request = Jampb::JoinRequest.new(:join_request_id => join_request_id, :username => username, :text => text)
|
||||
return Jampb::ClientMessage.new(:type => ClientMessage::Type::JOIN_REQUEST, :route_to => SESSION_TARGET_PREFIX + session_id, :join_request => join_request)
|
||||
# create a join request approved session message
|
||||
def join_request_approved(join_request_id, session_id, username, photo_url, msg, notification_id, created_at)
|
||||
req_approved = Jampb::JoinRequestApproved.new(:join_request_id => join_request_id, :session_id => session_id, :username => username, :photo_url => photo_url, :msg => msg, :notification_id => notification_id, :created_at => created_at)
|
||||
return Jampb::ClientMessage.new(:type => ClientMessage::Type::JOIN_REQUEST_APPROVED, :route_to => SESSION_TARGET_PREFIX + session_id, :join_request_approved => req_approved)
|
||||
end
|
||||
|
||||
# create a join request rejected session message
|
||||
def join_request_rejected(join_request_id, session_id, username, photo_url, msg, notification_id, created_at)
|
||||
req_rejected = Jampb::JoinRequestRejected.new(:join_request_id => join_request_id, :session_id => session_id, :username => username, :photo_url => photo_url, :msg => msg, :notification_id => notification_id, :created_at => created_at)
|
||||
return Jampb::ClientMessage.new(:type => ClientMessage::Type::JOIN_REQUEST_REJECTED, :route_to => SESSION_TARGET_PREFIX + session_id, :join_request_rejected => req_rejected)
|
||||
end
|
||||
|
||||
# create a test message to send in session
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
module JamRuby
|
||||
class IspScoreBatch < ActiveRecord::Base
|
||||
|
||||
self.primary_key = 'id'
|
||||
self.table_name = 'isp_score_batch'
|
||||
attr_accessible :json_scoring_data
|
||||
|
||||
validates :json_scoring_data, :presence => true
|
||||
|
||||
validate :json_format
|
||||
|
||||
def json_format
|
||||
errors[:json_scoring_data] << "not in json format" unless !json_scoring_data.nil? && json_scoring_data.is_json?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -11,7 +11,7 @@ module JamRuby
|
|||
|
||||
validates :user, :presence => true
|
||||
validates :music_session, :presence => true
|
||||
validates :text, presence: false, no_profanity: true, length: {maximum: 140} # arbitrary decision of 140. the database is at 2000 max on this field
|
||||
validates :text, no_profanity: true, length: {maximum: 140} # arbitrary decision of 140. the database is at 2000 max on this field
|
||||
|
||||
validates_uniqueness_of :user_id, :scope => :music_session_id
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,10 @@ module JamRuby
|
|||
end
|
||||
|
||||
def self.save(music_session_id, user_id, client_id)
|
||||
session_user_history = MusicSessionUserHistory.new()
|
||||
return true if 0 < self.where(:music_session_id => music_session_id,
|
||||
:user_id => user_id,
|
||||
:client_id => client_id).count
|
||||
session_user_history = MusicSessionUserHistory.new
|
||||
session_user_history.music_session_id = music_session_id
|
||||
session_user_history.user_id = user_id
|
||||
session_user_history.client_id = client_id
|
||||
|
|
|
|||
|
|
@ -108,32 +108,46 @@ module JamRuby
|
|||
return ids
|
||||
end
|
||||
|
||||
def format_msg(description, user)
|
||||
def format_msg(description, user = nil)
|
||||
name = ""
|
||||
unless user.nil?
|
||||
name = user.name
|
||||
else
|
||||
name = "Someone"
|
||||
end
|
||||
|
||||
case description
|
||||
when NotificationTypes::FRIEND_UPDATE
|
||||
return "#{user.name} is now "
|
||||
return "#{name} is now "
|
||||
|
||||
when NotificationTypes::FRIEND_REQUEST
|
||||
return "#{user.name} has sent you a friend request."
|
||||
return "#{name} has sent you a friend request."
|
||||
|
||||
when NotificationTypes::FRIEND_REQUEST_ACCEPTED
|
||||
return "#{user.name} has accepted your friend request."
|
||||
return "#{name} has accepted your friend request."
|
||||
|
||||
when NotificationTypes::FRIEND_SESSION_JOIN
|
||||
return "#{user.name} has joined the session."
|
||||
return "#{name} has joined the session."
|
||||
|
||||
when NotificationTypes::MUSICIAN_SESSION_JOIN
|
||||
return "#{user.name} has joined the session."
|
||||
return "#{name} has joined the session."
|
||||
|
||||
when NotificationTypes::MUSICIAN_SESSION_DEPART
|
||||
return "#{user.name} has left the session."
|
||||
return "#{name} has left the session."
|
||||
|
||||
when NotificationTypes::SESSION_INVITATION
|
||||
return "#{user.name} has invited you to a session."
|
||||
return "#{name} has invited you to a session."
|
||||
|
||||
when NotificationTypes::JOIN_REQUEST
|
||||
return "#{name} has requested to join your session."
|
||||
|
||||
when NotificationTypes::JOIN_REQUEST_APPROVED
|
||||
return "#{name} has approved your request to join the session."
|
||||
|
||||
when NotificationTypes::JOIN_REQUEST_REJECTED
|
||||
return "We're sorry, but you cannot join the session at this time."
|
||||
|
||||
# when "social_media_friend_joined"
|
||||
# when "join_request_approved"
|
||||
# when "join_request_rejected"
|
||||
# when "band_invitation"
|
||||
# when "band_invitation_accepted"
|
||||
# when "recording_available"
|
||||
|
|
@ -174,7 +188,7 @@ module JamRuby
|
|||
notification.save
|
||||
|
||||
# (2) create notification
|
||||
notification_msg = format_msg(NotificationTypes::FRIEND_REQUEST, user)
|
||||
notification_msg = format_msg(notification.description, user)
|
||||
msg = @@message_factory.friend_request(friend_request_id, user_id, user.name, user.photo_url, friend_id, notification_msg, notification.id, notification.created_at.to_s)
|
||||
|
||||
# (3) send notification
|
||||
|
|
@ -193,7 +207,7 @@ module JamRuby
|
|||
notification.save
|
||||
|
||||
# (2) create notification
|
||||
notification_msg = format_msg(NotificationTypes::FRIEND_REQUEST_ACCEPTED, friend)
|
||||
notification_msg = format_msg(notification.description, friend)
|
||||
msg = @@message_factory.friend_request_accepted(friend_id, friend.name, friend.photo_url, user_id, notification_msg, notification.id, notification.created_at.to_s)
|
||||
|
||||
# (3) send notification
|
||||
|
|
@ -224,7 +238,6 @@ module JamRuby
|
|||
msg = @@message_factory.musician_session_join(music_session.id, user.id, user.name, user.photo_url)
|
||||
|
||||
# (2) send notification
|
||||
puts "CONNECTION.CLIENT_ID=#{connection.client_id}"
|
||||
@@mq_router.server_publish_to_session(music_session, msg, sender = {:client_id => connection.client_id})
|
||||
end
|
||||
|
||||
|
|
@ -269,15 +282,58 @@ module JamRuby
|
|||
end
|
||||
end
|
||||
|
||||
def send_join_request(music_session, join_request, sender, text)
|
||||
def send_join_request(music_session, join_request, text)
|
||||
|
||||
# (1) save to database
|
||||
notification = Notification.new
|
||||
notification.description = NotificationTypes::JOIN_REQUEST
|
||||
notification.source_user_id = join_request.user.id
|
||||
notification.target_user_id = music_session.creator.id
|
||||
notification.session_id = music_session.id
|
||||
notification.save
|
||||
|
||||
# (2) create notification
|
||||
msg = @@message_factory.join_request(music_session.id, join_request.id, sender.name, text)
|
||||
notification_msg = format_msg(notification.description, join_request.user)
|
||||
msg = @@message_factory.join_request(join_request.id, music_session.id, join_request.user.name, join_request.user.photo_url, notification_msg, notification.id, notification.created_at.to_s)
|
||||
|
||||
# (3) send notification
|
||||
@@mq_router.server_publish_to_session(music_session, msg)
|
||||
@@mq_router.publish_to_user(music_session.creator.id, msg)
|
||||
end
|
||||
|
||||
def send_join_request_approved(music_session, join_request)
|
||||
|
||||
# (1) save to database
|
||||
notification = Notification.new
|
||||
notification.description = NotificationTypes::JOIN_REQUEST_APPROVED
|
||||
notification.source_user_id = music_session.creator.id
|
||||
notification.target_user_id = join_request.user.id
|
||||
notification.session_id = music_session.id
|
||||
notification.save
|
||||
|
||||
# (2) create notification
|
||||
notification_msg = format_msg(notification.description, music_session.creator)
|
||||
msg = @@message_factory.join_request_approved(join_request.id, music_session.id, music_session.creator.name, music_session.creator.photo_url, notification_msg, notification.id, notification.created_at.to_s)
|
||||
|
||||
# (3) send notification
|
||||
@@mq_router.publish_to_user(join_request.user.id, msg)
|
||||
end
|
||||
|
||||
def send_join_request_rejected(music_session, join_request)
|
||||
|
||||
# (1) save to database
|
||||
notification = Notification.new
|
||||
notification.description = NotificationTypes::JOIN_REQUEST_REJECTED
|
||||
notification.source_user_id = music_session.creator.id
|
||||
notification.target_user_id = join_request.user.id
|
||||
notification.session_id = music_session.id
|
||||
notification.save
|
||||
|
||||
# (2) create notification
|
||||
notification_msg = format_msg(notification.description, music_session.creator)
|
||||
msg = @@message_factory.join_request_rejected(join_request.id, music_session.id, music_session.creator.name, music_session.creator.photo_url, notification_msg, notification.id, notification.created_at.to_s)
|
||||
|
||||
# (3) send notification
|
||||
@@mq_router.publish_to_user(join_request.user.id, msg)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe IspScoreBatch do
|
||||
|
||||
let (:score) {IspScoreBatch.new}
|
||||
it "valid json" do
|
||||
score.json_scoring_data = "{}"
|
||||
score.save.should be_true
|
||||
end
|
||||
|
||||
it "no json" do
|
||||
score.save.should be_false
|
||||
end
|
||||
|
||||
it "invalid json" do
|
||||
score.json_scoring_data = "blurp a durp"
|
||||
score.save.should be_false
|
||||
end
|
||||
end
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 7.3 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 808 B |
|
After Width: | Height: | Size: 744 B |
|
After Width: | Height: | Size: 150 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 542 B |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 486 B |
|
After Width: | Height: | Size: 2.9 KiB |
|
|
@ -22,6 +22,8 @@
|
|||
FRIEND_UPDATE : "FRIEND_UPDATE",
|
||||
SESSION_INVITATION : "SESSION_INVITATION",
|
||||
JOIN_REQUEST : "JOIN_REQUEST",
|
||||
JOIN_REQUEST_APPROVED : "JOIN_REQUEST_APPROVED",
|
||||
JOIN_REQUEST_REJECTED : "JOIN_REQUEST_REJECTED",
|
||||
FRIEND_REQUEST : "FRIEND_REQUEST",
|
||||
FRIEND_REQUEST_ACCEPTED : "FRIEND_REQUEST_ACCEPTED",
|
||||
TEST_SESSION_MESSAGE : "TEST_SESSION_MESSAGE",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@
|
|||
|
||||
function navToAccount() {
|
||||
resetForm();
|
||||
window.location = '#/account';
|
||||
window.location = '/client#/account';
|
||||
}
|
||||
|
||||
function handleUpdateEmail() {
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
(function(context,$) {
|
||||
|
||||
"use strict";
|
||||
|
||||
context.JK = context.JK || {};
|
||||
context.JK.AlertDialog = function(app, okButtonText, message, sessionId, callback) {
|
||||
|
||||
var logger = context.JK.logger;
|
||||
|
||||
function events() {
|
||||
$('#btn-alert-ok').unbind("click");
|
||||
$('#btn-alert-ok').click(function(evt) {
|
||||
callback(sessionId);
|
||||
});
|
||||
|
||||
$('#btn-alert-cancel').unbind("click");
|
||||
$('#btn-alert-cancel').click(function(evt) {
|
||||
app.layout.closeDialog('alert');
|
||||
});
|
||||
}
|
||||
|
||||
function initialize() {
|
||||
events();
|
||||
$('#btn-alert-ok').text(okButtonText);
|
||||
$('#alert-message').html(message);
|
||||
}
|
||||
|
||||
this.initialize = initialize;
|
||||
|
||||
};
|
||||
})(window,jQuery);
|
||||
|
|
@ -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 .
|
||||
|
|
|
|||
|
|
@ -273,17 +273,17 @@
|
|||
}
|
||||
|
||||
function isChatInput(id) {
|
||||
// copy the arrays since $.grep modifies them
|
||||
// copy the arrays
|
||||
var chatOtherUnassignedListCopy = chatOtherUnassignedList;
|
||||
var chatOtherAssignedListCopy = chatOtherAssignedList;
|
||||
|
||||
// is this input in the unassigned list?
|
||||
$.grep(chatOtherUnassignedListCopy, function(n,i){
|
||||
chatOtherUnassignedListCopy = $.grep(chatOtherUnassignedListCopy, function(n,i){
|
||||
return n.chat && n.id === id;
|
||||
});
|
||||
|
||||
// is this input in the assigned list?
|
||||
$.grep(chatOtherAssignedListCopy, function(n,i){
|
||||
chatOtherAssignedListCopy = $.grep(chatOtherAssignedListCopy, function(n,i){
|
||||
return n.chat && n.id === id;
|
||||
});
|
||||
|
||||
|
|
@ -332,6 +332,7 @@
|
|||
// add each unused music input if it doesn't already exist
|
||||
$('#audio-inputs-unused > option').each(function() {
|
||||
if ($('#voice-inputs-unused > option[value="' + this.value + '"]').length === 0) {
|
||||
logger.debug("Appending " + this.value + " to the unused voice input box.");
|
||||
$('#voice-inputs-unused').append('<option value="' + this.value + '">' + this.text + '</option>');
|
||||
}
|
||||
});
|
||||
|
|
@ -343,6 +344,7 @@
|
|||
// if this input is not already in the available music inputs box and the selected input is not chat input, add
|
||||
// it to the unused music inputs box
|
||||
if ($('#audio-inputs-unused > option[value="' + this.value + '"]').length === 0 && !isChatInput(this.value)) {
|
||||
logger.debug("Appending " + this.value + " to the unused audio input box.");
|
||||
$('#audio-inputs-unused').append('<option value="' + this.value + '">' + this.text + '</option>');
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -106,7 +106,6 @@
|
|||
$('#btn-send-invitation').show();
|
||||
$('#btn-next-invitation').hide();
|
||||
clearTextFields();
|
||||
|
||||
app.layout.showDialog('inviteUsers')
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,29 @@
|
|||
var self = this;
|
||||
var logger = context.JK.logger;
|
||||
|
||||
function createJoinRequest(joinRequest) {
|
||||
logger.debug("joinRequest=" + JSON.stringify(joinRequest));
|
||||
return $.ajax({
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
url: '/api/join_requests',
|
||||
contentType: 'application/json',
|
||||
processData: false,
|
||||
data: JSON.stringify(joinRequest)
|
||||
});
|
||||
}
|
||||
|
||||
function updateJoinRequest(joinRequestId, isApproved) {
|
||||
return $.ajax({
|
||||
type: "PUT",
|
||||
dataType: "json",
|
||||
url: '/api/join_requests/' + joinRequestId,
|
||||
contentType: 'application/json',
|
||||
processData: false,
|
||||
data: JSON.stringify({"approved": isApproved})
|
||||
});
|
||||
}
|
||||
|
||||
function updateSession(id, newSession, onSuccess) {
|
||||
logger.debug('Rest.updateSession');
|
||||
return $.ajax('/api/sessions/' + id, {
|
||||
|
|
@ -270,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;
|
||||
}
|
||||
|
|
@ -297,6 +335,9 @@
|
|||
this.userDownloadedClient = userDownloadedClient;
|
||||
this.userCertifiedGear = userCertifiedGear;
|
||||
this.userSocialPromoted = userSocialPromoted;
|
||||
this.createJoinRequest = createJoinRequest;
|
||||
this.updateJoinRequest = updateJoinRequest;
|
||||
this.updateUser = updateUser;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -279,14 +282,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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -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)
|
||||
|
|
@ -7,6 +7,4 @@
|
|||
//= require ga
|
||||
//= require jam_rest
|
||||
//= require landing/init
|
||||
//= require landing/signup
|
||||
//= require landing/downloads
|
||||
//= require landing/congratulations
|
||||
//= require landing/signup
|
||||
|
|
@ -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',
|
||||
|
|
@ -401,7 +411,8 @@
|
|||
function closeDialog(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 +467,42 @@
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
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) {
|
||||
openDialogs.pop();
|
||||
}
|
||||
|
||||
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 +582,7 @@
|
|||
|
||||
this.notify = function(message, descriptor) {
|
||||
var $notify = $('[layout="notify"]');
|
||||
|
||||
|
||||
if (notifyQueue.length === 0) {
|
||||
firstNotification = true;
|
||||
setNotificationInfo(message, descriptor);
|
||||
|
|
@ -621,6 +663,20 @@
|
|||
$('#cancel-button', $notify).html("CANCEL");
|
||||
}
|
||||
}
|
||||
|
||||
if (descriptor.cancel_callback !== undefined) {
|
||||
$('#cancel-button', $notify).click(function() {
|
||||
if (descriptor.cancel_callback_args) {
|
||||
logger.debug("descriptor.cancel_callback_args=" + descriptor.cancel_callback_args);
|
||||
descriptor.cancel_callback(descriptor.cancel_callback_args);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
descriptor.cancel_callback();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
$('#ok-button', $notify).html("OKAY");
|
||||
|
|
|
|||
|
|
@ -171,7 +171,6 @@
|
|||
}
|
||||
|
||||
function sessionChanged() {
|
||||
logger.debug("sessionChanged()");
|
||||
|
||||
// TODO - in the specific case of a user changing their tracks using the configureTrack dialog,
|
||||
// this event appears to fire before the underlying mixers have updated. I have no event to
|
||||
|
|
@ -212,7 +211,6 @@
|
|||
}
|
||||
|
||||
function _initDialogs() {
|
||||
logger.debug("Calling _initDialogs");
|
||||
configureTrackDialog.initialize();
|
||||
addTrackDialog.initialize();
|
||||
addNewGearDialog.initialize();
|
||||
|
|
@ -437,8 +435,6 @@
|
|||
});
|
||||
});
|
||||
|
||||
logger.debug("416-myTracks.length=" + myTracks.length);
|
||||
|
||||
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);
|
||||
|
|
@ -637,6 +633,20 @@
|
|||
mixerId = mixerId + "_vur";
|
||||
}
|
||||
_updateVU(mixerId, vuVal);
|
||||
} else if (eventName === 'connection_status') {
|
||||
// Connection Quality Change
|
||||
var connectionClass = 'green';
|
||||
if (value < 7) {
|
||||
connectionClass = 'yellow';
|
||||
}
|
||||
if (value < 4) {
|
||||
connectionClass = 'red';
|
||||
}
|
||||
|
||||
var $connection = $('[mixer-id="' + mixerId + '_connection"]');
|
||||
$connection.removeClass('green yellow red');
|
||||
$connection.addClass(connectionClass);
|
||||
|
||||
} else if (eventName === 'add' || eventName === 'remove') {
|
||||
//logger.dbg('non-vu event: ' + eventName + ',' + mixerId + ',' + value);
|
||||
|
||||
|
|
@ -649,7 +659,7 @@
|
|||
} else {
|
||||
// Examples of other events
|
||||
// Add media file track: "add", "The_Abyss_4T", 0
|
||||
logger.debug('non-vu event: ' + eventName + ',' + mixerId + ',' + value);
|
||||
logger.dbg('non-vu event: ' + eventName + ',' + mixerId + ',' + value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -673,7 +683,6 @@
|
|||
function deleteTrack(evt) {
|
||||
var trackId = $(evt.currentTarget).attr("track-id");
|
||||
sessionModel.deleteTrack(sessionId, trackId);
|
||||
logger.debug("643-myTracks.length=" + myTracks.length);
|
||||
}
|
||||
|
||||
function _toggleVisualMuteControl($control, muting) {
|
||||
|
|
@ -818,6 +827,7 @@
|
|||
app.bindScreen('session', screenBindings);
|
||||
};
|
||||
|
||||
|
||||
this.tracks = tracks;
|
||||
|
||||
this.getCurrentSession = function() {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@
|
|||
context.JK = context.JK || {};
|
||||
context.JK.SessionList = function(app) {
|
||||
var logger = context.JK.logger;
|
||||
var termsDialog;
|
||||
var rest = context.JK.Rest();
|
||||
|
||||
var LATENCY = {
|
||||
GOOD : {description: "GOOD", style: "latency-green", min: 0.0, max: 20.0},
|
||||
MEDIUM : {description: "MEDIUM", style: "latency-yellow", min: 20.0, max: 40.0},
|
||||
|
|
@ -135,14 +136,43 @@
|
|||
|
||||
// wire up the Join Link to the T&Cs dialog
|
||||
var $parentRow = $('tr[id=' + session.id + ']', tbGroup);
|
||||
$('#join-link', $parentRow).click(function(evt) {
|
||||
openTerms(session.id);
|
||||
});
|
||||
|
||||
if (session.approval_required) {
|
||||
$('#join-link', $parentRow).click(function(evt) {
|
||||
openAlert(session.id);
|
||||
});
|
||||
}
|
||||
else {
|
||||
$('#join-link', $parentRow).click(function(evt) {
|
||||
openTerms(session.id);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function openAlert(sessionId) {
|
||||
var alertDialog = new context.JK.AlertDialog(app, "YES",
|
||||
"You must be approved to join this session. Would you like to send a request to join?",
|
||||
sessionId, onCreateJoinRequest);
|
||||
|
||||
alertDialog.initialize();
|
||||
app.layout.showDialog('alert');
|
||||
}
|
||||
|
||||
function onCreateJoinRequest(sessionId) {
|
||||
var joinRequest = {};
|
||||
joinRequest.music_session = sessionId;
|
||||
joinRequest.user = context.JK.currentUserId;
|
||||
rest.createJoinRequest(joinRequest)
|
||||
.done(function(response) {
|
||||
|
||||
}).error(app.ajaxError);
|
||||
|
||||
app.layout.closeDialog('alert');
|
||||
}
|
||||
|
||||
function openTerms(sessionId) {
|
||||
termsDialog = new context.JK.TermsDialog(app, sessionId, onTermsAccepted);
|
||||
var termsDialog = new context.JK.TermsDialog(app, sessionId, onTermsAccepted);
|
||||
termsDialog.initialize();
|
||||
app.layout.showDialog('terms');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
||||
|
|
@ -56,7 +56,7 @@
|
|||
}
|
||||
|
||||
function updateFriendList(response) {
|
||||
$('#sidebar-friend-list li:not(.invite-friend-row').remove();
|
||||
$('#sidebar-friend-list li:not(.invite-friend-row)').remove();
|
||||
|
||||
// show online friends first (sort by first name within online/offline groups)
|
||||
response.sort(function(a, b) {
|
||||
|
|
@ -147,6 +147,8 @@
|
|||
|
||||
// wire up "x" button to delete notification
|
||||
$notification.find('#img-delete-notification').click(deleteNotificationHandler);
|
||||
|
||||
// customize action buttons based on notification type
|
||||
if (type === context.JK.MessageType.FRIEND_REQUEST) {
|
||||
var $action_btn = $notification.find('#btn-notification-action');
|
||||
$action_btn.text('ACCEPT');
|
||||
|
|
@ -161,9 +163,26 @@
|
|||
var $action_btn = $notification.find('#btn-notification-action');
|
||||
$action_btn.text('JOIN');
|
||||
$action_btn.click(function() {
|
||||
joinSession({ "session_id": payload.session_id, "notification_id": payload.notification_id });
|
||||
openTerms({ "session_id": payload.session_id, "notification_id": payload.notification_id });
|
||||
});
|
||||
}
|
||||
else if (type === context.JK.MessageType.JOIN_REQUEST) {
|
||||
var $action_btn = $notification.find('#btn-notification-action');
|
||||
$action_btn.text('APPROVE');
|
||||
$action_btn.click(function() {
|
||||
approveJoinRequest({ "join_request_id": payload.join_request_id, "notification_id": payload.notification_id });
|
||||
});
|
||||
}
|
||||
else if (type === context.JK.MessageType.JOIN_REQUEST_APPROVED) {
|
||||
var $action_btn = $notification.find('#btn-notification-action');
|
||||
$action_btn.text('JOIN');
|
||||
$action_btn.click(function() {
|
||||
openTerms({ "session_id": payload.session_id, "notification_id": payload.notification_id });
|
||||
});
|
||||
}
|
||||
else if (type === context.JK.MessageType.JOIN_REQUEST_REJECTED) {
|
||||
$notification.find('#div-actions').hide();
|
||||
}
|
||||
}
|
||||
|
||||
function deleteNotificationHandler(evt) {
|
||||
|
|
@ -314,22 +333,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
function acceptFriendRequest(args) {
|
||||
|
||||
rest.acceptFriendRequest({
|
||||
status : 'accept',
|
||||
friend_request_id : args.friend_request_id
|
||||
}).done(function(response) {
|
||||
deleteNotification(args.notification_id); // delete notification corresponding to this friend request
|
||||
initializeFriendsPanel(); // refresh friends panel when request is accepted
|
||||
}).error(app.ajaxError);
|
||||
}
|
||||
|
||||
function joinSession(args) {
|
||||
context.location = "#/session/" + args.session_id;
|
||||
deleteNotification(args.notification_id);
|
||||
}
|
||||
|
||||
// default handler for incoming notification
|
||||
function handleNotification(payload, type) {
|
||||
var sidebarText;
|
||||
|
|
@ -406,11 +409,30 @@
|
|||
|
||||
$('.sidebar .invite-friend-row').hoverIntent(inviteHoverIn, inviteHoverOut);
|
||||
|
||||
// $('#sidebar-div').mouseleave(function(evt) {
|
||||
// hideSearchResults();
|
||||
// });
|
||||
registerFriendUpdate();
|
||||
registerFriendRequest();
|
||||
registerFriendRequestAccepted();
|
||||
registerMusicianSessionJoin();
|
||||
registerMusicianSessionDepart();
|
||||
registerFriendSessionJoin();
|
||||
registerSessionInvitation();
|
||||
registerJoinRequest();
|
||||
registerJoinRequestApproved();
|
||||
registerJoinRequestRejected();
|
||||
|
||||
// wire up FRIEND_UPDATE handler
|
||||
// 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;
|
||||
});
|
||||
}
|
||||
|
||||
function registerFriendUpdate() {
|
||||
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.FRIEND_UPDATE, function(header, payload) {
|
||||
logger.debug("Handling FRIEND_UPDATE msg " + JSON.stringify(payload));
|
||||
|
||||
|
|
@ -426,9 +448,9 @@
|
|||
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
|
||||
});
|
||||
});
|
||||
//////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
// wire up FRIEND_REQUEST handler
|
||||
function registerFriendRequest() {
|
||||
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.FRIEND_REQUEST, function(header, payload) {
|
||||
logger.debug("Handling FRIEND_REQUEST msg " + JSON.stringify(payload));
|
||||
|
||||
|
|
@ -447,9 +469,20 @@
|
|||
}
|
||||
);
|
||||
});
|
||||
//////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
// wire up FRIEND_REQUEST_ACCEPTED handler
|
||||
function acceptFriendRequest(args) {
|
||||
|
||||
rest.acceptFriendRequest({
|
||||
status : 'accept',
|
||||
friend_request_id : args.friend_request_id
|
||||
}).done(function(response) {
|
||||
deleteNotification(args.notification_id); // delete notification corresponding to this friend request
|
||||
initializeFriendsPanel(); // refresh friends panel when request is accepted
|
||||
}).error(app.ajaxError);
|
||||
}
|
||||
|
||||
function registerFriendRequestAccepted() {
|
||||
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.FRIEND_REQUEST_ACCEPTED, function(header, payload) {
|
||||
logger.debug("Handling FRIEND_REQUEST_ACCEPTED msg " + JSON.stringify(payload));
|
||||
|
||||
|
|
@ -465,9 +498,9 @@
|
|||
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
|
||||
});
|
||||
});
|
||||
//////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
// wire up MUSICIAN_SESSION_JOIN handler
|
||||
function registerMusicianSessionJoin() {
|
||||
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.MUSICIAN_SESSION_JOIN, function(header, payload) {
|
||||
logger.debug("Handling MUSICIAN_SESSION_JOIN msg " + JSON.stringify(payload));
|
||||
|
||||
|
|
@ -478,9 +511,9 @@
|
|||
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
|
||||
});
|
||||
});
|
||||
//////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
// wire up MUSICIAN_SESSION_DEPART handler
|
||||
function registerMusicianSessionDepart() {
|
||||
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.MUSICIAN_SESSION_DEPART, function(header, payload) {
|
||||
logger.debug("Handling MUSICIAN_SESSION_DEPART msg " + JSON.stringify(payload));
|
||||
|
||||
|
|
@ -491,9 +524,9 @@
|
|||
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
|
||||
});
|
||||
});
|
||||
//////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
// wire up MUSICIAN_SESSION_DEPART handler
|
||||
function registerFriendSessionJoin() {
|
||||
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.FRIEND_SESSION_JOIN, function(header, payload) {
|
||||
logger.debug("Handling FRIEND_SESSION_JOIN msg " + JSON.stringify(payload));
|
||||
|
||||
|
|
@ -504,9 +537,9 @@
|
|||
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
|
||||
});
|
||||
});
|
||||
//////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
// wire up SESSION_INVITATION handler
|
||||
function registerSessionInvitation() {
|
||||
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.SESSION_INVITATION, function(header, payload) {
|
||||
logger.debug("Handling SESSION_INVITATION msg " + JSON.stringify(payload));
|
||||
|
||||
|
|
@ -538,28 +571,104 @@
|
|||
},
|
||||
{
|
||||
"ok_text": "JOIN SESSION",
|
||||
"ok_callback": joinSession,
|
||||
"ok_callback": openTerms,
|
||||
"ok_callback_args": { "session_id": payload.session_id, "notification_id": payload.notification_id }
|
||||
}
|
||||
);
|
||||
});
|
||||
//////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
// watch for Invite More Users events
|
||||
$('#sidebar-div .btn-email-invitation').click(function() {
|
||||
invitationDialog.showEmailDialog();
|
||||
});
|
||||
function openTerms(args) {
|
||||
var termsDialog = new context.JK.TermsDialog(app, args, onTermsAccepted);
|
||||
termsDialog.initialize();
|
||||
app.layout.showDialog('terms');
|
||||
}
|
||||
|
||||
$('#sidebar-div .btn-gmail-invitation').click(function() {
|
||||
invitationDialog.showGoogleDialog();
|
||||
function onTermsAccepted(args) {
|
||||
deleteNotification(args.notification_id);
|
||||
context.location = '#/session/' + args.session_id;
|
||||
}
|
||||
|
||||
function registerJoinRequest() {
|
||||
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.JOIN_REQUEST, function(header, payload) {
|
||||
logger.debug("Handling JOIN_REQUEST msg " + JSON.stringify(payload));
|
||||
|
||||
handleNotification(payload, header.type);
|
||||
|
||||
// display notification
|
||||
app.notify({
|
||||
"title": "New Join Request",
|
||||
"text": payload.msg,
|
||||
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
|
||||
},
|
||||
{
|
||||
"ok_text": "APPROVE",
|
||||
"ok_callback": approveJoinRequest,
|
||||
"ok_callback_args": { "join_request_id": payload.join_request_id, "notification_id": payload.notification_id },
|
||||
"cancel_text": "REJECT",
|
||||
"cancel_callback": rejectJoinRequest,
|
||||
"cancel_callback_args": { "join_request_id": payload.join_request_id, "notification_id": payload.notification_id }
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
this.initialize = function() {
|
||||
function approveJoinRequest(args) {
|
||||
rest.updateJoinRequest(args.join_request_id, true)
|
||||
.done(function(response) {
|
||||
deleteNotification(args.notification_id);
|
||||
}).error(app.ajaxError);
|
||||
}
|
||||
|
||||
function rejectJoinRequest(args) {
|
||||
rest.updateJoinRequest(args.join_request_id, false)
|
||||
.done(function(response) {
|
||||
deleteNotification(args.notification_id);
|
||||
}).error(app.ajaxError);
|
||||
}
|
||||
|
||||
function registerJoinRequestApproved() {
|
||||
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.JOIN_REQUEST_APPROVED, function(header, payload) {
|
||||
logger.debug("Handling JOIN_REQUEST_APPROVED msg " + JSON.stringify(payload));
|
||||
|
||||
handleNotification(payload, header.type);
|
||||
|
||||
// display notification
|
||||
app.notify({
|
||||
"title": "Join Request Approved",
|
||||
"text": payload.msg,
|
||||
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
|
||||
},
|
||||
{
|
||||
"ok_text": "JOIN SESSION",
|
||||
"ok_callback": openTerms,
|
||||
"ok_callback_args": { "session_id": payload.session_id, "notification_id": payload.notification_id }
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function registerJoinRequestRejected() {
|
||||
context.JK.JamServer.registerMessageCallback(context.JK.MessageType.JOIN_REQUEST_REJECTED, function(header, payload) {
|
||||
logger.debug("Handling JOIN_REQUEST_REJECTED msg " + JSON.stringify(payload));
|
||||
|
||||
handleNotification(payload, header.type);
|
||||
|
||||
// display notification
|
||||
app.notify({
|
||||
"title": "Join Request Rejected",
|
||||
"text": payload.msg,
|
||||
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
this.initialize = function(invitationDialogInstance) {
|
||||
events();
|
||||
initializeFriendsPanel();
|
||||
initializeChatPanel();
|
||||
initializeNotificationsPanel();
|
||||
invitationDialog = invitationDialogInstance;
|
||||
};
|
||||
};
|
||||
})(window,jQuery);
|
||||
|
|
@ -3,13 +3,13 @@
|
|||
"use strict";
|
||||
|
||||
context.JK = context.JK || {};
|
||||
context.JK.TermsDialog = function(app, sessionId, callback) {
|
||||
context.JK.TermsDialog = function(app, args, callback) {
|
||||
|
||||
var logger = context.JK.logger;
|
||||
|
||||
function events() {
|
||||
$('#btn-accept-terms').click(function(evt) {
|
||||
callback(sessionId);
|
||||
callback(args);
|
||||
});
|
||||
|
||||
$('#btn-cancel-terms').click(function(evt) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -297,7 +297,12 @@
|
|||
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;
|
||||
}
|
||||
|
||||
evt.preventDefault();
|
||||
var href = $(this).attr("href");
|
||||
if (href) {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
congratulations.initialize = function initialize(musician, registrationType) {
|
||||
if(musician) {
|
||||
context.JK.Downloads.listClients();
|
||||
context.JK.Downloads.listClients(true);
|
||||
}
|
||||
|
||||
if(registrationType) {
|
||||
|
|
@ -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)
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
padding-top: 10px;
|
||||
border-top:solid 1px #444;
|
||||
height:13px;
|
||||
display:none;
|
||||
}
|
||||
|
||||
#copyright {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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%);
|
||||
}
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -18,6 +18,15 @@
|
|||
}
|
||||
|
||||
|
||||
.audio-devices {
|
||||
font-family:"Raleway", arial, sans-serif;
|
||||
border:none;
|
||||
-webkit-box-shadow: inset 2px 2px 3px 0px #888;
|
||||
box-shadow: inset 2px 2px 3px 0px #888;
|
||||
color:#666;
|
||||
}
|
||||
|
||||
|
||||
.track {
|
||||
width:70px;
|
||||
height:290px;
|
||||
|
|
@ -440,7 +449,7 @@ table.vu td {
|
|||
left:28px;
|
||||
}
|
||||
|
||||
.track-connection-green {
|
||||
.track-connection {
|
||||
position:absolute;
|
||||
bottom:0px;
|
||||
left:0px;
|
||||
|
|
@ -450,50 +459,22 @@ table.vu td {
|
|||
font-weight:bold;
|
||||
font-size:8px;
|
||||
text-align:center;
|
||||
overflow:hidden;
|
||||
}
|
||||
.track-connection.green {
|
||||
background-color:#72a43b;
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
.track-connection-yellow {
|
||||
position:absolute;
|
||||
bottom:0px;
|
||||
left:0px;
|
||||
width: 70px;
|
||||
height: 8px;
|
||||
font-family:Arial, Helvetica, sans-serif;
|
||||
font-weight:bold;
|
||||
font-size:8px;
|
||||
text-align:center;
|
||||
.track-connection.yellow {
|
||||
background-color:#cc9900;
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
.track-connection-red {
|
||||
position:absolute;
|
||||
bottom:0px;
|
||||
left:0px;
|
||||
width: 70px;
|
||||
height: 8px;
|
||||
font-family:Arial, Helvetica, sans-serif;
|
||||
font-weight:bold;
|
||||
font-size:8px;
|
||||
text-align:center;
|
||||
.track-connection.red {
|
||||
background-color:#980006;
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
.track-connection-grey {
|
||||
position:absolute;
|
||||
bottom:0px;
|
||||
left:0px;
|
||||
width: 70px;
|
||||
height: 8px;
|
||||
font-family:Arial, Helvetica, sans-serif;
|
||||
font-weight:bold;
|
||||
font-size:8px;
|
||||
text-align:center;
|
||||
.track-connection.grey {
|
||||
background-color:#666;
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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%);
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
*/
|
||||
|
|
@ -30,11 +30,29 @@ class ApiJoinRequestsController < ApiController
|
|||
respond_with @join_request
|
||||
else
|
||||
# send notification
|
||||
Notification.send_join_request(music_session, @join_request, sender, text)
|
||||
Notification.send_join_request(music_session, @join_request, text)
|
||||
respond_with @join_request, :responder => ApiResponder, :location => api_join_request_detail_url(@join_request)
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
@join_request = JoinRequest.find(params[:id])
|
||||
|
||||
if params[:approved]
|
||||
# generate invitation if join request is approved
|
||||
invitation = Invitation.new
|
||||
invitation.sender = current_user
|
||||
invitation.receiver = @join_request.user
|
||||
invitation.music_session = @join_request.music_session
|
||||
invitation.join_request = @join_request
|
||||
invitation.save
|
||||
|
||||
Notification.send_join_request_approved(@join_request.music_session, @join_request)
|
||||
else
|
||||
Notification.send_join_request_rejected(@join_request.music_session, @join_request)
|
||||
end
|
||||
end
|
||||
|
||||
def delete
|
||||
@join_request = JoinRequest.show(params[:id], current_user)
|
||||
@join_request.delete
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ class ApiMusicSessionsController < ApiController
|
|||
bucket = s3.buckets[SampleApp::Application.config.aws_bucket]
|
||||
|
||||
read_url = bucket.objects[uri].url_for(:read,
|
||||
:expires => Time.now + 90.days,
|
||||
:expires => Time.now + 25.years,
|
||||
:'response_content_type' => 'text/csv').to_s
|
||||
@perfdata.update_attribute(:uri, read_url)
|
||||
|
||||
|
|
|
|||
|
|
@ -65,6 +65,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
|
||||
|
||||
|
|
@ -420,13 +422,14 @@ class ApiUsersController < ApiController
|
|||
end
|
||||
|
||||
def isp_scoring
|
||||
if request.post?
|
||||
data = request.body.read
|
||||
User.connection.execute("INSERT INTO isp_score_batch(json_scoring_data) VALUES ('#{data}')")
|
||||
data = request.body.read
|
||||
score = IspScoreBatch.new
|
||||
score.json_scoring_data = data
|
||||
if score.save
|
||||
render :text => 'scoring recorded'
|
||||
return
|
||||
else
|
||||
render :text => "score invalid: #{score.errors.inspect}", status:422
|
||||
end
|
||||
render :nothing => true
|
||||
end
|
||||
|
||||
################# AVATAR #####################
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||