livestream beta commit
This commit is contained in:
parent
9691d815cd
commit
b9681fd418
|
|
@ -64,7 +64,7 @@ gem 'resque-lonely_job', '~> 1.0.0'
|
||||||
gem 'eventmachine', '1.2.3'
|
gem 'eventmachine', '1.2.3'
|
||||||
gem 'amqp', '0.9.8'
|
gem 'amqp', '0.9.8'
|
||||||
#gem 'logging-rails', :require => 'logging/rails'
|
#gem 'logging-rails', :require => 'logging/rails'
|
||||||
gem 'pg_migrate'
|
gem 'pg_migrate', '0.1.14'
|
||||||
gem 'ruby-protocol-buffers', '1.2.2'
|
gem 'ruby-protocol-buffers', '1.2.2'
|
||||||
gem 'sendgrid', '1.2.0'
|
gem 'sendgrid', '1.2.0'
|
||||||
gem 'geokit-rails'
|
gem 'geokit-rails'
|
||||||
|
|
@ -84,7 +84,7 @@ gem 'stripe'
|
||||||
gem 'zip-codes'
|
gem 'zip-codes'
|
||||||
gem 'email_validator'
|
gem 'email_validator'
|
||||||
gem 'best_in_place' #, github: 'bernat/best_in_place'
|
gem 'best_in_place' #, github: 'bernat/best_in_place'
|
||||||
|
gem 'auto_strip_attributes', '2.6.0'
|
||||||
|
|
||||||
|
|
||||||
#group :libv8 do
|
#group :libv8 do
|
||||||
|
|
@ -126,9 +126,9 @@ end
|
||||||
group :test do
|
group :test do
|
||||||
gem 'simplecov', '~> 0.7.1'
|
gem 'simplecov', '~> 0.7.1'
|
||||||
gem 'simplecov-rcov'
|
gem 'simplecov-rcov'
|
||||||
gem 'capybara-webkit'
|
# gem 'capybara-webkit'
|
||||||
gem 'capybara-screenshot', '0.3.22' # 1.0.0 broke compat with rspec. maybe we need newer rspec
|
# gem 'capybara-screenshot', '0.3.22' # 1.0.0 broke compat with rspec. maybe we need newer rspec
|
||||||
gem 'poltergeist'
|
# gem 'poltergeist'
|
||||||
end
|
end
|
||||||
|
|
||||||
gem 'pry'
|
gem 'pry'
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,8 @@ GEM
|
||||||
arel (6.0.4)
|
arel (6.0.4)
|
||||||
arr-pm (0.0.10)
|
arr-pm (0.0.10)
|
||||||
cabin (> 0)
|
cabin (> 0)
|
||||||
|
auto_strip_attributes (2.6.0)
|
||||||
|
activerecord (>= 4.0)
|
||||||
aws-sdk (1.67.0)
|
aws-sdk (1.67.0)
|
||||||
aws-sdk-v1 (= 1.67.0)
|
aws-sdk-v1 (= 1.67.0)
|
||||||
aws-sdk-v1 (1.67.0)
|
aws-sdk-v1 (1.67.0)
|
||||||
|
|
@ -114,13 +116,6 @@ GEM
|
||||||
rack (>= 1.0.0)
|
rack (>= 1.0.0)
|
||||||
rack-test (>= 0.5.4)
|
rack-test (>= 0.5.4)
|
||||||
xpath (~> 2.0)
|
xpath (~> 2.0)
|
||||||
capybara-screenshot (0.3.22)
|
|
||||||
capybara (>= 1.0, < 3)
|
|
||||||
colored
|
|
||||||
launchy
|
|
||||||
capybara-webkit (1.14.0)
|
|
||||||
capybara (>= 2.3.0, < 2.14.0)
|
|
||||||
json
|
|
||||||
carrierwave (0.11.2)
|
carrierwave (0.11.2)
|
||||||
activemodel (>= 3.2.0)
|
activemodel (>= 3.2.0)
|
||||||
activesupport (>= 3.2.0)
|
activesupport (>= 3.2.0)
|
||||||
|
|
@ -134,7 +129,6 @@ GEM
|
||||||
childprocess (0.8.0)
|
childprocess (0.8.0)
|
||||||
ffi (~> 1.0, >= 1.0.11)
|
ffi (~> 1.0, >= 1.0.11)
|
||||||
clamp (1.0.1)
|
clamp (1.0.1)
|
||||||
cliver (0.3.2)
|
|
||||||
cocoon (1.2.11)
|
cocoon (1.2.11)
|
||||||
coderay (1.1.2)
|
coderay (1.1.2)
|
||||||
coffee-rails (4.2.2)
|
coffee-rails (4.2.2)
|
||||||
|
|
@ -144,7 +138,6 @@ GEM
|
||||||
coffee-script-source
|
coffee-script-source
|
||||||
execjs
|
execjs
|
||||||
coffee-script-source (1.12.2)
|
coffee-script-source (1.12.2)
|
||||||
colored (1.2)
|
|
||||||
concurrent-ruby (1.0.5)
|
concurrent-ruby (1.0.5)
|
||||||
country-select (1.1.1)
|
country-select (1.1.1)
|
||||||
crass (1.0.3)
|
crass (1.0.3)
|
||||||
|
|
@ -403,10 +396,6 @@ GEM
|
||||||
insist
|
insist
|
||||||
mustache (= 0.99.8)
|
mustache (= 0.99.8)
|
||||||
stud
|
stud
|
||||||
poltergeist (1.17.0)
|
|
||||||
capybara (~> 2.1)
|
|
||||||
cliver (~> 0.3.1)
|
|
||||||
websocket-driver (>= 0.2.0)
|
|
||||||
polyamorous (1.3.3)
|
polyamorous (1.3.3)
|
||||||
activerecord (>= 3.0)
|
activerecord (>= 3.0)
|
||||||
postgres-copy (0.6.0)
|
postgres-copy (0.6.0)
|
||||||
|
|
@ -610,9 +599,6 @@ GEM
|
||||||
rack (>= 1.0.0)
|
rack (>= 1.0.0)
|
||||||
warden (1.2.7)
|
warden (1.2.7)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
websocket-driver (0.7.0)
|
|
||||||
websocket-extensions (>= 0.1.0)
|
|
||||||
websocket-extensions (0.1.3)
|
|
||||||
will_paginate (3.1.6)
|
will_paginate (3.1.6)
|
||||||
xdan-datetimepicker-rails (2.5.4)
|
xdan-datetimepicker-rails (2.5.4)
|
||||||
jquery-rails
|
jquery-rails
|
||||||
|
|
@ -629,6 +615,7 @@ DEPENDENCIES
|
||||||
activeadmin
|
activeadmin
|
||||||
activeadmin_addons
|
activeadmin_addons
|
||||||
amqp (= 0.9.8)
|
amqp (= 0.9.8)
|
||||||
|
auto_strip_attributes (= 2.6.0)
|
||||||
aws-sdk (~> 1)
|
aws-sdk (~> 1)
|
||||||
bcrypt-ruby (= 3.0.1)
|
bcrypt-ruby (= 3.0.1)
|
||||||
best_in_place
|
best_in_place
|
||||||
|
|
@ -636,8 +623,6 @@ DEPENDENCIES
|
||||||
bootstrap-will_paginate (= 0.0.6)
|
bootstrap-will_paginate (= 0.0.6)
|
||||||
bugsnag
|
bugsnag
|
||||||
capybara
|
capybara
|
||||||
capybara-screenshot (= 0.3.22)
|
|
||||||
capybara-webkit
|
|
||||||
carrierwave (= 0.11.2)
|
carrierwave (= 0.11.2)
|
||||||
carrierwave_direct
|
carrierwave_direct
|
||||||
cocoon
|
cocoon
|
||||||
|
|
@ -669,8 +654,7 @@ DEPENDENCIES
|
||||||
launchy
|
launchy
|
||||||
mime-types (= 1.25)
|
mime-types (= 1.25)
|
||||||
net-ssh
|
net-ssh
|
||||||
pg_migrate
|
pg_migrate (= 0.1.14)
|
||||||
poltergeist
|
|
||||||
postgres-copy (= 0.6.0)
|
postgres-copy (= 0.6.0)
|
||||||
postgres_ext
|
postgres_ext
|
||||||
protected_attributes
|
protected_attributes
|
||||||
|
|
@ -708,4 +692,4 @@ DEPENDENCIES
|
||||||
zip-codes
|
zip-codes
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
1.13.7
|
1.17.1
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
ActiveAdmin.register JamRuby::EventBriteOrder, :as => 'EventBriteOrder' do
|
||||||
|
menu :parent => 'Misc'
|
||||||
|
|
||||||
|
config.sort_order = 'created_at DESC'
|
||||||
|
|
||||||
|
filter :live_stream
|
||||||
|
filter :email
|
||||||
|
filter :order_id
|
||||||
|
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
ActiveAdmin.register_page "EventBriteOrderUploads" do
|
||||||
|
|
||||||
|
menu :label => 'Event Brite Order Upload', :parent => 'Misc'
|
||||||
|
|
||||||
|
page_action :upload_eventbriteorders, :method => :post do
|
||||||
|
EventBriteOrder.transaction do
|
||||||
|
|
||||||
|
puts params
|
||||||
|
|
||||||
|
|
||||||
|
live_stream = LiveStream.find_by_id!(params[:jam_ruby_event_brite_order][:live_stream_id])
|
||||||
|
|
||||||
|
file = params[:jam_ruby_event_brite_order][:csv]
|
||||||
|
|
||||||
|
upload = EventBriteOrderUpload.new
|
||||||
|
upload.upload_file_name = file.original_filename
|
||||||
|
upload.save!
|
||||||
|
|
||||||
|
array_of_arrays = CSV.read(file.tempfile.path, headers:true)
|
||||||
|
array_of_arrays.each do |row|
|
||||||
|
order_id = row['Order ID']
|
||||||
|
|
||||||
|
event_brite_order = EventBriteOrder.find_by_order_id(order_id)
|
||||||
|
if event_brite_order.nil?
|
||||||
|
event_brite_order = EventBriteOrder.new
|
||||||
|
end
|
||||||
|
event_brite_order.event_brite_order_upload = upload
|
||||||
|
event_brite_order.live_stream = live_stream
|
||||||
|
event_brite_order.event_name = row['Event Name']
|
||||||
|
event_brite_order.order_id = order_id
|
||||||
|
event_brite_order.ticket_count = row['Tickets']
|
||||||
|
event_brite_order.ticket_type = row['Type']
|
||||||
|
event_brite_order.first_name = row['First Name']
|
||||||
|
event_brite_order.last_name = row['Last Name']
|
||||||
|
event_brite_order.email = row['Email Address']
|
||||||
|
event_brite_order.save!
|
||||||
|
end
|
||||||
|
|
||||||
|
redirect_to admin_eventbriteorderuploads_path, :notice => "Created #{array_of_arrays.length} event brite orders!"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
content do
|
||||||
|
active_admin_form_for EventBriteOrder.new, :url => admin_eventbriteorderuploads_upload_eventbriteorders_path, :builder => ActiveAdmin::FormBuilder do |f|
|
||||||
|
f.inputs "Upload Event Brite Orders" do
|
||||||
|
f.input :csv, as: :file, required: true, :label => "An event brite order CSV exactly as exported from Eventbrite"
|
||||||
|
f.input :live_stream, required:true, as: :select, :collection => LiveStream.upcoming
|
||||||
|
end
|
||||||
|
f.actions
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
ActiveAdmin.register JamRuby::LiveStream, :as => 'LiveStream' do
|
||||||
|
menu :parent => 'Misc'
|
||||||
|
|
||||||
|
config.sort_order = 'created_at DESC'
|
||||||
|
|
||||||
|
filter :listed
|
||||||
|
filter :event_id
|
||||||
|
|
||||||
|
before_build do |record|
|
||||||
|
if !record.event_type.nil?
|
||||||
|
puts "escape"
|
||||||
|
else
|
||||||
|
record.slug = 'please-do-this-sort-of-thing'
|
||||||
|
record.starts_at = 10.days.from_now.midnight
|
||||||
|
record.ends_at = 11.days.from_now.midnight
|
||||||
|
record.img_width = 200
|
||||||
|
record.event_type = 'eventbrite'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
@ -30,3 +30,11 @@
|
||||||
border:1px solid gray;
|
border:1px solid gray;
|
||||||
padding:5px;
|
padding:5px;
|
||||||
}
|
}
|
||||||
|
.datetime_select li.fragment {
|
||||||
|
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: block;
|
||||||
|
width:auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -391,3 +391,4 @@ limit_counter_reminders.sql
|
||||||
amazon_v2.sql
|
amazon_v2.sql
|
||||||
store_backend_details_rate_session.sql
|
store_backend_details_rate_session.sql
|
||||||
invited_user_receiver.sql
|
invited_user_receiver.sql
|
||||||
|
live_streams.sql
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
CREATE TABLE live_streams (
|
||||||
|
id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||||
|
slug VARCHAR(512) NOT NULL UNIQUE,
|
||||||
|
title TEXT,
|
||||||
|
description TEXT,
|
||||||
|
social_description TEXT,
|
||||||
|
listed BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
|
starts_at TIMESTAMP,
|
||||||
|
ends_at TIMESTAMP,
|
||||||
|
img_url VARCHAR(1024),
|
||||||
|
img_width INTEGER,
|
||||||
|
img_height INTEGER,
|
||||||
|
youtube_code VARCHAR(1024),
|
||||||
|
eventbriteid VARCHAR(1024),
|
||||||
|
event_type VARCHAR(100),
|
||||||
|
event_brite_registration_url VARCHAR(1024),
|
||||||
|
allow_in BOOLEAN NOT NULL DEFAULT FALSE,
|
||||||
|
white_label_player BOOLEAN NOT NULL DEFAULT TRUE,
|
||||||
|
user_id VARCHAR(64) REFERENCES users(id) ON DELETE SET NULL,
|
||||||
|
band_id VARCHAR(64) REFERENCES bands(id) ON DELETE SET NULL,
|
||||||
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE event_brite_orders (
|
||||||
|
id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||||
|
live_stream_id VARCHAR(64) REFERENCES live_streams(id) ON DELETE CASCADE,
|
||||||
|
event_brite_order_upload_id VARCHAR(64) REFERENCES event_brite_order_uploads(id) ON DELETE CASCADE,
|
||||||
|
event_name VARCHAR(100) NOT NULL,
|
||||||
|
order_id VARCHAR(100) NOT NULL UNIQUE,
|
||||||
|
ticket_count INTEGER,
|
||||||
|
ticket_type VARCHAR(100),
|
||||||
|
first_name VARCHAR(100),
|
||||||
|
last_name VARCHAR(100),
|
||||||
|
email VARCHAR(200),
|
||||||
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
times_claimed INTEGER NOT NULL DEFAULT 0
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE event_brite_order_uploads (
|
||||||
|
id VARCHAR(64) PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||||
|
upload_file_name VARCHAR(500) NOT NULL,
|
||||||
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
@ -241,6 +241,9 @@ require "jam_ruby/models/jam_track_file"
|
||||||
require "jam_ruby/models/jam_track_mixdown"
|
require "jam_ruby/models/jam_track_mixdown"
|
||||||
require "jam_ruby/models/jam_track_mixdown_package"
|
require "jam_ruby/models/jam_track_mixdown_package"
|
||||||
require "jam_ruby/models/genre_jam_track"
|
require "jam_ruby/models/genre_jam_track"
|
||||||
|
require "jam_ruby/models/live_stream"
|
||||||
|
require "jam_ruby/models/event_brite_order"
|
||||||
|
require "jam_ruby/models/event_brite_order_upload"
|
||||||
require "jam_ruby/app/mailers/async_mailer"
|
require "jam_ruby/app/mailers/async_mailer"
|
||||||
require "jam_ruby/app/mailers/batch_mailer"
|
require "jam_ruby/app/mailers/batch_mailer"
|
||||||
require "jam_ruby/app/mailers/progress_mailer"
|
require "jam_ruby/app/mailers/progress_mailer"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
class JamRuby::EventBriteOrder < ActiveRecord::Base
|
||||||
|
|
||||||
|
|
||||||
|
belongs_to :live_stream, class_name: 'JamRuby::LiveStream'
|
||||||
|
belongs_to :event_brite_order_upload, class_name: 'JamRuby::EventBriteOrderUpload'
|
||||||
|
|
||||||
|
validates :event_name, presence: true
|
||||||
|
validates :order_id, presence: true
|
||||||
|
validates :ticket_count, presence: true
|
||||||
|
validates :ticket_type, presence: true
|
||||||
|
|
||||||
|
before_validation :sanitize
|
||||||
|
|
||||||
|
def sanitize
|
||||||
|
self.first_name.strip! if self.first_name
|
||||||
|
self.last_name.strip! if self.last_name
|
||||||
|
self.email.strip! if self.email
|
||||||
|
self.ticket_type.strip! if self.ticket_type
|
||||||
|
self.order_id.strip! if self.order_id
|
||||||
|
self.event_name.strip! if self.event_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
class JamRuby::EventBriteOrderUpload < ActiveRecord::Base
|
||||||
|
has_many :event_brite_orders, class_name: 'JamRuby::EventBriteOrder'
|
||||||
|
|
||||||
|
validates :upload_file_name, presence: true
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
class JamRuby::LiveStream < ActiveRecord::Base
|
||||||
|
|
||||||
|
attr_accessible :user_id, :band_id, :starts_at, :ends_at, :img_url, :slug, :title, :description, :listed, :allow_in, :white_label_player, :youtube_code, :eventbriteid, :event_type, :social_description, :event_brite_registration_url, as: :admin
|
||||||
|
|
||||||
|
#belongs_to :user, class_name: 'JamRuby::User'
|
||||||
|
#belongs_to :band, class_name: 'JamRuby::Band'
|
||||||
|
|
||||||
|
#validate :one_of_user_band
|
||||||
|
validates :slug, uniqueness: true, presence: true
|
||||||
|
|
||||||
|
before_validation :sanitize_active_admin
|
||||||
|
|
||||||
|
def ready_display
|
||||||
|
self.starts_at && self.ends_at && (self.user_id || self.band_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.upcoming
|
||||||
|
LiveStream.where(listed: true).where("starts_at > ?", 2.days.ago).order('starts_at DESC')
|
||||||
|
end
|
||||||
|
|
||||||
|
def sanitize_active_admin
|
||||||
|
self.img_url = nil if self.img_url == ''
|
||||||
|
self.user_id = nil if self.user_id == ''
|
||||||
|
self.band_id = nil if self.band_id == ''
|
||||||
|
self.social_description = nil if self.social_description == ''
|
||||||
|
end
|
||||||
|
|
||||||
|
def one_of_user_band
|
||||||
|
if band && user
|
||||||
|
errors.add(:user, 'specify band, or user. not both')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def admin_name
|
||||||
|
"#{title} EB:#{eventbriteid} #{starts_at}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
(function (context) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Javascript wrappers for the REST API
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var AuthorizedEventStorage = {}
|
||||||
|
context.JK = context.JK || {};
|
||||||
|
context.JK.AuthorizedEventStorage = AuthorizedEventStorage
|
||||||
|
|
||||||
|
var key = 'authorized_events'
|
||||||
|
|
||||||
|
AuthorizedEventStorage.storeAuthorizedEvent = (authorizedEvent) => {
|
||||||
|
console.log("storing authorized event", authorizedEvent)
|
||||||
|
var events = fetchFromStorage()
|
||||||
|
if(!events) {
|
||||||
|
events = {}
|
||||||
|
}
|
||||||
|
if(!events.list) {
|
||||||
|
events.list = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!authorizedEvent.event_id) {
|
||||||
|
console.error("no event_id on new event", authorizedEvent)
|
||||||
|
alert("Unable to store order (no event_id)! Please contact support@jamkazam.com.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(!authorizedEvent.order_id) {
|
||||||
|
console.error("no order_id on new event", authorizedEvent)
|
||||||
|
alert("Unable to store order (no order_id)! Please contact support@jamkazam.com.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
events.list[authorizedEvent.event_id] = authorizedEvent
|
||||||
|
|
||||||
|
try {
|
||||||
|
window.localStorage.setItem(key, JSON.stringify(events) )
|
||||||
|
}
|
||||||
|
catch(e) {
|
||||||
|
console.error("can't update localStorage")
|
||||||
|
alert("Could not update local storage ith order.\nPlease try a different browser. Please do not use incognito mode.")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthorizedEventStorage.locateEvent = (eventId) => {
|
||||||
|
var events = fetchFromStorage()
|
||||||
|
if(events && events.list) {
|
||||||
|
return events.list[eventId]
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log("no events found in storage")
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AuthorizedEventStorage.listAuthorizedEvents = () => {
|
||||||
|
var events = fetchFromStorage()
|
||||||
|
if(events) {
|
||||||
|
return events.list
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchFromStorage() {
|
||||||
|
var events = window.localStorage.getItem(key)
|
||||||
|
if(events){
|
||||||
|
try {
|
||||||
|
return JSON.parse(events)
|
||||||
|
}
|
||||||
|
catch(e){
|
||||||
|
console.log("events not parseable", events)
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})(window);
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
//= require ./jam_rest
|
||||||
|
//= require ./authorized_event_storage
|
||||||
|
//= require reflux
|
||||||
|
//= require react
|
||||||
|
//= require react_ujs
|
||||||
|
//= require react-init
|
||||||
|
//= require react-input-autosize
|
||||||
|
//= require react-select
|
||||||
|
//= require ./react-components
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
(function (context) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Javascript wrappers for the REST API
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var Rest2 = {}
|
||||||
|
context.JK = context.JK || {};
|
||||||
|
context.JK.Rest2 = Rest2
|
||||||
|
|
||||||
|
Rest2.listLiveStreams = () => {
|
||||||
|
return fetch('/api/live_streams', {
|
||||||
|
method: 'get',
|
||||||
|
credentials: 'same-origin', // include, *same-origin, omit
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Rest2.getLiveStream = (id) => {
|
||||||
|
return fetch('/api/live_streams/' + id, {
|
||||||
|
method: 'get',
|
||||||
|
credentials: 'same-origin', // include, *same-origin, omit
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
Rest2.authorizeLiveStream = (data) => {
|
||||||
|
return fetch('/api/live_streams/claim', {
|
||||||
|
method: 'post',
|
||||||
|
credentials: 'same-origin', // include, *same-origin, omit
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
cache: 'no-cache',
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})(window);
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
//= require_directory ./react-components/actions
|
||||||
|
//= require ./react-components/stores/EventStore
|
||||||
|
//= require_directory ./react-components
|
||||||
|
|
@ -0,0 +1,115 @@
|
||||||
|
context = window
|
||||||
|
EventActions = context.EventActions
|
||||||
|
|
||||||
|
context.EventList = React.createClass({
|
||||||
|
|
||||||
|
mixins: [Reflux.listenTo(EventStore, "onEventsChanged")],
|
||||||
|
|
||||||
|
events: null,
|
||||||
|
|
||||||
|
getInitialState: function () {
|
||||||
|
return {events: null}
|
||||||
|
},
|
||||||
|
|
||||||
|
componentDidMount: function () {
|
||||||
|
},
|
||||||
|
|
||||||
|
isModeYours: function() {
|
||||||
|
return this.props.mode == 'yours'
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function () {
|
||||||
|
return this.renderAll();
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
renderEvents() {
|
||||||
|
if(!this.state.events || this.state.events.length == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var items = []
|
||||||
|
|
||||||
|
|
||||||
|
var isModeYours = this.isModeYours();
|
||||||
|
for(var i = 0; i < this.state.events.length; i++) {
|
||||||
|
var event = this.state.events[i]
|
||||||
|
|
||||||
|
if(isModeYours && (!!event.authorization || event.allow_in) || !isModeYours && (!event.authorization && !event.allow_in)) {
|
||||||
|
|
||||||
|
var dynamic = null
|
||||||
|
var thumb = null
|
||||||
|
if(event.img_url) {
|
||||||
|
thumb = <img className="thumb" src={event.img_url} />
|
||||||
|
dynamic = 'event'
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dynamic = 'event no-image'
|
||||||
|
}
|
||||||
|
|
||||||
|
var title = event.title ? event.title : 'Missing event title'
|
||||||
|
title = <a className="title-link" href={"/events/" + event.slug}>{title}</a>
|
||||||
|
var when = event.starts_at ? new Date(event.starts_at).toLocaleString() : 'Unknown start time'
|
||||||
|
var item = <div className={dynamic} key={event.id}>
|
||||||
|
{thumb}
|
||||||
|
<div className="detail">
|
||||||
|
<div className="title">{title}</div>
|
||||||
|
<div className="when">{when}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
items.push(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return items
|
||||||
|
},
|
||||||
|
|
||||||
|
renderAll: function() {
|
||||||
|
var events = this.renderEvents()
|
||||||
|
var headerText = this.isModeYours() ? 'Your Registered Events' : 'All Upcoming Events'
|
||||||
|
|
||||||
|
if(!events || events.length == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(events) {
|
||||||
|
var response = <div className="EventList">
|
||||||
|
<div className="event-header">
|
||||||
|
{headerText}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="event-section">
|
||||||
|
{events}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return <div className="EventList">
|
||||||
|
<div className="event-header">
|
||||||
|
{headerText}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="event-section loading">
|
||||||
|
Loading ...
|
||||||
|
</div>
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onEventsChanged: function (allEvents) {
|
||||||
|
var scopedEvents = []
|
||||||
|
if(this.isModeYours()) {
|
||||||
|
allEvents.events.entries.forEach(function(event) {
|
||||||
|
if (event.authorization || event.allow_in) {
|
||||||
|
scopedEvents.push(event)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
scopedEvents = allEvents.events.entries
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.setState({events: scopedEvents})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,220 @@
|
||||||
|
context = window
|
||||||
|
EventActions = context.EventActions
|
||||||
|
|
||||||
|
context.EventPage = React.createClass({
|
||||||
|
|
||||||
|
mixins: [Reflux.listenTo(EventStore, "onEventsChanged")],
|
||||||
|
|
||||||
|
|
||||||
|
getInitialState: function () {
|
||||||
|
return {submitting: false, error: null, event: null}
|
||||||
|
},
|
||||||
|
|
||||||
|
parseSlug: function() {
|
||||||
|
var path = window.location.pathname
|
||||||
|
|
||||||
|
console.log("slug path: ", path)
|
||||||
|
|
||||||
|
var pathPart = path.substring('/events/'.length)
|
||||||
|
console.log("slug part", pathPart)
|
||||||
|
|
||||||
|
var query = pathPart.indexOf('?')
|
||||||
|
if(query > -1) {
|
||||||
|
var slug = pathPart.substring(0, query)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var slug = pathPart
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
console.log("slug", slug)
|
||||||
|
return slug;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
componentDidMount: function () {
|
||||||
|
EventActions.single(this.parseSlug())
|
||||||
|
// new Plyr('#video');
|
||||||
|
},
|
||||||
|
|
||||||
|
componentDidUpdate: function() {
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
authorizeDone: function(response) {
|
||||||
|
this.setState({submitting:false})
|
||||||
|
EventActions.addAuthorization(response)
|
||||||
|
},
|
||||||
|
|
||||||
|
authorizeFailed: function(e) {
|
||||||
|
if(e instanceof SyntaxError) {
|
||||||
|
this.setState({error: 'Server error. Please try again or contact support@jamkazam.com.'})
|
||||||
|
}
|
||||||
|
else if(e instanceof Error) {
|
||||||
|
this.setState({error: 'Please enter a valid Eventbrite Order ID'})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log("heheh", e)
|
||||||
|
}
|
||||||
|
this.setState({submitting:false})
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSubmit: function(event) {
|
||||||
|
var value = document.getElementById("order-input").value
|
||||||
|
if(value) {
|
||||||
|
context.JK.Rest2.authorizeLiveStream({order: value}).then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw Error(response.statusText);
|
||||||
|
}
|
||||||
|
return response.json()
|
||||||
|
}).then((response) => this.authorizeDone(response)).catch((jqXHR) => this.authorizeFailed(jqXHR))
|
||||||
|
this.setState({submitting: true, error:null})
|
||||||
|
}
|
||||||
|
event.preventDefault();
|
||||||
|
},
|
||||||
|
|
||||||
|
isErrored() {
|
||||||
|
return !!this.state.error
|
||||||
|
},
|
||||||
|
|
||||||
|
isReady() {
|
||||||
|
return !!this.state.event
|
||||||
|
},
|
||||||
|
|
||||||
|
isAuthorized() {
|
||||||
|
return this.state.event.authorization || this.state.event.allow_in
|
||||||
|
},
|
||||||
|
|
||||||
|
isNotAuthorized() {
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
|
||||||
|
videoCode() {
|
||||||
|
return this.state.event.youtube_code
|
||||||
|
},
|
||||||
|
|
||||||
|
title() {
|
||||||
|
return this.state.event.title ? this.state.event.title : 'Unknown title'
|
||||||
|
},
|
||||||
|
|
||||||
|
description() {
|
||||||
|
return this.state.event.description ? this.state.event.description : ''
|
||||||
|
},
|
||||||
|
|
||||||
|
startsAt() {
|
||||||
|
return this.state.event.starts_at? "Starts at " + new Date(this.state.event.starts_at).toLocaleString() : 'Unknown start time'
|
||||||
|
},
|
||||||
|
|
||||||
|
header() {
|
||||||
|
|
||||||
|
if(this.isErrored()) {
|
||||||
|
return <div className="header">
|
||||||
|
<div className="title">No event found.</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else if(this.isReady()) {
|
||||||
|
var title = this.title()
|
||||||
|
var description = this.description()
|
||||||
|
var startsAt = this.startsAt()
|
||||||
|
|
||||||
|
return <div className="header">
|
||||||
|
<div className="title">{title}</div>
|
||||||
|
<div className="description">{description}</div>
|
||||||
|
<div className="starts-at">{startsAt}</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return <div className="header">
|
||||||
|
<div className="title">Loading ...</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
body: function() {
|
||||||
|
var video = null
|
||||||
|
if(this.isErrored()) {
|
||||||
|
video = null
|
||||||
|
}
|
||||||
|
else if(this.isReady()) {
|
||||||
|
if(this.isAuthorized()) {
|
||||||
|
//video = <div id="player" className="video player">
|
||||||
|
// <div id="video" data-plyr-provider="youtube" data-plyr-embed-id={this.videoCode()}></div>
|
||||||
|
//</div>
|
||||||
|
|
||||||
|
var videoCode = this.videoCode()
|
||||||
|
if(videoCode) {
|
||||||
|
var src = "https://www.youtube.com/embed/" + this.videoCode() + "?modestbranding=true&autoplay=0&rel=0"
|
||||||
|
video = <div id="player">
|
||||||
|
<iframe src={src} frameBorder="0" style={ { position:"absolute", top:0,left:0,width:"100%", height:"100%"} } allow="accelerometer; encrypted-media; gyroscope; autoplay" allowFullScreen={true}></iframe>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
video = <div id="no-player" className="no-code"><div>No video yet</div></div>
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var notRegistered = <span className="no-register">You are not registered for this event!</span>
|
||||||
|
var onceDone = <li>Enter your EventBrite order code at the <a href="https://www.jamkazam.com/events" target="_blank"> JamKazam Event Registration</a> page when done registering.</li>
|
||||||
|
|
||||||
|
var eventBriteUrl = this.state.event.event_brite_registration_url
|
||||||
|
if(eventBriteUrl) {
|
||||||
|
var meat = <div>
|
||||||
|
{notRegistered}
|
||||||
|
<ol>
|
||||||
|
<li>Please register at <a target="_blank" href={eventBriteUrl}>EventBrite</a> to see this video</li>
|
||||||
|
{onceDone}
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var meat = <div>
|
||||||
|
{notRegistered}
|
||||||
|
<ol>
|
||||||
|
<li>Please find your event at <a target="_blank" href="https://www.eventbrite.com/d/online/jamkazam/">EventBrite</a> and register for this event.</li>
|
||||||
|
{onceDone}
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
video = <div id="no-player" className="no-code">
|
||||||
|
{meat}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
video = <div id="no-player"></div>
|
||||||
|
}
|
||||||
|
|
||||||
|
return video
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function () {
|
||||||
|
|
||||||
|
var header = this.header()
|
||||||
|
|
||||||
|
var body = this.body()
|
||||||
|
|
||||||
|
var response = <div className="EventPage">
|
||||||
|
<div id="header">
|
||||||
|
<div className="logo-holder"><img src="/assets/logo.png"/></div>
|
||||||
|
</div>
|
||||||
|
<div id="top-container">
|
||||||
|
{header}
|
||||||
|
</div>
|
||||||
|
<div className="listing">
|
||||||
|
{body}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
return response
|
||||||
|
},
|
||||||
|
|
||||||
|
onEventsChanged: function (allEvents) {
|
||||||
|
var event = null;
|
||||||
|
if(allEvents && allEvents.events && allEvents.events.entries && allEvents.events.entries.length > 0){
|
||||||
|
event = allEvents.events.entries[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("event change", event, allEvents)
|
||||||
|
this.setState({event: event, error:allEvents.events_error})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
context = window
|
||||||
|
EventActions = context.EventActions
|
||||||
|
|
||||||
|
context.EventsPage = React.createClass({
|
||||||
|
|
||||||
|
getInitialState: function () {
|
||||||
|
return {submitting: false, error: null}
|
||||||
|
},
|
||||||
|
|
||||||
|
componentDidMount: function () {
|
||||||
|
EventActions.refresh()
|
||||||
|
},
|
||||||
|
|
||||||
|
authorizeDone: function(response) {
|
||||||
|
this.setState({submitting:false})
|
||||||
|
EventActions.addAuthorization(response)
|
||||||
|
},
|
||||||
|
|
||||||
|
authorizeFailed: function(e) {
|
||||||
|
if(e instanceof SyntaxError) {
|
||||||
|
this.setState({error: 'Server error. Please try again or contact support@jamkazam.com.'})
|
||||||
|
}
|
||||||
|
else if(e instanceof Error) {
|
||||||
|
this.setState({error: 'Please enter a valid Eventbrite Order ID'})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log("heheh", e)
|
||||||
|
}
|
||||||
|
this.setState({submitting:false})
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSubmit: function(event) {
|
||||||
|
var value = document.getElementById("order-input").value
|
||||||
|
if(value) {
|
||||||
|
context.JK.Rest2.authorizeLiveStream({order: value}).then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw Error(response.statusText);
|
||||||
|
}
|
||||||
|
return response.json()
|
||||||
|
}).then((response) => this.authorizeDone(response)).catch((jqXHR) => this.authorizeFailed(jqXHR))
|
||||||
|
this.setState({submitting: true, error:null})
|
||||||
|
}
|
||||||
|
event.preventDefault();
|
||||||
|
},
|
||||||
|
render: function () {
|
||||||
|
|
||||||
|
var ctaButtonClasses = "cta-button"
|
||||||
|
if(this.state.submitting) {
|
||||||
|
ctaButtonClasses = ctaButtonClasses + " submitting"
|
||||||
|
}
|
||||||
|
var errorClasses = "error"
|
||||||
|
if(this.state.error) {
|
||||||
|
errorClasses = errorClasses + " active"
|
||||||
|
}
|
||||||
|
var response = <div className="EventsPage">
|
||||||
|
<div id="header">
|
||||||
|
<div className="logo-holder"><img src="/assets/logo.png"/></div>
|
||||||
|
</div>
|
||||||
|
<div id="top-container">
|
||||||
|
<div className="header">
|
||||||
|
<p>Enter your order number from<img className="eventbrite-logo" src="/assets/event/eventbrite-logo.png"/>below:</p>
|
||||||
|
</div>
|
||||||
|
<div className="submit-row">
|
||||||
|
<div className="submit promo-start">
|
||||||
|
<form id="unlock" onSubmit={this.handleSubmit}>
|
||||||
|
<input type="text" name="order" className="order-input" id="order-input"/>
|
||||||
|
<button className={ctaButtonClasses}>Unlock Livestream</button>
|
||||||
|
</form>
|
||||||
|
<span className={errorClasses}>{this.state.error}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="listings">
|
||||||
|
<div className="preview-and-action-box">
|
||||||
|
<div id="upcoming-yours">
|
||||||
|
<EventList mode="yours"/>
|
||||||
|
</div>
|
||||||
|
<div id="upcoming-all">
|
||||||
|
<EventList mode="all"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
return response
|
||||||
|
},
|
||||||
|
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
@EventActions = Reflux.createActions({
|
||||||
|
refresh: {},
|
||||||
|
single: {}
|
||||||
|
addAuthorization: {}
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
|
||||||
|
context = window
|
||||||
|
|
||||||
|
console.log(@EventActions)
|
||||||
|
console.log(window.EventActions)
|
||||||
|
|
||||||
|
@EventStore = Reflux.createStore(
|
||||||
|
{
|
||||||
|
listenables: window.EventActions
|
||||||
|
|
||||||
|
events: null
|
||||||
|
eventsError: null
|
||||||
|
eventStorage: null
|
||||||
|
AuthorizedEventsStorage: null
|
||||||
|
|
||||||
|
init: ->
|
||||||
|
@AuthorizedEventStorage = context.JK.AuthorizedEventStorage
|
||||||
|
|
||||||
|
changed: () ->
|
||||||
|
state = @getState()
|
||||||
|
@trigger(state)
|
||||||
|
|
||||||
|
addAuthorization: (authorization) ->
|
||||||
|
@AuthorizedEventStorage.storeAuthorizedEvent(authorization)
|
||||||
|
@collateEvents()
|
||||||
|
|
||||||
|
onRefresh: () ->
|
||||||
|
context.JK.Rest2.listLiveStreams().then((response) => response.json()).then((response) => @refreshDone(response)).catch((jqXHR) => @refreshFailed(jqXHR))
|
||||||
|
|
||||||
|
onSingle: (slug) ->
|
||||||
|
context.JK.Rest2.getLiveStream(slug).then((response) => response.json()).then((response) =>
|
||||||
|
console.log("single", response)
|
||||||
|
if(response.errors)
|
||||||
|
@refreshFailed(response)
|
||||||
|
else
|
||||||
|
matchedFormat = {entries:[ response ]}
|
||||||
|
@refreshDone(matchedFormat))
|
||||||
|
|
||||||
|
.catch((jqXHR) => @refreshFailed(jqXHR))
|
||||||
|
|
||||||
|
refreshDone: (events) ->
|
||||||
|
|
||||||
|
@eventsError = false
|
||||||
|
@events = events
|
||||||
|
@collateEvents()
|
||||||
|
|
||||||
|
refreshFailed: (events) ->
|
||||||
|
console.log("events error", events)
|
||||||
|
@eventsError = true
|
||||||
|
@changed()
|
||||||
|
|
||||||
|
collateEvents: () ->
|
||||||
|
authorizedEvents = @AuthorizedEventStorage.listAuthorizedEvents()
|
||||||
|
|
||||||
|
for event in @events.entries
|
||||||
|
|
||||||
|
authorization = authorizedEvents[event.id]
|
||||||
|
if authorization
|
||||||
|
console.log("event is authorized", event)
|
||||||
|
event.authorization = authorization
|
||||||
|
else
|
||||||
|
event.authorization = null
|
||||||
|
|
||||||
|
@changed()
|
||||||
|
|
||||||
|
getState:() ->
|
||||||
|
{events: @events, events_error: @eventsError}
|
||||||
|
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,125 @@
|
||||||
|
var defaultURL = 'http://127.0.0.1:3000/signup'; //<---- CHANGE TO YOUR WEBSITE URL
|
||||||
|
|
||||||
|
//show loading graphic
|
||||||
|
function showLoader(id) {
|
||||||
|
$('#' + id + ' img').fadeIn('slow');
|
||||||
|
}
|
||||||
|
|
||||||
|
//hdie loading graphic
|
||||||
|
function hideLoader(id) {
|
||||||
|
$('#' + id + ' img').fadeOut('slow');
|
||||||
|
}
|
||||||
|
|
||||||
|
//function to check load state of each frame
|
||||||
|
function allLoaded(){
|
||||||
|
var results = [];
|
||||||
|
$('iframe').each(function(){
|
||||||
|
if(!$(this).data('loaded')){results.push(false)}
|
||||||
|
});
|
||||||
|
var result = (results.length > 0) ? false : true;
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
function loadPage($frame, url) {
|
||||||
|
if ( url.substr(0,7) !== 'http://' && url.substr(0,8) !== 'https://' && url.substr(0, 7) !== 'file://' ) {
|
||||||
|
url = 'http://'+url;
|
||||||
|
}
|
||||||
|
$('iframe').not($frame).each(function(){showLoader($(this).parent().attr('id'));})
|
||||||
|
$('iframe').not($frame).data('loaded', false);
|
||||||
|
$('iframe').not($frame).attr('src', url);
|
||||||
|
}
|
||||||
|
|
||||||
|
$('.frame').each(function(){showLoader($(this).attr('id'))});
|
||||||
|
|
||||||
|
|
||||||
|
//when document loads
|
||||||
|
$(document).ready(function(){
|
||||||
|
|
||||||
|
loadPage('', defaultURL);
|
||||||
|
|
||||||
|
//query string
|
||||||
|
var qsArray = window.location.href.split('?');
|
||||||
|
var qs = qsArray[qsArray.length-1];
|
||||||
|
|
||||||
|
if(qs != '' && qsArray.length > 1){
|
||||||
|
$('#url input[type=text]').val(qs);
|
||||||
|
loadPage('', qs);
|
||||||
|
}
|
||||||
|
|
||||||
|
//set slidable div width
|
||||||
|
$('#frames #inner').css('width', function(){
|
||||||
|
var width = 0;
|
||||||
|
$('.frame').each(function(){width += $(this).outerWidth() + 20});
|
||||||
|
return width;
|
||||||
|
});
|
||||||
|
|
||||||
|
//add event handlers for options radio buttons
|
||||||
|
$('input[type=radio]').change(function(){
|
||||||
|
$frames = $('#frames');
|
||||||
|
$inputs = $('input[type=radio]:checked').val();
|
||||||
|
|
||||||
|
if($inputs == '1'){
|
||||||
|
$frames.addClass('widthOnly');
|
||||||
|
} else {
|
||||||
|
$frames.removeClass('widthOnly');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//add event handlers for scrollbars checkbox
|
||||||
|
$('input[type=checkbox]').change(function(){
|
||||||
|
var scrollBarWidth = 15;
|
||||||
|
$frames = $('#frames');
|
||||||
|
$inputs = $('#scrollbar:checked');
|
||||||
|
|
||||||
|
if( $inputs.length == 0 ){
|
||||||
|
scrollBarWidth = -15;
|
||||||
|
}
|
||||||
|
|
||||||
|
$frames.find('iframe').each(function(i,el) {
|
||||||
|
$(el).attr('width', parseInt($(el).attr('width')) + scrollBarWidth);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
//when the url textbox is used
|
||||||
|
$('form').submit(function(){
|
||||||
|
loadPage('' , $('#url input[type=text]').val());
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
//when frame loads
|
||||||
|
$('iframe').load(function(){
|
||||||
|
|
||||||
|
var $this = $(this);
|
||||||
|
var url = '';
|
||||||
|
var error = false;
|
||||||
|
|
||||||
|
try{
|
||||||
|
url = $this.contents().get(0).location.href;
|
||||||
|
} catch(e) {
|
||||||
|
error = true;
|
||||||
|
if($('#url input[type=text]').val() != ''){
|
||||||
|
url = $('#url input[type=text]').val();
|
||||||
|
} else {
|
||||||
|
url = defaultURL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//load other pages with the same URL
|
||||||
|
if(allLoaded()){
|
||||||
|
if(error){
|
||||||
|
alert('Browsers prevent navigation from inside iframes across domains.\nPlease use the textbox at the top for external sites.');
|
||||||
|
loadPage('', defaultURL);
|
||||||
|
}else{
|
||||||
|
loadPage($this, url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//when frame loads, hide loader graphic
|
||||||
|
else{
|
||||||
|
error = false;
|
||||||
|
hideLoader($(this).parent().attr('id'));
|
||||||
|
$(this).data('loaded',true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
@ -232,8 +232,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if(networkTest.length) {
|
if(networkTest.length) {
|
||||||
stepNetworkTest.initialize($wizardSteps.filter($('.network-test')), self);
|
// skip network test always
|
||||||
STEPS[dynamicStepCount++] = stepNetworkTest
|
//stepNetworkTest.initialize($wizardSteps.filter($('.network-test')), self);
|
||||||
|
//STEPS[dynamicStepCount++] = stepNetworkTest
|
||||||
}
|
}
|
||||||
|
|
||||||
STEPS[dynamicStepCount++]=stepSuccess
|
STEPS[dynamicStepCount++]=stepSuccess
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
|
||||||
|
$base-font-family: 'arial', sans-serif;
|
||||||
|
|
||||||
|
$large-font-size: 1.5rem;
|
||||||
|
$standard-font-size: 1rem;
|
||||||
|
$smaller-font-size: .8rem;
|
||||||
|
$small-font-size: .7rem;
|
||||||
|
$input-font-size: 1.0rem;
|
||||||
|
$submit-button-width:9rem;
|
||||||
|
$checkbox-label-width:14rem;
|
||||||
|
$create-account-width:10rem;
|
||||||
|
$start-promo-btn-width:13rem;
|
||||||
|
$jamkazam-background:#323232;
|
||||||
|
|
||||||
|
$copy-color-on-dark: #b9b9b9;
|
||||||
|
$copy-color-on-white: #575757;
|
||||||
|
$cta-color: #e03d04;
|
||||||
|
$chunkyBorderWidth: 6px;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
/**
|
||||||
|
|
||||||
|
*= require dialogs/banner
|
||||||
|
*= require_directory ./react-components
|
||||||
|
*/
|
||||||
|
|
||||||
|
@import "events/constants";
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
min-height: 100%;
|
||||||
|
overflow:auto;
|
||||||
|
background-color:$jamkazam-background;
|
||||||
|
color:white;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
min-height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.2;
|
||||||
|
font-family: Raleway, Arial, Helvetica, sans-serif;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
@import "events/constants";
|
||||||
|
@import "client/common.scss";
|
||||||
|
|
||||||
|
.EventList {
|
||||||
|
|
||||||
|
.event-header {
|
||||||
|
background-color: $cta-color;
|
||||||
|
color: white;
|
||||||
|
font-size: 24px;
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px 0;
|
||||||
|
border-width: $chunkyBorderWidth 0 $chunkyBorderWidth;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: $copy-color-on-dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
.event-section {
|
||||||
|
padding: 10px;
|
||||||
|
//s border-width: 0 0 $chunkyBorderWidth;
|
||||||
|
//border-style: solid;
|
||||||
|
//border-color: $copy-color-on-dark;
|
||||||
|
|
||||||
|
&.loading {
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.event {
|
||||||
|
display:grid;
|
||||||
|
grid-template-columns: 10rem 20rem;
|
||||||
|
align-content:center;
|
||||||
|
height:8rem;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 2px 0 2px 0;
|
||||||
|
border-color: $copy-color-on-dark;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
border-width:0 0 1px 0;
|
||||||
|
}
|
||||||
|
&:last-child {
|
||||||
|
border-width:1px 0 0 0;
|
||||||
|
}
|
||||||
|
&:only-child {
|
||||||
|
border-width:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.no-image {
|
||||||
|
grid-template-columns: 30rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-link {
|
||||||
|
color:white;
|
||||||
|
}
|
||||||
|
img.thumb {
|
||||||
|
width:100%;
|
||||||
|
max-height:400px;
|
||||||
|
}
|
||||||
|
div.thumb {
|
||||||
|
display: grid;
|
||||||
|
justify-content: center;
|
||||||
|
align-content: center;
|
||||||
|
text-transform: uppercase;
|
||||||
|
padding-right:1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail {
|
||||||
|
display:grid;
|
||||||
|
justify-content: center;
|
||||||
|
padding-left:1rem;
|
||||||
|
align-content:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size:1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.when {
|
||||||
|
font-size:1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
@import "events/constants";
|
||||||
|
@import "client/common.scss";
|
||||||
|
|
||||||
|
|
||||||
|
[data-react-class="EventPage"] {
|
||||||
|
width:100%;
|
||||||
|
|
||||||
|
.EventPage {
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header {
|
||||||
|
display:grid;
|
||||||
|
justify-content: center;
|
||||||
|
width:100%;
|
||||||
|
background-color:$jamkazam-background;
|
||||||
|
padding:1.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size:2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
color:gray;
|
||||||
|
font-size:1rem;
|
||||||
|
margin-top:.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.starts-at {
|
||||||
|
color:gray;
|
||||||
|
font-size:1rem;
|
||||||
|
margin-top:.2rem;
|
||||||
|
}
|
||||||
|
#root {
|
||||||
|
min-height: 100%;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
//justify-content: center;
|
||||||
|
min-width: 50%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
#player, #no-player {
|
||||||
|
position:relative;
|
||||||
|
padding-bottom:56.25%;
|
||||||
|
padding-top:30px;
|
||||||
|
height:0;
|
||||||
|
overflow:hidden;
|
||||||
|
top:-5rem;
|
||||||
|
border-width: $chunkyBorderWidth;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: $copy-color-on-dark;
|
||||||
|
a {
|
||||||
|
color:#fc0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#no-player {
|
||||||
|
display:grid;
|
||||||
|
align-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-register {
|
||||||
|
text-decoration: underline;
|
||||||
|
font-weight:bold;
|
||||||
|
margin-top:2rem;
|
||||||
|
display:block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-code {
|
||||||
|
background-color: black;
|
||||||
|
padding-bottom:0 !important;
|
||||||
|
height:auto !important;
|
||||||
|
min-height:200px !important;
|
||||||
|
padding-top:0 !important;
|
||||||
|
text-align:center;
|
||||||
|
font-size:1rem;
|
||||||
|
ul,ol {
|
||||||
|
text-align:left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#top-container {
|
||||||
|
background-color:black;
|
||||||
|
display: grid;
|
||||||
|
justify-content:center;
|
||||||
|
padding:2rem 0 7rem 0;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.root {
|
||||||
|
flex-grow: 1;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
font-size: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.listing {
|
||||||
|
width:50%;
|
||||||
|
margin:auto;
|
||||||
|
//display:grid;
|
||||||
|
//justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@media (min-width:1px) and (max-width: 1199px) {
|
||||||
|
html {
|
||||||
|
font-size: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,169 @@
|
||||||
|
@import "events/constants";
|
||||||
|
@import "client/common.scss";
|
||||||
|
|
||||||
|
|
||||||
|
[data-react-class="EventsPage"] {
|
||||||
|
width:100%;
|
||||||
|
|
||||||
|
.EventsPage {
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header {
|
||||||
|
display:grid;
|
||||||
|
justify-content: center;
|
||||||
|
width:100%;
|
||||||
|
background-color:$jamkazam-background;
|
||||||
|
padding:1.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#root {
|
||||||
|
min-height: 100%;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
//justify-content: center;
|
||||||
|
min-width: 50%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.order-input {
|
||||||
|
font-size:1rem;
|
||||||
|
padding:5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-button {
|
||||||
|
cursor:pointer;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: white;
|
||||||
|
background-color: $cta-color;
|
||||||
|
text-align: center;
|
||||||
|
padding: 5px;
|
||||||
|
margin-left:5px;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px outset buttonface;
|
||||||
|
font-family: Raleway, Arial, Helvetica, sans-serif;
|
||||||
|
|
||||||
|
&.submitting {
|
||||||
|
background-color: gray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.error {
|
||||||
|
margin-top: 1rem;
|
||||||
|
#position: absolute;
|
||||||
|
display:none;
|
||||||
|
color:red;
|
||||||
|
font-weight:bold;
|
||||||
|
&.active {
|
||||||
|
display:inline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.eventbrite-logo {
|
||||||
|
height:2rem;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
#top-container {
|
||||||
|
background-color:black;
|
||||||
|
display: grid;
|
||||||
|
justify-content:center;
|
||||||
|
padding:5rem 0 7rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.root {
|
||||||
|
flex-grow: 1;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo-holder {
|
||||||
|
max-width: 300px;
|
||||||
|
min-width:0;
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.submit-row {
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
margin:.5rem 0;
|
||||||
|
}
|
||||||
|
p:first-child {
|
||||||
|
margin-top:0;
|
||||||
|
}
|
||||||
|
p.last-child {
|
||||||
|
margin-bottom:0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
font-size: $large-font-size;
|
||||||
|
margin-top: 1rem;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 700px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
font-size: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.listings {
|
||||||
|
display:grid;
|
||||||
|
justify-content: center;
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-and-action-box {
|
||||||
|
background-color: black;
|
||||||
|
position:relative;
|
||||||
|
top: -2rem;
|
||||||
|
min-width: 400px;
|
||||||
|
@include border_box_sizing;
|
||||||
|
border-width: 0 $chunkyBorderWidth $chunkyBorderWidth;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: $copy-color-on-dark;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width:1px) and (max-width: 1199px) {
|
||||||
|
html {
|
||||||
|
font-size: 100%;
|
||||||
|
}
|
||||||
|
.code-input {
|
||||||
|
max-width:$submit-button-width;
|
||||||
|
}
|
||||||
|
.code-input input {
|
||||||
|
font-size: $standard-font-size;
|
||||||
|
}
|
||||||
|
.code-instructions {
|
||||||
|
width:$submit-button-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-input input {
|
||||||
|
width:$create-account-width;
|
||||||
|
}
|
||||||
|
.select-input select{
|
||||||
|
width:$create-account-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
.instructions.create-account {
|
||||||
|
margin-top:1rem;
|
||||||
|
text-align:justify;
|
||||||
|
}
|
||||||
|
.success-msg {
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
.logo-holder.create-account {
|
||||||
|
margin-top:2rem;
|
||||||
|
}
|
||||||
|
.code-form.create-account {
|
||||||
|
margin-top:1rem;
|
||||||
|
}
|
||||||
|
.powered-by.create-account {
|
||||||
|
margin-top:0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
|
||||||
|
class ApiLiveStreamsController < ApiController
|
||||||
|
|
||||||
|
|
||||||
|
respond_to :json
|
||||||
|
|
||||||
|
def log
|
||||||
|
@log || Logging.logger[ApiLiveStreamsController]
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def index
|
||||||
|
@live_streams = LiveStream.upcoming
|
||||||
|
|
||||||
|
render "api_live_streams/index", :layout => nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def claim
|
||||||
|
order = params[:order]
|
||||||
|
if order.nil?
|
||||||
|
render :json => {}, :status => 404, layout: nil
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
order.strip!
|
||||||
|
|
||||||
|
if order.start_with? "#"
|
||||||
|
order = order[1..-1]
|
||||||
|
end
|
||||||
|
|
||||||
|
event_brite_order = EventBriteOrder.find_by_order_id(order)
|
||||||
|
|
||||||
|
if event_brite_order.nil?
|
||||||
|
render :json => {}, :status => 404, layout: nil
|
||||||
|
else
|
||||||
|
EventBriteOrder.where(id: event_brite_order.id).update_all(times_claimed: event_brite_order.times_claimed + 1)
|
||||||
|
render :json => {event_id: event_brite_order.live_stream.id, order_id: event_brite_order.order_id, event_type: 'eventbrite'}, :status => :ok, layout: nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
slug = params[:slug]
|
||||||
|
@live_stream = LiveStream.find_by_slug!(slug)
|
||||||
|
render "api_live_streams/show", :layout => nil
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
@ -2,7 +2,20 @@ class EventsController < ApplicationController
|
||||||
|
|
||||||
respond_to :html
|
respond_to :html
|
||||||
|
|
||||||
|
|
||||||
|
def list
|
||||||
|
render 'events', layout: 'events'
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
@event = LiveStream.find_by_slug(params[:slug])
|
||||||
|
|
||||||
|
render 'event', :layout => 'events'
|
||||||
|
end
|
||||||
|
|
||||||
|
# 2014 lulz
|
||||||
|
def show_old
|
||||||
@event = Event.find_by_slug!(params[:slug])
|
@event = Event.find_by_slug!(params[:slug])
|
||||||
render 'event', :layout => "web"
|
render 'event', :layout => "web"
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,10 @@ class SpikesController < ApplicationController
|
||||||
render :layout => false
|
render :layout => false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def responsive
|
||||||
|
render :layout => false
|
||||||
|
end
|
||||||
|
|
||||||
def subscription
|
def subscription
|
||||||
|
|
||||||
#Notification.send_reload(MessageFactory::ALL_NATIVE_CLIENTS)
|
#Notification.send_reload(MessageFactory::ALL_NATIVE_CLIENTS)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
node :entries do |page|
|
||||||
|
partial "api_live_streams/show", object: @live_streams
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
object @live_stream
|
||||||
|
|
||||||
|
attributes :id, :slug, :title, :description, :starts_at, :allow_in, :ends_at, :img_url, :img_width, :img_height, :youtube_code, :eventbriteid, :event_type, :event_brite_registration_url, :white_label_player
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
- provide(:page_name, 'JamKazam Event')
|
||||||
|
- provide(:description, @description)
|
||||||
|
- provide(:title, @title)
|
||||||
|
|
||||||
|
#root
|
||||||
|
= react_component 'EventPage'
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
- provide(:page_name, 'Upcoming JamKazam Events')
|
||||||
|
- provide(:description, @description)
|
||||||
|
- provide(:title, @title)
|
||||||
|
|
||||||
|
#root
|
||||||
|
= react_component 'EventsPage'
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title><%= full_title(yield(:title)) %></title>
|
||||||
|
|
||||||
|
<!--[if IE]>
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/ie.css" media="screen, projection"/>
|
||||||
|
<![endif]-->
|
||||||
|
<link href='http://fonts.googleapis.com/css?family=Raleway:100,200,300,400,500,600,700' rel='stylesheet' type='text/css'>
|
||||||
|
<link rel="stylesheet" href="https://cdn.plyr.io/3.5.10/plyr.css" />
|
||||||
|
<%= stylesheet_link_tag "events/events", media: "all" %>
|
||||||
|
<%= include_gon(:init => true) %>
|
||||||
|
<%= csrf_meta_tags %>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
<meta name="description" content="<%= meta_description(yield(:description)) %>">
|
||||||
|
<% if content_for?(:social_meta) %>
|
||||||
|
<%= yield(:social_meta) %>
|
||||||
|
<% else %>
|
||||||
|
<%= render "layouts/social_meta" %>
|
||||||
|
<% end %>
|
||||||
|
<%= render "shared/ad_sense" %>
|
||||||
|
</head>
|
||||||
|
<body class="events <%= yield(:page_name) %>">
|
||||||
|
<div id="basic-container">
|
||||||
|
<!--<script src="https://cdn.plyr.io/3.5.10/plyr.polyfilled.js"></script>-->
|
||||||
|
<%= javascript_include_tag "events/events" %>
|
||||||
|
<div class="wrapper">
|
||||||
|
<%= yield %>
|
||||||
|
<div id="rt-e617b4394e0e49e1c234c63161bb2e15"></div> <script src="https://rumbletalk.com/client/?VHi@pnno"></script>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<%= render "clients/help" %>
|
||||||
|
<%= render 'dialogs/banner' %>
|
||||||
|
<%= render "shared/ga" %>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="description" content="Responsive design testing for the masses">
|
||||||
|
<title>Responsive Design Testing</title>
|
||||||
|
<style>
|
||||||
|
*{vertical-align:top;}
|
||||||
|
body{padding:20px;font-family:sans-serif;overflow-y:scroll;}
|
||||||
|
h2{margin:0 0 20px 0;}
|
||||||
|
span.small{font-size:60%;vertical-align:middle;}
|
||||||
|
#url{margin:0 0 20px 0px;display:block;}
|
||||||
|
#url input[type=text]{border:solid 1px #666;width:85%;margin:0 auto;font-size:2em;text-align:left;}
|
||||||
|
#url input[type=submit]{display:none;}
|
||||||
|
#url #options{float:right;line-height:25px;width:13%;}
|
||||||
|
#url #options input{margin-top:5px;}
|
||||||
|
#frames{overflow-x:scroll;width:100%;margin-bottom:10px;padding-bottom:20px;}
|
||||||
|
.frame{margin-right:20px;float:left;}
|
||||||
|
.frame:last-child{margin-right:0;}
|
||||||
|
.frame img{display:none;vertical-align:middle;}
|
||||||
|
iframe{border:solid 1px #000;}
|
||||||
|
.widthOnly {height:580px;}
|
||||||
|
.widthOnly h2 span{display:none;}
|
||||||
|
.widthOnly iframe{height:500px;}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body id="container">
|
||||||
|
<div id="url">
|
||||||
|
<form method="post">
|
||||||
|
<input type="text" placeholder="Test your own site... type the url and hit enter" />
|
||||||
|
<input type="submit" value="submit">
|
||||||
|
<div id="options">
|
||||||
|
<label for="normal"><input id="normal" type="radio" name="option" value="1" checked>Width only</label><br />
|
||||||
|
<label for="accurate"><input id="accurate" type="radio" name="option" value="2">Device sizes</label><br />
|
||||||
|
<label for="scrollbar"><input id="scrollbar" type="checkbox" name="scrollbar" value="1" checked>Visible Scrollbars</label>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div id="frames" class="widthOnly">
|
||||||
|
<div id="inner">
|
||||||
|
<div id="f1" class="frame">
|
||||||
|
<h2>240<span> x 320</span> <span class="small">(small phone)</span> <img src="http://mattkersley.com/wp-content/themes/mattkersley/images/loader_large.gif" /></h2>
|
||||||
|
<iframe sandbox="allow-same-origin allow-forms allow-scripts" seamless width="255" height="320"></iframe>
|
||||||
|
</div>
|
||||||
|
<div id="f2" class="frame">
|
||||||
|
<h2>320<span> x 480</span> <span class="small">(iPhone)</span> <img src="http://mattkersley.com/wp-content/themes/mattkersley/images/loader_large.gif" /></h2>
|
||||||
|
<iframe sandbox="allow-same-origin allow-forms allow-scripts" seamless width="335" height="480"></iframe>
|
||||||
|
</div>
|
||||||
|
<div id="f3" class="frame">
|
||||||
|
<h2>480<span> x 640</span> <span class="small">(small tablet)</span> <img src="http://mattkersley.com/wp-content/themes/mattkersley/images/loader_large.gif" /></h2>
|
||||||
|
<iframe sandbox="allow-same-origin allow-forms allow-scripts" seamless width="495" height="640"></iframe>
|
||||||
|
</div>
|
||||||
|
<div id="f4" class="frame">
|
||||||
|
<h2>768<span> x 1024</span> <span class="small">(iPad - Portrait)</span> <img src="http://mattkersley.com/wp-content/themes/mattkersley/images/loader_large.gif" /></h2>
|
||||||
|
<iframe sandbox="allow-same-origin allow-forms allow-scripts" seamless width="783" height="1024"></iframe>
|
||||||
|
</div>
|
||||||
|
<div id="f5" class="frame">
|
||||||
|
<h2>1024<span> x 768</span> <span class="small">(iPad - Landscape)</span> <img src="http://mattkersley.com/wp-content/themes/mattkersley/images/loader_large.gif" /></h2>
|
||||||
|
<iframe sandbox="allow-same-origin allow-forms allow-scripts" seamless width="1039" height="768"></iframe>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span>A tool by <a href="http://mattkersley.com">Matt Kersley</a> - <a href="https://github.com/mattkersley/Responsive-Design-Testing">Fork it on Github</a></span><br />
|
||||||
|
<span>Note: The content width may not be pixel perfect - I have added 15px to the iframes to cater for the scrollbars</span>
|
||||||
|
|
||||||
|
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script>
|
||||||
|
<%= javascript_include_tag "spikes/responsive.js" %>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -469,5 +469,5 @@ if defined?(Bundler)
|
||||||
|
|
||||||
config.rating_dialog_min_time = 60
|
config.rating_dialog_min_time = 60
|
||||||
config.rating_dialog_min_num = 1
|
config.rating_dialog_min_num = 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,7 @@ Rails.application.routes.draw do
|
||||||
get '/gmail_contacts', to: 'gmail#gmail_contacts'
|
get '/gmail_contacts', to: 'gmail#gmail_contacts'
|
||||||
|
|
||||||
get '/events/:slug', to: 'events#show', :as => 'event'
|
get '/events/:slug', to: 'events#show', :as => 'event'
|
||||||
|
get '/events', to: 'events#list', as: 'events'
|
||||||
|
|
||||||
get '/endorse/:id/:service', to: 'users#endorse', :as => 'endorse'
|
get '/endorse/:id/:service', to: 'users#endorse', :as => 'endorse'
|
||||||
|
|
||||||
|
|
@ -143,6 +144,7 @@ Rails.application.routes.draw do
|
||||||
require 'resque-retry/server'
|
require 'resque-retry/server'
|
||||||
mount Resque::Server.new, :at => "/resque" if Rails.env == "development"
|
mount Resque::Server.new, :at => "/resque" if Rails.env == "development"
|
||||||
|
|
||||||
|
get '/responsive', to: 'spikes#responsive'
|
||||||
# route to spike controller (proof-of-concepts)
|
# route to spike controller (proof-of-concepts)
|
||||||
get '/listen_in', to: 'spikes#listen_in'
|
get '/listen_in', to: 'spikes#listen_in'
|
||||||
get '/facebook_invite', to: 'spikes#facebook_invite'
|
get '/facebook_invite', to: 'spikes#facebook_invite'
|
||||||
|
|
@ -229,6 +231,11 @@ Rails.application.routes.draw do
|
||||||
|
|
||||||
post '/auths/login' => 'api_auths#login'
|
post '/auths/login' => 'api_auths#login'
|
||||||
|
|
||||||
|
# live streams
|
||||||
|
match '/live_streams' => 'api_live_streams#index', :via => :get
|
||||||
|
match '/live_streams/claim' => 'api_live_streams#claim', :via => :post
|
||||||
|
match '/live_streams/:slug' => 'api_live_streams#show', :via => :get
|
||||||
|
|
||||||
# music sessions
|
# music sessions
|
||||||
match '/sessions/:id/participants/legacy' => 'api_music_sessions#participant_create_legacy', :via => :post # can be removed when new Create Session comes in
|
match '/sessions/:id/participants/legacy' => 'api_music_sessions#participant_create_legacy', :via => :post # can be removed when new Create Session comes in
|
||||||
match '/sessions/:id/participants' => 'api_music_sessions#participant_create', :via => :post
|
match '/sessions/:id/participants' => 'api_music_sessions#participant_create', :via => :post
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue