Skip to content

Commit

Permalink
Merge branch 'react-europe-search-attendees' into react-europe
Browse files Browse the repository at this point in the history
* react-europe-search-attendees: (69 commits)
  fixing list behind search
  Added highlight words core
  removing stuff
  remove log
  fixing
  placeholder
  fix conflict
  remove Foundation import
  distinguish speakers from normal attendees and remove console logs
  Updated sorting logic
  Updated text input component
  fixing email and twitter
  fixing color
  Supplied query for highlighting to search results
  Attended special version of highlightable text component
  getting rid of animatedview thing
  Fix searchbar position on non-dank phones
  Searchbar
  Searchbar
  Fixed twitter util errors
  ...

Conflicts:
	src/Navigation.js
	src/screens/Details.js
	src/screens/index.js
  • Loading branch information
Horacio Herrera committed May 19, 2018
2 parents 3b99243 + fe601a5 commit 948e0a5
Show file tree
Hide file tree
Showing 16 changed files with 1,542 additions and 536 deletions.
21 changes: 19 additions & 2 deletions App.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
import React from "react";
import { ApolloClient } from 'apollo-client';
import { ApolloProvider } from 'react-apollo';
import { HttpLink } from 'apollo-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { Asset, AppLoading, Font, Updates } from "expo";
import { Platform } from "react-native";
import { Ionicons } from "@expo/vector-icons";
import { GQL } from './src/constants'
import { loadSavedTalksAsync } from "./src/utils/storage";
import { SafeAreaView } from "react-navigation";

if (Platform.OS === "android") {
SafeAreaView.setStatusBarHeight(0);
}

const client = new ApolloClient({
// By default, this client will send queries to the
// `/graphql` endpoint on the same host
// Pass the configuration option { uri: YOUR_GRAPHQL_API_URL } to the `HttpLink` to connect
// to a different host
link: new HttpLink({ uri: GQL.uri }),
cache: new InMemoryCache(),
});

import Navigation from "./src/Navigation";

export default class App extends React.Component {
Expand Down Expand Up @@ -83,7 +97,10 @@ export default class App extends React.Component {
/>
);
}

