flow: channel stuff + more

This commit is contained in:
cha0s 2020-07-15 00:18:51 -05:00
parent 66dbd2ca3e
commit d52d2d86fe
13 changed files with 381 additions and 82 deletions

View File

@ -18,7 +18,7 @@ const App = () => (
/>
<Route
component={Chat}
path="/chat"
path="/chat/:type/:name"
/>
</Switch>
</div>

View File

@ -33,10 +33,10 @@ export default function Bar(props) {
className="bar__buttonIcon"
role="img"
aria-label={label}
title={label}
>
{icon}
</span>
<span className="bar__buttonText">{label}</span>
</button>
</li>
))

View File

@ -51,24 +51,28 @@
}
.bar__button {
background-color: #2a2a2a;
background-color: #303030;
border: none;
height: 3.5em;
transition: 0.1s background-color;
width: 3.5em;
&:hover {
background-color: #272727;
background-color: #2a2a2a;
}
&.active {
background-color: $color-active;
}
.closed &.active {
background-color: #2a2a2a;
background-color: #303030;
&:hover {
background-color: #2a2a2a;
}
}
}
.bar__buttonIcon {
display: flow-root;
font-size: 1.5em;
}
.bar__buttonText {

65
src/client/channel.jsx Normal file
View File

@ -0,0 +1,65 @@
import './channel.scss';
import classnames from 'classnames';
import PropTypes from 'prop-types';
import React, {useState} from 'react';
export default function Channel(props) {
const {
actions,
href,
name,
prefix,
} = props;
const [isActioning, setIsActioning] = useState(false);
return (
<div
className={classnames('channel', {actioning: isActioning})}
>
<a
className="channel__link"
href={href}
onContextMenu={(event) => {
setIsActioning(!isActioning);
event.preventDefault();
}}
>
<span className="muted">{prefix}</span>
{name}
</a>
<div
className="channel__actions"
>
{actions.map(({icon, label, onClick}, i) => (
<button
className="channel__action"
// eslint-disable-next-line react/no-array-index-key
key={i}
onClick={onClick}
type="button"
>
<span
className="channel__icon"
role="img"
aria-label={label}
title={label}
>
{icon}
</span>
</button>
))}
</div>
</div>
);
}
Channel.propTypes = {
actions: PropTypes.arrayOf(PropTypes.shape({
icon: PropTypes.string,
label: PropTypes.string,
onClick: PropTypes.func,
})).isRequired,
href: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
prefix: PropTypes.string.isRequired,
};

37
src/client/channel.scss Normal file
View File

@ -0,0 +1,37 @@
.channel {
position: relative;
}
.channel__link {
color: #ffffff;
display: block;
font-family: var(--title-font-family);
padding: 1em;
text-decoration: none;
.muted {
font-size: 0.8em;
margin-right: 0.125em;
}
}
.channel__actions {
align-items: center;
display: flex;
padding-right: 0.5em;
position: absolute;
height: 3em;
right: 0;
top: 0;
transition: 0.2s right;
z-index: 10;
}
.channel__action {
background-color: transparent;
border: 0;
color: inherit;
padding: 0.5em;
&:hover {
background-color: rgba(255, 255, 255, 0.1);
}
}

View File

@ -5,20 +5,23 @@ import React, {useState} from 'react';
import useBreakpoints from './hooks/useBreakpoints';
import Bar from './bar';
import ChatLeftFriends from './chat--leftFriends';
import ChatLeftRooms from './chat--leftRooms';
export default function ChatLeft() {
const {desktop, tablet} = useBreakpoints();
const [active, setActive] = useState(0);
const [isOpen, setIsOpen] = useState(false);
const toggleOpen = () => setIsOpen(!isOpen);
const showsAsOpen = isOpen || desktop || !tablet;
const buttons = [
{
icon: '📜',
label: 'chat',
icon: '💬',
label: 'Chat',
},
{
icon: '😁',
label: 'friends',
label: 'Friends',
},
];
return (
@ -33,29 +36,11 @@ export default function ChatLeft() {
if (i === active || !isOpen) {
toggleOpen();
}
setActive(active);
}}
/>
<label className="channel__join">
Join
<span className="channel__joinTextWrapper">
<input className="channel__joinText" placeholder="reddichat" type="text" />
</span>
</label>
<h2 className="channel__chatsTitle">Chats</h2>
<ul className="channel__chatsList">
<li>
<a href="/chat/r/reddichat">
<span className="muted">/r/</span>
reddichat
</a>
</li>
<li>
<a href="/chat/r/anonymous">
<span className="muted">/r/</span>
anonymous
</a>
</li>
</ul>
{0 === active && <ChatLeftRooms />}
{1 === active && <ChatLeftFriends />}
</div>
);
}

