diff --git a/index.js b/index.js
index 48108b9..0d54d17 100644
--- a/index.js
+++ b/index.js
@@ -1,16 +1,19 @@
import { h, render } from 'preact'
import { useState } from 'preact/hooks'
+import { ThemeProvider } from 'styled-components'
import { BrowserRouter, Route, Switch } from 'react-router-dom'
import Main from './app'
import SeriesPage from './src/pages/SeriesPage'
import { useEventApi, useEventCalendar } from './src/hooks/data'
+import { useTheme } from './src/store'
import { useTimeout } from './src/hooks/timerHooks'
import LoaderLayout from './src/pages/LoaderLayout'
import FourOhFour from './src/pages/404'
import Series from './src/pages/Series'
const App = () => {
+ const { theme } = useTheme((store) => store)
const { data: calData, calLoading } = useEventCalendar()
const { data: seriesDataArray, loading: eventsLoading } = useEventApi()
const [minLoadTimePassed, setMinTimeUp] = useState(false)
@@ -22,23 +25,26 @@ const App = () => {
const seriesData = Object.values(seriesDataArray)
- return calLoading || eventsLoading || !minLoadTimePassed ? (
-
- ) : (
-
-
-
-
- {seriesData.length ? seriesData.map(series => (
-
-
- )) : null}
-
-
-
-
-
- )
+ return (
+
+ {calLoading || eventsLoading || !minLoadTimePassed ? (
+
+ ) : (
+
+
+
+
+ {seriesData.length ? seriesData.map(series => (
+
+
+ )) : null}
+
+
+
+
+
+ )}
+ )
}
diff --git a/src/components/Header/index.js b/src/components/Header/index.js
index 3df1d1b..1241dc6 100644
--- a/src/components/Header/index.js
+++ b/src/components/Header/index.js
@@ -1,66 +1,80 @@
import { h } from 'preact'
import { Link as ReactLink } from 'react-router-dom'
-import { RightBox, StyledRow as Row, Modal } from './styles'
+import { RightBox, StyledRow as Row, Modal, PositionedCross as CrossSvg } from './styles'
import { ImageLogo } from '../Logo'
import { useWindowSize } from '../../hooks/dom'
import Link from '../Link'
import { Span } from '../Text'
-import CrossSvg from '../Svg/Cross'
import navigation from '../../data/navigation'
import { colours, screenSizes, textSizes } from '../../assets/theme'
-import { useToggle } from '../../hooks/utility'
+import { useTheme, useUiStore } from '../../store'
-const Navigation = ({ theme = {}, lang = 'en', headerTheme }) => navigation[lang].map(navItem => (
+const Navigation = ({ theme = {}, lang = 'en', miniHeader, toggleMobileMenu }) => navigation[lang].map(navItem => (
{navItem.label}
))
-const NavigationModal = ({ theme = {}, lang = 'en', headerTheme, toggleMenuOpen, ...rest }) => (
-
-
-
-
-
-
-
-
-
-)
+export const NavigationModal = ({ theme = {}, lang = 'en', headerTheme, ...rest }) => {
+ const { toggleMobileMenu } = useUiStore(store => store)
-const FullHeader = ({ theme = {}, headerTheme = {}, lang = 'en', miniHeader, isMobile, toggleMenuOpen, ...rest }) => (
-
+ return (
+
+
+
+
+
+
+
+
+
+ )
+}
+
+const FullHeader = ({ theme = {}, lang = 'en', miniHeader, isMobile, ...rest }) => (
+
{!miniHeader ?
: null}
{!isMobile ? (
-
+
- ) : Menu}
+ ) : }
)
+export const MobileMenuToggle = ({ miniHeader, ...props }) => {
+ const { toggleMobileMenu } = useUiStore(store => store)
+ const { theme } = useTheme(store => store)
+
+ return (
+ Menu)
+}
+
const Header = ({ miniHeader, theme, ...rest }) => {
- const headerTheme = { foreground: theme.background, background: 'transparent', }
const { width: screenWidth } = useWindowSize()
- const [menuOpen, toggleMenuOpen] = useToggle(false)
+ const { menuOpen } = useUiStore(store => store)
const isMobile = screenWidth < screenSizes.lg
- if (menuOpen) return
-
- return
+ return
}
export default Header
diff --git a/src/components/Header/styles.js b/src/components/Header/styles.js
index 2382ef6..6b605ce 100644
--- a/src/components/Header/styles.js
+++ b/src/components/Header/styles.js
@@ -7,7 +7,7 @@ import CrossSvg from '../Svg/Cross'
export const StyledRow = styled(Row)`
pointer-events: all;
height: 100px;
- background-color: ${({ theme }) => theme.background};
+ background-color: transparent;
color: ${({ theme }) => theme.foreground};
position: absolute;
left: ${({ miniHeader }) => miniHeader ? 'initial' : '0'};
@@ -71,6 +71,7 @@ export const Modal = styled.div`
`
export const PositionedCross = styled(CrossSvg)`
position: fixed;
- right: 1em;
- top: 1em;
+ right: 2.5em;
+ top: 2em;
+ cursor: pointer;
`
\ No newline at end of file
diff --git a/src/components/Link/styles.js b/src/components/Link/styles.js
index 885c46b..e1d3fbe 100644
--- a/src/components/Link/styles.js
+++ b/src/components/Link/styles.js
@@ -3,7 +3,7 @@ import { Link } from 'react-router-dom'
import { colours } from '../../assets/theme'
export const RRLink = styled(Link)`
- color: ${props => { console.log({ col: props.$colour }); return props.$colour || colours.highlight }};
+ color: ${props => props.$colour || colours.highlight};
text-decoration: none;
${props => props.$navLink ? `
font-family: Lunchtype24;
diff --git a/src/hooks/data.js b/src/hooks/data.js
index 7ae13fa..1cab5a9 100644
--- a/src/hooks/data.js
+++ b/src/hooks/data.js
@@ -99,7 +99,7 @@ export const useEventCalendar = () => {
export const useEventApi = () => {
- const [series, setSeries] = useSeriesStore(store => [store.series, store.setSeries])
+ const [series, episodes, setSeries, setEpisodes] = useSeriesStore(store => [store.series, store.episodes, store.setSeries, store.setEpisodes])
const [loading, setLoading] = useState(!!series.length)
@@ -112,6 +112,9 @@ export const useEventApi = () => {
)
setSeries(responseData)
+ // setEpisodes()
+
+ // console.log({ episodes })
setLoading(false)
}
diff --git a/src/layouts/InfoLayout/styles.js b/src/layouts/InfoLayout/styles.js
index d8ac06c..4a6bbe1 100644
--- a/src/layouts/InfoLayout/styles.js
+++ b/src/layouts/InfoLayout/styles.js
@@ -98,6 +98,10 @@ export const LoaderWrapper = styled.div`
export const Content = styled.div`
padding-top: 80px;
+
+ @media screen and (max-width: ${screenSizes.md}px) {
+ padding-top: 100px;
+ }
img.img-logo {
max-height: 80px;
@@ -122,6 +126,10 @@ export const PositionedLink = styled(Link)`
max-height: 80px;
mix-blend-mode: exclusion;
padding: 0.5em 2em 0;
+
+ @media screen and (max-width: ${screenSizes.md}px) {
+ padding-left: 1em
+ }
}
`
diff --git a/src/layouts/Page/index.js b/src/layouts/Page/index.js
index ce3c19f..80f51cb 100644
--- a/src/layouts/Page/index.js
+++ b/src/layouts/Page/index.js
@@ -1,27 +1,42 @@
import { Fragment, h } from 'preact'
import PropTypes, { oneOfType, shape, string } from 'prop-types'
+import { useEffect } from 'preact/hooks'
import SEO from '../../components/Seo'
-import Header from '../../components/Header'
+import Header, { NavigationModal as MenuModal } from '../../components/Header'
import { capitaliseFirstLetter } from '../../helpers/string'
import { defaultTheme } from '../../assets/theme'
import { ThemedBlock } from './styles'
+import { useTheme, useUiStore } from '../../store'
-const Page = ({ children, title = '', description, metaImg, backTo, noindex, withHeader = true, theme = defaultTheme }) => (
-
-
- {withHeader ? : null}
-
- {children}
-
-
-)
+const Page = ({ children, title = '', description, metaImg, backTo, noindex, withHeader = true, theme = defaultTheme }) => {
+ const { setTheme } = useTheme(store => store)
+ const { mobileMenuOpen: menuOpen, toggleMenuOpen } = useUiStore(store => store)
+
+
+ useEffect(() => {
+ if (theme) {
+ setTheme(theme)
+ }
+ }, [])
+
+ return (
+
+
+ {withHeader ? : null}
+ {menuOpen ? : null}
+
+ {children}
+
+
+ )
+}
Page.propTypes = {
children: PropTypes.node.isRequired,
diff --git a/src/pages/SeriesPage/index.js b/src/pages/SeriesPage/index.js
index 7dbc6e3..297df1e 100644
--- a/src/pages/SeriesPage/index.js
+++ b/src/pages/SeriesPage/index.js
@@ -1,5 +1,6 @@
/* eslint-disable react/prop-types */
import { h, Fragment } from 'preact'
+import { useEffect } from 'preact/hooks'
import striptags from 'striptags'
import { H1 } from '../../components/Text'
@@ -18,8 +19,11 @@ import {
import Page from '../../layouts/Page'
import { splitArray } from '../../helpers/utils'
+import { defaultTheme } from '../../assets/theme'
const SeriesPage = ({ data }) => {
+ const theme = data.theme || defaultTheme
+
const credits = data.credits ? `
## Credits
${data.credits}
@@ -43,12 +47,12 @@ const SeriesPage = ({ data }) => {
return (
-
+
{data.title}:
{data.subtitle}
- {data.description ? {data.description} : null}
+ {data.description ? {data.description} : null}
{data.trailer ? (
@@ -75,7 +79,7 @@ const SeriesPage = ({ data }) => {
{translations.en.program}:
{data.episodes.future.map(feeditem => (
{
Past streams:
{data.episodes.past.map(feeditem => (
null} // todo: fix this
@@ -99,7 +103,7 @@ const SeriesPage = ({ data }) => {
) : null}
{credits ?
Credits
- {credits}
+ {credits}
: null}
diff --git a/src/store/helpers.js b/src/store/helpers.js
deleted file mode 100644
index 7e4215a..0000000
--- a/src/store/helpers.js
+++ /dev/null
@@ -1,35 +0,0 @@
-export const getMetadataByKey = (episode, key, firstItem = true) => {
- const filteredItems = episode.metadata.length ? episode.metadata.filter(
- meta => meta.key.includes(key)
- ) : null
-
- if (filteredItems) {
- return firstItem ? filteredItems[0].value : filteredItems
- }
-
- return null
-}
-
-export const getPostByKey = (posts, key) => {
- const filteredPostItems = posts.elements.length ? posts.elements.filter(post => post.title === key) : []
- return filteredPostItems.length ? filteredPostItems[0].body : null
-}
-
-export const getResourcesByKey = (resources, key, lookup = 'title') => {
- const filteredResources = resources.elements.length ? resources.elements.filter(resource => resource[lookup].includes(key)) : []
-
- if (!filteredResources.length) return null
-
- return filteredResources
-}
-
-export const getPeertubeIDfromUrl = (string) => string && string.includes('https://tv.undersco.re') ? string.split('/').pop() : string
-
-export const getEpisodeCode = (episode) => {
- const metaItems = getMetadataByKey(episode, 'mz:plain:', false)
- if (metaItems && metaItems.length) {
- // TODO
- }
-
- return 'TODO'
-}
\ No newline at end of file
diff --git a/src/store/index.js b/src/store/index.js
index 72ab87a..679ab32 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -1,56 +1,26 @@
import create from 'zustand'
-import striptags from 'striptags'
-import { isFuture, isPast } from 'date-fns'
-import { slugify } from '../helpers/string'
-import { getMetadataByKey, getPostByKey, getResourcesByKey, getPeertubeIDfromUrl, getEpisodeCode } from './helpers'
-import { colours, defaultTheme } from '../assets/theme'
+import { defaultTheme } from '../assets/theme'
-export const [useSeriesStore] = create(set => ({
+export const useSeriesStore = create((set, get) => ({
series: [],
-
- setSeries: seriesArray => {
- const allSeries = seriesArray.map(({ name, organizedEvents, posts, resources, banner, summary, members }) => {
-
-
- const allEpisodes = organizedEvents.elements.length ? organizedEvents.elements.map(ep => ({
- title: ep.title,
- beginsOn: ep.beginsOn,
- endsOn: ep.endsOn,
- description: ep.description,
- media: ep.media,
- image: ep.picture ? ep.picture.url : null,
- peertubeId: getPeertubeIDfromUrl(getMetadataByKey(ep, 'peertube:url')),
- code: getEpisodeCode(ep)
- })) : []
-
- const trailer = getResourcesByKey(resources, 'SERIES_TRAILER')?.[0]?.resourceUrl ?? null
- const theme = striptags(getPostByKey(posts, 'THEME'))
- const orgLinks = getResourcesByKey(resources, 'ORG_LINK:')?.map(link => link.title)
-
- console.log({ orgLinks })
-
-
- const series = {
- title: name,
- subtitle: striptags(summary),
- description: getPostByKey(posts, 'SERIES_INFO'),
- posts: posts.elements,
- resources: resources.elements,
- image: banner ? banner.url : '',
- episodes: {
- future: allEpisodes.filter(ep => isFuture(new Date(ep.endsOn))).sort((a, b) => new Date(a.beginsOn) - new Date(b.beginsOn)),
- past: allEpisodes.filter(ep => isPast(new Date(ep.endsOn))).sort((a, b) => new Date(a.beginsOn) - new Date(b.beginsOn))
- },
- slug: slugify(name),
- credits: getPostByKey(posts, 'SERIES_CREDITS'),
- trailer,
- links: getResourcesByKey(resources, 'SERIES_LINK') || [],
- theme: theme ? JSON.parse(theme) : defaultTheme,
- hosts: members.elements.filter(({ actor }) => actor.name !== 'streamappbot')
- }
- return series
- })
-
- set({ series: allSeries })
+ episodes: [],
+ setSeries: series => set({ series }),
+ setEpisodes: () => {
+ if (get().series) {
+ set({
+ episodes: get().series.map(series => series.episodes)
+ })
+ } else set({})
}
+}))
+
+export const [useTheme] = create(set => ({
+ theme: defaultTheme,
+ setTheme: (theme) => set({ theme }),
+ setDefaultTheme: () => set({ theme: defaultTheme })
+}))
+
+export const [useUiStore] = create((set, get) => ({
+ mobileMenuOpen: false,
+ toggleMobileMenu: () => set({ mobileMenuOpen: !get().mobileMenuOpen }),
}))
\ No newline at end of file