return <Navigation />;
return (
<ApolloProvider client={client}>
<Navigation />
</ApolloProvider>
);
}
}
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,23 @@
"lint": "eslint . --ext .js --quiet"
},
"dependencies": {
"apollo-client": "^2.3.1",
"apollo-client-preset": "^1.0.8",
"crypto-js": "^3.1.9-1",
"expo": "^27.0.0",
"fbemitter": "^2.1.1",
"global": "^4.3.2",
"graphql": "^0.13.2",
"graphql-tag": "^2.9.2",
"highlight-words-core": "^1.2.0",
"hoist-non-react-statics": "^2.3.1",
"lodash": "^4.17.4",
"moment": "2.21.0",
"moment-timezone": "^0.5.14",
"path": "^0.12.7",
"prettier": "^1.11.1",
"react": "16.3.1",
"react-apollo": "^2.1.4",
"react-native": "https://github.com/expo/react-native/archive/sdk-27.0.0.tar.gz",
"react-native-animatable": "^1.2.4",
"react-native-fade-in-image": "1.3.0",
Expand Down
8 changes: 7 additions & 1 deletion src/Navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ const MenuNavigation = StackNavigator(
Menu: { screen: Screens.Menu },
Speakers: { screen: Screens.Speakers },
Crew: { screen: Screens.Crew },
Sponsors: { screen: Screens.Sponsors }
Sponsors: { screen: Screens.Sponsors },
Attendees: { screen: Screens.Attendees },
AttendeeDetail: { screen: Screens.AttendeeDetail }
},
{
...DefaultStackConfig,
Expand Down Expand Up @@ -165,6 +167,10 @@ const PrimaryTabNavigator = TabNavigator(
export default StackNavigator(
{
Primary: { screen: PrimaryTabNavigator },
AttendeeDetail: { screen: Screens.AttendeeDetail },
TicketInstructions: { screen: Screens.TicketInstructions },

CheckedInAttendeeInfo: { screen: Screens.CheckedInAttendeeInfo },
QRScanner: { screen: QRScannerModalNavigation },
QRCheckinScanner: { screen: QRCheckinScannerModalNavigation },
QRContactScanner: { screen: QRContactScannerModalNavigation },
Expand Down
188 changes: 188 additions & 0 deletions src/components/AttendeesSearchResults.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
import React from 'react';
import { StyleSheet, View, FlatList } from 'react-native';
import { ScrollView, RectButton } from 'react-native-gesture-handler';
import { Entypo, MaterialIcons, MaterialCommunityIcons } from '@expo/vector-icons';
import _ from 'lodash';

import { Colors } from '../constants'
import { BoldText, SemiBoldText, RegularText } from './StyledText';
import GravatarImage from './GravatarImage';
import HighlightableText from './HighlightableText';

import { getContactTwitter } from '../utils';

export const Schedule = require('../data/schedule.json');

const SpeakersAndTalks = Schedule.events[0].speakers;
const SpeakersData = [{ data: SpeakersAndTalks, title: 'Speakers' }];

class AttendeesSearchResultRow extends React.Component {
render() {
const { attendee, searchQuery } = this.props;

let isSpeaker;
if (SpeakersData && SpeakersData.length) {
isSpeaker = SpeakersData[0].data.filter(speaker => {
return getContactTwitter(attendee) === speaker.twitter
})[0] ? true : false
}

return (
<RectButton
onPress={() => this.props.onPress(attendee)}
activeOpacity={0.05}
style={{ flex: 1, backgroundColor: '#fff' }}
>
<View style={[styles.row, { borderLeftWidth: isSpeaker ? 5 : 0 }]}>
{isSpeaker && <View style={styles.micIcon}><MaterialCommunityIcons
name="presentation"
size={32}
color="#aab8c2"
/></View>}
<View style={[styles.rowAvatarContainer, { paddingLeft: isSpeaker ? 0 : 5 }]}>
<GravatarImage style={styles.avatarImage} email={attendee.email} />
</View>
<View style={styles.rowData}>
<HighlightableText
TextComponent={BoldText}
highlightStyle={{ backgroundColor: '#e1e8ed' }}
searchWords={[searchQuery]}
textToHighlight={`${attendee.firstName} ${attendee.lastName}`}
/>
{attendee.email ? (
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<MaterialIcons
name={'email'}
size={16}
color="#aab8c2"
style={{ paddingRight: 3 }}
/>
<HighlightableText
TextComponent={SemiBoldText}
highlightStyle={{ backgroundColor: '#e1e8ed' }}
searchWords={[searchQuery]}
textToHighlight={attendee.email}
/>
</View>
) : null}
{getContactTwitter(attendee) ? (
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<Entypo name={'twitter'} size={16} color="#1da1f2" style={{ paddingRight: 3 }} />
<HighlightableText
TextComponent={RegularText}
highlightStyle={{ backgroundColor: '#e1e8ed' }}
searchWords={[searchQuery]}
textToHighlight={`@${getContactTwitter(attendee)}`}
/>
</View>
) : null}
</View>
</View>
</RectButton>
);
}
}


const AttendeesSearchResultPlaceholderRow = () => (
<RectButton
activeOpacity={0.05}
style={{ flex: 1, backgroundColor: '#fff' }}
>
<View style={styles.row}>
<View style={styles.rowAvatarContainer}>
<MaterialIcons
name={'account-circle'}
size={48}
style={styles.placeholderAvatarImage}
/>
</View>
<View style={styles.rowData}>
<BoldText style={{ backgroundColor: '#efefef', height: 14, marginBottom: 8 }}>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</BoldText>
<View style={{ flexDirection: 'row', alignItems: 'center' }}>
<SemiBoldText style={{ color: '#efefef', height: 14, marginRight: 8 }}></SemiBoldText>
<SemiBoldText style={{ backgroundColor: '#efefef', height: 14 }}>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</SemiBoldText>
</View>
</View>
</View>
</RectButton>
);

export default class AttendeesSearchResults extends React.Component {
render() {
const { attendees, isLoading } = this.props;
const maybeAttendees = isLoading ?
_.times(10).map((id) => ({ id })) :
attendees;
const itemRenderer = isLoading ? this._renderItemPlaceholder : this._renderItem;
return (
<FlatList
renderScrollComponent={props => <ScrollView {...props} />}
renderItem={itemRenderer}
data={maybeAttendees}
keyExtractor={item => `${item.id}`}
initialNumToRender={10}
keyboardDismissMode="on-drag"
style={styles.list}
/>
);
}

_renderItem = ({ item: attendee }) => (
<AttendeesSearchResultRow
attendee={attendee}
onPress={this.props.onPress}
searchQuery={this.props.searchQuery}
/>
);

_renderItemPlaceholder = () => (
<AttendeesSearchResultPlaceholderRow />
);

_handlePressRow = attendee => {
this.props.navigation.navigate('AttendeeDetail', { attendee });
};
}

const styles = StyleSheet.create({
row: {
flex: 1,
padding: 10,
borderBottomWidth: StyleSheet.hairlineWidth,
borderBottomColor: '#eee',
borderLeftColor: Colors.blue,
flexDirection: 'row',
},
rowAvatarContainer: {
paddingVertical: 5,
paddingRight: 10,
paddingLeft: 5,
},
avatarImage: {
width: 50,
height: 50,
borderRadius: 25,
},
placeholderAvatarImage: {
width: 50,
height: 50,
borderRadius: 25,
color: '#efefef'
},
rowData: {
flex: 1,
},
list: {
paddingTop: 80,
},
micIcon: {
position: 'absolute',
right: 24,
alignItems: 'center',
flex: 1,
justifyContent: 'center',
height: '100%',
top: 10,
}
});
10 changes: 9 additions & 1 deletion src/components/CachedImage.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export default class CachedImage extends React.Component {
source: null,
};

unmounting: false

async componentDidMount() {
let source = this.props.source;

Expand All @@ -28,10 +30,16 @@ export default class CachedImage extends React.Component {
} catch (e) {
console.log(e);
} finally {
this.setState({ source });
if (!this.unmounting) {
this.setState({ source });
}
}
}

componentWillUnmount() {
this.unmounting = true
}

render() {
if (this.state.source) {
return <Image {...this.props} source={this.state.source} />;
Expand Down
Loading

0 comments on commit 948e0a5

Please sign in to comment.