Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
C
condenser
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Container Registry
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
hive
condenser
Commits
8df241b4
Commit
8df241b4
authored
4 years ago
by
Quoc Huy Nguyen Dinh
Browse files
Options
Downloads
Patches
Plain Diff
Fix alt author field validation
parent
783c1826
No related branches found
No related tags found
2 merge requests
!212
Develop
,
!211
Fix alt author field validation
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/app/components/elements/ReplyEditor.jsx
+127
-416
127 additions, 416 deletions
src/app/components/elements/ReplyEditor.jsx
with
127 additions
and
416 deletions
src/app/components/elements/ReplyEditor.jsx
+
127
−
416
View file @
8df241b4
...
...
@@ -11,11 +11,7 @@ import * as userActions from 'app/redux/UserReducer';
import
MarkdownViewer
from
'
app/components/cards/MarkdownViewer
'
;
import
TagInput
from
'
app/components/cards/TagInput
'
;
import
{
validateTagInput
}
from
'
app/components/cards/TagInput
'
;
import
SlateEditor
,
{
serializeHtml
,
deserializeHtml
,
getDemoState
,
}
from
'
app/components/elements/SlateEditor
'
;
import
SlateEditor
,
{
serializeHtml
,
deserializeHtml
,
getDemoState
}
from
'
app/components/elements/SlateEditor
'
;
import
{
extractRtags
}
from
'
app/utils/ExtractContent
'
;
import
LoadingIndicator
from
'
app/components/elements/LoadingIndicator
'
;
import
PostCategoryBanner
from
'
app/components/elements/PostCategoryBanner
'
;
...
...
@@ -50,8 +46,7 @@ function allTags(userInput, originalCategory, hashtags) {
);
// remove original cat, if present
if
(
originalCategory
&&
/^
[
-a-z
\d]
+$/
.
test
(
originalCategory
))
tags
=
tags
.
delete
(
originalCategory
);
if
(
originalCategory
&&
/^
[
-a-z
\d]
+$/
.
test
(
originalCategory
))
tags
=
tags
.
delete
(
originalCategory
);
// append hashtags from post until limit is reached
const
tagged
=
[...
hashtags
];
...
...
@@ -110,11 +105,7 @@ class ReplyEditor extends React.Component {
if
(
process
.
env
.
BROWSER
)
{
// Check for rte editor preference
let
rte
=
this
.
props
.
isStory
&&
JSON
.
parse
(
localStorage
.
getItem
(
'
replyEditorData-rte
'
)
||
RTE_DEFAULT
);
let
rte
=
this
.
props
.
isStory
&&
JSON
.
parse
(
localStorage
.
getItem
(
'
replyEditorData-rte
'
)
||
RTE_DEFAULT
);
let
raw
=
null
;
// Process initial body value (if this is an edit)
...
...
@@ -137,15 +128,9 @@ class ReplyEditor extends React.Component {
if
(
title
)
title
.
props
.
onChange
(
draft
.
title
);
if
(
summary
)
summary
.
props
.
onChange
(
draft
.
summary
);
if
(
altAuthor
)
altAuthor
.
props
.
onChange
(
draft
.
altAuthor
);
if
(
draft
.
payoutType
)
this
.
props
.
setPayoutType
(
formId
,
draft
.
payoutType
);
if
(
draft
.
maxAcceptedPayout
)
this
.
props
.
setMaxAcceptedPayout
(
formId
,
draft
.
maxAcceptedPayout
);
if
(
draft
.
beneficiaries
)
this
.
props
.
setBeneficiaries
(
formId
,
draft
.
beneficiaries
);
if
(
draft
.
payoutType
)
this
.
props
.
setPayoutType
(
formId
,
draft
.
payoutType
);
if
(
draft
.
maxAcceptedPayout
)
this
.
props
.
setMaxAcceptedPayout
(
formId
,
draft
.
maxAcceptedPayout
);
if
(
draft
.
beneficiaries
)
this
.
props
.
setBeneficiaries
(
formId
,
draft
.
beneficiaries
);
raw
=
draft
.
body
;
}
...
...
@@ -185,18 +170,11 @@ class ReplyEditor extends React.Component {
if
(
label
&&
name
&&
weight
)
{
if
(
(
label
===
'
referrer
'
&&
weight
<=
$STM_Config
.
referral
.
max_fee_referrer
)
||
(
label
===
'
creator
'
&&
weight
<=
$STM_Config
.
referral
.
max_fee_creator
)
||
(
label
===
'
provider
'
&&
weight
<=
$STM_Config
.
referral
.
max_fee_provider
)
(
label
===
'
referrer
'
&&
weight
<=
$STM_Config
.
referral
.
max_fee_referrer
)
||
(
label
===
'
creator
'
&&
weight
<=
$STM_Config
.
referral
.
max_fee_creator
)
||
(
label
===
'
provider
'
&&
weight
<=
$STM_Config
.
referral
.
max_fee_provider
)
)
{
if
(
qualifiedBeneficiaries
.
find
(
beneficiary
=>
beneficiary
.
username
===
name
)
)
{
if
(
qualifiedBeneficiaries
.
find
(
beneficiary
=>
beneficiary
.
username
===
name
))
{
qualifiedBeneficiaries
.
find
(
beneficiary
=>
beneficiary
.
username
===
name
).
percent
+=
parseInt
((
weight
/
100
).
toFixed
(
0
));
...
...
@@ -257,10 +235,7 @@ class ReplyEditor extends React.Component {
const
tp
=
this
.
props
;
const
np
=
nextProps
;
if
(
typeof
nextProps
.
postTemplateName
!==
'
undefined
'
&&
nextProps
.
postTemplateName
!==
null
)
{
if
(
typeof
nextProps
.
postTemplateName
!==
'
undefined
'
&&
nextProps
.
postTemplateName
!==
null
)
{
const
{
formId
}
=
tp
;
if
(
nextProps
.
postTemplateName
.
indexOf
(
'
create_
'
)
===
0
)
{
...
...
@@ -268,10 +243,7 @@ class ReplyEditor extends React.Component {
const
{
body
,
title
,
summary
,
altAuthor
,
tags
}
=
ns
;
const
{
payoutType
,
beneficiaries
}
=
np
;
const
userTemplates
=
loadUserTemplates
(
username
);
const
newTemplateName
=
nextProps
.
postTemplateName
.
replace
(
'
create_
'
,
''
);
const
newTemplateName
=
nextProps
.
postTemplateName
.
replace
(
'
create_
'
,
''
);
const
newTemplate
=
{
name
:
nextProps
.
postTemplateName
.
replace
(
'
create_
'
,
''
),
beneficiaries
,
...
...
@@ -279,8 +251,7 @@ class ReplyEditor extends React.Component {
markdown
:
body
!==
undefined
?
body
.
value
:
''
,
title
:
title
!==
undefined
?
title
.
value
:
''
,
summary
:
summary
!==
undefined
?
summary
.
value
:
''
,
altAuthor
:
altAuthor
!==
undefined
?
altAuthor
.
value
:
''
,
altAuthor
:
altAuthor
!==
undefined
?
altAuthor
.
value
:
''
,
tags
:
tags
!==
undefined
?
tags
.
value
:
''
,
};
...
...
@@ -308,18 +279,10 @@ class ReplyEditor extends React.Component {
this
.
state
.
body
.
props
.
onChange
(
template
.
markdown
);
this
.
state
.
title
.
props
.
onChange
(
template
.
title
);
this
.
state
.
summary
.
props
.
onChange
(
template
.
summary
);
this
.
state
.
altAuthor
.
props
.
onChange
(
template
.
altAuthor
);
this
.
state
.
altAuthor
.
props
.
onChange
(
template
.
altAuthor
);
this
.
state
.
tags
.
props
.
onChange
(
template
.
tags
);
this
.
props
.
setPayoutType
(
formId
,
template
.
payoutType
);
this
.
props
.
setBeneficiaries
(
formId
,
template
.
beneficiaries
);
this
.
props
.
setPayoutType
(
formId
,
template
.
payoutType
);
this
.
props
.
setBeneficiaries
(
formId
,
template
.
beneficiaries
);
this
.
props
.
setPostTemplateName
(
formId
,
null
);
break
;
...
...
@@ -340,12 +303,7 @@ class ReplyEditor extends React.Component {
np
.
maxAcceptedPayout
!==
tp
.
maxAcceptedPayout
)
{
// also prevents saving after parent deletes this information
const
{
formId
,
payoutType
,
beneficiaries
,
maxAcceptedPayout
,
}
=
np
;
const
{
formId
,
payoutType
,
beneficiaries
,
maxAcceptedPayout
}
=
np
;
const
{
tags
,
title
,
summary
,
altAuthor
,
body
}
=
ns
;
const
data
=
{
formId
,
...
...
@@ -362,10 +320,7 @@ class ReplyEditor extends React.Component {
clearTimeout
(
saveEditorTimeout
);
saveEditorTimeout
=
setTimeout
(()
=>
{
// console.log('save formId', formId, body.value)
localStorage
.
setItem
(
'
replyEditorData-
'
+
formId
,
JSON
.
stringify
(
data
,
null
,
0
)
);
localStorage
.
setItem
(
'
replyEditorData-
'
+
formId
,
JSON
.
stringify
(
data
,
null
,
0
));
this
.
showDraftSaved
();
},
500
);
}
...
...
@@ -387,17 +342,15 @@ class ReplyEditor extends React.Component {
initialValues
:
props
.
initialValues
,
validation
:
values
=>
{
const
markdownRegex
=
/
(?:\*[\w\s]
*
\*
|
\#[\w\s]
*
\#
|_
[\w\s]
*_|~
[\w\s]
*~|
\]\s
*
\(
|
\]\s
*
\[)
/
;
const
altAuthorAllowedCharactersRegex
=
/^
[\w
.
\d
-
]
+$/
;
let
bodyValidation
=
null
;
if
(
!
values
.
body
)
{
bodyValidation
=
tt
(
'
g.required
'
);
}
if
(
values
.
body
&&
new
Blob
([
values
.
body
]).
size
>=
maxKb
*
1024
-
256
)
{
bodyValidation
=
`Post body exceeds
${
maxKb
*
1024
-
256
}
bytes.`
;
if
(
values
.
body
&&
new
Blob
([
values
.
body
]).
size
>=
maxKb
*
1024
-
256
)
{
bodyValidation
=
`Post body exceeds
${
maxKb
*
1024
-
256
}
bytes.`
;
}
return
{
title
:
isStory
&&
...
...
@@ -405,25 +358,21 @@ class ReplyEditor extends React.Component {
?
tt
(
'
g.required
'
)
:
values
.
title
.
length
>
255
?
tt
(
'
reply_editor.shorten_title
'
)
:
markdownRegex
.
test
(
values
.
title
)
?
tt
(
'
reply_editor.markdown_not_supported
'
)
:
null
),
:
markdownRegex
.
test
(
values
.
title
)
?
tt
(
'
reply_editor.markdown_not_supported
'
)
:
null
),
tags
:
isStory
&&
validateTagInput
(
values
.
tags
,
!
isEdit
),
body
:
bodyValidation
,
summary
:
isStory
&&
(
values
.
summary
.
length
>
140
?
tt
(
'
reply_editor.shorten_summary
'
)
:
markdownRegex
.
test
(
values
.
summary
)
?
tt
(
'
reply_editor.markdown_not_supported
'
)
:
null
),
:
markdownRegex
.
test
(
values
.
summary
)
?
tt
(
'
reply_editor.markdown_not_supported
'
)
:
null
),
altAuthor
:
isStory
&&
(
values
.
altAuthor
.
length
>
50
?
tt
(
'
reply_editor.shorten_alt_author
'
)
:
/^
[\w
.
\d
-
]
+$/
.
test
(
values
.
altAuthor
)
?
null
:
tt
(
'
reply_editor.invalid_username
'
)
),
:
values
.
altAuthor
&&
!
altAuthorAllowedCharactersRegex
.
test
(
values
.
altAuthor
)
?
tt
(
'
reply_editor.invalid_username
'
)
:
null
),
};
},
});
...
...
@@ -433,13 +382,9 @@ class ReplyEditor extends React.Component {
if
(
e
)
e
.
preventDefault
();
const
{
formId
,
onCancel
,
defaultPayoutType
}
=
this
.
props
;
const
{
replyForm
,
body
}
=
this
.
state
;
if
(
!
body
.
value
||
confirm
(
tt
(
'
reply_editor.are_you_sure_you_want_to_clear_this_form
'
))
)
{
if
(
!
body
.
value
||
confirm
(
tt
(
'
reply_editor.are_you_sure_you_want_to_clear_this_form
'
)))
{
replyForm
.
resetForm
();
if
(
this
.
refs
.
rte
)
this
.
refs
.
rte
.
setState
({
state
:
stateFromHtml
()
});
if
(
this
.
refs
.
rte
)
this
.
refs
.
rte
.
setState
({
state
:
stateFromHtml
()
});
this
.
setState
({
progress
:
{}
});
this
.
props
.
setPayoutType
(
formId
,
defaultPayoutType
);
this
.
props
.
setBeneficiaries
(
formId
,
[]);
...
...
@@ -461,9 +406,7 @@ class ReplyEditor extends React.Component {
const
state
=
{
rte
:
!
this
.
state
.
rte
};
if
(
state
.
rte
)
{
const
{
body
}
=
this
.
state
;
state
.
rte_value
=
isHtmlTest
(
body
.
value
)
?
stateFromHtml
(
body
.
value
)
:
stateFromMarkdown
(
body
.
value
);
state
.
rte_value
=
isHtmlTest
(
body
.
value
)
?
stateFromHtml
(
body
.
value
)
:
stateFromMarkdown
(
body
.
value
);
}
this
.
setState
(
state
);
localStorage
.
setItem
(
'
replyEditorData-rte
'
,
!
this
.
state
.
rte
);
...
...
@@ -485,10 +428,7 @@ class ReplyEditor extends React.Component {
if
(
this
.
props
.
payoutType
===
'
0%
'
)
{
this
.
props
.
setMaxAcceptedPayout
(
this
.
props
.
formId
,
0
);
}
else
{
this
.
props
.
setMaxAcceptedPayout
(
this
.
props
.
formId
,
this
.
props
.
maxAcceptedPayout
);
this
.
props
.
setMaxAcceptedPayout
(
this
.
props
.
formId
,
this
.
props
.
maxAcceptedPayout
);
}
this
.
props
.
showAdvancedSettings
(
this
.
props
.
formId
);
...
...
@@ -514,9 +454,7 @@ class ReplyEditor extends React.Component {
}
if
(
acceptedFiles
.
length
>
MAX_FILE_TO_UPLOAD
)
{
this
.
displayErrorMessage
(
`Please upload up to maximum
${
MAX_FILE_TO_UPLOAD
}
images.`
);
this
.
displayErrorMessage
(
`Please upload up to maximum
${
MAX_FILE_TO_UPLOAD
}
images.`
);
console
.
log
(
'
onDrop too many files to upload
'
);
return
;
}
...
...
@@ -582,9 +520,7 @@ class ReplyEditor extends React.Component {
if
(
imageToUpload
.
temporaryTag
===
''
)
{
imagesUploadCount
++
;
imageToUpload
.
temporaryTag
=
`![Uploading image #
${
imagesUploadCount
}
...]()`
;
imageToUpload
.
temporaryTag
=
`![Uploading image #
${
imagesUploadCount
}
...]()`
;
placeholder
+=
`\n
${
imageToUpload
.
temporaryTag
}
\n`
;
}
}
...
...
@@ -614,9 +550,7 @@ class ReplyEditor extends React.Component {
const
imageMd
=
``
;
// Replace temporary image MD tag with the real one
body
.
props
.
onChange
(
body
.
value
.
replace
(
image
.
temporaryTag
,
imageMd
)
);
body
.
props
.
onChange
(
body
.
value
.
replace
(
image
.
temporaryTag
,
imageMd
));
this
.
uploadNextImage
();
}
else
{
...
...
@@ -625,9 +559,7 @@ class ReplyEditor extends React.Component {
const
imageMd
=
``
;
// Remove temporary image MD tag
body
.
props
.
onChange
(
body
.
value
.
replace
(
image
.
temporaryTag
,
imageMd
)
);
body
.
props
.
onChange
(
body
.
value
.
replace
(
image
.
temporaryTag
,
imageMd
));
}
else
{
this
.
setState
({
progress
});
}
...
...
@@ -641,16 +573,7 @@ class ReplyEditor extends React.Component {
body
:
this
.
props
.
body
,
};
const
{
onCancel
}
=
this
;
const
{
title
,
tags
,
summary
,
altAuthor
,
body
,
community
,
disabledCommunity
,
enableSideBySide
,
}
=
this
.
state
;
const
{
title
,
tags
,
summary
,
altAuthor
,
body
,
community
,
disabledCommunity
,
enableSideBySide
}
=
this
.
state
;
const
{
reply
,
username
,
...
...
@@ -668,12 +591,7 @@ class ReplyEditor extends React.Component {
beneficiaries
,
maxAcceptedPayout
,
}
=
this
.
props
;
const
{
submitting
,
valid
,
handleSubmit
,
resetForm
,
}
=
this
.
state
.
replyForm
;
const
{
submitting
,
valid
,
handleSubmit
,
resetForm
}
=
this
.
state
.
replyForm
;
const
{
postError
,
rte
}
=
this
.
state
;
const
{
progress
,
noClipboardData
}
=
this
.
state
;
const
disabled
=
submitting
||
!
valid
;
...
...
@@ -725,19 +643,14 @@ class ReplyEditor extends React.Component {
errorCallback
,
};
const
postLabel
=
username
?
(
<
Tooltip
t
=
{
tt
(
'
g.post_as_user
'
,
{
username
})
}
>
{
tt
(
'
g.post
'
)
}
</
Tooltip
>
<
Tooltip
t
=
{
tt
(
'
g.post_as_user
'
,
{
username
})
}
>
{
tt
(
'
g.post
'
)
}
</
Tooltip
>
)
:
(
tt
(
'
g.post
'
)
);
const
hasTitleError
=
title
&&
title
.
touched
&&
title
.
error
;
let
titleError
=
null
;
// The Required title error (triggered onBlur) can shift the form making it hard to click on things..
if
(
hasTitleError
&&
(
title
.
error
!==
tt
(
'
g.required
'
)
||
body
.
value
!==
''
)
)
{
if
(
hasTitleError
&&
(
title
.
error
!==
tt
(
'
g.required
'
)
||
body
.
value
!==
''
))
{
titleError
=
(
<
div
className
=
{
hasTitleError
?
'
error
'
:
'
warning
'
}
>
{
title
.
error
}
...
...
@@ -757,8 +670,7 @@ class ReplyEditor extends React.Component {
);
}
const
hasAltAuthorError
=
altAuthor
&&
altAuthor
.
touched
&&
altAuthor
.
error
;
const
hasAltAuthorError
=
altAuthor
&&
altAuthor
.
touched
&&
altAuthor
.
error
;
let
altAuthorError
=
null
;
if
(
hasAltAuthorError
)
{
altAuthorError
=
(
...
...
@@ -772,9 +684,7 @@ class ReplyEditor extends React.Component {
// TODO: remove all references to these vframe classes. Removed from css and no longer needed.
const
vframe_class
=
isStory
?
'
vframe
'
:
''
;
const
vframe_section_class
=
isStory
?
'
vframe__section
'
:
''
;
const
vframe_section_shrink_class
=
isStory
?
'
vframe__section--shrink
'
:
''
;
const
vframe_section_shrink_class
=
isStory
?
'
vframe__section--shrink
'
:
''
;
const
toggleSideBySide
=
()
=>
{
this
.
setState
({
...
...
@@ -785,18 +695,14 @@ class ReplyEditor extends React.Component {
const
onSelectCoverImage
=
event
=>
{
const
{
target
}
=
event
;
const
postImages
=
document
.
getElementsByClassName
(
'
ReplyEditor__options__image_selector__image_container
'
);
const
postImages
=
document
.
getElementsByClassName
(
'
ReplyEditor__options__image_selector__image_container
'
);
for
(
let
pi
=
0
;
pi
<
postImages
.
length
;
pi
+=
1
)
{
const
postImage
=
postImages
[
pi
];
postImage
.
classList
.
remove
(
'
selected
'
);
}
target
.
classList
.
add
(
'
selected
'
);
selectedCoverImage
=
target
.
style
.
backgroundImage
.
slice
(
4
,
-
1
)
.
replace
(
/"/g
,
''
);
selectedCoverImage
=
target
.
style
.
backgroundImage
.
slice
(
4
,
-
1
).
replace
(
/"/g
,
''
);
};
return
(
...
...
@@ -825,10 +731,7 @@ class ReplyEditor extends React.Component {
onUndo
=
{
this
.
unshiftTagInput
.
bind
(
this
)
}
/>
)
}
<
div
ref
=
"draft"
className
=
"ReplyEditor__draft ReplyEditor__draft-hide"
>
<
div
ref
=
"draft"
className
=
"ReplyEditor__draft ReplyEditor__draft-hide"
>
{
tt
(
'
reply_editor.draft_saved
'
)
}
</
div
>
<
form
...
...
@@ -869,33 +772,18 @@ class ReplyEditor extends React.Component {
{
...
title
.
props
}
/>
{
titleError
}
<
div
className
=
"float-left primary"
style
=
{
{
margin
:
'
0.8rem 0 0 0
'
}
}
>
<
div
className
=
"float-left primary"
style
=
{
{
margin
:
'
0.8rem 0 0 0
'
}
}
>
{
rte
&&
(
<
a
href
=
"#"
onClick
=
{
this
.
toggleRte
}
>
<
a
href
=
"#"
onClick
=
{
this
.
toggleRte
}
>
{
body
.
value
?
`👁️
${
tt
(
'
reply_editor.view_html_source
'
)}
`
:
`🗒️
${
tt
(
'
reply_editor.enable_markdown_editor
'
)}
`
}
?
`👁️
${
tt
(
'
reply_editor.view_html_source
'
)}
`
:
`🗒️
${
tt
(
'
reply_editor.enable_markdown_editor
'
)}
`
}
</
a
>
)
}
{
!
rte
&&
(
isHtml
||
!
body
.
value
)
&&
(
<
a
href
=
"#"
onClick
=
{
this
.
toggleRte
}
>
{
`📰
${
tt
(
'
reply_editor.editor
'
)}
`
}
<
a
href
=
"#"
onClick
=
{
this
.
toggleRte
}
>
{
`📰
${
tt
(
'
reply_editor.editor
'
)}
`
}
</
a
>
)
}
</
div
>
...
...
@@ -906,19 +794,13 @@ class ReplyEditor extends React.Component {
<
div
className
=
{
'
ReplyEditor__body
'
+
(
rte
?
`rte
${
vframe_section_class
}
`
:
vframe_section_shrink_class
)
(
rte
?
`rte
${
vframe_section_class
}
`
:
vframe_section_shrink_class
)
}
>
{
process
.
env
.
BROWSER
&&
rte
?
(
<
SlateEditor
ref
=
"rte"
placeholder
=
{
isStory
?
'
Write your story...
'
:
'
Reply
'
}
placeholder
=
{
isStory
?
'
Write your story...
'
:
'
Reply
'
}
initialState
=
{
this
.
state
.
rte_value
}
onChange
=
{
this
.
onChange
}
/>
...
...
@@ -926,11 +808,7 @@ class ReplyEditor extends React.Component {
<
span
>
<
Dropzone
onDrop
=
{
this
.
onDrop
}
className
=
{
type
===
'
submit_story
'
?
'
dropzone
'
:
'
none
'
}
className
=
{
type
===
'
submit_story
'
?
'
dropzone
'
:
'
none
'
}
disableClick
multiple
accept
=
"image/*"
...
...
@@ -942,46 +820,25 @@ class ReplyEditor extends React.Component {
{
...
body
.
props
}
ref
=
"postRef"
onPasteCapture
=
{
this
.
onPasteCapture
}
className
=
{
type
===
'
submit_story
'
?
'
upload-enabled
'
:
''
}
className
=
{
type
===
'
submit_story
'
?
'
upload-enabled
'
:
''
}
disabled
=
{
loading
}
rows
=
{
isStory
?
10
:
3
}
placeholder
=
{
isStory
?
tt
(
'
g.write_your_story
'
)
:
tt
(
'
g.reply
'
)
}
placeholder
=
{
isStory
?
tt
(
'
g.write_your_story
'
)
:
tt
(
'
g.reply
'
)
}
autoComplete
=
"off"
tabIndex
=
{
2
}
/>
</
Dropzone
>
<
p
className
=
"drag-and-drop"
>
{
tt
(
'
reply_editor.insert_images_by_dragging_dropping
'
)
}
{
noClipboardData
?
''
:
tt
(
'
reply_editor.pasting_from_the_clipboard
'
)
}
{
tt
(
'
reply_editor.insert_images_by_dragging_dropping
'
)
}
{
noClipboardData
?
''
:
tt
(
'
reply_editor.pasting_from_the_clipboard
'
)
}
{
tt
(
'
reply_editor.or_by
'
)
}{
'
'
}
<
a
onClick
=
{
this
.
onOpenClick
}
>
{
tt
(
'
reply_editor.selecting_them
'
)
}
</
a
>
<
a
onClick
=
{
this
.
onOpenClick
}
>
{
tt
(
'
reply_editor.selecting_them
'
)
}
</
a
>
.
</
p
>
{
progress
.
message
&&
(
<
div
className
=
"info"
>
{
progress
.
message
}
</
div
>
)
}
{
progress
.
message
&&
<
div
className
=
"info"
>
{
progress
.
message
}
</
div
>
}
{
progress
.
error
&&
(
<
div
className
=
"error"
>
{
tt
(
'
reply_editor.image_upload
'
)
}
:
{
'
'
}
{
progress
.
error
}
{
tt
(
'
reply_editor.image_upload
'
)
}
:
{
progress
.
error
}
</
div
>
)
}
</
span
>
...
...
@@ -989,17 +846,11 @@ class ReplyEditor extends React.Component {
</
div
>
<
div
className
=
{
vframe_section_shrink_class
}
>
<
div
className
=
"error"
>
{
body
.
touched
&&
body
.
error
&&
body
.
error
!==
'
Required
'
&&
body
.
error
}
{
body
.
touched
&&
body
.
error
&&
body
.
error
!==
'
Required
'
&&
body
.
error
}
</
div
>
</
div
>
<
div
className
=
{
vframe_section_shrink_class
}
style
=
{
{
marginTop
:
'
0.5rem
'
}
}
>
<
div
className
=
{
vframe_section_shrink_class
}
style
=
{
{
marginTop
:
'
0.5rem
'
}
}
>
{
isStory
&&
(
<
span
>
<
input
...
...
@@ -1018,10 +869,7 @@ class ReplyEditor extends React.Component {
{
summaryError
}
</
div
>
<
div
className
=
{
vframe_section_shrink_class
}
style
=
{
{
marginTop
:
'
0.5rem
'
}
}
>
<
div
className
=
{
vframe_section_shrink_class
}
style
=
{
{
marginTop
:
'
0.5rem
'
}
}
>
{
isStory
&&
(
<
span
>
<
TagInput
...
...
@@ -1031,19 +879,12 @@ class ReplyEditor extends React.Component {
isEdit
=
{
isEdit
}
tabIndex
=
{
4
}
/>
{
(
tags
.
touched
||
tags
.
value
)
&&
(
<
div
className
=
"error"
>
{
tags
.
error
}{
'
'
}
</
div
>
)
}
{
(
tags
.
touched
||
tags
.
value
)
&&
<
div
className
=
"error"
>
{
tags
.
error
}
</
div
>
}
</
span
>
)
}
</
div
>
<
div
className
=
{
vframe_section_shrink_class
}
style
=
{
{
marginTop
:
'
0.5rem
'
}
}
>
<
div
className
=
{
vframe_section_shrink_class
}
style
=
{
{
marginTop
:
'
0.5rem
'
}
}
>
{
isStory
&&
(
<
span
>
<
input
...
...
@@ -1051,9 +892,7 @@ class ReplyEditor extends React.Component {
className
=
"ReplyEditor__altAuthor"
onChange
=
{
altAuthor
.
props
.
onChange
}
disabled
=
{
loading
}
placeholder
=
{
tt
(
'
reply_editor.alt_author
'
)
}
placeholder
=
{
tt
(
'
reply_editor.alt_author
'
)
}
autoComplete
=
"off"
ref
=
"altAuthorref"
tabIndex
=
{
5
}
...
...
@@ -1068,128 +907,74 @@ class ReplyEditor extends React.Component {
<
div
>
<
div
className
=
{
vframe_section_shrink_class
}
>
<
a
href
=
"#"
onClick
=
{
toggleSideBySide
}
>
{
(
enableSideBySide
&&
tt
(
'
reply_editor.disable_sidebyside
'
))
||
tt
(
'
reply_editor.enable_sidebyside
'
)
}
{
(
enableSideBySide
&&
tt
(
'
reply_editor.disable_sidebyside
'
))
||
tt
(
'
reply_editor.enable_sidebyside
'
)
}
</
a
>
</
div
>
{
Array
.
from
(
rtags
.
images
).
length
>
0
&&
(
<
div
className
=
"ReplyEditor__options__cover_image_selector"
>
<
h6
>
{
tt
(
'
reply_editor.select_cover_image
'
)
}
{
tt
(
'
reply_editor.select_cover_image
'
)
}
:
</
h6
>
<
div
className
=
"ReplyEditor__options__image_selector"
>
{
Array
.
from
(
rtags
.
images
).
map
(
image
=>
{
return
(
<
div
key
=
{
image
}
className
=
{
classNames
(
'
ReplyEditor__options__image_selector__image_container
'
,
{
selected
:
image
===
selectedCoverImage
,
}
)
}
style
=
{
{
backgroundImage
:
`url(
${
image
}
)`
,
}
}
onClick
=
{
onSelectCoverImage
{
Array
.
from
(
rtags
.
images
).
map
(
image
=>
{
return
(
<
div
key
=
{
image
}
className
=
{
classNames
(
'
ReplyEditor__options__image_selector__image_container
'
,
{
selected
:
image
===
selectedCoverImage
,
}
/>
);
}
)
}
)
}
style
=
{
{
backgroundImage
:
`url(
${
image
}
)`
,
}
}
onClick
=
{
onSelectCoverImage
}
/>
);
})
}
</
div
>
</
div
>
)
}
</
div
>
)
}
<
div
className
=
{
vframe_section_shrink_class
}
style
=
{
{
marginTop
:
'
0.5rem
'
}
}
>
<
div
className
=
{
vframe_section_shrink_class
}
style
=
{
{
marginTop
:
'
0.5rem
'
}
}
>
{
isStory
&&
!
isEdit
&&
(
<
div
className
=
"ReplyEditor__options"
>
<
h6
>
{
tt
(
'
reply_editor.post_options
'
)
}
:
</
h6
>
<
h6
>
{
tt
(
'
reply_editor.post_options
'
)
}
:
</
h6
>
<
div
>
{
this
.
props
.
maxAcceptedPayout
!==
null
&&
this
.
props
.
maxAcceptedPayout
!==
0
&&
(
{
this
.
props
.
maxAcceptedPayout
!==
null
&&
this
.
props
.
maxAcceptedPayout
!==
0
&&
(
<
div
>
{
tt
(
'
post_advanced_settings_jsx.max_accepted_payout
'
)
}
{
tt
(
'
post_advanced_settings_jsx.max_accepted_payout
'
)
}
{
'
:
'
}
{
this
.
props
.
maxAcceptedPayout
}{
'
'
}
HBD
{
this
.
props
.
maxAcceptedPayout
}
HBD
</
div
>
)
}
<
div
>
{
tt
(
'
g.rewards
'
)
}
{
'
:
'
}
{
this
.
props
.
payoutType
===
'
0%
'
&&
tt
(
'
reply_editor.decline_payout
'
)
}
{
this
.
props
.
payoutType
===
'
50%
'
&&
tt
(
'
reply_editor.default_50_50
'
)
}
{
this
.
props
.
payoutType
===
'
100%
'
&&
tt
(
'
reply_editor.power_up_100
'
)
}
{
this
.
props
.
payoutType
===
'
0%
'
&&
tt
(
'
reply_editor.decline_payout
'
)
}
{
this
.
props
.
payoutType
===
'
50%
'
&&
tt
(
'
reply_editor.default_50_50
'
)
}
{
this
.
props
.
payoutType
===
'
100%
'
&&
tt
(
'
reply_editor.power_up_100
'
)
}
</
div
>
<
div
>
{
beneficiaries
&&
beneficiaries
.
length
>
0
&&
(
beneficiaries
.
length
>
0
&&
(
<
span
>
{
tt
(
'
g.beneficiaries
'
)
}
{
tt
(
'
g.beneficiaries
'
)
}
{
'
:
'
}
{
tt
(
'
reply_editor.beneficiaries_set
'
,
{
count
:
beneficiaries
.
length
,
}
)
}
{
tt
(
'
reply_editor.beneficiaries_set
'
,
{
count
:
beneficiaries
.
length
,
})
}
</
span
>
)
}
</
div
>
<
a
href
=
"#"
onClick
=
{
this
.
showAdvancedSettings
}
>
{
tt
(
'
reply_editor.advanced_settings
'
)
}
<
a
href
=
"#"
onClick
=
{
this
.
showAdvancedSettings
}
>
{
tt
(
'
reply_editor.advanced_settings
'
)
}
</
a
>
{
'
'
}
<
br
/>
...
...
@@ -1198,21 +983,12 @@ class ReplyEditor extends React.Component {
)
}
</
div
>
<
div
className
=
{
vframe_section_shrink_class
}
>
{
postError
&&
(
<
div
className
=
"error"
>
{
postError
}
</
div
>
)
}
{
postError
&&
<
div
className
=
"error"
>
{
postError
}
</
div
>
}
</
div
>
<
div
className
=
{
vframe_section_shrink_class
}
>
{
!
loading
&&
(
<
button
type
=
"submit"
className
=
"button"
disabled
=
{
disabled
}
tabIndex
=
{
6
}
>
{
isEdit
?
tt
(
'
reply_editor.update_post
'
)
:
postLabel
}
<
button
type
=
"submit"
className
=
"button"
disabled
=
{
disabled
}
tabIndex
=
{
6
}
>
{
isEdit
?
tt
(
'
reply_editor.update_post
'
)
:
postLabel
}
</
button
>
)
}
{
loading
&&
(
...
...
@@ -1250,14 +1026,10 @@ class ReplyEditor extends React.Component {
<
div
className
=
"ReplyEditor__options float-right text-right"
>
{
tt
(
'
g.rewards
'
)
}
{
'
:
'
}
{
this
.
props
.
payoutType
==
'
0%
'
&&
tt
(
'
reply_editor.decline_payout
'
)
}
{
this
.
props
.
payoutType
==
'
100%
'
&&
tt
(
'
reply_editor.power_up_100
'
)
}
{
this
.
props
.
payoutType
==
'
0%
'
&&
tt
(
'
reply_editor.decline_payout
'
)
}
{
this
.
props
.
payoutType
==
'
100%
'
&&
tt
(
'
reply_editor.power_up_100
'
)
}
{
'
.
'
}
<
a
href
=
{
'
/@
'
+
username
+
'
/settings
'
}
>
Update settings
</
a
>
<
a
href
=
{
'
/@
'
+
username
+
'
/settings
'
}
>
Update settings
</
a
>
</
div
>
)
}
</
div
>
...
...
@@ -1296,10 +1068,7 @@ class ReplyEditor extends React.Component {
vframe_section_shrink_class
:
true
,
})
}
>
<
MarkdownViewer
text
=
{
body
.
value
}
large
=
{
isStory
}
/>
<
MarkdownViewer
text
=
{
body
.
value
}
large
=
{
isStory
}
/>
</
div
>
)
}
</
div
>
...
...
@@ -1350,19 +1119,12 @@ export default formId =>
// mapStateToProps
(
state
,
ownProps
)
=>
{
const
username
=
state
.
user
.
getIn
([
'
current
'
,
'
username
'
]);
const
referralSystem
=
state
.
app
.
getIn
([
'
user_preferences
'
,
'
referralSystem
'
,
]);
const
defaultBeneficiaries
=
state
.
user
.
getIn
([
'
current
'
,
'
defaultBeneficiaries
'
,
]);
const
referralSystem
=
state
.
app
.
getIn
([
'
user_preferences
'
,
'
referralSystem
'
]);
const
defaultBeneficiaries
=
state
.
user
.
getIn
([
'
current
'
,
'
defaultBeneficiaries
'
]);
const
fields
=
[
'
body
'
];
const
{
author
,
permlink
,
type
,
parent_author
}
=
ownProps
;
const
isEdit
=
type
===
'
edit
'
;
const
isStory
=
/submit_story/
.
test
(
type
)
||
(
isEdit
&&
!
parent_author
);
const
isStory
=
/submit_story/
.
test
(
type
)
||
(
isEdit
&&
!
parent_author
);
if
(
isStory
)
fields
.
push
(
'
title
'
);
if
(
isStory
)
fields
.
push
(
'
tags
'
);
if
(
isStory
)
fields
.
push
(
'
summary
'
);
...
...
@@ -1378,9 +1140,7 @@ export default formId =>
}
const
jsonMetadata
=
ownProps
.
jsonMetadata
?
ownProps
.
jsonMetadata
instanceof
Map
?
ownProps
.
jsonMetadata
.
toJS
()
:
ownProps
.
jsonMetadata
?
ownProps
.
jsonMetadata
instanceof
Map
?
ownProps
.
jsonMetadata
.
toJS
()
:
ownProps
.
jsonMetadata
:
{};
let
tags
=
category
;
...
...
@@ -1388,59 +1148,28 @@ export default formId =>
tags
=
OrderedSet
([
category
,
...
jsonMetadata
.
tags
]).
join
(
'
'
);
}
let
isNSFWCommunity
=
false
;
isNSFWCommunity
=
state
.
global
.
getIn
([
'
community
'
,
category
,
'
is_nsfw
'
,
]);
isNSFWCommunity
=
state
.
global
.
getIn
([
'
community
'
,
category
,
'
is_nsfw
'
]);
if
(
isNSFWCommunity
)
{
tags
=
`
${
tags
}
nsfw`
;
}
const
defaultPayoutType
=
state
.
app
.
getIn
(
[
'
user_preferences
'
,
isStory
?
'
defaultBlogPayout
'
:
'
defaultCommentPayout
'
,
],
[
'
user_preferences
'
,
isStory
?
'
defaultBlogPayout
'
:
'
defaultCommentPayout
'
],
'
50%
'
);
let
payoutType
=
state
.
user
.
getIn
([
'
current
'
,
'
post
'
,
formId
,
'
payoutType
'
,
]);
let
payoutType
=
state
.
user
.
getIn
([
'
current
'
,
'
post
'
,
formId
,
'
payoutType
'
]);
let
maxAcceptedPayout
;
if
(
isEdit
)
{
maxAcceptedPayout
=
parseFloat
(
state
.
global
.
getIn
([
'
content
'
,
`
${
author
}
/
${
permlink
}
`
,
'
max_accepted_payout
'
,
])
state
.
global
.
getIn
([
'
content
'
,
`
${
author
}
/
${
permlink
}
`
,
'
max_accepted_payout
'
])
);
}
else
{
maxAcceptedPayout
=
state
.
user
.
getIn
([
'
current
'
,
'
post
'
,
formId
,
'
maxAcceptedPayout
'
,
]);
maxAcceptedPayout
=
state
.
user
.
getIn
([
'
current
'
,
'
post
'
,
formId
,
'
maxAcceptedPayout
'
]);
}
if
(
!
payoutType
)
{
payoutType
=
defaultPayoutType
;
}
let
beneficiaries
=
state
.
user
.
getIn
([
'
current
'
,
'
post
'
,
formId
,
'
beneficiaries
'
,
]);
const
postTemplateName
=
state
.
user
.
getIn
([
'
current
'
,
'
post
'
,
formId
,
'
postTemplateName
'
,
]);
let
beneficiaries
=
state
.
user
.
getIn
([
'
current
'
,
'
post
'
,
formId
,
'
beneficiaries
'
]);
const
postTemplateName
=
state
.
user
.
getIn
([
'
current
'
,
'
post
'
,
formId
,
'
postTemplateName
'
]);
beneficiaries
=
beneficiaries
?
beneficiaries
.
toJS
()
:
[];
// Post full
...
...
@@ -1484,10 +1213,8 @@ export default formId =>
// mapDispatchToProps
dispatch
=>
({
uploadImage
:
(
file
,
progress
)
=>
dispatch
(
userActions
.
uploadImage
({
file
,
progress
})),
showAdvancedSettings
:
formId
=>
dispatch
(
userActions
.
showPostAdvancedSettings
({
formId
})),
uploadImage
:
(
file
,
progress
)
=>
dispatch
(
userActions
.
uploadImage
({
file
,
progress
})),
showAdvancedSettings
:
formId
=>
dispatch
(
userActions
.
showPostAdvancedSettings
({
formId
})),
setPayoutType
:
(
formId
,
payoutType
)
=>
dispatch
(
userActions
.
set
({
...
...
@@ -1554,17 +1281,13 @@ export default formId =>
// permlink, assigned in TransactionSaga
}
:
// edit existing
isEdit
?
{
author
,
permlink
,
parent_author
,
parent_permlink
}
:
null
;
isEdit
?
{
author
,
permlink
,
parent_author
,
parent_permlink
}
:
null
;
if
(
!
linkProps
)
throw
new
Error
(
'
Unknown type:
'
+
type
);
// If this is an HTML post, it MUST begin and end with the tag
if
(
isHtml
&&
!
body
.
match
(
/^<html>
[\s\S]
*<
\/
html>$/
))
{
errorCallback
(
'
HTML posts must begin with <html> and end with </html>
'
);
errorCallback
(
'
HTML posts must begin with <html> and end with </html>
'
);
return
;
}
...
...
@@ -1588,11 +1311,7 @@ export default formId =>
return
;
}
const
metaTags
=
allTags
(
tags
,
originalPost
.
category
,
rtags
.
hashtags
);
const
metaTags
=
allTags
(
tags
,
originalPost
.
category
,
rtags
.
hashtags
);
// merge
const
meta
=
isEdit
?
jsonMetadata
:
{};
...
...
@@ -1675,8 +1394,7 @@ export default formId =>
if
(
!
isEdit
)
{
switch
(
payoutType
)
{
case
'
0%
'
:
// decline payout
__config
.
comment_options
.
max_accepted_payout
=
'
0.000 HBD
'
;
__config
.
comment_options
.
max_accepted_payout
=
'
0.000 HBD
'
;
break
;
case
'
100%
'
:
// 100% steem power payout
__config
.
comment_options
.
percent_hbd
=
0
;
// 10000 === 100% (of 50%)
...
...
@@ -1690,12 +1408,7 @@ export default formId =>
{
beneficiaries
:
beneficiaries
.
sort
(
(
a
,
b
)
=>
a
.
username
<
b
.
username
?
-
1
:
a
.
username
>
b
.
username
?
1
:
0
(
a
,
b
)
=>
(
a
.
username
<
b
.
username
?
-
1
:
a
.
username
>
b
.
username
?
1
:
0
)
)
.
map
(
elt
=>
({
account
:
elt
.
username
,
...
...
@@ -1706,9 +1419,7 @@ export default formId =>
];
}
if
(
maxAcceptedPayout
!==
null
&&
maxAcceptedPayout
!==
0
)
{
__config
.
comment_options
.
max_accepted_payout
=
`
${
maxAcceptedPayout
.
toFixed
(
3
)}
HBD`
;
__config
.
comment_options
.
max_accepted_payout
=
`
${
maxAcceptedPayout
.
toFixed
(
3
)}
HBD`
;
}
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment