diff --git a/web/app/assets/javascripts/lesson_utils.js.coffee b/web/app/assets/javascripts/lesson_utils.js.coffee
new file mode 100644
index 000000000..d8a8d67ae
--- /dev/null
+++ b/web/app/assets/javascripts/lesson_utils.js.coffee
@@ -0,0 +1,39 @@
+#
+# Common utility functions.
+#
+
+$ = jQuery
+context = window
+context.JK ||= {};
+
+class LessonUtils
+ constructor: () ->
+ @logger = context.JK.logger
+
+ init: () =>
+
+ getTimeRemaining: (endtime) ->
+ t = new Date(endtime).getTime() - new Date().getTime()
+
+ originalT = t
+
+ if t < 0
+ seconds = Math.ceil( (t/1000) % 60 );
+ minutes = Math.ceil( (t/1000/60) % 60 );
+ hours = Math.ceil( (t/(1000*60*60)) % 24 );
+ days = Math.ceil( t/(1000*60*60*24) );
+ else
+ seconds = Math.floor( (t/1000) % 60 );
+ minutes = Math.floor( (t/1000/60) % 60 );
+ hours = Math.floor( (t/(1000*60*60)) % 24 );
+ days = Math.floor( t/(1000*60*60*24) );
+
+ return {
+ 'total': originalT,
+ 'days': days,
+ 'hours': hours,
+ 'minutes': minutes,
+ 'seconds': seconds
+ };
+# global instance
+context.JK.LessonUtils = new LessonUtils()
\ No newline at end of file
diff --git a/web/app/assets/javascripts/react-components.js b/web/app/assets/javascripts/react-components.js
index c8f7b2fb0..5e3fb6c53 100644
--- a/web/app/assets/javascripts/react-components.js
+++ b/web/app/assets/javascripts/react-components.js
@@ -6,6 +6,7 @@
//= require ./react-components/stores/NavStore
//= require ./react-components/stores/UserStore
//= require ./react-components/stores/UserActivityStore
+//= require ./react-components/stores/LessonTimerStore
//= require ./react-components/stores/SchoolStore
//= require ./react-components/stores/StripeStore
//= require ./react-components/stores/AvatarStore
diff --git a/web/app/assets/javascripts/react-components/InLessonBroadcast.js.jsx.coffee b/web/app/assets/javascripts/react-components/InLessonBroadcast.js.jsx.coffee
index fc85530ab..cccbe2b29 100644
--- a/web/app/assets/javascripts/react-components/InLessonBroadcast.js.jsx.coffee
+++ b/web/app/assets/javascripts/react-components/InLessonBroadcast.js.jsx.coffee
@@ -43,7 +43,6 @@ context = window
timeString
render: () ->
- console.log("@props.lessonSession", @props.lessonSession)
if @props.lessonSession.completed
if @props.lessonSession.success
content = `
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 d9f78a228..f45d34819 100644
--- a/web/app/assets/javascripts/react-components/JamClassScreen.js.jsx.coffee
+++ b/web/app/assets/javascripts/react-components/JamClassScreen.js.jsx.coffee
@@ -3,6 +3,8 @@ rest = context.JK.Rest()
logger = context.JK.logger
UserStore = context.UserStore
+LessonTimerStore = context.LessonTimerStore
+LessonTimerActions = context.LessonTimerActions
@JamClassScreen = React.createClass({
@@ -10,7 +12,8 @@ UserStore = context.UserStore
@ICheckMixin,
@PostProcessorMixin,
Reflux.listenTo(AppStore, "onAppInit"),
- Reflux.listenTo(UserStore, "onUserChanged")
+ Reflux.listenTo(UserStore, "onUserChanged"),
+ Reflux.listenTo(LessonTimerStore, "onLessonTimersChanged")
]
lookup : {
@@ -38,9 +41,20 @@ UserStore = context.UserStore
onUserChanged: (userState) ->
@setState({user: userState?.user})
+ onLessonTimersChanged: (lessons) ->
+ @setState({lessonTimes: lessons})
+
componentDidMount: () ->
@root = $(@getDOMNode())
+ componentWillUpdate: (nextProps, nextState) ->
+ # associate time info from LessonTimerStore with our lesson info
+ if nextState.lessonTimes? && nextState.lesson_sessions?.entries?
+ for lesson in nextState.lesson_sessions.entries
+ lessonWithTime = nextState.lessonTimes[lesson.id]
+ if lessonWithTime?
+ lesson.times = lessonWithTime.times
+
componentDidUpdate: () ->
items = @root.find('.jamtable tbody td.actionsColumn .lesson-session-actions-btn')
@@ -221,6 +235,7 @@ UserStore = context.UserStore
@postProcess(response)
+ LessonTimerActions.loadLessons(response)
@setState({lesson_sessions: response})
failedJamClassLoad: (jqXHR) ->
@@ -410,9 +425,22 @@ UserStore = context.UserStore
unreadMessages = `

