add message component and fix gateway connection (?)

This commit is contained in:
hippoz 2021-01-08 00:53:42 +02:00
parent ba170ac632
commit f9a5f1698b
No known key found for this signature in database
GPG key ID: 7C52899193467641
12 changed files with 106 additions and 18 deletions

View file

@ -6,7 +6,7 @@
<title>Brainlet</title> <title>Brainlet</title>
</head> </head>
<body> <body>
<noscript>Sorry, but JavaScript is required to render and view this page.</noscript> <noscript>Sorry, but JavaScript is required to render and interact with this page.</noscript>
<div id="root"></div> <div id="root"></div>
</body> </body>

View file

@ -1,4 +1,5 @@
import APIRequest from './APIRequest'; import APIRequest from './APIRequest';
import gatewayConnection from './Gateway/globalGatewayConnection';
const Authenticator = { const Authenticator = {
getLoggedInUserFromCookie: async function() { getLoggedInUserFromCookie: async function() {
@ -6,6 +7,8 @@ const Authenticator = {
if (!isOK && err) throw new Error(err); if (!isOK && err) throw new Error(err);
if (!isOK && !err) return undefined; if (!isOK && !err) return undefined;
if (!json || !json.user) return undefined; if (!json || !json.user) return undefined;
// NOTE(hippoz): this function has a stupid side-effect but this will have to do for now...
gatewayConnection.connect(json.user.token);
return json.user; return json.user;
} }
}; };

View file

@ -11,7 +11,7 @@ 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';
function App({ user }) { function App({ user, gateway }) {
const [ notificationText, setNotificationText ] = useState(''); const [ notificationText, setNotificationText ] = useState('');
const [ hasError, setHasError ] = useState(false); const [ hasError, setHasError ] = useState(false);
@ -20,7 +20,7 @@ function App({ user }) {
useEffect(() => { useEffect(() => {
Authenticator.getLoggedInUserFromCookie() Authenticator.getLoggedInUserFromCookie()
.then((res) => { .then((res) => {
dispatch({ type: 'authenticator/updatelocaluserobject', user: res }) dispatch({ type: 'authenticator/updatelocaluserobject', user: res });
}) })
.catch(() => { .catch(() => {
setNotificationText(couldNotReach); setNotificationText(couldNotReach);
@ -28,17 +28,25 @@ function App({ user }) {
}); });
}, [dispatch]); }, [dispatch]);
if (user === null) {
return (
<p>
Loading...
</p>
);
}
if (!hasError) { if (!hasError) {
return ( return (
<div id="main-container"> <div id="main-container">
<div id="root-container" className="main-display"> <div id="root-container" className="main-display">
<BrowserRouter> <BrowserRouter>
{ user && <Sidebar /> }
<Switch> <Switch>
<Route path="/login"> <Route path="/login">
<Login /> <Login />
</Route> </Route>
<Route path="/categories/:id"> <Route path="/categories/:id">
<Sidebar />
<CategoryView /> <CategoryView />
</Route> </Route>
<Route path="/"> <Route path="/">
@ -61,6 +69,7 @@ function App({ user }) {
const stateToProps = (state) => { const stateToProps = (state) => {
return { return {
user: state?.user, user: state?.user,
gateway: state?.gateway
}; };
}; };

View file

@ -16,9 +16,9 @@ export default function CategoryProfile({ category, size }) {
} }
return ( return (
<div className="category-profile"> <div className="profile-link">
{ picture } { picture }
{ category.title } <span className="profile-username">{ category.title }</span>
</div> </div>
) )
} }

View file

@ -1,5 +1,6 @@
import CategoryViewLoader from './CategoryViewLoader'; import CategoryViewLoader from './CategoryViewLoader';
import CategoryProfile from './CategoryProfile'; import CategoryProfile from './CategoryProfileLink';
import Message from '../Messages/Message';
import { useParams } from 'react-router-dom'; import { useParams } from 'react-router-dom';
import { connect } from 'react-redux' import { connect } from 'react-redux'
@ -13,6 +14,19 @@ function CategoryView({ categories }) {
category = categories.find(x => x._id === id); category = categories.find(x => x._id === id);
} }
const dummyMessage1 = {
author: {
username: '__SYSTEM',
_id: '5fc69864f15a7c5e504c9a1f'
},
category: {
title: 'alan',
_id: 'y8fyerghgh'
},
content: 'yes hello',
_id: 'i8ru354y89ty549ytg'
};
if (category) { if (category) {
return ( return (
<div className="card main-card main-content-card"> <div className="card main-card main-content-card">
@ -20,8 +34,7 @@ function CategoryView({ categories }) {
<CategoryProfile category={ category } /> <CategoryProfile category={ category } />
</div> </div>
<div className="card message-list-card"> <div className="card message-list-card">
In terms of development, the first year of a cats life is equal to the first 15 years of a human life. After its second year, a cat is 25 in human years. And after that, each year of a cats life is equal to about 7 human years. <Message message={ dummyMessage1 } />
Cats can rotate their ears 180 degrees.
</div> </div>
<div className="card bar-card-bottom"> <div className="card bar-card-bottom">
The hearing of the average cat is at least five times keener than that of a human adult. The hearing of the average cat is at least five times keener than that of a human adult.

View file

@ -0,0 +1,10 @@
import UserProfileLink from '../Users/UserProfileLink';
export default function Message({ message }) {
return (
<div className="message">
<UserProfileLink user={ message.author } />
<span>{ message.content }</span>
</div>
);
}

View file

@ -1,13 +1,10 @@
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import Sidebar from './UI/Sidebar';
export default function Root(props) { export default function Root(props) {
const history = useHistory(); const history = useHistory();
if (props.user) { if (props.user) {
return ( return null;
<Sidebar />
);
} else { } else {
return ( return (
<div id="login-message-container"> <div id="login-message-container">

View file

@ -1,3 +0,0 @@
export default function UserLink({ user }) {
return null; // TODO: implement
}

View file

@ -0,0 +1,24 @@
import defaultProfile from '../../Images/defaultprofile_256px-256px.png'
export default function UserProfileLink({ user, size }) {
let picture;
if (!size) size = 32;
// TODO: Make a debug error message for then the size does not exist
const pictureClass = `profile-picture profile-picture-${size}`;
if (user.picture) {
// Not actually implemented on the server and can be unsafe, this is just futureproofing
picture = <img className={ pictureClass } src={ user.picture } alt="Profile"></img>
} else {
picture = <img className={ pictureClass } src={ defaultProfile } alt="Profile"></img>
}
return (
<div className="profile-link">
{ picture }
<span className="profile-username">{ user.username }</span>
</div>
)
}

View file

@ -1,6 +1,14 @@
import GatewayConnection from './GatewayConnection'; import GatewayConnection from './GatewayConnection';
import config from '../Config'; import config from '../Config';
import store from '../store';
const globalGatewayConnection = new GatewayConnection(config.gatewayUrl); const globalGatewayConnection = new GatewayConnection(config.gatewayUrl);
globalGatewayConnection.onConnect = function() {
store.dispatch({ type: 'gateway/connectionstatus', gateway: { isConnected: true } });
};
globalGatewayConnection.onDisconnect = function() {
store.dispatch({ type: 'gateway/connectionstatus', gateway: { isConnected: false } });
};
export default globalGatewayConnection; export default globalGatewayConnection;

View file

@ -45,6 +45,7 @@ body {
padding: 0px; padding: 0px;
color: var(--default-text-color); color: var(--default-text-color);
background-color: var(--background-color);
font-family: Noto Sans,-apple-system,BlinkMacSystemFont,sans-serif; font-family: Noto Sans,-apple-system,BlinkMacSystemFont,sans-serif;
} }
@ -169,13 +170,24 @@ body {
} }
} }
.category-profile { .profile-link {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
justify-content: left; justify-content: left;
} }
.profile-username {
font-weight: bold;
}
.message {
@include card;
display: flex;
flex-direction: column;
}
@media only screen and (max-width: 600px) { @media only screen and (max-width: 600px) {
.button.category-button { .button.category-button {
min-width: 50px; min-width: 50px;

View file

@ -1,6 +1,12 @@
import { createStore } from 'redux'; import { createStore } from 'redux';
const reducer = (state, payload) => { const intitialState = {
user: null,
categories: null,
gateway: { isConnected: false }
};
const reducer = (state = intitialState, payload) => {
switch (payload.type) { switch (payload.type) {
case 'authenticator/updatelocaluserobject': { case 'authenticator/updatelocaluserobject': {
return { return {
@ -16,6 +22,15 @@ const reducer = (state, payload) => {
} }
} }
case 'gateway/connectionstatus': {
return {
...state,
gateway: {
isConnected: payload.gateway.isConnected
}
}
}
default: { default: {
return state; return state;
} }