diff --git a/app/components/elements/ReplyEditor.jsx b/app/components/elements/ReplyEditor.jsx index 69572e368ad539fc6a9e7cb4d63f9f6a8e95e602..2fa8b3a85508bea7ad43ae8e6cba7bb56097df05 100644 --- a/app/components/elements/ReplyEditor.jsx +++ b/app/components/elements/ReplyEditor.jsx @@ -123,6 +123,7 @@ class ReplyEditor extends React.Component { const {setMetaData, formId, jsonMetadata} = this.props if(process.env.BROWSER) { let editorData = localStorage.getItem('replyEditorData-' + formId) + let rte_value = RichTextEditor.createEmptyValue(); if(editorData) { editorData = JSON.parse(editorData) if(editorData.formId === formId) { @@ -131,8 +132,10 @@ class ReplyEditor extends React.Component { if(title) title.onChange(editorData.title) if (editorData.body) { body.onChange(editorData.body) - const html = getHtml(editorData.body) - this.state.rte_value = RichTextEditor.createValueFromString(html, 'html') + // const html = getHtml(editorData.body) + // console.log('createValueFromString mnt1', html); + // this.state.rte_value = RichTextEditor.createValueFromString(html, 'html') + // console.log('createValueFromString mnt1 done'); } } } @@ -144,7 +147,6 @@ class ReplyEditor extends React.Component { if(isStory) rte = JSON.parse(localStorage.getItem('replyEditorData-rte') || RTE_DEFAULT); } - let rte_value; if (RichTextEditor) { if (body.value) { if (isHtmlTest(body.value)) { @@ -153,12 +155,10 @@ class ReplyEditor extends React.Component { rte_value = RichTextEditor.createValueFromString(html, 'html') } else { rte = false; - rte_value = RichTextEditor.createEmptyValue(); - // body.initialValue causes 100% cpu when editing http://localhost:3002/steemit/@cryptomental/can-a-viral-introduceyourself-post-be-engineered + // console.log('createValueFromString mnt3'); // rte_value = RichTextEditor.createValueFromString(body.initialValue, 'html'); + // console.log('createValueFromString mnt3 done'); } - } else { - rte_value = RichTextEditor.createEmptyValue(); } } this.setState({rte, rte_value}) @@ -265,6 +265,11 @@ class ReplyEditor extends React.Component { this.setState(state); localStorage.setItem('replyEditorData-rte', !this.state.rte) } + + toggleAllSteemPower = () => { + this.setState({allSteemPower: !this.state.allSteemPower}) + } + render() { // NOTE title, category, and body are UI form fields .. const originalPost = { @@ -279,7 +284,7 @@ class ReplyEditor extends React.Component { author, permlink, parent_author, parent_permlink, type, jsonMetadata, metaLinkData, state, successCallback, handleSubmit, submitting, invalid, //lastComment, } = this.props - const {postError, markdownViewerText, loading, titleWarn, rte} = this.state + const {postError, markdownViewerText, loading, titleWarn, rte, allSteemPower} = this.state const {onTitleChange} = this const errorCallback = estr => { this.setState({ postError: estr, loading: false }) } const successCallbackWrapper = (...args) => { @@ -291,7 +296,8 @@ class ReplyEditor extends React.Component { const autoVoteValue = !isEdit && autoVote.value const replyParams = { author, permlink, parent_author, parent_permlink, type, state, originalPost, - jsonMetadata, metaLinkData, autoVote: autoVoteValue, successCallback: successCallbackWrapper, errorCallback + jsonMetadata, metaLinkData, autoVote: autoVoteValue, allSteemPower, + successCallback: successCallbackWrapper, errorCallback } const postLabel = username ? <Tooltip t={'Post as “' + username + 'â€'}>Post</Tooltip> : 'Post' const hasTitleError = title && title.touched && title.error @@ -366,6 +372,12 @@ class ReplyEditor extends React.Component { } {!loading && !this.props.onCancel && <button className="button hollow no-border" tabIndex={5} disabled={submitting} onClick={onCancel}>Clear</button>} {isStory && !isEdit && <div className="float-right"> + <small onClick={this.toggleAllSteemPower} title="Leave this unchecked to receive 1/2 your reward in Steem Power and 1/2 in Steem Dollars">Pay me 100% in Steem Power</small> + + <input type="checkbox" onChange={this.toggleAllSteemPower} checked={allSteemPower} /> + + <br /> + <small onClick={autoVoteOnChange}>Upvote post</small> <input type="checkbox" {...cleanReduxInput(autoVote)} onChange={autoVoteOnChange} /> @@ -447,7 +459,10 @@ export default formId => reduxForm( dispatch(g.actions.setMetaData({id, meta: jsonMetadata ? jsonMetadata.steem : null})) }, reply: ({category, title, body, author, permlink, parent_author, parent_permlink, - type, originalPost, autoVote = false, state, jsonMetadata, /*metaLinkData,*/ successCallback, errorCallback, loadingCallback}) => { + type, originalPost, autoVote = false, allSteemPower = false, + state, jsonMetadata, /*metaLinkData,*/ + successCallback, errorCallback, loadingCallback + }) => { // const post = state.global.getIn(['content', author + '/' + permlink]) const username = state.user.getIn(['current', 'username']) @@ -512,14 +527,22 @@ export default formId => reduxForm( errorCallback(`You have ${meta.tags.length} tags total${includingCategory}. Please use only 5 in your post and category line.`) return } + // loadingCallback starts the loading indicator + loadingCallback() + + const __config = {originalPost, autoVote} + + if(allSteemPower) { + __config.comment_options = { + percent_steem_dollars: 0, // 10000 === 100% + } + } const operation = { ...linkProps, category: rootCategory, title, body, json_metadata: meta, - __config: {originalPost, autoVote} + __config } - // loadingCallback starts the loading indicator - loadingCallback() dispatch(transaction.actions.broadcastOperation({ type: 'comment', operation, diff --git a/app/components/modules/SidePanel.scss b/app/components/modules/SidePanel.scss index 80d65e084505a41d8c41ded381afaad6584e964a..05b3380616693d97afb1bc82ef31df9e317c8eb0 100644 --- a/app/components/modules/SidePanel.scss +++ b/app/components/modules/SidePanel.scss @@ -47,6 +47,7 @@ $menu-width: 250px; &.right { right: -$menu-width; visibility: hidden; + overflow-y: scroll; } &.visible.right { diff --git a/app/components/pages/UserProfile.jsx b/app/components/pages/UserProfile.jsx index 1967b7c9d7e4a086580bc06dc7a9decabf9c5797..85d90ef7a08d53442b20d0ad4071831236d9eb2a 100644 --- a/app/components/pages/UserProfile.jsx +++ b/app/components/pages/UserProfile.jsx @@ -140,7 +140,7 @@ export default class UserProfile extends React.Component { if( account.posts ) { tab_content = <PostsList - emptyText={`Looks like ${account.name} hasn't made any posts yet!`} + emptyText={`Looks like ${account.name} hasn't made any comments yet!`} posts={account.posts.map(p => `${account.name}/${p}`)} loading={fetching} category="posts" diff --git a/app/redux/TransactionSaga.js b/app/redux/TransactionSaga.js index 52b46407b87a19755b134a69aeefeac0dfb7abf2..5ae48f195815533e002198ccc2600e73a809c46a 100644 --- a/app/redux/TransactionSaga.js +++ b/app/redux/TransactionSaga.js @@ -271,7 +271,7 @@ import secureRandom from 'secure-random' function* preBroadcast_comment({operation, username}) { if (!operation.author) operation.author = username let permlink = operation.permlink - const {author, __config: {originalPost, autoVote}} = operation + const {author, __config: {originalPost, autoVote, comment_options}} = operation const {parent_author = '', parent_permlink = operation.category } = operation const {title} = operation let {body} = operation @@ -306,15 +306,35 @@ function* preBroadcast_comment({operation, username}) { body: new Buffer(body2, 'utf-8'), } - // For immediate UI updates call g.actions.receiveComment(op). This requires a rollback. - // Show the original body (not the patch). - // yield put(g.actions.receiveComment({...op, body: new Buffer(body, 'utf-8')})) - if(!autoVote) return op - const vote = {voter: op.author, author: op.author, permlink: op.permlink, weight: 10000} - return [ + const comment_op = [ ['comment', op], - ['vote', vote], ] + + if(autoVote) { + const vote = {voter: op.author, author: op.author, permlink: op.permlink, weight: 10000} + comment_op.push(['vote', vote]) + } + + if(comment_options) { + const { + max_accepted_payout = "1000000.000 SBD", + percent_steem_dollars = 10000, // 10000 === 100% + allow_votes = true, + allow_curation_rewards = true, + } = comment_options + comment_op.push( + ['comment_options', { + author, + permlink, + max_accepted_payout, + percent_steem_dollars, + allow_votes, + allow_curation_rewards, + extensions: comment_options.extensions ? comment_options.extensions : [] + }] + ) + } + return comment_op } function* createPermlink(title, author, parent_author, parent_permlink) { diff --git a/server/api/oauth.js b/server/api/oauth.js index e8da1d3fe0b3e0d29d26979b10f012a1af9dbd45..00ad3fdad9744a2d90b161d8b89a12bc0e65576c 100644 --- a/server/api/oauth.js +++ b/server/api/oauth.js @@ -121,8 +121,10 @@ function* handleFacebookCallback() { return null; } if (!u.email) { - console.log('-- /handle_facebook_callback no email -->', this.session.uid, u.name); - throw new Error('Your Facebook account has no associated email address. Please add email to your Facebook account and try again.'); + console.log('-- /handle_facebook_callback no email -->', this.session.uid, u); + this.flash = 'Facebook login didn\'t provide any email addresses. Please make sure your Facebook account has a primary email address and try again.'; + this.redirect('/'); + return; } if (user) {