1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
import React from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import moment from 'moment';
import { UserType, MessageType } from './Types';
import Icon from './Icon';
import Avatar from './Avatar';
import { format } from '../utils/embed';
import './Message.css';
function Message({ data, visitor, children, ...rest }) {
const isCode = (data.tags || []).indexOf('code') >= 0;
return (
<div className="msg-cont">
<header className="h">
<Avatar user={data.user}>
<div className="msg-ts">
<Link to={{ pathname: `/${data.user.uname}/${data.mid}`, state: { msg: data } }}>
<time dateTime={data.timestamp}
title={moment.utc(data.timestamp).local().format('lll')}>
{moment.utc(data.timestamp).fromNow()}
</time>
</Link>
</div>
</Avatar>
<TagsList user={data.user} data={data.tags || []} />
</header>
<div className="msg-txt">
<MessageContainer isCode={isCode} data={{ __html: format(data.body, data.mid, isCode) }} />
</div>
{data.photo &&
<p className="ir"><a href={`//i.juick.com/p/${data.mid}.${data.attach}`} data-fname={`${data.mid}.${data.attach}`}>
<img src={`//i.juick.com/photos-512/${data.mid}.${data.attach}`} alt="" /></a>
</p>
}
<nav className="l">
{visitor.uid === data.user.uid ? (
<a href={`/${data.user.uname}/${data.mid}`} className="a-like msg-button">
<span className="msg-button-icon">
<Icon name="ei-heart" size="s" />
{data.likes > 0 && (` ${data.likes}`)}
</span>
<span> Recommend</span>
</a>
) : visitor.uid > 0 ? (
<Link to={{ pathname: '/post', search: `?body=!+%23${data.mid}` }} className="a-like msg-button">
<span className="msg-button-icon">
<Icon name="ei-heart" size="s" />
{data.likes > 0 && (` ${data.likes}`)}
</span>
<span> Recommend</span>
</Link>
) : (
<a href="/login" className="a-login msg-button">
<span className="msg-button-icon">
<Icon name="ei-heart" size="s" />
{data.likes > 0 && (` ${data.likes}`)}
</span>
<span> Recommend</span>
</a>
)}
{!data.ReadOnly | (visitor.uid === data.user.uid) && (
<>
<Link to={{ pathname: `/${data.user.uname}/${data.mid}`, state: { msg: data } }} className="a-comment msg-button">
<span className="msg-button-icon">
<Icon name="ei-comment" size="s" />
{data.replies > 0 &&
(visitor.unread && visitor.unread.includes(data.mid) ? (
<span className="badge">{data.replies}</span>
) : (
`${data.replies}`
))
}
</span>
<span> Comment</span>
</Link>
</>
)}
</nav>
{children}
</div>
);
}
export default React.memo(Message);
function MessageContainer({isCode, data}) {
return isCode ? (<pre dangerouslySetInnerHTML={data} />) : (<p dangerouslySetInnerHTML={data} />);
}
function Tags({ data, user, ...rest }) {
return data.length > 0 && (
<div className="msg-tags">
{
data.map(tag => {
return (<Link key={tag} to={{ pathname: `/${user.uname}`, search: `?tag=${tag}` }} title={tag}>{tag}</Link>);
}).reduce((prev, curr) => [prev, ', ', curr])
}
</div>
);
}
const TagsList = React.memo(Tags);
Message.propTypes = {
data: MessageType,
visitor: UserType.isRequired,
children: PropTypes.node
};
Tags.propTypes = {
user: UserType.isRequired,
data: PropTypes.array
};
|