diff --git a/web/app/assets/javascripts/jquery.lessonSessionActions.js b/web/app/assets/javascripts/jquery.lessonSessionActions.js
index cec184edf..bff821074 100644
--- a/web/app/assets/javascripts/jquery.lessonSessionActions.js
+++ b/web/app/assets/javascripts/jquery.lessonSessionActions.js
@@ -23,7 +23,6 @@
$parent.data('lessonSessionActions', options)
function onLessonActionSelected() {
- console.log("ON LESSION SECTION ANTHOUNHSE")
var $li = $(this);
var lessonAction = $li.attr('data-lesson-option');
diff --git a/web/app/assets/javascripts/react-components.js b/web/app/assets/javascripts/react-components.js
index 5e3fb6c53..c08afc511 100644
--- a/web/app/assets/javascripts/react-components.js
+++ b/web/app/assets/javascripts/react-components.js
@@ -10,6 +10,7 @@
//= require ./react-components/stores/SchoolStore
//= require ./react-components/stores/StripeStore
//= require ./react-components/stores/AvatarStore
+//= require ./react-components/stores/AttachmentStore
//= require ./react-components/stores/InstrumentStore
//= require ./react-components/stores/LanguageStore
//= require ./react-components/stores/GenreStore
diff --git a/web/app/assets/javascripts/react-components/AttachmentStatus.js.jsx.coffee b/web/app/assets/javascripts/react-components/AttachmentStatus.js.jsx.coffee
new file mode 100644
index 000000000..9dbd8d24a
--- /dev/null
+++ b/web/app/assets/javascripts/react-components/AttachmentStatus.js.jsx.coffee
@@ -0,0 +1,41 @@
+context = window
+rest = context.JK.Rest()
+logger = context.JK.logger
+
+AttachmentStore = context.AttachmentStore
+
+@AttachmentStatus = React.createClass({
+
+ mixins: [
+ Reflux.listenTo(AttachmentStore, "onAttachmentStore"),
+ ]
+
+ onAttachmentStore: (attachmentState) ->
+
+ componentDidMount: () ->
+ @root = $(@getDOMNode())
+ @attachmentNotation = @root.find('.attachment-notation')
+ @attachmentAudio = @root.find('.attachment-audio')
+
+ notationSelected: (e) ->
+ files = $(e.target).get(0).files
+ logger.debug("notation files selected: " + files)
+ window.AttachmentActions.uploadNotations(files)
+
+ audioSelected: (e) ->
+ files = $(e.target).get(0).files
+ logger.debug("audio files selected: " + files)
+
+ render: () ->
+ `
+
+
+
`
+
+})
+
diff --git a/web/app/assets/javascripts/react-components/JamClassScreen.js.jsx.coffee b/web/app/assets/javascripts/react-components/JamClassScreen.js.jsx.coffee
index 2278b6627..99f1ac078 100644
--- a/web/app/assets/javascripts/react-components/JamClassScreen.js.jsx.coffee
+++ b/web/app/assets/javascripts/react-components/JamClassScreen.js.jsx.coffee
@@ -94,6 +94,12 @@ LessonTimerActions = context.LessonTimerActions
SessionActions.enterSession(lesson.music_session.id)
else if data.lessonAction == 'reschedule'
@rescheduleLesson(lesson)
+ else if data.lessonAction == 'attach-recording'
+ window.AttachmentActions.startAttachRecording(lesson.id)
+ else if data.lessonAction == 'attach-notation'
+ window.AttachmentActions.startAttachNotation(lesson.id)
+ else if data.lessonAction == 'attach-audio'
+ window.AttachmentActions.startAttachAudio(lesson.id)
else if data.lessonAction == 'start-5-min'
rest.lessonStartTime({id: lessonId, minutes: 5}).done((response) => (@app.layout.notify({
title: 'Start Time Set',
@@ -560,7 +566,7 @@ LessonTimerActions = context.LessonTimerActions
`
my lessons
-
+
diff --git a/web/app/assets/javascripts/react-components/actions/AttachmentActions.js.coffee b/web/app/assets/javascripts/react-components/actions/AttachmentActions.js.coffee
new file mode 100644
index 000000000..b744ca86e
--- /dev/null
+++ b/web/app/assets/javascripts/react-components/actions/AttachmentActions.js.coffee
@@ -0,0 +1,8 @@
+context = window
+
+@AttachmentActions = Reflux.createActions({
+ startAttachRecording: {}
+ startAttachNotation: {}
+ startAttachAudio: {}
+ uploadNotations: {}
+})
diff --git a/web/app/assets/javascripts/react-components/stores/AttachmentStore.js.coffee b/web/app/assets/javascripts/react-components/stores/AttachmentStore.js.coffee
new file mode 100644
index 000000000..a94595513
--- /dev/null
+++ b/web/app/assets/javascripts/react-components/stores/AttachmentStore.js.coffee
@@ -0,0 +1,129 @@
+$ = jQuery
+context = window
+logger = context.JK.logger
+
+rest = context.JK.Rest()
+
+AttachmentActions = @AttachmentActions
+
+
+@AttachmentStore = Reflux.createStore(
+ {
+ listenables: AttachmentActions
+ lessonId: null
+ uploading: false
+
+ init: ->
+ # Register with the app store to get @app
+ this.listenTo(context.AppStore, this.onAppInit)
+
+ onAppInit: (@app) ->
+ @ui = new context.JK.UIHelper(@app);
+
+ recordingsSelected: (recordings) ->
+ logger.debug("recording selected", recordings)
+
+ onStartAttachRecording: (lessonId) ->
+ if @lessonId?
+ logger.warn("rejecting startAttachRecording attempt as currently busy")
+ return
+ @lessonId = lessonId
+
+ @ui.launchRecordingSelectorDialog([], (recordings) =>
+ @recordingsSelected(recordings)
+ )
+ @change()
+
+ onStartAttachNotation: (lessonId) ->
+ if @lessonId?
+ logger.warn("rejecting onStartAttachNotation attempt as currently busy")
+ return
+ @lessonId = lessonId
+
+ logger.debug("notation upload started")
+ @triggerNotation()
+ @change()
+
+ onStartAttachAudio: (lessonId) ->
+ if @lessonId?
+ logger.warn("rejecting onStartAttachAudio attempt as currently busy")
+ return
+ @lessonId = lessonId
+
+ logger.debug("audio upload started")
+ @triggerAudio()
+ @changed()
+
+ triggerNotation: () ->
+ if !@attachNotationBtn?
+ @attachNotationBtn = $('input.attachment-notation').eq(0)
+ @attachNotationBtn.trigger('click')
+
+ triggerAudio: () ->
+ if !@attachAudioBtn?
+ @attachAudioBtn = $('input.attachment-audio').eq(0)
+ @attachAudioBtn.trigger('click')
+
+
+ onUploadNotations: (notations, doneCallback, failCallback) ->
+ logger.debug("beginning upload of notations")
+ @uploading = true
+ @changed()
+
+ formData = new FormData()
+ maxExceeded = false;
+ $.each(notations, (i, file) => (
+ max = 10 * 1024 * 1024;
+ if file.size > max
+ maxExceeded = true
+ return false
+
+ formData.append('files[]', file)
+ ))
+
+ if maxExceeded
+ @app.notify({
+ title: "Maximum Music Notation Size Exceeded",
+ text: "You can only upload files up to 10 megabytes in size."
+ })
+ failCallback()
+ @uploading = false
+ @changed()
+ return
+
+
+ formData.append('client_id', app.clientId)
+ formData.append('lesson_session_id', @lessonid);
+
+ rest.uploadMusicNotations(formData)
+ .done((response) => @doneUploadingNotatations(notations, response))
+ .fail((jqXHR) => @failUploadingNotations(jqXHR))
+
+ doneUploadingNotatations: (notations, response) ->
+ error_files = [];
+ $.each(response, (i, music_notation) => (
+ if music_notation.errors
+ error_files.push(notations[i].name)
+ )
+ )
+ if error_files.length > 0
+ failCallback()
+ @app.notifyAlert("Failed to upload notations.", error_files.join(', '));
+ else
+ doneCallback()
+
+ failUploadingNotations: (jqXHR) ->
+ if jqXHR.status == 413
+ # the file is too big. Let the user know.
+ # This should happen when they select the file, but a misconfiguration on the server could cause this.
+ @app.notify({
+ title: "Maximum Music Notation Size Exceeded",
+ text: "You can only upload files up to 10 megabytes in size."
+ })
+ else
+ @app.notifyServerError(jqXHR, "Unable to upload music notations");
+
+ changed: () ->
+ this.trigger({lessonId: @lessonId, uploading: @uploading})
+ }
+)
\ No newline at end of file
diff --git a/web/app/assets/stylesheets/client/lessonSessionActions.css.scss b/web/app/assets/stylesheets/client/lessonSessionActions.css.scss
index 3b42c0153..f8d559669 100644
--- a/web/app/assets/stylesheets/client/lessonSessionActions.css.scss
+++ b/web/app/assets/stylesheets/client/lessonSessionActions.css.scss
@@ -13,12 +13,12 @@
}
&.is-scheduled .bt-content{
- height:122px;
+ height:185px;
width:120px;
}
&.is-admin .bt-content{
- height:152px;
+ height:215px;
width:135px;
}
diff --git a/web/app/assets/stylesheets/client/react-components/AttachmentStatus.css.scss b/web/app/assets/stylesheets/client/react-components/AttachmentStatus.css.scss
new file mode 100644
index 000000000..37386f2fb
--- /dev/null
+++ b/web/app/assets/stylesheets/client/react-components/AttachmentStatus.css.scss
@@ -0,0 +1,5 @@
+.attachment-status {
+ .hidden {
+ display:none;
+ }
+}
\ No newline at end of file
diff --git a/web/app/views/clients/_lessonSessionActions.html.slim b/web/app/views/clients/_lessonSessionActions.html.slim
index 570b351ab..26ebca9a7 100644
--- a/web/app/views/clients/_lessonSessionActions.html.slim
+++ b/web/app/views/clients/_lessonSessionActions.html.slim
@@ -34,6 +34,15 @@ script type='text/template' id='template-lesson-session-actions'
li data-lesson-option="messages"
a href='#' Attach Message
+ li data-lesson-option="attach-recording"
+ a href='#' Attach Recording
+
+ li data-lesson-option="attach-notation"
+ a href='#' Attach Notation File
+
+ li data-lesson-option="attach-audio"
+ a href='#' Attach Audio File
+
li data-lesson-option="join"
a href='#' Join Lesson Session
diff --git a/websocket-gateway/lib/jam_websockets/router.rb b/websocket-gateway/lib/jam_websockets/router.rb
index 1626d7a54..bec42b46b 100644
--- a/websocket-gateway/lib/jam_websockets/router.rb
+++ b/websocket-gateway/lib/jam_websockets/router.rb
@@ -1469,7 +1469,7 @@ module JamWebsockets
user = User.find_by_id(user_id) unless user_id.nil?
if music_session
- msuh = MusicSessionUserHistory.find_by_client_id(cid).order('updated_at DESC').first
+ msuh = MusicSessionUserHistory.where(client_id: cid).order('updated_at DESC').first
if msuh
msuh.session_removed_at = Time.now if msuh.session_removed_at.nil?
msuh.save(validate:false)