Home

Awesome

Flipr

Flipr, a web application similar to Flickr, allows users to upload and share photos with others. Users would also be able to explore the photos uploaded by others, collect these into their own album, and comment on each others' submissions.

HomePage

Features

Overall Site Design

Background Image

The background image is only shown at the splash page, the log-in and sign-up pages. All other pages have a white background instead. To dynamically switch the background based on a user's location, I took advantaged of componentDidMount and componentWillUnmount React functions in the splash, log-in, and sign-up pages' components:

componentWillUnmount() {
  let removeBackground = $(".background");
  removeBackground.removeClass("background");
  removeBackground.addClass("backgroundHidden");
}

componentDidMount() {
  let addBackground = $(".backgroundHidden");
  addBackground.removeClass("backgroundHidden");
  addBackground.addClass("background");
}

Authentication

Password Storage

Instead of storing passwords in plaintext, flipr uses the BCrypt hashing function to store salted password digests in the database.

Session Token

Session tokens are generated using SecureRandom, and is cross-referenced against existing session tokens to ensure each user has a unique session token when logging in. Their session token is reset when logging out.

Restricted Paths

Using AuthRoute and ProtectedRoute defined with React's router functionalities, users are redirected to /#/login when trying to view contents that require a session token. Conversely, users are prevented from visiting /#/login and /#/signup pages when already logged in.

const Auth = ({component: Component, path, loggedIn, exact}) => (
  <Route path={path} exact={exact} render={(props) => (
    !loggedIn ? (
      <Component {...props} />
    ) : (
      <Redirect to="/" />
    )
  )}/>
);

const Protected = ({component: Component, path, loggedIn, exact}) => (
  <Route path={path} exact={exact} render={(props) => (
      loggedIn ? (
        <Component {...props} />
      ) : (
        <Redirect to="/login" />
      )
    )} />
);

const mapStateToProps = state => {
  return {loggedIn: Boolean(state.session.id)};
};

export const AuthRoute = withRouter(connect(mapStateToProps, null)(Auth));

export const ProtectedRoute = withRouter(connect(mapStateToProps, null)(Protected));

Photos

Explore

Explore

Users are able to view all the photos uploaded to flipr on this page., which is rendered using the column CSS properties. The page will dynamically adjust the number of columns and image sizes to ensure a uniform grid representation regardless of the user's display window size.

My Photos

Users are also able to view all of the photos that they themselves have uploaded to flipr. The photos are rendered in a similar fashion as the /#/explore page, both using the index function of the Photos controller:

def index
  puts(params)
  if params[:owner_id]
    @photos = Photo.where(owner_id: params[:owner_id])
  else
    @photos = Photo.all
  end
  render :index
end
Upload

Users are able to upload pictures, which are stored on the Amazon SW3 servers.

Technologies Used

Front-End

Back-End

Additional Resources and Future Implementations

Additional Resources

Future Implementations