Test it out at otp-siege.herokuapp.com
An app that helps ๐ Six Siege players find other ๐ Six Siege players who are also looking for ๐ Six Siege players...to play ๐ Six Siege. And make friends.
- โ
Login
via Discord OAuth - โ In the
settings
page, setup your profile w/ your rank, your favorite attacker + defender, as well as images, links to your social media accounts, etc. - ๐ Save and go check out other people who have created profiles on the site!
- ๐ Swipe right on a profile to wait for a connection, or swipe left to pass.
- ๐ If the other person swipes right, its a match!
- ๐ Once you've matched, they'll show up in your
matches
tab. - ๐ Send them a discord friend request, or chat with them directly through the
chat
tab.
- โญ React
- โญ Typescript
- Express
- TypeORM
- Postgres
- Node
- ๐ฎ Discord OAuth
- โ๏ธ Cloudinary
To help manage state on a global level, and provide components on nonlinear branches with access to data without passing props around like a hot ๐ฅ, we used Redux (specifically, Redux Toolkit). This meant that we could store data in our central Redux store and access that data from any component without the need to pass that data in as props.
To oversimplify, like with state, we initialize any variables (like stuff=0
) we want in Redux and create a action for it (like setStuff
). When we want to update the state, we use the dispatch()
function and dispatch the data we want to set inside the set action we want to call. Dispatch will then go to the store where it compares the action we want against all the available actions, and will update the initial data with the dispatched data once a matching set action is found. Then we can call that updated data from the store using useSelector()
In OTP, Redux is used to store things such as the user's profile information upon loading the page, as well as the matches and chats they currently have. This frees us from making multiple similar api calls in different components. Saving information passed back from the socket in the store also allows for automatic responsiveness without having to reload when recording other user's sockets logging on/off when it comes to chat functionality.
const rootReducer = combineReducers({
// the 3 main reducers, each reducer holds data
// at a global level and is organized by what type of data it holds
profile: profileReducer,
match: matchReducer,
chat: chatReducer,
});
const store = configureStore({
// combines all the reducers into one
reducer: rootReducer,
});
// ...
// disptching
dispatch(initializeProfile(profileResponse));
// selecting
const rank = useSelector((state: RootState) => state.profile.rank);
WebSockets
allow for a persistent and open two-way communication channel between the client and the server. Servers can push information to clients, and so we don't need to constantly ping the API to check if there is any new information. This is especially useful for real-time functionality, like chat
. However, since websockets keep a constantly open connection, it can consume large amounts of your server's resources. And too many open connections to your database can โ it.
socket.io
is a JS library that uses the WebSocket protocol and allows for real-time, bi-directional connection between clients and the server.
OTP uses socket.io to create open WebSocket connections during while the client is interacting with the page. Each user has their own open socket which we track and identify.
with this, we can send chat messages from one user to another specific user
, and broadcast online/offline status'
.
import io from 'socket.io-client';
// client visits the page and their socket is sent to the server to be logged
//...
// conect to socket
const socket = io(API!);
// set the socket with the socket instance
setSocket(socket);
//socket instance.emit('event name', message being passed back)
socket.emit('sendMyId', discordId);
// getting the online/offline status of all the sockets that are online
// this is then mapped to a user's chats to see who is online or not
//...
socket.on('onlineChats', (onlineChats: string[]) => {
dispatch(setOnlineChats(onlineChats));
});
socket.on('nowOnline', (onlineId: string) => {
dispatch(setOnlineChat(onlineId));
});
socket.on('nowOffline', (offlineId: string) => {
dispatch(setOfflineChat(offlineId));
});
- ๐ Typescript when you try to write bad code.
- ๐ฅด Javascript when you write bad code. OTP was first written in JS and then converted to TS. TS is mean but it protects you from yourself and your own bad code.
// from interfaces.ts
export interface OTPRequestInit extends RequestInit {
headers?: HeadersInit | OTPHeaders;
}
You can only enter chats where you have matched ๐ with the other person. Otherwise you get the ๐ข.
const checkMatch = matches.filter(
(match, i) => buddyId === match.liker.discordId
);
Sockets are leveraged to check who is online and who is offline.
The buttons wiggle and changed based on where you are. I think its fun. ๐ค
useEffect(() => {
setBack(window.location.pathname === '/');
}, [location]);
If you're not logged in, you can't access any of the protected pages.
Lookup tables for all the att/def operators, and social media sites so we could save ourselves from some typing.