Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Read Mes #12450

Open
wants to merge 10 commits into
base: latest
Choose a base branch
from
40 changes: 39 additions & 1 deletion src/app/components/MediaLoader/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
## Description

This component loads a media player into our webpage. It uses the BBC Universal Media Player module (BUMP) to choose the correct Embedded Media Player (EMP) for the user's device. Using BUMP removes the concerns involved in serving different devices and web-browsers as BUMP automatically provides the best fitting EMP for the client. For example, BUMP can cater for differences between mobiles, laptops and desktops, but also factors such as whether the user is using network data (3G) or a WIFI.
Simple English:
The MediaLoader takes data from the BFF and converts it into a settings object that BUMP can understand.

BUMP (BBC Universal Media Player module) is a module that embeds videos into a webpage. Its an alternative to the standard <video> interface in HTML5.

Long English:
The MediaLoader uses the BBC Universal Media Player module (BUMP) to choose the correct Embedded Media Player (EMP) for the user's device. Using BUMP removes the concerns involved in serving different devices and web-browsers as BUMP automatically provides the best fitting EMP for the client. For example, BUMP can cater for differences between mobiles, laptops and desktops, but also factors such as whether the user is using network data (3G) or a WIFI.

## Local Development

Expand All @@ -21,3 +27,35 @@ Currently, the EMP is set to only load Live video assets by default. To load tes
## Note on playback in local development

In the Next.js app we have `reactStrictMode: true`. This causes lifecycle hooks to be called twice in development mode. This can result in the media player being loaded twice, causing mulitple playbacks of the same media. This does **not** happen in production mode.

## Component Structure

Component file structure

├── MediaLoader
├── configs
├── aresMedia.ts
├── audio.ts
├── clipMedia.ts
├── legacyMedia.ts
├── liveMedia.ts
├── liveRadio.ts
├── tv.ts
├── index.ts
├── Placeholder
├── index.tsx

The MediaLoader component takes in a video block from the BFF and converts it into a BUMP settings object through the function in `configs/index.ts`. The BFF does not provide video blocks in a uniformed way, since our editors publish videos from different sources. For greater flexibility, we allow the BFF to provide video data in its native form and use a respective script within the configs folder to process the data into a BUMP settings object.

The following sources that our configs folder currently support are:
|Source|Description |
|--|--|
| aresMedia | |
| audio | For podcasts. |
| clipMedia | |
| legacyMedia | |
Comment on lines +116 to +119
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we try and find descriptions for these configs?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yesss, I was hoping to pair with Aaron at some point to get greater clarity on these ones.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or use co-pilot to help?

