Unplanned is a location-based app that brings strangers together over coffee, food, or beer in the spur-of-the-moment. The catch is, they have to make a decision within 13 seconds of someone asking to meet up, otherwise, they'll lose the chance of meeting that person. The app's goal is to prevent us from overthinking decisions and encourage us to step out of our comfort zone to get to know people who we otherwise would never bother striking up a conversation.
- Usage
- Screenshots
- Getting Started
- Understanding the Code Base
- The Tech Stack
- Core Team
- Contributing
- Licensing
- Login with Facebook.
- Click on my profile to edit your contact information and profile
- Click on a user (represented by a marker) to view their profile
- Click on "Let's Meet" to send a meeting request
- Accept or reject a meeting request
- Enable sharing of location and microphone and video camera
Install Node and MongoDB in your development environment.
You'll also need to set up Facebook, Google Maps, and Peer JS API keys in order to develop for Unplanned:
Facebook Login Key/APP ID - Create a new Facebook App and retrieve the App ID. The Facebook callback URL should be set as http://localhost:8000/auth/facebook/callback, and then you will need to store your app ID in apiKeys.js inside of the public folder. apiKeys.example.js is provided as a template.
Google Maps API Key - You will need to store your Google Maps API key in apiKeys.js inside of the public folder. apiKeys.example.js is provided as a template.
PeerJS Key - For access to Video Calling. You will need to store your peer api key in apiKeys.js inside of the public folder. apiKey.example.js is provided as a template.
Finally, set up your Sublime Text with the ESLinter using Package Install. This is crucial to enforce linting convention. Use this guide to set up your Sublime for linting.
Everything else will be included inside NPM install.
From within the root directory:
npm install
After installing all dependencies, turn on MongoDB in terminal:
mongod
then run nodemon on the server.js file:
nodemon server/server.js
Webpack will automatically compile the code using the hotloader mechanism after the server starts; this could take a moment the first time. On completion, visit the localhost server on port 8000:
You'll be directed to the Splash page, and the app should be up and running.
EphemeralElixir
├── .github/
| └── PULL_REQUEST_TEMPLATE
|
├── client/
| └── components/
| | ├── meeting/
| | | ├── Accepted.jsx
| | | ├── CountdownTimer.jsx
| | | ├── RequestReceived.jsx
| | | └── RequestSent.jsx
| | |
| | ├── splash/
| | | ├── AboutTheDevelopers.jsx
| | | ├── Adventure.jsx
| | | ├── Splash.jsx
| | | └── Testimonial.jsx
| | |
| | ├── App.jsx
| | ├── EditProfile.jsx
| | ├── Gmap.jsx
| | ├── InsertBio.jsx
| | ├── Nav.jsx
| | ├── Options.jsx
| | ├── PeerConfig.jsx
| | ├── Popover.jsx
| | └── Socket.jsx
| |
| ├── public/
| | ├── assets/
| | | ├── font-awesome/
| | | ├── img/
| | | ├── fair.mp4
| | | ├── smoothscroll.js
| | | └── style.css
| | |
| | ├── index.html
| | ├── peer.js
| | └── webpack.min.js
| |
| ├── redux/
| | ├── actions.js
| | ├── reducer.js
| | └── store.js
| |
| └── webpackEntry.js
|
├── node_modules/
|
├── server/
| ├── config/
| | ├── middleware.js
| | └── socket.js
| |
| ├── users/
| | ├── userController.js
| | └── userModel.js
| |
| └── server.js
|
├── specs/
| └── socket-server-test.js
|
├── .eslintrc.js
├── .gitignore
├── _CONTRIBUTING.md
├── _PRESS-RELEASE.md
├── _STYLE-GUIDE
├── package.json
├── README.md
└── webpack.config.js
Using React, each component view have their own JSX file. If you would like to add a new feature, create a brand new component for it.
- Data is stored, maintained, and dispatched from the redux store
- Most of the socket event listeners are stored inside Socket.jsx
- The socket event emitters are stored inside of webpackEntry.js
- The components related to the main landing page (splash) are grouped together inside the splash/ directory.
- The components related to the meeting/rejecting requests are grouped inside the meeting/ directory.
- There are almost no HTTP ajax requests used in this application, so don't go lookin' for them.
- Most of the heavy-duty work is in socket.js
- The server uses sockets as a medium for clients to send and listen for individual requests. You can get really creative since it is very simple and flexible to use
- The server also makes use of Node Mailer (a javascript library) to handle sending emails to users
Server-side is heavily dependent on using websockets, since the app requires real-time data communication, especially with the video chat using Peer JS. We use the lightweight Socket.io JS framework to abstract and provide additionality functionality to work with websockets.
Keep in mind that socket connections are an upgraded version of HTTP, which effectively trims the data being sent back and forth between client and server (to a couple of bytes) and allows real-time communication. After the initial "handshake" between the server and client, the server does not need to wait for a request before sending back any data -- it can push data back and forth, to and from clients whenever it needs, through event emitters and event listeners.
Example usage:
const someHelperFunction = () => {
const bool = true;
const num = 10;
let obj = { me: 'Tai' };
let arr = [60];
// Client emitting an event to server, sending any number of arguments over
// Here, we are sending over some data as defined above
socket.emit('WriteYourOwnDescriptiveEventHere', "stringyyy", obj, arr, num, bool);
// FYI this could easily be the server emitting to a client as well.
};
//Invokes the function... it could be a click handler for example
someHelperFunction();
// Server or client listening for this specific event, and then accessing the
// arguments passed in through the callback function
socket.on('WriteYourOwnDescriptiveEventHere', function(str, obj, arr, num, bool) {
if (bool) {
obj[str] = arr;
obj[str].push(num, num + 2);
}
console.log(obj[str]); // { me: 'Tai', stringyyy: [60, 10, 12] }
});
Click here for a brief tutorial on sockets
Nice little cheat sheet for Socket.IO methods
This application is not database-heavy
- The schema is userID (unique), name, image url, email, and bio.
- The controller has three functions:
- Create and store a new user to the database
- Update an existing user's bio if they decide to change it
- Check for an existing user in the DB to see it needs to create and save a new one or retrieve
The current scope of testing is small. Feel free to add testing across the stack. Bless your heart if you can add testing for the front-end using React Test Utilities/Addons and React JSDOM.
Make sure mongod and nodemon is running, and then run the following code inside terminal:
mocha specs/socket-server-test.js
- Node
- Express
- MongoDB
- Mongoose
- Webpack, Webpack Hotloaders
- React, Redux, React Dom, React Google Maps
- Peer JS Video Streaming
- Node Mailer
- Eslint
- Babel
- Mocha
- Chai
- SocketIO
-
If you made a change but you're not seeing it reflect in the app, check the server (terminal) to see if webpack hot module loader compiled your code. Chances are, you have some linting issues that you need to make go away in order for webpack to compile.
-
Try testing using one of the computers using internet sharing, which will allow other macbooks in the same wifi network to connect directly to the same localhost. IE Sepehr starts up his server in his localhost and turns on internet sharing, Tai is able to go into the app by going to http://macla.local:8000 (assuming his macbook is named macla, etc..).
-
To set up unsecured testing so you can bypass the Chrome HTTPS requirement, run this in terminal:
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --user-data-dir=/tmp/foo -unsafely-treat-insecure-origin-as-secure="http://TYPE_THE_URL_HERE"
You'll want to fill out the actual URL of the person's laptop in order so Chrome will know.
- Product Owner: Leo Adelstein
- Scrum Master: Tai Huynh
- Development Team Members: Sepehr Vakili, Shane Hubbell, Leo Adelstein, Tai Huynh
- Fork the repo.
- Clone it to your local computer
- Cut a namespaced feature branch from master and name it appropriately
- Make commits and prefix each commit with the type of work you were doing
- BEFORE PUSHING UP YOUR CHANGES, rebase upstream changes into your branch, fix any potential conflicts, and then push to your fork.
- Submit a pull request directly to the master
- Someone else will perform code review to keep codebase clean
- Fix any errors or issues raised by the reviewer and push the fixes as a single new commit
- Repeat until the pull request is merged.
See CONTRIBUTING.md for contribution guidelines in detail.
M.I.T