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/App.js | 24 +- 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 --- vnext/src/index.html | 63 +++++ vnext/src/ui/Avatar.css | 27 +++ vnext/src/ui/Avatar.js | 44 ++++ vnext/src/ui/Button.css | 13 + vnext/src/ui/Button.js | 11 + vnext/src/ui/Chat.css | 9 + vnext/src/ui/Chat.js | 85 +++++++ vnext/src/ui/Contact.js | 21 ++ vnext/src/ui/Contacts.js | 49 ++++ vnext/src/ui/Feeds.js | 171 +++++++++++++ vnext/src/ui/Header.js | 69 ++++++ vnext/src/ui/Icon.js | 38 +++ vnext/src/ui/Input.css | 8 + vnext/src/ui/Input.js | 17 ++ vnext/src/ui/LoginButton.js | 90 +++++++ vnext/src/ui/Message.css | 210 ++++++++++++++++ vnext/src/ui/Message.js | 142 +++++++++++ vnext/src/ui/MessageInput.js | 107 ++++++++ vnext/src/ui/Modal.css | 95 ++++++++ vnext/src/ui/Modal.js | 29 +++ vnext/src/ui/NavigationIcon.css | 4 + vnext/src/ui/NavigationIcon.js | 21 ++ vnext/src/ui/PM.js | 51 ++++ vnext/src/ui/Post.js | 38 +++ vnext/src/ui/SearchBox.js | 26 ++ vnext/src/ui/Settings.js | 268 +++++++++++++++++++++ vnext/src/ui/Spinner.js | 42 ++++ vnext/src/ui/Thread.js | 181 ++++++++++++++ vnext/src/ui/Types.js | 15 ++ vnext/src/ui/UploadButton.js | 42 ++++ vnext/src/ui/UserInfo.css | 11 + vnext/src/ui/UserInfo.js | 117 +++++++++ vnext/src/ui/Users.js | 44 ++++ vnext/src/ui/__tests__/Avatar.test.js | 15 ++ vnext/src/ui/__tests__/LoginButton.test.js | 21 ++ vnext/src/ui/__tests__/MessageInput-test.js | 95 ++++++++ vnext/src/ui/__tests__/UserLink.test.js | 20 ++ .../ui/__tests__/__snapshots__/Avatar.test.js.snap | 41 ++++ .../__snapshots__/LoginButton.test.js.snap | 178 ++++++++++++++ .../__tests__/__snapshots__/UserLink.test.js.snap | 33 +++ vnext/src/views/index.html | 63 ----- vnext/webpack.config.js | 2 +- 82 files changed, 2574 insertions(+), 2574 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 create mode 100644 vnext/src/index.html create mode 100644 vnext/src/ui/Avatar.css create mode 100644 vnext/src/ui/Avatar.js create mode 100644 vnext/src/ui/Button.css create mode 100644 vnext/src/ui/Button.js create mode 100644 vnext/src/ui/Chat.css create mode 100644 vnext/src/ui/Chat.js create mode 100644 vnext/src/ui/Contact.js create mode 100644 vnext/src/ui/Contacts.js create mode 100644 vnext/src/ui/Feeds.js create mode 100644 vnext/src/ui/Header.js create mode 100644 vnext/src/ui/Icon.js create mode 100644 vnext/src/ui/Input.css create mode 100644 vnext/src/ui/Input.js create mode 100644 vnext/src/ui/LoginButton.js create mode 100644 vnext/src/ui/Message.css create mode 100644 vnext/src/ui/Message.js create mode 100644 vnext/src/ui/MessageInput.js create mode 100644 vnext/src/ui/Modal.css create mode 100644 vnext/src/ui/Modal.js create mode 100644 vnext/src/ui/NavigationIcon.css create mode 100644 vnext/src/ui/NavigationIcon.js create mode 100644 vnext/src/ui/PM.js create mode 100644 vnext/src/ui/Post.js create mode 100644 vnext/src/ui/SearchBox.js create mode 100644 vnext/src/ui/Settings.js create mode 100644 vnext/src/ui/Spinner.js create mode 100644 vnext/src/ui/Thread.js create mode 100644 vnext/src/ui/Types.js create mode 100644 vnext/src/ui/UploadButton.js create mode 100644 vnext/src/ui/UserInfo.css create mode 100644 vnext/src/ui/UserInfo.js create mode 100644 vnext/src/ui/Users.js create mode 100644 vnext/src/ui/__tests__/Avatar.test.js create mode 100644 vnext/src/ui/__tests__/LoginButton.test.js create mode 100644 vnext/src/ui/__tests__/MessageInput-test.js create mode 100644 vnext/src/ui/__tests__/UserLink.test.js create mode 100644 vnext/src/ui/__tests__/__snapshots__/Avatar.test.js.snap create mode 100644 vnext/src/ui/__tests__/__snapshots__/LoginButton.test.js.snap create mode 100644 vnext/src/ui/__tests__/__snapshots__/UserLink.test.js.snap delete mode 100644 vnext/src/views/index.html diff --git a/vnext/src/App.js b/vnext/src/App.js index 17f87e45..1f7e715e 100644 --- a/vnext/src/App.js +++ b/vnext/src/App.js @@ -2,18 +2,18 @@ import React, { useState, useEffect } from 'react'; import { BrowserRouter as Router, Route, Link, Switch } from 'react-router-dom'; import qs from 'qs'; -import Icon from './components/Icon'; -import { Discover, Discussions, Blog, Tag, Home } from './components/Feeds'; -import { Friends, Readers } from './components/Users'; -import Settings from './components/Settings'; -import Contacts from './components/Contacts'; -import Chat from './components/Chat'; -import Post from './components/Post'; -import Thread from './components/Thread'; -import LoginButton from './components/LoginButton'; -import { UserLink } from './components/UserInfo'; -import Header from './components/Header'; -import SearchBox from './components/SearchBox'; +import Icon from './ui/Icon'; +import { Discover, Discussions, Blog, Tag, Home } from './ui/Feeds'; +import { Friends, Readers } from './ui/Users'; +import Settings from './ui/Settings'; +import Contacts from './ui/Contacts'; +import Chat from './ui/Chat'; +import Post from './ui/Post'; +import Thread from './ui/Thread'; +import LoginButton from './ui/LoginButton'; +import { UserLink } from './ui/UserInfo'; +import Header from './ui/Header'; +import SearchBox from './ui/SearchBox'; import cookies from 'react-cookies'; 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}`} - : } - - : - } -
-
- - - {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 ( - - - - - - ); -} - -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 ( -
-
-