From 3cab6fb683917b649b6b39575846f51d1140733b Mon Sep 17 00:00:00 2001 From: Sunda <> Date: Mon, 11 Oct 2021 19:14:55 +0200 Subject: [PATCH] added store and some helpers to parse series data --- package.json | 3 ++- src/hooks/data.js | 20 ++++++++++++-------- src/store/helpers.js | 23 +++++++++++++++++++++++ src/store/index.js | 43 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 src/store/helpers.js create mode 100644 src/store/index.js diff --git a/package.json b/package.json index b77e8b9..5160cd9 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,8 @@ "prop-types": "^15.7.2", "react-router-dom": "^5.3.0", "striptags": "^3.2.0", - "styled-components": "^5.2.1" + "styled-components": "^5.2.1", + "zustand": "^3.5.13" }, "devDependencies": { "@babel/eslint-parser": "^7.13.10", diff --git a/src/hooks/data.js b/src/hooks/data.js index a92ca88..fce28b5 100644 --- a/src/hooks/data.js +++ b/src/hooks/data.js @@ -2,6 +2,7 @@ import { useEffect, useState } from 'preact/hooks' import axios from 'axios' import ICAL from 'ical.js' import config from '../data/config' +import { useSeriesStore } from '../store/index' export const useEventCalendar = () => { const [data, setData] = useState([]) @@ -97,24 +98,27 @@ export const useEventCalendar = () => { export const useEventApi = () => { - const [data, setData] = useState([]) + const [series, setSeries] = useSeriesStore(store => [store.series, store.setSeries]) const [loading, setLoading] = useState(true) + async function fetchData() { - setLoading(true) + if (!series.length) { + setLoading(true) - const { data: responseData } = await axios.get( - `${config.EVENTS_API_URL}/events` - ) + const { data: responseData } = await axios.get( + `${config.EVENTS_API_URL}/events` + ) - setData(responseData) + setSeries(responseData) - setLoading(false) + setLoading(false) + } } useEffect(() => { fetchData() }, []) - return { loading, data } + return { loading, data: series } } \ No newline at end of file diff --git a/src/store/helpers.js b/src/store/helpers.js new file mode 100644 index 0000000..a849023 --- /dev/null +++ b/src/store/helpers.js @@ -0,0 +1,23 @@ +export const getMetadataByKey = (episode, key) => { + const filteredItems = episode.metadata.length ? episode.metadata.filter( + meta => meta.key === key + ) : null + + if (filteredItems) { + return filteredItems[0].value + } + + 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) => { + const filteredResources = resources.elements.length ? resources.elements.filter(resource => resource.title === key) : [] + return filteredResources.length ? filteredResources[0].resourceUrl : null +} + +export const getPeertubeIDfromUrl = (string) => string && string.includes('https://tv.undersco.re') ? string.split('/').pop() : string \ No newline at end of file diff --git a/src/store/index.js b/src/store/index.js new file mode 100644 index 0000000..3239116 --- /dev/null +++ b/src/store/index.js @@ -0,0 +1,43 @@ +import create from 'zustand' +import striptags from 'striptags' +import { isFuture, isPast } from 'date-fns' +import { slugify } from '../helpers/string' +import { getMetadataByKey, getPostByKey, getResourcesByKey, getPeertubeIDfromUrl } from './helpers' + +export const [useSeriesStore] = create(set => ({ + series: [], + + setSeries: seriesArray => { + const allSeries = seriesArray.map(({ name, organizedEvents, posts, resources, banner, summary }) => { + + 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, 'mz:live:peertube:url')), + })) : [] + + 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'), + trailerId: getPeertubeIDfromUrl(getResourcesByKey(resources, 'SERIES_TRAILER')) + } + return series + }) + + set({ series: allSeries }) + } +})) \ No newline at end of file