aboutsummaryrefslogtreecommitdiff
path: root/vnext/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'vnext/src/components')
-rw-r--r--vnext/src/components/Chat.js10
-rw-r--r--vnext/src/components/Input.js12
-rw-r--r--vnext/src/components/Message.css1
-rw-r--r--vnext/src/components/MessageInput.js2
-rw-r--r--vnext/src/components/Post.js2
-rw-r--r--vnext/src/components/Settings.js9
-rw-r--r--vnext/src/components/Thread.js25
-rw-r--r--vnext/src/components/UserInfo.js4
8 files changed, 43 insertions, 22 deletions
diff --git a/vnext/src/components/Chat.js b/vnext/src/components/Chat.js
index e2b8d2f1..9ac2f2e5 100644
--- a/vnext/src/components/Chat.js
+++ b/vnext/src/components/Chat.js
@@ -1,4 +1,5 @@
import React, { useEffect, useState } from 'react';
+import PropTypes from 'prop-types';
import ReactRouterPropTypes from 'react-router-prop-types';
import { UserType } from './Types';
import moment from 'moment';
@@ -35,21 +36,21 @@ export default function Chat(props) {
setChats(response.data);
});
}
- }
+ };
let onMessage = (json) => {
const msg = JSON.parse(json.data);
if (msg.user.uname === props.match.params.user) {
setChats([msg, ...chats]);
}
- }
+ };
let onSend = (template) => {
pm(template.to.uname, template.body)
.then(res => {
loadChat(props.match.params.user);
}).catch(console.log);
- }
+ };
const uname = props.match.params.user;
return (
<div className="msg-cont">
@@ -77,5 +78,6 @@ export default function Chat(props) {
Chat.propTypes = {
visitor: UserType.isRequired,
- match: ReactRouterPropTypes.match.isRequired
+ match: ReactRouterPropTypes.match.isRequired,
+ connection: PropTypes.shape.isRequired
};
diff --git a/vnext/src/components/Input.js b/vnext/src/components/Input.js
index 5c150ec3..c74d595d 100644
--- a/vnext/src/components/Input.js
+++ b/vnext/src/components/Input.js
@@ -1,9 +1,17 @@
import React from 'react';
+import PropTypes from 'prop-types';
import './Input.css';
function Input({ name, value, ...rest }) {
- return(<input class="input" name={name} value={value} {...rest} />)
+ return (
+ <input className="input" name={name} value={value} {...rest} />
+ );
}
-export default React.memo(Input); \ No newline at end of file
+Input.propTypes = {
+ name: PropTypes.string.isRequired,
+ value: PropTypes.string.isRequired
+};
+
+export default React.memo(Input);
diff --git a/vnext/src/components/Message.css b/vnext/src/components/Message.css
index 1522c166..18d3d0d5 100644
--- a/vnext/src/components/Message.css
+++ b/vnext/src/components/Message.css
@@ -208,4 +208,3 @@ blockquote {
.msg-cont .nsfw .ir img:hover {
opacity: 1;
}
-
diff --git a/vnext/src/components/MessageInput.js b/vnext/src/components/MessageInput.js
index 311284cf..ef96b3b5 100644
--- a/vnext/src/components/MessageInput.js
+++ b/vnext/src/components/MessageInput.js
@@ -23,7 +23,7 @@ export default function MessageInput({ text, data, rows, children, onSend }) {
useEffect(() => {
textareaRef.current.value = text || '';
updateFocus();
- }, []);
+ }, [text]);
let handleCtrlEnter = (event) => {
if (event.ctrlKey && (event.charCode == 10 || event.charCode == 13)) {
diff --git a/vnext/src/components/Post.js b/vnext/src/components/Post.js
index 7958c36d..3dc23613 100644
--- a/vnext/src/components/Post.js
+++ b/vnext/src/components/Post.js
@@ -20,7 +20,7 @@ function PostComponent(props) {
this.props.history.push(`/${this.props.visitor.uname}/${msg.mid}`);
}
}).catch(console.log);
- }
+ };
return (
<div className="msg-cont">
<MessageInput rows="7" text={params.body || ''} data={{ mid: 0, timestamp: '0' }} onSend={postMessage}>
diff --git a/vnext/src/components/Settings.js b/vnext/src/components/Settings.js
index 29d1b4b5..cf6926f8 100644
--- a/vnext/src/components/Settings.js
+++ b/vnext/src/components/Settings.js
@@ -1,5 +1,6 @@
import React, { useState, useEffect, useRef } from 'react';
import PropTypes from 'prop-types';
+import ReactRouterPropTypes from 'react-router-prop-types';
import { me, updateAvatar } from '../api';
@@ -24,7 +25,7 @@ function ChangeAvatarForm({ visitor }) {
};
reader.readAsDataURL(avatarInput.current.files[0]);
}
- }
+ };
let previewUser = { ...visitor, uname: '<preview>' };
if (preview) {
previewUser = { ...visitor, avatar: preview, uname: '<preview>' };
@@ -39,7 +40,7 @@ function ChangeAvatarForm({ visitor }) {
this.props.onChange(visitor);
});
});
- }
+ };
return (
<form>
<small>Recommendations: PNG, 96x96, &lt;50Kb. Also, JPG and GIF supported.</small>
@@ -52,6 +53,10 @@ function ChangeAvatarForm({ visitor }) {
);
}
+ChangeAvatarForm.propTypes = {
+ visitor: UserType.isRequired
+};
+
export default class Settings extends React.Component {
constructor(props) {
super(props);
diff --git a/vnext/src/components/Thread.js b/vnext/src/components/Thread.js
index 90a7be90..22972752 100644
--- a/vnext/src/components/Thread.js
+++ b/vnext/src/components/Thread.js
@@ -1,10 +1,8 @@
import React, { useEffect, useState, useRef } from 'react';
+import PropTypes from 'prop-types';
import ReactRouterPropTypes from 'react-router-prop-types';
-import { UserType } from './Types';
-
-import { Link } from 'react-router-dom';
-import moment from 'moment';
+import { UserType, MessageType } from './Types';
import Message from './Message';
import MessageInput from './MessageInput';
@@ -73,6 +71,14 @@ function Comment({ msg, visitor, active, setActive, postComment }) {
);
}
+Comment.propTypes = {
+ msg: MessageType.isRequired,
+ visitor: UserType.isRequired,
+ active: PropTypes.bool.isRequired,
+ setActive: PropTypes.func.isRequired,
+ postComment: PropTypes.func.isRequired
+};
+
export default function Thread(props) {
const [message, setMessage] = useState(props.location.state || {});
const [replies, setReplies] = useState([]);
@@ -88,7 +94,7 @@ export default function Thread(props) {
if (props.connection) {
props.connection.removeEventListener('msg', onReply);
}
- }
+ };
}, [props.connection]);
let loadReplies = () => {
document.body.scrollTop = 0;
@@ -113,20 +119,20 @@ export default function Thread(props) {
).catch(ex => {
console.log(ex);
});
- }
+ };
let onReply = (json) => {
const msg = JSON.parse(json.data);
if (msg.mid == message.mid) {
setReplies([...this.state.replies, msg]);
}
- }
+ };
let postComment = (template) => {
const { mid, rid, body, attach } = template;
comment(mid, rid, body, attach).then(res => {
loadReplies();
})
.catch(console.log);
- }
+ };
const loaders = Math.min(message.replies || 0, 10);
return (
@@ -165,5 +171,6 @@ Thread.propTypes = {
location: ReactRouterPropTypes.location,
history: ReactRouterPropTypes.history,
match: ReactRouterPropTypes.match,
- visitor: UserType.isRequired
+ visitor: UserType.isRequired,
+ connection: PropTypes.shape.isRequired
};
diff --git a/vnext/src/components/UserInfo.js b/vnext/src/components/UserInfo.js
index 90cbb5e0..c190770b 100644
--- a/vnext/src/components/UserInfo.js
+++ b/vnext/src/components/UserInfo.js
@@ -66,8 +66,8 @@ function Summary({ user }) {
const readersUrl = `/${user.uname}/readers`;
const blUrl = `/${user.uname}/bl`;
let read = user.read && <Link key={readUrl} to={readUrl}>I read: {user.read.length}</Link>;
- let readers = user.readers && <Link key={readersUrl} to={readersUrl}>My readers: {user.readers.length}</Link>
- let mybl = user.statsMyBL && <Link key={blUrl} to={blUrl}>My blacklist: {user.statsMyBL}</Link>
+ let readers = user.readers && <Link key={readersUrl} to={readersUrl}>My readers: {user.readers.length}</Link>;
+ let mybl = user.statsMyBL && <Link key={blUrl} to={blUrl}>My blacklist: {user.statsMyBL}</Link>;
let presentItems = [read, readers, mybl].filter(Boolean);
return (
<div className="msg-summary">