diff --git a/app.js b/app.js index dadf66b..bf7d6bf 100644 --- a/app.js +++ b/app.js @@ -1,72 +1,46 @@ import { h } from 'preact' -import { useState, useEffect } from 'preact/hooks' -import { isWithinInterval, subHours, addHours } from 'date-fns' -import { zonedTimeToUtc, utcToZonedTime } from 'date-fns-tz' -import Video from './src/components/Video' -import Info from './src/components/Info' -import { useEventCalendar, useEventApi } from './src/hooks/data' -import { useTimeout } from './src/hooks/timerHooks' +import { H1 } from './src/components/Text' +import Page from './src/layouts/Page' -export default (props) => { +export default () => ( + +

LANGING PAGE

+
+) - // console.log({ props }) - const [currentVideo, setCurrentVideo] = useState(null) - const [streamIsLive, setStreamIsLive] = useState(false) - const [infoActive, setInfoActive] = useState(false) - const [minLoadTimePassed, setMinTimeUp] = useState(false) - const { data: calData, loading } = useEventCalendar() - const { data: eventsData, loading: eventsLoading } = useEventApi() - useTimeout(() => { - setMinTimeUp(true) - }, 1500) - useEffect(() => { - if (calData && calData.length) { - calData.forEach((stream, index) => { - const utcStartDate = zonedTimeToUtc( - new Date(stream.start), - 'Europe/Berlin' - ) - const utcEndDate = zonedTimeToUtc(new Date(stream.end), 'Europe/Berlin') - const { timeZone } = Intl.DateTimeFormat().resolvedOptions() +// useEffect(() => { +// if (calData && calData.length) { +// calData.forEach((stream, index) => { +// const utcStartDate = zonedTimeToUtc( +// new Date(stream.start), +// 'Europe/Berlin' +// ) +// const utcEndDate = zonedTimeToUtc(new Date(stream.end), 'Europe/Berlin') +// const { timeZone } = Intl.DateTimeFormat().resolvedOptions() + +// const zonedStartDate = utcToZonedTime(utcStartDate, timeZone) +// const zonedEndDate = utcToZonedTime(utcEndDate, timeZone) +// if ( +// isWithinInterval(new Date(), { +// start: subHours(zonedStartDate, 1), +// end: addHours(zonedEndDate, 1), +// }) +// ) { +// setCurrentVideo(stream) +// } +// if ( +// isWithinInterval(new Date(), { +// start: zonedStartDate, +// end: zonedEndDate, +// }) +// ) { +// setStreamIsLive(true) +// } +// }) +// } +// }, [calData, eventsData, eventsLoading]) - const zonedStartDate = utcToZonedTime(utcStartDate, timeZone) - const zonedEndDate = utcToZonedTime(utcEndDate, timeZone) - if ( - isWithinInterval(new Date(), { - start: subHours(zonedStartDate, 1), - end: addHours(zonedEndDate, 1), - }) - ) { - setCurrentVideo(stream) - } - if ( - isWithinInterval(new Date(), { - start: zonedStartDate, - end: zonedEndDate, - }) - ) { - setStreamIsLive(true) - } - }) - } - }, [calData, eventsData, eventsLoading]) - return ( -
- {currentVideo && !infoActive && minLoadTimePassed ? ( -
- ) -} diff --git a/index.html b/index.html index b477c05..217703c 100644 --- a/index.html +++ b/index.html @@ -1,7 +1,7 @@ - The Para-Real: Finding the Future in Unexpected Places + Underscore Streams diff --git a/package.json b/package.json index 5160cd9..5aefdaf 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "markdown-to-jsx": "^7.1.2", "preact": "^10.5.12", "prop-types": "^15.7.2", + "react-helmet": "^6.1.0", "react-router-dom": "^5.3.0", "striptags": "^3.2.0", "styled-components": "^5.2.1", diff --git a/src/assets/theme/index.js b/src/assets/theme/index.js index fc89ebb..c0c66df 100644 --- a/src/assets/theme/index.js +++ b/src/assets/theme/index.js @@ -26,8 +26,13 @@ export const textSizes = { hg: 200, } +export const defaultTheme = { + background: colours.rose, foreground: colours.midnight, highlight: colours.highlight +} + export default { colours, textSizes, ui, + defaultTheme } diff --git a/src/components/Button/index.js b/src/components/Button/index.js index 0ef7c4c..af915b1 100644 --- a/src/components/Button/index.js +++ b/src/components/Button/index.js @@ -3,11 +3,11 @@ import { colours } from '../../assets/theme' const Button = styled.button` background-color: transparent; - border: 1px solid ${colours.midnightDarker}; + border: 1px solid ${colours.rose}; padding: 0.3em 1em; font-family: Karla; font-weight: inherit; - color: ${colours.midnightDarker}; + color: ${colours.rose}; opacity: 1; text-decoration: none; font-size: 24px; @@ -21,8 +21,8 @@ const Button = styled.button` } :hover { - background-color: ${colours.midnightDarker}; - color: ${colours.roseLight}; + background-color: ${colours.rose}; + color: ${colours.midnightDarker}; svg { path { diff --git a/src/components/Info/helpers.js b/src/components/Info/helpers.js deleted file mode 100644 index 4b9b9e6..0000000 --- a/src/components/Info/helpers.js +++ /dev/null @@ -1,4 +0,0 @@ -export const sortData = data => - Object.values(data) - .filter(feedItem => feedItem.type === 'VEVENT') - .sort((a, b) => new Date(a.start) - new Date(b.start)) diff --git a/src/components/Info/index.js b/src/components/Info/index.js deleted file mode 100644 index 20e4aca..0000000 --- a/src/components/Info/index.js +++ /dev/null @@ -1,146 +0,0 @@ -/* eslint-disable react/prop-types */ -import { h, Fragment } from 'preact' -import { useState, useEffect } from 'preact/hooks' -import { isFuture, isPast } from 'date-fns' - -import { H1 } from '../Text' -import Markdown from '../Markdown' -import translations from '../../data/strings' -import InfoLayout from '../InfoLayout' -import VideoEmbed from '../VideoEmbed' -import { - VideoCard, - Title, - InfoContent, - PositionedCross as CrossSvg, - Row, - ActionButton as Button, - Trailer, -} from './styles' - -import intro from '../../data/intro.md' -import credits from '../../data/credits.md' - -import config from '../../data/config' -import trailerThumb from '../../assets/img/main_thumb.png' - -const Info = ({ data }) => { - const trailerUrl = `https://www.youtube-nocookie.com/embed/${config.seriesTrailerId}?autoplay=1&vq=hd1080` - const [embedURL, setEmbedUrl] = useState('') - - const onClickTrailerButton = () => { - setEmbedUrl(trailerUrl) - } - const deactivateEmbed = () => { - setEmbedUrl('') - } - - // const pastStreams = - // data && data.length - // ? data.filter(feeditem => isPast(new Date(feeditem.end))) - // : [] - - // const futureStreams = - // data && data.length - // ? data - // .filter( - // feeditem => - // feeditem.id !== (currentVideo && currentVideo.id) && - // isFuture(new Date(feeditem.start)) - // ) - // .sort( - // (a, b) => - // // Turn your strings into dates, and then subtract them - // // to get a value that is either negative, positive, or zero. - // new Date(a.start) - new Date(b.start) - // ) - // : [] - - const dateString = `${new Date()}` - let tzShort = - // Works for the majority of modern browsers - dateString.match(/\(([^\)]+)\)$/) || - // IE outputs date strings in a different format: - dateString.match(/([A-Z]+) [\d]{4}$/) - - if (tzShort) { - // Old Firefox uses the long timezone name (e.g., "Central - // Daylight Time" instead of "CDT") - tzShort = tzShort[1].match(/[A-Z]/g).join('') - } - - return ( - - {/* {embedURL ? ( - - ) : null} */} - - -

The Para-Real:

-

Finding the Future in Unexpected Places

- {intro} - - - - - - - - - - - -
- {/* {currentVideo && ( - - {translations.en.nowPlaying}: - - - )} - - {futureStreams.length ? ( - - {translations.en.nextStream}: - {futureStreams.map(feeditem => ( - - ))} - - ) : null} - - {pastStreams.length ? ( - - {translations.en.pastStream}: - {pastStreams.map(feeditem => ( - - setEmbedUrl(`${config.peertube_root}${feeditem.embedPath}`) - } - {...feeditem} - /> - ))} - - ) : null} */} - {/* - {credits} - */} -
- -
- ) -} - -export default Info diff --git a/src/components/Info/styles.js b/src/components/Info/styles.js deleted file mode 100644 index 6933a43..0000000 --- a/src/components/Info/styles.js +++ /dev/null @@ -1,240 +0,0 @@ -import { h, Fragment } from 'preact' -import { zonedTimeToUtc, utcToZonedTime, format } from 'date-fns-tz' -import styled from 'styled-components' -import { colours, textSizes } from '../../assets/theme' -import config from '../../data/config' -import Logo from '../Logo' -import translations from '../../data/strings' -import CrossSvg from '../Svg/Cross' -import PlaySvg from '../Svg/Play' - -import { P, H1, H2, Span, Label } from '../Text' -import Link from '../Link' -import { bool, instanceOf, string } from 'prop-types' -import Markdown from '../Markdown' -import Button from '../Button' - -export const Wrapper = styled.div` - height: 100vh; - width: 100vw; - padding: 2em; - display: flex; - justify-content: space-between; - flex-direction: column; - - background: url(https://images.unsplash.com/photo-1579762715118-a6f1d4b934f1?ixlib=rb-1.2.1&ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&auto=format&fit=crop&w=3031&q=80) - ${colours.rose}; - box-sizing: border-box; - background-size: cover; - background-position-y: 50%; - background-position-x: 20vw; - background-blend-mode: soft-light; - - p, - h1, - h2 { - color: ${colours.midnightDarker}; - } -` - -export const TrailerContainer = styled.div` - background: url(${props => props.imgSrc}); - /* width: 100%; */ - height: 20em; - background-size: cover; - display: flex; - justify-content: center; - align-items: center; - border: 1px solid ${colours.midnightDarker}; - cursor: pointer; - margin-bottom: 16px; - - div { - padding: 1em 2em; - background-color: #ffffffba; - display: flex; - flex-direction: row; - align-items: center; - } - - label { - color: ${colours.midnightDarker}; - margin-left: 8px; - font-size: 20px; - } - - :hover div { - background-color: #ffffff; - } -` - -export const Trailer = props => ( - -
- - -
-
-) - -export const ActionButton = styled(Button)` - font-size: 18px; -` - -export const Row = styled.div` - display: flex; - flex-direction: row; - margin-bottom: 32px; - - a { - display: block; - width: 50%; - &:not(:last-of-type) { - margin-right: 16px; - } - } -` - -export const InfoContent = styled.div` - max-width: 600px; - margin: 0 0 0em 2px; - padding-bottom: 1em; - - h1 { - display: none; - - &:last-of-type { - margin-bottom: 32px; - } - @media screen and (max-width: 1000px) { - display: block; - } - } -` - -export const PositionedLogo = styled(Logo)` - margin-bottom: 64px; -` - -export const TaglineContainer = styled.div` - h1 { - margin-top: 32px; - } -` - -export const Title = styled(H1)` - margin: 0.3em 0; -` - -export const PositionedCross = styled(CrossSvg)` - position: fixed; - right: 2.5em; - top: 2em; - /* width: 32px; */ - /* height: 32px; */ - cursor: pointer; - stroke: ${colours.midnightDarker}; - z-index: 5; - - &:hover { - opacity: 0.5; - } -` - -export const VCWrapper = styled.div` - max-width: 600px; - margin: 0 0 6em 2px; - - button { - margin-top: 16px; - } - - p { - margin-left: 2px; - } -` - -const VCImg = styled.img` - width: 100%; - margin-bottom: 8px; -` - -const ItemTitleWrapper = styled.div` - margin-bottom: 0.3em; -` - -const DateLabel = styled(Label)` - margin: 1em 0; - display: block; -` - -const LinkBlock = styled(Link)` - display: block; - width: 100%; -` - -const renderTitles = titles => - titles.split('\\n').map(title =>

{title}

) - -export const VideoCard = ({ - title, - description, - start, - previewPath, - hasPassed, - videoUrl, - onClickButton, - tzShort, -}) => { - const startDate = new Date(start) - const utcDate = zonedTimeToUtc(startDate, 'Europe/Berlin') - - const { timeZone } = Intl.DateTimeFormat().resolvedOptions() - const zonedDate = utcToZonedTime(utcDate, timeZone) - return ( - - - {`${hasPassed ? translations.en.streamDatePast : ''}`} - - {hasPassed - ? format(zonedDate, 'dd/MM/yy') - : `${format(zonedDate, 'do LLLL y // HH:mm')} ${tzShort}`} - - - {videoUrl && hasPassed ? ( - - {renderTitles(title)} - - - ) : ( - - {renderTitles(title)} - - - )} -

{description}

- {hasPassed ? ( - - ) : ( - - - - )} -
- ) -} - -VideoCard.propTypes = { - title: string, - description: string, - start: instanceOf(Date), - previewPath: string, - hasPassed: bool, - videoUrl: string, -} diff --git a/src/components/InfoLayout/index.js b/src/components/InfoLayout/index.js deleted file mode 100644 index ec7fa87..0000000 --- a/src/components/InfoLayout/index.js +++ /dev/null @@ -1,54 +0,0 @@ -import { h } from 'preact' -import { useEffect, useRef, useState } from 'preact/hooks' -import { bool, string } from 'prop-types' - -import { H1, H2, Label, Span } from '../Text' -import { - Wrapper, - TaglineContainer, - LoaderWrapper, - Content, - Hero, - FadeBottom, -} from './styles' -import translations from '../../data/strings' -import { colours } from '../../assets/theme' -import Loader from '../Loader' -import { useTimeout } from '../../hooks/timerHooks' -import { NdcLogo, RFLogo } from '../Logo' - -const InfoLayout = ({ title, subtitle, image, children }) => ( - - - {children} - - -
-

{title}

-

- {subtitle} -

-
- - - - - - - - - - -
-
-) - -InfoLayout.propTypes = { - loading: bool, -} - -export default InfoLayout diff --git a/src/components/Seo/index.js b/src/components/Seo/index.js new file mode 100644 index 0000000..6d66620 --- /dev/null +++ b/src/components/Seo/index.js @@ -0,0 +1,81 @@ +import { h } from 'preact' +import { bool, string } from 'prop-types' +import Helmet from 'react-helmet' + +const siteTitle = 'Underscore Streams' + +function SEO({ description, title, metaImg: imgSrc, noindex }) { + return ( + + ) +} + +SEO.defaultProps = { + meta: [], + description: '', +} + +SEO.propTypes = { + description: string, + metaImg: string, + title: string.isRequired, + noindex: bool, +} + +export default SEO diff --git a/src/components/VideoEmbed/index.js b/src/components/VideoEmbed/index.js index e71014f..35b2e2a 100644 --- a/src/components/VideoEmbed/index.js +++ b/src/components/VideoEmbed/index.js @@ -1,44 +1,29 @@ import { Fragment, h } from 'preact' -import { useEffect, useRef, useState } from 'preact/hooks' - import { string } from 'prop-types' -import { VideoWrapper, Iframe, StyledCrossSvg as CrossSvg } from './styles' +import { Iframe } from './styles' -const Video = ({ url, onClose }) => { - const overlayTimeout = useRef(null) - const [overlayActive, setOverlayActiveState] = useState(false) - - const activateOverlay = () => { - clearTimeout(overlayTimeout.current) - overlayTimeout.current = null - setOverlayActiveState(true) - - overlayTimeout.current = setTimeout( - () => setOverlayActiveState(false), - 1500 - ) - } +const VideoEmbed = ({ url, ...rest }) => { + console.log({ url }) + const id = url.split('/').pop() + const src = `https://tv.undersco.re/videos/embed/${id}?title=0&warningTitle=0&peertubeLink=0` return ( - - -