diff --git a/web/app/assets/javascripts/site_validator.js.coffee b/web/app/assets/javascripts/site_validator.js.coffee
index 48bf4eac8..312b578d3 100644
--- a/web/app/assets/javascripts/site_validator.js.coffee
+++ b/web/app/assets/javascripts/site_validator.js.coffee
@@ -16,7 +16,6 @@ context.JK.SiteValidator = class SiteValidator
this.setSiteStatus(null)
this.showFormatStatus()
@is_rec_src = false
- @recording_source_id = null
@deferred_status_check = null
@is_validating = false
@@ -53,13 +52,15 @@ context.JK.SiteValidator = class SiteValidator
this.validateSite()
validateSite: () =>
+ unless data = this.dataToValidate()
+ return null
this.setSiteStatus(null)
@spinner.show()
- @rest.validateUrlSite(this.dataToValidate(), @site_type)
- .done(this.processSiteCheck)
+ @rest.validateUrlSite(data, @site_type)
+ .done(this.processSiteCheckSucceed)
.fail(this.processSiteCheckFail)
- processSiteCheck: (response) =>
+ processSiteCheckSucceed: (response) =>
@spinner.hide()
if 'Valid Site' == response.message
@@ -116,23 +117,54 @@ context.JK.SiteValidator = class SiteValidator
else
dfr.reject()
return dfr.promise()
+
context.JK.RecordingSourceValidator = class RecordingSourceValidator extends SiteValidator
constructor: (site_type) ->
super(site_type)
@recording_sources = []
@is_rec_src = true
- @add_btn = @input_div.find('.rec_src_add')
+ @add_btn = @input_div.find('a.add-recording-source')
init: (sources) =>
super()
if sources
@recording_sources = sources
+ @add_btn.on 'click', =>
+ this.attemptAdd()
- processSiteCheck: (response) =>
+ processSiteCheckSucceed: (response) =>
super()
- @recording_source_id = response.recording_id
+ @add_btn.removeClass('disabled')
+ @recording_sources << { url: response.data, recording_id: response.recording_id }
- addSource: () ->
+ processSiteCheckFail: (response) =>
+ super()
+ @add_btn.removeClass('disabled')
+
+ didBlur: () =>
+ # do nothing, validate on add only
+
+ validateSite: () =>
@add_btn.addClass('disabled')
+ super()
+
+ attemptAdd: () =>
+ unless data = this.dataToValidate()
+ return false
+ unless this.containsRecordingurl(data)
+ this.validateSite()
+ return true
+ false
+
+ removeRecordingId: (recording_id) =>
+ start_len = @recording_sources.length
+ @recording_sources = $.grep @recording_sources, (src_data) ->
+ src_data['recording_id'] != recording_id
+ start_len != @recording_sources.length
+
+ containsRecordingUrl: (url) =>
+ vals = $.grep @recording_sources, (src_data) ->
+ src_data['url'] == url
+ 0 < vals.length
diff --git a/web/app/assets/stylesheets/client/site_validator.css.scss b/web/app/assets/stylesheets/client/site_validator.css.scss
index 549d58594..9db4f31f1 100644
--- a/web/app/assets/stylesheets/client/site_validator.css.scss
+++ b/web/app/assets/stylesheets/client/site_validator.css.scss
@@ -18,7 +18,6 @@
position: absolute;
margin-top: 0px;
margin-left: 520px;
- position: absolute;
left: 0px;
}
.error {
diff --git a/web/app/controllers/api_users_controller.rb b/web/app/controllers/api_users_controller.rb
index cd416f0cb..c9598a543 100644
--- a/web/app/controllers/api_users_controller.rb
+++ b/web/app/controllers/api_users_controller.rb
@@ -710,10 +710,10 @@ class ApiUsersController < ApiController
elsif Utils.recording_source?(site)
rec_id = Utils.extract_recording_id(site, data)
if rec_id
- render json: { message: 'Valid Site', recording_id: rec_id }, status: 200
+ render json: { message: 'Valid Site', recording_id: rec_id, data: data }, status: 200
return
else
- render json: { message: 'Invalid Site', errors: { site: ["Could not detect recording identifier"] } }, status: 200
+ render json: { message: 'Invalid Site', data: data, errors: { site: ["Could not detect recording identifier"] } }, status: 200
return
end
else
@@ -721,9 +721,9 @@ class ApiUsersController < ApiController
end
unless url.blank?
if errmsg = Utils.site_validator(url, site)
- render json: { message: 'Invalid Site', errors: { site: [errmsg] } }, status: 200
+ render json: { message: 'Invalid Site', data: data, errors: { site: [errmsg] } }, status: 200
else
- render json: { message: 'Valid Site' }, status: 200
+ render json: { message: 'Valid Site', data: data }, status: 200
end
else
render json: { message: "unknown validation for data '#{params[:data]}', site '#{params[:site]}'" }, status: :unprocessable_entity
diff --git a/web/app/controllers/spikes_controller.rb b/web/app/controllers/spikes_controller.rb
index 1c3c39e6e..4bfc90e54 100644
--- a/web/app/controllers/spikes_controller.rb
+++ b/web/app/controllers/spikes_controller.rb
@@ -42,4 +42,8 @@ class SpikesController < ApplicationController
render :layout => 'web'
end
+ def recording_source
+ render :layout => 'web'
+ end
+
end
diff --git a/web/app/views/clients/_site_validator.html.slim b/web/app/views/clients/_site_validator.html.slim
index d66dcf917..4c913459d 100644
--- a/web/app/views/clients/_site_validator.html.slim
+++ b/web/app/views/clients/_site_validator.html.slim
@@ -2,5 +2,7 @@ div class="site_validator" id="#{site_type}_validator"
span class="validate-checkmark"
span class="spinner-small upload-spinner"
input type='text' id="validate_input_#{site_type}" maxlength="2000"
- br
+ - if site_type =~ /^#{Utils::RECORDING_SRC_PREFIX}/
+ a id="add_btn_#{site_type}" class="button-grey add-recording-source right" ADD
+ br clear="all"
div class="error"
diff --git a/web/app/views/spikes/recording_source.html.slim b/web/app/views/spikes/recording_source.html.slim
new file mode 100644
index 000000000..ba7c0fb5b
--- /dev/null
+++ b/web/app/views/spikes/recording_source.html.slim
@@ -0,0 +1,19 @@
+= javascript_include_tag "site_validator"
+div style="width:50%"
+ = render "clients/site_validator", site_type: params[:site_type]
+= stylesheet_link_tag "client/site_validator"
+
+= select_tag "site_type", options_for_select(Utils::RECORDING_SOURCES, params[:site_type])
+
+javascript:
+ var initialized = false;
+ $(document).on('JAMKAZAM_READY', function(e, data) {
+ setTimeout(function() {
+ window.site_validator = new JK.SiteValidator('#{params[:site_type] || 'rec_youtube'}');
+ site_validator.init();
+ $('#validate_input_'+'#{params[:site_type] || 'url'}').val('jonathankolyer');
+ }, 1)
+ });
+ $('#site_type').change(function(){
+ location.href = 'recording_source?site_type='+$(this).val();
+ });
diff --git a/web/config/routes.rb b/web/config/routes.rb
index 700f2aaba..91d4ed24b 100644
--- a/web/config/routes.rb
+++ b/web/config/routes.rb
@@ -97,6 +97,7 @@ SampleApp::Application.routes.draw do
match '/websocket', to: 'spikes#websocket'
match '/test_subscription', to: 'spikes#subscription'
match '/site_validate', to: 'spikes#site_validate'
+ match '/recording_source', to: 'spikes#recording_source'
# junk pages
match '/help', to: 'static_pages#help'
diff --git a/web/lib/utils.rb b/web/lib/utils.rb
index 752717f19..80fe08cbe 100644
--- a/web/lib/utils.rb
+++ b/web/lib/utils.rb
@@ -1,6 +1,7 @@
class Utils
- RECORDING_SOURCES = %W{rec_youtube rec_soundcloud}
+ RECORDING_SRC_PREFIX = 'rec_'
+ RECORDING_SOURCES = ["#{RECORDING_SRC_PREFIX}youtube", "#{RECORDING_SRC_PREFIX}soundcloud"]
USERNAME_SITES = %W{youtube facebook soundcloud bandcamp fandalism twitter reverbnation}
SITE_TYPES = ['url'].concat(USERNAME_SITES).concat(RECORDING_SOURCES)
diff --git a/web/spec/javascripts/fixtures/recordingSource.html.slim b/web/spec/javascripts/fixtures/recordingSource.html.slim
new file mode 100644
index 000000000..723919dd4
--- /dev/null
+++ b/web/spec/javascripts/fixtures/recordingSource.html.slim
@@ -0,0 +1,2 @@
+div style="width:50%"
+ = render "clients/site_validator", site_type: 'rec_youtube'
diff --git a/web/spec/javascripts/recording_source_spec.js.coffee b/web/spec/javascripts/recording_source_spec.js.coffee
new file mode 100644
index 000000000..f1cae81de
--- /dev/null
+++ b/web/spec/javascripts/recording_source_spec.js.coffee
@@ -0,0 +1,51 @@
+describe "RecordingSource", ->
+
+ $('',
+ rel: 'stylesheet'
+ type: 'text/css'
+ href: '/assets/client/site_validator.css').appendTo 'head'
+ fixture.preload("recordingSource.html")
+
+ beforeEach ->
+ @server = sinon.fakeServer.create();
+ window.jamClient = sinon.stub()
+ @fixtures = fixture.load("recordingSource.html", true)
+ window.gon = {}
+ window.gon.isNativeClient = true
+
+ afterEach ->
+ @server.restore()
+
+ describe "youtube recording source", ->
+
+ beforeEach ->
+ @recSource = new JK.RecordingSourceValidator('rec_youtube')
+ sources = [{ url: 'https://www.youtube.com/watch?v=i_xFOmYxKYz', recording_id: 'i_xFOmYxKYz' }]
+ @recSource.init(sources)
+ @url = 'https://www.youtube.com/watch?v=i_xFOmYxKYz'
+
+ it "displays validator widget", ->
+ @recSource.data_input.val(@url)
+ @recSource.siteIsValid()
+ expect(@recSource.checkmark).toBeVisible()
+
+ xit "initializes sources properly", ->
+ expect(@recSource.hasSources()).toEqual(true)
+
+ xit "adds source entries properly", ->
+ @url += 'xx'
+ @server.respondWith("GET", '/api/data_validation?sitetype=url&data=' + encodeURIComponent(@url),
+ [200, { "content-type": "application/json" }, JSON.stringify({"message": "Valid Site"})])
+ sinon.spy()
+ @recSource.data_input.val(@url)
+ @recSource.add_btn.click()
+ @server.respond()
+ expect(@siteValidator.state().state()).toEqual('resolved')
+ expect(@server.containsRecordingUrl(@url)).toEqual(true)
+
+ xit "rejects duplicate source entries", ->
+
+ xit "removes sources", ->
+ expect(@recSource.removeRecordingId('i_xFOmYxKYz')).toEqual(true)
+
+