icon select view

This commit is contained in:
antelle 2019-09-15 20:09:28 +02:00
parent 7589a112d0
commit 43b11277ad
6 changed files with 70 additions and 50 deletions

View File

@ -1,6 +1,8 @@
import Backbone from 'backbone';
import { Tip } from 'util/ui/tip';
const backboneListenTo = Backbone.View.prototype.listenTo;
_.extend(Backbone.View.prototype, {
hide() {
Tip.hideTips(this.$el);
@ -38,7 +40,7 @@ _.extend(Backbone.View.prototype, {
},
renderTemplate(model, replace) {
Tip.hideTips(this.$el);
Tip.destroyTips(this.$el);
if (replace && replace.plain) {
this.$el.html(this.template(model));
} else {
@ -67,7 +69,7 @@ _.extend(Backbone.View.prototype, {
this.scroll.dispose();
} catch (e) {}
}
Tip.hideTips(this.$el);
Tip.destroyTips(this.$el);
this._parentRemove();
},
@ -84,5 +86,9 @@ _.extend(Backbone.View.prototype, {
});
this.views = {};
}
},
listenTo(obj, name, callback) {
return backboneListenTo.call(this, obj, name, callback.bind(this));
}
});

View File

@ -6,6 +6,7 @@ import { Logger } from 'util/logger';
class View extends EventEmitter {
parent = undefined;
replace = false;
template = undefined;
events = {};
views = {};
@ -14,10 +15,17 @@ class View extends EventEmitter {
boundEvents = [];
debugLogger = localStorage.debugViews ? new Logger('view', this.constructor.name) : undefined;
constructor(model) {
constructor(model, options = {}) {
super();
this.model = model;
if (options.parent) {
this.parent = options.parent;
}
if (options.replace) {
this.replace = options.replace;
}
}
render(templateData) {
@ -47,16 +55,21 @@ class View extends EventEmitter {
if (this.el) {
morphdom(this.el, html);
} else {
const el = document.createElement('div');
el.innerHTML = html;
this.el = el.firstChild;
if (this.parent) {
const parent = document.querySelector(this.parent);
if (!parent) {
throw new Error(
`Error rendering ${this.constructor.name}: parent not found: ${parent}`
);
let parent = this.parent;
if (typeof parent === 'string') {
parent = document.querySelector(this.parent);
}
if (!parent) {
throw new Error(`Error rendering ${this.constructor.name}: parent not found`);
}
if (this.replace) {
Tip.destroyTips(parent);
parent.innerHTML = '';
}
const el = document.createElement('div');
el.innerHTML = html;
this.el = el.firstChild;
parent.appendChild(this.el);
} else {
throw new Error(

View File

@ -134,6 +134,7 @@ const DetailsView = Backbone.View.extend({
},
render() {
Tip.destroyTips(this.$el);
this.removeScroll();
this.removeFieldViews();
this.removeInnerViews();
@ -547,14 +548,17 @@ const DetailsView = Backbone.View.extend({
return;
}
this.removeSubView();
const subView = new IconSelectView({
el: this.scroller,
model: {
const subView = new IconSelectView(
{
iconId: this.model.customIconId || this.model.iconId,
url: this.model.url,
file: this.model.file
},
{
parent: this.scroller[0],
replace: true
}
});
);
this.listenTo(subView, 'select', this.iconSelected);
subView.render();
this.pageResized();

View File

@ -91,13 +91,15 @@ class GrpView extends View {
if (this.views.sub) {
this.removeSubView();
} else {
const subView = new IconSelectView({
el: this.$el.find('.grp__icons'),
model: {
const subView = new IconSelectView(
{
iconId: this.model.get('customIconId') || this.model.get('iconId'),
file: this.model.file
},
{
parent: this.$el.find('.grp__icons')[0]
}
});
);
this.listenTo(subView, 'select', this.iconSelected);
subView.render();
this.views.sub = subView;

View File

@ -1,38 +1,33 @@
import Backbone from 'backbone';
import { View } from 'view-engine/view';
import { IconMap } from 'const/icon-map';
import { Logger } from 'util/logger';
import template from 'templates/icon-select.hbs';
const logger = new Logger('icon-select-view');
const IconSelectView = Backbone.View.extend({
template: require('templates/icon-select.hbs'),
class IconSelectView extends View {
template = template;
events: {
events = {
'click .icon-select__icon': 'iconClick',
'click .icon-select__icon-download': 'downloadIcon',
'click .icon-select__icon-select': 'selectIcon',
'change .icon-select__file-input': 'iconSelected'
},
};
initialize() {
this.special = {
select: null,
download: null
};
},
special = {
select: null,
download: null
};
render() {
this.renderTemplate(
{
sel: this.model.iconId,
icons: IconMap,
canDownloadFavicon: !!this.model.url,
customIcons: this.model.file.getCustomIcons()
},
true
);
return this;
},
super.render({
sel: this.model.iconId,
icons: IconMap,
canDownloadFavicon: !!this.model.url,
customIcons: this.model.file.getCustomIcons()
});
}
iconClick(e) {
const target = $(e.target).closest('.icon-select__icon');
@ -41,15 +36,15 @@ const IconSelectView = Backbone.View.extend({
const iconData = this.special[target.data('special')];
if (iconData) {
const id = this.model.file.addCustomIcon(iconData.data);
this.trigger('select', { id, custom: true });
this.emit('select', { id, custom: true });
e.preventDefault();
e.stopImmediatePropagation();
}
} else if (iconId) {
const isCustomIcon = target.hasClass('icon-select__icon-custom');
this.trigger('select', { id: iconId, custom: isCustomIcon });
this.emit('select', { id: iconId, custom: isCustomIcon });
}
},
}
downloadIcon() {
if (this.downloadingFavicon) {
@ -83,7 +78,7 @@ const IconSelectView = Backbone.View.extend({
.addClass('icon-select__icon--download-error');
this.downloadingFavicon = false;
};
},
}
getIconUrl(useService) {
if (!this.model.url) {
@ -100,11 +95,11 @@ const IconSelectView = Backbone.View.extend({
return 'https://favicon.keeweb.info/' + url.replace(/^.*:\/+/, '').replace(/\/.*/, '');
}
return url;
},
}
selectIcon() {
this.$el.find('.icon-select__file-input').click();
},
}
iconSelected(e) {
const file = e.target.files[0];
@ -129,7 +124,7 @@ const IconSelectView = Backbone.View.extend({
.find('.icon-select__icon-select')
.removeClass('icon-select__icon--custom-selected');
}
},
}
setSpecialImage(img, name) {
const size = Math.min(img.width, 32);
@ -141,6 +136,6 @@ const IconSelectView = Backbone.View.extend({
const data = canvas.toDataURL().replace(/^.*,/, '');
this.special[name] = { width: img.width, height: img.height, data };
}
});
}
export { IconSelectView };

View File

@ -49,7 +49,7 @@ const MenuItemView = Backbone.View.extend({
render() {
this.removeInnerViews();
this.renderTemplate(this.model.attributes);
this.iconEl = this.$el.find('i.menu__item-icon');
this.iconEl = this.$el.find('.menu__item-icon');
const items = this.model.get('items');
if (items) {
items.forEach(function(item) {