Initial commit.

This commit is contained in:
Ryan McGrath 2018-04-05 15:17:53 -04:00
commit 1f90ca2575
No known key found for this signature in database
GPG key ID: 811674B62B666830
63 changed files with 4059 additions and 0 deletions

View file

@ -0,0 +1,24 @@
/**
* BookmarksViewController
*
* Yeah, I do it iOS style. Handles bookmarked tournaments.
*
* @copyright Ryan McGrath 2018.
*/
import moment from 'moment';
import React from 'react';
import {FlatList, Image, Text, View, TouchableOpacity} from 'react-native';
import MemeleeViewController from './MemeleeViewController';
export default class BookmarksViewController extends MemeleeViewController {
state = {data: []};
keyExtractor = (item, index) => item.id;
render() {
return <FlatList data={this.state.data} keyExtractor={this.keyExtractor} renderItem={({item}) => {
return <View />;
}} />
}
}

View file

@ -0,0 +1,61 @@
/**
* BracketViewController
*
* Yeah, I do it iOS style. Handles displaying tournament bracket data.
*
* @copyright Ryan McGrath 2018.
*/
import moment from 'moment';
import React from 'react';
import {ScrollView, Text, View} from 'react-native';
import {v4} from 'uuid';
//import SmashGG from '../store';
import MemeleeViewController from './MemeleeViewController';
const Match = ({set, ...rest}) => (
<View style={{backgroundColor: '#3b3b48', borderColor: '#0e0e12', borderWidth: 0.5, borderRadius: 4, marginBottom: 20}}>
<Text style={{padding: 5, color: '#dbdbde'}}>{set.entrant1.name ? set.entrant1.name : ''} <Text>{set.entrant1Score}</Text></Text>
<View style={{borderTopWidth: 0.5, borderTopColor: '#2a2a33'}} />
<Text style={{padding: 5, color: '#dbdbde'}}>{set.entrant2.name ? set.entrant2.name : ''} <Text>{set.entrant2Score}</Text></Text>
</View>
);
export default class BracketViewController extends MemeleeViewController {
state = {
brackets: {
winners: [],
losers: [],
grandFinals: []
}
};
componentWillMount() {
const evtSlugs = this.props.evt.slug.split('/');
const evtSlug = evtSlugs.length > 0 ? evtSlugs[evtSlugs.length - 1] : null;
const tournamentSlug = this.props.tournament.slugs[0].replace('tournament/', '');
SmashGG.fetchBracketData(tournamentSlug, evtSlug, this.props.bracket.id).then(this.updateBracketsData).catch(console.error);
}
updateBracketsData = (brackets) => {
this.setState({brackets: brackets});
}
render() {
return (<ScrollView style={{flex: 1, backgroundColor: '#21212d'}} contentContainerStyle={{width: 10001}}>
{['winners', 'losers'].map(key => (
<View key={key} style={{backgroundColor: '#21212d', flexDirection: 'row', paddingTop: 20, paddingBottom: 20, paddingLeft: 20}}>
{this.state.brackets[key].map(bracket => (
<View key={bracket.key} style={{backgroundColor: '#21212d', marginRight: 20, width: 200, flexDirection: 'column'}}>
<Text>{bracket.title}</Text>
{bracket.sets.map(set => <Match key={set.id} set={set} />)}
</View>
))}
</View>
))}
</ScrollView>);
}
}

View file

@ -0,0 +1,81 @@
/**
* EventInfoViewController
*
* Yeah, I do it iOS style. Handles displaying tournament event data.
*
* @copyright Ryan McGrath 2018.
*/
import moment from 'moment';
import React from 'react';
import {ScrollView, Image, Text, View, TouchableOpacity} from 'react-native';
import Markdown from 'react-native-simple-markdown'
//import SmashGG from '../store';
import MemeleeViewController from './MemeleeViewController';
export default class EventInfoViewController extends MemeleeViewController {
state = {
standings: [],
brackets: []
};
componentWillMount() {
const evtSlugs = this.props.evt.slug.split('/');
const evtSlug = evtSlugs.length > 0 ? evtSlugs[evtSlugs.length - 1] : null;
const tournamentSlug = this.props.tournament.slugs[0].replace('tournament/', '');
if((evtSlug && evtSlug !== '') && (tournamentSlug && tournamentSlug != '')) {
SmashGG.fetchEventExpanded(tournamentSlug, evtSlug).then(this.updateBracketsData).catch(console.error);
SmashGG.fetchEventStandings(tournamentSlug, evtSlug).then(this.updateStandingsData).catch(console.error);
}
}
updateBracketsData = (data) => {
this.setState({brackets: data});
}
updateStandingsData = (data) => {
this.setState({standings: data});
}
onBracketPress = (bracket) => {
this.props.navigator.push({
screen: 'memelee.bracket',
title: bracket.name,
backButtonTitle: 'Back',
passProps: {
tournament: this.props.tournament,
evt: this.props.evt,
bracket: bracket
},
navigatorStyle: {tabBarHidden: true}
});
}
render() {
return (<ScrollView>
<Text style={{padding: 8, backgroundColor: '#003366', fontSize: 16}}>Brackets</Text>
{this.state.brackets.map(bracket => (
<TouchableOpacity key={bracket.id} onPress={() => this.onBracketPress(bracket)}>
<Text style={{padding: 8, backgroundColor: 'gray'}}>{bracket.name}</Text>
</TouchableOpacity>
))}
<Text style={{padding: 8, marginTop: 20, backgroundColor: '#003366', fontSize: 16}}>Standings</Text>
<View style={{flexDirection: 'row', backgroundColor: '#010101'}}>
<Text style={{backgroundColor: '#010101', color: '#f9f9f9', padding: 8, paddingLeft: 58, width: 230}}>Players</Text>
<Text style={{backgroundColor: '#010101', color: '#f9f9f9', padding: 8}}>Losses</Text>
</View>
{this.state.standings.map(standing => (
<View key={standing.id} style={{flexDirection: 'row', borderBottomWidth: 1, borderBottomColor: 'gray'}}>
<Text key={standing.id} style={{padding: 8, width: 50, textAlign: 'center', backgroundColor: 'gray'}}>
{standing.finalPlacement}
</Text>
<Text style={{padding: 8, width: 180}}>{standing.name}</Text>
<View style={{padding: 8, flex: 1}}>{standing.losses.map(loss => <Text key={standing.id + loss} style={{flexShrink: 1}}>{loss}</Text>)}</View>
</View>
))}
</ScrollView>);
}
}

