This commit is contained in:
Seth Call 2014-01-25 14:19:12 -06:00
commit e63e718091
97 changed files with 1380 additions and 529 deletions

3
.gitignore vendored
View File

@ -1,4 +1,5 @@
.idea
*~
*.swp
HTML
HTML
.DS_Store

View File

@ -91,4 +91,6 @@ music_session_constraints.sql
mixes_drop_manifest_add_retry.sql
music_sessions_unlogged.sql
integrate_icecast_into_sessions.sql
ms_recording_anonymous_likes.sql
ms_user_history_add_instruments.sql
icecast_config_changed.sql

View File

@ -0,0 +1,23 @@
alter table music_sessions_comments
add column ip_address inet;
alter table music_sessions_likers
add column ip_address inet;
alter table music_sessions_likers
alter column liker_id drop not null;
alter table recordings_comments
add column ip_address inet;
alter table recordings_likers
add column ip_address inet;
alter table recordings_likers
alter column liker_id drop not null;
alter table recordings_plays
add column ip_address inet;
alter table recordings_plays
alter column player_id drop not null;

View File

@ -0,0 +1 @@
alter table music_sessions_user_history add column instruments varchar(255);

View File

@ -6,4 +6,4 @@ ON UPDATE NO ACTION ON DELETE CASCADE;
alter table music_sessions_likers drop constraint music_sessions_likers_music_session_id_fkey;
alter table music_sessions_likers add constraint ms_likers_ms_history_fkey foreign key (music_session_id)
references music_sessions_history(music_session_id) match simple
ON UPDATE NO ACTION ON DELETE CASCADE;
ON UPDATE NO ACTION ON DELETE CASCADE;

View File

@ -109,7 +109,6 @@ message ClientMessage {
optional SessionJoin session_join = 190;
optional SessionDepart session_depart = 195;
optional MusicianSessionJoin musician_session_join = 196;
optional BandSessionJoin band_session_join = 197;
// recording notifications
optional MusicianRecordingSaved musician_recording_saved = 200;

View File

@ -311,7 +311,7 @@ SQL
else
blk.call(db_conn, connection) unless blk.nil?
user.update_progression_field(:first_music_session_at)
MusicSessionUserHistory.save(music_session_id, user_id, client_id)
MusicSessionUserHistory.save(music_session_id, user_id, client_id, tracks)
end
end

View File

@ -62,6 +62,13 @@ module JamRuby
return self.music_sessions.size
end
def recent_history
recordings = ClaimedRecording.joins(:recordings).where(:recordings => {:band_id => "#{self.id}"}).limit(10)
msh = MusicSessionHistory.where(:band_id => self.id).limit(10)
recordings.concat(msh)
recordings.sort! {|a,b| b.created_at <=> a.created_at}.first(5)
end
def location
loc = self.city.blank? ? '' : self.city
loc = loc.blank? ? self.state : "#{loc}, #{self.state}" unless self.state.blank?

View File

@ -5,6 +5,8 @@ module JamRuby
self.primary_key = 'id'
default_scope order('created_at DESC')
belongs_to :music_session, :class_name => "JamRuby::MusicSessionHistory", :foreign_key => "music_session_id"
belongs_to :user, :class_name => "JamRuby::User", :foreign_key => "creator_id"

View File

@ -15,10 +15,11 @@ module JamRuby
:foreign_key => :band_id,
:inverse_of => :music_session_history)
has_many :music_session_user_history, :class_name => "JamRuby::MusicSessionUserHistory", :foreign_key => "music_session_id"
has_many :comments, :class_name => "JamRuby::MusicSessionComment", :foreign_key => "music_session_id"
has_many :likes, :class_name => "JamRuby::MusicSessionLiker", :foreign_key => "music_session_id"
GENRE_SEPARATOR = '|'
SEPARATOR = '|'
def comment_count
self.comments.size
@ -28,6 +29,21 @@ module JamRuby
self.likes.size
end
def tracks
tracks = []
self.music_session_user_history.each do |msuh|
user = User.find(msuh.user_id)
instruments = msuh.instruments.split(SEPARATOR)
instruments.each do |instrument|
t = Track.new
t.user = user
t.instrument_id = instrument
tracks << t
end
end
tracks
end
def self.index(current_user, user_id, band_id = nil, genre = nil)
hide_private = false
if current_user.id != user_id
@ -74,7 +90,7 @@ module JamRuby
session_history.description = music_session.description unless music_session.description.nil?
session_history.user_id = music_session.creator.id
session_history.band_id = music_session.band.id unless music_session.band.nil?
session_history.genres = music_session.genres.map { |g| g.id }.join GENRE_SEPARATOR
session_history.genres = music_session.genres.map { |g| g.id }.join SEPARATOR
session_history.save!
end

View File

@ -12,6 +12,10 @@ module JamRuby
:foreign_key => "user_id",
:inverse_of => :music_session_user_histories)
belongs_to(:music_session_history,
:class_name => "MusicSessionHistory",
:foreign_key => "music_session_id")
validates_inclusion_of :rating, :in => 0..2, :allow_nil => true
after_save :track_user_progression
@ -23,7 +27,7 @@ module JamRuby
@perfdata ||= JamRuby::MusicSessionPerfData.find_by_client_id(self.client_id)
end
def self.save(music_session_id, user_id, client_id)
def self.save(music_session_id, user_id, client_id, tracks)
return true if 0 < self.where(:music_session_id => music_session_id,
:user_id => user_id,
:client_id => client_id).count
@ -31,6 +35,7 @@ module JamRuby
session_user_history.music_session_id = music_session_id
session_user_history.user_id = user_id
session_user_history.client_id = client_id
session_user_history.instruments = tracks.map {|t| t[:instrument_id]}.join("|")
session_user_history.save
end

View File

@ -5,6 +5,8 @@ module JamRuby
self.primary_key = 'id'
default_scope order('created_at DESC')
belongs_to :recording, :class_name => "JamRuby::Recording", :foreign_key => "recording_id"
belongs_to :user, :class_name => "JamRuby::User", :foreign_key => "creator_id"

View File