`
else
unreadMessages = null
+
+ timeStmt = lessonData.music_session.pretty_scheduled_start_with_timezone
+
+ if lessonData.times?
+ if lessonData.times.startingSoon
+ timeStmt = "Starts in #{lessonData.times.until.minutes} minutes"
+ else if lessonData.times.initialWindow
+ minutes = -lessonData.times.until.minutes
+
+ if minutes == 1
+ timeStmt = "This lesson just started. Join now!"
+ else
+ timeStmt = "Started #{minutes} minutes ago. Join now!"
lesson = `
{lessonData.other.first_name} {lessonData.other.last_name} |
- {lessonData.music_session.pretty_scheduled_start_with_timezone} |
+ {timeStmt} |
{lessonData.displayStatus} |
{unreadMessages} |
menu |
diff --git a/web/app/assets/javascripts/react-components/LessonBookingDecision.js.jsx.coffee b/web/app/assets/javascripts/react-components/LessonBookingDecision.js.jsx.coffee
index 1ede418fd..f7cd658a2 100644
--- a/web/app/assets/javascripts/react-components/LessonBookingDecision.js.jsx.coffee
+++ b/web/app/assets/javascripts/react-components/LessonBookingDecision.js.jsx.coffee
@@ -74,9 +74,13 @@
if name == 'slot-decision'
value = $(e.target).val()
+ logger.debug("LessonBookingDecision: slot-decision made with value: " + value)
+
+ @setState({slot_decision: value})
@props.onSlotDecision({slot_decision: value})
else if name == 'update-all'
checked = $(e.target).is(':checked')
+ logger.debug("LessonBookingDecision: update-all changed: " + checked)
@props.onUpdateAllDecision({update_all: checked})
else
throw "checkbox changed with unknown name #{name}"
diff --git a/web/app/assets/javascripts/react-components/actions/LessonTimerActions.js.coffee b/web/app/assets/javascripts/react-components/actions/LessonTimerActions.js.coffee
new file mode 100644
index 000000000..bf812cc97
--- /dev/null
+++ b/web/app/assets/javascripts/react-components/actions/LessonTimerActions.js.coffee
@@ -0,0 +1,6 @@
+context = window
+
+@LessonTimerActions = Reflux.createActions({
+ loadLessons: {}
+})
+
diff --git a/web/app/assets/javascripts/react-components/stores/BroadcastStore.js.coffee b/web/app/assets/javascripts/react-components/stores/BroadcastStore.js.coffee
index fb5f69aab..150b4f939 100644
--- a/web/app/assets/javascripts/react-components/stores/BroadcastStore.js.coffee
+++ b/web/app/assets/javascripts/react-components/stores/BroadcastStore.js.coffee
@@ -21,32 +21,10 @@ BroadcastStore = Reflux.createStore(
this.listenTo(context.AppStore, this.onAppInit)
this.listenTo(context.SessionStore, this.onSessionChange)
this.listenTo(context.NavStore, this.onNavChange)
+ @lessonUtils = context.JK.LessonUtils
onAppInit: (@app) ->
- getTimeRemaining: (endtime) ->
- t = new Date(endtime).getTime() - new Date().getTime()
-
- originalT = t
-
- if t < 0
- seconds = Math.ceil( (t/1000) % 60 );
- minutes = Math.ceil( (t/1000/60) % 60 );
- hours = Math.ceil( (t/(1000*60*60)) % 24 );
- days = Math.ceil( t/(1000*60*60*24) );
- else
- seconds = Math.floor( (t/1000) % 60 );
- minutes = Math.floor( (t/1000/60) % 60 );
- hours = Math.floor( (t/(1000*60*60)) % 24 );
- days = Math.floor( t/(1000*60*60*24) );
-
- return {
- 'total': originalT,
- 'days': days,
- 'hours': hours,
- 'minutes': minutes,
- 'seconds': seconds
- };
lessonTick: () ->
@timeManagement()
@@ -55,7 +33,7 @@ BroadcastStore = Reflux.createStore(
timeManagement: () ->
lastCheck = $.extend({}, @currentLesson)
lessonSession = @currentLesson
- lessonSession.until = @getTimeRemaining(lessonSession.scheduled_start)
+ lessonSession.until = @lessonUtils.getTimeRemaining(lessonSession.scheduled_start)
if lessonSession.until.total < 0
# we are past the start time
if lessonSession.until.total > -(10 * 60 * 1000) # 10 minutes
diff --git a/web/app/assets/javascripts/react-components/stores/LessonTimerStore.js.coffee b/web/app/assets/javascripts/react-components/stores/LessonTimerStore.js.coffee
new file mode 100644
index 000000000..dd101d0e8
--- /dev/null
+++ b/web/app/assets/javascripts/react-components/stores/LessonTimerStore.js.coffee
@@ -0,0 +1,55 @@
+$ = jQuery
+context = window
+logger = context.JK.logger
+rest = new context.JK.Rest()
+
+@LessonTimerStore = Reflux.createStore(
+ {
+ listenables: @LessonTimerActions
+ lessons: {}
+ slowTime: 10000
+ fastTime: 1000
+
+ init: ( ) ->
+ @timer()
+ this.listenTo(context.AppStore, this.onAppInit)
+
+ onAppInit: (@app) ->
+ @lessonUtils = context.JK.LessonUtils
+
+ timer: () ->
+ setInterval((() => @timeout()), @fastTime)
+
+ onLoadLessons: (lessons) ->
+ for lesson in lessons?.entries
+ @lessons[lesson.id] = lesson
+
+ timeout: () ->
+
+ for id, lesson of @lessons
+ untilInfo = @lessonUtils.getTimeRemaining(lesson.music_session.scheduled_start)
+
+ initialWindow = false
+ inThePast = false
+ beforeSession = false
+ startingSoon = false
+
+ if untilInfo.total < 0
+ # we are past the start time
+ if untilInfo.total > -(10 * 60 * 1000) # 10 minutes
+ initialWindow = true
+ else if untilInfo.total > -(15*60*1000) # 15 minute
+ inThePast = true
+ else
+ # we are before the due time
+ beforeSession = true
+ startingSoon = untilInfo.total <= (60 * 60 * 1000) # 60 minutes - 1hr until start time
+
+ lesson.times = {until:untilInfo, initialWindow: initialWindow, beforeSession: beforeSession, startingSoon: startingSoon, inThePast: inThePast}
+
+ @changed()
+
+ changed:() ->
+ this.trigger(@lessons)
+ }
+)
\ No newline at end of file