# Developing on the client

You want to work on our library and offer bug fixes or new features ? That's awesome ! 🤩

Here are some inputs about working with Panoramax web client code.

!!! note

    If something seems missing or incomplete, don't hesitate to contact us by [email](mailto:panoramax@panoramax.fr) or using [an issue](https://gitlab.com/panoramax/clients/web-viewer/-/issues). We really want Panoramax to be a collaborative project, so everyone is welcome (see our [code of conduct](https://gitlab.com/panoramax/clients/web-viewer/-/blob/develop/CODE_OF_CONDUCT.md)).

## Architecture

The current code is split between various elements:

- **Core components**: a single functional entry, like [Viewer](./reference/components/core/Viewer.md) (map + picture), [Photo Viewer](./reference/components/core/PhotoViewer.md) (picture only), [Coverage Map](./reference/components/core/CoverageMap.md) or [Editor](./reference/components/core/Editor.md). They share parts of code in [Basic](./reference/components/core/Basic.md) class. They specialized the behaviour of components depending on the needs.
- **UI components, menus & widgets**: reusable web components, like [Map](./reference/components/ui/Map.md), [Photo](./reference/components/ui/Photo.md) or [Loader](./reference/components/ui/Loader.md). They are used in some views depending of the context.
- **Utils**: utility functions, split into various files for clarity.

![Class diagram of Panoramax web viewer](./images/class_diagram.jpg)

The library is relies on various other libraries:

- [Lit](https://lit.dev/), for web components management
- [Photo Sphere Viewer](https://github.com/mistic100/Photo-Sphere-Viewer), for displaying classic and 360° pictures
- [Maplibre GL JS](https://github.com/maplibre/maplibre-gl-js), for displaying the map which shows sequences and pictures location
- [JS Library Boilerplate](https://github.com/hodgef/js-library-boilerplate), for having a ready-to-use development toolbox

## Good to know

### Components `z-index`

In order to offer a coherent overlay of widgets, we follow this general `z-index` ordering:

| Component type                    | Z-Index |
| --------------------------------- | :-----: |
| MapLibre GL & Photo Sphere Viewer | <= 110  |
| Widgets / Cornered Grid's corners |   120   |
| Togglable menus                   |   130   |
| Fullscreen loaders & popups       |   200   |

### Parameters handling

!!! note

    This concerns only __Viewer__ component. Editor & Coverage Map read input parameters only from Web Components attributes.

Viewer component can read parameters from 3 different sources:

- Web Component **attributes**, passed through DOM
- Browser **local storage**
- **URL search** parameters

This allows a flexible way to interact with viewer for users. Prioritization of parameters is managed by [InitParameters class](./reference/utils/InitParameters.md), URL parameters coming first, then local storage, to fallback with Web component attributes (and eventually some hard-coded defaults).

This means that, when developing, if you want to check if your attributes are well-defined, you may want to get rid of URL search parameters, as well as remove the `pnx-map-parameters` local storage item. Otherwise, they may not be read as they are lower priority than others.

### Third-party services URL

All third-party services URL (like geocoding API, OSM iD editor) are grouped into a dedicated `src/utils/services.js` file. You can easily change them to deploy a custom version of the viewer.

### Presets for semantics

The semantics system for sequences, pictures and annotations make use of **tagging presets**. These are JSON files hosted at [presets.panoramax.fr](https://presets.panoramax.fr/), they have their [dedicated Gitlab repository](https://gitlab.com/panoramax/server/tagging-presets).

In the viewer, they show up through icons and translated labels associated to pictures & annotations. If you want to change them, you have to edit them in Gitlab repository. Viewer automatically loads hosted files at start.

### Rendering on mobile

In order to improve performance, the 3D sphere used for projecting the picture on mobile has a lower amount of polygons, meaning a bit of distortions can appear on-screen. This is directly linked to [PSV Equirectangular adapter's resolution parameter](https://photo-sphere-viewer.js.org/guide/adapters/equirectangular.html#resolution).

![Comparative of mobile vs PC rendering](./images/comparative_3drender.jpg)

### Widgets breakpoints

To make default display more adaptative, many places in the _Viewer_ code uses breakpoints to have different rendering:

- Display height: 400px
- Display width: 576px
- Shown in iframe or not

These breakpoints are both used in CSS (with media-queries) or in JS (`isWidthSmall, isHeightSmall, isInIframe`).

## Testing

We're trying to make Panoramax as reliable and secure as possible. To ensure this, we rely heavily on code testing. A variety of testing tools is made available:

- `npm start` : launches a dev web server on [localhost:3000](http://localhost:3000)
- `npm run test` : unit testing
- `npm run lint` : syntax checks
- `npm run coverage` : amount of tested code

If you're working on bug fixes or new features, please **make sure to add appropriate tests** to keep Panoramax level of quality.

### Example pictures

As Panoramax accepts all kind of picture, we have a large variety of troubles that can come to display them. Here is a list of very different images (various types, orientation, metadata) that can be useful to check if your rendering is working well:

| UUID                                   | Type           | Heading | Comment                    |
| -------------------------------------- | -------------- | ------- | -------------------------- |
| `5bada38c-7cbc-4c81-a4d1-e39480fbec0b` | flat landscape | SE      |                            |
| `1d86cbbe-2293-4759-a4b6-23a815c49364` | flat portrait  | SW      |                            |
| `f21d15a7-7a48-4194-bef2-09f22db03225` | flat square    | NW      | roll/pitch                 |
| `b13976d5-fb07-44be-b6b6-2a2356a23cb8` | 360°           | W       |                            |
| `03f220b4-28b2-4104-bc64-bb9e41a8aa5d` | 360°           | W       | picture tags + annotations |
| `5d1800fd-44f6-446f-92b9-250f737c4b14` | 360°           | NE      | roll/pitch                 |
| `02b6dac1-6d6a-4568-9db4-f4b0219c03d3` | 360°           | E       | roll/pitch                 |
| `0552bbac-6054-41c1-b0d7-f06ffce7a56d` | 360°           | SW      | roll/pitch                 |
| `2f842858-2ada-4a25-a462-8d3bf256aca8` | H-cropped 360° | -       | annotations                |
| `66dbf066-cf13-4fe3-a32a-2210daaeb45d` | H-cropped 360° | ?       |                            |
| `adf47cb2-cddd-4a8b-a5c9-f64248b62f90` | H-cropped 360° | SW      |                            |
| `193245fa-3454-492a-b0fc-aa06feab772e` | 180°           | SE      |                            |

## Documentation

The documentation is a mix of:

- [JSDoc comments](https://jsdoc.app/about-getting-started) embed directly in source files, and exported in `docs/reference/` folder
- Higher-level docs as Markdown files, in `docs/` folder.

The JSDoc can be exported as Markdown using this command:

```bash
npm run doc
```

And all documentation can be previewed or built using [Mkdocs](https://www.mkdocs.org/):

```bash
pip install mkdocs mkdocs-material
mkdocs serve
mkdocs build
```

Online versions are available at:

- [docs.panoramax.fr](https://docs.panoramax.fr/web-viewer/) for **stable** version
- [viewer.geovisio.fr/docs](https://viewer.geovisio.fr/docs/) for **develop** version

## Make a release

See [dedicated documentation](./90_Releases.md).