@ -14,6 +14,10 @@ module JamRuby
validates :sound, :inclusion => {:in => SOUND}
def user
self.connection.user
end
def self.index(current_user, music_session_id)
query = Track
.joins(
@ -47,6 +51,10 @@ module JamRuby
Track.transaction do
connection = Connection.find_by_client_id!(clientId)
# each time tracks are synced we have to update the entry in music_sessions_user_history
msh = MusicSessionUserHistory.find_by_client_id!(clientId)
instruments = []
if tracks.length == 0
connection.tracks.delete_all
else
@ -62,9 +70,11 @@ module JamRuby
to_delete.delete(connection_track)
to_add.delete(track)
# don't update connection_id or client_id; it's unknown what would happen if these changed mid-session
connection_track.instrument = Instrument.find(track[:instrument_id])
connection_track.instrument_id = track[:instrument_id]
connection_track.sound = track[:sound]
connection_track.client_track_id = track[:client_track_id]
instruments << track[:instrument_id]
if connection_track.save
result.push(connection_track)
next
@ -76,10 +86,15 @@ module JamRuby
end
end
msh.instruments = instruments.join("|")
if !msh.save
raise ActiveRecord::Rollback
end
to_add.each do |track|
connection_track = Track.new
connection_track.connection = connection
connection_track.instrument = Instrument.find(track[:instrument_id])
connection_track.instrument_id = track[:instrument_id]
connection_track.sound = track[:sound]
connection_track.client_track_id = track[:client_track_id]
if connection_track.save
@ -90,7 +105,7 @@ module JamRuby
end
end
to_delete.each do| delete_me |
to_delete.each do |delete_me|
delete_me.delete
end
end
@ -101,7 +116,7 @@ module JamRuby
def self.save(id, connection_id, instrument_id, sound, client_track_id)
if id.nil?
track = Track.new()
track = Track.new
track.connection_id = connection_id
else
track = Track.find(id)

View File

@ -288,6 +288,13 @@ module JamRuby
def session_count
return self.music_sessions.size
end
def recent_history
recordings = ClaimedRecording.joins(:recording).where(:recordings => {:owner_id => "#{self.id}"}).limit(10)
msh = MusicSessionHistory.where(:user_id => self.id).limit(10)
recordings.concat(msh)
recordings.sort! {|a,b| b.created_at <=> a.created_at}.first(5)
end
def confirm_email!
self.email_confirmed = true

View File

@ -53,7 +53,7 @@ module JamRuby
def validate
raise "icecast_server_id not spceified" unless icecast_server_id
raise "queue routing mismatch error. requested icecast_server_id: #{icecast_server_id}, configured icceast_server_id: #{APP_CONFIG.icecast_server_id}" unless icecast_server_id == APP_CONFIG.icecast_server_id
raise "queue routing mismatch error. requested icecast_server_id: #{icecast_server_id}, configured icecast_server_id: #{APP_CONFIG.icecast_server_id}" unless icecast_server_id == APP_CONFIG.icecast_server_id
end
def execute(cmd)

View File

@ -14,7 +14,7 @@ describe IcecastConfigWriter do
it "no files specified" do
worker.icecast_server_id = 'something'
expect { worker.validate }.to raise_error("queue routing mismatch error")
expect { worker.validate }.to raise_error("queue routing mismatch error. requested icecast_server_id: #{worker.icecast_server_id}, configured icecast_server_id: #{APP_CONFIG.icecast_server_id}")
end
it "succeeds" do

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 999 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 B

View File

Before

Width:  |  Height:  |  Size: 896 B

After

Width:  |  Height:  |  Size: 896 B

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 764 B

After

Width:  |  Height:  |  Size: 764 B

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 892 B

After

Width:  |  Height:  |  Size: 892 B

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 913 B

After

Width:  |  Height:  |  Size: 913 B

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -98,7 +98,7 @@
if (mm['instruments'][jj].instrument_id in instrument_logo_map) {
instr = instrument_logo_map[mm['instruments'][jj].instrument_id];
}
instr_logos += '<img src="' + instr + '" width="24" height="24" />&nbsp;';
instr_logos += '<img src="' + instr + '"/>';
}
follows = '';
followVals = {};

View File

@ -1319,6 +1319,7 @@
configureTrackDialog.showVoiceChatPanel(true);
configureTrackDialog.showMusicAudioPanel(true);
});
$('#close-playback-recording').on('click', closeRecording);
$(playbackControls)
.on('pause', onPause)

View File

@ -0,0 +1,102 @@
(function(context,$) {
"use strict";
context.JK = context.JK || {};
context.JK.ShareDialog = function(app) {
var logger = context.JK.logger;
var rest = context.JK.Rest();
function registerEvents(onOff) {
}
/*function showEmailDialog() {
$('#invitation-dialog').show();
$('#invitation-textarea-container').show();
$('#invitation-checkbox-container').hide();
$('#btn-send-invitation').show();
$('#btn-next-invitation').hide();
clearTextFields();
app.layout.showDialog('inviteUsers')
}
function showGoogleDialog() {
$('#invitation-dialog').show();
$('#invitation-textarea-container').hide();
$('#invitation-checkbox-container').show();
$('#btn-send-invitation').hide();
$('#btn-next-invitation').show();
clearTextFields();
app.layout.showDialog('inviteUsers')
$('#invitation-checkboxes').html('<div style="text-align: center; margin-top: 100px;">Loading your contacts...</div>');
window._oauth_callback = function() {
window._oauth_win.close();
window._oauth_win = null;
window._oauth_callback = null;
$.ajax({
type: "GET",
url: "/gmail_contacts",
success: function(response) {
$('#invitation-checkboxes').html('');
for (var i in response) {
$('#invitation-checkboxes').append("<label><input type='checkbox' class='invitation-checkbox' data-email='" + response[i] + "' /> " + response[i] + "</label>");
}
$('.invitation-checkbox').change(function() {
var checkedBoxes = $('.invitation-checkbox:checkbox:checked');
var emails = '';
for (var i = 0; i < checkedBoxes.length; i++) {
emails += $(checkedBoxes[i]).data('email') + ', ';
}
emails = emails.replace(/, $/, '');
// track how many of these came from google
$('#txt-emails').val(emails).data('google_invite_count', checkedBoxes.length);
});
},
error: function() {
$('#invitation-checkboxes').html("Load failed!");
}
});
};
window._oauth_win = window.open("/auth/google_login", "_blank", "height=500,width=500,menubar=no,resizable=no,status=no");
}
function showFacebookDialog() {
window._oauth_callback = function() {
window._oauth_win.close();
window._oauth_win = null;
window._oauth_callback = null;
};
window._oauth_win = window.open("/auth/facebook_login", "_blank", "height=500,width=500,menubar=no,resizable=no,status=no");
}*/
function clearTextFields() {
}
function beforeShow() {
registerEvents(true);
}
function afterHide() {
registerEvents(false);
}
function initialize(){
var dialogBindings = {
'beforeShow' : beforeShow,
'afterHide': afterHide
};
app.bindDialog('shareSessionRecording', dialogBindings);
};
this.initialize = initialize;
}
return this;
})(window,jQuery);

View File

@ -71,6 +71,7 @@
// initially show avatar
function showAvatar() {
var photoUrl = context.JK.resolveAvatarUrl(userMe.photo_url);
logger.debug("photoUrl=" + photoUrl);
$('#header-avatar').attr('src', photoUrl);
}

View File

@ -42,18 +42,18 @@
// available, and allowing the browser to resize offers better quality.
var icon_map_base = {
"accordion":"accordion",
"acoustic guitar":"acoustic",
"acoustic guitar":"acoustic_guitar",
"banjo":"banjo",
"bass guitar":"bass",
"bass guitar":"bass_guitar",
"cello":"cello",
"clarinet":"clarinet",
"computer":"computer",
"default":"default",
"drums":"drums",
"electric guitar":"guitar",
"electric guitar":"electric_guitar",
"euphonium":"euphonium",
"flute":"flute",
"french horn":"frenchhorn",
"french horn":"french_horn",
"harmonica":"harmonica",
"keyboard":"keyboard",
"mandolin":"mandolin",

View File

@ -0,0 +1,10 @@
$(function() {
function like() {
}
// search click handler
$('#btnlike').click(like);
});

View File

@ -0,0 +1,10 @@
$(function() {
function like() {
}
// search click handler
$('#btnlike').click(like);
});

View File

@ -6,6 +6,7 @@
//= require AAC_underscore
//= require globals
//= require invitationDialog
//= require shareDialog
//= require layout
//= require user_dropdown
//= require jamkazam
@ -15,4 +16,6 @@
//= require landing/init
//= require landing/signup
//= require web/downloads
//= require web/congratulations
//= require web/congratulations
//= require web/sessions
//= require web/recordings

View File

@ -32,6 +32,7 @@
*= require ./search
*= require ./ftue
*= require ./invitationDialog
*= require ./shareDialog
*= require ./recordingFinishedDialog
*= require ./localRecordingsDialog
*= require ./createSession

View File

@ -34,8 +34,30 @@
padding-top: 5px;
padding-right: 5px;
padding-left: 5px;
}
.musician-following {
overflow: auto;
#result_instruments {
font-weight: normal;
> img {
margin-right: 4px;
height:24px;
width:24px;
}
}
.result-name {
font-size: 12px;
font-weight: bold;
margin-bottom: 2px;
}
.stats {
margin-top: 4px;
img {
vertical-align: middle;
}
}
.lcol {
width: 148px;
}
table.musicians {
margin-top:12px;
}
}

