mirror of
https://framagit.org/tykayn/mastodon.git
synced 2023-08-25 08:33:12 +02:00
add preview and style
This commit is contained in:
parent
e4df081141
commit
016b39ae75
@ -21,12 +21,11 @@ import { length } from 'stringz';
|
||||
import { countableText } from '../util/counter';
|
||||
import Icon from 'mastodon/components/icon';
|
||||
import snarkdown from 'snarkdown';
|
||||
|
||||
import DOMPurify from 'dompurify';
|
||||
|
||||
// import elephantUIPlane from '../../../images/elephant_ui_plane.svg';
|
||||
// import { mascot } from '../../initial_state';
|
||||
|
||||
|
||||
const allowedAroundShortCode = '><\u0085\u0020\u00a0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\u0009\u000a\u000b\u000c\u000d';
|
||||
|
||||
const messages = defineMessages({
|
||||
@ -39,35 +38,38 @@ const messages = defineMessages({
|
||||
export default @injectIntl
|
||||
class ComposeForm extends ImmutablePureComponent {
|
||||
|
||||
textMarkdownConverted = '';
|
||||
|
||||
static contextTypes = {
|
||||
router: PropTypes.object,
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
intl : PropTypes.object.isRequired,
|
||||
text : PropTypes.string.isRequired,
|
||||
suggestions : ImmutablePropTypes.list,
|
||||
spoiler : PropTypes.bool,
|
||||
privacy : PropTypes.string,
|
||||
spoilerText : PropTypes.string,
|
||||
focusDate : PropTypes.instanceOf(Date),
|
||||
caretPosition : PropTypes.number,
|
||||
maxTootCharsLimit : PropTypes.number,
|
||||
preselectDate : PropTypes.instanceOf(Date),
|
||||
isSubmitting : PropTypes.bool,
|
||||
isChangingUpload : PropTypes.bool,
|
||||
isUploading : PropTypes.bool,
|
||||
onChange : PropTypes.func.isRequired,
|
||||
onSubmit : PropTypes.func.isRequired,
|
||||
onClearSuggestions : PropTypes.func.isRequired,
|
||||
onFetchSuggestions : PropTypes.func.isRequired,
|
||||
onSuggestionSelected: PropTypes.func.isRequired,
|
||||
onChangeSpoilerText : PropTypes.func.isRequired,
|
||||
onPaste : PropTypes.func.isRequired,
|
||||
onPickEmoji : PropTypes.func.isRequired,
|
||||
showSearch : PropTypes.bool,
|
||||
anyMedia : PropTypes.bool,
|
||||
singleColumn : PropTypes.bool,
|
||||
intl : PropTypes.object.isRequired,
|
||||
text : PropTypes.string.isRequired,
|
||||
textMarkdownConverted: PropTypes.string,
|
||||
suggestions : ImmutablePropTypes.list,
|
||||
spoiler : PropTypes.bool,
|
||||
privacy : PropTypes.string,
|
||||
spoilerText : PropTypes.string,
|
||||
focusDate : PropTypes.instanceOf(Date),
|
||||
caretPosition : PropTypes.number,
|
||||
maxTootCharsLimit : PropTypes.number,
|
||||
preselectDate : PropTypes.instanceOf(Date),
|
||||
isSubmitting : PropTypes.bool,
|
||||
isChangingUpload : PropTypes.bool,
|
||||
isUploading : PropTypes.bool,
|
||||
onChange : PropTypes.func.isRequired,
|
||||
onSubmit : PropTypes.func.isRequired,
|
||||
onClearSuggestions : PropTypes.func.isRequired,
|
||||
onFetchSuggestions : PropTypes.func.isRequired,
|
||||
onSuggestionSelected : PropTypes.func.isRequired,
|
||||
onChangeSpoilerText : PropTypes.func.isRequired,
|
||||
onPaste : PropTypes.func.isRequired,
|
||||
onPickEmoji : PropTypes.func.isRequired,
|
||||
showSearch : PropTypes.bool,
|
||||
anyMedia : PropTypes.bool,
|
||||
singleColumn : PropTypes.bool,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
@ -80,14 +82,18 @@ class ComposeForm extends ImmutablePureComponent {
|
||||
};
|
||||
|
||||
handleKeyDown = (e) => {
|
||||
let markdownConverted = this.convertMarkdown(this.props.text);
|
||||
console.log('markdownConverted', markdownConverted);
|
||||
this.render();
|
||||
if (e.keyCode === 13 && (e.ctrlKey || e.metaKey)) {
|
||||
this.handleSubmit();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
getFulltextForCharacterCounting = () => {
|
||||
return [this.props.spoiler? this.props.spoilerText: '', countableText(this.props.text)].join('');
|
||||
}
|
||||
return [this.props.spoiler ? this.props.spoilerText : '', countableText(this.props.text)].join('');
|
||||
};
|
||||
|
||||
canSubmit = () => {
|
||||
const { isSubmitting, isChangingUpload, isUploading, anyMedia } = this.props;
|
||||
@ -95,7 +101,7 @@ class ComposeForm extends ImmutablePureComponent {
|
||||
const isOnlyWhitespace = fulltext.length !== 0 && fulltext.trim().length === 0;
|
||||
|
||||
return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > 500 || (isOnlyWhitespace && !anyMedia));
|
||||
}
|
||||
};
|
||||
|
||||
handleSubmit = () => {
|
||||
if (this.props.text !== this.autosuggestTextarea.textarea.value) {
|
||||
@ -193,13 +199,39 @@ class ComposeForm extends ImmutablePureComponent {
|
||||
this.props.onPickEmoji(position, data, needsSpace);
|
||||
};
|
||||
|
||||
convertMarkdown(){
|
||||
let md = '_this_ is **easy** to `use`.';
|
||||
let html = snarkdown(md);
|
||||
console.log(html);
|
||||
convertMarkdown(markdownInput) {
|
||||
let md = `# title ouane
|
||||
* aaaaaa
|
||||
* bbbbbb
|
||||
* cccccc
|
||||
aaaaa
|
||||
|
||||
## title deux
|
||||
deuuuux
|
||||
|
||||
### title trois
|
||||
|
||||
_this_ is **easy** to \` use\`.
|
||||
|
||||
* aaaaaa
|
||||
* bbbbbb
|
||||
* cccccc
|
||||
|
||||
un lien vers [[www.wikipedia.org]]
|
||||
[un lien vers cipherbliss.com](https://cipherbliss.com)
|
||||
`;
|
||||
let html = '';
|
||||
if (!markdownInput) {
|
||||
html = snarkdown(md);
|
||||
} else {
|
||||
html = snarkdown(markdownInput);
|
||||
html = DOMPurify.sanitize(markdownInput);
|
||||
}
|
||||
this.textMarkdownConverted = html;
|
||||
return html;
|
||||
};
|
||||
|
||||
render () {
|
||||
render() {
|
||||
const { intl, onPaste, showSearch } = this.props;
|
||||
const disabled = this.props.isSubmitting;
|
||||
let publishText = '';
|
||||
@ -210,7 +242,6 @@ class ComposeForm extends ImmutablePureComponent {
|
||||
} else {
|
||||
publishText = this.props.privacy !== 'unlisted' ? intl.formatMessage(messages.publishLoud, { publish: intl.formatMessage(messages.publish) }) : intl.formatMessage(messages.publish);
|
||||
}
|
||||
this.convertMarkdown();
|
||||
|
||||
return (
|
||||
<div className='compose-form'>
|
||||
@ -267,15 +298,38 @@ class ComposeForm extends ImmutablePureComponent {
|
||||
<PollButtonContainer />
|
||||
<PrivacyDropdownContainer />
|
||||
<SpoilerButtonContainer />
|
||||
</div>
|
||||
<div className='character-counter__wrapper'><CharacterCounter max={7777} text={this.getFulltextForCharacterCounting()} /></div>
|
||||
</div>
|
||||
</div >
|
||||
<div className='character-counter__wrapper'><CharacterCounter
|
||||
max={this.props.maxTootCharsLimit}
|
||||
text={this.getFulltextForCharacterCounting()}
|
||||
/></div >
|
||||
</div >
|
||||
|
||||
<div className='compose-form__publish'>
|
||||
<div className='compose-form__publish-button-wrapper'><Button text={publishText} onClick={this.handleSubmit} disabled={!this.canSubmit()} block /></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='compose-form__publish-button-wrapper'><Button
|
||||
text={publishText}
|
||||
onClick={this.handleSubmit}
|
||||
disabled={!this.canSubmit()}
|
||||
block
|
||||
/></div >
|
||||
</div >
|
||||
|
||||
{this.textMarkdownConverted &&
|
||||
|
||||
<div className='preview formatted-markdown'>
|
||||
<h1>Markdown:</h1>
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: this.textMarkdownConverted,
|
||||
}}
|
||||
>
|
||||
</div >
|
||||
</div >
|
||||
|
||||
}
|
||||
|
||||
</div >
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import {
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
text: state.getIn(['compose', 'text']),
|
||||
textMarkdownConverted: state.getIn(['compose', 'textMarkdownConverted']),
|
||||
suggestions: state.getIn(['compose', 'suggestions']),
|
||||
spoiler: state.getIn(['compose', 'spoiler']),
|
||||
spoilerText: state.getIn(['compose', 'spoiler_text']),
|
||||
|
@ -15,6 +15,7 @@
|
||||
@import 'bliss/compact_header';
|
||||
@import 'bliss/widgets';
|
||||
@import 'bliss/forms';
|
||||
@import 'bliss/markdown';
|
||||
@import 'bliss/accounts';
|
||||
@import 'bliss/statuses';
|
||||
@import 'bliss/boost';
|
||||
|
56
app/javascript/styles/bliss/_markdown.scss
Normal file
56
app/javascript/styles/bliss/_markdown.scss
Normal file
@ -0,0 +1,56 @@
|
||||
.formatted-markdown{
|
||||
padding: 1em;
|
||||
&.preview{
|
||||
|
||||
background: $dark-text-color;
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
h1,h2,h3,h4,h5,h6{
|
||||
&:first-letter{
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
h1{
|
||||
font-size: 1.5rem;
|
||||
margin-bottom: 1em;
|
||||
margin-top: 1.5em;
|
||||
font-weight: 500;
|
||||
}
|
||||
h2{
|
||||
font-size: 1.25rem;
|
||||
margin-bottom: 1em;
|
||||
margin-top: 1.25em;
|
||||
font-weight: 400;
|
||||
}
|
||||
h3{
|
||||
font-size: 1rem;
|
||||
margin-bottom: 1em;
|
||||
font-weight: 300;
|
||||
}
|
||||
h4{
|
||||
font-size: 0.85rem;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
h5{
|
||||
font-size: 0.75rem;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
h6{
|
||||
font-size: 0.70rem;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
strong{
|
||||
font-weight:700;
|
||||
}
|
||||
i{
|
||||
font-style: italic;
|
||||
}
|
||||
a {
|
||||
color: $primary-text-color;
|
||||
}
|
||||
em{
|
||||
background: $darker-text-color;
|
||||
padding: 0.25em;
|
||||
}
|
||||
}
|
@ -89,6 +89,7 @@
|
||||
"css-loader": "^5.0.1",
|
||||
"cssnano": "^4.1.10",
|
||||
"detect-passive-events": "^2.0.2",
|
||||
"dompurify": "^2.2.6",
|
||||
"dotenv": "^8.2.0",
|
||||
"emoji-mart": "Gargron/emoji-mart#build",
|
||||
"es6-symbol": "^3.1.3",
|
||||
|
@ -3956,6 +3956,11 @@ domexception@^2.0.1:
|
||||
dependencies:
|
||||
webidl-conversions "^5.0.0"
|
||||
|
||||
dompurify@^2.2.6:
|
||||
version "2.2.6"
|
||||
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.2.6.tgz#54945dc5c0b45ce5ae228705777e8e59d7b2edc4"
|
||||
integrity sha512-7b7ZArhhH0SP6W2R9cqK6RjaU82FZ2UPM7RO8qN1b1wyvC/NY1FNWcX1Pu00fFOAnzEORtwXe4bPaClg6pUybQ==
|
||||
|
||||
domutils@^1.7.0:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a"
|
||||
|
Loading…
Reference in New Issue
Block a user