@react-navigation/native#useTheme JavaScript Examples
The following examples show how to use
@react-navigation/native#useTheme.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: CommentListItem.js From reddit-clone with MIT License | 6 votes |
CommentListItem = ({ body, author, created, deleteComment }) => {
const { colors } = useTheme()
const { authState } = React.useContext(AuthContext)
return (
<View style={[styles.container, { backgroundColor: colors.bgColor }]}>
<View style={[styles.header, { borderBottomColor: colors.border }]}>
<Text style={[styles.authorName, { color: colors.blue }]}>{author?.username}</Text>
<View style={styles.headerRight}>
<Text style={[styles.dateText, { color: colors.text }]}>{moment(created).fromNow()}</Text>
{author?.id === authState.userInfo.id && (
<TouchableOpacity style={styles.trash} activeOpacity={0.5} onPress={deleteComment}>
<Trash color={colors.red} width={20} height={20} />
</TouchableOpacity>
)}
</View>
</View>
<View style={styles.body}>
<Text style={[styles.regularFont, { color: colors.text }]}>{body}</Text>
</View>
</View>
)
}
Example #2
Source File: SignModal.js From reddit-clone with MIT License | 6 votes |
SignModal = ({ navigation }) => {
const { colors } = useTheme()
return (
<TouchableWithoutFeedback onPress={() => navigation.goBack()}>
<View as={SafeAreaView} style={styles.container}>
<StatusBar hidden />
<View
style={[styles.modal, { backgroundColor: colors.background }]}
onStartShouldSetResponder={() => true}
>
<View style={styles.buttonContainer}>
<Button
bgColor={colors.signUpButton}
title="Sign Up"
onPress={() => navigation.navigate('SignUp')}
>
<PlusCircle color={colors.white} />
</Button>
<Button
bgColor={colors.signInButton}
title="Sign In"
onPress={() => navigation.navigate('SignIn')}
>
<LogIn color={colors.white} />
</Button>
</View>
</View>
</View>
</TouchableWithoutFeedback>
)
}
Example #3
Source File: CategoryPicker.js From reddit-clone with MIT License | 6 votes |
CategoryPicker = ({ selectedCategory, onClick, addAll, setFieldValue, ...props }) => {
const { colors } = useTheme()
return (
<View {...props}>
<FlatList
data={addAll ? ['all', ...categories] : categories}
horizontal
keyExtractor={item => item}
renderItem={({ item }) => (
<TouchableOpacity
onPress={() => (onClick ? onClick(item) : setFieldValue('category', item))}
>
<Text
style={[
styles.category,
{
fontWeight: item === selectedCategory ? 'bold' : 'normal',
borderBottomColor: item === selectedCategory ? colors.blue : 'transparent',
color: item === selectedCategory ? colors.blue : colors.text
}
]}
>
{item}
</Text>
</TouchableOpacity>
)}
/>
</View>
)
}
Example #4
Source File: Stations.js From timetable with MIT License | 6 votes |
Stations = () => {
const navigation = useNavigation()
const { i18n } = useTranslation()
const { dark } = useTheme()
const [db, setDb] = useState({
markers: []
})
useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
const station = i18n.language == 'en' ? EnDb.Stops : GeDb.Stops
setDb({ markers: station })
})
// Cleanup
return unsubscribe
}, [navigation])
// Opens Timetable screen which takes some props from map marker
const openTimetable = (stopId, name) => {
navigation.navigate('Timetable', {
stationTimetableId: stopId,
metadata: name
})
}
return (
<View style={styles.container}>
<Map
markerSource={db.markers}
onPressHandler={openTimetable}
isDark={dark}
/>
</View>
)
}
Example #5
Source File: CreatePost.js From reddit-clone with MIT License | 6 votes |
TypeSwichButton = ({ selected, onClick, type }) => {
const { colors } = useTheme()
return (
<TouchableOpacity
style={[
styles.typeButton,
type === 'link' ? styles.typeButtonRight : styles.typeButtonLeft,
selected === type ? { backgroundColor: colors.blue } : '',
{ borderColor: colors.border }
]}
onPress={() => onClick('type', type)}
>
<View>
<Text
style={[
styles.typeButtonLabel,
{ color: colors.text },
selected === type ? { color: 'white' } : ''
]}
>
{type}
</Text>
</View>
</TouchableOpacity>
)
}
Example #6
Source File: FilledButton.js From ReactNavigationAuthenticationFlowsWithHooks with MIT License | 6 votes |
export function FilledButton({title, style, onPress}) {
const {colors} = useTheme();
return (
<TouchableOpacity
style={[styles.container, style, {backgroundColor: colors.primary}]}
onPress={onPress}>
<Text style={styles.text}>{title.toUpperCase()}</Text>
</TouchableOpacity>
);
}
Example #7
Source File: CategoryLoader.js From reddit-clone with MIT License | 6 votes |
CategoryLoader = () => {
const { colors } = useTheme()
return (
<View style={[styles.loader, { backgroundColor: colors.bgColor }]}>
{[1, 2, 3, 4, 5].map(i => (
<TextLoader key={i} />
))}
</View>
)
}
Example #8
Source File: Button.js From reddit-clone with MIT License | 6 votes |
Button = ({ children, bgColor, title, ...props }) => {
const { colors } = useTheme()
return (
<TouchableOpacity
{...props}
style={[styles.button, { backgroundColor: bgColor }]}
activeOpacity={0.8}
>
{children}
<Text style={[styles.buttonText, { color: colors.white }]}>{title}</Text>
</TouchableOpacity>
)
}
Example #9
Source File: TextButton.js From ReactNavigationAuthenticationFlowsWithHooks with MIT License | 6 votes |
export function TextButton({title, style, onPress}) {
const {colors} = useTheme();
return (
<TouchableOpacity style={[styles.container, style]} onPress={onPress}>
<Text style={[styles.text, {color: colors.primary}]}>
{title.toUpperCase()}
</Text>
</TouchableOpacity>
);
}
Example #10
Source File: PostLoader.js From reddit-clone with MIT License | 6 votes |
PostLoader = ({ ...props }) => {
const { colors } = useTheme()
return (
<View style={[styles.loader, { backgroundColor: colors.bgColor }]} {...props}>
<TextLoader style={{ width: '30%', marginTop: 10 }} />
{[1, 2, 3].map(i => (
<TextLoader key={i} style={{ width: '100%', marginTop: 10 }} />
))}
<TextLoader style={{ width: '80%', marginTop: 10 }} />
</View>
)
}
Example #11
Source File: CreateComment.js From reddit-clone with MIT License | 6 votes |
CreateComment = ({ onPress, setComment, comment, setIsFocused }) => {
const { colors } = useTheme()
const textInputRef = React.useRef()
return (
<View style={[styles.container, { backgroundColor: colors.bgColor }]}>
<TextInput
style={[
styles.textInput,
{ backgroundColor: colors.background, borderColor: colors.border, color: colors.text }
]}
ref={textInputRef}
placeholder="Add a comment"
placeholderTextColor={colors.text}
onFocus={() => setIsFocused(true)}
onBlur={() => setIsFocused(false)}
onChangeText={setComment}
maxLength={2000}
autoCorrect={false}
value={comment}
/>
<TouchableOpacity
onPress={() => {
textInputRef.current.blur()
onPress()
}}
>
<Send color={colors.text} />
</TouchableOpacity>
</View>
)
}
Example #12
Source File: CommentLoader.js From reddit-clone with MIT License | 6 votes |
CommentLoader = ({ ...props }) => {
const { colors } = useTheme()
return (
<View style={[styles.loader, { backgroundColor: colors.bgColor }]} {...props}>
<TextLoader style={{ width: '30%', marginTop: 10 }} />
<TextLoader style={{ width: '100%', marginTop: 10 }} />
</View>
)
}
Example #13
Source File: TabBar.js From reddit-clone with MIT License | 5 votes |
function TabBar({ state, descriptors, navigation }) {
const { authState } = React.useContext(AuthContext)
const { colors } = useTheme()
return (
<View
style={[
styles.tabBarContainer,
{ backgroundColor: colors.bgColor, borderColor: colors.border }
]}
>
{state.routes.map((route, index) => {
const { options } = descriptors[route.key]
const label =
options.tabBarLabel !== undefined
? options.tabBarLabel
: options.title !== undefined
? options.title
: route.name
const isFocused = state.index === index
const onPress = () => {
const event = navigation.emit({
type: 'tabPress',
target: route.key,
canPreventDefault: true
})
if (!isFocused && !event.defaultPrevented) {
if (authState.token) {
navigation.navigate(route.name, {
username: authState.userInfo.username
})
} else {
navigation.navigate('SignModal')
}
}
}
return (
<TouchableOpacity key={route.key} onPress={onPress} style={styles.button}>
{label === 'Home' && <Home color={isFocused ? colors.blue : colors.text} />}
{label === 'CreatePost' && <PlusSquare color={isFocused ? colors.blue : colors.text} />}
{label === 'User' && <User color={isFocused ? colors.blue : colors.text} />}
</TouchableOpacity>
)
})}
</View>
)
}
Example #14
Source File: User.js From reddit-clone with MIT License | 5 votes |
User = ({ route }) => {
const { authState } = React.useContext(AuthContext)
const { colors } = useTheme()
const [isLoading, setIsLoaading] = React.useState(false)
const [userPosts, setuserPosts] = React.useState(null)
const username = route.params?.username
const getUserPostDetail = React.useCallback(async () => {
setIsLoaading(true)
const { data } = await axios.get(`user/${username || authState.userInfo.username}`)
setuserPosts(data)
setIsLoaading(false)
}, [authState.userInfo.username, username])
React.useEffect(() => {
getUserPostDetail()
}, [getUserPostDetail])
const deletePost = async (postId, index) => {
setIsLoaading(true)
const { status } = await axios.delete(`post/${postId}`)
if (status === 200) {
setuserPosts(prevData => {
prevData.splice(index, 1)
return prevData
})
}
setIsLoaading(false)
}
return (
<View as={SafeAreaView} style={styles.boxCenter}>
{userPosts ? (
<FlatList
data={userPosts.sort((a, b) => a.created < b.created)}
extraData={isLoading}
refreshing={isLoading}
onRefresh={() => getUserPostDetail()}
keyExtractor={item => item.id}
ListEmptyComponent={
<Text style={[styles.empty, { color: colors.text }]}>Ups! Not found any post!</Text>
}
ListHeaderComponent={<HeaderComponent username={username} postCount={userPosts.length} />}
stickyHeaderIndices={[0]}
ListHeaderComponentStyle={styles.headerComponentStyle}
renderItem={({ item, index }) => (
<Post
index={index}
postId={item.id}
userId={authState.userInfo.id}
score={item.score}
type={item.type}
title={item.title}
author={item.author}
category={item.category}
text={item.text}
comments={item.comments}
created={item.created}
url={item.url}
votes={item.votes}
views={item.views}
setIsLoaading={setIsLoaading}
setData={setuserPosts}
deleteButton={true}
deletePost={() => deletePost(item.id, index)}
/>
)}
/>
) : (
<>
{[1, 2, 3, 4, 5].map(i => (
<PostLoader key={i} />
))}
</>
)}
</View>
)
}
Example #15
Source File: TextLoader.js From reddit-clone with MIT License | 5 votes |
TextLoader = ({ ...props }) => {
const { colors } = useTheme()
return <View style={[styles.bgLight, props.style, { backgroundColor: colors.loader }]} />
}
Example #16
Source File: Home.js From reddit-clone with MIT License | 5 votes |
Home = () => {
const { authState } = React.useContext(AuthContext)
const { theme } = React.useContext(ThemeContext)
const { colors } = useTheme()
const [postData, setPostData] = React.useState(null)
const [category, setCategory] = React.useState('all')
const [isLoading, setIsLoaading] = React.useState(false)
const getPostData = React.useCallback(async () => {
setIsLoaading(true)
const { data } = await axios.get(
!category || category === 'all' ? 'posts' : `posts/${category}`
)
setPostData(data)
setIsLoaading(false)
}, [category])
React.useEffect(() => {
getPostData()
}, [getPostData])
return (
<View as={SafeAreaView} style={styles.container}>
<StatusBar
barStyle={theme === 'light' ? 'dark-content' : 'light-content'}
backgroundColor={colors.background}
/>
{postData ? (
<FlatList
data={postData}
extraData={isLoading}
refreshing={isLoading}
onRefresh={() => getPostData()}
keyExtractor={item => item.id}
ListHeaderComponent={
<CategoryPicker selectedCategory={category} onClick={setCategory} addAll />
}
ListHeaderComponentStyle={[styles.categoryPicker, { backgroundColor: colors.bgColor }]}
ListEmptyComponent={
<Text style={[styles.empty, { color: colors.text }]}>Ups! Not found any post!</Text>
}
renderItem={({ item, index }) => (
<Post
index={index}
postId={item.id}
userId={authState.userInfo.id}
score={item.score}
type={item.type}
title={item.title}
author={item.author}
category={item.category}
text={item.text}
comments={item.comments}
created={item.created}
url={item.url}
votes={item.votes}
views={item.views}
setIsLoaading={setIsLoaading}
setData={setPostData}
deleteButton={false}
/>
)}
/>
) : (
<>
<CategoryLoader />
{[1, 2, 3, 4, 5].map(i => (
<PostLoader key={i} />
))}
</>
)}
</View>
)
}
Example #17
Source File: User.js From reddit-clone with MIT License | 5 votes |
HeaderComponent = ({ username, postCount }) => {
const { signOut, authState } = React.useContext(AuthContext)
const { theme, changeTheme } = React.useContext(ThemeContext)
const { colors } = useTheme()
const navigation = useNavigation()
return (
<View style={[styles.userInfo, { backgroundColor: colors.bgColor }]}>
<View style={styles.infoBox}>
<Text style={[styles.label, { color: colors.text }]}>Username</Text>
<Text style={{ color: colors.text }}>{username ?? authState.userInfo.username}</Text>
</View>
<View style={styles.infoBox}>
<Text style={[styles.label, { color: colors.text }]}>Post Count</Text>
<Text style={{ color: colors.text }}>{postCount}</Text>
</View>
{username === authState.userInfo.username && (
<>
<View style={[styles.line, { borderColor: colors.border }]} />
<TouchableOpacity
onPress={() => changeTheme(theme === 'light' ? 'dark' : 'light')}
style={styles.infoBox}
>
{theme === 'light' ? <Moon color={colors.icon} /> : <Sun color={colors.icon} />}
<Text style={{ color: colors.text }}>
{theme === 'light' ? 'Dark Mode' : 'Light Mode'}
</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.infoBox}
onPress={() => {
signOut()
navigation.navigate('Home')
}}
>
<LogOut color={colors.red} />
<Text style={{ color: colors.red }}>Logout</Text>
</TouchableOpacity>
</>
)}
</View>
)
}
Example #18
Source File: SplashScreen.js From ReactNavigationAuthenticationFlowsWithHooks with MIT License | 5 votes |
export function SplashScreen() {
const {colors} = useTheme();
return <View style={[styles.container, {backgroundColor: colors.primary}]} />;
}
Example #19
Source File: IconButton.js From ReactNavigationAuthenticationFlowsWithHooks with MIT License | 5 votes |
export function IconButton({name, style, onPress}) {
const {colors} = useTheme();
return (
<TouchableOpacity style={[styles.container, style]} onPress={onPress}>
<Icon name={name} color={colors.primary} />
</TouchableOpacity>
);
}
Example #20
Source File: Heading.js From ReactNavigationAuthenticationFlowsWithHooks with MIT License | 5 votes |
export function Heading({children, style, ...props}) {
const {colors} = useTheme();
return (
<Text {...props} style={[styles.text, style, {color: colors.text}]}>
{children}
</Text>
);
}
Example #21
Source File: LinesMap.js From timetable with MIT License | 5 votes |
LinesMap = ({ route }) => {
const { i18n } = useTranslation()
const navigation = useNavigation()
const { dark } = useTheme()
const { busNumber, forward } = route.params
/**
* 'markerData' contains bus stations coords, Lat-Longitude!
* 'polylineData' contains entire bus route coords,
* which is used to display yellow polyline on the map.
**/
const [db, setDb] = useState({
markerData: [],
polylineData: []
})
/**
* Request for fetching bus number route coords!
* Based on direction that is set in the Lines Screen, whether it's forward or backward,
* forward variable is a boolean!
* API request sample.
* https://xxxxxxx:xxxx/xxxxxxxxx/?route=${busNumber}&forward=${forward}
**/
const endPoint =
i18n.language == 'en'
? `${process.env.API_LINESMAP_EN + busNumber + '&forward=' + forward}`
: `${process.env.API_LINESMAP_GE + busNumber + '&forward=' + forward}`
useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
const controller = new AbortController()
const signal = controller.signal
fetch(endPoint, { signal })
.then(res => res.json())
.then(data => {
setDb({
markerData: data.Stops,
polylineData: data.Stops.map(point => {
return { latitude: point.Lat, longitude: point.Lon }
})
})
})
.catch(err => console.log(err))
// Clean up
return () => controller.abort()
})
// Clean up
return unsubscribe
}, [navigation])
// Opens Bus station timetable screen
const openTimetable = (stopId, name) => {
navigation.navigate('Timetable', {
stationTimetableId: stopId,
metadata: name
})
}
return (
<Map
markerSource={db.markerData}
polylineSource={db.polylineData}
onPressHandler={openTimetable}
isDark={dark}
/>
)
}
Example #22
Source File: Feedback.js From timetable with MIT License | 5 votes |
Feedback = () => {
const navigation = useNavigation()
const { t } = useTranslation()
const { theme } = useTheme()
const sendEmailHandler = ({ name, email, message }) => {
const data = JSON.stringify({ name, email, message }).replace(/[{}'']/g, '')
fetch('https://api.sendgrid.com/v3/mail/send', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
Authorization: 'Bearer ' + process.env.API_SEND_GRID_KEY
},
body: JSON.stringify({
personalizations: [
{
to: [
{
email: process.env.SEND_GRID_EMAIL_TO
}
],
subject: 'Bus Timetable Feedback'
}
],
from: {
email: process.env.SEND_GRID_EMAIL_FROM
},
content: [
{
type: 'text/plain',
value: data
}
]
})
})
.then(() => {
Alert.alert('', t('feedback.onSuccessfulSubmit'), [
{
text: t('feedback.cancel'),
onPress: () => navigation.navigate('About')
}
])
})
.catch(() => {
Alert.alert(t('feedback.error'), t('feedback.onSubmitError'), [
{ text: t('feedback.cancel') }
])
})
}
return (
<TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}>
<View style={styles.container}>
<Text style={[styles.info, { color: theme.text }]}>
{t('feedback.info')}
</Text>
<ScrollView style={styles.form}>
<Form
onSubmitHandler={sendEmailHandler}
namePlaceholder={t('feedback.namePlaceholder')}
emailPlaceholder={t('feedback.emailPlaceholder')}
messagePlaceholder={t('feedback.messagePlaceholder')}
submitTitle={t('feedback.submitTitle')}
schemaRequiredName={t('feedback.schemaRequiredName')}
schemaRequiredEmail={t('feedback.schemaRequiredEmail')}
schemaRequiredMessage={t('feedback.schemaRequiredMessage')}
buttonColor={theme.buttonColor}
buttonText={theme.buttonText}
/>
</ScrollView>
</View>
</TouchableWithoutFeedback>
)
}
Example #23
Source File: Detail.js From curso-react-native with MIT License | 4 votes |
Detail = ({route, navigation}) => {
const [poke, setPoke] = useState({});
const {colors} = useTheme();
const {pokemon, previous} = route.params;
const colorByType = colors[poke.types?.[0].type.name];
const recursiveEvolutionChain = (chain) => {
const isCurrent = chain?.species.name === pokemon.name;
return (
<View style={styles.row}>
<TouchableOpacity
onPress={() => {
if (previous === chain?.species.name) {
navigation.goBack();
} else if (!isCurrent) {
navigation.push('Pokemon', {
pokemon: chain.species,
previous: pokemon.name,
});
}
}}>
<Text
style={[
styles.pokemonName,
{
marginHorizontal: 16,
color: isCurrent && colors.primary,
},
]}>
{chain?.species.name}
</Text>
</TouchableOpacity>
{chain?.evolves_to.length > 0 && (
<Text style={styles.pokemonName}>></Text>
)}
<View>
{chain?.evolves_to?.map((poke) => recursiveEvolutionChain(poke))}
</View>
</View>
);
};
useEffect(() => {
Promise.all([
P.getPokemonByName(pokemon.name),
P.getPokemonSpeciesByName(pokemon.name),
]).then(([pokemonInfo, speciesInfo]) => {
const {types, id} = pokemonInfo;
const {evolution_chain, flavor_text_entries} = speciesInfo;
const description = flavor_text_entries
.find((flavor) => flavor.language.name === 'es')
?.flavor_text.replace(/\n/g, ' ');
P.resource(evolution_chain.url).then((evolutionChain) => {
setPoke(
Pokemon({
...pokemon,
id,
description,
chain: evolutionChain.chain,
types: types.sort((a, b) =>
a.slot > b.slot ? 1 : a.slot < b.slot ? -1 : 0,
),
}),
);
});
});
}, []);
useEffect(() => {
navigation.setOptions({
headerStyle: {
backgroundColor: colorByType,
},
});
}, [colorByType]);
return (
<View style={{padding: 16}}>
<StatusBar backgroundColor={colorByType} barStyle="light-content" />
<View style={styles.row}>
<Image style={{width: 180, height: 180}} source={{uri: poke.image}} />
<View style={{paddingTop: 24}}>
<Text style={styles.pokemonName}>
#{poke.id} - {poke.name}
</Text>
<View style={styles.typesContainer}>
{poke.types?.map((type, index) => (
<Text
key={index}
style={[
styles.type,
{backgroundColor: colors[type.type.name]},
]}>
{type.type.name}
</Text>
))}
</View>
</View>
</View>
<Text style={{fontSize: 16}}>{poke.description}</Text>
<Text style={{fontSize: 24, marginTop: 16}}>Cadena Evolutiva</Text>
<ScrollView horizontal style={styles.typesContainer}>
{recursiveEvolutionChain(poke.chain)}
</ScrollView>
</View>
);
}
Example #24
Source File: Detail.js From curso-react-native with MIT License | 4 votes |
export default function Detail({route, navigation}) {
const [pokemon, setPokemon] = useState(route.params.pokemon);
const [isLoading, setLoading] = useState(true);
const {colors} = useTheme();
const colorByType = colors[pokemon.types?.[0].type.name];
useEffect(() => {
Promise.all([
P.getPokemonByName(pokemon.name),
P.getPokemonSpeciesByName(pokemon.name).then((res) =>
P.resource(res.evolution_chain.url).then((chain) => ({
description: res.flavor_text_entries
?.find((flavor) => flavor.language.name === 'es')
?.flavor_text?.replace(/\n/g, ' '),
chain: chain.chain,
})),
),
])
.then(([poke, evolutionChain]) => {
setPokemon(
Pokemon({
...pokemon,
...evolutionChain,
...poke,
}),
);
setLoading(false);
})
.catch(() => {
navigation.goBack();
});
// o
// fetch(pokemon.url)
// .then(res => res.json())
// .then(response => setPokemon({...pokemon, ...response}))
}, []);
useEffect(() => {
navigation.setOptions({
headerStyle: {
backgroundColor: colorByType,
},
});
}, [colorByType]);
const recursiveEvolutionChain = (chain) => {
const isCurrent = chain?.species.name === pokemon.name;
return (
<View style={styles.row}>
<TouchableOpacity
onPress={() => {
if (route.params.previous === chain?.species.name) {
navigation.goBack();
} else if (!isCurrent) {
navigation.push('Pokémon', {
pokemon: chain.species,
previous: pokemon.name,
});
}
}}>
<Text
style={[
styles.name,
{
marginHorizontal: 16,
color: isCurrent && colors.primary,
},
]}>
{chain?.species.name}
</Text>
</TouchableOpacity>
{chain?.evolves_to.length > 0 && <Text style={styles.name}>></Text>}
<View>
{chain?.evolves_to?.map((poke) => recursiveEvolutionChain(poke))}
</View>
</View>
);
};
return isLoading ? (
<ActivityIndicator
size={54}
color={colors.primary}
style={{marginTop: 36}}
/>
) : (
<ScrollView contentContainerStyle={{padding: 16}}>
<StatusBar backgroundColor={colorByType} barStyle="light-content" />
<View style={[styles.row, {justifyContent: 'flex-start'}]}>
<Image
style={styles.image}
resizeMode="contain"
source={{
uri: pokemon.image,
}}
/>
<View>
<Text style={styles.name}>
#{pokemon.id} - {pokemon.name}
</Text>
<View
style={[
styles.row,
{marginRight: 8, justifyContent: 'flex-start'},
]}>
{pokemon.types?.map((t) => (
<View
style={[
styles.type,
{
backgroundColor: colors[t.type.name],
},
]}>
<Text style={{color: 'white'}}>{t.type.name}</Text>
</View>
))}
</View>
</View>
</View>
<Text style={styles.description}>{pokemon.description}</Text>
{pokemon.chain?.evolves_to.length > 0 && (
<>
<Text style={styles.name}>Cadena evolutiva:</Text>
<ScrollView horizontal showsHorizontalScrollIndicator={false}>
{recursiveEvolutionChain(pokemon.chain)}
</ScrollView>
</>
)}
</ScrollView>
);
}
Example #25
Source File: Post.js From reddit-clone with MIT License | 4 votes |
Post = ({
index,
postId,
userId,
score,
type,
title,
author,
category,
text,
comments,
created,
url,
votes,
views,
setIsLoaading,
setData,
postType,
deleteButton,
deletePost
}) => {
const { colors } = useTheme()
const navigation = useNavigation()
const { authState } = React.useContext(AuthContext)
const route = useRoute()
const isUpVoted = () => {
return votes.find(v => v.user === userId)?.vote === 1
}
const isDownVoted = () => {
return votes.find(v => v.user === userId)?.vote === -1
}
const upVote = async () => {
setIsLoaading(true)
const { data } = await axios.get(`post/${postId}/upvote`)
if (postType !== 'item') {
setData(prevData => {
prevData[index] = data
return prevData
})
} else {
setData(data)
}
setIsLoaading(false)
}
const downVote = async () => {
setIsLoaading(true)
const { data } = await axios.get(`post/${postId}/downvote`)
if (postType !== 'item') {
setData(prevData => {
prevData[index] = data
return prevData
})
} else {
setData(data)
}
setIsLoaading(false)
}
const unVote = async () => {
setIsLoaading(true)
const { data } = await axios.get(`post/${postId}/unvote`)
if (postType !== 'item') {
setData(prevData => {
prevData[index] = data
return prevData
})
} else {
setData(data)
}
setIsLoaading(false)
}
return (
<View
as={SafeAreaView}
style={[
styles.container,
{ backgroundColor: colors.bgColor, borderColor: colors.postBorder }
]}
>
<View style={styles.headerContainer}>
<View style={styles.headerLeft}>
<Text style={[styles.regularFont, { color: colors.text }]}>{category} </Text>
<Text
style={[styles.italicFont, { color: colors.blue }]}
onPress={() => navigation.navigate('User', { username: author.username })}
>
@{author?.username} ·{' '}
</Text>
<Text style={[styles.dateText, { color: colors.text }]}>{moment(created).fromNow()}</Text>
</View>
<View style={styles.headerRight}>
{deleteButton && author?.id === authState.userInfo.id && (
<TouchableOpacity style={styles.trash} activeOpacity={0.5} onPress={deletePost}>
<Trash color={colors.red} width={20} height={20} />
</TouchableOpacity>
)}
</View>
</View>
<Text
style={[styles.title, { color: colors.text }]}
onPress={() => navigation.navigate('PostDetail', { postId, category, comments })}
>
{title}
</Text>
<Text
numberOfLines={route.name === 'PostDetail' ? 10000 : 10}
style={[
styles.regularFont,
{ color: colors.text },
type === 'link' && route.name === 'PostDetail' && styles.link
]}
onPress={() =>
route.name === 'PostDetail' && type === 'link'
? Linking.openURL(url)
: navigation.navigate('PostDetail', { postId, category, comments })
}
>
{type === 'link' ? url : text}
</Text>
<View style={styles.bottomContainer}>
<View style={styles.centerAlign}>
<TouchableOpacity onPress={() => (isUpVoted() ? unVote() : upVote())}>
<ArrowUp
width={22}
height={22}
strokeWidth={4}
color={isUpVoted() ? colors.green : colors.icon}
/>
</TouchableOpacity>
<Text style={[styles.score, { color: colors.text }]}>{score}</Text>
<TouchableOpacity onPress={() => (isDownVoted() ? unVote() : downVote())}>
<ArrowDown
width={22}
height={22}
strokeWidth={4}
color={isDownVoted() ? colors.red : colors.icon}
/>
</TouchableOpacity>
</View>
<TouchableOpacity
style={styles.centerAlign}
activeOpacity={0.7}
onPress={() => navigation.navigate('PostDetail', { postId, category, comments })}
>
<MessageSquare
color={colors.icon}
style={styles.commentIcon}
width={20}
height={20}
strokeWidth={3}
/>
<Text style={[styles.commentText, { color: colors.text }]}>{comments?.length}</Text>
</TouchableOpacity>
<Text style={[styles.italicFont, { color: colors.text }]}>{views} views</Text>
</View>
</View>
)
}
Example #26
Source File: Timetable.js From timetable with MIT License | 4 votes |
Timetable = ({ route }) => {
const { t, i18n } = useTranslation()
const { theme } = useTheme()
// netInfo helps to check network connection status. Timeout 15s
const netInfo = useNetInfo({ reachabilityRequestTimeout: 15 * 1000 })
// station ID which you get from Stations screen
const { stationTimetableId, metadata } = route.params
const metainfo = { station: stationTimetableId, info: metadata }
/**
* Arrival bus list!
* Used to get latest info.
* API request sample.
* https://xxxxxxx:xxxx/xxxxxxxxxxxx/?station=${stationTimetableId}
**/
const endPoint =
i18n.language == 'en'
? `${process.env.API_TIMETABLE_EN + stationTimetableId}`
: `${process.env.API_TIMETABLE_GE + stationTimetableId}`
// Local Time string object
const [localTime, setLocalTime] = useState('')
// Stream of data
const fetcher = (...args) => fetch(...args).then(res => res.json())
const { data, error } = useSWR(endPoint, fetcher, {
refreshInterval: 1000 * 10
})
// Bouncing animation
const focus = new Animated.Value(0)
Animated.loop(
Animated.timing(focus, {
toValue: 10,
duration: 4000,
easing: Easing.bounce,
useNativeDriver: true
})
).start()
useEffect(() => {
// Server related warning
if (error) {
Alert.alert(t('timetable.error'), t('timetable.server_err'), [
{ text: t('timetable.cancel') }
])
}
const interval = setInterval(() => {
setLocalTime(
new Date().toLocaleTimeString('en-US', { hour12: false }, 'ka-KA')
)
}, 1000)
// clean up
return () => {
clearInterval(interval), focus.stopAnimation()
}
}, [])
/**
* Saves station ID and metainfo to local storage!
* Checks if ID exist in storage and displays pop up warning.
**/
const saveFavoriteHandler = async () => {
try {
const result = await AsyncStorage.getItem('TestFavorite')
if (result == null) {
const createArray = [metainfo]
AsyncStorage.setItem('TestFavorite', JSON.stringify(createArray))
} else if (result !== null) {
const array = await JSON.parse(result)
let onAlert = false
array.forEach(value => {
if (value.station == stationTimetableId) {
onAlert = true
Alert.alert('', t('timetable.favorite'), [
{ text: t('timetable.cancel') }
])
}
})
if (onAlert == false) {
array.push(metainfo)
AsyncStorage.setItem('TestFavorite', JSON.stringify(array))
}
}
} catch (err) {
Alert.alert('', err, [{ text: t('timetable.cancel') }])
}
}
/**
* Displays Local Time!
* Shows night time if it's between 12:00AM - 6:00AM.
* Shows delay if timetable is empty between 7:00AM - 11:00PM,
* also for displaying delay we check network status.
**/
const DisplayTime = () => {
if (parseInt(localTime) >= 7 && parseInt(localTime) <= 22) {
return (
<View style={styles.localTime}>
<Text style={{ color: theme.text }}>{localTime} (GMT+4)</Text>
<Text style={{ color: theme.text }}>{t('timetable.localTime')}</Text>
<Text style={{ color: theme.text }}>
{t('timetable.localTimeDelay')}
</Text>
</View>
)
} else if (
(parseInt(localTime) >= 0 && parseInt(localTime) <= 6) ||
parseInt(localTime) == 23
) {
return (
<View style={styles.localTime}>
<Text style={{ color: theme.text }}>{localTime} (GMT+4)</Text>
<Text style={{ color: theme.text }}>{t('timetable.localTime')}</Text>
<Text style={{ color: theme.text }}>
{t('timetable.localTimeNight')}
</Text>
</View>
)
}
}
// FlatList Item
const Item = ({ title, time, bus, nowText, minText }) => {
// Apply animation if time is below two minutes and display 'Now' instead of time.
// Time is number it can be between 0-100: represents minutes.
const willBeIn = () => {
if (time <= 2 || 0) {
return (
<Animated.View style={{ opacity: focus }}>
<Text style={{ color: theme.text }}>{nowText}</Text>
</Animated.View>
)
} else {
return (
<Text style={{ color: theme.text }}>
{time} {minText}
</Text>
)
}
}
return (
<View style={[styles.listItemView, { borderColor: theme.border }]}>
<Text style={{ color: theme.text }}>{bus}</Text>
<Text style={[styles.title, { color: theme.text }]}>{title}</Text>
{willBeIn()}
</View>
)
}
return (
<View style={styles.container}>
<Text style={[styles.info, { color: theme.text }]}>
{t('timetable.station')} {stationTimetableId}
</Text>
<AntDesign
name='staro'
color='white'
size={30}
style={styles.favoriteIcon}
onPress={saveFavoriteHandler}
/>
<View style={styles.listHeader}>
<Text style={{ color: theme.text }}>{t('timetable.bus')}</Text>
<Text style={{ color: theme.text }}>{t('timetable.direction')}</Text>
<Text style={{ color: theme.text }}>{t('timetable.time')}</Text>
</View>
{!data ? null : (
<FlatList
data={data.ArrivalTime}
renderItem={({ item }) => (
<Item
title={item.DestinationStopName}
time={item.ArrivalTime}
bus={item.RouteNumber}
minText={t('timetable.minText')}
nowText={t('timetable.nowText')}
/>
)}
keyExtractor={item => item.RouteNumber}
/>
)}
{!data
? null
: netInfo.isConnected && data.ArrivalTime.length === 0 && DisplayTime()}
</View>
)
}
Example #27
Source File: CreatePost.js From reddit-clone with MIT License | 4 votes |
CreatePost = () => {
const { colors } = useTheme()
const [isLoading, setIsLoading] = React.useState(false)
const [message, setMessage] = React.useState(null)
const fadeAnim = React.useRef(new Animated.Value(0)).current
const fadeIn = () => {
Animated.timing(fadeAnim, {
toValue: 1,
duration: 2000,
useNativeDriver: true
}).start()
setTimeout(() => {
setMessage(null)
}, 6000)
}
return (
<ScrollView as={SafeAreaView} style={[styles.container, { backgroundColor: colors.bgColor }]}>
<Formik
initialValues={{
type: 'text',
category: '',
title: '',
url: '',
text: ''
}}
onSubmit={async (values, { setStatus, resetForm }) => {
setIsLoading(true)
try {
await axios.post('posts', values)
resetForm({ ...values, type: 'text' })
setMessage('Successfully Created!')
fadeIn()
} catch (error) {
setStatus(error.response.data.message)
}
setIsLoading(false)
}}
validationSchema={Yup.object({
type: Yup.mixed().oneOf(['text', 'link']),
category: Yup.string().required('Required'),
title: Yup.string()
.required('Required')
.max(100, 'Must be at most 100 characters long'),
text: Yup.string().when('type', {
is: 'text',
then: Yup.string()
.required('Required')
.min(4, 'Must be at least 4 characters long')
}),
url: Yup.string().when('type', {
is: 'link',
then: Yup.string()
.required('Required')
.url('Invalid Url')
})
})}
>
{({
handleChange,
handleBlur,
handleSubmit,
touched,
errors,
status,
values,
setFieldValue
}) => (
<View>
{message && (
<Animated.View
style={{
opacity: fadeAnim
}}
>
{!!message && <Text style={styles.message}>{message}</Text>}
</Animated.View>
)}
{!!status && <Text style={styles.status}>{status}</Text>}
<View style={styles.flexRow}>
<Text style={[styles.formLabel, { color: colors.text }]}>Type</Text>
{touched.type && errors.type && (
<Text style={styles.errorMessage}>{errors.type}</Text>
)}
</View>
<TypeSwichContainer>
<TypeSwichButton selected={values.type} onClick={setFieldValue} type="text" />
<TypeSwichButton selected={values.type} onClick={setFieldValue} type="link" />
</TypeSwichContainer>
<View style={styles.flexRow}>
<Text style={[styles.formLabel, { color: colors.text }]}>Category</Text>
{touched.category && errors.category && (
<Text style={styles.errorMessage}>{errors.category}</Text>
)}
</View>
<CategoryPicker selectedCategory={values.category} setFieldValue={setFieldValue} />
<View style={styles.flexRow}>
<Text style={[styles.formLabel, { color: colors.text }]}>Title</Text>
{touched.title && errors.title && (
<Text style={styles.errorMessage}>{errors.title}</Text>
)}
</View>
<TextInput
style={[
styles.textInput,
{ borderColor: colors.border, color: colors.text, height: 40 },
touched.title && errors.title && { borderColor: colors.red }
]}
value={values.title}
onChangeText={handleChange('title')}
onBlur={handleBlur('title')}
/>
{values.type === 'link' ? (
<>
<View style={styles.flexRow}>
<Text style={[styles.formLabel, { color: colors.text }]}>Url</Text>
{touched.url && errors.url && (
<Text style={styles.errorMessage}>{errors.url}</Text>
)}
</View>
<TextInput
style={[
styles.textInput,
{ borderColor: colors.border, color: colors.text },
touched.url && errors.url && { borderColor: colors.red }
]}
multiline
value={values.url}
onChangeText={handleChange('url')}
onBlur={handleBlur('url')}
/>
</>
) : (
<>
<View style={styles.flexRow}>
<Text style={[styles.formLabel, { color: colors.text }]}>Text</Text>
{touched.text && errors.text && (
<Text style={styles.errorMessage}>{errors.text}</Text>
)}
</View>
<TextInput
style={[
styles.textInput,
{ borderColor: colors.border, color: colors.text },
touched.text && errors.text && { borderColor: colors.red }
]}
multiline
value={values.text}
onChangeText={handleChange('text')}
onBlur={handleBlur('text')}
/>
</>
)}
<View style={styles.buttonContainer}>
<TouchableOpacity
style={[styles.submitButton, { backgroundColor: colors.blue }]}
onPress={handleSubmit}
>
{isLoading ? (
<ActivityIndicator size="small" color="white" />
) : (
<Plus color="white" />
)}
<Text style={styles.submitButtonText}>Create Post</Text>
</TouchableOpacity>
</View>
</View>
)}
</Formik>
</ScrollView>
)
}
Example #28
Source File: SignIn.js From reddit-clone with MIT License | 4 votes |
SignIn = ({ navigation }) => {
const { setStorage } = React.useContext(AuthContext)
const { colors } = useTheme()
const [isLoading, setIsLoading] = React.useState(false)
return (
<KeyboardAvoidingView behavior="padding" style={{ flex: 1 }}>
<Formik
initialValues={{ username: '', password: '' }}
onSubmit={async (values, { setStatus, resetForm }) => {
setIsLoading(true)
try {
const { data } = await axios.post('authenticate', values)
const { token, expiresAt, userInfo } = data
setStorage(token, expiresAt, userInfo)
navigation.navigate('Home')
resetForm({})
} catch (error) {
setStatus(error.response.data.message)
}
setIsLoading(false)
}}
validationSchema={Yup.object({
username: Yup.string()
.required('Required')
.max(32, 'Must be at most 32 characters long')
.matches(/^[a-zA-Z0-9_-]+$/, 'Contains invalid characters'),
password: Yup.string()
.required('Required')
.min(6, 'Must be at least 6 characters long')
.max(50, 'Must be at most 50 characters long')
})}
>
{({
handleChange,
handleBlur,
handleSubmit,
touched,
errors,
status,
values,
setTouched
}) => (
<TouchableWithoutFeedback onPress={() => navigation.goBack()}>
<View as={SafeAreaView} style={styles.container}>
<View
style={[styles.modal, { backgroundColor: colors.background }]}
onStartShouldSetResponder={() => true}
onResponderRelease={() => setTouched(errors)}
>
{!!status && <Text style={styles.status}>{status}</Text>}
{touched.username && errors.username && (
<Text style={styles.errorMessage}>{errors.username}</Text>
)}
<TextInput
style={[
styles.textInput,
touched.username && errors.username && { borderColor: colors.red },
{ color: colors.text }
]}
placeholder="Username"
placeholderTextColor={colors.text}
value={values.username}
autoCorrect={false}
onChangeText={handleChange('username')}
onBlur={handleBlur('username')}
/>
{touched.password && errors.password && (
<Text style={styles.errorMessage}>{errors.password}</Text>
)}
<TextInput
style={[
styles.textInput,
touched.password && errors.password && { borderColor: colors.red },
{ color: colors.text }
]}
placeholder="Password"
placeholderTextColor={colors.text}
value={values.password}
onChangeText={handleChange('password')}
onBlur={handleBlur('password')}
secureTextEntry
/>
<View style={styles.buttonContainer}>
<Button onPress={handleSubmit} title="Login" bgColor={colors.signInButton}>
{isLoading && <ActivityIndicator size="small" color="white" />}
</Button>
</View>
</View>
</View>
</TouchableWithoutFeedback>
)}
</Formik>
</KeyboardAvoidingView>
)
}
Example #29
Source File: Lines.js From timetable with MIT License | 4 votes |
Lines = () => {
const { i18n, t } = useTranslation()
const navigation = useNavigation()
const { theme } = useTheme()
const [busArray, setBusArray] = useState([])
useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
setBusArray(i18n.language == 'en' ? EnBus.Bus : GeBus.Bus)
})
// Cleanup
return unsubscribe
}, [navigation])
// FlatList Item
const Item = ({ busNumber, stopA, stopB }) => {
const [boolean, setBoolean] = useState(true)
// Change direction
const changeDirectionHandler = () => setBoolean(!boolean)
// Bus Line start-end direction
const direction = boolean ? (
<TouchableOpacity
onPress={() =>
navigation.navigate('LinesMap', { busNumber, forward: 0 })
}
>
<View style={styles.listItem}>
<Text style={{ color: theme.text }}>{stopA}</Text>
<Entypo name='arrow-long-right' color='#1f5c87' size={25} />
<Text style={{ color: theme.text }}>{stopB}</Text>
</View>
</TouchableOpacity>
) : (
<TouchableOpacity
onPress={() =>
navigation.navigate('LinesMap', { busNumber, forward: 1 })
}
>
<View style={styles.listItem}>
<Text style={{ color: theme.text }}>{stopB}</Text>
<Entypo name='arrow-long-right' color='#1f5c87' size={25} />
<Text style={{ color: theme.text }}>{stopA}</Text>
</View>
</TouchableOpacity>
)
return (
<View>
<View style={[styles.separator, { borderBottomColor: theme.border }]} />
<View
style={[
styles.wrapBusIcon,
{
backgroundColor: theme.backgroundColor,
borderColor: theme.border
}
]}
>
<MaterialCommunityIcons
name='bus'
color='#1f5c87'
size={15}
style={styles.busIcon}
/>
<Text style={[styles.busNumber, { color: theme.text }]}>
{busNumber}
</Text>
</View>
<Text style={[styles.from, { color: theme.text }]}>
{t('lines.from')}
</Text>
{direction}
<View style={styles.changeDirection}>
<Button
onPress={changeDirectionHandler}
text={t('lines.change')}
buttonColor={theme.buttonColor}
textColor={theme.buttonText}
margin={0}
paddingVertical={4}
fontSize={12}
/>
</View>
</View>
)
}
return (
<SafeAreaView style={styles.container}>
<FlatList
data={busArray}
renderItem={({ item }) => (
<Item
busNumber={item.RouteNumber}
stopA={item.StopA}
stopB={item.StopB}
/>
)}
keyExtractor={item => item.RouteNumber}
/>
</SafeAreaView>
)
}