add preview support
This commit is contained in:
+1
-5
@@ -25,11 +25,7 @@ POST {{host}}/api/v1/preview
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"text": "comment *blah* http://radio-t.com",
|
||||
"locator": {
|
||||
"url": "https://radio-t.com/blah1",
|
||||
"site": "remark"
|
||||
}
|
||||
"text": "comment *blah* http://radio-t.com"
|
||||
}
|
||||
|
||||
### update comment
|
||||
|
||||
+12
-1
@@ -2,6 +2,8 @@ import { siteId, url } from './settings';
|
||||
|
||||
import fetcher from './fetcher'
|
||||
|
||||
// TODO: rename actions
|
||||
|
||||
/* common */
|
||||
|
||||
export const logOut = () => fetcher.get({ url: `/auth/logout`, overriddenApiBase: '' });
|
||||
@@ -30,13 +32,21 @@ export const send = ({ text, pid }) => fetcher.post({
|
||||
text,
|
||||
locator: {
|
||||
site: siteId,
|
||||
url
|
||||
url,
|
||||
},
|
||||
...(pid ? { pid } : {}),
|
||||
},
|
||||
withCredentials: true,
|
||||
});
|
||||
|
||||
export const getPreview = ({ text }) => fetcher.post({
|
||||
url: '/preview',
|
||||
body: {
|
||||
text,
|
||||
},
|
||||
withCredentials: true,
|
||||
});
|
||||
|
||||
export const getUser = () => fetcher.get({
|
||||
url: '/user',
|
||||
withCredentials: true
|
||||
@@ -83,6 +93,7 @@ export default {
|
||||
vote,
|
||||
send,
|
||||
getUser,
|
||||
getPreview,
|
||||
|
||||
pin,
|
||||
unpin,
|
||||
|
||||
@@ -1,32 +1,3 @@
|
||||
.comment__text {
|
||||
margin-bottom: 4px;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
|
||||
+ p {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
// imported comments have br instead of p
|
||||
br {
|
||||
content: '';
|
||||
display: block;
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: #0aa;
|
||||
|
||||
&:hover {
|
||||
color: #06c5c5;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,7 +219,10 @@ export default class Comment extends Component {
|
||||
<a href={`${o.locator.url}#remark__comment-${o.id}`} className="comment__username">{o.user.name}</a>
|
||||
</div>
|
||||
{' '}
|
||||
<div className="comment__text" dangerouslySetInnerHTML={{ __html: o.text }}/>
|
||||
<div
|
||||
className={b('comment__text', { mix: 'raw-content' })}
|
||||
dangerouslySetInnerHTML={{ __html: o.text }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -273,7 +276,10 @@ export default class Comment extends Component {
|
||||
}
|
||||
</div>
|
||||
|
||||
<div className="comment__text" dangerouslySetInnerHTML={{ __html: o.text }}/>
|
||||
<div
|
||||
className={b('comment__text', { mix: 'raw-content' })}
|
||||
dangerouslySetInnerHTML={{ __html: o.text }}
|
||||
/>
|
||||
|
||||
<div className="comment__actions">
|
||||
{
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'components/raw-content';
|
||||
|
||||
export { default } from './comment';
|
||||
|
||||
require('./comment.scss');
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
.input__preview {
|
||||
margin-top: 8px;
|
||||
padding: 7px 11px;
|
||||
font-size: 16px;
|
||||
line-height: 1.2;
|
||||
border: 1px dashed #eee;
|
||||
border-radius: 2px;
|
||||
background: #fff;
|
||||
color: #333;
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'components/raw-content';
|
||||
|
||||
export { default } from './input';
|
||||
|
||||
require('./input.scss');
|
||||
@@ -8,3 +10,4 @@ require('./__button/_type/_send/input__button_type_send.scss');
|
||||
|
||||
require('./__buttons/input__buttons.scss');
|
||||
require('./__field/input__field.scss');
|
||||
require('./__preview/input__preview.scss');
|
||||
|
||||
@@ -6,8 +6,13 @@ export default class Input extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
preview: null,
|
||||
};
|
||||
|
||||
this.autoResize = this.autoResize.bind(this);
|
||||
this.send = this.send.bind(this);
|
||||
this.getPreview = this.getPreview.bind(this);
|
||||
this.onKeyDown = this.onKeyDown.bind(this);
|
||||
}
|
||||
|
||||
@@ -46,7 +51,7 @@ export default class Input extends Component {
|
||||
}
|
||||
|
||||
this.fieldNode.value = '';
|
||||
this.setState({ height: null });
|
||||
this.setState({ height: null, preview: null });
|
||||
})
|
||||
.catch(() => {
|
||||
// TODO: do smth?
|
||||
@@ -54,7 +59,19 @@ export default class Input extends Component {
|
||||
.finally(() => this.setState({ isFieldDisabled: false }));
|
||||
}
|
||||
|
||||
render(props, { height, isFieldDisabled }) {
|
||||
getPreview() {
|
||||
const text = this.fieldNode.value;
|
||||
|
||||
if (!text || !text.trim()) return;
|
||||
|
||||
api.getPreview({ text })
|
||||
.then(preview => this.setState({ preview }))
|
||||
.catch(() => {
|
||||
// TODO: do smth?
|
||||
});
|
||||
}
|
||||
|
||||
render(props, { height, isFieldDisabled, preview }) {
|
||||
return (
|
||||
<form className={b('input', props)} onSubmit={this.send}>
|
||||
<textarea
|
||||
@@ -71,9 +88,28 @@ export default class Input extends Component {
|
||||
</textarea>
|
||||
|
||||
<div className="input__buttons">
|
||||
<button className={b('input__button', {}, { type: 'preview' })} type="button">Preview</button>
|
||||
<button className={b('input__button', {}, { type: 'send' })} type="submit">Send</button>
|
||||
<button
|
||||
className={b('input__button', {}, { type: 'preview' })}
|
||||
type="button"
|
||||
onClick={this.getPreview}
|
||||
>Preview</button>
|
||||
|
||||
<button
|
||||
className={b('input__button', {}, { type: 'send' })}
|
||||
type="submit"
|
||||
>Send</button>
|
||||
</div>
|
||||
|
||||
{
|
||||
// TODO: it can be more elegant;
|
||||
// for example it can render full comment component here (or above textarea on mobile)
|
||||
!!preview && (
|
||||
<div
|
||||
className={b('input__preview', { mix: 'raw-content' })}
|
||||
dangerouslySetInnerHTML={{ __html: preview }}
|
||||
/>
|
||||
)
|
||||
}
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
require('./raw-content.scss');
|
||||
@@ -0,0 +1,30 @@
|
||||
.raw-content {
|
||||
p {
|
||||
margin: 0;
|
||||
|
||||
+ p {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
// imported comments have br instead of p
|
||||
br {
|
||||
content: '';
|
||||
display: block;
|
||||
margin-top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: #0aa;
|
||||
|
||||
&:hover {
|
||||
color: #06c5c5;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 300px;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user