View File

@ -13,54 +13,3 @@
.left.open {
width: 18em;
}
.channel__join[class] {
background-color: #272727;
flex-wrap: nowrap;
white-space: nowrap;
}
.channel__joinTextWrapper::before {
content: '/r/';
font-size: 0.8em;
padding: 0 0.25em 0 0.5em;
position: relative;
top: 1px;
}
.channel__joinText {
padding-left: 0.25em;
}
.channel__chatsTitle {
color: $color-muted;
font-family: var(--thick-title-font-family);
font-size: 0.7em;
font-weight: bold;
padding: 2.5em 1em 0.625em 1.375em;
text-transform: uppercase;
}
.channel__chatsList li {
&:nth-of-type(even) {
background-color: rgba(0, 0, 0, 0.1);
}
&:nth-of-type(odd) {
background-color: rgba(0, 0, 0, 0.2);
}
}
.channel__chatsList a {
color: #ffffff;
display: block;
font-family: var(--title-font-family);
padding: 1em;
text-decoration: none;
.muted {
font-size: 0.8em;
margin-right: 0.125em;
}
&:hover {
background-color: #444;
}
}

View File

@ -0,0 +1,81 @@
import './chat--leftFriends.scss';
import classnames from 'classnames';
import React from 'react';
import {useParams} from 'react-router-dom';
import Channel from './channel';
export default function ChatLeftRooms() {
const {type, name} = useParams();
const favorites = ['BabeHasHiccups'];
const friends = ['BabeHasHiccups', 'mystifired'].filter((channel) => -1 === favorites.indexOf(channel));
const favoritesActions = [
{
icon: '💔',
label: 'Unfavorite',
onClick: () => {},
},
];
const friendsActions = [
{
icon: '❤️',
label: 'Favorite',
onClick: () => {},
},
{
icon: '🚫',
label: 'Unfriend',
onClick: () => {},
},
{
icon: '☢️',
label: 'Block',
onClick: () => {},
},
];
return (
<div
className="chat--leftRooms"
>
<label className="friends__add">
Add
<span className="friends__addTextWrapper">
<input className="friends__addText" placeholder="cha0s" type="text" />
</span>
</label>
<h2 className="friends__chatsTitle">Favorites</h2>
<ul className="friends__chatsList">
{favorites.map((channel) => (
<li
className="friends__item"
>
<Channel
actions={favoritesActions}
href={`/chat/r/${channel}`}
name={channel}
prefix="/u/"
/>
</li>
))}
</ul>
<h2 className="friends__chatsTitle">Friends</h2>
<ul className="friends__chatsList">
{friends.map((channel) => (
<li
className="friends__item"
>
<Channel
actions={friendsActions}
href={`/chat/r/${channel}`}
name={channel}
prefix="/u/"
/>
</li>
))}
</ul>
</div>
);
}
ChatLeftRooms.propTypes = {};

View File

