# Frontend Docs

## Architecture Guidelines

1 .
**New module** is a new microservice.

- Should be created per each unique page
- Should be created directly in /src folder

2 .
**Module folder structure** must be organized:

**/containers**

- Folder for smart containers
- Redux connected components only
- No layout and no html in these files!!!
- No styled components and styling classes in render methods
- Group containers by feature if there are more than 3 files per feature

**/components**

- Folder for Dump component
- No redux here!!!
- Only layout and props reuse
- There are no styled-components in these folders
- Group components by feature if there are more than 3 files per feature

**/loadable**

- Folder for loadable entities for lazy loading of components (React.lazy)

**/hoc**

- Folder to keep high order components

**/s-components**

- Folder to keep styled components
- All files will have s- prefix and the same prefix will have the names of these components
- Group styled-components by feature if there are more than 2 files per feature

**api.ts**

- File to keep only api call methods

**selectors.ts**

- File to keep simple selectors
  - makeSelector syntax should be useв - which just returns createSelector
- createStructuredSelector function from 'reselect' should be used in smart containers
- Links to read: https://medium.com/@parkerdan/react-reselect-and-redux-b34017f8194c
- About makeSelector() syntax https://blog.isquaredsoftware.com/2017/12/idiomatic-redux-using-reselect-selectors/
- About createStructuredSelector() https://github.com/reduxjs/reselect#createstructuredselectorinputselectors-selectorcreator--createselector

**epics.ts**

- File to keep all epics logic

**reducer.ts**

- Reducer follows ducks modular architecture https://github.com/erikras/ducks-modular-redux

**transducers.ts**

- Pure functions (mappers) which only transform one data structure into another
- All algorithms and data manipulations should be here.
- Not in components! Not in selectors!

**constants.ts**

- File to keep all constants which belong to this module

**types.ts**

- File to keep shared types of this module in case using flow type checking

3 .
**App module** is the main module where all modules are combined.
Redux store is setup here. Ideally app module shouldn't have own reducer

- Redux setup here
- Root reducers are configured here
- Root epics are here
- This module shouldn't have its own reducer - it's only to combine all app modules
- Theme provider for styled components is configured here
- Persist gate and AsyncStorage connection
- Application routing is inside /navigation

4 .
**Common module** is to keep all shared among the app functionality
Ideally all general application logic should be inside common reducer.

- Common dictionaries should be created here and appropriate high order components placed to `/hoc` folder
- `yarn gen dictionary` command should be used to generate dictionary in any module!!!
- `utils/api-rx` and `utils/api` Api service (1-st rx.js based, 2-nd promised based)
- `containers/dynamic-form` incapsulates redux-form setup
- `utils/fp.js` - functional utils
- `utils/navigation-service` for navigation helper

5 .
**/auth** folder responds for everything related to authorization

6 .
**New modules**

- Root container of the module by default should inject own reducer and epics anisochronously
  - `withReducer({{moduleName}}, reducer)`
  - `withEpics({{moduleName}}, epics)`
- All files except containers should not use default export

7 .
**Styling and Styled-components**

- Styled-components examples https://medium.com/@pitipatdop/10-useful-tips-for-styled-components-b7710b021e6a
- Theme file should be used in all styled components

8 .
**../assets** contains static files

9 .
**Functional programming**

- All methods should be implemented and invoked in a functional way https://github.com/hemanth/functional-programming-jargon
- `src/common/utils/fp` - is a core of all auto curried pure functions
  - Lodash, Ramda and own methods should be reexported and implemented in this file
- Examples:
  - `_.map(mapper)(arr)`
  - `_.filter(predicate)(arr)`
  - `_.compose(_.filter(predicate), _.map(mapper))(arr)`
- `src/common/utils/fp-loggers` - are included in fp.js - to debug compositions

10 .
**Plop.js** is used to generate most of entities in the application https://plopjs.com/

- `yarn gen` command should be run in the terminal to start code generation
- When you memorize your favourite generator you can call it without navigation in terminal:
  - `yarn gen component` or
  - `yarn gen component component-name` or
  - `yarn gen component component-name module-name` etc.
- Files and entities such as redux actions and async epics shouldn't be created manually
- All generators ar inside `/plop` folder
- `/plop/generators` to describe new generators
- `/plop/templates` to create new templates for generators

11 .
**Naming conventions**

- `file-names`, `folder-names` should be in `dashed-case`
- `variableNames` and `propertyNames` should be in `camelCase`
- `CONSTANT_NAMES` should be in `CONSTANT_CASE`
- `class-names` must follow BEM "Two Dashes style" Naming Convention
- `underscored_case` is DEPRECATED

## Installation

```
$ yarn install
```

## Running

```
$ yarn start
```

## Scripts section

- `yarn debug` - open react native debugger
- `yarn qa` - run all linters before merge request

## Storybook

- Shown in drawer navigation in development mode
- Generate new story
  - `yarn gen story`

## Unit tests

- Run
  - `yarn test:gui`

## Tips

