alpinesmuseum-public/assets/js/components/AppContent/CIDetailView/DVBody.js

184 lines
5.1 KiB
JavaScript

import React, { useState } from 'react';
import PropTypes from 'prop-types';
import reduxLang from '../../../middleware/lang';
import DVLabel from './DVLabel';
import DetailViewShare from './DetailViewShare';
import { DefaultPlayer as Video } from 'react-html5video';
import { useSwipeable } from 'react-swipeable';
import Div100vh from 'react-div-100vh';
const DVBody = ({ item, isFirst, isLast, showNextItem, showPrevItem, t }) => (
<div className='DVBody'>
<DetailMediaContainer
item={item}
isFirst={isFirst}
isLast={isLast}
showNextItem={showNextItem}
showPrevItem={showPrevItem}
/>
<DetailViewShare title={item.title} />
<DetailViewTags tags={item.tags} label={t('category')} />
<DetailAttributeContainer
name={t('inventory_number')}
content={item['inventory_number']}
phone={true}
/>
<DetailAttributeContainer name={t('title')} content={item.title} />
<DetailAttributeContainer name={t('date')} content={item.date} />
<DetailAttributeContainer name={t('owner')} content={item.participant} />
<DetailAttributeContainer name={t('special')} content={item.description} />
{item.history && <DetailAttributeContainer name={t('story')} content={item.history} />}
</div>
);
DVBody.propTypes = {
item: PropTypes.object.isRequired,
isFirst: PropTypes.bool.isRequired,
isLast: PropTypes.bool.isRequired,
t: PropTypes.func.isRequired
};
export default reduxLang('DVBody')(DVBody);
const DetailMediaContainer = ({ item, isFirst, isLast, showNextItem, showPrevItem }) => {
const handlers = useSwipeable({
onSwipedLeft: !isLast ? showNextItem : undefined,
onSwipedRight: !isFirst ? showPrevItem : undefined
});
return (
<div className={`DetailMediaContainer${item.youtube ? ' youtube' : ''}`} {...handlers}>
{!isFirst && <LeftNavButton handler={showPrevItem} />}
<DVLabel text={item.inventory_number} />
{item.video || item.youtube ? (
<DIVideo video={item.video} youtube={item.youtube} alt={item.title} />
) : (
<DIImage item={item} alt={item.title} />
)}
{!isLast && <RightNavButton handler={showNextItem} />}
</div>
);
};
DetailMediaContainer.propTypes = {
item: PropTypes.object.isRequired,
isFirst: PropTypes.bool.isRequired,
isLast: PropTypes.bool.isRequired,
showNextItem: PropTypes.func.isRequired,
showPrevItem: PropTypes.func.isRequired
};
const LeftNavButton = ({ handler }) => (
<button className='LeftNavButton' onClick={handler}>
<img src='/static/gfx/alps_links.svg' alt='left' />
</button>
);
LeftNavButton.propTypes = {
handler: PropTypes.func.isRequired
};
const RightNavButton = ({ handler }) => (
<button className='RightNavButton' onClick={handler}>
<img src='/static/gfx/alps_rechts.svg' alt='right' />
</button>
);
RightNavButton.propTypes = {
handler: PropTypes.func.isRequired
};
function youtube_parser(url) {
var regExp = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
var match = url.match(regExp);
return match && match[7].length == 11 ? match[7] : false;
}
const DIVideo = ({ video, youtube }) => (
<div className='DIVideo'>
{!youtube ? (
<Video controls={['PlayPause', 'Seek', 'Time', 'Volume', 'Fullscreen']}>
<source src={video} type='video/mp4' />
</Video>
) : (
<iframe
width='100%'
src={`https://www.youtube.com/embed/${youtube_parser(youtube)}`}
frameBorder='0'
allow='accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture'
allowFullScreen
></iframe>
)}
</div>
);
DIVideo.propTypes = {
video: PropTypes.string,
youtube: PropTypes.string
};
const DIImage = ({ item, alt = '' }) => {
const [open, setOpen] = useState(false);
const openFullScreen = () => {
setOpen(true);
// fix cut off part on Safari
document.getElementById('CIDetailView').style.overflow = 'visible';
};
const closeFullScreen = () => {
setOpen(false);
// revert Safari fix don when opening
document.getElementById('CIDetailView').style.overflow = '';
};
if (open) {
return <FullScreenImage image={item.image} close={closeFullScreen} />;
}
return (
<div className='DIImage' onClick={openFullScreen}>
<img src={item.image} alt={alt} />
</div>
);
};
DIImage.propTypes = {
item: PropTypes.object.isRequired
};
const FullScreenImage = ({ image, close }) => (
<Div100vh>
<div
className='FullScreenImage'
style={{ backgroundImage: `url('${image}')` }}
onClick={close}
></div>
</Div100vh>
);
const DetailViewTags = ({ tags, label }) => (
<div className='DetailViewTags'>
<DVLabel text={label} />
<div>
{tags.map((tag, i) => (
<span className='Tag' key={i}>
<button style={{border: '0px solid black'}}>{tag.name}</button>
</span>
))}
</div>
</div>
);
const DetailAttributeContainer = ({ name, content, phone = false }) => (
<div className={`DetailAttributeContainer${phone ? ' phone-invetory-number' : ''}`}>
<DVLabel text={name} />
<DAContent content={content} />
</div>
);
DetailAttributeContainer.propTypes = {
name: PropTypes.string.isRequired,
content: PropTypes.any.isRequired
};
const DAContent = ({ content }) => (
<div className='DAContent'>
<p className='medium-text'>{content}</p>
</div>
);
DAContent.propTypes = {
content: PropTypes.any.isRequired
};