ch ch changes
This commit is contained in:
parent
fdc031c64b
commit
c24124c970
35
index.js
Normal file → Executable file
35
index.js
Normal file → Executable file
@ -16,13 +16,16 @@ import Series from './src/pages/Series'
|
||||
import Program from './src/pages/Program'
|
||||
import StreamPreview from './src/components/StreamPreview'
|
||||
import Video from './src/components/Video'
|
||||
import Chat from './src/components/Chat'
|
||||
// import { useWindowSize } from './src/hooks/dom'
|
||||
|
||||
const App = () => {
|
||||
const { theme } = useTheme((store) => store)
|
||||
const { theme } = useTheme(store => store)
|
||||
const { data, loading: eventsLoading, error } = useEventApi()
|
||||
const [minLoadTimePassed, setMinTimeUp] = useState(false)
|
||||
const { setCurrentStream, currentStream, streamIsLive } = useStreamStore(store => store)
|
||||
const { setCurrentStream, currentStream, streamIsLive } = useStreamStore(
|
||||
store => store
|
||||
)
|
||||
const streamActive = useUiStore(store => store.streamActive)
|
||||
usePeertubeApi(data.episodes)
|
||||
|
||||
@ -37,7 +40,10 @@ const App = () => {
|
||||
new Date(stream.beginsOn),
|
||||
'Europe/Berlin'
|
||||
)
|
||||
const utcEndDate = zonedTimeToUtc(new Date(stream.endsOn), 'Europe/Berlin')
|
||||
const utcEndDate = zonedTimeToUtc(
|
||||
new Date(stream.endsOn),
|
||||
'Europe/Berlin'
|
||||
)
|
||||
const { timeZone } = Intl.DateTimeFormat().resolvedOptions()
|
||||
|
||||
const zonedStartDate = utcToZonedTime(utcStartDate, 'Europe/Berlin')
|
||||
@ -69,23 +75,30 @@ const App = () => {
|
||||
<Route exact path="/" component={Program} />
|
||||
<Route exact path="/series" component={Series} />
|
||||
<Route exact path="/program" component={Program} />
|
||||
{seriesData.length ? seriesData.map(series => (
|
||||
<Route exact path={`/series/${series.slug}`}>
|
||||
<SeriesPage data={series} />
|
||||
</Route>)) : null}
|
||||
{seriesData.length
|
||||
? seriesData.map(series => (
|
||||
<Route exact path={`/series/${series.slug}`}>
|
||||
<SeriesPage data={series} />
|
||||
</Route>
|
||||
))
|
||||
: null}
|
||||
<Route path="*">
|
||||
<FourOhFour />
|
||||
</Route>
|
||||
</Switch>
|
||||
</BrowserRouter>
|
||||
{streamActive ? <Video stream={currentStream} /> :
|
||||
<StreamPreview stream={currentStream} isLive={streamIsLive} />}
|
||||
|
||||
{streamActive ? (
|
||||
<Video stream={currentStream} />
|
||||
) : (
|
||||
<StreamPreview stream={currentStream} isLive={streamIsLive} />
|
||||
)}
|
||||
</Fragment>
|
||||
)}
|
||||
</ThemeProvider>)
|
||||
</ThemeProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
const appEl = document.getElementById('app')
|
||||
|
||||
render(<App />, appEl)
|
||||
|
19
src/components/Chat/index.js
Normal file → Executable file
19
src/components/Chat/index.js
Normal file → Executable file
@ -26,18 +26,23 @@ const Chat = ({ overlayActive }) => {
|
||||
</Label>
|
||||
<CloseBox colour={colours.white} size={18} onClick={toggleChatOpen} />
|
||||
</ChatHeader>
|
||||
<iframe
|
||||
src={`https://titanembeds.com/embed/${config.chat.guildId}?css=${config.chat.css}&defaultchannel=${config.chat.channelId}&lang=en_EN`}
|
||||
height={(height / 4) * 3}
|
||||
{/* <iframe
|
||||
src="https://discord.com/widget?id=854082188785221662&theme=dark"
|
||||
width="350"
|
||||
height="500"
|
||||
allowTransparency="true"
|
||||
frameBorder="0"
|
||||
title="discord-chat"
|
||||
className="titanembed"
|
||||
/>
|
||||
sandbox="allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts"
|
||||
title="chat"
|
||||
/> */}
|
||||
</ChatFrame>
|
||||
</ChatWrapper>
|
||||
) : (
|
||||
<ChatHeader chatIsOpen={false} onClick={toggleChatOpen} $active={overlayActive}>
|
||||
<ChatHeader
|
||||
chatIsOpen={false}
|
||||
onClick={toggleChatOpen}
|
||||
$active={overlayActive}
|
||||
>
|
||||
<Label weight="400" size={16} colour={colours.midnightDarker}>
|
||||
CHAT
|
||||
</Label>
|
||||
|
30
src/components/EpisodeCard/styles.js
Normal file → Executable file
30
src/components/EpisodeCard/styles.js
Normal file → Executable file
@ -16,7 +16,8 @@ export const ButtonRow = styled(Flexbox)`
|
||||
width: 100%;
|
||||
align-items: stretch;
|
||||
|
||||
button, a{
|
||||
button,
|
||||
a {
|
||||
font-size: 16px;
|
||||
width: 49%;
|
||||
height: 100%;
|
||||
@ -29,34 +30,35 @@ export const ButtonRow = styled(Flexbox)`
|
||||
@media screen and (min-width: ${screenSizes.md}px) and (max-width: ${screenSizes.lg}px) {
|
||||
flex-direction: column;
|
||||
|
||||
button, a {
|
||||
button,
|
||||
a {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
`
|
||||
|
||||
export const Left = styled(FlexColumn)`
|
||||
margin-right: 2em;
|
||||
${imageWidthStyles};
|
||||
|
||||
|
||||
@media screen and (max-width: ${screenSizes.md}px) {
|
||||
margin-right: 0em;
|
||||
}
|
||||
`
|
||||
`
|
||||
|
||||
export const Center = styled(FlexColumn)`
|
||||
@media screen and (max-width: ${screenSizes.md}px) {
|
||||
order: 2;
|
||||
position: relative;
|
||||
top: -1em;
|
||||
}
|
||||
`
|
||||
@media screen and (max-width: ${screenSizes.md}px) {
|
||||
order: 2;
|
||||
position: relative;
|
||||
top: -1em;
|
||||
}
|
||||
`
|
||||
|
||||
export const Title = styled(H2)`
|
||||
max-width: 80%;
|
||||
margin-bottom: 1em;
|
||||
`
|
||||
`
|
||||
|
||||
export const Right = styled.div`
|
||||
flex: 1;
|
||||
@ -66,7 +68,7 @@ export const Right = styled.div`
|
||||
display: block;
|
||||
margin-bottom: 0.2em;
|
||||
}
|
||||
|
||||
|
||||
@media screen and (max-width: ${screenSizes.md}px) {
|
||||
position: relative;
|
||||
top: 1.2em;
|
||||
@ -89,4 +91,4 @@ export const Img = styled.div`
|
||||
position: relative;
|
||||
background-position: center;
|
||||
${imageWidthStyles};
|
||||
`
|
||||
`
|
||||
|
53
src/components/StreamPreview/index.js
Normal file → Executable file
53
src/components/StreamPreview/index.js
Normal file → Executable file
@ -1,10 +1,7 @@
|
||||
import { Fragment, h } from 'preact'
|
||||
import { h } from 'preact'
|
||||
import { useEffect, useRef } from 'preact/hooks'
|
||||
import { PeerTubePlayer } from '@peertube/embed-api'
|
||||
import { string } from 'prop-types'
|
||||
import Link from '../Link'
|
||||
import { Label } from '../Text'
|
||||
import strings from '../../data/strings'
|
||||
import { colours, textSizes } from '../../assets/theme'
|
||||
import { Row } from '../Flex'
|
||||
import CrossSvg from '../Svg/Cross'
|
||||
@ -13,18 +10,18 @@ import { getLabel } from './helpers'
|
||||
import Chevron from '../Svg/Chevron'
|
||||
|
||||
import { Frame, Img, Iframe, InnerWrapper } from './styles'
|
||||
// import { useEventApi } from '../../hooks/data'
|
||||
|
||||
const StreamPreview = ({ stream, isLive, ...rest }) => {
|
||||
const currentLanguage = 'en'
|
||||
const videoiFrame = useRef(null)
|
||||
const ptVideo = useRef(null)
|
||||
const { isMinimized, toggleMinimized, setStreamActive } = useUiStore(store => ({
|
||||
isMinimized: store.streamPreviewMinimized,
|
||||
toggleMinimized: store.toggleStreamPreviewMinimized,
|
||||
setStreamActive: store.setStreamActive
|
||||
}))
|
||||
|
||||
const { isMinimized, toggleMinimized, setStreamActive } = useUiStore(
|
||||
store => ({
|
||||
isMinimized: store.streamPreviewMinimized,
|
||||
toggleMinimized: store.toggleStreamPreviewMinimized,
|
||||
setStreamActive: store.setStreamActive,
|
||||
})
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
const setupAndPlayVideo = async () => {
|
||||
@ -47,12 +44,30 @@ const StreamPreview = ({ stream, isLive, ...rest }) => {
|
||||
return stream ? (
|
||||
<Frame isMinimized={isMinimized}>
|
||||
<Row justify="space-between">
|
||||
<Label colour={colours.midnightDarker} size={textSizes.lg} onClick={activateStream}>{getLabel(stream, isLive, isMinimized)}</Label>
|
||||
{isMinimized ? <Chevron colour={colours.midnightDarker} size={14} onClick={toggleMinimized} /> : <CrossSvg colour={colours.midnightDarker} size={16} onClick={toggleMinimized} />}
|
||||
<Label
|
||||
colour={colours.midnightDarker}
|
||||
size={textSizes.lg}
|
||||
onClick={activateStream}
|
||||
>
|
||||
{getLabel(stream, isLive, isMinimized)}
|
||||
</Label>
|
||||
{isMinimized ? (
|
||||
<Chevron
|
||||
colour={colours.midnightDarker}
|
||||
size={14}
|
||||
onClick={toggleMinimized}
|
||||
/>
|
||||
) : (
|
||||
<CrossSvg
|
||||
colour={colours.midnightDarker}
|
||||
size={16}
|
||||
onClick={toggleMinimized}
|
||||
/>
|
||||
)}
|
||||
</Row>
|
||||
{!isMinimized ?
|
||||
{!isMinimized ? (
|
||||
<InnerWrapper onClick={activateStream}>
|
||||
{isLive ?
|
||||
{isLive ? (
|
||||
<Iframe
|
||||
width="560"
|
||||
height="315"
|
||||
@ -64,11 +79,13 @@ const StreamPreview = ({ stream, isLive, ...rest }) => {
|
||||
allowFullScreen
|
||||
ref={videoiFrame}
|
||||
/>
|
||||
: <Img src={stream.image} onClick={activateStream} />}
|
||||
</InnerWrapper> : null}
|
||||
) : (
|
||||
<Img src={stream.image} onClick={activateStream} />
|
||||
)}
|
||||
</InnerWrapper>
|
||||
) : null}
|
||||
</Frame>
|
||||
) : null
|
||||
}
|
||||
|
||||
|
||||
export default StreamPreview
|
||||
|
32
src/pages/Series/index.js
Normal file → Executable file
32
src/pages/Series/index.js
Normal file → Executable file
@ -14,20 +14,23 @@ const Series = () => {
|
||||
const { data } = useEventApi()
|
||||
const pastSeries = []
|
||||
|
||||
const currentSeries = data.series ? data.series.filter(series => {
|
||||
if (series.episodes.future.length) {
|
||||
return true
|
||||
}
|
||||
if (series.episodes.past.every(({ beginsOn }) => isFuture(addYears(new Date(beginsOn), 1)))) {
|
||||
return true
|
||||
}
|
||||
|
||||
pastSeries.push(series)
|
||||
return false
|
||||
}) : []
|
||||
|
||||
console.log({ currentSeries })
|
||||
const currentSeries = data.series
|
||||
? data.series.filter(series => {
|
||||
if (series.episodes.future.length) {
|
||||
return true
|
||||
}
|
||||
if (
|
||||
series.episodes.past.every(({ beginsOn }) =>
|
||||
isFuture(addYears(new Date(beginsOn), 1))
|
||||
)
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
pastSeries.push(series)
|
||||
return false
|
||||
})
|
||||
: []
|
||||
|
||||
return (
|
||||
<Page title={strings.en.series}>
|
||||
@ -48,7 +51,8 @@ const Series = () => {
|
||||
<SeriesCard series={series} isPast />
|
||||
))}
|
||||
</SeriesGrid>
|
||||
</Fragment>) : null}
|
||||
</Fragment>
|
||||
) : null}
|
||||
</Content>
|
||||
</Page>
|
||||
)
|
||||
|
73
src/pages/SeriesPage/index.js
Normal file → Executable file
73
src/pages/SeriesPage/index.js
Normal file → Executable file
@ -26,24 +26,37 @@ const SeriesPage = ({ data }) => {
|
||||
const theme = data.theme || defaultTheme
|
||||
const { orgs } = data
|
||||
|
||||
const credits = data.credits ? `
|
||||
const credits = data.credits
|
||||
? `
|
||||
## Credits
|
||||
${data.credits}
|
||||
` : null
|
||||
`
|
||||
: null
|
||||
|
||||
const orgsList = Object.values(orgs || {})
|
||||
console.log({ orgsList })
|
||||
|
||||
const links = data.links.length ? splitArray(data.links, 2) : null
|
||||
|
||||
console.log({ description: data.description })
|
||||
|
||||
return (
|
||||
<Page title={data.title} theme={data.theme} withHeader={false}>
|
||||
<InfoLayout title={data.title} subtitle={data.subtitle} image={data.image} theme={theme}>
|
||||
<InfoLayout
|
||||
title={data.title}
|
||||
subtitle={data.subtitle}
|
||||
image={data.image}
|
||||
theme={theme}
|
||||
>
|
||||
<Fragment>
|
||||
<InfoContent>
|
||||
<H1>{data.title}:</H1>
|
||||
<H1>{data.subtitle}</H1>
|
||||
{data.description ? <Markdown withLinebreaks theme={theme}>{data.description}</Markdown> : null}
|
||||
{data.description ? (
|
||||
<Markdown withLinebreaks theme={theme}>
|
||||
{data.description}
|
||||
</Markdown>
|
||||
) : null}
|
||||
|
||||
{data.trailer ? (
|
||||
<TrailerContainer>
|
||||
@ -51,29 +64,27 @@ const SeriesPage = ({ data }) => {
|
||||
</TrailerContainer>
|
||||
) : null}
|
||||
|
||||
{links ?
|
||||
links.map(linkRow => <Row>
|
||||
{linkRow.map(link => (
|
||||
<a
|
||||
href={link.resourceUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Button>{link.summary}</Button>
|
||||
</a>
|
||||
))}
|
||||
</Row>) : null
|
||||
}
|
||||
{links
|
||||
? links.map(linkRow => (
|
||||
<Row>
|
||||
{linkRow.map(link => (
|
||||
<a
|
||||
href={link.resourceUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<Button>{link.summary}</Button>
|
||||
</a>
|
||||
))}
|
||||
</Row>
|
||||
))
|
||||
: null}
|
||||
</InfoContent>
|
||||
{data.episodes.future.length ? (
|
||||
<Fragment>
|
||||
<Title>{translations.en.program}:</Title>
|
||||
{data.episodes.future.map(feeditem => (
|
||||
<EpisodeCard
|
||||
theme={theme}
|
||||
key={feeditem.start}
|
||||
{...feeditem}
|
||||
/>
|
||||
<EpisodeCard theme={theme} key={feeditem.start} {...feeditem} />
|
||||
))}
|
||||
</Fragment>
|
||||
) : null}
|
||||
@ -91,18 +102,22 @@ const SeriesPage = ({ data }) => {
|
||||
))}
|
||||
</Fragment>
|
||||
) : null}
|
||||
{credits ? <InfoContent>
|
||||
<Markdown theme={theme}>{credits}</Markdown>
|
||||
</InfoContent> : null}
|
||||
{credits ? (
|
||||
<InfoContent>
|
||||
<Markdown theme={theme}>{credits}</Markdown>
|
||||
</InfoContent>
|
||||
) : null}
|
||||
</Fragment>
|
||||
{orgsList.length ? (
|
||||
<LogosRow $wrap>
|
||||
{orgsList.map((org, index) => (
|
||||
<Fragment>
|
||||
<a href={org.orgUrl}>
|
||||
<img src={org.logoUrl} alt={`${org.orgName} logo`} />
|
||||
</a>
|
||||
{orgsList.length === 2 && index + 1 !== orgsList.length ? <Label colour={theme.foreground}>{'//'}</Label> : null}
|
||||
<img src={org.logoUrl} alt={`${org.orgName} logo`} />
|
||||
{orgsList.length < 4 !== 1 &&
|
||||
orgsList.length < 4 &&
|
||||
index + 1 !== orgsList.length ? (
|
||||
<Label colour={theme.foreground}>{'//'}</Label>
|
||||
) : null}
|
||||
</Fragment>
|
||||
))}
|
||||
</LogosRow>
|
||||
|
65
src/pages/SeriesPage/styles.js
Normal file → Executable file
65
src/pages/SeriesPage/styles.js
Normal file → Executable file
@ -40,7 +40,6 @@ export const TrailerContainer = styled.div`
|
||||
}
|
||||
`
|
||||
|
||||
|
||||
export const ActionButton = styled(Button)`
|
||||
font-size: 18px;
|
||||
`
|
||||
@ -49,7 +48,7 @@ export const Row = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-bottom: 32px;
|
||||
flex-wrap: ${props => props.$wrap ? 'wrap' : 'nowrap'};
|
||||
flex-wrap: ${props => (props.$wrap ? 'wrap' : 'nowrap')};
|
||||
|
||||
a {
|
||||
display: block;
|
||||
@ -61,23 +60,24 @@ export const Row = styled.div`
|
||||
`
|
||||
|
||||
export const LogosRow = styled(Row)`
|
||||
align-items: center;
|
||||
max-width: 600px;
|
||||
justify-content: space-between;
|
||||
padding: 32px 0 ;
|
||||
align-items: center;
|
||||
max-width: 600px;
|
||||
justify-content: space-between;
|
||||
padding: 32px 0;
|
||||
|
||||
a {
|
||||
width: auto;
|
||||
margin-right: 0;
|
||||
a {
|
||||
width: auto;
|
||||
margin-right: 0;
|
||||
|
||||
&[href]:hover {
|
||||
opacity: 0.7
|
||||
}
|
||||
&[href]:hover {
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
height: 64px;
|
||||
}
|
||||
img {
|
||||
max-height: 42px;
|
||||
width: 25%;
|
||||
}
|
||||
`
|
||||
|
||||
export const InfoContent = styled.div`
|
||||
@ -170,7 +170,7 @@ export const EpisodeCard = ({
|
||||
videoUrl,
|
||||
theme,
|
||||
peertubeReplay,
|
||||
id
|
||||
id,
|
||||
}) => {
|
||||
const startDate = new Date(beginsOn)
|
||||
|
||||
@ -179,11 +179,14 @@ export const EpisodeCard = ({
|
||||
|
||||
const zonedDate = utcToZonedTime(utcDate, timeZone)
|
||||
|
||||
const timezoneLabel = format(zonedDate, hasPassed ? 'dd/MM/yy' : 'do LLLL y // HH:mm zzz', {
|
||||
timeZone,
|
||||
locale: enGB,
|
||||
})
|
||||
|
||||
const timezoneLabel = format(
|
||||
zonedDate,
|
||||
hasPassed ? 'dd/MM/yy' : 'do LLLL y // HH:mm zzz',
|
||||
{
|
||||
timeZone,
|
||||
locale: enGB,
|
||||
}
|
||||
)
|
||||
|
||||
return (
|
||||
<VCWrapper id={id}>
|
||||
@ -204,11 +207,25 @@ export const EpisodeCard = ({
|
||||
<VCImg src={image} alt="" />
|
||||
</Fragment>
|
||||
)}
|
||||
<Markdown withLinebreaks theme={theme}>{description}</Markdown>
|
||||
<Markdown withLinebreaks theme={theme}>
|
||||
{description}
|
||||
</Markdown>
|
||||
{hasPassed ? (
|
||||
<a href={peertubeReplay.url || url}><Button>{peertubeReplay.url ? translations.en.watchEpisode : translations.en.eventDetails}</Button></a>
|
||||
<a href={peertubeReplay.url || url}>
|
||||
<Button>
|
||||
{peertubeReplay.url
|
||||
? translations.en.watchEpisode
|
||||
: translations.en.eventDetails}
|
||||
</Button>
|
||||
</a>
|
||||
) : (
|
||||
<ButtonsRows title={title} description={description} beginsOn={beginsOn} endsOn={endsOn} url={url} />
|
||||
<ButtonsRows
|
||||
title={title}
|
||||
description={description}
|
||||
beginsOn={beginsOn}
|
||||
endsOn={endsOn}
|
||||
url={url}
|
||||
/>
|
||||
)}
|
||||
</VCWrapper>
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user