From: Daniel Karbach Date: Fri, 10 Feb 2023 15:13:18 +0000 (+0100) Subject: add helmet X-Git-Url: https://git.localhorst.tv/?a=commitdiff_plain;h=18cd02860ba7889360ce3547b44faa0daa807a5e;p=alttp.git add helmet --- diff --git a/package-lock.json b/package-lock.json index 6bc7914..99cc398 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "pusher-js": "^7.0.6", "qs": "^6.10.3", "react-bootstrap": "^2.2.0", + "react-helmet": "^6.1.0", "react-i18next": "^11.15.6", "react-router-bootstrap": "^0.26.0", "react-router-dom": "^6.2.2", @@ -9518,6 +9519,25 @@ "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz", "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==" }, + "node_modules/react-helmet": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-6.1.0.tgz", + "integrity": "sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==", + "dependencies": { + "object-assign": "^4.1.1", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.1.1", + "react-side-effect": "^2.1.0" + }, + "peerDependencies": { + "react": ">=16.3.0" + } + }, + "node_modules/react-helmet/node_modules/react-fast-compare": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", + "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" + }, "node_modules/react-i18next": { "version": "11.15.6", "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.15.6.tgz", @@ -9600,6 +9620,14 @@ "react-dom": ">=16.8" } }, + "node_modules/react-side-effect": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.2.tgz", + "integrity": "sha512-PVjOcvVOyIILrYoyGEpDN3vmYNLdy1CajSFNt4TDsVQC5KpTijDvWVoR+/7Rz2xT978D8/ZtFceXxzsPwZEDvw==", + "peerDependencies": { + "react": "^16.3.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-smooth": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.0.tgz", @@ -19259,6 +19287,24 @@ "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz", "integrity": "sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==" }, + "react-helmet": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-6.1.0.tgz", + "integrity": "sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==", + "requires": { + "object-assign": "^4.1.1", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.1.1", + "react-side-effect": "^2.1.0" + }, + "dependencies": { + "react-fast-compare": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", + "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" + } + } + }, "react-i18next": { "version": "11.15.6", "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.15.6.tgz", @@ -19314,6 +19360,12 @@ "react-router": "6.2.2" } }, + "react-side-effect": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.2.tgz", + "integrity": "sha512-PVjOcvVOyIILrYoyGEpDN3vmYNLdy1CajSFNt4TDsVQC5KpTijDvWVoR+/7Rz2xT978D8/ZtFceXxzsPwZEDvw==", + "requires": {} + }, "react-smooth": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-2.0.0.tgz", diff --git a/package.json b/package.json index 4f7a3a6..2429eb1 100644 --- a/package.json +++ b/package.json @@ -89,6 +89,7 @@ "pusher-js": "^7.0.6", "qs": "^6.10.3", "react-bootstrap": "^2.2.0", + "react-helmet": "^6.1.0", "react-i18next": "^11.15.6", "react-router-bootstrap": "^0.26.0", "react-router-dom": "^6.2.2", diff --git a/resources/js/components/App.js b/resources/js/components/App.js index d84474c..9656da2 100644 --- a/resources/js/components/App.js +++ b/resources/js/components/App.js @@ -1,5 +1,7 @@ import axios from 'axios'; import React, { useEffect, useState } from 'react'; +import { Helmet } from 'react-helmet'; +import { useTranslation } from 'react-i18next'; import { BrowserRouter, Navigate, Route, Routes } from 'react-router-dom'; import Footer from './common/Footer'; @@ -17,6 +19,8 @@ import UserContext from '../helpers/UserContext'; const App = () => { const [user, setUser] = useState(null); + const { t } = useTranslation(); + const checkAuth = async () => { try { const response = await axios.get('/api/user'); @@ -57,6 +61,10 @@ const App = () => { return + + {t('general.appName')} + +
} /> diff --git a/resources/js/components/pages/AlttpSeed.js b/resources/js/components/pages/AlttpSeed.js index 96589d4..43bc020 100644 --- a/resources/js/components/pages/AlttpSeed.js +++ b/resources/js/components/pages/AlttpSeed.js @@ -1,5 +1,6 @@ import axios from 'axios'; import React, { useCallback, useEffect, useState } from 'react'; +import { Helmet } from 'react-helmet'; import { useParams } from 'react-router-dom'; import NotFound from './NotFound'; @@ -24,7 +25,6 @@ const AosSeed = () => { setError(null); setLoading(false); setSeed(response.data); - window.document.title = response.data.hash; }) .catch(error => { setError(error); @@ -96,6 +96,11 @@ const AosSeed = () => { } return + + {seed ? + {seed.hash} + : null} + ; }; diff --git a/resources/js/components/pages/AosFront.js b/resources/js/components/pages/AosFront.js index d308f7d..9651110 100644 --- a/resources/js/components/pages/AosFront.js +++ b/resources/js/components/pages/AosFront.js @@ -1,9 +1,9 @@ import React from 'react'; import { Button, Col, Container, Row } from 'react-bootstrap'; -import { withTranslation } from 'react-i18next'; +import { Helmet } from 'react-helmet'; +import { useTranslation } from 'react-i18next'; import Icon from '../common/Icon'; -import i18n from '../../i18n'; const authEndpoint = 'https://discord.com/oauth2/authorize'; const clientId = '951113702839549982'; @@ -11,10 +11,13 @@ const botUrl = `${authEndpoint}?client_id=${clientId}&scope=bot%20applications.c const commandUrl = `${authEndpoint}?client_id=${clientId}&scope=applications.commands`; const AosFront = () => { - React.useEffect(() => { - window.document.title = 'Aos'; - }, []); + const { t } = useTranslation(); + return + + AoS + +

Castlevania: Aria of Sorrow

@@ -28,7 +31,7 @@ const AosFront = () => { > {' '} - {i18n.t('aos.randoDiscord')} + {t('aos.randoDiscord')} @@ -38,7 +41,7 @@ const AosFront = () => { target="_blank" variant="primary" > - {i18n.t('aos.randoWeb')} + {t('aos.randoWeb')} @@ -50,7 +53,7 @@ const AosFront = () => { > {' '} - {i18n.t('aos.tourneyDiscord')} + {t('aos.tourneyDiscord')} @@ -62,7 +65,7 @@ const AosFront = () => { > {' '} - {i18n.t('aos.inviteBot')} + {t('aos.inviteBot')} @@ -74,11 +77,11 @@ const AosFront = () => { > {' '} - {i18n.t('aos.inviteCommand')} + {t('aos.inviteCommand')}
; }; -export default withTranslation()(AosFront); +export default AosFront; diff --git a/resources/js/components/pages/AosGenerate.js b/resources/js/components/pages/AosGenerate.js index 0c27b06..b787848 100644 --- a/resources/js/components/pages/AosGenerate.js +++ b/resources/js/components/pages/AosGenerate.js @@ -1,17 +1,20 @@ import axios from 'axios'; import React, { useCallback, useEffect, useState } from 'react'; +import { Helmet } from 'react-helmet'; +import { useTranslation } from 'react-i18next'; import Generate from '../aos-generate/Generate'; import ErrorBoundary from '../common/ErrorBoundary'; import ErrorMessage from '../common/ErrorMessage'; import Loading from '../common/Loading'; -import i18n from '../../i18n'; const AosGenerate = () => { const [error, setError] = useState(null); const [loading, setLoading] = useState(true); const [presets, setPresets] = useState([]); + const { t } = useTranslation(); + const loadPresets = useCallback(ctrl => { axios .get('/api/aos-presets', { signal: ctrl.signal }) @@ -36,10 +39,6 @@ const AosGenerate = () => { }; }, []); - useEffect(() => { - window.document.title = i18n.t('aosGenerate.heading'); - }, [i18n.language]); - if (loading) { return ; } @@ -49,6 +48,9 @@ const AosGenerate = () => { } return + + {t('aosGenerate.heading')} + ; }; diff --git a/resources/js/components/pages/AosSeed.js b/resources/js/components/pages/AosSeed.js index 165a2be..ece8406 100644 --- a/resources/js/components/pages/AosSeed.js +++ b/resources/js/components/pages/AosSeed.js @@ -1,5 +1,6 @@ import axios from 'axios'; import React, { useCallback, useEffect, useState } from 'react'; +import { Helmet } from 'react-helmet'; import { useParams } from 'react-router-dom'; import NotFound from './NotFound'; @@ -24,7 +25,6 @@ const AosSeed = () => { setError(null); setLoading(false); setSeed(response.data); - window.document.title = response.data.hash; }) .catch(error => { setError(error); @@ -96,6 +96,11 @@ const AosSeed = () => { } return + + {seed ? + {seed.hash} + : null} + ; }; diff --git a/resources/js/components/pages/AosTracker.js b/resources/js/components/pages/AosTracker.js index 8eafd1f..5273d0b 100644 --- a/resources/js/components/pages/AosTracker.js +++ b/resources/js/components/pages/AosTracker.js @@ -1,14 +1,14 @@ import React from 'react'; import { Container } from 'react-bootstrap'; +import { Helmet } from 'react-helmet'; import Map from '../aos-tracker/Map'; const AosTracker = () => { - React.useEffect(() => { - window.document.title = 'Aos Tracker'; - }, []); - return + + AoS Tracker + ; }; diff --git a/resources/js/components/pages/Map.js b/resources/js/components/pages/Map.js index 841227c..cbd3581 100644 --- a/resources/js/components/pages/Map.js +++ b/resources/js/components/pages/Map.js @@ -1,5 +1,6 @@ import React from 'react'; import { Container } from 'react-bootstrap'; +import { Helmet } from 'react-helmet'; import { useTranslation } from 'react-i18next'; import Buttons from '../map/Buttons'; @@ -11,11 +12,11 @@ const Map = () => { const container = React.useRef(); const { t } = useTranslation(); - React.useEffect(() => { - window.document.title = t('map.heading'); - }, []); - return + + {t('map.heading')} + +

{t('map.heading')}

diff --git a/resources/js/components/pages/NotFound.js b/resources/js/components/pages/NotFound.js index 5e20596..19ccc72 100644 --- a/resources/js/components/pages/NotFound.js +++ b/resources/js/components/pages/NotFound.js @@ -1,8 +1,13 @@ import React from 'react'; +import { Helmet } from 'react-helmet'; -const NotFound = () =>
-

Not Found

-

Sorry

-
; +const NotFound = () => +
+ + Not Found + +

Not Found

+

Sorry

+
; export default NotFound; diff --git a/resources/js/components/pages/Technique.js b/resources/js/components/pages/Technique.js index 8c202ed..e380611 100644 --- a/resources/js/components/pages/Technique.js +++ b/resources/js/components/pages/Technique.js @@ -1,5 +1,6 @@ import axios from 'axios'; import React, { useEffect, useState } from 'react'; +import { Helmet } from 'react-helmet'; import { withTranslation } from 'react-i18next'; import { useParams } from 'react-router-dom'; @@ -39,12 +40,6 @@ const Technique = () => { }; }, [name]); - useEffect(() => { - if (technique) { - window.document.title = getTranslation(technique, 'title', i18n.language); - } - }, [technique, i18n.language]); - if (loading) { return ; } @@ -58,6 +53,10 @@ const Technique = () => { } return + + {getTranslation(technique, 'title', i18n.language)} + + ; }; diff --git a/resources/js/components/pages/Techniques.js b/resources/js/components/pages/Techniques.js index ddecf56..a89c3a2 100644 --- a/resources/js/components/pages/Techniques.js +++ b/resources/js/components/pages/Techniques.js @@ -1,6 +1,7 @@ import axios from 'axios'; import PropTypes from 'prop-types'; import React from 'react'; +import { Helmet } from 'react-helmet'; import { withTranslation } from 'react-i18next'; import NotFound from './NotFound'; @@ -36,7 +37,6 @@ const Techniques = ({ namespace, type }) => { if (!techniques.length) { setLoading(true); } - window.document.title = i18n.t(`${namespace}.heading`); axios .get(`/api/content`, { params: { @@ -63,7 +63,6 @@ const Techniques = ({ namespace, type }) => { }, [filter, namespace, type]); React.useEffect(() => { - window.document.title = i18n.t(`${namespace}.heading`); setTechniques(t => [...t].sort(compareTranslation('title', i18n.language))); }, [namespace, i18n.language]); @@ -80,6 +79,10 @@ const Techniques = ({ namespace, type }) => { } return + + {i18n.t(`${namespace}.heading`)} + + { setError(null); setLoading(false); setTournament(sortParticipants(response.data)); - window.document.title = response.data.title; }) .catch(error => { setError(error); @@ -128,6 +128,9 @@ const Tournament = () => { }; return + + {tournament.title} + ; }; diff --git a/resources/js/components/pages/User.js b/resources/js/components/pages/User.js index 3e868ba..b481112 100644 --- a/resources/js/components/pages/User.js +++ b/resources/js/components/pages/User.js @@ -1,5 +1,6 @@ import axios from 'axios'; import React, { useEffect, useState } from 'react'; +import { Helmet } from 'react-helmet'; import { useParams } from 'react-router-dom'; import ErrorBoundary from '../common/ErrorBoundary'; @@ -25,7 +26,6 @@ const User = () => { setError(null); setLoading(false); setUser(response.data); - window.document.title = response.data.nickname || response.data.username; }) .catch(error => { setError(error); @@ -64,6 +64,9 @@ const User = () => { } return + + {user.nickname || user.username} + ; }; diff --git a/resources/js/i18n/de.js b/resources/js/i18n/de.js index f130c08..fef88f4 100644 --- a/resources/js/i18n/de.js +++ b/resources/js/i18n/de.js @@ -292,6 +292,7 @@ export default { }, general: { anonymous: 'Anonym', + appDescription: 'Turniere und Tutorials für The Legend of Zelda: A Link to the Past Randomizer', appName: 'ALttP', }, icon: { @@ -379,6 +380,7 @@ export default { }, }, map: { + description: 'Karten von The Legend of Zelda: A Link to the Past', dwLong: 'Dark World', dwShort: 'DW', goToLocation: 'Zur Stelle springen', @@ -509,6 +511,7 @@ export default { heading: 'Regelsätze', }, techniques: { + description: 'Tutorials für The Legend of Zelda: A Link to the Past Randomizer', heading: 'Techniken', lastModified: 'Zuletzt geändert: {{ date, L }}', requirements: 'Erfordert: ', diff --git a/resources/js/i18n/en.js b/resources/js/i18n/en.js index a7ca19c..6820f30 100644 --- a/resources/js/i18n/en.js +++ b/resources/js/i18n/en.js @@ -292,6 +292,7 @@ export default { }, general: { anonymous: 'Anonym', + appDescription: 'Tournaments and tutorials for The Legend of Zelda: A Link to the Past Randomizer', appName: 'ALttP', }, icon: { @@ -379,6 +380,7 @@ export default { }, }, map: { + description: 'Maps of The Legend of Zelda: A Link to the Past', dwLong: 'Dark World', dwShort: 'DW', goToLocation: 'Go to location', @@ -509,6 +511,7 @@ export default { heading: 'Rulesets', }, techniques: { + description: 'Tutorials for The Legend of Zelda: A Link to the Past Randomizer', heading: 'Techniques', lastModified: 'Last modified: {{ date, L }}', requirements: 'Requires: ',