diff --git a/app.js b/app.js
index 10f95af..b86cad2 100644
--- a/app.js
+++ b/app.js
@@ -1,26 +1,21 @@
import { h } from 'preact'
import { useState, useEffect } from 'preact/hooks'
-import 'regenerator-runtime/runtime'
-import axios from 'axios'
+import { isWithinInterval, subHours } from 'date-fns'
+import { addHours } from 'date-fns/esm'
import Video from './src/components/Video'
import config from './src/data/config'
import Info from './src/components/Info'
-import { useCalendar } from './src/hooks/data'
+import { useEventStream } from './src/hooks/data'
import { useTimeout } from './src/hooks/timerHooks'
-// const appStates = [
-// 'noStream',
-// 'streamLive',
-// 'streamFinished'
-// ]
-
export default () => {
const [isPlaying, setIsPlaying] = useState(false)
- const [videoUrl, setVideoUrl] = useState(null)
- const [feedData, setFeedData] = useState([])
+ const [currentVideo, setCurrentVideo] = useState(null)
+ const [streamIsLive, setStreamLive] = useState(false)
+ const [infoActive, setInfoActive] = useState(false)
const [minLoadTimePassed, setMinTimeUp] = useState(false)
- const { data, loading } = useCalendar()
+ const { data, loading } = useEventStream()
useTimeout(() => {
setMinTimeUp(true)
@@ -28,40 +23,26 @@ export default () => {
useEffect(() => {
if (data && data.length) {
- data.forEach(async (calItem, index) => {
- if (calItem.url) {
- const id = calItem.url.val.split('/').pop()
-
- const {
- data: {
- account,
- category,
- channel,
- embedPath,
- language,
- name,
- state,
- previewPath,
- views,
- },
- } = await axios.get(`https://tv.undersco.re/api/v1/videos/${id}`)
-
- const item = {
- name,
- account,
- category,
- channel,
- description: calItem.description,
- embedPath,
- language,
- state,
- previewPath,
- views,
- start: calItem.start,
- end: calItem.end,
- id,
- }
- setFeedData(arr => [...arr, item])
+ data.forEach((stream, index) => {
+ // if (stream.title === 'A Wider Screen') {
+ if (index === 0) {
+ setCurrentVideo(stream)
+ }
+ if (
+ isWithinInterval(new Date(), {
+ start: subHours(stream.start, 1),
+ end: addHours(stream.end, 1),
+ })
+ ) {
+ setCurrentVideo(stream)
+ }
+ if (
+ isWithinInterval(new Date(), {
+ start: stream.start,
+ end: stream.end,
+ })
+ ) {
+ setStreamLive(`${config.peertube_root}${stream.embedPath}`)
}
})
}
@@ -69,16 +50,23 @@ export default () => {
return (
- {false ? (
+ {currentVideo && !infoActive && minLoadTimePassed ? (
) : (
-
+
)}
)
diff --git a/package.json b/package.json
index 9dd4d37..c29f780 100644
--- a/package.json
+++ b/package.json
@@ -35,4 +35,4 @@
"sass": "^1.32.8",
"scss": "^0.2.4"
}
-}
+}
\ No newline at end of file
diff --git a/src/assets/img/IconSM.png b/src/assets/img/IconSM.png
new file mode 100644
index 0000000..d554c12
Binary files /dev/null and b/src/assets/img/IconSM.png differ
diff --git a/src/assets/theme/index.js b/src/assets/theme/index.js
index 3471bfb..35bb412 100644
--- a/src/assets/theme/index.js
+++ b/src/assets/theme/index.js
@@ -3,7 +3,7 @@ export const colours = {
midnightDarker: '#112B39',
offwhite: '#f6f4f5',
- white: '#fff',
+ white: '#ffffff',
highlight: '#03a59e',
roseDarker: '#FEB9B3',
rose: '#F1CFCD',
diff --git a/src/components/Chat/index.js b/src/components/Chat/index.js
index c377332..d7771d9 100644
--- a/src/components/Chat/index.js
+++ b/src/components/Chat/index.js
@@ -1,19 +1,40 @@
import { h } from 'preact'
+import { useEffect, useRef, useState } from 'preact/hooks'
+import { useWindowDimensions } from '../../hooks/dom'
+import { useToggle } from '../../hooks/utility'
-import { ChatWrapper } from './styles'
+import { Label } from '../Text'
+import { ChatFrame, ChatWrapper, ChatHeader, CloseBox } from './styles'
+import { colours } from '../../assets/theme'
const Chat = ({}) => {
- return (
+ const { width, height } = useWindowDimensions()
+ const [chatIsOpen, toggleChatOpen] = useToggle(true)
+ return chatIsOpen ? (
-
+
+
+
+
+
+
+
+ ) : (
+
+
+
)
}
diff --git a/src/components/Chat/styles.js b/src/components/Chat/styles.js
index 7ff7a2b..84b1466 100644
--- a/src/components/Chat/styles.js
+++ b/src/components/Chat/styles.js
@@ -1,10 +1,55 @@
import styled from 'styled-components'
import { colours, ui } from '../../assets/theme'
+import CrossSvg from '../Svg/Cross'
+import { Label } from '../Text'
+
+export const ChatFrame = styled.div`
+ /* border: 2px solid ${colours.white}; */
+ /* padding: 20px; */
+`
export const ChatWrapper = styled.div`
position: fixed;
z-index: 10;
- bottom: 0;
- right: 32px;
+ bottom: -5px;
+ right: 0;
+ backdrop-filter: blur(20px);
+ background-color: ${colours.midnight}40;
+ /* padding: 20px; */
border-radius: ${ui.borderRadius}px;
`
+
+export const ChatHeader = styled.div`
+ position: absolute;
+ bottom: ${props => (props.chatIsOpen ? 'initial' : 0)};
+ top: ${props => (props.chatIsOpen ? '4px' : 'initial')};
+ /* cursor: ${props => (props.dragging ? 'grabbing' : 'grab')}; */
+ border-radius: ${ui.borderRadius}px 0 0 0;
+
+
+ height: 32px;
+ box-sizing: border-box;
+ display: flex;
+ align-items: center;
+ width: ${props => (props.chatIsOpen ? '100%' : 'fit-content')};
+
+ justify-content: space-between;
+ padding: 0px 0px 3px 0px;
+ right: 0;
+ box-sizing: content-box;
+ border: ${props =>
+ props.chatIsOpen ? 'none' : `1px solid ${colours.white}`};
+ border-bottom: ${props =>
+ props.chatIsOpen ? `1px solid ${colours.white}75` : 'none'};
+ border-right: none;
+
+ label {
+ margin-left: 12px;
+ margin-right: ${props => (props.chatIsOpen ? '0' : '12px')}
+ }
+`
+
+export const CloseBox = styled(CrossSvg)`
+ padding: 12px;
+ cursor: pointer;
+`
diff --git a/src/components/Info/index.js b/src/components/Info/index.js
index 60a06f2..352e576 100644
--- a/src/components/Info/index.js
+++ b/src/components/Info/index.js
@@ -1,39 +1,55 @@
/* eslint-disable react/prop-types */
import { h, Fragment } from 'preact'
-import { useEffect, useRef, useState } from 'preact/hooks'
-import { isBefore } from 'date-fns'
+import { isFuture, isPast } from 'date-fns'
import { P } from '../Text'
import translations from '../../data/strings'
import InfoLayout from '../InfoLayout'
-import { VideoCard, Title, InfoContent } from './styles'
+import {
+ VideoCard,
+ Title,
+ InfoContent,
+ PositionedCross as CrossSvg,
+} from './styles'
-const Info = ({ data, loading }) => {
- const now = new Date()
+const Info = ({ data, loading, infoActive, setInfoActive, currentVideo }) => {
const pastStreams =
data && data.length
- ? data.filter(feeditem => isBefore(new Date(feeditem.end), now))
+ ? data.filter(feeditem => isPast(new Date(feeditem.end)))
: []
const futureStreams =
data && data.length
- ? data.filter(feeditem => isBefore(now, new Date(feeditem.start)))
+ ? data.filter(
+ feeditem =>
+ feeditem.id !== (currentVideo && currentVideo.id) &&
+ isFuture(new Date(feeditem.start))
+ )
: []
+ console.log({ currentVideo })
+
return (
-
+
+ {infoActive && setInfoActive(false)} />}
{!loading && (
- {futureStreams.map(feeditem => (
-
- ))}
+ {currentVideo && (
+
+ {translations.en.nowPlaying}:
+
+
+ )}
+
+ {futureStreams.length && (
+
+ {translations.en.nextStream}:
+ {futureStreams.map(feeditem => (
+
+ ))}
+
+ )}
+
{pastStreams.length ? (
{translations.en.pastStream}:
diff --git a/src/components/Info/styles.js b/src/components/Info/styles.js
index ebcef2a..6d73930 100644
--- a/src/components/Info/styles.js
+++ b/src/components/Info/styles.js
@@ -5,8 +5,11 @@ import { colours } from '../../assets/theme'
import config from '../../data/config'
import Logo from '../Logo'
import translations from '../../data/strings'
+import CrossSvg from '../Svg/Cross'
import { P, H1, H2, Span, Label } from '../Text'
+import Link from '../Link'
+import { bool, instanceOf, string } from 'prop-types'
export const Wrapper = styled.div`
height: 100vh;
@@ -51,10 +54,24 @@ export const Title = styled(H1)`
margin: 0.3em 0;
`
+export const PositionedCross = styled(CrossSvg)`
+ position: fixed;
+ right: 2.5em;
+ top: 2em;
+ width: 24px;
+ height: 24px;
+ cursor: pointer;
+ stroke: ${colours.midnightDarker};
+
+ &:hover {
+ opacity: 0.5;
+ }
+`
+
const VCWrapper = styled.div`
max-width: 600px;
- margin-bottom: 3em;
- border-left: 7px solid ${colours.midnightDarker};
+ margin: 0 0 6em 2px;
+ border-left: 5px solid ${colours.midnightDarker};
padding-left: 1em;
`
@@ -71,29 +88,52 @@ const DateLabel = styled(Label)`
display: block;
`
+const LinkBlock = styled(Link)`
+ display: block;
+ width: 100%;
+`
+
export const VideoCard = ({
- name,
+ title,
description,
start,
end,
previewPath,
hasPassed,
-}) => {
- return (
-
- {name}
-
-
- {`${
- hasPassed
- ? translations.en.streamDatePast
- : translations.en.streamDateFuture
- }`}
-
- {format(new Date(start), 'hh:mm dd/MM/yy')}
-
-
- {description}
-
- )
+ videoUrl,
+}) => (
+
+ {videoUrl && hasPassed ? (
+
+ {title}
+
+
+ ) : (
+
+ {title}
+
+
+ )}
+
+ {`${
+ hasPassed
+ ? translations.en.streamDatePast
+ : translations.en.streamDateFuture
+ }`}
+
+ {format(new Date(start), 'hh:mm dd/MM/yy')}
+
+
+ {description}
+
+)
+
+VideoCard.propTypes = {
+ title: string,
+ description: string,
+ start: instanceOf(Date),
+ end: instanceOf(Date),
+ previewPath: string,
+ hasPassed: bool,
+ videoUrl: string,
}
diff --git a/src/components/InfoLayout/index.js b/src/components/InfoLayout/index.js
index 12ccc79..aca8c24 100644
--- a/src/components/InfoLayout/index.js
+++ b/src/components/InfoLayout/index.js
@@ -7,7 +7,7 @@ import {
Wrapper,
PositionedLogo as Logo,
TaglineContainer,
- Title,
+ LoaderWrapper,
Content,
Fade,
} from './styles'
@@ -16,7 +16,7 @@ import { colours } from '../../assets/theme'
import Loader from '../Loader'
import { useTimeout } from '../../hooks/timerHooks'
-const InfoLayout = ({ title, children, loading }) => {
+const InfoLayout = ({ children, loading }) => {
return (
@@ -24,13 +24,12 @@ const InfoLayout = ({ title, children, loading }) => {
{loading ? (
-
+
-
+
) : (
- {title}
+ children
)}
- {children}
@@ -46,7 +45,6 @@ const InfoLayout = ({ title, children, loading }) => {
}
InfoLayout.propTypes = {
- title: string,
loading: bool,
}
diff --git a/src/components/InfoLayout/styles.js b/src/components/InfoLayout/styles.js
index 01b9afa..05dca9c 100644
--- a/src/components/InfoLayout/styles.js
+++ b/src/components/InfoLayout/styles.js
@@ -59,8 +59,14 @@ export const Fade = styled.div`
left: 0;
background: ${getGradient('bottom')};
`
-export const Title = styled(H1)`
- margin: 0.5em 0;
+export const LoaderWrapper = styled.div`
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100vh;
+ position: fixed;
+ top: 0;
+ width: 50vw;
`
export const Content = styled.div`
diff --git a/src/components/Link/index.js b/src/components/Link/index.js
new file mode 100644
index 0000000..3e85cf9
--- /dev/null
+++ b/src/components/Link/index.js
@@ -0,0 +1,6 @@
+import styled from 'styled-components'
+
+export const Link = styled.a`
+ text-decoration: none;
+`
+export default Link
diff --git a/src/components/Svg/Cross.js b/src/components/Svg/Cross.js
new file mode 100644
index 0000000..8a53243
--- /dev/null
+++ b/src/components/Svg/Cross.js
@@ -0,0 +1,16 @@
+import { h } from 'preact'
+import { bool, string } from 'prop-types'
+
+const Cross = ({ colour = 'inherit', size, ...rest }) => (
+
+)
+
+export default Cross
diff --git a/src/components/Video/index.js b/src/components/Video/index.js
index 4569656..58570e1 100644
--- a/src/components/Video/index.js
+++ b/src/components/Video/index.js
@@ -4,16 +4,18 @@ import { bool, func, string } from 'prop-types'
import 'regenerator-runtime/runtime'
import { PeerTubePlayer } from '@peertube/embed-api'
-import Logo from '../Logo'
import Chat from '../Chat'
-import { H2 } from '../Text'
import Overlay from '../VideoOverlay'
+import { useToggle } from '../../hooks/utility'
import { VideoWrapper, Iframe } from './styles'
-const Video = ({ playing, setPlaying, src, title, org }) => {
+const Video = ({ playing, setPlaying, src, title, org, setInfoActive }) => {
const videoiFrame = useRef(null)
const overlayTimeout = useRef(null)
+ const videoWrapperEl = useRef(null)
const [videoReady, setVideoReady] = useState(false)
+ // const [isFullscreen, toggleFullscreen] = useToggle(false)
+ // const [chatActive, setChatActive] = useState(false)
const [overlayActive, setOverlayActiveState] = useState(true)
const ptVideo = useRef(null)
@@ -43,6 +45,37 @@ const Video = ({ playing, setPlaying, src, title, org }) => {
}
}, [playing])
+ const goFullscreen = () => {
+ // toggleFullscreen()
+ }
+
+ const exitFullscreen = () => {
+ // toggleFullscreen()
+ }
+
+ const handleKeyPress = keyCode => {
+ if (keyCode === 32) {
+ setPlaying(!playing)
+ }
+ // if (keyCode === 70 && !isFullscreen) {
+ // console.log('goFullscreen')
+ // goFullscreen()
+ // }
+ // if (keyCode === 70 && isFullscreen) {
+ // console.log('exitFullscreen')
+ // exitFullscreen()
+ // }
+ }
+
+ useEffect(() => {
+ window.addEventListener('keydown', ({ keyCode }) => handleKeyPress(keyCode))
+
+ return () =>
+ window.removeEventListener('keydown', ({ keyCode }) =>
+ handleKeyPress(keyCode)
+ )
+ }, [])
+
const activateOverlay = () => {
clearTimeout(overlayTimeout.current)
setOverlayActiveState(true)
@@ -58,8 +91,14 @@ const Video = ({ playing, setPlaying, src, title, org }) => {
$active={overlayActive || !playing}
onClick={() => setPlaying(!playing)}
onMouseMove={activateOverlay}
+ // ref={videoWrapperEl}
>
-
+