Filex.Path = Backbone.Collection.extend({
model: Filex.PathBit,
- initialize: function() {
- this.listenTo(this, 'reset add', this.setActive);
- },
-
- setActive: function() {
- _.each(this.initial(), function(bit) {
- bit.set('active', false);
- });
-
- this.last().set('active', true);
+ full: function() {
+ return this.pluck('name').join('/').replace(/^\/+/, '/');
},
- full: function() {
- return this.pluck('path').join('/') || '/';
+ append: function(name) {
+ return this.pluck('name').concat(name).join('/').replace(/^\/+/, '/');
}
});
// ------------------------------------------------------------------------
+ // Routers
+ // ------------------------------------------------------------------------
+
+ Filex.Router = Backbone.Router.extend({
+ routes: {
+ '*url': 'load'
+ }
+ });
+
+
+ // ------------------------------------------------------------------------
// Views
// ------------------------------------------------------------------------
render: function() {
var data = this.model.toJSON();
- data['url_params'] = $.param({
- host: this.view.host,
- path: this.view.path.full() + '/' + this.model.get('name')
- });
+
+ if (this.model.isDir()) {
+ data['url'] = this.view.host + '/' + this.view.path.append(this.model.get('name'))
+ }
+ else {
+ data['params'] = $.param({
+ host: this.view.host,
+ path: this.view.path.append(this.model.get('name'))
+ });
+ }
data['cid'] = this.model.cid;
this.$el.html(this.template()(data));
},
toggleHidden: function() {
- this.$el.toggleClass('hidden', this.model.isHidden() && !this.view.showHidden());
+ var isHidden = this.model.isHidden() && !this.view.showHidden();
+ this.$el.toggleClass('hidden', isHidden);
+
+ if (isHidden && this.model.get('checked'))
+ this.model.toggle();
},
toggleChecked: function(obj, value) {
},
click: function(e) {
- if (e.target.className == 'link') {
- if (this.model.isDir()) {
- e.preventDefault();
- this.model.trigger('selected:dir', this.model);
- }
-
- return;
- }
-
- this.model.toggle();
+ if (e.target.className != 'link')
+ this.model.toggle();
}
});
Filex.Breadcrumb = Backbone.View.extend({
tagName: 'li',
- events: {
- 'click a': 'selected'
- },
-
initialize: function() {
this.listenTo(this.model, 'change:active', this.render);
this.listenTo(this.model, 'remove', this.remove);
render: function() {
if (this.model.get('active')) {
- this.$el.text(this.model.get('text'));
+ this.$el.addClass('active');
+ this.$el.text(this.model.get('name'));
}
else {
this.$el.html($('<a/>', {
- href: '#',
- text: this.model.get('text')
+ href: '#' + this.model.get('url'),
+ text: this.model.get('name')
}));
}
- this.$el.toggleClass('active', this.model.get('active'));
return this;
- },
-
- selected: function(e) {
- e.preventDefault();
- this.model.trigger('selected', this.model);
}
});
this.path = new Filex.Path();
this.files = new Filex.FileList();
+ this.router = new Filex.Router();
- this.listenTo(this.path, 'reset', this.resetPath);
this.listenTo(this.path, 'add', this.addPath);
- this.listenTo(this.path, 'add reset', this.changedPath);
- this.listenTo(this.path, 'selected', this.selectedPath);
+ this.listenTo(this.path, 'reset', this.resetPath);
this.listenTo(this.files, 'reset', this.resetFiles);
- this.listenTo(this.files, 'selected:dir', this.selectedDir);
this.listenTo(this.files, 'change:checked', this.updateSelectAll);
+ this.listenTo(this.router, 'route:load', this.load);
// used in selectize callbacks
var view = this,
- optionTemplate = _.template('<div><div><%= host %></div><div class="small text-muted"><%= path %></div></div>');
+ optionTemplate = _.template('<div><div><%- host %></div><div class="small text-muted"><%- path %></div></div>');
this.$('#host-selector').selectize({
optgroupField: 'group',
lockOptgroupOrder: true,
create: function(input, callback) {
var $form = $('#favorite-form'),
- parts = input.split('/', 1),
+ parts = input.split('/'),
callback_called = false;
- $form.find('#id_host').val(parts[0]);
+ $form[0].reset();
+ $form.find('.alert-danger').remove();
+ $form.find('#id_host').val(parts.shift());
- if (parts.length > 1)
- $form.find('#id_path').val(parts[1]);
+ if (parts.length)
+ $form.find('#id_path').val(parts.join('/'));
+ $form.off();
$form.on('submit', function(e) {
var $this = $(this),
$btn = $this.find('[type="submit"]');
e.preventDefault();
$btn.button('loading');
+ $this.find('.alert-danger').remove();
$.post($this.attr('action'), $this.serialize(), function(data) {
callback(data);
$this.modal('hide');
$btn.button('reset');
- }, 'json').fail(function() {
+ }, 'json').fail(function(xhr) {
console.error(arguments);
- $btn.button('error');
+ var error = (xhr.responseJSON || {}).error || undefined;
+
+ if (error.__all__) {
+ error = 'Podana lokalizacja jest już zapisana'
+ }
+ else if (xhr.status == 400) {
+ error = 'Niepoprawna nazwa hosta lub ścieżka'
+ }
+
+ if (typeof error === 'string') {
+ $('<div>', {
+ 'class': 'alert alert-danger',
+ html: '<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> ' + error
+ }).prependTo($this.find('.modal-body'));
+ $btn.button('reset');
+ }
+ else {
+ $btn.button('error');
+ }
});
});
}
},
onItemAdd: function(value) {
- view.load(value);
+ view.router.navigate('#' + value, {trigger: true});
this.blur();
},
onBlur: function() {
this.hostSelectize = this.$('#host-selector')[0].selectize;
this.render();
+ Backbone.history.start();
},
render: function() {
},
load: function(location) {
- var path = location.replace(/(^\/+|\/+$)/g, '').split('/'),
- host = path.shift(),
- pathBits = [new Filex.PathBit({'text': '/', 'path': ''})].concat(_.map(path, function(name) {
- return new Filex.PathBit({'text': name, 'path': name});
- }));
+ if (!location)
+ return;
- this.host = host;
- this.path.reset(pathBits);
+ var hostRootPath = location.split(/\/(\/|~)(.*)/), self = this;
+ this.host = hostRootPath[0];
this.$host.text(this.host);
+
+ this.path.reset([new Filex.PathBit({'name': hostRootPath[1], url: this.host + '/' + hostRootPath[1]})]);
+ _.each(hostRootPath[2].split('/'), function(item) {
+ if (item)
+ self.path.add(new Filex.PathBit({name: item, url: self.host + '/' + self.path.append(item)}));
+ });
+ this.path.last().set('active', true);
+
+ this.reloadFiles();
+ this.updateFavorites();
+
+ localStorage.last_location = location;
},
reloadFiles: function() {
this.render();
},
- selectedDir: function(dir) {
- this.path.add({'text': dir.get('name'), 'path': dir.get('name')});
- },
-
- selectedPath: function(bit) {
- this.path.reset(this.path.slice(0, this.path.indexOf(bit) + 1));
- },
-
showHidden: function() {
return this.$showHidden[0].checked;
},
$btn.button('loading');
- $.post(url, data, 'json').done(function () {
+ $.post(url, data, 'json').done(function (response) {
$btn.button('reset');
- if (is_active) {
- locations.removeOption(data.host + data.path);
- }
- else {
- locations.addOption({
- group: 'usr',
- host: data.host,
- path: data.path,
- value: data.host + data.path
- });
- }
+ if (is_active)
+ locations.removeOption(data.host + '/' + data.path);
+ else
+ locations.addOption(response);
}).fail(function() {
$btn.button('reset');
$btn.button('toggle');
},
initialLoad: function() {
- if (!this.host) {
- var opts = this.hostSelectize.options;
-
- this.load(opts[Object.keys(opts)[0]].value);
- }
- },
+ var opts = this.hostSelectize.options,
+ location = localStorage.last_location || opts[Object.keys(opts)[0]].value;
- changedPath: function () {
- this.reloadFiles();
- this.updateFavorites();
+ this.router.navigate('#' + location, {trigger: true, replace: true});
},
updateFavorites: function() {
- var loc = this.host + this.path.full(),
+ var loc = this.host + '/' + this.path.full(),
favorites = this.hostSelectize.options;
if (favorites.hasOwnProperty(loc)) {