# @openstapps/app

[![pipeline status](https://img.shields.io/gitlab/pipeline/openstapps/app.svg?style=flat-square)](https://gitlab.com/openstapps/app/commits/main)
[![documentation](https://img.shields.io/badge/documentation-online-blue.svg?style=flat-square)](https://openstapps.gitlab.io/app)

This is a hybrid mobile app which is built using [Ionic](https://github.com/ionic-team/ionic) and [Angular] (https://angular.io/).

### Why not refactoring legacy app?

The StApps 1.x.x (legacy app, but current app in stores) is written using Ionic 1 framework (AngularJS). For StApps 2.x.x project (this repository) we want to use the latest version of Ionic (Ionic 2+ which uses Angular 2+; at the time of writing of the documentation current versions are: Ionic 4, Angular 6), which introduces significant changes. That said, simple refactoring of the app 1.x.x was not viable solution and this project was created with goal of coding of the existing and new features, defined by in new requirements (details available in internal documents).

## How to quickly start running the app?

There are (`npm`) scripts defined to get the app running as quickly as possible. Those scripts (shortcuts for docker commands) are called using the syntax `npm run + <script-name>`. So we have the following commands available:

```sh
npm run docker:pull
```

which pulls the up-to-date image ([Dockerfile](Dockerfile)) which contains all the tools needed for building, serving and deploying the app.

```sh
npm run docker:enter
```

which enters the container on docker builder image, where we can run `npm install` (to install the required npm packages) and `npm build` (to build the app: convert into executable files), but also any other arbitrary commands with the tools available in the docker image.

```sh
npm run docker:build
```

which runs `npm install` (to install the required npm packages) and `npm build` (to build the app: convert into executable files) in the docker container which runs on the docker builder image.

```sh
npm run docker:serve
```

which serves the app for running it in the browser. It basically runs `ionic serve` in the docker container (in the docker builder image).

## How to build and start the app using the default backend?

```sh
npm run build
npm run start
```

will build and serve the app using the configuration for a default backend.

## Further explanation of npm scripts

All the npm scripts are defined in `package.json` [file](package.json). It is recommended to open the file and check what these scripts exactly do.

## Most useful commands

### Editing the Ionic Database from the browser

Add the following function using the browser console

```js
function addToIonicDB(key, value) {
  indexedDB.open('_ionicstorage').onsuccess = event => {
    const db = event.target.result;
    db.transaction('_ionickv', 'readwrite').objectStore('_ionickv').put(value, key);
  };
}
```

You can then call the function in the browser to add values to the
ionic database in the IndexedDB.

For example, you can add a stored authorization like this:

```js
addToIonicDB(
  'token_response',
  JSON.stringify({
    access_token: 'AT-123-abcdefghi',
    refresh_token: 'RT-123-jklmnopqrs',
    scope: '',
    token_type: 'bearer',
    issued_at: 1696852785,
    expires_in: '28800',
  }),
);
```

You'll need to run _Chromium_ using

```sh
pnpm chromium:no-cors
```

### Help, I can't log in!

Login services will often block hosts not coming from the production
server.

#### Web

On the web you can circumvent this locally by using the `:virtual-host` scripts:

```sh
# Start the dev server on mobile.app.uni-frankfurt.de
pnpm start:virtual-host
# Run chromium with flags that redirect mobile.app.uni-frankfurt.de to localhost:8100
pnpm chromium:virtual-host
```

#### Android

On Android you will need to change the `custom_url_scheme` values
to `de.unifrankfurt.app` in the following files:

- `android/app/src/main/res/values/strings.xml`
- `src/environment/environment.ts`

Then start the app normally as you would

```sh
pnpm run:android
```

**This alone will not make auth work**, only the login flow.

If you need to test login, you have to disable live reload:

```sh
pnpm ionic capacitor run android
```

_**CAUTION:** a remote chrome debugging session can in some
cases hijack the device's ADB connection. If the connection
fails for no obvious reason, close chrome and uninstall the
app, then try again._

#### iOS

On Android you will need to change the `custom_url_scheme` value in
`src/environment/environment.ts` as well as the `CFBundleURLTypes`
in `ios/App/App/Info.plist`.

- make sure to remove any `Info.plist.orig` as capacitor might override
  the modified `Info.plist` with that.
- make sure you have a valid device in XCode (Simulator or real device).

After that, run

```sh
pnpm run:ios
```

### Running the app

Install the npm packages needed for running the app (as for any other node project which uses npm):

```sh
npm install
```

Check the code for linter issues:

```sh
npm run lint
```

Automatically fix linter issues (those where autofix is possible):

```sh
npm run lint:fix
```

Build the app (transpile etc.):

```sh
npm run build
```

Open the app in the browser:

```sh
ionic serve
```

### Android

Run the app for testing on an android device (with live reload in the webview / device, when files are changed):

```sh
npm run build # if needed
npm run resources:android # generate needed resources (icons and splashscreens)
npm run docker:run:android # runs "ionic capacitor run android --livereload --external" on a selected device
```

**Troubleshooting**: The device should be listed as the docker container where the run happens gets access to the USB devices. In case your device is not listed, it is possible that Chrome is blocking the access to it. Make sure `chrome://inspect` is not opened in your Chrome or any other program, which would block access to the device by using it on the host.

After the app is running on the android device you can use an IDE or Chrome to debug the WebView (JavaScript / Typescript) of the app (set breakpoints, watch variables, look at the call stack etc.).

For example in Chrome:

1. Open `chrome://inspect`
2. Click the App's WebView which is listed there (you can recognize it by the app's ID)
3. Go to `Sources` and add the app's folder to the `FileSystem`

Besides that, it is possible to monitor processes (and so the processes related to the app itself, using its ID) using [adb logcat](https://developer.android.com/studio/command-line/logcat), which you can run inside of the running container.

Build the (debug) app for testing on an android device (creates an APK file in the android's build outputs path):

```sh
npm run docker:build:android
```

The mentioned `docker:*:android` npm commands are executed in a docker container, so it is not mandatory to have the android (command line) tools installed on the host computer. Alternatively, you can install the tools and additionally Android Studio on the host machine and then run and build the app on the host (without using docker).

### Executing tests

Execute unit tests:

```sh
npm test
```

Execute e2e tests:

```sh
npm run e2e
```

As mentioned, we can always check the [package.json](package.json) for details on each npm script/command.

## Using Gitlab CI as a reference

As we use GitLab CI for building the app, running tests and deployment of the app, we can always refer to [.gitlab-ci.yml](.gitlab-ci.yml), file which shows us which commands (`script` part) should be run for each phase of the development process. We can use these commands to reproduce the same thing on our local computers in a docker container (as we can use the same docker image GitLab CI is using).
