/*jslint laxbreak:true */ /*jslint laxcomma:true */ /*jslint loopfunc:true */ /*jslint strict:true */ /*jslint browser:true */ /*jslint devel:true */ define([ "underscore" , "jquery" , "backbone" , "bootstrap" , "async" , "config" , "collections/server" , "text!../../templates/sidebar/server-list-item.html" , "text!../../templates/sidebar/modal-new-server.html" ] , function ( _ , $ , Backbone , Bootstrap , async , Config , ServerCollection , tmplServerListItem , tmplModalNewServer ) { "use strict"; var SideBar = Backbone.View.extend({ events: { "click > ul > li:last-child > span > a.sidebar-list-action": "_addServerItem" } , router: null , initialize: function (options) { _.bindAll(this, "renderServerItem", "_addServerItem", "_routerActionPlaylist", "_routerActionClient"); var that = this , serverModel = null ; SideBar.__super__.initialize.apply(that, arguments); this.servers = options.servers; async.forEach(this.servers, that.renderServerItem, function __fnSideBarViewCbInitialRender() { that.trigger("rendered"); that.router = new Backbone.Router.extend({ "playlist": that._routerActionPlaylist , "servers/:server": that._routerActionClient , ":server/items/:item": that._routerActionClient //"*actions": "defaultRoute" // matches http://example.com/#anything-here }); }); this.servers.on("add", function (server) { that.renderServerItem(server); }); this.$el.delegate("> ul > li:first-child", "click", function __fnSideBarEventDblclickPlaylist(event) { Backbone.Router.prototype.navigate("playlist", true); setTimeout(function __fnSideBarViewTimeoutTogglePlaylistClass() { that.$el.find("li.selected").removeClass("selected"); $(event.target).parents("ul:first").find("> li:first-child").addClass("selected"); }, 10); }); } , select: function (serverModel) { var that = this , cid = (serverModel.cid && "#" + serverModel.cid) || serverModel , $server = that.$el.find(cid) ; that.$el.find("li.selected").removeClass("selected"); $server.addClass("selected"); } , _routerActionPlaylist: function (event) { console.log(event); } , _routerActionClient: function (event) { console.log(event); } , _addServerItem: function(event) { var that = this , modalEl = $(tmplModalNewServer) ; modalEl.modal(); modalEl.find("button[data-save='modal']").on("click", function (event) { modalEl.find("form").submit(); }); modalEl.find("form").on("submit", function (event) { var $input = $(event.target).find("input") , value = $input.val() , protocol = "http" , port = 3689 , domain = "" , errors = [] ; if (value.substr(-1) === "/") { value = value.substr(0, value.length - 1); } if (/^(?:http|daap)(?:s)?:\/\//.test(value)) { protocol = value.substring(0, value.indexOf(":")).replace("daap", "http"); value = value.substr(value.indexOf(":") + 3); } if (value.indexOf(":") > 0) { port = value.substring(value.indexOf(":") + 1); value = value.substring(0, value.indexOf(":")); } else if (protocol === "https") { port = 443; } domain = value.toLowerCase(); if (isNaN((port = parseInt(port, 10)))) { errors.push("Invalid port number: 3689"); } if (protocol !== "http" && protocol !== "https") { errors.push("Invalid protocol: http(s)"); } if (_.isEmpty(domain) || /^([a-z0-9]([\-a-z0-9]*[a-z0-9])?\\.)+((a[cdefgilmnoqrstuwxz]|aero|arpa)|(b[abdefghijmnorstvwyz]|biz)|(c[acdfghiklmnorsuvxyz]|cat|com|coop)|d[ejkmoz]|(e[ceghrstu]|edu)|f[ijkmor]|(g[abdefghilmnpqrstuwy]|gov)|h[kmnrtu]|(i[delmnoqrst]|info|int)|(j[emop]|jobs)|k[eghimnprwyz]|l[abcikrstuvy]|(m[acdghklmnopqrstuvwxyz]|mil|mobi|museum)|(n[acefgilopruz]|name|net)|(om|org)|(p[aefghklmnrstwy]|pro)|qa|r[eouw]|s[abcdeghijklmnortvyz]|(t[cdfghjklmnoprtvwz]|travel)|u[agkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw])$/.test(domain)) { errors.push("Invalid server domain"); } if (errors.length > 0) { alert("Please correct the following errors:\n" + errors.join("\n")); } else { modalEl.modal("hide"); that.servers.add({ protocol: protocol , port: port , hostname: domain }); } return false; }); modalEl.on("hidden", function (event) { $(event.target).remove(); }); } , renderServerItem: function (item) { var that = this , itemHtml = _.template(tmplServerListItem, { cid: item.cid , server_name: item.getName() }) , $item = $(itemHtml) ; this.$el.find("ul:first > li > ul.siderbar-server-list").append($item); item.on("change", function __fnSideBarViewClientItemChanged(event) { if (event.get("name")) { $item.find("span > span").text(event.getName()); } }); item.client.on("state", function __fnSideBarViewEventClientState(client, state) { that.changeServerItemState($item.find("span > i:first-child"), client, state); }); $item.find("a.sidebar-list-action").on("click", function (model) { return function __fnSideBarClickRemoveAction (event) { var confirmMessage = "Are you sure you want to delete:\n" + item.getName(); if (window.confirm(confirmMessage)) { $(event.target).parents("li:first").fadeOut(300, function() { $(this).remove(); }); setTimeout(function () { model.destroy(); }, 10); } event.preventDefault(); }; }(item)); $item.on("click", function __fnSideBarViewEventDblClickItem(event) { // FIXME: This needs to check the state of the client and debounce that.$el.find("li.selected").removeClass("selected"); $item.addClass("selected"); /* if (item.client.state < item.client._states.loaded) { item.client.fetchDatabases(item.client.fetchDatabase); } else { console.log(item.client.collections); } */ Backbone.Router.prototype.navigate("servers/" + item.id, true); }); } , changeServerItemState: function ($glyph, client, state) { var newClass = "icon-folder-closed" ; switch (state) { case 2: case 5: newClass = "icon-loading"; break; case 3: newClass = "icon-exclamation-sign"; break; case 4: newClass = "icon-ok-sign"; break; case 6: newClass = "icon-folder-open"; break; case -1: newClass = "icon-warning-sign"; break; default: case 0: case 1: newClass = "icon-folder-closed"; break; } $glyph.removeClass(); $glyph.addClass(newClass); } }); return SideBar; });