@ -0,0 +1,51 @@
@import '~/client/scss/colors.scss';
.friends__add[class] {
background-color: #272727;
flex-wrap: nowrap;
white-space: nowrap;
}
.friends__addTextWrapper::before {
content: '/u/';
font-size: 0.8em;
padding: 0 0.25em 0 0.5em;
position: relative;
top: 1px;
}
.friends__addText {
padding-left: 0.25em;
}
.friends__chatsTitle {
color: $color-muted;
font-family: var(--thick-title-font-family);
font-size: 0.7em;
font-weight: bold;
padding: 2.5em 1em 0.625em 1.375em;
text-transform: uppercase;
}
.friends__item {
position: relative;
width: 100%;
&:nth-of-type(even) {
background-color: rgba(0, 0, 0, 0.1);
&:hover {
background-color: rgba(255, 255, 255, 0.2);
}
}
&:nth-of-type(odd) {
background-color: rgba(0, 0, 0, 0.2);
&:hover {
background-color: rgba(255, 255, 255, 0.1);
}
}
&.active[class] {
background-color: $color-active;
&:hover {
background-color: lighten($color-active, 5%);
}
}
}

View File

@ -0,0 +1,76 @@
import './chat--leftRooms.scss';
import classnames from 'classnames';
import React from 'react';
import {useParams} from 'react-router-dom';
import Channel from './channel';
export default function ChatLeftRooms() {
const {type, name} = useParams();
const favorites = ['reddichat'];
const recent = ['reddichat', 'anonymous'].filter((channel) => -1 === favorites.indexOf(channel));
const favoritesActions = [
{
icon: '💔',
label: 'Unfavorite',
onClick: () => {},
},
];
const recentActions = [
{
icon: '❤️',
label: 'Favorite',
onClick: () => {},
},
{
icon: '×',
label: 'Close',
onClick: () => {},
},
];
return (
<div
className="chat--leftRooms"
>
<label className="channels__join">
Join
<span className="channels__joinTextWrapper">
<input className="channels__joinText" placeholder="reddichat" type="text" />
</span>
</label>
<h2 className="channels__chatsTitle">Favorites</h2>
<ul className="channels__chatsList">
{favorites.map((channel) => (
<li
className="channels__item"
>
<Channel
actions={favoritesActions}
href={`/chat/r/${channel}`}
name={channel}
prefix="/r/"
/>
</li>
))}
</ul>
<h2 className="channels__chatsTitle">Recent</h2>
<ul className="channels__chatsList">
{recent.map((channel) => (
<li
className="channels__item"
>
<Channel
actions={recentActions}
href={`/chat/r/${channel}`}
name={channel}
prefix="/r/"
/>
</li>
))}
</ul>
</div>
);
}
ChatLeftRooms.propTypes = {};

View File

@ -0,0 +1,51 @@
@import '~/client/scss/colors.scss';
.channels__join[class] {
background-color: #272727;
flex-wrap: nowrap;
white-space: nowrap;
}
.channels__joinTextWrapper::before {
content: '/r/';
font-size: 0.8em;
padding: 0 0.25em 0 0.5em;
position: relative;
top: 1px;
}
.channels__joinText {
padding-left: 0.25em;
}
.channels__chatsTitle {
color: $color-muted;
font-family: var(--thick-title-font-family);
font-size: 0.7em;
font-weight: bold;
padding: 2.5em 1em 0.625em 1.375em;
text-transform: uppercase;
}
.channels__item {
position: relative;
width: 100%;
&:nth-of-type(even) {
background-color: rgba(0, 0, 0, 0.1);
&:hover {
background-color: rgba(255, 255, 255, 0.2);
}
}
&:nth-of-type(odd) {
background-color: rgba(0, 0, 0, 0.2);
&:hover {
background-color: rgba(255, 255, 255, 0.1);
}
}
&.active[class] {
background-color: $color-active;
&:hover {
background-color: lighten($color-active, 5%);
}
}
}

View File

@ -14,7 +14,7 @@ export default function ChatRight() {
const buttons = [
{
icon: '🙃',
label: 'present',
label: 'Present',
},
];
return (

View File

@ -11,7 +11,7 @@
}
.right .bar--vertical {
float: right;
float: left;
}
.right.open {