From f470636a70943a8ecad8bddc791a1c2dddd28e1e Mon Sep 17 00:00:00 2001
From: Vitaly Takmazov
Date: Sat, 4 May 2019 21:13:12 +0300
Subject: Components -> UI
---
vnext/src/components/Avatar.css | 27 ---
vnext/src/components/Avatar.js | 44 ----
vnext/src/components/Button.css | 13 -
vnext/src/components/Button.js | 11 -
vnext/src/components/Chat.css | 9 -
vnext/src/components/Chat.js | 85 -------
vnext/src/components/Contact.js | 21 --
vnext/src/components/Contacts.js | 49 ----
vnext/src/components/Feeds.js | 171 -------------
vnext/src/components/Header.js | 69 ------
vnext/src/components/Icon.js | 38 ---
vnext/src/components/Input.css | 8 -
vnext/src/components/Input.js | 17 --
vnext/src/components/LoginButton.js | 90 -------
vnext/src/components/Message.css | 210 ----------------
vnext/src/components/Message.js | 142 -----------
vnext/src/components/MessageInput.js | 107 --------
vnext/src/components/Modal.css | 95 --------
vnext/src/components/Modal.js | 29 ---
vnext/src/components/NavigationIcon.css | 4 -
vnext/src/components/NavigationIcon.js | 21 --
vnext/src/components/PM.js | 51 ----
vnext/src/components/Post.js | 38 ---
vnext/src/components/SearchBox.js | 26 --
vnext/src/components/Settings.js | 268 ---------------------
vnext/src/components/Spinner.js | 42 ----
vnext/src/components/Thread.js | 181 --------------
vnext/src/components/Types.js | 15 --
vnext/src/components/UploadButton.js | 42 ----
vnext/src/components/UserInfo.css | 11 -
vnext/src/components/UserInfo.js | 117 ---------
vnext/src/components/Users.js | 44 ----
vnext/src/components/__tests__/Avatar.test.js | 15 --
vnext/src/components/__tests__/LoginButton.test.js | 21 --
.../src/components/__tests__/MessageInput-test.js | 95 --------
vnext/src/components/__tests__/UserLink.test.js | 20 --
.../__tests__/__snapshots__/Avatar.test.js.snap | 41 ----
.../__snapshots__/LoginButton.test.js.snap | 178 --------------
.../__tests__/__snapshots__/UserLink.test.js.snap | 33 ---
39 files changed, 2498 deletions(-)
delete mode 100644 vnext/src/components/Avatar.css
delete mode 100644 vnext/src/components/Avatar.js
delete mode 100644 vnext/src/components/Button.css
delete mode 100644 vnext/src/components/Button.js
delete mode 100644 vnext/src/components/Chat.css
delete mode 100644 vnext/src/components/Chat.js
delete mode 100644 vnext/src/components/Contact.js
delete mode 100644 vnext/src/components/Contacts.js
delete mode 100644 vnext/src/components/Feeds.js
delete mode 100644 vnext/src/components/Header.js
delete mode 100644 vnext/src/components/Icon.js
delete mode 100644 vnext/src/components/Input.css
delete mode 100644 vnext/src/components/Input.js
delete mode 100644 vnext/src/components/LoginButton.js
delete mode 100644 vnext/src/components/Message.css
delete mode 100644 vnext/src/components/Message.js
delete mode 100644 vnext/src/components/MessageInput.js
delete mode 100644 vnext/src/components/Modal.css
delete mode 100644 vnext/src/components/Modal.js
delete mode 100644 vnext/src/components/NavigationIcon.css
delete mode 100644 vnext/src/components/NavigationIcon.js
delete mode 100644 vnext/src/components/PM.js
delete mode 100644 vnext/src/components/Post.js
delete mode 100644 vnext/src/components/SearchBox.js
delete mode 100644 vnext/src/components/Settings.js
delete mode 100644 vnext/src/components/Spinner.js
delete mode 100644 vnext/src/components/Thread.js
delete mode 100644 vnext/src/components/Types.js
delete mode 100644 vnext/src/components/UploadButton.js
delete mode 100644 vnext/src/components/UserInfo.css
delete mode 100644 vnext/src/components/UserInfo.js
delete mode 100644 vnext/src/components/Users.js
delete mode 100644 vnext/src/components/__tests__/Avatar.test.js
delete mode 100644 vnext/src/components/__tests__/LoginButton.test.js
delete mode 100644 vnext/src/components/__tests__/MessageInput-test.js
delete mode 100644 vnext/src/components/__tests__/UserLink.test.js
delete mode 100644 vnext/src/components/__tests__/__snapshots__/Avatar.test.js.snap
delete mode 100644 vnext/src/components/__tests__/__snapshots__/LoginButton.test.js.snap
delete mode 100644 vnext/src/components/__tests__/__snapshots__/UserLink.test.js.snap
(limited to 'vnext/src/components')
diff --git a/vnext/src/components/Avatar.css b/vnext/src/components/Avatar.css
deleted file mode 100644
index 7bdb3115..00000000
--- a/vnext/src/components/Avatar.css
+++ /dev/null
@@ -1,27 +0,0 @@
-.Avatar {
- display: flex;
- width: 100%;
-}
-.msg-avatar {
- max-height: 48px;
- margin-right: 10px;
- max-width: 48px;
-}
-.msg-avatar img {
- max-height: 48px;
- vertical-align: top;
- max-width: 48px;
-}
-
-.info-avatar img {
- max-height: 24px;
- max-width: 24px;
- padding: 6px;
- vertical-align: middle;
-}
-
-@media screen and (min-width: 450px) {
- .Avatar {
- width: 300px;
- }
-}
diff --git a/vnext/src/components/Avatar.js b/vnext/src/components/Avatar.js
deleted file mode 100644
index dda5449f..00000000
--- a/vnext/src/components/Avatar.js
+++ /dev/null
@@ -1,44 +0,0 @@
-import React, { memo } from 'react';
-import PropTypes from 'prop-types';
-import { Link } from 'react-router-dom';
-
-import { UserType } from './Types';
-
-import Icon from './Icon';
-
-import './Avatar.css';
-
-function Avatar({ user, style, link, children}) {
- return (
-
-
- {
- user.uname ?
-
- {user.avatar ?
-
- :
}
-
- :
- }
-
-
-
-
- {user.uname}
-
-
- {children}
-
-
- );
-}
-
-export default memo(Avatar);
-
-Avatar.propTypes = {
- user: UserType,
- link: PropTypes.string,
- style: PropTypes.object,
- children: PropTypes.node
-};
diff --git a/vnext/src/components/Button.css b/vnext/src/components/Button.css
deleted file mode 100644
index 2acb87be..00000000
--- a/vnext/src/components/Button.css
+++ /dev/null
@@ -1,13 +0,0 @@
-.Button {
- background: #fff;
- border: 1px solid #eee;
- color: #888;
- cursor: pointer;
- display: inline-block;
- margin: 5px;
- padding: 4px 10px;
-}
-.Button:hover {
- background: #f8f8f8;
- border-bottom: 1px solid #ff339a;
-}
diff --git a/vnext/src/components/Button.js b/vnext/src/components/Button.js
deleted file mode 100644
index 18cab0a7..00000000
--- a/vnext/src/components/Button.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import React from 'react';
-
-import './Button.css';
-
-function Button(props) {
- return (
-
- );
-}
-
-export default React.memo(Button);
diff --git a/vnext/src/components/Chat.css b/vnext/src/components/Chat.css
deleted file mode 100644
index 520a5c9b..00000000
--- a/vnext/src/components/Chat.css
+++ /dev/null
@@ -1,9 +0,0 @@
-.Chat_messages {
- box-sizing: border-box;
- padding: 0 20px;
- overflow-y: auto;
- height: 450px;
- display: flex;
- flex-direction: column-reverse;
- width: 100%;
-}
diff --git a/vnext/src/components/Chat.js b/vnext/src/components/Chat.js
deleted file mode 100644
index a1254a10..00000000
--- a/vnext/src/components/Chat.js
+++ /dev/null
@@ -1,85 +0,0 @@
-import React, { useEffect, useState, useCallback } from 'react';
-import PropTypes from 'prop-types';
-import ReactRouterPropTypes from 'react-router-prop-types';
-import { UserType } from './Types';
-import moment from 'moment';
-
-import PM from './PM';
-import MessageInput from './MessageInput';
-import UserInfo from './UserInfo';
-
-import { getChat, pm } from '../api';
-
-import './Chat.css';
-
-export default function Chat(props) {
- const [chats, setChats] = useState([]);
- useEffect(() => {
- if (props.connection.addEventListener) {
- props.connection.addEventListener('msg', onMessage);
- }
- loadChat(props.match.params.user);
- console.log(props.connection);
- return () => {
- if (props.connection.removeEventListener) {
- props.connection.removeEventListener('msg', onMessage);
- }
- };
- }, [props.connection, onMessage, loadChat, props.match.params.user]);
-
- let loadChat = useCallback((uname) => {
- const { hash } = props.visitor;
- setChats([]);
- if (hash && uname) {
- getChat(uname)
- .then(response => {
- setChats(response.data);
- });
- }
- }, [props.visitor]);
-
- let onMessage = useCallback((json) => {
- const msg = JSON.parse(json.data);
- if (msg.user.uname === props.match.params.user) {
- setChats((oldChat) => {
- return [msg, ...oldChat];
- });
- }
- }, [props.match.params.user]);
-
- 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 (
-
-
- {uname ? (
-
-
- {
- chats.map((chat) =>
-
- )
- }
-
-
- Reply...
-
-
- ) : (
-
- )
- }
-
- );
-}
-
-Chat.propTypes = {
- visitor: UserType.isRequired,
- match: ReactRouterPropTypes.match.isRequired,
- connection: PropTypes.object.isRequired
-};
diff --git a/vnext/src/components/Contact.js b/vnext/src/components/Contact.js
deleted file mode 100644
index 24aabe15..00000000
--- a/vnext/src/components/Contact.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { UserType } from './Types';
-
-import Avatar from './Avatar';
-
-function Contact({ user, style, ...rest }) {
- return (
-
- {user.unreadCount && {user.unreadCount}}
- {user.lastMessageText}
-
- );
-}
-
-export default React.memo(Contact);
-
-Contact.propTypes = {
- user: UserType,
- style: PropTypes.object
-};
diff --git a/vnext/src/components/Contacts.js b/vnext/src/components/Contacts.js
deleted file mode 100644
index 3852b26f..00000000
--- a/vnext/src/components/Contacts.js
+++ /dev/null
@@ -1,49 +0,0 @@
-import React, { useEffect, useState } from 'react';
-
-import { getChats } from '../api';
-
-
-import Contact from './Contact.js';
-import { ChatSpinner } from './Spinner';
-
-export default function Contacts(props) {
- const [pms, setPms] = useState([]);
- useEffect(() => {
- getChats()
- .then(response => {
- setPms(response.data.pms);
- });
- }, []);
- return (
-
-
- {
- pms.length ? pms.map((chat) =>
-
- ) : <>>
- }
-
-
- );
-}
-
-const wrapperStyle = {
- display: 'flex',
- backgroundColor: '#fff'
-};
-
-const chatListStyle = {
- display: 'flex',
- flexDirection: 'column',
- width: '100%',
- padding: '12px'
-};
-
-const chatTitleStyle = {
- width: '100%',
- padding: '12px',
- textAlign: 'left',
- background: '#fff',
- color: '#222',
- borderBottom: '1px solid #eee'
-};
diff --git a/vnext/src/components/Feeds.js b/vnext/src/components/Feeds.js
deleted file mode 100644
index c7b857b7..00000000
--- a/vnext/src/components/Feeds.js
+++ /dev/null
@@ -1,171 +0,0 @@
-import React, { useState, useEffect } from 'react';
-import PropTypes from 'prop-types';
-import ReactRouterPropTypes from 'react-router-prop-types';
-import { Link } from 'react-router-dom';
-import qs from 'qs';
-import moment from 'moment';
-
-import Message from './Message';
-import Spinner from './Spinner';
-
-import UserInfo from './UserInfo';
-
-import { getMessages } from '../api';
-import { UserType } from './Types';
-
-export function Discover(props) {
- let search = qs.parse(props.location.search.substring(1));
- const query = {
- baseUrl: '/api/messages',
- search: search,
- pageParam: search.search ? 'page' : 'before_mid'
- };
- return ();
-}
-
-export function Discussions(props) {
- const query = {
- baseUrl: '/api/messages/discussions',
- pageParam: 'to'
- };
- return ();
-}
-
-export function Blog(props) {
- const { user } = props.match.params;
- let search = qs.parse(props.location.search.substring(1));
- search.uname = user;
- const query = {
- baseUrl: '/api/messages',
- search: search,
- pageParam: search.search ? 'page' : 'before_mid'
- };
- return (
- <>
-
-
-
-
- >
- );
-}
-
-export function Tag(props) {
- const { tag } = props.match.params;
- const query = {
- baseUrl: '/api/messages',
- search: {
- tag: tag
- },
- pageParam: 'before_mid'
- };
- return ();
-}
-
-export function Home(props) {
- const query = {
- baseUrl: '/api/home',
- pageParam: 'before_mid'
- };
- return ();
-}
-
-function Feed(props) {
- const [msgs, setMsgs] = useState([]);
- const [loading, setLoading] = useState(true);
- const [nextpage, setNextpage] = useState(null);
- const [error, setError] = useState(false);
-
- useEffect(() => {
- let loadMessages = (hash = '', filter = '') => {
- document.body.scrollTop = 0;
- document.documentElement.scrollTop = 0;
- setMsgs([]);
- const filterParams = qs.parse(filter);
- let params = Object.assign({}, filterParams || {}, props.query.search || {});
- let url = props.query.baseUrl;
- if (hash) {
- params.hash = hash;
- }
- if (!params.hash && props.authRequired) {
- props.history.push('/');
- }
- getMessages(url, params)
- .then(response => {
- const { data } = response;
- const { pageParam } = props.query;
- const lastMessage = data.slice(-1)[0] || {};
- const nextpage = getPageParam(pageParam, lastMessage, filterParams);
- setMsgs(data);
- setLoading(false);
- setNextpage(nextpage);
- }).catch(ex => {
- setError(true);
- });
- };
- loadMessages(props.visitor.hash, props.location.search.substring(1));
- }, [props]);
-
- let getPageParam = (pageParam, lastMessage, filterParams) => {
- const pageValue = pageParam === 'before_mid' ? lastMessage.mid : pageParam === 'page' ? (Number(filterParams.page) || 0) + 1 : moment.utc(lastMessage.updated).valueOf();
- let newFilter = { ...filterParams };
- newFilter[pageParam] = pageValue;
- return `?${qs.stringify(newFilter)}`;
- };
- const { tag } = qs.parse(location.search.substring(1) || {});
- const nodes = (
- <>
- {
- tag && (
-
-
- ← All posts with tag {tag}
-
-
- )
- }
- {
- msgs.map(msg =>
- )
- }
- {
- msgs.length >= 20 && (
-
- Next →
-
- )
- }
- >
- );
- return msgs.length > 0 ? (
- {nodes}
- ) : error ? error
: loading ?
: No more messages
;
-}
-
-Discover.propTypes = {
- location: ReactRouterPropTypes.location.isRequired,
- search: PropTypes.string
-};
-
-Blog.propTypes = {
- match: ReactRouterPropTypes.match.isRequired,
- location: ReactRouterPropTypes.location.isRequired,
- search: PropTypes.string
-};
-
-Tag.propTypes = {
- match: ReactRouterPropTypes.match.isRequired
-};
-
-Feed.propTypes = {
- authRequired: PropTypes.bool,
- visitor: UserType,
- history: ReactRouterPropTypes.history.isRequired,
- location: ReactRouterPropTypes.location.isRequired,
- msgs: PropTypes.array,
- query: PropTypes.shape({
- baseUrl: PropTypes.string.isRequired,
- search: PropTypes.object,
- pageParam: PropTypes.string.isRequired
- })
-};
diff --git a/vnext/src/components/Header.js b/vnext/src/components/Header.js
deleted file mode 100644
index 48f89360..00000000
--- a/vnext/src/components/Header.js
+++ /dev/null
@@ -1,69 +0,0 @@
-import React, { useEffect, useCallback, useRef } from 'react';
-import ReactDOM from 'react-dom';
-import PropTypes from 'prop-types';
-
-const elClassHidden = 'header--hidden';
-
-const header = document.getElementById('header');
-header.removeChild(document.getElementById('header_wrapper'));
-
-export default function Header({ children }) {
- let dHeight = useRef(0);
- let wHeight = useRef(0);
- let wScrollCurrent = useRef(0);
- let wScrollBefore = useRef(0);
- let wScrollDiff = useRef(0);
-
- useEffect(() => {
- window.addEventListener('scroll', () => (!window.requestAnimationFrame)
- ? throttle(250, updateHeader)
- : window.requestAnimationFrame(updateHeader), false);
- }, [updateHeader]);
- let throttle = (delay, fn) => {
- var last, deferTimer;
- return function () {
- var context = this, args = arguments, now = +new Date;
- if (last && now < last + delay) {
- clearTimeout(deferTimer);
- deferTimer = setTimeout(
- function () {
- last = now;
- fn.apply(context, args);
- },
- delay);
- } else {
- last = now;
- fn.apply(context, args);
- }
- };
- };
- let updateHeader = useCallback(() => {
- dHeight.current = document.body.offsetHeight;
- wHeight.current = window.innerHeight;
- wScrollCurrent.current = window.pageYOffset;
- wScrollDiff.current = wScrollBefore.current - wScrollCurrent.current;
-
- if (wScrollCurrent.current <= 0) {
- // scrolled to the very top; element sticks to the top
- header.classList.remove(elClassHidden);
- } else if (wScrollDiff > 0 && header.classList.contains(elClassHidden)) {
- // scrolled up; element slides in
- header.classList.remove(elClassHidden);
- } else if (wScrollDiff.current < 0) {
- // scrolled down
- if (wScrollCurrent.current + wHeight.current >= dHeight.current && header.classList.contains(elClassHidden)) {
- // scrolled to the very bottom; element slides in
- header.classList.remove(elClassHidden);
- } else {
- // scrolled down; element slides out
- header.classList.add(elClassHidden);
- }
- }
- wScrollBefore.current = wScrollCurrent.current;
- }, []);
- return ReactDOM.createPortal(children, header);
-}
-
-Header.propTypes = {
- children: PropTypes.node
-};
diff --git a/vnext/src/components/Icon.js b/vnext/src/components/Icon.js
deleted file mode 100644
index faf1a704..00000000
--- a/vnext/src/components/Icon.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-const Icon = React.memo(props => {
- var size = props.size ? ' icon--' + props.size : '';
- var className = props.className ? ' ' + props.className : '';
- var klass = 'icon' + (!props.noFill ? ' icon--' + props.name : '') + size + className;
-
- var name = '#' + props.name + '-icon';
- var useTag = '';
- var Icon = React.createElement('svg', { className: 'icon__cnt', dangerouslySetInnerHTML: { __html: useTag } });
- return React.createElement(
- 'div',
- { className: klass },
- wrapSpinner(Icon, klass)
- );
-});
-
-function wrapSpinner(Html, klass) {
- if (klass.indexOf('spinner') > -1) {
- return React.createElement(
- 'div',
- { className: 'icon__spinner' },
- Html
- );
- } else {
- return Html;
- }
-}
-
-export default Icon;
-
-Icon.propTypes = {
- size: PropTypes.string.isRequired,
- name: PropTypes.string.isRequired,
- className: PropTypes.string,
- noFill: PropTypes.bool
-};
diff --git a/vnext/src/components/Input.css b/vnext/src/components/Input.css
deleted file mode 100644
index dbe55eae..00000000
--- a/vnext/src/components/Input.css
+++ /dev/null
@@ -1,8 +0,0 @@
-.input {
- background: #FFF;
- border: 1px solid #ccc;
- outline: none !important;
- padding: 4px;
- -webkit-appearance: none;
- border-radius: 0;
-}
diff --git a/vnext/src/components/Input.js b/vnext/src/components/Input.js
deleted file mode 100644
index c74d595d..00000000
--- a/vnext/src/components/Input.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-import './Input.css';
-
-function Input({ name, value, ...rest }) {
- return (
-
- );
-}
-
-Input.propTypes = {
- name: PropTypes.string.isRequired,
- value: PropTypes.string.isRequired
-};
-
-export default React.memo(Input);
diff --git a/vnext/src/components/LoginButton.js b/vnext/src/components/LoginButton.js
deleted file mode 100644
index cd26252e..00000000
--- a/vnext/src/components/LoginButton.js
+++ /dev/null
@@ -1,90 +0,0 @@
-import React, { useState } from 'react';
-import PropTypes from 'prop-types';
-import Icon from './Icon';
-import Modal from './Modal';
-import Button from './Button';
-import Input from './Input';
-import { useFormState } from 'react-use-form-state';
-
-import { me, facebookLink, vkLink } from '../api';
-
-function LoginButton({ onAuth, title }) {
- const [open, setOpen] = useState(false);
- const [formState, { text, password }] = useFormState();
-
- let onToggle = (event) => {
- if (event) {
- event.preventDefault();
- }
- setOpen(!open);
- };
- let onSubmit = (event) => {
- event.preventDefault();
- me(formState.values.username, formState.values.password)
- .then(response => {
- onToggle();
- onAuth(response);
- }
- ).catch(ex => {
- console.log(ex);
- });
- };
- return (
- <>
-
-
- {title}
-
-
-
-
Please, introduce yourself:
-
-
Already registered?
-
-
-
- >
- );
-}
-
-LoginButton.propTypes = {
- title: PropTypes.string.isRequired,
- onAuth: PropTypes.func.isRequired
-};
-
-const socialButtonsStyle = {
- display: 'flex',
- justifyContent: 'space-evenly',
- padding: '4px'
-};
-
-const facebookButtonStyle = {
- color: '#fff',
- padding: '2px 14px',
- background: '#3b5998'
-};
-
-const vkButtonStyle = {
- color: '#fff',
- padding: '2px 14px',
- background: '#4c75a3'
-};
-
-export default LoginButton;
diff --git a/vnext/src/components/Message.css b/vnext/src/components/Message.css
deleted file mode 100644
index 18d3d0d5..00000000
--- a/vnext/src/components/Message.css
+++ /dev/null
@@ -1,210 +0,0 @@
-.msg-cont .ir {
- padding: 12px;
-}
-.msg-cont .ir img {
- max-width: 100%;
- height: auto;
-}
-.msg-cont > .h,
-.msg-cont .msg-header {
- padding: 12px;
-}
-.msg-cont > .l {
- border-top: 1px solid #eee;
- display: flex;
- align-items: center;
- justify-content: space-around;
- background: #fdfdfe;
-}
-.msg-cont > .l a {
- color: #88958d;
- margin-right: 15px;
- font-size: small;
-}
-.msg-tags {
- color: #88958d;
- margin-top: 12px;
- min-height: 1px;
-}
-.badge,
-.msg-tags > a {
- color: #88958d;
- display: inline-block;
- font-size: small;
-}
-.msgthread {
- margin-bottom: 0;
-}
-.msg-cont {
- background: #FFF;
- box-shadow: 0 0 3px rgba(0, 0, 0, 0.16);
- line-height: 140%;
- margin-bottom: 12px;
-}
-.reply-new .msg-cont {
- border-right: 5px solid #0C0;
-}
-.msg-ts {
- font-size: small;
- vertical-align: top;
-}
-.msg-ts,
-.msg-ts > a {
- color: #88958d;
-}
-.msg-txt {
- margin: 0 0 12px;
- padding: 12px;
- word-wrap: break-word;
- overflow-wrap: break-word;
-}
-q:before,
-q:after {
- content: "";
-}
-q,
-blockquote {
- border-left: 3px solid #CCC;
- color: #666;
- display: block;
- margin: 10px 0 10px 10px;
- padding-left: 10px;
- word-break: break-word;
-}
-.msg-media {
- text-align: center;
-}
-.msg-links {
- color: #88958d;
- font-size: small;
- margin: 5px 0 0 0;
- padding: 12px;
-}
-.msg-comments {
- color: #88958d;
- font-size: small;
- margin-top: 10px;
- overflow: hidden;
- text-indent: 10px;
-}
-.ta-wrapper {
- border: 1px solid #DDD;
- display: flex;
- flex-grow: 1;
-}
-.msg-comment {
- display: flex;
- margin-top: 10px;
-}
-.msg-comment-hidden {
- display: none;
-}
-.msg-comment textarea {
- border: 0;
- flex-grow: 1;
- outline: none !important;
- padding: 4px;
- resize: vertical;
- vertical-align: top;
-}
-.attach-photo {
- cursor: pointer;
-}
-.attach-photo-active {
- color: green;
-}
-.msg-comment input {
- align-self: flex-start;
- background: #EEE;
- border: 1px solid #CCC;
- color: #999;
- margin: 0 0 0 6px;
- position: sticky;
- top: 70px;
- vertical-align: top;
- width: 50px;
-}
-.msg-recomms {
- color: #88958d;
- background: #fdfdfe;
- font-size: small;
- margin-bottom: 10px;
- padding: 6px;
- border-bottom: 1px solid #eee;
- overflow: hidden;
- text-indent: 10px;
-}
-.msg-summary,
-.msg-summary a {
- color: #88958d;
- font-size: small;
- padding: 12px;
- text-align: right;
-}
-#replies .msg-txt,
-#private-messages .msg-txt {
- margin: 0;
-}
-.title2 {
- background: #fff;
- margin: 20px 0;
- padding: 10px 20px;
-}
-.title2-right {
- float: right;
- line-height: 24px;
-}
-#content .title2 h2 {
- font-size: x-large;
- margin: 0;
-}
-
-.embedContainer {
- display: flex;
- flex-wrap: wrap;
- align-items: center;
- justify-content: center;
- padding: 12px;
- margin: 30px -3px 15px -3px;
-}
-.embedContainer > * {
- box-sizing: border-box;
- flex-grow: 1;
- margin: 3px;
- min-width: 49%;
-}
-.embedContainer > .compact {
- flex-grow: 0;
-}
-.embedContainer .picture img {
- display: block;
-}
-.embedContainer img,
-.embedContainer video {
- max-width: 100%;
- max-height: 80vh;
-}
-.embedContainer > .audio,
-.embedContainer > .youtube {
- min-width: 90%;
-}
-.embedContainer audio {
- width: 100%;
-}
-.embedContainer iframe {
- overflow: hidden;
- resize: vertical;
- display: block;
-}
-.msg-cont .nsfw .embedContainer img,
-.msg-cont .nsfw .embedContainer video,
-.msg-cont .nsfw .embedContainer iframe,
-.msg-cont .nsfw .ir img {
- opacity: 0.1;
-}
-.msg-cont .nsfw .embedContainer img:hover,
-.msg-cont .nsfw .embedContainer video:hover,
-.msg-cont .nsfw .embedContainer iframe:hover,
-.msg-cont .nsfw .ir img:hover {
- opacity: 1;
-}
diff --git a/vnext/src/components/Message.js b/vnext/src/components/Message.js
deleted file mode 100644
index eb008bfe..00000000
--- a/vnext/src/components/Message.js
+++ /dev/null
@@ -1,142 +0,0 @@
-import React, { useEffect, useRef } 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 { UserLink } from './UserInfo';
-
-import { format, embedUrls } from '../utils/embed';
-
-import './Message.css';
-
-export default function Message({ data, visitor, children, ...rest }) {
- const isCode = (data.tags || []).indexOf('code') >= 0;
- const likesSummary = data.likes ? `${data.likes}` : 'Recommend';
- const commentsSummary = data.replies ? `${data.replies}` : 'Comment';
- const embedRef = useRef();
- const msgRef = useRef();
- useEffect(() => {
- if (msgRef.current) {
- embedUrls(msgRef.current.querySelectorAll('a'), embedRef.current);
- if (!embedRef.current.hasChildNodes()) {
- embedRef.current.style.display = 'none';
- }
- }
- }, []);
- return (
-
-
-
- {
- data.body &&
-
-
-
- }
- {
- data.photo &&
-
- }
-
-
- {children}
-
- );
-}
-
-function MessageContainer({ isCode, data }) {
- return isCode ? () : ();
-}
-
-function Tags({ data, user, ...rest }) {
- return data.length > 0 && (
-
- {
- data.map(tag => {
- return ({tag});
- }).reduce((prev, curr) => [prev, ', ', curr])
- }
-
- );
-}
-
-const TagsList = React.memo(Tags);
-
-function Recommends({ forMessage, ...rest }) {
- const { likes, recommendations } = forMessage;
- return recommendations && recommendations.length > 0 && (
- {'♡ by '}
- {
- recommendations.map(it => (
-
- )).reduce((prev, curr) => [prev, ', ', curr])
- }
- {
- likes > recommendations.length && ( and {likes - recommendations.length} others)
- }
-
- ) || null;
-}
-
-const Recommendations = React.memo(Recommends);
-
-Message.propTypes = {
- data: MessageType,
- visitor: UserType.isRequired,
- children: PropTypes.node
-};
-
-MessageContainer.propTypes = {
- isCode: PropTypes.bool.isRequired,
- data: PropTypes.object.isRequired
-};
-
-Tags.propTypes = {
- user: UserType.isRequired,
- data: PropTypes.array
-};
-
diff --git a/vnext/src/components/MessageInput.js b/vnext/src/components/MessageInput.js
deleted file mode 100644
index e4988d59..00000000
--- a/vnext/src/components/MessageInput.js
+++ /dev/null
@@ -1,107 +0,0 @@
-import React, { useState, useEffect, useRef } from 'react';
-import PropTypes from 'prop-types';
-
-import { useFormState } from 'react-use-form-state';
-
-import { MessageType } from './Types';
-
-import Icon from './Icon';
-import Button from './Button';
-
-import UploadButton from './UploadButton';
-
-export default function MessageInput({ text, data, rows, children, onSend }) {
- let textareaRef = useRef();
- let fileinput = useRef();
-
- let updateFocus = () => {
- const isDesktop = window.matchMedia('(min-width: 62.5rem)');
- if (isDesktop.matches) {
- textareaRef.current.focus();
- }
- };
- useEffect(() => {
- textareaRef.current.value = text || '';
- updateFocus();
- }, [text]);
-
- let handleCtrlEnter = (event) => {
- if (event.ctrlKey && (event.charCode == 10 || event.charCode == 13)) {
- onSubmit({});
- }
- };
- let textChanged = (event) => {
- const el = textareaRef.current;
- const offset = el.offsetHeight - el.clientHeight;
- const height = el.scrollHeight + offset;
- el.style.height = `${height + offset}px`;
- };
- const [attach, setAttach] = useState('');
- const [formState, { textarea }] = useFormState();
- let uploadValueChanged = (attach) => {
- setAttach(attach);
- };
- let onSubmit = (event) => {
- if (event.preventDefault) {
- event.preventDefault();
- }
- const input = fileinput.current;
- onSend({
- mid: data.mid,
- rid: data.rid || 0,
- body: formState.values.body,
- attach: attach ? input.files[0] : '',
- to: data.to || {}
- });
- setAttach('');
- formState.clearField('body');
- textareaRef.current.style.height = '';
- updateFocus();
- };
- return (
-
- );
-}
-
-const commentStyle = {
- display: 'flex',
- flexDirection: 'column',
- borderTop: '1px #eee solid',
- width: '100%',
- marginTop: '10px'
-};
-
-const inputBarStyle = {
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'space-between',
- padding: '3px'
-};
-
-const textInputStyle = {
- overflow: 'hidden',
- resize: 'none',
- display: 'block',
- boxSizing: 'border-box',
- border: 0,
- outline: 'none',
- padding: '4px'
-};
-
-MessageInput.propTypes = {
- children: PropTypes.node,
- data: MessageType.isRequired,
- onSend: PropTypes.func.isRequired,
- rows: PropTypes.string,
- text: PropTypes.string
-};
diff --git a/vnext/src/components/Modal.css b/vnext/src/components/Modal.css
deleted file mode 100644
index 931b9d81..00000000
--- a/vnext/src/components/Modal.css
+++ /dev/null
@@ -1,95 +0,0 @@
-#dialogt {
- height: 100%;
- left: 0;
- position: fixed;
- top: 0;
- width: 100%;
- z-index: 10;
- display: flex;
- align-items: center;
- justify-content: center;
- background-color: rgba(0, 0, 0, 0.3);
-}
-#dialogw {
- z-index: 11;
- max-width: 96%;
- max-height: calc(100% - 100px);
- background-color: #fff;
-}
-#dialogw a {
- display: block;
-}
-#dialogw img {
- max-height: 100%;
- max-height: 90vh;
- max-width: 100%;
-}
-#dialog_header {
- width: 100%;
- height: 44px;
- display: flex;
- flex-direction: row-reverse;
- align-items: center;
-}
-.header_image {
- background: rgba(0, 0, 0, 0.28);
-}
-#dialogc {
- cursor: pointer;
- color: #ccc;
- padding-right: 6px;
-}
-.dialoglogin {
- background: #fff;
- padding: 25px;
-}
-.dialog-opened {
- overflow: hidden;
-}
-#signemail,
-#signfb,
-#signvk {
- display: block;
- line-height: 32px;
- margin: 10px 0;
- text-decoration: none;
- width: 100%;
-}
-#signvk {
- margin-bottom: 30px;
-}
-.dialoglogin form {
- margin-top: 7px;
-}
-.signinput,
-.signsubmit {
- border: 1px solid #CCC;
- margin: 3px 0;
- padding: 3px;
-}
-.signsubmit {
- width: 70px;
-}
-.dialogshare {
- background: #fff;
- min-width: 300px;
- overflow: auto;
- padding: 20px;
-}
-.dialogl {
- background: #fff;
- border: 1px solid #DDD;
- margin: 3px 0 20px;
- padding: 5px;
-}
-.dialogshare li {
- float: left;
- margin: 5px 10px 0 0;
-}
-.dialogshare a {
- display: block;
-}
-.dialogtxt {
- background: #fff;
- padding: 20px;
-}
diff --git a/vnext/src/components/Modal.js b/vnext/src/components/Modal.js
deleted file mode 100644
index 799a6f35..00000000
--- a/vnext/src/components/Modal.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-import Icon from './Icon';
-
-import './Modal.css';
-
-function Modal(props) {
- return props.show ? (
-
-
-
- {props.children}
-
-
- ) : (null);
-}
-
-export default React.memo(Modal);
-
-Modal.propTypes = {
- onClose: PropTypes.func.isRequired,
- show: PropTypes.bool,
- children: PropTypes.node
-};
diff --git a/vnext/src/components/NavigationIcon.css b/vnext/src/components/NavigationIcon.css
deleted file mode 100644
index caff6195..00000000
--- a/vnext/src/components/NavigationIcon.css
+++ /dev/null
@@ -1,4 +0,0 @@
-#navicon {
- padding: 12px;
- color: #88958d;
-}
diff --git a/vnext/src/components/NavigationIcon.js b/vnext/src/components/NavigationIcon.js
deleted file mode 100644
index 0a22ac57..00000000
--- a/vnext/src/components/NavigationIcon.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-import Icon from './Icon';
-
-import './NavigationIcon.css';
-
-function NavigationIcon(props) {
- return (
-
-
-
- );
-}
-
-export default React.memo(NavigationIcon);
-
-NavigationIcon.propTypes = {
- onToggle: PropTypes.func.isRequired
-};
-
diff --git a/vnext/src/components/PM.js b/vnext/src/components/PM.js
deleted file mode 100644
index a1e70ad5..00000000
--- a/vnext/src/components/PM.js
+++ /dev/null
@@ -1,51 +0,0 @@
-import React from 'react';
-
-import { UserType, MessageType } from './Types';
-
-import Avatar from './Avatar';
-import { format } from '../utils/embed';
-
-function PM(props) {
- const { chat } = props;
- return (
-
-
-
- );
-}
-
-export default React.memo(PM);
-
-function bubbleStyle(me, msg) {
- const isMe = me.uid === msg.user.uid;
- const color = isMe ? '#fff' : '#222';
- const background = isMe ? '#ec4b98' : '#eee';
- return {
- background: background,
- color: color,
- padding: '12px'
- };
-}
-
-function chatItemStyle(me, msg) {
- const isMe = me.uid === msg.user.uid;
- const alignment = isMe ? 'flex-end' : 'flex-start';
- return {
- padding: '3px 6px',
- listStyle: 'none',
- margin: '10px 0',
- display: 'flex',
- flexDirection: 'column',
- alignItems: alignment
- };
-}
-
-PM.propTypes = {
- chat: MessageType.isRequired,
- visitor: UserType.isRequired
-};
diff --git a/vnext/src/components/Post.js b/vnext/src/components/Post.js
deleted file mode 100644
index 3dc23613..00000000
--- a/vnext/src/components/Post.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import React, { memo } from 'react';
-
-import ReactRouterPropTypes from 'react-router-prop-types';
-import { UserType } from './Types';
-
-import qs from 'qs';
-
-import MessageInput from './MessageInput';
-
-import { post } from '../api';
-
-function PostComponent(props) {
- let params = qs.parse(window.location.search.substring(1));
- let postMessage = (template) => {
- const { attach, body } = template;
- post(body, attach)
- .then(response => {
- if (response.status === 200) {
- const msg = response.data.newMessage;
- this.props.history.push(`/${this.props.visitor.uname}/${msg.mid}`);
- }
- }).catch(console.log);
- };
- return (
-
-
- *weather It is very cold today!
-
-
- );
-}
-
-export default memo(PostComponent);
-
-PostComponent.propTypes = {
- history: ReactRouterPropTypes.history.isRequired,
- visitor: UserType
-};
diff --git a/vnext/src/components/SearchBox.js b/vnext/src/components/SearchBox.js
deleted file mode 100644
index a79100cd..00000000
--- a/vnext/src/components/SearchBox.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import ReactRouterPropTypes from 'react-router-prop-types';
-import { withRouter } from 'react-router-dom';
-import { useFormState } from 'react-use-form-state';
-
-function SearchBox({ onSearch, history, pathname }) {
- let onSubmit = (event) => {
- event.preventDefault();
- onSearch(history, pathname, formState.values.search);
- };
- const [formState, { text }] = useFormState();
- return (
-
- );
-}
-
-SearchBox.propTypes = {
- pathname: PropTypes.string.isRequired,
- onSearch: PropTypes.func.isRequired,
- history: ReactRouterPropTypes.history.isRequired
-};
-export default withRouter(SearchBox);
diff --git a/vnext/src/components/Settings.js b/vnext/src/components/Settings.js
deleted file mode 100644
index cf6926f8..00000000
--- a/vnext/src/components/Settings.js
+++ /dev/null
@@ -1,268 +0,0 @@
-import React, { useState, useEffect, useRef } from 'react';
-import PropTypes from 'prop-types';
-import ReactRouterPropTypes from 'react-router-prop-types';
-
-import { me, updateAvatar } from '../api';
-
-import { UserType } from './Types';
-
-import Button from './Button';
-import Icon from './Icon';
-import UploadButton from './UploadButton';
-import Avatar from './Avatar';
-
-function ChangeAvatarForm({ visitor }) {
- const [avatar, setAvatar] = useState('');
- const [preview, setPreview] = useState();
- const avatarInput = useRef();
- let avatarChanged = (newAvatar) => {
- setAvatar(newAvatar);
- setPreview('');
- if (newAvatar) {
- let reader = new FileReader();
- reader.onloadend = (preview) => {
- setPreview(preview.target.result);
- };
- reader.readAsDataURL(avatarInput.current.files[0]);
- }
- };
- let previewUser = { ...visitor, uname: '' };
- if (preview) {
- previewUser = { ...visitor, avatar: preview, uname: '' };
- }
- let onSubmitAvatar = (event) => {
- if (event.preventDefault) {
- event.preventDefault();
- }
- updateAvatar(avatarInput.current.files[0]).then(() => {
- avatarChanged('');
- me().then(visitor => {
- this.props.onChange(visitor);
- });
- });
- };
- return (
-
- );
-}
-
-ChangeAvatarForm.propTypes = {
- visitor: UserType.isRequired
-};
-
-export default class Settings extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- settings: {
- },
- me: {}
- };
- }
- componentDidMount() {
- me().then(visitor => {
- this.setState({
- me: visitor
- });
- });
- }
-
- passwordChanged = (event) => {
- let newState = update(this.state, {
- settings: { password: { $set: event.target.value } }
- });
- this.setState(newState);
- }
- onSubmitPassword = (event) => {
- if (event.preventDefault) {
- event.preventDefault();
- }
- console.log('password update');
- }
- emailChanged = (event) => {
- let newState = update(this.state, {
- me: { activeEmail: { $set: event.target.value } }
- });
- this.setState(newState);
- console.log('email update');
- }
- disableTelegram = () => {
- console.log('telegram disable');
- }
- disableFacebook = (event) => {
- if (event.preventDefault) {
- event.preventDefault();
- }
- console.log('facebook disable');
- }
- enableFacebook = (event) => {
- if (event.preventDefault) {
- event.preventDefault();
- }
- console.log('facebook enable');
- }
- disableTwitter = () => {
- console.log('twitter disable');
- }
-
- render() {
- const { me, settings } = this.state;
- return (
-
-
-
-
- {me.jids && (
-
- )}
-
-
-
-
-
- );
- }
-}
-
-Settings.propTypes = {
- visitor: UserType.isRequired,
- onChange: PropTypes.func.isRequired
-};
-
diff --git a/vnext/src/components/Spinner.js b/vnext/src/components/Spinner.js
deleted file mode 100644
index e866369f..00000000
--- a/vnext/src/components/Spinner.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import React from 'react';
-import ContentLoader from 'react-content-loader';
-
-function Spinner(props) {
- return (
-
- );
-}
-
-export default React.memo(Spinner);
-
-export function ChatSpinner(props) {
- return (
-
-
-
-
-
- );
-}
diff --git a/vnext/src/components/Thread.js b/vnext/src/components/Thread.js
deleted file mode 100644
index e7ccb032..00000000
--- a/vnext/src/components/Thread.js
+++ /dev/null
@@ -1,181 +0,0 @@
-import React, { useEffect, useState, useRef, useCallback } from 'react';
-import PropTypes from 'prop-types';
-
-import ReactRouterPropTypes from 'react-router-prop-types';
-import { UserType, MessageType } from './Types';
-
-import Message from './Message';
-import MessageInput from './MessageInput';
-import Spinner from './Spinner';
-import Avatar from './Avatar';
-import Button from './Button';
-
-import { format, embedUrls } from '../utils/embed';
-
-import { getMessages, comment, markReadTracker } from '../api';
-
-function Comment({ msg, visitor, active, setActive, postComment }) {
- const embedRef = useRef();
- const msgRef = useRef();
- useEffect(() => {
- if (msgRef.current) {
- embedUrls(msgRef.current.querySelectorAll('a'), embedRef.current);
- if (!embedRef.current.hasChildNodes()) {
- embedRef.current.style.display = 'none';
- }
- }
- }, []);
- return (
-
-
- {
- msg.html ?
- :
-
- }
- {
- msg.photo &&
-
- }
-
-
- {
- visitor.uid > 0 ? (
- <>
- {active === msg.rid || setActive(msg.rid)}>Reply}
- {active === msg.rid && Write a comment...}
- >
- ) : (
- <>
- · {active === msg.rid || }
- >
- )
- }
-
-
- );
-}
-
-Comment.propTypes = {
- msg: MessageType.isRequired,
- visitor: UserType.isRequired,
- active: PropTypes.number.isRequired,
- setActive: PropTypes.func.isRequired,
- postComment: PropTypes.func.isRequired
-};
-
-export default function Thread(props) {
- const [message, setMessage] = useState((props.location.state || {}).msg || {});
- const [replies, setReplies] = useState([]);
- const [loading, setLoading] = useState(false);
- const [active, setActive] = useState(0);
- useEffect(() => {
- setActive(0);
- loadReplies();
- }, [loadReplies]);
- useEffect(() => {
- if (props.connection.addEventListener && message.mid) {
- props.connection.addEventListener('msg', onReply);
- }
- return () => {
- if (props.connection.removeEventListener && message.mid) {
- props.connection.removeEventListener('msg', onReply);
- }
- };
- }, [props.connection, message.mid, onReply]);
-
- let loadReplies = useCallback(() => {
- document.body.scrollTop = 0;
- document.documentElement.scrollTop = 0;
-
- setReplies([]);
- setLoading(true);
- const { mid } = props.match.params;
- let params = {
- mid: mid
- };
- if (props.visitor && props.visitor.hash) {
- params.hash = props.visitor.hash;
- }
- getMessages('/api/thread', params)
- .then(response => {
- setMessage(response.data.shift());
- setReplies(response.data);
- setLoading(false);
- setActive(0);
- }
- ).catch(ex => {
- console.log(ex);
- });
- }, [props.visitor, props.match.params]);
- let onReply = useCallback((json) => {
- const msg = JSON.parse(json.data);
- if (msg.mid == message.mid) {
- setReplies(oldReplies => {
- return [...oldReplies, msg];
- });
- }
- }, [message]);
- 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 (
- <>
- {
- message.mid ? (
-
- {active === (message.rid || 0) && Write a comment...}
-
- ) : (
-
- )
- }
-
- {
- !loading ? replies.map((msg) => (
- -
-
-
- )) : (
- <>
- {Array(loaders).fill().map((it, i) => )}
- >
- )
- }
-
- >
- );
-}
-
-const linkStyle = {
- cursor: 'pointer'
-};
-
-Thread.propTypes = {
- location: ReactRouterPropTypes.location,
- history: ReactRouterPropTypes.history,
- match: ReactRouterPropTypes.match,
- visitor: UserType.isRequired,
- connection: PropTypes.object.isRequired
-};
diff --git a/vnext/src/components/Types.js b/vnext/src/components/Types.js
deleted file mode 100644
index 9bf7b513..00000000
--- a/vnext/src/components/Types.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import PropTypes from 'prop-types';
-
-export const UserType = PropTypes.shape({
- uid: PropTypes.number.isRequired,
- uname: PropTypes.string,
- avatar: PropTypes.string,
- uri: PropTypes.string
-});
-
-export const MessageType = PropTypes.shape({
- mid: PropTypes.number,
- user: UserType,
- timestamp: PropTypes.string.isRequired,
- body: PropTypes.string
-});
diff --git a/vnext/src/components/UploadButton.js b/vnext/src/components/UploadButton.js
deleted file mode 100644
index 73cbbfcf..00000000
--- a/vnext/src/components/UploadButton.js
+++ /dev/null
@@ -1,42 +0,0 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-
-import Icon from './Icon';
-
-export default function UploadButton(props) {
- let openfile = () => {
- const input = props.inputRef.current;
- if (props.value) {
- props.onChange('');
- } else {
- input.click();
- }
- };
- let attachmentChanged = (event) => {
- props.onChange(event.target.value);
- };
- return (
-
-
- e.stopPropagation()}
- style={{ display: 'none' }} ref={props.inputRef} value={props.value}
- onChange={attachmentChanged} />
-
- );
-}
-
-UploadButton.propTypes = {
- value: PropTypes.string.isRequired,
- onChange: PropTypes.func.isRequired,
- inputRef: PropTypes.shape({ current: PropTypes.instanceOf(Element) })
-};
-
-const inactiveStyle = {
- cursor: 'pointer',
- color: '#888'
-};
-const activeStyle = {
- cursor: 'pointer',
- color: 'green'
-};
diff --git a/vnext/src/components/UserInfo.css b/vnext/src/components/UserInfo.css
deleted file mode 100644
index 92cfdb6c..00000000
--- a/vnext/src/components/UserInfo.css
+++ /dev/null
@@ -1,11 +0,0 @@
-.userinfo {
- padding: 40px;
- background-color: #fdfdfe;
- margin: 12px;
-}
-.info-avatar img {
- max-height: 24px;
- max-width: 24px;
- padding: 6px;
- vertical-align: middle;
-}
diff --git a/vnext/src/components/UserInfo.js b/vnext/src/components/UserInfo.js
deleted file mode 100644
index 7d84488e..00000000
--- a/vnext/src/components/UserInfo.js
+++ /dev/null
@@ -1,117 +0,0 @@
-import React, { useState, useEffect } from 'react';
-import PropTypes from 'prop-types';
-import { Link } from 'react-router-dom';
-
-import { UserType } from './Types';
-
-import { info, fetchUserUri } from '../api';
-
-import Avatar from './Avatar';
-import Icon from './Icon';
-import SearchBox from './SearchBox';
-
-import './UserInfo.css';
-
-let isMounted;
-
-export default function UserInfo(props) {
- const [user, setUser] = useState({ uname: props.user, uid: 0 });
- const { onUpdate } = props;
- useEffect(() => {
- isMounted = true;
- if (!user.avatar) {
- info(user.uname).then(response => {
- if (isMounted) {
- setUser(response.data);
- onUpdate && onUpdate(response.data);
- }
- });
- }
- return () => {
- isMounted = false;
- };
- }, [onUpdate, user, user.avatar]);
- return (
- <>
-
-
- Was online recently
-
-
-
-
- {
- user.uid > 0 &&
- <>
-
-
- PM
-
-
-
- Recommendations
-
-
-
- Photos
-
- >
- }
-
- {props.children}
- >
- );
-}
-
-function Summary({ user }) {
- const readUrl = `/${user.uname}/friends`;
- const readersUrl = `/${user.uname}/readers`;
- const blUrl = `/${user.uname}/bl`;
- let read = user.read && I read: {user.read.length};
- let readers = user.readers && My readers: {user.readers.length};
- let mybl = user.statsMyBL && My blacklist: {user.statsMyBL};
- let presentItems = [read, readers, mybl].filter(Boolean);
- return (
-
- {presentItems.length > 0 && presentItems.reduce((prev, curr) => [prev, ' ', curr])}
-
- );
-}
-
-Summary.propTypes = {
- user: UserType.isRequired
-};
-
-const UserSummary = React.memo(Summary);
-
-export function UserLink(props) {
- const [user, setUser] = useState(props.user);
- useEffect(() => {
- isMounted = true;
- if (!user.uid && user.uri) {
- fetchUserUri(user.uri).then(response => {
- if (isMounted) {
- setUser({ ...response.data, uid: 66666666 });
- }
- });
- }
- return () => {
- isMounted = false;
- };
- }, [user.uid, user.uri]);
- return (
- user.uid ?
- {user.uname}
- : {user.uname}
- );
-}
-
-UserInfo.propTypes = {
- user: PropTypes.string.isRequired,
- onUpdate: PropTypes.func,
- children: PropTypes.node
-};
-
-UserLink.propTypes = {
- user: UserType.isRequired
-};
diff --git a/vnext/src/components/Users.js b/vnext/src/components/Users.js
deleted file mode 100644
index a10bba7f..00000000
--- a/vnext/src/components/Users.js
+++ /dev/null
@@ -1,44 +0,0 @@
-import React, { useState } from 'react';
-import PropTypes from 'prop-types';
-import ReactRouterPropTypes from 'react-router-prop-types';
-
-import UserInfo from './UserInfo';
-import Avatar from './Avatar';
-
-export function Friends({ match }) {
- return ;
-}
-
-export function Readers({ match }) {
- return ;
-}
-
-function Users(props) {
- const [user, setUser] = useState({ uid: 0, uname: props.user });
- return (
-
-
- {
- user[props.prop] &&
- user[props.prop].map(user =>
-
- )
- }
-
-
- );
-}
-
-
-Friends.propTypes = {
- match: ReactRouterPropTypes.match.isRequired
-};
-
-Readers.propTypes = {
- match: ReactRouterPropTypes.match.isRequired
-};
-
-Users.propTypes = {
- user: PropTypes.string.isRequired,
- prop: PropTypes.string.isRequired
-};
diff --git a/vnext/src/components/__tests__/Avatar.test.js b/vnext/src/components/__tests__/Avatar.test.js
deleted file mode 100644
index e7221871..00000000
--- a/vnext/src/components/__tests__/Avatar.test.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import React from 'react';
-import { MemoryRouter } from 'react-router-dom';
-
-import Avatar from '../Avatar';
-import renderer from 'react-test-renderer';
-
-test('Avatar renders correctly', () => {
- const component = renderer.create(
-
-
-
- );
- let tree = component.toJSON();
- expect(tree).toMatchSnapshot();
-});
diff --git a/vnext/src/components/__tests__/LoginButton.test.js b/vnext/src/components/__tests__/LoginButton.test.js
deleted file mode 100644
index da80abb0..00000000
--- a/vnext/src/components/__tests__/LoginButton.test.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import React from 'react';
-
-import LoginButton from '../LoginButton';
-import { create, act } from 'react-test-renderer';
-
-test('Login button and form are renders correctly', () => {
- var button = null;
- act(() => {
- button = create(
- { }} />
- );
- });
- let link = button.toJSON();
- expect(link).toMatchSnapshot();
-
- act(() => {
- button.root.findByType('a').props.onClick();
- });
- let modal = button.toJSON();
- expect(modal).toMatchSnapshot();
-});
diff --git a/vnext/src/components/__tests__/MessageInput-test.js b/vnext/src/components/__tests__/MessageInput-test.js
deleted file mode 100644
index 7ac69ed0..00000000
--- a/vnext/src/components/__tests__/MessageInput-test.js
+++ /dev/null
@@ -1,95 +0,0 @@
-import React from 'react';
-import { create, act } from 'react-test-renderer';
-
-import MessageInput from '../MessageInput';
-
-const testMessage = {
- mid: 1,
- rid: 0,
- body: 'test message',
- timestamp: new Date().toISOString(),
- attach: '',
- to: {}
-};
-
-window.matchMedia = window.matchMedia || function () {
- return {
- matches: true,
- addListener: function () { },
- removeListener: function () { }
- };
-};
-
-it('Gives immediate focus on to textarea on load', () => {
- let focused = false;
- act(() => {
- create( { }} />, {
- createNodeMock: (element) => {
- if (element.type === 'textarea') {
- // mock a focus function
- return {
- focus: () => {
- focused = true;
- },
- style: {}
- };
- }
- return null;
- }
- });
- });
- expect(focused).toEqual(true, 'textarea was not focused');
-});
-
-
-it('Submits on ctrl-enter', () => {
- const onSend = jest.fn();
- var messageInput = null;
- act(() => {
- messageInput = create(, {
- createNodeMock: (element) => {
- if (element.type === 'textarea') {
- return {
- focus: () => { },
- style: {}
- };
- }
- return null;
- }
- });
- });
- let textarea = messageInput.root.findByType('textarea');
- act(() => {
-
- textarea.props.onKeyPress({
- charCode: 13,
- which: 13,
- keyCode: 13,
- ctrlKey: false
- });
- });
- expect(onSend).toHaveBeenCalledTimes(0);
- act(() => {
- textarea.props.onKeyPress({
- charCode: 13,
- which: 13,
- keyCode: 13,
- ctrlKey: true
- });
- });
- expect(onSend).toHaveBeenCalledTimes(1);
- expect(textarea.props.value).toEqual('');
- act(() => {
- textarea.props.onChange({
- target: {
- value: ' ',
- validity: {}
- }
- });
- });
- expect(textarea.props.value).toEqual(' ');
- act(() => {
- messageInput.root.findByType('form').props.onSubmit({ event: {} });
- });
- expect(textarea.props.value).toEqual('', 'Value should be cleared after submit');
-});
diff --git a/vnext/src/components/__tests__/UserLink.test.js b/vnext/src/components/__tests__/UserLink.test.js
deleted file mode 100644
index a75344b0..00000000
--- a/vnext/src/components/__tests__/UserLink.test.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import React from 'react';
-import { MemoryRouter, Switch, Route } from 'react-router-dom';
-
-import { UserLink } from '../UserInfo';
-import renderer from 'react-test-renderer';
-
-test('UserLink renders correctly', async () => {
- const component = renderer.create(
-
- <>
-
-
-
- >
-
- );
- await Promise.resolve();
- let tree = component.toJSON();
- expect(tree).toMatchSnapshot();
-});
diff --git a/vnext/src/components/__tests__/__snapshots__/Avatar.test.js.snap b/vnext/src/components/__tests__/__snapshots__/Avatar.test.js.snap
deleted file mode 100644
index 47614f5a..00000000
--- a/vnext/src/components/__tests__/__snapshots__/Avatar.test.js.snap
+++ /dev/null
@@ -1,41 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Avatar renders correctly 1`] = `
-
-`;
diff --git a/vnext/src/components/__tests__/__snapshots__/LoginButton.test.js.snap b/vnext/src/components/__tests__/__snapshots__/LoginButton.test.js.snap
deleted file mode 100644
index cd08b1b4..00000000
--- a/vnext/src/components/__tests__/__snapshots__/LoginButton.test.js.snap
+++ /dev/null
@@ -1,178 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Login button and form are renders correctly 1`] = `
-
-
- ",
- }
- }
- />
-
-
- Log in
-
-
-`;
-
-exports[`Login button and form are renders correctly 2`] = `
-Array [
-
-
- ",
- }
- }
- />
-
-
- Log in
-
- ,
-
-
-
-
-
- Please, introduce yourself:
-
-
-
- Already registered?
-
-
-
-
-
,
-]
-`;
diff --git a/vnext/src/components/__tests__/__snapshots__/UserLink.test.js.snap b/vnext/src/components/__tests__/__snapshots__/UserLink.test.js.snap
deleted file mode 100644
index 15e25367..00000000
--- a/vnext/src/components/__tests__/__snapshots__/UserLink.test.js.snap
+++ /dev/null
@@ -1,33 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`UserLink renders correctly 1`] = `
-Array [
-
-
- ugnich
- ,
-
-
- ugnich
- ,
-
-
-
- ,
-]
-`;
--
cgit v1.2.3