diff --git a/App.js b/App.js index b5b288b..4f6194a 100644 --- a/App.js +++ b/App.js @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useRef } from 'react'; import { NativeBaseProvider } from 'native-base'; import 'react-native-gesture-handler'; import ProgramContainer from './src/containers/program-container'; @@ -10,6 +10,7 @@ import SpaceProgramContainer from './src/containers/space-program-container'; import SpaceListContainer from './src/containers/space-list-container'; import InfoContainer from './src/containers/info-container'; import ProgramUpdater from './src/services/program-updater'; +import Announcement from './src/components/announcement'; import { ProgramContextProvider } from './src/services/program-context'; import { NavigationContainer } from '@react-navigation/native'; @@ -18,9 +19,11 @@ import { createStackNavigator } from '@react-navigation/stack'; const Stack = createStackNavigator(); export default function App() { + const navigationRef = useRef(null); + return ( - + @@ -33,6 +36,7 @@ export default function App() { + diff --git a/src/components/announcement.js b/src/components/announcement.js new file mode 100644 index 0000000..e1e3eac --- /dev/null +++ b/src/components/announcement.js @@ -0,0 +1,106 @@ +import React, { useEffect, useState } from 'react'; +import { View, Text, StyleSheet, TouchableHighlight, Linking } from 'react-native'; +import AsyncStorage from '@react-native-async-storage/async-storage'; +import { Center, Button, Modal } from 'native-base'; +import { CROWDFUNDING_URL, CROWDFUNDING_START, CROWDFUNDING_END } from '../event-properties'; +import { getNow } from '../helpers/program-helpers'; +import { getEsMoment } from '../helpers/date-helpers'; + +import { + TOUCHABLE_UNDERLAY_COLOR, + LINK_COLOR +} from '../styles/colors'; + +import { iconsMap } from '../helpers/icon-helpers'; + +const Announcement = ({ navigationRef }) => { + const [showAnnouncement, setShowAnnouncement] = useState(false); + + const openInfo = () => { + setShowAnnouncement(false); + navigationRef.current.navigate('Info', {}); + }; + + useEffect(() => { + const nowDt = getEsMoment(getNow()); + if (nowDt >= getEsMoment(CROWDFUNDING_START) && nowDt < getEsMoment(CROWDFUNDING_END)) { + AsyncStorage.getItem('announcementHasBeenShown') + .then((value) => { + if (!value) { + setShowAnnouncement(true); + AsyncStorage.setItem('announcementHasBeenShown', 'true'); + } + }) + .catch((error) => { + console.error('Error getting announcement storage:', error); + }); + } + }, []); + + if (!showAnnouncement) { + return null; + } + + return ( +
+ setShowAnnouncement(false)} size='lg'> + + + Información Importante! + + Este año tenemos crowdfunding... + Linking.openURL(CROWDFUNDING_URL)} + > + + {iconsMap.get('crowdfunding', { color: LINK_COLOR })} + Ir a Crowdfunding + + + + + Si no quieres visitar la página ahora, puedes encontrar el enlace en la pantalla de openInfo()}>Info {iconsMap.get('info', { size: 14, color: LINK_COLOR })} + + + + + + + + + +
+ ); +}; + +const styles = StyleSheet.create({ + headerText: { + fontWeight: 'bold', + fontSize: 22 + }, + bodyText: { + fontSize: 18 + }, + buttonText: { + color: LINK_COLOR, + fontWeight: 'bold', + letterSpacing: 0.5 + }, + linkContainer: { + flexDirection: 'row', + paddingVertical: 4, + alignItems: 'center' + }, + link: { + fontWeight: 'bold', + color: LINK_COLOR, + fontSize: 16 + }, + inlineLink: { + color: LINK_COLOR + } +}); + +export default Announcement; diff --git a/src/components/draw-attention-view.js b/src/components/draw-attention-view.js index 007dad4..ce458c8 100644 --- a/src/components/draw-attention-view.js +++ b/src/components/draw-attention-view.js @@ -5,17 +5,19 @@ import { Animated } from 'react-native'; export default function DrawAttentionView(props) { const fadeAnim = useRef(new Animated.Value(0)).current; + const duration = props.duration || 666; + useEffect(() => { Animated.loop( Animated.sequence([ Animated.timing(fadeAnim, { toValue: 1, - duration: 666, + duration, useNativeDriver: true }), Animated.timing(fadeAnim, { toValue: 0.0, - duration: 666, + duration, useNativeDriver: true }) ]) diff --git a/src/containers/info-container.js b/src/containers/info-container.js index bbabb68..b670687 100644 --- a/src/containers/info-container.js +++ b/src/containers/info-container.js @@ -1,17 +1,36 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { View, StyleSheet, Text, Linking, TouchableHighlight, ScrollView } from 'react-native'; import PageLayout from './page-layout'; import { iconsMap } from '../helpers/icon-helpers'; +import DrawAttentionView from '../components/draw-attention-view'; import { LINK_COLOR, TOUCHABLE_UNDERLAY_COLOR } from '../styles/colors'; +import { + CROWDFUNDING_URL, + CROWDFUNDING_START, + CROWDFUNDING_END, + WEB_URL, + INSTAGRAM_URL, + YOUTUBE_URL +} from '../event-properties'; +import { getEsMoment } from '../helpers/date-helpers'; +import { getNow } from '../helpers/program-helpers'; + const InfoContainer = ({ navigation }) => { - const WEB_URL = 'https://beniconfusionfest.es/es/inicio'; - const INSTAGRAM_URL = 'https://www.instagram.com/benimacletconfusion/'; - const YOUTUBE_URL = 'https://www.youtube.com/c/conFusi%C3%B3nfest/featured'; + const [crowdfundintActive, setCrowdfundingActive] = useState(false); + + useEffect(() => { + const nowDt = getEsMoment(getNow()); + if (nowDt >= getEsMoment(CROWDFUNDING_START) && nowDt < getEsMoment(CROWDFUNDING_END)) { + setCrowdfundingActive(true); + } else { + setCrowdfundingActive(false); + } + }); return ( @@ -38,7 +57,7 @@ const InfoContainer = ({ navigation }) => { onPress={() => Linking.openURL(INSTAGRAM_URL)} > - {iconsMap.get('instagram', { color: LINK_COLOR })} + {iconsMap.get('instagram', { color: LINK_COLOR })} @benimacletconfusion @@ -52,6 +71,17 @@ const InfoContainer = ({ navigation }) => { Benimaclet conFusión + {crowdfundintActive && + Linking.openURL(CROWDFUNDING_URL)} + > + + {iconsMap.get('crowdfunding', { color: LINK_COLOR, size: 28 })} + Ayúdanos participando en el crowdfunding! + + } @@ -106,6 +136,11 @@ const styles = StyleSheet.create({ color: LINK_COLOR, fontSize: 14 }, + linkImportant: { + fontWeight: 'bold', + color: LINK_COLOR, + fontSize: 16 + }, linksContainer: { paddingHorizontal: 12, marginBottom: 12 diff --git a/src/event-properties.js b/src/event-properties.js index b938004..c828627 100644 --- a/src/event-properties.js +++ b/src/event-properties.js @@ -25,3 +25,11 @@ export const EVENT_CATEGORIES_INFO = [ export const EVENT_CATEGORIES = EVENT_CATEGORIES_INFO.map(categoryInfo => [categoryInfo.id, categoryInfo.name] ); + +export const CROWDFUNDING_URL = 'https://vkm.is/confusion10'; +export const CROWDFUNDING_START = '2023-10-01'; +export const CROWDFUNDING_END = '2023-10-16'; + +export const WEB_URL = 'https://beniconfusionfest.es/es/inicio'; +export const INSTAGRAM_URL = 'https://www.instagram.com/benimacletconfusion/'; +export const YOUTUBE_URL = 'https://www.youtube.com/c/conFusi%C3%B3nfest/featured'; diff --git a/src/helpers/icon-helpers.js b/src/helpers/icon-helpers.js index 7c03838..8fceab9 100644 --- a/src/helpers/icon-helpers.js +++ b/src/helpers/icon-helpers.js @@ -1,5 +1,5 @@ import React from 'react'; -import { Feather, FontAwesome5, MaterialCommunityIcons, AntDesign, Ionicons, Entypo } from '@expo/vector-icons'; +import { Feather, FontAwesome5, MaterialIcons, MaterialCommunityIcons, AntDesign, Ionicons, Entypo } from '@expo/vector-icons'; const values = new Map([ ['0', ({ size, color, styleClass }) => ], @@ -27,7 +27,8 @@ const values = new Map([ ['fusion', ({ size, color, styleClass }) => ], ['instagram', ({ size, color, styleClass }) => ], ['youtube', ({ size, color, styleClass }) => ], - ['web', ({ size, color, styleClass }) => ] + ['web', ({ size, color, styleClass }) => ], + ['crowdfunding', ({ size, color, styleClass }) => ] ]); export const iconsMap = {