flow: channel stuff + more
This commit is contained in:
parent
66dbd2ca3e
commit
d52d2d86fe
|
@ -18,7 +18,7 @@ const App = () => (
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
component={Chat}
|
component={Chat}
|
||||||
path="/chat"
|
path="/chat/:type/:name"
|
||||||
/>
|
/>
|
||||||
</Switch>
|
</Switch>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -33,10 +33,10 @@ export default function Bar(props) {
|
||||||
className="bar__buttonIcon"
|
className="bar__buttonIcon"
|
||||||
role="img"
|
role="img"
|
||||||
aria-label={label}
|
aria-label={label}
|
||||||
|
title={label}
|
||||||
>
|
>
|
||||||
{icon}
|
{icon}
|
||||||
</span>
|
</span>
|
||||||
<span className="bar__buttonText">{label}</span>
|
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
))
|
))
|
||||||
|
|
|
@ -51,24 +51,28 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.bar__button {
|
.bar__button {
|
||||||
background-color: #2a2a2a;
|
background-color: #303030;
|
||||||
border: none;
|
border: none;
|
||||||
height: 3.5em;
|
height: 3.5em;
|
||||||
transition: 0.1s background-color;
|
transition: 0.1s background-color;
|
||||||
width: 3.5em;
|
width: 3.5em;
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: #272727;
|
background-color: #2a2a2a;
|
||||||
}
|
}
|
||||||
&.active {
|
&.active {
|
||||||
background-color: $color-active;
|
background-color: $color-active;
|
||||||
}
|
}
|
||||||
.closed &.active {
|
.closed &.active {
|
||||||
|
background-color: #303030;
|
||||||
|
&:hover {
|
||||||
background-color: #2a2a2a;
|
background-color: #2a2a2a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.bar__buttonIcon {
|
.bar__buttonIcon {
|
||||||
display: flow-root;
|
display: flow-root;
|
||||||
|
font-size: 1.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bar__buttonText {
|
.bar__buttonText {
|
||||||
|
|
65
src/client/channel.jsx
Normal file
65
src/client/channel.jsx
Normal 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
37
src/client/channel.scss
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,20 +5,23 @@ import React, {useState} from 'react';
|
||||||
|
|
||||||
import useBreakpoints from './hooks/useBreakpoints';
|
import useBreakpoints from './hooks/useBreakpoints';
|
||||||
import Bar from './bar';
|
import Bar from './bar';
|
||||||
|
import ChatLeftFriends from './chat--leftFriends';
|
||||||
|
import ChatLeftRooms from './chat--leftRooms';
|
||||||
|
|
||||||
export default function ChatLeft() {
|
export default function ChatLeft() {
|
||||||
const {desktop, tablet} = useBreakpoints();
|
const {desktop, tablet} = useBreakpoints();
|
||||||
|
const [active, setActive] = useState(0);
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const toggleOpen = () => setIsOpen(!isOpen);
|
const toggleOpen = () => setIsOpen(!isOpen);
|
||||||
const showsAsOpen = isOpen || desktop || !tablet;
|
const showsAsOpen = isOpen || desktop || !tablet;
|
||||||
const buttons = [
|
const buttons = [
|
||||||
{
|
{
|
||||||
icon: '📜',
|
icon: '💬',
|
||||||
label: 'chat',
|
label: 'Chat',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
icon: '😁',
|
icon: '😁',
|
||||||
label: 'friends',
|
label: 'Friends',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
return (
|
return (
|
||||||
|
@ -33,29 +36,11 @@ export default function ChatLeft() {
|
||||||
if (i === active || !isOpen) {
|
if (i === active || !isOpen) {
|
||||||
toggleOpen();
|
toggleOpen();
|
||||||
}
|
}
|
||||||
|
setActive(active);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<label className="channel__join">
|
{0 === active && <ChatLeftRooms />}
|
||||||
Join
|
{1 === active && <ChatLeftFriends />}
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,54 +13,3 @@
|
||||||
.left.open {
|
.left.open {
|
||||||
width: 18em;
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
81
src/client/chat--leftFriends.jsx
Normal file
81
src/client/chat--leftFriends.jsx
Normal 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 = {};
|
51
src/client/chat--leftFriends.scss
Normal file
51
src/client/chat--leftFriends.scss
Normal 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%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
76
src/client/chat--leftRooms.jsx
Normal file
76
src/client/chat--leftRooms.jsx
Normal 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 = {};
|
51
src/client/chat--leftRooms.scss
Normal file
51
src/client/chat--leftRooms.scss
Normal 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%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,7 +14,7 @@ export default function ChatRight() {
|
||||||
const buttons = [
|
const buttons = [
|
||||||
{
|
{
|
||||||
icon: '🙃',
|
icon: '🙃',
|
||||||
label: 'present',
|
label: 'Present',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.right .bar--vertical {
|
.right .bar--vertical {
|
||||||
float: right;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.right.open {
|
.right.open {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user