mirror of https://github.com/keeweb/keeweb.git
custom icons rendering
This commit is contained in:
parent
5d5a033cd1
commit
f84985b79a
11
TODO.md
11
TODO.md
|
@ -1,16 +1,5 @@
|
|||
# TODO
|
||||
|
||||
## v0.4
|
||||
Nov
|
||||
- [x] desktop dropbox
|
||||
- [x] lock flow, auto-lock
|
||||
- [x] minimize to tray
|
||||
- [x] trim history by rules
|
||||
- [ ] custom icons, favicons
|
||||
- [x] drag to trash
|
||||
- [x] switch view
|
||||
- [x] option to check updates without install
|
||||
|
||||
## v0.5
|
||||
Dec
|
||||
- [ ] conflict-free 2-way merge sync
|
||||
|
|
|
@ -4,6 +4,7 @@ var Backbone = require('backbone'),
|
|||
AttachmentModel = require('./attachment-model'),
|
||||
IconMap = require('../const/icon-map'),
|
||||
Color = require('../util/color'),
|
||||
IconUrl = require('../util/icon-url'),
|
||||
kdbxweb = require('kdbxweb');
|
||||
|
||||
var EntryModel = Backbone.Model.extend({
|
||||
|
@ -66,10 +67,7 @@ var EntryModel = Backbone.Model.extend({
|
|||
_buildCustomIcon: function() {
|
||||
this.customIcon = null;
|
||||
if (this.entry.customIcon) {
|
||||
var iconData = this.file.db.meta.customIcons[this.entry.customIcon];
|
||||
if (iconData) {
|
||||
this.customIcon = kdbxweb.ByteUtils.bytesToBase64(iconData);
|
||||
}
|
||||
this.customIcon = IconUrl.toDataUrl(this.file.db.meta.customIcons[this.entry.customIcon]);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
var MenuItemModel = require('./menu/menu-item-model'),
|
||||
EntryModel = require('../models/entry-model'),
|
||||
IconMap = require('../const/icon-map'),
|
||||
KdbxIcons = require('kdbxweb').Consts.Icons,
|
||||
IconUrl = require('../util/icon-url'),
|
||||
kdbxweb = require('kdbxweb'),
|
||||
KdbxIcons = kdbxweb.Consts.Icons,
|
||||
GroupCollection, EntryCollection;
|
||||
|
||||
var GroupModel = MenuItemModel.extend({
|
||||
|
@ -49,7 +51,8 @@ var GroupModel = MenuItemModel.extend({
|
|||
this.set({
|
||||
title: this.group.name,
|
||||
iconId: this.group.icon,
|
||||
icon: this._iconFromId(this.group.icon)
|
||||
icon: this._iconFromId(this.group.icon),
|
||||
customIcon: this._buildCustomIcon()
|
||||
}, { silent: silent });
|
||||
},
|
||||
|
||||
|
@ -60,6 +63,14 @@ var GroupModel = MenuItemModel.extend({
|
|||
return IconMap[id];
|
||||
},
|
||||
|
||||
_buildCustomIcon: function() {
|
||||
this.customIcon = null;
|
||||
if (this.group.customIcon) {
|
||||
return IconUrl.toDataUrl(this.file.db.meta.customIcons[this.group.customIcon]);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
_groupModified: function() {
|
||||
this.file.setModified();
|
||||
if (this.isJustCreated) {
|
||||
|
|
|
@ -8,6 +8,7 @@ var MenuItemModel = Backbone.Model.extend({
|
|||
defaults: {
|
||||
title: '',
|
||||
icon: '',
|
||||
customIcon: null,
|
||||
active: false,
|
||||
expanded: true,
|
||||
items: null,
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
'use strict';
|
||||
|
||||
var kdbxweb = require('kdbxweb');
|
||||
|
||||
var IconUrl = {
|
||||
toDataUrl: function(iconData) {
|
||||
return iconData ? 'data:image/png;base64,' + kdbxweb.ByteUtils.bytesToBase64(iconData) : null;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = IconUrl;
|
|
@ -25,6 +25,7 @@ var GrpView = Backbone.View.extend({
|
|||
this.$el.html(this.template({
|
||||
title: this.model.get('title'),
|
||||
icon: this.model.get('icon') || 'folder',
|
||||
customIcon: this.model.get('customIcon'),
|
||||
readonly: this.model.get('top')
|
||||
}));
|
||||
if (!this.model.get('title')) {
|
||||
|
|
|
@ -62,6 +62,11 @@
|
|||
&-icon {
|
||||
width: 1.4em;
|
||||
text-align: center;
|
||||
&--icon {
|
||||
background-position: center center;
|
||||
background-size: 28px 28px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,10 @@
|
|||
padding: $base-padding-px;
|
||||
@include align-self(flex-start);
|
||||
@include area-selectable();
|
||||
&--image {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
&__buttons {
|
||||
|
|
|
@ -107,7 +107,7 @@
|
|||
@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)); }
|
||||
&.red { @include filter(grayscale(1) sepia(1) hue-rotate(316deg) brightness(1.1) saturate(6)); }
|
||||
&.orange { @include filter(grayscale(1) sepia(1) hue-rotate(355deg) brightness(0.92) saturate(5)); }
|
||||
&.blue { @include filter(grayscale(1) sepia(1) hue-rotate(180deg) brightness(0.9) saturate(5)); }
|
||||
&.violet { @include filter(grayscale(1) sepia(1) hue-rotate(238deg) brightness(1) saturate(6.2)); }
|
||||
|
|
|
@ -105,6 +105,12 @@
|
|||
|
||||
&-icon {
|
||||
width: .8em;
|
||||
&--image {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
&--no-icon:before {
|
||||
content: $fa-var-folder-open;
|
||||
.menu__item--collapsed>.menu__item-body>& {
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
@include transform-style(perspective-3d);
|
||||
}
|
||||
|
||||
.grayscale {
|
||||
@include filter(grayscale(1));
|
||||
}
|
||||
|
||||
@include keyframes(flip3d) {
|
||||
from {
|
||||
@include transform(rotateY(0));
|
||||
|
|
|
@ -14,7 +14,11 @@
|
|||
</span>
|
||||
</i>
|
||||
<h1 class="details__header-title"><%- title || '(no title)' %></h1>
|
||||
<% if (customIcon) { %>
|
||||
<div class="details__header-icon details__header-icon--icon" style="background-image: url(<%= customIcon %>)" title="Change icon"></div>
|
||||
<% } else { %>
|
||||
<i class="details__header-icon fa fa-<%= icon %>" title="Change icon"></i>
|
||||
<% } %>
|
||||
</div>
|
||||
<div class="details__body">
|
||||
<div class="scroller">
|
||||
|
|
|
@ -10,7 +10,11 @@
|
|||
required <%= readonly ? 'readonly' : '' %> />
|
||||
</div>
|
||||
<label>Icon:</label>
|
||||
<% if (customIcon) { %>
|
||||
<img src="<%= customIcon %>" class="grp__icon grp__icon--image" />
|
||||
<% } else { %>
|
||||
<i class="fa fa-<%- icon %> grp__icon"></i>
|
||||
<% } %>
|
||||
<div class="grp__icons"></div>
|
||||
</div>
|
||||
<div class="scroller__bar-wrapper"><div class="scroller__bar"></div></div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<div class="list__item <%= active ? 'list__item--active' : '' %> <%= expired ? 'list__item--expired' : '' %>" id="<%= id %>" draggable="true">
|
||||
<% if (customIcon) { %><img src="data:image/png;base64,<%= customIcon %>" class="list__item-icon list__item-icon--custom <%= color || '' %>" /><% }
|
||||
<% if (customIcon) { %><img src="<%= customIcon %>" class="list__item-icon list__item-icon--custom <%= color || '' %>" /><% }
|
||||
else { %><i class="fa fa-<%= icon %> <%= color ? color+'-color' : '' %> list__item-icon"></i><% } %>
|
||||
<span class="list__item-title"><%- title || '(no title)' %></span><span class="list__item-descr thin"><%- description %></span>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<tr class="list__item list__item--table <%= active ? 'list__item--active' : '' %> <%= expired ? 'list__item--expired' : '' %>" id="<%= id %>" draggable="true">
|
||||
<td><% if (customIcon) { %><img src="data:image/png;base64,<%= customIcon %>" class="list__item-icon list__item-icon--custom <%= color || '' %>" /><% }
|
||||
<td><% if (customIcon) { %><img src="<%= customIcon %>" class="list__item-icon list__item-icon--custom <%= color || '' %>" /><% }
|
||||
else { %><i class="fa fa-<%= icon %> <%= color ? color+'-color' : '' %> list__item-icon"></i><% } %></td>
|
||||
<td><%- title || '(no title)' %></td>
|
||||
<td><%- description %></td>
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
options && options.length ? 'menu__item--with-options' : '' %> <%=
|
||||
cls ? cls : '' %>">
|
||||
<div class="menu__item-body" <%= drag ? 'draggable="true"' : '' %>>
|
||||
<i class="menu__item-icon fa <%= icon ? 'fa-' + icon : 'menu__item-icon--no-icon' %>"></i><span
|
||||
class="menu__item-title"><%- title || '(no title)' %></span>
|
||||
<% if (customIcon) { %><img src="<%= customIcon %>" class="menu__item-icon menu__item-icon--image" /><% }
|
||||
else { %><i class="menu__item-icon fa <%= icon ? 'fa-' + icon : 'menu__item-icon--no-icon' %>"></i><% }
|
||||
%><span class="menu__item-title"><%- title || '(no title)' %></span>
|
||||
<% if (options) { %>
|
||||
<div class="menu__item-options">
|
||||
<% options.forEach(function(option) { %>
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
Release notes
|
||||
-------------
|
||||
##### vNext
|
||||
Locking, better Dropbox, security enhancements, bugfixes
|
||||
Locking, better Dropbox, custom icons, security enhancements, bugfixes
|
||||
`+` lock flow, auto-lock
|
||||
`+` entries list display table layout
|
||||
`+` minimize to tray on windows
|
||||
`+` desktop Dropbox
|
||||
`+` Dropbox notification in self-hosted apps
|
||||
`+` custom icons support
|
||||
`+` option to check updates without install
|
||||
`+` clear clipboard password after timeout
|
||||
`+` trim history by rules
|
||||
|
|
Loading…
Reference in New Issue