| liveMedia | For live content provided through Silver (SImple Live Video sERvice): [More information](https://confluence.dev.bbc.co.uk/display/LiveSchedule/Silver+-+Simple+Live+Video+Service) |
| liveRadio | |
| tv | |

**Important: The media loader will not play live videos on the test environment and vice-versa.**
100 changes: 77 additions & 23 deletions ws-nextjs-app/pages/[service]/live/[id]/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,45 @@

## Description

This is the first page to be created through our new NextJS app. It uses several NextJS features, including server side rendering and NextJS' pages router.
Live pages provide live media streams and posts updated in real time.

## BFF Response

A sample BFF response for a given Live page can be found here:
[BFF Send Response](https://fabl.api.bbci.co.uk/playground?env=production&module=simorgh-bff&params=id%3Dc7p765ynk9qt%3Btrue%2Cservice%3Dpidgin%3Btrue%2CpageType%3Dlive%3Btrue&context=ctx-service-env%3Dtest)

## How routes are handled

Our Live Page is served through the following route:
Our Live Page is served through the following route:
`/pages/[service]/live/[id]/[[variant]]`, where the double brackets in `[[variant]]` means that the variant is optional.

This route matches the file structure of this repo:
📦ws-nextjs-app
┗ 📂pages
┃ ┣ 📂[service]
┃ ┃ ┣ 📂live
┃ ┃ ┃ ┗ 📂[id]
┃ ┃ ┃ ┃ ┗ 📜[[...variant]].page.tsx
┃ ┃ ┗ 📜[[...]].page.tsx
┃ ┣ 📜_app.page.tsx
┃ ┗ 📜_document.page.tsx

Sample routes that match this construct are:

| Service | URL |
|----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Pidgin (no variant) | `/pidgin/live/cdvxv61l6x8t` |
| Serbian (with variant lat) | `/serbian/live/c003pmmldygt/lat` |
| Serbian | `/serbian/live/c003pmmldygt` This will ONLY work on your local host. This will NOT be served through the live NextJS app as upstream services are programmed to recognise an absence of the variant and it will instead re-route this request to alternative servers. |
This route matches the file structure of this repo:

├── ws-nextjs-app
├── pages
├── [service]
├── live
├── [id]
├── [[...variant]].page.tsx
├── [[...]].page.tsx
├── _app.page.tsx
├── _document.page.tsx

Sample routes that match this construct are:

| Service | URL |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Pidgin (no variant) | `/pidgin/live/c7p765ynk9qt` |
| Serbian (with variant lat) | `/serbian/live/c003pmmldygt/lat` |
| Serbian | `/serbian/live/c003pmmldygt` This will ONLY work on your local host. This will NOT be served through the live NextJS app as upstream services are programmed to recognise an absence of the variant and it will instead re-route this request to alternative servers. |

#### Server Side functions

Within `[[variant]].page.tsx`, the `getServerSideProps` function is called on the server side when a request to a live page is made. It's important that this function returns an object that directly correlates to the props expected by the default exported component within `[[variant]].page.tsx`.

```
export const getServerSideProps: GetServerSideProps = async context => {

context.res.statusCode = data.status;

return {
Expand All @@ -47,6 +53,54 @@ export const getServerSideProps: GetServerSideProps = async context => {
export default LivePageLayout;
```

In the code snippet above, NextJS will serve the component returned by `LivePageLayout`. Before doing so, it calls `getServerSideProps` (on the server) to retrieve the requisite props, which are then used to call `LivePageLayout`, which in turn returns a valid HTML element.
In the code snippet above, NextJS will serve the component returned by `LivePageLayout`. Before doing so, it calls `getServerSideProps` (on the server) to retrieve the requisite props, which are then used to call `LivePageLayout`, which in turn returns a valid HTML element.

**It's important that request/response data is stored within `context.res`, so that requests can be handled appropriately by our ELBs.**

## Component Structure

A typical Live page can be found here: https://www.test.bbc.com/pidgin/live/c7p765ynk9qt

Component file structure

├── ws-nextjs-app
├── pages
├── [service]
├── Live
├── [id]
├── Header
├── KeyPoints
├── Posts
├── ShareButton
├── Stream
├── LivePageLayout


The LivePageLayout propagates respective parts of BFF data to the Header, KeyPoints, Stream and Pagination components.

### Stream component

The stream component takes in the following properties:

{
streamContent: StreamResponse | null;
contributors: string | null;
}

The stream component will process streamContent and populate its body with a series of posts. Posts can currently support the following content types: paragraph, unorderedList, orderedList, image, video and social.

### Header component

The header component takes in the following properties:

{
showLiveLabel: boolean;
title: string;
description?: string;
imageUrl?: string;
imageUrlTemplate?: string;
imageWidth?: number;
mediaCollections?: MediaCollection[] | null;
}

**It's incredibly important that request/response data is stored within `context.res` that requests can be handled appropriately.**
`mediaCollections` contains the necessary information for live video streams.
103 changes: 103 additions & 0 deletions ws-nextjs-app/pages/[service]/send/[id]/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# UGC Uploader Form

## Description

User Generated Content (UGC) refers to any content that is generated by the user. Our uploader form supports the following types of UGC: long text, short text, checkbox, e-mail, telephone, files and images.

## BFF Response

A sample BFF response for a given UGC/Send page can be found here:
[BFF Send Response](https://fabl.api.bbci.co.uk/playground?env=production&module=simorgh-bff&params=id=u50853489;true,service=mundo;true,pageType=ugcForm;true&context=ctx-service-env=live)

## How routes are handled

Our UGC Uploader Page is served through the following route:
`/pages/[service]/send/[id]/[[variant]]`, where the double brackets in `[[variant]]` means that the variant is optional.

This route matches the file structure of this repo:

├── ws-nextjs-app
├── pages
├── [service]
├── send
├── [id]
├── [[...variant]].page.tsx
├── [[...]].page.tsx
├── _app.page.tsx
├── _document.page.tsx

Sample routes that match this construct are:

| Service | URL |
| ------------------ | ----------------------- |
| Mundo (no variant) | `/mundo/send/u50853489` |

#### Server Side functions

Within `[[variant]].page.tsx`, the `getServerSideProps` function is called on the server side when a request to a send page is made. It's important that this function returns an object that directly correlates to the props expected by the default exported component within `[[variant]].page.tsx`.

```
export const getServerSideProps: GetServerSideProps = async context => {

context.res.statusCode = data.status;

return {
props: {
...props expected by UGCPageLayout
},
};
};

export default UGCPageLayout;
```

In the code snippet above, NextJS will serve the component returned by `UGCPageLayout`. Before doing so, it calls `getServerSideProps` (on the server) to retrieve the requisite props, which are then used to call `UGCPageLayout`, which in turn returns a valid HTML element.

**It's important that request/response data is stored within `context.res`, so that requests can be handled appropriately by our ELBs.**

## Component Structure

A typical UGC form can be found here: https://www.bbc.com/mundo/send/u50853489

Component file structure

├── ws-nextjs-app
├── pages
├── [service]
├── send
├── [id]
├── FormContext
├── FormScreen
├── FormField
├── File
├── Checkbox
├── EmailInput
├── FieldLabel
├── Telephone
├── TextArea
├── TextInput

The FormScreen component takes in a list of fields from the BFF and populates itself with a respective body of form fields, based on the components we have available. This is a sample BFF Response:

For example, if the BFF returned the following under `data.sections.fields`, then it would render a phone field followed by a text area:

{ "id": "txt49018963",
"type": "text",
"validation": { "mandatory": false },
"htmlType": "phone",
"label": "Número de teléfono",
"description": "",
"textArea": false
},
{ "id": "txt49019016",
"type": "text",
"validation": { "mandatory": true },
"htmlType": "textarea",
"label": "Comentario (obligatorio)",
"description": "",
"textArea": true
},

### Form Context

The FormContext acts as controller to collate and send all UGC inputted into the form. The `handleSubmit` function within the FormContext effectively validates the form field values and sends it off to the UGC team.
Loading