194 lines
5.4 KiB
JavaScript
194 lines
5.4 KiB
JavaScript
import React, { useState } from 'react';
|
|
import PropTypes from 'prop-types';
|
|
import reduxLang from '../../middleware/lang';
|
|
import DVKownMore from './DVKownMore';
|
|
import DVLabel from './../AppContent/CIDetailView/DVLabel';
|
|
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, participated,
|
|
sendParticipation, toggleParticipated, doYouKnowMoreURL, color, t }) => {
|
|
return <div className='DVBody'>
|
|
<DetailMediaContainer
|
|
item={item}
|
|
isFirst={isFirst}
|
|
isLast={isLast}
|
|
showNextItem={showNextItem}
|
|
showPrevItem={showPrevItem}
|
|
/>
|
|
<DVKownMore
|
|
item={item}
|
|
participated={participated}
|
|
sendParticipation={sendParticipation}
|
|
toggleParticipated={toggleParticipated}
|
|
doYouKnowMoreURL={doYouKnowMoreURL}
|
|
color={color}
|
|
/>
|
|
<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
|
|
};
|