mirror of
https://github.com/twisterarmy/twister-react.git
synced 2025-01-11 15:38:00 +00:00
export key
This commit is contained in:
parent
44931065da
commit
8d2bc300ff
1187
build/app-bundle.js
1187
build/app-bundle.js
File diff suppressed because it is too large
Load Diff
4849
build/twister-lib.js
4849
build/twister-lib.js
File diff suppressed because one or more lines are too long
BIN
fonts/glyphicons-halflings-regular.woff2
Normal file
BIN
fonts/glyphicons-halflings-regular.woff2
Normal file
Binary file not shown.
BIN
fonts/passwordsP2P.pdf
Normal file
BIN
fonts/passwordsP2P.pdf
Normal file
Binary file not shown.
197
jsx/common/PostComposer.js
Normal file
197
jsx/common/PostComposer.js
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
var React = require('react');
|
||||||
|
var ContentEditable = require('react-wysiwyg');
|
||||||
|
var PostContentHelper = require('../common/PostContentHelper.js');
|
||||||
|
var SafeStateChangeMixin = require('../common/SafeStateChangeMixin.js');
|
||||||
|
|
||||||
|
|
||||||
|
var ReactBootstrap = require('react-bootstrap')
|
||||||
|
, Button = ReactBootstrap.Button
|
||||||
|
, DropdownButton = ReactBootstrap.DropdownButton
|
||||||
|
, MenuItem = ReactBootstrap.MenuItem
|
||||||
|
, ButtonGroup = ReactBootstrap.ButtonGroup
|
||||||
|
, OverlayTrigger = ReactBootstrap.OverlayTrigger
|
||||||
|
, Popover = ReactBootstrap.Popover
|
||||||
|
, Glyphicon = ReactBootstrap.Glyphicon
|
||||||
|
, Grid = ReactBootstrap.Grid
|
||||||
|
, Col = ReactBootstrap.Col
|
||||||
|
, Row = ReactBootstrap.Row
|
||||||
|
|
||||||
|
var escape = document.createElement('textarea')
|
||||||
|
|
||||||
|
function escapeHTML(html) {
|
||||||
|
escape.textContent = html;
|
||||||
|
return escape.innerHTML;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = PostComposer = React.createClass({
|
||||||
|
mixins:[SafeStateChangeMixin],
|
||||||
|
getInitialState: function(){
|
||||||
|
var editing = false
|
||||||
|
var defaultValue = ''
|
||||||
|
|
||||||
|
return {
|
||||||
|
html: defaultValue,
|
||||||
|
editing: true,
|
||||||
|
placeholder: true,
|
||||||
|
maxLength: 140,
|
||||||
|
totalLength: defaultValue.length,
|
||||||
|
queryMention: false,
|
||||||
|
text: defaultValue
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
componentDidMount: function () {
|
||||||
|
// Gives the window a callback to call before the next repaint.
|
||||||
|
window.requestAnimationFrame(this.checkCursor)
|
||||||
|
},
|
||||||
|
|
||||||
|
checkCursor: function (timestamp) {
|
||||||
|
var self = this
|
||||||
|
var selection = window.getSelection()
|
||||||
|
|
||||||
|
|
||||||
|
if (this.state.editing && selection.focusNode) {
|
||||||
|
|
||||||
|
var node = selection
|
||||||
|
.getRangeAt(0)
|
||||||
|
.commonAncestorContainer
|
||||||
|
.parentNode
|
||||||
|
|
||||||
|
if (node.className === 'show-dropdown') {
|
||||||
|
// you could use the node to determine its position,
|
||||||
|
// and show the dropdown inline, too.
|
||||||
|
this.setStateSafe({ queryMention : node.textContent })
|
||||||
|
} else if (this.state.queryMention) {
|
||||||
|
this.setStateSafe({ queryMention: false })
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (this.state.queryMention) {
|
||||||
|
this.setStateSafe({ queryMention: false })
|
||||||
|
}
|
||||||
|
|
||||||
|
window.requestAnimationFrame(self.checkCursor)
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function(){
|
||||||
|
|
||||||
|
var isValid = (this.state.maxLength >= this.state.totalLength)
|
||||||
|
&& (this.state.totalLength > 0)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div>{this.state.error}</div>
|
||||||
|
<ContentEditable
|
||||||
|
ref='editable'
|
||||||
|
tagName='div'
|
||||||
|
html={this.state.html}
|
||||||
|
placeholder={this.state.placeholder}
|
||||||
|
placeholderText='write'
|
||||||
|
onKeyPress={this.onKeyPress}
|
||||||
|
preventStyling
|
||||||
|
noLinebreaks
|
||||||
|
onChange={this.onChange}
|
||||||
|
editing={this.state.editing}
|
||||||
|
style={{"outline": "none"}}
|
||||||
|
/>
|
||||||
|
<Row>
|
||||||
|
<Col xs={9} md={9}>
|
||||||
|
</Col>
|
||||||
|
<Col xs={1} md={1}>
|
||||||
|
<Button disabled id="content-length">
|
||||||
|
{this.state.maxLength - this.state.totalLength}
|
||||||
|
</Button>
|
||||||
|
</Col>
|
||||||
|
<Col xs={2} md={2}>
|
||||||
|
<Button disabled={!isValid} onClick={this.handleSubmit}>
|
||||||
|
Twist
|
||||||
|
</Button>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
/*<div>
|
||||||
|
Show autocomplete? {this.state.queryMention ? 'Yes ' + this.state.queryMention : 'No'}
|
||||||
|
</div>*/
|
||||||
|
},
|
||||||
|
|
||||||
|
handleSubmit: function(){
|
||||||
|
this.props.onSubmit(this.state.text);
|
||||||
|
},
|
||||||
|
|
||||||
|
autofocus: function () {
|
||||||
|
if (this.state.editing) {
|
||||||
|
this.refs.editable.autofocus()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onChange: function(text, setPlaceholder) {
|
||||||
|
// in order to render the updated html,
|
||||||
|
// you need to pass it as a prop to contentEditable.
|
||||||
|
// This gives you increased flexibility.
|
||||||
|
if (setPlaceholder) {
|
||||||
|
this.setState({
|
||||||
|
placeholder: true,
|
||||||
|
html: '',
|
||||||
|
totalLength: 0,
|
||||||
|
text: ''
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
|
||||||
|
var copy = text.slice(0, this.state.maxLength)
|
||||||
|
|
||||||
|
var parsedContent = PostContentHelper.parseContent(copy);
|
||||||
|
|
||||||
|
//console.log(copy,parsedContent);
|
||||||
|
|
||||||
|
var output = "";
|
||||||
|
|
||||||
|
parsedContent.map(function(item,index){
|
||||||
|
//console.log(item.raw)
|
||||||
|
switch(item.type) {
|
||||||
|
case "mention":
|
||||||
|
output+=('<a class="text-muted" href="#/profile/"'+item.raw.substr(1)+'">'+item.raw+'</a>');
|
||||||
|
break;
|
||||||
|
case "hashtag":
|
||||||
|
output+=('<a class="text-muted" href="#/hashtag/"'+item.raw.substr(1)+'">'+item.raw+'</a>');
|
||||||
|
break;
|
||||||
|
case "url":
|
||||||
|
output+=('<a class="text-primary" href="'+item.raw+'" target="_blank">'+item.raw+'</a>');
|
||||||
|
break;
|
||||||
|
case "email":
|
||||||
|
output+=('<span class="text-primary">'+item.raw+'</span>');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
output+=('<span>'+item.raw+'</span>');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// text overflow
|
||||||
|
if (text.length > this.state.maxLength) {
|
||||||
|
var overflow = '<span style="text-decoration: line-through;">' +
|
||||||
|
text.slice(this.state.maxLength) +
|
||||||
|
'</span>'
|
||||||
|
output = output + overflow
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
placeholder: false,
|
||||||
|
html: output,
|
||||||
|
totalLength: text.length,
|
||||||
|
text: copy
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
enableEditing: function(){
|
||||||
|
var editing = !this.state.editing
|
||||||
|
// set your contenteditable field into editing mode.
|
||||||
|
this.setState({ editing: editing });
|
||||||
|
if (editing) {
|
||||||
|
this.refs.editable.autofocus()
|
||||||
|
this.refs.editable.setCursorToEnd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
152
jsx/common/PostContentHelper.js
Normal file
152
jsx/common/PostContentHelper.js
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
module.exports = {
|
||||||
|
extractUsername: function(s) {
|
||||||
|
var username = "";
|
||||||
|
for( var i = 0; i < s.length; i++ ) {
|
||||||
|
var c = s.charCodeAt(i);
|
||||||
|
if( (c >= 'a'.charCodeAt(0) && c <= 'z'.charCodeAt(0)) ||
|
||||||
|
(c >= 'A'.charCodeAt(0) && c <= 'Z'.charCodeAt(0)) ||
|
||||||
|
(c >= '0'.charCodeAt(0) && c <= '9'.charCodeAt(0)) ||
|
||||||
|
c == '_'.charCodeAt(0) ) {
|
||||||
|
username += s[i];
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return username;
|
||||||
|
},
|
||||||
|
extractHashtag: function(s) {
|
||||||
|
var hashtag = "";
|
||||||
|
s = this.reverseHtmlEntities(s);
|
||||||
|
for( var i = 0; i < s.length; i++ ) {
|
||||||
|
if( " \n\t.,:/?!;'\"()[]{}*#".indexOf(s[i]) < 0 ) {
|
||||||
|
hashtag += s[i];
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hashtag;
|
||||||
|
},
|
||||||
|
escapeHtmlEntities: function(str) {
|
||||||
|
return str
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>')
|
||||||
|
.replace(/"/g, '"')
|
||||||
|
.replace(/'/g, ''');
|
||||||
|
},
|
||||||
|
reverseHtmlEntities: function(str) {
|
||||||
|
return str
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>')
|
||||||
|
.replace(/"/g, '"')
|
||||||
|
.replace(/'/g, "'")
|
||||||
|
.replace(/&/g, '&');
|
||||||
|
},
|
||||||
|
parseContent: function( msg ) {
|
||||||
|
|
||||||
|
//return [{type:"text",raw:msg}];
|
||||||
|
|
||||||
|
var output = [];
|
||||||
|
|
||||||
|
var tmp;
|
||||||
|
var match = null;
|
||||||
|
var index;
|
||||||
|
var strUrlRegexp = "http[s]?://";
|
||||||
|
var strEmailRegexp = "\\S+@\\S+\\.\\S+";
|
||||||
|
var strSplitCounterR = "\\(\\d{1,2}\\/\\d{1,2}\\)$";
|
||||||
|
var reAll = new RegExp("(?:^|[ \\n\\t.,:\\/?!])(#|@|" + strUrlRegexp + "|" + strEmailRegexp + "|" + strSplitCounterR + ")");
|
||||||
|
var reHttp = new RegExp(strUrlRegexp);
|
||||||
|
var reEmail = new RegExp(strEmailRegexp);
|
||||||
|
var reSplitCounter = new RegExp(strSplitCounterR);
|
||||||
|
|
||||||
|
//msg = this.escapeHtmlEntities(msg);
|
||||||
|
|
||||||
|
while( msg != undefined && msg.length ) {
|
||||||
|
|
||||||
|
match = reAll.exec(msg);
|
||||||
|
if( match ) {
|
||||||
|
index = (match[0] === match[1]) ? match.index : match.index + 1;
|
||||||
|
if( match[1] == "@" ) {
|
||||||
|
output.push({type:"text",raw:(msg.substr(0, index))});
|
||||||
|
tmp = msg.substr(index+1);
|
||||||
|
var username = this.extractUsername(tmp);
|
||||||
|
if( username.length ) {
|
||||||
|
output.push({type:"mention",raw:"@"+username});
|
||||||
|
}else{
|
||||||
|
output.push({type:"text",raw:"@"});
|
||||||
|
}
|
||||||
|
msg = tmp.substr(String(username).length);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( reHttp.exec(match[1]) ) {
|
||||||
|
output.push({type:"text",raw:(msg.substr(0, index))});
|
||||||
|
tmp = msg.substring(index);
|
||||||
|
//console.log(tmp)
|
||||||
|
var space = tmp.search(/\s/);
|
||||||
|
//console.log(space)
|
||||||
|
var url;
|
||||||
|
if( space != -1 ) url = tmp.substring(0,space); else url = tmp;
|
||||||
|
if( url.length ) {
|
||||||
|
output.push({type:"url",raw:url});
|
||||||
|
}
|
||||||
|
msg = tmp.substr(String(url).length);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( reEmail.exec(match[1]) ) {
|
||||||
|
output.push({type:"text",raw:(msg.substr(0, index))});
|
||||||
|
tmp = msg.substring(index);
|
||||||
|
var space = tmp.search(/\s/);
|
||||||
|
var email;
|
||||||
|
if( space != -1 ) email = tmp.substring(0,space); else email = tmp;
|
||||||
|
if( email.length ) {
|
||||||
|
output.push({type:"email",raw:email});
|
||||||
|
}
|
||||||
|
msg = tmp.substr(String(email).length);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( match[1] == "#" ) {
|
||||||
|
output.push({type:"text",raw:(msg.substr(0, index))});
|
||||||
|
tmp = msg.substr(index+1);
|
||||||
|
var hashtag = this.extractHashtag(tmp);
|
||||||
|
if( hashtag.length ) {
|
||||||
|
// var hashtag_lc='';
|
||||||
|
// for( var i = 0; i < hashtag.length; i++ ) {
|
||||||
|
// var c = hashtag[i];
|
||||||
|
// hashtag_lc += (c >= 'A' && c <= 'Z') ? c.toLowerCase() : c;
|
||||||
|
// }
|
||||||
|
output.push({type:"hashtag",raw:"#"+hashtag});
|
||||||
|
|
||||||
|
}else{
|
||||||
|
output.push({type:"text",raw:"@"});
|
||||||
|
}
|
||||||
|
msg = tmp.substr(String(hashtag).length);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if (reSplitCounter.exec(match[1])) {
|
||||||
|
output.append({type:"text",raw:(msg.substr(0, index))});
|
||||||
|
tmp = msg.substring(index);
|
||||||
|
if( tmp.length ) {
|
||||||
|
var splitCounter = $('<span class="splited-post-counter"></span>');
|
||||||
|
splitCounter.text(tmp);
|
||||||
|
output.append(splitCounter);
|
||||||
|
msg = "";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
msg = tmp.substr(String(hashtag).length);
|
||||||
|
continue;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
output.push({type:"text",raw:this.reverseHtmlEntities(msg)});
|
||||||
|
msg = "";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ var EventListenerMixin = require('../common/EventListenerMixin.js');
|
|||||||
var AppSettingsMixin = require('../common/AppSettingsMixin.js');
|
var AppSettingsMixin = require('../common/AppSettingsMixin.js');
|
||||||
|
|
||||||
var ImportAccountModalButton = require('../other/ImportAccountModalButton.js');
|
var ImportAccountModalButton = require('../other/ImportAccountModalButton.js');
|
||||||
|
var ExportAccountModalButton = require('../other/ExportAccountModalButton.js');
|
||||||
var GenerateAccountModalButton = require('../other/GenerateAccountModalButton.js');
|
var GenerateAccountModalButton = require('../other/GenerateAccountModalButton.js');
|
||||||
|
|
||||||
var ReactBootstrap = require('react-bootstrap')
|
var ReactBootstrap = require('react-bootstrap')
|
||||||
@ -40,7 +41,10 @@ module.exports = Accounts = React.createClass({
|
|||||||
return (
|
return (
|
||||||
<div key={"miniprofile:"+acc.name}>
|
<div key={"miniprofile:"+acc.name}>
|
||||||
<MiniProfile username={acc.name} pollIntervalProfile={thisComponent.props.pollIntervalProfile}/>
|
<MiniProfile username={acc.name} pollIntervalProfile={thisComponent.props.pollIntervalProfile}/>
|
||||||
<p>{acc.status}</p>
|
<p>
|
||||||
|
{acc.status}
|
||||||
|
<ExportAccountModalButton username={acc.name}/>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
@ -24,13 +24,10 @@ module.exports = Conversation = React.createClass({
|
|||||||
SafeStateChangeMixin,
|
SafeStateChangeMixin,
|
||||||
EventListenerMixin('newpostbyuser')
|
EventListenerMixin('newpostbyuser')
|
||||||
],
|
],
|
||||||
contextTypes: {
|
|
||||||
router: React.PropTypes.func
|
|
||||||
},
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
username: this.context.router.getCurrentParams().username,
|
username: this.props.params.username,
|
||||||
postid: parseInt(this.context.router.getCurrentParams().postid),
|
postid: parseInt(this.props.params.postid),
|
||||||
data: [],
|
data: [],
|
||||||
postIdentifiers: {},
|
postIdentifiers: {},
|
||||||
loading: true
|
loading: true
|
||||||
|
171
jsx/other/ExportAccountModalButton.js
Normal file
171
jsx/other/ExportAccountModalButton.js
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
|
||||||
|
var ReactBootstrap = require('react-bootstrap')
|
||||||
|
, Button = ReactBootstrap.Button
|
||||||
|
, ButtonGroup = ReactBootstrap.ButtonGroup
|
||||||
|
, Glyphicon = ReactBootstrap.Glyphicon
|
||||||
|
, Modal = ReactBootstrap.Modal
|
||||||
|
, Input = ReactBootstrap.Input
|
||||||
|
|
||||||
|
var React = require('react');
|
||||||
|
|
||||||
|
var SafeStateChangeMixin = require('../common/SafeStateChangeMixin.js');
|
||||||
|
var SetIntervalMixin = require("../common/SetIntervalMixin.js");
|
||||||
|
|
||||||
|
module.exports = ExportAccountModalButton = React.createClass({
|
||||||
|
mixins: [
|
||||||
|
SafeStateChangeMixin
|
||||||
|
],
|
||||||
|
getInitialState: function () {
|
||||||
|
return {
|
||||||
|
isModalOpen: false,
|
||||||
|
useEncryption: true,
|
||||||
|
passphrase1: "",
|
||||||
|
passphrase2: "",
|
||||||
|
setupComplete: false,
|
||||||
|
encryptionInProgess: false,
|
||||||
|
encryptionComplete: false,
|
||||||
|
encryptedKey: "",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
handleUseEncryptionChange: function(e) {
|
||||||
|
this.setState({
|
||||||
|
useEncryption: e.target.checked,
|
||||||
|
encryptionInProgess: false,
|
||||||
|
encryptionComplete: false,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handlePassphrase1Change: function(e) {
|
||||||
|
this.setState({
|
||||||
|
passphrase1: e.target.value,
|
||||||
|
encryptionInProgess: false,
|
||||||
|
encryptionComplete: false,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handlePassphrase2Change: function(e) {
|
||||||
|
this.setState({
|
||||||
|
passphrase2: e.target.value,
|
||||||
|
encryptionInProgess: false,
|
||||||
|
encryptionComplete: false,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleToggle: function () {
|
||||||
|
this.setState({
|
||||||
|
isModalOpen: !this.state.isModalOpen
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleEncryption: function (e) {
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
var thisComponent = this;
|
||||||
|
|
||||||
|
if(this.state.useEncryption){
|
||||||
|
|
||||||
|
var passphrase = this.state.passphrase1;
|
||||||
|
|
||||||
|
thisComponent.setStateSafe({encryptionInProgess: true});
|
||||||
|
|
||||||
|
Twister.getAccount(this.props.username).encryptPrivateKey(passphrase,
|
||||||
|
function(encryptedKey){
|
||||||
|
|
||||||
|
thisComponent.setStateSafe({encryptedKey: encryptedKey, encryptionComplete: true, encryptionInProgess: false});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}else{
|
||||||
|
|
||||||
|
var wif = Twister.getAccount(this.props.username).getPrivateKey();
|
||||||
|
|
||||||
|
thisComponent.setStateSafe({encryptedKey: wif, encryptionComplete: true, encryptionInProgess: false});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
|
||||||
|
var belowForm = (
|
||||||
|
<p/>
|
||||||
|
);
|
||||||
|
|
||||||
|
if(this.state.encryptionInProgess){
|
||||||
|
belowForm = (
|
||||||
|
<p>Encryption in progress. Sorry for the lag.</p>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.state.encryptionComplete){
|
||||||
|
if(this.state.useEncryption){
|
||||||
|
|
||||||
|
var formattedBody = "Your encrypted key for Twister: "
|
||||||
|
+this.state.encryptedKey
|
||||||
|
+"\n\nAdvice: Print this email and note down your username and passphrase on the same piece of paper.";
|
||||||
|
|
||||||
|
var subject = "Encrypted Twister Private Key";
|
||||||
|
|
||||||
|
var mailToLink = "mailto:?body=" + encodeURIComponent(formattedBody) + "&subject=" + encodeURIComponent(subject);
|
||||||
|
|
||||||
|
belowForm = (
|
||||||
|
<p>
|
||||||
|
{"Your encrypted key: "+this.state.encryptedKey}
|
||||||
|
<Button href={mailToLink}>Send via Email</Button>
|
||||||
|
</p>
|
||||||
|
)
|
||||||
|
}else{
|
||||||
|
belowForm = (
|
||||||
|
<p>
|
||||||
|
{"Your private key: "+this.state.encryptedKey}
|
||||||
|
</p>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var submitButton = (
|
||||||
|
<Input type='submit' value='Encrypt Private Key' disabled={this.state.passphrase1!=this.state.passphrase2}/>
|
||||||
|
)
|
||||||
|
if(!this.state.useEncryption){
|
||||||
|
submitButton = (
|
||||||
|
<Input type='submit' value='Reveal Private Key'/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button onClick={this.handleToggle}>
|
||||||
|
Export Account
|
||||||
|
<Modal show={this.state.isModalOpen} bsStyle='primary' onHide={this.handleToggle}>
|
||||||
|
<Modal.Header>
|
||||||
|
<Glyphicon glyph='export'/>
|
||||||
|
</Modal.Header>
|
||||||
|
<Modal.Body>
|
||||||
|
<form onSubmit={this.handleEncryption}>
|
||||||
|
<Input
|
||||||
|
type='checkbox'
|
||||||
|
label='Use Encrpytion (highly recommended)'
|
||||||
|
checked={this.state.useEncryption}
|
||||||
|
onChange={this.handleUseEncryptionChange}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
type='password'
|
||||||
|
label='Passphrase'
|
||||||
|
value={this.state.passphrase1}
|
||||||
|
onChange={this.handlePassphrase1Change}
|
||||||
|
disabled={!this.state.useEncryption}
|
||||||
|
/>
|
||||||
|
<Input
|
||||||
|
type='password'
|
||||||
|
label='Repeat Passphrase'
|
||||||
|
value={this.state.passphrase2}
|
||||||
|
onChange={this.handlePassphrase2Change}
|
||||||
|
disabled={!this.state.useEncryption}
|
||||||
|
/>
|
||||||
|
{submitButton}
|
||||||
|
</form>
|
||||||
|
{belowForm}
|
||||||
|
|
||||||
|
</Modal.Body>
|
||||||
|
</Modal>
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
120
jsx/other/GenerateAccountModalButton.js
Normal file
120
jsx/other/GenerateAccountModalButton.js
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
|
||||||
|
var ReactBootstrap = require('react-bootstrap')
|
||||||
|
, Button = ReactBootstrap.Button
|
||||||
|
, ButtonGroup = ReactBootstrap.ButtonGroup
|
||||||
|
, Glyphicon = ReactBootstrap.Glyphicon
|
||||||
|
, Modal = ReactBootstrap.Modal
|
||||||
|
, Input = ReactBootstrap.Input
|
||||||
|
|
||||||
|
var React = require('react');
|
||||||
|
|
||||||
|
var SafeStateChangeMixin = require('../common/SafeStateChangeMixin.js');
|
||||||
|
var SetIntervalMixin = require("../common/SetIntervalMixin.js");
|
||||||
|
|
||||||
|
module.exports = GenerateAccountModalButton = React.createClass({
|
||||||
|
mixins: [SafeStateChangeMixin],
|
||||||
|
getInitialState: function () {
|
||||||
|
return {
|
||||||
|
isModalOpen: false,
|
||||||
|
username: "",
|
||||||
|
checkedUsername: "",
|
||||||
|
available: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
handleUsernameChange: function(e) {
|
||||||
|
this.setState({username: e.target.value});
|
||||||
|
var thisComponent = this;
|
||||||
|
if(e.target.value.length){
|
||||||
|
Twister.checkUsernameAvailable(e.target.value,function(result){
|
||||||
|
thisComponent.setStateSafe({
|
||||||
|
checkedUsername: e.target.value,
|
||||||
|
available: result
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleToggle: function () {
|
||||||
|
this.setState({
|
||||||
|
isModalOpen: !this.state.isModalOpen
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleGenerateAccount: function (e) {
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
var newusername = this.state.username;
|
||||||
|
|
||||||
|
Twister.generateClientSideAccount(newusername,function(newaccount){
|
||||||
|
|
||||||
|
console.log(newaccount._name);
|
||||||
|
|
||||||
|
var event = new CustomEvent('newaccountbyuser',{detail: newaccount});
|
||||||
|
//alert("scrolled to bottom")
|
||||||
|
window.dispatchEvent(event);
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
this.handleToggle();
|
||||||
|
|
||||||
|
return;
|
||||||
|
},
|
||||||
|
render: function() {
|
||||||
|
|
||||||
|
var showAvailable = (
|
||||||
|
<span/>
|
||||||
|
);
|
||||||
|
|
||||||
|
if(this.state.username.length==0){
|
||||||
|
|
||||||
|
showAvailable = (
|
||||||
|
<p>try a username</p>
|
||||||
|
);
|
||||||
|
|
||||||
|
}else{
|
||||||
|
if((this.state.username==this.state.checkedUsername)){
|
||||||
|
|
||||||
|
if(this.state.available){
|
||||||
|
showAvailable = (
|
||||||
|
<p>{this.state.username + " is available"}</p>
|
||||||
|
)
|
||||||
|
}else{
|
||||||
|
showAvailable = (
|
||||||
|
<p>{this.state.username + " is allready taken"}</p>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
|
||||||
|
showAvailable = (
|
||||||
|
<p>checking ...</p>
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button onClick={this.handleToggle}>
|
||||||
|
Generate Account
|
||||||
|
<Modal show={this.state.isModalOpen} bsStyle='primary' onHide={this.handleToggle}>
|
||||||
|
<Modal.Header>
|
||||||
|
<Glyphicon glyph='certificate'/>
|
||||||
|
</Modal.Header>
|
||||||
|
<Modal.Body>
|
||||||
|
<form onSubmit={this.handleGenerateAccount}>
|
||||||
|
<Input
|
||||||
|
type='text'
|
||||||
|
label='Username'
|
||||||
|
value={this.state.username}
|
||||||
|
onChange={this.handleUsernameChange}
|
||||||
|
/>
|
||||||
|
{showAvailable}
|
||||||
|
<Input type='submit' value='Generate Account' data-dismiss="modal" />
|
||||||
|
</form>
|
||||||
|
</Modal.Body>
|
||||||
|
</Modal>
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
@ -19,6 +19,7 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "jsx jsx build-buffer && node test/PosContentTest.js",
|
"test": "jsx jsx build-buffer && node test/PosContentTest.js",
|
||||||
|
"watch": "watch \"npm run pull-lib-and-build\" jsx",
|
||||||
"build": "jsx jsx build-buffer && browserify build-buffer/App.js -o build/app-bundle.js",
|
"build": "jsx jsx build-buffer && browserify build-buffer/App.js -o build/app-bundle.js",
|
||||||
"pull-lib-and-build": "cd ../twister-lib-js && npm run bundle && cd ../twister-react && cp ../twister-lib-js/twister-lib.js build && jsx jsx build-buffer && browserify build-buffer/App.js -o build/app-bundle.js"
|
"pull-lib-and-build": "cd ../twister-lib-js && npm run bundle && cd ../twister-react && cp ../twister-lib-js/twister-lib.js build && jsx jsx build-buffer && browserify build-buffer/App.js -o build/app-bundle.js"
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user