diff --git a/ruby/lib/jam_ruby/models/active_music_session.rb b/ruby/lib/jam_ruby/models/active_music_session.rb index c909156fe..16260f839 100644 --- a/ruby/lib/jam_ruby/models/active_music_session.rb +++ b/ruby/lib/jam_ruby/models/active_music_session.rb @@ -863,6 +863,10 @@ module JamRuby self.save!(:validate => false) end + def in_session?(user) + self.users.exists?(user.id) + end + def connected_participant_count Connection.where(:music_session_id => self.id, :aasm_state => Connection::CONNECT_STATE.to_s, diff --git a/ruby/lib/jam_ruby/models/recording.rb b/ruby/lib/jam_ruby/models/recording.rb index 0f2b10381..88c005875 100644 --- a/ruby/lib/jam_ruby/models/recording.rb +++ b/ruby/lib/jam_ruby/models/recording.rb @@ -75,6 +75,10 @@ module JamRuby has_stream_mix end + def can_stop?(user) + # only allow the starting-user to create (ideally, perhaps, only the client that did it) + user == owner + end # this should be a has-one relationship. until this, this is easiest way to get from recording > mix def mix self.mixes[0] if self.mixes.length > 0 @@ -214,7 +218,7 @@ module JamRuby def has_access?(user) return false if user.nil? - users.exists?(user.id) || attached_with_lesson(user) || (music_session && music_session.part_of_session?(user)) + users.exists?(user.id) || attached_with_lesson(user) || (music_session && music_session.in_session?(user)) end def attached_with_lesson(user) diff --git a/web/app/assets/javascripts/react-components/SessionRecordBtn.js.jsx.coffee b/web/app/assets/javascripts/react-components/SessionRecordBtn.js.jsx.coffee index 6cc032783..c3da9cd5b 100644 --- a/web/app/assets/javascripts/react-components/SessionRecordBtn.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/SessionRecordBtn.js.jsx.coffee @@ -11,7 +11,7 @@ AppStore = context.AppStore onSessionMixerChange: (sessionMixers) -> #console.log("_DEBUG_* SessionRecordBtn onSessionMixerChange", sessionMixers.session) @setState({isRecording: sessionMixers.session.isRecording}) - @setState({isRecordingOwner: sessionMixers.session.recordingOwnerId && sessionMixers.session.recordingOwnerId == @app.currentUserId}) + @setState({thisClientStartedRecording: sessionMixers.session.thisClientStartedRecording}) getInitialState: () -> {childWindow: null, isRecording: false} @@ -25,7 +25,7 @@ AppStore = context.AppStore return 'noclose' handleClick: () -> - if @state.isRecording && @state.isRecordingOwner + if @state.isRecording && @state.thisClientStartedRecording RecordingActions.stopRecording() else @openRecording() @@ -52,8 +52,8 @@ AppStore = context.AppStore render: () -> btnStyles = "session-record session-record-btn left" - if this.state.isRecording - if this.state.isRecordingOwner + if this.state.isRecording + if this.state.thisClientStartedRecording btnStyles = btnStyles+' button-orange' ` diff --git a/web/app/assets/javascripts/react-components/SessionRecordingSettings.js.jsx.coffee b/web/app/assets/javascripts/react-components/SessionRecordingSettings.js.jsx.coffee index 5cab385fc..19e6ff13a 100644 --- a/web/app/assets/javascripts/react-components/SessionRecordingSettings.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/SessionRecordingSettings.js.jsx.coffee @@ -23,7 +23,7 @@ mixins.push(Reflux.listenTo(RecordingStore, "onRecordingStateChanged")) # @setState({audioFormat: recordingState.audioRecordingFormat}) onRecordingStateChanged: `function (recordingState) { - console.log('_REC_ onRecordingStateChanged', recordingState); + //console.log('_REC_ onRecordingStateChanged', recordingState); if (recordingState.audioRecordingFormat) { this.setState({audioFormat: recordingState.audioRecordingFormat}); } diff --git a/web/app/assets/javascripts/react-components/SessionRecordingStatus.js.jsx.coffee b/web/app/assets/javascripts/react-components/SessionRecordingStatus.js.jsx.coffee index 1fa82f09a..489ca5f47 100644 --- a/web/app/assets/javascripts/react-components/SessionRecordingStatus.js.jsx.coffee +++ b/web/app/assets/javascripts/react-components/SessionRecordingStatus.js.jsx.coffee @@ -41,7 +41,11 @@ RecordingStore = @RecordingStore events = [] for event in @state.events events.push(`
  • {event[0]} brid={event[1]}
  • `) - body = `
    {recording} {cause} {waitingOnClientStop} {waitingOnServerStop}
    ` + + initiator = "" + if this.state.thisClientStartedRecording + initiator = "Initatior" + body = `
    {recording} {initiator} {cause} {waitingOnClientStop} {waitingOnServerStop}
    ` `
    {body} diff --git a/web/app/assets/javascripts/react-components/helpers/SessionHelper.js.coffee b/web/app/assets/javascripts/react-components/helpers/SessionHelper.js.coffee index d8af09d29..3f853b573 100644 --- a/web/app/assets/javascripts/react-components/helpers/SessionHelper.js.coffee +++ b/web/app/assets/javascripts/react-components/helpers/SessionHelper.js.coffee @@ -2,7 +2,7 @@ context = window @SessionHelper = class SessionHelper - constructor: (app, session, participantsEverSeen, isRecording, downloadingJamTrack, preppingVstEnable, sessionRules, subscriptionRules, recordingOwnerId) -> + constructor: (app, session, participantsEverSeen, isRecording, downloadingJamTrack, preppingVstEnable, sessionRules, subscriptionRules, thisClientStartedRecording) -> @app = app @session = session @participantsEverSeen = participantsEverSeen @@ -12,7 +12,7 @@ context = window @isLesson = @session?.lesson_session? @sessionRules = sessionRules @subscriptionRules = subscriptionRules - @recordingOwnerId = recordingOwnerId + @thisClientStartedRecording = thisClientStartedRecording if @isLesson @lessonId = @session.lesson_session.id diff --git a/web/app/assets/javascripts/react-components/stores/RecordingStore.js.jsx b/web/app/assets/javascripts/react-components/stores/RecordingStore.js.jsx index 25c8df1cb..dfb368610 100644 --- a/web/app/assets/javascripts/react-components/stores/RecordingStore.js.jsx +++ b/web/app/assets/javascripts/react-components/stores/RecordingStore.js.jsx @@ -34,35 +34,42 @@ window.RecordingStore = Reflux.createStore({ onInitModel(recordingModel) { this.recordingModel = recordingModel; this.events = []; - this.trigger({ isRecording: this.recordingModel.isRecording(), events: this.events }); + this.trigger({ isRecording: this.recordingModel.isRecording(), events: this.events, thisClientStartedRecording: false }); }, onResetRecordingState() { console.log("onResetRecordingState"); this.events = [] - this.trigger({ isRecording: this.recordingModel.isRecording(), cause: '', events: this.events }); + this.trigger({ isRecording: this.recordingModel.isRecording(), cause: '', events: this.events, thisClientStartedRecording: false }); }, - onStartRecording(recordSettings) { + async augmentWithBackendRecordingId(lastEvent) { + const backendRecordingId = await context.jamClient.GetCurrentRecordingId(); + lastEvent.push(backendRecordingId); + return backendRecordingId; + }, + + async onStartRecording(recordSettings) { this.recordingModel.startRecording(recordSettings); this.events = []; this.events.push(["StartRecording"]); - this.augmentWithBackendRecordingId(this.events); - this.trigger({ events: this.events }); + await this.augmentWithBackendRecordingId(this.events[this.events.length - 1]); + this.trigger({ events: this.events, thisClientStartedRecording: this.recordingModel.getThisClientStartedRecording() }); }, - onStopRecording() { + async onStopRecording() { this.recordingModel.stopRecording(); this.events.push(["StopRecording"]); - this.augmentWithBackendRecordingId(this.events); - this.trigger({ events: this.events }); + await this.augmentWithBackendRecordingId(this.events[this.events.length - 1]); + this.trigger({ events: this.events, thisClientStartedRecording: this.recordingModel.getThisClientStartedRecording() }); }, - onStartingRecording(details) { + async onStartingRecording(details) { details.cause = 'starting'; + details.thisClientStartedRecording = this.recordingModel.getThisClientStartedRecording(); this.mixTransferred = false; this.events.push(["OnStartingRecording"]); - this.augmentWithBackendRecordingId(this.events); + await this.augmentWithBackendRecordingId(this.events[this.events.length - 1]); details.events = this.events; this.trigger(details); if (!this.recordingWindowOpened) { @@ -70,37 +77,44 @@ window.RecordingStore = Reflux.createStore({ } }, - async augmentWithBackendRecordingId(events) { - const backendRecordingId = await context.jamClient.GetCurrentRecordingId(); - events[events.length - 1].push(backendRecordingId); - }, - - onStartedRecording(details) { + async onStartedRecording(details) { details.cause = 'started'; + details.thisClientStartedRecording = this.recordingModel.getThisClientStartedRecording(); this.mixTransferred = false; this.events.push(["OnStartedRecording"]); details.events = this.events; - this.augmentWithBackendRecordingId(this.events); - this.trigger(details); + const backendRecordingId = await this.augmentWithBackendRecordingId(this.events[this.events.length - 1]); + if(backendRecordingId == null) { + // if recording Id is empty here, we need to unwind that we are recording. + console.error("No backend recording ID present when startRecording signal received"); + context.JK.Banner.showAlert("The JamKazam application is out-of-sync on this start of this recording. " + + "Please leave the session and re-join to fix the issue."); + this.recordingModel.stopRecording(this.recordingModel.currentOrLastRecordingId(), "start-failure", "backend recording ID not set on started signal"); + } + else { + this.trigger(details); + } if (this.recordingWindowOpened) { this.closeRecordingWindow(); } }, - onStoppingRecording(details) { + async onStoppingRecording(details) { details.cause = 'stopping'; + details.thisClientStartedRecording = this.recordingModel.getThisClientStartedRecording(); this.events.push(["OnStoppingRecording"]); details.events = this.events; - this.augmentWithBackendRecordingId(this.events); + await this.augmentWithBackendRecordingId(this.events[this.events.length - 1]); this.trigger(details); }, - onStoppedRecording(details) { + async onStoppedRecording(details) { details.cause = 'stopped'; + details.thisClientStartedRecording = this.recordingModel.getThisClientStartedRecording(); this.events.push(["OnStoppedRecording"]); details.events = this.events; - this.augmentWithBackendRecordingId(this.events); + await this.augmentWithBackendRecordingId(this.events[this.events.length - 1]); if (this.recordingWindowOpened) { this.closeRecordingWindow(); @@ -109,11 +123,12 @@ window.RecordingStore = Reflux.createStore({ this.trigger(details); }, - onAbortedRecording(details) { + async onAbortedRecording(details) { details.cause = 'aborted'; + details.thisClientStartedRecording = this.recordingModel.getThisClientStartedRecording(); this.events.push(["OnAbortedRecording"]); details.events = this.events; - this.augmentWithBackendRecordingId(this.events); + await this.augmentWithBackendRecordingId(this.events[this.events.length - 1]); if (this.recordingWindowOpened) { this.closeRecordingWindow(); @@ -141,7 +156,7 @@ window.RecordingStore = Reflux.createStore({ onAudioRecordingFormatChanged(audioFormat) { console.log("_DEBUG_ onAudioRecordingFormatChanged", JSON.stringify(this.recordingModel)); - this.trigger({ audioRecordingFormat: audioFormat, isRecording: this.recordingModel.isRecording() }); + this.trigger({ audioRecordingFormat: audioFormat, isRecording: this.recordingModel.isRecording(), thisClientStartedRecording: this.recordingModel.getThisClientStartedRecording() }); }, popupRecordingControls() { diff --git a/web/app/assets/javascripts/react-components/stores/SessionStore.js.coffee b/web/app/assets/javascripts/react-components/stores/SessionStore.js.coffee index f11844595..f8bab1d50 100644 --- a/web/app/assets/javascripts/react-components/stores/SessionStore.js.coffee +++ b/web/app/assets/javascripts/react-components/stores/SessionStore.js.coffee @@ -44,6 +44,7 @@ ConfigureTracksActions = @ConfigureTracksActions openBackingTrack: null helper: null downloadingJamTrack: false + startedRecording: false init: -> # Register with the app store to get @app @@ -57,7 +58,7 @@ ConfigureTracksActions = @ConfigureTracksActions @sessionUtils = context.JK.SessionUtils @recordingModel = new context.JK.RecordingModel(@app, rest, context.jamClient); RecordingActions.initModel(@recordingModel) - @helper = new context.SessionHelper(@app, @currentSession, @participantsEverSeen, @isRecording, @downloadingJamTrack, @enableVstTimeout?, @sessionRules, @subscriptionRules, @recordingOwnerId) + @helper = new context.SessionHelper(@app, @currentSession, @participantsEverSeen, @isRecording, @downloadingJamTrack, @enableVstTimeout?, @sessionRules, @subscriptionRules, @thisClientStartedRecording) # onSessionJoinedByOther: (payload) -> # clientId = payload.client_id @@ -95,7 +96,7 @@ ConfigureTracksActions = @ConfigureTracksActions onVideoChanged: (@videoState) -> issueChange: () -> - @helper = new context.SessionHelper(@app, @currentSession, @participantsEverSeen, @isRecording, @downloadingJamTrack, @enableVstTimeout?, @sessionRules, @subscriptionRules, @recordingOwnerId) + @helper = new context.SessionHelper(@app, @currentSession, @participantsEverSeen, @isRecording, @downloadingJamTrack, @enableVstTimeout?, @sessionRules, @subscriptionRules, @thisClientStartedRecording) this.trigger(@helper) onWindowBackgrounded: () -> @@ -885,12 +886,14 @@ ConfigureTracksActions = @ConfigureTracksActions onRecordingChanged: `async function(details) { let detail, reason, timeline, title; logger.debug("SessionStore.onRecordingChanged: " + details.cause); - //console.log("_DEBUG_* SessionStore.onRecordingChanged: " + JSON.stringify(details)); - //this.isRecording = details.isRecording; + // console.log("_DEBUG_* SessionStore.onRecordingChanged: " + JSON.stringify(details)); + this.isRecording = details.isRecording; + + this.thisClientStartedRecording = details.thisClientStartedRecording; this.recordingClinetId = details.clientId; - let recordingState = await this.recordingModel.getCurrentRecordingState(); - this.recordingOwnerId = recordingState.recordingOwnerId; - this.isRecording = recordingState.isRecording; + //let recordingState = await this.recordingModel.getCurrentRecordingState(); + //this.recordingOwnerId = recordingState.recordingOwnerId; + //this.isRecording = recordingState.isRecording; switch (details.cause) { case 'started': @@ -2022,7 +2025,6 @@ ConfigureTracksActions = @ConfigureTracksActions //} //logger.debug("session changed") - logger.debug("issue change"); return this.issueChange(); }` diff --git a/web/app/assets/javascripts/recordingModel.js b/web/app/assets/javascripts/recordingModel.js index 6b593f58d..8f7f5a095 100644 --- a/web/app/assets/javascripts/recordingModel.js +++ b/web/app/assets/javascripts/recordingModel.js @@ -22,6 +22,7 @@ var currentRecording = null; // the JSON response from the server for a recording var currentOrLastRecordingId = null; var currentRecordingId = null; + var thisClientStartedRecording = false; // set by the person who starts it var rest = _rest; var currentlyRecording = false; var startingRecording = false; @@ -53,6 +54,10 @@ } } + function getThisClientStartedRecording() { + return thisClientStartedRecording; + } + /** called every time a session is joined, to ensure clean state */ function reset(_sessionId) { console.log("[RecordingState]: reset") @@ -66,6 +71,7 @@ currentRecording = null; currentRecordingId = null; stoppingRecording = false; + thisClientStartedRecording = false; sessionId = _sessionId } @@ -97,6 +103,7 @@ currentlyRecording = true; stoppingRecording = false; + thisClientStartedRecording = true; context.RecordingActions.startingRecording({isRecording: false}) @@ -134,9 +141,7 @@ // return; //} - const isRecordingOwner = recording.owner.id == context.JK.currentUserId; - - console.log(`[RecordingState]: stopRecording userInitiated=${userInitiated} isRecordingOwner=${isRecordingOwner} reason=${reason} detail=${detail}`) + console.log(`[RecordingState]: stopRecording userInitiated=${userInitiated} thisClientStartedRecording=${thisClientStartedRecording} reason=${reason} detail=${detail}`) if(stoppingRecording) { console.log("ignoring stopRecording because we are already stopping"); @@ -165,7 +170,7 @@ //await jamClient.StopRecording(recording.id, groupedTracks); await jamClient.FrontStopRecording(recording.id, groupedTracks); - if(isRecordingOwner) { + if(thisClientStartedRecording) { rest.stopRecording({"id": recording.id}) .done(function () { waitingOnServerStop = false; @@ -250,7 +255,7 @@ context.SessionStore.updateSessionInfo(session, true) getCurrentRecordingState().then(function (recordingState) { - if (recordingState.isRecording && recordingState.recordingOwnerId === app.currentUserId) { + if (recordingState.isRecording && recordingState.thisClientStartedRecording) { // we are still recording, so don't transition to stopped console.log("recording is still running, so don't transition to stopped"); return; @@ -306,7 +311,33 @@ } } + function postServerRecordingFetch(recording) { + + if(currentRecordingId == null) { + currentRecordingId = recording.id; + currentOrLastRecordingId = recording.id; + + var details = {recordingId: currentRecordingId, isRecording: false} + $self.triggerHandler('startingRecording', details); + context.RecordingActions.startingRecording(details); + currentlyRecording = true; + + details = {clientId: app.clientId, recordingId: currentRecordingId, isRecording: true} + $self.triggerHandler('startedRecording', details); + context.RecordingActions.startedRecording(details); + } + else if (currentRecordingId == recording.id) { + // noop - we fetched recording but we already know about it + } + else { + console.error("[RecordingState] we've missed the stop of previous recording", currentRecordingId, recording.id); + context.JK.Banner.showAlert("The JamKazam application is out-of-sync on this recording. " + + "Please leave the session and re-join to fix the issue."); + } + } + function handleRecordingStarted(recordingId, result, clientId) { + reset(sessionId); context.RecordingActions.resetRecordingState() console.log("[RecordingState] handleRecordingStarted called", { @@ -339,8 +370,7 @@ currentUserId: context.JK.currentUserId, recordingState: recording }); - currentRecordingId = recording.id; - currentOrLastRecordingId = recording.id; + postServerRecordingFetch(recording) }) .catch(function(error) { console.error("[RecordingState] Failed to fetch recording data", { @@ -355,15 +385,6 @@ currentlyRecording }); }); - - var details = {recordingId: recordingId, isRecording: false} - $self.triggerHandler('startingRecording', details); - context.RecordingActions.startingRecording(details) - currentlyRecording = true; - - details = {clientId: clientId, recordingId: recordingId, isRecording: true} - $self.triggerHandler('startedRecording', details); - context.RecordingActions.startedRecording(details) } function handleRecordingStopped(recordingId, result) { @@ -374,17 +395,11 @@ context.SessionStore.updateSessionInfo(session, true) } - // if(recordState.isRecording) { - // //we are still recording, so don't stop - // return; - // } - if(recordingId == "video") { // comes from VideoRecordingStopped return; } - var success = result.success; var reason = result.reason; var detail = result.detail; @@ -399,40 +414,41 @@ if(recordingId == null || recordingId == "") { // this occurs when you are told by the backend to stop; i.e., you are a non-creator of the // recording. Stop, don't tell the server to stop; you aren't supposed to hve permission to + transitionToStopped(); var details = {recordingId: recordingId, reason: reason, detail: detail, isRecording: false} - context.RecordingActions.stoppedRecording(details) + context.RecordingActions.stoppedRecording(details); return; } rest.stopRecording({ id: recordingId }) - .always(function() { - transitionToStopped(); - }) - .fail(function(jqXHR, textStatus, errorMessage) { - if(jqXHR.status == 422) { - console.log("recording already stopped %o", arguments); - var details = {recordingId: recordingId, reason: reason, detail: detail, isRecording: false} - $self.triggerHandler('stoppedRecording', details); - context.RecordingActions.stoppedRecording(details) - } - else if(jqXHR.status == 404) { - console.log("recording is already deleted %o", arguments); - var details = {recordingId: recordingId, reason: reason, detail: detail, isRecording: false} - $self.triggerHandler('stoppedRecording', details); - context.RecordingActions.stoppedRecording(details) - } - else { - var details = {recordingId: recordingId, reason: textStatus, detail: errorMessage, isRecording: false} - $self.triggerHandler('stoppedRecording', details); - context.RecordingActions.stoppedRecording(details) - } - }) - .done(function() { + .always(function() { + transitionToStopped(); + }) + .fail(function(jqXHR, textStatus, errorMessage) { + if(jqXHR.status == 422) { + console.log("recording already stopped %o", arguments); var details = {recordingId: recordingId, reason: reason, detail: detail, isRecording: false} $self.triggerHandler('stoppedRecording', details); context.RecordingActions.stoppedRecording(details) - }) + } + else if(jqXHR.status == 404) { + console.log("recording is already deleted %o", arguments); + var details = {recordingId: recordingId, reason: reason, detail: detail, isRecording: false} + $self.triggerHandler('stoppedRecording', details); + context.RecordingActions.stoppedRecording(details) + } + else { + var details = {recordingId: recordingId, reason: textStatus, detail: errorMessage, isRecording: false} + $self.triggerHandler('stoppedRecording', details); + context.RecordingActions.stoppedRecording(details) + } + }) + .done(function() { + var details = {recordingId: recordingId, reason: reason, detail: detail, isRecording: false} + $self.triggerHandler('stoppedRecording', details); + context.RecordingActions.stoppedRecording(details) + }) } function handleRecordingAborted(recordingId, result) { @@ -516,7 +532,6 @@ async function getCurrentRecordingState() { var recording = null; var session = context.SessionStore.getCurrentOrLastSession(); - var recordingId = await context.jamClient.GetCurrentRecordingId(); var isRecording = recordingId && recordingId != ""; @@ -541,13 +556,13 @@ if (!session) { console.debug("no session, so no recording"); - return { isRecording: false, serverRecording: null, recordingOwnerId: null }; + return { isRecording: false, serverRecording: null, thisClientStartedRecording: false }; } return { isRecording: isRecording, isServerRecording: !!recording, - recordingOwnerId: isRecording && recording ? recording.owner.id : null, + thisClientStartedRecording: thisClientStartedRecording } } @@ -560,6 +575,7 @@ this.onServerStopRecording = onServerStopRecording; this.onServerStartRecording = onServerStartRecording; this.isRecording = isRecording; + this.getThisClientStartedRecording = getThisClientStartedRecording; this.reset = reset; this.stopRecordingIfNeeded = stopRecordingIfNeeded; this.getState = getState; diff --git a/web/app/assets/javascripts/sidebar.js b/web/app/assets/javascripts/sidebar.js index dc76ccf89..2e7396bb4 100644 --- a/web/app/assets/javascripts/sidebar.js +++ b/web/app/assets/javascripts/sidebar.js @@ -290,19 +290,20 @@ if (app.clientId !== payload.client_id) { - var recordingId = payload.recording_id; + // this logic below is from when anyone leaving would stop a recording + //var recordingId = payload.recording_id; //console.log("Sidebar: SESSION_DEPART isRecording", context.RecordingStore.recordingModel.isRecording(recordingId)); - if (recordingId && context.RecordingStore.recordingModel.isRecording(recordingId)) { + //if (recordingId && context.RecordingStore.recordingModel.isRecording(recordingId)) { //alert("Sidebar: SESSION_DEPART: calling onServerStopRecording"); - context.RecordingStore.recordingModel.onServerStopRecording(recordingId); - } - else { + //context.RecordingStore.recordingModel.onServerStopRecording(recordingId); + //} + // else { app.notify({ "title": "Musician Left Session", "text": payload.msg, "icon_url": context.JK.resolveAvatarUrl(payload.photo_url) }); - } + //} } //if (context.jamClient.ClientLeftSession) { await context.jamClient.ClientLeftSession(payload["source_user_id"], payload["client_id"], payload["session_id"]) diff --git a/web/app/controllers/api_recordings_controller.rb b/web/app/controllers/api_recordings_controller.rb index 3564e514e..640f33bbd 100644 --- a/web/app/controllers/api_recordings_controller.rb +++ b/web/app/controllers/api_recordings_controller.rb @@ -186,6 +186,10 @@ class ApiRecordingsController < ApiController end def stop + # only allow the creator to stop the recording + if @recording.can_stop?(current_user) == false + raise JamPermissionError, ValidationMessages::PERMISSION_VALIDATION_ERROR + end @recording.stop diff --git a/web/config/application.rb b/web/config/application.rb index c4d736654..8b2697739 100644 --- a/web/config/application.rb +++ b/web/config/application.rb @@ -386,6 +386,7 @@ if defined?(Bundler) config.video_available = "full" config.alerts_api_enabled = true + config.show_recording_debug_status = false config.gear_check_ignore_high_latency = false config.remove_whitespace_credit_card = false config.estimate_taxes = true diff --git a/web/config/environments/development.rb b/web/config/environments/development.rb index 445be24a3..729cc059e 100644 --- a/web/config/environments/development.rb +++ b/web/config/environments/development.rb @@ -112,6 +112,8 @@ SampleApp::Application.configure do config.rating_dialog_min_num = 1 config.root_redirect_on = false + config.show_recording_debug_status = true + config.video_conferencing_host = "http://localhost:3001" config.use_video_conferencing_server = true config.latency_data_host = "http://localhost:4001/local" diff --git a/web/config/initializers/gon.rb b/web/config/initializers/gon.rb index cbf6ec62e..6f675776f 100644 --- a/web/config/initializers/gon.rb +++ b/web/config/initializers/gon.rb @@ -31,5 +31,6 @@ Gon.global.braintree_token = Rails.application.config.braintree_token Gon.global.paypal_admin_only = Rails.application.config.paypal_admin_only Gon.global.use_video_conferencing_server = Rails.application.config.use_video_conferencing_server Gon.global.manual_override_installer_ends_with = Rails.application.config.manual_override_installer_ends_with +Gon.global.show_recording_debug_status = Rails.application.config.show_recording_debug_status Gon.global.env = Rails.env Gon.global.version = ::JamWeb::VERSION