/*jslint laxbreak:true */ /*jslint laxcomma:true */ /*jslint loopfunc:true */ /*jslint strict:true */ /*jslint browser:true */ /*jslint devel:true */ // Filename: app.js define([ "underscore" , "async" , "backbone" , "jquery" , "bootstrap" , "config" , "views/app" , "views/footer" , "views/sidebar" , "views/player" , "views/main" , "models/client" // , "models/dmap" , "collections/server" , "collections/playlist" , "views/client" , "views/list" , "text!../templates/app/modal-loading.html" , "text!../templates/app/modal-login.html" , "text!../templates/app/modal-about.html" ], function( _ , async , Backbone , $ , Bootstrap , Config , AppView , FooterView , SideBarView , PlayerView , MainView , ClientModel //, DMAPModel , ServerCollection , PlaylistCollection , ClientView , ListView , tmplModalLoading , tmplModalLogin , tmplModalAbout ) { "use strict"; var App = Backbone.Router.extend({ routes: { "about": "_routerActionAbout" , "playlist": "_routerActionPlaylist" , "servers/:server": "_routerActionClient" , "playlist/:item": "_routerActionPlaylistItem" , ":server/items/:item": "_routerActionServerItem" //"*actions": "defaultRoute" // matches http://example.com/#anything-here } , historyStart: window.history.length , initialize: function() { _.bindAll(this , "_routerActionAbout" , "_routerActionPlaylist" , "_routerActionClient" , "_routerActionItem" , "_routerActionServerItem" , "_serverInit" , "__showModalAbout" ); var that = this ; console.log("app.js::init()"); // Setup underscore templates with mustache styles _.templateSettings.interpolate = /\{\{(.+?)\}\}/g; this.servers = new ServerCollection(); this.playlist = new PlaylistCollection(); this.servers.on("add", function (server) { server.save(); }); async.waterfall([ function __asyncAppFetchServerCollection(callback) { that.servers.fetch({ success: function (collection, modelsAttributes) { if (modelsAttributes.length === 0) { console.info("Adding default daap server"); collection.add(Config.daap); } callback(null, collection); } , error: callback }); } , function __asyncAppAttachStateEvents(servers, callback) { async.forEach(that.servers.models, function (server) { that._serverInit(server); }); that.servers.on("add", function (server) { that._serverInit(server); }); callback(null, servers); } ] , function __asyncAppDependenciesReady(err, result) { that.Views = {}; that.Views.App = new AppView(); that.Views.SideBar = new SideBarView({ el: that.Views.App.Layout.panes.west , servers: that.servers }); that.Views.Player = new PlayerView({ el: that.Views.App.Layout.panes.north }); that.Views.Footer = new FooterView({ el: that.Views.App.Layout.panes.south }); that.Views.Main = new MainView({ el: that.Views.App.Layout.panes.center }); that.Views.Main.setView("playlist", new ListView()); that.Views.Footer.on("toggle:sidebar", function __fnAppEventTogglerSiderBar(event) { that.Views.App.toggleSideBar(); }); that.Views.Footer.on("toggle:random", function __fnAppEventTogglerRandom(event) { // TODO:... }); that.Views.Footer.on("toggle:repeat", function __fnAppEventTogglerRepeater(event) { // TODO:... }); that.Views.Footer.on("show:about", that.__showModalAbout); that.Views.App.$el.delegate("div.modal", "hidden", function __fnAppEventRemoveModals(event) { $(event.target).remove(); }); Backbone.history.start({ pushState: true , root: Config.docRoot }); console.log(Bootstrap); // For now let's reset the state when we start up //that.navigate("", false); App.__super__.initialize.apply(that, that.routes); }); return this; } , _routerActionAbout: function () { var that = this ; that.__showModalAbout(); } , _routerActionPlaylist: function () { var that = this ; that.Views.SideBar.select("> ul > li:first"); that.Views.Main.showView("playlist"); } , _routerActionClient: function (hostname) { var that = this , server = this.servers.get(hostname) , client = server && server.client || undefined ; if (server && client) { that.Views.SideBar.select(server); var __fnAppEventClientLoaded = function () { if (!that.Views.Main.getView(server.get("hostname"))) { that.Views.Main.setView(server.client.attributes.hostname, new ClientView({ /*el: that.Views.App.Layout.panes.center , */server: server , aoppendEl: that.Views.App.Layout.panes.center })); } that.Views.Main.showView(server.get("hostname")); } , __fnAppEventClientInitited = function () { client.fetchDatabases(function __fnAppCbFetchDatabases() { client.fetchDatabase(function __fnAppCbFetchDatabase() { __fnAppEventClientLoaded(); }); }); }; if (client.state < 4) { client.on("inited", __fnAppEventClientInitited); if (client.state <= 0) { client.init(); } } else if (client.state === 4) { __fnAppEventClientInitited(); } else if (client.state > 4) { __fnAppEventClientLoaded(); } } } , _routerActionPlaylistItem: function (item) { var that = this ; that.Views.SideBar.select("> ul > li:first"); } , _routerActionServerItem: function (server, item) { var that = this ; that.Views.SideBar.select(server); that.Views.Main.showView(server.get("hostname")); } , _serverInit: function(server) { var that = this ; that.loadingStates = 0; that.loadingModal = $(tmplModalLoading); that.loadingTimeout = null; server.client.off("all"); server.client.on("state", function __fnAppEventClientStateChange(client, state) { if (state === ClientModel.defaults._states.loading) { if (that.loadingStates === 0) { that.loadingTimeout = setTimeout(function __fnAppTimeoutLoadingStat() { that.loadingModal.modal(); that.loadingTimeout = null; }, 800); } that.loadingStates++; } else if (state === ClientModel.defaults._states.loaded) { that.loadingStates--; if (that.loadingStates === 0) { clearTimeout(that.loadingTimeout); if (that.loadingModal.modal) { that.loadingModal.modal("hide"); } } } }); server.client.on("unauthorized", function __fnAppEventClientUnauthorized(client, xhr) { var tmplHtml = _.template(tmplModalLogin)({ dmap_itemname: client.url() }) , serverModel = that.servers.get(client.attributes.hostname) ; that._modalLogin = $(tmplHtml); that._modalLogin.find("form").on("submit", function __fnAppEventModalLogin(event) { var username = $(event.target).find("input[type='text']").val() , password = $(event.target).find("input[type='password']").val() , saveCredentials = $(event.target).find("input[type='checkbox']").is(':checked') ; client.setAuth(username, password); if (saveCredentials) { var newModel = (_.clone({}, serverModel.attributes, {username: username, password: password})); serverModel.set("username", username, {silent: true}); serverModel.set("password", password, {silent: true}); serverModel.save(newModel, {silence: true}); } that._modalLogin.modal("hide"); setTimeout(client.init, 250); event.preventDefault(); }); that._modalLogin.delegate("input[type='checkbox']", "click", function __fnEventModalRemember(event) { if (event.target.checked === true) { if (!confirm("Using this feature will save the login and password locally in clear text, are you sure?")) { event.target.checked = false; event.preventDefault(); } } }); setTimeout(function __fnEventAppUnauthorizedDisplayModal() { that._modalLogin.modal(); }, 50); }); server.client.init(); } , __showModalAbout: function () { var that = this ; that._modalAbout = $(tmplModalAbout); that._modalAbout.on("hidden", function __fnEventAppModalAboutClosed(event) { if (window.history.length === that.historyStart) { that.navigate("", false); } else { window.history.back(); } }); that._modalAbout.modal(); } }); return App; });