2014-06-09 03:26:50 +00:00
( function ( context , $ ) {
"use strict" ;
context . JK = context . JK || { } ;
context . JK . VoiceChatHelper = function ( app ) {
var logger = context . JK . logger ;
2014-06-12 18:36:51 +00:00
var ALERT _NAMES = context . JK . ALERT _NAMES ;
2014-06-09 03:26:50 +00:00
var ASSIGNMENT = context . JK . ASSIGNMENT ;
var VOICE _CHAT = context . JK . VOICE _CHAT ;
var MAX _TRACKS = context . JK . MAX _TRACKS ;
var MAX _OUTPUTS = context . JK . MAX _OUTPUTS ;
var gearUtils = context . JK . GearUtils ;
var $parent = null ;
var $reuseAudioInputRadio = null ;
var $useChatInputRadio = null ;
var $chatInputs = null ;
var $templateChatInput = null ;
var $selectedChatInput = null ; // should only be used if isChatEnabled = true
2014-06-13 17:51:03 +00:00
var $voiceChatVuLeft = null ;
var $voiceChatVuRight = null ;
var $voiceChatFader = null ;
2014-06-09 03:26:50 +00:00
2014-06-13 17:51:03 +00:00
var saveImmediate = null ; // if true, then every action by the user results in a save to the backend immediately, false means you have to call trySave to persist
var uniqueCallbackName = null ;
2014-06-10 14:02:51 +00:00
// needed because iCheck fires iChecked event even when you programmatically change it, unlike when using .val(x)
2014-06-10 14:44:50 +00:00
var ignoreICheckEvent = false ;
2014-06-12 18:36:51 +00:00
var lastSavedTime = new Date ( ) ;
2014-06-13 17:51:03 +00:00
var vuOptions = null ;
var faderHeight = null ;
var startingState = null ;
2014-06-16 02:42:57 +00:00
var resettedOnInvalidDevice = false ; // this is set to true when we clear chat, and set to false when the user interacts in anyway
2014-06-10 14:02:51 +00:00
2014-06-09 03:26:50 +00:00
function defaultReuse ( ) {
2014-06-10 14:02:51 +00:00
suppressChange ( function ( ) {
$reuseAudioInputRadio . iCheck ( 'check' ) . attr ( 'checked' , 'checked' ) ;
$useChatInputRadio . removeAttr ( 'checked' ) ;
} )
2014-06-09 03:26:50 +00:00
}
function isChatEnabled ( ) {
return $useChatInputRadio . is ( ':checked' ) ;
}
2014-06-12 18:36:51 +00:00
function onInvalidAudioDevice ( e , data ) {
2014-06-12 19:52:26 +00:00
logger . debug ( "voice_chat_helper: onInvalidAudioDevice" )
2014-06-16 02:42:57 +00:00
if ( resettedOnInvalidDevice ) {
// we've already tried to clear the audio device, and the user hasn't interacted, but still we are getting this event
// we can't keep taking action, so stop
logger . error ( "voice_chat_helper: onInvalidAudioDevice: ignoring event because we have already tried to handle it" ) ;
return ;
}
resettedOnInvalidDevice = true ;
2014-06-12 19:52:26 +00:00
$selectedChatInput = null ;
// you can't do this in the event callback; it hangs the app indefinitely, and somehow 'sticks' the mic input into bad state until reboot
setTimeout ( function ( ) {
context . jamClient . FTUEClearChatInput ( ) ;
context . jamClient . TrackSetChatEnable ( true ) ;
var result = context . jamClient . TrackSaveAssignments ( ) ;
2014-06-16 02:42:57 +00:00
2014-06-12 19:52:26 +00:00
if ( ! result || result . length == 0 ) {
context . JK . Banner . showAlert ( 'It appears the selected chat input is not functioning. Please try another chat input.' ) ;
}
else {
context . JK . alertSupportedNeeded ( "Unable to unwind invalid chat input selection." )
}
} , 1 ) ;
2014-06-12 18:36:51 +00:00
}
function beforeShow ( ) {
2014-06-16 02:42:57 +00:00
userInteracted ( ) ;
2014-06-13 17:51:03 +00:00
renderNoVolume ( ) ;
2014-06-12 19:29:38 +00:00
context . JK . onBackendEvent ( ALERT _NAMES . AUDIO _DEVICE _NOT _PRESENT , 'voice_chat_helper' , onInvalidAudioDevice ) ;
2014-06-13 17:51:03 +00:00
registerVuCallbacks ( ) ;
2014-06-12 18:36:51 +00:00
}
2014-09-22 19:20:58 +00:00
2014-06-12 18:36:51 +00:00
function beforeHide ( ) {
2014-06-12 19:29:38 +00:00
context . JK . offBackendEvent ( ALERT _NAMES . AUDIO _DEVICE _NOT _PRESENT , 'voice_chat_helper' , onInvalidAudioDevice ) ;
2014-06-13 17:51:03 +00:00
jamClient . FTUERegisterVUCallbacks ( '' , '' , '' ) ;
2014-06-12 18:36:51 +00:00
}
2014-06-16 02:42:57 +00:00
function userInteracted ( ) {
resettedOnInvalidDevice = false ;
}
2014-06-10 14:02:51 +00:00
function reset ( forceDisabledChat ) {
2014-06-09 03:26:50 +00:00
$selectedChatInput = null ;
2014-06-10 14:02:51 +00:00
if ( ! forceDisabledChat && context . jamClient . TrackGetChatEnable ( ) ) {
2014-06-09 03:26:50 +00:00
enableChat ( false ) ;
}
else {
disableChat ( false ) ;
}
$chatInputs . empty ( ) ;
var chatInputs = gearUtils . getChatInputs ( ) ;
context . _ . each ( chatInputs , function ( chatInput ) {
if ( chatInput . assignment > 0 ) {
return ;
}
var chatChannelName = chatInput . name ;
var chatChannelId = chatInput . id ;
var isCurrentlyChat = chatInput . assignment == ASSIGNMENT . CHAT ;
var $chat = $ ( context . _ . template ( $templateChatInput . html ( ) , { id : chatChannelId , name : chatChannelName } , { variable : 'data' } ) ) ;
var $chatInput = $chat . find ( 'input' ) ;
if ( isCurrentlyChat ) {
$selectedChatInput = $chatInput ;
$selectedChatInput . attr ( 'checked' , 'checked' ) ;
}
2014-06-16 02:42:57 +00:00
//$chat.hide(); // we'll show it once it's styled with iCheck
2014-06-09 03:26:50 +00:00
$chatInputs . append ( $chat ) ;
} ) ;
var $radioButtons = $chatInputs . find ( 'input[name="chat-device"]' ) ;
context . JK . checkbox ( $radioButtons ) . on ( 'ifChecked' , function ( e ) {
2014-06-16 02:42:57 +00:00
userInteracted ( ) ;
2014-06-09 03:26:50 +00:00
var $input = $ ( e . currentTarget ) ;
$selectedChatInput = $input ; // for use in handleNext
if ( saveImmediate ) {
var channelId = $input . attr ( 'data-channel-id' ) ;
2014-06-12 18:36:51 +00:00
lastSavedTime = new Date ( ) ;
2014-06-11 20:37:15 +00:00
context . jamClient . TrackSetChatInput ( channelId ) ;
2014-06-12 18:36:51 +00:00
lastSavedTime = new Date ( ) ;
2014-06-11 20:37:15 +00:00
//context.jamClient.TrackSetAssignment(channelId, true, ASSIGNMENT.CHAT);
2014-06-09 03:26:50 +00:00
var result = context . jamClient . TrackSaveAssignments ( ) ;
if ( ! result || result . length == 0 ) {
// success
}
else {
2014-06-12 18:36:51 +00:00
context . jamClient . FTUEClearChatInput ( ) ;
context . jamClient . TrackSetChatEnable ( true ) ;
var result = context . jamClient . TrackSaveAssignments ( ) ;
if ( ! result || result . length == 0 ) {
context . JK . Banner . showAlert ( 'Unable to save chat selection. ' + result ) ;
}
else {
context . JK . alertSupportedNeeded ( "Unable to unwind invalid chat selection." )
}
2014-06-09 03:26:50 +00:00
return false ;
}
}
} ) ;
if ( ! isChatEnabled ( ) ) {
2014-06-10 14:02:51 +00:00
disableChatButtonsUI ( ) ;
2014-06-09 03:26:50 +00:00
}
2014-06-13 17:51:03 +00:00
renderVolumes ( ) ;
startingState = getCurrentState ( ) ;
2014-06-09 03:26:50 +00:00
}
2014-06-10 14:02:51 +00:00
function disableChatButtonsUI ( ) {
var $radioButtons = $chatInputs . find ( 'input[name="chat-device"]' ) ;
$radioButtons . iCheck ( 'disable' )
$chatInputs . addClass ( 'disabled' ) ;
2014-06-11 20:37:15 +00:00
$radioButtons . iCheck ( 'uncheck' ) ;
$selectedChatInput = null ;
2014-06-10 14:02:51 +00:00
}
function enableChatButtonsUI ( ) {
var $radioButtons = $chatInputs . find ( 'input[name="chat-device"]' ) ;
$radioButtons . iCheck ( 'enable' )
$chatInputs . removeClass ( 'disabled' ) ;
}
function suppressChange ( proc ) {
2014-06-10 14:44:50 +00:00
ignoreICheckEvent = true ;
2014-06-10 14:02:51 +00:00
try {
proc ( ) ;
}
finally {
2014-06-10 14:44:50 +00:00
ignoreICheckEvent = false ;
2014-06-10 14:02:51 +00:00
}
}
2014-06-09 03:26:50 +00:00
function disableChat ( applyToBackend ) {
if ( saveImmediate && applyToBackend ) {
logger . debug ( "voiceChatHelper: disabling chat to backend" ) ;
2014-06-10 14:44:50 +00:00
var state = getCurrentState ( ) ;
//context.jamClient.TrackSetChatEnable(false);
//if(state.chat_channel) {
// context.jamClient.TrackSetAssignment(state.chat_channel, true, ASSIGNMENT.UNASSIGNED);
//}
context . jamClient . FTUEClearChatInput ( ) ;
2014-06-09 03:26:50 +00:00
var result = context . jamClient . TrackSaveAssignments ( ) ;
if ( ! result || result . length == 0 ) {
2014-06-13 17:51:03 +00:00
renderNoVolume ( ) ;
2014-06-09 03:26:50 +00:00
// success
2014-06-10 14:02:51 +00:00
suppressChange ( function ( ) {
$reuseAudioInputRadio . iCheck ( 'check' ) . attr ( 'checked' , 'checked' ) ;
$useChatInputRadio . removeAttr ( 'checked' ) ;
} )
2014-06-09 03:26:50 +00:00
}
else {
context . JK . Banner . showAlert ( 'Unable to disable chat. ' + result ) ;
return false ;
}
}
else {
logger . debug ( "voiceChatHelper: disabling chat UI only" ) ;
2014-06-10 14:02:51 +00:00
suppressChange ( function ( ) {
$reuseAudioInputRadio . iCheck ( 'check' ) . attr ( 'checked' , 'checked' ) ;
$useChatInputRadio . removeAttr ( 'checked' ) ;
} )
2014-06-09 03:26:50 +00:00
}
2014-06-13 17:51:03 +00:00
disableChatButtonsUI ( ) ;
2014-06-09 03:26:50 +00:00
}
function enableChat ( applyToBackend ) {
if ( saveImmediate && applyToBackend ) {
logger . debug ( "voiceChatHelper: enabling chat to backend" ) ;
context . jamClient . TrackSetChatEnable ( true ) ;
var result = context . jamClient . TrackSaveAssignments ( ) ;
if ( ! result || result . length == 0 ) {
// success
2014-06-10 14:02:51 +00:00
suppressChange ( function ( ) {
$useChatInputRadio . iCheck ( 'check' ) . attr ( 'checked' , 'checked' ) ;
$reuseAudioInputRadio . removeAttr ( 'checked' ) ;
} )
2014-06-09 03:26:50 +00:00
}
else {
context . JK . Banner . showAlert ( 'Unable to enable chat. ' + result ) ;
return false ;
}
}
else {
logger . debug ( "voiceChatHelper: enabling chat UI only" ) ;
2014-06-10 14:02:51 +00:00
suppressChange ( function ( ) {
$useChatInputRadio . iCheck ( 'check' ) . attr ( 'checked' , 'checked' ) ;
$reuseAudioInputRadio . removeAttr ( 'checked' ) ;
} )
2014-06-09 03:26:50 +00:00
}
2014-06-10 14:02:51 +00:00
enableChatButtonsUI ( ) ;
2014-06-13 17:51:03 +00:00
renderVolumes ( ) ;
2014-06-09 03:26:50 +00:00
}
function handleChatEnabledToggle ( ) {
context . JK . checkbox ( $reuseAudioInputRadio ) ;
context . JK . checkbox ( $useChatInputRadio ) ;
// plugin sets to relative on the element; have to do this as an override
$reuseAudioInputRadio . closest ( '.iradio_minimal' ) . css ( 'position' , 'absolute' ) ;
$useChatInputRadio . closest ( '.iradio_minimal' ) . css ( 'position' , 'absolute' ) ;
2014-06-16 02:42:57 +00:00
$reuseAudioInputRadio . on ( 'ifChecked' , function ( ) {
if ( ! ignoreICheckEvent ) {
userInteracted ( ) ;
disableChat ( true ) ;
}
} ) ;
$useChatInputRadio . on ( 'ifChecked' , function ( ) {
if ( ! ignoreICheckEvent ) {
userInteracted ( ) ;
enableChat ( true )
}
} ) ;
2014-06-09 03:26:50 +00:00
}
// gets the state of the UI
function getCurrentState ( ) {
var state = {
enabled : null ,
chat _channel : null
} ;
state . enabled = $useChatInputRadio . is ( ':checked' ) ;
state . chat _channel = $selectedChatInput && $selectedChatInput . attr ( 'data-channel-id' ) ;
logger . debug ( "desired chat state: enabled=" + state . enabled + ", chat_channel=" + state . chat _channel )
return state ;
}
2014-06-13 17:51:03 +00:00
function cancel ( ) {
logger . debug ( "canceling voice chat state" ) ;
return trySave ( startingState ) ;
}
2014-06-09 03:26:50 +00:00
2014-06-13 17:51:03 +00:00
function trySave ( state ) {
if ( ! state ) {
state = getCurrentState ( ) ;
}
2014-06-09 03:26:50 +00:00
if ( state . enabled && state . chat _channel ) {
logger . debug ( "enabling chat. chat_channel=" + state . chat _channel ) ;
context . jamClient . TrackSetChatEnable ( true ) ;
context . jamClient . FTUESetChatInput ( state . chat _channel ) ;
//context.jamClient.TrackSetAssignment(state.chat_channel, true, ASSIGNMENT.CHAT);
}
else {
logger . debug ( "disabling chat." ) ;
2014-06-10 14:44:50 +00:00
context . jamClient . FTUEClearChatInput ( ) ;
//context.jamClient.TrackSetChatEnable(false);
//if(state.chat_channel) {
//context.jamClient.TrackSetAssignment(state.chat_channel, true, ASSIGNMENT.UNASSIGNED);
//}
2014-06-09 03:26:50 +00:00
}
var result = context . jamClient . TrackSaveAssignments ( ) ;
if ( ! result || result . length == 0 ) {
// success
2014-06-13 17:51:03 +00:00
if ( ! state . enabled ) {
renderNoVolume ( ) ;
}
2014-06-09 03:26:50 +00:00
return true ;
}
else {
context . JK . Banner . showAlert ( 'Unable to save chat assignments. ' + result ) ;
return false ;
}
}
2014-06-13 17:51:03 +00:00
function initializeVUMeters ( ) {
context . JK . VuHelpers . renderVU ( $voiceChatVuLeft , vuOptions ) ;
context . JK . VuHelpers . renderVU ( $voiceChatVuRight , vuOptions ) ;
context . JK . FaderHelpers . renderFader ( $voiceChatFader , { faderId : '' , faderType : "vertical" , height : faderHeight } ) ;
$voiceChatFader . on ( 'fader_change' , faderChange ) ;
}
// renders volumes based on what the backend says
function renderVolumes ( ) {
2015-07-15 15:04:45 +00:00
var $fader = $voiceChatFader . find ( '[data-control="fader"]' ) ;
2014-06-13 17:51:03 +00:00
var db = context . jamClient . FTUEGetChatInputVolume ( ) ;
var faderPct = db + 80 ;
context . JK . FaderHelpers . setHandlePosition ( $fader , faderPct ) ;
}
function renderNoVolume ( ) {
2015-07-15 15:04:45 +00:00
var $fader = $voiceChatFader . find ( '[data-control="fader"]' ) ;
2014-06-13 17:51:03 +00:00
context . JK . FaderHelpers . setHandlePosition ( $fader , 50 ) ;
context . JK . VuHelpers . updateVU ( $voiceChatVuLeft , 0 ) ;
context . JK . VuHelpers . updateVU ( $voiceChatVuRight , 0 ) ;
}
function faderChange ( e , data ) {
// TODO - using hardcoded range of -80 to 20 for output levels.
var mixerLevel = data . percentage - 80 ; // Convert our [0-100] to [-80 - +20] range
context . jamClient . FTUESetChatInputVolume ( mixerLevel ) ;
}
function registerVuCallbacks ( ) {
logger . debug ( "voice-chat-helper: registering vu callbacks" ) ;
jamClient . FTUERegisterVUCallbacks (
"JK.voiceChatHelperAudioOutputVUCallback" ,
"JK.voiceChatHelperAudioInputVUCallback" ,
"JK." + uniqueCallbackName
) ;
jamClient . SetVURefreshRate ( 200 ) ;
}
function initialize ( _$step , caller , _saveImmediate , _vuOptions , _faderHeight ) {
2014-06-09 03:26:50 +00:00
$parent = _$step ;
saveImmediate = _saveImmediate ;
2014-06-13 17:51:03 +00:00
vuOptions = _vuOptions ;
faderHeight = _faderHeight ;
2014-06-09 03:26:50 +00:00
$reuseAudioInputRadio = $parent . find ( '.reuse-audio-input input' ) ;
$useChatInputRadio = $parent . find ( '.use-chat-input input' ) ;
$chatInputs = $parent . find ( '.chat-inputs' ) ;
$templateChatInput = $ ( '#template-chat-input' ) ;
2014-06-13 17:51:03 +00:00
$voiceChatVuLeft = $parent . find ( '.voice-chat-vu-left' ) ;
$voiceChatVuRight = $parent . find ( '.voice-chat-vu-right' ) ;
$voiceChatFader = $parent . find ( '.chat-fader' )
2014-06-09 03:26:50 +00:00
handleChatEnabledToggle ( ) ;
2014-06-13 17:51:03 +00:00
initializeVUMeters ( ) ;
renderVolumes ( ) ;
uniqueCallbackName = 'voiceChatHelperChatInputVUCallback' + caller ;
2015-07-15 15:04:45 +00:00
context . JK [ uniqueCallbackName ] = function ( dbValue , leftClip , rightClip ) {
2014-06-13 17:51:03 +00:00
context . JK . ftueVUCallback ( dbValue , $voiceChatVuLeft ) ;
context . JK . ftueVUCallback ( dbValue , $voiceChatVuRight ) ;
}
2014-06-09 03:26:50 +00:00
}
2014-06-13 17:51:03 +00:00
context . JK . voiceChatHelperAudioInputVUCallback = function ( dbValue ) { } ;
context . JK . voiceChatHelperAudioOutputVUCallback = function ( dbValue ) { } ;
2014-06-09 03:26:50 +00:00
this . reset = reset ;
this . trySave = trySave ;
2014-06-13 17:51:03 +00:00
this . cancel = cancel ;
2014-06-09 03:26:50 +00:00
this . initialize = initialize ;
2014-06-12 18:36:51 +00:00
this . beforeShow = beforeShow ;
this . beforeHide = beforeHide ;
2014-06-09 03:26:50 +00:00
return this ;
} ;
} ) ( window , jQuery ) ;