View file

@ -0,0 +1,15 @@
/**
* MemeleeViewController.js
*
* Yes yes iOS style etc etc. Handles ensuring that all view controllers have default styling
* and such applied.
*
* @copyright Ryan McGrath 2018.
*/
import React from 'react';
import styles from '../styles';
export default class MemeleeController extends React.Component {
static navigatorStyle = styles.navigatorStyles;
};

View file

@ -0,0 +1,73 @@
/**
* TournamentInfoViewController
*
* Yeah, I do it iOS style. Handles fetching and displaying tournament data.
*
* @copyright Ryan McGrath 2018.
*/
import moment from 'moment';
import React from 'react';
import {ScrollView, StyleSheet, Image, Text, View, TouchableOpacity, Dimensions} from 'react-native';
//import Markdown from 'react-native-simple-markdown'
import Markdown from 'react-native-markdown-renderer';
import SegmentedControlTab from 'react-native-segmented-control-tab';
import SettingsList, {Header, Item} from 'react-native-settings-list';
import styles from '../styles';
import MemeleeViewController from './MemeleeViewController';
const w = Dimensions.get('screen').width;
/* <View style={styles.tournamentInfoButtonsRow}>
<TouchableOpacity style={styles.tournamentRegistrationButton} onPress={this.registerForTournament}>
<Text style={styles.tournamentRegistrationButtonText}>Register</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.tournamentBookmarkButton} onPress={this.registerForTournament}>
<Text style={styles.tournamentRegistrationButtonText}>Bookmark</Text>
</TouchableOpacity>
</View>
*/
export default class TournamentInfoViewController extends MemeleeViewController {
state = {
selectedIndex: 0
};
onEventTapped = (evt) => {
this.props.navigator.push({
screen: 'memelee.tournamentEventInfoScreen',
title: evt.name,
passProps: {tournament: this.props.tournament, evt: evt},
navigatorStyle: {tabBarHidden: true}
});
}
swapIndex = (index) => {
this.setState({
selectedIndex: index
});
}
render() {
const s = StyleSheet.flatten(styles.tournamentDetailsEventWrapper);
return (<ScrollView>
<Image style={[styles.tournamentInfoHeader, {width: w}]} source={this.props.tournament.memeleePromoImage.msrc} />
<SegmentedControlTab values={['Overview', 'Events']} borderRadius={0} activeTabStyle={styles.tournamentInfoActiveTableStyle} tabStyle={styles.tournamentInfoTabsStyle} tabTextStyle={styles.tournamentInfoTabTextStyle} selectedIndex={this.state.selectedIndex} onTabPress={this.swapIndex} />
{this.state.selectedIndex === 0 ? (<View style={styles.tournamentDetailsTextWrapper}>
<Markdown style={styles.tournamentDetailsText}>
{this.props.tournament.details && this.props.tournament.details !== '' ? this.props.tournament.details : ''}
</Markdown>
</View>) : null}
{this.state.selectedIndex === 1 ? (<SettingsList style={styles.tournamentEventsWrapper} borderWidth={s.borderBottomWidth} borderColor={s.borderBottomColor}>
{this.props.tournament.memeleeEvents.map(evt => (
<Item key={evt.id} itemWidth={50} title={evt.name} backgroundColor={s.backgroundColor} style={styles.tournamentDetailsEventWrapper} titleStyle={styles.tournamentDetailsEventItem} />
))}
</SettingsList>) : null}
</ScrollView>);
}
}

