]> git.localhorst.tv Git - alttp.git/blob - resources/js/components/map/Item.js
improved underworld map navigation
[alttp.git] / resources / js / components / map / Item.js
1 import PropTypes from 'prop-types';
2 import React from 'react';
3 import { Button } from 'react-bootstrap';
4 import { useTranslation } from 'react-i18next';
5 import { Link, useSearchParams } from 'react-router-dom';
6
7 import { useOpenSeadragon } from './OpenSeadragon';
8 import Icon from '../common/Icon';
9 import Rulesets from '../techniques/Rulesets';
10 import {
11         getLink,
12         getRelations,
13         getTranslation,
14         hasRelations,
15         sorted,
16 } from '../../helpers/Technique';
17 import i18n from '../../i18n';
18
19 const Item = ({ pin }) => {
20         const { viewer } = useOpenSeadragon();
21         const [, setSearchParams] = useSearchParams();
22         const { t } = useTranslation();
23
24         const goToLocation = React.useCallback(pin => {
25                 setSearchParams({ x: pin.x, y: pin.y, z: 4 });
26                 if (viewer && viewer.element) {
27                         viewer.element.scrollIntoView();
28                 }
29         }, [viewer]);
30
31         return <li className="d-flex align-items-start justify-content-between">
32                 <div className="flex-grow-1">
33                                 {pin.technique.type === 'location' ? <>
34                                         <h2>{getTranslation(pin.technique, 'title', i18n.language)}</h2>
35                                         <p>{getTranslation(pin.technique, 'short', i18n.language)}</p>
36                                         {hasRelations(pin.technique, 'related') ?
37                                                 sorted(getRelations(pin.technique, 'related')).map(r =>
38                                                         <div
39                                                                 className="d-flex align-items-start justify-content-between"
40                                                                 key={r.id}
41                                                         >
42                                                                 <div className="me-auto">
43                                                                         <h3>
44                                                                                 <Link to={getLink(r)}>
45                                                                                         {getTranslation(r, 'title', i18n.language)}
46                                                                                 </Link>
47                                                                         </h3>
48                                                                         <p>{getTranslation(r, 'short', i18n.language)}</p>
49                                                                 </div>
50                                                                 {r.rulesets ?
51                                                                         <Rulesets technique={r} />
52                                                                 : null}
53                                                         </div>
54                                                 )
55                                         : null}
56                                 </> : <div className="d-flex align-items-start justify-content-between">
57                                         <div className="flex-grow-1">
58                                                 <h2>
59                                                         <Link to={getLink(pin.technique)}>
60                                                                 {getTranslation(pin.technique, 'title', i18n.language)}
61                                                         </Link>
62                                                 </h2>
63                                                 <p>{getTranslation(pin.technique, 'short', i18n.language)}</p>
64                                         </div>
65                                         {pin.technique.rulesets ?
66                                                 <Rulesets technique={pin.technique} />
67                                         : null}
68                                 </div>}
69                         </div>
70                 <Button
71                         className="m-2"
72                         onClick={() => goToLocation(pin)}
73                         title={t('map.goToLocation')}
74                         variant="outline-secondary"
75                 >
76                         <Icon.CROSSHAIRS title="" />
77                 </Button>
78         </li>;
79 };
80
81 Item.propTypes = {
82         pin: PropTypes.shape({
83                 technique: PropTypes.shape({
84                         rulesets: PropTypes.shape({
85                         }),
86                         type: PropTypes.string,
87                 }),
88                 x: PropTypes.number,
89                 y: PropTypes.number,
90         }),
91 };
92
93 export default Item;