major code clean-up: the ChannelView component is now smaller, main-card css class has been removed, among other changes

This commit is contained in:
hippoz 2021-08-20 21:31:56 +03:00
parent eb89803398
commit 63fc9d7d50
Signed by: hippoz
GPG key ID: 7C52899193467641
18 changed files with 87 additions and 111 deletions

View file

@ -66,7 +66,7 @@ export default function Create() {
} }
if (specialCodePrompt) return ( if (specialCodePrompt) return (
<div id="login-container" className="main-card"> <div id="login-container" className="card">
<h1>One more thing!</h1> <h1>One more thing!</h1>
<p>You need a special code to sign up here!</p> <p>You need a special code to sign up here!</p>
<label htmlFor="specialcode">Special Code</label> <label htmlFor="specialcode">Special Code</label>
@ -78,7 +78,7 @@ export default function Create() {
); );
return ( return (
<div id="login-container" className="main-card"> <div id="login-container" className="card">
<h1>Create an account</h1> <h1>Create an account</h1>
<label htmlFor="username">Username</label> <label htmlFor="username">Username</label>
<br /> <br />

View file

@ -49,7 +49,7 @@ export default function Login() {
} }
return ( return (
<div id="login-container" className="main-card"> <div id="login-container" className="card">
<h1>Log in</h1> <h1>Log in</h1>
<label htmlFor="username">Username</label> <label htmlFor="username">Username</label>
<br /> <br />

View file

@ -0,0 +1,29 @@
import Message from "../Messages/Message";
import { useRef, useEffect } from 'react';
export default function ChannelMessageView({messages}) {
const invisibleBottomMessageRef = useRef(null);
useEffect(() => {
if (invisibleBottomMessageRef && invisibleBottomMessageRef.current) {
invisibleBottomMessageRef.current.scrollIntoView({ behaviour: 'smooth' });
}
}, [messages]);
let messagesView = messages.map((m, i) => {
return <Message key={ m._id } message={ m } />;
});
if (messagesView === undefined || messagesView.length <= 0) {
messagesView = (
<div className='no-messages-warning'>
<span>No messages yet...</span>
</div>
);
}
return <div className="message-list-card">
{ messagesView }
<div ref={ invisibleBottomMessageRef }></div>
</div>;
}

View file

@ -2,7 +2,7 @@ import UserProfileButton from '../Users/UserButton';
function ChannelUserList({ presence }) { function ChannelUserList({ presence }) {
return ( return (
<div className="main-card sidebar"> <div className="card sidebar">
<div className="channel-list"> <div className="channel-list">
{ Object.keys(presence).map((userId) => <UserProfileButton key={ userId } user={ presence[userId] } />) } { Object.keys(presence).map((userId) => <UserProfileButton key={ userId } user={ presence[userId] } />) }
</div> </div>

View file

@ -1,120 +1,64 @@
import ChannelViewLoader from '../UI/ProfileLinkLoader';
import ChannelProfile from './ChannelProfileLink'; import ChannelProfile from './ChannelProfileLink';
import Message from '../Messages/Message';
import gatewayConnection from '../../API/Gateway/globalGatewayConnection'; import gatewayConnection from '../../API/Gateway/globalGatewayConnection';
import ChannelUserList from "./ChannelUserList"; import ChannelUserList from "./ChannelUserList";
import { useParams } from 'react-router-dom';
import { connect, useDispatch } from 'react-redux'; import { connect, useDispatch } from 'react-redux';
import { useState, useRef, useEffect } from 'react'; import { useState, useRef, useEffect } from 'react';
import ChannelMessageView from './ChannelMessageView';
const ChannelView = ({ messages, channel, channelPresenceClientList }) => {
const ChannelView = ({ channels, messages, channel, selectedChannelId, experiments, channelPresenceClientList, gradientBannerNotificationText }) => {
const { id } = useParams();
const [ textInput, setTextInput ] = useState(''); const [ textInput, setTextInput ] = useState('');
const textInputRef = useRef(null); const textInputRef = useRef(null);
const invisibleBottomMessageRef = useRef(null);
const dispatch = useDispatch(); const dispatch = useDispatch();
useEffect(() => {
if (invisibleBottomMessageRef && invisibleBottomMessageRef.current) {
invisibleBottomMessageRef.current.scrollIntoView({ behaviour: 'smooth' });
}
}, [messages]);
const handleTextboxKeydown = (e) => { const handleTextboxKeydown = (e) => {
if (e.key === 'Enter') { if (e.key === 'Enter') {
gatewayConnection.sendMessage(textInput, id); gatewayConnection.sendMessage(textInput, channel._id);
textInputRef.current.value = ''; textInputRef.current.value = '';
setTextInput(''); setTextInput('');
} }
} }
useEffect(() => { useEffect(() => {
if (!channels) return;
if (!channel) return; if (!channel) return;
if (channel._id === selectedChannelId) return;
dispatch({ type: 'channels/selectchannel', channelId: channel._id }); dispatch({ type: 'channels/selectchannel', channelId: channel._id });
}, [channels, id, dispatch, channel, selectedChannelId]); }, [dispatch, channel]);
if (channel) { if (channel) {
let messagesView = messages.map((m, i) => {
//if (messages[i-1] && messages[i-1].author.username === m.author.username) return <Message key={ m._id } message={ m } hideUsername={ true } />
return <Message key={ m._id } message={ m } />;
});
if (messagesView === undefined || messagesView.length <= 0) {
messagesView = (
<div className='no-messages-warning'>
<div className="profile-picture default-user no-messages-icon">
<div className="default-channel-styled-text no-messages-text">
#?
</div>
</div>
<span style={ { marginTop: "1em" } }>No messages yet...</span>
</div>
);
}
return ( return (
<div className="col-flex-card hidden-overflow"> <div className="col-flex-card hidden-overflow">
<div className="bar-card-accent"> <div className="bar-card-accent">
<ChannelProfile channel={ channel } size="24" /> <ChannelProfile channel={ channel } size="24" />
{/*
{ (experiments.voiceSFUTesting) && <button className="button" onClick={ () => gatewayConnection.beginVoiceSession(channel._id) }> { (experiments.voiceSFUTesting) && <button className="button" onClick={ () => gatewayConnection.beginVoiceSession(channel._id) }>
Join voice Join voice
</button>} </button>}
*/}
</div> </div>
{(gradientBannerNotificationText !== undefined) && <div className="gradient-banner-card" onClick={ () => dispatch({ type: "application/updatebannertext", text: undefined }) }> <div className="row-flex-card hidden-overflow">
{ gradientBannerNotificationText }
</div>}
<div className="main-card row-flex-card hidden-overflow">
<div className="col-flex-card channel-message-panel hidden-overflow"> <div className="col-flex-card channel-message-panel hidden-overflow">
<div className="message-list-card"> <ChannelMessageView messages={messages}></ChannelMessageView>
{ messagesView }
<div ref={ invisibleBottomMessageRef }></div>
</div>
<div className="invis-bar"> <div className="invis-bar">
<input className="text-input message-input" type="text" placeholder="Go on, type something interesting!" ref={ textInputRef } onKeyDown={ handleTextboxKeydown } onChange={ ({ target }) => setTextInput(target.value) }></input> <input className="text-input message-input" type="text" placeholder="Go on, type something interesting!" ref={ textInputRef } onKeyDown={ handleTextboxKeydown } onChange={ ({ target }) => setTextInput(target.value) }></input>
</div> </div>
</div> </div>
{ (experiments.userListTest) && <ChannelUserList presence={ channelPresenceClientList || [] } /> } <ChannelUserList presence={ channelPresenceClientList || [] } />
</div> </div>
</div> </div>
) );
} else {
return (
<div className="main-card col-flex-card">
<div className="bar-card">
<ChannelViewLoader />
</div>
<div className="message-list-card">
</div>
<div className="bar-card-bottom">
</div>
</div>
)
} }
return null;
}; };
const stateToProps = (state, ownProps) => { const stateToProps = (state, ownProps) => {
const channelId = ownProps.match.params.id; // NOTE: kind of a hack, but it works and idk if theres any other solution const channelId = ownProps.channelId;
return { return {
channels: state?.channels,
channel: state?.channels?.find(x => x._id === channelId), channel: state?.channels?.find(x => x._id === channelId),
messages: state?.messages[channelId] || [], messages: state?.messages[channelId] || [],
selectedChannelId: state?.selectedChannelId,
experiments: state?.experiments || {},
channelPresenceClientList: state?.channelPresenceClientList, channelPresenceClientList: state?.channelPresenceClientList,
gradientBannerNotificationText: state?.gradientBannerNotificationText
}; };
}; };

View file

@ -4,12 +4,12 @@ import Root from '../Home/Root';
import Authenticator from '../../API/Authenticator'; import Authenticator from '../../API/Authenticator';
import Notification from '../UI/Notification'; import Notification from '../UI/Notification';
import './../../Styles/App.scss'; import './../../Styles/App.scss';
import ChannelView from '../Channels/ChannelView';
import Sidebar from '../UI/Sidebar'; import Sidebar from '../UI/Sidebar';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { useDispatch, connect } from 'react-redux' import { useDispatch, connect } from 'react-redux'
import { BrowserRouter, Switch, Route } from 'react-router-dom'; import { BrowserRouter, Switch, Route } from 'react-router-dom';
import LoggedInMount from './LoggedInMount';
function App({ user }) { function App({ user }) {
const [ notificationText ] = useState(''); const [ notificationText ] = useState('');
@ -37,14 +37,7 @@ function App({ user }) {
<Route path="/login" component={ Login } /> <Route path="/login" component={ Login } />
<Route path="/create" component={ Create } /> <Route path="/create" component={ Create } />
<Route path="/channels/:id" <Route path="/channels/:id"
render={(props) => { render={() => <LoggedInMount />}
return (
<>
<Sidebar />
<ChannelView match={ props.match } />
</>
);
}}
/> />
<Route path="/"> <Route path="/">

View file

@ -0,0 +1,11 @@
import { useParams } from "react-router-dom";
import Sidebar from "../UI/Sidebar";
import ChannelView from "../Channels/ChannelView";
export default function LoggedInMount() {
const { id: channelId } = useParams();
return <>
<Sidebar />
<ChannelView channelId={ channelId } />
</>;
}

View file

@ -0,0 +1,5 @@
export default function GradientBanner() {
return (gradientBannerNotificationText !== undefined) && <div className="gradient-banner-card" onClick={ () => dispatch({ type: "application/updatebannertext", text: undefined }) }>
{ gradientBannerNotificationText }
</div>;
}

View file

@ -6,7 +6,7 @@ import { connect } from 'react-redux';
function Sidebar({ user }) { function Sidebar({ user }) {
return ( return (
<div className="main-card sidebar"> <div className="sidebar">
<div className="bar-card" style={{ <div className="bar-card" style={{
color: "var(--darker-text-color)" color: "var(--darker-text-color)"
}}> }}>

View file

@ -16,7 +16,7 @@
background: var(--accent-color-light); background: var(--accent-color-light);
} }
::-webkit-scrollbar-thumb { ::-webkit-scrollbar-thumb {
background: var(--default-main-card-color); background: var(--default-scrollbar-color);
} }
body { body {
@ -29,6 +29,15 @@ body {
padding: 0px; padding: 0px;
} }
* { button,
font-size: 18px !important; input,
optgroup,
select,
textarea {
font-family: inherit;
font-size: 100%;
}
* {
font-size: 18px;
} }

View file

@ -14,7 +14,6 @@
&-channel { &-channel {
@extend .button; @extend .button;
box-shadow: none;
border-radius: var(--channel-button-border-radius); border-radius: var(--channel-button-border-radius);
width: 200px; width: 200px;
min-height: 40px; min-height: 40px;

View file

@ -1,9 +1,8 @@
@mixin card { @mixin card {
padding: 0px; padding: 0px;
margin: 0px; margin: 0px;
background-color: var(--default-main-card-color); background-color: rgba(0, 0, 0, 0);
border-radius: var(--default-border-radius); border-radius: var(--default-border-radius);
box-shadow: 0px 1px 1px var(--card-box-shadow-color);
} }
// hh // hh
@ -23,7 +22,7 @@
align-items: center; align-items: center;
justify-content: left; justify-content: left;
font-size: medium; font-size: medium;
z-index: 100; z-index: 10;
&-accent { &-accent {
@extend .bar-card; @extend .bar-card;
@ -37,23 +36,14 @@
@include fancy-scrollbar-firefox; @include fancy-scrollbar-firefox;
background-color: var(--channel-message-list-background-color); background-color: var(--channel-message-list-background-color);
box-shadow: none;
flex-basis: 100%; flex-basis: 100%;
border-radius: 0px; border-radius: 0px;
overflow: auto; overflow: auto;
} }
.main-card {
@include card;
box-shadow: none;
}
.col-flex-card { .col-flex-card {
@include card; @include card;
box-shadow: none;
flex-grow: 1; flex-grow: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -62,8 +52,6 @@
.row-flex-card { .row-flex-card {
@include card; @include card;
box-shadow: none;
flex-grow: 10; flex-grow: 10;
display: flex; display: flex;
flex-direction: row; flex-direction: row;

View file

@ -10,6 +10,7 @@
.sidebar { .sidebar {
@include fancy-scrollbar-firefox; @include fancy-scrollbar-firefox;
@include card;
background-color: var(--channel-list-background-color); background-color: var(--channel-list-background-color);

View file

@ -1,8 +1,6 @@
.message { .message {
@include card; @include card;
box-shadow: none;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
margin: 3px; margin: 3px;

View file

@ -79,17 +79,17 @@
} }
.default-channel-styled-text { .default-channel-styled-text {
font-size: 24px !important; font-size: 24px;
filter: drop-shadow(2px 2px hsl(300, 60%, 25%)); filter: drop-shadow(2px 2px hsl(300, 60%, 25%));
user-select: none; user-select: none;
&.no-messages-text { &.no-messages-text {
filter: drop-shadow(45px 0 hsl(300, 60%, 40%)); filter: drop-shadow(45px 0 hsl(300, 60%, 40%));
font-size: 8em !important; font-size: 8em;
} }
} }
.default-user-styled-text { .default-user-styled-text {
font-size: 24px !important; font-size: 24px;
user-select: none; user-select: none;
} }

View file

@ -13,6 +13,6 @@
height: 32px; height: 32px;
padding: 6px; padding: 6px;
padding-left: 16px; padding-left: 16px;
font-size: 16px !important; font-size: 16px;
} }
} }

View file

@ -1,4 +1,4 @@
@mixin fancy-scrollbar-firefox { @mixin fancy-scrollbar-firefox {
scrollbar-width: none; scrollbar-width: none;
scrollbar-color: var(--default-main-card-color) var(--accent-color-light); scrollbar-color: var(--default-scrollbar-color) var(--accent-color-light);
} }

View file

@ -5,8 +5,7 @@
--card-accent-color: hsl(0, 0%, 10%); --card-accent-color: hsl(0, 0%, 10%);
--card-accent-color-dark: hsl(0, 0%, 5%); --card-accent-color-dark: hsl(0, 0%, 5%);
--default-main-card-color: var(--background-color); --default-scrollbar-color: var(--background-color);
--card-box-shadow-color: 0 1px 0 #1d1a1abe;
--focus-accent-background: var(--card-accent-color); --focus-accent-background: var(--card-accent-color);
--focus-accent-background-deep: var(--card-accent-color-dark); --focus-accent-background-deep: var(--card-accent-color-dark);