From 5466b771ed58eee80115398e4ebbfce6617ea3be Mon Sep 17 00:00:00 2001 From: Leander Furumo Date: Sat, 23 Nov 2024 15:31:19 +0100 Subject: [PATCH] initial implementation of new events api expo is garbage. why can't i suddenly launch the app in dev mode? why do i have to be forced to dev blindly? because fuck you! stable software is too much to ask for, especially in the js world. fuck this garbage piece of shit software. i fucking despise mobile dev with a burning passion --- src/modules/events/EventDetail.tsx | 295 ---------------------------- src/modules/events/EventList.tsx | 31 ++- src/modules/events/useEventList.tsx | 13 +- 3 files changed, 17 insertions(+), 322 deletions(-) delete mode 100644 src/modules/events/EventDetail.tsx diff --git a/src/modules/events/EventDetail.tsx b/src/modules/events/EventDetail.tsx deleted file mode 100644 index 87d5150..0000000 --- a/src/modules/events/EventDetail.tsx +++ /dev/null @@ -1,295 +0,0 @@ -import { FontAwesome } from '@expo/vector-icons'; -import moment from 'moment'; -import React from 'react'; -import { - Linking, - StyleSheet, - ScrollView, - Text, - Platform, - View, - Image, - TouchableOpacity, - useWindowDimensions, -} from 'react-native'; -import RenderHtml from 'react-native-render-html'; - -import theme from 'src/theme'; -import type { EventType } from 'src/types/data'; -import type { EventDetailProps } from 'src/types/navigation'; - -moment.locale('nb'); - -const CHATEAU_NEUF_ADDRESS = 'Chateau Neuf, Slemdalsveien 15, 0369 Oslo'; - -const FORMAT_TIME = 'HH:mm'; -const FORMAT_MONTH = 'MMM'; -const FORMAT_DAY = 'DD.'; -const FORMAT_LOCAL_DAY = 'dddd'; -const FORMAT_YEAR = 'YYYY'; - -const formatRelative = (time: string) => moment(time).fromNow(); - -const format = (time: string, formatString = FORMAT_TIME) => moment(time).format(formatString); - -const formatTicketText = (event: EventType) => { - /* FIXME: This should be handled by API */ - let regularPrice = ''; - let memberPrice = ''; - if (event.price_regular === '0') { - event.price_regular = 'Gratis'; - } - if (event.price_member === '0') { - event.price_member = 'Gratis'; - } - if (event.price_regular !== 'Gratis') { - regularPrice = ' kr'; - } - if (event.price_member !== 'Gratis') { - memberPrice = ' kr'; - } - - let text = ''; - if (event.price_regular && event.price_member) { - text = `Pris: ${event.price_regular}${regularPrice} / Medlemmer: ${event.price_member}${memberPrice}`; - } else if (event.price_regular) { - text = `Pris: ${event.price_regular}${regularPrice}`; - } else if (event.price_member) { - text = `Pris (Medlemmer): ${event.price_member}${memberPrice}`; - } else { - return ''; - } - return text; -}; - -const onFacebookUrlPress = (link: string) => { - const fbEventPattern = /https?:\/\/www\.facebook\.com\/events\/(\d+)\/?/i; - const matches = fbEventPattern.exec(link); - let iosURL = link; - if (matches && matches.length) { - iosURL = `fb://event/?id=${matches[1]}`; - } - const url = - Platform.select({ - ios: iosURL, - android: link, - }) || ''; - Linking.canOpenURL(url) - .then((supported) => { - if (!supported) { - return Linking.openURL(link); - } - return Linking.openURL(url); - }) - .catch((err) => console.error('An error occurred', err)); -}; - -const onLocationPress = (venue: string) => { - if (venue !== 'Annetsteds') { - Linking.openURL(`https://www.google.com/maps/dir/?api=1&destination=${CHATEAU_NEUF_ADDRESS}`); - } -}; - -const VenueLocation = ({ venue }: Pick) => - venue !== 'Annetsteds' ? CHATEAU_NEUF_ADDRESS : 'Ukjent adresse'; - -const PriceAndTicket = ({ event }: { event: EventType }) => { - const text = formatTicketText(event); - - if (text === '') { - return null; - } - - if (event.ticket_url) { - return ( - Linking.openURL(event.ticket_url)}> - - - - - {text} - Kjøp billett - - - ); - } - - return ( - - - - - - {text} - Billett i døra - - - ); -}; - -const FaceButton = ({ event }: { event: EventType }) => { - if (!event.facebook_url) { - return null; - } - - return ( - onFacebookUrlPress(event.facebook_url)} style={styles.metaInner}> - - - - - På Facebook - - - ); -}; - -const Year = ({ startTime }: { startTime: string }) => { - if (moment().year() === moment(startTime).year()) { - return null; - } - return {format(startTime, FORMAT_YEAR)}; -}; - -const formatTimeFull = (event: EventType) => { - const endTime = event.end_time ? ` - ${format(event.end_time, FORMAT_TIME)}` : ''; - const startTime = `${format(event.start_time, FORMAT_LOCAL_DAY)} kl. ${format(event.start_time, FORMAT_TIME)}`; - return `${startTime}${endTime}`; -}; - -const EventDetail = ({ - route: { - params: { event }, - }, -}: EventDetailProps) => { - const { width } = useWindowDimensions(); - return ( - - {event.thumbnail.medium_large && } - - {/* Date and title */} - - - - {format(event.start_time, FORMAT_DAY)} - {format(event.start_time, FORMAT_MONTH)} - - - - - - {event.title.decoded} - - - - {/* Time and calendar */} - - - - - - {formatTimeFull(event)} - {formatRelative(event.start_time)} - - - {/* Location and maps */} - onLocationPress(event.venue)}> - - - - - {event.venue} - - - - - - - - - - - ); -}; - -export default EventDetail; - -const styles = StyleSheet.create({ - dateAndTitle: { - flexDirection: 'row', - marginBottom: 8, - }, - titleContainer: { - paddingLeft: 10, - justifyContent: 'center', - flex: 4, - }, - title: { - fontSize: 20, - fontWeight: 'bold', - color: theme.colors.neufBlack, - }, - image: { - height: 260, - width: null, - }, - time: { - fontSize: 14, - color: theme.colors.lightText, - }, - metaInner: { - flexDirection: 'row', - marginVertical: 8, - }, - metaIcon: { - width: 16, - paddingTop: 3, - marginHorizontal: 8, - marginVertical: 8, - }, - metaText: { - color: theme.colors.neufBlack, - }, - metaSubtitle: { - color: theme.colors.neufBlack, - }, - content: { - borderTopWidth: StyleSheet.hairlineWidth, - borderColor: theme.colors.neufGray, - marginTop: 8, - paddingTop: 10, - }, - dateContainer: { - flex: 1, - justifyContent: 'center', - }, - dateCard: { - margin: 0, - padding: 0, - paddingBottom: 6, - width: 62, - }, - day: { - paddingTop: 5, - fontSize: 20, - color: theme.colors.neufBlack, - textAlign: 'center', - }, - month: { - textAlign: 'center', - paddingHorizontal: 16, - }, - year: { - fontSize: 9, - color: theme.colors.neufWhite, - backgroundColor: theme.colors.neufOrange, - textAlign: 'center', - paddingRight: 20, - paddingBottom: 3, - paddingLeft: 20, - paddingTop: 3, - }, - icons: { - fontSize: 15, - }, -}); diff --git a/src/modules/events/EventList.tsx b/src/modules/events/EventList.tsx index af18652..8d9e4ec 100644 --- a/src/modules/events/EventList.tsx +++ b/src/modules/events/EventList.tsx @@ -1,7 +1,16 @@ import { SimpleLineIcons as Icon } from '@expo/vector-icons'; import moment from 'moment'; import React from 'react'; -import { StyleSheet, View, Platform, SectionList, TouchableOpacity, ActivityIndicator, Text } from 'react-native'; +import { + StyleSheet, + View, + Platform, + SectionList, + TouchableOpacity, + ActivityIndicator, + Text, + Linking, +} from 'react-native'; import { Button } from 'react-native-ui-lib'; import 'moment/locale/nb'; @@ -24,21 +33,21 @@ const renderSectionHeader = ({ section }: { section: { title: string } }) => ( const Header = () => ; const EventList = () => { - const { eventsSectioned, refreshing, handleRefresh, handleLoadMore, showEvent, error, loading } = useEventList(); + const { eventsSectioned, refreshing, handleRefresh, handleLoadMore, error, loading } = useEventList(); const renderItem = ({ item }: { item: EventType }) => ( { - showEvent(item); + return Linking.openURL(items.url); }} style={styles.listItem} > - {item.title.decoded} + {item.title} - {formatTime(item.start_time)} + {formatTime(item.nextOccurence.start)} @@ -56,18 +65,6 @@ const EventList = () => { ); - // TODO: temporary. Remove this once the new website is up - // @ts-expect-error message is not a property of type. we don't care because this block of code is temporary - if (error && error.message === 'I am a teapot') { - return ( - - - Vi lager ny nettside! Programmet vil derfor være utilgjengelig inntil alt er på plass! - - - ); - } - if (error) { return ( diff --git a/src/modules/events/useEventList.tsx b/src/modules/events/useEventList.tsx index ed3be27..eeb7cc3 100644 --- a/src/modules/events/useEventList.tsx +++ b/src/modules/events/useEventList.tsx @@ -59,23 +59,19 @@ const useEventList = () => { }; const fetchEvents = async () => { - const url = `${process.env.EXPO_PUBLIC_EVENT_API_URL}/wp-json/wp/v2/events?page=${page}&future=1`; + const url = `${process.env.EXPO_PUBLIC_EVENT_API_URL}?view=compact-app`; setLoading(true); let eventData; try { const res = await fetchWithTimeout(url); - if (res.status === 418) { - // TODO: temporary. Remove once new website is up and running - throw new Error('I am a teapot'); - } - setTotalPages(parseInt(res.headers.get('x-wp-totalpages') || '0', 10)); - eventData = await res.json(); + eventData = await res.json().events; } catch (err) { setError(err); setLoading(false); return; } + setTotalPages(Math.floor(eventData.total / 10)); setEvents(page === 1 ? eventData : [...events, ...eventData]); setEventsSectioned(page === 1 ? toSectionFormat(eventData) : toSectionFormat([...events, ...eventData])); setError(eventData.error || null); @@ -89,9 +85,6 @@ const useEventList = () => { }, []); return { - showEvent: (event: EventType) => { - navigate('EventStack', { screen: 'EventDetail', params: { event } }); - }, handleRefresh, handleLoadMore, error,