diff options
Diffstat (limited to 'vnext/src')
-rw-r--r-- | vnext/src/api/index.js | 18 | ||||
-rw-r--r-- | vnext/src/components/Button.js | 2 | ||||
-rw-r--r-- | vnext/src/components/Chat.js | 13 | ||||
-rw-r--r-- | vnext/src/components/Contact.js | 5 | ||||
-rw-r--r-- | vnext/src/components/Contacts.js | 12 | ||||
-rw-r--r-- | vnext/src/components/Feeds.js | 15 | ||||
-rw-r--r-- | vnext/src/components/Footer.js | 4 | ||||
-rw-r--r-- | vnext/src/components/Header.js | 27 | ||||
-rw-r--r-- | vnext/src/components/Icon.js | 2 | ||||
-rw-r--r-- | vnext/src/components/Message.js | 7 | ||||
-rw-r--r-- | vnext/src/components/MessageInput.js | 20 | ||||
-rw-r--r-- | vnext/src/components/PM.js | 11 | ||||
-rw-r--r-- | vnext/src/components/Post.js | 25 | ||||
-rw-r--r-- | vnext/src/components/Settings.js | 10 | ||||
-rw-r--r-- | vnext/src/components/Spinner.js | 2 | ||||
-rw-r--r-- | vnext/src/components/Thread.js | 23 | ||||
-rw-r--r-- | vnext/src/index.js | 4 |
17 files changed, 127 insertions, 73 deletions
diff --git a/vnext/src/api/index.js b/vnext/src/api/index.js index 653360f5..74280ed5 100644 --- a/vnext/src/api/index.js +++ b/vnext/src/api/index.js @@ -19,14 +19,14 @@ export function me(username = '', password = '') { client.get('/me', { headers: username ? { - 'Authorization': 'Basic ' + window.btoa(unescape(encodeURIComponent(username + ":" + password))) + 'Authorization': 'Basic ' + window.btoa(unescape(encodeURIComponent(username + ':' + password))) } : {} }).then(response => { localStorage.visitor = JSON.stringify(response.data); - resolve(response.data) + resolve(response.data); }).catch(reason => { - localStorage.clear() - reject(reason) + localStorage.clear(); + reject(reason); }) }); } @@ -57,9 +57,9 @@ export function getMessages(path, params) { } export function post(body, attach) { - let form = new FormData() - form.append('attach', attach) - form.append('body', body) + let form = new FormData(); + form.append('attach', attach); + form.append('body', body); return client.post('/post', form); } @@ -69,7 +69,7 @@ export function comment(mid, rid, body, attach) { form.append('rid', rid); form.append('body', body); form.append('attach', attach); - return client.post('/comment', form) + return client.post('/comment', form); } function socialLink(network) { @@ -86,4 +86,4 @@ export function vkLink() { export function markReadTracker(msg, visitor) { return `${apiBaseUrl}/thread/mark_read/${msg.mid}-${msg.rid || 0}.gif?hash=${visitor.hash}`; -}
\ No newline at end of file +} diff --git a/vnext/src/components/Button.js b/vnext/src/components/Button.js index 583f8e4b..656c0426 100644 --- a/vnext/src/components/Button.js +++ b/vnext/src/components/Button.js @@ -1,4 +1,4 @@ -import React from 'react' +import React from 'react'; export default function Button(props) { return ( diff --git a/vnext/src/components/Chat.js b/vnext/src/components/Chat.js index 916de003..dd94dd9e 100644 --- a/vnext/src/components/Chat.js +++ b/vnext/src/components/Chat.js @@ -1,4 +1,6 @@ import React from 'react'; +import ReactRouterPropTypes from 'react-router-prop-types'; +import { UserType } from './Types'; import moment from 'moment'; import PM from './PM'; @@ -14,7 +16,7 @@ export default class Chat extends React.Component { chats: [] }; } - componentWillMount() { + componentDidMount() { this.loadChat(this.props.match.params.user); } @@ -57,14 +59,14 @@ export default class Chat extends React.Component { {uname ? ( <div className="chatroom"> - <ul style={chatStyle} ref="chats"> + <ul style={chatStyle}> { chats.map((chat) => <PM key={moment.utc(chat.timestamp).valueOf()} chat={chat} {...this.props} /> ) } </ul> - <MessageInput data={{ mid: 0, timestamp: "0", to: { uname: uname } }} onSend={this.onSend}> + <MessageInput data={{ mid: 0, timestamp: '0', to: { uname: uname } }} onSend={this.onSend}> Reply... </MessageInput> </div> @@ -78,6 +80,11 @@ export default class Chat extends React.Component { } } +Chat.propTypes = { + visitor: UserType.isRequired, + match: ReactRouterPropTypes.match.isRequired +}; + const chatStyle = { boxSizing: 'border-box', padding: '0 20px', diff --git a/vnext/src/components/Contact.js b/vnext/src/components/Contact.js index 0e969cc1..01dd1ae6 100644 --- a/vnext/src/components/Contact.js +++ b/vnext/src/components/Contact.js @@ -1,4 +1,5 @@ import React from 'react'; +import { UserType } from './Types'; import Avatar from './Avatar'; @@ -14,3 +15,7 @@ export default class Contact extends React.Component { ); } } + +Contact.propTypes = { + user: UserType +}; diff --git a/vnext/src/components/Contacts.js b/vnext/src/components/Contacts.js index 3f2e7288..84a6ec9f 100644 --- a/vnext/src/components/Contacts.js +++ b/vnext/src/components/Contacts.js @@ -1,4 +1,5 @@ import React from 'react'; + import { getChats } from '../api'; @@ -11,7 +12,7 @@ export default class Contacts extends React.Component { pms: [] }; } - componentWillMount() { + componentDidMount() { this.refreshChats(); } @@ -26,11 +27,10 @@ export default class Contacts extends React.Component { } render() { const { pms } = this.state; - const user = this.props.visitor; return ( <div className="msgs"> <div style={wrapperStyle} className="msg-cont"> - <ul style={chatListStyle} ref="chats"> + <ul style={chatListStyle}> { pms && pms.map((chat) => <li key={chat.uname} style={chatTitleStyle}> @@ -48,7 +48,7 @@ export default class Contacts extends React.Component { const wrapperStyle = { display: 'flex', backgroundColor: '#fff' -} +}; const chatListStyle = { boxSizing: 'border-box', @@ -57,7 +57,7 @@ const chatListStyle = { alignItems: 'center', flexDirection: 'column', width: '100%' -} +}; const chatTitleStyle = { width: '100%', @@ -66,4 +66,4 @@ const chatTitleStyle = { background: '#fff', color: '#222', borderBottom: '1px solid #eee' -}
\ No newline at end of file +}; diff --git a/vnext/src/components/Feeds.js b/vnext/src/components/Feeds.js index 821a93f7..7b6713f6 100644 --- a/vnext/src/components/Feeds.js +++ b/vnext/src/components/Feeds.js @@ -1,5 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; +import ReactRouterPropTypes from 'react-router-prop-types'; import { Link } from 'react-router-dom'; import * as qs from 'query-string'; import moment from 'moment'; @@ -11,7 +12,7 @@ import { getMessages } from '../api'; export function Discover(props) { const query = { - baseUrl: "/messages", + baseUrl: '/messages', pageParam: 'before_mid' }; return (<Feed query={query} {...props} />) @@ -19,7 +20,7 @@ export function Discover(props) { export function Discussions(props) { const query = { - baseUrl: "/messages/discussions", + baseUrl: '/messages/discussions', pageParam: 'to' }; return (<Feed authRequired="true" query={query} {...props} />) @@ -28,7 +29,7 @@ export function Discussions(props) { export function Blog(props) { const { user } = props.match.params; const query = { - baseUrl: `/messages`, + baseUrl: '/messages', search: { uname: user }, @@ -134,6 +135,14 @@ class Feed extends React.Component { } } +Blog.propTypes = { + match: ReactRouterPropTypes.match.isRequired +}; + +Tag.propTypes = { + match: ReactRouterPropTypes.match.isRequired +}; + Feed.propTypes = { msgs: PropTypes.array, query: PropTypes.shape({ diff --git a/vnext/src/components/Footer.js b/vnext/src/components/Footer.js index b2551b95..a775833e 100644 --- a/vnext/src/components/Footer.js +++ b/vnext/src/components/Footer.js @@ -1,6 +1,6 @@ -import React from 'react' +import React from 'react'; -import Icon from './Icon' +import Icon from './Icon'; export default function Footer(props) { diff --git a/vnext/src/components/Header.js b/vnext/src/components/Header.js index fd1c1705..43935f4c 100644 --- a/vnext/src/components/Header.js +++ b/vnext/src/components/Header.js @@ -1,6 +1,7 @@ import React from 'react'; +import PropTypes from 'prop-types'; -const elClassHidden = 'header--hidden' +const elClassHidden = 'header--hidden'; const elClassBackground = 'header--background'; export default class Header extends React.Component { @@ -11,7 +12,7 @@ export default class Header extends React.Component { this.wScrollCurrent = 0; this.wScrollBefore = 0; this.wScrollDiff = 0; - this.header = React.createRef() + this.header = React.createRef(); } componentDidMount() { const header = this.header.current; @@ -23,21 +24,21 @@ export default class Header extends React.Component { if (this.wScrollCurrent <= 0) { // scrolled to the very top; element sticks to the top - header.classList.remove(elClassHidden) - header.classList.remove(elClassBackground) + header.classList.remove(elClassHidden); + header.classList.remove(elClassBackground); } else if (this.wScrollDiff > 0 && header.classList.contains(elClassHidden)) { // scrolled up; element slides in - header.classList.remove(elClassHidden) - header.classList.add(elClassBackground) + header.classList.remove(elClassHidden); + header.classList.add(elClassBackground); } else if (this.wScrollDiff < 0) { // scrolled down if (this.wScrollCurrent + this.wHeight >= this.dHeight && header.classList.contains(elClassHidden)) { // scrolled to the very bottom; element slides in - header.classList.remove(elClassHidden) - header.classList.add(elClassBackground) + header.classList.remove(elClassHidden); + header.classList.add(elClassBackground); } else { // scrolled down; element slides out - header.classList.add(elClassHidden) + header.classList.add(elClassHidden); } } this.wScrollBefore = this.wScrollCurrent; @@ -60,8 +61,12 @@ export default class Header extends React.Component { fn.apply(context, args); } }; - }; + } render() { return (<header ref={this.header}>{this.props.children}</header>); } -}
\ No newline at end of file +} + +Header.propTypes = { + children: PropTypes.node +}; diff --git a/vnext/src/components/Icon.js b/vnext/src/components/Icon.js index 743a007c..0a4c7dbc 100644 --- a/vnext/src/components/Icon.js +++ b/vnext/src/components/Icon.js @@ -39,4 +39,4 @@ Icon.propTypes = { name: PropTypes.string.isRequired, className: PropTypes.string, noFill: PropTypes.bool -} +}; diff --git a/vnext/src/components/Message.js b/vnext/src/components/Message.js index ae981df6..d9a32a11 100644 --- a/vnext/src/components/Message.js +++ b/vnext/src/components/Message.js @@ -47,7 +47,7 @@ export default function Message({ data, visitor, children, ...rest }) { <span> Recommend</span> </a> ) : visitor.uid > 0 ? ( - <Link to={{ pathname: "/post", search: `?body=!+%23${data.mid}` }} className="a-like msg-button"> + <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}`)} @@ -63,13 +63,13 @@ export default function Message({ data, visitor, children, ...rest }) { <span> Recommend</span> </a> )} - {!Boolean(data.ReadOnly) | (visitor.uid === data.user.uid) && ( + {!data.ReadOnly | (visitor.uid === data.user.uid) && ( <React.Fragment> <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 && - (Boolean(data.unread) ? ( + (data.unread ? ( <span className="badge">${data.replies}</span> ) : ( `${data.replies}` @@ -107,6 +107,7 @@ function Tags({ data, user, ...rest }) { Message.propTypes = { data: MessageType, + visitor: UserType.isRequired, children: PropTypes.node }; diff --git a/vnext/src/components/MessageInput.js b/vnext/src/components/MessageInput.js index 5d603a4b..1260b6fb 100644 --- a/vnext/src/components/MessageInput.js +++ b/vnext/src/components/MessageInput.js @@ -8,7 +8,7 @@ import Button from './Button'; export default class MessageInput extends React.Component { constructor(props) { - super(props) + super(props); this.textarea = React.createRef(); this.fileinput = React.createRef(); this.state = { @@ -23,7 +23,7 @@ export default class MessageInput extends React.Component { handleCtrlEnter = (event) => { if (event.ctrlKey && (event.charCode == 10 || event.charCode == 13)) { - this.onSubmit({}) + this.onSubmit({}); } } @@ -65,9 +65,9 @@ export default class MessageInput extends React.Component { if (this.state.attach) { this.setState({ attach: '' - }) + }); } else { - input.click() + input.click(); } } render() { @@ -76,7 +76,7 @@ export default class MessageInput extends React.Component { <div style={commentStyle}> <textarea name="body" onChange={this.textChanged} onKeyPress={this.handleCtrlEnter} ref={this.textarea} style={textInputStyle} value={this.state.body} - rows={this.props.rows || "1"} placeholder={this.props.children} /> + rows={this.props.rows || '1'} placeholder={this.props.children} /> <div style={inputBarStyle}> <div style={this.state.attach ? activeStyle : inactiveStyle} onClick={this.openfile}> @@ -115,7 +115,7 @@ const inputBarStyle = { alignItems: 'center', justifyContent: 'space-between', padding: '3px' -} +}; const textInputStyle = { overflow: 'hidden', @@ -124,13 +124,13 @@ const textInputStyle = { boxSizing: 'border-box', border: 0, outline: 'none', - padding: '4px', - resize: 'none' -} + padding: '4px' +}; MessageInput.propTypes = { + children: PropTypes.node, data: MessageType.isRequired, onSend: PropTypes.func.isRequired, rows: PropTypes.string, text: PropTypes.string -};
\ No newline at end of file +}; diff --git a/vnext/src/components/PM.js b/vnext/src/components/PM.js index 7684c6ac..61e28e9a 100644 --- a/vnext/src/components/PM.js +++ b/vnext/src/components/PM.js @@ -1,5 +1,7 @@ import React from 'react'; +import { UserType, MessageType } from './Types'; + import Avatar from './Avatar'; import { format } from '../utils/embed'; @@ -25,7 +27,7 @@ function bubbleStyle(me, msg) { background: background, color: color, padding: '0 12px' - } + }; } function chatItemStyle(me, msg) { @@ -38,5 +40,10 @@ function chatItemStyle(me, msg) { display: 'flex', flexDirection: 'column', alignItems: alignment - } + }; +} + +PM.propTypes = { + chat: MessageType.isRequired, + visitor: UserType.isRequired }
\ No newline at end of file diff --git a/vnext/src/components/Post.js b/vnext/src/components/Post.js index e8ebab5c..ff99cc27 100644 --- a/vnext/src/components/Post.js +++ b/vnext/src/components/Post.js @@ -1,4 +1,8 @@ import React from 'react'; + +import ReactRouterPropTypes from 'react-router-prop-types'; +import { UserType } from './Types'; + import * as qs from 'query-string'; import MessageInput from './MessageInput'; @@ -7,23 +11,23 @@ import { post } from '../api'; export default class Post extends React.Component { constructor(props) { - super(props) + super(props); let params = qs.parse(window.location.search); this.state = { attach: '', body: params.body || '' } this.fileinput = React.createRef(); - console.log(props) + console.log(props); } postMessage = (template) => { const { attach, body } = template; post(body, attach) .then(response => { - console.log(response) + console.log(response); if (response.status === 200) { const msg = response.data.newMessage; - console.log(msg) + console.log(msg); this.props.history.push(`/${this.props.visitor.uname}/${msg.mid}`); } }).catch(console.log); @@ -31,22 +35,27 @@ export default class Post extends React.Component { attachChanged = (event) => { this.setState({ attach: event.target.value - }) + }); } bodyChanged = (event) => { this.setState({ body: event.target.value - }) + }); } render() { return ( <div className="msgs"> <article className="msg-cont"> - <MessageInput rows="7" text={this.state.body} data={{ mid: 0, timestamp: "0" }} onSend={this.postMessage}> - *weather It's very cold today! + <MessageInput rows="7" text={this.state.body} data={{ mid: 0, timestamp: '0' }} onSend={this.postMessage}> + *weather It is very cold today! </MessageInput> </article> </div> ); } } + +Post.propTypes = { + history: ReactRouterPropTypes.history.isRequired, + visitor: UserType +}; diff --git a/vnext/src/components/Settings.js b/vnext/src/components/Settings.js index 95f7e60d..a97d4be9 100644 --- a/vnext/src/components/Settings.js +++ b/vnext/src/components/Settings.js @@ -2,12 +2,12 @@ import React from 'react'; export default class Settings extends React.Component { constructor(props) { - super(props) + super(props); this.state = { settings: {}, userinfo: {}, facebook: {} - } + }; } render() { const { settings, userinfo, facebook } = this.state; @@ -60,7 +60,7 @@ export default class Settings extends React.Component { }}>Telegram</legend> {settings.telegramName ? ( <form action="/settings" method="post"> - <div>Telegram: <b>{{ telegram_name }}</b> — + <div>Telegram: <b> telegram_name </b> — <input type="hidden" name="page" value="telegram-del" /> <input type="submit" value=" Disable " /> </div> @@ -82,13 +82,13 @@ export default class Settings extends React.Component { <p> { settings.jids.map(jid => - <React.Fragment> + <React.Fragment key="jid"> <label><input type="radio" name="delete" value={jid} />${jid}</label><br /> </React.Fragment> ) } {settings.auths.map(auth => - <React.Fragment> + <React.Fragment key={auth.account}> <label><input type="radio" name="delete" value={auth.account} />{auth.account}</label> — <a href="#" diff --git a/vnext/src/components/Spinner.js b/vnext/src/components/Spinner.js index db0c9460..48979339 100644 --- a/vnext/src/components/Spinner.js +++ b/vnext/src/components/Spinner.js @@ -1,5 +1,5 @@ import React from 'react'; -import ContentLoader from "react-content-loader"; +import ContentLoader from 'react-content-loader'; export default function Spinner(props) { return ( diff --git a/vnext/src/components/Thread.js b/vnext/src/components/Thread.js index 52ca1f0f..7ec6fff6 100644 --- a/vnext/src/components/Thread.js +++ b/vnext/src/components/Thread.js @@ -1,4 +1,8 @@ import React from 'react'; + +import ReactRouterPropTypes from 'react-router-prop-types'; +import { UserType } from './Types'; + import { Link } from 'react-router-dom'; import moment from 'moment'; @@ -31,10 +35,10 @@ export default class Thread extends React.Component { const { mid } = this.props.match.params; let params = { mid: mid - } - if (this.props.visitor && this.props.visitor.hash) { - params.hash = this.props.visitor.hash }; + if (this.props.visitor && this.props.visitor.hash) { + params.hash = this.props.visitor.hash; + } getMessages('/thread', params) .then(response => { let msg = response.data.shift(); @@ -64,9 +68,9 @@ export default class Thread extends React.Component { postComment = (template) => { const { mid, rid, body, attach } = template; comment(mid, rid, body, attach).then(res => { - this.loadReplies() + this.loadReplies(); }) - .catch(console.log) + .catch(console.log); } render() { @@ -155,7 +159,14 @@ export default class Thread extends React.Component { const linkStyle = { cursor: 'pointer' -} +}; + +Thread.propTypes = { + location: ReactRouterPropTypes.location, + history: ReactRouterPropTypes.history, + match: ReactRouterPropTypes.match, + visitor: UserType.isRequired +}; function Recommendations({src, ...rest}) { return src.length > 0 && ( diff --git a/vnext/src/index.js b/vnext/src/index.js index fda85fed..2299ab56 100644 --- a/vnext/src/index.js +++ b/vnext/src/index.js @@ -42,7 +42,7 @@ class App extends React.Component { let url = `${proto}//api.juick.com/ws/?${qs.stringify(params)}`; this.ws = new WebSocket(url); this.ws.onopen = () => { - console.log("online"); + console.log('online'); } this.ws.onclose = () => { console.log('offline'); @@ -211,7 +211,7 @@ class App extends React.Component { user.iread && <div className="iread"> { - user.iread.map(u => <Avatar user={u} />) + user.iread.map(u => <Avatar user={u} key={u.uid} />) } </div> } |