8
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						@ -57,3 +57,11 @@ buck-out/
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# CocoaPods
 | 
					# CocoaPods
 | 
				
			||||||
/ios/Pods/
 | 
					/ios/Pods/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Rust
 | 
				
			||||||
 | 
					/target/
 | 
				
			||||||
 | 
					/cms/target/
 | 
				
			||||||
 | 
					/cms/cms_macro/target/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Environment
 | 
				
			||||||
 | 
					*.env
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2423
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										5
									
								
								Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					[workspace]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					members = [
 | 
				
			||||||
 | 
					    "cms",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
@ -4,6 +4,7 @@ import android.app.Application;
 | 
				
			|||||||
import android.content.Context;
 | 
					import android.content.Context;
 | 
				
			||||||
import com.facebook.react.PackageList;
 | 
					import com.facebook.react.PackageList;
 | 
				
			||||||
import com.facebook.react.ReactApplication;
 | 
					import com.facebook.react.ReactApplication;
 | 
				
			||||||
 | 
					import com.zoontek.rnlocalize.RNLocalizePackage;
 | 
				
			||||||
import com.reactnativecommunity.webview.RNCWebViewPackage;
 | 
					import com.reactnativecommunity.webview.RNCWebViewPackage;
 | 
				
			||||||
import com.reactnativecommunity.webview.RNCWebViewPackage;
 | 
					import com.reactnativecommunity.webview.RNCWebViewPackage;
 | 
				
			||||||
import com.oblador.vectoricons.VectorIconsPackage;
 | 
					import com.oblador.vectoricons.VectorIconsPackage;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,6 @@
 | 
				
			|||||||
rootProject.name = 'blazerapp'
 | 
					rootProject.name = 'blazerapp'
 | 
				
			||||||
 | 
					include ':react-native-localize'
 | 
				
			||||||
 | 
					project(':react-native-localize').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-localize/android')
 | 
				
			||||||
include ':react-native-webview'
 | 
					include ':react-native-webview'
 | 
				
			||||||
project(':react-native-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview/android')
 | 
					project(':react-native-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview/android')
 | 
				
			||||||
include ':react-native-webview'
 | 
					include ':react-native-webview'
 | 
				
			||||||
 | 
				
			|||||||
@ -22,49 +22,108 @@ import styles from './styles/liststyles'
 | 
				
			|||||||
import { url } from './resources/fetchInfo.json'
 | 
					import { url } from './resources/fetchInfo.json'
 | 
				
			||||||
import { SearchBar } from 'react-native-elements';
 | 
					import { SearchBar } from 'react-native-elements';
 | 
				
			||||||
import Icon from 'react-native-vector-icons/AntDesign'
 | 
					import Icon from 'react-native-vector-icons/AntDesign'
 | 
				
			||||||
import AsyncStorage from '@react-native-community/async-storage'
 | 
					import Ionicons from 'react-native-vector-icons/Ionicons';
 | 
				
			||||||
 | 
					import AsyncStorage from '@react-native-async-storage/async-storage'
 | 
				
			||||||
 | 
					import LinearGradient from 'react-native-linear-gradient';
 | 
				
			||||||
 | 
					import I18n from './i18n';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const STORAGE_KEY = "teacherAnnouncements"
 | 
					const STORAGE_KEY = "teacherAnnouncements"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Announcement = ({item}) => {
 | 
					const getCurrentDate=()=>{
 | 
				
			||||||
	const date = new Date
 | 
						var date = new Date().getDate();
 | 
				
			||||||
	const dateStr = `${date.getMonth()+1}/${date.getDate()}/${date.getFullYear()}`
 | 
						var month = new Date().getMonth();
 | 
				
			||||||
	const dateInfo = dateStr===item.item.date&&item.item.time!==undefined?item.item.time:item.item.date;
 | 
						var year = new Date().getFullYear();
 | 
				
			||||||
	return (
 | 
					 | 
				
			||||||
		<View style={styles.item1}>
 | 
					 | 
				
			||||||
			<View style = {{display: 'flex', flexDirection: 'row', justifyContent: 'space-between'}}>
 | 
					 | 
				
			||||||
				<View style = {{width: '75%'}}>
 | 
					 | 
				
			||||||
					<Text style={styles.title3}>{item.item.message}</Text>
 | 
					 | 
				
			||||||
				</View>
 | 
					 | 
				
			||||||
				<View style = {{display: 'flex', flexDirection: 'row'}}>
 | 
					 | 
				
			||||||
					{dateInfo!==undefined?<Text style={{fontSize: 16, alignSelf: 'center'}}>{dateInfo}</Text>:<></>}
 | 
					 | 
				
			||||||
				</View>
 | 
					 | 
				
			||||||
			</View>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return new Date(year, month, date);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Announcement = ({item}) => {
 | 
				
			||||||
 | 
						const todayDate = getCurrentDate()
 | 
				
			||||||
 | 
						const itemDate = new Date(item.item.date)
 | 
				
			||||||
 | 
						const dateInfo = todayDate.getTime()===itemDate.getTime()&&item.item.time!==undefined?item.item.time:(item.item.date+", " + item.item.time)
 | 
				
			||||||
 | 
						return (
 | 
				
			||||||
 | 
							<View style={{borderWidth: 1, borderColor: '#323232', padding: '2%', marginHorizontal: '2%', marginBottom: '2%', borderRadius: 12}}>
 | 
				
			||||||
 | 
								<View style = {{display: 'flex', flexDirection: 'column', justifyContent: 'space-between'}}>
 | 
				
			||||||
 | 
									<View style = {{width: '100%'}}>
 | 
				
			||||||
 | 
										<Text style={styles.title}>{item.item.message}</Text>
 | 
				
			||||||
 | 
									</View>
 | 
				
			||||||
 | 
									{dateInfo!==undefined?<Text style={{fontSize: 12, fontWeight: '200'}}>{dateInfo}</Text>:<></>}
 | 
				
			||||||
 | 
								</View>
 | 
				
			||||||
		</View>
 | 
							</View>
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const TeacherList = ({route}) => {
 | 
					function NewTeacherList(props) {
 | 
				
			||||||
	return (
 | 
						return (
 | 
				
			||||||
		<View style={{}}>
 | 
						  <View>
 | 
				
			||||||
 | 
							<LinearGradient start={{x: 0.25, y: .5}} end={{x: 1, y: 1}} colors={['#FF8484', '#FF1111']} style={{backgroundColor: 'red', width: '20%', padding: '2%', borderTopRightRadius: 20, borderBottomRightRadius: 20, marginVertical: '2%'}}>
 | 
				
			||||||
 | 
							  <Text style={[styles.title, {color: 'white', fontWeight: 'bold'}]}>{I18n.t('dates.'+props.name)}</Text>
 | 
				
			||||||
 | 
							</LinearGradient>
 | 
				
			||||||
		<FlatList
 | 
							<FlatList
 | 
				
			||||||
				data={route.params.data}
 | 
							  data={props.list}
 | 
				
			||||||
		  renderItem={item=><Announcement item={item}/>} 
 | 
							  renderItem={item=><Announcement item={item}/>} 
 | 
				
			||||||
		  keyExtractor={item=>JSON.stringify(item)}
 | 
							  keyExtractor={item=>JSON.stringify(item)}
 | 
				
			||||||
		/>
 | 
							/>
 | 
				
			||||||
	  </View>
 | 
						  </View>
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const TeacherList = ({route}) => {
 | 
				
			||||||
 | 
						const todayDate = getCurrentDate()
 | 
				
			||||||
 | 
						const weekPastDate = new Date();
 | 
				
			||||||
 | 
						var pastDate = weekPastDate.getDate() - 7;
 | 
				
			||||||
 | 
						weekPastDate.setDate(pastDate);
 | 
				
			||||||
 | 
						const weekFutureDate = new Date();
 | 
				
			||||||
 | 
						var futureDate = weekFutureDate.getDate() + 7;
 | 
				
			||||||
 | 
						weekFutureDate.setDate(futureDate);
 | 
				
			||||||
 | 
						const today = []
 | 
				
			||||||
 | 
						const past = []
 | 
				
			||||||
 | 
						const future = []
 | 
				
			||||||
 | 
						var todayBoolean = true
 | 
				
			||||||
 | 
						var pastBoolean = true
 | 
				
			||||||
 | 
						var futureBoolean = true
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						for (var i = 0; i < route.params.data.length; i++) {
 | 
				
			||||||
 | 
							const itemDate = new Date(route.params.data[i].date)
 | 
				
			||||||
 | 
							if (itemDate.getTime() == todayDate.getTime()) {
 | 
				
			||||||
 | 
								today.push(route.params.data[i])
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else if (itemDate.getTime() > todayDate.getTime() && itemDate.getTime() <= weekFutureDate.getTime()) {
 | 
				
			||||||
 | 
								future.push(route.params.data[i])
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							//else if (itemDate >= weekPastDate && itemDate < todayDate) {
 | 
				
			||||||
 | 
							else if (itemDate.getTime() < todayDate.getTime()) {
 | 
				
			||||||
 | 
								past.push(route.params.data[i])
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (today.length === 0) todayBoolean = false
 | 
				
			||||||
 | 
						if (past.length === 0) pastBoolean = false
 | 
				
			||||||
 | 
						if (future.length === 0) futureBoolean = false
 | 
				
			||||||
 | 
						var noAnn = (todayBoolean||pastBoolean||futureBoolean)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return (
 | 
				
			||||||
 | 
							<ScrollView style={{flex:1, backgroundColor: 'white'}}>
 | 
				
			||||||
 | 
								{todayBoolean?<NewTeacherList name = 'today' list = {today} />:<></>}
 | 
				
			||||||
 | 
								{pastBoolean?<NewTeacherList name = 'past' list = {past} />:<></>}
 | 
				
			||||||
 | 
								{futureBoolean?<NewTeacherList name = 'future' list = {future} />:<></>}
 | 
				
			||||||
 | 
								{!noAnn?<Text style={{textAlign: 'center', fontSize: 20, paddingTop: '2%'}}>{I18n.t('announcements.noAnnouncements')}</Text>:<></>}
 | 
				
			||||||
 | 
							</ScrollView>
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function TeacherButton(props) {
 | 
					function TeacherButton(props) {
 | 
				
			||||||
	const [color, setColor] = useState(props.color?props.color:'lightgrey')
 | 
						const [color, setColor] = useState(props.color?props.color:'lightgrey')
 | 
				
			||||||
	return (
 | 
						return (
 | 
				
			||||||
		<View style={[styles.item1,{flexDirection:'row'}]}>
 | 
							<View>
 | 
				
			||||||
		  <TouchableOpacity style={{flex:1, justifyContent: 'center'}} onPress={()=>{props.navigation.navigate('TeacherList',{data:props.data,name:props.name})}} activeOpacity={0.8}>
 | 
								<TouchableOpacity style={styles.listItem} onPress={()=>{props.navigation.navigate('TeacherList',{data:props.data,name:props.name})}} activeOpacity={0.8}>
 | 
				
			||||||
			<Text style={styles.title3}>{props.name}</Text>
 | 
									<View style={styles.container2}>
 | 
				
			||||||
 | 
										<Ionicons name="megaphone-outline" size={36} color={'#323232'}style={{marginRight: 15}}/>
 | 
				
			||||||
 | 
										<View style={styles.accordian}>
 | 
				
			||||||
 | 
											<Text style={[styles.title, {alignSelf:'center'}]}>{props.name}</Text>
 | 
				
			||||||
 | 
											{props.icon?<Icon name="pushpino" size={24} color={color} onPress={()=>{setColor(color=='red'?'lightgrey':'red');props.addFavorite(props.name)}}/>:<></>}
 | 
				
			||||||
 | 
										</View>
 | 
				
			||||||
 | 
									</View>
 | 
				
			||||||
		  </TouchableOpacity>
 | 
							  </TouchableOpacity>
 | 
				
			||||||
		  {props.icon?<Icon.Button color={color} name="star" size={30} style={{alignSelf:'center'}} backgroundColor="white" onPress={()=>{setColor(color=='#dba309'?'lightgrey':'#dba309');props.addFavorite(props.name)}}/>:<></>}
 | 
					 | 
				
			||||||
		</View>
 | 
							</View>
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -124,14 +183,14 @@ class Announcements extends React.Component {
 | 
				
			|||||||
	
 | 
						
 | 
				
			||||||
	render() {
 | 
						render() {
 | 
				
			||||||
		return (
 | 
							return (
 | 
				
			||||||
			<View style={[styles.container]}>
 | 
								<ScrollView style={styles.moreDefault}>
 | 
				
			||||||
				<TeacherButton data={this.state.data.filter(x=>x.teacher==null||x.teacher.trim()==='')} name="No Teacher" navigation={this.props.navigation} />
 | 
									<TeacherButton data={this.state.data.filter(x=>x.teacher==null||x.teacher.trim()==='')} name="No Teacher" navigation={this.props.navigation} />
 | 
				
			||||||
				<FlatList
 | 
									<FlatList
 | 
				
			||||||
					data={this.state.favoriteNames.concat(this.state.teacherNames.filter(x=>this.state.favoriteNames.map(({name})=>name).indexOf(x.name) < 0))}
 | 
										data={this.state.favoriteNames.concat(this.state.teacherNames.filter(x=>this.state.favoriteNames.map(({name})=>name).indexOf(x.name) < 0))}
 | 
				
			||||||
					renderItem={({item})=><TeacherButton color={this.state.favoriteNames.indexOf(item) >= 0?'#dba309':'lightgrey'} item={item} data={this.state.data.filter(x=>x.teacher===item.name)} name={item.name} navigation={this.props.navigation} icon={true} addFavorite={this.addFavorite}/>}
 | 
										renderItem={({item})=><TeacherButton color={this.state.favoriteNames.indexOf(item) >= 0?'red':'lightgrey'} item={item} data={this.state.data.filter(x=>x.teacher===item.name)} name={item.name} navigation={this.props.navigation} icon={true} addFavorite={this.addFavorite}/>}
 | 
				
			||||||
					keyExtractor={(item,index)=>item.name+index}
 | 
										keyExtractor={(item,index)=>item.name+index}
 | 
				
			||||||
				/>
 | 
									/>
 | 
				
			||||||
			</View>
 | 
								</ScrollView>
 | 
				
			||||||
		)
 | 
							)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										23
									
								
								app/App.js
									
									
									
									
									
								
							
							
						
						@ -27,25 +27,18 @@ import Staff from './Staff'
 | 
				
			|||||||
import OpeningPage from './OpeningPage';
 | 
					import OpeningPage from './OpeningPage';
 | 
				
			||||||
import OpenPage from './OpenPage';
 | 
					import OpenPage from './OpenPage';
 | 
				
			||||||
import Ionicons from 'react-native-vector-icons/Ionicons';
 | 
					import Ionicons from 'react-native-vector-icons/Ionicons';
 | 
				
			||||||
import I18n from './i18n';
 | 
					import I18n from './i18n.js'
 | 
				
			||||||
import AsyncStorage from '@react-native-community/async-storage'
 | 
					import AsyncStorage from '@react-native-async-storage/async-storage'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Tab = createBottomTabNavigator();
 | 
					const Tab = createBottomTabNavigator();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AsyncStorage.getItem('language')
 | 
					AsyncStorage.getItem('language')
 | 
				
			||||||
  .then((token) => { 
 | 
					  .then((token) => { 
 | 
				
			||||||
	console.log("lang: " + token);
 | 
						console.log("lang: " + token);
 | 
				
			||||||
	I18n.locale = token;
 | 
						I18n.locale = token;
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AsyncStorage.getItem('announcementNotifs')
 | 
					 | 
				
			||||||
	.then((token) => { 
 | 
					 | 
				
			||||||
	console.log("announcementNotifs: " + token);
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
AsyncStorage.getItem('eventNotifs')
 | 
					 | 
				
			||||||
	.then((token) => { 
 | 
					 | 
				
			||||||
	console.log("eventNotifs: " + token);
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class App extends React.Component {
 | 
					class App extends React.Component {
 | 
				
			||||||
	state = {
 | 
						state = {
 | 
				
			||||||
@ -86,11 +79,11 @@ class App extends React.Component {
 | 
				
			|||||||
						fontSize:16
 | 
											fontSize:16
 | 
				
			||||||
					}}}
 | 
										}}}
 | 
				
			||||||
				>	
 | 
									>	
 | 
				
			||||||
					<Tab.Screen name={I18n.t('app.home')} component={Home}/>
 | 
										<Tab.Screen name={I18n.t("app.home")} component={Home}/>
 | 
				
			||||||
					<Tab.Screen name={I18n.t('app.calendar')} component={Calendar}/>
 | 
										<Tab.Screen name={I18n.t("app.calendar")} component={Calendar}/>
 | 
				
			||||||
					<Tab.Screen name={I18n.t('app.clubs')} component={Clubs}/>
 | 
										<Tab.Screen name={I18n.t("app.clubs")} component={Clubs}/>
 | 
				
			||||||
					<Tab.Screen name={I18n.t('app.staff')} component={Staff}/>
 | 
										<Tab.Screen name={I18n.t("app.staff")} component={Staff}/>
 | 
				
			||||||
					<Tab.Screen name={I18n.t('app.more')} component={More}/>
 | 
										<Tab.Screen name={I18n.t("app.more")} component={More}/>
 | 
				
			||||||
				</Tab.Navigator>
 | 
									</Tab.Navigator>
 | 
				
			||||||
				: <OpenPage />}
 | 
									: <OpenPage />}
 | 
				
			||||||
			</NavigationContainer>
 | 
								</NavigationContainer>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										235
									
								
								app/Calendar.js
									
									
									
									
									
								
							
							
						
						@ -14,85 +14,142 @@ import {
 | 
				
			|||||||
import {	 
 | 
					import {	 
 | 
				
			||||||
  ReloadInstructions,
 | 
					  ReloadInstructions,
 | 
				
			||||||
} from 'react-native/Libraries/NewAppScreen';
 | 
					} from 'react-native/Libraries/NewAppScreen';
 | 
				
			||||||
 | 
					import Ionicons from 'react-native-vector-icons/Ionicons';
 | 
				
			||||||
 | 
					import Icon from 'react-native-vector-icons/AntDesign'
 | 
				
			||||||
import LinearGradient from 'react-native-linear-gradient';
 | 
					import LinearGradient from 'react-native-linear-gradient';
 | 
				
			||||||
import I18n from './i18n';
 | 
					import { NavigationContainer } from '@react-navigation/native'
 | 
				
			||||||
 | 
					import { createStackNavigator } from '@react-navigation/stack'
 | 
				
			||||||
import styles from './styles/liststyles'
 | 
					import styles from './styles/liststyles'
 | 
				
			||||||
import { url } from './resources/fetchInfo.json'
 | 
					import { url } from './resources/fetchInfo.json'
 | 
				
			||||||
 | 
					import morestyles from './styles/morestyles'
 | 
				
			||||||
 | 
					import I18n from './i18n.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const Stack = createStackNavigator();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getCurrentDate=()=>{
 | 
					const getCurrentDate=()=>{
 | 
				
			||||||
  var date = new Date().getDate();
 | 
					  var date = new Date().getDate();
 | 
				
			||||||
  var month = new Date().getMonth() + 1;
 | 
					  var month = new Date().getMonth() + 1;
 | 
				
			||||||
  var year = new Date().getFullYear();
 | 
					  var year = new Date().getFullYear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return year + ',' + month + ',' + date;
 | 
					  return new Date(year, month, date);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
const getWeekDate=()=>{
 | 
					export const EventInfo = ({route}) => {
 | 
				
			||||||
  var date = new Date().getDate()-8;
 | 
					  const item = route.params;
 | 
				
			||||||
  var month = new Date().getMonth()+1;
 | 
					  const itemDate = new Date(item.date)
 | 
				
			||||||
  var year = new Date().getFullYear();
 | 
					  const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
 | 
				
			||||||
 | 
					  const months = ['January','February','March','April','May','June','July','August','September','October','November','December',]
 | 
				
			||||||
 | 
					  const dayOfWeek = days[itemDate.getDay()]
 | 
				
			||||||
 | 
					  const month = months[itemDate.getMonth()]
 | 
				
			||||||
 | 
					  const date = itemDate.getDate()
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  return year + ',' + month + ',' + date;
 | 
					  return (
 | 
				
			||||||
 | 
					    <ScrollView style = {{backgroundColor: 'white', flex:1, padding: '5%', paddingRight: '10%'}}>
 | 
				
			||||||
 | 
					      <View style={{marginBottom: '7%'}}>
 | 
				
			||||||
 | 
					        <Text style={[styles.title, {fontWeight: 'bold', marginBottom: '2%'}]}>{I18n.t('calendar.info')}</Text>
 | 
				
			||||||
 | 
					        <Text style={[styles.title, {fontWeight: '200'}]}>{item.text}</Text>
 | 
				
			||||||
 | 
					      </View>
 | 
				
			||||||
 | 
					      <View style={{}}>
 | 
				
			||||||
 | 
					        <View style={{display: 'flex', flexDirection: 'row', marginBottom: '5%'}}>
 | 
				
			||||||
 | 
					          <Ionicons name='location-outline' size={28} color={'#323232'}style={{marginRight: 15, alignSelf: 'center'}}/>
 | 
				
			||||||
 | 
					          <View style={{display: 'flex', marginLeft: -15, paddingHorizontal: '5%'}}>
 | 
				
			||||||
 | 
					            <Text style={{fontSize: 16}}>{I18n.t('calendar.location')}</Text>
 | 
				
			||||||
 | 
					            <Text style={[styles.title, {fontSize: 16, fontWeight: '200'}]}>{item.location}</Text>
 | 
				
			||||||
 | 
					          </View>
 | 
				
			||||||
 | 
					        </View>
 | 
				
			||||||
 | 
					        <View style={{display: 'flex', flexDirection: 'row', marginBottom: '5%'}}>
 | 
				
			||||||
 | 
					          <Ionicons name='time-outline' size={28} color={'#323232'}style={{marginRight: 15, alignSelf: 'center'}}/>
 | 
				
			||||||
 | 
					          <View style={{display: 'flex', marginLeft: -15, paddingHorizontal: '5%'}}>
 | 
				
			||||||
 | 
					            <Text style={{fontSize: 16}}>{I18n.t('calendar.date')}</Text>
 | 
				
			||||||
 | 
					            <Text style={[styles.title, {fontSize: 16, fontWeight: '200'}]}>{dayOfWeek}, {month} {date}</Text>
 | 
				
			||||||
 | 
					          </View>
 | 
				
			||||||
 | 
					        </View>
 | 
				
			||||||
 | 
					        <View style={{display: 'flex', flexDirection: 'row'}}>
 | 
				
			||||||
 | 
					          <Ionicons name='person-circle-outline' size={28} color={'#323232'}style={{marginRight: 15, alignSelf: 'center'}}/>
 | 
				
			||||||
 | 
					          <View style={{display: 'flex', marginLeft: -15, paddingHorizontal: '5%'}}>
 | 
				
			||||||
 | 
					            <Text style={{fontSize: 16}}>{I18n.t('calendar.organizer')}</Text>
 | 
				
			||||||
 | 
					            <Text style={[styles.title, {fontSize: 16, fontWeight: '200'}]}>{item.name}</Text>
 | 
				
			||||||
 | 
					            <Text style={[styles.title, {fontSize: 16, fontWeight: '200', textDecorationLine: 'underline'}]}>{item.emails}</Text>
 | 
				
			||||||
 | 
					          </View>
 | 
				
			||||||
 | 
					        </View>
 | 
				
			||||||
 | 
					      </View>
 | 
				
			||||||
 | 
					    </ScrollView>
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					const Event = (props) => {
 | 
				
			||||||
 | 
					  const item = props.item
 | 
				
			||||||
 | 
					  const date = item.item.date.split('-')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <View>
 | 
				
			||||||
 | 
					      <TouchableOpacity style={[styles.listItem, {padding: '2%'}]} onPress={()=>props.navigation.navigate('EventInfo', {data:props.data, title: item.item.title,text:item.item.text,location:item.item.location,date:item.item.date, name:item.item.name, emails: item.item.emails})} activeOpacity={0.8}>
 | 
				
			||||||
 | 
					        <View style = {[styles.container2, {justifyContent: 'space-between'}]}>
 | 
				
			||||||
 | 
					          <View style={{display: 'flex', flexDirection: 'row'}}>
 | 
				
			||||||
 | 
					            <Ionicons name='calendar' size={32} color={'#323232'} style={{marginRight: 15}}/>
 | 
				
			||||||
 | 
					            <View style = {{display: 'flex', alignContent: 'center', width: '80%'}}>
 | 
				
			||||||
 | 
					              <Text style={styles.title}>{item.item.title}</Text>
 | 
				
			||||||
 | 
					              <View style={{paddingBottom: '2%'}}><Text style = {{fontSize: 12, fontWeight: '200'}}>{`${date[1]}/${date[2]}/${date[0]}`}</Text></View>
 | 
				
			||||||
 | 
					            </View>
 | 
				
			||||||
 | 
					          </View>
 | 
				
			||||||
 | 
					          <Image source = {require('./assets/forward.png')} style={{tintColor: '#b2b2b2'}}/>
 | 
				
			||||||
 | 
					        </View>
 | 
				
			||||||
 | 
					      </TouchableOpacity>
 | 
				
			||||||
 | 
					    </View>    
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Event = ({item}) => {
 | 
					const background = (<LinearGradient
 | 
				
			||||||
	const [visible, setVisible] = useState(false)
 | 
					  colors={['#f99', 'white']}
 | 
				
			||||||
  const today = new Date(getCurrentDate())
 | 
					  style = {{flex:1,borderBottomColor:'black',borderBottomWidth:0.5}}
 | 
				
			||||||
  const itemDate = new Date(item.item.date)
 | 
					  />)
 | 
				
			||||||
  const week = new Date(getWeekDate())
 | 
					 | 
				
			||||||
	const extra = (
 | 
					 | 
				
			||||||
		<>
 | 
					 | 
				
			||||||
			<Text style={{fontSize:20, paddingHorizontal: '1%'}}>{item.item.text}</Text>
 | 
					 | 
				
			||||||
      <View style={{display: 'flex', flexDirection: 'row', alignItems: 'center'}}>
 | 
					 | 
				
			||||||
        <View style={{width: '10%', display: 'flex', justifyContent: 'center'}}>
 | 
					 | 
				
			||||||
          <Image source={require('./assets/location.png')} style={{height: 22, width: 22}}/>
 | 
					 | 
				
			||||||
        </View>
 | 
					 | 
				
			||||||
        <View style={{width: '90%'}}>
 | 
					 | 
				
			||||||
          <Text style={{fontSize:20}}>{item.item.location}</Text>
 | 
					 | 
				
			||||||
        </View>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      </View>
 | 
					function CalendarEvents () {
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <NavigationContainer independent={true}>
 | 
				
			||||||
 | 
					      <Stack.Navigator>
 | 
				
			||||||
 | 
					        <Stack.Screen 
 | 
				
			||||||
 | 
					          name = {I18n.t('calendar.calendar')}
 | 
				
			||||||
 | 
					          component = {Calendar}
 | 
				
			||||||
 | 
					          options={({
 | 
				
			||||||
 | 
					            headerShown: true,
 | 
				
			||||||
 | 
					            headerTitleStyle:morestyles.headerTitle,
 | 
				
			||||||
 | 
					            headerBackground: ()=>background,
 | 
				
			||||||
 | 
					            //headerLeft: null,
 | 
				
			||||||
 | 
					            headerTitleAlign: 'center',
 | 
				
			||||||
 | 
					            headerBackTitleVisible:false,
 | 
				
			||||||
 | 
					            headerTintColor: 'black'
 | 
				
			||||||
 | 
					          })}
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					        <Stack.Screen 
 | 
				
			||||||
 | 
					          name = "EventInfo"
 | 
				
			||||||
 | 
					          component = {EventInfo}
 | 
				
			||||||
 | 
					          options={({route})=>({
 | 
				
			||||||
 | 
					            title:route.params.title,
 | 
				
			||||||
 | 
					            headerTitleStyle:morestyles.headerTitle,
 | 
				
			||||||
 | 
					            headerBackground: ()=>background,
 | 
				
			||||||
 | 
					            //headerLeft: null,
 | 
				
			||||||
 | 
					            headerTitleAlign: 'center',
 | 
				
			||||||
 | 
					            headerBackTitleVisible:false,
 | 
				
			||||||
 | 
					            headerTintColor: 'black'
 | 
				
			||||||
 | 
					          })}
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					      </Stack.Navigator>
 | 
				
			||||||
 | 
					    </NavigationContainer>
 | 
				
			||||||
 | 
					  ) 
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		</>
 | 
					function NewCalendarCategory (props) {
 | 
				
			||||||
  )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (itemDate.getTime() >= today.getTime()) {
 | 
					 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
      <TouchableOpacity style={styles.item1} onPress={()=>setVisible(!visible)} activeOpacity={0.8}>
 | 
					    <View>
 | 
				
			||||||
        <View style = {{display: 'flex', flexDirection: 'row', alignContent: 'center', justifyContent: 'space-between'}}>
 | 
					      <LinearGradient start={{x: 0.25, y: .5}} end={{x: 1, y: 1}} colors={['#FF8484', '#FF1111']} style={{backgroundColor: 'red', width: '20%', padding: '2%', borderTopRightRadius: 20, borderBottomRightRadius: 20, marginVertical: '2%'}}>
 | 
				
			||||||
        <View style = {{display: 'flex', flexDirection: 'row', alignContent: 'center', width: '60%'}}>
 | 
					        <Text style={[styles.title, {color: 'white', fontWeight: 'bold'}]}>{I18n.t('dates.'+props.name)}</Text>
 | 
				
			||||||
          <Image source ={require('./assets/calendar.png')}  style = {{height: 40, width: 40, marginRight: 15}}/>
 | 
					      </LinearGradient>
 | 
				
			||||||
          <Text style={styles.title3}>{item.item.title}</Text>
 | 
					      <FlatList
 | 
				
			||||||
 | 
					        data={props.list}
 | 
				
			||||||
 | 
					        renderItem={item=><Event item={item} name={props.itemname} navigation={props.navigation}/>} 
 | 
				
			||||||
 | 
					        keyExtractor={item=>JSON.stringify(item)}
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
    </View>
 | 
					    </View>
 | 
				
			||||||
        <View style = {{display: 'flex', flexDirection: 'row', alignContent: 'center'}}>
 | 
					 | 
				
			||||||
          <Text style = {{fontSize: 16, alignSelf: 'center'}}>{item.item.date}</Text>
 | 
					 | 
				
			||||||
        </View>
 | 
					 | 
				
			||||||
      </View>
 | 
					 | 
				
			||||||
        {visible?extra:<></>}
 | 
					 | 
				
			||||||
		  </TouchableOpacity>
 | 
					 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  else if (itemDate.getTime() >= week.getTime()){
 | 
					 | 
				
			||||||
    return (
 | 
					 | 
				
			||||||
		<TouchableOpacity style={{backgroundColor: '#e3e3e3', padding: 15, borderBottomWidth: 1, borderColor: 'black', width: '100%',}} onPress={()=>setVisible(!visible)} activeOpacity={0.8}>
 | 
					 | 
				
			||||||
			<View style = {{display: 'flex', flexDirection: 'row', alignContent: 'center', justifyContent: 'space-between'}}>
 | 
					 | 
				
			||||||
        <View style = {{display: 'flex', flexDirection: 'row', alignContent: 'center', width: '60%'}}>
 | 
					 | 
				
			||||||
          <Image source ={require('./assets/calendar.png')}  style = {{height: 40, width: 40, marginRight: 15}}/>
 | 
					 | 
				
			||||||
          <Text style={styles.title3}>{item.item.title}</Text>
 | 
					 | 
				
			||||||
        </View>
 | 
					 | 
				
			||||||
        <View style = {{display: 'flex', flexDirection: 'row', alignContent: 'center'}}>
 | 
					 | 
				
			||||||
          <Text style = {{fontSize: 16, alignSelf: 'center'}}>{item.item.date}</Text>
 | 
					 | 
				
			||||||
        </View>
 | 
					 | 
				
			||||||
      </View>
 | 
					 | 
				
			||||||
			{visible?extra:<></>}
 | 
					 | 
				
			||||||
		</TouchableOpacity>
 | 
					 | 
				
			||||||
	  )
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  else {
 | 
					 | 
				
			||||||
    return (
 | 
					 | 
				
			||||||
      null
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Calendar extends React.Component {
 | 
					class Calendar extends React.Component {
 | 
				
			||||||
@ -125,31 +182,53 @@ class Calendar extends React.Component {
 | 
				
			|||||||
		  .then((json) => {
 | 
							  .then((json) => {
 | 
				
			||||||
			const data = JSON.parse(json).data
 | 
								const data = JSON.parse(json).data
 | 
				
			||||||
      data.sort((a,b)=>new Date(b.date).getTime()-new Date(a.date).getTime())
 | 
					      data.sort((a,b)=>new Date(b.date).getTime()-new Date(a.date).getTime())
 | 
				
			||||||
 | 
					      console.log(data);
 | 
				
			||||||
			this.setState({data: data});
 | 
								this.setState({data: data});
 | 
				
			||||||
		  })
 | 
							  })
 | 
				
			||||||
		  .catch((error) => console.error(error))
 | 
							  .catch((error) => console.error(error))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	render() {
 | 
						render() {
 | 
				
			||||||
		return (
 | 
					    const todayDate = getCurrentDate()
 | 
				
			||||||
			<View>
 | 
					    const weekPastDate = new Date();
 | 
				
			||||||
        <View style = {{height: 90, display: 'flex'}}>
 | 
					    var pastDate = weekPastDate.getDate() - 7;
 | 
				
			||||||
          <LinearGradient
 | 
					    weekPastDate.setDate(pastDate);
 | 
				
			||||||
            colors={['#f99', 'white']}
 | 
					    const weekFutureDate = new Date();
 | 
				
			||||||
            style = {{height: '100%', borderBottomColor:'black', borderBottomWidth:0.5, display: 'flex', justifyContent: 'flex-end', paddingBottom: '2.5%'}}
 | 
					    var futureDate = weekFutureDate.getDate() + 7;
 | 
				
			||||||
          >
 | 
					    weekFutureDate.setDate(futureDate);
 | 
				
			||||||
            <Text style = {{fontSize: 24, fontWeight: 'bold', alignSelf: 'center'}}>{I18n.t('calendar.calendarEvents')}</Text>
 | 
					    const today = []
 | 
				
			||||||
          </LinearGradient>
 | 
					    const past = []
 | 
				
			||||||
 | 
					    const future = []
 | 
				
			||||||
 | 
					    var todayBoolean = true
 | 
				
			||||||
 | 
					    var pastBoolean = true
 | 
				
			||||||
 | 
					    var futureBoolean = true
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
        </View>
 | 
					    for (var i =0; i < this.state.data.length; i++) {
 | 
				
			||||||
				<FlatList
 | 
					      const itemDate = new Date(this.state.data[i].date)
 | 
				
			||||||
					data={this.state.data}
 | 
					      if (itemDate == todayDate) {
 | 
				
			||||||
					renderItem={item=><Event item={item}/>}
 | 
					        today.push(this.state.data[i])
 | 
				
			||||||
					keyExtractor={item=>JSON.stringify(item)}
 | 
					      }
 | 
				
			||||||
				/>
 | 
					      else if (itemDate > todayDate && itemDate <= weekFutureDate) {
 | 
				
			||||||
			</View>
 | 
					        future.push(this.state.data[i])
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      //else if (itemDate >= weekPastDate && itemDate < todayDate) {
 | 
				
			||||||
 | 
					      else if (itemDate < todayDate) {
 | 
				
			||||||
 | 
					        past.push(this.state.data[i])
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (today.length === 0) todayBoolean = false
 | 
				
			||||||
 | 
					    if (past.length === 0) pastBoolean = false
 | 
				
			||||||
 | 
					    if (future.length === 0) futureBoolean = false
 | 
				
			||||||
 | 
					    var noAnn = (todayBoolean||pastBoolean||futureBoolean)
 | 
				
			||||||
 | 
							return (
 | 
				
			||||||
 | 
								<ScrollView style={{flex:1, backgroundColor: 'white'}}>
 | 
				
			||||||
 | 
					        {todayBoolean?<NewCalendarCategory name = 'today' list = {today} navigation={this.props.navigation} />: <></>}
 | 
				
			||||||
 | 
					        {pastBoolean?<NewCalendarCategory name = 'past' list = {past} navigation={this.props.navigation} />: <></>}
 | 
				
			||||||
 | 
					        {futureBoolean?<NewCalendarCategory name = 'future' list = {future} navigation={this.props.navigation} />: <></>}
 | 
				
			||||||
 | 
					        {!noAnn?<Text style={{textAlign: 'center', fontSize: 20, paddingTop: '2%'}}>{I18n.t('calendar.noEvents')}</Text>:<></>}
 | 
				
			||||||
 | 
					      </ScrollView>
 | 
				
			||||||
		)
 | 
							)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Calendar;
 | 
					export default CalendarEvents;
 | 
				
			||||||
@ -7,6 +7,9 @@ import {
 | 
				
			|||||||
  Text,
 | 
					  Text,
 | 
				
			||||||
  StatusBar,
 | 
					  StatusBar,
 | 
				
			||||||
  Linking,
 | 
					  Linking,
 | 
				
			||||||
 | 
					  Animated,
 | 
				
			||||||
 | 
					  TouchableOpacity,
 | 
				
			||||||
 | 
					  Image
 | 
				
			||||||
} from 'react-native';
 | 
					} from 'react-native';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
@ -18,12 +21,14 @@ import {
 | 
				
			|||||||
} from 'react-native/Libraries/NewAppScreen';
 | 
					} from 'react-native/Libraries/NewAppScreen';
 | 
				
			||||||
import styles from './styles/liststyles';
 | 
					import styles from './styles/liststyles';
 | 
				
			||||||
import { url } from './resources/fetchInfo.json'
 | 
					import { url } from './resources/fetchInfo.json'
 | 
				
			||||||
 | 
					import I18n from 'i18n-js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ChallengeWeek extends React.Component {
 | 
					class ChallengeWeek extends React.Component {
 | 
				
			||||||
	constructor(props) {
 | 
						constructor(props) {
 | 
				
			||||||
		super(props)
 | 
							super(props)
 | 
				
			||||||
		this.state = {
 | 
							this.state = {
 | 
				
			||||||
			isLoading: true
 | 
								isLoading: true,
 | 
				
			||||||
 | 
								flip: true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
@ -37,17 +42,70 @@ class ChallengeWeek extends React.Component {
 | 
				
			|||||||
		}).then((json) => {
 | 
							}).then((json) => {
 | 
				
			||||||
			this.setState({data: JSON.parse(json),isLoading:false});
 | 
								this.setState({data: JSON.parse(json),isLoading:false});
 | 
				
			||||||
		}).catch((error) => console.error(error))
 | 
							}).catch((error) => console.error(error))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/*this.animatedValue=new Animated.Value(0);
 | 
				
			||||||
 | 
							this.value=0;
 | 
				
			||||||
 | 
							this.animatedValue.addListener(({value}) => {
 | 
				
			||||||
 | 
								this.value=value;
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							this.frontInterpolate = this.animatedValue.interpolate({
 | 
				
			||||||
 | 
								inputRange:[0,180],
 | 
				
			||||||
 | 
								outputRange:['0deg', '180deg'],
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							this.backInterpolate = this.animatedValue.interpolate({
 | 
				
			||||||
 | 
								inputRange:[0,180],
 | 
				
			||||||
 | 
								outputRange: ['180deg','360deg']
 | 
				
			||||||
 | 
							})*/
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*flipCard() {
 | 
				
			||||||
 | 
							if (this.value >= 90) {
 | 
				
			||||||
 | 
								Animated.spring(this.animatedValue, {
 | 
				
			||||||
 | 
									toValue:0,
 | 
				
			||||||
 | 
									friction:8,
 | 
				
			||||||
 | 
									tension: 10
 | 
				
			||||||
 | 
								}).start();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else {
 | 
				
			||||||
 | 
								Animated.spring(this.animatedValue, {
 | 
				
			||||||
 | 
									toValue:180,
 | 
				
			||||||
 | 
									friction: 8,
 | 
				
			||||||
 | 
									tension: 10
 | 
				
			||||||
 | 
								}).start();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							this.setState({flip:!this.state.flip})
 | 
				
			||||||
 | 
						}*/
 | 
				
			||||||
 | 
						
 | 
				
			||||||
	render() {
 | 
						render() {
 | 
				
			||||||
 | 
							{/*const frontAnimatedStyle = {
 | 
				
			||||||
 | 
								transform: [
 | 
				
			||||||
 | 
									{rotateY:this.frontInterpolate}
 | 
				
			||||||
 | 
								]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							const backAnimatedStyle = {
 | 
				
			||||||
 | 
								transform: [
 | 
				
			||||||
 | 
									{rotateY:this.backInterpolate}
 | 
				
			||||||
 | 
								]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							var styling={}
 | 
				
			||||||
 | 
							var styling2={}
 | 
				
			||||||
 | 
							if (this.state.flip) {
 | 
				
			||||||
 | 
								styling=({height: '100%', width: '100%', backgroundColor: 'white', borderRadius: 20, textAlign: 'center', display: 'flex', alignContent: 'center', padding: '5%', paddingTop: '15%', borderColor: 'red', borderWidth: 1})
 | 
				
			||||||
 | 
								styling2=({display:'none'})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else {
 | 
				
			||||||
 | 
								styling=({display:'none'})
 | 
				
			||||||
 | 
								styling2=({height: '100%', width: '100%', backgroundColor: 'white', borderRadius: 20, textAlign: 'center', display: 'flex', alignContent: 'center', padding: '5%', paddingTop: '15%', borderColor: 'red', borderWidth: 1})
 | 
				
			||||||
 | 
							}*/}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
		if (this.state.isLoading) {
 | 
							if (this.state.isLoading) {
 | 
				
			||||||
			return <View/>
 | 
								return <View/>
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			return (
 | 
								return (
 | 
				
			||||||
				<View style={{alignItems:'center',paddingTop:'5%',paddingiorizontal:'10%', height: '100%', backgroundColor: 'white'}}>
 | 
									<View style={{alignItems:'center',paddingiorizontal:'10%', height: '100%', backgroundColor: 'white', justifyContent: 'center', padding: '2%'}}>
 | 
				
			||||||
					<Text style={{fontSize: 32, fontWeight: 'bold', marginBottom: '10%', color: 'red'}}>{this.state.data.title}</Text>
 | 
										<Text style={{fontSize: 32, fontWeight: 'bold', marginBottom: '10%', color: 'red', textAlign: 'center'}}>{this.state.data.title}</Text>
 | 
				
			||||||
					<Text style={{textAlign:'center', fontSize: 24, marginBottom: '5%'}}>{this.state.data.text}</Text>
 | 
										<Text style={{textAlign:'center', fontSize: 24, marginBottom: '5%', textAlign: 'center', fontWeight: '200'}}>{this.state.data.text}</Text>
 | 
				
			||||||
					<Text style={{textAlign:'center', fontSize: 20, textDecorationLine: 'underline', textDecorationStyle: "solid", textDecorationColor: "#000",}} onPress={() => Linking.openURL(this.state.data.link)}>{this.state.data.link}</Text>
 | 
										<Text style={{textAlign:'center', fontSize: 20, textDecorationLine: 'underline', textDecorationStyle: "solid", textDecorationColor: "#000"}} onPress={() => Linking.openURL(this.state.data.link)}>{I18n.t("challenge.link")}</Text>
 | 
				
			||||||
				</View>
 | 
									</View>
 | 
				
			||||||
			)
 | 
								)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										67
									
								
								app/Clubs.js
									
									
									
									
									
								
							
							
						
						@ -29,50 +29,50 @@ import morestyles from './styles/morestyles'
 | 
				
			|||||||
import { url } from './resources/fetchInfo.json'
 | 
					import { url } from './resources/fetchInfo.json'
 | 
				
			||||||
import LinearGradient from 'react-native-linear-gradient';
 | 
					import LinearGradient from 'react-native-linear-gradient';
 | 
				
			||||||
import I18n from './i18n';
 | 
					import I18n from './i18n';
 | 
				
			||||||
 | 
					import Ionicons from 'react-native-vector-icons/Ionicons';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Stack = createStackNavigator();
 | 
					const Stack = createStackNavigator();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const ClubInfo = ({route}) => {
 | 
					export const ClubInfo = ({route}) => {
 | 
				
			||||||
  const item = route.params;
 | 
					  const item = route.params;
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <View style = {{padding: 10, backgroundColor: 'white', height: '100%'}}>
 | 
					    <ScrollView style = {{backgroundColor: 'white', flex:1, padding: '5%', paddingRight: '10%'}}>
 | 
				
			||||||
      <View style ={[styles.infoContainer, {flexDirection: 'row', alignItems: 'center'}]}>
 | 
					      <View style={{display: 'flex', flexDirection: 'row', marginBottom: '5%'}}>
 | 
				
			||||||
        <View style={{width: '17%', display: 'flex', justifyContent: 'center'}}>
 | 
					        <Ionicons name='location-outline' size={28} color={'#323232'}style={{marginRight: 15, alignSelf: 'center'}}/>
 | 
				
			||||||
          <Image source ={require('./assets/time.png')} style={{width: 50, height: 50}}/>
 | 
					        <View style={{display: 'flex', marginLeft: -15, paddingHorizontal: '5%'}}>
 | 
				
			||||||
        </View>
 | 
					          <Text style={{fontSize: 16}}>Meeting Location </Text>
 | 
				
			||||||
        <View style={{width: '83%'}}>
 | 
					          <Text style={[styles.title, styles.linktext, {fontSize: 16, fontWeight: '200'}]} onPress={() => Linking.openURL(item.link)}>{item.link}</Text>
 | 
				
			||||||
          <Text style = {{fontSize:20}}>{item.meeting}</Text>
 | 
					 | 
				
			||||||
        </View>
 | 
					        </View>
 | 
				
			||||||
      </View>
 | 
					      </View>
 | 
				
			||||||
      <View style ={[styles.infoContainer, {flexDirection: 'row', alignItems: 'center'}]}>
 | 
					      <View style={{display: 'flex', flexDirection: 'row', marginBottom: '5%'}}>
 | 
				
			||||||
        <View style={{width: '17%', display: 'flex', justifyContent: 'center'}}>
 | 
					        <Ionicons name='time-outline' size={28} color={'#323232'}style={{marginRight: 15, alignSelf: 'center'}}/>
 | 
				
			||||||
          <Image source ={require('./assets/zoom.png')} style={{width: 50, height: 50}}/>
 | 
					        <View style={{display: 'flex'}}>
 | 
				
			||||||
        </View>
 | 
					          <Text style={{fontSize: 16}}>Meeting Date</Text>
 | 
				
			||||||
        <View style={{width: '83%'}}>
 | 
					          <Text style={[styles.title, {fontSize: 16, fontWeight: '200'}]}>{item.meeting}</Text>
 | 
				
			||||||
          <Text style = {[styles.linktext,{fontSize:20}]} onPress={() => Linking.openURL(item.link)}>{item.link}</Text>
 | 
					 | 
				
			||||||
        </View>
 | 
					        </View>
 | 
				
			||||||
      </View>
 | 
					      </View>
 | 
				
			||||||
			<View style ={[styles.infoContainer, {flexDirection: 'row', alignItems: 'center'}]}>
 | 
					      <View style={{display: 'flex', flexDirection: 'row'}}>
 | 
				
			||||||
        <View style={{width: '17%', display: 'flex', justifyContent: 'center'}}>
 | 
					        <Ionicons name='person-circle-outline' size={28} color={'#323232'}style={{marginRight: 15, alignSelf: 'center'}}/>
 | 
				
			||||||
          <Image source ={require('./assets/sponsor.png')} style={{width: 50, height: 50}}/>
 | 
					        <View style={{display: 'flex'}}>
 | 
				
			||||||
        </View>
 | 
					          <Text style={{fontSize: 16}}>Sponsor</Text>
 | 
				
			||||||
        <View style={{width: '83%'}}>
 | 
					          <Text style={[styles.title, {fontSize: 16, fontWeight: '200'}]}>{item.sponsor}</Text>
 | 
				
			||||||
          <Text style = {{fontSize:20}}>{item.sponsor}</Text>
 | 
					 | 
				
			||||||
        </View>
 | 
					 | 
				
			||||||
        </View>
 | 
					        </View>
 | 
				
			||||||
      </View>
 | 
					      </View>
 | 
				
			||||||
 | 
					    </ScrollView>
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
function ClubElement (props) {
 | 
					function ClubElement (props) {
 | 
				
			||||||
  const item = props.item;
 | 
					  const item = props.item;
 | 
				
			||||||
  return(
 | 
					  return(
 | 
				
			||||||
	<View>
 | 
						<View>
 | 
				
			||||||
      <TouchableOpacity style={styles.item1} onPress={()=>props.navigation.navigate('ClubInfo', {data:props.data,name:props.name,meeting:item.meeting,link:item.link,sponsor:item.sponsor})} activeOpacity={0.8}>
 | 
					      <TouchableOpacity style={[styles.listItem]} onPress={()=>props.navigation.navigate('ClubInfo', {data:props.data,name:props.name,meeting:item.meeting,link:item.link,sponsor:item.sponsor})} activeOpacity={0.8}>
 | 
				
			||||||
        <View style = {{display: 'flex', flexDirection: 'row', alignItems: 'center'}}>
 | 
					        <View style = {[styles.container2, {justifyContent: 'space-between'}]}>
 | 
				
			||||||
          <Image source = {require('./assets/clubs.png')} style = {{height: 40, width: 40, marginRight: 10}}/>
 | 
					          <View style={{display: 'flex', flexDirection: 'row'}}> 
 | 
				
			||||||
          <Text style={styles.title3}>{props.item.name}</Text>
 | 
					            <Ionicons name = "ios-people-circle-outline" size={36} color={'#323232'} style={{marginRight: 15}} />
 | 
				
			||||||
 | 
					            <Text style={[styles.title, {alignSelf:'center'}]}>{props.item.name}</Text>
 | 
				
			||||||
 | 
					          </View>
 | 
				
			||||||
 | 
					          <Image source = {require('./assets/forward.png')} style={{tintColor: '#b2b2b2'}}/>
 | 
				
			||||||
        </View>
 | 
					        </View>
 | 
				
			||||||
        
 | 
					 | 
				
			||||||
      </TouchableOpacity>
 | 
					      </TouchableOpacity>
 | 
				
			||||||
	</View>
 | 
						</View>
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
@ -91,7 +91,14 @@ function Club () {
 | 
				
			|||||||
          name = "Clubs"
 | 
					          name = "Clubs"
 | 
				
			||||||
          component = {Clubs}
 | 
					          component = {Clubs}
 | 
				
			||||||
          options={({
 | 
					          options={({
 | 
				
			||||||
            headerShown: false
 | 
					            headerShown: true,
 | 
				
			||||||
 | 
					            headerTitleStyle:morestyles.headerTitle,
 | 
				
			||||||
 | 
					            headerBackground: ()=>background,
 | 
				
			||||||
 | 
					            //headerleft: null,
 | 
				
			||||||
 | 
					            headerTitleAlign: 'center',
 | 
				
			||||||
 | 
					            headerBackTitleVisible:false,
 | 
				
			||||||
 | 
					            headerTintColor: 'black',
 | 
				
			||||||
 | 
					            title:I18n.t('app.clubs'),
 | 
				
			||||||
          })}
 | 
					          })}
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
        <Stack.Screen 
 | 
					        <Stack.Screen 
 | 
				
			||||||
@ -100,7 +107,10 @@ function Club () {
 | 
				
			|||||||
          options={({route})=>({
 | 
					          options={({route})=>({
 | 
				
			||||||
            title:route.params.name,
 | 
					            title:route.params.name,
 | 
				
			||||||
            headerTitleStyle:[morestyles.headerTitle,{alignSelf:'center'}],
 | 
					            headerTitleStyle:[morestyles.headerTitle,{alignSelf:'center'}],
 | 
				
			||||||
            headerBackground: ()=>background
 | 
					            headerBackground: ()=>background,
 | 
				
			||||||
 | 
					            headerBackTitleVisible:false,
 | 
				
			||||||
 | 
					            headerTintColor: 'black',
 | 
				
			||||||
 | 
					            headerTitleAlign: 'center',
 | 
				
			||||||
          })}
 | 
					          })}
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
      </Stack.Navigator>
 | 
					      </Stack.Navigator>
 | 
				
			||||||
@ -157,7 +167,7 @@ class Clubs extends React.Component {
 | 
				
			|||||||
    const { data , dataSearch,search} = this.state;
 | 
					    const { data , dataSearch,search} = this.state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <SafeAreaView style={styles.container}>
 | 
					      <SafeAreaView style={styles.moreDefault}>
 | 
				
			||||||
        <SearchBar
 | 
					        <SearchBar
 | 
				
			||||||
        lightTheme
 | 
					        lightTheme
 | 
				
			||||||
        placeholder={I18n.t('clubs.searchClubs')}
 | 
					        placeholder={I18n.t('clubs.searchClubs')}
 | 
				
			||||||
@ -170,7 +180,6 @@ class Clubs extends React.Component {
 | 
				
			|||||||
        renderItem={({item}) => <ClubElement item={item} name={item.name} navigation={this.props.navigation}/>}
 | 
					        renderItem={({item}) => <ClubElement item={item} name={item.name} navigation={this.props.navigation}/>}
 | 
				
			||||||
        keyExtractor={item => JSON.stringify(item)}
 | 
					        keyExtractor={item => JSON.stringify(item)}
 | 
				
			||||||
      />
 | 
					      />
 | 
				
			||||||
      
 | 
					 | 
				
			||||||
    </SafeAreaView>
 | 
					    </SafeAreaView>
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										569
									
								
								app/Home.js
									
									
									
									
									
								
							
							
						
						@ -1,36 +0,0 @@
 | 
				
			|||||||
import React, { useState } from 'react';
 | 
					 | 
				
			||||||
import {
 | 
					 | 
				
			||||||
  SafeAreaView,
 | 
					 | 
				
			||||||
  StyleSheet,
 | 
					 | 
				
			||||||
  ScrollView,
 | 
					 | 
				
			||||||
  View,
 | 
					 | 
				
			||||||
  Text,
 | 
					 | 
				
			||||||
  StatusBar,
 | 
					 | 
				
			||||||
  Modal,
 | 
					 | 
				
			||||||
  TouchableHighlight,
 | 
					 | 
				
			||||||
  Image,
 | 
					 | 
				
			||||||
} from 'react-native';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import {
 | 
					 | 
				
			||||||
  Header,
 | 
					 | 
				
			||||||
  LearnMoreLinks,
 | 
					 | 
				
			||||||
  Colors,
 | 
					 | 
				
			||||||
  DebugInstructions,
 | 
					 | 
				
			||||||
  ReloadInstructions,
 | 
					 | 
				
			||||||
} from 'react-native/Libraries/NewAppScreen';
 | 
					 | 
				
			||||||
import styles from './styles/morestyles'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const Images = {
 | 
					 | 
				
			||||||
    sslopps: require('./assets/sslopps.png'),
 | 
					 | 
				
			||||||
    lunch: require('./assets/lunch.png'),
 | 
					 | 
				
			||||||
    settings:require('./assets/settings.png'),
 | 
					 | 
				
			||||||
    challenge:require('./assets/challenge.png'),
 | 
					 | 
				
			||||||
    student:require('./assets/student.png'),
 | 
					 | 
				
			||||||
    announcements:require('./assets/announcements.png'),
 | 
					 | 
				
			||||||
    resources:require('./assets/resources.png'),
 | 
					 | 
				
			||||||
    polls:require('./assets/polls.png'),
 | 
					 | 
				
			||||||
    notifs:require('./assets/notifs.png'),
 | 
					 | 
				
			||||||
    lang:require('./assets/lang.png'),
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default Images;
 | 
					 | 
				
			||||||
@ -2,13 +2,13 @@ import React, { Component } from 'react';
 | 
				
			|||||||
import { DevSettings } from 'react-native';
 | 
					import { DevSettings } from 'react-native';
 | 
				
			||||||
import { Platform, StyleSheet, TouchableOpacity, Text, ScrollView, View } from 'react-native';
 | 
					import { Platform, StyleSheet, TouchableOpacity, Text, ScrollView, View } from 'react-native';
 | 
				
			||||||
import I18n from './i18n';
 | 
					import I18n from './i18n';
 | 
				
			||||||
import AsyncStorage from '@react-native-community/async-storage'
 | 
					import AsyncStorage from '@react-native-async-storage/async-storage'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const STORAGE_KEY = "language"
 | 
					const STORAGE_KEY = "language"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const language = [
 | 
					const language = [
 | 
				
			||||||
      {lang: <Text>{I18n.t('language.English')}</Text>, code: "en"},
 | 
					      {lang: <Text>English</Text>, code: "en-US"},
 | 
				
			||||||
      {lang: <Text>{I18n.t('language.Spanish')}</Text>, code: "es"},
 | 
					      {lang: <Text>Spanish</Text>, code: "es-US"},
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class extends Component {
 | 
					export default class extends Component {
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,20 @@ export default {
 | 
				
			|||||||
        Hobbies: "Hobbies",
 | 
					        Hobbies: "Hobbies",
 | 
				
			||||||
        Achievements: "Achievements",
 | 
					        Achievements: "Achievements",
 | 
				
			||||||
        Messages: "Messages",
 | 
					        Messages: "Messages",
 | 
				
			||||||
        Announcements: "Announcements"
 | 
					        Announcements: "Announcements",
 | 
				
			||||||
 | 
					        noAnnouncements: "No Announcements",
 | 
				
			||||||
 | 
					        lunch: "Lunch Events",
 | 
				
			||||||
 | 
					        news: "News",
 | 
				
			||||||
 | 
					        shortcut: "Shortcut: ",
 | 
				
			||||||
 | 
					        seeLunch: "See Lunch Events",
 | 
				
			||||||
 | 
					        noNews: "No news for today",
 | 
				
			||||||
 | 
					        noAnnouncements: "No announcements for today",
 | 
				
			||||||
 | 
					        moreOn: "More on"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    dates: {
 | 
				
			||||||
 | 
					        today: "Today",
 | 
				
			||||||
 | 
					        past: "Past",
 | 
				
			||||||
 | 
					        future: "Future"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    app: {
 | 
					    app: {
 | 
				
			||||||
        home: "Home",
 | 
					        home: "Home",
 | 
				
			||||||
@ -17,7 +30,12 @@ export default {
 | 
				
			|||||||
        more: "More"
 | 
					        more: "More"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    calendar: {
 | 
					    calendar: {
 | 
				
			||||||
        calendarEvents: "Calendar Events"
 | 
					        calendar: "Calendar",
 | 
				
			||||||
 | 
					        info: "Info",
 | 
				
			||||||
 | 
					        location: "Location",
 | 
				
			||||||
 | 
					        date: "Date",
 | 
				
			||||||
 | 
					        organizer: "Organizer",
 | 
				
			||||||
 | 
					        noEvents: "No Events"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    clubs: {
 | 
					    clubs: {
 | 
				
			||||||
        searchClubs: "Search Clubs"
 | 
					        searchClubs: "Search Clubs"
 | 
				
			||||||
@ -25,12 +43,27 @@ export default {
 | 
				
			|||||||
    staff: {
 | 
					    staff: {
 | 
				
			||||||
        searchStaff: "Search Staff"
 | 
					        searchStaff: "Search Staff"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    announcements: {
 | 
				
			||||||
 | 
					        noAnnouncements: "No Announcements"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    student: {
 | 
					    student: {
 | 
				
			||||||
        Grade: "Grade",
 | 
					        Grade: "Grade",
 | 
				
			||||||
        Hobbies: "Hobbies",
 | 
					        Hobbies: "Hobbies",
 | 
				
			||||||
        Achievements: "Achievements",
 | 
					        Achievements: "Achievements",
 | 
				
			||||||
        Messages: "Messages",
 | 
					        Messages: "Messages",
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    lunch: {
 | 
				
			||||||
 | 
					        information: "Information",
 | 
				
			||||||
 | 
					        location: "Location"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    ssl: {
 | 
				
			||||||
 | 
					        information: "Information",
 | 
				
			||||||
 | 
					        sponsor: "Sponsor",
 | 
				
			||||||
 | 
					        location: "Location"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    challenge: {
 | 
				
			||||||
 | 
					        link: "Link"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    polls: {
 | 
					    polls: {
 | 
				
			||||||
        textInPoll: "Press the image to take the poll!"
 | 
					        textInPoll: "Press the image to take the poll!"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@ -38,7 +71,7 @@ export default {
 | 
				
			|||||||
        Announcements: "Announcements",
 | 
					        Announcements: "Announcements",
 | 
				
			||||||
        Resources: "Resources",
 | 
					        Resources: "Resources",
 | 
				
			||||||
        SOTW: "Student of the Week",
 | 
					        SOTW: "Student of the Week",
 | 
				
			||||||
        lunch: "LunchEvents",
 | 
					        lunch: "Lunch Events",
 | 
				
			||||||
        ssl: "SSL Opportunities",
 | 
					        ssl: "SSL Opportunities",
 | 
				
			||||||
        COTW: "Challenge of the Week",
 | 
					        COTW: "Challenge of the Week",
 | 
				
			||||||
        Polls: "Polls",
 | 
					        Polls: "Polls",
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,20 @@ export default {
 | 
				
			|||||||
        Hobbies: "El pasatiempo",
 | 
					        Hobbies: "El pasatiempo",
 | 
				
			||||||
        Achievements: "Logros",
 | 
					        Achievements: "Logros",
 | 
				
			||||||
        Messages: "Mensajes",
 | 
					        Messages: "Mensajes",
 | 
				
			||||||
        Announcements: "Anuncios"
 | 
					        Announcements: "Anuncios",
 | 
				
			||||||
 | 
					        noAnnouncements: "ESNo Announcements",
 | 
				
			||||||
 | 
					        lunch: "Eventos de almuerzo",
 | 
				
			||||||
 | 
					        news: "ESNews",
 | 
				
			||||||
 | 
					        shortcut: "ESShortcut: ",
 | 
				
			||||||
 | 
					        seeLunch: "ESSee Lunch Events",
 | 
				
			||||||
 | 
					        noNews: "ESNo news for today",
 | 
				
			||||||
 | 
					        noAnnouncements: "ESNo announcements for today",
 | 
				
			||||||
 | 
					        moreOn: "ESMore on"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    dates: {
 | 
				
			||||||
 | 
					        today: "ESToday",
 | 
				
			||||||
 | 
					        past: "ESPast",
 | 
				
			||||||
 | 
					        future: "ESFuture"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    app: {
 | 
					    app: {
 | 
				
			||||||
        home: "Casa",
 | 
					        home: "Casa",
 | 
				
			||||||
@ -17,7 +30,12 @@ export default {
 | 
				
			|||||||
        more: "Más"
 | 
					        more: "Más"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    calendar: {
 | 
					    calendar: {
 | 
				
			||||||
        calendarEvents: "Eventos del calendario"
 | 
					        calendar: "ESCalendar",
 | 
				
			||||||
 | 
					        info: "ESInfo",
 | 
				
			||||||
 | 
					        location: "ESLocation",
 | 
				
			||||||
 | 
					        date: "ESDate",
 | 
				
			||||||
 | 
					        organizer: "ESOrganizer",
 | 
				
			||||||
 | 
					        noEvents: "ESNo Events"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    clubs: {
 | 
					    clubs: {
 | 
				
			||||||
        searchClubs: "Buscar clubes"
 | 
					        searchClubs: "Buscar clubes"
 | 
				
			||||||
@ -25,12 +43,27 @@ export default {
 | 
				
			|||||||
    staff: {
 | 
					    staff: {
 | 
				
			||||||
        searchStaff: "Personal de búsqueda"
 | 
					        searchStaff: "Personal de búsqueda"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    announcements: {
 | 
				
			||||||
 | 
					        noAnnouncements: "ESNo Announcements"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    student: {
 | 
					    student: {
 | 
				
			||||||
        Grade: "El año",
 | 
					        Grade: "El año",
 | 
				
			||||||
        Hobbies: "El pasatiempo",
 | 
					        Hobbies: "El pasatiempo",
 | 
				
			||||||
        Achievements: "Logros",
 | 
					        Achievements: "Logros",
 | 
				
			||||||
        Messages: "Mensajes",
 | 
					        Messages: "Mensajes",
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    lunch: {
 | 
				
			||||||
 | 
					        information: "ESInformation",
 | 
				
			||||||
 | 
					        location: "ESLocation"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    ssl: {
 | 
				
			||||||
 | 
					        information: "ESInformation",
 | 
				
			||||||
 | 
					        sponsor: "ESSponsor",
 | 
				
			||||||
 | 
					        location: "ESLocation"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    challenge: {
 | 
				
			||||||
 | 
					        link: "ESLink"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    polls: {
 | 
					    polls: {
 | 
				
			||||||
        textInPoll: "¡Pulsa la imagen para realizar la encuesta!'"
 | 
					        textInPoll: "¡Pulsa la imagen para realizar la encuesta!'"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
				
			|||||||
@ -9,6 +9,7 @@ import {
 | 
				
			|||||||
  FlatList,
 | 
					  FlatList,
 | 
				
			||||||
  TouchableOpacity,
 | 
					  TouchableOpacity,
 | 
				
			||||||
  Image,
 | 
					  Image,
 | 
				
			||||||
 | 
					  Dimensions
 | 
				
			||||||
} from 'react-native';
 | 
					} from 'react-native';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
@ -22,9 +23,12 @@ import { NavigationContainer } from '@react-navigation/native'
 | 
				
			|||||||
import { createStackNavigator } from '@react-navigation/stack'
 | 
					import { createStackNavigator } from '@react-navigation/stack'
 | 
				
			||||||
import styles from './styles/liststyles'
 | 
					import styles from './styles/liststyles'
 | 
				
			||||||
import { url } from './resources/fetchInfo.json'
 | 
					import { url } from './resources/fetchInfo.json'
 | 
				
			||||||
 | 
					import LinearGradient from 'react-native-linear-gradient';
 | 
				
			||||||
 | 
					import Ionicons from 'react-native-vector-icons/Ionicons';
 | 
				
			||||||
 | 
					import I18n from 'i18n-js';
 | 
				
			||||||
const Stack = createStackNavigator();
 | 
					const Stack = createStackNavigator();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const LunchInfo = ({route}) => {
 | 
					{/*export const LunchInfo = ({route}) => {
 | 
				
			||||||
    const item = route.params;
 | 
					    const item = route.params;
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <View style = {{padding: 10, backgroundColor: 'white', height: '100%'}}>
 | 
					      <View style = {{padding: 10, backgroundColor: 'white', height: '100%'}}>
 | 
				
			||||||
@ -46,17 +50,22 @@ export const LunchInfo = ({route}) => {
 | 
				
			|||||||
        </View>
 | 
					        </View>
 | 
				
			||||||
      </View>
 | 
					      </View>
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
}
 | 
					}*/}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function LunchEvent (props) {
 | 
					function LunchEvent (props) {
 | 
				
			||||||
    const item = props.item
 | 
					    const item = props.item
 | 
				
			||||||
 | 
					    const [expand, setExpand] = useState(false);
 | 
				
			||||||
    return(
 | 
					    return(
 | 
				
			||||||
        <View>
 | 
					        <View>
 | 
				
			||||||
            <TouchableOpacity style={styles.item1} onPress={()=>props.navigation.navigate('LunchInfo', {data:props.data,name:item.title,text:item.text,loc:item.loc})} activeOpacity={0.8}>
 | 
					            <TouchableOpacity style={styles.listItem} onPress={()=>setExpand(!expand)}>
 | 
				
			||||||
            <View style = {{display: 'flex', flexDirection: 'row', alignItems: 'center'}}>
 | 
					                <View style={styles.container2}>
 | 
				
			||||||
                <Image source = {require('./assets/lunch.png')} style = {{height: 40, width: 40, marginRight: 10}}/>
 | 
					                    <Ionicons name="fast-food-outline" size={36} color={'#323232'} style={{marginRight: 15}} />
 | 
				
			||||||
                <Text style={styles.title3}>{item.title}</Text>
 | 
					                    <View style = {styles.accordian}>
 | 
				
			||||||
 | 
					                        <Text style={styles.title}>{item.title}</Text>
 | 
				
			||||||
 | 
					                        {expand?<LinearGradient start={{x: 0, y: 0.25}} end={{x: .5, y: 1}} colors={['red', '#FF7373']} style={{borderRadius: 24, alignSelf: 'center'}}><Image source = {require('./assets/collapse.png')} style={{tintColor: 'white'}}/></LinearGradient>:<Image source = {require('./assets/expand.png')} style={{tintColor: '#b2b2b2', alignSelf: 'center'}}/>}
 | 
				
			||||||
                    </View>
 | 
					                    </View>
 | 
				
			||||||
 | 
					                </View>
 | 
				
			||||||
 | 
					                {expand?<View style={{marginLeft: 50}}><Text style={styles.accordianHeader}>{I18n.t('lunch.information')}</Text><Text style={styles.accordianText}>{item.text}</Text><Text style={styles.accordianHeader}>{'\n'}{I18n.t('lunch.location')}</Text><Text style={[styles.accordianText, {paddingBottom: '4%'}]}>{item.loc}</Text></View>:<></>}
 | 
				
			||||||
            </TouchableOpacity>
 | 
					            </TouchableOpacity>
 | 
				
			||||||
        </View>
 | 
					        </View>
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
@ -89,13 +98,13 @@ class LunchEvents extends React.Component {
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
    render() {
 | 
					    render() {
 | 
				
			||||||
        return (
 | 
					        return (
 | 
				
			||||||
            <View style={styles.container}>
 | 
					            <ScrollView style={styles.moreDefault}>
 | 
				
			||||||
                <FlatList
 | 
					                <FlatList
 | 
				
			||||||
                    data={this.state.data}
 | 
					                    data={this.state.data}
 | 
				
			||||||
                    renderItem={({item}) => <LunchEvent item={item} name={this.props.title} navigation={this.props.navigation}/>}
 | 
					                    renderItem={({item}) => <LunchEvent item={item} name={this.props.title} navigation={this.props.navigation}/>}
 | 
				
			||||||
                    keyExtractor={item=>JSON.stringify(item)}
 | 
					                    keyExtractor={item=>JSON.stringify(item)}
 | 
				
			||||||
                />
 | 
					                />
 | 
				
			||||||
            </View>
 | 
					            </ScrollView>
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										193
									
								
								app/More.js
									
									
									
									
									
								
							
							
						
						@ -9,6 +9,7 @@ import {
 | 
				
			|||||||
  FlatList,
 | 
					  FlatList,
 | 
				
			||||||
  TouchableOpacity,
 | 
					  TouchableOpacity,
 | 
				
			||||||
  Image,
 | 
					  Image,
 | 
				
			||||||
 | 
					  Dimensions
 | 
				
			||||||
} from 'react-native';
 | 
					} from 'react-native';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
@ -20,7 +21,7 @@ import {
 | 
				
			|||||||
} from 'react-native/Libraries/NewAppScreen';
 | 
					} from 'react-native/Libraries/NewAppScreen';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { NavigationContainer } from '@react-navigation/native'
 | 
					import { NavigationContainer } from '@react-navigation/native'
 | 
				
			||||||
import { createStackNavigator } from '@react-navigation/stack'
 | 
					import { createStackNavigator, HeaderBackButton } from '@react-navigation/stack'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import styles from './styles/morestyles'
 | 
					import styles from './styles/morestyles'
 | 
				
			||||||
import Announcements, {TeacherList} from './Announcements'
 | 
					import Announcements, {TeacherList} from './Announcements'
 | 
				
			||||||
@ -29,10 +30,10 @@ import StudentWeek from './StudentWeek'
 | 
				
			|||||||
import SSLOps, {SSLInfo} from './SSLOps'
 | 
					import SSLOps, {SSLInfo} from './SSLOps'
 | 
				
			||||||
import LunchEvents, {LunchInfo} from './LunchEvents'
 | 
					import LunchEvents, {LunchInfo} from './LunchEvents'
 | 
				
			||||||
import ChallengeWeek from './ChallengeWeek'
 | 
					import ChallengeWeek from './ChallengeWeek'
 | 
				
			||||||
import Settings from './Settings'
 | 
					 | 
				
			||||||
import Poll from './Poll'
 | 
					import Poll from './Poll'
 | 
				
			||||||
import Images from './Images'
 | 
					import Language from './Language'
 | 
				
			||||||
import LinearGradient from 'react-native-linear-gradient'
 | 
					import LinearGradient from 'react-native-linear-gradient'
 | 
				
			||||||
 | 
					import Ionicons from 'react-native-vector-icons/Ionicons';
 | 
				
			||||||
import I18n from './i18n';
 | 
					import I18n from './i18n';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Stack = createStackNavigator()
 | 
					const Stack = createStackNavigator()
 | 
				
			||||||
@ -45,23 +46,27 @@ class MoreSwitch extends React.Component {
 | 
				
			|||||||
	
 | 
						
 | 
				
			||||||
	render() {
 | 
						render() {
 | 
				
			||||||
		return (
 | 
							return (
 | 
				
			||||||
			<View style={{flex:1,backgroundColor:'red'}}>
 | 
								<View style={{flex:1,backgroundColor:'white', paddingHorizontal: '5%'}}>
 | 
				
			||||||
				<FlatList
 | 
									<FlatList
 | 
				
			||||||
					data={[
 | 
										data={[
 | 
				
			||||||
						{name:'Announcements',key:"announce", img:Images.announcements},
 | 
											{name:I18n.t("more.Announcements"),key:"announce", img:"megaphone-outline"},
 | 
				
			||||||
						{name:"Resources",key:"resources", img:Images.resources},
 | 
											{name:I18n.t("more.Resources"),key:"resources", img:"newspaper-outline"},
 | 
				
			||||||
						{name:"SOTW",key:"studentweek", img:Images.student},
 | 
											{name:I18n.t("more.SOTW"),key:"studentweek", img:"ribbon-outline"},
 | 
				
			||||||
						{name:"lunch",key:"lunchevent", img:Images.lunch},
 | 
											{name:I18n.t("more.lunch"),key:"lunchevent", img:"fast-food-outline"},
 | 
				
			||||||
						{name:"ssl",key:"sslopps", img:Images.sslopps},
 | 
											{name:I18n.t("more.ssl"),key:"sslopps", img:"school-outline"},
 | 
				
			||||||
						{name:"COTW",key:"challengeweek", img:Images.challenge},
 | 
											{name:I18n.t("more.COTW"),key:"challengeweek", img:"golf-outline"},
 | 
				
			||||||
						{name:"Polls", key:"polls", img: Images.polls},
 | 
											{name:I18n.t("more.Polls"), key:"polls", img: "stats-chart-outline"},
 | 
				
			||||||
						{name:"Settings", key:"settings", img: Images.settings},
 | 
											{name:I18n.t("more.Settings"), key:"settings", img: "settings-outline"},
 | 
				
			||||||
					]}
 | 
										]}
 | 
				
			||||||
					renderItem={({item})=>
 | 
										renderItem={({item})=>
 | 
				
			||||||
						
 | 
											
 | 
				
			||||||
						<TouchableOpacity style={styles.moreitem} onPress={()=>this.props.navigation.navigate(item.key)}>
 | 
											<TouchableOpacity style={styles.moreitem} onPress={()=>this.props.navigation.navigate(item.key)}>
 | 
				
			||||||
							<Image source = {item.img} style = {{height: 40, width: 40, marginRight: 10, tintColor: '#e3e3e3'}}/>
 | 
												<Ionicons name={item.img} size={36} color={'#323232'}style={{marginRight: 15}}/>
 | 
				
			||||||
							<Text style={styles.moretext}>{I18n.t('more.'+item.name)}</Text>
 | 
												<View style={{display: 'flex', flexDirection: 'row', justifyContent: 'space-between', width: '85%'}}>
 | 
				
			||||||
 | 
													<Text style={styles.moretext}>{item.name}</Text>
 | 
				
			||||||
 | 
													<Image source = {require('./assets/forward.png')} style={{tintColor: '#b2b2b2'}}/>
 | 
				
			||||||
 | 
												</View>
 | 
				
			||||||
 | 
												
 | 
				
			||||||
						</TouchableOpacity>
 | 
											</TouchableOpacity>
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				/>
 | 
									/>
 | 
				
			||||||
@ -70,6 +75,35 @@ class MoreSwitch extends React.Component {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SettingSwitch extends React.Component {
 | 
				
			||||||
 | 
						constructor(props) {
 | 
				
			||||||
 | 
							super(props)
 | 
				
			||||||
 | 
							this.props = props
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						render() {
 | 
				
			||||||
 | 
							return (
 | 
				
			||||||
 | 
								<View style={{flex:1,backgroundColor:'white', paddingHorizontal: '5%'}}>
 | 
				
			||||||
 | 
									<FlatList
 | 
				
			||||||
 | 
										data={[
 | 
				
			||||||
 | 
											{name:"Language",key:"language", img:'language-outline'}
 | 
				
			||||||
 | 
										]}
 | 
				
			||||||
 | 
										renderItem={({item})=>
 | 
				
			||||||
 | 
											<TouchableOpacity style={styles.moreitem} onPress={()=>this.props.navigation.navigate(item.key)}>
 | 
				
			||||||
 | 
												<Ionicons name={item.img} size={36} color={'#323232'}style={{marginRight: 15}}/>
 | 
				
			||||||
 | 
												<View style={{display: 'flex', flexDirection: 'row', justifyContent: 'space-between', width: '85%'}}>
 | 
				
			||||||
 | 
													<Text style={styles.moretext}>{I18n.t('settings.' + item.key)}</Text>
 | 
				
			||||||
 | 
													<Image source = {require('./assets/forward.png')} style={{tintColor: '#b2b2b2'}}/>
 | 
				
			||||||
 | 
												</View>
 | 
				
			||||||
 | 
											</TouchableOpacity>
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									/>
 | 
				
			||||||
 | 
								</View>
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const background = (<LinearGradient
 | 
					const background = (<LinearGradient
 | 
				
			||||||
                    colors={['#f99', 'white']}
 | 
					                    colors={['#f99', 'white']}
 | 
				
			||||||
                    style = {{flex:1,borderBottomColor:'black',borderBottomWidth:0.5}}
 | 
					                    style = {{flex:1,borderBottomColor:'black',borderBottomWidth:0.5}}
 | 
				
			||||||
@ -84,119 +118,140 @@ class More extends React.Component {
 | 
				
			|||||||
						name="Chooser" 
 | 
											name="Chooser" 
 | 
				
			||||||
						component={MoreSwitch}
 | 
											component={MoreSwitch}
 | 
				
			||||||
						options={{
 | 
											options={{
 | 
				
			||||||
							title:I18n.t('more.More'),
 | 
												title:I18n.t("more.More"),
 | 
				
			||||||
							headerTitleStyle:styles.headerTitle,
 | 
												headerTitleStyle:styles.headerTitle,
 | 
				
			||||||
							headerBackground: ()=>background
 | 
												headerBackground: ()=>background,
 | 
				
			||||||
 | 
												headerTitleAlign: 'center'
 | 
				
			||||||
						}}
 | 
											}}
 | 
				
			||||||
					/>
 | 
										/>
 | 
				
			||||||
					<Stack.Screen 
 | 
										<Stack.Screen 
 | 
				
			||||||
						name="announce" 
 | 
											name="announce" 
 | 
				
			||||||
						component={Announcements}
 | 
											component={Announcements}
 | 
				
			||||||
						options={{
 | 
											options={{
 | 
				
			||||||
							title:I18n.t('more.Announcements'),
 | 
												title:I18n.t("more.Announcements"),
 | 
				
			||||||
							headerTitleStyle:[styles.headerTitle,{alignSelf:'center'}],
 | 
												headerTitleStyle:[styles.headerTitle],
 | 
				
			||||||
							headerLeft:null,
 | 
												headerBackground: ()=>background,
 | 
				
			||||||
							headerBackground: ()=>background
 | 
												headerTitleAlign: 'center',
 | 
				
			||||||
 | 
												headerBackTitleVisible:false,
 | 
				
			||||||
 | 
												headerTintColor: 'black'
 | 
				
			||||||
						}}
 | 
											}}
 | 
				
			||||||
					/>
 | 
										/>
 | 
				
			||||||
					<Stack.Screen 
 | 
										<Stack.Screen 
 | 
				
			||||||
						name="resources" 
 | 
											name="resources" 
 | 
				
			||||||
						component={Resources}
 | 
											component={Resources}
 | 
				
			||||||
						options={{
 | 
											options={{
 | 
				
			||||||
							title:I18n.t('more.Resources'),
 | 
												title:I18n.t("more.Resources"),
 | 
				
			||||||
							headerTitleStyle:[styles.headerTitle,{alignSelf:'center'}],
 | 
												headerTitleStyle:styles.headerTitle,
 | 
				
			||||||
							headerLeft:null,
 | 
												//headerLeft:null,
 | 
				
			||||||
							headerBackground: ()=>background
 | 
												headerBackground: ()=>background,
 | 
				
			||||||
 | 
												headerTitleAlign: 'center',
 | 
				
			||||||
 | 
												headerBackTitleVisible:false,
 | 
				
			||||||
 | 
												headerTintColor: 'black'
 | 
				
			||||||
						}}
 | 
											}}
 | 
				
			||||||
					/>
 | 
										/>
 | 
				
			||||||
					<Stack.Screen 
 | 
										<Stack.Screen 
 | 
				
			||||||
						name="studentweek" 
 | 
											name="studentweek" 
 | 
				
			||||||
						component={StudentWeek}
 | 
											component={StudentWeek}
 | 
				
			||||||
						options={{
 | 
											options={{
 | 
				
			||||||
							title:I18n.t('more.SOTW'),
 | 
												title:I18n.t("more.SOTW"),
 | 
				
			||||||
							headerTitleStyle:[styles.headerTitle,{alignSelf:'center'}],
 | 
												headerTitleStyle:styles.headerTitle,
 | 
				
			||||||
							headerLeft:null,
 | 
												//headerLeft:null,
 | 
				
			||||||
							headerBackground: ()=>background
 | 
												headerBackground: ()=>background,
 | 
				
			||||||
 | 
												headerTitleAlign: 'center',
 | 
				
			||||||
 | 
												headerBackTitleVisible:false,
 | 
				
			||||||
 | 
												headerTintColor: 'black'
 | 
				
			||||||
						}}
 | 
											}}
 | 
				
			||||||
					/>
 | 
										/>
 | 
				
			||||||
					<Stack.Screen 
 | 
										<Stack.Screen 
 | 
				
			||||||
						name="lunchevent" 
 | 
											name="lunchevent" 
 | 
				
			||||||
						component={LunchEvents}
 | 
											component={LunchEvents}
 | 
				
			||||||
						options={{
 | 
											options={{
 | 
				
			||||||
							title:I18n.t('more.lunch'),
 | 
												title:I18n.t("more.lunch"),
 | 
				
			||||||
							headerTitleStyle:[styles.headerTitle,{alignSelf:'center'}],
 | 
												headerTitleStyle:styles.headerTitle,
 | 
				
			||||||
							headerLeft:null,
 | 
												//headerLeft:null,
 | 
				
			||||||
							headerBackground: ()=>background
 | 
												headerBackground: ()=>background,
 | 
				
			||||||
 | 
												headerTitleAlign: 'center',
 | 
				
			||||||
 | 
												headerBackTitleVisible:false,
 | 
				
			||||||
 | 
												headerTintColor: 'black'
 | 
				
			||||||
						}}
 | 
											}}
 | 
				
			||||||
					/>
 | 
										/>
 | 
				
			||||||
					<Stack.Screen 
 | 
										<Stack.Screen 
 | 
				
			||||||
						name="sslopps" 
 | 
											name="sslopps" 
 | 
				
			||||||
						component={SSLOps}
 | 
											component={SSLOps}
 | 
				
			||||||
						options={{
 | 
											options={{
 | 
				
			||||||
							title:I18n.t('more.ssl'),
 | 
												title:I18n.t("more.ssl"),
 | 
				
			||||||
							headerTitleStyle:[styles.headerTitle,{alignSelf:'center'}],
 | 
												headerTitleStyle:styles.headerTitle,
 | 
				
			||||||
							headerLeft:null,
 | 
												//headerLeft:null,
 | 
				
			||||||
							headerBackground: ()=>background
 | 
												headerBackground: ()=>background,
 | 
				
			||||||
 | 
												headerTitleAlign: 'center',
 | 
				
			||||||
 | 
												headerBackTitleVisible:false,
 | 
				
			||||||
 | 
												headerTintColor: 'black'
 | 
				
			||||||
						}}
 | 
											}}
 | 
				
			||||||
					/>
 | 
										/>
 | 
				
			||||||
					<Stack.Screen 
 | 
										<Stack.Screen 
 | 
				
			||||||
						name="challengeweek" 
 | 
											name="challengeweek" 
 | 
				
			||||||
						component={ChallengeWeek}
 | 
											component={ChallengeWeek}
 | 
				
			||||||
						options={{
 | 
											options={{
 | 
				
			||||||
							title:I18n.t('more.COTW'),
 | 
												title:I18n.t("more.COTW"),
 | 
				
			||||||
							headerTitleStyle:[styles.headerTitle,{alignSelf:'center'}],
 | 
												headerTitleStyle:styles.headerTitle,
 | 
				
			||||||
							headerLeft:null,
 | 
												//headerLeft:null,
 | 
				
			||||||
							headerBackground: ()=>background
 | 
												headerBackground: ()=>background,
 | 
				
			||||||
 | 
												headerTitleAlign: 'center',
 | 
				
			||||||
 | 
												headerBackTitleVisible:false,
 | 
				
			||||||
 | 
												headerTintColor: 'black'
 | 
				
			||||||
						}}
 | 
											}}
 | 
				
			||||||
					/>
 | 
										/>
 | 
				
			||||||
					<Stack.Screen 
 | 
										<Stack.Screen 
 | 
				
			||||||
						name="polls" 
 | 
											name="polls" 
 | 
				
			||||||
						component={Poll}
 | 
											component={Poll}
 | 
				
			||||||
						options={{
 | 
											options={{
 | 
				
			||||||
							title:I18n.t('more.Polls'),
 | 
												title:I18n.t("more.Polls"),
 | 
				
			||||||
							headerTitleStyle:[styles.headerTitle,{alignSelf:'center'}],
 | 
												headerTitleStyle:styles.headerTitle,
 | 
				
			||||||
							headerLeft:null,
 | 
												//headerLeft:null,
 | 
				
			||||||
							headerBackground: ()=>background
 | 
												headerBackground: ()=>background,
 | 
				
			||||||
 | 
												headerTitleAlign: 'center',
 | 
				
			||||||
 | 
												headerBackTitleVisible:false,
 | 
				
			||||||
 | 
												headerTintColor: 'black'
 | 
				
			||||||
						}}
 | 
											}}
 | 
				
			||||||
					/>
 | 
										/>
 | 
				
			||||||
					<Stack.Screen 
 | 
										<Stack.Screen 
 | 
				
			||||||
						name="settings" 
 | 
											name="settings" 
 | 
				
			||||||
						component={Settings}
 | 
											component={SettingSwitch}
 | 
				
			||||||
						options={{
 | 
											options={{
 | 
				
			||||||
							title:I18n.t('more.Settings'),
 | 
												title:I18n.t("more.Settings"),
 | 
				
			||||||
 | 
												headerTitleStyle:[styles.headerTitle],
 | 
				
			||||||
 | 
												//headerLeft:null,
 | 
				
			||||||
 | 
												headerBackground: ()=>background,
 | 
				
			||||||
 | 
												headerBackTitleVisible:false,
 | 
				
			||||||
 | 
												headerTintColor: 'black',
 | 
				
			||||||
 | 
												headerTitleAlign: 'center'
 | 
				
			||||||
 | 
											}}
 | 
				
			||||||
 | 
										/>
 | 
				
			||||||
 | 
										<Stack.Screen 
 | 
				
			||||||
 | 
											name="language" 
 | 
				
			||||||
 | 
											component={Language}
 | 
				
			||||||
 | 
											options={{
 | 
				
			||||||
 | 
												title:I18n.t("settings.language"),
 | 
				
			||||||
							headerTitleStyle:[styles.headerTitle,{alignSelf:'center'}],
 | 
												headerTitleStyle:[styles.headerTitle,{alignSelf:'center'}],
 | 
				
			||||||
							headerLeft:null,
 | 
												headerBackground: ()=>background,
 | 
				
			||||||
							headerBackground: ()=>background
 | 
												//headerLeft: null,
 | 
				
			||||||
 | 
												headerBackTitleVisible:false,
 | 
				
			||||||
 | 
												headerTintColor: 'black',
 | 
				
			||||||
 | 
												headerTitleAlign: 'center'
 | 
				
			||||||
						}}
 | 
											}}
 | 
				
			||||||
					/>
 | 
										/>
 | 
				
			||||||
					<Stack.Screen 
 | 
										<Stack.Screen 
 | 
				
			||||||
						name="TeacherList" 
 | 
											name="TeacherList" 
 | 
				
			||||||
						component={TeacherList}
 | 
											component={TeacherList}
 | 
				
			||||||
						options={({route})=>({
 | 
											options={({route})=>({
 | 
				
			||||||
							headerTitleStyle:[styles.headerTitle,{alignSelf:'center',fontSize:Math.min(24,24*23/route.params.name.length)}],
 | 
												headerTitleStyle:[styles.headerTitle],
 | 
				
			||||||
							title:route.params.name,
 | 
												title:route.params.name,
 | 
				
			||||||
							headerRight:()=>(<></>),
 | 
												headerRight:()=>(<></>),
 | 
				
			||||||
							headerBackground: ()=>background
 | 
					 | 
				
			||||||
						})}
 | 
					 | 
				
			||||||
					/>
 | 
					 | 
				
			||||||
					<Stack.Screen 
 | 
					 | 
				
			||||||
						name="LunchInfo" 
 | 
					 | 
				
			||||||
						component={LunchInfo}
 | 
					 | 
				
			||||||
						options={({route})=>({
 | 
					 | 
				
			||||||
							headerTitleStyle:[styles.headerTitle,{alignSelf:'center',fontSize:Math.min(24,24*23/route.params.name.length)}],
 | 
					 | 
				
			||||||
							title:route.params.name,
 | 
					 | 
				
			||||||
							headerRight:()=>(<></>),
 | 
					 | 
				
			||||||
							headerBackground: ()=>background
 | 
					 | 
				
			||||||
						})}
 | 
					 | 
				
			||||||
					/>
 | 
					 | 
				
			||||||
					<Stack.Screen 
 | 
					 | 
				
			||||||
						name="SSLInfo" 
 | 
					 | 
				
			||||||
						component={SSLInfo}
 | 
					 | 
				
			||||||
						options={({route})=>({
 | 
					 | 
				
			||||||
							headerTitleStyle:[styles.headerTitle,{alignSelf:'center',fontSize:Math.min(24,24*23/route.params.name.length)}],
 | 
					 | 
				
			||||||
							title:route.params.name,
 | 
					 | 
				
			||||||
							headerBackground: ()=>background,
 | 
												headerBackground: ()=>background,
 | 
				
			||||||
							headerRight:()=>(<></>)
 | 
												headerBackTitleVisible:false,
 | 
				
			||||||
 | 
												headerTintColor: 'black',
 | 
				
			||||||
 | 
												headerTitleAlign: 'center'
 | 
				
			||||||
 | 
												//headerLeft: null,
 | 
				
			||||||
						})}
 | 
											})}
 | 
				
			||||||
					/>
 | 
										/>
 | 
				
			||||||
				</Stack.Navigator>
 | 
									</Stack.Navigator>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
import React, { Component, useState } from 'react';
 | 
					/*import React, { Component, useState } from 'react';
 | 
				
			||||||
import { 
 | 
					import { 
 | 
				
			||||||
    Platform, 
 | 
					    Platform, 
 | 
				
			||||||
    StyleSheet, 
 | 
					    StyleSheet, 
 | 
				
			||||||
@ -119,4 +119,4 @@ class Notifications extends Component {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Notifications
 | 
					export default Notifications*/
 | 
				
			||||||
							
								
								
									
										44
									
								
								app/Poll.js
									
									
									
									
									
								
							
							
						
						@ -1,4 +1,4 @@
 | 
				
			|||||||
import React from 'react';
 | 
					/*import React from 'react';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  SafeAreaView,
 | 
					  SafeAreaView,
 | 
				
			||||||
  StyleSheet,
 | 
					  StyleSheet,
 | 
				
			||||||
@ -21,7 +21,7 @@ import {WebView} from 'react-native-webview';
 | 
				
			|||||||
import LinearGradient from 'react-native-linear-gradient';
 | 
					import LinearGradient from 'react-native-linear-gradient';
 | 
				
			||||||
import { Linking } from 'react-native';
 | 
					import { Linking } from 'react-native';
 | 
				
			||||||
import { url } from './resources/fetchInfo.json'
 | 
					import { url } from './resources/fetchInfo.json'
 | 
				
			||||||
import I18n from './i18n';
 | 
					//import I18n from './i18n';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Poll extends React.Component {
 | 
					class Poll extends React.Component {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -47,7 +47,7 @@ componentDidMount() {
 | 
				
			|||||||
    })
 | 
					    })
 | 
				
			||||||
    .catch((error) => console.error(error))
 | 
					    .catch((error) => console.error(error))
 | 
				
			||||||
}*/
 | 
					}*/
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
	render() {
 | 
						render() {
 | 
				
			||||||
		return (
 | 
							return (
 | 
				
			||||||
      <View style = {{backgroundColor: 'white'}}>
 | 
					      <View style = {{backgroundColor: 'white'}}>
 | 
				
			||||||
@ -55,11 +55,47 @@ componentDidMount() {
 | 
				
			|||||||
          <TouchableOpacity  onPress={()=>Linking.openURL("https://google.com")}>
 | 
					          <TouchableOpacity  onPress={()=>Linking.openURL("https://google.com")}>
 | 
				
			||||||
            <Image source={require('./assets/polls.png')} style={{marginTop: 50, height: 300, width: 300, tintColor: 'red'}}/>
 | 
					            <Image source={require('./assets/polls.png')} style={{marginTop: 50, height: 300, width: 300, tintColor: 'red'}}/>
 | 
				
			||||||
          </TouchableOpacity>
 | 
					          </TouchableOpacity>
 | 
				
			||||||
          <Text style ={{fontSize: 20, marginTop: 30}}>{I18n.t('polls.textInPoll')}</Text>
 | 
					          <Text style ={{fontSize: 20, marginTop: 30}}>Take A Poll!</Text>
 | 
				
			||||||
        </View>
 | 
					        </View>
 | 
				
			||||||
      </View>
 | 
					      </View>
 | 
				
			||||||
		)
 | 
							)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default Poll;*/
 | 
				
			||||||
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  SafeAreaView,
 | 
				
			||||||
 | 
					  StyleSheet,
 | 
				
			||||||
 | 
					  ScrollView,
 | 
				
			||||||
 | 
					  View,
 | 
				
			||||||
 | 
					  Text,
 | 
				
			||||||
 | 
					  StatusBar,
 | 
				
			||||||
 | 
					} from 'react-native';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  Header,
 | 
				
			||||||
 | 
					  LearnMoreLinks,
 | 
				
			||||||
 | 
					  Colors,
 | 
				
			||||||
 | 
					  DebugInstructions,
 | 
				
			||||||
 | 
					  ReloadInstructions,
 | 
				
			||||||
 | 
					} from 'react-native/Libraries/NewAppScreen';
 | 
				
			||||||
 | 
					import {WebView} from 'react-native-webview';
 | 
				
			||||||
 | 
					class Poll extends React.Component {
 | 
				
			||||||
 | 
						render() {
 | 
				
			||||||
 | 
							return (
 | 
				
			||||||
 | 
								<WebView
 | 
				
			||||||
 | 
					        source = {{uri: 'https://docs.google.com/forms/d/e/1FAIpQLSfR0XP2yo3TV3egz7aMok56wnP9kG4FQt2v3rHrrayf8uC7Vw/viewform?usp=sf_link'}}
 | 
				
			||||||
 | 
					        javaScriptEnabled={true}
 | 
				
			||||||
 | 
					        domStorageEnabled={true}
 | 
				
			||||||
 | 
					        startInLoadingState={true}
 | 
				
			||||||
 | 
					        style={{marginTop: 0}}
 | 
				
			||||||
 | 
					        cacheEnabled={true}
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					      />
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default Poll;
 | 
					export default Poll;
 | 
				
			||||||
@ -8,7 +8,8 @@ import {
 | 
				
			|||||||
  StatusBar,
 | 
					  StatusBar,
 | 
				
			||||||
  Linking,
 | 
					  Linking,
 | 
				
			||||||
  Image,
 | 
					  Image,
 | 
				
			||||||
  TouchableOpacity
 | 
					  TouchableOpacity,
 | 
				
			||||||
 | 
					  Dimensions
 | 
				
			||||||
} from 'react-native';
 | 
					} from 'react-native';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
@ -20,12 +21,16 @@ import {
 | 
				
			|||||||
} from 'react-native/Libraries/NewAppScreen';
 | 
					} from 'react-native/Libraries/NewAppScreen';
 | 
				
			||||||
import styles from './styles/morestyles';
 | 
					import styles from './styles/morestyles';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const windowWidth = Dimensions.get('window').width*.80/3.5;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function ResourceLink(props) { 
 | 
					function ResourceLink(props) { 
 | 
				
			||||||
	return (
 | 
						return (
 | 
				
			||||||
		<TouchableOpacity style={styles.resourceContainer} onPress={() => Linking.openURL(props.url)}>
 | 
							<TouchableOpacity style={styles.resourceContainer, {paddingHorizontal: '5%', paddingBottom: '5%'}} onPress={() => Linking.openURL(props.url)}>
 | 
				
			||||||
          <Image source={props.img} style={styles.image}/>
 | 
					      <View style={{display: 'flex', textAlign: 'center', width: windowWidth}}>
 | 
				
			||||||
		      <View style={styles.textContainer}>
 | 
					        <View style={{aspectRatio: 1}}>
 | 
				
			||||||
            <Text style={styles.resourceText}>{props.name}</Text> 
 | 
					          <Image source={props.img} style={{width: '100%', height: '100%', borderRadius: 30}}/>
 | 
				
			||||||
 | 
					        </View>
 | 
				
			||||||
 | 
					        <Text style={{color: 'black', alignSelf: 'center', textAlign: 'center', marginTop: '2%', fontSize: 16}}>{props.name}</Text>
 | 
				
			||||||
      </View>
 | 
					      </View>
 | 
				
			||||||
    </TouchableOpacity>
 | 
					    </TouchableOpacity>
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
@ -35,12 +40,18 @@ class Resources extends React.Component {
 | 
				
			|||||||
	render() {
 | 
						render() {
 | 
				
			||||||
		return (
 | 
							return (
 | 
				
			||||||
      <ScrollView style = {{backgroundColor: 'white'}}>
 | 
					      <ScrollView style = {{backgroundColor: 'white'}}>
 | 
				
			||||||
				<ResourceLink url='https://classroom.mcpsmd.org/' img={require('./assets/canvaslogo.png')} name='MyMCPS Classroom'/>
 | 
					        <View style = {{display: 'flex', flexDirection: 'row', flexWrap: 'wrap', paddingVertical: '5%'}}>
 | 
				
			||||||
				<ResourceLink url='https://md-mcps-psv.edupoint.com/Home_PXP2.aspx' img={require('./assets/studentvue.jpg')} name='StudentVUE'/>
 | 
					          <ResourceLink url='https://classroom.mcpsmd.org/' img={require('./assets/canvas.jpeg')} name='MyMCPS Classroom'/>
 | 
				
			||||||
 | 
					          <ResourceLink url='https://md-mcps-psv.edupoint.com/Home_PXP2.aspx' img={require('./assets/studentvue.png')} name='StudentVUE'/>
 | 
				
			||||||
          <ResourceLink url='https://student.naviance.com/mbhs' img={require('./assets/naviance.png')} name='Naviance'/>
 | 
					          <ResourceLink url='https://student.naviance.com/mbhs' img={require('./assets/naviance.png')} name='Naviance'/>
 | 
				
			||||||
				<ResourceLink url='https://blairblazersathletics.com/' img={require('./assets/athletics.jpg')} name='Blair Athletics'/>
 | 
					          <ResourceLink url='https://classroom.google.com/u/0/h' img={require('./assets/gc.png')} name='Google Classroom'/>
 | 
				
			||||||
				<ResourceLink url='https://classroom.google.com/u/0/h' img={require('./assets/googleclassroom.jpg')} name='Google Classroom'/>
 | 
					          <ResourceLink url='https://mbhs.edu/' img={require('./assets/blair_logo.png')} name='MBHS'/>
 | 
				
			||||||
 | 
					          <ResourceLink url='https://sites.google.com/mcpsmd.net/mbhs-schoolcounseling-team/home/mbhs-school-counseling-team' img={require('./assets/counselor.jpeg')} name='Counseling Team'/>
 | 
				
			||||||
 | 
					          <ResourceLink url='http://bnconline.net/c/infoflow/' img={require('./assets/infoflow.jpeg')} name='Infoflow'/>
 | 
				
			||||||
 | 
					          <ResourceLink url='https://silverchips.mbhs.edu/' img={require('./assets/sco.jpeg')} name='Silver Chips Online'/>
 | 
				
			||||||
 | 
								  </View>
 | 
				
			||||||
      </ScrollView>
 | 
					      </ScrollView>
 | 
				
			||||||
 | 
								
 | 
				
			||||||
		)
 | 
							)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -9,6 +9,7 @@ import {
 | 
				
			|||||||
  FlatList,
 | 
					  FlatList,
 | 
				
			||||||
  TouchableOpacity,
 | 
					  TouchableOpacity,
 | 
				
			||||||
  Image,
 | 
					  Image,
 | 
				
			||||||
 | 
					  Dimensions
 | 
				
			||||||
} from 'react-native';
 | 
					} from 'react-native';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
@ -22,11 +23,13 @@ import { NavigationContainer } from '@react-navigation/native'
 | 
				
			|||||||
import { createStackNavigator } from '@react-navigation/stack'
 | 
					import { createStackNavigator } from '@react-navigation/stack'
 | 
				
			||||||
import styles from './styles/liststyles';
 | 
					import styles from './styles/liststyles';
 | 
				
			||||||
import { url } from './resources/fetchInfo.json';
 | 
					import { url } from './resources/fetchInfo.json';
 | 
				
			||||||
 | 
					import LinearGradient from 'react-native-linear-gradient';
 | 
				
			||||||
 | 
					import Ionicons from 'react-native-vector-icons/Ionicons';
 | 
				
			||||||
import I18n from './i18n';
 | 
					import I18n from './i18n';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const Stack = createStackNavigator();
 | 
					const Stack = createStackNavigator();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const SSLInfo = ({route}) => {
 | 
					{/*export const SSLInfo = ({route}) => {
 | 
				
			||||||
	const item = route.params;
 | 
						const item = route.params;
 | 
				
			||||||
	console
 | 
						console
 | 
				
			||||||
	return (
 | 
						return (
 | 
				
			||||||
@ -57,17 +60,22 @@ export const SSLInfo = ({route}) => {
 | 
				
			|||||||
			</View>
 | 
								</View>
 | 
				
			||||||
		</View>
 | 
							</View>
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
  }
 | 
					  }*/}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function SSLElement (props) {
 | 
					function SSLElement (props) {
 | 
				
			||||||
	const item = props.item;
 | 
						const item = props.item;
 | 
				
			||||||
 | 
						const [expand, setExpand] = useState(false);
 | 
				
			||||||
	return(
 | 
						return(
 | 
				
			||||||
		<View>
 | 
							<View>
 | 
				
			||||||
			<TouchableOpacity style={styles.item1} onPress={()=>props.navigation.navigate('SSLInfo', {data: props.data, name: item.item.title, text: item.item.text, loc:item.item.loc, teacher: item.item.teacher})} activeOpacity={0.8}>
 | 
								<TouchableOpacity style={styles.listItem} onPress={()=>setExpand(!expand)}>
 | 
				
			||||||
				<View style = {{display: 'flex', flexDirection: 'row', alignItems: 'center'}}>
 | 
									<View style = {styles.container2}>
 | 
				
			||||||
					<Image source = {require('./assets/sslopps.png')} style = {{height: 40, width: 40, marginRight: 10}}/>
 | 
										<Ionicons name="school-outline" size={36} color={'#323232'} style={{marginRight: 15}} />
 | 
				
			||||||
					<Text style={styles.title3}>{item.item.title}</Text>
 | 
										<View style = {styles.accordian}>
 | 
				
			||||||
 | 
					                        <Text style={styles.title}>{item.item.title}</Text>
 | 
				
			||||||
 | 
					                        {expand?<LinearGradient start={{x: 0, y: 0.25}} end={{x: .5, y: 1}} colors={['red', '#FF7373']} style={{borderRadius: 24, alignSelf: 'center'}}><Image source = {require('./assets/collapse.png')} style={{tintColor: 'white'}}/></LinearGradient>:<Image source = {require('./assets/expand.png')} style={{tintColor: '#b2b2b2', alignSelf: 'center'}}/>}
 | 
				
			||||||
                    </View>
 | 
					                    </View>
 | 
				
			||||||
 | 
									</View>
 | 
				
			||||||
 | 
									{expand?<View style={{marginLeft: 50}}><Text style={styles.accordianHeader}>{I18n.t('ssl.information')}</Text><Text style={styles.accordianText}>{item.item.text}</Text><Text style={styles.accordianHeader}>{'\n'}{I18n.t('ssl.sponsor')}</Text><Text style={styles.accordianText}>{item.item.teacher}</Text><Text style={styles.accordianHeader}>{'\n'}{I18n.t('ssl.location')}</Text><Text style={[styles.accordianText, {paddingBottom: '4%'}]}>{item.item.loc}</Text></View>:<></>}
 | 
				
			||||||
			</TouchableOpacity>
 | 
								</TouchableOpacity>
 | 
				
			||||||
		</View>
 | 
							</View>
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
@ -100,13 +108,14 @@ class SSLOps extends React.Component {
 | 
				
			|||||||
	
 | 
						
 | 
				
			||||||
	render() {
 | 
						render() {
 | 
				
			||||||
		return (
 | 
							return (
 | 
				
			||||||
			<View style={styles.container}>
 | 
								<ScrollView style={styles.moreDefault}>
 | 
				
			||||||
				<FlatList
 | 
									<FlatList
 | 
				
			||||||
					data={this.state.data}
 | 
										data={this.state.data}
 | 
				
			||||||
					renderItem={item=><SSLElement item={item} name={item.title} navigation={this.props.navigation}/>}
 | 
										renderItem={item=><SSLElement item={item} name={item.title} navigation={this.props.navigation}/>}
 | 
				
			||||||
					keyExtractor={item=>JSON.stringify(item)}
 | 
										keyExtractor={item=>JSON.stringify(item)}
 | 
				
			||||||
				/>
 | 
									/>
 | 
				
			||||||
			</View>
 | 
								</ScrollView>
 | 
				
			||||||
 | 
								
 | 
				
			||||||
		)
 | 
							)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										106
									
								
								app/Settings.js
									
									
									
									
									
								
							
							
						
						@ -1,106 +0,0 @@
 | 
				
			|||||||
import React from 'react';
 | 
					 | 
				
			||||||
import {
 | 
					 | 
				
			||||||
  SafeAreaView,
 | 
					 | 
				
			||||||
  StyleSheet,
 | 
					 | 
				
			||||||
  ScrollView,
 | 
					 | 
				
			||||||
  View,
 | 
					 | 
				
			||||||
  Text,
 | 
					 | 
				
			||||||
  StatusBar,
 | 
					 | 
				
			||||||
  Modal,
 | 
					 | 
				
			||||||
  TouchableHighlight,
 | 
					 | 
				
			||||||
  Image,
 | 
					 | 
				
			||||||
  FlatList,
 | 
					 | 
				
			||||||
  TouchableOpacity,
 | 
					 | 
				
			||||||
} from 'react-native';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import {
 | 
					 | 
				
			||||||
  Header,
 | 
					 | 
				
			||||||
  LearnMoreLinks,
 | 
					 | 
				
			||||||
  Colors,
 | 
					 | 
				
			||||||
  DebugInstructions,
 | 
					 | 
				
			||||||
  ReloadInstructions,
 | 
					 | 
				
			||||||
} from 'react-native/Libraries/NewAppScreen';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import styles from './styles/morestyles'
 | 
					 | 
				
			||||||
import LinearGradient from 'react-native-linear-gradient'
 | 
					 | 
				
			||||||
import Images from './Images'
 | 
					 | 
				
			||||||
import { NavigationContainer } from '@react-navigation/native'
 | 
					 | 
				
			||||||
import { createStackNavigator } from '@react-navigation/stack'
 | 
					 | 
				
			||||||
import I18n from './i18n';
 | 
					 | 
				
			||||||
import Language from './Language'
 | 
					 | 
				
			||||||
import Notifications from './Notifications'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const Stack = createStackNavigator()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class SettingSwitch extends React.Component {
 | 
					 | 
				
			||||||
	constructor(props) {
 | 
					 | 
				
			||||||
		super(props)
 | 
					 | 
				
			||||||
		this.props = props
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	render() {
 | 
					 | 
				
			||||||
		return (
 | 
					 | 
				
			||||||
			<View style={{flex:1,backgroundColor:'red'}}>
 | 
					 | 
				
			||||||
				<FlatList
 | 
					 | 
				
			||||||
					data={[
 | 
					 | 
				
			||||||
						{name:"Language",key:"language", img:Images.lang},
 | 
					 | 
				
			||||||
						{name:"Notifications",key:"notifications", img:Images.notifs},
 | 
					 | 
				
			||||||
					]}
 | 
					 | 
				
			||||||
					renderItem={({item})=>
 | 
					 | 
				
			||||||
						<TouchableOpacity style={styles.moreitem} onPress={()=>this.props.navigation.navigate(item.key)}>
 | 
					 | 
				
			||||||
							<Image source = {item.img} style = {{height: 40, width: 40, marginRight: 10, tintColor: '#e3e3e3'}}/>
 | 
					 | 
				
			||||||
							<Text style={styles.moretext}>{I18n.t('settings.' + item.key)}</Text>
 | 
					 | 
				
			||||||
						</TouchableOpacity>
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				/>
 | 
					 | 
				
			||||||
			</View>
 | 
					 | 
				
			||||||
		)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const background = (<LinearGradient
 | 
					 | 
				
			||||||
                    colors={['#f99', 'white']}
 | 
					 | 
				
			||||||
                    style = {{flex:1,borderBottomColor:'black',borderBottomWidth:0.5}}
 | 
					 | 
				
			||||||
                    />)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Settings extends React.Component {
 | 
					 | 
				
			||||||
	render() {
 | 
					 | 
				
			||||||
		return (
 | 
					 | 
				
			||||||
			<NavigationContainer independent={true}>
 | 
					 | 
				
			||||||
				<Stack.Navigator>
 | 
					 | 
				
			||||||
					<Stack.Screen 
 | 
					 | 
				
			||||||
						name="Chooser" 
 | 
					 | 
				
			||||||
						component={SettingSwitch}
 | 
					 | 
				
			||||||
						options={{
 | 
					 | 
				
			||||||
							title:'Settings',
 | 
					 | 
				
			||||||
							headerTitleStyle:styles.headerTitle,
 | 
					 | 
				
			||||||
							headerBackground: ()=>background
 | 
					 | 
				
			||||||
						}}
 | 
					 | 
				
			||||||
					/>
 | 
					 | 
				
			||||||
					<Stack.Screen 
 | 
					 | 
				
			||||||
						name="language" 
 | 
					 | 
				
			||||||
						component={Language}
 | 
					 | 
				
			||||||
						options={{
 | 
					 | 
				
			||||||
							title:'Language',
 | 
					 | 
				
			||||||
							headerTitleStyle:[styles.headerTitle,{alignSelf:'center'}],
 | 
					 | 
				
			||||||
							headerLeft:null,
 | 
					 | 
				
			||||||
							headerBackground: ()=>background
 | 
					 | 
				
			||||||
						}}
 | 
					 | 
				
			||||||
					/>
 | 
					 | 
				
			||||||
					<Stack.Screen 
 | 
					 | 
				
			||||||
						name="notifications" 
 | 
					 | 
				
			||||||
						component={Notifications}
 | 
					 | 
				
			||||||
						options={{
 | 
					 | 
				
			||||||
							title:'Notifications',
 | 
					 | 
				
			||||||
							headerTitleStyle:[styles.headerTitle,{alignSelf:'center'}],
 | 
					 | 
				
			||||||
							headerLeft:null,
 | 
					 | 
				
			||||||
							headerBackground: ()=>background
 | 
					 | 
				
			||||||
						}}
 | 
					 | 
				
			||||||
					/>
 | 
					 | 
				
			||||||
				</Stack.Navigator>
 | 
					 | 
				
			||||||
			</NavigationContainer>
 | 
					 | 
				
			||||||
		)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export default Settings;
 | 
					 | 
				
			||||||
							
								
								
									
										139
									
								
								app/Staff.js
									
									
									
									
									
								
							
							
						
						@ -10,6 +10,7 @@ import {
 | 
				
			|||||||
  FlatList,
 | 
					  FlatList,
 | 
				
			||||||
  TouchableOpacity,
 | 
					  TouchableOpacity,
 | 
				
			||||||
  Image,
 | 
					  Image,
 | 
				
			||||||
 | 
					  TouchableHighlight,
 | 
				
			||||||
  Linking
 | 
					  Linking
 | 
				
			||||||
} from 'react-native';
 | 
					} from 'react-native';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -20,43 +21,135 @@ import {
 | 
				
			|||||||
  DebugInstructions,
 | 
					  DebugInstructions,
 | 
				
			||||||
  ReloadInstructions,
 | 
					  ReloadInstructions,
 | 
				
			||||||
} from 'react-native/Libraries/NewAppScreen';
 | 
					} from 'react-native/Libraries/NewAppScreen';
 | 
				
			||||||
 | 
					import { NavigationContainer } from '@react-navigation/native'
 | 
				
			||||||
 | 
					import { createStackNavigator } from '@react-navigation/stack'
 | 
				
			||||||
import { SearchBar } from 'react-native-elements';
 | 
					import { SearchBar } from 'react-native-elements';
 | 
				
			||||||
import styles from './styles/liststyles'
 | 
					import styles from './styles/liststyles'
 | 
				
			||||||
 | 
					import morestyles from './styles/morestyles'
 | 
				
			||||||
import { url } from './resources/fetchInfo.json'
 | 
					import { url } from './resources/fetchInfo.json'
 | 
				
			||||||
 | 
					import LinearGradient from 'react-native-linear-gradient';
 | 
				
			||||||
 | 
					import Ionicons from 'react-native-vector-icons/Ionicons';
 | 
				
			||||||
import I18n from './i18n';
 | 
					import I18n from './i18n';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const StaffElement = ({item}) => {
 | 
					const Stack = createStackNavigator();
 | 
				
			||||||
  const [visible, setVisible] = useState(false)
 | 
					
 | 
				
			||||||
  const extra = (
 | 
					export const StaffInfo = ({route}) => {
 | 
				
			||||||
    [
 | 
					  const item = route.params;
 | 
				
			||||||
      ...item.item.emails.map(email=>(
 | 
					
 | 
				
			||||||
      <View style={{display: 'flex', flexDirection: 'row', alignItems: 'center', marginTop: '2%', paddingHorizontal: '1%'}}>
 | 
					  console.log(item);
 | 
				
			||||||
        <View style={{width: '10%', display: 'flex', justifyContent: 'center'}}>
 | 
					
 | 
				
			||||||
          <Image source={require('./assets/email.png')}  style={{height: 22, width: 22}}/>
 | 
					  return (
 | 
				
			||||||
 | 
					    /*<View style = {{padding: 10, backgroundColor: 'white', height: '100%'}}>
 | 
				
			||||||
 | 
					      {item.emails.map(email =>
 | 
				
			||||||
 | 
					        <View style ={[styles.infoContainer, {flexDirection: 'row', alignItems: 'center'}]}>
 | 
				
			||||||
 | 
					          <View style={{display: 'flex', justifyContent: 'center'}}>
 | 
				
			||||||
 | 
					            <Ionicons name='mail-outline' size={28} style={{marginRight: 15}}/>
 | 
				
			||||||
          </View>
 | 
					          </View>
 | 
				
			||||||
        <View style={{width: '90%'}}>
 | 
					          <View style={{}}>
 | 
				
			||||||
          <Text key={email}><Text style={styles.linktext} onPress={()=>Linking.openURL("mailto:"+email)}><Text></Text>{email}</Text></Text>
 | 
					            <Text style = {{fontSize:16}}>{email}</Text>
 | 
				
			||||||
          </View>
 | 
					          </View>
 | 
				
			||||||
        </View>
 | 
					        </View>
 | 
				
			||||||
      ))
 | 
					      )}
 | 
				
			||||||
    ]
 | 
					    </View>*/
 | 
				
			||||||
 | 
					    <ScrollView style={{paddingTop:'5%',paddingHorizontal:'10%', backgroundColor: 'white', height: '100%'}}>
 | 
				
			||||||
 | 
					      <View style={{backgroundColor: 'white',borderRadius: 150, height: 300, width: 300, alignSelf: 'center', shadowColor: 'red', shadowOffset: {width: 0, height: 2}, shadowOpacity: 0.5, shadowRadius: 7}}>
 | 
				
			||||||
 | 
					        <Image style={{resizeMode: 'cover',borderRadius: 150, height: 300, width: 300, alignSelf: 'center'}} source = {{/* CHANGE */}} /> 
 | 
				
			||||||
 | 
					      </View>
 | 
				
			||||||
 | 
					      <Text style={{fontSize:28,marginTop:'5%',textAlign:'center'}}>{item.name}</Text>
 | 
				
			||||||
 | 
					      <Text style={{fontSize:20,textAlign:'center', fontWeight: '200'}}>{item.position || ""}</Text>
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      {item.emails &&
 | 
				
			||||||
 | 
					        <View style={{display: 'flex', padding:'2%', borderRadius: 8, marginTop:'5%'}}>
 | 
				
			||||||
 | 
					          <View style={{display:'flex', flexDirection: 'row'}}>
 | 
				
			||||||
 | 
					            <Ionicons name='mail-outline' size={28} style={{marginRight: 15}}/>
 | 
				
			||||||
 | 
					            <View style = {{display: 'flex', flexDirection: 'row', width: '85%', justifyContent: 'space-between', paddingHorizontal:'2%',}}>
 | 
				
			||||||
 | 
					              <Text style={{fontSize: 20,  alignSelf: 'center'}}>{"Email"}</Text>
 | 
				
			||||||
 | 
					            </View>
 | 
				
			||||||
 | 
					          </View>
 | 
				
			||||||
 | 
					          <Text style = {{marginLeft: 50, paddingHorizontal: '2%', paddingBottom: '2%'}}>
 | 
				
			||||||
 | 
					            {item.emails.map(email =>
 | 
				
			||||||
 | 
					              <Text key={email}>{email}</Text>
 | 
				
			||||||
 | 
					            )}
 | 
				
			||||||
 | 
					          </Text>
 | 
				
			||||||
 | 
					        </View>
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      {item.phone &&
 | 
				
			||||||
 | 
					        <View style={{display: 'flex', padding:'2%', borderRadius: 8, marginTop:'5%'}}>
 | 
				
			||||||
 | 
					          <View style={{display:'flex', flexDirection: 'row'}}>
 | 
				
			||||||
 | 
					            <Ionicons name='call-outline' size={28} style={{marginRight: 15}}/>
 | 
				
			||||||
 | 
					            <View style = {{display: 'flex', flexDirection: 'row', width: '85%', justifyContent: 'space-between', paddingHorizontal:'2%',}}>
 | 
				
			||||||
 | 
					              <Text style={{fontSize: 20,  alignSelf: 'center'}}>{"Phone"}</Text>
 | 
				
			||||||
 | 
					            </View>
 | 
				
			||||||
 | 
					          </View>
 | 
				
			||||||
 | 
					          <Text style = {{marginLeft: 50, paddingHorizontal: '2%', paddingBottom: '2%'}}>
 | 
				
			||||||
 | 
					          {item.phone.map(num =>
 | 
				
			||||||
 | 
					            <Text key={num}>{num}</Text>
 | 
				
			||||||
 | 
					          )}
 | 
				
			||||||
 | 
					          </Text>
 | 
				
			||||||
 | 
					        </View>
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    </ScrollView>
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
  //const extra = [...item.item.emails.map(email=>(<Text key={email}>{'\n'}Email: <Text style={styles.linktext} onPress={()=>Linking.openURL("mailto:"+email)}>{email}</Text></Text>))]
 | 
					}
 | 
				
			||||||
 | 
					function StaffElement (props) {
 | 
				
			||||||
 | 
					  const item = props.item;
 | 
				
			||||||
  return(
 | 
					  return(
 | 
				
			||||||
	<View>
 | 
						<View>
 | 
				
			||||||
	  <TouchableOpacity style={styles.item1} onPress={()=>setVisible(!visible)} activeOpacity={0.8}>
 | 
					      <TouchableOpacity style={[styles.listItem]} onPress={()=>props.navigation.navigate('StaffInfo', {data:props.data,name:props.name,emails:item.emails})} activeOpacity={0.8}>
 | 
				
			||||||
    <View style = {{display: 'flex', flexDirection: 'row', alignItems: 'center'}}>
 | 
					        <View style = {[styles.container2, {justifyContent: 'space-between'}]}>
 | 
				
			||||||
      <Image source = {require('./assets/staff.png')} style = {{height: 40, width: 40, marginRight: 10}}/>
 | 
					          <View style={{display: 'flex', flexDirection: 'row'}}> 
 | 
				
			||||||
      <Text style={styles.title3}>{item.item.name}</Text>
 | 
					            <Ionicons name = "ios-nutrition-outline" size={36} color={'#323232'} style={{marginRight: 15}} />
 | 
				
			||||||
 | 
					            <Text style={[styles.title, {alignSelf:'center'}]}>{props.item.name}</Text>
 | 
				
			||||||
 | 
					          </View>
 | 
				
			||||||
 | 
					          <Image source = {require('./assets/forward.png')} style={{tintColor: '#b2b2b2'}}/>
 | 
				
			||||||
        </View>
 | 
					        </View>
 | 
				
			||||||
		{visible?extra:<></>}
 | 
					 | 
				
			||||||
      </TouchableOpacity>
 | 
					      </TouchableOpacity>
 | 
				
			||||||
	</View>
 | 
						</View>
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
class Staff extends React.Component {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const background = (<LinearGradient
 | 
				
			||||||
 | 
					  colors={['#f99', 'white']}
 | 
				
			||||||
 | 
					  style = {{flex:1,borderBottomColor:'black',borderBottomWidth:0.5}}
 | 
				
			||||||
 | 
					  />)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function Staff () {
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    <NavigationContainer independent={true}>
 | 
				
			||||||
 | 
					      <Stack.Navigator>
 | 
				
			||||||
 | 
					        <Stack.Screen 
 | 
				
			||||||
 | 
					          name = "Staff"
 | 
				
			||||||
 | 
					          component = {Staffs}
 | 
				
			||||||
 | 
					          options={({
 | 
				
			||||||
 | 
					            headerShown: true,
 | 
				
			||||||
 | 
					            headerTitleStyle:morestyles.headerTitle,
 | 
				
			||||||
 | 
					            headerBackground: ()=>background,
 | 
				
			||||||
 | 
					            //headerleft: null,
 | 
				
			||||||
 | 
					            title:I18n.t('app.staff'),
 | 
				
			||||||
 | 
					            headerBackTitleVisible:false,
 | 
				
			||||||
 | 
					            headerTintColor: 'black',
 | 
				
			||||||
 | 
					            headerTitleAlign: 'center'
 | 
				
			||||||
 | 
					          })}
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					        <Stack.Screen 
 | 
				
			||||||
 | 
					          name = "StaffInfo"
 | 
				
			||||||
 | 
					          component = {StaffInfo}
 | 
				
			||||||
 | 
					          options={({route})=>({
 | 
				
			||||||
 | 
					            title:route.params.name,
 | 
				
			||||||
 | 
					            headerTitleStyle:[morestyles.headerTitle,{alignSelf:'center'}],
 | 
				
			||||||
 | 
					            headerBackground: ()=>background,
 | 
				
			||||||
 | 
					            headerBackTitleVisible:false,
 | 
				
			||||||
 | 
					            headerTintColor: 'black',
 | 
				
			||||||
 | 
					            headerTitleAlign: 'center',
 | 
				
			||||||
 | 
					          })}
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					      </Stack.Navigator>
 | 
				
			||||||
 | 
					    </NavigationContainer>
 | 
				
			||||||
 | 
					  ) 
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Staffs extends React.Component {
 | 
				
			||||||
	constructor(props) {
 | 
						constructor(props) {
 | 
				
			||||||
    super(props);
 | 
					    super(props);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -95,7 +188,7 @@ class Staff extends React.Component {
 | 
				
			|||||||
  updateSearch = (search) => {
 | 
					  updateSearch = (search) => {
 | 
				
			||||||
    this.setState({ search:search });
 | 
					    this.setState({ search:search });
 | 
				
			||||||
	const searchPool = search.startsWith(this.state.search)?this.state.dataSearch:this.state.data;
 | 
						const searchPool = search.startsWith(this.state.search)?this.state.dataSearch:this.state.data;
 | 
				
			||||||
    const ds = searchPool.filter((thing)=>{return thing.name.toLowerCase().split(' ').some(x=>x.startsWith(search.toLowerCase()))})
 | 
					    const ds = searchPool.filter((thing)=>{return thing.name.toLowerCase().startsWith(search.toLowerCase())})
 | 
				
			||||||
    this.setState({dataSearch: ds})
 | 
					    this.setState({dataSearch: ds})
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  clearSearch  = (search)=>{
 | 
					  clearSearch  = (search)=>{
 | 
				
			||||||
@ -104,8 +197,9 @@ class Staff extends React.Component {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  render() {
 | 
					  render() {
 | 
				
			||||||
    const { data , dataSearch,search} = this.state;
 | 
					    const { data , dataSearch,search} = this.state;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <SafeAreaView style={styles.container}>
 | 
					      <SafeAreaView style={styles.moreDefault}>
 | 
				
			||||||
        <SearchBar
 | 
					        <SearchBar
 | 
				
			||||||
        lightTheme
 | 
					        lightTheme
 | 
				
			||||||
        placeholder={I18n.t('staff.searchStaff')}
 | 
					        placeholder={I18n.t('staff.searchStaff')}
 | 
				
			||||||
@ -115,10 +209,11 @@ class Staff extends React.Component {
 | 
				
			|||||||
        value={this.state.search}/>
 | 
					        value={this.state.search}/>
 | 
				
			||||||
      <FlatList
 | 
					      <FlatList
 | 
				
			||||||
        data={dataSearch}
 | 
					        data={dataSearch}
 | 
				
			||||||
        renderItem={item => <StaffElement item={item}/>}
 | 
					        renderItem={({item}) => <StaffElement item={item} name={item.name} navigation={this.props.navigation}/>}
 | 
				
			||||||
        keyExtractor={item => JSON.stringify(item)}
 | 
					        keyExtractor={item => JSON.stringify(item)}
 | 
				
			||||||
      />
 | 
					      />
 | 
				
			||||||
    </SafeAreaView>
 | 
					    </SafeAreaView>
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
import React from 'react';
 | 
					import React, { useState } from 'react';
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  SafeAreaView,
 | 
					  SafeAreaView,
 | 
				
			||||||
  StyleSheet,
 | 
					  StyleSheet,
 | 
				
			||||||
@ -7,6 +7,7 @@ import {
 | 
				
			|||||||
  Text,
 | 
					  Text,
 | 
				
			||||||
  StatusBar,
 | 
					  StatusBar,
 | 
				
			||||||
  Image,
 | 
					  Image,
 | 
				
			||||||
 | 
					  TouchableOpacity
 | 
				
			||||||
} from 'react-native';
 | 
					} from 'react-native';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
@ -18,15 +19,36 @@ import {
 | 
				
			|||||||
} from 'react-native/Libraries/NewAppScreen';
 | 
					} from 'react-native/Libraries/NewAppScreen';
 | 
				
			||||||
import I18n from './i18n';
 | 
					import I18n from './i18n';
 | 
				
			||||||
import { url } from './resources/fetchInfo.json'
 | 
					import { url } from './resources/fetchInfo.json'
 | 
				
			||||||
 | 
					import LinearGradient from 'react-native-linear-gradient';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class StudentWeek extends React.Component {
 | 
					class StudentWeek extends React.Component {
 | 
				
			||||||
	constructor(props) {
 | 
						constructor(props) {
 | 
				
			||||||
		super(props)
 | 
							super(props)
 | 
				
			||||||
		this.state = {
 | 
							this.state = {
 | 
				
			||||||
			isLoading: true
 | 
								isLoading: true,
 | 
				
			||||||
 | 
								hobbyExpanded: false,
 | 
				
			||||||
 | 
								achievementExpanded: false,
 | 
				
			||||||
 | 
								messageExpanded: false,
 | 
				
			||||||
 | 
								hobbyArrow:require('./assets/expand.png'),
 | 
				
			||||||
 | 
								achievementArrow:require('./assets/expand.png'),
 | 
				
			||||||
 | 
								messageArrow:require('./assets/expand.png')
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						clickHobby() {
 | 
				
			||||||
 | 
							if (!this.state.hobbyExpanded) this.setState({hobbyExpanded:true, hobbyArrow: require('./assets/collapse.png')});
 | 
				
			||||||
 | 
							else this.setState({hobbyExpanded: false,hobbyArrow:require('./assets/expand.png')});
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						clickAchievements() {
 | 
				
			||||||
 | 
							if (!this.state.achievementExpanded) this.setState({achievementExpanded:true, achievementArrow: require('./assets/collapse.png')});
 | 
				
			||||||
 | 
							else this.setState({achievementExpanded: false, achievementArrow:require('./assets/expand.png')});
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						clickMessages() {
 | 
				
			||||||
 | 
							if (!this.state.messageExpanded) this.setState({messageExpanded:true, messageArrow: require('./assets/collapse.png')});
 | 
				
			||||||
 | 
							else this.setState({messageExpanded: false, messageArrow:require('./assets/expand.png')});
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						
 | 
				
			||||||
	componentDidMount() {
 | 
						componentDidMount() {
 | 
				
			||||||
		fetch(`${url}/api/en/student`,{
 | 
							fetch(`${url}/api/en/student`,{
 | 
				
			||||||
		  headers: {
 | 
							  headers: {
 | 
				
			||||||
@ -44,35 +66,53 @@ class StudentWeek extends React.Component {
 | 
				
			|||||||
			return <View/>
 | 
								return <View/>
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			const iconURI = this.state.data.icon !== undefined?`data:image/png;charset=utf-8;base64,${this.state.data.icon}`:'';
 | 
								const iconURI = this.state.data.icon !== undefined?`data:image/png;charset=utf-8;base64,${this.state.data.icon}`:'';
 | 
				
			||||||
 | 
								const hobbyText = (<Text style = {{marginLeft: 50, paddingHorizontal: '2%', paddingBottom: '2%'}}>{this.state.data.hobbies}</Text>)
 | 
				
			||||||
 | 
								const achievementText = (<Text style = {{marginLeft: 50, paddingHorizontal: '2%', paddingBottom: '2%'}}>{this.state.data.achievements}</Text>)
 | 
				
			||||||
 | 
								const messageText = (<Text style = {{marginLeft: 50, paddingHorizontal: '2%', paddingBottom: '2%'}}>{this.state.data.messages}</Text>)
 | 
				
			||||||
			return (
 | 
								return (
 | 
				
			||||||
				<View style={{paddingTop:'5%',paddingHorizontal:'10%', backgroundColor: 'white', height: '100%'}}>
 | 
									<ScrollView style={{paddingTop:'5%',paddingHorizontal:'10%', backgroundColor: 'white', height: '100%'}}>
 | 
				
			||||||
					<View style = {{display: 'flex', flexDirection: 'row', justifyContent: 'space-between'}}>
 | 
										<View style={{backgroundColor: 'white',borderRadius: 150, height: 300, width: 300, alignSelf: 'center', shadowColor: 'red', shadowOffset: {width: 0, height: 2}, shadowOpacity: 0.5, shadowRadius: 7}}>
 | 
				
			||||||
						<View>
 | 
											<Image style={{resizeMode: 'cover',borderRadius: 150, height: 300, width: 300, alignSelf: 'center'}} source = {{iconURI}} /> 
 | 
				
			||||||
							<Text style={{fontSize:28,marginBottom:'10%',textAlign:'center'}}>{this.state.data.name}</Text>	
 | 
					 | 
				
			||||||
							<Text style={{fontSize:20}}>{'\t'}{I18n.t('student.Grade')} {this.state.data.year}</Text>
 | 
					 | 
				
			||||||
					</View>
 | 
										</View>
 | 
				
			||||||
						<View style = {{height: 150, width: 150}}>
 | 
										<Text style={{fontSize:28,marginTop:'5%',textAlign:'center'}}>{this.state.data.name}</Text>
 | 
				
			||||||
							<Image style = {{height: '100%', width:'100%', borderRadius: 6}}source={{iconURI}} />
 | 
										<Text style={{fontSize:20,textAlign:'center', fontWeight: '200'}}>{I18n.t('student.Grade')} {this.state.data.year}</Text>
 | 
				
			||||||
 | 
										<View>
 | 
				
			||||||
 | 
											<View style={{display: 'flex', padding:'2%', borderRadius: 8, marginTop:'5%'}}>
 | 
				
			||||||
 | 
												<TouchableOpacity onPress = {this.clickHobby.bind(this)}>
 | 
				
			||||||
 | 
													<View style={{display:'flex', flexDirection: 'row'}}>
 | 
				
			||||||
 | 
														<Image source = {require('./assets/hobbies.png')} />
 | 
				
			||||||
 | 
														<View style = {{display: 'flex', flexDirection: 'row', width: '85%', justifyContent: 'space-between', paddingHorizontal:'2%',}}>
 | 
				
			||||||
 | 
															<Text style={{fontSize: 20,  alignSelf: 'center'}}>{I18n.t('student.Hobbies')}</Text>
 | 
				
			||||||
 | 
															{this.state.hobbyExpanded?<LinearGradient start={{x: 0, y: 0.25}} end={{x: .5, y: 1}} colors={['red', '#FF7373']} style={{borderRadius: 24, alignSelf: 'center'}}><Image source = {require('./assets/collapse.png')} style={{tintColor: 'white'}}/></LinearGradient>:<Image source = {require('./assets/expand.png')} style={{tintColor: '#b2b2b2', alignSelf: 'center'}}/>}
 | 
				
			||||||
 | 
														</View>
 | 
				
			||||||
 | 
													</View>
 | 
				
			||||||
 | 
													{this.state.hobbyExpanded?hobbyText:<></>}
 | 
				
			||||||
 | 
												</TouchableOpacity>
 | 
				
			||||||
 | 
												<TouchableOpacity onPress = {this.clickAchievements.bind(this)}>
 | 
				
			||||||
 | 
													<View style={{display: 'flex', borderTopWidth: 1, borderTopColor: '#8D8D8D', shadowColor: 'black', flexDirection: 'row'}}>
 | 
				
			||||||
 | 
														<Image source = {require('./assets/achievements.png')} />
 | 
				
			||||||
 | 
														<View style = {{display: 'flex', flexDirection: 'row', width: '85%', justifyContent: 'space-between', paddingHorizontal:'2%',}}>
 | 
				
			||||||
 | 
															<Text style={{fontSize: 20, alignSelf: 'center'}}>{I18n.t('student.Achievements')}</Text>
 | 
				
			||||||
 | 
															{this.state.achievementExpanded?<LinearGradient start={{x: 0, y: 0.25}} end={{x: .5, y: 1}} colors={['red', '#FF7373']} style={{borderRadius: 24, alignSelf: 'center'}}><Image source = {require('./assets/collapse.png')} style={{tintColor: 'white'}}/></LinearGradient>:<Image source = {require('./assets/expand.png')} style={{tintColor: '#b2b2b2', alignSelf: 'center'}}/>}
 | 
				
			||||||
 | 
														</View>
 | 
				
			||||||
 | 
													</View>
 | 
				
			||||||
 | 
													{this.state.achievementExpanded?achievementText:<></>}
 | 
				
			||||||
 | 
												</TouchableOpacity>
 | 
				
			||||||
 | 
												<TouchableOpacity onPress = {this.clickMessages.bind(this)}>
 | 
				
			||||||
 | 
													<View style={{display: 'flex', borderTopWidth: 1, borderTopColor: '#8D8D8D', shadowColor: 'black', flexDirection: 'row'}}>
 | 
				
			||||||
 | 
														<Image source = {require('./assets/message.png')} />
 | 
				
			||||||
 | 
														<View style = {{display: 'flex', flexDirection: 'row', width: '85%', justifyContent: 'space-between', paddingHorizontal:'2%',}}>
 | 
				
			||||||
 | 
															<Text style={{fontSize: 20, alignSelf: 'center'}}>{I18n.t('student.Messages')}</Text>
 | 
				
			||||||
 | 
															{this.state.messageExpanded?<LinearGradient start={{x: 0, y: 0.25}} end={{x: .5, y: 1}} colors={['red', '#FF7373']} style={{borderRadius: 24, alignSelf: 'center'}}><Image source = {require('./assets/collapse.png')} style={{tintColor: 'white'}}/></LinearGradient>:<Image source = {require('./assets/expand.png')} style={{tintColor: '#b2b2b2', alignSelf: 'center'}}/>}
 | 
				
			||||||
 | 
														</View>
 | 
				
			||||||
 | 
													</View>
 | 
				
			||||||
 | 
													{this.state.messageExpanded?messageText:<></>}
 | 
				
			||||||
 | 
												</TouchableOpacity>
 | 
				
			||||||
						</View>
 | 
											</View>
 | 
				
			||||||
						
 | 
											
 | 
				
			||||||
					</View>
 | 
										</View>
 | 
				
			||||||
					
 | 
										
 | 
				
			||||||
					<View style = {{paddingTop:'10%', height: '55%', display: 'flex', flexDirection: 'column', justifyContent: 'space-between'}}>
 | 
									</ScrollView>
 | 
				
			||||||
						<View>
 | 
					 | 
				
			||||||
							<Text style={{fontSize: 20, fontWeight: 'bold'}}>{"\n"}{I18n.t('student.Hobbies')}</Text>
 | 
					 | 
				
			||||||
							<Text style={{fontSize: 20}}>{'\t'}{this.state.data.hobbies}</Text>
 | 
					 | 
				
			||||||
						</View>
 | 
					 | 
				
			||||||
						<View>
 | 
					 | 
				
			||||||
							<Text style={{fontSize: 20, fontWeight: 'bold'}}>{"\n"}{I18n.t('student.Achievements')} </Text>
 | 
					 | 
				
			||||||
							<Text style={{fontSize: 20}}>{'\t'}{this.state.data.achievements}</Text>
 | 
					 | 
				
			||||||
						</View>
 | 
					 | 
				
			||||||
						<View>
 | 
					 | 
				
			||||||
							<Text style={{fontSize: 20, fontWeight: 'bold'}}>{"\n"}{I18n.t('student.Messages')}</Text>
 | 
					 | 
				
			||||||
							<Text style={{fontSize: 20}}>{'\t'}{this.state.data.messages}</Text>
 | 
					 | 
				
			||||||
						</View>
 | 
					 | 
				
			||||||
					</View>
 | 
					 | 
				
			||||||
					
 | 
					 | 
				
			||||||
				</View>
 | 
					 | 
				
			||||||
			)
 | 
								)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								app/assets/achievements.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.1 KiB  | 
| 
		 Before Width: | Height: | Size: 5.3 KiB  | 
| 
		 Before Width: | Height: | Size: 28 KiB  | 
| 
		 Before Width: | Height: | Size: 6.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								app/assets/canvas.jpeg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 14 KiB  | 
| 
		 Before Width: | Height: | Size: 86 KiB  | 
| 
		 Before Width: | Height: | Size: 5.1 KiB  | 
| 
		 Before Width: | Height: | Size: 7.1 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								app/assets/collapse.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 183 B  | 
							
								
								
									
										
											BIN
										
									
								
								app/assets/counselor.jpeg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 19 KiB  | 
| 
		 Before Width: | Height: | Size: 6.5 KiB  | 
| 
		 Before Width: | Height: | Size: 7.6 KiB  | 
| 
		 Before Width: | Height: | Size: 7.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								app/assets/expand.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 186 B  | 
							
								
								
									
										
											BIN
										
									
								
								app/assets/forward.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 167 B  | 
							
								
								
									
										
											BIN
										
									
								
								app/assets/gc.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 21 KiB  | 
| 
		 Before Width: | Height: | Size: 27 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								app/assets/hobbies.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.3 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								app/assets/infoflow.jpeg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 13 KiB  | 
| 
		 Before Width: | Height: | Size: 5.7 KiB  | 
| 
		 Before Width: | Height: | Size: 5.6 KiB  | 
| 
		 Before Width: | Height: | Size: 5.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								app/assets/message.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.1 KiB  | 
| 
		 Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 15 KiB  | 
| 
		 Before Width: | Height: | Size: 5.2 KiB  | 
| 
		 Before Width: | Height: | Size: 4.4 KiB  | 
| 
		 Before Width: | Height: | Size: 5.2 KiB  | 
| 
		 Before Width: | Height: | Size: 38 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								app/assets/sco.jpeg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 10 KiB  | 
| 
		 Before Width: | Height: | Size: 6.2 KiB  | 
| 
		 Before Width: | Height: | Size: 5.5 KiB  | 
| 
		 Before Width: | Height: | Size: 5.8 KiB  | 
| 
		 Before Width: | Height: | Size: 6.0 KiB  | 
| 
		 Before Width: | Height: | Size: 6.5 KiB  | 
| 
		 Before Width: | Height: | Size: 40 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								app/assets/studentvue.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 58 KiB  | 
| 
		 Before Width: | Height: | Size: 5.4 KiB  | 
| 
		 Before Width: | Height: | Size: 5.8 KiB  | 
| 
		 Before Width: | Height: | Size: 5.0 KiB  | 
							
								
								
									
										16
									
								
								app/i18n.js
									
									
									
									
									
								
							
							
						
						@ -1,12 +1,18 @@
 | 
				
			|||||||
'use strict';
 | 
					import I18n from "i18n-js";
 | 
				
			||||||
import I18n from 'react-native-i18n';
 | 
					import * as RNLocalize from "react-native-localize";
 | 
				
			||||||
import en from './Languages/en'
 | 
					import en from "./Languages/en.js";
 | 
				
			||||||
import es from './Languages/es'
 | 
					import es from "./Languages/es.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const locales = RNLocalize.getLocales();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (Array.isArray(locales)) {
 | 
				
			||||||
 | 
					  I18n.locale = locales[0].languageTag;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
I18n.fallbacks = true;
 | 
					I18n.fallbacks = true;
 | 
				
			||||||
I18n.translations = {
 | 
					I18n.translations = {
 | 
				
			||||||
  en,
 | 
					  en,
 | 
				
			||||||
  es,
 | 
					  es
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default I18n;
 | 
					export default I18n;
 | 
				
			||||||
@ -1 +1 @@
 | 
				
			|||||||
{"url":"http://127.0.0.1:5000"}
 | 
					{"url":"https://blazerappcms.ml/"}
 | 
				
			||||||
@ -1,9 +1,9 @@
 | 
				
			|||||||
import {StyleSheet, StatusBar} from 'react-native';
 | 
					import {StyleSheet, StatusBar, Dimensions} from 'react-native';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const styles = StyleSheet.create({
 | 
					const styles = StyleSheet.create({
 | 
				
			||||||
  container: {
 | 
					  container: {
 | 
				
			||||||
    flex: 1,
 | 
					    flex: 1,
 | 
				
			||||||
    marginTop: StatusBar.currentHeight || 0
 | 
					    marginTop: /*StatusBar.currentHeight ||*/ 0
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  item: {
 | 
					  item: {
 | 
				
			||||||
    backgroundColor: 'white',
 | 
					    backgroundColor: 'white',
 | 
				
			||||||
@ -11,6 +11,43 @@ const styles = StyleSheet.create({
 | 
				
			|||||||
    borderBottomWidth: 1.5,
 | 
					    borderBottomWidth: 1.5,
 | 
				
			||||||
    borderColor: 'black'
 | 
					    borderColor: 'black'
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					  moreDefault: {
 | 
				
			||||||
 | 
					    flex: 1,
 | 
				
			||||||
 | 
					    backgroundColor:'white', 
 | 
				
			||||||
 | 
					    paddingHorizontal: '5%'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  listItem: {
 | 
				
			||||||
 | 
					    display: 'flex', 
 | 
				
			||||||
 | 
					    borderBottomColor:'#D5D5D5',
 | 
				
			||||||
 | 
					    borderBottomWidth:.5
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  container2: {
 | 
				
			||||||
 | 
					    display: 'flex', 
 | 
				
			||||||
 | 
					    flexDirection: 'row', 
 | 
				
			||||||
 | 
					    height: Dimensions.get('window').height*0.075,
 | 
				
			||||||
 | 
					    alignItems: 'center'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  sideImage: {
 | 
				
			||||||
 | 
					    height: 40,
 | 
				
			||||||
 | 
					    width: 40, 
 | 
				
			||||||
 | 
					    marginRight: 10,
 | 
				
			||||||
 | 
					    tintColor: '#323232'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  accordian: {
 | 
				
			||||||
 | 
					    display: 'flex',
 | 
				
			||||||
 | 
					    flexDirection: 'row',
 | 
				
			||||||
 | 
					    justifyContent: 'space-between',
 | 
				
			||||||
 | 
					    width: '85%'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
						accordianHeader: {
 | 
				
			||||||
 | 
							paddingBottom: '2%',
 | 
				
			||||||
 | 
							fontSize:16
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					  accordianText: {
 | 
				
			||||||
 | 
					    paddingBottom: '2%',
 | 
				
			||||||
 | 
							fontSize:16,
 | 
				
			||||||
 | 
					    fontWeight: '200',
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  item1: {
 | 
					  item1: {
 | 
				
			||||||
    backgroundColor: 'white',
 | 
					    backgroundColor: 'white',
 | 
				
			||||||
    padding: 15,
 | 
					    padding: 15,
 | 
				
			||||||
 | 
				
			|||||||
@ -5,9 +5,9 @@ console.log(Dimensions.get('window'))
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const styles=StyleSheet.create({
 | 
					const styles=StyleSheet.create({
 | 
				
			||||||
	moreitem: {
 | 
						moreitem: {
 | 
				
			||||||
		backgroundColor:'red',
 | 
							backgroundColor:'white',
 | 
				
			||||||
		borderBottomColor:'white',
 | 
							borderBottomColor:'#D5D5D5',
 | 
				
			||||||
		borderBottomWidth:0.5,
 | 
							borderBottomWidth:.5,
 | 
				
			||||||
		height: Dimensions.get('window').height*0.075,
 | 
							height: Dimensions.get('window').height*0.075,
 | 
				
			||||||
		paddingLeft: '3%',
 | 
							paddingLeft: '3%',
 | 
				
			||||||
		fontSize: 32,
 | 
							fontSize: 32,
 | 
				
			||||||
@ -16,35 +16,17 @@ const styles=StyleSheet.create({
 | 
				
			|||||||
		alignItems: 'center',
 | 
							alignItems: 'center',
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	moretext: {
 | 
						moretext: {
 | 
				
			||||||
		color:'#e3e3e3',
 | 
							fontSize:20,
 | 
				
			||||||
		fontSize:22,
 | 
					 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	headerTitle: {
 | 
						headerTitle: {
 | 
				
			||||||
		fontWeight: 'bold',
 | 
							fontWeight: 'bold',
 | 
				
			||||||
		fontSize:24,
 | 
							fontSize:24,
 | 
				
			||||||
 | 
							alignSelf: 'center'
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	resourceContainer: {
 | 
						resourceContainer: {
 | 
				
			||||||
		alignItems: 'center',
 | 
							alignItems: 'center',
 | 
				
			||||||
    	marginTop: '3%',
 | 
					    	marginTop: '3%',
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	image: {
 | 
					 | 
				
			||||||
		height: 100,
 | 
					 | 
				
			||||||
		width: 400,
 | 
					 | 
				
			||||||
		borderTopRightRadius: 16,
 | 
					 | 
				
			||||||
		borderTopLeftRadius: 16,
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
	textContainer: {
 | 
					 | 
				
			||||||
		backgroundColor: 'black',
 | 
					 | 
				
			||||||
		width: 400,
 | 
					 | 
				
			||||||
		borderBottomLeftRadius: 16,
 | 
					 | 
				
			||||||
		borderBottomRightRadius: 16,
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
	resourceText: {
 | 
					 | 
				
			||||||
		fontWeight: 'bold',
 | 
					 | 
				
			||||||
		color: 'white',
 | 
					 | 
				
			||||||
		fontSize:32,
 | 
					 | 
				
			||||||
		textAlign:'center',
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
	openPage: {
 | 
						openPage: {
 | 
				
			||||||
		display: 'flex',
 | 
							display: 'flex',
 | 
				
			||||||
		flexDirection: 'column',
 | 
							flexDirection: 'column',
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										41
									
								
								cms/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					[package]
 | 
				
			||||||
 | 
					name = "cms"
 | 
				
			||||||
 | 
					version = "0.1.0"
 | 
				
			||||||
 | 
					edition = "2018"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[dependencies]
 | 
				
			||||||
 | 
					rocket = "0.4.10"
 | 
				
			||||||
 | 
					dotenv = "0.15.0"
 | 
				
			||||||
 | 
					clap = "2.33.3"
 | 
				
			||||||
 | 
					ansi_term = "0.12.1"
 | 
				
			||||||
 | 
					chrono = "0.4.19"
 | 
				
			||||||
 | 
					diesel_migrations = "1.4.0"
 | 
				
			||||||
 | 
					url = "2.2.2"
 | 
				
			||||||
 | 
					oauth2 = "4.1.0"
 | 
				
			||||||
 | 
					serde_json = "1.0.66"
 | 
				
			||||||
 | 
					base64 = "0.13.0"
 | 
				
			||||||
 | 
					quote = "1.0.9"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[dependencies.reqwest]
 | 
				
			||||||
 | 
					version = "0.11.4"
 | 
				
			||||||
 | 
					features = ["blocking", "json"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[dependencies.diesel]
 | 
				
			||||||
 | 
					version = "1.4.4"
 | 
				
			||||||
 | 
					features = ["postgres", "extras"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[dependencies.rocket_contrib]
 | 
				
			||||||
 | 
					version = "0.4.10"
 | 
				
			||||||
 | 
					default-features = false
 | 
				
			||||||
 | 
					features = ["handlebars_templates", "diesel_postgres_pool", "json"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[dependencies.serde]
 | 
				
			||||||
 | 
					version = "1.0.126"
 | 
				
			||||||
 | 
					features = ["derive"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[dependencies.rand]
 | 
				
			||||||
 | 
					version = "0.8.4"
 | 
				
			||||||
 | 
					features = ["getrandom"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[dependencies.cms_macro]
 | 
				
			||||||
 | 
					path = "cms_macro"
 | 
				
			||||||
							
								
								
									
										10
									
								
								cms/Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					FROM rustlang/rust:nightly AS build
 | 
				
			||||||
 | 
					COPY / /build
 | 
				
			||||||
 | 
					WORKDIR /build
 | 
				
			||||||
 | 
					RUN cargo build --release
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FROM ubuntu:20.04 AS release
 | 
				
			||||||
 | 
					WORKDIR /root
 | 
				
			||||||
 | 
					COPY --from=build /build/target/release/cms ./cms
 | 
				
			||||||
 | 
					CMD [ "./cms" ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										17
									
								
								cms/cms_macro/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					[package]
 | 
				
			||||||
 | 
					name = "cms_macro"
 | 
				
			||||||
 | 
					version = "0.1.0"
 | 
				
			||||||
 | 
					edition = "2018"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[lib]
 | 
				
			||||||
 | 
					proc-macro=true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[dependencies]
 | 
				
			||||||
 | 
					quote = "1.0.9"
 | 
				
			||||||
 | 
					proc-macro2 = "1.0.28"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[dependencies.diesel]
 | 
				
			||||||
 | 
					version = "1.4.4"
 | 
				
			||||||
 | 
					features = ["postgres", "extras"]
 | 
				
			||||||
							
								
								
									
										327
									
								
								cms/cms_macro/src/lib.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,327 @@
 | 
				
			|||||||
 | 
					extern crate proc_macro;
 | 
				
			||||||
 | 
					#[macro_use]
 | 
				
			||||||
 | 
					extern crate quote;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use proc_macro2::*;
 | 
				
			||||||
 | 
					use std::fmt::Debug;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug)]
 | 
				
			||||||
 | 
					struct Row(Ident, Ident, Ident, Ident);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn api_route_inner(item: TokenStream) -> TokenStream {
 | 
				
			||||||
 | 
					    let iterator = item.into_iter().clone().collect::<Vec<TokenTree>>();
 | 
				
			||||||
 | 
					    let name = iterator[0].clone();
 | 
				
			||||||
 | 
					    let name_literal = &iterator[0].clone().to_string();
 | 
				
			||||||
 | 
					    let name_dir = format!("/{}", name_literal);
 | 
				
			||||||
 | 
					    let name_add = format!("/{}/add", name_literal);
 | 
				
			||||||
 | 
					    let name_upd = format!("/{}/upd", name_literal);
 | 
				
			||||||
 | 
					    let name_del = format!("/{}/del", name_literal);
 | 
				
			||||||
 | 
					    let name_api = format!("/<lang>/{}", name_literal);
 | 
				
			||||||
 | 
					    let name_redir = format!("/ui/{}", name_literal);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let value_group = iterator[1].clone();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let (delim, stream) = match value_group {
 | 
				
			||||||
 | 
					        TokenTree::Group(g) => (g.delimiter(), g.stream()),
 | 
				
			||||||
 | 
					        n => panic!("Incorrect syntax at brace => {:?}", n),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert_eq!(delim, Delimiter::Brace);
 | 
				
			||||||
 | 
					    let splitted = &mut stream.into_iter().clone().collect::<Vec<TokenTree>>()[..]
 | 
				
			||||||
 | 
					        .split(|token| {
 | 
				
			||||||
 | 
					            if let TokenTree::Punct(p) = token.clone() {
 | 
				
			||||||
 | 
					                p.as_char() == ',' && p.spacing() == Spacing::Alone
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                false
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .map(Vec::from)
 | 
				
			||||||
 | 
					        .collect::<Vec<Vec<TokenTree>>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    splitted.pop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut rows: Vec<Row> = vec![];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for vecs in splitted.into_iter() {
 | 
				
			||||||
 | 
					        let mut vals_iter = vecs.split(|token| {
 | 
				
			||||||
 | 
					            if let TokenTree::Punct(p) = token.clone() {
 | 
				
			||||||
 | 
					                p.as_char() == ':' && p.spacing() == Spacing::Alone
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                false
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let name = vals_iter.next().unwrap().to_vec();
 | 
				
			||||||
 | 
					        let vals = vals_iter.next().unwrap().to_vec();
 | 
				
			||||||
 | 
					        let (brack, val_stream) = match vals.get(0).unwrap() {
 | 
				
			||||||
 | 
					            TokenTree::Group(g) => (g.delimiter(), g.stream()),
 | 
				
			||||||
 | 
					            n => panic!("Incorrect syntax at parenthesis => {:?}", n),
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        assert_eq!(brack, Delimiter::Parenthesis);
 | 
				
			||||||
 | 
					        assert_eq!(name.len(), 1);
 | 
				
			||||||
 | 
					        let name = match name.get(0).unwrap() {
 | 
				
			||||||
 | 
					            TokenTree::Ident(g) => g,
 | 
				
			||||||
 | 
					            n => panic!("Incorrect syntax at name => {:?}", n),
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let vals = &val_stream.into_iter().clone().collect::<Vec<TokenTree>>()[..]
 | 
				
			||||||
 | 
					            .split(|token| {
 | 
				
			||||||
 | 
					                if let TokenTree::Punct(p) = token.clone() {
 | 
				
			||||||
 | 
					                    p.as_char() == ',' && p.spacing() == Spacing::Alone
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    false
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            .map(|x| match x.to_vec().get(0).unwrap().clone() {
 | 
				
			||||||
 | 
					                TokenTree::Ident(i) => i,
 | 
				
			||||||
 | 
					                n => panic!("Incorrect syntax at group => {:?}", n),
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            .collect::<Vec<Ident>>();
 | 
				
			||||||
 | 
					        rows.push(Row(
 | 
				
			||||||
 | 
					            name.clone(),
 | 
				
			||||||
 | 
					            vals.get(0).unwrap().clone(),
 | 
				
			||||||
 | 
					            vals.get(1).unwrap().clone(),
 | 
				
			||||||
 | 
					            vals.get(2).unwrap().clone(),
 | 
				
			||||||
 | 
					        ));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let names_vec = rows
 | 
				
			||||||
 | 
					        .iter()
 | 
				
			||||||
 | 
					        .map(|x| TokenTree::Ident(x.0.clone()))
 | 
				
			||||||
 | 
					        .collect::<Vec<TokenTree>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let schema_value = rows
 | 
				
			||||||
 | 
					        .iter()
 | 
				
			||||||
 | 
					        .map(|x| TokenTree::Ident(x.1.clone()))
 | 
				
			||||||
 | 
					        .collect::<Vec<TokenTree>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let get_value = rows
 | 
				
			||||||
 | 
					        .iter()
 | 
				
			||||||
 | 
					        .map(|x| TokenTree::Ident(x.2.clone()))
 | 
				
			||||||
 | 
					        .collect::<Vec<TokenTree>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let put_value = rows
 | 
				
			||||||
 | 
					        .iter()
 | 
				
			||||||
 | 
					        .map(|x| TokenTree::Ident(x.3.clone()))
 | 
				
			||||||
 | 
					        .collect::<Vec<TokenTree>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let impl_value = rows
 | 
				
			||||||
 | 
					        .iter()
 | 
				
			||||||
 | 
					        .map(|x| {
 | 
				
			||||||
 | 
					            if x.2.to_string() == x.3.to_string() {
 | 
				
			||||||
 | 
					                let s = x.0.clone();
 | 
				
			||||||
 | 
					                quote! {
 | 
				
			||||||
 | 
					                    #s: self.#s,
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                let s = x.0.clone();
 | 
				
			||||||
 | 
					                quote! {
 | 
				
			||||||
 | 
					                    #s: *self.#s,
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .collect::<Vec<TokenStream>>()
 | 
				
			||||||
 | 
					        .into_iter()
 | 
				
			||||||
 | 
					        .map(|x| x.into_iter().collect::<Vec<TokenTree>>())
 | 
				
			||||||
 | 
					        .flatten()
 | 
				
			||||||
 | 
					        .collect::<Vec<TokenTree>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let impls = quote! {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        impl Post {
 | 
				
			||||||
 | 
					            fn convert(self) -> Create {
 | 
				
			||||||
 | 
					                Create {
 | 
				
			||||||
 | 
					                    lang: self.lang,
 | 
				
			||||||
 | 
					                    #(#impl_value)*
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        impl Update {
 | 
				
			||||||
 | 
					            fn convert(self) -> Create {
 | 
				
			||||||
 | 
					                Create {
 | 
				
			||||||
 | 
					                    lang: self.lang,
 | 
				
			||||||
 | 
					                    #(#impl_value)*
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let schema = quote! {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        pub mod schema {
 | 
				
			||||||
 | 
					            table! {
 | 
				
			||||||
 | 
					                use diesel::sql_types::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                #name (id) {
 | 
				
			||||||
 | 
					                    id -> Integer,
 | 
				
			||||||
 | 
					                    lang -> Text,
 | 
				
			||||||
 | 
					                    #(#names_vec -> #schema_value,)
 | 
				
			||||||
 | 
					                    *
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let structs = quote! {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        use schema::#name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #[derive(Debug, Clone, Queryable, Serialize)]
 | 
				
			||||||
 | 
					        pub struct Get {
 | 
				
			||||||
 | 
					            pub id: i32,
 | 
				
			||||||
 | 
					            pub lang: String,
 | 
				
			||||||
 | 
					            #(pub #names_vec: #get_value),
 | 
				
			||||||
 | 
					            *
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #[derive(Debug, AsChangeset, Insertable)]
 | 
				
			||||||
 | 
					        #[table_name = #name_literal]
 | 
				
			||||||
 | 
					        pub struct Create {
 | 
				
			||||||
 | 
					            pub lang: String,
 | 
				
			||||||
 | 
					            #(pub #names_vec: #get_value),
 | 
				
			||||||
 | 
					            *
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #[derive(Debug, FromForm)]
 | 
				
			||||||
 | 
					        pub struct Post {
 | 
				
			||||||
 | 
					            pub lang: String,
 | 
				
			||||||
 | 
					            #(pub #names_vec: #put_value),
 | 
				
			||||||
 | 
					            *
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #[derive(Debug, FromForm)]
 | 
				
			||||||
 | 
					        pub struct Update {
 | 
				
			||||||
 | 
					            pub id: i32,
 | 
				
			||||||
 | 
					            pub lang: String,
 | 
				
			||||||
 | 
					            #(pub #names_vec: #put_value),
 | 
				
			||||||
 | 
					            *
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #[derive(Debug, FromForm)]
 | 
				
			||||||
 | 
					        pub struct Delete {
 | 
				
			||||||
 | 
					            pub id: i32,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let imports = quote! {
 | 
				
			||||||
 | 
					        use crate::data::{defs::*, Lang};
 | 
				
			||||||
 | 
					        use crate::auth::Token;
 | 
				
			||||||
 | 
					        use ::chrono::naive::*;
 | 
				
			||||||
 | 
					        use ::diesel::{prelude::*, Insertable, Queryable};
 | 
				
			||||||
 | 
					        use ::rocket::{http::Status, request::Form, response::Redirect, State};
 | 
				
			||||||
 | 
					        use ::rocket_contrib::{json::Json, templates::Template};
 | 
				
			||||||
 | 
					        use ::serde::Serialize;
 | 
				
			||||||
 | 
					        use ::std::{collections::*, sync::Mutex};
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let endpoints = quote! {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        pub fn create(conn: &PgConnection, create: Create) -> Result<Get, diesel::result::Error> {
 | 
				
			||||||
 | 
					            diesel::insert_into(#name::table)
 | 
				
			||||||
 | 
					                .values(&create)
 | 
				
			||||||
 | 
					                .get_result(conn)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        pub fn get(conn: &PgConnection, lg: Lang) -> Result<Vec<Get>, diesel::result::Error> {
 | 
				
			||||||
 | 
					            use schema::#name::dsl::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            #name.filter(lang.eq(lg.0)).load::<Get>(conn)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        pub fn get_all(conn: &PgConnection) -> Result<Vec<Get>, diesel::result::Error> {
 | 
				
			||||||
 | 
					            use schema::#name::dsl::*;
 | 
				
			||||||
 | 
					            #name.load::<Get>(conn)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        pub fn update(
 | 
				
			||||||
 | 
					            conn: &PgConnection,
 | 
				
			||||||
 | 
					            idn: i32,
 | 
				
			||||||
 | 
					            create: Create,
 | 
				
			||||||
 | 
					        ) -> Result<Get, diesel::result::Error> {
 | 
				
			||||||
 | 
					            use schema::#name::dsl::*;
 | 
				
			||||||
 | 
					            diesel::update(#name.find(idn))
 | 
				
			||||||
 | 
					                .set(&create)
 | 
				
			||||||
 | 
					                .get_result::<Get>(conn)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        pub fn delete(conn: &PgConnection, idn: i32) -> Result<usize, diesel::result::Error> {
 | 
				
			||||||
 | 
					            use schema::#name::dsl::*;
 | 
				
			||||||
 | 
					            diesel::delete(#name.find(idn)).execute(conn)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #[get(#name_api)]
 | 
				
			||||||
 | 
					        pub fn api(pg: State<Mutex<PgConnection>>, lang: Lang) -> Result<Json<Vec<Get>>, Status> {
 | 
				
			||||||
 | 
					            Ok(Json(
 | 
				
			||||||
 | 
					                get(&*(pg.lock().unwrap()), lang).map_err(|_| Status::InternalServerError)?,
 | 
				
			||||||
 | 
					            ))
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #[post(#name_add, data = "<form>")]
 | 
				
			||||||
 | 
					        pub fn add(_token: Token, pg: State<Mutex<PgConnection>>, form: Form<Post>) -> Result<Redirect, Status> {
 | 
				
			||||||
 | 
					            match create(&*(pg.lock().unwrap()), form.into_inner().convert()) {
 | 
				
			||||||
 | 
					                Ok(_) => Ok(Redirect::to(#name_redir)),
 | 
				
			||||||
 | 
					                Err(_) => Err(Status::InternalServerError),
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #[post(#name_del, data = "<form>")]
 | 
				
			||||||
 | 
					        pub fn del(_token: Token, pg: State<Mutex<PgConnection>>, form: Form<Delete>) -> Result<Redirect, Status> {
 | 
				
			||||||
 | 
					            match delete(&*(pg.lock().unwrap()), form.id) {
 | 
				
			||||||
 | 
					                Ok(_) => Ok(Redirect::to(#name_redir)),
 | 
				
			||||||
 | 
					                Err(_) => Err(Status::InternalServerError),
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #[post(#name_upd, data = "<form>")]
 | 
				
			||||||
 | 
					        pub fn upd(_token: Token, pg: State<Mutex<PgConnection>>, form: Form<Update>) -> Result<Redirect, Status> {
 | 
				
			||||||
 | 
					            match update(&*(pg.lock().unwrap()), form.id, form.into_inner().convert()) {
 | 
				
			||||||
 | 
					                Ok(_) => Ok(Redirect::to(#name_redir)),
 | 
				
			||||||
 | 
					                Err(_) => Err(Status::InternalServerError),
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #[get(#name_dir)]
 | 
				
			||||||
 | 
					        pub fn ui(_token: Token, pg: State<Mutex<PgConnection>>) -> Result<Template, Status> {
 | 
				
			||||||
 | 
					            let ctx = get_all(&*(pg.lock().unwrap()))
 | 
				
			||||||
 | 
					                .map_err(|_| Status::InternalServerError)?
 | 
				
			||||||
 | 
					                .iter()
 | 
				
			||||||
 | 
					                .map(|x| (x.id, x.clone()))
 | 
				
			||||||
 | 
					                .collect::<HashMap<i32, Get>>();
 | 
				
			||||||
 | 
					            Ok(Template::render(#name_literal, &ctx))
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let tok = quote! {
 | 
				
			||||||
 | 
					        pub mod #name {
 | 
				
			||||||
 | 
					            #imports
 | 
				
			||||||
 | 
					            #schema
 | 
				
			||||||
 | 
					            #structs
 | 
				
			||||||
 | 
					            #impls
 | 
				
			||||||
 | 
					            #endpoints
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    tok.into()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[proc_macro]
 | 
				
			||||||
 | 
					pub fn api_route(item: proc_macro::TokenStream) -> proc_macro::TokenStream {
 | 
				
			||||||
 | 
					    api_route_inner(TokenStream::from(item)).into()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[test]
 | 
				
			||||||
 | 
					pub fn test() {
 | 
				
			||||||
 | 
					    let val = quote! {
 | 
				
			||||||
 | 
					        events {
 | 
				
			||||||
 | 
					            title: (Text, String, String),
 | 
				
			||||||
 | 
					            location: (Text, String, String),
 | 
				
			||||||
 | 
					            text: (Text, String, String),
 | 
				
			||||||
 | 
					            event_date: (Text, NaiveDate, DateForm),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let macr = api_route_inner(val);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    println!("{}", macr);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										0
									
								
								cms/migrations/.gitkeep
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										3
									
								
								cms/migrations/setup/down.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					DROP TABLE auth_val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DROP TABLE events;
 | 
				
			||||||
							
								
								
									
										15
									
								
								cms/migrations/setup/up.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					CREATE TABLE auth_val (
 | 
				
			||||||
 | 
					    id SERIAL PRIMARY KEY,
 | 
				
			||||||
 | 
					    email VARCHAR
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					INSERT INTO auth_val(email) VALUES('hkailadka88@gmail.com');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CREATE TABLE events (
 | 
				
			||||||
 | 
					    id SERIAL PRIMARY KEY,
 | 
				
			||||||
 | 
					    lang VARCHAR,
 | 
				
			||||||
 | 
					    title VARCHAR NOT NULL,
 | 
				
			||||||
 | 
					    text VARCHAR,
 | 
				
			||||||
 | 
					    location VARCHAR NOT NULL,
 | 
				
			||||||
 | 
					    event_date DATE
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
							
								
								
									
										209
									
								
								cms/src/auth.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,209 @@
 | 
				
			|||||||
 | 
					use diesel::{prelude::*, Queryable};
 | 
				
			||||||
 | 
					use oauth2::{
 | 
				
			||||||
 | 
					    basic::BasicClient, reqwest::http_client, AuthUrl, AuthorizationCode, ClientId, ClientSecret,
 | 
				
			||||||
 | 
					    CsrfToken, RedirectUrl, RevocationUrl, Scope, TokenResponse, TokenUrl,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					use reqwest::blocking::Client;
 | 
				
			||||||
 | 
					use rocket::{
 | 
				
			||||||
 | 
					    http::{Cookie, Cookies, SameSite, Status},
 | 
				
			||||||
 | 
					    request,
 | 
				
			||||||
 | 
					    request::FromRequest,
 | 
				
			||||||
 | 
					    response::Redirect,
 | 
				
			||||||
 | 
					    Outcome, Request, State,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					use serde::Serialize;
 | 
				
			||||||
 | 
					use serde_json::Value;
 | 
				
			||||||
 | 
					use std::{fmt::Debug, sync::Mutex};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mod schema {
 | 
				
			||||||
 | 
					    table! {
 | 
				
			||||||
 | 
					        use diesel::sql_types::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        auth_val (id) {
 | 
				
			||||||
 | 
					            id -> Integer,
 | 
				
			||||||
 | 
					            email -> Text,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub struct Host(String);
 | 
				
			||||||
 | 
					pub struct Token(String);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Clone)]
 | 
				
			||||||
 | 
					pub struct Settings {
 | 
				
			||||||
 | 
					    pub id: String,
 | 
				
			||||||
 | 
					    pub secret: String,
 | 
				
			||||||
 | 
					    pub auth_url: AuthUrl,
 | 
				
			||||||
 | 
					    pub token_url: TokenUrl,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Queryable, Serialize)]
 | 
				
			||||||
 | 
					struct Auth {
 | 
				
			||||||
 | 
					    pub id: i32,
 | 
				
			||||||
 | 
					    pub email: String,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn get_auth(conn: &PgConnection) -> Result<Vec<Auth>, diesel::result::Error> {
 | 
				
			||||||
 | 
					    use schema::auth_val::dsl::*;
 | 
				
			||||||
 | 
					    auth_val.load::<Auth>(conn)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<'a, 'r> FromRequest<'a, 'r> for Host {
 | 
				
			||||||
 | 
					    type Error = ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
 | 
				
			||||||
 | 
					        let host = request.headers().get_one("Host");
 | 
				
			||||||
 | 
					        match host {
 | 
				
			||||||
 | 
					            Some(host) => Outcome::Success(Host(host.to_string())),
 | 
				
			||||||
 | 
					            None => Outcome::Failure((Status::Unauthorized, ())),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<'a, 'r> FromRequest<'a, 'r> for Token {
 | 
				
			||||||
 | 
					    type Error = Redirect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
 | 
				
			||||||
 | 
					        match request.cookies().get("token") {
 | 
				
			||||||
 | 
					            Some(token) => {
 | 
				
			||||||
 | 
					                let resp: Value = Client::new()
 | 
				
			||||||
 | 
					                    .get("https://www.googleapis.com/userinfo/v2/me")
 | 
				
			||||||
 | 
					                    .bearer_auth(token.name_value().1)
 | 
				
			||||||
 | 
					                    .send()
 | 
				
			||||||
 | 
					                    .unwrap()
 | 
				
			||||||
 | 
					                    .json()
 | 
				
			||||||
 | 
					                    .unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if resp["error"] != Value::Null {
 | 
				
			||||||
 | 
					                    return Outcome::Forward(());
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    let email = resp["email"].clone();
 | 
				
			||||||
 | 
					                    let pg = request.guard::<State<Mutex<PgConnection>>>().unwrap();
 | 
				
			||||||
 | 
					                    let diesel_op = get_auth(&*(pg.lock().unwrap()));
 | 
				
			||||||
 | 
					                    let auths: Vec<String> = match diesel_op {
 | 
				
			||||||
 | 
					                        Ok(n) => n.into_iter().map(|x| x.email).collect::<Vec<String>>(),
 | 
				
			||||||
 | 
					                        Err(_) => vec![],
 | 
				
			||||||
 | 
					                    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if auths.into_iter().any(|x| x == email.as_str().unwrap_or("")) {
 | 
				
			||||||
 | 
					                        return Outcome::Success(Token(String::from(email.as_str().unwrap_or(""))));
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        return Outcome::Forward(());
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            None => Outcome::Forward(())
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[get("/oauth")]
 | 
				
			||||||
 | 
					pub fn oauth(
 | 
				
			||||||
 | 
					    mut cookies: Cookies,
 | 
				
			||||||
 | 
					    settings: State<Settings>,
 | 
				
			||||||
 | 
					    host: Host,
 | 
				
			||||||
 | 
					) -> Result<Redirect, Status> {
 | 
				
			||||||
 | 
					    let client = get_client(settings.inner().clone(), host);
 | 
				
			||||||
 | 
					    let csrf_token = CsrfToken::new_random();
 | 
				
			||||||
 | 
					    let csrf: String = csrf_token.secret().into();
 | 
				
			||||||
 | 
					    cookies.add(Cookie::new("state", csrf));
 | 
				
			||||||
 | 
					    let (authorize_url, _csrf_state) = client
 | 
				
			||||||
 | 
					        .authorize_url(|| csrf_token.clone())
 | 
				
			||||||
 | 
					        .add_scope(Scope::new(
 | 
				
			||||||
 | 
					            "https://www.googleapis.com/auth/userinfo.email".to_owned(),
 | 
				
			||||||
 | 
					        ))
 | 
				
			||||||
 | 
					        .url();
 | 
				
			||||||
 | 
					    let auth = authorize_url.to_string();
 | 
				
			||||||
 | 
					    Ok(Redirect::to(auth))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[get("/logout")]
 | 
				
			||||||
 | 
					pub fn logout(mut cookies: Cookies) -> Redirect {
 | 
				
			||||||
 | 
					    match cookies.get("token") {
 | 
				
			||||||
 | 
					        Some(_) => {
 | 
				
			||||||
 | 
					            cookies.remove(Cookie::named("token"));
 | 
				
			||||||
 | 
					            Redirect::to("/")
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        None => Redirect::to("/"),
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[get("/callback?<state>&<code>")]
 | 
				
			||||||
 | 
					pub fn callback(
 | 
				
			||||||
 | 
					    state: String,
 | 
				
			||||||
 | 
					    code: String,
 | 
				
			||||||
 | 
					    pg: State<Mutex<PgConnection>>,
 | 
				
			||||||
 | 
					    mut cookies: Cookies,
 | 
				
			||||||
 | 
					    host: Host,
 | 
				
			||||||
 | 
					    sa: State<Settings>,
 | 
				
			||||||
 | 
					) -> Result<Redirect, Status> {
 | 
				
			||||||
 | 
					    let sc = cookies.get("state");
 | 
				
			||||||
 | 
					    match sc {
 | 
				
			||||||
 | 
					        Some(c) => {
 | 
				
			||||||
 | 
					            if state != c.value() {
 | 
				
			||||||
 | 
					                return Err(Status::Forbidden);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                cookies.remove(Cookie::named("state"));
 | 
				
			||||||
 | 
					                let client = get_client(sa.inner().clone(), host);
 | 
				
			||||||
 | 
					                let token_result = client
 | 
				
			||||||
 | 
					                    .exchange_code(AuthorizationCode::new(code))
 | 
				
			||||||
 | 
					                    .request(http_client);
 | 
				
			||||||
 | 
					                match token_result {
 | 
				
			||||||
 | 
					                    Ok(n) => {
 | 
				
			||||||
 | 
					                        let secret = n.access_token().secret();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        let resp: Value = Client::new()
 | 
				
			||||||
 | 
					                            .get("https://www.googleapis.com/userinfo/v2/me")
 | 
				
			||||||
 | 
					                            .bearer_auth(secret)
 | 
				
			||||||
 | 
					                            .send()
 | 
				
			||||||
 | 
					                            .unwrap()
 | 
				
			||||||
 | 
					                            .json()
 | 
				
			||||||
 | 
					                            .unwrap();
 | 
				
			||||||
 | 
					                        if resp["error"] != Value::Null {
 | 
				
			||||||
 | 
					                            return Err(Status::BadRequest);
 | 
				
			||||||
 | 
					                        } else {
 | 
				
			||||||
 | 
					                            let email = resp["email"].clone();
 | 
				
			||||||
 | 
					                            let diesel_op = get_auth(&*(pg.lock().unwrap()));
 | 
				
			||||||
 | 
					                            let auths: Vec<String> = match diesel_op {
 | 
				
			||||||
 | 
					                                Ok(n) => n.into_iter().map(|x| x.email).collect::<Vec<String>>(),
 | 
				
			||||||
 | 
					                                Err(_) => vec![],
 | 
				
			||||||
 | 
					                            };
 | 
				
			||||||
 | 
					                            if auths.into_iter().any(|x| x == email.as_str().unwrap_or("")) {
 | 
				
			||||||
 | 
					                                let mut cook = Cookie::new("token", secret.to_string());
 | 
				
			||||||
 | 
					                                cook.set_same_site(SameSite::Strict);
 | 
				
			||||||
 | 
					                                cook.set_http_only(true);
 | 
				
			||||||
 | 
					                                cook.set_secure(true);
 | 
				
			||||||
 | 
					                                cookies.add(cook);
 | 
				
			||||||
 | 
					                                return Ok(Redirect::to("/"));
 | 
				
			||||||
 | 
					                            } else {
 | 
				
			||||||
 | 
					                                return Err(Status::Forbidden);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    Err(_) => return Err(Status::InternalServerError),
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        None => Err(Status::BadRequest),
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn get_client(settings: Settings, host: Host) -> BasicClient {
 | 
				
			||||||
 | 
					    let gcid = ClientId::new(settings.id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let gcs = ClientSecret::new(settings.secret);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let auth_url = settings.auth_url;
 | 
				
			||||||
 | 
					    let token_url = settings.token_url;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let base: String = host.0.to_owned();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    BasicClient::new(gcid, Some(gcs), auth_url, Some(token_url))
 | 
				
			||||||
 | 
					        .set_redirect_uri(
 | 
				
			||||||
 | 
					            RedirectUrl::new(format!("http://{}/callback", base)).expect("Invalid redirect URL"),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        .set_revocation_uri(
 | 
				
			||||||
 | 
					            RevocationUrl::new("https://oauth2.googleapis.com/revoke".to_owned())
 | 
				
			||||||
 | 
					                .expect("Invalid revocation endpoint URL"),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										78
									
								
								cms/src/data/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,78 @@
 | 
				
			|||||||
 | 
					use rocket::{
 | 
				
			||||||
 | 
					    http::{RawStr, Status},
 | 
				
			||||||
 | 
					    request::FromParam,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					use std::borrow::Cow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use cms_macro::api_route;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub struct Lang<'a>(Cow<'a, str>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn valid_lang(lang: &str) -> bool {
 | 
				
			||||||
 | 
					    lang.chars().all(|c| (c >= 'a' && c <= 'z')) && lang.chars().count() == 2
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<'a> FromParam<'a> for Lang<'a> {
 | 
				
			||||||
 | 
					    type Error = Status;
 | 
				
			||||||
 | 
					    fn from_param(param: &'a RawStr) -> Result<Lang<'a>, Status> {
 | 
				
			||||||
 | 
					        match valid_lang(param) {
 | 
				
			||||||
 | 
					            true => Ok(Lang(Cow::Borrowed(param))),
 | 
				
			||||||
 | 
					            false => Err(Status::InternalServerError),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub mod defs {
 | 
				
			||||||
 | 
					    use chrono::naive::NaiveDate;
 | 
				
			||||||
 | 
					    use rocket::{http::RawStr, request::FromFormValue};
 | 
				
			||||||
 | 
					    use std::ops::Deref;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[derive(Debug)]
 | 
				
			||||||
 | 
					    pub struct DateForm(NaiveDate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    impl Deref for DateForm {
 | 
				
			||||||
 | 
					        type Target = NaiveDate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fn deref(&self) -> &NaiveDate {
 | 
				
			||||||
 | 
					            &self.0
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    impl<'v> FromFormValue<'v> for DateForm {
 | 
				
			||||||
 | 
					        type Error = ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fn from_form_value(value: &'v RawStr) -> Result<DateForm, ()> {
 | 
				
			||||||
 | 
					            let value_uri = match value.url_decode() {
 | 
				
			||||||
 | 
					                Ok(n) => n,
 | 
				
			||||||
 | 
					                Err(_) => return Err(()),
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            let naivedate = NaiveDate::parse_from_str(&value_uri[..], "%m/%d/%Y");
 | 
				
			||||||
 | 
					            match naivedate {
 | 
				
			||||||
 | 
					                Ok(n) => Ok(DateForm(n)),
 | 
				
			||||||
 | 
					                Err(_) => Err(()),
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					api_route! {
 | 
				
			||||||
 | 
					    events {
 | 
				
			||||||
 | 
					        title: (Text, String, String),
 | 
				
			||||||
 | 
					        location: (Text, String, String),
 | 
				
			||||||
 | 
					        text: (Text, String, String),
 | 
				
			||||||
 | 
					        event_date: (Date, NaiveDate, DateForm),
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					api_route! {
 | 
				
			||||||
 | 
					    teachers {
 | 
				
			||||||
 | 
					        name: (Text, String, String),
 | 
				
			||||||
 | 
					        emails: (Array<Text>, Vec<String>, Vec<String>),
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					//TODO: fix value parsing to read a TokenStream until the `,` to allow for containerized types in
 | 
				
			||||||
 | 
					//the macro
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										158
									
								
								cms/src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,158 @@
 | 
				
			|||||||
 | 
					#![feature(decl_macro)]
 | 
				
			||||||
 | 
					#[macro_use]
 | 
				
			||||||
 | 
					extern crate diesel;
 | 
				
			||||||
 | 
					#[macro_use]
 | 
				
			||||||
 | 
					extern crate diesel_migrations;
 | 
				
			||||||
 | 
					#[macro_use]
 | 
				
			||||||
 | 
					extern crate rocket;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mod auth;
 | 
				
			||||||
 | 
					mod data;
 | 
				
			||||||
 | 
					mod secret;
 | 
				
			||||||
 | 
					mod utils;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use auth::Settings;
 | 
				
			||||||
 | 
					use clap::{App, Arg};
 | 
				
			||||||
 | 
					use diesel::prelude::*;
 | 
				
			||||||
 | 
					use dotenv::dotenv;
 | 
				
			||||||
 | 
					use oauth2::{AuthUrl, TokenUrl};
 | 
				
			||||||
 | 
					use rocket::{
 | 
				
			||||||
 | 
					    config::{Config, Environment},
 | 
				
			||||||
 | 
					    Rocket,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					use rocket_contrib::templates::Template;
 | 
				
			||||||
 | 
					use std::{
 | 
				
			||||||
 | 
					    collections::*,
 | 
				
			||||||
 | 
					    env,
 | 
				
			||||||
 | 
					    net::IpAddr,
 | 
				
			||||||
 | 
					    path::{Path, PathBuf},
 | 
				
			||||||
 | 
					    sync::Mutex,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					use utils::{db_conn, exit_with_error};
 | 
				
			||||||
 | 
					use rocket::response::Redirect;
 | 
				
			||||||
 | 
					use auth::Token;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[get("/")]
 | 
				
			||||||
 | 
					fn home(_token: Token) -> Template {
 | 
				
			||||||
 | 
					    let context: HashMap<&str, &str> = HashMap::new();
 | 
				
			||||||
 | 
					    Template::render("home", &context)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[get("/", rank=2)]
 | 
				
			||||||
 | 
					fn home_not_logged_in() -> Redirect {
 | 
				
			||||||
 | 
					    Redirect::to(uri!(login))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[get("/login")]
 | 
				
			||||||
 | 
					fn login() -> Template {
 | 
				
			||||||
 | 
					    let context: HashMap<&str, &str> = [("oauth", "/oauth")].iter().cloned().collect();
 | 
				
			||||||
 | 
					    Template::render("login", &context)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[get("/static/<path..>")]
 | 
				
			||||||
 | 
					fn static_files(path: PathBuf) -> Option<rocket::response::NamedFile> {
 | 
				
			||||||
 | 
					    rocket::response::NamedFile::open(Path::new("cms/static/").join(path)).ok()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn rocket(port: u16, address: String, env: Environment, pg: PgConnection, sa: Settings) -> Rocket {
 | 
				
			||||||
 | 
					    let mut config = Config::build(env)
 | 
				
			||||||
 | 
					        .port(port)
 | 
				
			||||||
 | 
					        .address(address)
 | 
				
			||||||
 | 
					        .secret_key(secret::create_secret())
 | 
				
			||||||
 | 
					        .unwrap();
 | 
				
			||||||
 | 
					    let mut extras = HashMap::new();
 | 
				
			||||||
 | 
					    extras.insert("template_dir".to_string(), "cms/templates/".into());
 | 
				
			||||||
 | 
					    config.set_extras(extras);
 | 
				
			||||||
 | 
					    rocket::custom(config)
 | 
				
			||||||
 | 
					        .attach(Template::fairing())
 | 
				
			||||||
 | 
					        .manage(Mutex::new(pg))
 | 
				
			||||||
 | 
					        .manage(sa)
 | 
				
			||||||
 | 
					        .mount(
 | 
				
			||||||
 | 
					            "/",
 | 
				
			||||||
 | 
					            routes![home, home_not_logged_in, login, auth::callback, auth::oauth, static_files],
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        .mount("/api", routes![data::events::api])
 | 
				
			||||||
 | 
					        .mount(
 | 
				
			||||||
 | 
					            "/ui",
 | 
				
			||||||
 | 
					            routes![
 | 
				
			||||||
 | 
					                data::events::ui,
 | 
				
			||||||
 | 
					                data::events::add,
 | 
				
			||||||
 | 
					                data::events::del,
 | 
				
			||||||
 | 
					                data::events::upd
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn main() {
 | 
				
			||||||
 | 
					    dotenv().ok();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let gcid = env::var("BLAZERCMS_CLIENT_ID")
 | 
				
			||||||
 | 
					        .unwrap_or_else(|_| exit_with_error("BLAZERCMS_CLIENT_ID must be set"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let gcs = env::var("BLAZERCMS_SECRET")
 | 
				
			||||||
 | 
					        .unwrap_or_else(|_| exit_with_error("BLAZERCMS_SECRET must be set"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let auth_url = AuthUrl::new("https://accounts.google.com/o/oauth2/v2/auth".to_owned())
 | 
				
			||||||
 | 
					        .expect("Invalid authorization endpoint.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let token_url = TokenUrl::new("https://www.googleapis.com/oauth2/v3/token".to_owned())
 | 
				
			||||||
 | 
					        .expect("Invalid token endpoint. ");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let postgres = db_conn();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let matches = App::new("blazercms")
 | 
				
			||||||
 | 
					        .version("1.0")
 | 
				
			||||||
 | 
					        .arg(
 | 
				
			||||||
 | 
					            Arg::with_name("port")
 | 
				
			||||||
 | 
					                .short("p")
 | 
				
			||||||
 | 
					                .long("port")
 | 
				
			||||||
 | 
					                .default_value("8080"),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        .arg(
 | 
				
			||||||
 | 
					            Arg::with_name("prod")
 | 
				
			||||||
 | 
					                .short("r")
 | 
				
			||||||
 | 
					                .long("prod")
 | 
				
			||||||
 | 
					                .takes_value(false),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        .arg(
 | 
				
			||||||
 | 
					            Arg::with_name("addr")
 | 
				
			||||||
 | 
					                .short("a")
 | 
				
			||||||
 | 
					                .long("addr")
 | 
				
			||||||
 | 
					                .default_value("127.0.0.1"),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        .get_matches();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let port = matches
 | 
				
			||||||
 | 
					        .value_of("port")
 | 
				
			||||||
 | 
					        .unwrap()
 | 
				
			||||||
 | 
					        .parse::<u16>()
 | 
				
			||||||
 | 
					        .unwrap_or_else(|_| exit_with_error("Port must be an integer! "));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let addr = matches
 | 
				
			||||||
 | 
					        .value_of("addr")
 | 
				
			||||||
 | 
					        .unwrap()
 | 
				
			||||||
 | 
					        .parse::<IpAddr>()
 | 
				
			||||||
 | 
					        .unwrap_or_else(|_| exit_with_error("Address must be a valid IP Address! "))
 | 
				
			||||||
 | 
					        .to_string();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let env;
 | 
				
			||||||
 | 
					    if matches.is_present("prod") {
 | 
				
			||||||
 | 
					        env = Environment::Production;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        env = Environment::Development;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let auth_settings = Settings {
 | 
				
			||||||
 | 
					        id: gcid,
 | 
				
			||||||
 | 
					        secret: gcs,
 | 
				
			||||||
 | 
					        auth_url: auth_url,
 | 
				
			||||||
 | 
					        token_url: token_url,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let err = rocket(port, addr, env, postgres, auth_settings).launch();
 | 
				
			||||||
 | 
					    exit_with_error(&format!("Error: {}", err));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										7
									
								
								cms/src/secret.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					use rand::{rngs::OsRng, RngCore};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn create_secret() -> String {
 | 
				
			||||||
 | 
					    let mut secret = [0u8; 32];
 | 
				
			||||||
 | 
					    OsRng.fill_bytes(&mut secret);
 | 
				
			||||||
 | 
					    base64::encode(&secret)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										21
									
								
								cms/src/utils.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					use ansi_term::Colour::Red;
 | 
				
			||||||
 | 
					use diesel::{pg::PgConnection, prelude::*};
 | 
				
			||||||
 | 
					use std::env;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn exit_with_error(msg: &str) -> ! {
 | 
				
			||||||
 | 
					    eprintln!("{}", Red.paint(msg));
 | 
				
			||||||
 | 
					    std::process::exit(1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn db_conn() -> PgConnection {
 | 
				
			||||||
 | 
					    embed_migrations!("migrations");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let database_url = env::var("BLAZERCMS_DATABASE_URL")
 | 
				
			||||||
 | 
					        .unwrap_or_else(|_| exit_with_error("BLAZERCMS_DATABASE_URL must be set"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let db = PgConnection::establish(&database_url)
 | 
				
			||||||
 | 
					        .unwrap_or_else(|_| exit_with_error("Error connecting to database. "));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    embedded_migrations::run(&db).unwrap_or_else(|_| exit_with_error("Error migrating database. "));
 | 
				
			||||||
 | 
					    db
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										3
									
								
								cms/static/style.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					body {
 | 
				
			||||||
 | 
					    background-color: lightblue;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										25
									
								
								cms/templates/events.html.hbs
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					<!-- vim: set ft=html: -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<html>
 | 
				
			||||||
 | 
					    <head>
 | 
				
			||||||
 | 
					        <link rel="stylesheet" href="/static/style.css">
 | 
				
			||||||
 | 
					    </head>
 | 
				
			||||||
 | 
					    <body>
 | 
				
			||||||
 | 
					        <p>{{6.title}}</p>
 | 
				
			||||||
 | 
					        <br>
 | 
				
			||||||
 | 
					        <form action="events/add" method="post">
 | 
				
			||||||
 | 
					            <input type="text", id="lang", name="lang">
 | 
				
			||||||
 | 
					            <input type="text", id="title", name="title">
 | 
				
			||||||
 | 
					            <input type="text", id="location", name="location">
 | 
				
			||||||
 | 
					            <input type="text", id="text", name="text">
 | 
				
			||||||
 | 
					            <input type="text", id="event_date", name="event_date">
 | 
				
			||||||
 | 
					            <input type="submit", value="Submit">
 | 
				
			||||||
 | 
					        </form>
 | 
				
			||||||
 | 
					        <form action="events/del" method="post">
 | 
				
			||||||
 | 
					            <input type="number", id="id", name="id">
 | 
				
			||||||
 | 
					            <input type="submit", value="Submit">
 | 
				
			||||||
 | 
					        </form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    </body>
 | 
				
			||||||
 | 
					    </head>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										9
									
								
								cms/templates/home.html.hbs
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					{{! vim: set ft=html: }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<html>
 | 
				
			||||||
 | 
					    <head>
 | 
				
			||||||
 | 
					    </head>
 | 
				
			||||||
 | 
					    <body>
 | 
				
			||||||
 | 
					        <a href="/ui/events">Events</a>
 | 
				
			||||||
 | 
					    </body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										10
									
								
								cms/templates/login.html.hbs
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					<!-- vim: set ft=html: -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<html>
 | 
				
			||||||
 | 
					    <head>
 | 
				
			||||||
 | 
					    </head>
 | 
				
			||||||
 | 
					    <body>
 | 
				
			||||||
 | 
					        <a href={{oauth}}>Login</a>
 | 
				
			||||||
 | 
					    </body>
 | 
				
			||||||
 | 
					    </head>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										19
									
								
								docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					version: "3.9"
 | 
				
			||||||
 | 
					services:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  postgres:
 | 
				
			||||||
 | 
					    image: "postgres:alpine"
 | 
				
			||||||
 | 
					    environment:
 | 
				
			||||||
 | 
					      POSTGRES_PASSWORD: ${BLAZERCMS_POSTGRES}
 | 
				
			||||||
 | 
					    ports:
 | 
				
			||||||
 | 
					      - "5432:5432"
 | 
				
			||||||
 | 
					  web:
 | 
				
			||||||
 | 
					    build: cms/
 | 
				
			||||||
 | 
					    ports:
 | 
				
			||||||
 | 
					      - "8080:8080"
 | 
				
			||||||
 | 
					    depends_on:
 | 
				
			||||||
 | 
					      - postgres
 | 
				
			||||||
 | 
					    environment:
 | 
				
			||||||
 | 
					      BLAZERCMS_DATABASE_URL: ${BLAZERCMS_DATABASE_URL}
 | 
				
			||||||
 | 
					      BLAZERCMS_CLIENT_ID: ${BLAZERCMS_CLIENT_ID}
 | 
				
			||||||
 | 
					      BLAZERCMS_SECRET: ${BLAZERCMS_SECRET}
 | 
				
			||||||
							
								
								
									
										11
									
								
								ios/Podfile
									
									
									
									
									
								
							
							
						
						@ -15,19 +15,26 @@ target 'blazerapp' do
 | 
				
			|||||||
  pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons'
 | 
					  pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  pod 'RNLocalize', :path => '../node_modules/react-native-localize'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  target 'blazerappTests' do
 | 
					  target 'blazerappTests' do
 | 
				
			||||||
    inherit! :complete
 | 
					    inherit! :complete
 | 
				
			||||||
    # Pods for testing
 | 
					    # Pods for testing
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					 | 
				
			||||||
  # Enables Flipper.
 | 
					  # Enables Flipper.
 | 
				
			||||||
  #
 | 
					  #
 | 
				
			||||||
  # Note that if you have use_frameworks! enabled, Flipper will not work and
 | 
					  # Note that if you have use_frameworks! enabled, Flipper will not work and
 | 
				
			||||||
  # you should disable these next few lines.
 | 
					  # you should disable these next few lines.
 | 
				
			||||||
  use_flipper!
 | 
					  use_flipper!({'Flipper' => '0.87.0' , 'Flipper-Folly' => '2.5.3' , 'Flipper-RSocket' => '1.3.1' })
 | 
				
			||||||
  post_install do |installer|
 | 
					  post_install do |installer|
 | 
				
			||||||
    flipper_post_install(installer)
 | 
					    flipper_post_install(installer)
 | 
				
			||||||
 | 
					    installer.pods_project.targets.each do |target|
 | 
				
			||||||
 | 
					      target.build_configurations.each do |config|
 | 
				
			||||||
 | 
					       config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0'
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					     end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
target 'blazerapp-tvOS' do
 | 
					target 'blazerapp-tvOS' do
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										532
									
								
								ios/Podfile.lock
									
									
									
									
									
								
							
							
						
						@ -3,60 +3,70 @@ PODS:
 | 
				
			|||||||
  - BVLinearGradient (2.5.6):
 | 
					  - BVLinearGradient (2.5.6):
 | 
				
			||||||
    - React
 | 
					    - React
 | 
				
			||||||
  - CocoaAsyncSocket (7.6.5)
 | 
					  - CocoaAsyncSocket (7.6.5)
 | 
				
			||||||
  - CocoaLibEvent (1.0.0)
 | 
					 | 
				
			||||||
  - DoubleConversion (1.1.6)
 | 
					  - DoubleConversion (1.1.6)
 | 
				
			||||||
  - FBLazyVector (0.63.2)
 | 
					  - FBLazyVector (0.63.4)
 | 
				
			||||||
  - FBReactNativeSpec (0.63.2):
 | 
					  - FBReactNativeSpec (0.63.4):
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - RCTRequired (= 0.63.2)
 | 
					    - RCTRequired (= 0.63.4)
 | 
				
			||||||
    - RCTTypeSafety (= 0.63.2)
 | 
					    - RCTTypeSafety (= 0.63.4)
 | 
				
			||||||
    - React-Core (= 0.63.2)
 | 
					    - React-Core (= 0.63.4)
 | 
				
			||||||
    - React-jsi (= 0.63.2)
 | 
					    - React-jsi (= 0.63.4)
 | 
				
			||||||
    - ReactCommon/turbomodule/core (= 0.63.2)
 | 
					    - ReactCommon/turbomodule/core (= 0.63.4)
 | 
				
			||||||
  - Flipper (0.41.5):
 | 
					  - Flipper (0.87.0):
 | 
				
			||||||
    - Flipper-Folly (~> 2.2)
 | 
					    - Flipper-Folly (~> 2.5)
 | 
				
			||||||
    - Flipper-RSocket (~> 1.1)
 | 
					    - Flipper-RSocket (~> 1.3)
 | 
				
			||||||
  - Flipper-DoubleConversion (1.1.7)
 | 
					  - Flipper-DoubleConversion (1.1.7)
 | 
				
			||||||
  - Flipper-Folly (2.2.0):
 | 
					  - Flipper-Folly (2.5.3):
 | 
				
			||||||
    - boost-for-react-native
 | 
					    - boost-for-react-native
 | 
				
			||||||
    - CocoaLibEvent (~> 1.0)
 | 
					 | 
				
			||||||
    - Flipper-DoubleConversion
 | 
					    - Flipper-DoubleConversion
 | 
				
			||||||
    - Flipper-Glog
 | 
					    - Flipper-Glog
 | 
				
			||||||
    - OpenSSL-Universal (= 1.0.2.19)
 | 
					    - libevent (~> 2.1.12)
 | 
				
			||||||
 | 
					    - OpenSSL-Universal (= 1.1.180)
 | 
				
			||||||
  - Flipper-Glog (0.3.6)
 | 
					  - Flipper-Glog (0.3.6)
 | 
				
			||||||
  - Flipper-PeerTalk (0.0.4)
 | 
					  - Flipper-PeerTalk (0.0.4)
 | 
				
			||||||
  - Flipper-RSocket (1.1.0):
 | 
					  - Flipper-RSocket (1.3.1):
 | 
				
			||||||
    - Flipper-Folly (~> 2.2)
 | 
					    - Flipper-Folly (~> 2.5)
 | 
				
			||||||
  - FlipperKit (0.41.5):
 | 
					  - FlipperKit (0.87.0):
 | 
				
			||||||
    - FlipperKit/Core (= 0.41.5)
 | 
					    - FlipperKit/Core (= 0.87.0)
 | 
				
			||||||
  - FlipperKit/Core (0.41.5):
 | 
					  - FlipperKit/Core (0.87.0):
 | 
				
			||||||
    - Flipper (~> 0.41.5)
 | 
					    - Flipper (~> 0.87.0)
 | 
				
			||||||
    - FlipperKit/CppBridge
 | 
					    - FlipperKit/CppBridge
 | 
				
			||||||
    - FlipperKit/FBCxxFollyDynamicConvert
 | 
					    - FlipperKit/FBCxxFollyDynamicConvert
 | 
				
			||||||
    - FlipperKit/FBDefines
 | 
					    - FlipperKit/FBDefines
 | 
				
			||||||
    - FlipperKit/FKPortForwarding
 | 
					    - FlipperKit/FKPortForwarding
 | 
				
			||||||
  - FlipperKit/CppBridge (0.41.5):
 | 
					  - FlipperKit/CppBridge (0.87.0):
 | 
				
			||||||
    - Flipper (~> 0.41.5)
 | 
					    - Flipper (~> 0.87.0)
 | 
				
			||||||
  - FlipperKit/FBCxxFollyDynamicConvert (0.41.5):
 | 
					  - FlipperKit/FBCxxFollyDynamicConvert (0.87.0):
 | 
				
			||||||
    - Flipper-Folly (~> 2.2)
 | 
					    - Flipper-Folly (~> 2.5)
 | 
				
			||||||
  - FlipperKit/FBDefines (0.41.5)
 | 
					  - FlipperKit/FBDefines (0.87.0)
 | 
				
			||||||
  - FlipperKit/FKPortForwarding (0.41.5):
 | 
					  - FlipperKit/FKPortForwarding (0.87.0):
 | 
				
			||||||
    - CocoaAsyncSocket (~> 7.6)
 | 
					    - CocoaAsyncSocket (~> 7.6)
 | 
				
			||||||
    - Flipper-PeerTalk (~> 0.0.4)
 | 
					    - Flipper-PeerTalk (~> 0.0.4)
 | 
				
			||||||
  - FlipperKit/FlipperKitHighlightOverlay (0.41.5)
 | 
					  - FlipperKit/FlipperKitHighlightOverlay (0.87.0)
 | 
				
			||||||
  - FlipperKit/FlipperKitLayoutPlugin (0.41.5):
 | 
					  - FlipperKit/FlipperKitLayoutHelpers (0.87.0):
 | 
				
			||||||
    - FlipperKit/Core
 | 
					    - FlipperKit/Core
 | 
				
			||||||
    - FlipperKit/FlipperKitHighlightOverlay
 | 
					    - FlipperKit/FlipperKitHighlightOverlay
 | 
				
			||||||
    - FlipperKit/FlipperKitLayoutTextSearchable
 | 
					    - FlipperKit/FlipperKitLayoutTextSearchable
 | 
				
			||||||
 | 
					  - FlipperKit/FlipperKitLayoutIOSDescriptors (0.87.0):
 | 
				
			||||||
 | 
					    - FlipperKit/Core
 | 
				
			||||||
 | 
					    - FlipperKit/FlipperKitHighlightOverlay
 | 
				
			||||||
 | 
					    - FlipperKit/FlipperKitLayoutHelpers
 | 
				
			||||||
    - YogaKit (~> 1.18)
 | 
					    - YogaKit (~> 1.18)
 | 
				
			||||||
  - FlipperKit/FlipperKitLayoutTextSearchable (0.41.5)
 | 
					  - FlipperKit/FlipperKitLayoutPlugin (0.87.0):
 | 
				
			||||||
  - FlipperKit/FlipperKitNetworkPlugin (0.41.5):
 | 
					 | 
				
			||||||
    - FlipperKit/Core
 | 
					    - FlipperKit/Core
 | 
				
			||||||
  - FlipperKit/FlipperKitReactPlugin (0.41.5):
 | 
					    - FlipperKit/FlipperKitHighlightOverlay
 | 
				
			||||||
 | 
					    - FlipperKit/FlipperKitLayoutHelpers
 | 
				
			||||||
 | 
					    - FlipperKit/FlipperKitLayoutIOSDescriptors
 | 
				
			||||||
 | 
					    - FlipperKit/FlipperKitLayoutTextSearchable
 | 
				
			||||||
 | 
					    - YogaKit (~> 1.18)
 | 
				
			||||||
 | 
					  - FlipperKit/FlipperKitLayoutTextSearchable (0.87.0)
 | 
				
			||||||
 | 
					  - FlipperKit/FlipperKitNetworkPlugin (0.87.0):
 | 
				
			||||||
    - FlipperKit/Core
 | 
					    - FlipperKit/Core
 | 
				
			||||||
  - FlipperKit/FlipperKitUserDefaultsPlugin (0.41.5):
 | 
					  - FlipperKit/FlipperKitReactPlugin (0.87.0):
 | 
				
			||||||
    - FlipperKit/Core
 | 
					    - FlipperKit/Core
 | 
				
			||||||
  - FlipperKit/SKIOSNetworkPlugin (0.41.5):
 | 
					  - FlipperKit/FlipperKitUserDefaultsPlugin (0.87.0):
 | 
				
			||||||
 | 
					    - FlipperKit/Core
 | 
				
			||||||
 | 
					  - FlipperKit/SKIOSNetworkPlugin (0.87.0):
 | 
				
			||||||
    - FlipperKit/Core
 | 
					    - FlipperKit/Core
 | 
				
			||||||
    - FlipperKit/FlipperKitNetworkPlugin
 | 
					    - FlipperKit/FlipperKitNetworkPlugin
 | 
				
			||||||
  - Folly (2020.01.13.00):
 | 
					  - Folly (2020.01.13.00):
 | 
				
			||||||
@ -69,254 +79,252 @@ PODS:
 | 
				
			|||||||
    - DoubleConversion
 | 
					    - DoubleConversion
 | 
				
			||||||
    - glog
 | 
					    - glog
 | 
				
			||||||
  - glog (0.3.5)
 | 
					  - glog (0.3.5)
 | 
				
			||||||
  - OpenSSL-Universal (1.0.2.19):
 | 
					  - libevent (2.1.12)
 | 
				
			||||||
    - OpenSSL-Universal/Static (= 1.0.2.19)
 | 
					  - OpenSSL-Universal (1.1.180)
 | 
				
			||||||
  - OpenSSL-Universal/Static (1.0.2.19)
 | 
					  - RCTRequired (0.63.4)
 | 
				
			||||||
  - RCTRequired (0.63.2)
 | 
					  - RCTTypeSafety (0.63.4):
 | 
				
			||||||
  - RCTTypeSafety (0.63.2):
 | 
					    - FBLazyVector (= 0.63.4)
 | 
				
			||||||
    - FBLazyVector (= 0.63.2)
 | 
					 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - RCTRequired (= 0.63.2)
 | 
					    - RCTRequired (= 0.63.4)
 | 
				
			||||||
    - React-Core (= 0.63.2)
 | 
					    - React-Core (= 0.63.4)
 | 
				
			||||||
  - React (0.63.2):
 | 
					  - React (0.63.4):
 | 
				
			||||||
    - React-Core (= 0.63.2)
 | 
					    - React-Core (= 0.63.4)
 | 
				
			||||||
    - React-Core/DevSupport (= 0.63.2)
 | 
					    - React-Core/DevSupport (= 0.63.4)
 | 
				
			||||||
    - React-Core/RCTWebSocket (= 0.63.2)
 | 
					    - React-Core/RCTWebSocket (= 0.63.4)
 | 
				
			||||||
    - React-RCTActionSheet (= 0.63.2)
 | 
					    - React-RCTActionSheet (= 0.63.4)
 | 
				
			||||||
    - React-RCTAnimation (= 0.63.2)
 | 
					    - React-RCTAnimation (= 0.63.4)
 | 
				
			||||||
    - React-RCTBlob (= 0.63.2)
 | 
					    - React-RCTBlob (= 0.63.4)
 | 
				
			||||||
    - React-RCTImage (= 0.63.2)
 | 
					    - React-RCTImage (= 0.63.4)
 | 
				
			||||||
    - React-RCTLinking (= 0.63.2)
 | 
					    - React-RCTLinking (= 0.63.4)
 | 
				
			||||||
    - React-RCTNetwork (= 0.63.2)
 | 
					    - React-RCTNetwork (= 0.63.4)
 | 
				
			||||||
    - React-RCTSettings (= 0.63.2)
 | 
					    - React-RCTSettings (= 0.63.4)
 | 
				
			||||||
    - React-RCTText (= 0.63.2)
 | 
					    - React-RCTText (= 0.63.4)
 | 
				
			||||||
    - React-RCTVibration (= 0.63.2)
 | 
					    - React-RCTVibration (= 0.63.4)
 | 
				
			||||||
  - React-callinvoker (0.63.2)
 | 
					  - React-callinvoker (0.63.4)
 | 
				
			||||||
  - React-Core (0.63.2):
 | 
					  - React-Core (0.63.4):
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - glog
 | 
					    - glog
 | 
				
			||||||
    - React-Core/Default (= 0.63.2)
 | 
					    - React-Core/Default (= 0.63.4)
 | 
				
			||||||
    - React-cxxreact (= 0.63.2)
 | 
					    - React-cxxreact (= 0.63.4)
 | 
				
			||||||
    - React-jsi (= 0.63.2)
 | 
					    - React-jsi (= 0.63.4)
 | 
				
			||||||
    - React-jsiexecutor (= 0.63.2)
 | 
					    - React-jsiexecutor (= 0.63.4)
 | 
				
			||||||
    - Yoga
 | 
					    - Yoga
 | 
				
			||||||
  - React-Core/CoreModulesHeaders (0.63.2):
 | 
					  - React-Core/CoreModulesHeaders (0.63.4):
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - glog
 | 
					    - glog
 | 
				
			||||||
    - React-Core/Default
 | 
					    - React-Core/Default
 | 
				
			||||||
    - React-cxxreact (= 0.63.2)
 | 
					    - React-cxxreact (= 0.63.4)
 | 
				
			||||||
    - React-jsi (= 0.63.2)
 | 
					    - React-jsi (= 0.63.4)
 | 
				
			||||||
    - React-jsiexecutor (= 0.63.2)
 | 
					    - React-jsiexecutor (= 0.63.4)
 | 
				
			||||||
    - Yoga
 | 
					    - Yoga
 | 
				
			||||||
  - React-Core/Default (0.63.2):
 | 
					  - React-Core/Default (0.63.4):
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - glog
 | 
					    - glog
 | 
				
			||||||
    - React-cxxreact (= 0.63.2)
 | 
					    - React-cxxreact (= 0.63.4)
 | 
				
			||||||
    - React-jsi (= 0.63.2)
 | 
					    - React-jsi (= 0.63.4)
 | 
				
			||||||
    - React-jsiexecutor (= 0.63.2)
 | 
					    - React-jsiexecutor (= 0.63.4)
 | 
				
			||||||
    - Yoga
 | 
					    - Yoga
 | 
				
			||||||
  - React-Core/DevSupport (0.63.2):
 | 
					  - React-Core/DevSupport (0.63.4):
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - glog
 | 
					    - glog
 | 
				
			||||||
    - React-Core/Default (= 0.63.2)
 | 
					    - React-Core/Default (= 0.63.4)
 | 
				
			||||||
    - React-Core/RCTWebSocket (= 0.63.2)
 | 
					    - React-Core/RCTWebSocket (= 0.63.4)
 | 
				
			||||||
    - React-cxxreact (= 0.63.2)
 | 
					    - React-cxxreact (= 0.63.4)
 | 
				
			||||||
    - React-jsi (= 0.63.2)
 | 
					    - React-jsi (= 0.63.4)
 | 
				
			||||||
    - React-jsiexecutor (= 0.63.2)
 | 
					    - React-jsiexecutor (= 0.63.4)
 | 
				
			||||||
    - React-jsinspector (= 0.63.2)
 | 
					    - React-jsinspector (= 0.63.4)
 | 
				
			||||||
    - Yoga
 | 
					    - Yoga
 | 
				
			||||||
  - React-Core/RCTActionSheetHeaders (0.63.2):
 | 
					  - React-Core/RCTActionSheetHeaders (0.63.4):
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - glog
 | 
					    - glog
 | 
				
			||||||
    - React-Core/Default
 | 
					    - React-Core/Default
 | 
				
			||||||
    - React-cxxreact (= 0.63.2)
 | 
					    - React-cxxreact (= 0.63.4)
 | 
				
			||||||
    - React-jsi (= 0.63.2)
 | 
					    - React-jsi (= 0.63.4)
 | 
				
			||||||
    - React-jsiexecutor (= 0.63.2)
 | 
					    - React-jsiexecutor (= 0.63.4)
 | 
				
			||||||
    - Yoga
 | 
					    - Yoga
 | 
				
			||||||
  - React-Core/RCTAnimationHeaders (0.63.2):
 | 
					  - React-Core/RCTAnimationHeaders (0.63.4):
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - glog
 | 
					    - glog
 | 
				
			||||||
    - React-Core/Default
 | 
					    - React-Core/Default
 | 
				
			||||||
    - React-cxxreact (= 0.63.2)
 | 
					    - React-cxxreact (= 0.63.4)
 | 
				
			||||||
    - React-jsi (= 0.63.2)
 | 
					    - React-jsi (= 0.63.4)
 | 
				
			||||||
    - React-jsiexecutor (= 0.63.2)
 | 
					    - React-jsiexecutor (= 0.63.4)
 | 
				
			||||||
    - Yoga
 | 
					    - Yoga
 | 
				
			||||||
  - React-Core/RCTBlobHeaders (0.63.2):
 | 
					  - React-Core/RCTBlobHeaders (0.63.4):
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - glog
 | 
					    - glog
 | 
				
			||||||
    - React-Core/Default
 | 
					    - React-Core/Default
 | 
				
			||||||
    - React-cxxreact (= 0.63.2)
 | 
					    - React-cxxreact (= 0.63.4)
 | 
				
			||||||
    - React-jsi (= 0.63.2)
 | 
					    - React-jsi (= 0.63.4)
 | 
				
			||||||
    - React-jsiexecutor (= 0.63.2)
 | 
					    - React-jsiexecutor (= 0.63.4)
 | 
				
			||||||
    - Yoga
 | 
					    - Yoga
 | 
				
			||||||
  - React-Core/RCTImageHeaders (0.63.2):
 | 
					  - React-Core/RCTImageHeaders (0.63.4):
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - glog
 | 
					    - glog
 | 
				
			||||||
    - React-Core/Default
 | 
					    - React-Core/Default
 | 
				
			||||||
    - React-cxxreact (= 0.63.2)
 | 
					    - React-cxxreact (= 0.63.4)
 | 
				
			||||||
    - React-jsi (= 0.63.2)
 | 
					    - React-jsi (= 0.63.4)
 | 
				
			||||||
    - React-jsiexecutor (= 0.63.2)
 | 
					    - React-jsiexecutor (= 0.63.4)
 | 
				
			||||||
    - Yoga
 | 
					    - Yoga
 | 
				
			||||||
  - React-Core/RCTLinkingHeaders (0.63.2):
 | 
					  - React-Core/RCTLinkingHeaders (0.63.4):
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - glog
 | 
					    - glog
 | 
				
			||||||
    - React-Core/Default
 | 
					    - React-Core/Default
 | 
				
			||||||
    - React-cxxreact (= 0.63.2)
 | 
					    - React-cxxreact (= 0.63.4)
 | 
				
			||||||
    - React-jsi (= 0.63.2)
 | 
					    - React-jsi (= 0.63.4)
 | 
				
			||||||
    - React-jsiexecutor (= 0.63.2)
 | 
					    - React-jsiexecutor (= 0.63.4)
 | 
				
			||||||
    - Yoga
 | 
					    - Yoga
 | 
				
			||||||
  - React-Core/RCTNetworkHeaders (0.63.2):
 | 
					  - React-Core/RCTNetworkHeaders (0.63.4):
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - glog
 | 
					    - glog
 | 
				
			||||||
    - React-Core/Default
 | 
					    - React-Core/Default
 | 
				
			||||||
    - React-cxxreact (= 0.63.2)
 | 
					    - React-cxxreact (= 0.63.4)
 | 
				
			||||||
    - React-jsi (= 0.63.2)
 | 
					    - React-jsi (= 0.63.4)
 | 
				
			||||||
    - React-jsiexecutor (= 0.63.2)
 | 
					    - React-jsiexecutor (= 0.63.4)
 | 
				
			||||||
    - Yoga
 | 
					    - Yoga
 | 
				
			||||||
  - React-Core/RCTSettingsHeaders (0.63.2):
 | 
					  - React-Core/RCTSettingsHeaders (0.63.4):
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - glog
 | 
					    - glog
 | 
				
			||||||
    - React-Core/Default
 | 
					    - React-Core/Default
 | 
				
			||||||
    - React-cxxreact (= 0.63.2)
 | 
					    - React-cxxreact (= 0.63.4)
 | 
				
			||||||
    - React-jsi (= 0.63.2)
 | 
					    - React-jsi (= 0.63.4)
 | 
				
			||||||
    - React-jsiexecutor (= 0.63.2)
 | 
					    - React-jsiexecutor (= 0.63.4)
 | 
				
			||||||
    - Yoga
 | 
					    - Yoga
 | 
				
			||||||
  - React-Core/RCTTextHeaders (0.63.2):
 | 
					  - React-Core/RCTTextHeaders (0.63.4):
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - glog
 | 
					    - glog
 | 
				
			||||||
    - React-Core/Default
 | 
					    - React-Core/Default
 | 
				
			||||||
    - React-cxxreact (= 0.63.2)
 | 
					    - React-cxxreact (= 0.63.4)
 | 
				
			||||||
    - React-jsi (= 0.63.2)
 | 
					    - React-jsi (= 0.63.4)
 | 
				
			||||||
    - React-jsiexecutor (= 0.63.2)
 | 
					    - React-jsiexecutor (= 0.63.4)
 | 
				
			||||||
    - Yoga
 | 
					    - Yoga
 | 
				
			||||||
  - React-Core/RCTVibrationHeaders (0.63.2):
 | 
					  - React-Core/RCTVibrationHeaders (0.63.4):
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - glog
 | 
					    - glog
 | 
				
			||||||
    - React-Core/Default
 | 
					    - React-Core/Default
 | 
				
			||||||
    - React-cxxreact (= 0.63.2)
 | 
					    - React-cxxreact (= 0.63.4)
 | 
				
			||||||
    - React-jsi (= 0.63.2)
 | 
					    - React-jsi (= 0.63.4)
 | 
				
			||||||
    - React-jsiexecutor (= 0.63.2)
 | 
					    - React-jsiexecutor (= 0.63.4)
 | 
				
			||||||
    - Yoga
 | 
					    - Yoga
 | 
				
			||||||
  - React-Core/RCTWebSocket (0.63.2):
 | 
					  - React-Core/RCTWebSocket (0.63.4):
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - glog
 | 
					    - glog
 | 
				
			||||||
    - React-Core/Default (= 0.63.2)
 | 
					    - React-Core/Default (= 0.63.4)
 | 
				
			||||||
    - React-cxxreact (= 0.63.2)
 | 
					    - React-cxxreact (= 0.63.4)
 | 
				
			||||||
    - React-jsi (= 0.63.2)
 | 
					    - React-jsi (= 0.63.4)
 | 
				
			||||||
    - React-jsiexecutor (= 0.63.2)
 | 
					    - React-jsiexecutor (= 0.63.4)
 | 
				
			||||||
    - Yoga
 | 
					    - Yoga
 | 
				
			||||||
  - React-CoreModules (0.63.2):
 | 
					  - React-CoreModules (0.63.4):
 | 
				
			||||||
    - FBReactNativeSpec (= 0.63.2)
 | 
					    - FBReactNativeSpec (= 0.63.4)
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - RCTTypeSafety (= 0.63.2)
 | 
					    - RCTTypeSafety (= 0.63.4)
 | 
				
			||||||
    - React-Core/CoreModulesHeaders (= 0.63.2)
 | 
					    - React-Core/CoreModulesHeaders (= 0.63.4)
 | 
				
			||||||
    - React-jsi (= 0.63.2)
 | 
					    - React-jsi (= 0.63.4)
 | 
				
			||||||
    - React-RCTImage (= 0.63.2)
 | 
					    - React-RCTImage (= 0.63.4)
 | 
				
			||||||
    - ReactCommon/turbomodule/core (= 0.63.2)
 | 
					    - ReactCommon/turbomodule/core (= 0.63.4)
 | 
				
			||||||
  - React-cxxreact (0.63.2):
 | 
					  - React-cxxreact (0.63.4):
 | 
				
			||||||
    - boost-for-react-native (= 1.63.0)
 | 
					    - boost-for-react-native (= 1.63.0)
 | 
				
			||||||
    - DoubleConversion
 | 
					    - DoubleConversion
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - glog
 | 
					    - glog
 | 
				
			||||||
    - React-callinvoker (= 0.63.2)
 | 
					    - React-callinvoker (= 0.63.4)
 | 
				
			||||||
    - React-jsinspector (= 0.63.2)
 | 
					    - React-jsinspector (= 0.63.4)
 | 
				
			||||||
  - React-jsi (0.63.2):
 | 
					  - React-jsi (0.63.4):
 | 
				
			||||||
    - boost-for-react-native (= 1.63.0)
 | 
					    - boost-for-react-native (= 1.63.0)
 | 
				
			||||||
    - DoubleConversion
 | 
					    - DoubleConversion
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - glog
 | 
					    - glog
 | 
				
			||||||
    - React-jsi/Default (= 0.63.2)
 | 
					    - React-jsi/Default (= 0.63.4)
 | 
				
			||||||
  - React-jsi/Default (0.63.2):
 | 
					  - React-jsi/Default (0.63.4):
 | 
				
			||||||
    - boost-for-react-native (= 1.63.0)
 | 
					    - boost-for-react-native (= 1.63.0)
 | 
				
			||||||
    - DoubleConversion
 | 
					    - DoubleConversion
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - glog
 | 
					    - glog
 | 
				
			||||||
  - React-jsiexecutor (0.63.2):
 | 
					  - React-jsiexecutor (0.63.4):
 | 
				
			||||||
    - DoubleConversion
 | 
					    - DoubleConversion
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - glog
 | 
					    - glog
 | 
				
			||||||
    - React-cxxreact (= 0.63.2)
 | 
					    - React-cxxreact (= 0.63.4)
 | 
				
			||||||
    - React-jsi (= 0.63.2)
 | 
					    - React-jsi (= 0.63.4)
 | 
				
			||||||
  - React-jsinspector (0.63.2)
 | 
					  - React-jsinspector (0.63.4)
 | 
				
			||||||
  - react-native-safe-area-context (3.1.4):
 | 
					  - react-native-safe-area-context (3.2.0):
 | 
				
			||||||
    - React
 | 
					    - React-Core
 | 
				
			||||||
  - react-native-splash-screen (3.2.0):
 | 
					  - react-native-splash-screen (3.2.0):
 | 
				
			||||||
    - React
 | 
					    - React
 | 
				
			||||||
  - react-native-webview (11.0.2):
 | 
					  - react-native-webview (11.6.4):
 | 
				
			||||||
    - React-Core
 | 
					    - React-Core
 | 
				
			||||||
  - React-RCTActionSheet (0.63.2):
 | 
					  - React-RCTActionSheet (0.63.4):
 | 
				
			||||||
    - React-Core/RCTActionSheetHeaders (= 0.63.2)
 | 
					    - React-Core/RCTActionSheetHeaders (= 0.63.4)
 | 
				
			||||||
  - React-RCTAnimation (0.63.2):
 | 
					  - React-RCTAnimation (0.63.4):
 | 
				
			||||||
    - FBReactNativeSpec (= 0.63.2)
 | 
					    - FBReactNativeSpec (= 0.63.4)
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - RCTTypeSafety (= 0.63.2)
 | 
					    - RCTTypeSafety (= 0.63.4)
 | 
				
			||||||
    - React-Core/RCTAnimationHeaders (= 0.63.2)
 | 
					    - React-Core/RCTAnimationHeaders (= 0.63.4)
 | 
				
			||||||
    - React-jsi (= 0.63.2)
 | 
					    - React-jsi (= 0.63.4)
 | 
				
			||||||
    - ReactCommon/turbomodule/core (= 0.63.2)
 | 
					    - ReactCommon/turbomodule/core (= 0.63.4)
 | 
				
			||||||
  - React-RCTBlob (0.63.2):
 | 
					  - React-RCTBlob (0.63.4):
 | 
				
			||||||
    - FBReactNativeSpec (= 0.63.2)
 | 
					    - FBReactNativeSpec (= 0.63.4)
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - React-Core/RCTBlobHeaders (= 0.63.2)
 | 
					    - React-Core/RCTBlobHeaders (= 0.63.4)
 | 
				
			||||||
    - React-Core/RCTWebSocket (= 0.63.2)
 | 
					    - React-Core/RCTWebSocket (= 0.63.4)
 | 
				
			||||||
    - React-jsi (= 0.63.2)
 | 
					    - React-jsi (= 0.63.4)
 | 
				
			||||||
    - React-RCTNetwork (= 0.63.2)
 | 
					    - React-RCTNetwork (= 0.63.4)
 | 
				
			||||||
    - ReactCommon/turbomodule/core (= 0.63.2)
 | 
					    - ReactCommon/turbomodule/core (= 0.63.4)
 | 
				
			||||||
  - React-RCTImage (0.63.2):
 | 
					  - React-RCTImage (0.63.4):
 | 
				
			||||||
    - FBReactNativeSpec (= 0.63.2)
 | 
					    - FBReactNativeSpec (= 0.63.4)
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - RCTTypeSafety (= 0.63.2)
 | 
					    - RCTTypeSafety (= 0.63.4)
 | 
				
			||||||
    - React-Core/RCTImageHeaders (= 0.63.2)
 | 
					    - React-Core/RCTImageHeaders (= 0.63.4)
 | 
				
			||||||
    - React-jsi (= 0.63.2)
 | 
					    - React-jsi (= 0.63.4)
 | 
				
			||||||
    - React-RCTNetwork (= 0.63.2)
 | 
					    - React-RCTNetwork (= 0.63.4)
 | 
				
			||||||
    - ReactCommon/turbomodule/core (= 0.63.2)
 | 
					    - ReactCommon/turbomodule/core (= 0.63.4)
 | 
				
			||||||
  - React-RCTLinking (0.63.2):
 | 
					  - React-RCTLinking (0.63.4):
 | 
				
			||||||
    - FBReactNativeSpec (= 0.63.2)
 | 
					    - FBReactNativeSpec (= 0.63.4)
 | 
				
			||||||
    - React-Core/RCTLinkingHeaders (= 0.63.2)
 | 
					    - React-Core/RCTLinkingHeaders (= 0.63.4)
 | 
				
			||||||
    - React-jsi (= 0.63.2)
 | 
					    - React-jsi (= 0.63.4)
 | 
				
			||||||
    - ReactCommon/turbomodule/core (= 0.63.2)
 | 
					    - ReactCommon/turbomodule/core (= 0.63.4)
 | 
				
			||||||
  - React-RCTNetwork (0.63.2):
 | 
					  - React-RCTNetwork (0.63.4):
 | 
				
			||||||
    - FBReactNativeSpec (= 0.63.2)
 | 
					    - FBReactNativeSpec (= 0.63.4)
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - RCTTypeSafety (= 0.63.2)
 | 
					    - RCTTypeSafety (= 0.63.4)
 | 
				
			||||||
    - React-Core/RCTNetworkHeaders (= 0.63.2)
 | 
					    - React-Core/RCTNetworkHeaders (= 0.63.4)
 | 
				
			||||||
    - React-jsi (= 0.63.2)
 | 
					    - React-jsi (= 0.63.4)
 | 
				
			||||||
    - ReactCommon/turbomodule/core (= 0.63.2)
 | 
					    - ReactCommon/turbomodule/core (= 0.63.4)
 | 
				
			||||||
  - React-RCTSettings (0.63.2):
 | 
					  - React-RCTSettings (0.63.4):
 | 
				
			||||||
    - FBReactNativeSpec (= 0.63.2)
 | 
					    - FBReactNativeSpec (= 0.63.4)
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - RCTTypeSafety (= 0.63.2)
 | 
					    - RCTTypeSafety (= 0.63.4)
 | 
				
			||||||
    - React-Core/RCTSettingsHeaders (= 0.63.2)
 | 
					    - React-Core/RCTSettingsHeaders (= 0.63.4)
 | 
				
			||||||
    - React-jsi (= 0.63.2)
 | 
					    - React-jsi (= 0.63.4)
 | 
				
			||||||
    - ReactCommon/turbomodule/core (= 0.63.2)
 | 
					    - ReactCommon/turbomodule/core (= 0.63.4)
 | 
				
			||||||
  - React-RCTText (0.63.2):
 | 
					  - React-RCTText (0.63.4):
 | 
				
			||||||
    - React-Core/RCTTextHeaders (= 0.63.2)
 | 
					    - React-Core/RCTTextHeaders (= 0.63.4)
 | 
				
			||||||
  - React-RCTVibration (0.63.2):
 | 
					  - React-RCTVibration (0.63.4):
 | 
				
			||||||
    - FBReactNativeSpec (= 0.63.2)
 | 
					    - FBReactNativeSpec (= 0.63.4)
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - React-Core/RCTVibrationHeaders (= 0.63.2)
 | 
					    - React-Core/RCTVibrationHeaders (= 0.63.4)
 | 
				
			||||||
    - React-jsi (= 0.63.2)
 | 
					    - React-jsi (= 0.63.4)
 | 
				
			||||||
    - ReactCommon/turbomodule/core (= 0.63.2)
 | 
					    - ReactCommon/turbomodule/core (= 0.63.4)
 | 
				
			||||||
  - ReactCommon/turbomodule/core (0.63.2):
 | 
					  - ReactCommon/turbomodule/core (0.63.4):
 | 
				
			||||||
    - DoubleConversion
 | 
					    - DoubleConversion
 | 
				
			||||||
    - Folly (= 2020.01.13.00)
 | 
					    - Folly (= 2020.01.13.00)
 | 
				
			||||||
    - glog
 | 
					    - glog
 | 
				
			||||||
    - React-callinvoker (= 0.63.2)
 | 
					    - React-callinvoker (= 0.63.4)
 | 
				
			||||||
    - React-Core (= 0.63.2)
 | 
					    - React-Core (= 0.63.4)
 | 
				
			||||||
    - React-cxxreact (= 0.63.2)
 | 
					    - React-cxxreact (= 0.63.4)
 | 
				
			||||||
    - React-jsi (= 0.63.2)
 | 
					    - React-jsi (= 0.63.4)
 | 
				
			||||||
  - RNCAsyncStorage (1.13.0):
 | 
					  - RNCAsyncStorage (1.15.5):
 | 
				
			||||||
 | 
					    - React-Core
 | 
				
			||||||
 | 
					  - RNCMaskedView (0.1.11):
 | 
				
			||||||
    - React
 | 
					    - React
 | 
				
			||||||
  - RNCMaskedView (0.1.10):
 | 
					  - RNGestureHandler (1.10.3):
 | 
				
			||||||
    - React
 | 
					    - React-Core
 | 
				
			||||||
  - RNGestureHandler (1.7.0):
 | 
					  - RNLocalize (2.1.1):
 | 
				
			||||||
    - React
 | 
					    - React-Core
 | 
				
			||||||
  - RNI18n (2.0.15):
 | 
					  - RNScreens (3.4.0):
 | 
				
			||||||
    - React
 | 
					    - React-Core
 | 
				
			||||||
  - RNReanimated (1.10.2):
 | 
					    - React-RCTImage
 | 
				
			||||||
    - React
 | 
					  - RNVectorIcons (7.1.0):
 | 
				
			||||||
  - RNScreens (2.10.1):
 | 
					 | 
				
			||||||
    - React
 | 
					 | 
				
			||||||
  - RNVectorIcons (7.0.0):
 | 
					 | 
				
			||||||
    - React
 | 
					    - React
 | 
				
			||||||
  - Yoga (1.14.0)
 | 
					  - Yoga (1.14.0)
 | 
				
			||||||
  - YogaKit (1.18.1):
 | 
					  - YogaKit (1.18.1):
 | 
				
			||||||
@ -327,25 +335,25 @@ DEPENDENCIES:
 | 
				
			|||||||
  - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
 | 
					  - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
 | 
				
			||||||
  - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
 | 
					  - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
 | 
				
			||||||
  - FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`)
 | 
					  - FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`)
 | 
				
			||||||
  - Flipper (~> 0.41.1)
 | 
					  - Flipper (= 0.87.0)
 | 
				
			||||||
  - Flipper-DoubleConversion (= 1.1.7)
 | 
					  - Flipper-DoubleConversion (= 1.1.7)
 | 
				
			||||||
  - Flipper-Folly (~> 2.2)
 | 
					  - Flipper-Folly (= 2.5.3)
 | 
				
			||||||
  - Flipper-Glog (= 0.3.6)
 | 
					  - Flipper-Glog (= 0.3.6)
 | 
				
			||||||
  - Flipper-PeerTalk (~> 0.0.4)
 | 
					  - Flipper-PeerTalk (~> 0.0.4)
 | 
				
			||||||
  - Flipper-RSocket (~> 1.1)
 | 
					  - Flipper-RSocket (= 1.3.1)
 | 
				
			||||||
  - FlipperKit (~> 0.41.1)
 | 
					  - FlipperKit (= 0.87.0)
 | 
				
			||||||
  - FlipperKit/Core (~> 0.41.1)
 | 
					  - FlipperKit/Core (= 0.87.0)
 | 
				
			||||||
  - FlipperKit/CppBridge (~> 0.41.1)
 | 
					  - FlipperKit/CppBridge (= 0.87.0)
 | 
				
			||||||
  - FlipperKit/FBCxxFollyDynamicConvert (~> 0.41.1)
 | 
					  - FlipperKit/FBCxxFollyDynamicConvert (= 0.87.0)
 | 
				
			||||||
  - FlipperKit/FBDefines (~> 0.41.1)
 | 
					  - FlipperKit/FBDefines (= 0.87.0)
 | 
				
			||||||
  - FlipperKit/FKPortForwarding (~> 0.41.1)
 | 
					  - FlipperKit/FKPortForwarding (= 0.87.0)
 | 
				
			||||||
  - FlipperKit/FlipperKitHighlightOverlay (~> 0.41.1)
 | 
					  - FlipperKit/FlipperKitHighlightOverlay (= 0.87.0)
 | 
				
			||||||
  - FlipperKit/FlipperKitLayoutPlugin (~> 0.41.1)
 | 
					  - FlipperKit/FlipperKitLayoutPlugin (= 0.87.0)
 | 
				
			||||||
  - FlipperKit/FlipperKitLayoutTextSearchable (~> 0.41.1)
 | 
					  - FlipperKit/FlipperKitLayoutTextSearchable (= 0.87.0)
 | 
				
			||||||
  - FlipperKit/FlipperKitNetworkPlugin (~> 0.41.1)
 | 
					  - FlipperKit/FlipperKitNetworkPlugin (= 0.87.0)
 | 
				
			||||||
  - FlipperKit/FlipperKitReactPlugin (~> 0.41.1)
 | 
					  - FlipperKit/FlipperKitReactPlugin (= 0.87.0)
 | 
				
			||||||
  - FlipperKit/FlipperKitUserDefaultsPlugin (~> 0.41.1)
 | 
					  - FlipperKit/FlipperKitUserDefaultsPlugin (= 0.87.0)
 | 
				
			||||||
  - FlipperKit/SKIOSNetworkPlugin (~> 0.41.1)
 | 
					  - FlipperKit/SKIOSNetworkPlugin (= 0.87.0)
 | 
				
			||||||
  - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
 | 
					  - Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
 | 
				
			||||||
  - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
 | 
					  - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
 | 
				
			||||||
  - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
 | 
					  - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
 | 
				
			||||||
@ -373,11 +381,10 @@ DEPENDENCIES:
 | 
				
			|||||||
  - React-RCTText (from `../node_modules/react-native/Libraries/Text`)
 | 
					  - React-RCTText (from `../node_modules/react-native/Libraries/Text`)
 | 
				
			||||||
  - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
 | 
					  - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
 | 
				
			||||||
  - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
 | 
					  - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
 | 
				
			||||||
  - "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)"
 | 
					  - "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)"
 | 
				
			||||||
  - "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)"
 | 
					  - "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)"
 | 
				
			||||||
  - RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
 | 
					  - RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
 | 
				
			||||||
  - RNI18n (from `../node_modules/react-native-i18n`)
 | 
					  - RNLocalize (from `../node_modules/react-native-localize`)
 | 
				
			||||||
  - RNReanimated (from `../node_modules/react-native-reanimated`)
 | 
					 | 
				
			||||||
  - RNScreens (from `../node_modules/react-native-screens`)
 | 
					  - RNScreens (from `../node_modules/react-native-screens`)
 | 
				
			||||||
  - RNVectorIcons (from `../node_modules/react-native-vector-icons`)
 | 
					  - RNVectorIcons (from `../node_modules/react-native-vector-icons`)
 | 
				
			||||||
  - Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
 | 
					  - Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
 | 
				
			||||||
@ -386,7 +393,6 @@ SPEC REPOS:
 | 
				
			|||||||
  trunk:
 | 
					  trunk:
 | 
				
			||||||
    - boost-for-react-native
 | 
					    - boost-for-react-native
 | 
				
			||||||
    - CocoaAsyncSocket
 | 
					    - CocoaAsyncSocket
 | 
				
			||||||
    - CocoaLibEvent
 | 
					 | 
				
			||||||
    - Flipper
 | 
					    - Flipper
 | 
				
			||||||
    - Flipper-DoubleConversion
 | 
					    - Flipper-DoubleConversion
 | 
				
			||||||
    - Flipper-Folly
 | 
					    - Flipper-Folly
 | 
				
			||||||
@ -394,6 +400,7 @@ SPEC REPOS:
 | 
				
			|||||||
    - Flipper-PeerTalk
 | 
					    - Flipper-PeerTalk
 | 
				
			||||||
    - Flipper-RSocket
 | 
					    - Flipper-RSocket
 | 
				
			||||||
    - FlipperKit
 | 
					    - FlipperKit
 | 
				
			||||||
 | 
					    - libevent
 | 
				
			||||||
    - OpenSSL-Universal
 | 
					    - OpenSSL-Universal
 | 
				
			||||||
    - YogaKit
 | 
					    - YogaKit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -457,15 +464,13 @@ EXTERNAL SOURCES:
 | 
				
			|||||||
  ReactCommon:
 | 
					  ReactCommon:
 | 
				
			||||||
    :path: "../node_modules/react-native/ReactCommon"
 | 
					    :path: "../node_modules/react-native/ReactCommon"
 | 
				
			||||||
  RNCAsyncStorage:
 | 
					  RNCAsyncStorage:
 | 
				
			||||||
    :path: "../node_modules/@react-native-community/async-storage"
 | 
					    :path: "../node_modules/@react-native-async-storage/async-storage"
 | 
				
			||||||
  RNCMaskedView:
 | 
					  RNCMaskedView:
 | 
				
			||||||
    :path: "../node_modules/@react-native-community/masked-view"
 | 
					    :path: "../node_modules/@react-native-community/masked-view"
 | 
				
			||||||
  RNGestureHandler:
 | 
					  RNGestureHandler:
 | 
				
			||||||
    :path: "../node_modules/react-native-gesture-handler"
 | 
					    :path: "../node_modules/react-native-gesture-handler"
 | 
				
			||||||
  RNI18n:
 | 
					  RNLocalize:
 | 
				
			||||||
    :path: "../node_modules/react-native-i18n"
 | 
					    :path: "../node_modules/react-native-localize"
 | 
				
			||||||
  RNReanimated:
 | 
					 | 
				
			||||||
    :path: "../node_modules/react-native-reanimated"
 | 
					 | 
				
			||||||
  RNScreens:
 | 
					  RNScreens:
 | 
				
			||||||
    :path: "../node_modules/react-native-screens"
 | 
					    :path: "../node_modules/react-native-screens"
 | 
				
			||||||
  RNVectorIcons:
 | 
					  RNVectorIcons:
 | 
				
			||||||
@ -477,53 +482,52 @@ SPEC CHECKSUMS:
 | 
				
			|||||||
  boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
 | 
					  boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
 | 
				
			||||||
  BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872
 | 
					  BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872
 | 
				
			||||||
  CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
 | 
					  CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
 | 
				
			||||||
  CocoaLibEvent: 2fab71b8bd46dd33ddb959f7928ec5909f838e3f
 | 
					 | 
				
			||||||
  DoubleConversion: cde416483dac037923206447da6e1454df403714
 | 
					  DoubleConversion: cde416483dac037923206447da6e1454df403714
 | 
				
			||||||
  FBLazyVector: 3ef4a7f62e7db01092f9d517d2ebc0d0677c4a37
 | 
					  FBLazyVector: 3bb422f41b18121b71783a905c10e58606f7dc3e
 | 
				
			||||||
  FBReactNativeSpec: dc7fa9088f0f2a998503a352b0554d69a4391c5a
 | 
					  FBReactNativeSpec: f2c97f2529dd79c083355182cc158c9f98f4bd6e
 | 
				
			||||||
  Flipper: 33585e2d9810fe5528346be33bcf71b37bb7ae13
 | 
					  Flipper: 1bd2db48dcc31e4b167b9a33ec1df01c2ded4893
 | 
				
			||||||
  Flipper-DoubleConversion: 38631e41ef4f9b12861c67d17cb5518d06badc41
 | 
					  Flipper-DoubleConversion: 38631e41ef4f9b12861c67d17cb5518d06badc41
 | 
				
			||||||
  Flipper-Folly: c12092ea368353b58e992843a990a3225d4533c3
 | 
					  Flipper-Folly: 755929a4f851b2fb2c347d533a23f191b008554c
 | 
				
			||||||
  Flipper-Glog: 1dfd6abf1e922806c52ceb8701a3599a79a200a6
 | 
					  Flipper-Glog: 1dfd6abf1e922806c52ceb8701a3599a79a200a6
 | 
				
			||||||
  Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9
 | 
					  Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9
 | 
				
			||||||
  Flipper-RSocket: 64e7431a55835eb953b0bf984ef3b90ae9fdddd7
 | 
					  Flipper-RSocket: 127954abe8b162fcaf68d2134d34dc2bd7076154
 | 
				
			||||||
  FlipperKit: bc68102cd4952a258a23c9c1b316c7bec1fecf83
 | 
					  FlipperKit: 651f50a42eb95c01b3e89a60996dd6aded529eeb
 | 
				
			||||||
  Folly: b73c3869541e86821df3c387eb0af5f65addfab4
 | 
					  Folly: b73c3869541e86821df3c387eb0af5f65addfab4
 | 
				
			||||||
  glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3
 | 
					  glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3
 | 
				
			||||||
  OpenSSL-Universal: 8b48cc0d10c1b2923617dfe5c178aa9ed2689355
 | 
					  libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
 | 
				
			||||||
  RCTRequired: f13f25e7b12f925f1f6a6a8c69d929a03c0129fe
 | 
					  OpenSSL-Universal: 1aa4f6a6ee7256b83db99ec1ccdaa80d10f9af9b
 | 
				
			||||||
  RCTTypeSafety: 44982c5c8e43ff4141eb519a8ddc88059acd1f3a
 | 
					  RCTRequired: 082f10cd3f905d6c124597fd1c14f6f2655ff65e
 | 
				
			||||||
  React: e1c65dd41cb9db13b99f24608e47dd595f28ca9a
 | 
					  RCTTypeSafety: 8c9c544ecbf20337d069e4ae7fd9a377aadf504b
 | 
				
			||||||
  React-callinvoker: 552a6a6bc8b3bb794cf108ad59e5a9e2e3b4fc98
 | 
					  React: b0a957a2c44da4113b0c4c9853d8387f8e64e615
 | 
				
			||||||
  React-Core: 9d341e725dc9cd2f49e4c49ad1fc4e8776aa2639
 | 
					  React-callinvoker: c3f44dd3cb195b6aa46621fff95ded79d59043fe
 | 
				
			||||||
  React-CoreModules: 5335e168165da7f7083ce7147768d36d3e292318
 | 
					  React-Core: d3b2a1ac9a2c13c3bcde712d9281fc1c8a5b315b
 | 
				
			||||||
  React-cxxreact: d3261ec5f7d11743fbf21e263a34ea51d1f13ebc
 | 
					  React-CoreModules: 0581ff36cb797da0943d424f69e7098e43e9be60
 | 
				
			||||||
  React-jsi: 54245e1d5f4b690dec614a73a3795964eeef13a8
 | 
					  React-cxxreact: c1480d4fda5720086c90df537ee7d285d4c57ac3
 | 
				
			||||||
  React-jsiexecutor: 8ca588cc921e70590820ce72b8789b02c67cce38
 | 
					  React-jsi: a0418934cf48f25b485631deb27c64dc40fb4c31
 | 
				
			||||||
  React-jsinspector: b14e62ebe7a66e9231e9581279909f2fc3db6606
 | 
					  React-jsiexecutor: 93bd528844ad21dc07aab1c67cb10abae6df6949
 | 
				
			||||||
  react-native-safe-area-context: 0ed9288ed4409beabb0817b54efc047286fc84da
 | 
					  React-jsinspector: 58aef7155bc9a9683f5b60b35eccea8722a4f53a
 | 
				
			||||||
 | 
					  react-native-safe-area-context: f0906bf8bc9835ac9a9d3f97e8bde2a997d8da79
 | 
				
			||||||
  react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865
 | 
					  react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865
 | 
				
			||||||
  react-native-webview: b2542d6fd424bcc3e3b2ec5f854f0abb4ec86c87
 | 
					  react-native-webview: 1a19adb5578cdf7f005b7961dcc50c1c6b70f41b
 | 
				
			||||||
  React-RCTActionSheet: 910163b6b09685a35c4ebbc52b66d1bfbbe39fc5
 | 
					  React-RCTActionSheet: 89a0ca9f4a06c1f93c26067af074ccdce0f40336
 | 
				
			||||||
  React-RCTAnimation: 9a883bbe1e9d2e158d4fb53765ed64c8dc2200c6
 | 
					  React-RCTAnimation: 1bde3ecc0c104c55df246eda516e0deb03c4e49b
 | 
				
			||||||
  React-RCTBlob: 39cf0ece1927996c4466510e25d2105f67010e13
 | 
					  React-RCTBlob: a97d378b527740cc667e03ebfa183a75231ab0f0
 | 
				
			||||||
  React-RCTImage: de355d738727b09ad3692f2a979affbd54b5f378
 | 
					  React-RCTImage: c1b1f2d3f43a4a528c8946d6092384b5c880d2f0
 | 
				
			||||||
  React-RCTLinking: 8122f221d395a63364b2c0078ce284214bd04575
 | 
					  React-RCTLinking: 35ae4ab9dc0410d1fcbdce4d7623194a27214fb2
 | 
				
			||||||
  React-RCTNetwork: 8f96c7b49ea6a0f28f98258f347b6ad218bc0830
 | 
					  React-RCTNetwork: 29ec2696f8d8cfff7331fac83d3e893c95ef43ae
 | 
				
			||||||
  React-RCTSettings: 8a49622aff9c1925f5455fa340b6fe4853d64ab6
 | 
					  React-RCTSettings: 60f0691bba2074ef394f95d4c2265ec284e0a46a
 | 
				
			||||||
  React-RCTText: 1b6773e776e4b33f90468c20fe3b16ca3e224bb8
 | 
					  React-RCTText: 5c51df3f08cb9dedc6e790161195d12bac06101c
 | 
				
			||||||
  React-RCTVibration: 4d2e726957f4087449739b595f107c0d4b6c2d2d
 | 
					  React-RCTVibration: ae4f914cfe8de7d4de95ae1ea6cc8f6315d73d9d
 | 
				
			||||||
  ReactCommon: a0a1edbebcac5e91338371b72ffc66aa822792ce
 | 
					  ReactCommon: 73d79c7039f473b76db6ff7c6b159c478acbbb3b
 | 
				
			||||||
  RNCAsyncStorage: b34c5db7bd4b2ef9a7ced5b59b1e6a0c5c6eb24e
 | 
					  RNCAsyncStorage: 56a3355a10b5d660c48c6e37325ac85ebfd09885
 | 
				
			||||||
  RNCMaskedView: f5c7d14d6847b7b44853f7acb6284c1da30a3459
 | 
					  RNCMaskedView: 0e1bc4bfa8365eba5fbbb71e07fbdc0555249489
 | 
				
			||||||
  RNGestureHandler: b6b359bb800ae399a9c8b27032bdbf7c18f08a08
 | 
					  RNGestureHandler: a479ebd5ed4221a810967000735517df0d2db211
 | 
				
			||||||
  RNI18n: e2f7e76389fcc6e84f2c8733ea89b92502351fd8
 | 
					  RNLocalize: 82a569022724d35461e2dc5b5d015a13c3ca995b
 | 
				
			||||||
  RNReanimated: 7de2dca51deacff78bb880f63c1389a24311b376
 | 
					  RNScreens: 21b73c94c9117e1110a79ee0ee80c93ccefed8ce
 | 
				
			||||||
  RNScreens: b748efec66e095134c7166ca333b628cd7e6f3e2
 | 
					  RNVectorIcons: bc69e6a278b14842063605de32bec61f0b251a59
 | 
				
			||||||
  RNVectorIcons: da6fe858f5a65d7bbc3379540a889b0b12aa5976
 | 
					  Yoga: 4bd86afe9883422a7c4028c00e34790f560923d6
 | 
				
			||||||
  Yoga: 7740b94929bbacbddda59bf115b5317e9a161598
 | 
					 | 
				
			||||||
  YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
 | 
					  YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PODFILE CHECKSUM: 06472af1eb4acd0770fd4d29e23ee525801f7cd1
 | 
					PODFILE CHECKSUM: 685f7c9567d158eb76c7fbd85c7248da2f22d7c8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
COCOAPODS: 1.9.3
 | 
					COCOAPODS: 1.10.1
 | 
				
			||||||
 | 
				
			|||||||
@ -249,6 +249,7 @@
 | 
				
			|||||||
				00E356EB1AD99517003FC87E /* Frameworks */,
 | 
									00E356EB1AD99517003FC87E /* Frameworks */,
 | 
				
			||||||
				00E356EC1AD99517003FC87E /* Resources */,
 | 
									00E356EC1AD99517003FC87E /* Resources */,
 | 
				
			||||||
				7BC6AD0A9D3DE575F2E558E1 /* [CP] Copy Pods Resources */,
 | 
									7BC6AD0A9D3DE575F2E558E1 /* [CP] Copy Pods Resources */,
 | 
				
			||||||
 | 
									8EEC6804BF6C2BF286A5F7D9 /* [CP] Embed Pods Frameworks */,
 | 
				
			||||||
			);
 | 
								);
 | 
				
			||||||
			buildRules = (
 | 
								buildRules = (
 | 
				
			||||||
			);
 | 
								);
 | 
				
			||||||
@ -271,6 +272,7 @@
 | 
				
			|||||||
				13B07F8E1A680F5B00A75B9A /* Resources */,
 | 
									13B07F8E1A680F5B00A75B9A /* Resources */,
 | 
				
			||||||
				00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
 | 
									00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
 | 
				
			||||||
				D2DD3F2F99A693C12757405F /* [CP] Copy Pods Resources */,
 | 
									D2DD3F2F99A693C12757405F /* [CP] Copy Pods Resources */,
 | 
				
			||||||
 | 
									2E1AEAA3F8B118A5A91DE143 /* [CP] Embed Pods Frameworks */,
 | 
				
			||||||
			);
 | 
								);
 | 
				
			||||||
			buildRules = (
 | 
								buildRules = (
 | 
				
			||||||
			);
 | 
								);
 | 
				
			||||||
@ -326,7 +328,7 @@
 | 
				
			|||||||
		83CBB9F71A601CBA00E9B192 /* Project object */ = {
 | 
							83CBB9F71A601CBA00E9B192 /* Project object */ = {
 | 
				
			||||||
			isa = PBXProject;
 | 
								isa = PBXProject;
 | 
				
			||||||
			attributes = {
 | 
								attributes = {
 | 
				
			||||||
				LastUpgradeCheck = 1130;
 | 
									LastUpgradeCheck = 1240;
 | 
				
			||||||
				TargetAttributes = {
 | 
									TargetAttributes = {
 | 
				
			||||||
					00E356ED1AD99517003FC87E = {
 | 
										00E356ED1AD99517003FC87E = {
 | 
				
			||||||
						CreatedOnToolsVersion = 6.2;
 | 
											CreatedOnToolsVersion = 6.2;
 | 
				
			||||||
@ -474,6 +476,24 @@
 | 
				
			|||||||
			shellPath = /bin/sh;
 | 
								shellPath = /bin/sh;
 | 
				
			||||||
			shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh";
 | 
								shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh";
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
							2E1AEAA3F8B118A5A91DE143 /* [CP] Embed Pods Frameworks */ = {
 | 
				
			||||||
 | 
								isa = PBXShellScriptBuildPhase;
 | 
				
			||||||
 | 
								buildActionMask = 2147483647;
 | 
				
			||||||
 | 
								files = (
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
								inputPaths = (
 | 
				
			||||||
 | 
									"${PODS_ROOT}/Target Support Files/Pods-blazerapp/Pods-blazerapp-frameworks.sh",
 | 
				
			||||||
 | 
									"${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL/OpenSSL.framework/OpenSSL",
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
								name = "[CP] Embed Pods Frameworks";
 | 
				
			||||||
 | 
								outputPaths = (
 | 
				
			||||||
 | 
									"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework",
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
								runOnlyForDeploymentPostprocessing = 0;
 | 
				
			||||||
 | 
								shellPath = /bin/sh;
 | 
				
			||||||
 | 
								shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-blazerapp/Pods-blazerapp-frameworks.sh\"\n";
 | 
				
			||||||
 | 
								showEnvVarsInLog = 0;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
		7BC6AD0A9D3DE575F2E558E1 /* [CP] Copy Pods Resources */ = {
 | 
							7BC6AD0A9D3DE575F2E558E1 /* [CP] Copy Pods Resources */ = {
 | 
				
			||||||
			isa = PBXShellScriptBuildPhase;
 | 
								isa = PBXShellScriptBuildPhase;
 | 
				
			||||||
			buildActionMask = 2147483647;
 | 
								buildActionMask = 2147483647;
 | 
				
			||||||
@ -524,6 +544,24 @@
 | 
				
			|||||||
			shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-blazerapp-blazerappTests/Pods-blazerapp-blazerappTests-resources.sh\"\n";
 | 
								shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-blazerapp-blazerappTests/Pods-blazerapp-blazerappTests-resources.sh\"\n";
 | 
				
			||||||
			showEnvVarsInLog = 0;
 | 
								showEnvVarsInLog = 0;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
							8EEC6804BF6C2BF286A5F7D9 /* [CP] Embed Pods Frameworks */ = {
 | 
				
			||||||
 | 
								isa = PBXShellScriptBuildPhase;
 | 
				
			||||||
 | 
								buildActionMask = 2147483647;
 | 
				
			||||||
 | 
								files = (
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
								inputPaths = (
 | 
				
			||||||
 | 
									"${PODS_ROOT}/Target Support Files/Pods-blazerapp-blazerappTests/Pods-blazerapp-blazerappTests-frameworks.sh",
 | 
				
			||||||
 | 
									"${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL/OpenSSL.framework/OpenSSL",
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
								name = "[CP] Embed Pods Frameworks";
 | 
				
			||||||
 | 
								outputPaths = (
 | 
				
			||||||
 | 
									"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework",
 | 
				
			||||||
 | 
								);
 | 
				
			||||||
 | 
								runOnlyForDeploymentPostprocessing = 0;
 | 
				
			||||||
 | 
								shellPath = /bin/sh;
 | 
				
			||||||
 | 
								shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-blazerapp-blazerappTests/Pods-blazerapp-blazerappTests-frameworks.sh\"\n";
 | 
				
			||||||
 | 
								showEnvVarsInLog = 0;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
		93A4E96E8852D8799C8883AB /* [CP] Check Pods Manifest.lock */ = {
 | 
							93A4E96E8852D8799C8883AB /* [CP] Check Pods Manifest.lock */ = {
 | 
				
			||||||
			isa = PBXShellScriptBuildPhase;
 | 
								isa = PBXShellScriptBuildPhase;
 | 
				
			||||||
			buildActionMask = 2147483647;
 | 
								buildActionMask = 2147483647;
 | 
				
			||||||
@ -719,7 +757,7 @@
 | 
				
			|||||||
					"$(inherited)",
 | 
										"$(inherited)",
 | 
				
			||||||
				);
 | 
									);
 | 
				
			||||||
				INFOPLIST_FILE = blazerappTests/Info.plist;
 | 
									INFOPLIST_FILE = blazerappTests/Info.plist;
 | 
				
			||||||
				IPHONEOS_DEPLOYMENT_TARGET = 10.0;
 | 
									IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 | 
				
			||||||
				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 | 
									LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 | 
				
			||||||
				OTHER_LDFLAGS = (
 | 
									OTHER_LDFLAGS = (
 | 
				
			||||||
					"-ObjC",
 | 
										"-ObjC",
 | 
				
			||||||
@ -739,7 +777,7 @@
 | 
				
			|||||||
				BUNDLE_LOADER = "$(TEST_HOST)";
 | 
									BUNDLE_LOADER = "$(TEST_HOST)";
 | 
				
			||||||
				COPY_PHASE_STRIP = NO;
 | 
									COPY_PHASE_STRIP = NO;
 | 
				
			||||||
				INFOPLIST_FILE = blazerappTests/Info.plist;
 | 
									INFOPLIST_FILE = blazerappTests/Info.plist;
 | 
				
			||||||
				IPHONEOS_DEPLOYMENT_TARGET = 10.0;
 | 
									IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 | 
				
			||||||
				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 | 
									LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 | 
				
			||||||
				OTHER_LDFLAGS = (
 | 
									OTHER_LDFLAGS = (
 | 
				
			||||||
					"-ObjC",
 | 
										"-ObjC",
 | 
				
			||||||
@ -761,7 +799,7 @@
 | 
				
			|||||||
				CURRENT_PROJECT_VERSION = 1;
 | 
									CURRENT_PROJECT_VERSION = 1;
 | 
				
			||||||
				ENABLE_BITCODE = NO;
 | 
									ENABLE_BITCODE = NO;
 | 
				
			||||||
				INFOPLIST_FILE = blazerapp/Info.plist;
 | 
									INFOPLIST_FILE = blazerapp/Info.plist;
 | 
				
			||||||
				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
 | 
									IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 | 
				
			||||||
				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
 | 
									LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
 | 
				
			||||||
				OTHER_LDFLAGS = (
 | 
									OTHER_LDFLAGS = (
 | 
				
			||||||
					"$(inherited)",
 | 
										"$(inherited)",
 | 
				
			||||||
@ -784,7 +822,7 @@
 | 
				
			|||||||
				CLANG_ENABLE_MODULES = YES;
 | 
									CLANG_ENABLE_MODULES = YES;
 | 
				
			||||||
				CURRENT_PROJECT_VERSION = 1;
 | 
									CURRENT_PROJECT_VERSION = 1;
 | 
				
			||||||
				INFOPLIST_FILE = blazerapp/Info.plist;
 | 
									INFOPLIST_FILE = blazerapp/Info.plist;
 | 
				
			||||||
				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
 | 
									IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 | 
				
			||||||
				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
 | 
									LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
 | 
				
			||||||
				OTHER_LDFLAGS = (
 | 
									OTHER_LDFLAGS = (
 | 
				
			||||||
					"$(inherited)",
 | 
										"$(inherited)",
 | 
				
			||||||
@ -822,7 +860,7 @@
 | 
				
			|||||||
				PRODUCT_NAME = "$(TARGET_NAME)";
 | 
									PRODUCT_NAME = "$(TARGET_NAME)";
 | 
				
			||||||
				SDKROOT = appletvos;
 | 
									SDKROOT = appletvos;
 | 
				
			||||||
				TARGETED_DEVICE_FAMILY = 3;
 | 
									TARGETED_DEVICE_FAMILY = 3;
 | 
				
			||||||
				TVOS_DEPLOYMENT_TARGET = 11.0;
 | 
									TVOS_DEPLOYMENT_TARGET = 12.0;
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
			name = Debug;
 | 
								name = Debug;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
@ -850,7 +888,7 @@
 | 
				
			|||||||
				PRODUCT_NAME = "$(TARGET_NAME)";
 | 
									PRODUCT_NAME = "$(TARGET_NAME)";
 | 
				
			||||||
				SDKROOT = appletvos;
 | 
									SDKROOT = appletvos;
 | 
				
			||||||
				TARGETED_DEVICE_FAMILY = 3;
 | 
									TARGETED_DEVICE_FAMILY = 3;
 | 
				
			||||||
				TVOS_DEPLOYMENT_TARGET = 11.0;
 | 
									TVOS_DEPLOYMENT_TARGET = 12.0;
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
			name = Release;
 | 
								name = Release;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
@ -877,7 +915,7 @@
 | 
				
			|||||||
				PRODUCT_NAME = "$(TARGET_NAME)";
 | 
									PRODUCT_NAME = "$(TARGET_NAME)";
 | 
				
			||||||
				SDKROOT = appletvos;
 | 
									SDKROOT = appletvos;
 | 
				
			||||||
				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/blazerapp-tvOS.app/blazerapp-tvOS";
 | 
									TEST_HOST = "$(BUILT_PRODUCTS_DIR)/blazerapp-tvOS.app/blazerapp-tvOS";
 | 
				
			||||||
				TVOS_DEPLOYMENT_TARGET = 10.1;
 | 
									TVOS_DEPLOYMENT_TARGET = 12.0;
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
			name = Debug;
 | 
								name = Debug;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
@ -904,7 +942,7 @@
 | 
				
			|||||||
				PRODUCT_NAME = "$(TARGET_NAME)";
 | 
									PRODUCT_NAME = "$(TARGET_NAME)";
 | 
				
			||||||
				SDKROOT = appletvos;
 | 
									SDKROOT = appletvos;
 | 
				
			||||||
				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/blazerapp-tvOS.app/blazerapp-tvOS";
 | 
									TEST_HOST = "$(BUILT_PRODUCTS_DIR)/blazerapp-tvOS.app/blazerapp-tvOS";
 | 
				
			||||||
				TVOS_DEPLOYMENT_TARGET = 10.1;
 | 
									TVOS_DEPLOYMENT_TARGET = 12.0;
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
			name = Release;
 | 
								name = Release;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
@ -931,6 +969,7 @@
 | 
				
			|||||||
				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
 | 
									CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
 | 
				
			||||||
				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
 | 
									CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
 | 
				
			||||||
				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
 | 
									CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
 | 
				
			||||||
 | 
									CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
 | 
				
			||||||
				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
 | 
									CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
 | 
				
			||||||
				CLANG_WARN_STRICT_PROTOTYPES = YES;
 | 
									CLANG_WARN_STRICT_PROTOTYPES = YES;
 | 
				
			||||||
				CLANG_WARN_SUSPICIOUS_MOVE = YES;
 | 
									CLANG_WARN_SUSPICIOUS_MOVE = YES;
 | 
				
			||||||
@ -955,7 +994,7 @@
 | 
				
			|||||||
				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 | 
									GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 | 
				
			||||||
				GCC_WARN_UNUSED_FUNCTION = YES;
 | 
									GCC_WARN_UNUSED_FUNCTION = YES;
 | 
				
			||||||
				GCC_WARN_UNUSED_VARIABLE = YES;
 | 
									GCC_WARN_UNUSED_VARIABLE = YES;
 | 
				
			||||||
				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
 | 
									IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 | 
				
			||||||
				LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)";
 | 
									LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)";
 | 
				
			||||||
				LIBRARY_SEARCH_PATHS = (
 | 
									LIBRARY_SEARCH_PATHS = (
 | 
				
			||||||
					"\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
 | 
										"\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
 | 
				
			||||||
@ -991,6 +1030,7 @@
 | 
				
			|||||||
				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
 | 
									CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
 | 
				
			||||||
				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
 | 
									CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
 | 
				
			||||||
				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
 | 
									CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
 | 
				
			||||||
 | 
									CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
 | 
				
			||||||
				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
 | 
									CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
 | 
				
			||||||
				CLANG_WARN_STRICT_PROTOTYPES = YES;
 | 
									CLANG_WARN_STRICT_PROTOTYPES = YES;
 | 
				
			||||||
				CLANG_WARN_SUSPICIOUS_MOVE = YES;
 | 
									CLANG_WARN_SUSPICIOUS_MOVE = YES;
 | 
				
			||||||
@ -1008,7 +1048,7 @@
 | 
				
			|||||||
				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 | 
									GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 | 
				
			||||||
				GCC_WARN_UNUSED_FUNCTION = YES;
 | 
									GCC_WARN_UNUSED_FUNCTION = YES;
 | 
				
			||||||
				GCC_WARN_UNUSED_VARIABLE = YES;
 | 
									GCC_WARN_UNUSED_VARIABLE = YES;
 | 
				
			||||||
				IPHONEOS_DEPLOYMENT_TARGET = 11.0;
 | 
									IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 | 
				
			||||||
				LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)";
 | 
									LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)";
 | 
				
			||||||
				LIBRARY_SEARCH_PATHS = (
 | 
									LIBRARY_SEARCH_PATHS = (
 | 
				
			||||||
					"\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
 | 
										"\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
<Scheme
 | 
					<Scheme
 | 
				
			||||||
   LastUpgradeVersion = "1130"
 | 
					   LastUpgradeVersion = "1250"
 | 
				
			||||||
   version = "1.3">
 | 
					   version = "1.3">
 | 
				
			||||||
   <BuildAction
 | 
					   <BuildAction
 | 
				
			||||||
      parallelizeBuildables = "YES"
 | 
					      parallelizeBuildables = "YES"
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
<Scheme
 | 
					<Scheme
 | 
				
			||||||
   LastUpgradeVersion = "1130"
 | 
					   LastUpgradeVersion = "1250"
 | 
				
			||||||
   version = "1.3">
 | 
					   version = "1.3">
 | 
				
			||||||
   <BuildAction
 | 
					   <BuildAction
 | 
				
			||||||
      parallelizeBuildables = "YES"
 | 
					      parallelizeBuildables = "YES"
 | 
				
			||||||
 | 
				
			|||||||
@ -2,37 +2,52 @@
 | 
				
			|||||||
  "images" : [
 | 
					  "images" : [
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      "idiom" : "iphone",
 | 
					      "idiom" : "iphone",
 | 
				
			||||||
      "size" : "29x29",
 | 
					      "scale" : "2x",
 | 
				
			||||||
      "scale" : "2x"
 | 
					      "size" : "20x20"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      "idiom" : "iphone",
 | 
					      "idiom" : "iphone",
 | 
				
			||||||
      "size" : "29x29",
 | 
					      "scale" : "3x",
 | 
				
			||||||
      "scale" : "3x"
 | 
					      "size" : "20x20"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      "idiom" : "iphone",
 | 
					      "idiom" : "iphone",
 | 
				
			||||||
      "size" : "40x40",
 | 
					      "scale" : "2x",
 | 
				
			||||||
      "scale" : "2x"
 | 
					      "size" : "29x29"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      "idiom" : "iphone",
 | 
					      "idiom" : "iphone",
 | 
				
			||||||
      "size" : "40x40",
 | 
					      "scale" : "3x",
 | 
				
			||||||
      "scale" : "3x"
 | 
					      "size" : "29x29"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      "idiom" : "iphone",
 | 
					      "idiom" : "iphone",
 | 
				
			||||||
      "size" : "60x60",
 | 
					      "scale" : "2x",
 | 
				
			||||||
      "scale" : "2x"
 | 
					      "size" : "40x40"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      "idiom" : "iphone",
 | 
					      "idiom" : "iphone",
 | 
				
			||||||
      "size" : "60x60",
 | 
					      "scale" : "3x",
 | 
				
			||||||
      "scale" : "3x"
 | 
					      "size" : "40x40"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      "idiom" : "iphone",
 | 
				
			||||||
 | 
					      "scale" : "2x",
 | 
				
			||||||
 | 
					      "size" : "60x60"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      "idiom" : "iphone",
 | 
				
			||||||
 | 
					      "scale" : "3x",
 | 
				
			||||||
 | 
					      "size" : "60x60"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      "idiom" : "ios-marketing",
 | 
				
			||||||
 | 
					      "scale" : "1x",
 | 
				
			||||||
 | 
					      "size" : "1024x1024"
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
  "info" : {
 | 
					  "info" : {
 | 
				
			||||||
    "version" : 1,
 | 
					    "author" : "xcode",
 | 
				
			||||||
    "author" : "xcode"
 | 
					    "version" : 1
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										26261
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
							
								
								
									
										22
									
								
								package.json
									
									
									
									
									
								
							
							
						
						@ -11,27 +11,27 @@
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "@k3rn31p4nic/google-translate-api": "github:k3rn31p4nic/google-translate-api",
 | 
					    "@k3rn31p4nic/google-translate-api": "github:k3rn31p4nic/google-translate-api",
 | 
				
			||||||
    "@react-native-community/async-storage": "github:react-native-community/async-storage",
 | 
					    "@react-native-async-storage/async-storage": "^1.15.5",
 | 
				
			||||||
    "@react-native-community/masked-view": "^0.1.10",
 | 
					    "@react-native-community/masked-view": "^0.1.11",
 | 
				
			||||||
    "@react-navigation/bottom-tabs": "^5.8.0",
 | 
					    "@react-navigation/bottom-tabs": "^5.8.0",
 | 
				
			||||||
    "@react-navigation/native": "^5.7.3",
 | 
					    "@react-navigation/native": "^5.9.4",
 | 
				
			||||||
    "@react-navigation/stack": "^5.9.0",
 | 
					    "@react-navigation/stack": "^5.9.0",
 | 
				
			||||||
    "@vitalets/google-translate-api": "^4.0.0",
 | 
					    "@vitalets/google-translate-api": "^4.0.0",
 | 
				
			||||||
    "events": "^3.2.0",
 | 
					    "events": "^3.2.0",
 | 
				
			||||||
    "i18next": "^19.8.4",
 | 
					    "i18n-js": "^3.8.0",
 | 
				
			||||||
    "i18next-react-native-language-detector": "^1.0.2",
 | 
					    "i18next": "^20.3.3",
 | 
				
			||||||
 | 
					    "lodash.memoize": "^4.1.2",
 | 
				
			||||||
    "querystring": "^0.2.0",
 | 
					    "querystring": "^0.2.0",
 | 
				
			||||||
    "react": "16.13.1",
 | 
					    "react": "16.13.1",
 | 
				
			||||||
    "react-i18next": "^11.8.5",
 | 
					    "react-i18next": "^11.11.3",
 | 
				
			||||||
    "react-native": "^0.63.2",
 | 
					    "react-native": "^0.63.2",
 | 
				
			||||||
    "react-native-elements": "^2.2.0",
 | 
					    "react-native-elements": "^2.2.0",
 | 
				
			||||||
    "react-native-gesture-handler": "^1.7.0",
 | 
					    "react-native-gesture-handler": "^1.10.3",
 | 
				
			||||||
    "react-native-i18n": "^2.0.15",
 | 
					 | 
				
			||||||
    "react-native-linear-gradient": "^2.5.6",
 | 
					    "react-native-linear-gradient": "^2.5.6",
 | 
				
			||||||
    "react-native-locale-detector": "^1.0.1",
 | 
					    "react-native-locale-detector": "^1.0.1",
 | 
				
			||||||
    "react-native-reanimated": "^1.10.2",
 | 
					    "react-native-localize": "^2.1.1",
 | 
				
			||||||
    "react-native-safe-area-context": "^3.1.4",
 | 
					    "react-native-safe-area-context": "^3.2.0",
 | 
				
			||||||
    "react-native-screens": "^2.10.1",
 | 
					    "react-native-screens": "^3.4.0",
 | 
				
			||||||
    "react-native-splash-screen": "^3.2.0",
 | 
					    "react-native-splash-screen": "^3.2.0",
 | 
				
			||||||
    "react-native-vector-icons": "^7.0.0",
 | 
					    "react-native-vector-icons": "^7.0.0",
 | 
				
			||||||
    "react-native-webview": "^11.0.2",
 | 
					    "react-native-webview": "^11.0.2",
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2
									
								
								rustfmt.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					imports_granularity="Crate"
 | 
				
			||||||
 | 
					reorder_imports = true
 | 
				
			||||||