Bug fixes and copy

parent 44fcd80a
......@@ -4,7 +4,7 @@ export const sampleCaches: Cache[] = [
{
id: '0',
name: 'milan.digiuseppe',
message: 'Ok gamer time',
message: 'My first geocache!!!',
found: new Date(2020, 0, 2, 0, 0, 0, 0).valueOf(),
lat: 40.7464687,
lng: -73.9844323,
......@@ -13,7 +13,7 @@ export const sampleCaches: Cache[] = [
{
id: '1',
name: 'will.brown',
message: 'Check out my cute ass dogs. Follow my on ig. I post epic dogs',
message: 'Has anyone discovered the tunnels under UW? Where do they go? Do ghosts live in there?',
found: new Date(2019, 9, 20, 0, 0, 0, 0).valueOf(),
lat: 40.7464687,
lng: -73.9844323,
......@@ -22,7 +22,7 @@ export const sampleCaches: Cache[] = [
{
id: '2',
name: 'jayson',
message: 'My first cache, and also a cry for help. Please help me I\'m stuck in a cache writing factory',
message: 'Geocaching is fun :) I\'m gonna tell all my friends',
found: new Date(2020, 1, 14, 0, 0, 0, 0).valueOf(),
lat: 40.7464687,
lng: -73.9844323,
......
......@@ -51,8 +51,8 @@ interface Props {
}
const CustomMarker: React.FC<Props> = ({
icon = 'cat',
backgroundColor = theme.colors.pink,
icon = 'paw',
backgroundColor = theme.colors.red,
}) => (
<View>
<View style={[styles.bubble, { backgroundColor }]}>
......
......@@ -70,6 +70,9 @@ const DiscoverMap: React.FC = ({ children }) => {
provider={'google'}
style={styles.map}
customMapStyle={customMapStyle}
showsBuildings={false}
showsIndoors={false}
showsPointsOfInterest={false}
initialCamera={{
center: userLocation!,
heading: 0,
......@@ -77,7 +80,6 @@ const DiscoverMap: React.FC = ({ children }) => {
zoom: 18,
altitude: 0, // not used for Google Maps
}}
showsPointsOfInterest={false}
loadingEnabled // TODO: test
pitchEnabled={false}
zoomEnabled={false}
......
......@@ -2,9 +2,10 @@ import React, { useCallback } from 'react';
import {
StyleSheet,
Text,
TouchableWithoutFeedback,
View,
} from 'react-native';
import moment from 'moment';
import { TouchableWithoutFeedback } from 'react-native-gesture-handler';
import { useNavigation } from '@react-navigation/native';
import theme from '../theme';
import GeoText from './GeoText';
......@@ -37,12 +38,14 @@ const SavedMessage: React.FC<Props> = ({
const { navigate } = useNavigation();
const onPress = useCallback(() => navigate('CacheDetail', { id, title: `${name}'s Cache` } as NavParams), [navigate, id]);
return (
<TouchableWithoutFeedback style={styles.container} onPress={onPress}>
<Text>
<GeoText variant={'textBold'} text={`${name} `} />
<GeoText variant={'text'} text={`${message} `} />
<GeoText variant={'textWeak'} text={moment(found).fromNow()} />
</Text>
<TouchableWithoutFeedback onPress={onPress}>
<View style={styles.container}>
<Text>
<GeoText variant={'textBold'} text={`${name} `} />
<GeoText variant={'text'} text={`${message} `} />
<GeoText variant={'textWeak'} text={moment(found).fromNow()} />
</Text>
</View>
</TouchableWithoutFeedback>
);
};
......
......@@ -6,7 +6,7 @@ import { Icon } from 'react-native-elements';
import theme from '../theme';
import GeoText from './GeoText';
export const FLAIR_TYPES = [
export const TAG_TYPES = [
'artsy',
'basic',
'creative',
......@@ -21,10 +21,10 @@ export const FLAIR_TYPES = [
'love',
'mdg',
] as const;
type Flair = typeof FLAIR_TYPES[number];
type Tag = typeof TAG_TYPES[number];
type ColorMap = {
[key in Flair]: string;
[key in Tag]: string;
}
const COLOR_MAP: ColorMap = {
artsy: '#91F9E5',
......@@ -43,7 +43,7 @@ const COLOR_MAP: ColorMap = {
} as const;
const styles = StyleSheet.create({
flair: {
tag: {
flexDirection: 'row',
alignItems: 'center',
alignSelf: 'flex-start', // hack (?) to prevent full-width
......@@ -57,7 +57,7 @@ const styles = StyleSheet.create({
height: 40,
borderRadius: 40,
},
addFlairButton: {
addTagButton: {
backgroundColor: theme.colors.white,
borderColor: theme.colors.mediumgray,
borderWidth: 2,
......@@ -65,35 +65,35 @@ const styles = StyleSheet.create({
},
});
interface AddFlairButtonProps {
interface AddTagButtonProps {
onAdd: () => void;
style?: ViewStyle;
}
export const AddFlairButton: React.FC<AddFlairButtonProps> = ({ onAdd, style }) => (
export const AddTagButton: React.FC<AddTagButtonProps> = ({ onAdd, style }) => (
<TouchableOpacity onPress={onAdd} style={style}>
<View style={[styles.flair, styles.addFlairButton, styles.small]}>
<GeoText text={'Add flair'} color={'mediumgray'} style={{ fontWeight: '400' }} />
<View style={[styles.tag, styles.addTagButton, styles.small]}>
<GeoText text={'Add tag'} color={'mediumgray'} style={{ fontWeight: '400' }} />
</View>
</TouchableOpacity>
);
interface Props {
flair: Flair;
tag: Tag;
onRemove?: () => void;
size?: 'small' | 'large';
style?: ViewStyle;
}
const Flair: React.FC<Props> = ({
flair,
const Tag: React.FC<Props> = ({
tag,
onRemove,
size = 'small',
style,
}) => (
<View style={[style, styles.flair, styles[size], { backgroundColor: COLOR_MAP[flair] }]}>
<View style={[style, styles.tag, styles[size], { backgroundColor: COLOR_MAP[tag] }]}>
<Text style={{ color: 'white', fontWeight: '400', fontSize: size === 'small' ? 16 : 24 }}>
{flair}
{tag}
</Text>
{ onRemove && (
<Icon
......@@ -108,4 +108,4 @@ const Flair: React.FC<Props> = ({
</View>
);
export default Flair;
export default Tag;
......@@ -4,17 +4,20 @@ import { Icon } from 'react-native-elements';
import theme from '../theme';
interface Props {
location: LatLng;
location?: LatLng;
}
const UserLocationMarker: React.FC<Props> = ({ location }) => (
<Marker coordinate={location}>
<Icon
color={theme.colors.darkgray}
name={'male'}
type={'font-awesome-5'}
size={48}
/>
</Marker>
);
const UserLocationMarker: React.FC<Props> = ({ location }) => {
if (!location) return null; // Prevent warning before location is available
return (
<Marker coordinate={location}>
<Icon
color={theme.colors.darkgray}
name={'male'}
type={'font-awesome-5'}
size={48}
/>
</Marker>
);
};
export default UserLocationMarker;
......@@ -5,14 +5,14 @@ import CameraModal from '../screens/create/CameraModal';
import SettingsScreen from '../screens/SettingsScreen';
import DevScreen from '../screens/DevScreen';
import HomeNavigator from './HomeNavigator';
import FlairScreen from '../screens/FlairScreen';
import TagScreen from '../screens/TagScreen';
const Stack = createStackNavigator();
const AppNavigator = () => (
<Stack.Navigator
mode={'modal'}
screenOptions={({ route, navigation }) => ({
headerShown: ['Settings', 'FlairScreen'].includes(route.name),
headerShown: ['Settings', 'TagScreen'].includes(route.name),
headerLeft: () => (
<BackButton
isX
......@@ -40,9 +40,9 @@ const AppNavigator = () => (
component={CameraModal}
/>
<Stack.Screen
name={'FlairScreen'}
component={FlairScreen}
options={{ title: 'Flair' }}
name={'TagScreen'}
component={TagScreen}
options={{ title: 'Tag' }}
/>
<Stack.Screen
name={'DevScreen'}
......
......@@ -8,7 +8,7 @@ import { makeGetSavedCache } from '../store/caches/CachesSelectors';
import customMapStyle from '../CustomMapStyle.json';
import theme from '../theme';
import GeoText from '../components/GeoText';
import Flair from '../components/Flair';
import Tag from '../components/Tag';
import ProfileCard from '../components/ProfileCard';
import GeoMarker from '../components/GeoMarker';
......@@ -48,7 +48,7 @@ const CacheDetailScreen = () => {
<View style={{ flex: 1, justifyContent: 'space-between' }}>
<ScrollView contentContainerStyle={styles.container}>
<ProfileCard initials={cache.name[0]} name={cache.name} style={{ marginTop: theme.spacing.medium }} />
<Flair flair={'epic'} style={{ marginTop: theme.spacing.large }} />
<Tag tag={'epic'} style={{ marginTop: theme.spacing.large }} />
<GeoText text={cache.message} style={{ marginTop: theme.spacing.small }} />
</ScrollView>
<View style={styles.mapContainer}>
......@@ -56,6 +56,9 @@ const CacheDetailScreen = () => {
provider={'google'}
style={styles.map}
customMapStyle={customMapStyle}
showsBuildings={false}
showsIndoors={false}
showsPointsOfInterest={false}
initialCamera={{
center: cacheLocation,
heading: 0,
......@@ -63,7 +66,6 @@ const CacheDetailScreen = () => {
zoom: 18,
altitude: 0, // not used for Google Maps
}}
showsPointsOfInterest={false}
loadingEnabled // TODO: test
pitchEnabled={false}
zoomEnabled={false}
......
import React, { useCallback, useMemo } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { StyleSheet, View } from 'react-native';
import { StyleSheet, View, SectionListData } from 'react-native';
import theme from '../theme';
import SavedMessage from '../components/SavedMessage';
import ScreenHeader from '../components/ScreenHeader';
......@@ -75,15 +75,28 @@ const SavedMessagesScreen: React.FC = () => {
[],
);
const renderSavedMessage = useCallback(({
id, found, name, message, isUserCreated,
}: Cache) => <SavedMessage id={id} found={found} name={isUserCreated ? 'me' : name} message={message} />, []);
const renderSavedMessage = ({
id,
found,
name,
message,
isUserCreated,
}: Cache) => (
<SavedMessage
id={id}
found={found}
name={isUserCreated ? 'me' : name}
message={message}
/>
);
const renderSectionHeader = useCallback((section) => <SectionHeader title={section.title} />, []);
const renderSectionHeader = (section: SectionListData<Cache>) => (
<SectionHeader title={section.title} />
);
return (
<>
<ScreenHeader title={'Saved Caches'} />
<ScreenHeader title={'Saved'} />
<SwipeableList
keyExtractor={(cache) => cache.id}
sections={listSections}
......
......@@ -9,7 +9,6 @@ import GeoButton from '../components/GeoButton';
import {
getUserName,
getUserId,
getUserImageUrl,
} from '../store/auth/AuthSelectors';
......@@ -25,7 +24,6 @@ const SettingsScreen = () => {
const onDevPress = useCallback(() => navigate('DevScreen'), [navigate]);
const userName: string = useSelector(getUserName);
const userId: string = useSelector(getUserId);
const userImageUrl: string = useSelector(getUserImageUrl);
return (
......@@ -33,7 +31,7 @@ const SettingsScreen = () => {
<View style={{ alignItems: 'center' }}>
<Avatar
rounded
title={'MD'}
source={{ uri: userImageUrl }}
containerStyle={styles.avatar}
size={'xlarge'}
/>
......
......@@ -4,13 +4,13 @@ import { useNavigation } from '@react-navigation/native';
import { TouchableWithoutFeedback } from 'react-native-gesture-handler';
import { useDispatch } from 'react-redux';
import theme from '../theme';
import Flair, { FLAIR_TYPES } from '../components/Flair';
import Tag, { TAG_TYPES } from '../components/Tag';
import GeoButton from '../components/GeoButton';
import { setPendingCacheFlair } from '../store/pendingNewCache/PendingCacheSlice';
import { setPendingCacheTag } from '../store/pendingNewCache/PendingCacheSlice';
import ScreenContainer from './create/ScreenContainer';
const styles = StyleSheet.create({
flairsContainer: {
tagsContainer: {
flex: 1,
justifyContent: 'center',
},
......@@ -21,42 +21,42 @@ const styles = StyleSheet.create({
},
});
const FlairScreen = () => {
const TagScreen = () => {
const navigation = useNavigation();
const dispatch = useDispatch();
const [flair, setFlair] = useState<Flair | undefined>();
const [tag, setTag] = useState<Tag | undefined>();
const onSubmit = useCallback(() => {
dispatch(setPendingCacheFlair(flair));
dispatch(setPendingCacheTag(tag));
navigation.goBack();
}, [navigation, flair]);
}, [navigation, tag]);
const rows = useMemo(() => {
const result = [];
const flairs = FLAIR_TYPES.slice();
while (flairs.length > 0) {
const tags = TAG_TYPES.slice();
while (tags.length > 0) {
const count: number = (result.length % 2 === 0) ? 3 : 2;
result.push(flairs.splice(0, count));
result.push(tags.splice(0, count));
}
return result;
}, [FLAIR_TYPES]);
}, [TAG_TYPES]);
return (
<ScreenContainer>
<View style={styles.flairsContainer}>
<View style={styles.tagsContainer}>
{rows.map((row) => (
<View key={row[0]} style={styles.row}>
{row.map((f) => (
<TouchableWithoutFeedback
key={f}
onPress={() => setFlair(f)}
onPress={() => setTag(f)}
style={{ marginHorizontal: theme.spacing.small }}
>
<Flair
flair={f}
<Tag
tag={f}
size={'large'}
style={{
borderColor: f === flair ? theme.colors.black : 'transparent',
borderColor: f === tag ? theme.colors.black : 'transparent',
borderWidth: 2,
borderStyle: 'solid',
}}
......@@ -70,7 +70,7 @@ const FlairScreen = () => {
<GeoButton
title={'Choose'}
onPress={onSubmit}
disabled={!flair}
disabled={!tag}
style={{ marginVertical: theme.spacing.medium }}
/>
</View>
......@@ -78,4 +78,4 @@ const FlairScreen = () => {
);
};
export default FlairScreen;
export default TagScreen;
......@@ -10,6 +10,7 @@ import theme from '../../theme';
import { DURATION_OPTIONS, setPendingCacheDuration } from '../../store/pendingNewCache/PendingCacheSlice';
import { getPendingCacheDuration } from '../../store/pendingNewCache/PendingCacheSelectors';
import GeoButton from '../../components/GeoButton';
import GeoText from '../../components/GeoText';
const { spacing } = theme;
......@@ -32,6 +33,10 @@ const CacheDurationScreen = () => {
return (
<View style={styles.container}>
<GeoText
style={{ fontSize: 20, fontWeight: '400' }}
text={'How long will your geocache be discoverable?'}
/>
<Picker
selectedValue={duration}
onValueChange={(value) => setDuration(value)}
......
......@@ -12,13 +12,14 @@ import { ScrollView } from 'react-native-gesture-handler';
import { ImageInfo } from 'expo-image-picker/build/ImagePicker.types';
import theme from '../../theme';
import GeoText from '../../components/GeoText';
import { setPendingCacheContent, setPendingCacheImage, setPendingCacheFlair } from '../../store/pendingNewCache/PendingCacheSlice';
import { setPendingCacheContent, setPendingCacheImage, setPendingCacheTag } from '../../store/pendingNewCache/PendingCacheSlice';
import GeoButton from '../../components/GeoButton';
import ScreenContainer from './ScreenContainer';
import IconButton from '../../components/IconButton';
import { getPendingCacheImage, getPendingCacheFlair } from '../../store/pendingNewCache/PendingCacheSelectors';
import Flair, { AddFlairButton } from '../../components/Flair';
import { getPendingCacheImage, getPendingCacheTag } from '../../store/pendingNewCache/PendingCacheSelectors';
import Tag, { AddTagButton } from '../../components/Tag';
import ProfileCard from '../../components/ProfileCard';
import { getUserName } from '../../store/auth/AuthSelectors';
const CHAR_MAX = 100;
......@@ -53,6 +54,7 @@ const CacheMessageScreen: React.FC = () => {
const dispatch = useDispatch();
const [text, setText] = useState('');
const image = useSelector(getPendingCacheImage);
const displayName = useSelector(getUserName);
const setImage = useCallback((img: ImageInfo) => {
dispatch(setPendingCacheImage(img));
}, [dispatch]);
......@@ -92,9 +94,9 @@ const CacheMessageScreen: React.FC = () => {
navigate('CacheDuration');
}, [dispatch, navigate, text]);
const flair = useSelector(getPendingCacheFlair);
const onAddFlair = useCallback(() => navigate('FlairScreen'), [navigate]);
const onRemoveFlair = useCallback(() => dispatch(setPendingCacheFlair(undefined)), [dispatch]);
const tag = useSelector(getPendingCacheTag);
const onAddTag = useCallback(() => navigate('TagScreen'), [navigate]);
const onRemoveTag = useCallback(() => dispatch(setPendingCacheTag(undefined)), [dispatch]);
return (
<ScreenContainer>
......@@ -104,12 +106,12 @@ const CacheMessageScreen: React.FC = () => {
showsVerticalScrollIndicator={false}
onLayout={onScrollViewLayout}
>
<ProfileCard initials={'MD'} name={'milan.digiuseppe'} style={{ marginTop: theme.spacing.medium }} />
<ProfileCard initials={'MD'} name={displayName} style={{ marginTop: theme.spacing.medium }} />
<View style={{ marginTop: theme.spacing.medium }}>
{flair ? (
<Flair flair={flair} onRemove={onRemoveFlair} />
{tag ? (
<Tag tag={tag} onRemove={onRemoveTag} />
) : (
<AddFlairButton onAdd={onAddFlair} />
<AddTagButton onAdd={onAddTag} />
)}
</View>
<TextInput
......
......@@ -3,4 +3,4 @@ import { RootState } from '../RootReducer';
export const getPendingCacheContent = (state: RootState) => state.pendingCache.content;
export const getPendingCacheDuration = (state: RootState) => state.pendingCache.duration;
export const getPendingCacheImage = (state: RootState) => state.pendingCache.image;
export const getPendingCacheFlair = (state: RootState) => state.pendingCache.flair;
export const getPendingCacheTag = (state: RootState) => state.pendingCache.tag;
import { createSlice } from '@reduxjs/toolkit';
import Flair from '../../components/Flair';
import Tag from '../../components/Tag';
export const DURATION_OPTIONS = [1, 4, 12, 24] as const;
type DurationOption = typeof DURATION_OPTIONS[number]
......@@ -14,7 +14,7 @@ export interface PendingNewCacheState {
content: string;
duration: DurationOption;
image?: ImageInfo;
flair?: Flair;
tag?: Tag;
}
const pendingCacheSlice = createSlice({
......@@ -33,8 +33,8 @@ const pendingCacheSlice = createSlice({
setImage(state, action) {
state.image = action.payload;
},
setFlair(state, action) {
state.flair = action.payload;
setTag(state, action) {
state.tag = action.payload;
},
},
});
......@@ -44,5 +44,5 @@ export const {
setContent: setPendingCacheContent,
setDuration: setPendingCacheDuration,
setImage: setPendingCacheImage,
setFlair: setPendingCacheFlair,
setTag: setPendingCacheTag,
} = pendingCacheSlice.actions;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment