More work on logic flow + info page
This commit is contained in:
parent
4973f351aa
commit
0ba8deacd0
65
app.js
65
app.js
@ -1,14 +1,13 @@
|
||||
import { h } from 'preact'
|
||||
import axios from 'axios'
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
import { useState, useEffect } from 'preact/hooks'
|
||||
import 'regenerator-runtime/runtime'
|
||||
import { useEffect, useState } from 'preact/hooks'
|
||||
import axios from 'axios'
|
||||
|
||||
import Video from './src/components/Video'
|
||||
import config from './src/data/config'
|
||||
import Info from './src/components/Info'
|
||||
import { useFetch } from './src/assets/hooks/calendar'
|
||||
import { P } from './src/components/Text'
|
||||
import { useCalendar } from './src/hooks/data'
|
||||
import { useTimeout } from './src/hooks/timerHooks'
|
||||
|
||||
// const appStates = [
|
||||
// 'noStream',
|
||||
@ -19,13 +18,58 @@ import { P } from './src/components/Text'
|
||||
export default () => {
|
||||
const [isPlaying, setIsPlaying] = useState(false)
|
||||
const [videoUrl, setVideoUrl] = useState(null)
|
||||
// const [feedData, setFeedData] = useState([])
|
||||
const [feedData, setFeedData] = useState([])
|
||||
const [minLoadTimePassed, setMinTimeUp] = useState(false)
|
||||
const { data, loading } = useCalendar()
|
||||
|
||||
const { data: feedData, loading } = useFetch(`${config.calendar}`)
|
||||
useTimeout(() => {
|
||||
setMinTimeUp(true)
|
||||
}, 1500)
|
||||
|
||||
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])
|
||||
|
||||
return (
|
||||
<div>
|
||||
{/* {false ? (
|
||||
{false ? (
|
||||
<Video
|
||||
playing={isPlaying}
|
||||
setPlaying={setIsPlaying}
|
||||
@ -33,8 +77,9 @@ export default () => {
|
||||
title={config.next_stream.title}
|
||||
org={config.next_stream.org}
|
||||
/>
|
||||
) : ( */}
|
||||
{loading ? <P>LOADING :)</P> : <Info data={feedData} />}
|
||||
) : (
|
||||
<Info data={feedData} loading={loading || !minLoadTimePassed} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -16,6 +16,8 @@
|
||||
"dependencies": {
|
||||
"@peertube/embed-api": "^0.0.4",
|
||||
"axios": "^0.21.1",
|
||||
"date-fns": "^2.19.0",
|
||||
"ical": "^0.8.0",
|
||||
"preact": "^10.5.12",
|
||||
"prop-types": "^15.7.2",
|
||||
"styled-components": "^5.2.1"
|
||||
|
BIN
src/assets/fonts/Karla/Karla-Regular.ttf
Normal file
BIN
src/assets/fonts/Karla/Karla-Regular.ttf
Normal file
Binary file not shown.
@ -1,23 +0,0 @@
|
||||
import { useEffect, useState } from 'preact/hooks'
|
||||
import axios from 'axios'
|
||||
|
||||
export const useFetch = url => {
|
||||
const [data, setData] = useState(null)
|
||||
const [loading, setLoading] = useState(true)
|
||||
|
||||
async function fetchData() {
|
||||
setLoading(true)
|
||||
|
||||
const { data: responseData } = await axios.get(url)
|
||||
console.log('url', url)
|
||||
console.log('responseData', responseData)
|
||||
setData(responseData)
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
fetchData()
|
||||
}, [])
|
||||
|
||||
return { loading, data }
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
import { PeerTubePlayer } from '@peertube/embed-api';
|
||||
import 'regenerator-runtime/runtime';
|
||||
import { toggleVideoPlaying } from './video-controls';
|
||||
import { getVideoData } from './scheduling';
|
||||
|
||||
const streamData = getVideoData();
|
||||
|
||||
const videoWrapper = document.getElementById('video-wrapper');
|
||||
const overlay = document.getElementById('overlay');
|
||||
const videoiFrame = document.querySelector('iframe.video-player');
|
||||
|
||||
const video = {
|
||||
isPlaying: false,
|
||||
overlayVisible: false,
|
||||
};
|
||||
|
||||
export const setUpPlayer = async () => {
|
||||
const player = new PeerTubePlayer(videoiFrame);
|
||||
|
||||
await player.ready;
|
||||
|
||||
onPlayerReady(player);
|
||||
app();
|
||||
};
|
||||
|
||||
const app = () => {
|
||||
if (streamData && streamData) {
|
||||
console.log({ streamData });
|
||||
}
|
||||
};
|
||||
|
||||
const onPlayerReady = (player) => {
|
||||
videoWrapper.addEventListener('mousemove', showOverlay);
|
||||
|
||||
videoWrapper.addEventListener('click', () => {
|
||||
toggleVideoPlaying({
|
||||
player,
|
||||
video,
|
||||
onPlay: () => {
|
||||
hideOverlay();
|
||||
},
|
||||
onPause: () => {
|
||||
showOverlay();
|
||||
},
|
||||
});
|
||||
video.isPlaying = !video.isPlaying;
|
||||
});
|
||||
};
|
||||
|
||||
const showOverlay = () => {
|
||||
if (!video.overlayVisible) {
|
||||
videoWrapper.classList.add('active');
|
||||
overlay.classList.add('active');
|
||||
|
||||
setTimeout(hideOverlay, 2000);
|
||||
}
|
||||
video.overlayVisible = true;
|
||||
};
|
||||
|
||||
const hideOverlay = () => {
|
||||
if (video.isPlaying) {
|
||||
video.overlayVisible = false;
|
||||
videoWrapper.classList.remove('active');
|
||||
overlay.classList.remove('active');
|
||||
}
|
||||
};
|
||||
|
||||
setUpPlayer();
|
@ -1,12 +0,0 @@
|
||||
import axios from 'axios';
|
||||
import 'regenerator-runtime/runtime';
|
||||
import config from '../../data/conf.json';
|
||||
|
||||
export const getVideoData = async () => {
|
||||
console.log({ config });
|
||||
const { data } = await axios.get(`https://tv.undersco.re/api/v1/videos/${config.next_stream.peertube_id}`);
|
||||
|
||||
console.log(data);
|
||||
|
||||
return data;
|
||||
};
|
@ -1,15 +0,0 @@
|
||||
export const toggleVideoPlaying = ({ player, video, onPlay, onPause }) => {
|
||||
console.log('video', video);
|
||||
|
||||
if (video.isPlaying) {
|
||||
player.pause();
|
||||
if (typeof onPause === 'function') {
|
||||
onPause();
|
||||
}
|
||||
} else {
|
||||
player.play();
|
||||
if (typeof onPlay === 'function') {
|
||||
onPlay();
|
||||
}
|
||||
}
|
||||
};
|
@ -1,3 +1,11 @@
|
||||
/* Karla Regular */
|
||||
@font-face {
|
||||
font-family: 'Karla';
|
||||
src: url('../fonts/Karla/Karla-Regular.ttf') format('truetype');
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* Karla Medium */
|
||||
@font-face {
|
||||
font-family: 'Karla';
|
||||
|
4
src/components/Info/helpers.js
Normal file
4
src/components/Info/helpers.js
Normal file
@ -0,0 +1,4 @@
|
||||
export const sortData = data =>
|
||||
Object.values(data)
|
||||
.filter(feedItem => feedItem.type === 'VEVENT')
|
||||
.sort((a, b) => new Date(a.start) - new Date(b.start))
|
@ -1,42 +1,51 @@
|
||||
import { h } from 'preact'
|
||||
/* eslint-disable react/prop-types */
|
||||
import { h, Fragment } from 'preact'
|
||||
import { useEffect, useRef, useState } from 'preact/hooks'
|
||||
import { isBefore } from 'date-fns'
|
||||
|
||||
import { H1, H2, P } from '../Text'
|
||||
import {
|
||||
Wrapper,
|
||||
PositionedLogo as Logo,
|
||||
TaglineContainer,
|
||||
Top,
|
||||
} from './styles'
|
||||
import { P } from '../Text'
|
||||
import translations from '../../data/strings'
|
||||
import InfoLayout from '../InfoLayout'
|
||||
import { VideoCard, Title, InfoContent } from './styles'
|
||||
|
||||
const allowedChannels = [7, 4] // ReclaimFutures, NDC
|
||||
const Info = ({ data, loading }) => {
|
||||
const now = new Date()
|
||||
const pastStreams =
|
||||
data && data.length
|
||||
? data.filter(feeditem => isBefore(new Date(feeditem.end), now))
|
||||
: []
|
||||
|
||||
const Info = ({ data }) => {
|
||||
// const [feed, setFeed] = useState([])
|
||||
|
||||
// useEffect(() => {
|
||||
// setFeed(sortData(data))
|
||||
// }, [data])
|
||||
|
||||
useEffect(() => {
|
||||
console.log({ data })
|
||||
}, [data])
|
||||
const futureStreams =
|
||||
data && data.length
|
||||
? data.filter(feeditem => isBefore(now, new Date(feeditem.start)))
|
||||
: []
|
||||
|
||||
return (
|
||||
<InfoLayout title={translations.en.noStreams}>
|
||||
<P>ding dong</P>
|
||||
<InfoLayout
|
||||
title={
|
||||
data && data.length
|
||||
? `${translations.en.nextStream}:`
|
||||
: translations.en.noStreams
|
||||
}
|
||||
loading={loading}
|
||||
>
|
||||
{!loading && (
|
||||
<InfoContent>
|
||||
{futureStreams.map(feeditem => (
|
||||
<VideoCard key={feeditem.start} {...feeditem} />
|
||||
))}
|
||||
{pastStreams.length ? (
|
||||
<Fragment>
|
||||
<Title>{translations.en.pastStream}:</Title>
|
||||
{pastStreams.map(feeditem => (
|
||||
<VideoCard key={feeditem.start} hasPassed {...feeditem} />
|
||||
))}
|
||||
</Fragment>
|
||||
) : null}
|
||||
</InfoContent>
|
||||
)}
|
||||
</InfoLayout>
|
||||
)
|
||||
}
|
||||
|
||||
const sortData = data => {
|
||||
// if (!data || data?.length === 0) return
|
||||
// console.log('data', data)
|
||||
// return data.filter(feedItem => {
|
||||
// return allowedChannels.includes(feedItem.channel.id) && feedItem.isLive
|
||||
// })
|
||||
}
|
||||
|
||||
export default Info
|
||||
|
@ -1,6 +1,12 @@
|
||||
import { format } from 'date-fns'
|
||||
import { h, Fragment } from 'preact'
|
||||
import styled from 'styled-components'
|
||||
import { colours } from '../../assets/theme'
|
||||
import config from '../../data/config'
|
||||
import Logo from '../Logo'
|
||||
import translations from '../../data/strings'
|
||||
|
||||
import { P, H1, H2, Span, Label } from '../Text'
|
||||
|
||||
export const Wrapper = styled.div`
|
||||
height: 100vh;
|
||||
@ -27,6 +33,10 @@ export const Wrapper = styled.div`
|
||||
|
||||
export const Top = styled.div``
|
||||
|
||||
export const InfoContent = styled.div`
|
||||
padding-bottom: 1em;
|
||||
`
|
||||
|
||||
export const PositionedLogo = styled(Logo)`
|
||||
margin-bottom: 64px;
|
||||
`
|
||||
@ -36,3 +46,54 @@ export const TaglineContainer = styled.div`
|
||||
margin-top: 32px;
|
||||
}
|
||||
`
|
||||
|
||||
export const Title = styled(H1)`
|
||||
margin: 0.3em 0;
|
||||
`
|
||||
|
||||
const VCWrapper = styled.div`
|
||||
max-width: 600px;
|
||||
margin-bottom: 3em;
|
||||
border-left: 7px solid ${colours.midnightDarker};
|
||||
padding-left: 1em;
|
||||
`
|
||||
|
||||
const VCImg = styled.img`
|
||||
width: 100%;
|
||||
`
|
||||
|
||||
const ItemTitle = styled(H2)`
|
||||
margin-bottom: 0.3em;
|
||||
`
|
||||
|
||||
const DateLabel = styled(Label)`
|
||||
margin: 1em 0;
|
||||
display: block;
|
||||
`
|
||||
|
||||
export const VideoCard = ({
|
||||
name,
|
||||
description,
|
||||
start,
|
||||
end,
|
||||
previewPath,
|
||||
hasPassed,
|
||||
}) => {
|
||||
return (
|
||||
<VCWrapper>
|
||||
<ItemTitle>{name}</ItemTitle>
|
||||
<VCImg src={`${config.peertube_root}${previewPath}`} alt="" />
|
||||
<DateLabel colour={colours.midnight} size="18">
|
||||
{`${
|
||||
hasPassed
|
||||
? translations.en.streamDatePast
|
||||
: translations.en.streamDateFuture
|
||||
}`}
|
||||
<Span bold colour={colours.midnight}>
|
||||
{format(new Date(start), 'hh:mm dd/MM/yy')}
|
||||
</Span>
|
||||
</DateLabel>
|
||||
<P>{description}</P>
|
||||
</VCWrapper>
|
||||
)
|
||||
}
|
||||
|
@ -1,34 +1,53 @@
|
||||
import { h } from 'preact'
|
||||
import { useEffect, useRef, useState } from 'preact/hooks'
|
||||
import { bool, string } from 'prop-types'
|
||||
|
||||
import { H1, H2, P } from '../Text'
|
||||
import { H1, H2 } from '../Text'
|
||||
import {
|
||||
Wrapper,
|
||||
PositionedLogo as Logo,
|
||||
TaglineContainer,
|
||||
Top,
|
||||
Title,
|
||||
Content,
|
||||
Fade,
|
||||
} from './styles'
|
||||
import translations from '../../data/strings'
|
||||
import { colours } from '../../assets/theme'
|
||||
import Loader from '../Loader'
|
||||
import { useTimeout } from '../../hooks/timerHooks'
|
||||
|
||||
const InfoLayout = ({ title, children }) => {
|
||||
const InfoLayout = ({ title, children, loading }) => {
|
||||
return (
|
||||
<Wrapper>
|
||||
<Fade>
|
||||
<Logo active colour={colours.midnightDarker} />
|
||||
</Fade>
|
||||
<Content>
|
||||
<H2>{title}</H2>
|
||||
{loading ? (
|
||||
<div>
|
||||
<Loader />
|
||||
</div>
|
||||
) : (
|
||||
<Title>{title}</Title>
|
||||
)}
|
||||
{children}
|
||||
</Content>
|
||||
|
||||
<TaglineContainer>
|
||||
{translations &&
|
||||
translations.en.underscoreTagline.map(line => (
|
||||
<H1 key={line}>{line}</H1>
|
||||
<H1 align="right" key={line}>
|
||||
{line}
|
||||
</H1>
|
||||
))}
|
||||
</TaglineContainer>
|
||||
</Wrapper>
|
||||
)
|
||||
}
|
||||
|
||||
InfoLayout.propTypes = {
|
||||
title: string,
|
||||
loading: bool,
|
||||
}
|
||||
|
||||
export default InfoLayout
|
||||
|
@ -1,5 +1,8 @@
|
||||
import styled from 'styled-components'
|
||||
import { colours } from '../../assets/theme'
|
||||
|
||||
import { H1 } from '../Text'
|
||||
|
||||
import Logo from '../Logo'
|
||||
|
||||
export const Wrapper = styled.div`
|
||||
@ -41,14 +44,52 @@ export const Wrapper = styled.div`
|
||||
export const Top = styled.div`
|
||||
width: 50%;
|
||||
`
|
||||
export const Content = styled.div``
|
||||
|
||||
export const PositionedLogo = styled(Logo)`
|
||||
const gradientColour = '#F8E5E2'
|
||||
const getGradient = direction =>
|
||||
`linear-gradient(to ${direction}, ${gradientColour}ee 0%,${gradientColour}00 100%);`
|
||||
|
||||
// prettier-ignore
|
||||
export const Fade = styled.div`
|
||||
width: 100%;
|
||||
background-color: linear;
|
||||
position: fixed;
|
||||
top: 2em;
|
||||
padding: 2em 0 1em 2em;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background: ${getGradient('bottom')};
|
||||
`
|
||||
export const Title = styled(H1)`
|
||||
margin: 0.5em 0;
|
||||
`
|
||||
|
||||
export const Content = styled.div`
|
||||
/* margin-bottom: 3em; */
|
||||
`
|
||||
|
||||
export const PositionedLogo = styled(Logo)``
|
||||
|
||||
export const TaglineContainer = styled.div`
|
||||
background: ${getGradient('top')};
|
||||
position: fixed;
|
||||
bottom: 2em;
|
||||
bottom: 0em;
|
||||
padding-bottom: 0.5em;
|
||||
right: 1em;
|
||||
pointer-events: none;
|
||||
|
||||
@media screen and (max-width: 1200px) {
|
||||
width: 100vw;
|
||||
right: auto;
|
||||
left: 1.5em;
|
||||
h1 {
|
||||
font-size: 32px;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 800px) {
|
||||
h1 {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
`
|
||||
|
38
src/components/Loader/index.js
Normal file
38
src/components/Loader/index.js
Normal file
@ -0,0 +1,38 @@
|
||||
import { h } from 'preact'
|
||||
import { useRef, useState } from 'preact/hooks'
|
||||
import { useInterval, useTimeout } from '../../hooks/timerHooks'
|
||||
import { colours } from '../../assets/theme'
|
||||
import { H1 } from '../Text'
|
||||
|
||||
// const symbols = ['⌏', '⌎', '⌌', '⌍']
|
||||
|
||||
const Loader = ({
|
||||
active = true,
|
||||
offset = 0,
|
||||
animation = [':..', '.:.', '..:', '...'],
|
||||
}) => {
|
||||
const [text, setText] = useState('.')
|
||||
const arrayPosition = useRef(offset)
|
||||
const rate = 350
|
||||
|
||||
useInterval(
|
||||
() => {
|
||||
setText(animation[arrayPosition.current])
|
||||
|
||||
if (arrayPosition.current === animation.length - 1) {
|
||||
arrayPosition.current = 0
|
||||
} else {
|
||||
arrayPosition.current += 1
|
||||
}
|
||||
},
|
||||
active ? rate : null
|
||||
)
|
||||
|
||||
return (
|
||||
<H1 as="span" colour={colours.midnightDarker}>
|
||||
{text}
|
||||
</H1>
|
||||
)
|
||||
}
|
||||
|
||||
export default Loader
|
@ -25,7 +25,7 @@ const Text = ({
|
||||
weight={weight}
|
||||
lineHeight={lineHeight}
|
||||
$fontFamily={fontFamily}
|
||||
size={size}
|
||||
$size={size}
|
||||
selectable={selectable}
|
||||
{...rest}
|
||||
>
|
||||
@ -66,7 +66,7 @@ export const H1 = ({ children, ...rest }) => {
|
||||
<Text
|
||||
tag="h1"
|
||||
weight="700"
|
||||
size="48"
|
||||
$size="48"
|
||||
lineHeight="0.8"
|
||||
fontFamily="Lunchtype24"
|
||||
{...rest}
|
||||
@ -80,7 +80,7 @@ export const H2 = ({ children, ...rest }) => (
|
||||
<Text
|
||||
tag="h2"
|
||||
weight="700"
|
||||
size="25"
|
||||
$size="25"
|
||||
lineHeight="1"
|
||||
fontFamily="Lunchtype24"
|
||||
{...rest}
|
||||
@ -92,9 +92,9 @@ export const H2 = ({ children, ...rest }) => (
|
||||
export const P = ({ children, ...rest }) => (
|
||||
<Text
|
||||
tag="p"
|
||||
weight="500"
|
||||
size="13"
|
||||
lineHeight="16px"
|
||||
weight="400"
|
||||
$size="15"
|
||||
lineHeight="21px"
|
||||
fontFamily="Karla"
|
||||
{...rest}
|
||||
>
|
||||
@ -102,15 +102,15 @@ export const P = ({ children, ...rest }) => (
|
||||
</Text>
|
||||
)
|
||||
export const Span = ({ children, ...rest }) => (
|
||||
<Text tag="span" size="inherit" weight="inherit" {...rest}>
|
||||
<Text tag="span" $size="inherit" weight="inherit" {...rest}>
|
||||
{children}
|
||||
</Text>
|
||||
)
|
||||
export const Label = ({ children, ...rest }) => (
|
||||
export const Label = ({ children, size, ...rest }) => (
|
||||
<Text
|
||||
tag="label"
|
||||
weight="500"
|
||||
size="13"
|
||||
$size={size || '15'}
|
||||
lineHeight="13px"
|
||||
fontFamily="Karla"
|
||||
{...rest}
|
||||
|
@ -3,7 +3,7 @@ import { colours } from '../../assets/theme'
|
||||
|
||||
export const TextBase = styled.span`
|
||||
${({
|
||||
size,
|
||||
$size,
|
||||
weight,
|
||||
colour,
|
||||
align,
|
||||
@ -21,7 +21,7 @@ export const TextBase = styled.span`
|
||||
opacity: ${opacity};
|
||||
user-select: ${selectable ? 'inherit' : 'none'};
|
||||
text-decoration: ${underline ? 'underline' : 'none'};
|
||||
font-size: ${size}px;
|
||||
font-size: ${$size}px;
|
||||
|
||||
::selection {
|
||||
background-color: ${colours.midnightDarker};
|
||||
|
@ -1,7 +1,10 @@
|
||||
export default {
|
||||
en: {
|
||||
nextStream: 'Next stream',
|
||||
nextStream: 'Next streams',
|
||||
pastStream: 'Latest streams',
|
||||
noStreams: 'No upcoming streams, check back soon.',
|
||||
underscoreTagline: ['LEAVE THE', 'SURVEILLANCE ECONOMY', '— TOGETHER.'],
|
||||
streamDateFuture: 'Going live at: ',
|
||||
streamDatePast: 'First broadcast: ',
|
||||
},
|
||||
}
|
||||
|
96
src/hooks/data.js
Normal file
96
src/hooks/data.js
Normal file
@ -0,0 +1,96 @@
|
||||
import { useEffect, useState } from 'preact/hooks'
|
||||
import axios from 'axios'
|
||||
import ical from 'ical'
|
||||
import config from '../data/config'
|
||||
|
||||
export const useCalendar = () => {
|
||||
const [data, setData] = useState(null)
|
||||
const [loading, setLoading] = useState(true)
|
||||
|
||||
async function fetchData() {
|
||||
setLoading(true)
|
||||
|
||||
const { data: responseData } = await axios.get(`${config.calendar}`)
|
||||
const streamsData = Object.values(ical.parseICS(responseData))
|
||||
.filter(feedItem => feedItem.type === 'VEVENT')
|
||||
.sort((a, b) => new Date(a.start) - new Date(b.start))
|
||||
setData(streamsData)
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
fetchData()
|
||||
}, [])
|
||||
|
||||
return { loading, data }
|
||||
}
|
||||
|
||||
// export const useCalendar = () => {
|
||||
// const [data, setData] = useState(null)
|
||||
// const [loading, setLoading] = useState(true)
|
||||
|
||||
// async function fetchData() {
|
||||
// setLoading(true)
|
||||
|
||||
// const { data: responseData } = await axios.get(`${config.calendar}`)
|
||||
// const streamsData = Object.values(ical.parseICS(responseData))
|
||||
// .filter(feedItem => feedItem.type === 'VEVENT')
|
||||
// .sort((a, b) => new Date(a.start) - new Date(b.start))
|
||||
// setData(streamsData)
|
||||
// setLoading(false)
|
||||
// }
|
||||
|
||||
// useEffect(() => {
|
||||
// fetchData()
|
||||
// }, [])
|
||||
|
||||
// return { loading, data }
|
||||
// }
|
||||
// useEffect(() => {
|
||||
// const feedPromise =
|
||||
// data &&
|
||||
// data.map(async feedItem => {
|
||||
// if (feedItem.url) {
|
||||
// const id = feedItem.url.val.split('/').pop()
|
||||
|
||||
// const {
|
||||
// data: {
|
||||
// account,
|
||||
// category,
|
||||
// channel,
|
||||
// description,
|
||||
// embedPath,
|
||||
// language,
|
||||
// name,
|
||||
// state,
|
||||
// previewPath,
|
||||
// views,
|
||||
// },
|
||||
// } = await axios.get(`https://tv.undersco.re/api/v1/videos/${id}`)
|
||||
|
||||
// const item = {
|
||||
// name,
|
||||
// account,
|
||||
// category,
|
||||
// channel,
|
||||
// description,
|
||||
// embedPath,
|
||||
// language,
|
||||
// state,
|
||||
// previewPath,
|
||||
// views,
|
||||
// start: feedItem.start,
|
||||
// end: feedItem.end,
|
||||
// }
|
||||
|
||||
// console.log(item)
|
||||
|
||||
// return item
|
||||
// }
|
||||
// return null
|
||||
// })
|
||||
|
||||
// feedPromise.then(result => {
|
||||
// console.log(result)
|
||||
// })
|
||||
// }, [data])
|
38
src/hooks/timerHooks.js
Normal file
38
src/hooks/timerHooks.js
Normal file
@ -0,0 +1,38 @@
|
||||
/* eslint-disable consistent-return */
|
||||
import { useEffect, useRef } from 'preact/hooks'
|
||||
|
||||
export const useInterval = (callback, interval) => {
|
||||
const savedCallback = useRef()
|
||||
|
||||
useEffect(() => {
|
||||
savedCallback.current = callback
|
||||
}, [callback])
|
||||
|
||||
useEffect(() => {
|
||||
function tick() {
|
||||
savedCallback.current()
|
||||
}
|
||||
if (interval !== null) {
|
||||
const id = setInterval(tick, interval)
|
||||
return () => clearInterval(id)
|
||||
}
|
||||
}, [interval])
|
||||
}
|
||||
|
||||
export const useTimeout = (callback, timeout) => {
|
||||
const savedCallback = useRef()
|
||||
|
||||
useEffect(() => {
|
||||
savedCallback.current = callback
|
||||
}, [callback])
|
||||
|
||||
useEffect(() => {
|
||||
function tick() {
|
||||
savedCallback.current()
|
||||
}
|
||||
if (timeout !== null) {
|
||||
const id = setTimeout(tick, timeout)
|
||||
return () => clearTimeout(id)
|
||||
}
|
||||
}, [timeout])
|
||||
}
|
24
yarn.lock
24
yarn.lock
@ -2483,6 +2483,11 @@ data-urls@^1.1.0:
|
||||
whatwg-mimetype "^2.2.0"
|
||||
whatwg-url "^7.0.0"
|
||||
|
||||
date-fns@^2.19.0:
|
||||
version "2.19.0"
|
||||
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.19.0.tgz#65193348635a28d5d916c43ec7ce6fbd145059e1"
|
||||
integrity sha512-X3bf2iTPgCAQp9wvjOQytnf5vO5rESYRXlPIVcgSbtT5OTScPcsf9eZU+B/YIkKAtYr5WeCii58BgATrNitlWg==
|
||||
|
||||
deasync@^0.1.14:
|
||||
version "0.1.21"
|
||||
resolved "https://registry.yarnpkg.com/deasync/-/deasync-0.1.21.tgz#bb11eabd4466c0d8776f0d82deb8a6126460d30f"
|
||||
@ -3612,6 +3617,13 @@ https-browserify@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
|
||||
integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
|
||||
|
||||
ical@^0.8.0:
|
||||
version "0.8.0"
|
||||
resolved "https://registry.yarnpkg.com/ical/-/ical-0.8.0.tgz#aa93f021dfead58e54aaa22076a11ca07d65886b"
|
||||
integrity sha512-/viUSb/RGLLnlgm0lWRlPBtVeQguQRErSPYl3ugnUaKUnzQswKqOG3M8/P1v1AB5NJwlHTuvTq1cs4mpeG2rCg==
|
||||
dependencies:
|
||||
rrule "2.4.1"
|
||||
|
||||
iconv-lite@0.4.24, iconv-lite@^0.4.17:
|
||||
version "0.4.24"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
||||
@ -4263,6 +4275,11 @@ lru-cache@^4.0.1, lru-cache@^4.1.5:
|
||||
pseudomap "^1.0.2"
|
||||
yallist "^2.1.2"
|
||||
|
||||
luxon@^1.3.3:
|
||||
version "1.26.0"
|
||||
resolved "https://registry.yarnpkg.com/luxon/-/luxon-1.26.0.tgz#d3692361fda51473948252061d0f8561df02b578"
|
||||
integrity sha512-+V5QIQ5f6CDXQpWNICELwjwuHdqeJM1UenlZWx5ujcRMc9venvluCjFb4t5NYLhb6IhkbMVOxzVuOqkgMxee2A==
|
||||
|
||||
magic-string@^0.22.4:
|
||||
version "0.22.5"
|
||||
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.22.5.tgz#8e9cf5afddf44385c1da5bc2a6a0dbd10b03657e"
|
||||
@ -5792,6 +5809,13 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
|
||||
hash-base "^3.0.0"
|
||||
inherits "^2.0.1"
|
||||
|
||||
rrule@2.4.1:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/rrule/-/rrule-2.4.1.tgz#1d0db4e45f2b0e92e2cca62d2f7093729ac7ec94"
|
||||
integrity sha512-+NcvhETefswZq13T8nkuEnnQ6YgUeZaqMqVbp+ZiFDPCbp3AVgQIwUvNVDdMNrP05bKZG9ddDULFp0qZZYDrxg==
|
||||
optionalDependencies:
|
||||
luxon "^1.3.3"
|
||||
|
||||
run-async@^2.2.0:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455"
|
||||
|
Loading…
Reference in New Issue
Block a user