* merged
This commit is contained in:
commit
b648c40587
|
|
@ -1,5 +1,5 @@
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
remote: http://rubygems.org/
|
||||
specs:
|
||||
little-plugger (1.1.3)
|
||||
logging (1.7.2)
|
||||
|
|
|
|||
|
|
@ -98,4 +98,7 @@ invited_users_facebook_support.sql
|
|||
first_recording_at.sql
|
||||
share_token.sql
|
||||
facebook_signup.sql
|
||||
audiomixer_mp3.sql
|
||||
audiomixer_mp3.sql
|
||||
share_token_2.sql
|
||||
large_photo_url.sql
|
||||
add_secret_to_user_authorization.sql
|
||||
|
|
@ -0,0 +1 @@
|
|||
ALTER TABLE user_authorizations ADD COLUMN secret VARCHAR(255);
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
ALTER TABLE users ADD COLUMN large_photo_url VARCHAR(2048);
|
||||
ALTER TABLE users ADD COLUMN cropped_large_s3_path VARCHAR(512);
|
||||
ALTER TABLE users ADD COLUMN cropped_large_fpfile VARCHAR(8000);
|
||||
|
||||
ALTER TABLE bands ADD COLUMN large_photo_url VARCHAR(2048);
|
||||
ALTER TABLE bands ADD COLUMN cropped_large_s3_path_photo VARCHAR(512);
|
||||
ALTER TABLE bands ADD COLUMN cropped_large_fpfile_photo VARCHAR(8000);
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
alter table music_sessions_history drop column share_token;
|
||||
alter table claimed_recordings drop column share_token;
|
||||
|
||||
CREATE TABLE share_tokens
|
||||
(
|
||||
id character varying(64) NOT NULL DEFAULT uuid_generate_v4(),
|
||||
token varchar(15) NOT NULL,
|
||||
shareable_id varchar(64) NOT NULL,
|
||||
shareable_type varchar(50) NOT NULL,
|
||||
created_at timestamp without time zone NOT NULL DEFAULT now(),
|
||||
updated_at timestamp without time zone NOT NULL DEFAULT now(),
|
||||
CONSTRAINT token_uniqkey UNIQUE (token),
|
||||
CONSTRAINT share_tokens_pkey PRIMARY KEY (id)
|
||||
);
|
||||
|
|
@ -94,6 +94,7 @@ require "jam_ruby/models/recording_liker"
|
|||
require "jam_ruby/models/recording_play"
|
||||
require "jam_ruby/models/recorded_track"
|
||||
require "jam_ruby/models/recorded_track_observer"
|
||||
require "jam_ruby/models/share_token"
|
||||
require "jam_ruby/models/mix"
|
||||
require "jam_ruby/models/claimed_recording"
|
||||
require "jam_ruby/models/crash_dump"
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ module JamRuby
|
|||
class Band < ActiveRecord::Base
|
||||
|
||||
attr_accessible :name, :website, :biography, :city, :state,
|
||||
:country, :original_fpfile_photo, :cropped_fpfile_photo,
|
||||
:cropped_s3_path_photo, :crop_selection_photo, :photo_url
|
||||
:country, :original_fpfile_photo, :cropped_fpfile_photo, :cropped_large_fpfile_photo,
|
||||
:cropped_s3_path_photo, :cropped_large_s3_path_photo, :crop_selection_photo, :photo_url, :large_photo_url
|
||||
|
||||
attr_accessor :updating_photo
|
||||
|
||||
|
|
@ -88,6 +88,7 @@ module JamRuby
|
|||
# we want to mak sure that original_fpfile and cropped_fpfile seems like real fpfile info objects (i.e, json objects from filepicker.io)
|
||||
errors.add(:original_fpfile_photo, ValidationMessages::INVALID_FPFILE) if self.original_fpfile_photo.nil? || self.original_fpfile_photo["key"].nil? || self.original_fpfile_photo["url"].nil?
|
||||
errors.add(:cropped_fpfile_photo, ValidationMessages::INVALID_FPFILE) if self.cropped_fpfile_photo.nil? || self.cropped_fpfile_photo["key"].nil? || self.cropped_fpfile_photo["url"].nil?
|
||||
errors.add(:cropped_large_fpfile_photo, ValidationMessages::INVALID_FPFILE) if self.cropped_large_fpfile_photo.nil? || self.cropped_large_fpfile_photo["key"].nil? || self.cropped_large_fpfile_photo["url"].nil?
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -196,18 +197,21 @@ module JamRuby
|
|||
return band
|
||||
end
|
||||
|
||||
def update_photo(original_fpfile, cropped_fpfile, crop_selection, aws_bucket)
|
||||
def update_photo(original_fpfile, cropped_fpfile, cropped_large_fpfile, crop_selection, aws_bucket)
|
||||
self.updating_photo = true
|
||||
|
||||
cropped_s3_path = cropped_fpfile["key"]
|
||||
cropped_large_s3_path = cropped_large_fpfile["key"]
|
||||
|
||||
return self.update_attributes(
|
||||
:original_fpfile_photo => original_fpfile,
|
||||
:cropped_fpfile_photo => cropped_fpfile,
|
||||
:cropped_large_fpfile_photo => cropped_large_fpfile,
|
||||
:cropped_s3_path_photo => cropped_s3_path,
|
||||
:cropped_large_s3_path_photo => cropped_large_s3_path,
|
||||
:crop_selection_photo => crop_selection,
|
||||
:photo_url => S3Util.url(aws_bucket, cropped_s3_path, :secure => false)
|
||||
)
|
||||
:photo_url => S3Util.url(aws_bucket, cropped_s3_path, :secure => false),
|
||||
:large_photo_url => S3Util.url(aws_bucket, cropped_large_s3_path, :secure => false))
|
||||
end
|
||||
|
||||
def delete_photo(aws_bucket)
|
||||
|
|
@ -217,15 +221,18 @@ module JamRuby
|
|||
unless self.cropped_s3_path_photo.nil?
|
||||
S3Util.delete(aws_bucket, File.dirname(self.cropped_s3_path_photo) + '/cropped.jpg')
|
||||
S3Util.delete(aws_bucket, self.cropped_s3_path_photo)
|
||||
S3Util.delete(aws_bucket, self.cropped_large_s3_path_photo)
|
||||
end
|
||||
|
||||
return self.update_attributes(
|
||||
:original_fpfile_photo => nil,
|
||||
:cropped_fpfile_photo => nil,
|
||||
:cropped_large_fpfile_photo => nil,
|
||||
:cropped_s3_path_photo => nil,
|
||||
:cropped_large_s3_path_photo => nil,
|
||||
:crop_selection_photo => nil,
|
||||
:photo_url => nil
|
||||
)
|
||||
:photo_url => nil,
|
||||
:large_photo_url => nil)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ module JamRuby
|
|||
validates :genre, presence: true
|
||||
validates_uniqueness_of :recording_id, :scope => :user_id
|
||||
|
||||
|
||||
belongs_to :recording, :class_name => "JamRuby::Recording", :inverse_of => :claimed_recordings
|
||||
belongs_to :user, :class_name => "JamRuby::User", :inverse_of => :claimed_recordings
|
||||
belongs_to :genre, :class_name => "JamRuby::Genre"
|
||||
has_many :recorded_tracks, :through => :recording, :class_name => "JamRuby::RecordedTrack"
|
||||
has_many :playing_sessions, :class_name => "JamRuby::MusicSession"
|
||||
has_one :share_token, :class_name => "JamRuby::ShareToken", :inverse_of => :shareable, :foreign_key => 'shareable_id'
|
||||
|
||||
before_create :generate_share_token
|
||||
|
||||
|
|
@ -54,12 +54,16 @@ module JamRuby
|
|||
private
|
||||
|
||||
def generate_share_token
|
||||
self.share_token = loop do
|
||||
token = loop do
|
||||
token = SecureRandom.urlsafe_base64(SHARE_TOKEN_LENGTH, false)
|
||||
token = remove_non_alpha_num(token)
|
||||
token.upcase!
|
||||
break token unless MusicSessionHistory.exists?(share_token: token)
|
||||
break token unless ShareToken.exists?(token: token)
|
||||
end
|
||||
|
||||
self.share_token = ShareToken.new
|
||||
self.share_token.token = token
|
||||
self.share_token.shareable_type = "recording"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -40,6 +40,11 @@ module JamRuby
|
|||
validate :creator_is_musician
|
||||
validate :no_new_playback_while_playing
|
||||
|
||||
before_create :create_uuid
|
||||
def create_uuid
|
||||
#self.id = SecureRandom.uuid
|
||||
end
|
||||
|
||||
def before_destroy
|
||||
self.mount.destroy if self.mount
|
||||
end
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ module JamRuby
|
|||
has_many :music_session_user_histories, :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"
|
||||
has_one :share_token, :class_name => "JamRuby::ShareToken", :inverse_of => :shareable, :foreign_key => 'shareable_id'
|
||||
|
||||
before_create :generate_share_token
|
||||
|
||||
|
|
@ -124,6 +125,10 @@ module JamRuby
|
|||
session_history.save!
|
||||
end
|
||||
|
||||
def is_over?
|
||||
!session_removed_at.nil?
|
||||
end
|
||||
|
||||
def end_history
|
||||
self.update_attribute(:session_removed_at, Time.now)
|
||||
|
||||
|
|
@ -155,12 +160,18 @@ module JamRuby
|
|||
|
||||
private
|
||||
def generate_share_token
|
||||
self.share_token = loop do
|
||||
self.id = music_session.id # unify music_session.id and music_session_history.id
|
||||
|
||||
token = loop do
|
||||
token = SecureRandom.urlsafe_base64(SHARE_TOKEN_LENGTH, false)
|
||||
token = remove_non_alpha_num(token)
|
||||
token.upcase!
|
||||
break token unless MusicSessionHistory.exists?(share_token: token)
|
||||
break token unless ShareToken.exists?(token: token)
|
||||
end
|
||||
|
||||
self.share_token = ShareToken.new
|
||||
self.share_token.token = token
|
||||
self.share_token.shareable_type = "session"
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ module JamRuby
|
|||
validates :sound, :inclusion => {:in => SOUND}
|
||||
validates :client_id, :presence => true # not a connection relation on purpose
|
||||
validates :track_id, :presence => true # not a track relation on purpose
|
||||
validates :client_track_id, :presence => true
|
||||
validates :md5, :presence => true, :if => :upload_starting?
|
||||
validates :length, length: {minimum: 1, maximum: 1024 * 1024 * 256 }, if: :upload_starting? # 256 megs max. is this reasonable? surely...
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
module JamRuby
|
||||
class ShareToken < ActiveRecord::Base
|
||||
belongs_to :shareable, :polymorphic => true
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -13,7 +13,7 @@ module JamRuby
|
|||
|
||||
after_save :check_lat_lng
|
||||
|
||||
attr_accessible :first_name, :last_name, :email, :city, :password, :password_confirmation, :state, :country, :birth_date, :subscribe_email, :terms_of_service, :original_fpfile, :cropped_fpfile, :cropped_s3_path, :photo_url, :crop_selection, :lat, :lng
|
||||
attr_accessible :first_name, :last_name, :email, :city, :password, :password_confirmation, :state, :country, :birth_date, :subscribe_email, :terms_of_service, :original_fpfile, :cropped_fpfile, :cropped_large_fpfile, :cropped_s3_path, :cropped_large_s3_path, :photo_url, :large_photo_url, :crop_selection, :lat, :lng
|
||||
|
||||
# updating_password corresponds to a lost_password
|
||||
attr_accessor :updating_password, :updating_email, :updated_email, :update_email_confirmation_url, :administratively_created, :current_password, :setting_password, :confirm_current_password, :updating_avatar, :updating_progression_field
|
||||
|
|
@ -187,6 +187,7 @@ module JamRuby
|
|||
# we want to mak sure that original_fpfile and cropped_fpfile seems like real fpfile info objects (i.e, json objects from filepicker.io)
|
||||
errors.add(:original_fpfile, ValidationMessages::INVALID_FPFILE) if self.original_fpfile.nil? || self.original_fpfile["key"].nil? || self.original_fpfile["url"].nil?
|
||||
errors.add(:cropped_fpfile, ValidationMessages::INVALID_FPFILE) if self.cropped_fpfile.nil? || self.cropped_fpfile["key"].nil? || self.cropped_fpfile["url"].nil?
|
||||
errors.add(:cropped_large_fpfile, ValidationMessages::INVALID_FPFILE) if self.cropped_large_fpfile.nil? || self.cropped_large_fpfile["key"].nil? || self.cropped_large_fpfile["url"].nil?
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -898,17 +899,21 @@ module JamRuby
|
|||
self.save
|
||||
end
|
||||
|
||||
def update_avatar(original_fpfile, cropped_fpfile, crop_selection, aws_bucket)
|
||||
def update_avatar(original_fpfile, cropped_fpfile, cropped_large_fpfile, crop_selection, aws_bucket)
|
||||
self.updating_avatar = true
|
||||
|
||||
cropped_s3_path = cropped_fpfile["key"]
|
||||
cropped_large_s3_path = cropped_large_fpfile["key"]
|
||||
|
||||
return self.update_attributes(
|
||||
:original_fpfile => original_fpfile,
|
||||
:cropped_fpfile => cropped_fpfile,
|
||||
:cropped_large_fpfile => cropped_large_fpfile,
|
||||
:cropped_s3_path => cropped_s3_path,
|
||||
:cropped_large_s3_path => cropped_large_s3_path,
|
||||
:crop_selection => crop_selection,
|
||||
:photo_url => S3Util.url(aws_bucket, cropped_s3_path, :secure => false)
|
||||
:photo_url => S3Util.url(aws_bucket, cropped_s3_path, :secure => false),
|
||||
:large_photo_url => S3Util.url(aws_bucket, cropped_large_s3_path, :secure => false)
|
||||
)
|
||||
end
|
||||
|
||||
|
|
@ -919,14 +924,18 @@ module JamRuby
|
|||
unless self.cropped_s3_path.nil?
|
||||
S3Util.delete(aws_bucket, File.dirname(self.cropped_s3_path) + '/cropped.jpg')
|
||||
S3Util.delete(aws_bucket, self.cropped_s3_path)
|
||||
S3Util.delete(aws_bucket, self.cropped_large_s3_path)
|
||||
end
|
||||
|
||||
return self.update_attributes(
|
||||
:original_fpfile => nil,
|
||||
:cropped_fpfile => nil,
|
||||
:cropped_large_fpfile => nil,
|
||||
:cropped_s3_path => nil,
|
||||
:cropped_large_s3_path => nil,
|
||||
:photo_url => nil,
|
||||
:crop_selection => nil
|
||||
:crop_selection => nil,
|
||||
:large_photo_url => nil
|
||||
)
|
||||
end
|
||||
|
||||
|
|
@ -965,6 +974,50 @@ module JamRuby
|
|||
end
|
||||
end
|
||||
|
||||
def invalidate_user_authorization(provider)
|
||||
auth = user_authorization(provider)
|
||||
auth.destroy if auth
|
||||
end
|
||||
|
||||
def user_authorization(provider)
|
||||
user_authorizations.where(provider: provider).first
|
||||
end
|
||||
|
||||
def auth_twitter
|
||||
!user_authorization('twitter').nil?
|
||||
end
|
||||
|
||||
def build_twitter_authorization(auth_hash)
|
||||
|
||||
twitter_uid = auth_hash[:uid]
|
||||
credentials = auth_hash[:credentials]
|
||||
secret = credentials[:secret] if credentials
|
||||
token = credentials[:token] if credentials
|
||||
|
||||
if twitter_uid && secret && token
|
||||
user_authorization = nil
|
||||
|
||||
unless self.new_record?
|
||||
# see if this user has an existing user_authorization for this provider
|
||||
user_authorization = UserAuthorization.find_by_user_id_and_provider(self.id, 'twitter')
|
||||
end
|
||||
end
|
||||
|
||||
if user_authorization.nil?
|
||||
user_authorization = UserAuthorization.new(provider: 'twitter',
|
||||
uid: twitter_uid,
|
||||
token: token,
|
||||
secret: secret,
|
||||
user: self)
|
||||
else
|
||||
user_authorization.uid = twitter_uid
|
||||
user_authorization.token = token
|
||||
user_authorization.secret = secret
|
||||
end
|
||||
|
||||
user_authorization
|
||||
end
|
||||
|
||||
# updates an existing user_authorization for facebook, or creates a new one if none exist
|
||||
def update_fb_authorization(fb_signup)
|
||||
if fb_signup.uid && fb_signup.token && fb_signup.token_expires_at
|
||||
|
|
@ -980,11 +1033,13 @@ module JamRuby
|
|||
self.user_authorizations.build provider: 'facebook',
|
||||
uid: fb_signup.uid,
|
||||
token: fb_signup.token,
|
||||
token_expiration: fb_signup.token_expires_at
|
||||
token_expiration: fb_signup.token_expires_at,
|
||||
user: self
|
||||
else
|
||||
user_authorization.uid = fb_signup.uid
|
||||
user_authorization.token = fb_signup.token
|
||||
user_authorization.token_expiration = fb_signup.token_expires_at
|
||||
user_authorization.save
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,18 +1,16 @@
|
|||
module JamRuby
|
||||
class UserAuthorization < ActiveRecord::Base
|
||||
|
||||
attr_accessible :provider, :uid, :token, :token_expiration
|
||||
attr_accessible :provider, :uid, :token, :token_expiration, :secret, :user
|
||||
|
||||
self.table_name = "user_authorizations"
|
||||
|
||||
self.primary_key = 'id'
|
||||
|
||||
belongs_to :user, :class_name => "JamRuby::User", :foreign_key => "user_id"
|
||||
validates :provider, :uid, :presence => true
|
||||
validates :provider, :uid, :user, :presence => true
|
||||
validates_uniqueness_of :uid, scope: :provider
|
||||
|
||||
# token and token_expiration can be missing
|
||||
|
||||
# token, secret, token_expiration can be missing
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ FactoryGirl.define do
|
|||
end
|
||||
end
|
||||
|
||||
factory :music_session, :class => JamRuby::MusicSession do
|
||||
factory :music_session_no_history, :class => JamRuby::MusicSession do
|
||||
sequence(:description) { |n| "Music Session #{n}" }
|
||||
fan_chat true
|
||||
fan_access true
|
||||
|
|
@ -42,8 +42,16 @@ FactoryGirl.define do
|
|||
genres [JamRuby::Genre.first]
|
||||
association :creator, :factory => :user
|
||||
|
||||
factory :music_session_with_mount do
|
||||
factory :music_session do
|
||||
|
||||
after(:create) { |session|
|
||||
MusicSessionHistory.save(session)
|
||||
}
|
||||
|
||||
factory :music_session_with_mount do
|
||||
association :mount, :factory => :icecast_mount
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -109,14 +117,46 @@ FactoryGirl.define do
|
|||
end
|
||||
|
||||
factory :recorded_track, :class => JamRuby::RecordedTrack do
|
||||
instrument JamRuby::Instrument.first
|
||||
sound 'stereo'
|
||||
sequence(:client_id) { |n| "client_id-#{n}"}
|
||||
sequence(:track_id) { |n| "track_id-#{n}"}
|
||||
sequence(:client_track_id) { |n| "client_track_id-#{n}"}
|
||||
md5 'abc'
|
||||
length 1
|
||||
fully_uploaded true
|
||||
association :user, factory: :user
|
||||
association :recording, factory: :recording
|
||||
end
|
||||
|
||||
factory :instrument, :class => JamRuby::Instrument do
|
||||
|
||||
description { |n| "Instrument #{n}" }
|
||||
end
|
||||
|
||||
|
||||
factory :recording, :class => JamRuby::Recording do
|
||||
|
||||
association :owner, factory: :user
|
||||
association :music_session, factory: :music_session
|
||||
|
||||
factory :recording_with_track do
|
||||
before(:create) { |recording|
|
||||
recording.recorded_tracks << FactoryGirl.create(:recorded_track, recording: recording, user: recording.owner)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
factory :claimed_recording, :class => JamRuby::ClaimedRecording do
|
||||
sequence(:name) { |n| "name-#{n}" }
|
||||
sequence(:description) { |n| "description-#{n}" }
|
||||
is_public true
|
||||
is_downloadable true
|
||||
association :genre, factory: :genre
|
||||
association :user, factory: :user
|
||||
|
||||
before(:create) { |claimed_recording|
|
||||
claimed_recording.recording = FactoryGirl.create(:recording_with_track, owner: claimed_recording.user)
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
factory :musician_instrument, :class => JamRuby::MusicianInstrument do
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ describe 'Band search' do
|
|||
it "by now playing" do
|
||||
# should get 1 result with 1 active session
|
||||
session = make_session(@band3)
|
||||
FactoryGirl.create(:music_session_history, :music_session => session)
|
||||
#FactoryGirl.create(:music_session_history, :music_session => session)
|
||||
|
||||
results = Search.band_filter({ :orderby => 'playing' })
|
||||
expect(results.results.count).to be 1
|
||||
|
|
@ -129,7 +129,7 @@ describe 'Band search' do
|
|||
# should get 2 results with 2 active sessions
|
||||
# sort order should be created_at DESC
|
||||
session = make_session(@band4)
|
||||
FactoryGirl.create(:music_session_history, :music_session => session)
|
||||
#FactoryGirl.create(:music_session_history, :music_session => session)
|
||||
results = Search.band_filter({ :orderby => 'playing' })
|
||||
expect(results.results.count).to be 2
|
||||
expect(results.results[0].id).to eq(@band4.id)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ require 'spec_helper'
|
|||
describe MusicSessionHistory do
|
||||
|
||||
let(:some_user) { FactoryGirl.create(:user) }
|
||||
let(:music_session) { FactoryGirl.create(:music_session) }
|
||||
let(:music_session) { FactoryGirl.create(:music_session_no_history) }
|
||||
let(:history) { FactoryGirl.create(:music_session_history, :music_session => music_session) }
|
||||
let(:user_history1) { FactoryGirl.create(:music_session_user_history, :history => history, :user => music_session.creator) }
|
||||
let(:user_history2) { FactoryGirl.create(:music_session_user_history, :history => history, :user => some_user) }
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ require 'spec_helper'
|
|||
describe MusicSessionUserHistory do
|
||||
|
||||
let(:some_user) { FactoryGirl.create(:user) }
|
||||
let(:music_session) { FactoryGirl.create(:music_session) }
|
||||
let(:music_session) { FactoryGirl.create(:music_session_no_history) }
|
||||
let(:history) { FactoryGirl.create(:music_session_history, :music_session => music_session) }
|
||||
let(:user_history1) { FactoryGirl.create(:music_session_user_history, :history => history, :user => music_session.creator) }
|
||||
let(:user_history2) { FactoryGirl.create(:music_session_user_history, :history => history, :user => some_user) }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe ShareToken do
|
||||
|
||||
let(:user) { FactoryGirl.create(:user) }
|
||||
let(:music_session) {FactoryGirl.create(:music_session) }
|
||||
let(:claimed_recording) {FactoryGirl.create(:claimed_recording) }
|
||||
|
||||
before(:each) do
|
||||
ShareToken.delete_all
|
||||
end
|
||||
|
||||
it "can reference a music session" do
|
||||
music_session.touch # should create a MSH, and a token, too
|
||||
ShareToken.count.should == 1
|
||||
music_session.music_session_history.share_token.should_not be_nil
|
||||
token = ShareToken.find_by_shareable_id!(music_session.id)
|
||||
token.should == music_session.music_session_history.share_token
|
||||
token.shareable_id.should == music_session.id
|
||||
token.shareable_type.should == 'session'
|
||||
end
|
||||
|
||||
it "can reference a claimed recording" do
|
||||
claimed_recording.touch # should create a share token
|
||||
ShareToken.count.should == 2 # one for MSH, one for recording
|
||||
claimed_recording.share_token.should_not be_nil
|
||||
token = ShareToken.find_by_shareable_id!(claimed_recording.id)
|
||||
claimed_recording.share_token.should == token
|
||||
token.shareable_type.should == 'recording'
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -403,7 +403,8 @@ describe User do
|
|||
@user.user_authorizations.build provider: 'facebook',
|
||||
uid: '1',
|
||||
token: '1',
|
||||
token_expiration: Time.now
|
||||
token_expiration: Time.now,
|
||||
user: @user
|
||||
@user.save!
|
||||
end
|
||||
|
||||
|
|
@ -411,14 +412,16 @@ describe User do
|
|||
@user.user_authorizations.build provider: 'facebook',
|
||||
uid: '1',
|
||||
token: '1',
|
||||
token_expiration: Time.now
|
||||
token_expiration: Time.now,
|
||||
user: @user
|
||||
@user.save!
|
||||
|
||||
@user2 = FactoryGirl.create(:user)
|
||||
@user2.user_authorizations.build provider: 'facebook',
|
||||
uid: '1',
|
||||
token: '1',
|
||||
token_expiration: Time.now
|
||||
token_expiration: Time.now,
|
||||
user: @user2
|
||||
@user2.save.should be_false
|
||||
@user2.errors[:user_authorizations].should == ['is invalid']
|
||||
end
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ ActiveRecord::Base.add_observer UserObserver.instance
|
|||
ActiveRecord::Base.add_observer FeedbackObserver.instance
|
||||
ActiveRecord::Base.add_observer RecordedTrackObserver.instance
|
||||
|
||||
RecordedTrack.observers.disable :all # only a few tests want this observer active
|
||||
|
||||
# put ActionMailer into test mode
|
||||
ActionMailer::Base.delivery_method = :test
|
||||
|
|
|
|||
|
|
@ -40,7 +40,9 @@ gem 'amqp', '0.9.8'
|
|||
gem 'logging-rails', :require => 'logging/rails'
|
||||
gem 'omniauth', '1.1.1'
|
||||
gem 'omniauth-facebook', '1.4.1'
|
||||
gem 'omniauth-twitter'
|
||||
gem 'omniauth-google-oauth2', '0.2.1'
|
||||
gem 'twitter'
|
||||
gem 'fb_graph', '2.5.9'
|
||||
gem 'sendgrid', '1.1.0'
|
||||
gem 'recaptcha', '0.3.4'
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 92 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
|
|
@ -13,6 +13,7 @@
|
|||
var avatar;
|
||||
var selection = null;
|
||||
var targetCropSize = 88;
|
||||
var largerCropSize = 200;
|
||||
var updatingAvatar = false;
|
||||
var userDropdown;
|
||||
|
||||
|
|
@ -320,15 +321,32 @@
|
|||
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,
|
||||
crop_selection: currentSelection
|
||||
})
|
||||
.done(updateAvatarSuccess)
|
||||
.fail(app.ajaxError)
|
||||
.always(function() { removeAvatarSpinner(); self.updatingAvatar = false;})
|
||||
filepicker.convert(cropped, {
|
||||
height: largerCropSize,
|
||||
width: largerCropSize,
|
||||
fit: 'scale',
|
||||
format: 'jpg',
|
||||
quality: 75,
|
||||
policy: filepickerPolicy.policy,
|
||||
signature: filepickerPolicy.signature
|
||||
}, { path: createStorePath(self.userDetail) + 'large.jpg', access: 'public' },
|
||||
function(scaledLarger) {
|
||||
logger.debug("converted and scaled final image %o", scaled);
|
||||
rest.updateAvatar({
|
||||
original_fpfile: determineCurrentFpfile(),
|
||||
cropped_fpfile: scaled,
|
||||
cropped_large_fpfile: scaledLarger,
|
||||
crop_selection: currentSelection
|
||||
})
|
||||
.done(updateAvatarSuccess)
|
||||
.fail(app.ajaxError)
|
||||
.always(function() { removeAvatarSpinner(); self.updatingAvatar = false;})
|
||||
},
|
||||
function(fperror) {
|
||||
alert("unable to scale larger selection. error code: " + fperror.code);
|
||||
removeAvatarSpinner();
|
||||
self.updatingAvatar = false;
|
||||
});
|
||||
},
|
||||
function(fperror) {
|
||||
alert("unable to scale selection. error code: " + fperror.code);
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
//= require jquery.Jcrop
|
||||
//= require jquery.naturalsize
|
||||
//= require jquery.queryparams
|
||||
//= require jquery.clipboard
|
||||
//= require jquery.timeago
|
||||
//= require globals
|
||||
//= require_directory .
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@
|
|||
if (bandId.length === 0) {
|
||||
rest.createBand(band).done(function(response) {
|
||||
createBandInvitations(response.id, function() {
|
||||
context.location = "#/bandProfile/" + response.id;
|
||||
context.location = "/client#/bandProfile/" + response.id;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -200,7 +200,7 @@
|
|||
band.id = bandId;
|
||||
rest.updateBand(band).done(function(response) {
|
||||
createBandInvitations(band.id, function() {
|
||||
context.location = "#/bandProfile/" + band.id;
|
||||
context.location = "/client#/bandProfile/" + band.id;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -473,7 +473,7 @@
|
|||
|
||||
$('#btn-band-setup-cancel').click(function() {
|
||||
resetForm();
|
||||
context.location = "#/home";
|
||||
context.location = "/client#/home";
|
||||
});
|
||||
|
||||
$('#btn-band-setup-next').click(function() {
|
||||
|
|
@ -510,7 +510,7 @@
|
|||
$('#band-change-photo').click(function(evt) {
|
||||
evt.stopPropagation();
|
||||
$("#hdn-band-id").val(bandId);
|
||||
context.location = '#/band/setup/photo';
|
||||
context.location = '/client#/band/setup/photo';
|
||||
return false;
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -14,13 +14,14 @@
|
|||
var bandPhoto;
|
||||
var selection = null;
|
||||
var targetCropSize = 88;
|
||||
var largeCropSize = 200;
|
||||
var updatingBandPhoto = false;
|
||||
|
||||
function beforeShow(data) {
|
||||
bandId = $("#hdn-band-id").val();
|
||||
logger.debug("bandId=" + bandId);
|
||||
if (!bandId) {
|
||||
context.location = '#/home';
|
||||
context.location = '/client#/home';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -143,7 +144,7 @@
|
|||
function navToEditProfile() {
|
||||
resetForm();
|
||||
$("#hdn-band-id").val(bandId);
|
||||
context.location = '#/band/setup';
|
||||
context.location = '/client#/band/setup';
|
||||
}
|
||||
|
||||
function renderBandPhotoSpinner() {
|
||||
|
|
@ -322,16 +323,34 @@
|
|||
signature: filepickerPolicy.signature
|
||||
}, { path: createStorePath(self.bandDetail), access: 'public' },
|
||||
function(scaled) {
|
||||
logger.debug("converted and scaled final image %o", scaled);
|
||||
rest.updateBandPhoto({
|
||||
original_fpfile: determineCurrentFpfile(),
|
||||
cropped_fpfile: scaled,
|
||||
crop_selection: currentSelection,
|
||||
id: bandId
|
||||
})
|
||||
.done(updateBandPhotoSuccess)
|
||||
.fail(app.ajaxError)
|
||||
.always(function() { removeBandPhotoSpinner(); self.updatingBandPhoto = false;})
|
||||
|
||||
filepicker.convert(cropped, {
|
||||
height: largeCropSize,
|
||||
width: largeCropSize,
|
||||
fit: 'scale',
|
||||
format: 'jpg',
|
||||
quality: 75,
|
||||
policy: filepickerPolicy.policy,
|
||||
signature: filepickerPolicy.signature
|
||||
}, { path: createStorePath(self.bandDetail) + 'large.jpg', access: 'public' },
|
||||
function(scaledLarger) {
|
||||
logger.debug("converted and scaled final image %o", scaled);
|
||||
rest.updateBandPhoto({
|
||||
original_fpfile: determineCurrentFpfile(),
|
||||
cropped_fpfile: scaled,
|
||||
cropped_large_fpfile: scaledLarger,
|
||||
crop_selection: currentSelection,
|
||||
id: bandId
|
||||
})
|
||||
.done(updateBandPhotoSuccess)
|
||||
.fail(app.ajaxError)
|
||||
.always(function() { removeBandPhotoSpinner(); self.updatingBandPhoto = false;})
|
||||
},
|
||||
function(fperror) {
|
||||
alert("unable to scale larger selection. error code: " + fperror.code);
|
||||
removeBandPhotoSpinner();
|
||||
self.updatingBandPhoto = false;
|
||||
})
|
||||
},
|
||||
function(fperror) {
|
||||
alert("unable to scale selection. error code: " + fperror.code);
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@
|
|||
success: function(response) {
|
||||
var newSessionId = response.id;
|
||||
var invitationCount = inviteMusiciansUtil.createInvitations(newSessionId, function() {
|
||||
context.location = '#/session/' + newSessionId;
|
||||
context.location = '/client#/session/' + newSessionId;
|
||||
});
|
||||
// Re-loading the session settings will cause the form to reset with the right stuff in it.
|
||||
// This is an extra xhr call, but it keeps things to a single codepath
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
(function(context,$) {
|
||||
"use strict";
|
||||
|
||||
context.JK = context.JK || {};
|
||||
context.JK.FacebookHelper = function(app) {
|
||||
var logger = context.JK.logger;
|
||||
var loginStatusDeferred = null;
|
||||
var $self = $(this);
|
||||
var connected = false;
|
||||
|
||||
function promptLogin() {
|
||||
|
||||
if(connected) {
|
||||
// instantly return previous login info
|
||||
return loginStatusDeferred;
|
||||
}
|
||||
|
||||
loginStatusDeferred = $.Deferred();
|
||||
|
||||
FB.login(function(response) {
|
||||
handle_fblogin_response(response);
|
||||
}, {scope:'publish_stream'});
|
||||
|
||||
return loginStatusDeferred;
|
||||
}
|
||||
|
||||
function handle_fblogin_response(response) {
|
||||
|
||||
console.log("facebook login response: status=" + response.status)
|
||||
|
||||
if(response.status == "connected") {
|
||||
connected = true;
|
||||
}
|
||||
|
||||
$self.triggerHandler('fb.login_response', {response: response});
|
||||
|
||||
loginStatusDeferred.resolve(response);
|
||||
}
|
||||
|
||||
function initialize(fbAppID) {
|
||||
loginStatusDeferred = $.Deferred();
|
||||
var fbAppID_ = fbAppID;
|
||||
window.fbAsyncInit = function() {
|
||||
FB.init({
|
||||
appId : fbAppID_,
|
||||
// channelUrl : '//WWW.YOUR_DOMAIN.COM/channel.html',
|
||||
status : true, // check the login status upon init?
|
||||
cookie : true, // set sessions cookies to allow server to access the session?
|
||||
xfbml : true, // parse XFBML tags on this page?
|
||||
oauth : true // enable OAuth 2.0
|
||||
});
|
||||
|
||||
// listen to see if the user is known/logged in
|
||||
FB.getLoginStatus(function(response) {
|
||||
handle_fblogin_response(response);
|
||||
});
|
||||
};
|
||||
|
||||
// Load the SDK Asynchronously
|
||||
(function(d){
|
||||
var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
|
||||
js = d.createElement('script'); js.id = id; js.async = true;
|
||||
js.src = "//connect.facebook.net/en_US/all.js";
|
||||
d.getElementsByTagName('head')[0].appendChild(js);
|
||||
}(document));
|
||||
}
|
||||
|
||||
this.initialize = initialize;
|
||||
this.promptLogin = promptLogin;
|
||||
};
|
||||
|
||||
|
||||
|
||||
})(window, jQuery);
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
(function(context,$) {
|
||||
|
||||
/**
|
||||
* Javascript wrappers for the REST API
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
context.JK = context.JK || {};
|
||||
context.JK.FacebookRest = function() {
|
||||
|
||||
var self = this;
|
||||
var logger = context.JK.logger;
|
||||
|
||||
// https://developers.facebook.com/docs/reference/api/post
|
||||
function post(options) {
|
||||
var d = $.Deferred();
|
||||
|
||||
FB.api(
|
||||
'https://graph.facebook.com/me/feed',
|
||||
'post',
|
||||
options,
|
||||
function(response) {
|
||||
if (!response || response.error) {
|
||||
d.reject(response)
|
||||
} else {
|
||||
d.resolve(response);
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
this.post = post;
|
||||
|
||||
return this;
|
||||
};
|
||||
})(window,jQuery);
|
||||
|
|
@ -94,7 +94,7 @@
|
|||
|
||||
function events() {
|
||||
$('body').on('click', 'div[layout="header"] h1', function() {
|
||||
context.location = '#/home';
|
||||
context.location = '/client#/home';
|
||||
});
|
||||
|
||||
$('#account-identity-form').submit(handleIdentitySubmit);
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@
|
|||
|
||||
app.bindDialog('inviteUsers', dialogBindings);
|
||||
|
||||
callFB(fbAppID);
|
||||
//callFB(fbAppID);
|
||||
};
|
||||
|
||||
this.initialize = initialize;
|
||||
|
|
|
|||
|
|
@ -43,6 +43,16 @@
|
|||
});
|
||||
}
|
||||
|
||||
function getSessionHistory(id) {
|
||||
return $.ajax({
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
url: '/api/sessions/' + id + '/history',
|
||||
contentType: 'application/json',
|
||||
processData: false
|
||||
});
|
||||
}
|
||||
|
||||
function addSessionComment(sessionId, userId, comment) {
|
||||
return $.ajax({
|
||||
url: '/api/sessions/' + sessionId + "/comments",
|
||||
|
|
@ -274,11 +284,13 @@
|
|||
|
||||
var original_fpfile = options['original_fpfile'];
|
||||
var cropped_fpfile = options['cropped_fpfile'];
|
||||
var cropped_large_fpfile = options['cropped_large_fpfile'];
|
||||
var crop_selection = options['crop_selection'];
|
||||
|
||||
logger.debug(JSON.stringify({
|
||||
original_fpfile : original_fpfile,
|
||||
cropped_fpfile : cropped_fpfile,
|
||||
cropped_large_fpfile : cropped_large_fpfile,
|
||||
crop_selection : crop_selection
|
||||
}));
|
||||
|
||||
|
|
@ -292,6 +304,7 @@
|
|||
data: JSON.stringify({
|
||||
original_fpfile : original_fpfile,
|
||||
cropped_fpfile : cropped_fpfile,
|
||||
cropped_large_fpfile : cropped_large_fpfile,
|
||||
crop_selection : crop_selection
|
||||
})
|
||||
});
|
||||
|
|
@ -328,11 +341,13 @@
|
|||
|
||||
var original_fpfile = options['original_fpfile'];
|
||||
var cropped_fpfile = options['cropped_fpfile'];
|
||||
var cropped_large_fpfile = options['cropped_large_fpfile'];
|
||||
var crop_selection = options['crop_selection'];
|
||||
|
||||
logger.debug(JSON.stringify({
|
||||
original_fpfile : original_fpfile,
|
||||
cropped_fpfile : cropped_fpfile,
|
||||
cropped_large_fpfile : cropped_large_fpfile,
|
||||
crop_selection : crop_selection
|
||||
}));
|
||||
|
||||
|
|
@ -346,6 +361,7 @@
|
|||
data: JSON.stringify({
|
||||
original_fpfile : original_fpfile,
|
||||
cropped_fpfile : cropped_fpfile,
|
||||
cropped_large_fpfile : cropped_large_fpfile,
|
||||
crop_selection : crop_selection
|
||||
})
|
||||
});
|
||||
|
|
@ -665,7 +681,6 @@
|
|||
}
|
||||
|
||||
function getClaimedRecordings(options) {
|
||||
|
||||
return $.ajax({
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
|
|
@ -675,6 +690,15 @@
|
|||
});
|
||||
}
|
||||
|
||||
function getClaimedRecording(id) {
|
||||
return $.ajax({
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
contentType: 'application/json',
|
||||
url: "/api/claimed_recordings/" + id
|
||||
});
|
||||
}
|
||||
|
||||
function claimRecording(options) {
|
||||
var recordingId = options["id"];
|
||||
|
||||
|
|
@ -743,6 +767,44 @@
|
|||
});
|
||||
}
|
||||
|
||||
function getShareSession(options) {
|
||||
var id = getId(options);
|
||||
var provider = options['provider'];
|
||||
delete options['provider']
|
||||
|
||||
return $.ajax({
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
contentType: 'application/json',
|
||||
url: "/api/users/" + id + "/share/session/" + provider,
|
||||
data: options
|
||||
})
|
||||
}
|
||||
|
||||
function getShareRecording(options) {
|
||||
var id = getId(options);
|
||||
var provider = options['provider'];
|
||||
delete options['provider']
|
||||
|
||||
return $.ajax({
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
contentType: 'application/json',
|
||||
url: "/api/users/" + id + "/share/recording/" + provider,
|
||||
data: options
|
||||
})
|
||||
}
|
||||
|
||||
function tweet(options) {
|
||||
return $.ajax({
|
||||
type: "POST",
|
||||
dataType: "json",
|
||||
contentType: 'application/json',
|
||||
url: "/api/twitter/tweet",
|
||||
data: JSON.stringify(options)
|
||||
})
|
||||
}
|
||||
|
||||
function initialize() {
|
||||
return self;
|
||||
}
|
||||
|
|
@ -770,6 +832,7 @@
|
|||
this.getBandFollowing = getBandFollowing;
|
||||
this.getBands = getBands;
|
||||
this.updateSession = updateSession;
|
||||
this.getSessionHistory = getSessionHistory;
|
||||
this.addSessionComment = addSessionComment;
|
||||
this.addSessionLike = addSessionLike;
|
||||
this.addRecordingComment = addRecordingComment;
|
||||
|
|
@ -792,6 +855,7 @@
|
|||
this.stopRecording = stopRecording;
|
||||
this.getRecording = getRecording;
|
||||
this.getClaimedRecordings = getClaimedRecordings;
|
||||
this.getClaimedRecording = getClaimedRecording;
|
||||
this.claimRecording = claimRecording;
|
||||
this.startPlayClaimedRecording = startPlayClaimedRecording;
|
||||
this.stopPlayClaimedRecording = stopPlayClaimedRecording;
|
||||
|
|
@ -807,6 +871,9 @@
|
|||
this.updateBandInvitation = updateBandInvitation;
|
||||
this.removeBandMember = removeBandMember;
|
||||
this.login = login;
|
||||
this.getShareSession = getShareSession;
|
||||
this.getShareRecording = getShareRecording;
|
||||
this.tweet = tweet;
|
||||
|
||||
return this;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@
|
|||
if (targetArg) {
|
||||
targetUrl += "/:" + targetArg;
|
||||
}
|
||||
rules[target] = {route: '/' + targetUrl + '/d:?', method: target};
|
||||
rules[target] = {route: '/' + targetUrl + '/:d?', method: target};
|
||||
routingContext[target] = fn;
|
||||
});
|
||||
routes.context(routingContext);
|
||||
|
|
@ -328,7 +328,7 @@
|
|||
hash = null;
|
||||
}
|
||||
|
||||
var url = '#/home';
|
||||
var url = '/client#/home';
|
||||
if (hash) {
|
||||
url = hash;
|
||||
}
|
||||
|
|
@ -337,6 +337,7 @@
|
|||
context.location = url;
|
||||
}
|
||||
|
||||
|
||||
this.unloadFunction = function() {
|
||||
logger.debug("window.unload function called.");
|
||||
|
||||
|
|
@ -359,6 +360,7 @@
|
|||
this.layout = new context.JK.Layout();
|
||||
this.layout.initialize(this.opts.layoutOpts);
|
||||
events();
|
||||
this.layout.handleDialogState();
|
||||
|
||||
if(opts.inClient) {
|
||||
registerLoginAck();
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@
|
|||
gridOuterMargin: 6, // Outer margin on Grids (added to screenMargin if screen)
|
||||
gridPadding: 8, // Padding around grid cells. Added to outer margin.
|
||||
animationDuration: 400,
|
||||
allowBodyOverflow: false // Allow tests to disable the body-no-scroll policy
|
||||
allowBodyOverflow: false, // Allow tests to disable the body-no-scroll policy
|
||||
sizeOverlayToContent: false // if true, use the size of <body> tag to decide overlay size everytime overlay is shown. should be used in non-client settings
|
||||
};
|
||||
|
||||
var width = $(context).width();
|
||||
|
|
@ -400,7 +401,7 @@
|
|||
var destination = $(evt.currentTarget).attr('layout-link');
|
||||
var destinationType = $('[layout-id="' + destination + '"]').attr("layout");
|
||||
if (destinationType === "screen") {
|
||||
context.location = '#/' + destination;
|
||||
context.location = '/client#/' + destination;
|
||||
} else if (destinationType === "dialog") {
|
||||
showDialog(destination);
|
||||
}
|
||||
|
|
@ -522,6 +523,15 @@
|
|||
function showDialog(dialog) {
|
||||
if(!dialogEvent(dialog, 'beforeShow')) {return;}
|
||||
var $overlay = $('.dialog-overlay')
|
||||
|
||||
if(opts.sizeOverlayToContent) {
|
||||
var $body = $('body')
|
||||
$('.dialog-overlay').css({
|
||||
width: $body.width() + 'px',
|
||||
height: $body.height() + 'px'
|
||||
});
|
||||
}
|
||||
|
||||
$overlay.show();
|
||||
centerDialog(dialog);
|
||||
var $dialog = $('[layout-id="' + dialog + '"]');
|
||||
|
|
@ -532,6 +542,7 @@
|
|||
|
||||
function centerDialog(dialog) {
|
||||
var $dialog = $('[layout-id="' + dialog + '"]');
|
||||
console.log("$dialog.width, height", $dialog.width(), $dialog.height())
|
||||
$dialog.css({
|
||||
left: width/2 - ($dialog.width()/2) + "px",
|
||||
top: height/2 - ($dialog.height()/2) + "px"
|
||||
|
|
@ -578,6 +589,29 @@
|
|||
context.JK.GA.virtualPageView(location.pathname + location.search + location.hash);
|
||||
}
|
||||
|
||||
function handleDialogState() {
|
||||
var rawDialogState = $.cookie('dialog_state');
|
||||
try {
|
||||
var dialogState = JSON.parse(rawDialogState);
|
||||
if(!dialogState) { $.removeCookie('dialog_state'); return; }
|
||||
}
|
||||
catch (e) {$.removeCookie('dialog_state'); return; }
|
||||
|
||||
var dialogName = dialogState['name'];
|
||||
if(dialogName) {
|
||||
setTimeout(function() {
|
||||
// TODO: we need a 'everything is initialized' event
|
||||
showDialog(dialogName);
|
||||
}, 0);
|
||||
}
|
||||
$.removeCookie('dialog_state');
|
||||
}
|
||||
|
||||
// on next page load, a dialog of this name will show
|
||||
function queueDialog(name) {
|
||||
$.cookie('dialog_state', JSON.stringify({name:name}))
|
||||
}
|
||||
|
||||
function events() {
|
||||
$(context).resize(function() {
|
||||
if (resizing) {
|
||||
|
|
@ -725,6 +759,9 @@
|
|||
|
||||
this.closeDialog = closeDialog;
|
||||
|
||||
this.handleDialogState = handleDialogState;
|
||||
this.queueDialog = queueDialog;
|
||||
|
||||
/**
|
||||
* Given information on a grid, and a given card's grid settings, use the
|
||||
* margin options and return a list of [top, left, width, height]
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@
|
|||
$('#search-results').empty();
|
||||
var query = $('#search-input').val();
|
||||
if (query) {
|
||||
context.location = '#/searchResults/:' + query;
|
||||
context.location = '/client#/searchResults/:' + query;
|
||||
} else {
|
||||
query = $('#query').html();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -102,6 +102,9 @@
|
|||
sessionId = data.id;
|
||||
$('#session-mytracks-container').empty();
|
||||
displayDoneRecording(); // assumption is that you can't join a recording session, so this should be safe
|
||||
|
||||
var shareDialog = new JK.ShareDialog(context.JK.app, sessionId, "session");
|
||||
shareDialog.initialize(context.JK.FacebookHelperInstance);
|
||||
}
|
||||
|
||||
function alertCallback(type, text) {
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@
|
|||
}
|
||||
|
||||
function onTermsAccepted(sessionId) {
|
||||
context.location = '#/session/' + sessionId;
|
||||
context.location = '/client#/session/' + sessionId;
|
||||
}
|
||||
|
||||
function events() {
|
||||
|
|
|
|||
|
|
@ -2,114 +2,483 @@
|
|||
|
||||
"use strict";
|
||||
context.JK = context.JK || {};
|
||||
context.JK.ShareDialog = function(app) {
|
||||
context.JK.ShareDialog = function(app, entityId, entityType) {
|
||||
var logger = context.JK.logger;
|
||||
var rest = context.JK.Rest();
|
||||
var dialogId = '#share-dialog'
|
||||
var facebookRest = context.JK.FacebookRest();
|
||||
var facebookHelper = null;
|
||||
var dialogId = '#share-dialog';
|
||||
var userDetail = null;
|
||||
var entity = null;
|
||||
var remainingCap = 140 - 22 - 1; // 140 tweet max, minus 22 for link size, minus 1 for space
|
||||
|
||||
function registerEvents(onOff) {
|
||||
var textMap = {
|
||||
LIVE_SESSION: "LIVE SESSION",
|
||||
SESSION: "SESSION",
|
||||
RECORDING: "RECORDING",
|
||||
RECORDED: "RECORDED"
|
||||
};
|
||||
|
||||
$(dialogId + ' .dialog-share-button').unbind('click').click(function(e) {
|
||||
function showSpinner() {
|
||||
$(dialogId + ' .dialog-inner').hide();
|
||||
var spinner = $('<div class="spinner spinner-large"></div>')
|
||||
$(dialogId + ' .content-head').after(spinner);
|
||||
|
||||
|
||||
return false;
|
||||
})
|
||||
}
|
||||
|
||||
this.fb_login = function() {
|
||||
FB.login(function(response) {
|
||||
handle_fblogin_response(response);
|
||||
}, {scope:'publish_stream'});
|
||||
function hideSpinner() {
|
||||
$(dialogId + ' .spinner').remove();
|
||||
$(dialogId + ' .dialog-inner').show();
|
||||
}
|
||||
|
||||
|
||||
|
||||
function handleRecordingShareWithGoogle(message) {
|
||||
var defer = $.Deferred();
|
||||
|
||||
defer.resolve(); // remove when implemented
|
||||
|
||||
return defer;
|
||||
}
|
||||
|
||||
function handleRecordingShareWithTwitter(message) {
|
||||
var defer = $.Deferred();
|
||||
|
||||
rest.tweet({message: message + ' ' + entity.share_url})
|
||||
.done(function() {
|
||||
defer.resolve();
|
||||
})
|
||||
.fail(function(jqXHR) {
|
||||
if(jqXHR.status == 422) {
|
||||
// implies twitter token error.
|
||||
app.notify({
|
||||
title : "Failed to Tweet",
|
||||
text : "You need to re-authorize JamKazam to access your Twitter account. Click (sign in) in the Share Dialog.",
|
||||
"icon_url": "/assets/content/icon_alert_big.png"
|
||||
});
|
||||
disableTwitter();
|
||||
}
|
||||
else {
|
||||
app.notifyServerError(jqXHR, "Unable to Share with Twitter");
|
||||
}
|
||||
defer.reject();
|
||||
})
|
||||
return defer;
|
||||
}
|
||||
|
||||
function handleRecordingShareWithFacebook(message) {
|
||||
var defer = $.Deferred();
|
||||
|
||||
rest.getShareRecording({ provider:'facebook', claimed_recording: entityId})
|
||||
.done(function(data) {
|
||||
facebookHelper.promptLogin()
|
||||
.done(function(response) {
|
||||
if(response.status == "connected") {
|
||||
facebookRest.post({
|
||||
access_token: response.authResponse.accessToken,
|
||||
message: message,
|
||||
description: data.description,
|
||||
caption: data.caption,
|
||||
name: data.title,
|
||||
picture: data.photo_url
|
||||
})
|
||||
.done(function(response) {
|
||||
defer.resolve();
|
||||
})
|
||||
.fail(function(response) {
|
||||
app.notify({
|
||||
title : "Unable to Share with Facebook",
|
||||
text : "Error: " + response,
|
||||
"icon_url": "/assets/content/icon_alert_big.png"
|
||||
});
|
||||
defer.reject();
|
||||
})
|
||||
}
|
||||
else {
|
||||
// user doesn't want to auth; this is a form of success
|
||||
defer.resolve();
|
||||
}
|
||||
})
|
||||
})
|
||||
.fail(function(jqXHR) {
|
||||
app.notifyServerError(jqXHR, "Unable to Populate Share Data");
|
||||
defer.reject();
|
||||
})
|
||||
|
||||
return defer;
|
||||
|
||||
}
|
||||
|
||||
function handleSessionShareWithGoogle(message) {
|
||||
var defer = $.Deferred();
|
||||
|
||||
defer.resolve(); // remove when implemented
|
||||
|
||||
return defer;
|
||||
}
|
||||
|
||||
// 116 characters
|
||||
// abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdef
|
||||
function handleSessionShareWithTwitter(message) {
|
||||
var defer = $.Deferred();
|
||||
|
||||
rest.tweet({message: message + ' ' + entity.share_url})
|
||||
.done(function() {
|
||||
defer.resolve();
|
||||
})
|
||||
.fail(function(jqXHR) {
|
||||
if(jqXHR.status == 422) {
|
||||
// implies twitter token error.
|
||||
app.notify({
|
||||
title : "Failed to Tweet",
|
||||
text : "You need to re-authorize JamKazam to access your Twitter account. Click (sign in) in the Share Dialog.",
|
||||
"icon_url": "/assets/content/icon_alert_big.png"
|
||||
});
|
||||
disableTwitter();
|
||||
}
|
||||
else {
|
||||
app.notifyServerError(jqXHR, "Unable to Share with Twitter");
|
||||
}
|
||||
defer.reject();
|
||||
})
|
||||
|
||||
|
||||
return defer;
|
||||
}
|
||||
|
||||
function handleSessionShareWithFacebook(message) {
|
||||
var defer = $.Deferred();
|
||||
|
||||
rest.getShareSession({ provider:'facebook', music_session: entityId})
|
||||
.done(function(data) {
|
||||
facebookHelper.promptLogin()
|
||||
.done(function(response) {
|
||||
if(response.status == "connected") {
|
||||
facebookRest.post({
|
||||
access_token: response.authResponse.accessToken,
|
||||
message: message,
|
||||
description: data.description,
|
||||
caption: data.caption,
|
||||
name: data.title,
|
||||
picture: data.photo_url
|
||||
})
|
||||
.done(function(response) {
|
||||
defer.resolve();
|
||||
})
|
||||
.fail(function(response) {
|
||||
app.notify({
|
||||
title : "Unable to Share with Facebook",
|
||||
text : "Error: " + response,
|
||||
"icon_url": "/assets/content/icon_alert_big.png"
|
||||
});
|
||||
defer.reject();
|
||||
})
|
||||
}
|
||||
else {
|
||||
// user doesn't want to auth; this is a form of success
|
||||
defer.resolve();
|
||||
}
|
||||
})
|
||||
})
|
||||
.fail(function(jqXHR) {
|
||||
app.notifyServerError(jqXHR, "Unable to Populate Share Data");
|
||||
defer.reject();
|
||||
})
|
||||
|
||||
return defer;
|
||||
}
|
||||
|
||||
function messageTooLongForTwitter(message) {
|
||||
return message && message.length > remainingCap;
|
||||
}
|
||||
|
||||
function socialShare() {
|
||||
var facebookCheckbox = $(dialogId + ' .share-with-facebook input');
|
||||
var shareWithFacebook = facebookCheckbox.is(':checked') && !facebookCheckbox.is(':disabled');
|
||||
|
||||
var googleCheckbox = $(dialogId + ' .share-with-google input');
|
||||
var shareWithGoogle = googleCheckbox.is(':checked') && !googleCheckbox.is(':disabled');
|
||||
|
||||
var twitterCheckbox = $(dialogId + ' .share-with-twitter input');
|
||||
var shareWithTwitter = twitterCheckbox.is(':checked') && !twitterCheckbox.is(':disabled');
|
||||
|
||||
if(!shareWithFacebook && !shareWithGoogle && !shareWithTwitter) {
|
||||
$(dialogId + ' .share-options').addClass('error')
|
||||
return;
|
||||
}
|
||||
else {
|
||||
$(dialogId + ' .share-options').removeClass('error')
|
||||
}
|
||||
|
||||
|
||||
var message = $(dialogId + ' .share-message').val();
|
||||
if(!message) { message = undefined; }
|
||||
|
||||
|
||||
|
||||
if(shareWithTwitter && !message) {
|
||||
$(dialogId + ' .share-message-holder').addClass('error')
|
||||
$(dialogId + ' .share-message-holder .error-msg').text("You must specify a message for Twitter.");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
$(dialogId + ' .share-message-holder').removeClass('error')
|
||||
$(dialogId + ' .share-message-holder .error-msg').text('');
|
||||
}
|
||||
|
||||
// validate twitter message length
|
||||
if(shareWithTwitter && messageTooLongForTwitter(message)) {
|
||||
$(dialogId + ' .share-message-holder').addClass('error')
|
||||
$(dialogId + ' .share-message-holder .error-msg').text("Your message must be less than " + (remainingCap + 1) + " characters in length for Twitter (currently " + message.length + ").");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
$(dialogId + ' .share-message-holder').removeClass('error')
|
||||
$(dialogId + ' .share-message-holder .error-msg').text('');
|
||||
}
|
||||
|
||||
showSpinner();
|
||||
|
||||
var chain = [];
|
||||
|
||||
if(entityType == 'session') {
|
||||
if(shareWithFacebook) {
|
||||
chain.push(handleSessionShareWithFacebook(message))
|
||||
}
|
||||
if(shareWithTwitter) {
|
||||
chain.push(handleSessionShareWithTwitter(message))
|
||||
}
|
||||
if(shareWithGoogle) {
|
||||
chain.push(handleSessionShareWithGoogle(message))
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(shareWithFacebook) {
|
||||
chain.push(handleRecordingShareWithFacebook(message))
|
||||
}
|
||||
if(shareWithTwitter) {
|
||||
chain.push(handleRecordingShareWithTwitter(message))
|
||||
}
|
||||
if(shareWithGoogle) {
|
||||
chain.push(handleRecordingShareWithGoogle(message))
|
||||
}
|
||||
}
|
||||
|
||||
$.when.apply($, chain)
|
||||
.done(function() {
|
||||
app.layout.closeDialog('share-dialog');
|
||||
})
|
||||
.fail(function() {
|
||||
logger.error("share failed")
|
||||
})
|
||||
.always(function() {
|
||||
hideSpinner();
|
||||
});
|
||||
}
|
||||
|
||||
function enableFacebook() {
|
||||
$(dialogId + ' .share-with-facebook input').removeAttr('disabled')
|
||||
$(dialogId + ' .share-with-facebook a').css('visibility', 'hidden');
|
||||
}
|
||||
|
||||
function disableFacebook() {
|
||||
$(dialogId + ' .share-with-facebook input').attr('disabled', 'disabled')
|
||||
$(dialogId + ' .share-with-facebook a').css('visibility', 'visible');
|
||||
}
|
||||
|
||||
function enableTwitter() {
|
||||
$(dialogId + ' .share-with-twitter input').removeAttr('disabled')
|
||||
$(dialogId + ' .share-with-twitter a').css('visibility', 'hidden');
|
||||
}
|
||||
|
||||
function disableTwitter() {
|
||||
$(dialogId + ' .share-with-twitter input').attr('disabled', 'disabled')
|
||||
$(dialogId + ' .share-with-twitter a').css('visibility', 'visible');
|
||||
}
|
||||
|
||||
function handleFbStateChange(response) {
|
||||
|
||||
if (response && response.status == "connected") {
|
||||
enableFacebook();
|
||||
}
|
||||
else{
|
||||
disableFacebook();
|
||||
}
|
||||
}
|
||||
function registerEvents(onOff) {
|
||||
$(dialogId + ' .dialog-share-button').unbind('click').click(function(e){
|
||||
socialShare();
|
||||
return false;
|
||||
});
|
||||
|
||||
$(dialogId + ' .share-with-facebook a').unbind('click').click(function(e) {
|
||||
facebookHelper.promptLogin();
|
||||
return false;
|
||||
});
|
||||
|
||||
$(dialogId + ' .share-with-twitter a').unbind('click').click(function(e) {
|
||||
app.layout.queueDialog('share-dialog')
|
||||
window.location = '/auth/twitter';
|
||||
return false;
|
||||
|
||||
})
|
||||
/*
|
||||
$("#btn-share-copy").zclip({
|
||||
path: 'zeroclipboard.swf',
|
||||
copy: function() {
|
||||
// console.log("copied " + $(".link-contents").text());
|
||||
return "TEXT";
|
||||
}
|
||||
});*/
|
||||
}
|
||||
|
||||
function showDialog() {
|
||||
app.layout.showDialog('share-dialog');
|
||||
}
|
||||
|
||||
/*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 initDialog() {
|
||||
var sessionText = textMap.SESSION;
|
||||
var liveSessionText = textMap.LIVE_SESSION;
|
||||
|
||||
function showGoogleDialog() {
|
||||
$('#invitation-dialog').show();
|
||||
$('#invitation-textarea-container').hide();
|
||||
$('#invitation-checkbox-container').show();
|
||||
$('#btn-send-invitation').hide();
|
||||
$('#btn-next-invitation').show();
|
||||
clearTextFields();
|
||||
var fill = entityType === sessionText.toLowerCase() ? "teal-fill" : "orange-fill";
|
||||
|
||||
app.layout.showDialog('inviteUsers')
|
||||
$("#shareType").text(entityType);
|
||||
|
||||
$('#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>");
|
||||
$("#divWidgetCodeHeader").addClass(fill);
|
||||
$("#divWidgetPreviewHeader").addClass(fill);
|
||||
$("#divWidgetPreview").addClass(entityType);
|
||||
|
||||
// SESSION
|
||||
if (entityType === sessionText.toLowerCase()) {
|
||||
$("#lblWidgetCodeType").html(sessionText.toLowerCase());
|
||||
$("#lblWidgetPreviewType").html(sessionText.toLowerCase());
|
||||
$("#spnWidgetCodeBranding").text(liveSessionText.toLowerCase());
|
||||
$("#spnWidgetPreviewBranding").text(liveSessionText.toLowerCase());
|
||||
|
||||
rest.getSessionHistory(entityId)
|
||||
.done(function(response) {
|
||||
// var name, photoUrl;
|
||||
$(".link-contents").html(response.share_url);
|
||||
});
|
||||
}
|
||||
|
||||
// RECORDING
|
||||
else if (entityType === "recording") {
|
||||
var recordedText = textMap.RECORDED.toLowerCase();
|
||||
$("#lblWidgetCodeType").text(textMap.RECORDING);
|
||||
$("#lblWidgetPreviewType").text(textMap.RECORDING);
|
||||
$("#spnWidgetCodeBranding").text(recordedText);
|
||||
$("#spnWidgetPreviewBranding").text(recordedText);
|
||||
|
||||
rest.getClaimedRecording(entityId)
|
||||
.done(function(response) {
|
||||
var name, photoUrl;
|
||||
|
||||
if (response.recording.band) {
|
||||
name = response.recording.band.name;
|
||||
photoUrl = context.JK.resolveBandAvatarUrl(response.recording.band.photo_url);
|
||||
}
|
||||
else {
|
||||
name = response.recording.owner.name;
|
||||
photoUrl = context.JK.resolveAvatarUrl(response.recording.owner.photo_url);
|
||||
}
|
||||
|
||||
$('.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);
|
||||
$(".link-contents").html(response.share_url);
|
||||
|
||||
$("#imgWidgetCodeAvatar").attr('src', photoUrl);
|
||||
$("#imgWidgetPreviewAvatar").attr('src', photoUrl);
|
||||
|
||||
$("#divWidgetPreviewTitle").html(response.recording.name);
|
||||
|
||||
$("#spnWidgetCodeArtistName").html(name);
|
||||
$("#spnWidgetPreviewArtistName").html(name);
|
||||
|
||||
$.each(response.recording.recorded_tracks, function(index, val) {
|
||||
$(".widget-members").append('<div class="widget-avatar-small">' + '<img src="' + context.JK.resolveAvatarUrl(val.user.photo_url) + '" alt="" />' + '</div>');
|
||||
});
|
||||
},
|
||||
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() {
|
||||
disableTwitter();
|
||||
// no disableFacebook on purpose
|
||||
|
||||
if(entityType == 'recording') {
|
||||
rest.getClaimedRecording(entityId)
|
||||
.done(function(data) {
|
||||
entity = data;
|
||||
$(dialogId + ' .link-contents').text(entity.share_url)
|
||||
})
|
||||
.fail(function(jqXHR) {
|
||||
app.notifyServerError(jqXHR, "Unable to Fetch Session Data");
|
||||
})
|
||||
}
|
||||
else {
|
||||
rest.getSession(entityId)
|
||||
.done(function(data) {
|
||||
entity = data;
|
||||
$(dialogId + ' .link-contents').text(entity.share_url)
|
||||
})
|
||||
.fail(function(jqXHR) {
|
||||
app.notifyServerError(jqXHR, "Unable to Fetch Session Data");
|
||||
});
|
||||
}
|
||||
rest.getUserDetail()
|
||||
.done(function(data) {
|
||||
userDetail = data;
|
||||
if(data.auth_twitter) {
|
||||
enableTwitter();
|
||||
}
|
||||
else {
|
||||
disableTwitter();
|
||||
}
|
||||
});
|
||||
|
||||
$(dialogId + ' .share-message-holder').removeClass('error')
|
||||
$(dialogId + ' .share-message-holder .error-msg').text('');
|
||||
|
||||
$(dialogId + ' .share-options').removeClass('error');
|
||||
registerEvents(true);
|
||||
}
|
||||
|
||||
function afterShow() {
|
||||
$("#btn-share-copy").clipboard({
|
||||
path: '/assets/jquery.clipboard.swf',
|
||||
copy: function() {
|
||||
// Return text in closest element (useful when you have multiple boxes that can be copied)
|
||||
return $(".link-contents").text();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function afterHide() {
|
||||
hideSpinner();
|
||||
registerEvents(false);
|
||||
}
|
||||
|
||||
function initialize(){
|
||||
function initialize(_facebookHelper){
|
||||
facebookHelper = _facebookHelper;
|
||||
|
||||
var dialogBindings = {
|
||||
'beforeShow' : beforeShow,
|
||||
'afterShow' : afterShow,
|
||||
'afterHide': afterHide
|
||||
};
|
||||
|
||||
app.bindDialog('shareRecording', dialogBindings);
|
||||
app.bindDialog('share-dialog', dialogBindings);
|
||||
|
||||
// callFB(fbAppID);
|
||||
initDialog();
|
||||
|
||||
$(facebookHelper).on('fb.login_response', function(e, data) {
|
||||
handleFbStateChange(data.response);
|
||||
})
|
||||
};
|
||||
|
||||
this.initialize = initialize;
|
||||
|
|
@ -117,4 +486,4 @@
|
|||
}
|
||||
|
||||
return this;
|
||||
})(window,jQuery);
|
||||
})(window,jQuery)
|
||||
|
|
@ -585,7 +585,7 @@
|
|||
|
||||
function onTermsAccepted(args) {
|
||||
deleteNotification(args.notification_id);
|
||||
context.location = '#/session/' + args.session_id;
|
||||
context.location = '/client#/session/' + args.session_id;
|
||||
}
|
||||
|
||||
function registerSessionEnded() {
|
||||
|
|
|
|||
|
|
@ -79,7 +79,6 @@
|
|||
// initially show avatar
|
||||
function showAvatar() {
|
||||
var photoUrl = context.JK.resolveAvatarUrl(userMe.photo_url);
|
||||
logger.debug("photoUrl=" + photoUrl);
|
||||
$('#header-avatar').attr('src', photoUrl);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,75 @@
|
|||
$(function() {
|
||||
(function(context, $) {
|
||||
|
||||
function like() {
|
||||
context.JK.ShowRecording = function(app) {
|
||||
var logger = context.JK.logger;
|
||||
var rest = new JK.Rest();
|
||||
var recordingId = null;
|
||||
var claimedRecordingId = null;
|
||||
|
||||
}
|
||||
function like() {
|
||||
rest.addRecordingLike(recordingId, JK.currentUserId)
|
||||
.done(function(response) {
|
||||
$("#spnLikeCount").html(parseInt($("#spnLikeCount").text()) + 1);
|
||||
$("#btnLike").unbind("click");
|
||||
});
|
||||
}
|
||||
|
||||
// search click handler
|
||||
$('#btnlike').click(like);
|
||||
function play() {
|
||||
rest.addRecordingPlay(recordingId, JK.currentUserId)
|
||||
.done(function(response) {
|
||||
$("#spnPlayCount").html(parseInt($("#spnPlayCount").text()) + 1);
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
function addComment() {
|
||||
var comment = $("#txtRecordingComment").val();
|
||||
if ($.trim(comment).length > 0) {
|
||||
rest.addRecordingComment(recordingId, JK.currentUserId, comment)
|
||||
.done(function(response) {
|
||||
$("#spnCommentCount").html(parseInt($("#spnCommentCount").text()) + 1);
|
||||
|
||||
var template = $('#template-landing-comment').html();
|
||||
var commentHtml = context.JK.fillTemplate(template, {
|
||||
avatar_url: context.JK.currentUserAvatarUrl,
|
||||
name: context.JK.currentUserName,
|
||||
comment: comment
|
||||
});
|
||||
|
||||
$(".landing-comment-scroller").prepend(commentHtml);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function initialize(_claimedRecordingId, _recordingId) {
|
||||
recordingId = _recordingId;
|
||||
claimedRecordingId = _claimedRecordingId;
|
||||
|
||||
if (JK.currentUserId) {
|
||||
var shareDialog = new JK.ShareDialog(JK.app, claimedRecordingId, "recording");
|
||||
shareDialog.initialize(context.JK.FacebookHelperInstance);
|
||||
|
||||
$("#btnShare").click(function(e) {
|
||||
shareDialog.showDialog();
|
||||
});
|
||||
|
||||
$("#txtRecordingComment").keypress(function(e) {
|
||||
if (e.which === 13) {
|
||||
addComment();
|
||||
$(this).val('');
|
||||
$(this).blur();
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
$("#txtRecordingComment").attr("disabled", "disabled");
|
||||
$("#txtRecordingComment").val("You must be logged in to add a comment.");
|
||||
}
|
||||
|
||||
$("#btnLike").click(like);
|
||||
$("#btnPlay").click(play);
|
||||
}
|
||||
|
||||
this.initialize = initialize;
|
||||
}
|
||||
|
||||
})(window, jQuery);
|
||||
|
|
@ -1,10 +1,69 @@
|
|||
$(function() {
|
||||
(function(context, $) {
|
||||
|
||||
function like() {
|
||||
context.JK.ShowMusicSession = function(app) {
|
||||
var logger = context.JK.logger;
|
||||
var rest = new JK.Rest();
|
||||
var sessionId = null;
|
||||
|
||||
}
|
||||
function like() {
|
||||
rest.addSessionLike(sessionId, JK.currentUserId)
|
||||
.done(function(response) {
|
||||
$("#spnLikeCount").html(parseInt($("#spnLikeCount").text()) + 1);
|
||||
$("#btnLike").unbind("click");
|
||||
});
|
||||
}
|
||||
|
||||
// search click handler
|
||||
$('#btnlike').click(like);
|
||||
function addComment() {
|
||||
var comment = $("#txtSessionComment").val();
|
||||
if ($.trim(comment).length > 0) {
|
||||
rest.addSessionComment(sessionId, JK.currentUserId, comment)
|
||||
.done(function(response) {
|
||||
$("#spnCommentCount").html(parseInt($("#spnCommentCount").text()) + 1);
|
||||
|
||||
var template = $('#template-landing-comment').html();
|
||||
var commentHtml = context.JK.fillTemplate(template, {
|
||||
avatar_url: context.JK.currentUserAvatarUrl,
|
||||
name: context.JK.currentUserName,
|
||||
comment: comment
|
||||
});
|
||||
|
||||
});
|
||||
$(".landing-comment-scroller").prepend(commentHtml);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function initialize(musicSessionId) {
|
||||
|
||||
sessionId = musicSessionId;
|
||||
|
||||
if (context.JK.currentUserId) {
|
||||
|
||||
var shareDialog = new JK.ShareDialog(context.JK.app, sessionId, "session");
|
||||
shareDialog.initialize(context.JK.FacebookHelperInstance);
|
||||
|
||||
// shareDialog.showDialog();
|
||||
|
||||
$("#btnShare").click(function(e) {
|
||||
shareDialog.showDialog();
|
||||
});
|
||||
|
||||
$("#txtSessionComment").keypress(function(e) {
|
||||
if (e.which === 13) {
|
||||
addComment();
|
||||
$(this).val('');
|
||||
$(this).blur();
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
$("#txtSessionComment").attr("disabled", "disabled");
|
||||
$("#txtSessionComment").val("You must be logged in to add a comment.");
|
||||
}
|
||||
|
||||
$("#btnLike").click(like);
|
||||
}
|
||||
|
||||
this.initialize = initialize;
|
||||
}
|
||||
|
||||
})(window, jQuery);
|
||||
|
|
@ -2,9 +2,12 @@
|
|||
//= require jquery_ujs
|
||||
//= require jquery.queryparams
|
||||
//= require jquery.hoverIntent
|
||||
//= require jquery.cookie
|
||||
//= require jquery.clipboard
|
||||
//= require AAA_Log
|
||||
//= require AAC_underscore
|
||||
//= require globals
|
||||
//= require facebook_helper
|
||||
//= require web/signupDialog
|
||||
//= require web/signinDialog
|
||||
//= require invitationDialog
|
||||
|
|
@ -15,6 +18,7 @@
|
|||
//= require utils
|
||||
//= require ga
|
||||
//= require jam_rest
|
||||
//= require facebook_rest
|
||||
//= require landing/init
|
||||
//= require landing/signup
|
||||
//= require web/downloads
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
*= require ./ftue
|
||||
*= require ./invitationDialog
|
||||
*= require ./shareDialog
|
||||
*= require ./hoverBubble
|
||||
*= require ./recordingFinishedDialog
|
||||
*= require ./localRecordingsDialog
|
||||
*= require ./createSession
|
||||
|
|
|
|||
|
|
@ -1,194 +1,283 @@
|
|||
body.widgets {
|
||||
background:#fff;
|
||||
padding:20px;
|
||||
}
|
||||
#share-dialog {
|
||||
|
||||
h3 {
|
||||
font-size:20px;
|
||||
font-weight:normal;
|
||||
}
|
||||
width:500px;
|
||||
|
||||
.share-overlay {
|
||||
.button-orange {
|
||||
margin:0 2px 0 0;
|
||||
}
|
||||
|
||||
}
|
||||
body.widgets {
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.widget {
|
||||
width:430px;
|
||||
height:180px;
|
||||
background:#353535;
|
||||
border:solid 1px;
|
||||
text-align:left;
|
||||
}
|
||||
h3 {
|
||||
font-size: 20px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.widget.session {
|
||||
border-color:#0b6672;
|
||||
}
|
||||
.share-overlay {
|
||||
|
||||
.widget.recording {
|
||||
border-color:#ed3618;
|
||||
}
|
||||
}
|
||||
|
||||
.widget-header {
|
||||
color:#fff;
|
||||
font-size:17px;
|
||||
padding:8px;
|
||||
}
|
||||
.share-to-social-media {
|
||||
margin-bottom: 20px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.widget-content {
|
||||
width:100%;
|
||||
color:#ccc;
|
||||
position:relative;
|
||||
}
|
||||
.widget {
|
||||
width: 430px;
|
||||
height: 180px;
|
||||
background: #353535;
|
||||
border: solid 1px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.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.session {
|
||||
border-color: #0b6672;
|
||||
}
|
||||
|
||||
.widget-avatar img {
|
||||
width:110px;
|
||||
height:110px;
|
||||
-webkit-border-radius:55px;
|
||||
-moz-border-radius:55px;
|
||||
border-radius:55px;
|
||||
}
|
||||
.widget.recording {
|
||||
border-color: #ed3618;
|
||||
}
|
||||
|
||||
.widget-playbutton {
|
||||
position:absolute;
|
||||
top:55px;
|
||||
left:55px;
|
||||
width:35px;
|
||||
height:31px;
|
||||
background-image:url(../shared/play_button.png);
|
||||
background-repeat:no-repeat;
|
||||
}
|
||||
.widget-header {
|
||||
color: #fff;
|
||||
font-size: 17px;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.widget-pausebutton {
|
||||
position:absolute;
|
||||
top:55px;
|
||||
left:55px;
|
||||
width:35px;
|
||||
height:31px;
|
||||
background-image:url(../shared/pause_button.png);
|
||||
background-repeat:no-repeat;
|
||||
}
|
||||
.widget-content {
|
||||
width: 100%;
|
||||
color: #ccc;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.widget-title {
|
||||
font-size:18px;
|
||||
position:absolute;
|
||||
top:20px;
|
||||
left:153px;
|
||||
width:260px;
|
||||
height:22px;
|
||||
overflow:hidden;
|
||||
white-space:nowrap;
|
||||
text-overflow:ellipsis;
|
||||
}
|
||||
.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-description {
|
||||
font-size:13px;
|
||||
position:absolute;
|
||||
top:15px;
|
||||
left:153px;
|
||||
width:260px;
|
||||
height:32px;
|
||||
overflow:hidden;
|
||||
text-overflow:ellipsis;
|
||||
}
|
||||
.widget-avatar img {
|
||||
width: 110px;
|
||||
height: 110px;
|
||||
-webkit-border-radius: 55px;
|
||||
-moz-border-radius: 55px;
|
||||
border-radius: 55px;
|
||||
}
|
||||
|
||||
.widget-controls {
|
||||
position:absolute;
|
||||
top:25px;
|
||||
left:153px;
|
||||
width:270px;
|
||||
height:32px;
|
||||
}
|
||||
.widget-playbutton {
|
||||
position: absolute;
|
||||
top: 55px;
|
||||
left: 55px;
|
||||
width: 35px;
|
||||
height: 31px;
|
||||
background-image: url(../shared/play_button.png);
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.widget-members {
|
||||
position:absolute;
|
||||
left:153px;
|
||||
top:60px;
|
||||
width:280px;
|
||||
height:38px;
|
||||
overflow:hidden;
|
||||
}
|
||||
.widget-pausebutton {
|
||||
position: absolute;
|
||||
top: 55px;
|
||||
left: 55px;
|
||||
width: 35px;
|
||||
height: 31px;
|
||||
background-image: url(../shared/pause_button.png);
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.widget-social {
|
||||
position:absolute;
|
||||
top:75px;
|
||||
left:153px;
|
||||
width:270px;
|
||||
height:20px;
|
||||
font-size:13px;
|
||||
}
|
||||
.widget-title {
|
||||
font-size: 18px;
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 153px;
|
||||
width: 260px;
|
||||
height: 22px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.widget-branding {
|
||||
.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;
|
||||
}
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.widget .recording-controls {
|
||||
margin-top:0px;
|
||||
height:22px;
|
||||
padding:8px 5px;
|
||||
}
|
||||
.widget .recording-controls {
|
||||
margin-top: 0px;
|
||||
height: 22px;
|
||||
padding: 8px 5px;
|
||||
}
|
||||
|
||||
.widget .recording-playback {
|
||||
width:65%;
|
||||
}
|
||||
.widget .recording-playback {
|
||||
width: 65%;
|
||||
}
|
||||
|
||||
.widget .recording-position {
|
||||
margin-left:-30px;
|
||||
width:95%;
|
||||
}
|
||||
.widget .recording-position {
|
||||
margin-left: -30px;
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
.widget .recording-current {
|
||||
top:8px;
|
||||
}
|
||||
.widget .recording-current {
|
||||
top: 8px;
|
||||
}
|
||||
|
||||
.widget a {
|
||||
color:#ccc;
|
||||
text-decoration:none;
|
||||
}
|
||||
.widget a {
|
||||
color: #ccc;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
img.space {
|
||||
margin-left:28px;
|
||||
}
|
||||
img.space {
|
||||
margin-left: 28px;
|
||||
}
|
||||
|
||||
.widget a:hover {
|
||||
color:#fff;
|
||||
}
|
||||
.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 {
|
||||
.widget-avatar-small {
|
||||
float: left;
|
||||
padding: 1px;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
-webkit-border-radius:18px;
|
||||
-moz-border-radius:18px;
|
||||
border-radius:18px;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
.share-button-holder {
|
||||
float: right;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
|
||||
.share-message-holder {
|
||||
|
||||
margin:0 0 10px 0;
|
||||
|
||||
.share-message {
|
||||
width: 100%;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
.error-msg {
|
||||
display:none;
|
||||
margin-top: 10px;
|
||||
text-align: center;
|
||||
color: #F00;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
&.error {
|
||||
background-color: #330000;
|
||||
border: 1px solid #990000;
|
||||
padding: 4px;
|
||||
|
||||
.error-msg {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.share-options {
|
||||
.error-msg {
|
||||
display: none;
|
||||
margin-top: 10px;
|
||||
text-align: center;
|
||||
color: #F00;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
img {
|
||||
margin-right:1px;
|
||||
}
|
||||
|
||||
a {
|
||||
font-size:12px;
|
||||
margin-right:15px;
|
||||
}
|
||||
}
|
||||
|
||||
.share-options.error {
|
||||
|
||||
background-color: #330000;
|
||||
border: 1px solid #990000;
|
||||
padding: 4px;
|
||||
|
||||
.error-msg {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.share-link {
|
||||
h3 {
|
||||
margin-bottom:20px;
|
||||
}
|
||||
|
||||
.link-contents {
|
||||
margin-bottom:20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +1,20 @@
|
|||
html {
|
||||
height:100%;
|
||||
min-height:100%;
|
||||
}
|
||||
|
||||
p, div {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
|
||||
body.web {
|
||||
background-repeat: repeat-x;
|
||||
margin:0 !important;
|
||||
padding:0 !important;
|
||||
position:relative !important;
|
||||
overflow: visible !important;
|
||||
overflow: auto !important;
|
||||
width:auto !important;
|
||||
min-height:100%;
|
||||
|
||||
div.wrapper {
|
||||
width:1100px;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
*= require client/dialog
|
||||
*= require client/invitationDialog
|
||||
*= require client/shareDialog
|
||||
*= require client/hoverBubble
|
||||
*= require web/main
|
||||
*= require web/footer
|
||||
*= require web/recordings
|
||||
|
|
|
|||
|
|
@ -191,10 +191,11 @@ class ApiBandsController < ApiController
|
|||
def update_photo
|
||||
original_fpfile = params[:original_fpfile]
|
||||
cropped_fpfile = params[:cropped_fpfile]
|
||||
cropped_large_fpfile = params[:cropped_large_fpfile]
|
||||
crop_selection = params[:crop_selection]
|
||||
|
||||
# public bucket to allow images to be available to public
|
||||
@band.update_photo(original_fpfile, cropped_fpfile, crop_selection, Rails.application.config.aws_bucket_public)
|
||||
@band.update_photo(original_fpfile, cropped_fpfile, cropped_large_fpfile, crop_selection, Rails.application.config.aws_bucket_public)
|
||||
|
||||
if @band.errors.any?
|
||||
render :json => { :message => "Unexpected error updating photo."}, :status => :unprocessable_entity
|
||||
|
|
|
|||
|
|
@ -11,10 +11,19 @@ class ApiClaimedRecordingsController < ApiController
|
|||
end
|
||||
|
||||
def show
|
||||
if !@claimed_recording.is_public && @claimed_recording.user_id != current_user.id
|
||||
raise PermissionError, 'this claimed recording is not public'
|
||||
end
|
||||
|
||||
@claimed_recording
|
||||
end
|
||||
|
||||
def update
|
||||
|
||||
if @claimed_recording.user_id != current_user.id
|
||||
raise PermissionError, 'only owner of claimed_recording can update it'
|
||||
end
|
||||
|
||||
begin
|
||||
@claimed_recording.update_fields(current_user, params)
|
||||
respond_with responder: ApiResponder, :status => 204
|
||||
|
|
@ -24,6 +33,9 @@ class ApiClaimedRecordingsController < ApiController
|
|||
end
|
||||
|
||||
def delete
|
||||
if @claimed_recording.user_id != current_user.id
|
||||
raise PermissionError, 'only owner of claimed_recording can update it'
|
||||
end
|
||||
#begin
|
||||
#@claimed_recording.discard(current_user)
|
||||
#render :json => {}, :status => 204
|
||||
|
|
@ -37,7 +49,7 @@ class ApiClaimedRecordingsController < ApiController
|
|||
|
||||
def look_up_claimed_recording
|
||||
@claimed_recording = ClaimedRecording.find(params[:id])
|
||||
if @claimed_recording.nil? || @claimed_recording.user_id != current_user.id
|
||||
if @claimed_recording.nil?
|
||||
render :json => { :message => "claimed_recording not found" }, :status => 404
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
class ApiSearchController < ApiController
|
||||
class ApiSessionsController < ApiController
|
||||
|
||||
def login
|
||||
user = User.authenticate(params[:email], params[:password])
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
class ApiTwittersController < ApiController
|
||||
|
||||
before_filter :api_signed_in_user
|
||||
|
||||
respond_to :json
|
||||
|
||||
rescue_from 'Twitter::Error::Unauthorized' do |exception|
|
||||
# invalidate current tokens
|
||||
current_user.invalidate_user_authorization('twitter')
|
||||
|
||||
render :json => { :errors => { :token => ["is invalid"] } }, :status => 422
|
||||
end
|
||||
|
||||
|
||||
def tweet
|
||||
|
||||
twitter_auth = current_user.user_authorization('twitter')
|
||||
|
||||
raise JamRuby::PermissionError unless twitter_auth
|
||||
|
||||
client = Twitter::REST::Client.new do |config|
|
||||
config.consumer_key = Rails.application.config.twitter_app_id
|
||||
config.consumer_secret = Rails.application.config.twitter_app_secret
|
||||
config.access_token = twitter_auth.token
|
||||
config.access_token_secret = twitter_auth.secret
|
||||
end
|
||||
|
||||
text = params[:message]
|
||||
|
||||
client.update(text)
|
||||
|
||||
render json: {}, status: :ok
|
||||
end
|
||||
end
|
||||
|
|
@ -10,7 +10,9 @@ class ApiUsersController < ApiController
|
|||
:friend_show, :friend_destroy, # friends
|
||||
:notification_index, :notification_destroy, # notifications
|
||||
:band_invitation_index, :band_invitation_show, :band_invitation_update, # band invitations
|
||||
:set_password, :begin_update_email, :update_avatar, :delete_avatar, :generate_filepicker_policy]
|
||||
:set_password, :begin_update_email, :update_avatar, :delete_avatar, :generate_filepicker_policy,
|
||||
:share_session, :share_recording]
|
||||
|
||||
respond_to :json
|
||||
|
||||
def index
|
||||
|
|
@ -411,10 +413,11 @@ class ApiUsersController < ApiController
|
|||
def update_avatar
|
||||
original_fpfile = params[:original_fpfile]
|
||||
cropped_fpfile = params[:cropped_fpfile]
|
||||
cropped_large_fpfile = params[:cropped_large_fpfile]
|
||||
crop_selection = params[:crop_selection]
|
||||
|
||||
# public bucket to allow images to be available to public
|
||||
@user.update_avatar(original_fpfile, cropped_fpfile, crop_selection, Rails.application.config.aws_bucket_public)
|
||||
@user.update_avatar(original_fpfile, cropped_fpfile, cropped_large_fpfile, crop_selection, Rails.application.config.aws_bucket_public)
|
||||
|
||||
if @user.errors.any?
|
||||
respond_with @user, status: :unprocessable_entity
|
||||
|
|
@ -547,6 +550,59 @@ class ApiUsersController < ApiController
|
|||
render :json => {}, :status => 200
|
||||
end
|
||||
|
||||
# creates display-ready session data for sharing
|
||||
def share_session
|
||||
provider = params[:provider]
|
||||
music_session_id = params[:music_session]
|
||||
history = MusicSessionHistory.find_by_music_session_id!(music_session_id)
|
||||
|
||||
if provider == 'facebook'
|
||||
|
||||
render json: {
|
||||
description: view_context.description_for_music_session_history(history),
|
||||
title: view_context.title_for_music_session_history(history, current_user),
|
||||
photo_url: view_context.facebook_image_for_music_session_history(history),
|
||||
caption: 'www.jamkazam.com'
|
||||
}, status: 200
|
||||
|
||||
elsif provider == 'twitter'
|
||||
|
||||
render json: {
|
||||
message: view_context.title_for_music_session_history(history, current_user)
|
||||
}, status: 200
|
||||
|
||||
else
|
||||
render :json => { :errors => {:provider => ['not valid']} }, :status => 422
|
||||
end
|
||||
end
|
||||
|
||||
# creates display-ready recording data for sharing
|
||||
def share_recording
|
||||
provider = params[:provider]
|
||||
claimed_recording_id = params[:claimed_recording]
|
||||
claimed_recording = ClaimedRecording.find(claimed_recording_id)
|
||||
|
||||
if provider == 'facebook'
|
||||
|
||||
render json: {
|
||||
description: view_context.description_for_claimed_recording(claimed_recording),
|
||||
title: view_context.title_for_claimed_recording(claimed_recording, current_user),
|
||||
photo_url: view_context.facebook_image_for_claimed_recording(claimed_recording),
|
||||
caption: 'www.jamkazam.com'
|
||||
}, status: 200
|
||||
|
||||
elsif provider == 'twitter'
|
||||
|
||||
render json: {
|
||||
message: view_context.title_for_claimed_recording(history, current_user) + " at " + request.host_with_port
|
||||
}, status: 200
|
||||
|
||||
|
||||
else
|
||||
render :json => { :errors => {:provider => ['not valid']} }, :status => 422
|
||||
end
|
||||
end
|
||||
|
||||
###################### RECORDINGS #######################
|
||||
# def recording_index
|
||||
# @recordings = User.recording_index(current_user, params[:id])
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
# this is not a jam session - this is an 'auth session'
|
||||
class SessionsController < ApplicationController
|
||||
|
||||
layout "web"
|
||||
|
||||
def new
|
||||
@login_error = false
|
||||
render :layout => "landing"
|
||||
|
|
@ -23,6 +25,7 @@ class SessionsController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
# OAuth docs
|
||||
# http://net.tutsplus.com/tutorials/ruby/how-to-use-omniauth-to-authenticate-your-users/
|
||||
def create_oauth
|
||||
|
|
@ -39,7 +42,6 @@ class SessionsController < ApplicationController
|
|||
# For debugging - to see what all is there:
|
||||
# render :text => auth_hash.to_yaml
|
||||
#FbGraph.debug!
|
||||
#app = FbGraph::Application.new '468555793186398', :secret => '546a5b253972f3e2e8b36d9a3dd5a06e'
|
||||
token = auth_hash[:credentials][:token]
|
||||
|
||||
# FIXME:
|
||||
|
|
@ -65,14 +67,26 @@ class SessionsController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
# https://github.com/intridea/omniauth/wiki/Saving-User-Location
|
||||
def oauth_callback
|
||||
|
||||
auth_hash = request.env['omniauth.auth']
|
||||
|
||||
provider = auth_hash[:provider]
|
||||
|
||||
if provider == 'facebook'
|
||||
if provider == 'twitter'
|
||||
@user_authorization = current_user.build_twitter_authorization(auth_hash)
|
||||
if !@user_authorization.save
|
||||
# this is a very poorly styled page, but it's better than a server error.
|
||||
# the only reason this happens is because some other account has authed this twitter acct
|
||||
render "twitter_oauth_failure"
|
||||
return
|
||||
end
|
||||
|
||||
redirect_to request.env['omniauth.origin'] || '/'
|
||||
return
|
||||
elsif provider == 'facebook'
|
||||
fb_uid = auth_hash[:uid]
|
||||
token = auth_hash[:credentials][:token]
|
||||
token_expiration = Time.at(auth_hash[:credentials][:expires_at])
|
||||
|
|
@ -144,7 +158,7 @@ class SessionsController < ApplicationController
|
|||
end
|
||||
|
||||
def failure
|
||||
|
||||
redirect_to request.query_parameters['origin'] || '/'
|
||||
end
|
||||
|
||||
def connection_state
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
class ShareTokensController < ApplicationController
|
||||
|
||||
respond_to :html
|
||||
|
||||
def shareable_resolver
|
||||
share_token = ShareToken.find_by_token!(params[:id])
|
||||
# TODO: clean this up later to truly use polymorphic associations
|
||||
if share_token.shareable_type == "session"
|
||||
redirect_to music_session_detail_url(share_token.shareable_id)
|
||||
else
|
||||
redirect_to recording_detail_url(share_token.shareable_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -43,4 +43,5 @@ class SpikesController < ApplicationController
|
|||
|
||||
render :layout => 'web'
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
module MusicSessionHelper
|
||||
|
||||
def facebook_image_for_music_session_history(music_session)
|
||||
if music_session.band
|
||||
path = !music_session.band.large_photo_url.blank? ? music_session.band.large_photo_url : "/assets/web/logo-256.png"
|
||||
else
|
||||
path = "/assets/web/logo-256.png"
|
||||
end
|
||||
|
||||
request.protocol + request.host_with_port + path
|
||||
end
|
||||
|
||||
# careful; this mirrors logic of facebook_image_for_music_session_history
|
||||
def facebook_image_size_for_music_session_history(music_session)
|
||||
if music_session.band
|
||||
!music_session.band.large_photo_url.blank? ? 200 : 256
|
||||
else
|
||||
256
|
||||
end
|
||||
end
|
||||
|
||||
def title_for_music_session_history(music_session, sharer = nil)
|
||||
if music_session.band
|
||||
"LIVE SESSION: #{music_session.band.name}"
|
||||
else
|
||||
unique_users = music_session.unique_users
|
||||
if sharer && unique_users.exists?(sharer)
|
||||
"LIVE SESSION: #{sharer.name}#{additional_member_count(unique_users)}"
|
||||
else
|
||||
"LIVE SESSION: #{music_session.user.name}#{additional_member_count(unique_users)}"
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
def additional_member_count(unique_users)
|
||||
length = unique_users.length
|
||||
if length < 2
|
||||
""
|
||||
else
|
||||
" & #{length} OTHERS"
|
||||
end
|
||||
end
|
||||
|
||||
def description_for_music_session_history(music_session)
|
||||
truncate(music_session.description, length:250)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
module RecordingHelper
|
||||
|
||||
def facebook_image_for_claimed_recording(claimed_recording)
|
||||
if claimed_recording.recording.band
|
||||
path = !claimed_recording.recording.band.large_photo_url.blank? ? claimed_recording.recording.band.large_photo_url : "/assets/web/logo-256.png"
|
||||
else
|
||||
path = "/assets/web/logo-256.png"
|
||||
end
|
||||
|
||||
request.protocol + request.host_with_port + path
|
||||
end
|
||||
|
||||
# careful; this mirrors logic of facebook_image_for_music_session_history
|
||||
def facebook_image_size_for_claimed_recording(claimed_recording)
|
||||
if claimed_recording.recording.band
|
||||
!claimed_recording.recording.band.large_photo_url.blank? ? 200 : 256
|
||||
else
|
||||
256
|
||||
end
|
||||
end
|
||||
|
||||
def title_for_claimed_recording(claimed_recording, sharer = nil)
|
||||
if claimed_recording.recording.band
|
||||
"RECORDING: #{claimed_recording.recording.band.name}"
|
||||
else
|
||||
unique_users = claimed_recording.recording.users
|
||||
if sharer && unique_users.exists?(sharer)
|
||||
"RECORDING: #{sharer.name}#{additional_member_count(unique_users)}"
|
||||
else
|
||||
"RECORDING: #{claimed_recording.user.name}#{additional_member_count(unique_users)}"
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
def additional_member_count(unique_users)
|
||||
length = unique_users.length
|
||||
if length < 2
|
||||
""
|
||||
else
|
||||
" & #{length} OTHERS"
|
||||
end
|
||||
end
|
||||
|
||||
def description_for_claimed_recording(claimed_recording)
|
||||
truncate(claimed_recording.name, length:250)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
module ShareTokenHelper
|
||||
|
||||
|
||||
end
|
||||
|
|
@ -6,11 +6,22 @@ object @claimed_recording
|
|||
|
||||
attributes :id, :name, :description, :is_public, :is_downloadable, :genre_id
|
||||
|
||||
node :share_url do |claimed_recording|
|
||||
unless claimed_recording.share_token.nil?
|
||||
share_token_url(claimed_recording.share_token.token)
|
||||
end
|
||||
end
|
||||
|
||||
child(:recording => :recording) {
|
||||
attributes :id, :created_at, :duration, :comment_count, :like_count, :play_count
|
||||
|
||||
child(:band => :band) {
|
||||
attributes :id, :name
|
||||
}
|
||||
attributes :id, :name, :photo_url
|
||||
}
|
||||
|
||||
child(:owner => :owner) {
|
||||
attributes :id, :name, :photo_url
|
||||
}
|
||||
|
||||
child(:mixes => :mixes) {
|
||||
attributes :id, :mp3_url, :ogg_url, :is_completed
|
||||
|
|
@ -20,14 +31,10 @@ child(:recording => :recording) {
|
|||
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
|
||||
attributes :id, :first_name, :last_name, :name, :city, :state, :country, :photo_url
|
||||
}
|
||||
}
|
||||
|
||||
child(:band => :band) {
|
||||
attributes :id, :name, :photo_url
|
||||
}
|
||||
|
||||
child(:comments => :comments) {
|
||||
attributes :comment, :created_at
|
||||
|
||||
|
|
|
|||
|
|
@ -2,18 +2,24 @@ object @history
|
|||
|
||||
attributes :music_session_id, :description, :genres
|
||||
|
||||
node :share_url do |history|
|
||||
unless history.share_token.nil?
|
||||
share_token_url(history.share_token.token)
|
||||
end
|
||||
end
|
||||
|
||||
child(:user => :creator) {
|
||||
attributes :name, :photo_url
|
||||
attributes :name, :photo_url
|
||||
}
|
||||
|
||||
child(:band => :band) {
|
||||
attributes :name, :photo_url
|
||||
attributes :name, :photo_url
|
||||
}
|
||||
|
||||
child(:music_session_user_histories => :users) {
|
||||
attributes :instruments
|
||||
attributes :instruments
|
||||
|
||||
child(:user => :user) {
|
||||
attributes :name, :photo_url
|
||||
}
|
||||
child(:user => :user) {
|
||||
attributes :name, :photo_url
|
||||
}
|
||||
}
|
||||
|
|
@ -12,6 +12,12 @@ if :is_recording?
|
|||
end
|
||||
end
|
||||
|
||||
node :share_url do |music_session|
|
||||
unless music_session.music_session_history.share_token.nil?
|
||||
share_token_url(music_session.music_session_history.share_token.token)
|
||||
end
|
||||
end
|
||||
|
||||
child(:connections => :participants) {
|
||||
collection @music_sessions, :object_root => false
|
||||
attributes :ip_address, :client_id
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ end
|
|||
|
||||
# give back more info if the user being fetched is yourself
|
||||
if @user == current_user
|
||||
attributes :email, :original_fpfile, :cropped_fpfile, :crop_selection, :session_settings, :show_whats_next, :subscribe_email
|
||||
attributes :email, :original_fpfile, :cropped_fpfile, :crop_selection, :session_settings, :show_whats_next, :subscribe_email, :auth_twitter
|
||||
|
||||
elsif current_user
|
||||
node :is_friend do |uu|
|
||||
current_user.friends?(@user)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
<!-- band hover -->
|
||||
<div id="band-detail-1" class="hidden bubble">
|
||||
<h2>Band Detail</h2>
|
||||
<div class="bubble-inner">
|
||||
<a href="#" class="avatar_large left mr20"><img src="images/content/avatar_band3.jpg" /></a>
|
||||
<div class="left"><h3>Fox Force Five</h3>
|
||||
<small>Richmond, VA<br />
|
||||
<strong>Jazz</strong></small><br />
|
||||
|
||||
12 <img src="images/content/icon_like.png" width="12" height="12" align="absmiddle" /> 4 <img src="images/content/icon_followers.png" width="22" height="12" align="absmiddle" /> 17 <img src="images/content/icon_recordings.png" width="12" height="13" align="absmiddle" /> 64 <img src="images/content/icon_session_tiny.png" width="12" height="12" align="absmiddle" />
|
||||
</div>
|
||||
<br clear="all" /><br />
|
||||
|
||||
<div class="f11">Nulla facilisi. In vel sem. Morbi id urna in diam dignissim feugiat. Proin molestie tortor eu velit. Aliquam erat volutpat. Nullam ultrices, diam tempus vulputate egestas, eros pede varius leo, sed imperdiet lectus est ornare odio.</div>
|
||||
<table class="musicians" cellpadding="0" cellspacing="5">
|
||||
<tr>
|
||||
<td width="24"><a href="#" class="avatar-tiny" id="musician1"><img src="images/shared/avatar_david.jpg" /></a></td>
|
||||
<td><a href="#">John Doe</a></td>
|
||||
<td><div class="nowrap"><img src="images/content/icon_instrument_guitar24.png" width="24" height="24" /> <img src="images/content/icon_instrument_vocal24.png" width="24" height="24" /></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="24"><a href="#" class="avatar-tiny"><img src="images/shared/avatar_creepyeye.jpg" /></a></td>
|
||||
<td><a href="#">Cassandra Defrenza</a></td>
|
||||
<td><img src="images/content/icon_instrument_keyboard24.png" width="24" height="24" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="24"><a href="#" class="avatar-tiny"><img src="images/shared/avatar_silverfox.jpg" /></a></td>
|
||||
<td><a href="#">Jimmy Stratham</a></td>
|
||||
<td><img src="images/content/icon_instrument_guitar24.png" width="24" height="24" /></td>
|
||||
</tr>
|
||||
</table><br />
|
||||
|
||||
<div align="center">
|
||||
<div class="left"><a href="#" class="button-orange">PROFILE</a></div>
|
||||
<div class="left"><a href="#" class="button-orange">LIKE</a></div>
|
||||
<div class="left"><a href="#" class="button-orange">FOLLOW</a></div>
|
||||
</div>
|
||||
<br /><br />
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script type="text/template" id="template-hover-bubble">
|
||||
<div class="hover-bubble">
|
||||
|
||||
</div>
|
||||
</script>
|
||||
|
|
@ -1,3 +1,232 @@
|
|||
<!-- band hover -->
|
||||
<div id="band-detail-1" class="hidden bubble">
|
||||
<h2>Band Detail</h2>
|
||||
<div class="bubble-inner">
|
||||
<a href="#" class="avatar_large left mr20"><img src="images/content/avatar_band3.jpg" /></a>
|
||||
<div class="left"><h3>Fox Force Five</h3>
|
||||
<small>Richmond, VA<br />
|
||||
<strong>Jazz</strong></small><br />
|
||||
|
||||
12 <img src="images/content/icon_like.png" width="12" height="12" align="absmiddle" /> 4 <img src="images/content/icon_followers.png" width="22" height="12" align="absmiddle" /> 17 <img src="images/content/icon_recordings.png" width="12" height="13" align="absmiddle" /> 64 <img src="images/content/icon_session_tiny.png" width="12" height="12" align="absmiddle" />
|
||||
</div>
|
||||
<br clear="all" /><br />
|
||||
|
||||
<div class="f11">Nulla facilisi. In vel sem. Morbi id urna in diam dignissim feugiat. Proin molestie tortor eu velit. Aliquam erat volutpat. Nullam ultrices, diam tempus vulputate egestas, eros pede varius leo, sed imperdiet lectus est ornare odio.</div>
|
||||
<table class="musicians" cellpadding="0" cellspacing="5">
|
||||
<tr>
|
||||
<td width="24"><a href="#" class="avatar-tiny" id="musician1"><img src="images/shared/avatar_david.jpg" /></a></td>
|
||||
<td><a href="#">John Doe</a></td>
|
||||
<td><div class="nowrap"><img src="images/content/icon_instrument_guitar24.png" width="24" height="24" /> <img src="images/content/icon_instrument_vocal24.png" width="24" height="24" /></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="24"><a href="#" class="avatar-tiny"><img src="images/shared/avatar_creepyeye.jpg" /></a></td>
|
||||
<td><a href="#">Cassandra Defrenza</a></td>
|
||||
<td><img src="images/content/icon_instrument_keyboard24.png" width="24" height="24" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="24"><a href="#" class="avatar-tiny"><img src="images/shared/avatar_silverfox.jpg" /></a></td>
|
||||
<td><a href="#">Jimmy Stratham</a></td>
|
||||
<td><img src="images/content/icon_instrument_guitar24.png" width="24" height="24" /></td>
|
||||
</tr>
|
||||
</table><br />
|
||||
|
||||
<div align="center">
|
||||
<div class="left"><a href="#" class="button-orange">PROFILE</a></div>
|
||||
<div class="left"><a href="#" class="button-orange">LIKE</a></div>
|
||||
<div class="left"><a href="#" class="button-orange">FOLLOW</a></div>
|
||||
</div>
|
||||
<br /><br />
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<!-- musician hover -->
|
||||
<div id="musician-detail-1" class="hidden bubble">
|
||||
<h2>Musician Detail</h2>
|
||||
<div class="bubble-inner">
|
||||
<a href="#" class="avatar_large left mr20"><img src="images/shared/avatar_david.jpg" /></a>
|
||||
<div class="left ib"><h3>John Doe</h3>
|
||||
<small>Austin, TX</small><br /><br />
|
||||
|
||||
<div class="left mr10 mb"><img src="images/content/icon_instrument_guitar24.png" width="24" height="24" /></div>
|
||||
<div class="left mr10"><img src="images/content/icon_instrument_vocal24.png" width="24" height="24" /></div>
|
||||
<div class="left mr10"><img src="images/content/icon_instrument_keyboard24.png" width="24" height="24" /></div>
|
||||
<br clear="all" />
|
||||
|
||||
122 <img src="images/content/icon_friend.png" align="absmiddle" /> 4 <img src="images/content/icon_followers.png" width="22" height="12" align="absmiddle" /> 17 <img src="images/content/icon_recordings.png" width="12" height="13" align="absmiddle" /> 64 <img src="images/content/icon_session_tiny.png" width="12" height="12" align="absmiddle" /></div><br clear="all" /><br />
|
||||
<div class="f12"><strong>IN SESSION — <a href="#">Click to Join</a></strong></div>
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
<div class="f11">Nulla facilisi. In vel sem. Morbi id urna in diam dignissim feugiat. Proin molestie tortor eu velit. Aliquam erat volutpat. Nullam ultrices, diam tempus vulputate egestas, eros pede varius leo, sed imperdiet lectus est ornare odio.</div><br />
|
||||
|
||||
<small><strong>FOLLOWING:</strong></small>
|
||||
<table class="musicians" cellpadding="0" cellspacing="5">
|
||||
<tr>
|
||||
<td width="24"><a href="#" class="avatar-tiny"><img src="images/content/avatar_band3.jpg" /></a></td>
|
||||
<td><a href="#"><strong>Fox Force Five</strong></a></td>
|
||||
<td width="24"><a href="#" class="avatar-tiny"><img src="images/content/avatar_band1.jpg" /></a></td>
|
||||
<td><a href="#"><strong>Tammany Hall</strong></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="24"><a href="#" class="avatar-tiny"><img src="images/content/avatar_band2.jpg" /></a></td>
|
||||
<td><a href="#"><strong>Bethany Grey</strong></a></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
</table><br />
|
||||
|
||||
<div align="center">
|
||||
<div class="left"><a href="#" class="button-orange">PROFILE</a></div>
|
||||
<div class="left"><a href="#" class="button-orange">LIKE</a></div>
|
||||
<div class="left"><a href="#" class="button-orange">FRIEND</a></div>
|
||||
<div class="left"><a href="#" class="button-orange">FOLLOW</a></div>
|
||||
</div>
|
||||
<br /><br />
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- fan hover -->
|
||||
<div id="fan-detail-1" class="hidden bubble">
|
||||
<h2>Fan Detail</h2>
|
||||
<div class="bubble-inner">
|
||||
<a href="#" class="avatar_large left mr20"><img src="images/shared/avatar_creepyeye.jpg" /></a>
|
||||
<div class="left ib"><h3>Tomas Jones</h3>
|
||||
<small>Austin, TX</small><br /><br />
|
||||
|
||||
122 <img src="images/content/icon_friend.png" align="absmiddle" /> 4 <img src="images/content/icon_followers.png" width="22" height="12" align="absmiddle" /></div><br clear="all" /><br />
|
||||
<br />
|
||||
|
||||
<div class="f11">Nulla facilisi. In vel sem. Morbi id urna in diam dignissim feugiat. Proin molestie tortor eu velit. Aliquam erat volutpat. Nullam ultrices, diam tempus vulputate egestas, eros pede varius leo, sed imperdiet lectus est ornare odio.</div><br />
|
||||
|
||||
<small><strong>FOLLOWING:</strong></small>
|
||||
<table class="musicians" cellpadding="0" cellspacing="5">
|
||||
<tr>
|
||||
<td width="24"><a href="#" class="avatar-tiny"><img src="images/content/avatar_band3.jpg" /></a></td>
|
||||
<td><a href="#"><strong>Fox Force Five</strong></a></td>
|
||||
<td width="24"><a href="#" class="avatar-tiny"><img src="images/shared/avatar_silverfox.jpg" /></a></td>
|
||||
<td><a href="#"><strong>Bob Scrothers</strong></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="24"><a href="#" class="avatar-tiny"><img src="images/content/avatar_band2.jpg" /></a></td>
|
||||
<td><a href="#"><strong>Bethany Grey</strong></a></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
</table><br />
|
||||
|
||||
<div align="center">
|
||||
<div class="left"><a href="#" class="button-orange">PROFILE</a></div>
|
||||
<div class="left"><a href="#" class="button-orange">FOLLOW</a></div>
|
||||
</div>
|
||||
<br /><br />
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- session hover -->
|
||||
<div id="session-detail-1" class="hidden bubble">
|
||||
<h2>Session Detail</h2>
|
||||
<div class="bubble-inner">
|
||||
<div class="small left">JAZZ</div>
|
||||
<div class="small right">01/25/14 - 11:23 pm</div>
|
||||
<br clear="all" />
|
||||
<div class="f11 mt5 mb5">Nulla facilisi. In vel sem. Morbi id urna in diam dignissim feugiat. Proin molestie tortor eu velit. Aliquam erat volutpat. Nullam ultrices, diam tempus vulputate egestas, eros pede varius leo, sed imperdiet lectus est ornare odio.</div>
|
||||
<div class="small">12 <img src="images/content/icon_arrow.png" width="7" height="12" align="absmiddle" /> 4 <img src="images/content/icon_comment.png" width="13" height="12" align="absmiddle" /> 17 <img src="images/content/icon_like.png" width="12" height="12" align="absmiddle" /></div><br />
|
||||
|
||||
MUSICIANS:
|
||||
<!-- sub-table of musicians -->
|
||||
<table class="musicians" cellpadding="0" cellspacing="5">
|
||||
<tr>
|
||||
<td width="24"><a href="#" class="avatar-tiny" id="musician1"><img src="images/shared/avatar_david.jpg" /></a></td>
|
||||
<td><a href="#">John Doe</a></td>
|
||||
<td><div class="nowrap"><img src="images/content/icon_instrument_guitar24.png" width="24" height="24" /> <img src="images/content/icon_instrument_vocal24.png" width="24" height="24" /></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="24"><a href="#" class="avatar-tiny"><img src="images/shared/avatar_creepyeye.jpg" /></a></td>
|
||||
<td><a href="#">Cassandra Defrenza</a></td>
|
||||
<td><img src="images/content/icon_instrument_keyboard24.png" width="24" height="24" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="24"><a href="#" class="avatar-tiny"><img src="images/shared/avatar_silverfox.jpg" /></a></td>
|
||||
<td><a href="#">Jimmy Stratham</a></td>
|
||||
<td><img src="images/content/icon_instrument_guitar24.png" width="24" height="24" /></td>
|
||||
</tr>
|
||||
</table><br /><br />
|
||||
|
||||
<div align="center">
|
||||
<div class="left"><a href="#" class="button-orange">LIKE</a></div>
|
||||
<div class="left"><a href="#" class="button-orange">COMMENT</a></div>
|
||||
<div class="left"><a href="#" class="button-orange">SHARE</a></div>
|
||||
</div>
|
||||
<br /><br />
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- recording hover -->
|
||||
<div id="recording-detail-1" class="hidden bubble">
|
||||
<h2>Recording Detail</h2>
|
||||
<div class="bubble-inner">
|
||||
<h3>Twelve Weeks</h3>
|
||||
<div class="small left">JAZZ</div>
|
||||
<div class="small right">01/25/14 - 11:23 pm</div>
|
||||
<br clear="all" />
|
||||
<div class="f11 mt5 mb5">Nulla facilisi. In vel sem. Morbi id urna in diam dignissim feugiat. Proin molestie tortor eu velit. Aliquam erat volutpat. Nullam ultrices, diam tempus vulputate egestas, eros pede varius leo, sed imperdiet lectus est ornare odio.</div>
|
||||
<div class="small">12 <img src="images/content/icon_arrow.png" width="7" height="12" align="absmiddle" /> 4 <img src="images/content/icon_comment.png" width="13" height="12" align="absmiddle" /> 17 <img src="images/content/icon_like.png" width="12" height="12" align="absmiddle" /><br />
|
||||
<br />
|
||||
<a href="#" class="avatar_large left mr20"><img src="images/content/avatar_band3.jpg" /></a>
|
||||
<div class="left"><h3>Fox Force Five</h3>
|
||||
<small>Richmond, VA</small></div>
|
||||
<br clear="all" /><br />
|
||||
MUSICIANS:
|
||||
<!-- sub-table of musicians -->
|
||||
<table class="musicians" cellpadding="0" cellspacing="5">
|
||||
<tr>
|
||||
<td width="24"><a href="#" class="avatar-tiny" id="musician1"><img src="images/shared/avatar_david.jpg" /></a></td>
|
||||
<td><a href="#">John Doe</a></td>
|
||||
<td><div class="nowrap"><img src="images/content/icon_instrument_guitar24.png" width="24" height="24" /> <img src="images/content/icon_instrument_vocal24.png" width="24" height="24" /></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="24"><a href="#" class="avatar-tiny"><img src="images/shared/avatar_creepyeye.jpg" /></a></td>
|
||||
<td><a href="#">Cassandra Defrenza</a></td>
|
||||
<td><img src="images/content/icon_instrument_keyboard24.png" width="24" height="24" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="24"><a href="#" class="avatar-tiny"><img src="images/shared/avatar_silverfox.jpg" /></a></td>
|
||||
<td><a href="#">Jimmy Stratham</a></td>
|
||||
<td><img src="images/content/icon_instrument_guitar24.png" width="24" height="24" /></td>
|
||||
</tr>
|
||||
</table><br /><br />
|
||||
|
||||
<div align="center">
|
||||
<div class="left"><a href="#" class="button-orange">LIKE</a></div>
|
||||
<div class="left"><a href="#" class="button-orange">COMMENT</a></div>
|
||||
<div class="left"><a href="#" class="button-orange">SHARE</a></div>
|
||||
</div>
|
||||
<br /><br />
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<script type="text/template" id="template-hover-bubble">
|
||||
<div class="hover-bubble">
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
<!-- fan hover -->
|
||||
<div id="fan-detail-1" class="hidden bubble">
|
||||
<h2>Fan Detail</h2>
|
||||
<div class="bubble-inner">
|
||||
<a href="#" class="avatar_large left mr20"><img src="images/shared/avatar_creepyeye.jpg" /></a>
|
||||
<div class="left ib"><h3>Tomas Jones</h3>
|
||||
<small>Austin, TX</small><br /><br />
|
||||
|
||||
122 <img src="images/content/icon_friend.png" align="absmiddle" /> 4 <img src="images/content/icon_followers.png" width="22" height="12" align="absmiddle" /></div><br clear="all" /><br />
|
||||
<br />
|
||||
|
||||
<div class="f11">Nulla facilisi. In vel sem. Morbi id urna in diam dignissim feugiat. Proin molestie tortor eu velit. Aliquam erat volutpat. Nullam ultrices, diam tempus vulputate egestas, eros pede varius leo, sed imperdiet lectus est ornare odio.</div><br />
|
||||
|
||||
<small><strong>FOLLOWING:</strong></small>
|
||||
<table class="musicians" cellpadding="0" cellspacing="5">
|
||||
<tr>
|
||||
<td width="24"><a href="#" class="avatar-tiny"><img src="images/content/avatar_band3.jpg" /></a></td>
|
||||
<td><a href="#"><strong>Fox Force Five</strong></a></td>
|
||||
<td width="24"><a href="#" class="avatar-tiny"><img src="images/shared/avatar_silverfox.jpg" /></a></td>
|
||||
<td><a href="#"><strong>Bob Scrothers</strong></a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="24"><a href="#" class="avatar-tiny"><img src="images/content/avatar_band2.jpg" /></a></td>
|
||||
<td><a href="#"><strong>Bethany Grey</strong></a></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
</table><br />
|
||||
|
||||
<div align="center">
|
||||
<div class="left"><a href="#" class="button-orange">PROFILE</a></div>
|
||||
<div class="left"><a href="#" class="button-orange">FOLLOW</a></div>
|
||||
</div>
|
||||
<br /><br />
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script type="text/template" id="template-hover-bubble">
|
||||
<div class="hover-bubble">
|
||||
|
||||
</div>
|
||||
</script>
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
<!-- recording hover -->
|
||||
<div id="recording-detail-1" class="hidden bubble">
|
||||
<h2>Recording Detail</h2>
|
||||
<div class="bubble-inner">
|
||||
<h3>Twelve Weeks</h3>
|
||||
<div class="small left">JAZZ</div>
|
||||
<div class="small right">01/25/14 - 11:23 pm</div>
|
||||
<br clear="all" />
|
||||
<div class="f11 mt5 mb5">Nulla facilisi. In vel sem. Morbi id urna in diam dignissim feugiat. Proin molestie tortor eu velit. Aliquam erat volutpat. Nullam ultrices, diam tempus vulputate egestas, eros pede varius leo, sed imperdiet lectus est ornare odio.</div>
|
||||
<div class="small">12 <img src="images/content/icon_arrow.png" width="7" height="12" align="absmiddle" /> 4 <img src="images/content/icon_comment.png" width="13" height="12" align="absmiddle" /> 17 <img src="images/content/icon_like.png" width="12" height="12" align="absmiddle" /><br />
|
||||
<br />
|
||||
<a href="#" class="avatar_large left mr20"><img src="images/content/avatar_band3.jpg" /></a>
|
||||
<div class="left"><h3>Fox Force Five</h3>
|
||||
<small>Richmond, VA</small></div>
|
||||
<br clear="all" /><br />
|
||||
MUSICIANS:
|
||||
<!-- sub-table of musicians -->
|
||||
<table class="musicians" cellpadding="0" cellspacing="5">
|
||||
<tr>
|
||||
<td width="24"><a href="#" class="avatar-tiny" id="musician1"><img src="images/shared/avatar_david.jpg" /></a></td>
|
||||
<td><a href="#">John Doe</a></td>
|
||||
<td><div class="nowrap"><img src="images/content/icon_instrument_guitar24.png" width="24" height="24" /> <img src="images/content/icon_instrument_vocal24.png" width="24" height="24" /></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="24"><a href="#" class="avatar-tiny"><img src="images/shared/avatar_creepyeye.jpg" /></a></td>
|
||||
<td><a href="#">Cassandra Defrenza</a></td>
|
||||
<td><img src="images/content/icon_instrument_keyboard24.png" width="24" height="24" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="24"><a href="#" class="avatar-tiny"><img src="images/shared/avatar_silverfox.jpg" /></a></td>
|
||||
<td><a href="#">Jimmy Stratham</a></td>
|
||||
<td><img src="images/content/icon_instrument_guitar24.png" width="24" height="24" /></td>
|
||||
</tr>
|
||||
</table><br /><br />
|
||||
|
||||
<div align="center">
|
||||
<div class="left"><a href="#" class="button-orange">LIKE</a></div>
|
||||
<div class="left"><a href="#" class="button-orange">COMMENT</a></div>
|
||||
<div class="left"><a href="#" class="button-orange">SHARE</a></div>
|
||||
</div>
|
||||
<br /><br />
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<script type="text/template" id="template-hover-bubble">
|
||||
<div class="hover-bubble">
|
||||
|
||||
</div>
|
||||
</script>
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
<!-- session hover -->
|
||||
<div id="session-detail-1" class="hidden bubble">
|
||||
<h2>Session Detail</h2>
|
||||
<div class="bubble-inner">
|
||||
<div class="small left">JAZZ</div>
|
||||
<div class="small right">01/25/14 - 11:23 pm</div>
|
||||
<br clear="all" />
|
||||
<div class="f11 mt5 mb5">Nulla facilisi. In vel sem. Morbi id urna in diam dignissim feugiat. Proin molestie tortor eu velit. Aliquam erat volutpat. Nullam ultrices, diam tempus vulputate egestas, eros pede varius leo, sed imperdiet lectus est ornare odio.</div>
|
||||
<div class="small">12 <img src="images/content/icon_arrow.png" width="7" height="12" align="absmiddle" /> 4 <img src="images/content/icon_comment.png" width="13" height="12" align="absmiddle" /> 17 <img src="images/content/icon_like.png" width="12" height="12" align="absmiddle" /></div><br />
|
||||
|
||||
MUSICIANS:
|
||||
<!-- sub-table of musicians -->
|
||||
<table class="musicians" cellpadding="0" cellspacing="5">
|
||||
<tr>
|
||||
<td width="24"><a href="#" class="avatar-tiny" id="musician1"><img src="images/shared/avatar_david.jpg" /></a></td>
|
||||
<td><a href="#">John Doe</a></td>
|
||||
<td><div class="nowrap"><img src="images/content/icon_instrument_guitar24.png" width="24" height="24" /> <img src="images/content/icon_instrument_vocal24.png" width="24" height="24" /></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="24"><a href="#" class="avatar-tiny"><img src="images/shared/avatar_creepyeye.jpg" /></a></td>
|
||||
<td><a href="#">Cassandra Defrenza</a></td>
|
||||
<td><img src="images/content/icon_instrument_keyboard24.png" width="24" height="24" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="24"><a href="#" class="avatar-tiny"><img src="images/shared/avatar_silverfox.jpg" /></a></td>
|
||||
<td><a href="#">Jimmy Stratham</a></td>
|
||||
<td><img src="images/content/icon_instrument_guitar24.png" width="24" height="24" /></td>
|
||||
</tr>
|
||||
</table><br /><br />
|
||||
|
||||
<div align="center">
|
||||
<div class="left"><a href="#" class="button-orange">LIKE</a></div>
|
||||
<div class="left"><a href="#" class="button-orange">COMMENT</a></div>
|
||||
<div class="left"><a href="#" class="button-orange">SHARE</a></div>
|
||||
</div>
|
||||
<br /><br />
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<script type="text/template" id="template-hover-bubble">
|
||||
<div class="hover-bubble">
|
||||
|
||||
</div>
|
||||
</script>
|
||||
|
|
@ -1,123 +1,54 @@
|
|||
<!-- Share dialog -->
|
||||
<div class="dialog share-overlay" layout="dialog" layout-id="share-dialog" 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" %>
|
||||
<input type="checkbox" />
|
||||
<%= image_tag "content/icon_twitter.png", :size => "24x24", :align => "absmiddle", :alt => "", :style => "vertical-align:middle" %>
|
||||
<input type="checkbox" />
|
||||
<%= image_tag "content/icon_google.png", :size => "24x24", :align => "absmiddle", :alt => "", :style => "vertical-align:middle" %>
|
||||
</div>
|
||||
<div class=" right mr10 mt5"><a class="button-orange dialog-share-button">SHARE</a></div>
|
||||
</td>
|
||||
<td valign="top" width="48%">
|
||||
<div class="ml10">
|
||||
<h3>Share a Link:</h3><br />
|
||||
<%= true ? '' : "#{root_url}#{share_token}" %>
|
||||
<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 & 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">
|
||||
<a href="#"><img src="images/content/icon_like.png" width="12" height="12" alt=""/> LIKE</a>
|
||||
<a href="#"><img class="space" src="images/content/icon_comment.png" width="12" height="12" alt=""/> COMMENT</a>
|
||||
<a href="#"><img class="space" src="images/content/icon_share.png" width="13" height="15" alt=""/> 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 & 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>
|
||||
<!-- 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 class="dialog share-overlay" layout="dialog" layout-id="share-dialog" id="share-dialog">
|
||||
<div class="content-head"><h1>share this <span id="shareType"></span></h1></div>
|
||||
<div class="dialog-inner">
|
||||
|
||||
<div class="right"><a class="button-orange" layout-action="close">X CLOSE</a></div>
|
||||
<br clear="both" />
|
||||
|
||||
<div class="share-to-social-media border-bottom">
|
||||
|
||||
<h3 class="mb5">Share to Social Media:</h3>
|
||||
|
||||
<div class="share-message-holder">
|
||||
<textarea class="share-message" rows="4" placeholder="Add a Message..."></textarea><br/>
|
||||
<span class="error-msg"></span>
|
||||
</div>
|
||||
|
||||
<div class="share-options left">
|
||||
<span class="share-with-facebook">
|
||||
<input type="checkbox" disabled="disabled"/>
|
||||
<%= image_tag "content/icon_facebook.png", :size => "24x24", :align => "absmiddle", :alt => "", :style => "vertical-align:middle" %>
|
||||
<a href="#" class="authorize">(sign in)</a>
|
||||
</span>
|
||||
<span class="share-with-twitter">
|
||||
<input type="checkbox" disabled="disabled"/>
|
||||
<%= image_tag "content/icon_twitter.png", :size => "24x24", :align => "absmiddle", :alt => "", :style => "vertical-align:middle" %>
|
||||
<a href="#" class="authorize">(sign in)</a>
|
||||
</span>
|
||||
|
||||
<!--
|
||||
<div class="share-with-google">
|
||||
<input type="checkbox" disabled="disabled" />
|
||||
<%= image_tag "content/icon_google.png", :size => "24x24", :align => "absmiddle", :alt => "", :style => "vertical-align:middle" %>
|
||||
</div>-->
|
||||
|
||||
<div class="error-msg">Please select at least one</div>
|
||||
</div>
|
||||
<div class="share-button-holder"><a class="button-orange dialog-share-button">SHARE</a></div>
|
||||
<br clear="both" />
|
||||
</div>
|
||||
|
||||
<div class="share-link">
|
||||
<h3>Share a Link:</h3>
|
||||
<div class="link-contents">
|
||||
</div>
|
||||
|
||||
<div class="right"><a id="btn-share-copy" class="button-orange">COPY LINK</a></div>
|
||||
</div>
|
||||
|
||||
<!-- contains syndication widget code -->
|
||||
<% #render 'shareDialogUnused' %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,87 @@
|
|||
<table class="w100">
|
||||
<tr>
|
||||
<td valign="top" width="40%"><h3>Get a Widget:</h3>
|
||||
<!-- ########## Javascript code for widget ########## -->
|
||||
<textarea class="w95" rows="10">
|
||||
<!-- widget -->
|
||||
<div id="divWidgetCode" class="widget">
|
||||
<!-- header -->
|
||||
<div id="divWidgetCodeHeader" class="widget-header"><strong><span id="lblWidgetCodeType"></span></strong> by <span id="spnWidgetCodeArtistName"></span></div>
|
||||
<!-- start widget content -->
|
||||
<div class="widget-content">
|
||||
<!-- band avatar -->
|
||||
<div class="widget-avatar"><img id="imgWidgetCodeAvatar" 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">
|
||||
<a href="#"><img src="images/content/icon_like.png" width="12" height="12" alt=""/> LIKE</a>
|
||||
<a href="#"><img class="space" src="images/content/icon_comment.png" width="12" height="12" alt=""/> COMMENT</a>
|
||||
<a href="#"><img class="space" src="images/content/icon_share.png" width="13" height="15" alt=""/> SHARE</a>
|
||||
</div>
|
||||
<!-- jamkazam branding -->
|
||||
<div class="widget-branding"><span id="spnWidgetCodeBranding"></span> 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 id="divWidgetPreview" class="widget">
|
||||
<!-- header -->
|
||||
<div id="divWidgetPreviewHeader" class="widget-header"><strong><span id="lblWidgetPreviewType"></span></strong> by <span id="spnWidgetPreviewArtistName"></span></div>
|
||||
<!-- start widget content -->
|
||||
<div class="widget-content">
|
||||
<!-- band avatar -->
|
||||
<div class="widget-avatar"><img id="imgWidgetPreviewAvatar" src="" alt=""/></div>
|
||||
<a href="javascript:void(0)" class="widget-playbutton" title="play"></a>
|
||||
|
||||
<!-- song title -->
|
||||
<div id="divWidgetPreviewTitle" class="widget-title"></div>
|
||||
|
||||
<!-- avatars -->
|
||||
<div class="widget-members"></div>
|
||||
|
||||
<!-- jamkazam branding -->
|
||||
<div class="widget-branding"><span id="spnWidgetPreviewBranding"></span> on
|
||||
<a href=<%= "#{root_url}" %>>
|
||||
<%= image_tag "shared/jk_logo_small.png", :size => "142x26", :align => "absbottom", :alt => "" %>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end widget content -->
|
||||
</div>
|
||||
<!-- /widget -->
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
@ -52,6 +52,8 @@
|
|||
|
||||
JK = JK || {};
|
||||
|
||||
JK.root_url = "<%= root_url %>"
|
||||
|
||||
<% if Rails.env == "development" %>
|
||||
// if in development mode, we assume you are running websocket-gateway
|
||||
// on the same host as you hit your server.
|
||||
|
|
@ -85,8 +87,12 @@
|
|||
|
||||
<% if current_user %>
|
||||
JK.currentUserId = '<%= current_user.id %>';
|
||||
JK.currentUserAvatarUrl = JK.resolveAvatarUrl('<%= current_user.photo_url %>');
|
||||
JK.currentUserName = '<%= current_user.name %>';
|
||||
<% else %>
|
||||
JK.currentUserId = null;
|
||||
JK.currentUserAvatarUrl = null;
|
||||
JK.currentUserName = null;
|
||||
<% end %>
|
||||
|
||||
|
||||
|
|
@ -95,11 +101,11 @@
|
|||
|
||||
var recordingManager = new JK.RecordingManager();
|
||||
|
||||
var invitationDialog = new JK.InvitationDialog(JK.app);
|
||||
invitationDialog.initialize('<%= SampleApp::Application.config.facebook_key %>');
|
||||
var facebookHelper = new JK.FacebookHelper(JK.app);
|
||||
facebookHelper.initialize(gon.global.facebook_app_id);
|
||||
|
||||
var shareDialog = new JK.ShareDialog(JK.app);
|
||||
shareDialog.initialize();
|
||||
var invitationDialog = new JK.InvitationDialog(JK.app);
|
||||
invitationDialog.initialize(gon.global.facebook_app_id);
|
||||
|
||||
var localRecordingsDialog = new JK.LocalRecordingsDialog(JK.app);
|
||||
localRecordingsDialog.initialize();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
<meta property="fb:app_id" content="<%= Rails.application.config.facebook_app_id %>" />
|
||||
<meta property="og:title" content="<%= "JamKazam" %>" />
|
||||
<meta property="og:url" content="<%= request.original_url %>" />
|
||||
<meta property="og:description" content="Play music together over the Internet as if in the same room." />
|
||||
<meta property="og:image" content="<%= request.protocol + request.host_with_port + image_path("web/logo-256.png") %>" />
|
||||
<meta property="og:image:width" content="256" />
|
||||
<meta property="og:image:height" content="256" />
|
||||
<meta property="og:type" content="website" />
|
||||
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="twitter:site" content="@jamkazam">
|
||||
<meta name="twitter:title" content="JamKazam" />
|
||||
<meta name="twitter:description" content="Play music together over the Internet as if in the same room." />
|
||||
|
|
@ -44,10 +44,16 @@
|
|||
$(function () {
|
||||
JK = JK || {};
|
||||
|
||||
JK.root_url = "<%= root_url %>"
|
||||
|
||||
<% if current_user %>
|
||||
JK.currentUserId = '<%= current_user.id %>';
|
||||
JK.currentUserAvatarUrl = JK.resolveAvatarUrl('<%= current_user.photo_url %>');
|
||||
JK.currentUserName = '<%= current_user.name %>';
|
||||
<% else %>
|
||||
JK.currentUserId = null;
|
||||
JK.currentUserAvatarUrl = null;
|
||||
JK.currentUserName = null;
|
||||
<% end %>
|
||||
})
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,11 @@
|
|||
<%= include_gon %>
|
||||
<%= javascript_include_tag "application" %>
|
||||
<%= csrf_meta_tags %>
|
||||
<% if content_for?(:social_meta) %>
|
||||
<%= yield(:social_meta) %>
|
||||
<% else %>
|
||||
<%= render "layouts/social_meta" %>
|
||||
<% end %>
|
||||
</head>
|
||||
<body>
|
||||
<%= yield %>
|
||||
|
|
|
|||
|
|
@ -12,6 +12,11 @@
|
|||
<%= include_gon(:init => true) %>
|
||||
<%= javascript_include_tag "corp/corporate" %>
|
||||
<%= csrf_meta_tags %>
|
||||
<% if content_for?(:social_meta) %>
|
||||
<%= yield(:social_meta) %>
|
||||
<% else %>
|
||||
<%= render "layouts/social_meta" %>
|
||||
<% end %>
|
||||
</head>
|
||||
<body class="corporate" data-purpose="<%= yield(:purpose) %>">
|
||||
|
||||
|
|
@ -59,10 +64,16 @@
|
|||
$(function () {
|
||||
JK = JK || {};
|
||||
|
||||
JK.root_url = "<%= root_url %>"
|
||||
|
||||
<% if current_user %>
|
||||
JK.currentUserId = '<%= current_user.id %>';
|
||||
JK.currentUserAvatarUrl = JK.resolveAvatarUrl('<%= current_user.photo_url %>');
|
||||
JK.currentUserName = '<%= current_user.name %>';
|
||||
<% else %>
|
||||
JK.currentUserId = null;
|
||||
JK.currentUserAvatarUrl = null;
|
||||
JK.currentUserName = null;
|
||||
<% end %>
|
||||
})
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,11 @@
|
|||
<% end %>
|
||||
<%= include_gon(:init => true) %>
|
||||
<%= csrf_meta_tags %>
|
||||
<% if content_for?(:social_meta) %>
|
||||
<%= yield(:social_meta) %>
|
||||
<% else %>
|
||||
<%= render "layouts/social_meta" %>
|
||||
<% end %>
|
||||
</head>
|
||||
<body>
|
||||
<div id="landing-container">
|
||||
|
|
@ -41,10 +46,16 @@
|
|||
$(function () {
|
||||
JK = JK || {};
|
||||
|
||||
JK.root_url = "<%= root_url %>"
|
||||
|
||||
<% if current_user %>
|
||||
JK.currentUserId = '<%= current_user.id %>';
|
||||
JK.currentUserAvatarUrl = JK.resolveAvatarUrl('<%= current_user.photo_url %>');
|
||||
JK.currentUserName = '<%= current_user.name %>';
|
||||
<% else %>
|
||||
JK.currentUserId = null;
|
||||
JK.currentUserAvatarUrl = null;
|
||||
JK.currentUserName = null;
|
||||
<% end %>
|
||||
})
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,11 @@
|
|||
<% end %>
|
||||
<%= include_gon(:init => true) %>
|
||||
<%= csrf_meta_tags %>
|
||||
<% if content_for?(:social_meta) %>
|
||||
<%= yield(:social_meta) %>
|
||||
<% else %>
|
||||
<%= render "layouts/social_meta" %>
|
||||
<% end %>
|
||||
</head>
|
||||
<body class="web">
|
||||
<%= javascript_include_tag "web/web" %>
|
||||
|
|
@ -51,23 +56,34 @@
|
|||
<%= render "clients/invitationDialog" %>
|
||||
<%= render "users/signupDialog" %>
|
||||
<%= render "users/signinDialog" %>
|
||||
<%= yield(:extra_dialogs) %>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
|
||||
JK = JK || {};
|
||||
|
||||
JK.root_url = "<%= root_url %>"
|
||||
|
||||
<% if current_user %>
|
||||
JK.currentUserId = '<%= current_user.id %>';
|
||||
JK.currentUserAvatarUrl = JK.resolveAvatarUrl('<%= current_user.photo_url %>');
|
||||
JK.currentUserName = '<%= current_user.name %>';
|
||||
<% else %>
|
||||
JK.currentUserId = null;
|
||||
JK.currentUserAvatarUrl = null;
|
||||
JK.currentUserName = null;
|
||||
<% end %>
|
||||
|
||||
JK.app = JK.JamKazam();
|
||||
JK.app.initialize({inClient: false, layoutOpts: {layoutFooter: false}});
|
||||
JK.app.initialize({inClient: false, layoutOpts: {layoutFooter: false, sizeOverlayToContent: true}});
|
||||
|
||||
var facebookHelper = new JK.FacebookHelper(JK.app);
|
||||
JK.FacebookHelperInstance = facebookHelper;
|
||||
facebookHelper.initialize(gon.global.facebook_app_id);
|
||||
|
||||
var invitationDialog = new JK.InvitationDialog(JK.app);
|
||||
invitationDialog.initialize();
|
||||
invitationDialog.initialize(facebookHelper);
|
||||
|
||||
var userDropdown = new JK.UserDropdown(JK.app);
|
||||
userDropdown.initialize(invitationDialog);
|
||||
|
|
@ -75,11 +91,12 @@
|
|||
var signupDialog = new JK.SignupDialog(JK.app);
|
||||
signupDialog.initialize();
|
||||
|
||||
var signinDialog = new JK.SigninDialog(JK.app);
|
||||
signinDialog.initialize();
|
||||
})
|
||||
</script>
|
||||
|
||||
<%= yield(:extra_js) %>
|
||||
|
||||
|
||||
<%= render "shared/ga" %>
|
||||
<!-- version info: <%= version %> -->
|
||||
</body>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,21 @@
|
|||
<% provide(:title, "#{@music_session.description}") %>
|
||||
|
||||
<% content_for :social_meta do %>
|
||||
<meta property="fb:app_id" content="<%= Rails.application.config.facebook_app_id %>" />
|
||||
<meta property="og:title" content="<%= title_for_music_session_history(@music_session) %>" />
|
||||
<meta property="og:url" content="<%= request.original_url %>" />
|
||||
<meta property="og:description" content="<%= description_for_music_session_history(@music_session) %>" />
|
||||
<meta property="og:image" content="<%= facebook_image_for_music_session_history(@music_session) %>" />
|
||||
<meta property="og:image:width" content="<%= facebook_image_size_for_music_session_history(@music_session) %>" />
|
||||
<meta property="og:image:height" content="<%= facebook_image_size_for_music_session_history(@music_session) %>" />
|
||||
<meta property="og:type" content="website" />
|
||||
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="twitter:site" content="@jamkazam">
|
||||
<meta name="twitter:title" content="<%= title_for_music_session_history(@music_session) %>" />
|
||||
<meta name="twitter:description" content="<%= description_for_music_session_history(@music_session) %>" />
|
||||
<% end %>
|
||||
|
||||
<div class="landing-band">
|
||||
<% unless @music_session.band.nil? %>
|
||||
<div class="landing-avatar">
|
||||
|
|
@ -78,64 +94,15 @@
|
|||
|
||||
<%= javascript_include_tag "web/sessions" %>
|
||||
|
||||
<%= render :partial => "clients/shareDialog", :locals => {:session => @music_session, :share_token => @music_session.share_token} %>
|
||||
<% content_for :extra_dialogs do %>
|
||||
<%= render :partial => "clients/shareDialog" %>
|
||||
<% end %>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
|
||||
JK = JK || {};
|
||||
|
||||
<% if current_user %>
|
||||
JK.currentUserId = '<%= current_user.id %>';
|
||||
<% else %>
|
||||
JK.currentUserId = null;
|
||||
<% end %>
|
||||
|
||||
if (JK.currentUserId) {
|
||||
JK.app = JK.JamKazam();
|
||||
JK.app.initialize({inClient: false, layoutOpts: {layoutFooter: false}});
|
||||
|
||||
var shareDialog = new JK.ShareDialog(JK.app);
|
||||
shareDialog.initialize();
|
||||
|
||||
$("#btnShare").click(function(e) {
|
||||
shareDialog.showDialog();
|
||||
});
|
||||
|
||||
$("#txtSessionComment").keypress(function(e) {
|
||||
if (e.which === 13) {
|
||||
addComment();
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
$("#txtSessionComment").attr("disabled", "disabled");
|
||||
$("#txtSessionComment").val("You must be logged in to add a comment.");
|
||||
}
|
||||
|
||||
JK.sessionId = "<%= @music_session.music_session_id %>";
|
||||
|
||||
var rest = new JK.Rest();
|
||||
|
||||
$("#btnLike").click(like);
|
||||
|
||||
function like() {
|
||||
rest.addSessionLike(JK.sessionId, JK.currentUserId)
|
||||
.done(function(response) {
|
||||
$("#spnLikeCount").html(parseInt($("#spnLikeCount").text()) + 1);
|
||||
$("#btnLike").unbind("click");
|
||||
});
|
||||
}
|
||||
|
||||
function addComment() {
|
||||
var comment = $("#txtSessionComment").val();
|
||||
if ($.trim(comment).length > 0) {
|
||||
rest.addSessionComment(JK.sessionId, JK.currentUserId, comment)
|
||||
.done(function(response) {
|
||||
$("#spnCommentCount").html(parseInt($("#spnCommentCount").text()) + 1);
|
||||
$(".landing-comment-scroller").prepend(comment);
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<% content_for :extra_js do %>
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
var showMusicSession = new JK.ShowMusicSession(JK.app);
|
||||
showMusicSession.initialize("<%= @music_session.music_session_id %>");
|
||||
})
|
||||
</script>
|
||||
<% end %>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,22 @@
|
|||
<% provide(:title, "#{@claimed_recording.name}") %>
|
||||
|
||||
|
||||
<% content_for :social_meta do %>
|
||||
<meta property="fb:app_id" content="<%= Rails.application.config.facebook_app_id %>" />
|
||||
<meta property="og:title" content="<%= title_for_claimed_recording(@claimed_recording) %>" />
|
||||
<meta property="og:url" content="<%= request.original_url %>" />
|
||||
<meta property="og:description" content="<%= description_for_claimed_recording(@claimed_recording) %>" />
|
||||
<meta property="og:image" content="<%= facebook_image_for_claimed_recording(@claimed_recording) %>" />
|
||||
<meta property="og:image:width" content="<%= facebook_image_size_for_claimed_recording(@claimed_recording) %>" />
|
||||
<meta property="og:image:height" content="<%= facebook_image_size_for_claimed_recording(@claimed_recording) %>" />
|
||||
<meta property="og:type" content="website" />
|
||||
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="twitter:site" content="@jamkazam">
|
||||
<meta name="twitter:title" content="<%= title_for_claimed_recording(@claimed_recording) %>" />
|
||||
<meta name="twitter:description" content="<%= description_for_claimed_recording(@claimed_recording) %>" />
|
||||
<% end %>
|
||||
|
||||
<div class="landing-band">
|
||||
<% unless @claimed_recording.recording.band.nil? %>
|
||||
<div class="landing-avatar">
|
||||
|
|
@ -77,72 +94,16 @@
|
|||
|
||||
<%= javascript_include_tag "web/recordings" %>
|
||||
|
||||
<%= render :partial => "clients/shareDialog", :locals => {:recording => @claimed_recording, :share_token => @claimed_recording.share_token} %>
|
||||
<% content_for :extra_dialogs do %>
|
||||
<%= render :partial => "clients/shareDialog" %>
|
||||
<% end %>
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
<% content_for :extra_js do %>
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
var showRecording = new JK.ShowRecording(JK.app);
|
||||
showRecording.initialize("<%= @claimed_recording.id %>", "<%= @claimed_recording.recording_id %>");
|
||||
})
|
||||
</script>
|
||||
<% end %>
|
||||
|
||||
JK = JK || {};
|
||||
|
||||
<% if current_user %>
|
||||
JK.currentUserId = '<%= current_user.id %>';
|
||||
<% else %>
|
||||
JK.currentUserId = null;
|
||||
<% end %>
|
||||
|
||||
if (JK.currentUserId) {
|
||||
JK.app = JK.JamKazam();
|
||||
JK.app.initialize({inClient: false, layoutOpts: {layoutFooter: false}});
|
||||
|
||||
var shareDialog = new JK.ShareDialog(JK.app);
|
||||
shareDialog.initialize();
|
||||
|
||||
$("#btnShare").click(function(e) {
|
||||
shareDialog.showDialog();
|
||||
});
|
||||
|
||||
$("#txtRecordingComment").keypress(function(e) {
|
||||
if (e.which === 13) {
|
||||
addComment();
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
$("#txtRecordingComment").attr("disabled", "disabled");
|
||||
$("#txtRecordingComment").val("You must be logged in to add a comment.");
|
||||
}
|
||||
|
||||
JK.recordingId = "<%= @claimed_recording.recording.id %>";
|
||||
|
||||
var rest = new JK.Rest();
|
||||
|
||||
$("#btnLike").click(like);
|
||||
$("#btnPlay").click(play);
|
||||
|
||||
function like() {
|
||||
rest.addRecordingLike(JK.recordingId, JK.currentUserId)
|
||||
.done(function(response) {
|
||||
$("#spnLikeCount").html(parseInt($("#spnLikeCount").text()) + 1);
|
||||
$("#btnLike").unbind("click");
|
||||
});
|
||||
}
|
||||
|
||||
function play() {
|
||||
rest.addRecordingPlay(JK.recordingId, JK.currentUserId)
|
||||
.done(function(response) {
|
||||
$("#spnPlayCount").html(parseInt($("#spnPlayCount").text()) + 1);
|
||||
});
|
||||
}
|
||||
|
||||
function addComment() {
|
||||
var comment = $("#txtRecordingComment").val();
|
||||
if ($.trim(comment).length > 0) {
|
||||
rest.addRecordingComment(JK.recordingId, JK.currentUserId, comment)
|
||||
.done(function(response) {
|
||||
$("#spnCommentCount").html(parseInt($("#spnCommentCount").text()) + 1);
|
||||
$(".landing-comment-scroller").prepend(comment);
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
<script type="text/javascript">
|
||||
|
||||
</script>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
Unable to authorize application. Reasons:
|
||||
|
||||
<ul>
|
||||
<% @user_authorization.errors.each do |field, error| %>
|
||||
<% if field == :uid && error.include?('has already been taken') %>
|
||||
<li>This twitter account is already associated with someone else</li>
|
||||
<% else %>
|
||||
<li><%= @user_authorization.errors.full_message(field, error) %></li>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</ul>
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
<%= image_tag "shared/avatar_generic.png", {:alt => ""} %>
|
||||
</div>
|
||||
<div class="left w80 p10">
|
||||
<textarea id="<%= id %>" class="w100 p5 f15" rows="2" onfocus="$(this).html('')" onblur="if($(this).html() == ''){$(this).html('Enter a comment...')}">Enter a comment...</textarea>
|
||||
<textarea id="<%= id %>" class="w100 p5 f15" rows="2" placeholder="Enter a comment..."></textarea>
|
||||
</div>
|
||||
<br clear="all" />
|
||||
|
||||
|
|
@ -25,4 +25,16 @@
|
|||
<br clear="all" />
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/template" id="template-landing-comment">
|
||||
<div class="avatar-small mr10">
|
||||
<img src="{avatar_url}" alt="" />
|
||||
</div>
|
||||
<div class="w80 left p10 lightgrey mt10">
|
||||
<a href="#">{name}</a> {comment}
|
||||
<br />
|
||||
<div class="f12 grey mt5">Just now</div>
|
||||
</div>
|
||||
<br clear="all" />
|
||||
</script>
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
window.fbAsyncInit = function() {
|
||||
// init the FB JS SDK
|
||||
FB.init({
|
||||
appId : '<%= SampleApp::Application.config.facebook_key %>', // App ID from the App Dashboard
|
||||
appId : gon.global.facebook_app_id, // App ID from the App Dashboard
|
||||
// channelUrl : '//WWW.YOUR_DOMAIN.COM/channel.html', // Channel File for x-domain communication
|
||||
status : true, // check the login status upon init?
|
||||
cookie : true, // set sessions cookies to allow your server to access the session?
|
||||
|
|
|
|||
|
|
@ -133,9 +133,6 @@ include JamRuby
|
|||
# cloudfront host
|
||||
config.cloudfront_host = "d34f55ppvvtgi3.cloudfront.net"
|
||||
|
||||
# facebook keys
|
||||
config.facebook_key = '468555793186398'
|
||||
|
||||
# google api keys
|
||||
config.google_client_id = '785931784279-gd0g8on6sc0tuesj7cu763pitaiv2la8.apps.googleusercontent.com'
|
||||
config.google_secret = 'UwzIcvtErv9c2-GIsNfIo7bA'
|
||||
|
|
@ -196,7 +193,10 @@ include JamRuby
|
|||
config.email_smtp_password = 'jamjamblueberryjam'
|
||||
config.email_smtp_starttls_auto = true
|
||||
|
||||
config.facebook_app_id = '468555793186398'
|
||||
config.facebook_app_secret = '546a5b253972f3e2e8b36d9a3dd5a06e'
|
||||
config.facebook_app_id = ENV['FACEBOOK_APP_ID'] || '468555793186398'
|
||||
config.facebook_app_secret = ENV['FACEBOOK_APP_SECRET'] || '546a5b253972f3e2e8b36d9a3dd5a06e'
|
||||
|
||||
config.twitter_app_id = ENV['TWITTER_APP_ID'] || 'nQj2oEeoJZxECC33tiTuIg'
|
||||
config.twitter_app_secret = ENV['TWITTER_APP_SECRET'] || 'Azcy3QqfzYzn2fsojFPYXcn72yfwa0vG6wWDrZ3KT8'
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -89,4 +89,7 @@ SampleApp::Application.configure do
|
|||
|
||||
config.facebook_app_id = '1412328362347190' # staging
|
||||
config.facebook_app_secret = '8b1f20430356d44fb49c0a504a9ff401' # staging
|
||||
|
||||
config.twitter_app_id = 'RHv0NJod7NLCXH6Kv29LWw' # staging
|
||||
config.twitter.app_secret = 'ZjLl7rtagTozYDuKKyZNtaTQ4aGFmZPVCO8EoUJmg' # staging
|
||||
end
|
||||
|
|
|
|||
|
|
@ -62,5 +62,8 @@ SampleApp::Application.configure do
|
|||
|
||||
config.facebook_app_id = '1441492266082868'
|
||||
config.facebook_app_secret = '233bd040a07e47dcec1cff3e490bfce7'
|
||||
|
||||
config.twitter_app_id = 'e7hGc71gmcBgo6Wvdta6Sg'
|
||||
config.twitter_app_secret = 'PfG1jAUMnyrimPcDooUVQaJrG1IuDjUyGg5KciOo'
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
Gon.global.facebook_app_id = Rails.application.config.facebook_app_id
|
||||
|
|
@ -1,5 +1,10 @@
|
|||
Rails.application.config.middleware.use OmniAuth::Builder do
|
||||
provider :facebook, Rails.application.config.facebook_app_id, Rails.application.config.facebook_app_secret, {name: "facebook", :scope => 'email,user_location'}
|
||||
provider :google_oauth2, Rails.application.config.google_client_id, Rails.application.config.google_secret, {name: "google_login", approval_prompt: '', scope: 'userinfo.email, userinfo.profile, https://www.google.com/m8/feeds'}
|
||||
provider :facebook, Rails.application.config.facebook_app_id, Rails.application.config.facebook_app_secret, {name: "facebook", :scope => 'email,user_location'}
|
||||
provider :google_oauth2, Rails.application.config.google_client_id, Rails.application.config.google_secret, {name: "google_login", approval_prompt: '', scope: 'userinfo.email, userinfo.profile, https://www.google.com/m8/feeds'}
|
||||
provider :twitter, Rails.application.config.twitter_app_id, Rails.application.config.twitter_app_secret, {x_auth_access_type: 'write' }
|
||||
end
|
||||
|
||||
# https://github.com/intridea/omniauth/wiki/FAQ
|
||||
OmniAuth.config.on_failure = Proc.new { |env|
|
||||
OmniAuth::FailureEndpoint.new(env).redirect_to_failure
|
||||
}
|
||||
|
|
@ -64,6 +64,9 @@ SampleApp::Application.routes.draw do
|
|||
match '/gmail_contacts', to: 'spikes#gmail_contacts'
|
||||
match '/listen_in', to: 'spikes#listen_in'
|
||||
|
||||
# share tokens
|
||||
match '/s/:id', to: 'share_tokens#shareable_resolver', :as => 'share_token'
|
||||
|
||||
# password reset
|
||||
match '/request_reset_password' => 'users#request_reset_password', :via => :get
|
||||
match '/reset_password' => 'users#reset_password', :via => :post
|
||||
|
|
@ -215,6 +218,10 @@ SampleApp::Application.routes.draw do
|
|||
match '/users/progression/certified_gear' => 'api_users#qualified_gear', :via => :post
|
||||
match '/users/progression/social_promoted' => 'api_users#social_promoted', :via => :post
|
||||
|
||||
# social
|
||||
match '/users/:id/share/session/:provider' => 'api_users#share_session', :via => :get
|
||||
match '/users/:id/share/recording/:provider' => 'api_users#share_recording', :via => :get
|
||||
|
||||
# user recordings
|
||||
# match '/users/:id/recordings' => 'api_users#recording_index', :via => :get
|
||||
# match '/users/:id/recordings/:recording_id' => 'api_users#recording_show', :via => :get, :as => 'api_recording_detail'
|
||||
|
|
@ -336,6 +343,8 @@ SampleApp::Application.routes.draw do
|
|||
match '/icecast/mount_remove' => 'api_icecast#mount_remove', :via => :post
|
||||
match '/icecast/listener_add' => 'api_icecast#listener_add', :via => :post
|
||||
match '/icecast/listener_remove' => 'api_icecast#listener_remove', :via => :post
|
||||
|
||||
match '/twitter/tweet' => 'api_twitters#tweet', :via => :post
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,4 +10,4 @@ pre-start script
|
|||
chown jam-web:jam-web /var/run/jam-web
|
||||
end script
|
||||
|
||||
exec start-stop-daemon --start --chuid jam-web:jam-web --chdir /var/lib/jam-web --exec /var/lib/jam-web/script/package/upstart-run.sh
|
||||
exec start-stop-daemon --start --chuid jam-web:jam-web --chdir /var/lib/jam-web --exec /var/lib/jam-web/script/package/upstart-run.sh
|
||||
|
|
@ -2,7 +2,9 @@ require 'spec_helper'
|
|||
|
||||
describe SessionsController do
|
||||
render_views
|
||||
|
||||
|
||||
let(:user) { FactoryGirl.create(:user) }
|
||||
|
||||
describe "GET 'new'" do
|
||||
it "should work" do
|
||||
get :new
|
||||
|
|
@ -36,40 +38,81 @@ describe SessionsController do
|
|||
end
|
||||
|
||||
describe "create_oauth" do
|
||||
|
||||
before(:each) do
|
||||
OmniAuth.config.mock_auth[:facebook] = OmniAuth::AuthHash.new({
|
||||
'uid' => '100',
|
||||
'provider' => 'facebook',
|
||||
'info' => {
|
||||
'first_name' => 'FirstName',
|
||||
'last_name' => 'LastName',
|
||||
'email' => 'test_oauth@example.com',
|
||||
'location' => 'mylocation'
|
||||
},
|
||||
'credentials' => {
|
||||
'token' => 'facebooktoken',
|
||||
'expires_at' => 1000000000
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
describe "twitter" do
|
||||
|
||||
|
||||
before(:each) do
|
||||
|
||||
OmniAuth.config.mock_auth[:twitter] = OmniAuth::AuthHash.new({
|
||||
'uid' => '100',
|
||||
'provider' => 'twitter',
|
||||
'credentials' => {
|
||||
'token' => 'twittertoken',
|
||||
'secret' => 'twittersecret'
|
||||
}
|
||||
})
|
||||
|
||||
end
|
||||
|
||||
it "should update user_authorization for existing user" do
|
||||
cookie_jar[:remember_token] = user.remember_token # controller.current_user is not working. i think because of omniauth
|
||||
request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:twitter]
|
||||
visit '/auth/twitter'
|
||||
user.reload
|
||||
auth = user.user_authorization('twitter')
|
||||
auth.uid.should == '100'
|
||||
auth.token.should == 'twittertoken'
|
||||
auth.secret.should == 'twittersecret'
|
||||
|
||||
# also verify that a second visit does *not* create another new user
|
||||
visit '/auth/twitter'
|
||||
|
||||
user.reload
|
||||
auth = user.user_authorization('twitter')
|
||||
auth.uid.should == '100'
|
||||
auth.token.should == 'twittertoken'
|
||||
auth.secret.should == 'twittersecret'
|
||||
end
|
||||
end
|
||||
|
||||
it "should create a user when oauth comes in with a non-currently existing user" do
|
||||
pending "needs this fixed: https://jamkazam.atlassian.net/browse/VRFS-271"
|
||||
request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:facebook]
|
||||
lambda do
|
||||
visit '/auth/facebook'
|
||||
end.should change(User, :count).by(1)
|
||||
user = User.find_by_email('test_oauth@example.com')
|
||||
user.should_not be_nil
|
||||
user.first_name.should == "FirstName"
|
||||
response.should be_success
|
||||
|
||||
# also verify that a second visit does *not* create another new user
|
||||
lambda do
|
||||
visit '/auth/facebook'
|
||||
end.should change(User, :count).by(0)
|
||||
|
||||
describe "facebook" do
|
||||
before(:each) do
|
||||
OmniAuth.config.mock_auth[:facebook] = OmniAuth::AuthHash.new({
|
||||
'uid' => '100',
|
||||
'provider' => 'facebook',
|
||||
'info' => {
|
||||
'first_name' => 'FirstName',
|
||||
'last_name' => 'LastName',
|
||||
'email' => 'test_oauth@example.com',
|
||||
'location' => 'mylocation'
|
||||
},
|
||||
'credentials' => {
|
||||
'token' => 'facebooktoken',
|
||||
'expires_at' => 1000000000
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
it "should create a user when oauth comes in with a non-currently existing user" do
|
||||
pending "needs this fixed: https://jamkazam.atlassian.net/browse/VRFS-271"
|
||||
request.env["omniauth.auth"] = OmniAuth.config.mock_auth[:facebook]
|
||||
lambda do
|
||||
visit '/auth/facebook'
|
||||
end.should change(User, :count).by(1)
|
||||
user = User.find_by_email('test_oauth@example.com')
|
||||
user.should_not be_nil
|
||||
user.first_name.should == "FirstName"
|
||||
response.should be_success
|
||||
|
||||
# also verify that a second visit does *not* create another new user
|
||||
lambda do
|
||||
visit '/auth/facebook'
|
||||
end.should change(User, :count).by(0)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe ShareTokensController do
|
||||
render_views
|
||||
|
||||
let(:user) { FactoryGirl.create(:user) }
|
||||
let(:music_session) {FactoryGirl.create(:music_session, creator: user) }
|
||||
let(:claimed_recording) {FactoryGirl.create(:claimed_recording) }
|
||||
|
||||
it "resolves music session" do
|
||||
music_session.touch
|
||||
get :shareable_resolver, :id => music_session.music_session_history.share_token.token
|
||||
|
||||
location_header = response.headers["Location"]
|
||||
location_header.should == music_session_detail_url(music_session.id)
|
||||
|
||||
end
|
||||
|
||||
it "resolves claimed recording" do
|
||||
claimed_recording.touch
|
||||
get :shareable_resolver, :id => claimed_recording.share_token.token
|
||||
|
||||
location_header = response.headers["Location"]
|
||||
location_header.should == recording_detail_url(claimed_recording.id)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -60,12 +60,14 @@ FactoryGirl.define do
|
|||
musician_access true
|
||||
legal_terms true
|
||||
genres [JamRuby::Genre.first]
|
||||
association :creator, :factory => :user
|
||||
|
||||
after(:create) { |session|
|
||||
MusicSessionHistory.save(session)
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
factory :music_session_user_history, :class => JamRuby::MusicSessionUserHistory do
|
||||
end
|
||||
|
||||
|
|
@ -119,20 +121,52 @@ FactoryGirl.define do
|
|||
priority 0
|
||||
end
|
||||
|
||||
factory :recording, :class => JamRuby::Recording do
|
||||
|
||||
end
|
||||
|
||||
factory :track, :class => JamRuby::Track do
|
||||
sound "mono"
|
||||
sequence(:client_track_id) { |n| "client_track_id_seq_#{n}"}
|
||||
|
||||
end
|
||||
|
||||
|
||||
factory :recorded_track, :class => JamRuby::RecordedTrack do
|
||||
instrument JamRuby::Instrument.first
|
||||
sound 'stereo'
|
||||
sequence(:client_id) { |n| "client_id-#{n}"}
|
||||
sequence(:track_id) { |n| "track_id-#{n}"}
|
||||
sequence(:client_track_id) { |n| "client_track_id-#{n}"}
|
||||
md5 'abc'
|
||||
length 1
|
||||
fully_uploaded true
|
||||
association :user, factory: :user
|
||||
association :recording, factory: :recording
|
||||
end
|
||||
|
||||
factory :recording, :class => JamRuby::Recording do
|
||||
|
||||
association :owner, factory: :user
|
||||
association :music_session, factory: :music_session
|
||||
|
||||
factory :recording_with_track do
|
||||
before(:create) { |recording|
|
||||
recording.recorded_tracks << FactoryGirl.create(:recorded_track, recording: recording, user: recording.owner)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
factory :claimed_recording, :class => JamRuby::ClaimedRecording do
|
||||
sequence(:name) { |n| "name-#{n}" }
|
||||
sequence(:description) { |n| "description-#{n}" }
|
||||
is_public true
|
||||
is_downloadable true
|
||||
association :genre, factory: :genre
|
||||
association :user, factory: :user
|
||||
|
||||
before(:create) { |claimed_recording|
|
||||
claimed_recording.recording = FactoryGirl.create(:recording_with_track, owner: claimed_recording.user)
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
|
||||
factory :geocoder, :class => JamRuby::MaxMindGeo do
|
||||
country 'US'
|
||||
sequence(:region) { |n| ['NC', 'CA'][(n-1).modulo(2)] }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,115 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe "social metadata" do
|
||||
|
||||
include MusicSessionHelper
|
||||
include RecordingHelper
|
||||
|
||||
|
||||
subject { page }
|
||||
|
||||
|
||||
|
||||
share_examples_for :has_default_metadata do
|
||||
it "should have default metadata" do
|
||||
page.find('meta[property="fb:app_id"]', :visible => false)['content'].should == Rails.application.config.facebook_app_id
|
||||
page.find('meta[property="og:title"]', :visible => false)['content'].should == "JamKazam"
|
||||
page.find('meta[property="og:description"]', :visible => false)['content'].should == "Play music together over the Internet as if in the same room."
|
||||
page.find('meta[property="og:image"]', :visible => false)['content'].include?("/assets/web/logo-256.png").should be_true
|
||||
page.find('meta[property="og:image:width"]', :visible => false)['content'].should == "256"
|
||||
page.find('meta[property="og:image:height"]', :visible => false)['content'].should == "256"
|
||||
page.find('meta[property="og:type"]', :visible => false)['content'].should == "website"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
describe "default layout metadata" do
|
||||
let(:user) {FactoryGirl.create(:user) }
|
||||
|
||||
describe "web layout" do
|
||||
before(:each) do
|
||||
visit '/'
|
||||
end
|
||||
it_behaves_like :has_default_metadata
|
||||
end
|
||||
|
||||
describe "corp layout" do
|
||||
before(:each) do
|
||||
visit '/corp/about'
|
||||
end
|
||||
it_behaves_like :has_default_metadata
|
||||
end
|
||||
|
||||
describe "client layout" do
|
||||
before(:each) do
|
||||
sign_in user
|
||||
visit '/client'
|
||||
end
|
||||
it_behaves_like :has_default_metadata
|
||||
end
|
||||
|
||||
describe "landing layout" do
|
||||
before(:each) do
|
||||
visit '/signin'
|
||||
end
|
||||
it_behaves_like :has_default_metadata
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
describe "music session metadata" do
|
||||
|
||||
let(:user) { FactoryGirl.create(:user) }
|
||||
let(:connection) { FactoryGirl.create(:connection, :user => user) }
|
||||
let(:instrument) { FactoryGirl.create(:instrument, :description => 'a great instrument') }
|
||||
let(:track) { FactoryGirl.create(:track, :connection => connection, :instrument => instrument) }
|
||||
let(:music_session) { ms = FactoryGirl.create(:music_session, :creator => user, :musician_access => true); ms.connections << connection; ms.save!; ms }
|
||||
|
||||
it "renders facebook metadata" do
|
||||
visit "/sessions/#{music_session.id}"
|
||||
|
||||
page.find('meta[property="fb:app_id"]', :visible => false)['content'].should == Rails.application.config.facebook_app_id
|
||||
page.find('meta[property="og:title"]', :visible => false)['content'].should == title_for_music_session_history(music_session.music_session_history)
|
||||
page.find('meta[property="og:url"]', :visible => false)['content'].include?("/sessions/#{music_session.id}").should be_true
|
||||
page.find('meta[property="og:description"]', :visible => false)['content'].should == music_session.music_session_history.description
|
||||
page.find('meta[property="og:image"]', :visible => false)['content'].include?("/assets/web/logo-256.png").should be_true
|
||||
page.find('meta[property="og:image:width"]', :visible => false)['content'].should == "256"
|
||||
page.find('meta[property="og:image:height"]', :visible => false)['content'].should == "256"
|
||||
page.find('meta[property="og:type"]', :visible => false)['content'].should == "website"
|
||||
end
|
||||
end
|
||||
|
||||
describe "recording metadata" do
|
||||
|
||||
before(:each) do
|
||||
@user = FactoryGirl.create(:user)
|
||||
@connection = FactoryGirl.create(:connection, :user => @user)
|
||||
@instrument = FactoryGirl.create(:instrument, :description => 'a great instrument')
|
||||
@track = FactoryGirl.create(:track, :connection => @connection, :instrument => @instrument)
|
||||
@music_session = FactoryGirl.create(:music_session, :creator => @user, :musician_access => true)
|
||||
@music_session.connections << @connection
|
||||
@music_session.save
|
||||
@recording = Recording.start(@music_session, @user)
|
||||
@recording.stop
|
||||
@recording.reload
|
||||
@genre = FactoryGirl.create(:genre)
|
||||
@recording.claim(@user, "name", "description", @genre, true, true)
|
||||
@recording.reload
|
||||
@claimed_recording = @recording.claimed_recordings.first
|
||||
end
|
||||
|
||||
it "renders facebook metadata" do
|
||||
visit "/recordings/#{@claimed_recording.id}"
|
||||
|
||||
page.find('meta[property="fb:app_id"]', :visible => false)['content'].should == Rails.application.config.facebook_app_id
|
||||
page.find('meta[property="og:title"]', :visible => false)['content'].should == title_for_claimed_recording(@claimed_recording)
|
||||
page.find('meta[property="og:url"]', :visible => false)['content'].include?("/recordings/#{@claimed_recording.id}").should be_true
|
||||
page.find('meta[property="og:description"]', :visible => false)['content'].should == @claimed_recording.name
|
||||
page.find('meta[property="og:image"]', :visible => false)['content'].include?("/assets/web/logo-256.png").should be_true
|
||||
page.find('meta[property="og:image:width"]', :visible => false)['content'].should == "256"
|
||||
page.find('meta[property="og:image:height"]', :visible => false)['content'].should == "256"
|
||||
page.find('meta[property="og:type"]', :visible => false)['content'].should == "website"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe "Welcome", :js => true, :type => :feature, :capybara_feature => true do
|
||||
|
||||
subject { page }
|
||||
|
||||
before(:all) do
|
||||
Capybara.javascript_driver = :poltergeist
|
||||
Capybara.current_driver = Capybara.javascript_driver
|
||||
Capybara.default_wait_time = 10
|
||||
end
|
||||
|
||||
let(:user) { FactoryGirl.create(:user, email: 'twitter_user1@jamkazam.com') }
|
||||
let(:user2) { FactoryGirl.create(:user, email: 'twitter_user2@jamkazam.com') }
|
||||
let(:twitter_auth) {
|
||||
{ :provider => "twitter",
|
||||
:uid => "1234",
|
||||
:credentials => {:token => "twitter_token", :secret => 'twitter_secret'} }
|
||||
}
|
||||
|
||||
|
||||
before(:each) do
|
||||
|
||||
OmniAuth.config.mock_auth[:twitter] = OmniAuth::AuthHash.new(twitter_auth)
|
||||
User.where(email: 'twitter_user1@jamkazam.com').delete_all
|
||||
User.where(email: 'twitter_user2@jamkazam.com').delete_all
|
||||
|
||||
page.driver.headers = { 'User-Agent' => ' JamKazam ' }
|
||||
sign_in_poltergeist user
|
||||
visit "/"
|
||||
find('h1', text: 'Play music together over the Internet as if in the same room')
|
||||
end
|
||||
|
||||
it "redirects back when done, and updates user_auth" do
|
||||
visit '/auth/twitter'
|
||||
find('h1', text: 'Play music together over the Internet as if in the same room')
|
||||
sleep 1
|
||||
user.reload
|
||||
auth = user.user_authorization('twitter')
|
||||
auth.should_not be_nil
|
||||
auth.uid.should == '1234'
|
||||
auth.token.should == 'twitter_token'
|
||||
auth.secret.should == 'twitter_secret'
|
||||
|
||||
visit '/auth/twitter'
|
||||
find('h1', text: 'Play music together over the Internet as if in the same room')
|
||||
user.reload
|
||||
auth = user.user_authorization('twitter')
|
||||
auth.uid.should == '1234'
|
||||
auth.token.should == 'twitter_token'
|
||||
auth.secret.should == 'twitter_secret'
|
||||
end
|
||||
|
||||
it "shows error when two users try to auth same twitter account" do
|
||||
visit '/auth/twitter'
|
||||
find('h1', text: 'Play music together over the Internet as if in the same room')
|
||||
sleep 1
|
||||
user.reload
|
||||
auth = user.user_authorization('twitter')
|
||||
auth.uid.should == '1234'
|
||||
|
||||
sign_in_poltergeist user2
|
||||
visit '/'
|
||||
find('h1', text: 'Play music together over the Internet as if in the same room')
|
||||
visit '/auth/twitter'
|
||||
find('li', text: 'This twitter account is already associated with someone else')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue