mirror of
http://git.whoc.org.uk/git/password-manager.git
synced 2024-11-14 23:49:02 +01:00
Implemented Marco's remarks on PIN and Preferences
This commit is contained in:
parent
f2b85dd506
commit
e21645028f
@ -119,7 +119,6 @@ http://jonibologna.com/flexbox-cheatsheet/
|
|||||||
-ms-transform: rotate(0deg) translate(0, 0);
|
-ms-transform: rotate(0deg) translate(0, 0);
|
||||||
-o-transform: rotate(0deg) translate(0, 0);
|
-o-transform: rotate(0deg) translate(0, 0);
|
||||||
transform: rotate(0deg) translate(0, 0); }
|
transform: rotate(0deg) translate(0, 0); }
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
-webkit-transform: rotate(359deg) translate(0, 0);
|
-webkit-transform: rotate(359deg) translate(0, 0);
|
||||||
-moz-transform: rotate(359deg) translate(0, 0);
|
-moz-transform: rotate(359deg) translate(0, 0);
|
||||||
@ -133,7 +132,6 @@ http://jonibologna.com/flexbox-cheatsheet/
|
|||||||
-ms-transform: rotate(0deg) translate(0, 0);
|
-ms-transform: rotate(0deg) translate(0, 0);
|
||||||
-o-transform: rotate(0deg) translate(0, 0);
|
-o-transform: rotate(0deg) translate(0, 0);
|
||||||
transform: rotate(0deg) translate(0, 0); }
|
transform: rotate(0deg) translate(0, 0); }
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
-webkit-transform: rotate(359deg) translate(0, 0);
|
-webkit-transform: rotate(359deg) translate(0, 0);
|
||||||
-moz-transform: rotate(359deg) translate(0, 0);
|
-moz-transform: rotate(359deg) translate(0, 0);
|
||||||
@ -147,7 +145,6 @@ http://jonibologna.com/flexbox-cheatsheet/
|
|||||||
-ms-transform: rotate(0deg) translate(0, 0);
|
-ms-transform: rotate(0deg) translate(0, 0);
|
||||||
-o-transform: rotate(0deg) translate(0, 0);
|
-o-transform: rotate(0deg) translate(0, 0);
|
||||||
transform: rotate(0deg) translate(0, 0); }
|
transform: rotate(0deg) translate(0, 0); }
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
-webkit-transform: rotate(359deg) translate(0, 0);
|
-webkit-transform: rotate(359deg) translate(0, 0);
|
||||||
-moz-transform: rotate(359deg) translate(0, 0);
|
-moz-transform: rotate(359deg) translate(0, 0);
|
||||||
@ -161,7 +158,6 @@ http://jonibologna.com/flexbox-cheatsheet/
|
|||||||
-ms-transform: rotate(0deg) translate(0, 0);
|
-ms-transform: rotate(0deg) translate(0, 0);
|
||||||
-o-transform: rotate(0deg) translate(0, 0);
|
-o-transform: rotate(0deg) translate(0, 0);
|
||||||
transform: rotate(0deg) translate(0, 0); }
|
transform: rotate(0deg) translate(0, 0); }
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
-webkit-transform: rotate(359deg) translate(0, 0);
|
-webkit-transform: rotate(359deg) translate(0, 0);
|
||||||
-moz-transform: rotate(359deg) translate(0, 0);
|
-moz-transform: rotate(359deg) translate(0, 0);
|
||||||
@ -480,73 +476,61 @@ div.overlay {
|
|||||||
@-webkit-keyframes overlay-spin {
|
@-webkit-keyframes overlay-spin {
|
||||||
from {
|
from {
|
||||||
opacity: 1; }
|
opacity: 1; }
|
||||||
|
|
||||||
to {
|
to {
|
||||||
opacity: 0.25; } }
|
opacity: 0.25; } }
|
||||||
@-moz-keyframes overlay-spin {
|
@-moz-keyframes overlay-spin {
|
||||||
from {
|
from {
|
||||||
opacity: 1; }
|
opacity: 1; }
|
||||||
|
|
||||||
to {
|
to {
|
||||||
opacity: 0.25; } }
|
opacity: 0.25; } }
|
||||||
@-ms-keyframes overlay-spin {
|
@-ms-keyframes overlay-spin {
|
||||||
from {
|
from {
|
||||||
opacity: 1; }
|
opacity: 1; }
|
||||||
|
|
||||||
to {
|
to {
|
||||||
opacity: 0.25; } }
|
opacity: 0.25; } }
|
||||||
@keyframes overlay-spin {
|
@keyframes overlay-spin {
|
||||||
from {
|
from {
|
||||||
opacity: 1; }
|
opacity: 1; }
|
||||||
|
|
||||||
to {
|
to {
|
||||||
opacity: 0.25; } }
|
opacity: 0.25; } }
|
||||||
@-webkit-keyframes ios-overlay-show {
|
@-webkit-keyframes ios-overlay-show {
|
||||||
0% {
|
0% {
|
||||||
opacity: 0; }
|
opacity: 0; }
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
opacity: 1; } }
|
opacity: 1; } }
|
||||||
@-moz-keyframes ios-overlay-show {
|
@-moz-keyframes ios-overlay-show {
|
||||||
0% {
|
0% {
|
||||||
opacity: 0; }
|
opacity: 0; }
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
opacity: 1; } }
|
opacity: 1; } }
|
||||||
@-ms-keyframes ios-overlay-show {
|
@-ms-keyframes ios-overlay-show {
|
||||||
0% {
|
0% {
|
||||||
opacity: 0; }
|
opacity: 0; }
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
opacity: 1; } }
|
opacity: 1; } }
|
||||||
@keyframes ios-overlay-show {
|
@keyframes ios-overlay-show {
|
||||||
0% {
|
0% {
|
||||||
opacity: 0; }
|
opacity: 0; }
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
opacity: 1; } }
|
opacity: 1; } }
|
||||||
@-webkit-keyframes ios-overlay-hide {
|
@-webkit-keyframes ios-overlay-hide {
|
||||||
0% {
|
0% {
|
||||||
opacity: 1; }
|
opacity: 1; }
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
opacity: 0; } }
|
opacity: 0; } }
|
||||||
@-moz-keyframes ios-overlay-hide {
|
@-moz-keyframes ios-overlay-hide {
|
||||||
0% {
|
0% {
|
||||||
opacity: 1; }
|
opacity: 1; }
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
opacity: 0; } }
|
opacity: 0; } }
|
||||||
@-ms-keyframes ios-overlay-hide {
|
@-ms-keyframes ios-overlay-hide {
|
||||||
0% {
|
0% {
|
||||||
opacity: 1; }
|
opacity: 1; }
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
opacity: 0; } }
|
opacity: 0; } }
|
||||||
@keyframes ios-overlay-hide {
|
@keyframes ios-overlay-hide {
|
||||||
0% {
|
0% {
|
||||||
opacity: 1; }
|
opacity: 1; }
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
opacity: 0; } }
|
opacity: 0; } }
|
||||||
/*
|
/*
|
||||||
@ -2293,13 +2277,13 @@ span.count {
|
|||||||
#extraFeaturesPanel .extraFeatureIndex footer {
|
#extraFeaturesPanel .extraFeatureIndex footer {
|
||||||
font-size: 8pt;
|
font-size: 8pt;
|
||||||
padding: 5px 5px 5px 5px;
|
padding: 5px 5px 5px 5px;
|
||||||
border-top: 1px solid #999999; }
|
border-top: 1px solid #999; }
|
||||||
#extraFeaturesPanel .extraFeatureIndex footer span {
|
#extraFeaturesPanel .extraFeatureIndex footer span {
|
||||||
color: #999999; }
|
color: #999; }
|
||||||
#extraFeaturesPanel .extraFeatureIndex footer span:after {
|
#extraFeaturesPanel .extraFeatureIndex footer span:after {
|
||||||
content: ":"; }
|
content: ":"; }
|
||||||
#extraFeaturesPanel .extraFeatureIndex footer a {
|
#extraFeaturesPanel .extraFeatureIndex footer a {
|
||||||
color: #999999;
|
color: #999;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
padding-left: 5px;
|
padding-left: 5px;
|
||||||
font-weight: bold; }
|
font-weight: bold; }
|
||||||
@ -2674,15 +2658,11 @@ span.count {
|
|||||||
padding: 0 1em;
|
padding: 0 1em;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
cursor: pointer; }
|
cursor: pointer; }
|
||||||
#extraFeaturesPanel .extraFeatureContent .devicePIN .pinDigit {
|
|
||||||
display: inline-block;
|
|
||||||
width: 2em;
|
|
||||||
margin-right: 0.5em;
|
|
||||||
text-align: center; }
|
|
||||||
#extraFeaturesPanel .extraFeatureContent .devicePIN .pinValue {
|
#extraFeaturesPanel .extraFeatureContent .devicePIN .pinValue {
|
||||||
display: inline-block;
|
display: block;
|
||||||
width: 4em;
|
width: 4em;
|
||||||
margin-right: 1em; }
|
margin-right: 1em;
|
||||||
|
margin-top: 8px; }
|
||||||
#extraFeaturesPanel .extraFeatureContent .devicePIN :enabled {
|
#extraFeaturesPanel .extraFeatureContent .devicePIN :enabled {
|
||||||
border: 2px solid #ff9900; }
|
border: 2px solid #ff9900; }
|
||||||
#extraFeaturesPanel .extraFeatureContent .devicePIN .content {
|
#extraFeaturesPanel .extraFeatureContent .devicePIN .content {
|
||||||
@ -3101,7 +3081,7 @@ div.cardList ul {
|
|||||||
padding-right: 0px;
|
padding-right: 0px;
|
||||||
box-shadow: -4px 0px 3px -1px rgba(0, 0, 0, 0.2); }
|
box-shadow: -4px 0px 3px -1px rgba(0, 0, 0, 0.2); }
|
||||||
div.cardList ul li.archived {
|
div.cardList ul li.archived {
|
||||||
background-color: #eeeeee;
|
background-color: #eee;
|
||||||
color: #999; }
|
color: #999; }
|
||||||
div.cardList ul li .favicon {
|
div.cardList ul li .favicon {
|
||||||
width: 48px;
|
width: 48px;
|
||||||
@ -3188,7 +3168,7 @@ div.cardList.narrow {
|
|||||||
content: ""; }
|
content: ""; }
|
||||||
|
|
||||||
#cardDetailPage .view.archived, .cardDetail .view.archived {
|
#cardDetailPage .view.archived, .cardDetail .view.archived {
|
||||||
background-color: #eeeeee; }
|
background-color: #eee; }
|
||||||
#cardDetailPage .view .cardDetailToolbar, .cardDetail .view .cardDetailToolbar {
|
#cardDetailPage .view .cardDetailToolbar, .cardDetail .view .cardDetailToolbar {
|
||||||
background-color: #1863a1;
|
background-color: #1863a1;
|
||||||
color: white; }
|
color: white; }
|
||||||
@ -3433,7 +3413,7 @@ div.cardList.narrow {
|
|||||||
cursor: grab;
|
cursor: grab;
|
||||||
cursor: -moz-grab;
|
cursor: -moz-grab;
|
||||||
cursor: -webkit-grab;
|
cursor: -webkit-grab;
|
||||||
background: repeating-linear-gradient(0deg, white, white 2px, #dddddd 2px, #dddddd 3px);
|
background: repeating-linear-gradient(0deg, white, white 2px, #ddd 2px, #ddd 3px);
|
||||||
width: 28px;
|
width: 28px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
margin-left: 6px;
|
margin-left: 6px;
|
||||||
@ -3659,7 +3639,7 @@ div.cardList.narrow {
|
|||||||
min-width: 220px;
|
min-width: 220px;
|
||||||
width: 80%;
|
width: 80%;
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
background-color: #333333;
|
background-color: #333;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
-webkit-border-radius: 6px;
|
-webkit-border-radius: 6px;
|
||||||
-moz-border-radius: 6px;
|
-moz-border-radius: 6px;
|
||||||
@ -3674,7 +3654,7 @@ div.cardList.narrow {
|
|||||||
margin-left: 0px;
|
margin-left: 0px;
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
border-top: 5px solid #333333;
|
border-top: 5px solid #333;
|
||||||
border-left: 5px solid transparent;
|
border-left: 5px solid transparent;
|
||||||
border-right: 5px solid transparent; }
|
border-right: 5px solid transparent; }
|
||||||
.passwordGenerator .passwordGeneratorBaloon form span {
|
.passwordGenerator .passwordGeneratorBaloon form span {
|
||||||
|
File diff suppressed because one or more lines are too long
@ -41,19 +41,27 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User.Header.Preferences, Clipperz.PM.
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
'mergeDefaultPreferences': function(somePreferences) {
|
'mergePreferences': function(somePreferences, someOtherPreferences) {
|
||||||
var result;
|
var result;
|
||||||
|
|
||||||
result = new Clipperz.KeyValueObjectStore();
|
result = new Clipperz.KeyValueObjectStore();
|
||||||
|
|
||||||
result.setValues(MochiKit.Base.updatetree(
|
result.setValues(MochiKit.Base.updatetree(
|
||||||
Clipperz.Base.deepClone(Clipperz.PM.DataModel.User.Header.Preferences.defaultPreferences),
|
Clipperz.Base.deepClone(someOtherPreferences),
|
||||||
somePreferences
|
somePreferences
|
||||||
));
|
));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'mergeDefaultPreferences': function(somePreferences) {
|
||||||
|
return this.mergePreferences(somePreferences, Clipperz.PM.DataModel.User.Header.Preferences.defaultPreferences);
|
||||||
|
},
|
||||||
|
|
||||||
|
'mergeUserPreferences': function(somePreferences) {
|
||||||
|
return this.mergePreferences(somePreferences, this._objectDataStore.values());
|
||||||
|
},
|
||||||
|
|
||||||
'getPreferences': function() {
|
'getPreferences': function() {
|
||||||
return Clipperz.Async.callbacks("User.Header.Preferences.getPreferences", [
|
return Clipperz.Async.callbacks("User.Header.Preferences.getPreferences", [
|
||||||
MochiKit.Base.method(this, 'values'),
|
MochiKit.Base.method(this, 'values'),
|
||||||
@ -68,6 +76,14 @@ Clipperz.Base.extend(Clipperz.PM.DataModel.User.Header.Preferences, Clipperz.PM.
|
|||||||
], {trace:false});
|
], {trace:false});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
'setPreferences': function(anObject) {
|
||||||
|
return Clipperz.Async.callbacks("User.Header.Preferences.setPreferences", [
|
||||||
|
MochiKit.Base.method(this, 'mergeUserPreferences', anObject),
|
||||||
|
MochiKit.Base.methodcaller('values'),
|
||||||
|
MochiKit.Base.method(this, 'setValues')
|
||||||
|
], {trace:false});
|
||||||
|
},
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
__syntaxFix__: "syntax fix"
|
__syntaxFix__: "syntax fix"
|
||||||
});
|
});
|
||||||
|
@ -929,10 +929,10 @@ console.log("Warning: User.recordWithLabel('" + aLabel + "') is returning more t
|
|||||||
], {trace:false});
|
], {trace:false});
|
||||||
},
|
},
|
||||||
|
|
||||||
'setPreference': function(aKey, aValue) {
|
setPreferences: function(anObject) {
|
||||||
return Clipperz.Async.callbacks("User.setPreference", [
|
return Clipperz.Async.callbacks("User.setPreferences", [
|
||||||
MochiKit.Base.method(this, 'getHeaderIndex', 'preferences'),
|
MochiKit.Base.method(this, 'getHeaderIndex', 'preferences'),
|
||||||
MochiKit.Base.methodcaller('setValue', aKey, aValue),
|
MochiKit.Base.methodcaller('setPreferences', anObject),
|
||||||
MochiKit.Base.method(this, 'saveChanges')
|
MochiKit.Base.method(this, 'saveChanges')
|
||||||
], {trace:false});
|
], {trace:false});
|
||||||
},
|
},
|
||||||
|
@ -38,124 +38,47 @@ Clipperz.PM.UI.Components.ExtraFeatures.DevicePINClass = React.createClass({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_editModeLocked: false,
|
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
||||||
enterEditMode: function() {
|
|
||||||
this.setState({
|
|
||||||
'isEditing': true,
|
|
||||||
'pinValue': ''
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
exitEditMode: function() {
|
|
||||||
this.setState({
|
|
||||||
'isEditing': false,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
lockEditMode: function() {
|
|
||||||
this._editModeLocked = true;
|
|
||||||
},
|
|
||||||
|
|
||||||
unlockEditMode: function() {
|
|
||||||
this._editModeLocked = false;
|
|
||||||
},
|
|
||||||
|
|
||||||
handleFocus: function(anEvent) {
|
|
||||||
anEvent.preventDefault();
|
|
||||||
|
|
||||||
this.refs['pinValue'].getDOMNode().focus();
|
|
||||||
},
|
|
||||||
|
|
||||||
handleBlur: function(anEvent) {
|
|
||||||
if (! this._editModeLocked) {
|
|
||||||
if (anEvent.target.value.length < this.props['PIN'].DEFAULT_PIN_LENGTH) {
|
|
||||||
this.exitEditMode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
handleKeyDown: function(anEvent) {
|
|
||||||
if (anEvent.keyCode == 27) {
|
|
||||||
this.refs['pinValue'].getDOMNode().blur();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
handleChange: function(anEvent) {
|
handleChange: function(anEvent) {
|
||||||
if (anEvent.target.value.length == this.props['PIN'].DEFAULT_PIN_LENGTH) {
|
if (anEvent.target.value.length <= this.props['PIN'].DEFAULT_PIN_LENGTH) {
|
||||||
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'updatePIN', anEvent.target.value);
|
|
||||||
this.refs['pinValue'].getDOMNode().blur();
|
|
||||||
this.exitEditMode();
|
|
||||||
} else {
|
|
||||||
this.setState({
|
this.setState({
|
||||||
'pinValue': anEvent.target.value
|
'pinValue': anEvent.target.value
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
handleCheckboxChange: function(anEvent) {
|
setFocus: function() {
|
||||||
if (this.props['PIN'].isSet() || this.state['isEditing']) {
|
this.refs['pinValue'].getDOMNode().focus();
|
||||||
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'disablePIN', anEvent.target.value);
|
|
||||||
this.exitEditMode();
|
|
||||||
} else {
|
|
||||||
this.enterEditMode();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
handleResetPIN: function() {
|
resetPIN: function() {
|
||||||
this.enterEditMode();
|
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'disablePIN');
|
||||||
|
MochiKit.Async.callLater(0.1, MochiKit.Base.method(this, 'setState', this.getInitialState()));
|
||||||
|
MochiKit.Async.callLater(0.1, MochiKit.Base.method(this, 'setFocus'));
|
||||||
|
},
|
||||||
|
|
||||||
|
savePIN: function() {
|
||||||
|
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'updatePIN', this.state.pinValue);
|
||||||
|
MochiKit.Async.callLater(0.1, MochiKit.Base.method(this, 'setState', this.getInitialState()));
|
||||||
},
|
},
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
||||||
// renderDigitInputs: function() {
|
renderButton: function() {
|
||||||
// var i;
|
var isButtonEnabled = (this.props['PIN'].isSet() || this.state['pinValue'].length == this.props['PIN'].DEFAULT_PIN_LENGTH);
|
||||||
// var result;
|
var buttonText = this.props['PIN'].isSet() ? "Reset" : "Save";
|
||||||
|
var buttonOnClick = (this.props['PIN'].isSet()) ? this.resetPIN : this.savePIN;
|
||||||
|
|
||||||
// result = [];
|
return React.DOM.a({
|
||||||
// for (i = 0; i<this.props['PIN'].DEFAULT_PIN_LENGTH; i++) {
|
'className': 'button' + ((isButtonEnabled) ? '' : ' disabled'),
|
||||||
// var boxIsFull = (this.state['isEditing']&&this.state['pinValue'][i])
|
'onClick': (isButtonEnabled) ? buttonOnClick : null,
|
||||||
// ||
|
}, buttonText);
|
||||||
// (!this.state['isEditing']&&this.props['PIN'].isSet())
|
|
||||||
|
|
||||||
// result.push(React.DOM.input({
|
|
||||||
// 'key': 'pin-digit-'+i,
|
|
||||||
// 'ref': 'pin-digit-'+i,
|
|
||||||
// 'name': 'pin-digit-'+i,
|
|
||||||
// 'className': 'pinDigit',
|
|
||||||
// 'readOnly': true,
|
|
||||||
// 'type': 'text',
|
|
||||||
// 'value': boxIsFull ? '*' : '',
|
|
||||||
// 'min': 0,
|
|
||||||
// 'max': 9,
|
|
||||||
// 'disabled': !this.state['isEditing'],
|
|
||||||
// 'onFocus': this.handleFocus,
|
|
||||||
// }));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return result;
|
|
||||||
// },
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
|
|
||||||
componentDidUpdate: function() {
|
|
||||||
if (this.state['isEditing']) {
|
|
||||||
this.refs['pinValue'].getDOMNode().focus();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function () {
|
render: function () {
|
||||||
var displayedPin;
|
var isInputEnabled = ! this.props['PIN'].isSet();
|
||||||
var isFormEnabled = (this.props['PIN'].isSet() || this.state.isEditing);
|
var displayedPin = (this.props['PIN'].isSet()) ? '*****' : this.state.pinValue;
|
||||||
var isResetButtonEnabled = (! this.state['isEditing'] && this.props['PIN'].isSet());
|
|
||||||
|
|
||||||
if (this.state.isEditing) {
|
|
||||||
displayedPin = this.state['pinValue'];
|
|
||||||
} else {
|
|
||||||
displayedPin = (this.props['PIN'].isSet()) ? '*****' : '';
|
|
||||||
}
|
|
||||||
|
|
||||||
return React.DOM.div({className:'extraFeature devicePIN'}, [
|
return React.DOM.div({className:'extraFeature devicePIN'}, [
|
||||||
React.DOM.div({'className':'header'}, [
|
React.DOM.div({'className':'header'}, [
|
||||||
@ -169,41 +92,19 @@ Clipperz.PM.UI.Components.ExtraFeatures.DevicePINClass = React.createClass({
|
|||||||
]),
|
]),
|
||||||
]),
|
]),
|
||||||
React.DOM.div({'className': 'content'}, [
|
React.DOM.div({'className': 'content'}, [
|
||||||
|
React.DOM.p({}, "PIN is "+((this.props['PIN'].isSet()) ? '' : 'not ')+"set on this device"),
|
||||||
React.DOM.form({},[
|
React.DOM.form({},[
|
||||||
React.DOM.p({}, [
|
|
||||||
React.DOM.input({
|
|
||||||
'type': 'checkbox',
|
|
||||||
'key': 'pinEnabled',
|
|
||||||
'checked': isFormEnabled,
|
|
||||||
'onChange': this.handleCheckboxChange,
|
|
||||||
'onMouseDown': this.lockEditMode,
|
|
||||||
'onMouseUp': this.unlockEditMode,
|
|
||||||
}),
|
|
||||||
React.DOM.label({
|
|
||||||
'key': 'pinEnabledLabel',
|
|
||||||
'htmlFor': 'pinEnabled',
|
|
||||||
'onClick': this.handleCheckboxChange,
|
|
||||||
'onMouseDown': this.lockEditMode,
|
|
||||||
'onMouseUp': this.unlockEditMode,
|
|
||||||
}, "Enable PIN on your device")
|
|
||||||
]),
|
|
||||||
// this.renderDigitInputs(),
|
|
||||||
React.DOM.input({
|
React.DOM.input({
|
||||||
'type': 'tel',
|
'type': 'tel',
|
||||||
'key': 'pinValue',
|
'key': 'pinValue',
|
||||||
'ref': 'pinValue',
|
'ref': 'pinValue',
|
||||||
'className': 'pinValue',
|
'className': 'pinValue',
|
||||||
'disabled': !this.state['isEditing'],
|
'disabled': ! isInputEnabled,
|
||||||
'onKeyDown': this.handleKeyDown,
|
|
||||||
'onChange': this.handleChange,
|
'onChange': this.handleChange,
|
||||||
'onBlur': this.handleBlur,
|
'onBlur': this.handleBlur,
|
||||||
'value': displayedPin,
|
'value': displayedPin,
|
||||||
// 'style': {'position': 'fixed', 'top': -1000}
|
|
||||||
}),
|
}),
|
||||||
React.DOM.a({
|
this.renderButton(),
|
||||||
'className': 'button'+(isResetButtonEnabled ? '' : ' disabled'),
|
|
||||||
'onClick': (isResetButtonEnabled) ? this.handleResetPIN : null
|
|
||||||
}, "Reset PIN"),
|
|
||||||
])
|
])
|
||||||
])
|
])
|
||||||
]);
|
]);
|
||||||
|
@ -26,70 +26,89 @@ Clipperz.Base.module('Clipperz.PM.UI.Components.ExtraFeatures');
|
|||||||
|
|
||||||
Clipperz.PM.UI.Components.ExtraFeatures.PreferencesClass = React.createClass({
|
Clipperz.PM.UI.Components.ExtraFeatures.PreferencesClass = React.createClass({
|
||||||
|
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
'editedPreferences': new Clipperz.KeyValueObjectStore()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
},
|
},
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
preference: function (aKeyPath) {
|
preference: function (aKeyPath) {
|
||||||
return this.props['preferences'].getValue(aKeyPath);
|
return (this.state['editedPreferences'].getValue(aKeyPath)!=null) ? this.state['editedPreferences'].getValue(aKeyPath) : this.props['preferences'].getValue(aKeyPath);
|
||||||
},
|
},
|
||||||
|
|
||||||
setPreference: function (aKeyPath) {
|
removeEditedPreference: function(aKeyPath) {
|
||||||
return function (anEvent) {
|
var newEditedPreferences;
|
||||||
var value;
|
var parentKeyPath;
|
||||||
var target;
|
|
||||||
|
|
||||||
target = anEvent.target;
|
parentKeyPath = aKeyPath.split('.');
|
||||||
if (target.type == 'checkbox') {
|
parentKeyPath.pop();
|
||||||
value = target.checked;
|
parentKeyPath = parentKeyPath.join('.');
|
||||||
target.defaultChecked = value;
|
|
||||||
// } else if (target.type == 'text') {
|
|
||||||
// value = target.value;
|
|
||||||
// target.defaultValue = value;
|
|
||||||
} else if (target.type == 'select-one') {
|
|
||||||
value = target.value;
|
|
||||||
target.defaultValue = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'setPreference', aKeyPath, value);
|
newEditedPreferences = this.state['editedPreferences'];
|
||||||
|
newEditedPreferences.removeValue(aKeyPath);
|
||||||
|
|
||||||
|
if (parentKeyPath.length > 0 && MochiKit.Base.keys(newEditedPreferences.getValue(parentKeyPath)).length == 0) {
|
||||||
|
this.removeEditedPreference(parentKeyPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
'editedPreferences': newEditedPreferences,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
checkboxClick: function (aRef) {
|
checkboxClick: function (aRef) {
|
||||||
return MochiKit.Base.bind(function (anEvent) {
|
return MochiKit.Base.bind(function (anEvent) {
|
||||||
//console.log("CHECKBOX CLICK", this, this.refs, this.refs[aRef]);
|
// console.log("CHECKBOX CLICK", this, this.refs, this.refs[aRef]);
|
||||||
this.refs[aRef].getDOMNode().click();
|
this.refs[aRef].getDOMNode().click();
|
||||||
}, this);
|
}, this);
|
||||||
},
|
},
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
handleKeyDown: function (aKeyPath) {
|
handleChange: function(aKeyPath, aValuePattern) {
|
||||||
return MochiKit.Base.bind(function (anEvent) {
|
return MochiKit.Base.method(this, 'handleEditEvent', aKeyPath, aValuePattern);
|
||||||
var value = anEvent.target.value;
|
},
|
||||||
|
|
||||||
// console.log("HANDLE KEY DOWN", anEvent, anEvent.keyCode, value);
|
handleEditEvent: function(aKeyPath, aValuePattern, anEvent) {
|
||||||
if (anEvent.target.defaultValue != value) {
|
var newEditedPreferences;
|
||||||
switch (anEvent.keyCode) {
|
|
||||||
case 9: // tab
|
var target = anEvent.target;
|
||||||
case 13: // enter - TODO: edit next preference
|
var value = (target.type == 'checkbox') ? target.checked : target.value;
|
||||||
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'setPreference', aKeyPath, value);
|
|
||||||
anEvent.target.defaultValue = anEvent.target.value;
|
if (!aValuePattern || aValuePattern.test(value)) {
|
||||||
break;
|
if (value == this.props['preferences'].getValue(aKeyPath)) {
|
||||||
case 27: // escape
|
this.removeEditedPreference(aKeyPath);
|
||||||
// console.log("ESCAPE");
|
} else {
|
||||||
anEvent.target.value = anEvent.target.defaultValue;
|
newEditedPreferences = this.state['editedPreferences'];
|
||||||
break;
|
newEditedPreferences.setValue(aKeyPath, value);
|
||||||
}
|
|
||||||
|
this.setState({
|
||||||
|
'editedPreferences': newEditedPreferences,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}, this);
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSave: function() {
|
||||||
|
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'setPreferences', this.state['editedPreferences'].values());
|
||||||
|
MochiKit.Async.callLater(0.1, MochiKit.Base.method(this, 'setState', this.getInitialState()));
|
||||||
},
|
},
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
|
isSaveButtonEnabled: function() {
|
||||||
|
return MochiKit.Base.keys(this.state['editedPreferences'].values()).length != 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
render: function () {
|
render: function () {
|
||||||
var result;
|
var result;
|
||||||
if (! this.props['preferences']) {
|
if (! this.props['preferences']) {
|
||||||
@ -108,7 +127,7 @@ Clipperz.PM.UI.Components.ExtraFeatures.PreferencesClass = React.createClass({
|
|||||||
React.DOM.h3({'key':'1'}, "Lock"),
|
React.DOM.h3({'key':'1'}, "Lock"),
|
||||||
React.DOM.div({'key':'2', 'className':'row two lockEnabled'}, [
|
React.DOM.div({'key':'2', 'className':'row two lockEnabled'}, [
|
||||||
React.DOM.div({'className':'col one'}, [
|
React.DOM.div({'className':'col one'}, [
|
||||||
React.DOM.input({'type':'checkbox', 'defaultChecked':this.preference('lock.enabled'), 'onChange':this.setPreference('lock.enabled'), 'ref':'lock-enabled'}),
|
React.DOM.input({'type':'checkbox', 'checked':this.preference('lock.enabled'), 'onClick':this.handleChange('lock.enabled'), 'ref':'lock-enabled'}),
|
||||||
]),
|
]),
|
||||||
React.DOM.div({'className':'col two'}, [
|
React.DOM.div({'className':'col two'}, [
|
||||||
React.DOM.span({'className':'clickable', 'onClick':this.checkboxClick('lock-enabled')}, "Enable auto-lock"),
|
React.DOM.span({'className':'clickable', 'onClick':this.checkboxClick('lock-enabled')}, "Enable auto-lock"),
|
||||||
@ -117,7 +136,7 @@ Clipperz.PM.UI.Components.ExtraFeatures.PreferencesClass = React.createClass({
|
|||||||
React.DOM.div({'key':'3', 'className':'row one lockTimeout'}, [
|
React.DOM.div({'key':'3', 'className':'row one lockTimeout'}, [
|
||||||
React.DOM.p({'className':(this.preference('lock.enabled') ? 'enabled' : 'disabled')}, [
|
React.DOM.p({'className':(this.preference('lock.enabled') ? 'enabled' : 'disabled')}, [
|
||||||
React.DOM.span({}, "Lock timeout"),
|
React.DOM.span({}, "Lock timeout"),
|
||||||
React.DOM.input({'type':'text', 'defaultValue':this.preference('lock.timeoutInMinutes'), 'onKeyDown':this.handleKeyDown('lock.timeoutInMinutes')}),
|
React.DOM.input({'type':'text', 'value':this.preference('lock.timeoutInMinutes'), 'onChange':this.handleChange('lock.timeoutInMinutes', /^[1-9][0-9]*$/)}),
|
||||||
React.DOM.span({'className':'timeUnit'}, "minutes"),
|
React.DOM.span({'className':'timeUnit'}, "minutes"),
|
||||||
])
|
])
|
||||||
]),
|
]),
|
||||||
@ -128,22 +147,22 @@ Clipperz.PM.UI.Components.ExtraFeatures.PreferencesClass = React.createClass({
|
|||||||
React.DOM.div({'key':'2', 'className':'row one passwordLength'}, [
|
React.DOM.div({'key':'2', 'className':'row one passwordLength'}, [
|
||||||
React.DOM.p({}, [
|
React.DOM.p({}, [
|
||||||
React.DOM.span({}, "Password length"),
|
React.DOM.span({}, "Password length"),
|
||||||
React.DOM.input({'type':'text', 'defaultValue':this.preference('passwordGenerator.length'), 'onKeyDown':this.handleKeyDown('passwordGenerator.length')}),
|
React.DOM.input({'type':'text', 'value':this.preference('passwordGenerator.length'), 'onChange':this.handleChange('passwordGenerator.length', /^[1-9][0-9]*$/)}),
|
||||||
React.DOM.span({'className':'sizeUnit'}, "characters"),
|
React.DOM.span({'className':'sizeUnit'}, "characters"),
|
||||||
])
|
])
|
||||||
]),
|
]),
|
||||||
React.DOM.div({'key':'3', 'className':'row one passwordCharSets'}, [
|
React.DOM.div({'key':'3', 'className':'row one passwordCharSets'}, [
|
||||||
React.DOM.p({'key':'label'}, "Characters"),
|
React.DOM.p({'key':'label'}, "Characters"),
|
||||||
React.DOM.ul({'key':'list'}, [
|
React.DOM.ul({'key':'list'}, [
|
||||||
React.DOM.li({'key':'A-Z'}, [ React.DOM.span({'className':'clickable', 'onClick':this.checkboxClick('A-Z')}, "A-Z"), React.DOM.input({'type':'checkbox', 'defaultChecked':this.preference('passwordGenerator.characters.A-Z'), 'onChange':this.setPreference('passwordGenerator.characters.A-Z'), 'ref':'A-Z'}) ]),
|
React.DOM.li({'key':'A-Z'}, [ React.DOM.span({'className':'clickable', 'onClick':this.checkboxClick('A-Z')}, "A-Z"), React.DOM.input({'type':'checkbox', 'checked':this.preference('passwordGenerator.characters.A-Z'), 'onChange':this.handleChange('passwordGenerator.characters.A-Z'), 'ref':'A-Z'}) ]),
|
||||||
React.DOM.li({'key':'a-z'}, [ React.DOM.span({'className':'clickable', 'onClick':this.checkboxClick('a-z')}, "a-z"), React.DOM.input({'type':'checkbox', 'defaultChecked':this.preference('passwordGenerator.characters.a-z'), 'onChange':this.setPreference('passwordGenerator.characters.a-z'), 'ref':'a-z'}) ]),
|
React.DOM.li({'key':'a-z'}, [ React.DOM.span({'className':'clickable', 'onClick':this.checkboxClick('a-z')}, "a-z"), React.DOM.input({'type':'checkbox', 'checked':this.preference('passwordGenerator.characters.a-z'), 'onChange':this.handleChange('passwordGenerator.characters.a-z'), 'ref':'a-z'}) ]),
|
||||||
React.DOM.li({'key':'0-9'}, [ React.DOM.span({'className':'clickable', 'onClick':this.checkboxClick('0-9')}, "0-9"), React.DOM.input({'type':'checkbox', 'defaultChecked':this.preference('passwordGenerator.characters.0-9'), 'onChange':this.setPreference('passwordGenerator.characters.0-9'), 'ref':'0-9'}) ]),
|
React.DOM.li({'key':'0-9'}, [ React.DOM.span({'className':'clickable', 'onClick':this.checkboxClick('0-9')}, "0-9"), React.DOM.input({'type':'checkbox', 'checked':this.preference('passwordGenerator.characters.0-9'), 'onChange':this.handleChange('passwordGenerator.characters.0-9'), 'ref':'0-9'}) ]),
|
||||||
React.DOM.li({'key':'space'}, [ React.DOM.span({'className':'clickable', 'onClick':this.checkboxClick('space')}, "space"), React.DOM.input({'type':'checkbox', 'defaultChecked':this.preference('passwordGenerator.characters.space'), 'onChange':this.setPreference('passwordGenerator.characters.space'), 'ref':'space'}) ]),
|
React.DOM.li({'key':'space'}, [ React.DOM.span({'className':'clickable', 'onClick':this.checkboxClick('space')}, "space"), React.DOM.input({'type':'checkbox', 'checked':this.preference('passwordGenerator.characters.space'), 'onChange':this.handleChange('passwordGenerator.characters.space'), 'ref':'space'}) ]),
|
||||||
React.DOM.li({'key':'!#?'}, [ React.DOM.span({'className':'clickable', 'onClick':this.checkboxClick('!#?')}, "!#?"), React.DOM.input({'type':'checkbox', 'defaultChecked':this.preference('passwordGenerator.characters.!#?'), 'onChange':this.setPreference('passwordGenerator.characters.!#?'), 'ref':'!#?'}) ]),
|
React.DOM.li({'key':'!#?'}, [ React.DOM.span({'className':'clickable', 'onClick':this.checkboxClick('!#?')}, "!#?"), React.DOM.input({'type':'checkbox', 'checked':this.preference('passwordGenerator.characters.!#?'), 'onChange':this.handleChange('passwordGenerator.characters.!#?'), 'ref':'!#?'}) ]),
|
||||||
]),
|
]),
|
||||||
// React.DOM.p({}, [
|
// React.DOM.p({}, [
|
||||||
// React.DOM.span({}, "Charset"),
|
// React.DOM.span({}, "Charset"),
|
||||||
// React.DOM.input({'type':'text', 'defaultValue':this.preference('passwordGenerator.charset'), 'onKeyDown':this.handleKeyDown('passwordGenerator.charset')}),
|
// React.DOM.input({'type':'text', 'value':this.preference('passwordGenerator.charset'), 'onKeyDown':this.handleKeyDown('passwordGenerator.charset')}),
|
||||||
// ]),
|
// ]),
|
||||||
]),
|
]),
|
||||||
]),
|
]),
|
||||||
@ -151,7 +170,7 @@ Clipperz.PM.UI.Components.ExtraFeatures.PreferencesClass = React.createClass({
|
|||||||
React.DOM.li({'key': 'language'}, [
|
React.DOM.li({'key': 'language'}, [
|
||||||
React.DOM.h3({'key':'1'}, "Language"),
|
React.DOM.h3({'key':'1'}, "Language"),
|
||||||
React.DOM.div({'key':'2', 'className':'row one language'}, [
|
React.DOM.div({'key':'2', 'className':'row one language'}, [
|
||||||
React.DOM.select({'defaultValue':this.preference('preferredLanguage'), 'onChange':this.setPreference('preferredLanguage')}, [
|
React.DOM.select({'value':this.preference('preferredLanguage'), 'onChange':this.handleChange('preferredLanguage')}, [
|
||||||
React.DOM.option({'value':'en'}, "English"),
|
React.DOM.option({'value':'en'}, "English"),
|
||||||
React.DOM.option({'value':'fr'}, "Français"),
|
React.DOM.option({'value':'fr'}, "Français"),
|
||||||
React.DOM.option({'value':'it'}, "Italiano"),
|
React.DOM.option({'value':'it'}, "Italiano"),
|
||||||
@ -163,7 +182,7 @@ Clipperz.PM.UI.Components.ExtraFeatures.PreferencesClass = React.createClass({
|
|||||||
React.DOM.h3({'key':'1'}, "Donation reminder"),
|
React.DOM.h3({'key':'1'}, "Donation reminder"),
|
||||||
React.DOM.div({'key':'2', 'className':'row two donationReminder'}, [
|
React.DOM.div({'key':'2', 'className':'row two donationReminder'}, [
|
||||||
React.DOM.div({'className':'col one'}, [
|
React.DOM.div({'className':'col one'}, [
|
||||||
React.DOM.input({'type':'checkbox', 'defaultChecked':this.preference('shouldShowDonationPanel'), 'onChange':this.setPreference('shouldShowDonationPanel'), 'ref':'shouldShowDonationPanel'}),
|
React.DOM.input({'type':'checkbox', 'checked':this.preference('shouldShowDonationPanel'), 'onChange':this.handleChange('shouldShowDonationPanel'), 'ref':'shouldShowDonationPanel'}),
|
||||||
]),
|
]),
|
||||||
React.DOM.div({'className':'col two'}, [
|
React.DOM.div({'className':'col two'}, [
|
||||||
React.DOM.span({'className':'clickable', 'onClick':this.checkboxClick('shouldShowDonationPanel')}, "Show donation reminder"),
|
React.DOM.span({'className':'clickable', 'onClick':this.checkboxClick('shouldShowDonationPanel')}, "Show donation reminder"),
|
||||||
@ -172,6 +191,10 @@ Clipperz.PM.UI.Components.ExtraFeatures.PreferencesClass = React.createClass({
|
|||||||
]),
|
]),
|
||||||
*/
|
*/
|
||||||
]),
|
]),
|
||||||
|
React.DOM.a({
|
||||||
|
'className': 'button'+((this.isSaveButtonEnabled()) ? '' : ' disabled'),
|
||||||
|
'onClick': (this.isSaveButtonEnabled()) ? this.handleSave : null,
|
||||||
|
}, "Save Preferences"),
|
||||||
])
|
])
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ Clipperz.PM.UI.MainController = function() {
|
|||||||
'enableLock', 'disableLock', 'unlock',
|
'enableLock', 'disableLock', 'unlock',
|
||||||
'updatePIN', 'disablePIN', 'forcePassphraseLogin', 'forcePassphraseUnlock',
|
'updatePIN', 'disablePIN', 'forcePassphraseLogin', 'forcePassphraseUnlock',
|
||||||
'changePassphrase', 'deleteAccount',
|
'changePassphrase', 'deleteAccount',
|
||||||
/*'updateUserPreferences',*/ 'setPreference',
|
/*'updateUserPreferences',*/ 'setPreferences',
|
||||||
'updateOTPListAndDetails', 'createNewOTP', 'deleteOTPs', 'changeOTPLabel',
|
'updateOTPListAndDetails', 'createNewOTP', 'deleteOTPs', 'changeOTPLabel',
|
||||||
'importCards',
|
'importCards',
|
||||||
'downloadExport',
|
'downloadExport',
|
||||||
@ -1566,10 +1566,10 @@ Clipperz.log("THE BROWSER IS OFFLINE");
|
|||||||
], {trace:false});
|
], {trace:false});
|
||||||
},
|
},
|
||||||
|
|
||||||
setPreference_handler: function(aKeyPath, aValue) {
|
setPreferences_handler: function(anObject) {
|
||||||
return Clipperz.Async.callbacks("MainController.setPreference_handler", [
|
return Clipperz.Async.callbacks("MainController.setPreferences_handler", [
|
||||||
MochiKit.Base.method(this.overlay(), 'show', "", true),
|
MochiKit.Base.method(this.overlay(), 'show', "", true),
|
||||||
MochiKit.Base.method(this.user(), 'setPreference', aKeyPath, aValue),
|
MochiKit.Base.method(this.user(), 'setPreferences', anObject),
|
||||||
MochiKit.Base.method(this, 'updateUserPreferences'),
|
MochiKit.Base.method(this, 'updateUserPreferences'),
|
||||||
MochiKit.Base.method(this, 'refreshCurrentPage'),
|
MochiKit.Base.method(this, 'refreshCurrentPage'),
|
||||||
MochiKit.Base.method(this.overlay(), 'done', "", 0.5),
|
MochiKit.Base.method(this.overlay(), 'done', "", 0.5),
|
||||||
|
@ -711,17 +711,11 @@ refer to http://www.clipperz.com.
|
|||||||
}
|
}
|
||||||
|
|
||||||
.devicePIN {
|
.devicePIN {
|
||||||
.pinDigit {
|
|
||||||
display: inline-block;
|
|
||||||
width: 2em;
|
|
||||||
margin-right: 0.5em;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pinValue {
|
.pinValue {
|
||||||
display: inline-block;
|
display: block;
|
||||||
width: 4em;
|
width: 4em;
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
|
margin-top:8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:enabled {
|
:enabled {
|
||||||
|
Loading…
Reference in New Issue
Block a user