View file

@ -0,0 +1,63 @@
/**
* UpcomingTournamentsViewController
*
* Yeah, I do it iOS style. Handles fetching and displaying upcoming tournaments.
*
* @copyright Ryan McGrath 2018.
*/
import moment from 'moment';
import React from 'react';
import {FlatList, View, ActivityIndicator} from 'react-native';
import {inject, observer} from 'mobx-react/native';
import {SearchBar} from 'react-native-elements';
import styles from '../styles';
import MemeleeViewController from './MemeleeViewController';
import TournamentRow from './components/TournamentRow';
const keyExtractor = (item, index) => item.id;
@inject('Tournaments') @observer
export default class UpcomingTournamentsViewController extends MemeleeViewController {
componentWillMount() {
this.props.Tournaments.fetchFeatured();
}
onTap = (tournament) => {
this.props.navigator.push({
screen: 'memelee.tournamentInfoScreen',
title: tournament.name,
passProps: {tournament: tournament},
navigatorStyle: {tabBarHidden: true}
});
}
renderHeader = () => (
<SearchBar lightTheme round placeholder={""} onChangeText={this.props.Tournaments.search} containerStyle={styles.searchContainerStyle} />
)
renderFooter = () => (
this.props.Tournaments.fetchingData ? (<View style={{paddingTop: 200}}>
<ActivityIndicator animating size="large" />
</View>) : null
)
renderItem = ({item}) => (<TournamentRow tournament={item} onTap={this.onTap} />)
render() {
const props = {
data: this.props.Tournaments.fetchingData ? [] :
this.props.Tournaments.mode === 'search' ? this.props.Tournaments.searchResults :
this.props.Tournaments.tournamentsList,
keyExtractor: keyExtractor,
contentContainerStyle: styles.tournamentsListView,
ListHeaderComponent: this.renderHeader,
ListFooterComponent: this.renderFooter,
renderItem: this.renderItem
};
return <FlatList {...props} renderItem={this.renderItem} />
}
}

View file

@ -0,0 +1,51 @@
/**
* TournamentRow.js
*
* That row that displays tournament info.
*
* @copyright Ryan McGrath 2018.
*/
import React from 'react';
import {Image, Text, View, TouchableOpacity, Dimensions} from 'react-native';
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import styles from '../../styles';
const width = Dimensions.get('window').width;
export default class TournamentRow extends React.Component {
onPress = () => {
this.props.onTap(this.props.tournament);
}
render() {
const x = width - 32;
const w = {width: x, height: 130}; //x * this.props.tournament.memeleePromoImage.ratio};
return (<View style={styles.tournamentRowWrapper}>
<TouchableOpacity onPress={this.onPress} style={styles.tournamentRow}>
<Image style={[styles.tournamentRowPromoImage, w]} source={this.props.tournament.memeleePromoImage.msrc} />
<View style={styles.tournamentRowTextWrapper}>
<Text style={styles.tournamentRowName}>{this.props.tournament.name}</Text>
<Text style={styles.tournamentRowDateRange}>
<Icon name="calendar-text" size={16} color={styles.tournamentPromoIconColors.calendar} /> {this.props.tournament.memeleeTournamentRange}
</Text>
<Text style={styles.tournamentRowLocation}>
<Icon name="map-marker" size={16} color={styles.tournamentPromoIconColors.mapMarker} /> {this.props.tournament.hasOnlineEvents && (!this.props.tournament.city || this.props.tournament.city === '') ? 'Online' : (this.props.tournament.city ? this.props.tournament.city + ', ' : '') + this.props.tournament.addrState}</Text>
<View style={{flexDirection: 'row'}}>
<Text style={styles.tournamentRowEventsCount}>
<Icon name="trophy-variant" size={16} color={styles.tournamentPromoIconColors.eventsCount} />
{this.props.tournament.memeleeEventsCount} Events
</Text>
<Text style={[styles.tournamentRowEventsCount, {marginLeft: 10}]}>
<Icon name="human-greeting" size={16} color={styles.tournamentPromoIconColors.attendeesCount} /> {this.props.tournament.attendeeCount} Attendees
</Text>
</View>
</View>
</TouchableOpacity>
</View>);
}
}

View file

@ -0,0 +1,27 @@
/**
* SettingsViewController
*
* Yeah, I do it iOS style. Handles settings.
*
* @copyright Ryan McGrath 2018.
*/
import React from 'react';
import {ScrollView} from 'react-native';
import SettingsList, {Header, Item} from 'react-native-settings-list';
import styles from '../../styles';
import MemeleeViewController from '../MemeleeViewController';
export default class SettingsViewController extends MemeleeViewController {
pressed = () => {}
render() {
return (<ScrollView>
<SettingsList>
<Header headerText='First Grouping' headerStyle={{color:'white'}}/>
<Item itemWidth={50} title='Icon Example' onPress={this.pressed} />
</SettingsList>
</ScrollView>);
}
}