diff options
Diffstat (limited to 'vnext')
-rw-r--r-- | vnext/src/App.js | 60 | ||||
-rw-r--r-- | vnext/src/api/index.js | 2 | ||||
-rw-r--r-- | vnext/src/components/Avatar.js | 21 | ||||
-rw-r--r-- | vnext/src/components/Feeds.js | 11 | ||||
-rw-r--r-- | vnext/src/components/Message.js | 24 | ||||
-rw-r--r-- | vnext/src/components/Thread.js | 49 | ||||
-rw-r--r-- | vnext/src/components/UserInfo.js | 85 | ||||
-rw-r--r-- | vnext/src/index.js | 4 | ||||
-rw-r--r-- | vnext/src/style/main.css | 80 | ||||
-rw-r--r-- | vnext/src/views/index.html | 12 |
10 files changed, 154 insertions, 194 deletions
diff --git a/vnext/src/App.js b/vnext/src/App.js index 955c1200..71dc3926 100644 --- a/vnext/src/App.js +++ b/vnext/src/App.js @@ -166,66 +166,6 @@ export default class App extends React.Component { <Route exact path="/:user/:mid" render={(props) => <Thread ref={this.thread} visitor={user} {...props} />} /> </Switch> </section> - <aside id="column"> - { - user.uid > 0 && - <> - <ul> - <li> - <Link to="/home"> - <Icon name="ei-clock" size="s" />My feed - </Link> - </li> - <li> - <Link to="/pm"> - <Icon name="ei-envelope" size="s" />PM - </Link> - </li> - <li> - <Link to={`/${user.uname}/?show=recomm`} rel="nofollow"> - <Icon name="ei-heart" size="s" />Recommendations - </Link> - </li> - <li> - <Link to={`/${user.uname}/?media=1`} rel="nofollow"> - <Icon name="ei-camera" size="s" />Photos - </Link> - </li> - <li> - <Link to="/settings" rel="nofollow"> - <Icon name="ei-gear" size="s" />Settings - </Link> - </li> - </ul> - <hr /> - <SearchBox pathname={`/${user.uname}/`} onSearch={this.search} {...this.props} /> - <hr /> - <div id="ustats"> - <ul> - { - user.read && - <li><Link to={`/${user.uname}/friends`}>I read: { user.read.length }</Link></li> - } - <li><Link to={`/${user.uname}/readers`}>My readers: {user.readers? user.readers.length : 0}</Link></li> - { - user.statsMyBL && - <li><Link to={`/${user.uname}/bl`}>My blacklist: {user.statsMyBL}</Link></li> - } - <li>Messages: {user.statsMessages}</li> - <li>Comments: {user.statsReplies}</li> - </ul> - { - user.read && - <div className="iread"> - { - user.read.map(u => <Avatar user={u} key={u.uid} />) - } - </div> - } - </div> - </> - } - </aside> </div> </> </Router> diff --git a/vnext/src/api/index.js b/vnext/src/api/index.js index 90c8b15e..ab26a359 100644 --- a/vnext/src/api/index.js +++ b/vnext/src/api/index.js @@ -32,7 +32,7 @@ export function me(username = '', password = '') { } export function info(username) { - return client.get(`/info/${username}`); + return client.get(`/users?uname=${username}`); } export function getChats() { diff --git a/vnext/src/components/Avatar.js b/vnext/src/components/Avatar.js index 0df0dbd7..f79d7b09 100644 --- a/vnext/src/components/Avatar.js +++ b/vnext/src/components/Avatar.js @@ -6,15 +6,26 @@ import { UserType } from './Types'; export default function Avatar(props) { return ( - <div className="msg-avatar"> - <Link to={{ pathname: props.link || `/${props.user.uname}/`}}> - <img src={`//i.juick.com/a/${props.user.uid}.png`} alt={`${props.user.uname}`} /> - </Link> + <div style={{ display: 'flex' }}> + <div className="msg-avatar"> + <Link to={{ pathname: props.link || `/${props.user.uname}/` }}> + <img src={`//i.juick.com/a/${props.user.uid}.png`} alt={`${props.user.uname}`} /> + </Link> + </div> + <div style={{ display: 'flex', flexDirection: 'column' }}> + <span itemProp="author" itemScope="" itemType="http://schema.org/Person"> + <Link to={{ pathname: `/${props.user.uname}/` }} itemProp="url" rel="author"> + <span itemProp="name">{props.user.uname}</span> + </Link> + </span> + {props.children} + </div> </div> ); } Avatar.propTypes = { user: UserType, - link: PropTypes.string + link: PropTypes.string, + children: PropTypes.node }; diff --git a/vnext/src/components/Feeds.js b/vnext/src/components/Feeds.js index 194af71c..a7833f67 100644 --- a/vnext/src/components/Feeds.js +++ b/vnext/src/components/Feeds.js @@ -8,6 +8,8 @@ import moment from 'moment'; import Message from './Message'; import Spinner from './Spinner'; +import UserInfo from './UserInfo'; + import { getMessages } from '../api'; import { UserType } from './Types'; @@ -38,7 +40,12 @@ export function Blog(props) { search: search, pageParam: search.search ? 'page' : 'before_mid' }; - return (<Feed authRequired={false} query={query} {...props} />); + return ( + <> + <UserInfo user={user} /> + <Feed authRequired={false} query={query} {...props} /> + </> + ); } export function Tag(props) { @@ -75,7 +82,7 @@ class Feed extends React.Component { shouldComponentUpdate(nextProps, nextState) { return this.props.visitor.uid !== nextProps.visitor.uid - || this.state !== nextState || this.props.location !== nextProps.location; + || this.state !== nextState || this.props.location !== nextProps.location; } getSnapshotBeforeUpdate(prevProps) { diff --git a/vnext/src/components/Message.js b/vnext/src/components/Message.js index f091296b..b36936ba 100644 --- a/vnext/src/components/Message.js +++ b/vnext/src/components/Message.js @@ -13,20 +13,16 @@ export default function Message({ data, visitor, children, ...rest }) { return ( <div className="msg-cont" itemProp="blogPost" itemScope="" itemType="http://schema.org/BlogPosting" itemRef="org"> <header className="h"> - <span itemProp="author" itemScope="" itemType="http://schema.org/Person"> - <Link to={{ pathname: `/${data.user.uname}/` }} itemProp="url" rel="author"> - <span itemProp="name">{data.user.uname}</span> - </Link> - </span> - <Avatar user={data.user} /> - <div className="msg-ts"> - <Link to={{ pathname: `/${data.user.uname}/${data.mid}`, state: { msg: data } }}> - <time itemProp="datePublished dateModified" itemType="http://schema.org/Date" dateTime={data.timestamp} - title={moment.utc(data.timestamp).local().format('lll')}> - {moment.utc(data.timestamp).fromNow()} - </time> - </Link> - </div> + <Avatar user={data.user}> + <div className="msg-ts"> + <Link to={{ pathname: `/${data.user.uname}/${data.mid}`, state: { msg: data } }}> + <time itemProp="datePublished dateModified" itemType="http://schema.org/Date" dateTime={data.timestamp} + title={moment.utc(data.timestamp).local().format('lll')}> + {moment.utc(data.timestamp).fromNow()} + </time> + </Link> + </div> + </Avatar> <Tags user={data.user} data={data.tags || []} /> </header> <div className="msg-txt"> diff --git a/vnext/src/components/Thread.js b/vnext/src/components/Thread.js index b0e73b40..2097a315 100644 --- a/vnext/src/components/Thread.js +++ b/vnext/src/components/Thread.js @@ -45,7 +45,7 @@ export default class Thread extends React.Component { .then(response => { let msg = response.data.shift(); this.setState({ - msg: {...msg}, + msg: { ...msg }, replies: response.data, loading: false, active: 0 @@ -100,29 +100,20 @@ export default class Thread extends React.Component { <li id={msg.rid} key={msg.rid} className="msg"> <div className="msg-cont"> <div className="msg-header"> - {!msg.user.banned ? ( - <> - <span itemProp="author" itemScope="" itemType="http://schema.org/Person"> - <Link to={`/${msg.user.uname}/`} itemProp="url" rel="author"><span itemProp="name">{msg.user.uname}</span></Link> - </span><Avatar user={msg.user} /> - </>) : ( - <> - <span>[удалено]:</span><Avatar user={{ uid: 0 }} /> - </> - ) - } - <div className="msg-ts"> - <a href={`/${msg.user.uname}/${msg.mid}`}> - <time itemProp="datePublished dateModified" itemType="http://schema.org/Date" dateTime={msg.timestamp} - title={moment.utc(msg.timestamp).local().format('lll')}> - {moment.utc(msg.timestamp).fromNow()} - </time> - </a> - {msg.replyto > 0 && - ( - <a href={`#${msg.replyto}`}> in reply to {msg.to.uname} </a> - )} - </div> + <Avatar user={msg.user}> + <div className="msg-ts"> + <a href={`/${msg.user.uname}/${msg.mid}`}> + <time itemProp="datePublished dateModified" itemType="http://schema.org/Date" dateTime={msg.timestamp} + title={moment.utc(msg.timestamp).local().format('lll')}> + {moment.utc(msg.timestamp).fromNow()} + </time> + </a> + {msg.replyto > 0 && + ( + <a href={`#${msg.replyto}`}> in reply to {msg.to.uname} </a> + )} + </div> + </Avatar> </div> <div className="msg-txt"><p dangerouslySetInnerHTML={{ __html: format(msg.body, msg.mid, (msg.tags || []).indexOf('code') >= 0) }}></p></div> { @@ -149,10 +140,10 @@ export default class Thread extends React.Component { </li> )) : ( <> - {Array(loaders).fill().map((it, i) => <Spinner key={i} />)} - </> - ) - } + {Array(loaders).fill().map((it, i) => <Spinner key={i} />)} + </> + ) + } </ul> </> ); @@ -170,7 +161,7 @@ Thread.propTypes = { visitor: UserType.isRequired }; -function Recommendations({forMessage, ...rest}) { +function Recommendations({ forMessage, ...rest }) { const { likes, recommendations } = forMessage; return recommendations && recommendations.length > 0 && ( <div className="msg-recomms">{'Recommended by '} diff --git a/vnext/src/components/UserInfo.js b/vnext/src/components/UserInfo.js new file mode 100644 index 00000000..147bb6f8 --- /dev/null +++ b/vnext/src/components/UserInfo.js @@ -0,0 +1,85 @@ +import React from 'react'; + +import { Link } from 'react-router-dom'; + +import { info } from '../api'; + +import Avatar from './Avatar'; +import Icon from './Icon'; +import SearchBox from './SearchBox'; + +export default class UserInfo extends React.Component { + constructor(props) { + super(props); + this.state = { + user: { uname: props.user, uid: 0 } + }; + } + componentDidMount() { + info(this.state.user.uname).then(response => { + this.setState({ + user: response.data[0] + }); + }); + } + render() { + const { user } = this.state; + return ( + <div style={{ padding: '14px' }}> + <Avatar user={user}> + <div className="msg-ts">Was online recently</div> + </Avatar> + <div> + { + user.uid > 0 && + <> + <ul> + <li> + <Link to="/pm"> + <Icon name="ei-envelope" size="s" />PM + </Link> + </li> + <li> + <Link to={`/${user.uname}/?show=recomm`} rel="nofollow"> + <Icon name="ei-heart" size="s" />Recommendations + </Link> + </li> + <li> + <Link to={`/${user.uname}/?media=1`} rel="nofollow"> + <Icon name="ei-camera" size="s" />Photos + </Link> + </li> + </ul> + <hr /> + <SearchBox pathname={`/${user.uname}/`} onSearch={this.search} {...this.props} /> + <hr /> + <div id="ustats"> + <ul> + { + user.read && + <li><Link to={`/${user.uname}/friends`}>I read: {user.read.length}</Link></li> + } + <li><Link to={`/${user.uname}/readers`}>My readers: {user.readers ? user.readers.length : 0}</Link></li> + { + user.statsMyBL && + <li><Link to={`/${user.uname}/bl`}>My blacklist: {user.statsMyBL}</Link></li> + } + <li>Messages: {user.statsMessages}</li> + <li>Comments: {user.statsReplies}</li> + </ul> + { + user.read && + <div className="iread"> + { + user.read.map(u => <Avatar user={u} key={u.uid} />) + } + </div> + } + </div> + </> + } + </div> + </div> + ); + } +}
\ No newline at end of file diff --git a/vnext/src/index.js b/vnext/src/index.js index b9fc5f54..24fe9352 100644 --- a/vnext/src/index.js +++ b/vnext/src/index.js @@ -5,7 +5,7 @@ import App from './App'; let container = document.createElement('div'); ReactDOM.render(<App />, container); -let body = document.getElementById('wrapper').parentNode; +let body = document.getElementById('content').parentNode; body.replaceChild(container.getElementsByTagName('header')[0], body.querySelector('#header')); -body.replaceChild(container.querySelector('#wrapper'), body.querySelector('#wrapper')); +body.replaceChild(container.querySelector('#content'), body.querySelector('#content')); diff --git a/vnext/src/style/main.css b/vnext/src/style/main.css index a5e0326d..913572dc 100644 --- a/vnext/src/style/main.css +++ b/vnext/src/style/main.css @@ -70,27 +70,10 @@ html { background: #f8f8f8; color: #222; } -#wrapper { - margin: 0 auto; - width: 1000px; - margin-top: 52px; -} -#column { - float: left; - margin-left: 10px; - overflow: hidden; - padding-top: 10px; - width: 240px; -} #content { - float: right; - margin: 12px 0 0 0; - width: 728px; -} -#minimal_content { margin: 0 auto; - min-width: 310px; - width: auto; + width: 728px; + margin-top: 62px; } noscript article { background-image: url("matrix.jpg"); @@ -135,7 +118,6 @@ body > header { transform: translateY(-100%); } #footer { - clear: both; color: #999; font-size: 10pt; margin: 40px; @@ -147,7 +129,6 @@ body > header { text-size-adjust: 100%; } body, - #wrapper, #topwrapper, #content, #footer { @@ -156,18 +137,9 @@ body > header { min-width: 310px; width: auto; } - #wrapper { - margin-top: 50px; - } body > header { margin-bottom: 15px; } - #column { - float: none; - margin: 0 10px; - padding-top: 0; - width: auto; - } } /* #endregion */ @@ -229,46 +201,6 @@ body > header { border-top: 1px solid #CCC; } -#column ul, -#column p, -#column hr { - margin: 10px 0; -} -#column li > a { - display: block; - height: 100%; - padding: 6px; -} -#column li > a:hover { - background-color: #fff; - box-shadow: 0 0 3px rgba(0, 0, 0, 0.16); - transition: background-color 0.2s ease-in; -} -#column .margtop { - margin-top: 15px; -} - -#column .tags { - background: #fff; - box-shadow: 0 0 3px rgba(0, 0, 0, 0.16); - line-height: 140%; - padding: 6px; - text-align: justify; -} -#column .inp { - background: #fff; - border: 1px solid #ddddd5; - outline: none !important; - padding: 4px; - width: 222px; -} -#column .tags h4 { - background: #eee; - border: 1px solid #eee; - color: #888; - display: block; - text-align: center; -} #ctitle { font-size: 14pt; } @@ -403,10 +335,9 @@ article .tags > a, margin-bottom: 0; } .msg-avatar { - float: left; - height: 48px; + min-height: 48px; margin-right: 10px; - width: 48px; + min-width: 48px; } .msg-avatar img { height: 48px; @@ -419,7 +350,6 @@ article .tags > a, line-height: 140%; margin-bottom: 12px; padding: 20px; - width: 640px; } .reply-new .msg-cont { border-right: 5px solid #0C0; @@ -542,7 +472,7 @@ article .tags > a, } @media screen and (max-width: 480px) { - #wrapper { + #content { margin-top: 104px; } #search { diff --git a/vnext/src/views/index.html b/vnext/src/views/index.html index 35a876ea..e5862bc1 100644 --- a/vnext/src/views/index.html +++ b/vnext/src/views/index.html @@ -44,15 +44,15 @@ <body id="body"> <div id="header"> - <div id="header_wrapper"> - <div id="logo"><a href="/">Juick</a></div> - </div> + <div id="header_wrapper"> + <div id="logo"><a href="/">Juick</a></div> + </div> </div> - <div id="wrapper"> + <div id="content"> <noscript> <article> - Javascript is required to use Juick from browser.<br /> - Alternatively we have <a href="mailto:juick@juick.com">maillist-like</a> and <a href="xmpp:juick@juick.com">chat</a> interfaces. + Javascript is required to use Juick from browser.<br /> Alternatively we have <a href="mailto:juick@juick.com">maillist-like</a> + and <a href="xmpp:juick@juick.com">chat</a> interfaces. </article> </noscript> </div> |