diff --git a/bfrontend/src/API/Gateway/GatewayConnection.js b/bfrontend/src/API/Gateway/GatewayConnection.js index d0b9e3a..684db8f 100644 --- a/bfrontend/src/API/Gateway/GatewayConnection.js +++ b/bfrontend/src/API/Gateway/GatewayConnection.js @@ -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); diff --git a/bfrontend/src/API/Gateway/globalGatewayConnection.js b/bfrontend/src/API/Gateway/globalGatewayConnection.js index 90c8e32..c559694 100644 --- a/bfrontend/src/API/Gateway/globalGatewayConnection.js +++ b/bfrontend/src/API/Gateway/globalGatewayConnection.js @@ -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 } }); diff --git a/bfrontend/src/Components/Auth/Login.js b/bfrontend/src/Components/Auth/Login.js index f842e92..4d79df2 100644 --- a/bfrontend/src/Components/Auth/Login.js +++ b/bfrontend/src/Components/Auth/Login.js @@ -59,7 +59,7 @@ export default function Login() {
setPasswordInput(target.value) } />
- + ); diff --git a/bfrontend/src/Components/Channels/ChannelUserList.js b/bfrontend/src/Components/Channels/ChannelUserList.js index 59ab94c..74f56e6 100644 --- a/bfrontend/src/Components/Channels/ChannelUserList.js +++ b/bfrontend/src/Components/Channels/ChannelUserList.js @@ -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 (
- { users.map((user) => ) } + { Object.keys(presence).map((userId) => ) }
) } -const stateToProps = (state) => { - return { - channelPresenceClientList: state?.channelPresenceClientList - }; -}; - -export default connect(stateToProps)(ChannelUserList); \ No newline at end of file +export default ChannelUserList; \ No newline at end of file diff --git a/bfrontend/src/Components/Channels/ChannelView.js b/bfrontend/src/Components/Channels/ChannelView.js index 0761761..ed90a9c 100644 --- a/bfrontend/src/Components/Channels/ChannelView.js +++ b/bfrontend/src/Components/Channels/ChannelView.js @@ -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 } + {(gradientBannerNotificationText !== undefined) &&
+ { gradientBannerNotificationText } +
} +
@@ -71,7 +75,7 @@ const ChannelView = ({ channels, messages, channel, selectedChannelId, experimen setTextInput(target.value) }>
- { (experiments.userListTest) && } + { (experiments.userListTest) && }
) @@ -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 }; }; diff --git a/bfrontend/src/Components/Home/Root.js b/bfrontend/src/Components/Home/Root.js index 69e085f..4118647 100644 --- a/bfrontend/src/Components/Home/Root.js +++ b/bfrontend/src/Components/Home/Root.js @@ -9,7 +9,7 @@ export default function Root(props) { return (

Welcome back!

- +
); diff --git a/bfrontend/src/Components/UI/ProfileLink.js b/bfrontend/src/Components/UI/ProfileLink.js index 358dd66..22acb6b 100644 --- a/bfrontend/src/Components/UI/ProfileLink.js +++ b/bfrontend/src/Components/UI/ProfileLink.js @@ -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; diff --git a/bfrontend/src/Components/Users/UserButton.js b/bfrontend/src/Components/Users/UserButton.js index ea6fca4..30beefa 100644 --- a/bfrontend/src/Components/Users/UserButton.js +++ b/bfrontend/src/Components/Users/UserButton.js @@ -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 ( ); } \ No newline at end of file diff --git a/bfrontend/src/Components/Users/UserProfileLink.js b/bfrontend/src/Components/Users/UserProfileLink.js index b8c4176..fe46ca9 100644 --- a/bfrontend/src/Components/Users/UserProfileLink.js +++ b/bfrontend/src/Components/Users/UserProfileLink.js @@ -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 ( - + { subtext }) } /> ); } \ No newline at end of file diff --git a/bfrontend/src/Global/store.js b/bfrontend/src/Global/store.js index 83dcfda..d4e9fa6 100644 --- a/bfrontend/src/Global/store.js +++ b/bfrontend/src/Global/store.js @@ -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; } diff --git a/bfrontend/src/Styles/Components/Button.scss b/bfrontend/src/Styles/Components/Button.scss index 8f46f89..b7042dc 100644 --- a/bfrontend/src/Styles/Components/Button.scss +++ b/bfrontend/src/Styles/Components/Button.scss @@ -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) { diff --git a/bfrontend/src/Styles/Components/Card.scss b/bfrontend/src/Styles/Components/Card.scss index f476f74..1b9a29f 100644 --- a/bfrontend/src/Styles/Components/Card.scss +++ b/bfrontend/src/Styles/Components/Card.scss @@ -67,4 +67,15 @@ flex-grow: 10; 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; } \ No newline at end of file diff --git a/bfrontend/src/Styles/Components/Containers.scss b/bfrontend/src/Styles/Components/Containers.scss index f658c47..056a717 100644 --- a/bfrontend/src/Styles/Components/Containers.scss +++ b/bfrontend/src/Styles/Components/Containers.scss @@ -17,7 +17,7 @@ flex-direction: column; overflow: auto; overflow-x: hidden; - min-width: 230px; + min-width: 235px; } .channel-list { diff --git a/bfrontend/src/Styles/Components/Message.scss b/bfrontend/src/Styles/Components/Message.scss index 0f1cdb4..faace9c 100644 --- a/bfrontend/src/Styles/Components/Message.scss +++ b/bfrontend/src/Styles/Components/Message.scss @@ -24,5 +24,5 @@ .message-content { padding-left: 6px; - text-rendering: "optimizeLegibility"; + text-rendering: optimizeLegibility; } \ No newline at end of file diff --git a/bfrontend/src/Styles/root.scss b/bfrontend/src/Styles/root.scss index a77844c..dbd9888 100644 --- a/bfrontend/src/Styles/root.scss +++ b/bfrontend/src/Styles/root.scss @@ -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);