Recording seems to be working well enough atm. With new clients only

This commit is contained in:
Seth Call 2025-06-08 22:24:37 -05:00
parent e83805bd4a
commit 324d34ff61
14 changed files with 152 additions and 98 deletions

View File

@ -863,6 +863,10 @@ module JamRuby
self.save!(:validate => false) self.save!(:validate => false)
end end
def in_session?(user)
self.users.exists?(user.id)
end
def connected_participant_count def connected_participant_count
Connection.where(:music_session_id => self.id, Connection.where(:music_session_id => self.id,
:aasm_state => Connection::CONNECT_STATE.to_s, :aasm_state => Connection::CONNECT_STATE.to_s,

View File

@ -75,6 +75,10 @@ module JamRuby
has_stream_mix has_stream_mix
end 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 # this should be a has-one relationship. until this, this is easiest way to get from recording > mix
def mix def mix
self.mixes[0] if self.mixes.length > 0 self.mixes[0] if self.mixes.length > 0
@ -214,7 +218,7 @@ module JamRuby
def has_access?(user) def has_access?(user)
return false if user.nil? 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 end
def attached_with_lesson(user) def attached_with_lesson(user)

View File

@ -11,7 +11,7 @@ AppStore = context.AppStore
onSessionMixerChange: (sessionMixers) -> onSessionMixerChange: (sessionMixers) ->
#console.log("_DEBUG_* SessionRecordBtn onSessionMixerChange", sessionMixers.session) #console.log("_DEBUG_* SessionRecordBtn onSessionMixerChange", sessionMixers.session)
@setState({isRecording: sessionMixers.session.isRecording}) @setState({isRecording: sessionMixers.session.isRecording})
@setState({isRecordingOwner: sessionMixers.session.recordingOwnerId && sessionMixers.session.recordingOwnerId == @app.currentUserId}) @setState({thisClientStartedRecording: sessionMixers.session.thisClientStartedRecording})
getInitialState: () -> getInitialState: () ->
{childWindow: null, isRecording: false} {childWindow: null, isRecording: false}
@ -25,7 +25,7 @@ AppStore = context.AppStore
return 'noclose' return 'noclose'
handleClick: () -> handleClick: () ->
if @state.isRecording && @state.isRecordingOwner if @state.isRecording && @state.thisClientStartedRecording
RecordingActions.stopRecording() RecordingActions.stopRecording()
else else
@openRecording() @openRecording()
@ -52,8 +52,8 @@ AppStore = context.AppStore
render: () -> render: () ->
btnStyles = "session-record session-record-btn left" btnStyles = "session-record session-record-btn left"
if this.state.isRecording if this.state.isRecording
if this.state.isRecordingOwner if this.state.thisClientStartedRecording
btnStyles = btnStyles+' button-orange' btnStyles = btnStyles+' button-orange'
`<a className={btnStyles} data-is-recording={this.state.isRecording} onClick={this.handleClick}> `<a className={btnStyles} data-is-recording={this.state.isRecording} onClick={this.handleClick}>
<img src="/assets/content/icon_record.png" align="texttop" height="14" width="14"/> <img src="/assets/content/icon_record.png" align="texttop" height="14" width="14"/>

View File

@ -23,7 +23,7 @@ mixins.push(Reflux.listenTo(RecordingStore, "onRecordingStateChanged"))
# @setState({audioFormat: recordingState.audioRecordingFormat}) # @setState({audioFormat: recordingState.audioRecordingFormat})
onRecordingStateChanged: `function (recordingState) { onRecordingStateChanged: `function (recordingState) {
console.log('_REC_ onRecordingStateChanged', recordingState); //console.log('_REC_ onRecordingStateChanged', recordingState);
if (recordingState.audioRecordingFormat) { if (recordingState.audioRecordingFormat) {
this.setState({audioFormat: recordingState.audioRecordingFormat}); this.setState({audioFormat: recordingState.audioRecordingFormat});
} }

View File

@ -41,7 +41,11 @@ RecordingStore = @RecordingStore
events = [] events = []
for event in @state.events for event in @state.events
events.push(`<li key={event[0]}>{event[0]} brid={event[1]}</li>`) events.push(`<li key={event[0]}>{event[0]} brid={event[1]}</li>`)
body = `<div className="msg">{recording} {cause} {waitingOnClientStop} {waitingOnServerStop}</div>`
initiator = ""
if this.state.thisClientStartedRecording
initiator = "Initatior"
body = `<div className="msg">{recording} {initiator} {cause} {waitingOnClientStop} {waitingOnServerStop}</div>`
`<div className={classes}> `<div className={classes}>
{body} {body}

View File

@ -2,7 +2,7 @@ context = window
@SessionHelper = class SessionHelper @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 @app = app
@session = session @session = session
@participantsEverSeen = participantsEverSeen @participantsEverSeen = participantsEverSeen
@ -12,7 +12,7 @@ context = window
@isLesson = @session?.lesson_session? @isLesson = @session?.lesson_session?
@sessionRules = sessionRules @sessionRules = sessionRules
@subscriptionRules = subscriptionRules @subscriptionRules = subscriptionRules
@recordingOwnerId = recordingOwnerId @thisClientStartedRecording = thisClientStartedRecording
if @isLesson if @isLesson
@lessonId = @session.lesson_session.id @lessonId = @session.lesson_session.id

View File

@ -34,35 +34,42 @@ window.RecordingStore = Reflux.createStore({
onInitModel(recordingModel) { onInitModel(recordingModel) {
this.recordingModel = recordingModel; this.recordingModel = recordingModel;
this.events = []; this.events = [];
this.trigger({ isRecording: this.recordingModel.isRecording(), events: this.events }); this.trigger({ isRecording: this.recordingModel.isRecording(), events: this.events, thisClientStartedRecording: false });
}, },
onResetRecordingState() { onResetRecordingState() {
console.log("onResetRecordingState"); console.log("onResetRecordingState");
this.events = [] 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.recordingModel.startRecording(recordSettings);
this.events = []; this.events = [];
this.events.push(["StartRecording"]); this.events.push(["StartRecording"]);
this.augmentWithBackendRecordingId(this.events); await this.augmentWithBackendRecordingId(this.events[this.events.length - 1]);
this.trigger({ events: this.events }); this.trigger({ events: this.events, thisClientStartedRecording: this.recordingModel.getThisClientStartedRecording() });
}, },
onStopRecording() { async onStopRecording() {
this.recordingModel.stopRecording(); this.recordingModel.stopRecording();
this.events.push(["StopRecording"]); this.events.push(["StopRecording"]);
this.augmentWithBackendRecordingId(this.events); await this.augmentWithBackendRecordingId(this.events[this.events.length - 1]);
this.trigger({ events: this.events }); this.trigger({ events: this.events, thisClientStartedRecording: this.recordingModel.getThisClientStartedRecording() });
}, },
onStartingRecording(details) { async onStartingRecording(details) {
details.cause = 'starting'; details.cause = 'starting';
details.thisClientStartedRecording = this.recordingModel.getThisClientStartedRecording();
this.mixTransferred = false; this.mixTransferred = false;
this.events.push(["OnStartingRecording"]); this.events.push(["OnStartingRecording"]);
this.augmentWithBackendRecordingId(this.events); await this.augmentWithBackendRecordingId(this.events[this.events.length - 1]);
details.events = this.events; details.events = this.events;
this.trigger(details); this.trigger(details);
if (!this.recordingWindowOpened) { if (!this.recordingWindowOpened) {
@ -70,37 +77,44 @@ window.RecordingStore = Reflux.createStore({
} }
}, },
async augmentWithBackendRecordingId(events) { async onStartedRecording(details) {
const backendRecordingId = await context.jamClient.GetCurrentRecordingId();
events[events.length - 1].push(backendRecordingId);
},
onStartedRecording(details) {
details.cause = 'started'; details.cause = 'started';
details.thisClientStartedRecording = this.recordingModel.getThisClientStartedRecording();
this.mixTransferred = false; this.mixTransferred = false;
this.events.push(["OnStartedRecording"]); this.events.push(["OnStartedRecording"]);
details.events = this.events; details.events = this.events;
this.augmentWithBackendRecordingId(this.events); const backendRecordingId = await this.augmentWithBackendRecordingId(this.events[this.events.length - 1]);
this.trigger(details); 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) { if (this.recordingWindowOpened) {
this.closeRecordingWindow(); this.closeRecordingWindow();
} }
}, },
onStoppingRecording(details) { async onStoppingRecording(details) {
details.cause = 'stopping'; details.cause = 'stopping';
details.thisClientStartedRecording = this.recordingModel.getThisClientStartedRecording();
this.events.push(["OnStoppingRecording"]); this.events.push(["OnStoppingRecording"]);
details.events = this.events; details.events = this.events;
this.augmentWithBackendRecordingId(this.events); await this.augmentWithBackendRecordingId(this.events[this.events.length - 1]);
this.trigger(details); this.trigger(details);
}, },
onStoppedRecording(details) { async onStoppedRecording(details) {
details.cause = 'stopped'; details.cause = 'stopped';
details.thisClientStartedRecording = this.recordingModel.getThisClientStartedRecording();
this.events.push(["OnStoppedRecording"]); this.events.push(["OnStoppedRecording"]);
details.events = this.events; details.events = this.events;
this.augmentWithBackendRecordingId(this.events); await this.augmentWithBackendRecordingId(this.events[this.events.length - 1]);
if (this.recordingWindowOpened) { if (this.recordingWindowOpened) {
this.closeRecordingWindow(); this.closeRecordingWindow();
@ -109,11 +123,12 @@ window.RecordingStore = Reflux.createStore({
this.trigger(details); this.trigger(details);
}, },
onAbortedRecording(details) { async onAbortedRecording(details) {
details.cause = 'aborted'; details.cause = 'aborted';
details.thisClientStartedRecording = this.recordingModel.getThisClientStartedRecording();
this.events.push(["OnAbortedRecording"]); this.events.push(["OnAbortedRecording"]);
details.events = this.events; details.events = this.events;
this.augmentWithBackendRecordingId(this.events); await this.augmentWithBackendRecordingId(this.events[this.events.length - 1]);
if (this.recordingWindowOpened) { if (this.recordingWindowOpened) {
this.closeRecordingWindow(); this.closeRecordingWindow();
@ -141,7 +156,7 @@ window.RecordingStore = Reflux.createStore({
onAudioRecordingFormatChanged(audioFormat) { onAudioRecordingFormatChanged(audioFormat) {
console.log("_DEBUG_ onAudioRecordingFormatChanged", JSON.stringify(this.recordingModel)); 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() { popupRecordingControls() {

View File

@ -44,6 +44,7 @@ ConfigureTracksActions = @ConfigureTracksActions
openBackingTrack: null openBackingTrack: null
helper: null helper: null
downloadingJamTrack: false downloadingJamTrack: false
startedRecording: false
init: -> init: ->
# Register with the app store to get @app # Register with the app store to get @app
@ -57,7 +58,7 @@ ConfigureTracksActions = @ConfigureTracksActions
@sessionUtils = context.JK.SessionUtils @sessionUtils = context.JK.SessionUtils
@recordingModel = new context.JK.RecordingModel(@app, rest, context.jamClient); @recordingModel = new context.JK.RecordingModel(@app, rest, context.jamClient);
RecordingActions.initModel(@recordingModel) 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) -> # onSessionJoinedByOther: (payload) ->
# clientId = payload.client_id # clientId = payload.client_id
@ -95,7 +96,7 @@ ConfigureTracksActions = @ConfigureTracksActions
onVideoChanged: (@videoState) -> onVideoChanged: (@videoState) ->
issueChange: () -> 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) this.trigger(@helper)
onWindowBackgrounded: () -> onWindowBackgrounded: () ->
@ -885,12 +886,14 @@ ConfigureTracksActions = @ConfigureTracksActions
onRecordingChanged: `async function(details) { onRecordingChanged: `async function(details) {
let detail, reason, timeline, title; let detail, reason, timeline, title;
logger.debug("SessionStore.onRecordingChanged: " + details.cause); logger.debug("SessionStore.onRecordingChanged: " + details.cause);
//console.log("_DEBUG_* SessionStore.onRecordingChanged: " + JSON.stringify(details)); // console.log("_DEBUG_* SessionStore.onRecordingChanged: " + JSON.stringify(details));
//this.isRecording = details.isRecording; this.isRecording = details.isRecording;
this.thisClientStartedRecording = details.thisClientStartedRecording;
this.recordingClinetId = details.clientId; this.recordingClinetId = details.clientId;
let recordingState = await this.recordingModel.getCurrentRecordingState(); //let recordingState = await this.recordingModel.getCurrentRecordingState();
this.recordingOwnerId = recordingState.recordingOwnerId; //this.recordingOwnerId = recordingState.recordingOwnerId;
this.isRecording = recordingState.isRecording; //this.isRecording = recordingState.isRecording;
switch (details.cause) { switch (details.cause) {
case 'started': case 'started':
@ -2022,7 +2025,6 @@ ConfigureTracksActions = @ConfigureTracksActions
//} //}
//logger.debug("session changed") //logger.debug("session changed")
logger.debug("issue change");
return this.issueChange(); return this.issueChange();
}` }`

View File

@ -22,6 +22,7 @@
var currentRecording = null; // the JSON response from the server for a recording var currentRecording = null; // the JSON response from the server for a recording
var currentOrLastRecordingId = null; var currentOrLastRecordingId = null;
var currentRecordingId = null; var currentRecordingId = null;
var thisClientStartedRecording = false; // set by the person who starts it
var rest = _rest; var rest = _rest;
var currentlyRecording = false; var currentlyRecording = false;
var startingRecording = false; var startingRecording = false;
@ -53,6 +54,10 @@
} }
} }
function getThisClientStartedRecording() {
return thisClientStartedRecording;
}
/** called every time a session is joined, to ensure clean state */ /** called every time a session is joined, to ensure clean state */
function reset(_sessionId) { function reset(_sessionId) {
console.log("[RecordingState]: reset") console.log("[RecordingState]: reset")
@ -66,6 +71,7 @@
currentRecording = null; currentRecording = null;
currentRecordingId = null; currentRecordingId = null;
stoppingRecording = false; stoppingRecording = false;
thisClientStartedRecording = false;
sessionId = _sessionId sessionId = _sessionId
} }
@ -97,6 +103,7 @@
currentlyRecording = true; currentlyRecording = true;
stoppingRecording = false; stoppingRecording = false;
thisClientStartedRecording = true;
context.RecordingActions.startingRecording({isRecording: false}) context.RecordingActions.startingRecording({isRecording: false})
@ -134,9 +141,7 @@
// return; // return;
//} //}
const isRecordingOwner = recording.owner.id == context.JK.currentUserId; console.log(`[RecordingState]: stopRecording userInitiated=${userInitiated} thisClientStartedRecording=${thisClientStartedRecording} reason=${reason} detail=${detail}`)
console.log(`[RecordingState]: stopRecording userInitiated=${userInitiated} isRecordingOwner=${isRecordingOwner} reason=${reason} detail=${detail}`)
if(stoppingRecording) { if(stoppingRecording) {
console.log("ignoring stopRecording because we are already stopping"); console.log("ignoring stopRecording because we are already stopping");
@ -165,7 +170,7 @@
//await jamClient.StopRecording(recording.id, groupedTracks); //await jamClient.StopRecording(recording.id, groupedTracks);
await jamClient.FrontStopRecording(recording.id, groupedTracks); await jamClient.FrontStopRecording(recording.id, groupedTracks);
if(isRecordingOwner) { if(thisClientStartedRecording) {
rest.stopRecording({"id": recording.id}) rest.stopRecording({"id": recording.id})
.done(function () { .done(function () {
waitingOnServerStop = false; waitingOnServerStop = false;
@ -250,7 +255,7 @@
context.SessionStore.updateSessionInfo(session, true) context.SessionStore.updateSessionInfo(session, true)
getCurrentRecordingState().then(function (recordingState) { 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 // we are still recording, so don't transition to stopped
console.log("recording is still running, so don't transition to stopped"); console.log("recording is still running, so don't transition to stopped");
return; 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) { function handleRecordingStarted(recordingId, result, clientId) {
reset(sessionId);
context.RecordingActions.resetRecordingState() context.RecordingActions.resetRecordingState()
console.log("[RecordingState] handleRecordingStarted called", { console.log("[RecordingState] handleRecordingStarted called", {
@ -339,8 +370,7 @@
currentUserId: context.JK.currentUserId, currentUserId: context.JK.currentUserId,
recordingState: recording recordingState: recording
}); });
currentRecordingId = recording.id; postServerRecordingFetch(recording)
currentOrLastRecordingId = recording.id;
}) })
.catch(function(error) { .catch(function(error) {
console.error("[RecordingState] Failed to fetch recording data", { console.error("[RecordingState] Failed to fetch recording data", {
@ -355,15 +385,6 @@
currentlyRecording 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) { function handleRecordingStopped(recordingId, result) {
@ -374,17 +395,11 @@
context.SessionStore.updateSessionInfo(session, true) context.SessionStore.updateSessionInfo(session, true)
} }
// if(recordState.isRecording) {
// //we are still recording, so don't stop
// return;
// }
if(recordingId == "video") { if(recordingId == "video") {
// comes from VideoRecordingStopped // comes from VideoRecordingStopped
return; return;
} }
var success = result.success; var success = result.success;
var reason = result.reason; var reason = result.reason;
var detail = result.detail; var detail = result.detail;
@ -399,40 +414,41 @@
if(recordingId == null || recordingId == "") { if(recordingId == null || recordingId == "") {
// this occurs when you are told by the backend to stop; i.e., you are a non-creator of the // 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 // 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} var details = {recordingId: recordingId, reason: reason, detail: detail, isRecording: false}
context.RecordingActions.stoppedRecording(details) context.RecordingActions.stoppedRecording(details);
return; return;
} }
rest.stopRecording({ rest.stopRecording({
id: recordingId id: recordingId
}) })
.always(function() { .always(function() {
transitionToStopped(); transitionToStopped();
}) })
.fail(function(jqXHR, textStatus, errorMessage) { .fail(function(jqXHR, textStatus, errorMessage) {
if(jqXHR.status == 422) { if(jqXHR.status == 422) {
console.log("recording already stopped %o", arguments); 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} var details = {recordingId: recordingId, reason: reason, detail: detail, isRecording: false}
$self.triggerHandler('stoppedRecording', details); $self.triggerHandler('stoppedRecording', details);
context.RecordingActions.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) { function handleRecordingAborted(recordingId, result) {
@ -516,7 +532,6 @@
async function getCurrentRecordingState() { async function getCurrentRecordingState() {
var recording = null; var recording = null;
var session = context.SessionStore.getCurrentOrLastSession(); var session = context.SessionStore.getCurrentOrLastSession();
var recordingId = await context.jamClient.GetCurrentRecordingId(); var recordingId = await context.jamClient.GetCurrentRecordingId();
var isRecording = recordingId && recordingId != ""; var isRecording = recordingId && recordingId != "";
@ -541,13 +556,13 @@
if (!session) { if (!session) {
console.debug("no session, so no recording"); console.debug("no session, so no recording");
return { isRecording: false, serverRecording: null, recordingOwnerId: null }; return { isRecording: false, serverRecording: null, thisClientStartedRecording: false };
} }
return { return {
isRecording: isRecording, isRecording: isRecording,
isServerRecording: !!recording, isServerRecording: !!recording,
recordingOwnerId: isRecording && recording ? recording.owner.id : null, thisClientStartedRecording: thisClientStartedRecording
} }
} }
@ -560,6 +575,7 @@
this.onServerStopRecording = onServerStopRecording; this.onServerStopRecording = onServerStopRecording;
this.onServerStartRecording = onServerStartRecording; this.onServerStartRecording = onServerStartRecording;
this.isRecording = isRecording; this.isRecording = isRecording;
this.getThisClientStartedRecording = getThisClientStartedRecording;
this.reset = reset; this.reset = reset;
this.stopRecordingIfNeeded = stopRecordingIfNeeded; this.stopRecordingIfNeeded = stopRecordingIfNeeded;
this.getState = getState; this.getState = getState;

View File

@ -290,19 +290,20 @@
if (app.clientId !== payload.client_id) { 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)); //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"); //alert("Sidebar: SESSION_DEPART: calling onServerStopRecording");
context.RecordingStore.recordingModel.onServerStopRecording(recordingId); //context.RecordingStore.recordingModel.onServerStopRecording(recordingId);
} //}
else { // else {
app.notify({ app.notify({
"title": "Musician Left Session", "title": "Musician Left Session",
"text": payload.msg, "text": payload.msg,
"icon_url": context.JK.resolveAvatarUrl(payload.photo_url) "icon_url": context.JK.resolveAvatarUrl(payload.photo_url)
}); });
} //}
} }
//if (context.jamClient.ClientLeftSession) { //if (context.jamClient.ClientLeftSession) {
await context.jamClient.ClientLeftSession(payload["source_user_id"], payload["client_id"], payload["session_id"]) await context.jamClient.ClientLeftSession(payload["source_user_id"], payload["client_id"], payload["session_id"])

View File

@ -186,6 +186,10 @@ class ApiRecordingsController < ApiController
end end
def stop 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 @recording.stop

View File

@ -386,6 +386,7 @@ if defined?(Bundler)
config.video_available = "full" config.video_available = "full"
config.alerts_api_enabled = true config.alerts_api_enabled = true
config.show_recording_debug_status = false
config.gear_check_ignore_high_latency = false config.gear_check_ignore_high_latency = false
config.remove_whitespace_credit_card = false config.remove_whitespace_credit_card = false
config.estimate_taxes = true config.estimate_taxes = true

View File

@ -112,6 +112,8 @@ SampleApp::Application.configure do
config.rating_dialog_min_num = 1 config.rating_dialog_min_num = 1
config.root_redirect_on = false config.root_redirect_on = false
config.show_recording_debug_status = true
config.video_conferencing_host = "http://localhost:3001" config.video_conferencing_host = "http://localhost:3001"
config.use_video_conferencing_server = true config.use_video_conferencing_server = true
config.latency_data_host = "http://localhost:4001/local" config.latency_data_host = "http://localhost:4001/local"

View File

@ -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.paypal_admin_only = Rails.application.config.paypal_admin_only
Gon.global.use_video_conferencing_server = Rails.application.config.use_video_conferencing_server 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.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.env = Rails.env
Gon.global.version = ::JamWeb::VERSION Gon.global.version = ::JamWeb::VERSION