|
| 1 | +## Technologies used |
| 2 | + |
| 3 | +### Framework 🖼️ |
| 4 | + |
| 5 | +This app uses Expo which is a framework of React Native which simplifies the DX drastically for a lot of use cases. |
| 6 | + |
| 7 | +### Data Fetching ⬇️ |
| 8 | + |
| 9 | +The project uses `tanstack-query` library for its simplified data handling, automatic background refetching, and performance optimization |
| 10 | +through built-in caching. Its powerful DevTools and flexibility in supporting various use cases enhance our development |
| 11 | +efficiency, while an active community ensures we stay updated with the best practices. |
| 12 | + |
| 13 | +### Navigation 🧭 |
| 14 | + |
| 15 | +A significant majority of React Native projects use the `react-navigation` navigation library. This project, however, uses |
| 16 | +a file-based routing solution built on top of it by Expo, called `expo-router`. Expo-router comes with some additional features, |
| 17 | +such as deploying your application on the web in 3 different ways ('static', 'single' and 'server'). |
| 18 | + |
| 19 | +The 'static' export is what allows us to deploy the app to GitHub pages as a set of html files (hence the name "static"). |
| 20 | +This allows us to refresh the page without 404 errors unlike a "single" export (which would be the only option if we didn't use `expo-router`). |
| 21 | +However, there is currently a problem that comes up when deploying the app to GH Pages, which was patched in the `/patches/` folder. Currently, an issue |
| 22 | +in the Expo Github repo is created and assigned to a team member there. |
| 23 | + |
| 24 | +Each page is navigated to with a `backend` param so that the chosen instance link is determined by the URL and not the internal memory state. |
| 25 | +For example, if the user has `foo.bar` chosen in settings and gets a link to `owntube.tv/video?backend=bar.baz&id=123`, then they will watch a video from `bar.baz` that they were sent. |
| 26 | + |
| 27 | +The video page also has params such as `id` (the video uuid) and `timestamp` (the time when we want the video to start from when the link is opened) |
| 28 | + |
| 29 | +The settings page has only the `backend` param and uses it to show the currently selected instance, when the user select a new one they are "navigated" to the same page with a different `backend` param. |
| 30 | + |
| 31 | +### Video playback 📼 |
| 32 | + |
| 33 | +The turnkey solution for Expo apps is expo-video. However, this library is still in beta state and is considered unsupported |
| 34 | +on TV devices. So, the OwnTube.tv client uses an older `expo-av` library. |
| 35 | + |
| 36 | +A PeerTube instance outputs two variants when a video is fetched - either an mp4 video file, or an HLS streaming playlist, |
| 37 | +or both. However, not all videos have both, so we need to be able to play both variants. |
| 38 | + |
| 39 | +HLS is a technology which is not supported natively on desktop browsers except for Safari. Thus, we need a custom solution to support Chrome and FF. |
| 40 | +The `video.js` library includes the `hls.js` library which is used by PeerTube on the frontend in their custom peer-to-peer loader. However this custom loader is not |
| 41 | +necessary for the current needs of OwnTube.tv. |
| 42 | +In our case, a platform-specific component is used for the Web platform (React Native is able to determine where it is running and will supply the specific component). |
| 43 | +Through video.js we are converting the hls stream into a stream of mp4 chunks which are readable in any browser on the fly using ffmpeg, thus enabling the hls playback. |
| 44 | + |
| 45 | +The video controls are overlaid above the video player, this way the experience is unified regardless of the platform. |
| 46 | +You can skip 10 seconds in each direction, seek through the video, play/pause, mute. |
| 47 | + |
| 48 | +### Testing |
| 49 | + |
| 50 | +Jest is used throughout the app for testing, both for component tests and unit tests. For testing React components, the |
| 51 | +`@testing-library/react-native` package is used, which allows us to test components as real functioning entities, |
| 52 | +with state changes, user interactions etc. which in turn allows us to write tests similar to integration tests (e.g. user |
| 53 | +clicks X button and sees Y result). |
| 54 | + |
| 55 | +Data fetching is tested against a real peertube nightly instance, without mocking the API response. |
0 commit comments