presence, experiment overrides, design improvements
This commit is contained in:
parent
2f220e511e
commit
033d0e4da1
15 changed files with 99 additions and 44 deletions
|
@ -10,6 +10,8 @@ const opcodes = {
|
|||
2: { name: "YOO_ACK", data: "JSON" },
|
||||
3: { name: "ACTION_CREATE_MESSAGE", data: "JSON" },
|
||||
4: { name: "EVENT_CREATE_MESSAGE", data: "JSON" },
|
||||
5: { name: "ACTION_UPDATE_STATUS", data: "JSON" },
|
||||
6: { name: "EVENT_CHANNEL_MEMBERS", data: "JSON" },
|
||||
21: { name: "ACTION_VOICE_REQUEST_SESSION", data: "JSON" },
|
||||
22: { name: "EVENT_VOICE_ASSIGN_SERVER", data: "JSON" },
|
||||
23: { name: "ACTION_VOICE_CONNECTION_REQUEST", data: "JSON" },
|
||||
|
@ -84,6 +86,20 @@ GatewayConnection.prototype.connect = function(token) {
|
|||
this.ws.send(this.packet("YOO", { token }));
|
||||
break;
|
||||
}
|
||||
case "EVENT_CHANNEL_MEMBERS": {
|
||||
this.presence = {
|
||||
...this.presence,
|
||||
...packet.data
|
||||
}
|
||||
|
||||
for (const [userId, user] of Object.entries(this.presence)) {
|
||||
if (user.status <= 0)
|
||||
delete this.presence[userId];
|
||||
}
|
||||
|
||||
this.fire("presenceUpdate", this.presence);
|
||||
break;
|
||||
}
|
||||
case "YOO_ACK": {
|
||||
// Server accepted connection
|
||||
logGateway("Got YOO_ACK", packet.data);
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import GatewayConnection from './GatewayConnection';
|
||||
import config from '../../Config';
|
||||
import store from '../../Global/store';
|
||||
import logger from '../../Util/Logger';
|
||||
|
||||
const { warn } = logger(["Experiments"]);
|
||||
|
||||
const globalGatewayConnection = new GatewayConnection(config.gatewayUrl);
|
||||
|
||||
|
@ -8,13 +11,29 @@ globalGatewayConnection.onopen = (sessionData) => {
|
|||
store.dispatch({ type: 'gateway/connectionstatus', gateway: { isConnected: true } });
|
||||
store.dispatch({ type: 'authenticator/updatelocaluserobject', user: sessionData.user });
|
||||
store.dispatch({ type: 'channels/updatechannellist', channels: sessionData.channels });
|
||||
store.dispatch({ type: 'application/updateexperiments', experiments: sessionData.__global_experiments || [] });
|
||||
|
||||
if (localStorage.getItem("enableExperimentOverrides")) {
|
||||
warn("Experiment overrides are enabled");
|
||||
const experimentModifiers = JSON.parse(localStorage.getItem("experimentOverrides"));
|
||||
const experiments = {
|
||||
...sessionData.__global_experiments || {},
|
||||
...experimentModifiers || {}
|
||||
};
|
||||
store.dispatch({ type: 'application/updateexperiments', experiments });
|
||||
store.dispatch({ type: 'application/updatebannertext', text: "Experiment overrides are enabled! Things could go haywire!" });
|
||||
} else {
|
||||
store.dispatch({ type: 'application/updateexperiments', experiments: sessionData.__global_experiments || {} });
|
||||
}
|
||||
};
|
||||
|
||||
globalGatewayConnection.onmessage = (message) => {
|
||||
store.dispatch({ type: 'messagestore/addmessage', message });
|
||||
};
|
||||
|
||||
globalGatewayConnection.presenceUpdate = (presence) => {
|
||||
store.dispatch({ type: 'channels/updatepresence', clientListEvent: presence });
|
||||
};
|
||||
|
||||
globalGatewayConnection.onclose = function() {
|
||||
store.dispatch({ type: 'authenticator/updatelocaluserobject', user: undefined });
|
||||
store.dispatch({ type: 'gateway/connectionstatus', gateway: { isConnected: false } });
|
||||
|
|
|
@ -59,7 +59,7 @@ export default function Login() {
|
|||
<br />
|
||||
<input type="password" name="password" className="text-input" onChange={ ({ target }) => setPasswordInput(target.value) } />
|
||||
<br />
|
||||
<button id="login-submit" className="button" onClick={ handleLoginContinueButton }>Continue</button>
|
||||
<button id="login-submit" className="button-pressed" onClick={ handleLoginContinueButton }>Continue</button>
|
||||
<Notification text={ info } />
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,26 +1,14 @@
|
|||
import UserProfileButton from '../Users/UserButton';
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
function ChannelUserList({ channelPresenceClientList }) {
|
||||
const users = [
|
||||
{ username: "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", _id: "a" },
|
||||
{ username: "FDGFEGSDFHRFGHNERTYBNRNBTYJMNUM", _id: "b" }
|
||||
];
|
||||
|
||||
function ChannelUserList({ presence }) {
|
||||
console.log(presence);
|
||||
return (
|
||||
<div className="main-card sidebar">
|
||||
<div className="channel-list">
|
||||
{ users.map((user) => <UserProfileButton key={ user._id } user={ user } />) }
|
||||
{ Object.keys(presence).map((userId) => <UserProfileButton key={ userId } user={ presence[userId] } />) }
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const stateToProps = (state) => {
|
||||
return {
|
||||
channelPresenceClientList: state?.channelPresenceClientList
|
||||
};
|
||||
};
|
||||
|
||||
export default connect(stateToProps)(ChannelUserList);
|
||||
export default ChannelUserList;
|
|
@ -9,7 +9,7 @@ import { connect, useDispatch } from 'react-redux';
|
|||
import { useState, useRef, useEffect } from 'react';
|
||||
|
||||
|
||||
const ChannelView = ({ channels, messages, channel, selectedChannelId, experiments }) => {
|
||||
const ChannelView = ({ channels, messages, channel, selectedChannelId, experiments, channelPresenceClientList, gradientBannerNotificationText }) => {
|
||||
const { id } = useParams();
|
||||
const [ textInput, setTextInput ] = useState('');
|
||||
|
||||
|
@ -60,6 +60,10 @@ const ChannelView = ({ channels, messages, channel, selectedChannelId, experimen
|
|||
</button>}
|
||||
</div>
|
||||
|
||||
{(gradientBannerNotificationText !== undefined) && <div className="gradient-banner-card">
|
||||
{ gradientBannerNotificationText }
|
||||
</div>}
|
||||
|
||||
<div className="main-card row-flex-card hidden-overflow">
|
||||
<div className="col-flex-card channel-message-panel hidden-overflow">
|
||||
<div className="message-list-card">
|
||||
|
@ -71,7 +75,7 @@ const ChannelView = ({ channels, messages, channel, selectedChannelId, experimen
|
|||
<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>
|
||||
{ (experiments.userListTest) && <ChannelUserList /> }
|
||||
{ (experiments.userListTest) && <ChannelUserList presence={ channelPresenceClientList || [] } /> }
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
@ -100,7 +104,9 @@ const stateToProps = (state, ownProps) => {
|
|||
channel: state?.channels?.find(x => x._id === channelId),
|
||||
messages: state?.messages[channelId] || [],
|
||||
selectedChannelId: state?.selectedChannelId,
|
||||
experiments: state?.experiments || {}
|
||||
experiments: state?.experiments || {},
|
||||
channelPresenceClientList: state?.channelPresenceClientList,
|
||||
gradientBannerNotificationText: state?.gradientBannerNotificationText
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ export default function Root(props) {
|
|||
return (
|
||||
<div id="login-message-container">
|
||||
<h1>Welcome back!</h1>
|
||||
<button className="button" onClick={ () => { history.push('/login') } }>Log in</button>
|
||||
<button className="button-pressed" onClick={ () => { history.push('/login') } }>Log in</button>
|
||||
<button className="button" onClick={ () => { history.push('/create') } }>Create an account</button>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import defaultProfile from '../../Content/Images/defaultprofile_256px-256px.png'
|
||||
|
||||
// This is a mess pls fix later
|
||||
export default function ProfileLink({ object, size, type, offset=true, children=null }) {
|
||||
let picture;
|
||||
|
|
|
@ -2,7 +2,7 @@ import UserProfile from './UserProfileLink';
|
|||
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
export default function ChannelUserButton({ user }) {
|
||||
export default function ChannelUserButton({ user, subtext }) {
|
||||
const history = useHistory();
|
||||
|
||||
let buttonClasses = 'button button-channel';
|
||||
|
@ -13,7 +13,7 @@ export default function ChannelUserButton({ user }) {
|
|||
|
||||
return (
|
||||
<button className={ buttonClasses } onClick={ handleClick }>
|
||||
<UserProfile user={ user } size="32" />
|
||||
<UserProfile subtext={ subtext } user={ user } size="32" />
|
||||
</button>
|
||||
);
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
import ProfileLink from '../UI/ProfileLink'
|
||||
|
||||
// TODO: Stop using this component and just use the ProfileLink component
|
||||
export default function ChannelProfile({ user, size, offset=false }) {
|
||||
export default function UserProfile({ user, size, subtext }) {
|
||||
return (
|
||||
<ProfileLink object={ user } size={ size } type="user" offset={ offset } />
|
||||
<ProfileLink object={ user } size={ size } type="user" offset={ subtext !== undefined } children={ (subtext) && (<span>{ subtext }</span>) } />
|
||||
);
|
||||
}
|
|
@ -8,6 +8,7 @@ const intitialState = {
|
|||
gateway: { isConnected: false },
|
||||
messages: {},
|
||||
channelPresenceClientList: {},
|
||||
gradientBannerNotificationText: undefined,
|
||||
|
||||
selectedChannelId: undefined
|
||||
};
|
||||
|
@ -57,13 +58,10 @@ const reducer = (state = intitialState, payload) => {
|
|||
};
|
||||
}
|
||||
|
||||
case 'presence/channel/clientlistupdate': {
|
||||
case 'channels/updatepresence': {
|
||||
return {
|
||||
...state,
|
||||
channelPresenceClientList: {
|
||||
...state.channelPresenceClientList || [],
|
||||
[payload.clientListEvent.channel._id]: payload.clientListEvent.clientList
|
||||
}
|
||||
channelPresenceClientList: payload.clientListEvent
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -74,6 +72,13 @@ const reducer = (state = intitialState, payload) => {
|
|||
}
|
||||
}
|
||||
|
||||
case 'application/updatebannertext': {
|
||||
return {
|
||||
...state,
|
||||
gradientBannerNotificationText: payload.text
|
||||
}
|
||||
}
|
||||
|
||||
default: {
|
||||
return state;
|
||||
}
|
||||
|
|
|
@ -26,13 +26,13 @@
|
|||
&-pressed {
|
||||
@extend .button;
|
||||
|
||||
background-color: var(--button-selected-color);
|
||||
background: var(--focus-accent-background);
|
||||
color: var(--default-text-color);
|
||||
}
|
||||
}
|
||||
|
||||
.button:hover:not(.button-pressed) {
|
||||
background-color: var(--button-hover-color);
|
||||
background: var(--focus-accent-background-deep);
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 600px) {
|
||||
|
|
|
@ -68,3 +68,14 @@
|
|||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.gradient-banner-card {
|
||||
background: var(--default-user-background);
|
||||
height: 1.5rem;
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
border-radius: 0.3243rem;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
flex-direction: column;
|
||||
overflow: auto;
|
||||
overflow-x: hidden;
|
||||
min-width: 230px;
|
||||
min-width: 235px;
|
||||
}
|
||||
|
||||
.channel-list {
|
||||
|
|
|
@ -24,5 +24,5 @@
|
|||
|
||||
.message-content {
|
||||
padding-left: 6px;
|
||||
text-rendering: "optimizeLegibility";
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
|
@ -1,21 +1,33 @@
|
|||
:root {
|
||||
--background-color: #030303;
|
||||
--background-color: hsl(0, 0%, 1%);
|
||||
--default-text-color: hsl(0, 0%, 79%);
|
||||
--darker-text-color: hsl(0, 0%, 53%);
|
||||
--card-accent-color: hsl(0, 0%, 10%);
|
||||
--card-accent-color-dark: hsl(0, 0%, 5%);
|
||||
|
||||
--default-main-card-color: var(--background-color);
|
||||
--card-box-shadow-color: 0 1px 0 #1d1a1abe;
|
||||
|
||||
--default-text-color: #cacaca;
|
||||
--darker-text-color: #808080;
|
||||
--focus-accent-background: var(--card-accent-color);
|
||||
--focus-accent-background-deep: var(--card-accent-color-dark);
|
||||
|
||||
--card-accent-color: #212121;
|
||||
--focus-accent-color: hsl(246, 57%, 38%);
|
||||
--focus-accent-color-deep: hsl(255, 70%, 30%);
|
||||
--default-user-background: linear-gradient(
|
||||
to bottom right,
|
||||
hsl(275, 55%, 40%),
|
||||
hsl(300, 55%, 40%),
|
||||
hsl(325, 55%, 40%)
|
||||
);
|
||||
--default-channel-background: linear-gradient(
|
||||
to bottom right,
|
||||
hsl(150, 55%, 40%),
|
||||
hsl(175, 55%, 40%),
|
||||
hsl(200, 55%, 40%)
|
||||
);
|
||||
|
||||
--channel-top-bar-color-accent: var(--background-color);
|
||||
--channel-top-bar-color: var(--background-color);
|
||||
--bar-card-border-bottom: solid 1px #1d1d1d;
|
||||
--message-box-color: var(--card-accent-color);
|
||||
--message-box-shadow: #22222273 6px 8px 12px;
|
||||
--channel-top-bar-border-color: var(--accent-color-dark);
|
||||
|
||||
--channel-list-background-color: var(--background-color);
|
||||
|
|
Loading…
Reference in a new issue