diff --git a/.github/workflows/firebase-live.yml b/.github/workflows/firebase-live.yml index 4e08bf141..ad0a44d35 100644 --- a/.github/workflows/firebase-live.yml +++ b/.github/workflows/firebase-live.yml @@ -16,6 +16,6 @@ jobs: run: yarn && MODE=demo yarn build - uses: FirebaseExtended/action-hosting-deploy@v0 with: - repoToken: "${{ secrets.GITHUB_TOKEN }}" - firebaseServiceAccount: "${{ secrets.FIREBASE_SERVICE_ACCOUNT }}" + repoToken: '${{ secrets.GITHUB_TOKEN }}' + firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT }}' channelId: live diff --git a/.github/workflows/firebase-preview.yml b/.github/workflows/firebase-preview.yml index 5ca1c0ef2..7939f4ba8 100644 --- a/.github/workflows/firebase-preview.yml +++ b/.github/workflows/firebase-preview.yml @@ -1,20 +1,35 @@ -name: 'Firebase Preview' +name: Preview and Lighthouse on: pull_request: - branches: [ 'develop', 'feat/*', 'feature/*', 'release' ] + branches: ['develop', 'feat/*', 'feature/*', 'release'] jobs: build_and_preview: + name: Build and preview runs-on: ubuntu-latest + outputs: + output1: ${{ steps.firebase_hosting_preview.outputs.details_url }} steps: - uses: actions/checkout@v2 - - name: Build + - name: Build Preview Link env: APP_PLAYER_LICENSE_KEY: ${{ secrets.PLAYER_LICENSE_KEY }} run: yarn && MODE=preview yarn build - uses: FirebaseExtended/action-hosting-deploy@v0 + id: firebase_hosting_preview with: - repoToken: "${{ secrets.GITHUB_TOKEN }}" - firebaseServiceAccount: "${{ secrets.FIREBASE_SERVICE_ACCOUNT }}" + repoToken: '${{ secrets.GITHUB_TOKEN }}' + firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT }}' expires: 30d + + lhci: + name: Lighthouse + runs-on: ubuntu-latest + needs: build_and_preview + steps: + - uses: actions/checkout@v2 + - name: Install Lighthouse CI + run: sudo yarn global add @lhci/cli@0.12.x + - name: Run Lighthouse CI + run: lhci autorun --collect.url=${{ needs.build_and_preview.outputs.output1 }}?app-config=gnnuzabk --config=./lighthouserc.js diff --git a/.github/workflows/lhci.yml b/.github/workflows/lhci.yml deleted file mode 100644 index 153fe1caf..000000000 --- a/.github/workflows/lhci.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Lighthouse -on: [workflow_dispatch] -jobs: - lhci: - name: Lighthouse - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Use Node.js 18.x - uses: actions/setup-node@v1 - with: - node-version: 18.x - - name: yarn install, build - run: | - yarn install - yarn run build - - name: install Lighthouse CI - run: | - sudo yarn global add @lhci/cli@0.7.x http-server - - name: run Lighthouse CI - run: | - lhci autorun diff --git a/.gitignore b/.gitignore index 5f4fbbc82..1e466dee5 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ yarn-error.log .firebase firebase-debug.log .stylelintcache +.lighthouseci # os or editor .idea diff --git a/lighthouserc.js b/lighthouserc.js index a2a00469e..c53baf810 100644 --- a/lighthouserc.js +++ b/lighthouserc.js @@ -1,16 +1,19 @@ module.exports = { ci: { collect: { - url: ['http://127.0.0.1:4000'], - startServerCommand: 'http-server ./build -p 4000 -g', - startServerReadyPattern: 'Available on', - numberOfRuns: 1, + numberOfRuns: 3, }, upload: { target: 'temporary-public-storage', }, assert: { - preset: 'lighthouse:no-pwa', + assertions: { + 'categories:performance': ['warn', { minScore: 0.9 }], + 'categories:seo': ['error', { minScore: 0.9 }], + 'categories:accessibility': ['warn', { minScore: 0.9 }], + 'categories:best-practices': ['warn', { minScore: 0.9 }], + 'categories:pwa': ['warn', { minScore: 0.9 }], + }, }, }, }; diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 62b035bbf..f02640f48 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -12,6 +12,7 @@ "confirm": "Yes" }, "default_site_name": "My OTT Application", + "default_description": "JW OTT Webapp is an open-source, dynamically generated video website.", "filter_videos_by": "Filter videos by {{name}}", "filter_videos_by_genre": "Filter videos by genre", "home": "Home", diff --git a/public/locales/en/demo.json b/public/locales/en/demo.json index ba40a298e..77338558e 100644 --- a/public/locales/en/demo.json +++ b/public/locales/en/demo.json @@ -1,5 +1,6 @@ { "app_config_not_found": "Invalid or Missing App Config", + "app_config_learn_more": "Learn more about App Configs", "cancel_config_id": "Cancel", "click_to_unselect_config": "(click here to unselect this config)", "currently_previewing_config": "You are currently previewing config: '{{configSource}}'", diff --git a/public/locales/es/common.json b/public/locales/es/common.json index b614b872b..79dd8fc24 100644 --- a/public/locales/es/common.json +++ b/public/locales/es/common.json @@ -12,6 +12,7 @@ "confirm": "Sí" }, "default_site_name": "Mi aplicación OTT", + "default_description": "", "filter_videos_by": "Filtrar videos por {{name}}", "filter_videos_by_genre": "Filtrar videos por género", "home": "Inicio", diff --git a/public/locales/es/demo.json b/public/locales/es/demo.json index a85af0d08..3c364c192 100644 --- a/public/locales/es/demo.json +++ b/public/locales/es/demo.json @@ -1,5 +1,6 @@ { "app_config_not_found": "Configuración de aplicación inválida o no encontrada", + "app_config_learn_more": "", "cancel_config_id": "Cancelar", "click_to_unselect_config": "(haz clic aquí para deseleccionar esta configuración)", "currently_previewing_config": "Actualmente estás previsualizando la configuración: '{{configSource}}'", diff --git a/src/components/Button/Button.tsx b/src/components/Button/Button.tsx index 59e0f5eb1..46c1c1340 100644 --- a/src/components/Button/Button.tsx +++ b/src/components/Button/Button.tsx @@ -28,6 +28,7 @@ type Props = { disabled?: boolean; busy?: boolean; id?: string; + as?: 'button' | 'a'; } & React.AriaAttributes; const Button: React.FC = ({ @@ -43,6 +44,7 @@ const Button: React.FC = ({ busy, type, to, + as = 'button', onClick, className, ...rest diff --git a/src/components/DemoConfigDialog/DemoConfigDialog.tsx b/src/components/DemoConfigDialog/DemoConfigDialog.tsx index 33aa9837d..78f4da019 100644 --- a/src/components/DemoConfigDialog/DemoConfigDialog.tsx +++ b/src/components/DemoConfigDialog/DemoConfigDialog.tsx @@ -2,6 +2,7 @@ import React, { ChangeEventHandler, MouseEventHandler, useEffect, useState } fro import { useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router'; import type { UseQueryResult } from 'react-query'; +import { Helmet } from 'react-helmet'; import styles from './DemoConfigDialog.module.scss'; @@ -9,7 +10,6 @@ import ErrorPage from '#components/ErrorPage/ErrorPage'; import TextField from '#components/TextField/TextField'; import Button from '#components/Button/Button'; import { getConfigNavigateCallback } from '#src/utils/configOverride'; -import Link from '#components/Link/Link'; import ConfirmationDialog from '#components/ConfirmationDialog/ConfirmationDialog'; import LoadingOverlay from '#components/LoadingOverlay/LoadingOverlay'; import type { Config } from '#types/Config'; @@ -136,16 +136,22 @@ const DemoConfigDialog = ({ selectedConfigSource, configQuery }: Props) => { return ( <> + {!configQuery.isSuccess && ( + + + + )} {configQuery.isSuccess && (
{t('currently_previewing_config', { configSource: selectedConfigSource })}
- {t('click_to_unselect_config')} +
)} {!configQuery.isSuccess && (
diff --git a/src/components/DemoConfigDialog/__snapshots__/DemoConfigDialog.test.tsx.snap b/src/components/DemoConfigDialog/__snapshots__/DemoConfigDialog.test.tsx.snap index 65169612e..2251711a7 100644 --- a/src/components/DemoConfigDialog/__snapshots__/DemoConfigDialog.test.tsx.snap +++ b/src/components/DemoConfigDialog/__snapshots__/DemoConfigDialog.test.tsx.snap @@ -8,11 +8,13 @@ exports[` > renders and matches snapshot 1`] = `
currently_previewing_config
- - click_to_unselect_config - + + click_to_unselect_config + +
`; @@ -104,7 +106,7 @@ exports[` > renders and matches snapshot error dialog 1`] = ` rel="noreferrer" target="_blank" > - learn_more + app_config_learn_more

diff --git a/src/containers/Layout/Layout.tsx b/src/containers/Layout/Layout.tsx index 81420583d..ad2621a8c 100644 --- a/src/containers/Layout/Layout.tsx +++ b/src/containers/Layout/Layout.tsx @@ -26,6 +26,7 @@ const Layout = () => { const { t, i18n } = useTranslation('common'); const { config, accessModel } = useConfigStore(({ config, accessModel }) => ({ config, accessModel }), shallow); const { menu, assets, siteName, description, styling, features } = config; + const metaDescription = description || t('default_description'); const { clientId } = useClientIntegration(); const { searchPlaylist } = features || {}; const { footerText } = styling || {}; @@ -105,11 +106,11 @@ const Layout = () => {
{siteName} - - + + - +