custom icons layout

This commit is contained in:
Antelle 2015-11-21 20:04:04 +03:00
parent 564f1af7fe
commit 5d5a033cd1
5 changed files with 108 additions and 11 deletions

View File

@ -189,7 +189,7 @@ var DetailsView = Backbone.View.extend({
return;
}
this.removeSubView();
var subView = new IconSelectView({ el: this.scroller, model: this.model });
var subView = new IconSelectView({ el: this.scroller, model: this.model, url: this.model.get('url') });
this.listenTo(subView, 'select', this.iconSelected);
subView.render();
this.pageResized();

View File

@ -7,13 +7,17 @@ var IconSelectView = Backbone.View.extend({
template: require('templates/icon-select.html'),
events: {
'click .icon-select__icon': 'iconClick'
'click .icon-select__icon': 'iconClick',
'click .icon-select__icon-download': 'downloadIcon',
'click .icon-select__icon-select': 'selectIcon',
'change .icon-select__file-input': 'iconSelected'
},
render: function() {
this.renderTemplate({
sel: this.model.iconId,
icons: IconMap
icons: IconMap,
canDownloadFavicon: !!this.model.url
}, true);
return this;
},
@ -23,6 +27,67 @@ var IconSelectView = Backbone.View.extend({
if (typeof iconId === 'number' && !isNaN(iconId)) {
this.trigger('select', iconId);
}
},
downloadIcon: function() {
if (this.downloadingFavicon) {
return;
}
this.downloadingFavicon = true;
this.$el.find('.icon-select__icon-download>i').addClass('fa-spinner fa-spin');
var that = this;
var url = this.getIconUrl();
var img = document.createElement('img');
img.src = url;
img.width = 16;
img.height = 16;
img.onload = function() {
that.$el.find('.icon-select__icon-download img').remove();
that.$el.find('.icon-select__icon-download>i').removeClass('fa-spinner fa-spin');
that.$el.find('.icon-select__icon-download').addClass('icon-select__icon--custom-selected').append(img);
that.downloadingFavicon = false;
};
img.onerror = function(e) {
console.error('Favicon download error: ' + url, e);
that.$el.find('.icon-select__icon-download>i').removeClass('fa-spinner fa-spin');
that.$el.find('.icon-select__icon-download').removeClass('icon-select__icon--custom-selected');
that.downloadingFavicon = false;
};
},
getIconUrl: function() {
if (!this.model.url) {
return null;
}
var url = this.model.url.replace(/([^\/:]\/.*)?$/, function(match) { return (match && match[0]) + '/favicon.ico'; });
if (url.indexOf('://') < 0) {
url = 'http://' + url;
}
return url;
},
selectIcon: function() {
this.$el.find('.icon-select__file-input').click();
},
iconSelected: function(e) {
var that = this;
var file = e.target.files[0];
if (file) {
var reader = new FileReader();
reader.onload = function(e) {
var img = document.createElement('img');
img.src = e.target.result;
img.width = 16;
img.height = 16;
that.$el.find('.icon-select__icon-select img').remove();
that.$el.find('.icon-select__icon-select').addClass('icon-select__icon--custom-selected').append(img);
};
reader.readAsDataURL(file);
} else {
that.$el.find('.icon-select__icon-select img').remove();
that.$el.find('.icon-select__icon-select').removeClass('icon-select__icon--custom-selected');
}
}
});

View File

@ -103,8 +103,8 @@
width: 16px;
height: 16px;
&--custom {
@include filter(grayscale(1));
vertical-align: text-bottom;
@include filter(grayscale(1));
&.yellow { @include filter(grayscale(1) sepia(1) hue-rotate(20deg) brightness(1.17) saturate(5.7)); }
&.green { @include filter(grayscale(1) sepia(1) hue-rotate(55deg) brightness(1.01) saturate(4.9)); }
&.red { @include filter(grayscale(1) sepia(1) hue-rotate(316deg) brightness(1) saturate(7.4)); }

View File

@ -1,10 +1,22 @@
&.icon-select {
@include display(flex);
@include align-items(flex-start);
@include flex-direction(row);
@include align-items(stretch);
@include flex-direction(column);
@include justify-content(flex-start);
@include flex-wrap(wrap);
@include user-select(none);
&__items {
@include flex(1 1 auto);
@include display(flex);
@include align-items(flex-start);
@include flex-direction(row);
@include justify-content(flex-start);
@include flex-wrap(wrap);
@include user-select(none);
padding-bottom: $base-padding-h;
&--custom {
padding-top: $base-padding-h;
@include th { border-top: 1px solid light-border-color(); }
}
}
&__icon {
@include area-selectable(bottom);
width: 26px;
@ -14,5 +26,12 @@
&.icon-select__icon--active {
@include area-selected(bottom);
}
&-btn {
padding: 5px 10px;
}
&--custom-selected {
//@include filter(grayscale(1));
>i { display: none; }
}
}
}

View File

@ -1,5 +1,18 @@
<div class="icon-select">
<% icons.forEach(function(icon, ix) { %>
<i class="fa fa-<%= icon %> icon-select__icon <%= ix === sel ? 'icon-select__icon--active' : '' %>" data-val="<%= ix %>"></i>
<% }); %>
<div class="icon-select__items">
<% icons.forEach(function(icon, ix) { %>
<i class="fa fa-<%= icon %> icon-select__icon <%= ix === sel ? 'icon-select__icon--active' : '' %>" data-val="<%= ix %>"></i>
<% }); %>
</div>
<div class="icon-select__items icon-select__items--custom">
<input type="file" class="icon-select__file-input hide-by-pos" accept="image/*" />
<% if (canDownloadFavicon) { %>
<span class="icon-select__icon icon-select__icon-btn icon-select__icon-download" title="Download and use website favicon">
<i class="fa fa-cloud-download"></i>
</span>
<% } %>
<span class="icon-select__icon icon-select__icon-btn icon-select__icon-select" title="Select custom icon">
<i class="fa fa-ellipsis-h"></i>
</span>
</div>
</div>