- To measure everything inside mac os
  - [QuickLens](https://quicklens.app/)
- To measure random sizes inside invision
  - [Dimensions](https://chrome.google.com/webstore/detail/dimensions/baocaagndhipibgklemoalmkljaimfdj)
  - [Page Ruler](https://chrome.google.com/webstore/detail/page-ruler/emliamioobfffbgcfdchabfibonehkme)
  - [Design Grid Overlay](https://chrome.google.com/webstore/detail/design-grid-overlay/kmaadknbpdklpcommafmcboghdlopmbi)
  - [MB Ruler](https://chrome.google.com/webstore/detail/mb-ruler-for-chrome/amljbooecondkehcjahklnjokfohkfnk)
- React-tips connect
  - [react-tips connect](https://github.com/streamich/react-use/issues/187#issuecomment-481659574)
  - `import useTitle from 'react-use/lib/useTitle';`

## Git

- Git flow
  ![release diagram](docs/gitflow-new.png)

* Branch names

```
feature/XXX-1233-description-dash - branches with new functions, wich will be merged into for develop and develop2
bugfix/XXX-1235-description-dash  - branches with fixes for develop and develop2
hotfix/XXX-1234-description-dash  - branches with hot-fixes into master
merge/master-to-develop           - branches for PR one branch to another
```

- Commit messages
  - We use [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/)
  - Jira ticket must go inside message body in format: `- [XX-XXX] Short description`
  - If we have multiple tickets per commit they go inside body each per line in format: `- [XX-XXX] Short description`

* Feature Branching

```
git checkout develop
git fetch
git rebase
git checkout -b feature/XXX-42-short-desciption
git add .
yarn cz
git push
# Create pr of feature/XXX-42-short-desciption -> develop
# Squash + Rebase
```

- Production Hotfix Flow

```
git checkout master
git fetch
git rebase
git checkout -b hotfix/XXX-42-short-desciption

# In order to make OTA updates work:
# increment manually: `"channel": "production-vXX"` inside eas.json where XX is the major version from package.json

git add .
yarn cz
git push
# Create pr of hotfix/XXX-42-short-desciption -> master

**MERGE SHOULD BE DONE WITHOUT SQUASH AND REBASE**

# To upgrade develop after merging hotfix to master
git checkout develop
git fetch
git merge origin/master
#resolve conflicts if any
git checkout -b merge/master-to-develop
git add .
yarn cz
git push
# Create pr of merge/master-to-develop -> develop
```

## Making release/release candidate build

- Release version is based on the last stable `develop` branch version.
- Release version is created by freezing `develop` branch and switching development activities to `develop2` branch.
- Versioning inside `develop2` are incremented manually as `R` in format: `X.Y.Z-alpha.R`, where `X.Y.Z` == latest version of `develop` plus 1
- Every hotfix commit for release will increase patch version of the stable development branch after starting of release
- If we merge some fixes to the frozen release `develop` branch - then during merging to `develop2` the version in `develop2` should be incremented following the rule: `X.Y.Z-alpha.R` where `X.Y.Z` == develop latest version plus 1
  procedure (for example: stable develop before release - `1.1.79`, version of release after making 3 hotfixes - `1.1.82`). Than can be done by running `yarn semver` - short syntax to update patch level only.
- While preparing release no updates in scope of the current release are allowed.
- While preparing release no new functionality from future releases can be developed: only **in development** tasks can be finished.

## Semantic Versioning

Before each merge to develop branch app version should be
incremented following Semantic Versioning
[semver.org](https://semver.org/)

- You can increment the version manually or you can use generator:
- `yarn gen semver`
- `yarn gen semver patch`
- `yarn gen semver minor`
- `yarn semver` - short syntax to update patch level only

For example:

- develop branch before commit - `1.1.79`,
- `yarn gen semver patch` or `yarn semver`
- develop branch after commit - `1.1.80`

## Tagging release

- `git tag -a "vX.X.X" -m "Month DAY, YEAR"`, e.g. `December 17, 2020`
- `git push origin --tags`
- Release should be greate on github using this tag

## Writing changelog

### 📚 3rd party library updates

### 🛠 Breaking changes

### 🎉 New features

### 🐛 Bug fixes

## After release

We must merge master branch back to develop and increment minor version
of the app e.g. release version 1.0.99 -> becomes 1.1.0.
It will allow OTA updates work fine.
If we want to enforce users reinstall the app from AppStore then we
need increment the major version e.g. 1.0.99 -> becomes 2.0.0.
Also update production-vXX string inside eas.json file so that XX correspond
to the major version in package.json
Also don't forget to increment manually `versionCode` value in `app.config.ts`

## Expo Push Notifications Notes

- [About Firebase setup](https://blog.expo.io/android-gcm-notifications-are-going-away-7fc2ef5fa3e9)
- [Using FCM for Push Notifications](https://docs.expo.io/versions/latest/guides/using-fcm)
- Steps to integrate:
  - `https://console.firebase.google.com/project/{PROJECT_NAME}/settings/general/android:{app.json.expo.android.package}`
  - Download `google-service.json`
  - At the top of the sidebar, click the gear icon to the right of Project Overview to go to your project settings.
  - Click on the Cloud Messaging tab in the Settings pane.
  - Copy the token listed next to Server key.
  - Run `expo push:android:upload --api-key <your-token-here>`, replacing <your-token-here> with the string you just copied.

## Remote logging

- In env.ts inside any release channel add the following:
  `devRemoteLogApi: 'http://socket-io-example.sony.com/',`
- Implement socket.io node.js server on `http://socket-io-example.sony.com/` to receive log messages in real time
