about and help settings sections

pull/8/head
Antelle 2015-10-22 21:03:44 +03:00
parent 30512f6365
commit 6b39d53d30
18 changed files with 190 additions and 50 deletions

View File

@ -10,7 +10,8 @@ module.exports = function(grunt) {
require('load-grunt-tasks')(grunt);
var webpack = require('webpack');
var pkg = require('./package');
var pkg = require('./package.json');
var dt = new Date().toISOString().replace(/T.*/, '');
function replaceFont(css) {
css.walkAtRules('font-face', function (rule) {
@ -113,7 +114,7 @@ module.exports = function(grunt) {
options: {
replacements: [{
pattern: '# YYYY-MM-DD:v0.0.0',
replacement: '# ' + new Date().toISOString().replace(/T.*/, '') + ':v' + require('./package').version
replacement: '# ' + dt + ':v' + require('./package').version
}]
},
files: { 'dist/manifest.appcache': 'app/manifest.appcache' }
@ -158,6 +159,10 @@ module.exports = function(grunt) {
pattern: /\r?\n\s*/g,
replacement: function() { return '\n'; }
}]})},
{ test: /runtime\-info\.js$/, loader: StringReplacePlugin.replace({ replacements: [
{ pattern: /@@VERSION/g, replacement: function() { return pkg.version; } },
{ pattern: /@@DATE/g, replacement: function() { return dt; } }
]})},
{ test: /zepto(\.min)?\.js$/, loader: 'exports?Zepto; delete window.$; delete window.Zepto;' },
{ test: /baron(\.min)?\.js$/, loader: 'exports?baron; delete window.baron;' },
{ test: /pikadat\.js$/, loader: 'uglify' }

View File

@ -40,12 +40,14 @@ var MenuModel = Backbone.Model.extend({
this.generalSection = new MenuSectionModel([{ title: 'General', icon: 'cog', page: 'general', active: true }]);
this.shortcutsSection = new MenuSectionModel([{ title: 'Shortcuts', icon: 'keyboard-o', page: 'shortcuts' }]);
this.aboutSection = new MenuSectionModel([{ title: 'About', icon: 'info', page: 'about' }]);
this.helpSection = new MenuSectionModel([{ title: 'Help', icon: 'question', page: 'help' }]);
this.filesSection = new MenuSectionModel();
this.filesSection.set({ scrollable: true, grow: true });
this.menus.settings = new MenuSectionCollection([
this.generalSection,
this.shortcutsSection,
this.aboutSection,
this.helpSection,
this.filesSection
]);
this.set('sections', this.menus.app);

View File

@ -0,0 +1,14 @@
'use strict';
var Launcher;
if (window.process && window.process.versions && window.process.versions.electron) {
Launcher = {
req: window.require,
openLink: function(href) {
this.req('shell').openExternal(href);
}
};
}
module.exports = Launcher;

View File

@ -0,0 +1,10 @@
'use strict';
var RuntimeInfo = {
version: '@@VERSION',
buildDate: '@@DATE',
userAgent: navigator.userAgent,
launcher: window.process && window.process.versions && window.process.versions.electron
};
module.exports = RuntimeInfo;

View File

@ -10,7 +10,8 @@ var Backbone = require('backbone'),
SettingsView = require('../views/settings/settings-view'),
Alerts = require('../util/alerts'),
Keys = require('../const/keys'),
KeyHandler = require('../util/key-handler');
KeyHandler = require('../util/key-handler'),
Launcher = require('../util/launcher');
var AppView = Backbone.View.extend({
el: 'body',
@ -20,7 +21,8 @@ var AppView = Backbone.View.extend({
events: {
'contextmenu': 'contextmenu',
'drop': 'drop',
'dragover': 'dragover'
'dragover': 'dragover',
'click a[target=_blank]': 'extLinkClick'
},
views: null,
@ -189,11 +191,24 @@ var AppView = Backbone.View.extend({
this.showFileSettings({ fileId: this.model.files.first().cid });
},
toggleSettings: function() {
toggleSettings: function(page) {
var menuItem = page ? this.model.menu[page + 'Section'] : null;
if (menuItem) {
menuItem = menuItem.get('items').first();
}
if (this.views.settings) {
this.showEntries();
if (this.views.settings.page === page) {
this.showEntries();
} else {
if (menuItem) {
this.model.menu.select({item: menuItem});
}
}
} else {
this.showSettings();
if (menuItem) {
this.model.menu.select({item: menuItem});
}
}
},
@ -223,6 +238,13 @@ var AppView = Backbone.View.extend({
}
});
document.body.classList.add('th-' + theme);
},
extLinkClick: function(e) {
if (Launcher) {
e.preventDefault();
Launcher.openLink(e.target.href);
}
}
});

View File

@ -12,6 +12,7 @@ var FooterView = Backbone.View.extend({
'click .footer__db-item': 'showFile',
'click .footer__db-open': 'openFile',
'click .footer__btn-view': 'switchView',
'click .footer__btn-help': 'toggleHelp',
'click .footer__btn-settings': 'toggleSettings',
'click .footer__btn-generate': 'genPass',
'click .footer__btn-lock': 'lockWorkspace'
@ -73,8 +74,12 @@ var FooterView = Backbone.View.extend({
Backbone.trigger('switch-view');
},
toggleHelp: function() {
Backbone.trigger('toggle-settings', 'help');
},
toggleSettings: function() {
Backbone.trigger('toggle-settings');
Backbone.trigger('toggle-settings', 'general');
}
});

View File

@ -26,7 +26,8 @@ var GeneratorView = Backbone.View.extend({
render: function() {
var canCopy = document.queryCommandSupported('copy');
this.renderTemplate({ btnTitle: this.model.copy && canCopy ? 'Copy' : 'OK', opt: this.gen });
var btnTitle = this.model.copy ? canCopy ? 'Copy' : 'Close' : 'OK';
this.renderTemplate({ btnTitle: btnTitle, opt: this.gen });
this.resultEl = this.$el.find('.gen__result');
this.$el.css(this.model.pos);
this.generate();

View File

@ -53,7 +53,10 @@ var OpenFileView = Backbone.View.extend({
}
},
openKeyFile: function() {
openKeyFile: function(e) {
if (e.target.hasAttribute('disabled')) {
return;
}
if (!this.model.get('opening')) {
if (this.keyFileData) {
this.keyFileData = null;

View File

@ -1,12 +1,15 @@
'use strict';
var Backbone = require('backbone');
var Backbone = require('backbone'),
RuntimeInfo = require('../../util/runtime-info');
var SettingsAboutView = Backbone.View.extend({
template: require('templates/settings/settings-about.html'),
render: function() {
this.renderTemplate();
this.renderTemplate({
version: RuntimeInfo.version
});
}
});

View File

@ -11,7 +11,8 @@ var SettingsAboutView = Backbone.View.extend({
events: {
'click .settings__file-button-save-file': 'saveToFile',
'click .settings__file-button-export-xml': 'exportAsXml',
'click .settings__file-button-save-dropbox': 'saveToDropbox'
'click .settings__file-button-save-dropbox': 'saveToDropbox',
'change .settings__file-key-file': 'keyfileChange'
},
render: function() {
@ -35,6 +36,35 @@ var SettingsAboutView = Backbone.View.extend({
saveToDropbox: function() {
Alerts.notImplemented();
},
keyfileChange: function(e) {
switch (e.target.value) {
case 'ex':
this.useExistingKeyFile();
break;
case 'sel':
this.selectKeyFile();
break;
case 'gen':
this.generateKeyFile();
break;
default:
this.clearKeyFile();
break;
}
},
useExistingKeyFile: function() {
},
selectKeyFile: function() {
},
generateKeyFile: function() {
},
clearKeyFile: function() {
}
});

View File

@ -0,0 +1,20 @@
'use strict';
var Backbone = require('backbone'),
RuntimeInfo = require('../../util/runtime-info');
var SettingsHelpView = Backbone.View.extend({
template: require('templates/settings/settings-help.html'),
render: function() {
var appInfo = 'KeeWeb v' + RuntimeInfo.version + ' (built at ' + RuntimeInfo.buildDate + ')\n' +
'Environment: ' + (RuntimeInfo.launcher ? RuntimeInfo.launcher : 'web') + '\n' +
'User-Agent: ' + RuntimeInfo.userAgent;
this.renderTemplate({
issueBody: encodeURIComponent('!please, describe your issue here!\n\n' + appInfo),
appInfo: _.escape(appInfo)
});
}
});
module.exports = SettingsHelpView;

View File

@ -48,6 +48,7 @@ var SettingsView = Backbone.View.extend({
this.views.page = new SettingsPageView({ el: this.pageEl, model: e.file });
this.views.page.render();
this.file = e.file;
this.page = e.page;
this.pageResized();
},

View File

@ -43,11 +43,19 @@
}
}
&__select, &__input {
&__select, &__input, &__pre {
width: 60%;
height: 2em;
@media (max-width: 800px) {
width: calc(100% - 20px);
}
}
&__select, &__input {
height: 2em;
}
&__pre {
@include user-select(text);
white-space: pre-wrap;
}
}

View File

@ -6,6 +6,7 @@
<% }); %>
<div class="footer__db footer__db--dimmed footer__db--expanded footer__db-open"><i class="fa fa-plus"></i> Open / New</div>
<!--<div class="footer__btn footer__btn-view"><i class="fa fa-list-ul"></i></div>-->
<div class="footer__btn footer__btn-help"><i class="fa fa-question"></i></div>
<div class="footer__btn footer__btn-settings"><i class="fa fa-cog"></i></div>
<div class="footer__btn footer__btn-generate"><i class="fa fa-bolt"></i></div>
<div class="footer__btn footer__btn-lock"><i class="fa fa-lock"></i></div>

View File

@ -1,10 +1,11 @@
<h1><i class="fa fa-info"></i> About</h1>
<h1><i class="fa fa-info"></i> About KeeWeb v<%= version %></h1>
<p>This is an open-source app created by <a href="http://antelle.net" target="_blank">Antelle</a> and licensed under
<a href="http://github.com/antelle/keepass-web/MIT-LICENSE.txt" target="_blank">MIT</a>.
The source code and issues are <a href="http://github.com/antelle/keepass-web" target="_blank">on GitHub <i class="fa fa-github-alt"></i></a>.</p>
<p>This app is built with these awesome tools:</p>
<h3>Libraries</h3>
<ul>
<li><a href="http://electron.atom.io/" target="_blank">electron</a><span class="muted-color">, cross-platform desktop apps framework</span></li>
<li><a href="http://backbonejs.org/" target="_blank">backbone</a><span class="muted-color">, JavaScript framework</span></li>
<li><a href="http://underscorejs.org/" target="_blank">underscore</a><span class="muted-color">, utility-belt library for JavaScript</span></li>
<li><a href="http://zeptojs.com/" target="_blank">zepto.js</a><span class="muted-color">, a minimalist JavaScript library for modern browsers,

View File

@ -1,34 +1,38 @@
<h1><i class="fa fa-lock"></i> <%- file.get('name') %></h1>
<p>This database is opened as local file. To enable auto-save and saving with shortcut <%= cmd %>S,
please, save it to Dropbox.</p>
<form>
<div class="settings__file-buttons">
<button class="settings__file-button-save-file btn-silent">Save to file</button>
<button class="settings__file-button-export-xml btn-silent">Export to XML</button>
<button class="settings__file-button-save-dropbox btn-silent">Save to Dropbox</button>
</div>
<h2>Settings</h2>
<label for="settings__file-master-key">Master key:</label>
<input type="password" class="settings__input" id="settings__file-master-key" value="<%- file.get('passwordLength') %>" />
<input type="checkbox" class="settings__input" id="settings__file-key-file" <%- file.keyFileName ? 'checked' : '' %> />
<label for="settings__file-key-file">Use key file</label>
<div class="settings__file-buttons">
<button class="settings__file-button-save-file btn-silent">Save to file</button>
<button class="settings__file-button-export-xml btn-silent">Export to XML</button>
<button class="settings__file-button-save-dropbox btn-silent">Sync with Dropbox</button>
</div>
<h2>Names</h2>
<label for="settings__file-name">Name:</label>
<input type="text" class="settings__input" id="settings__file-name" value="<%- file.get('name') %>" />
<label for="settings__file-def-user">Default username:</label>
<input type="text" class="settings__input" id="settings__file-def-user" value="<%- file.db.meta.defaultUser %>" />
<h2>Settings</h2>
<label for="settings__file-master-key">Master key:</label>
<input type="password" class="settings__input" id="settings__file-master-key" value="<%- file.get('passwordLength') %>" />
<label for="settings__file-key-file">Key file:</label>
<select class="settings__select" id="settings__file-key-file">
<option value="">Don't use key file</option>
<option value="ex">Use existing key file</option>
<option value="gen">Generate new key file</option>
<option value="sel">Select a key file</option>
</select>
<h2>History</h2>
<input type="checkbox" class="settings__input" id="settings__file-trash" <%- file.db.meta.recycleBinEnabled ? 'checked' : '' %> />
<label for="settings__file-trash">Enable trash</label>
<label for="settings__file-hist-len">History length, keep last records per entry:</label>
<input type="text" class="settings__input" id="settings__file-hist-len" value="<%- file.db.meta.historyMaxItems %>" />
<label for="settings__file-hist-size">History size, total MB per file:</label>
<input type="text" class="settings__input" id="settings__file-hist-size" value="<%- file.db.meta.historyMaxSize/1024/1024 %>" />
<h2>Names</h2>
<label for="settings__file-name">Name:</label>
<input type="text" class="settings__input" id="settings__file-name" value="<%- file.get('name') %>" />
<label for="settings__file-def-user">Default username:</label>
<input type="text" class="settings__input" id="settings__file-def-user" value="<%- file.db.meta.defaultUser %>" />
<h2>Advanced</h2>
<label for="settings__file-key-rounds">Key encryption rounds:</label>
<input type="text" class="settings__input" id="settings__file-key-rounds" value="<%- file.db.header.keyEncryptionRounds %>" />
</form>
<h2>History</h2>
<input type="checkbox" class="settings__input" id="settings__file-trash" <%- file.db.meta.recycleBinEnabled ? 'checked' : '' %> />
<label for="settings__file-trash">Enable trash</label>
<label for="settings__file-hist-len">History length, keep last records per entry:</label>
<input type="text" class="settings__input" id="settings__file-hist-len" value="<%- file.db.meta.historyMaxItems %>" />
<label for="settings__file-hist-size">History size, total MB per file:</label>
<input type="text" class="settings__input" id="settings__file-hist-size" value="<%- file.db.meta.historyMaxSize/1024/1024 %>" />
<h2>Advanced</h2>
<label for="settings__file-key-rounds">Key encryption rounds:</label>
<input type="text" class="settings__input" id="settings__file-key-rounds" value="<%- file.db.header.keyEncryptionRounds %>" />

View File

@ -1,11 +1,9 @@
<h1><i class="fa fa-cog"></i> General Settings</h1>
<div>
<form>
<label for="settings__general-theme">Theme:</label>
<select class="settings__general-theme settings__select" id="settings__general-theme">
<% _.forEach(themes, function(name, key) { %>
<option value="<%= key %>" <%= key === activeTheme ? 'selected' : '' %>><%- name %></option>
<% }); %>
</select>
</form>
<label for="settings__general-theme">Theme:</label>
<select class="settings__general-theme settings__select" id="settings__general-theme">
<% _.forEach(themes, function(name, key) { %>
<option value="<%= key %>" <%= key === activeTheme ? 'selected' : '' %>><%- name %></option>
<% }); %>
</select>
</div>

View File

@ -0,0 +1,12 @@
<h1><i class="fa fa-question"></i> Help</h1>
<h2>File Format</h2>
<p>This is a port of <a href="http://keepass.info/" target="_blank">KeePass</a> app built with web technologies.
It understands files in KeePass format (kdbx). You can create such files (password databases) either in KeePass, or in this app.
The file format is 100% compatible and should be understood by both apps.
</p>
<h2>Problems?</h2>
<p>If something goes wrong, please, <a href="https://github.com/antelle/keeweb/issues/new?body=<%= issueBody %>" target="_blank">open an issue on GitHub</a>
or <a href="http://antelle.net/" target="_blank">connect a developer</a> directly.
</p>
<p>App information:</p>
<pre class="settings__pre"><%= appInfo %></pre>