summaryrefslogtreecommitdiff
path: root/frontend/delta/js/Clipperz/PM/UI
Side-by-side diff
Diffstat (limited to 'frontend/delta/js/Clipperz/PM/UI') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/delta/js/Clipperz/PM/UI/Components/CardDetail.js85
-rw-r--r--frontend/delta/js/Clipperz/PM/UI/Components/CardList.js13
-rw-r--r--frontend/delta/js/Clipperz/PM/UI/Components/Checkbox.js44
-rw-r--r--frontend/delta/js/Clipperz/PM/UI/Components/LoginForm.js6
-rw-r--r--frontend/delta/js/Clipperz/PM/UI/Components/Overlay.js7
-rw-r--r--frontend/delta/js/Clipperz/PM/UI/Components/PreferencePage.js88
-rw-r--r--frontend/delta/js/Clipperz/PM/UI/MainController.js130
7 files changed, 329 insertions, 44 deletions
diff --git a/frontend/delta/js/Clipperz/PM/UI/Components/CardDetail.js b/frontend/delta/js/Clipperz/PM/UI/Components/CardDetail.js
index df514a2..12ddce3 100644
--- a/frontend/delta/js/Clipperz/PM/UI/Components/CardDetail.js
+++ b/frontend/delta/js/Clipperz/PM/UI/Components/CardDetail.js
@@ -37,6 +37,7 @@ Clipperz.PM.UI.Components.CardDetail = React.createClass({
return {
// showSearch: false,
// searchTimer: null,
+ unmaskedFields: new Clipperz.Set(),
starred: false
};
},
@@ -45,6 +46,32 @@ Clipperz.PM.UI.Components.CardDetail = React.createClass({
MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'runDirectLogin', {record:this.props.card['reference'], directLogin:aDirectLoginReference});
},
+ toggleFieldVisibility: function (aField, anEvent) {
+ var unmaskedFields;
+ var fieldReference;
+
+ unmaskedFields = this.state['unmaskedFields'];
+ fieldReference = aField['reference']
+ if (unmaskedFields.contains(fieldReference)) {
+ unmaskedFields.remove(fieldReference)
+ } else {
+ unmaskedFields.add(fieldReference)
+ }
+
+ this.setState({'unmaskedFields': unmaskedFields});
+ },
+
+ handleGoAction: function (aField, anEvent) {
+ var newWindow;
+
+ newWindow = MochiKit.DOM.currentWindow().open(aField['value'], '_blank');
+ newWindow.focus();
+ },
+
+ handleEmailAction: function (aField, anEvent) {
+ MochiKit.DOM.currentWindow().location = 'mailto:' + aField['value'];
+ },
+
//=========================================================================
normalizeFieldValue: function (aValue) {
@@ -61,30 +88,56 @@ Clipperz.PM.UI.Components.CardDetail = React.createClass({
return result;
},
- renderField: function (aField) {
-//console.log("FIELD", aField);
- var actionLabel;
+ renderFieldActionButton: function (aField) {
+// var actionLabel;
+ var result;
if (aField['actionType'] == 'URL') {
- actionLabel = "go";
+ result = React.DOM.div({className:'actionWrapper', onClick:MochiKit.Base.method(this, 'handleGoAction', aField)}, [
+ React.DOM.a({className:aField['actionType']}, "go")
+ ]);
} else if (aField['actionType'] == 'PASSWORD') {
- actionLabel = "locked";
+ var icon;
+
+ if (this.state['unmaskedFields'].contains(aField['reference'])) {
+ icon = "unlocked";
+ } else {
+ icon = "locked";
+ }
+ result = React.DOM.div({className:'actionWrapper', onClick:MochiKit.Base.method(this, 'toggleFieldVisibility', aField)}, [
+ React.DOM.a({className:aField['actionType']}, icon)
+ ]);
} else if (aField['actionType'] == 'EMAIL') {
- actionLabel = "email";
+ result = React.DOM.div({className:'actionWrapper', onClick:MochiKit.Base.method(this, 'handleEmailAction', aField)}, [
+ React.DOM.a({className:aField['actionType']}, "email")
+ ]);
} else {
- actionLabel = "";
+ result = null;
+ }
+
+ return result;
+ },
+
+ renderField: function (aField) {
+//console.log("FIELD", aField);
+ var fieldExtraClass;
+
+ fieldExtraClass = aField['actionType'];
+ if (this.state['unmaskedFields'].contains(aField['reference'])) {
+ fieldExtraClass = fieldExtraClass + ' unlocked';
}
- return React.DOM.div({className:'listItem ' + aField['actionType']}, [
+ return React.DOM.div({className:'listItem ' + fieldExtraClass, key:aField['reference']}, [
React.DOM.div({className:'fieldWrapper'}, [
React.DOM.div({className:'fieldInnerWrapper'}, [
React.DOM.div({className:'labelWrapper'}, React.DOM.span({className:'label'}, aField['label'])),
- React.DOM.div({className:'valueWrapper'}, React.DOM.span({className:'value ' + aField['actionType']}, this.normalizeFieldValue(aField['value'])))
+ React.DOM.div({className:'valueWrapper'}, React.DOM.span({className:'value ' + fieldExtraClass}, this.normalizeFieldValue(aField['value'])))
])
]),
- React.DOM.div({className:'actionWrapper'}, [
- React.DOM.div({className:aField['actionType']}, actionLabel)
- ])
+ this.renderFieldActionButton(aField)
+// React.DOM.div({className:'actionWrapper'}, [
+// React.DOM.div({className:aField['actionType']}, actionLabel)
+// ])
]);
},
@@ -98,7 +151,8 @@ Clipperz.PM.UI.Components.CardDetail = React.createClass({
},
handleBackClick: function (anEvent) {
- window.history.back();
+// window.history.back();
+ MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'goBack');
},
handleStarClick: function (anEvent) {
@@ -109,7 +163,7 @@ Clipperz.PM.UI.Components.CardDetail = React.createClass({
render: function () {
var card = this.props.card;
- var starredStatus = (this.state['starred'] ? "starred" : "unstarred");
+// var starredStatus = (this.state['starred'] ? "starred" : "unstarred");
if ((typeof(card['fields']) != 'undefined') && (card['notes'] != '')) {
card['fields'].push({ 'actionType': 'NOTES', 'isHidden': false, 'label': "notes", 'reference': "notes", 'value': card['notes'] })
@@ -118,9 +172,8 @@ Clipperz.PM.UI.Components.CardDetail = React.createClass({
return React.DOM.div({className:'cardDetail'}, [
React.DOM.div({className:'header'}, [
React.DOM.div({className:'titleWrapper'}, React.DOM.div({className:'title'}, card.title)),
-// React.DOM.div({className:'titleWrapper'}, React.DOM.div({className:'title'}, card.title + ' ' + card.title + ' ' + card.title + ' ' + card.title)),
React.DOM.div({className:'backWrapper'}, React.DOM.a({className:'button back', onClick:this.handleBackClick}, "back")),
- React.DOM.div({className:'starWrapper'}, React.DOM.a({className:'star', onClick:this.handleStarClick}, starredStatus))
+// React.DOM.div({className:'starWrapper'}, React.DOM.a({className:'star', onClick:this.handleStarClick}, starredStatus))
]),
React.DOM.div({className:'content'}, [
card.fields ? React.DOM.div({className:'fields'}, MochiKit.Base.map(this.renderField, card.fields)) : null,
diff --git a/frontend/delta/js/Clipperz/PM/UI/Components/CardList.js b/frontend/delta/js/Clipperz/PM/UI/Components/CardList.js
index 66d20f1..5a44a4a 100644
--- a/frontend/delta/js/Clipperz/PM/UI/Components/CardList.js
+++ b/frontend/delta/js/Clipperz/PM/UI/Components/CardList.js
@@ -97,11 +97,18 @@ console.log("focusOnSearchField", this.refs['searchField']);
//=========================================================================
+ showPreferences: function (anEvent) {
+ MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'showPreferences', anEvent);
+ },
+
+ //=========================================================================
+
cardItem: function (aRecordReference) {
var reference = aRecordReference['_reference'];
var selectedCard = (reference == this.props.selectedCard);
- return React.DOM.div({className:'listItem', onClick:MochiKit.Base.method(this, 'handleClickOnCardDetail', reference)}, [
+ // TODO: verify if it is possible to put the onClick handler on the container 'div', instead of adding it to each 'div' item.
+ return React.DOM.div({className:'listItem', key:reference, onClick:MochiKit.Base.method(this, 'handleClickOnCardDetail', reference)}, [
React.DOM.div({className:'labelWrapper'}, React.DOM.span({className:'label'}, aRecordReference.label)),
// React.DOM.div({className:'labelWrapper'}, React.DOM.span({className:'label'}, aRecordReference.label + ' ' + aRecordReference.label + ' ' + aRecordReference.label + ' ' + aRecordReference.label + ' ' + aRecordReference.label)),
React.DOM.div({className:'faviconWrapper'}, aRecordReference.favicon ? React.DOM.img({className:'favicon', src:aRecordReference.favicon}) : React.DOM.div({className:'favicon'}, '\u00A0')),
@@ -146,9 +153,9 @@ console.log("focusOnSearchField", this.refs['searchField']);
React.DOM.div({className:'header'}, [
React.DOM.a({className:'account'}, 'clipperz'),
React.DOM.div({className:'features'}, [
- React.DOM.a({className:'addCard'}, 'add'),
+// React.DOM.a({className:'addCard'}, 'add'),
React.DOM.a({className:'search ' + (this.state.showSearch ? 'selected' : ''), onClick:this.toggleSearch}, 'search'),
- React.DOM.a({className:'settings'}, 'settings')
+ React.DOM.a({className:'settings', onClick:this.showPreferences}, 'settings')
]),
// this.searchBox()
]),
diff --git a/frontend/delta/js/Clipperz/PM/UI/Components/Checkbox.js b/frontend/delta/js/Clipperz/PM/UI/Components/Checkbox.js
new file mode 100644
index 0000000..9538063
--- a/dev/null
+++ b/frontend/delta/js/Clipperz/PM/UI/Components/Checkbox.js
@@ -0,0 +1,44 @@
+/*
+
+Copyright 2008-2013 Clipperz Srl
+
+This file is part of Clipperz, the online password manager.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com.
+
+* Clipperz is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+* Clipperz is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Clipperz. If not, see http://www.gnu.org/licenses/.
+
+*/
+
+Clipperz.PM.UI.Components.Checkbox = React.createClass({
+// http://development.tobypitman.com/iphoneCheckboxes/iphoneCheckboxes2.html
+
+ propTypes: {
+ 'checked': React.PropTypes.bool.isRequired,
+ 'id': React.PropTypes.string.isRequired,
+ 'eventHandler': React.PropTypes.func.isRequired
+ },
+
+ //=========================================================================
+
+ render: function () {
+ return React.DOM.div({className:'checkbox', onClick:this.props['eventHandler']}, [
+ React.DOM.input({name:this.props['id'], id:this.props['id'], value:this.props['id'], type:'checkbox', checked:this.props['checked']}),
+ React.DOM.label({className:'check', 'for':this.props['id']}),
+ React.DOM.label({className:'info', 'for':this.props['id']}, "enable local storage")
+ ]);
+ }
+
+ //=========================================================================
+});
diff --git a/frontend/delta/js/Clipperz/PM/UI/Components/LoginForm.js b/frontend/delta/js/Clipperz/PM/UI/Components/LoginForm.js
index 2b5b4a4..801549f 100644
--- a/frontend/delta/js/Clipperz/PM/UI/Components/LoginForm.js
+++ b/frontend/delta/js/Clipperz/PM/UI/Components/LoginForm.js
@@ -92,14 +92,14 @@ Clipperz.PM.UI.Components.LoginForm = React.createClass({
loginForm: function () {
registrationLink = React.DOM.div({'className':'registrationLink'}, [
- React.DOM.a({'onClick':this.handleRegistrationLinkClick}, "Need an account")
+ React.DOM.a({'onClick':this.handleRegistrationLinkClick}, "Sign up")
]);
return React.DOM.div({'className':'loginForm credentials'},[
React.DOM.form({onChange: this.handleChange, onSubmit:this.handleCredentialSubmit}, [
React.DOM.div(null,[
- React.DOM.label({'for':'name'}, "username"),
+ React.DOM.label({'for' :'name'}, "username"),
React.DOM.input({'type':'text', 'name':'name', 'ref':'username', 'placeholder':"username", 'key':'username', 'autoCapitalize':'none'}),
- React.DOM.label({'for':'passphrase'}, "passphrase"),
+ React.DOM.label({'for' :'passphrase'}, "passphrase"),
React.DOM.input({'type':'password', 'name':'passphrase', 'ref':'passphrase', 'placeholder':"passphrase", 'key':'passphrase'})
]),
React.DOM.button({'type':'submit', 'disabled':!this.shouldEnableLoginButton(), 'className':'button'}, "login")
diff --git a/frontend/delta/js/Clipperz/PM/UI/Components/Overlay.js b/frontend/delta/js/Clipperz/PM/UI/Components/Overlay.js
index cc4a06c..cb5f81a 100644
--- a/frontend/delta/js/Clipperz/PM/UI/Components/Overlay.js
+++ b/frontend/delta/js/Clipperz/PM/UI/Components/Overlay.js
@@ -94,9 +94,10 @@ Clipperz.Base.extend(Clipperz.PM.UI.Components.Overlay, Object, {
},
'hide': function () {
- MochiKit.DOM.removeElementClass(this.element(), 'ios-overlay-show');
- MochiKit.DOM.addElementClass(this.element(), 'ios-overlay-hide');
- MochiKit.Async.callLater(1, MochiKit.Style.hideElement, this.element());
+ var element = this.element();
+ MochiKit.DOM.removeElementClass(element, 'ios-overlay-show');
+ MochiKit.DOM.addElementClass(element, 'ios-overlay-hide');
+ MochiKit.Async.callLater(1, MochiKit.Style.hideElement, element);
},
'hideSpinner': function () {
diff --git a/frontend/delta/js/Clipperz/PM/UI/Components/PreferencePage.js b/frontend/delta/js/Clipperz/PM/UI/Components/PreferencePage.js
new file mode 100644
index 0000000..822acc2
--- a/dev/null
+++ b/frontend/delta/js/Clipperz/PM/UI/Components/PreferencePage.js
@@ -0,0 +1,88 @@
+/*
+
+Copyright 2008-2013 Clipperz Srl
+
+This file is part of Clipperz, the online password manager.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com.
+
+* Clipperz is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+* Clipperz is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Clipperz. If not, see http://www.gnu.org/licenses/.
+
+*/
+
+Clipperz.PM.UI.Components.PreferencePage = React.createClass({
+
+ getDefaultProps: function () {
+ return {
+ }
+ },
+
+ propTypes: {
+// card: React.PropTypes.object.isRequired
+// checked: React.PropTypes.boolean.isRequired
+ },
+
+ getInitialState: function () {
+// return {
+// shouldStoreDataLocally: false
+// };
+ },
+
+ handleBackClick: function (anEvent) {
+ MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'goBack');
+ },
+
+ toggleShouldStoreDataLocally: function (anEvent) {
+// this.setState({shouldStoreDataLocally: !this.state['shouldStoreDataLocally']});
+ Clipperz.PM.DataModel.devicePreferences.setShouldStoreDataLocally(!Clipperz.PM.DataModel.devicePreferences.shouldStoreDataLocally());
+ this.setState({});
+ },
+
+ shouldStoreDataLocally: function () {
+ return Clipperz.PM.DataModel.devicePreferences.shouldStoreDataLocally();
+ },
+
+ syncNow: function (anEvent) {
+ MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'synchronizeLocalData');
+ },
+
+ //=========================================================================
+
+ render: function () {
+ return React.DOM.div({className:'preferences'}, [
+ React.DOM.div({className:'header'}, [
+ React.DOM.div({className:'titleWrapper'}, React.DOM.div({className:'title'}, "Preferences")),
+ React.DOM.div({className:'backWrapper'}, React.DOM.a({className:'button back', onClick:this.handleBackClick}, "back")),
+ ]),
+ React.DOM.div({className:'content'}, [
+ React.DOM.form(null, [
+ React.DOM.div({className:'section'}, [
+ React.DOM.h4(null, "Local storage"),
+ React.DOM.p(null, "Store you account data locally for offline viewing"),
+ new Clipperz.PM.UI.Components.Checkbox({'id':'shouldStoreLocally_checkbox', 'checked':this.shouldStoreDataLocally(), 'eventHandler':this.toggleShouldStoreDataLocally}),
+ this.shouldStoreDataLocally() ? React.DOM.div({className:'syncInfo'}, [
+// React.DOM.h5(null, "data were never synchronized before"),
+ React.DOM.a({className:'button', onClick:this.syncNow}, "Sync now")
+ ]) : null
+ ])
+ ])
+ ]),
+ React.DOM.div({className:'footer'}, [
+
+ ])
+ ]);
+ }
+
+ //=========================================================================
+});
diff --git a/frontend/delta/js/Clipperz/PM/UI/MainController.js b/frontend/delta/js/Clipperz/PM/UI/MainController.js
index da7540e..20ff041 100644
--- a/frontend/delta/js/Clipperz/PM/UI/MainController.js
+++ b/frontend/delta/js/Clipperz/PM/UI/MainController.js
@@ -26,7 +26,7 @@ Clipperz.Base.module('Clipperz.PM.UI');
Clipperz.PM.UI.MainController = function() {
var pages;
- this._proxy = null;
+// this._proxy = null;
this._user = null;
this._filter = '';
@@ -39,12 +39,14 @@ Clipperz.PM.UI.MainController = function() {
'registrationPage': new Clipperz.PM.UI.Components.RegistrationWizard(),
'cardListPage': new Clipperz.PM.UI.Components.CardList(),
'cardDetailPage': new Clipperz.PM.UI.Components.CardDetail({card: {}}),
+ 'preferencePage': new Clipperz.PM.UI.Components.PreferencePage(),
'errorPage': new Clipperz.PM.UI.Components.ErrorPage({message:''})
};
MochiKit.Base.map(function (anId) {React.renderComponent(pages[anId], MochiKit.DOM.getElement(anId))}, MochiKit.Base.keys(pages));
this._pages = pages;
this.registerForNotificationCenterEvents();
+ MochiKit.Signal.connect(MochiKit.DOM.currentDocument(), 'onselectionchange', this, 'selectionChangeHandler');
return this;
}
@@ -73,10 +75,12 @@ MochiKit.Base.update(Clipperz.PM.UI.MainController.prototype, {
isOnline: function() {
return navigator.onLine;
+// return false;
},
hasLocalData: function() {
- return false;
+// return false;
+ return (Clipperz.PM.DataModel.devicePreferences.accountData() != null);
},
loginMode: function () {
@@ -98,26 +102,41 @@ MochiKit.Base.update(Clipperz.PM.UI.MainController.prototype, {
//=========================================================================
+ showOfflineError: function () {
+console.log("THE BROWSER IS OFFLINE");
+ },
+
selectInitialProxy: function () {
if (this.isOnline()) {
- this._proxy = Clipperz.PM.Proxy.defaultProxy;
+// this._proxy = Clipperz.PM.Proxy.defaultProxy;
} else {
if (this.hasLocalData()) {
- this._proxy = new Clipperz.PM.Proxy.Offline({dataStore: new Clipperz.PM.Proxy.Offline.LocalStorageDataStore(), shouldPayTolls:false});
+// this._proxy = new Clipperz.PM.Proxy.Offline({dataStore: new Clipperz.PM.Proxy.Offline.LocalStorageDataStore(), shouldPayTolls:false});
+ Clipperz.PM.Proxy.defaultProxy = new Clipperz.PM.Proxy.Offline({dataStore: new Clipperz.PM.Proxy.Offline.LocalStorageDataStore(), shouldPayTolls:false});
} else {
this.showOfflineError();
}
}
},
- proxy: function () {
- return this._proxy;
- },
+// proxy: function () {
+// return this._proxy;
+// },
//=========================================================================
registerForNotificationCenterEvents: function () {
- var events = ['doLogin', 'registerNewUser', 'showRegistrationForm', 'goBack', 'showRecord', 'searchCards', 'runDirectLogin'];
+ var events = [
+ 'doLogin',
+ 'registerNewUser',
+ 'showRegistrationForm',
+ 'goBack',
+ 'showRecord',
+ 'searchCards',
+ 'showPreferences',
+ 'runDirectLogin',
+ 'synchronizeLocalData'
+ ];
var self = this;
MochiKit.Base.map(function (anEvent) {
@@ -130,12 +149,53 @@ MochiKit.Base.update(Clipperz.PM.UI.MainController.prototype, {
//-------------------------------------------------------------------------
+ selectionChangeHandler: function (anEvent) {
+ var selection;
+ var selectionRange;
+ var selectionNode;
+ var valueElement;
+// other hints: http://www.bearpanther.com/2013/05/27/easy-text-selection-in-mobile-safari/
+// SELECTION: https://developer.mozilla.org/en-US/docs/Web/API/Selection
+// RANGE: https://developer.mozilla.org/en-US/docs/Web/API/Range
+// NODE TYPES: https://developer.mozilla.org/en-US/docs/Web/API/Node.nodeType
+
+ selection = MochiKit.DOM.currentWindow().getSelection();
+//console.log("-- selection", selection);
+ selectionRange = selection.getRangeAt(0);
+ selectionNode = selectionRange.startContainer.childNodes[selectionRange.startOffset];
+//console.log("-- selectionNode", selectionNode);
+
+ if (selectionNode != undefined) {
+ valueElement = MochiKit.DOM.getFirstElementByTagAndClassName('*', 'value', selectionNode);
+//console.log("-- valueElement", valueElement);
+ }
+
+ if ((valueElement != null) && (valueElement != selectionNode)) {
+ var range;
+ range = MochiKit.DOM.currentDocument().createRange();
+ range.selectNodeContents(valueElement);
+ selection.removeAllRanges();
+ selection.addRange(range);
+
+ anEvent.preventDefault();
+ anEvent.stopPropagation();
+
+//console.log("updated selection", MochiKit.DOM.currentWindow().getSelection());
+ }
+//console.log("-----------");
+ },
+
+ //-------------------------------------------------------------------------
+
run: function (parameters) {
var shouldShowRegistrationForm;
+ var canRegisterNewUsers;
+
+ canRegisterNewUsers = Clipperz.PM.Proxy.defaultProxy.canRegisterNewUsers();
this.selectInitialProxy();
- shouldShowRegistrationForm = parameters['shouldShowRegistrationForm'] && this.proxy().canRegisterNewUsers();
- this.pages()['loginPage'].setProps({'mode':this.loginMode(), 'isNewUserRegistrationAvailable': this.proxy().canRegisterNewUsers()});
+ shouldShowRegistrationForm = parameters['shouldShowRegistrationForm'] && canRegisterNewUsers;
+ this.pages()['loginPage'].setProps({'mode':this.loginMode(), 'isNewUserRegistrationAvailable':canRegisterNewUsers});
if (shouldShowRegistrationForm) {
this.showRegistrationForm();
@@ -151,7 +211,7 @@ MochiKit.Base.update(Clipperz.PM.UI.MainController.prototype, {
var loginFormPage;
loginFormPage = this.pages()['loginPage'];
- loginFormPage.setProps({'mode':this.loginMode(), 'isNewUserRegistrationAvailable': this.proxy().canRegisterNewUsers()});
+ loginFormPage.setProps({'mode':this.loginMode(), 'isNewUserRegistrationAvailable':Clipperz.PM.Proxy.defaultProxy.canRegisterNewUsers()});
this.moveInPage(this.currentPage(), 'loginPage');
MochiKit.Async.callLater(0.5, MochiKit.Base.method(loginFormPage, 'setInitialFocus'));
},
@@ -202,9 +262,9 @@ MochiKit.Base.update(Clipperz.PM.UI.MainController.prototype, {
deferredResult.addErrback(MochiKit.Base.bind(function (anEvent, anError) {
if (anError['isPermanent'] != true) {
this.pages()['loginPage'].setProps({disabled:false, 'mode':this.loginMode()});
- this.pages()['loginPage'].setInitialFocus();
- }
- return anError;
+ this.pages()['loginPage'].setInitialFocus();
+ }
+ return anError;
}, this, event))
deferredResult.callback();
@@ -323,8 +383,11 @@ MochiKit.Base.update(Clipperz.PM.UI.MainController.prototype, {
runApplication: function () {
MochiKit.Signal.connect(window, 'onpopstate', MochiKit.Base.method(this, 'historyGoBack'));
+/// TODO: remove this TEST HACK
this.moveInPage(this.currentPage(), 'cardListPage');
return this.showRecordList();
+
+// this.moveInPage(this.currentPage(), 'preferencePage');
},
showRecord: function (aRecordReference) {
@@ -333,7 +396,6 @@ MochiKit.Base.update(Clipperz.PM.UI.MainController.prototype, {
this.pages()['cardListPage'].setProps({selectedCard:aRecordReference});
deferredResult = new Clipperz.Async.Deferred('MainController.runApplication', {trace:false});
-// deferredResult.addMethod(this.user(), 'getRecord', aRecordReference['_reference']);
deferredResult.addMethod(this.user(), 'getRecord', aRecordReference);
deferredResult.addMethodcaller('content');
deferredResult.addCallback(MochiKit.Base.bind(function (aCard) {
@@ -348,12 +410,10 @@ MochiKit.Base.update(Clipperz.PM.UI.MainController.prototype, {
},
runDirectLogin: function (someParameters) {
-console.log("RUN DIRECT LOGIN", someParameters);
+//console.log("RUN DIRECT LOGIN", someParameters);
var deferredResult;
-// this.pages()['cardListPage'].setProps({selectedCard:aRecordReference});
deferredResult = new Clipperz.Async.Deferred('MainController.runDirectLogin', {trace:false});
-// deferredResult.addMethod(this.user(), 'getRecord', aRecordReference['_reference']);
deferredResult.addMethod(this.user(), 'getRecord', someParameters['record']);
deferredResult.addMethodcaller('directLoginWithReference', someParameters['directLogin']);
deferredResult.addCallback(Clipperz.PM.UI.DirectLoginRunner.openDirectLogin);
@@ -363,13 +423,26 @@ console.log("RUN DIRECT LOGIN", someParameters);
},
shouldExitApp: function (anEvent) {
-console.log("SHOULD EXIT APP");
+//console.log("SHOULD EXIT APP");
anEvent.preventDefault();
anEvent.stopPropagation();
},
//=========================================================================
+ showPreferences: function (anEvent) {
+ var deferredResult;
+
+ this.pages()['preferencePage'].setProps({});
+ deferredResult = new Clipperz.Async.Deferred('MainController.showPreferences', {trace:false});
+ deferredResult.addMethod(this, 'moveInPage', this.currentPage(), 'preferencePage', true);
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
genericErrorHandler: function (anEvent, anError) {
var errorMessage;
var result;
@@ -480,6 +553,25 @@ console.log("SHOULD EXIT APP");
},
//=========================================================================
+
+ synchronizeLocalData: function (anEvent) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred('MainController.synchronizeLocalData', {trace:true});
+// deferredResult.addMethod(this.proxy(), 'message', 'downloadAccountData', {});
+ deferredResult.addMethod(this.user().connection(), 'message', 'downloadAccountData', {});
+ deferredResult.addCallback(function (aResult) {
+ Clipperz.PM.DataModel.devicePreferences.setAccountDataWityResponse(aResult);
+// localStorage.setItem('clipperz_dump_data', aResult['data']);
+// localStorage.setItem('clipperz_dump_version', aResult['version']);
+// localStorage.setItem('clipperz_dump_date', new Date());
+ })
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
/*
wrongAppVersion: function (anError) {
// this.pages()['errorPage'].setProps({message:anError.message});