]> git.localhorst.tv Git - alttp.git/blob - resources/js/components/pages/AlttpSeed.js
add helmet
[alttp.git] / resources / js / components / pages / AlttpSeed.js
1 import axios from 'axios';
2 import React, { useCallback, useEffect, useState } from 'react';
3 import { Helmet } from 'react-helmet';
4 import { useParams } from 'react-router-dom';
5
6 import NotFound from './NotFound';
7 import Seed from '../alttp-seeds/Seed';
8 import ErrorBoundary from '../common/ErrorBoundary';
9 import ErrorMessage from '../common/ErrorMessage';
10 import Loading from '../common/Loading';
11
12 const AosSeed = () => {
13         const params = useParams();
14         const { hash } = params;
15
16         const [error, setError] = useState(null);
17         const [loading, setLoading] = useState(true);
18         const [patch, setPatch] = useState(null);
19         const [seed, setSeed] = useState(null);
20
21         const loadSeed = useCallback((hash, ctrl) => {
22                 axios
23                         .get(`/api/alttp-seed/${hash}`, { signal: ctrl.signal })
24                         .then(response => {
25                                 setError(null);
26                                 setLoading(false);
27                                 setSeed(response.data);
28                         })
29                         .catch(error => {
30                                 setError(error);
31                                 setLoading(false);
32                                 setSeed(null);
33                         });
34         }, []);
35
36         useEffect(() => {
37                 setLoading(true);
38                 const ctrl = new AbortController();
39                 loadSeed(hash, ctrl);
40                 return () => {
41                         ctrl.abort();
42                 };
43         }, [hash]);
44
45         useEffect(() => {
46                 if (!seed || seed.status !== 'pending') {
47                         return;
48                 }
49                 const ctrl = new AbortController();
50                 const timer = setTimeout(() => {
51                         loadSeed(seed.hash, ctrl);
52                 }, 2000);
53                 return () => {
54                         clearTimeout(timer);
55                         ctrl.abort();
56                 };
57         }, [seed]);
58
59         useEffect(() => {
60                 setPatch(null);
61                 if (!seed || seed.status !== 'generated') {
62                         return;
63                 }
64                 const ctrl = new AbortController();
65                 axios
66                         .get(`/alttp-seeds/${hash}.bps`, {
67                                 responseType: 'arraybuffer',
68                                 signal: ctrl.signal,
69                         })
70                         .then(response => {
71                                 setPatch(response.data);
72                         })
73                         .catch(error => {
74                                 setError(error);
75                         });
76                 return () => {
77                         ctrl.abort();
78                 };
79         }, [hash, seed]);
80
81         const retry = useCallback(async () => {
82                 await axios.post(`/api/alttp-seed/${hash}/retry`);
83                 setSeed(seed => ({ ...seed, status: 'pending' }));
84         });
85
86         if (loading) {
87                 return <Loading />;
88         }
89
90         if (error) {
91                 return <ErrorMessage error={error} />;
92         }
93
94         if (!seed) {
95                 return <NotFound />;
96         }
97
98         return <ErrorBoundary>
99                 <Helmet>
100                         {seed ?
101                                 <title>{seed.hash}</title>
102                         : null}
103                 </Helmet>
104                 <Seed onRetry={retry} patch={patch} seed={seed} />
105         </ErrorBoundary>;
106 };
107
108 export default AosSeed;