View File

@ -169,10 +169,13 @@ a {
display:inline-block;
}
small {
font-size:11px;
small, .small {
font-size:11px;
}
.bold {
font-weight:bold;
}
.button-grey {
margin:0px 8px 0px 8px;
background-color:#666;
@ -207,6 +210,11 @@ small {
text-decoration:none;
}
.smallbutton {
font-size:10px;
padding:2px 8px;
}
.button-orange:hover {
background-color:#f16750;
color:#FFF;
@ -233,161 +241,99 @@ a img {
.clearall {
clear:both;
}
.left {
float:left;
.clearleft {
clear:left;
}
.right {
float:right;
}
.f8 {font-size:8px !important}
.f9 {font-size:9px !important}
.f10 {font-size:10px !important}
.f11 {font-size:11px !important}
.f12 {font-size:12px !important}
.f13 {font-size:13px !important}
.f14 {font-size:14px !important}
.f15 {font-size:15px !important}
.f16 {font-size:16px !important}
.f17 {font-size:17px !important}
.f18 {font-size:18px !important}
.f19 {font-size:19px !important}
.f20 {font-size:20px !important}
.f8 {
font-size: 8px !important;
}
.m0 {margin: 0 !important;}
.f9 {
font-size: 9px !important;
}
.mr5 {margin-right:5px;}
.mr10 {margin-right:10px;}
.mr20 {margin-right:20px;}
.mr30 {margin-right:30px;}
.mr35 {margin-right:35px;}
.mr40 {margin-right:40px;}
.mr120 {margin-right:120px;}
.f10 {
font-size: 10px !important;
}
.ml5 {margin-left:5px;}
.ml10 {margin-left:10px;}
.ml20 {margin-left:20px;}
.ml25 {margin-left:25px;}
.ml30 {margin-left:30px;}
.ml35 {margin-left:35px;}
.ml45 {margin-left:45px;}
.f11 {
font-size: 11px !important;
}
.mt5 {margin-top:5px;}
.mt10 {margin-top:10px;}
.mt15 {margin-top:15px;}
.mt20 {margin-top:20px;}
.mt25 {margin-top:25px;}
.mt30 {margin-top:30px;}
.mt35 {margin-top:35px;}
.mt40 {margin-top:40px;}
.mt45 {margin-top:45px;}
.mt50 {margin-top:50px;}
.mt55 {margin-top:55px;}
.mt65 {margin-top:65px;}
.f12 {
font-size: 12px !important;
}
.mb5 {margin-bottom:5px;}
.mb15 {margin-bottom:15px;}
.f13 {
font-size: 13px !important;
}
.w0 {width:0% !important}
.w5 {width:5% !important}
.w10 {width:10% !important}
.w15 {width:15% !important}
.w20 {width:20% !important}
.w25 {width:25% !important}
.w30 {width:30% !important}
.w35 {width:35% !important}
.w40 {width:40% !important}
.w45 {width:45% !important}
.w50 {width:50% !important}
.w55 {width:55% !important}
.w60 {width:60% !important}
.w65 {width:65% !important}
.w70 {width:70% !important}
.w75 {width:75% !important}
.w80 {width:80% !important}
.w85 {width:85% !important}
.w90 {width:90% !important}
.w95 {width:95% !important}
.w100 {width:100% !important}
.f14 {
font-size: 14px !important;
}
.p5 {padding:5px !important}
.p10 {padding:10px !important}
.p15 {padding:15px !important}
.p20 {padding:20px !important}
.p25 {padding:25px !important}
.p30 {padding:30px !important}
.f15 {
font-size: 15px !important;
}
.border-right {border-right:solid 1px #999;}
.border-left {border-left:solid 1px #999;}
.border-bottom {border-bottom:solid 1px #999;}
.border-top {border-top:solid 1px #999;}
.m0 {
margin: 0 !important;
}
.whitespace {white-space:normal;}
.clearall {clear:both;}
.mr5 {
margin-right:5px;
}
.mr10 {
margin-right:10px;
}
.mr20 {
margin-right:20px;
}
.mr30 {
margin-right:30px;
}
.mr35 {
margin-right:35px;
}
.mr40 {
margin-right:40px;
}
.mr120 {
margin-right:120px;
}
.ml5 {
margin-left:5px;
}
.ml10 {
margin-left:10px;
}
.ml20 {
margin-left:20px;
}
.ml25 {
margin-left:25px;
}
.ml30 {
margin-left:30px;
}
.ml35 {
margin-left:35px;
}
.ml45 {
margin-left:45px;
}
.mt5 {
margin-top:5px;
}
.mt10 {
margin-top:10px;
}
.mt15 {
margin-top:15px;
}
.mt20 {
margin-top:20px;
}
.mt25 {
margin-top:25px;
}
.mt30 {
margin-top:30px;
}
.mt35 {
margin-top:35px;
}
.mt40 {
margin-top:40px;
}
.mt45 {
margin-top:45px;
}
.mt50 {
margin-top:50px;
}
.mt55 {
margin-top:55px;
}
.mt65 {
margin-top:65px;
}
.mb5 {
margin-bottom:5px;
}
.mb15 {
margin-bottom:15px;
.error {
background-color:#300;
padding:5px;
border: solid 1px #900;
}
.op50 {
@ -443,20 +389,16 @@ a img {
width:239px;
}
.white {
color:#fff;
}
.lightgrey {
color:#ccc;
}
.grey {
color:#999;
}
.darkgrey {
color:#333;
}
.white {color:#fff;}
.lightgrey {color:#ccc;}
.grey {color:#999;}
.darkgrey {color:#333;}
.orange {color:#ED3618 !important;}
.teal {color:#2b8897;}
.green-fill {background-color:#72a43b;}
.gold-fill {background-color:#cc9900;}
.red-fill {background-color:#660000;}
.orange-fill {background-color:#ed3618;}
.teal-fill {background-color:#0b6672;}
/* End of Jeff's common.css file */

View File

@ -0,0 +1,185 @@
body.widgets {
background:#fff;
padding:20px;
}
.widget {
width:430px;
height:180px;
background:#353535;
border:solid 1px;
text-align:left;
}
.widget.session {
border-color:#0b6672;
}
.widget.recording {
border-color:#ed3618;
}
.widget-header {
color:#fff;
font-size:17px;
padding:8px;
}
.widget-content {
width:100%;
color:#ccc;
position:relative;
}
.widget-avatar {
top:15px;
left:15px;
position:absolute;
padding:2px;
width:110px;
height:110px;
background-color:#ed3618;
-webkit-border-radius:57px;
-moz-border-radius:57px;
border-radius:57px;
margin-bottom:10px;
}
.widget-avatar img {
width:110px;
height:110px;
-webkit-border-radius:55px;
-moz-border-radius:55px;
border-radius:55px;
}
.widget-playbutton {
position:absolute;
top:55px;
left:55px;
width:35px;
height:31px;
background-image:url(../shared/play_button.png);
background-repeat:no-repeat;
}
.widget-pausebutton {
position:absolute;
top:55px;
left:55px;
width:35px;
height:31px;
background-image:url(../shared/pause_button.png);
background-repeat:no-repeat;
}
.widget-title {
font-size:18px;
position:absolute;
top:20px;
left:153px;
width:260px;
height:22px;
overflow:hidden;
white-space:nowrap;
text-overflow:ellipsis;
}
.widget-description {
font-size:13px;
position:absolute;
top:15px;
left:153px;
width:260px;
height:32px;
overflow:hidden;
text-overflow:ellipsis;
}
.widget-controls {
position:absolute;
top:25px;
left:153px;
width:270px;
height:32px;
}
.widget-members {
position:absolute;
left:153px;
top:60px;
width:280px;
height:38px;
overflow:hidden;
}
.widget-social {
position:absolute;
top:75px;
left:153px;
width:270px;
height:20px;
font-size:13px;
}
.widget-branding {
position: absolute;
top: 110px;
right: 8px;
width: 270px;
height: 34px;
font-size: 13px;
text-align:right;
}
.widget .recording-controls {
margin-top:0px;
height:22px;
padding:8px 5px;
}
.widget .recording-playback {
width:65%;
}
.widget .recording-position {
margin-left:-30px;
width:95%;
}
.widget .recording-current {
top:8px;
}
.widget a {
color:#ccc;
text-decoration:none;
}
img.space {
margin-left:28px;
}
.widget a:hover {
color:#fff;
}
.widget-avatar-small {
float:left;
padding:1px;
width: 36px;
height:36px;
background-color:#ed3618;
-webkit-border-radius:18px;
-moz-border-radius:18px;
border-radius:18px;
margin-right:15px;
}
.widget-avatar-small img {
width: 36px;
height: 36px;
-webkit-border-radius:18px;
-moz-border-radius:18px;
border-radius:18px;
}

View File

@ -7,12 +7,18 @@
}
#profile {
width:auto;
float:right;
height:64px;
float: right;
height: 54px;
margin-top: 30px;
text-align: right;
ul {
margin-bottom:0;
}
.signin {
position:relative;
margin-top:40px;
text-decoration: underline;
cursor: auto;
}
}
@ -35,7 +41,7 @@
border-radius:26px;
}
#user {
.user {
margin:18px 0px 0px 10px;
font-size:20px;
font-weight:200;

View File

@ -2,6 +2,10 @@ html {
height:100%;
}
p, div {
white-space: normal;
}
body.web {
background-repeat: repeat-x;
margin:0 !important;
@ -10,165 +14,259 @@ body.web {
overflow: visible !important;
width:auto !important;
#web-container {
padding:3% 0;
.logo-home {
width: 298px;
margin-top: 30px;
display: inline-block;
}
.landing-tag {
display:inline-block;
margin-left:70px;
width:400px;
}
.landing-tag h1 {
color:#ed3718;
font-size:26px;
font-weight:300;
}
.landing-content {
background-color:black;
width:100%;
padding-bottom:15px;
min-height: 366px;
position:relative;
padding-bottom:30px;
}
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;
}
white-space:nowrap;
position:relative;
}
#profile {
.landing-sidebar {
width:350px;
background:#353535;
border:solid 1px #ed3718;
position:absolute;
top:-80px;
right:0;
top:30px;
right:0px;
padding:25px;
padding-top:0px;
line-height:130%;
}
ul {
margin-bottom:0;
.landing-sidebar h2 {
font-size:18px !important;
line-height:normal;
color:#fff;
}
.landing-band {
float:left;
text-align:center;
width: 115px;
margin-right:25px;
font-size:17px;
color:#fff;
}
.landing-avatar {
padding:2px;
width:110px;
height:110px;
background-color:#ed3618;
-webkit-border-radius:57px;
-moz-border-radius:57px;
border-radius:57px;
margin-bottom:10px;
}
.landing-avatar img {
width:110px;
height:110px;
-webkit-border-radius:55px;
-moz-border-radius:55px;
border-radius:55px;
}
.landing-details {
float:left;
width:515px;
font-size:14px;
font-weight:400;
color:#666;
}
.landing-details a {
text-decoration:none;
color:#ccc;
}
.landing-details a:hover {
color:#fff;
}
.landing-content h2 {
font-size:24px;
color:#ccc;
font-weight:200;
}
.landing-comments {
margin-left:140px;
width:515px;
}
.landing-comments a {
text-decoration:none;
font-weight:bold;
color:#ED3618;
}
.landing-comment-scroller {
height:470px;
overflow:auto;
}
.landing .cta {
margin-top:25px;
}
.avatar-small {
float:left;
padding:1px;
width:36px;
height:36px;
background-color:#ed3618;
margin:10px;
-webkit-border-radius:18px;
-moz-border-radius:18px;
border-radius:18px;
}
.avatar-small img {
width: 36px;
height: 36px;
-webkit-border-radius:18px;
-moz-border-radius:18px;
border-radius:18px;
}
.cta {
margin-top:40px;
text-align:center;
width:345px;
font-size:12px;
}
white-space: nowrap;
p, ul {
color:#999;
line-height:160%;
margin-bottom:20px;
width:90%;
white-space:normal;
font-size:16px;
}
h2 {
font-size: 1.5em;
font-weight:300;
}
.content-wrapper {
border-bottom: medium none;
padding: 0;
}
// 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%;
}
}
}
@ -215,11 +313,6 @@ body.web {
}
}
#landing-container {
padding: 3% 0;
position:relative;
text-align: center;
}
.signin-overlay {
position:relative;

View File

@ -0,0 +1,59 @@
.feed-entry .recording-controls, .feed-entry .session-controls, .landing-details .recording-controls {
margin-top:0px;
margin-bottom:5px;
padding:8px 5px 8px 10px;
width:98%;
position:relative;
text-align:center;
background-color:#242323;
}
.recording-position {
display:inline-block;
width:80%;
margin-left:-20px;
font-family:Arial, Helvetica, sans-serif;
font-size:11px;
height:18px;
vertical-align:top;
}
.landing-details .recording-position {
width:100%;
}
.recording-time {
display:inline-block;
height:16px;
vertical-align:top;
margin-top:4px;
}
.landing-details .recording-current {
top:8px;
}
.recording-playback {
display:inline-block;
background-image:url(../content/bkg_playcontrols.png);
background-repeat:repeat-x;
position:relative;
width:70%;
height:16px;
margin-top:2px;
}
.recording-slider {
position:absolute;
left:25%;
top:0px;
}
.recording-current {
font-family:Arial, Helvetica, sans-serif;
display:inline-block;
font-size:18px;
position:absolute;
top:3px;
right:4px;
}

View File

@ -0,0 +1,2 @@

View File

@ -7,6 +7,9 @@
*= require client/user_dropdown
*= require client/dialog
*= require client/invitationDialog
*= require client/shareDialog
*= require web/main
*= require web/footer
*= require web/recordings
#= require web/sessions
*/

View File

@ -37,34 +37,26 @@ class ApiInvitationsController < ApiController
sender = current_user
join_request = JoinRequest.find(params[:join_request]) unless params[:join_request].nil?
@invitation = Invitation.limit(1)
.where(:receiver_id => params[:receiver],
:sender_id => current_user.id,
:music_session_id => params[:music_session])
.first
if @invitation
@invitation = Invitation.new
@invitation.music_session = music_session
@invitation.sender = sender
@invitation.receiver = receiver
@invitation.join_request = join_request
@invitation.save
unless @invitation.errors.any?
User.save_session_settings(current_user, music_session)
# send notification
Notification.send_session_invitation(receiver, current_user, music_session.id)
respond_with @invitation, :responder => ApiResponder, :location => api_invitation_detail_url(@invitation)
else
@invitation = Invitation.new
@invitation.music_session = music_session
@invitation.sender = sender
@invitation.receiver = receiver
@invitation.join_request = join_request
@invitation.save
unless @invitation.errors.any?
User.save_session_settings(current_user, music_session)
# send notification
Notification.send_session_invitation(receiver, current_user, music_session.id)
respond_with @invitation, :responder => ApiResponder, :location => api_invitation_detail_url(@invitation)
else
# we have to do this because api_invitation_detail_url will fail with a bad @invitation
response.status = :unprocessable_entity
respond_with @invitation
end
# we have to do this because api_invitation_detail_url will fail with a bad @invitation
response.status = :unprocessable_entity
respond_with @invitation
end
end
def show

View File

@ -3,7 +3,7 @@ require 'aws-sdk'
class ApiMusicSessionsController < ApiController
# have to be signed in currently to see this screen
before_filter :api_signed_in_user
before_filter :api_signed_in_user, :except => [ :add_like ]
before_filter :lookup_session, only: [:show, :update, :delete, :claimed_recording_start, :claimed_recording_stop]
skip_before_filter :api_signed_in_user, only: [:perf_upload]
@ -257,6 +257,7 @@ class ApiMusicSessionsController < ApiController
comment.music_session_id = params[:id]
comment.creator_id = params[:user_id]
comment.comment = params[:comment]
comment.ip_address = request.remote_ip
comment.save
if comment.errors.any?
@ -278,6 +279,7 @@ class ApiMusicSessionsController < ApiController
liker = MusicSessionLiker.new
liker.music_session_id = params[:id]
liker.liker_id = params[:user_id]
liker.ip_address = request.remote_ip
liker.save
if liker.errors.any?

View File

@ -1,6 +1,6 @@
class ApiRecordingsController < ApiController
before_filter :api_signed_in_user
before_filter :api_signed_in_user, :except => [ :add_like, :add_play ]
before_filter :look_up_recording, :only => [ :show, :stop, :claim, :discard, :keep ]
before_filter :parse_filename, :only => [ :download, :upload_next_part, :upload_sign, :upload_part_complete, :upload_complete ]
@ -97,6 +97,7 @@ class ApiRecordingsController < ApiController
comment.recording_id = params[:id]
comment.creator_id = params[:user_id]
comment.comment = params[:comment]
comment.ip_address = request.remote_ip
comment.save
if comment.errors.any?
@ -118,6 +119,7 @@ class ApiRecordingsController < ApiController
liker = RecordingLiker.new
liker.recording_id = params[:id]
liker.liker_id = params[:user_id]
liker.ip_address = request.remote_ip
liker.save
if liker.errors.any?
@ -139,6 +141,7 @@ class ApiRecordingsController < ApiController
play = RecordingPlay.new
play.recording_id = params[:id]
play.player_id = params[:user_id]
play.ip_address = request.remote_ip
play.save
if play.errors.any?
@ -209,10 +212,7 @@ class ApiRecordingsController < ApiController
end
end
private
def parse_filename
@recorded_track = RecordedTrack.find_by_recording_id_and_client_track_id!(params[:id], params[:track_id])
raise PermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR unless @recorded_track.recording.has_access?(current_user)

View File

@ -1,50 +1,10 @@
class MusicSessionsController < ApplicationController
# have to be signed in currently to see this screen
before_filter :signed_in_user
respond_to :html
def index
@music_sessions = MusicSession.paginate(page: params[:page])
end
def show
@music_session = MusicSession.find(params[:id])
# use gon to pass variables into javascript
gon.websocket_gateway_uri = Rails.application.config.websocket_gateway_uri
gon.music_session_id = @music_session.id
end
def new
@music_session = MusicSession.new
end
def create
@music_session = MusicSession.new()
@music_session.creator = current_user
@music_session.description = params[:jam_ruby_music_session][:description]
if @music_session.save
flash[:success] = "Music Session created"
redirect_to @music_session
else
render 'new'
end
end
def edit
end
def update
end
def destroy
MusicSession.find(params[:id]).destroy
flash[:success] = "Jam Session deleted."
redirect_to music_sessions_url
@music_session = MusicSessionHistory.find_by_music_session_id(params[:id])
render :layout => "web"
end
end

View File

@ -0,0 +1,10 @@
class RecordingsController < ApplicationController
respond_to :html
def show
@claimed_recording = ClaimedRecording.find(params[:id])
render :layout => "web"
end
end

View File

@ -1,13 +1,13 @@
# I'm not sure this is right at all. The idea is to bring in all the stuff you would need to play the tracks.
# I don't think I need to include URLs since that's handled by syncing. This is jsut to make the metadata
# I don't think I need to include URLs since that's handled by syncing. This is just to make the metadata
# depictable.
object @claimed_recording
attributes :id, :name, :description, :is_public, :is_downloadable
attributes :id, :name, :description, :is_public, :is_downloadable, :genre_id
child(:recording => :recording) {
attributes :id, :created_at, :duration
attributes :id, :created_at, :duration, :comment_count, :like_count, :play_count
child(:band => :band) {
attributes :id, :name
}
@ -19,9 +19,20 @@ child(:recording => :recording) {
child(:recorded_tracks => :recorded_tracks) {
attributes :id, :fully_uploaded, :url, :client_track_id, :client_id, :instrument_id
child(:user => :user) {
attributes :id, :first_name, :last_name, :city, :state, :country, :photo_url
}
child(:user => :user) {
attributes :id, :first_name, :last_name, :city, :state, :country, :photo_url
}
}
}
child(:band => :band) {
attributes :id, :name, :photo_url
}
child(:comments => :comments) {
attributes :comment, :created_at
child(:user => :creator) {
attributes :id, :first_name, :last_name, :photo_url
}
}
}

View File

@ -20,45 +20,44 @@
<% end -%>
<!-- Session Row Template -->
<script type="text/template" id="template-find-musician-row">
<script type="text/template" id="template-find-musician-row"><!-- -->
<div class="profile-band-list-result musician-list-result">
<div class="left" data-hint="container">
<div class="left">
<div class="f11" data-hint="container">
<div class="left" style="width:63px;margin-top:-12px;">
<!-- avatar -->
<div class="avatar-small"><img src="{avatar_url}" /></div>
</div>
<div class="left">
<div data-hint="top-row">
<div class="left">
<div class="right musician-following" style="width: 120px;">
<div class="bold">FOLLOWING:</div>
<table class="musicians" cellpadding="0" cellspacing="5">{musician_follow_template}</table>
</div>
<div class="" style="margin-left: 63px; margin-right: 130px;margin-top: 12px;"">
<div class="first-row" data-hint="top-row">
<div class="lcol left">
<!-- name & location -->
<div style="" class="result-name">{musician_name}</div>
<div class="result-location">{musician_location}</div>
<div id="result_instruments" class="nowrap">{instruments}</div>
<div class="result-name">{musician_name}</div>
<div class="result-location">{musician_location}</div>
<div id="result_instruments" class="nowrap mt10">{instruments}</div>
</div>
<div class="left ml35 f11 whitespace w40">
<div class="whitespace">
<div class="biography">{biography}</div>
</div>
<div class="clearleft"></div>
</div>
<div data-hint="button-row">
<div class="stats">
{friend_count} <img src="../assets/content/icon_friend.png" width="14" height="12" align="absmiddle" />&nbsp;&nbsp;&nbsp;
{follow_count} <img src="../assets/content/icon_followers.png" width="22" height="12" align="absmiddle" />&nbsp;&nbsp;&nbsp;
{recording_count} <img src="../assets/content/icon_recordings.png" width="12" height="13" align="absmiddle" />&nbsp;&nbsp;&nbsp;
<div class="button-row" data-hint="button-row">
<div class="lcol stats left">
{friend_count} <img src="../assets/content/icon_friend.png" width="14" height="12" align="absmiddle" style="margin-right:4px;"/>
{follow_count} <img src="../assets/content/icon_followers.png" width="22" height="12" align="absmiddle" style="margin-right:4px;"/>
{recording_count} <img src="../assets/content/icon_recordings.png" width="12" height="13" align="absmiddle" style="margin-right:4px;"/>
{session_count} <img src="../assets/content/icon_session_tiny.png" width="12" height="12" align="absmiddle" />
</div>
<div class="result-list-button-wrapper" data-musician-id={musician_id}>
{musician_action_template}
</div>
<div class="clearall"></div>
</div>
</div>
</div>
<div class="left ml10 w20 musician-following">
<br />
<small><strong>FOLLOWING:</strong></small>
<table class="musicians" cellpadding="0" cellspacing="5">{musician_follow_template}</table>
</div>
<br clear="all" />
</div>
</script>
@ -74,7 +73,7 @@
<script type="text/template" id="template-musician-follow-info">
<tr>
<td width="24">
<td width="32">
<a href="{profile_url}" class="avatar-tiny"><img src="{avatar_url}" /></a>
</td>
<td>

View File

@ -18,7 +18,7 @@
<%= image_tag "content/icon_settings_sm.png", {:align => "texttop", :height => 12, :width => 12} %>
SETTINGS
</a>
<a class="button-grey left">
<a layout-link="share-dialog" class="button-grey left">
<%= image_tag "content/icon_share.png", {:align => "texttop", :height => 12, :width => 12} %>
SHARE
</a>
@ -137,6 +137,7 @@
<%= render "addNewGear" %>
<%= render "error" %>
<%= render "sessionSettings" %>
<%= render "shareDialog" %>
<!-- Track Template -->
<script type="text/template" id="template-session-track">

View File

@ -0,0 +1,122 @@
<!-- Share dialog -->
<div class="dialog" layout="dialog" layout-id="share-dialog" style="width:800px; height:auto;">
<div class="content-head"><h1>share this session</h1></div>
<div class="dialog-inner">
<div class="right"> <a class="button-orange" layout-action="close">X CLOSE</a></div>
<table class="w100">
<tr>
<td valign="top" width="45%" class="border-right"><h3 class="mb5">Share to Social Media:</h3>
<textarea class="w95" rows="3">Add a Message...</textarea><br />
<div class="left">
<input type="checkbox" />
<%= image_tag "content/icon_facebook.png", :size => "24x24", :align => "absmiddle", :alt => "", :style => "vertical-align:middle" %>&nbsp;
<input type="checkbox" />
<%= image_tag "content/icon_twitter.png", :size => "24x24", :align => "absmiddle", :alt => "", :style => "vertical-align:middle" %>&nbsp;
<input type="checkbox" />
<%= image_tag "content/icon_google.png", :size => "24x24", :align => "absmiddle", :alt => "", :style => "vertical-align:middle" %>&nbsp;
</div>
<div class=" right mr10 mt5"><a class="button-orange" id="dialog-share-button">SHARE</a></div>
</td>
<td valign="top" width="48%">
<div class="ml10">
<h3>Share a Link:</h3><br />http://jamkazam.com/TD48JKZ1<br /><br />
<div class="right"><a class="button-orange">COPY LINK</a></div>
</div>
</td>
</tr>
<tr><td colspan=2 class="border-bottom"><br /><br /></td></tr>
</table><br /><br />
<table class="w100">
<tr>
<td valign="top" width="40%"><h3>Get a Widget:</h3>
<!-- ########## Javascript code for widget ########## -->
<textarea class="w95" rows="10">
<!-- session widget -->
<div class="widget session">
<!-- header -->
<div class="widget-header orange-fill"><strong>LIVE SESSION</strong> by Raven &amp; The Blackbirds</div>
<!-- start widget content -->
<div class="widget-content">
<!-- band avatar -->
<div class="widget-avatar"><img src="images/content/avatar_band4.jpg" alt=""/></div>
<a href="javascript:void(0)" class="widget-pausebutton" title="pause"></a>
<!-- song title -->
<div class="widget-controls">
<!-- timeline and controls -->
<div class="w100">
<!-- recording play controls -->
<div class="recording-controls">
<!-- playback position -->
<div class="recording-position">
<!-- start time -->
<div class="recording-time">0:00</div>
<!-- playback background & slider -->
<div class="recording-playback">
<div class="recording-slider"><img src="images/content/slider_playcontrols.png" width="5" height="16" /></div>
</div>
<!-- end time -->
<div class="recording-time">4:59</div>
</div>
<!-- end playback position -->
<!-- current playback time -->
<div class="recording-current">1:23</div>
</div>
<!-- end recording play controls -->
</div>
</div>
<!-- band member avatars -->
<div class="widget-social">&nbsp;
<a href="#"><img src="images/content/icon_like.png" width="12" height="12" alt=""/>&nbsp;&nbsp;LIKE</a>
<a href="#"><img class="space" src="images/content/icon_comment.png" width="12" height="12" alt=""/>&nbsp;&nbsp;COMMENT</a>
<a href="#"><img class="space" src="images/content/icon_share.png" width="13" height="15" alt=""/>&nbsp;&nbsp;SHARE</a>
</div>
<!-- jamkazam branding -->
<div class="widget-branding">recorded on
<a href="http://jamkazam.com"><img src="images/shared/jk_logo_small.png" alt="" width="142" height="26" align="absbottom"/></a>
</div>
</div>
<!-- end widget content -->
</div>
<!-- /widget -->
</textarea> <br /><br />
<div class="right"><a class="button-orange mr10">COPY WIDGET CODE</a></div>
</td>
<td>
<div class="ml10">Preview:
<!-- recording widget -->
<div class="widget session">
<!-- header -->
<div class="widget-header teal-fill"><strong>LIVE SESSION</strong> by Raven &amp; The Blackbirds</div>
<!-- start widget content -->
<div class="widget-content">
<!-- band avatar -->
<div class="widget-avatar"><%= image_tag "content/avatar_band4.jpg", :alt => "" %></div>
<a href="javascript:void(0)" class="widget-playbutton" title="play"></a>
<!-- song title -->
<div class="widget-title">You Hurt Me Bad</div>
<!-- band member avatars -->
<div class="widget-members">
<div class="widget-avatar-small"><%= image_tag "shared/avatar_david.jpg", :alt => "" %></div>
<div class="widget-avatar-small"><%= image_tag "shared/avatar_silverfox.jpg", :alt => "" %></div>
<div class="widget-avatar-small"><%= image_tag "shared/avatar_saltnpepper.jpg", :alt => "" %></div>
<div class="widget-avatar-small"><%= image_tag "shared/avatar_creepyeye.jpg", :alt => "" %></div>
<div class="widget-avatar-small"><%= image_tag "shared/avatar_silverfox.jpg", :alt => "" %></div>
<div class="widget-avatar-small"><%= image_tag "shared/avatar_saltnpepper.jpg", :alt => "" %></div>
</div>
<!-- jamkazam branding -->
<div class="widget-branding">live session on
<a href="http://www.jamkazam.com">
<%= image_tag "shared/jk_logo_small.png", :size => "142x26", :align => "absbottom", :alt => "" %>
</a>
</div>
</div>
<!-- end widget content -->
</div>
<!-- /widget -->
</div>
</td>
</tr>
</table>
</div>
</div>

View File

@ -97,6 +97,9 @@
var invitationDialog = new JK.InvitationDialog(JK.app);
invitationDialog.initialize();
var shareDialog = new JK.ShareDialog(JK.app);
shareDialog.initialize();
var localRecordingsDialog = new JK.LocalRecordingsDialog(JK.app);
localRecordingsDialog.initialize();

View File

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

View File

@ -1,24 +1,72 @@
<% provide(:title, "Now Playing: #{@music_session.description}") %>
<div class="row">
<aside class="span4">
<section>
<h1>
<%= "Now Playing: #{@music_session.description}" %>
</h1>
</section>
</aside>
<div class="span8">
<h3>Internal Session Activity</h3>
<div id="internal_session_activity">
<p>Wait a moment... </p>
</div>
</div>
<% provide(:title, "#{@music_session.description}") %>
<div class="landing-band">
<% unless @music_session.band.nil? %>
<div class="landing-avatar">
<% unless @music_session.band.photo_url.blank? %>
<%= image_tag "#{@music_session.band.photo_url}", {:alt => ""} %>
<% else %>
<%= image_tag "shared/avatar_generic_band.png", {:alt => ""} %>
<% end %>
</div>
<%= @music_session.band.name %>
<% else %>
<div class="landing-avatar">
<% unless @music_session.creator.photo_url.blank? %>
<%= image_tag "#{@music_session.creator.photo_url}", {:alt => ""} %>
<% else %>
<%= image_tag "shared/avatar_generic.png", {:alt => ""} %>
<% end %>
</div>
<%= @music_session.creator.name %>
<% end %>
</div>
<% content_for :post_scripts do %>
<script type="text/javascript">
$(function() {
window.jamsocket.init()
})
</script>
<div class="landing-details">
<div class="left f20 teal"><strong>SESSION: Live Session in Progress</strong></div>
<div class="right f14 grey"><%= @cmusic_session.created_at.strftime("%b %e %Y, %l:%M %p") %></div>
<br clear="all" /><br />
<h2 class="left"><%= @music_session.name %></h2>
<div class="right">
<a href="#"><%= image_tag "content/icon_like.png", {:width => 12, :height => 12} %>&nbsp;LIKE</a>&nbsp;&nbsp;&nbsp;
<a href="#"><%= image_tag "content/icon_share.png", {:width => 13, :height => 15} %>&nbsp;SHARE</a>
</div>
<br clear="all" />TODO: Which field is this in the database??<br /><br />
<div class="w100">
<div class="recording-controls">
<a class="left mr20" href="#"><%= image_tag "content/icon_playbutton.png", {:width => 20, :height => 20} %></a>
<div class="session-status">LIVE SESSION IN PROGRESS</div>
<div class="recording-current">1:23</div>
</div>
<div class="left white"><%= @music_session.genres.split('|').first.id.capitalize %></div>
<div class="right white">
<%= @music_session.comment_count %>
<%= image_tag "content/icon_comment.png", {:width => 13, :height => 12, :align => "absmiddle"} %>&nbsp;&nbsp;&nbsp;&nbsp;
<%= @music_session.like_count %>
<%= image_tag "content/icon_like.png", {:width => 12, :height => 12, :align => "absmiddle"} %>
</div>
</div>
<br clear="all" /><br />
<%= render :partial => "shared/track_details", :locals => {:tracks => @music_session.tracks} %>
</div>
<br clear="all" />
<% if signed_in? %>
<% unless @music_session.band.nil? %>
<%= render :partial => "shared/landing_sidebar", :locals => {:user => @music_session.band, :recent_history => @music_session.band.recent_history} %>
<% else %>
<%= render :partial => "shared/landing_sidebar", :locals => {:user => @music_session.user, :recent_history => @music_session.user.recent_history} %>
<% end %>
<% else %>
<%= render :partial => "shared/cta_sidebar" %>
<% end %>
<% content_for :after_black_bar do %>
<br />
<%= render :partial => "shared/comments", :locals => {:comments => @music_session.comments} %>
<% end %>
<%= javascript_include_tag "web/sessions" %>
<%= render "clients/shareDialog" %>

View File

@ -0,0 +1,80 @@
<% provide(:title, "#{@claimed_recording.name}") %>
<div class="landing-band">
<% unless @claimed_recording.recording.band.nil? %>
<div class="landing-avatar">
<% unless @claimed_recording.recording.band.photo_url.blank? %>
<%= image_tag "#{@claimed_recording.recording.band.photo_url}", {:alt => ""} %>
<% else %>
<%= image_tag "shared/avatar_generic_band.png", {:alt => ""} %>
<% end %>
</div>
<%= @claimed_recording.recording.band.name %>
<% else %>
<div class="landing-avatar">
<% unless @claimed_recording.recording.owner.photo_url.blank? %>
<%= image_tag "#{@claimed_recording.recording.owner.photo_url}", {:alt => ""} %>
<% else %>
<%= image_tag "shared/avatar_generic.png", {:alt => ""} %>
<% end %>
</div>
<%= @claimed_recording.recording.owner.name %>
<% end %>
</div>
<div class="landing-details">
<div class="left f20 orange"><strong>RECORDING</strong></div>
<div class="right f14 grey"><%= @claimed_recording.recording.created_at.strftime("%b %e %Y, %l:%M %p") %></div>
<br clear="all" /><br />
<h2 class="left"><%= @claimed_recording.name %></h2>
<div class="right">
<a href="#"><%= image_tag "content/icon_like.png", {:width => 12, :height => 12} %>&nbsp;LIKE</a>&nbsp;&nbsp;&nbsp;
<a href="#"><%= image_tag "content/icon_share.png", {:width => 13, :height => 15} %>&nbsp;SHARE</a>
</div>
<br clear="all" />TODO: Which field is this in the database??<br /><br />
<div class="w100">
<div class="recording-controls">
<a class="left" href="#"><%= image_tag "content/icon_playbutton.png", {:width => 20, :height => 20} %></a>
<div class="recording-position">
<div class="recording-time">0:00</div>
<div class="recording-playback">
<div class="recording-slider"><%= image_tag "content/slider_playcontrols.png", {:width => 5, :height => 16} %></div>
</div>
<div class="recording-time">4:59</div>
</div>
<div class="recording-current">1:23</div>
</div>
<div class="left white"><%= @claimed_recording.genre_id.capitalize %></div>
<div class="right white">
<%= @claimed_recording.recording.play_count %>
<%= image_tag "content/icon_arrow.png", {:width => 7, :height => 12, :align => "absmiddle"} %>&nbsp;&nbsp;&nbsp;&nbsp;
<%= @claimed_recording.recording.comment_count %>
<%= image_tag "content/icon_comment.png", {:width => 13, :height => 12, :align => "absmiddle"} %>&nbsp;&nbsp;&nbsp;&nbsp;
<%= @claimed_recording.recording.like_count %>
<%= image_tag "content/icon_like.png", {:width => 12, :height => 12, :align => "absmiddle"} %>
</div>
</div>
<br clear="all" /><br />
<%= render :partial => "shared/track_details", :locals => {:tracks => @claimed_recording.recording.recorded_tracks} %>
</div>
<br clear="all" />
<% if signed_in? %>
<% unless @claimed_recording.recording.band.nil? %>
<%= render :partial => "shared/landing_sidebar", :locals => {:user => @claimed_recording.recording.band, :recent_history => @claimed_recording.recording.band.recent_history} %>
<% else %>
<%= render :partial => "shared/landing_sidebar", :locals => {:user => @claimed_recording.recording.owner, :recent_history => @claimed_recording.recording.owner.recent_history} %>
<% end %>
<% else %>
<%= render :partial => "shared/cta_sidebar" %>
<% end %>
<% content_for :after_black_bar do %>
<br />
<%= render :partial => "shared/comments", :locals => {:comments => @claimed_recording.recording.comments} %>
<% end %>
<%= javascript_include_tag "web/recordings" %>
<%= render "clients/shareDialog" %>

View File

@ -0,0 +1,28 @@
<div class="landing-comments">
<h2>Comments:</h2><br/>
<div class="avatar-small">
<%= image_tag "shared/avatar_generic.png", {:alt => ""} %>
</div>
<div class="left w80 p10">
<textarea class="w100 p5 f15" rows="2" onfocus="$(this).html('')" onblur="if($(this).html() == ''){$(this).html('Enter a comment...')}">Enter a comment...</textarea>
</div>
<br clear="all" />
<div class="landing-comment-scroller">
<% comments.each do |c| %>
<div class="avatar-small mr10">
<% unless c.user.photo_url.blank? %>
<%= image_tag "#{c.user.photo_url}", {:alt => ""} %>
<% else %>
<%= image_tag "shared/avatar_generic.png", {:alt => ""} %>
<% end %>
</div>
<div class="w80 left p10 lightgrey mt10">
<a href="#"><%= c.user.name %></a>&nbsp;<%= c.comment %>
<br />
<div class="f12 grey mt5"><%= c.created_at.strftime("%b %e %Y, %l:%M %p") %></div>
</div>
<br clear="all" />
<% end %>
</div>
</div>

View File

@ -0,0 +1,10 @@
<div class="landing-sidebar">
<div class="cta">
<a href="/signup"><%= image_tag "web/cta_button.png", {:width => 348, :height => 92} %></a><br />
<a href="/signin">Already have an account?</a>
</div>
<br /><br />
<%= image_tag "web/carousel_musicians.jpg", {:width => 350, :alt => ""} %><br /><br />
<%= image_tag "web/carousel_fans.jpg", {:width => 350, :alt => ""} %><br /><br />
<%= image_tag "web/carousel_bands.jpg", {:width => 350, :alt => ""} %>
</div>

View File

@ -0,0 +1,26 @@
<div class="landing-sidebar"><br />
<h2>More by <%= user.name %>:</h2><br />
<div class="grey f16"><em>Now:</em></div>
<div class="f16"><span class="teal"><strong>SESSION:</strong></span> <a href="#" class="white">Live Session in Progress</a></div>
<div class="f13 lightgrey">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi commodo, ipsum sed pharetra gravida, orci magna rhoncus neque, id pulvinar odio lorem non turpis.</div>
<br /><br />
<div class="grey f16"><em>Yesterday:</em></div>
<div class="f16"><span class="orange"><strong>RECORDING:</strong></span> <a href="#" class="white">You Hurt Me Bad</a></div>
<div class="f13 lightgrey">Nullam sit amet enim. Suspendisse id velit vitae ligula volutpat condimentum. Aliquam erat volutpat. Sed quis velit. Nulla facilisi. </div>
<br /><br />
<div class="grey f16"><em>Dec. 18th:</em></div>
<div class="f16"><span class="teal"><strong>SESSION:</strong></span> <span class="grey">Session Ended. Unavailable.</span></div>
<div class="f13 lightgrey">Nulla libero. Vivamus pharetra posuere sapien. Nam consectetuer. Sed aliquam, nunc eget euismod ullamcorper, lectus nunc ullamcorper orci, fermentum bibendum enim nibh eget ipsum. </div>
<br /><br />
<div class="grey f16"><em>Dec. 12th:</em></div>
<div class="f16"><span class="orange"><strong>RECORDING:</strong></span> <a href="#" class="white">Bustin' My Chops</a></div>
<div class="f13 lightgrey">Donec porttitor ligula eu dolor. Maecenas vitae nulla consequat libero cursus venenatis. Nam magna enim, accumsan eu, blandit sed, blandit a, eros.</div>
<br /><br />
<div class="grey f16"><em>Dec. 10th:</em></div>
<div class="f16"><span class="teal"><strong>SESSION:</strong></span> <span class="grey">Session Ended. Unavailable.</span></div>
<div class="f13 lightgrey">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Morbi commodo, ipsum sed pharetra gravida, orci magna rhoncus neque, id pulvinar odio lorem non turpis. Nullam sit amet enim.</div>
<br /><br />
<div class="grey f16"><em>Nov. 29th:</em></div>
<div class="f16"><span class="teal"><strong>SESSION:</strong></span> <span class="grey">Session Ended. Unavailable.</span></div>
<div class="f13 lightgrey">Nulla libero. Vivamus pharetra posuere sapien. Nam consectetuer. </div>
</div>

View File

@ -0,0 +1,33 @@
<table class="w100">
<% tracks.each_with_index do |track, index| %>
<% if index % 2 == 0 %>
<tr><td height="15px;">&nbsp;</td></tr>
<tr>
<% end %>
<td width="50%">
<table>
<tr>
<td>
<div class="avatar-small m0">
<% unless track.user.photo_url.blank? %>
<%= image_tag "#{track.user.photo_url}", {:alt => ""} %>
<% else %>
<%= image_tag "shared/avatar_generic.png", {:alt => ""} %>
<% end %>
</div>
</td>
<td style="width:150px;"><div class="lightgrey f15 ml10"><%= track.user.name %></div></td>
<td class="p10">
<div class="ml10">
<%= image_tag "content/icon_instrument_#{track.instrument_id.tr(" ", "_")}45.png", {:width => 32, :alt => "", :title => "#{track.instrument_id}"} %>
</div>
</td>
<td width="10%"></td>
</tr>
</table>
</td>
<% if index % 2 > 0 %>
</tr>
<% end %>
<% end %>
</table>

View File

@ -1,17 +1,18 @@
<div id="profile" class="userinfo">
<!-- avatar -->
<a href="#" class="avatar_large">
<img id="header-avatar" src="/assets/shared/avatar_generic.png" />
</a>
<% if signed_in? %>
<!-- profile area -->
<!-- avatar -->
<div class="avatar_large">
<img id="header-avatar" />
</div>
<!-- user name -->
<div id="user"></div>
<div id="user" class="user"></div>
<div class="arrow-down"></div>
<ul class="shortcuts">
<ul class="shortcuts" style="z-index:1000;">
<!-- <li><a layout-link="account">Profile</a></li> -->
<li class="account-home"><%= link_to "Account Home", '/client#/account' %></li>
<li class="identity"><%= link_to "Identity", '/client#/account/identity' %></li>
@ -36,7 +37,7 @@
<!-- end profile area -->
<% else %>
<a class="signin" href="/signin">Sign In</a>
<div class="user"><a class="signin" href="/signup">Sign Up</a>&nbsp;or&nbsp;<a class="signin" href="/signin">Sign In</a></div>
<% end %>
</div>
</div>

View File

@ -6,7 +6,6 @@ SampleApp::Application.routes.draw do
end
resources :users
resources :sessions, only: [:new, :create, :destroy]
#root to: 'static_pages#home'
@ -24,10 +23,14 @@ SampleApp::Application.routes.draw do
match '/signin', to: 'sessions#new'
match '/signout', to: 'sessions#destroy', via: :delete
# oauth
match '/auth/:provider/callback', :to => 'sessions#oauth_callback'
match '/auth/failure', :to => 'sessions#failure'
# session / recording landing pages
match '/sessions/:id' => 'music_sessions#show', :via => :get, :as => 'music_session_detail'
match '/recordings/:id' => 'recordings#show', :via => :get, :as => 'recording_detail'
match '/isp', :to => 'users#isp'
match '/isp/ping.jar', :to => redirect('/ping.jar')
@ -297,6 +300,8 @@ SampleApp::Application.routes.draw do
match '/claimed_recordings/:id' => 'api_claimed_recordings#update', :via => :put
match '/claimed_recordings/:id' => 'api_claimed_recordings#delete', :via => :delete
# Mixes
match '/mixes/schedule' => 'api_mixes#schedule', :via => :post
match '/mixes/next' => 'api_mixes#next', :via => :get
match '/mixes/:id/finish' => 'api_mixes#finish', :via => :put
match '/mixes/:id/download' => 'api_mixes#download', :via => :get