Skip to content

nypinstripes/stash-search

Repository files navigation

Stashy Logo

Stashy Tagline

(aka stash-search)

Stashy Launch

Tweet Stashy Open Stashy Code of Conduct

Mcconaughey Murray Murphy Aykroyd

  1. Setting up Stashy
  2. Specifications Checklist
  3. Application Architecture
  4. Pages & Previews
  5. TODOs

Setting up Stashy

Prerequisites

You will need the following things properly installed on your computer.

  • Homebrew  (or compatible Node installing package manager, mac-ports?)

  • Node.js (with Yarn or NPM)

Step 1: Check your node version & upgrade if needed.

$ node -v
v8.0.0 # if you see this or higher, you're good!

If not:

$ brew update
$ brew upgrade node

Step 2: Clone the "Stashy" (stash-search) repo & cd into the directory.

$ git clone [email protected]:nypinstripes/stash-search.git
$ cd stash-search

Step 3: Install App Dependencies with yarn or npm.

The app was initialized & built using Yarn, however it has been tested & confirmed to work with npm.

$ yarn install

or

$ npm install

Step 4: Build & Start the App (in Production Mode)

Individual build (dev/prod), test & server start commands can be found in the scripts hash in package.json.

$ yarn launch

or

$ npm start

Step 5: Running Tests

There are a few ways to run the Stashy test suite. Presently, only tests for renderring routes & persistant layout elements.

  • yarn/npm test to execute the test suite in single run mode & generate Jest snapshots.
  • yarn/npm test:update to execute the test suite in single run mode & update Jest snapshots that have changed.
  • yarn/npm test:watch to execute the test suite in constant watch mode & update Jest snapshots as they're changed.
  • yarn/npm test:coverage to view code coverage (lcov) & render performance reports using the built-in react tool (formerly Istanbul).

Specifications Checklist

  • The app serves a page consisting of a simple form with a text field and a button.
  • When the user enters text, use Javascript to request some GIFs from the Giphy API.
  • A user can click a GIF to add it to their "favorites".
  • A user can view another page which displays their favorite GIFs.
  • The GIPHY url used in the async operations, appears as https://api.giphy.com/v1/gifs/search with query params, api_key & q.
  • Use of the latest ES2017 (ES6) JS standard throughout the app.
  • Follow React, JSX, SASS, SVG, SSR & Accessibility Patterns, Best Practices & Platform Conventions.
  • Careful attention payed to UI/UX details, including responsive layout paradigms for use on multiple sized devices.
  • Install dependencies on yarn/npm install.
  • Build App & Start Server on http://localhost:3000/ with yarn launch or npm start.
  • Have Fun doing what we do best.

Application Architecture

Favorites Storage Strategy

In place of a database/api backend, I decided to use local storage to write favorite selections to and read them back from.

When you select a gif to add as a favorite:

  • A copy of the item's data is first written to LocalStorage.
  • It is also then added to the redux store.

When you deselect a gif to remove it from your favorites:

  • The LocalStorage favorites object is retrieved.
  • The item removed.
  • Then the modified favorites object is written back to LocalStorage.
  • Then LocalStorage is read from again which updates the favorites redux state and ensures the action's integrity.
Sync Favorites with Redux <> Local Storage

local storage favorites

The actions can be found in Action Requests.

Web Backend

NodeJS

The runtime environment (rte) is NodeJS and was written on v11.2.0, however it should be able to run without issue on any NodeJS version higher than 8.0.0.

In Lieu of not requiring the ability to load env/shell/docker variables, the launch/start commands will pass the GIPHY_API key to the server on start as a CLI parameter.

Express

The webserver is ExpressJS as it continues to be the more popular of the choices for running web backends on Node, Hapi would be a suitable alternative.

EJS

The server-side markup is renderred using the EJS templating engine, which has a high degree of reliability with build tools like Webpack however does have some drawbacks (with webpack), like not permitting the use of partials. Many suitable alternatives exist (Jade, Haml, Handlebars, dotJS etc.) and may be worth trying out next time.

UAParser

As a simple alternative to polyfilling with a library like modernizr, there's also a JS library I used called UAParserJS, which detects & extracts loads of useful info about the client machine upon the first request. With this info we can look at things like the client's user-agent to determine if their browser is among the ones that are supported.

The list of supported browsers can be found in the server helper utils file under agents.

In addition to helper functions, UAParserJS also offers fine-grain access to:

ua,
browser: { name, version },
engine: { name, version },
os: { name, version },
device: { model, type, vendor },
cpu: { architecture }

Build & Transpiler Tools

Frontend Application

React/Redux
Component Architecture

jsx structures

Sass (SCSS syntax)
The 7-1 Pattern

scss structures

App Styles

Folder Description
/base/.. Styles applicable globally, throughout the app, like browser resets/normalize files.
/common/.. Styles for visual elements with specific classes, but do not have components attached to them (e.g., .overlays, .animations). Files should be separated by their purpose.
/components/.. Styles applicable to individual components (these files are appended near the end and are overridden only by vendor styles).
/layout/.. Styles for standard elements that are persistent throughout the experience & on every page. Files should be separated by elements.
/vendor/.. Styles for elements that are particular to 3rd party plugin libraries and secondary browser type & version support. These styles load last and have the highest precedence.

Shared Sass Helpers /shared/data /shared/scss

Folder Description
_breakpoints Definition of app wide media query breakpoint rules, logic & utility.
_colors All colors should be predefined named variables sourced from the sip or swatches OSX apps, or similar interface (based on Chirag Mehta's famous "name that color" tool), or from formal design guides except those inherent to browsers W3 Color Names, which will not appear in this list. Please keep them alpha sorted, use all lower-case dasherized variable names.
_functions Sass helper functions - Things like custom short hand utilities for fonts, colors, borders etc.
_mixins Sass mixins
Vendor Libraries
Naming Colors Resources
Testing with Jest

jest structures

Snapshots are generated using the jest testing library, at present there are only basic Route/Layout load & render tests in the suite.

Pages & Previews

Previews

Search

404

Favorite

404

Pages

... Descriptions to follow

   404

404 404

   Favorites

favorites favorites

   Empty Favorites

favorites none favorites none

 Item Detail Overlay

item

   Landing

landing landing

   Stashy Search Results

results results

   No Results

results none results none

   Unsupported Browser

unsupported unsupported

Filler Docs Type Pages
(for wrangling text properties with new fonts)

TODOs

  • On List/Grid views, remove custom pagination & add Infinite (Fetch &) Scroll, with React-Virtualized.
  • Complete adding < Prev & Next > navigation controls on Item detail (ImageItemOverlay) view.
  • Handle item image (load & access) errors gracefully.
  • Make navigating between items in Item detail (ImageItemOverlay) views "perma-linkable" & update url on navigating.
  • Add tap, touch & swipe controls for mobile devices.
  • Add more tests & increase coverage & reliability.
  • Performance (loading, updating & painting) audit, with network optimized media sizes.
  • More inline Documentation!!
  • Perform more x-browser/device/OS UI/UX sanity/QA checking (currently only verified with Chrome).
  • Fix occasional flickers & jumps on toggling states in ListItem Stills & MP4s.
  • Fix occasional double render issues for lists on search.
  • Mock item share controls on the ListItem component and on the Item detail (ImageItemOverlay) view.
  • Make use of some of the deeper webpack optimization features like Tree-Shaking, CommonsChunking.
  • Attempt lazy component loading with System.import();
  • Use system memory / database to store favorites as opposed to LocalStorage.

About

A GIF Search Experiment

Resources

License

Code of conduct

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published