(function (context, $) { "use strict"; // Change underscore's default templating characters as they // conflict withe the ERB rendering. Templates will use: // {{ interpolate }} // {% evaluate %} // {{- escape }} // context._.templateSettings = { evaluate: /\{%([\s\S]+?)%\}/g, interpolate: /\{\{([\s\S]+?)\}\}/g, escape: /\{\{-([\s\S]+?)\}\}/g }; context.JK = context.JK || {}; var JamKazam = context.JK.JamKazam = function () { var app; var logger = context.JK.logger; var rest = context.JK.Rest(); var inBadState = false; var userDeferred = null; var userData = null; var self = this; var opts = { inClient: true, // specify false if you want the app object but none of the client-oriented features layoutOpts: { layoutFooter: true // specify false if you want footer to be left alone } }; /** * Dynamically build routes from markup. Any layout="screen" will get a route corresponding to * his layout-id attribute. If a layout-arg attribute is present, that will be named as a data * section of the route. */ function routing() { var routes = context.RouteMap, rules = {}, rule, routingContext = {}; $('div[layout="screen"]').each(function () { var target = $(this).attr('layout-id'), targetUrl = target, targetArg = $(this).attr('layout-arg'), fn = function (data) { data.screen = target; app.layout.changeToScreen(target, data); }; if (targetArg) { targetUrl += "/:" + targetArg; } rules[target] = {route: '/' + targetUrl + '/:d?', method: target}; routingContext[target] = fn; // allow dialogs to take an optional argument rules[target+'opt'] = {route: '/' + targetUrl + '/:d?/d1:', method: target}; routingContext[target + 'opt'] = fn; }); routes.context(routingContext); for (rule in rules) if (rules.hasOwnProperty(rule)) routes.add(rules[rule]); $(context).bind('hashchange', function(e) { app.layout.onHashChange(e, routes.handler)}); $(routes.handler); } /** * This occurs when the websocket gateway loses a connection to the backend messaging system, * resulting in severe loss of functionality */ function serverBadStateError() { if (!inBadState) { inBadState = true; app.notify({title: "Server Unstable", text: "The server is currently unstable, resulting in feature loss. If you are experiencing any problems, please try to use JamKazam later."}) } } /** * This occurs when the websocket gateway loses a connection to the backend messaging system, * resulting in severe loss of functionality */ function serverBadStateRecovered() { if (inBadState) { inBadState = false; app.notify({title: "Server Recovered", text: "The server is now stable again. If you are still experiencing problems, either create a new music session or restart the client altogether."}) } } /** * This occurs when a new download from a recording has become available */ function downloadAvailable() { context.jamClient.OnDownloadAvailable(); } /** * This most likely occurs when multiple tabs in the same browser are open, until we make a fix for this... */ function duplicateClientError() { context.JK.Banner.showAlert("Duplicate Window (Development Mode Only)", "You have logged in another window in this browser. This window will continue to work but with degraded functionality. This limitation will soon be fixed.") context.JK.JamServer.noReconnect = true; } function registerBadStateError() { context.JK.JamServer.registerMessageCallback(context.JK.MessageType.SERVER_BAD_STATE_ERROR, serverBadStateError); } function registerBadStateRecovered() { context.JK.JamServer.registerMessageCallback(context.JK.MessageType.SERVER_BAD_STATE_RECOVERED, serverBadStateRecovered); } function registerDownloadAvailable() { context.JK.JamServer.registerMessageCallback(context.JK.MessageType.DOWNLOAD_AVAILABLE, downloadAvailable); } function registerDuplicateClientError() { context.JK.JamServer.registerMessageCallback(context.JK.MessageType.SERVER_DUPLICATE_CLIENT_ERROR, duplicateClientError); } /** * Generic error handler for Ajax calls. */ function ajaxError(jqXHR, textStatus, errorMessage) { if (!textStatus) { textStatus = 'n/a' } if (!errorMessage) { errorMessage = 'n/a' } //var err; //try { throw new Error('lurp'); } catch(e) { err = e }; //console.log("TRACE", JSON.stringify(err)) if (jqXHR.status === 404) { logger.error("Unexpected ajax error: " + textStatus + ", msg:" + errorMessage); app.notify({title: "Oops!", text: "What you were looking for is gone now."}); } else if(jqXHR.status === 403) { logger.debug("not logged in or something else"); try { var responseJson = JSON.parse(jqXHR.responseText) if (responseJson['message'] == 'IP blacklisted') { app.notify({title: 'Suspicious Activity', text: 'The IP address you are accessing JamKazam from has shown suspicious activity in the past. If you believe this is in error, please contact support@jamkazam.com.', icon_url: "/assets/content/icon_alert_big.png"}) return; } if (responseJson['message'] == 'User blacklisted') { app.notify({title: 'Suspicious Activity', text: 'The user account that you are accessing JamKazam from has shown suspicious activity in the past. If you believe this is in error, please contact support@jamkazam.com.', icon_url: "/assets/content/icon_alert_big.png"}) return; } }catch(e) { } app.notify({title: 'Not Logged In', text: 'Please log in.', icon_url: "/assets/content/icon_alert_big.png"}) } else if (jqXHR.status === 422) { logger.error("Unexpected ajax error: " + textStatus + ", msg: " + errorMessage + ", response: " + jqXHR.responseText); // present a nicer message try { var text = "