# mobile-web

[![GitHub](https://img.shields.io/badge/-GitHub-24292e.svg?style=for-the-badge)](https://git-aws.internal.justin.tv/mobile-web/channel-lambda/tree/master/packages/mobile-web)
[![Wiki](https://img.shields.io/badge/-Wiki-4b367c.svg?style=for-the-badge)](https://wiki.twitch.com/display/ENG/Mobile+Web)
[![Architecture](https://img.shields.io/badge/-Architecture%20Documents-blue.svg?style=for-the-badge)](https://drive.google.com/drive/folders/1STYzY9VmxI01v8TUhYbKaPJYm6uUfhqV)
[![Analytics](https://img.shields.io/badge/-Mode%20Analytics-green.svg?style=for-the-badge)](https://modeanalytics.com/twitch/spaces/6405a1094dfe)
[![Jenkins](https://img.shields.io/badge/-Jenkins-yellow.svg?style=for-the-badge)](https://jenkins.internal.justin.tv/view/mobile-web/)
[![JIRA](https://img.shields.io/badge/-JIRA-orange.svg?style=for-the-badge)](https://jira.twitch.com/projects/MWC/summary)
[![Roadmap](https://img.shields.io/badge/-Roadmap-red.svg?style=for-the-badge)](https://wiki.twitch.com/display/ENG/Mobile+Web+Roadmap)

This is the package for the main mobile web codebase which is currently the:
* mobile web client
* mobile web lambda event handler (for backend rendering services)
* mobile web development server

The mobile web client is a universal SPA web client written in TypeScript and
served out of AWS lambda that provides a mobile-optimized user experience.

## Table of Contents

* [Quick Start](#quick-start)
  * [Setup](#setup)
    * [Updating Dependencies](#updating-dependencies)
  * [Working on a Ticket](#working-on-a-ticket)
* [Configure Your Editor](#configure-your-editor)
  * [VisualStudio Code](#visualstudio-code)
  * [Atom](#atom)
* [Testing](#testing)
* [Running the service](#running-the-service)
* [Translations](#translations)
* [Setting up experiments](#setting-up-experiments)
* [Background](#background)
* [Recommended Reading](#recommended-reading)
  * [General](#general)
  * [MWC\-Specific](#mwc-specific)
  * [Performance](#performance)
  * [Typescript](#typescript)
  * [React](#react)
  * [Redux](#redux)
  * [Webpack](#webpack)
  * [Other Tech](#other-tech)

## Quick Start

### Setup

* Run the commands from the [Getting Started](https://git-aws.internal.justin.tv/mobile-web/channel-lambda/blob/master/README.md#getting-started) section of the base [README](https://git-aws.internal.justin.tv/mobile-web/channel-lambda/blob/master/README.md).
* Run the following commands to create a mock function for testing the lambda.
    ```
    yarn build:client:prod
    yarn build:lambda
    ```

#### Updating Dependencies
The following command should be run from time-to-time to assure that no newly
added dependencies are missing.

  ```
  yarn setup
  ```

This is run initially by the `firstTime` script in the mono repo.

### Working on a Ticket

* Create a branch and give it a descriptive name that will allow others to know the purpose of the branch.
* Edit code as necessary and add tests.
* The following commands are useful to run during development.
    * `yarn start`
        * The server will be running on [localhost.twitch.tv:3003](http://localhost.twitch.tv:3003).
        * *Note: this will hot-reload the client on code changes, but not the server. If you alter the server code, you will need to restart this process to see changes.*
    * `yarn test:watch`
    * `yarn test:client:watch`
* Run `yarn prettier` to format your code according to team standards.
    * *Note: if you configure your editor as [defined below](#configure-your-editor) this step can be skipped.*
* Run `yarn ci` to verify that everything is working.
* Create a pull request against master.

## Configure Your Editor

### VisualStudio Code

If you are using VisualStudio Code you will get a list of recommended extensions
to install. These do a number of things to improve QOL, like auto-importing and
linting, as well as compliance, like running prettier. You should install these
extensions.

### Atom

If you are using Atom you should install the `prettier-atom` plugin. Once it is
installed you should configure it to `Format Files on Save`, use
`Single Quotes`, and to add trailing commas (`Trailing Comma` set to `all`).

## Testing

`yarn test` currently only runs tests through mocha, if you also want to run
tests through phantom then you'll also want to do `yarn test:client`.
`yarn test:watch` will have mocha run in test watching mode. It is a future
goal to have `yarn test:watch` to run tests through both mocha & through phantom
and it is a future, future goal to have them run through mocha and on a useful
environment, like the iOS or Android simulator (or both!). Until then you can
use `yarn test:client:watch` to have phantom watch and rerun tests. Add
`terminal-notifier` (`sudo gem install terminal-notifier`) if you want growl
notifications to work.

## Running the service

Right now the service is best run via `yarn start`. Once running,
react-hot-loader will propagate most of your changes automatically, but CSS
changes require a page refresh due to the CSS living in HEAD. There are
some other changes that require rebuilds, so you can fall back to restarting
the service if things aren't updating as you expect. As a last resort for any
weirdness, use `yarn cleanup` to destroy all build artifacts and start
totally fresh, because there are several caching layers in play when it comes
to hot-reloading and other features, and sometimes they don't properly
invalidate.

## Translations

If you are working with the translation files, there are a few things to note.
By default, most of the react-intl logging is disabled to limit console spam.
If you want more information about the keys being used or not used, run
`yarn start:intl` to get more detailed logging information. In this mode,
you'll see an initial pass of the react-intl manager showing no keys being
used, which you can disregard as that first pass is solely to help smooth our
build process. (You'll see a second pass when the server-side entry point goes
through transpilation and then a third when the hot-reloading client-side
entry point happens as well. Both of these are legit and should match.) When
you make changes to any file, just fully restart the server and they will show
up. If things are really acting wonky, trying using `yarn cleanup`.

To submit new strings for translation, add them to the `en-us.yaml` file and
then create a new LOC ticket by cloning the
[template](https://jira.twitch.com/browse/LOC-128). Then run `yarn i18n:submit`
and follow the CLI instructions, making sure to not re-submit previously
submitted strings.

## Setting up experiments

To set up an experiment, add a UUID and name/codename to `ExperimentUUIDs` and
`ExperimentNames` in `actions/experiments` and then create an action generator
that utilizes the `getRandomValue()` method to test against your desired
threshold:
```
const SHOW_CHAT_UUID = '2e0cb30b-7aaa-4e01-9fdd-b7046605b41f';
const SHOW_CHAT_NAME = 'SERPENTINE_AURA';
const SHOW_CHAT_THRESHOLD = 0.9; // show chat to 90% of users
function experimentsShowChat(deviceID: string): ExperimentsAction {
  const showChat = getRandomValue(SHOW_CHAT_UUID, deviceID) < SHOW_CHAT_THRESHOLD;
  return {
    type: EXPERIMENTS_CONFIGURED,
    payload: {
      uuid: SHOW_CHAT_UUID,
      name: SHOW_CHAT_NAME,
      group: showChat ? EXPERIMENT_TREATMENT : EXPERIMENT_CONTROL,
    },
  };
}
```

Then create selectors to convert the current user's experiment group
membership (recorded in the experiments reducer) into boolean you need:
```
function showChat(state: RootState): boolean {
  return state.experiments[SHOW_CHAT_NAME] === 'treatment';
}
```

You can create overrides in the action generator (optional parameters,
checking local storage, etc.) as well.

## Background

The channel-lambda repo is actually inaptly named as it is the complete mobile
web client. This will be fixed at a future date, probably before it matters
_too_ much.

The mobile web client is now mostly a single page app (SPA), but is in reality
a universal, multi-page app (MPA) because there are some pages to which a user
can't directly navigate from within the app. The MPA has 3 entry-points:

* The main app (directories, player pages, etc)
* The upsell page for unimplemented pages
* The events page for Oracle events

Additionally, there are 2 entry-points related to the "server" side of things:

* Dev server.
* Production lambda.

Please see READMEs in the various directories to get a better idea of the
specific parts.

## Recommended Reading

Note, not all the docs and videos listed here are things that MWC intends to
adhere to. However, having background on many approaches and ideas will improve
the discussion and, subsequently, the mobile web product.

### General
* [The Future of the Mobile Web](https://www.youtube.com/watch?v=rWYifOE8LDc&t=22s) - Paul Kinlan 2016 Strange Loop keynote. Very high level, but drives home some good points.
* [Building React Apps with Idiomatic Redux](https://egghead.io/courses/building-react-applications-with-idiomatic-redux) - General react/redux course
* [Organizing Large React Apps](http://engineering.kapost.com/2016/01/organizing-large-react-applications/) - Talks about approaches to organizing react/redux apps
* [SurviveJS Blog](http://survivejs.com/blog/) - Wide variety of JS topics covered on blog.
* [Getting Started with Progressive Web Apps](https://addyosmani.com/blog/getting-started-with-progressive-web-apps/)

### MWC-Specific
* [Mobile Web Device Testing](https://twitchtv.atlassian.net/wiki/display/MWC/Mobile+Web+Device+Testing) How to test on an actual device.
* [Mobile Web Technical Considerations](https://docs.google.com/document/d/1UvZGSRQVeunQk-ya1WN7qE4XUtzou37BPPxWFhHrG2w/edit#heading=h.e55lbiksicen)
* [Mobile Web (Generation 1)](https://docs.google.com/document/d/1ftLkYulSx6RIVdQA5arGuNw96AIWAH0Z9BqSzNdd_Fg/edit)
* [Device Perf Comparisons (work in progress)](https://docs.google.com/document/d/1lKmH69GUxAJHZ-ncYXzAg7gawbRcKxM9phDmt9USELc/edit)

### Performance
* [Planning for Performance](https://www.youtube.com/watch?v=RWLzUnESylc) - Talks about the constraints of performance on devices, very good.
* [Breaking the 1000ms Time to Glass Mobile Barrier](https://www.youtube.com/watch?v=Il4swGfTOSM) - Ilya goes into great depth about the performance of cellular networks.
* [Progressive Performance](https://www.youtube.com/watch?v=4bZvq3nodf4) - Alex talks about mobile performance, the whys and how to not be bad
* [PWAs across all Frameworks](https://www.youtube.com/watch?v=srdKq0DckXQ&t=15s) - Addy Osmani talk about performance with various frameworks
* [High Performance Browser Networking](https://hpbn.co/)
* [High Performance Images](https://community.akamai.com/docs/DOC-4088)

### Typescript
* [Typescript docs](https://www.typescriptlang.org/docs/tutorial.html)
* [Typescript Weekly](http://paper.li/ronniedrengen/1386937876)
* [React & Webpack](https://www.typescriptlang.org/docs/handbook/react-&-webpack.html) - Example TS that uses React, Redux, & TS

### React
* [React docs](https://facebook.github.io/react/docs/hello-world.html)
* [React tutorial](https://facebook.github.io/react/tutorial/tutorial.html)
* [React Fundamentals](https://egghead.io/courses/react-fundamentals)
* [Getting Started With React Router](https://egghead.io/courses/getting-started-with-react-router)
* [Performance without Compromise](https://www.youtube.com/watch?v=kDARP5QZ6nU)
* [High Performance Components](https://www.youtube.com/watch?v=KYzlpRvWZ6c)
* [Formatting with FormatJS & React-Intl](https://www.youtube.com/watch?v=I7IdS-PbEgI&t=318s)

### Redux
* [Redux docs](http://redux.js.org/)
* [Getting Started With Redux](https://egghead.io/courses/getting-started-with-redux)

### Webpack
* [Webpack docs](http://webpack.github.io/)
* [egghead.io webpack course](https://egghead.io/courses/angular-and-webpack-for-modular-applications)

### Other Tech
* [AMP](https://www.ampproject.org/) - Accelerated Mobile Pages, tech from Google that (a) improves load from Google search & (b) gets special treatment
