8
.gitignore
vendored
|
@ -57,3 +57,11 @@ buck-out/
|
|||
|
||||
# CocoaPods
|
||||
/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 com.facebook.react.PackageList;
|
||||
import com.facebook.react.ReactApplication;
|
||||
import com.zoontek.rnlocalize.RNLocalizePackage;
|
||||
import com.reactnativecommunity.webview.RNCWebViewPackage;
|
||||
import com.reactnativecommunity.webview.RNCWebViewPackage;
|
||||
import com.oblador.vectoricons.VectorIconsPackage;
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
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'
|
||||
project(':react-native-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview/android')
|
||||
include ':react-native-webview'
|
||||
|
|
|
@ -22,49 +22,108 @@ import styles from './styles/liststyles'
|
|||
import { url } from './resources/fetchInfo.json'
|
||||
import { SearchBar } from 'react-native-elements';
|
||||
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 Announcement = ({item}) => {
|
||||
const date = new Date
|
||||
const dateStr = `${date.getMonth()+1}/${date.getDate()}/${date.getFullYear()}`
|
||||
const dateInfo = dateStr===item.item.date&&item.item.time!==undefined?item.item.time:item.item.date;
|
||||
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>
|
||||
const getCurrentDate=()=>{
|
||||
var date = new Date().getDate();
|
||||
var month = new Date().getMonth();
|
||||
var year = new Date().getFullYear();
|
||||
|
||||
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>
|
||||
)
|
||||
}
|
||||
|
||||
export const TeacherList = ({route}) => {
|
||||
function NewTeacherList(props) {
|
||||
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
|
||||
data={route.params.data}
|
||||
data={props.list}
|
||||
renderItem={item=><Announcement item={item}/>}
|
||||
keyExtractor={item=>JSON.stringify(item)}
|
||||
/>
|
||||
</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) {
|
||||
const [color, setColor] = useState(props.color?props.color:'lightgrey')
|
||||
return (
|
||||
<View style={[styles.item1,{flexDirection:'row'}]}>
|
||||
<TouchableOpacity style={{flex:1, justifyContent: 'center'}} onPress={()=>{props.navigation.navigate('TeacherList',{data:props.data,name:props.name})}} activeOpacity={0.8}>
|
||||
<Text style={styles.title3}>{props.name}</Text>
|
||||
<View>
|
||||
<TouchableOpacity style={styles.listItem} onPress={()=>{props.navigation.navigate('TeacherList',{data:props.data,name:props.name})}} activeOpacity={0.8}>
|
||||
<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>
|
||||
{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>
|
||||
)
|
||||
}
|
||||
|
@ -124,14 +183,14 @@ class Announcements extends React.Component {
|
|||
|
||||
render() {
|
||||
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} />
|
||||
<FlatList
|
||||
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}
|
||||
/>
|
||||
</View>
|
||||
</ScrollView>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
23
app/App.js
|
@ -27,25 +27,18 @@ import Staff from './Staff'
|
|||
import OpeningPage from './OpeningPage';
|
||||
import OpenPage from './OpenPage';
|
||||
import Ionicons from 'react-native-vector-icons/Ionicons';
|
||||
import I18n from './i18n';
|
||||
import AsyncStorage from '@react-native-community/async-storage'
|
||||
import I18n from './i18n.js'
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage'
|
||||
|
||||
const Tab = createBottomTabNavigator();
|
||||
|
||||
|
||||
AsyncStorage.getItem('language')
|
||||
.then((token) => {
|
||||
console.log("lang: " + 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 {
|
||||
state = {
|
||||
|
@ -86,11 +79,11 @@ class App extends React.Component {
|
|||
fontSize:16
|
||||
}}}
|
||||
>
|
||||
<Tab.Screen name={I18n.t('app.home')} component={Home}/>
|
||||
<Tab.Screen name={I18n.t('app.calendar')} component={Calendar}/>
|
||||
<Tab.Screen name={I18n.t('app.clubs')} component={Clubs}/>
|
||||
<Tab.Screen name={I18n.t('app.staff')} component={Staff}/>
|
||||
<Tab.Screen name={I18n.t('app.more')} component={More}/>
|
||||
<Tab.Screen name={I18n.t("app.home")} component={Home}/>
|
||||
<Tab.Screen name={I18n.t("app.calendar")} component={Calendar}/>
|
||||
<Tab.Screen name={I18n.t("app.clubs")} component={Clubs}/>
|
||||
<Tab.Screen name={I18n.t("app.staff")} component={Staff}/>
|
||||
<Tab.Screen name={I18n.t("app.more")} component={More}/>
|
||||
</Tab.Navigator>
|
||||
: <OpenPage />}
|
||||
</NavigationContainer>
|
||||
|
|
235
app/Calendar.js
|
@ -14,85 +14,142 @@ import {
|
|||
import {
|
||||
ReloadInstructions,
|
||||
} 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 I18n from './i18n';
|
||||
import { NavigationContainer } from '@react-navigation/native'
|
||||
import { createStackNavigator } from '@react-navigation/stack'
|
||||
import styles from './styles/liststyles'
|
||||
import { url } from './resources/fetchInfo.json'
|
||||
import morestyles from './styles/morestyles'
|
||||
import I18n from './i18n.js'
|
||||
|
||||
const Stack = createStackNavigator();
|
||||
|
||||
const getCurrentDate=()=>{
|
||||
var date = new Date().getDate();
|
||||
var month = new Date().getMonth() + 1;
|
||||
var year = new Date().getFullYear();
|
||||
|
||||
return year + ',' + month + ',' + date;
|
||||
return new Date(year, month, date);
|
||||
}
|
||||
const getWeekDate=()=>{
|
||||
var date = new Date().getDate()-8;
|
||||
var month = new Date().getMonth()+1;
|
||||
var year = new Date().getFullYear();
|
||||
export const EventInfo = ({route}) => {
|
||||
const item = route.params;
|
||||
const itemDate = new Date(item.date)
|
||||
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 [visible, setVisible] = useState(false)
|
||||
const today = new Date(getCurrentDate())
|
||||
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>
|
||||
const background = (<LinearGradient
|
||||
colors={['#f99', 'white']}
|
||||
style = {{flex:1,borderBottomColor:'black',borderBottomWidth:0.5}}
|
||||
/>)
|
||||
|
||||
</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>
|
||||
)
|
||||
}
|
||||
|
||||
</>
|
||||
)
|
||||
|
||||
if (itemDate.getTime() >= today.getTime()) {
|
||||
function NewCalendarCategory (props) {
|
||||
return (
|
||||
<TouchableOpacity style={styles.item1} 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>
|
||||
<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
|
||||
data={props.list}
|
||||
renderItem={item=><Event item={item} name={props.itemname} navigation={props.navigation}/>}
|
||||
keyExtractor={item=>JSON.stringify(item)}
|
||||
/>
|
||||
</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 {
|
||||
|
@ -125,31 +182,53 @@ class Calendar extends React.Component {
|
|||
.then((json) => {
|
||||
const data = JSON.parse(json).data
|
||||
data.sort((a,b)=>new Date(b.date).getTime()-new Date(a.date).getTime())
|
||||
console.log(data);
|
||||
this.setState({data: data});
|
||||
})
|
||||
.catch((error) => console.error(error))
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<View style = {{height: 90, display: 'flex'}}>
|
||||
<LinearGradient
|
||||
colors={['#f99', 'white']}
|
||||
style = {{height: '100%', borderBottomColor:'black', borderBottomWidth:0.5, display: 'flex', justifyContent: 'flex-end', paddingBottom: '2.5%'}}
|
||||
>
|
||||
<Text style = {{fontSize: 24, fontWeight: 'bold', alignSelf: 'center'}}>{I18n.t('calendar.calendarEvents')}</Text>
|
||||
</LinearGradient>
|
||||
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
|
||||
|
||||
</View>
|
||||
<FlatList
|
||||
data={this.state.data}
|
||||
renderItem={item=><Event item={item}/>}
|
||||
keyExtractor={item=>JSON.stringify(item)}
|
||||
/>
|
||||
</View>
|
||||
for (var i =0; i < this.state.data.length; i++) {
|
||||
const itemDate = new Date(this.state.data[i].date)
|
||||
if (itemDate == todayDate) {
|
||||
today.push(this.state.data[i])
|
||||
}
|
||||
else if (itemDate > todayDate && itemDate <= weekFutureDate) {
|
||||
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,
|
||||
StatusBar,
|
||||
Linking,
|
||||
Animated,
|
||||
TouchableOpacity,
|
||||
Image
|
||||
} from 'react-native';
|
||||
|
||||
import {
|
||||
|
@ -18,12 +21,14 @@ import {
|
|||
} from 'react-native/Libraries/NewAppScreen';
|
||||
import styles from './styles/liststyles';
|
||||
import { url } from './resources/fetchInfo.json'
|
||||
import I18n from 'i18n-js';
|
||||
|
||||
class ChallengeWeek extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
isLoading: true
|
||||
isLoading: true,
|
||||
flip: true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,17 +42,70 @@ class ChallengeWeek extends React.Component {
|
|||
}).then((json) => {
|
||||
this.setState({data: JSON.parse(json),isLoading:false});
|
||||
}).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() {
|
||||
{/*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) {
|
||||
return <View/>
|
||||
} else {
|
||||
return (
|
||||
<View style={{alignItems:'center',paddingTop:'5%',paddingiorizontal:'10%', height: '100%', backgroundColor: 'white'}}>
|
||||
<Text style={{fontSize: 32, fontWeight: 'bold', marginBottom: '10%', color: 'red'}}>{this.state.data.title}</Text>
|
||||
<Text style={{textAlign:'center', fontSize: 24, marginBottom: '5%'}}>{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>
|
||||
<View style={{alignItems:'center',paddingiorizontal:'10%', height: '100%', backgroundColor: 'white', justifyContent: 'center', padding: '2%'}}>
|
||||
<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%', 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)}>{I18n.t("challenge.link")}</Text>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
|
67
app/Clubs.js
|
@ -29,50 +29,50 @@ import morestyles from './styles/morestyles'
|
|||
import { url } from './resources/fetchInfo.json'
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
import I18n from './i18n';
|
||||
import Ionicons from 'react-native-vector-icons/Ionicons';
|
||||
|
||||
const Stack = createStackNavigator();
|
||||
|
||||
export const ClubInfo = ({route}) => {
|
||||
const item = route.params;
|
||||
return (
|
||||
<View style = {{padding: 10, backgroundColor: 'white', height: '100%'}}>
|
||||
<View style ={[styles.infoContainer, {flexDirection: 'row', alignItems: 'center'}]}>
|
||||
<View style={{width: '17%', display: 'flex', justifyContent: 'center'}}>
|
||||
<Image source ={require('./assets/time.png')} style={{width: 50, height: 50}}/>
|
||||
</View>
|
||||
<View style={{width: '83%'}}>
|
||||
<Text style = {{fontSize:20}}>{item.meeting}</Text>
|
||||
<ScrollView style = {{backgroundColor: 'white', flex:1, padding: '5%', paddingRight: '10%'}}>
|
||||
<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}}>Meeting Location </Text>
|
||||
<Text style={[styles.title, styles.linktext, {fontSize: 16, fontWeight: '200'}]} onPress={() => Linking.openURL(item.link)}>{item.link}</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style ={[styles.infoContainer, {flexDirection: 'row', alignItems: 'center'}]}>
|
||||
<View style={{width: '17%', display: 'flex', justifyContent: 'center'}}>
|
||||
<Image source ={require('./assets/zoom.png')} style={{width: 50, height: 50}}/>
|
||||
</View>
|
||||
<View style={{width: '83%'}}>
|
||||
<Text style = {[styles.linktext,{fontSize:20}]} onPress={() => Linking.openURL(item.link)}>{item.link}</Text>
|
||||
<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'}}>
|
||||
<Text style={{fontSize: 16}}>Meeting Date</Text>
|
||||
<Text style={[styles.title, {fontSize: 16, fontWeight: '200'}]}>{item.meeting}</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style ={[styles.infoContainer, {flexDirection: 'row', alignItems: 'center'}]}>
|
||||
<View style={{width: '17%', display: 'flex', justifyContent: 'center'}}>
|
||||
<Image source ={require('./assets/sponsor.png')} style={{width: 50, height: 50}}/>
|
||||
</View>
|
||||
<View style={{width: '83%'}}>
|
||||
<Text style = {{fontSize:20}}>{item.sponsor}</Text>
|
||||
</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'}}>
|
||||
<Text style={{fontSize: 16}}>Sponsor</Text>
|
||||
<Text style={[styles.title, {fontSize: 16, fontWeight: '200'}]}>{item.sponsor}</Text>
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>
|
||||
)
|
||||
}
|
||||
function ClubElement (props) {
|
||||
const item = props.item;
|
||||
return(
|
||||
<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}>
|
||||
<View style = {{display: 'flex', flexDirection: 'row', alignItems: 'center'}}>
|
||||
<Image source = {require('./assets/clubs.png')} style = {{height: 40, width: 40, marginRight: 10}}/>
|
||||
<Text style={styles.title3}>{props.item.name}</Text>
|
||||
<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 = {[styles.container2, {justifyContent: 'space-between'}]}>
|
||||
<View style={{display: 'flex', flexDirection: 'row'}}>
|
||||
<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>
|
||||
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
)
|
||||
|
@ -91,7 +91,14 @@ function Club () {
|
|||
name = "Clubs"
|
||||
component = {Clubs}
|
||||
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
|
||||
|
@ -100,7 +107,10 @@ function Club () {
|
|||
options={({route})=>({
|
||||
title:route.params.name,
|
||||
headerTitleStyle:[morestyles.headerTitle,{alignSelf:'center'}],
|
||||
headerBackground: ()=>background
|
||||
headerBackground: ()=>background,
|
||||
headerBackTitleVisible:false,
|
||||
headerTintColor: 'black',
|
||||
headerTitleAlign: 'center',
|
||||
})}
|
||||
/>
|
||||
</Stack.Navigator>
|
||||
|
@ -157,7 +167,7 @@ class Clubs extends React.Component {
|
|||
const { data , dataSearch,search} = this.state;
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<SafeAreaView style={styles.moreDefault}>
|
||||
<SearchBar
|
||||
lightTheme
|
||||
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}/>}
|
||||
keyExtractor={item => JSON.stringify(item)}
|
||||
/>
|
||||
|
||||
</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 { Platform, StyleSheet, TouchableOpacity, Text, ScrollView, View } from 'react-native';
|
||||
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 language = [
|
||||
{lang: <Text>{I18n.t('language.English')}</Text>, code: "en"},
|
||||
{lang: <Text>{I18n.t('language.Spanish')}</Text>, code: "es"},
|
||||
{lang: <Text>English</Text>, code: "en-US"},
|
||||
{lang: <Text>Spanish</Text>, code: "es-US"},
|
||||
]
|
||||
|
||||
export default class extends Component {
|
||||
|
|
|
@ -7,7 +7,20 @@ export default {
|
|||
Hobbies: "Hobbies",
|
||||
Achievements: "Achievements",
|
||||
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: {
|
||||
home: "Home",
|
||||
|
@ -17,7 +30,12 @@ export default {
|
|||
more: "More"
|
||||
},
|
||||
calendar: {
|
||||
calendarEvents: "Calendar Events"
|
||||
calendar: "Calendar",
|
||||
info: "Info",
|
||||
location: "Location",
|
||||
date: "Date",
|
||||
organizer: "Organizer",
|
||||
noEvents: "No Events"
|
||||
},
|
||||
clubs: {
|
||||
searchClubs: "Search Clubs"
|
||||
|
@ -25,12 +43,27 @@ export default {
|
|||
staff: {
|
||||
searchStaff: "Search Staff"
|
||||
},
|
||||
announcements: {
|
||||
noAnnouncements: "No Announcements"
|
||||
},
|
||||
student: {
|
||||
Grade: "Grade",
|
||||
Hobbies: "Hobbies",
|
||||
Achievements: "Achievements",
|
||||
Messages: "Messages",
|
||||
},
|
||||
lunch: {
|
||||
information: "Information",
|
||||
location: "Location"
|
||||
},
|
||||
ssl: {
|
||||
information: "Information",
|
||||
sponsor: "Sponsor",
|
||||
location: "Location"
|
||||
},
|
||||
challenge: {
|
||||
link: "Link"
|
||||
},
|
||||
polls: {
|
||||
textInPoll: "Press the image to take the poll!"
|
||||
},
|
||||
|
@ -38,7 +71,7 @@ export default {
|
|||
Announcements: "Announcements",
|
||||
Resources: "Resources",
|
||||
SOTW: "Student of the Week",
|
||||
lunch: "LunchEvents",
|
||||
lunch: "Lunch Events",
|
||||
ssl: "SSL Opportunities",
|
||||
COTW: "Challenge of the Week",
|
||||
Polls: "Polls",
|
||||
|
|
|
@ -7,7 +7,20 @@ export default {
|
|||
Hobbies: "El pasatiempo",
|
||||
Achievements: "Logros",
|
||||
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: {
|
||||
home: "Casa",
|
||||
|
@ -17,7 +30,12 @@ export default {
|
|||
more: "Más"
|
||||
},
|
||||
calendar: {
|
||||
calendarEvents: "Eventos del calendario"
|
||||
calendar: "ESCalendar",
|
||||
info: "ESInfo",
|
||||
location: "ESLocation",
|
||||
date: "ESDate",
|
||||
organizer: "ESOrganizer",
|
||||
noEvents: "ESNo Events"
|
||||
},
|
||||
clubs: {
|
||||
searchClubs: "Buscar clubes"
|
||||
|
@ -25,12 +43,27 @@ export default {
|
|||
staff: {
|
||||
searchStaff: "Personal de búsqueda"
|
||||
},
|
||||
announcements: {
|
||||
noAnnouncements: "ESNo Announcements"
|
||||
},
|
||||
student: {
|
||||
Grade: "El año",
|
||||
Hobbies: "El pasatiempo",
|
||||
Achievements: "Logros",
|
||||
Messages: "Mensajes",
|
||||
},
|
||||
lunch: {
|
||||
information: "ESInformation",
|
||||
location: "ESLocation"
|
||||
},
|
||||
ssl: {
|
||||
information: "ESInformation",
|
||||
sponsor: "ESSponsor",
|
||||
location: "ESLocation"
|
||||
},
|
||||
challenge: {
|
||||
link: "ESLink"
|
||||
},
|
||||
polls: {
|
||||
textInPoll: "¡Pulsa la imagen para realizar la encuesta!'"
|
||||
},
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
FlatList,
|
||||
TouchableOpacity,
|
||||
Image,
|
||||
Dimensions
|
||||
} from 'react-native';
|
||||
|
||||
import {
|
||||
|
@ -22,9 +23,12 @@ import { NavigationContainer } from '@react-navigation/native'
|
|||
import { createStackNavigator } from '@react-navigation/stack'
|
||||
import styles from './styles/liststyles'
|
||||
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();
|
||||
|
||||
export const LunchInfo = ({route}) => {
|
||||
{/*export const LunchInfo = ({route}) => {
|
||||
const item = route.params;
|
||||
return (
|
||||
<View style = {{padding: 10, backgroundColor: 'white', height: '100%'}}>
|
||||
|
@ -46,17 +50,22 @@ export const LunchInfo = ({route}) => {
|
|||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
}*/}
|
||||
|
||||
function LunchEvent (props) {
|
||||
const item = props.item
|
||||
const [expand, setExpand] = useState(false);
|
||||
return(
|
||||
<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}>
|
||||
<View style = {{display: 'flex', flexDirection: 'row', alignItems: 'center'}}>
|
||||
<Image source = {require('./assets/lunch.png')} style = {{height: 40, width: 40, marginRight: 10}}/>
|
||||
<Text style={styles.title3}>{item.title}</Text>
|
||||
<TouchableOpacity style={styles.listItem} onPress={()=>setExpand(!expand)}>
|
||||
<View style={styles.container2}>
|
||||
<Ionicons name="fast-food-outline" size={36} color={'#323232'} style={{marginRight: 15}} />
|
||||
<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>
|
||||
{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>
|
||||
</View>
|
||||
)
|
||||
|
@ -89,13 +98,13 @@ class LunchEvents extends React.Component {
|
|||
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<ScrollView style={styles.moreDefault}>
|
||||
<FlatList
|
||||
data={this.state.data}
|
||||
renderItem={({item}) => <LunchEvent item={item} name={this.props.title} navigation={this.props.navigation}/>}
|
||||
keyExtractor={item=>JSON.stringify(item)}
|
||||
/>
|
||||
</View>
|
||||
</ScrollView>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
193
app/More.js
|
@ -9,6 +9,7 @@ import {
|
|||
FlatList,
|
||||
TouchableOpacity,
|
||||
Image,
|
||||
Dimensions
|
||||
} from 'react-native';
|
||||
|
||||
import {
|
||||
|
@ -20,7 +21,7 @@ import {
|
|||
} from 'react-native/Libraries/NewAppScreen';
|
||||
|
||||
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 Announcements, {TeacherList} from './Announcements'
|
||||
|
@ -29,10 +30,10 @@ import StudentWeek from './StudentWeek'
|
|||
import SSLOps, {SSLInfo} from './SSLOps'
|
||||
import LunchEvents, {LunchInfo} from './LunchEvents'
|
||||
import ChallengeWeek from './ChallengeWeek'
|
||||
import Settings from './Settings'
|
||||
import Poll from './Poll'
|
||||
import Images from './Images'
|
||||
import Language from './Language'
|
||||
import LinearGradient from 'react-native-linear-gradient'
|
||||
import Ionicons from 'react-native-vector-icons/Ionicons';
|
||||
import I18n from './i18n';
|
||||
|
||||
const Stack = createStackNavigator()
|
||||
|
@ -45,23 +46,27 @@ class MoreSwitch extends React.Component {
|
|||
|
||||
render() {
|
||||
return (
|
||||
<View style={{flex:1,backgroundColor:'red'}}>
|
||||
<View style={{flex:1,backgroundColor:'white', paddingHorizontal: '5%'}}>
|
||||
<FlatList
|
||||
data={[
|
||||
{name:'Announcements',key:"announce", img:Images.announcements},
|
||||
{name:"Resources",key:"resources", img:Images.resources},
|
||||
{name:"SOTW",key:"studentweek", img:Images.student},
|
||||
{name:"lunch",key:"lunchevent", img:Images.lunch},
|
||||
{name:"ssl",key:"sslopps", img:Images.sslopps},
|
||||
{name:"COTW",key:"challengeweek", img:Images.challenge},
|
||||
{name:"Polls", key:"polls", img: Images.polls},
|
||||
{name:"Settings", key:"settings", img: Images.settings},
|
||||
{name:I18n.t("more.Announcements"),key:"announce", img:"megaphone-outline"},
|
||||
{name:I18n.t("more.Resources"),key:"resources", img:"newspaper-outline"},
|
||||
{name:I18n.t("more.SOTW"),key:"studentweek", img:"ribbon-outline"},
|
||||
{name:I18n.t("more.lunch"),key:"lunchevent", img:"fast-food-outline"},
|
||||
{name:I18n.t("more.ssl"),key:"sslopps", img:"school-outline"},
|
||||
{name:I18n.t("more.COTW"),key:"challengeweek", img:"golf-outline"},
|
||||
{name:I18n.t("more.Polls"), key:"polls", img: "stats-chart-outline"},
|
||||
{name:I18n.t("more.Settings"), key:"settings", img: "settings-outline"},
|
||||
]}
|
||||
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('more.'+item.name)}</Text>
|
||||
<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}>{item.name}</Text>
|
||||
<Image source = {require('./assets/forward.png')} style={{tintColor: '#b2b2b2'}}/>
|
||||
</View>
|
||||
|
||||
</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
|
||||
colors={['#f99', 'white']}
|
||||
style = {{flex:1,borderBottomColor:'black',borderBottomWidth:0.5}}
|
||||
|
@ -84,119 +118,140 @@ class More extends React.Component {
|
|||
name="Chooser"
|
||||
component={MoreSwitch}
|
||||
options={{
|
||||
title:I18n.t('more.More'),
|
||||
title:I18n.t("more.More"),
|
||||
headerTitleStyle:styles.headerTitle,
|
||||
headerBackground: ()=>background
|
||||
headerBackground: ()=>background,
|
||||
headerTitleAlign: 'center'
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="announce"
|
||||
component={Announcements}
|
||||
options={{
|
||||
title:I18n.t('more.Announcements'),
|
||||
headerTitleStyle:[styles.headerTitle,{alignSelf:'center'}],
|
||||
headerLeft:null,
|
||||
headerBackground: ()=>background
|
||||
title:I18n.t("more.Announcements"),
|
||||
headerTitleStyle:[styles.headerTitle],
|
||||
headerBackground: ()=>background,
|
||||
headerTitleAlign: 'center',
|
||||
headerBackTitleVisible:false,
|
||||
headerTintColor: 'black'
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="resources"
|
||||
component={Resources}
|
||||
options={{
|
||||
title:I18n.t('more.Resources'),
|
||||
headerTitleStyle:[styles.headerTitle,{alignSelf:'center'}],
|
||||
headerLeft:null,
|
||||
headerBackground: ()=>background
|
||||
title:I18n.t("more.Resources"),
|
||||
headerTitleStyle:styles.headerTitle,
|
||||
//headerLeft:null,
|
||||
headerBackground: ()=>background,
|
||||
headerTitleAlign: 'center',
|
||||
headerBackTitleVisible:false,
|
||||
headerTintColor: 'black'
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="studentweek"
|
||||
component={StudentWeek}
|
||||
options={{
|
||||
title:I18n.t('more.SOTW'),
|
||||
headerTitleStyle:[styles.headerTitle,{alignSelf:'center'}],
|
||||
headerLeft:null,
|
||||
headerBackground: ()=>background
|
||||
title:I18n.t("more.SOTW"),
|
||||
headerTitleStyle:styles.headerTitle,
|
||||
//headerLeft:null,
|
||||
headerBackground: ()=>background,
|
||||
headerTitleAlign: 'center',
|
||||
headerBackTitleVisible:false,
|
||||
headerTintColor: 'black'
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="lunchevent"
|
||||
component={LunchEvents}
|
||||
options={{
|
||||
title:I18n.t('more.lunch'),
|
||||
headerTitleStyle:[styles.headerTitle,{alignSelf:'center'}],
|
||||
headerLeft:null,
|
||||
headerBackground: ()=>background
|
||||
title:I18n.t("more.lunch"),
|
||||
headerTitleStyle:styles.headerTitle,
|
||||
//headerLeft:null,
|
||||
headerBackground: ()=>background,
|
||||
headerTitleAlign: 'center',
|
||||
headerBackTitleVisible:false,
|
||||
headerTintColor: 'black'
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="sslopps"
|
||||
component={SSLOps}
|
||||
options={{
|
||||
title:I18n.t('more.ssl'),
|
||||
headerTitleStyle:[styles.headerTitle,{alignSelf:'center'}],
|
||||
headerLeft:null,
|
||||
headerBackground: ()=>background
|
||||
title:I18n.t("more.ssl"),
|
||||
headerTitleStyle:styles.headerTitle,
|
||||
//headerLeft:null,
|
||||
headerBackground: ()=>background,
|
||||
headerTitleAlign: 'center',
|
||||
headerBackTitleVisible:false,
|
||||
headerTintColor: 'black'
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="challengeweek"
|
||||
component={ChallengeWeek}
|
||||
options={{
|
||||
title:I18n.t('more.COTW'),
|
||||
headerTitleStyle:[styles.headerTitle,{alignSelf:'center'}],
|
||||
headerLeft:null,
|
||||
headerBackground: ()=>background
|
||||
title:I18n.t("more.COTW"),
|
||||
headerTitleStyle:styles.headerTitle,
|
||||
//headerLeft:null,
|
||||
headerBackground: ()=>background,
|
||||
headerTitleAlign: 'center',
|
||||
headerBackTitleVisible:false,
|
||||
headerTintColor: 'black'
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="polls"
|
||||
component={Poll}
|
||||
options={{
|
||||
title:I18n.t('more.Polls'),
|
||||
headerTitleStyle:[styles.headerTitle,{alignSelf:'center'}],
|
||||
headerLeft:null,
|
||||
headerBackground: ()=>background
|
||||
title:I18n.t("more.Polls"),
|
||||
headerTitleStyle:styles.headerTitle,
|
||||
//headerLeft:null,
|
||||
headerBackground: ()=>background,
|
||||
headerTitleAlign: 'center',
|
||||
headerBackTitleVisible:false,
|
||||
headerTintColor: 'black'
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="settings"
|
||||
component={Settings}
|
||||
component={SettingSwitch}
|
||||
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'}],
|
||||
headerLeft:null,
|
||||
headerBackground: ()=>background
|
||||
headerBackground: ()=>background,
|
||||
//headerLeft: null,
|
||||
headerBackTitleVisible:false,
|
||||
headerTintColor: 'black',
|
||||
headerTitleAlign: 'center'
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="TeacherList"
|
||||
component={TeacherList}
|
||||
options={({route})=>({
|
||||
headerTitleStyle:[styles.headerTitle,{alignSelf:'center',fontSize:Math.min(24,24*23/route.params.name.length)}],
|
||||
headerTitleStyle:[styles.headerTitle],
|
||||
title:route.params.name,
|
||||
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,
|
||||
headerRight:()=>(<></>)
|
||||
headerBackTitleVisible:false,
|
||||
headerTintColor: 'black',
|
||||
headerTitleAlign: 'center'
|
||||
//headerLeft: null,
|
||||
})}
|
||||
/>
|
||||
</Stack.Navigator>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { Component, useState } from 'react';
|
||||
/*import React, { Component, useState } from 'react';
|
||||
import {
|
||||
Platform,
|
||||
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 {
|
||||
SafeAreaView,
|
||||
StyleSheet,
|
||||
|
@ -21,7 +21,7 @@ import {WebView} from 'react-native-webview';
|
|||
import LinearGradient from 'react-native-linear-gradient';
|
||||
import { Linking } from 'react-native';
|
||||
import { url } from './resources/fetchInfo.json'
|
||||
import I18n from './i18n';
|
||||
//import I18n from './i18n';
|
||||
|
||||
class Poll extends React.Component {
|
||||
|
||||
|
@ -47,7 +47,7 @@ componentDidMount() {
|
|||
})
|
||||
.catch((error) => console.error(error))
|
||||
}*/
|
||||
|
||||
/*
|
||||
render() {
|
||||
return (
|
||||
<View style = {{backgroundColor: 'white'}}>
|
||||
|
@ -55,11 +55,47 @@ componentDidMount() {
|
|||
<TouchableOpacity onPress={()=>Linking.openURL("https://google.com")}>
|
||||
<Image source={require('./assets/polls.png')} style={{marginTop: 50, height: 300, width: 300, tintColor: 'red'}}/>
|
||||
</TouchableOpacity>
|
||||
<Text style ={{fontSize: 20, marginTop: 30}}>{I18n.t('polls.textInPoll')}</Text>
|
||||
<Text style ={{fontSize: 20, marginTop: 30}}>Take A Poll!</Text>
|
||||
</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;
|
|
@ -8,7 +8,8 @@ import {
|
|||
StatusBar,
|
||||
Linking,
|
||||
Image,
|
||||
TouchableOpacity
|
||||
TouchableOpacity,
|
||||
Dimensions
|
||||
} from 'react-native';
|
||||
|
||||
import {
|
||||
|
@ -20,12 +21,16 @@ import {
|
|||
} from 'react-native/Libraries/NewAppScreen';
|
||||
import styles from './styles/morestyles';
|
||||
|
||||
const windowWidth = Dimensions.get('window').width*.80/3.5;
|
||||
|
||||
function ResourceLink(props) {
|
||||
return (
|
||||
<TouchableOpacity style={styles.resourceContainer} onPress={() => Linking.openURL(props.url)}>
|
||||
<Image source={props.img} style={styles.image}/>
|
||||
<View style={styles.textContainer}>
|
||||
<Text style={styles.resourceText}>{props.name}</Text>
|
||||
<TouchableOpacity style={styles.resourceContainer, {paddingHorizontal: '5%', paddingBottom: '5%'}} onPress={() => Linking.openURL(props.url)}>
|
||||
<View style={{display: 'flex', textAlign: 'center', width: windowWidth}}>
|
||||
<View style={{aspectRatio: 1}}>
|
||||
<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>
|
||||
</TouchableOpacity>
|
||||
)
|
||||
|
@ -35,12 +40,18 @@ class Resources extends React.Component {
|
|||
render() {
|
||||
return (
|
||||
<ScrollView style = {{backgroundColor: 'white'}}>
|
||||
<ResourceLink url='https://classroom.mcpsmd.org/' img={require('./assets/canvaslogo.png')} name='MyMCPS Classroom'/>
|
||||
<ResourceLink url='https://md-mcps-psv.edupoint.com/Home_PXP2.aspx' img={require('./assets/studentvue.jpg')} name='StudentVUE'/>
|
||||
<View style = {{display: 'flex', flexDirection: 'row', flexWrap: 'wrap', paddingVertical: '5%'}}>
|
||||
<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://blairblazersathletics.com/' img={require('./assets/athletics.jpg')} name='Blair Athletics'/>
|
||||
<ResourceLink url='https://classroom.google.com/u/0/h' img={require('./assets/googleclassroom.jpg')} name='Google Classroom'/>
|
||||
<ResourceLink url='https://classroom.google.com/u/0/h' img={require('./assets/gc.png')} 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>
|
||||
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
FlatList,
|
||||
TouchableOpacity,
|
||||
Image,
|
||||
Dimensions
|
||||
} from 'react-native';
|
||||
|
||||
import {
|
||||
|
@ -22,11 +23,13 @@ import { NavigationContainer } from '@react-navigation/native'
|
|||
import { createStackNavigator } from '@react-navigation/stack'
|
||||
import styles from './styles/liststyles';
|
||||
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';
|
||||
|
||||
const Stack = createStackNavigator();
|
||||
|
||||
export const SSLInfo = ({route}) => {
|
||||
{/*export const SSLInfo = ({route}) => {
|
||||
const item = route.params;
|
||||
console
|
||||
return (
|
||||
|
@ -57,17 +60,22 @@ export const SSLInfo = ({route}) => {
|
|||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
}*/}
|
||||
|
||||
function SSLElement (props) {
|
||||
const item = props.item;
|
||||
const [expand, setExpand] = useState(false);
|
||||
return(
|
||||
<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}>
|
||||
<View style = {{display: 'flex', flexDirection: 'row', alignItems: 'center'}}>
|
||||
<Image source = {require('./assets/sslopps.png')} style = {{height: 40, width: 40, marginRight: 10}}/>
|
||||
<Text style={styles.title3}>{item.item.title}</Text>
|
||||
<TouchableOpacity style={styles.listItem} onPress={()=>setExpand(!expand)}>
|
||||
<View style = {styles.container2}>
|
||||
<Ionicons name="school-outline" size={36} color={'#323232'} style={{marginRight: 15}} />
|
||||
<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>
|
||||
{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>
|
||||
</View>
|
||||
)
|
||||
|
@ -100,13 +108,14 @@ class SSLOps extends React.Component {
|
|||
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<ScrollView style={styles.moreDefault}>
|
||||
<FlatList
|
||||
data={this.state.data}
|
||||
renderItem={item=><SSLElement item={item} name={item.title} navigation={this.props.navigation}/>}
|
||||
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,
|
||||
TouchableOpacity,
|
||||
Image,
|
||||
TouchableHighlight,
|
||||
Linking
|
||||
} from 'react-native';
|
||||
|
||||
|
@ -20,43 +21,135 @@ import {
|
|||
DebugInstructions,
|
||||
ReloadInstructions,
|
||||
} from 'react-native/Libraries/NewAppScreen';
|
||||
import { NavigationContainer } from '@react-navigation/native'
|
||||
import { createStackNavigator } from '@react-navigation/stack'
|
||||
import { SearchBar } from 'react-native-elements';
|
||||
import styles from './styles/liststyles'
|
||||
import morestyles from './styles/morestyles'
|
||||
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';
|
||||
|
||||
const StaffElement = ({item}) => {
|
||||
const [visible, setVisible] = useState(false)
|
||||
const extra = (
|
||||
[
|
||||
...item.item.emails.map(email=>(
|
||||
<View style={{display: 'flex', flexDirection: 'row', alignItems: 'center', marginTop: '2%', paddingHorizontal: '1%'}}>
|
||||
<View style={{width: '10%', display: 'flex', justifyContent: 'center'}}>
|
||||
<Image source={require('./assets/email.png')} style={{height: 22, width: 22}}/>
|
||||
const Stack = createStackNavigator();
|
||||
|
||||
export const StaffInfo = ({route}) => {
|
||||
const item = route.params;
|
||||
|
||||
console.log(item);
|
||||
|
||||
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 style={{width: '90%'}}>
|
||||
<Text key={email}><Text style={styles.linktext} onPress={()=>Linking.openURL("mailto:"+email)}><Text></Text>{email}</Text></Text>
|
||||
<View style={{}}>
|
||||
<Text style = {{fontSize:16}}>{email}</Text>
|
||||
</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(
|
||||
<View>
|
||||
<TouchableOpacity style={styles.item1} onPress={()=>setVisible(!visible)} activeOpacity={0.8}>
|
||||
<View style = {{display: 'flex', flexDirection: 'row', alignItems: 'center'}}>
|
||||
<Image source = {require('./assets/staff.png')} style = {{height: 40, width: 40, marginRight: 10}}/>
|
||||
<Text style={styles.title3}>{item.item.name}</Text>
|
||||
<TouchableOpacity style={[styles.listItem]} onPress={()=>props.navigation.navigate('StaffInfo', {data:props.data,name:props.name,emails:item.emails})} activeOpacity={0.8}>
|
||||
<View style = {[styles.container2, {justifyContent: 'space-between'}]}>
|
||||
<View style={{display: 'flex', flexDirection: 'row'}}>
|
||||
<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>
|
||||
{visible?extra:<></>}
|
||||
</TouchableOpacity>
|
||||
</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) {
|
||||
super(props);
|
||||
|
||||
|
@ -95,7 +188,7 @@ class Staff extends React.Component {
|
|||
updateSearch = (search) => {
|
||||
this.setState({ search:search });
|
||||
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})
|
||||
};
|
||||
clearSearch = (search)=>{
|
||||
|
@ -104,8 +197,9 @@ class Staff extends React.Component {
|
|||
}
|
||||
render() {
|
||||
const { data , dataSearch,search} = this.state;
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<SafeAreaView style={styles.moreDefault}>
|
||||
<SearchBar
|
||||
lightTheme
|
||||
placeholder={I18n.t('staff.searchStaff')}
|
||||
|
@ -115,10 +209,11 @@ class Staff extends React.Component {
|
|||
value={this.state.search}/>
|
||||
<FlatList
|
||||
data={dataSearch}
|
||||
renderItem={item => <StaffElement item={item}/>}
|
||||
renderItem={({item}) => <StaffElement item={item} name={item.name} navigation={this.props.navigation}/>}
|
||||
keyExtractor={item => JSON.stringify(item)}
|
||||
/>
|
||||
</SafeAreaView>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
SafeAreaView,
|
||||
StyleSheet,
|
||||
|
@ -7,6 +7,7 @@ import {
|
|||
Text,
|
||||
StatusBar,
|
||||
Image,
|
||||
TouchableOpacity
|
||||
} from 'react-native';
|
||||
|
||||
import {
|
||||
|
@ -18,15 +19,36 @@ import {
|
|||
} from 'react-native/Libraries/NewAppScreen';
|
||||
import I18n from './i18n';
|
||||
import { url } from './resources/fetchInfo.json'
|
||||
import LinearGradient from 'react-native-linear-gradient';
|
||||
|
||||
class StudentWeek extends React.Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
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() {
|
||||
fetch(`${url}/api/en/student`,{
|
||||
headers: {
|
||||
|
@ -44,35 +66,53 @@ class StudentWeek extends React.Component {
|
|||
return <View/>
|
||||
} else {
|
||||
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 (
|
||||
<View style={{paddingTop:'5%',paddingHorizontal:'10%', backgroundColor: 'white', height: '100%'}}>
|
||||
<View style = {{display: 'flex', flexDirection: 'row', justifyContent: 'space-between'}}>
|
||||
<View>
|
||||
<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>
|
||||
<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 = {{iconURI}} />
|
||||
</View>
|
||||
<View style = {{height: 150, width: 150}}>
|
||||
<Image style = {{height: '100%', width:'100%', borderRadius: 6}}source={{iconURI}} />
|
||||
<Text style={{fontSize:28,marginTop:'5%',textAlign:'center'}}>{this.state.data.name}</Text>
|
||||
<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 style = {{paddingTop:'10%', height: '55%', display: 'flex', flexDirection: 'column', justifyContent: 'space-between'}}>
|
||||
<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>
|
||||
</ScrollView>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
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 'react-native-i18n';
|
||||
import en from './Languages/en'
|
||||
import es from './Languages/es'
|
||||
import I18n from "i18n-js";
|
||||
import * as RNLocalize from "react-native-localize";
|
||||
import en from "./Languages/en.js";
|
||||
import es from "./Languages/es.js";
|
||||
|
||||
const locales = RNLocalize.getLocales();
|
||||
|
||||
if (Array.isArray(locales)) {
|
||||
I18n.locale = locales[0].languageTag;
|
||||
}
|
||||
|
||||
I18n.fallbacks = true;
|
||||
I18n.translations = {
|
||||
en,
|
||||
es,
|
||||
es
|
||||
};
|
||||
|
||||
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({
|
||||
container: {
|
||||
flex: 1,
|
||||
marginTop: StatusBar.currentHeight || 0
|
||||
marginTop: /*StatusBar.currentHeight ||*/ 0
|
||||
},
|
||||
item: {
|
||||
backgroundColor: 'white',
|
||||
|
@ -11,6 +11,43 @@ const styles = StyleSheet.create({
|
|||
borderBottomWidth: 1.5,
|
||||
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: {
|
||||
backgroundColor: 'white',
|
||||
padding: 15,
|
||||
|
|
|
@ -5,9 +5,9 @@ console.log(Dimensions.get('window'))
|
|||
|
||||
const styles=StyleSheet.create({
|
||||
moreitem: {
|
||||
backgroundColor:'red',
|
||||
borderBottomColor:'white',
|
||||
borderBottomWidth:0.5,
|
||||
backgroundColor:'white',
|
||||
borderBottomColor:'#D5D5D5',
|
||||
borderBottomWidth:.5,
|
||||
height: Dimensions.get('window').height*0.075,
|
||||
paddingLeft: '3%',
|
||||
fontSize: 32,
|
||||
|
@ -16,35 +16,17 @@ const styles=StyleSheet.create({
|
|||
alignItems: 'center',
|
||||
},
|
||||
moretext: {
|
||||
color:'#e3e3e3',
|
||||
fontSize:22,
|
||||
fontSize:20,
|
||||
},
|
||||
headerTitle: {
|
||||
fontWeight: 'bold',
|
||||
fontSize:24,
|
||||
alignSelf: 'center'
|
||||
},
|
||||
resourceContainer: {
|
||||
alignItems: 'center',
|
||||
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: {
|
||||
display: 'flex',
|
||||
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 'RNLocalize', :path => '../node_modules/react-native-localize'
|
||||
|
||||
target 'blazerappTests' do
|
||||
inherit! :complete
|
||||
# Pods for testing
|
||||
end
|
||||
|
||||
# Enables Flipper.
|
||||
#
|
||||
# Note that if you have use_frameworks! enabled, Flipper will not work and
|
||||
# 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|
|
||||
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
|
||||
|
||||
target 'blazerapp-tvOS' do
|
||||
|
|
532
ios/Podfile.lock
|
@ -3,60 +3,70 @@ PODS:
|
|||
- BVLinearGradient (2.5.6):
|
||||
- React
|
||||
- CocoaAsyncSocket (7.6.5)
|
||||
- CocoaLibEvent (1.0.0)
|
||||
- DoubleConversion (1.1.6)
|
||||
- FBLazyVector (0.63.2)
|
||||
- FBReactNativeSpec (0.63.2):
|
||||
- FBLazyVector (0.63.4)
|
||||
- FBReactNativeSpec (0.63.4):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- RCTRequired (= 0.63.2)
|
||||
- RCTTypeSafety (= 0.63.2)
|
||||
- React-Core (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- ReactCommon/turbomodule/core (= 0.63.2)
|
||||
- Flipper (0.41.5):
|
||||
- Flipper-Folly (~> 2.2)
|
||||
- Flipper-RSocket (~> 1.1)
|
||||
- RCTRequired (= 0.63.4)
|
||||
- RCTTypeSafety (= 0.63.4)
|
||||
- React-Core (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- ReactCommon/turbomodule/core (= 0.63.4)
|
||||
- Flipper (0.87.0):
|
||||
- Flipper-Folly (~> 2.5)
|
||||
- Flipper-RSocket (~> 1.3)
|
||||
- Flipper-DoubleConversion (1.1.7)
|
||||
- Flipper-Folly (2.2.0):
|
||||
- Flipper-Folly (2.5.3):
|
||||
- boost-for-react-native
|
||||
- CocoaLibEvent (~> 1.0)
|
||||
- Flipper-DoubleConversion
|
||||
- Flipper-Glog
|
||||
- OpenSSL-Universal (= 1.0.2.19)
|
||||
- libevent (~> 2.1.12)
|
||||
- OpenSSL-Universal (= 1.1.180)
|
||||
- Flipper-Glog (0.3.6)
|
||||
- Flipper-PeerTalk (0.0.4)
|
||||
- Flipper-RSocket (1.1.0):
|
||||
- Flipper-Folly (~> 2.2)
|
||||
- FlipperKit (0.41.5):
|
||||
- FlipperKit/Core (= 0.41.5)
|
||||
- FlipperKit/Core (0.41.5):
|
||||
- Flipper (~> 0.41.5)
|
||||
- Flipper-RSocket (1.3.1):
|
||||
- Flipper-Folly (~> 2.5)
|
||||
- FlipperKit (0.87.0):
|
||||
- FlipperKit/Core (= 0.87.0)
|
||||
- FlipperKit/Core (0.87.0):
|
||||
- Flipper (~> 0.87.0)
|
||||
- FlipperKit/CppBridge
|
||||
- FlipperKit/FBCxxFollyDynamicConvert
|
||||
- FlipperKit/FBDefines
|
||||
- FlipperKit/FKPortForwarding
|
||||
- FlipperKit/CppBridge (0.41.5):
|
||||
- Flipper (~> 0.41.5)
|
||||
- FlipperKit/FBCxxFollyDynamicConvert (0.41.5):
|
||||
- Flipper-Folly (~> 2.2)
|
||||
- FlipperKit/FBDefines (0.41.5)
|
||||
- FlipperKit/FKPortForwarding (0.41.5):
|
||||
- FlipperKit/CppBridge (0.87.0):
|
||||
- Flipper (~> 0.87.0)
|
||||
- FlipperKit/FBCxxFollyDynamicConvert (0.87.0):
|
||||
- Flipper-Folly (~> 2.5)
|
||||
- FlipperKit/FBDefines (0.87.0)
|
||||
- FlipperKit/FKPortForwarding (0.87.0):
|
||||
- CocoaAsyncSocket (~> 7.6)
|
||||
- Flipper-PeerTalk (~> 0.0.4)
|
||||
- FlipperKit/FlipperKitHighlightOverlay (0.41.5)
|
||||
- FlipperKit/FlipperKitLayoutPlugin (0.41.5):
|
||||
- FlipperKit/FlipperKitHighlightOverlay (0.87.0)
|
||||
- FlipperKit/FlipperKitLayoutHelpers (0.87.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitHighlightOverlay
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable
|
||||
- FlipperKit/FlipperKitLayoutIOSDescriptors (0.87.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitHighlightOverlay
|
||||
- FlipperKit/FlipperKitLayoutHelpers
|
||||
- YogaKit (~> 1.18)
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable (0.41.5)
|
||||
- FlipperKit/FlipperKitNetworkPlugin (0.41.5):
|
||||
- FlipperKit/FlipperKitLayoutPlugin (0.87.0):
|
||||
- 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/FlipperKitUserDefaultsPlugin (0.41.5):
|
||||
- FlipperKit/FlipperKitReactPlugin (0.87.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/SKIOSNetworkPlugin (0.41.5):
|
||||
- FlipperKit/FlipperKitUserDefaultsPlugin (0.87.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/SKIOSNetworkPlugin (0.87.0):
|
||||
- FlipperKit/Core
|
||||
- FlipperKit/FlipperKitNetworkPlugin
|
||||
- Folly (2020.01.13.00):
|
||||
|
@ -69,254 +79,252 @@ PODS:
|
|||
- DoubleConversion
|
||||
- glog
|
||||
- glog (0.3.5)
|
||||
- OpenSSL-Universal (1.0.2.19):
|
||||
- OpenSSL-Universal/Static (= 1.0.2.19)
|
||||
- OpenSSL-Universal/Static (1.0.2.19)
|
||||
- RCTRequired (0.63.2)
|
||||
- RCTTypeSafety (0.63.2):
|
||||
- FBLazyVector (= 0.63.2)
|
||||
- libevent (2.1.12)
|
||||
- OpenSSL-Universal (1.1.180)
|
||||
- RCTRequired (0.63.4)
|
||||
- RCTTypeSafety (0.63.4):
|
||||
- FBLazyVector (= 0.63.4)
|
||||
- Folly (= 2020.01.13.00)
|
||||
- RCTRequired (= 0.63.2)
|
||||
- React-Core (= 0.63.2)
|
||||
- React (0.63.2):
|
||||
- React-Core (= 0.63.2)
|
||||
- React-Core/DevSupport (= 0.63.2)
|
||||
- React-Core/RCTWebSocket (= 0.63.2)
|
||||
- React-RCTActionSheet (= 0.63.2)
|
||||
- React-RCTAnimation (= 0.63.2)
|
||||
- React-RCTBlob (= 0.63.2)
|
||||
- React-RCTImage (= 0.63.2)
|
||||
- React-RCTLinking (= 0.63.2)
|
||||
- React-RCTNetwork (= 0.63.2)
|
||||
- React-RCTSettings (= 0.63.2)
|
||||
- React-RCTText (= 0.63.2)
|
||||
- React-RCTVibration (= 0.63.2)
|
||||
- React-callinvoker (0.63.2)
|
||||
- React-Core (0.63.2):
|
||||
- RCTRequired (= 0.63.4)
|
||||
- React-Core (= 0.63.4)
|
||||
- React (0.63.4):
|
||||
- React-Core (= 0.63.4)
|
||||
- React-Core/DevSupport (= 0.63.4)
|
||||
- React-Core/RCTWebSocket (= 0.63.4)
|
||||
- React-RCTActionSheet (= 0.63.4)
|
||||
- React-RCTAnimation (= 0.63.4)
|
||||
- React-RCTBlob (= 0.63.4)
|
||||
- React-RCTImage (= 0.63.4)
|
||||
- React-RCTLinking (= 0.63.4)
|
||||
- React-RCTNetwork (= 0.63.4)
|
||||
- React-RCTSettings (= 0.63.4)
|
||||
- React-RCTText (= 0.63.4)
|
||||
- React-RCTVibration (= 0.63.4)
|
||||
- React-callinvoker (0.63.4)
|
||||
- React-Core (0.63.4):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default (= 0.63.2)
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- React-Core/Default (= 0.63.4)
|
||||
- React-cxxreact (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- React-jsiexecutor (= 0.63.4)
|
||||
- Yoga
|
||||
- React-Core/CoreModulesHeaders (0.63.2):
|
||||
- React-Core/CoreModulesHeaders (0.63.4):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- React-cxxreact (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- React-jsiexecutor (= 0.63.4)
|
||||
- Yoga
|
||||
- React-Core/Default (0.63.2):
|
||||
- React-Core/Default (0.63.4):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- React-cxxreact (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- React-jsiexecutor (= 0.63.4)
|
||||
- Yoga
|
||||
- React-Core/DevSupport (0.63.2):
|
||||
- React-Core/DevSupport (0.63.4):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default (= 0.63.2)
|
||||
- React-Core/RCTWebSocket (= 0.63.2)
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- React-jsinspector (= 0.63.2)
|
||||
- React-Core/Default (= 0.63.4)
|
||||
- React-Core/RCTWebSocket (= 0.63.4)
|
||||
- React-cxxreact (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- React-jsiexecutor (= 0.63.4)
|
||||
- React-jsinspector (= 0.63.4)
|
||||
- Yoga
|
||||
- React-Core/RCTActionSheetHeaders (0.63.2):
|
||||
- React-Core/RCTActionSheetHeaders (0.63.4):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- React-cxxreact (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- React-jsiexecutor (= 0.63.4)
|
||||
- Yoga
|
||||
- React-Core/RCTAnimationHeaders (0.63.2):
|
||||
- React-Core/RCTAnimationHeaders (0.63.4):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- React-cxxreact (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- React-jsiexecutor (= 0.63.4)
|
||||
- Yoga
|
||||
- React-Core/RCTBlobHeaders (0.63.2):
|
||||
- React-Core/RCTBlobHeaders (0.63.4):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- React-cxxreact (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- React-jsiexecutor (= 0.63.4)
|
||||
- Yoga
|
||||
- React-Core/RCTImageHeaders (0.63.2):
|
||||
- React-Core/RCTImageHeaders (0.63.4):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- React-cxxreact (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- React-jsiexecutor (= 0.63.4)
|
||||
- Yoga
|
||||
- React-Core/RCTLinkingHeaders (0.63.2):
|
||||
- React-Core/RCTLinkingHeaders (0.63.4):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- React-cxxreact (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- React-jsiexecutor (= 0.63.4)
|
||||
- Yoga
|
||||
- React-Core/RCTNetworkHeaders (0.63.2):
|
||||
- React-Core/RCTNetworkHeaders (0.63.4):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- React-cxxreact (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- React-jsiexecutor (= 0.63.4)
|
||||
- Yoga
|
||||
- React-Core/RCTSettingsHeaders (0.63.2):
|
||||
- React-Core/RCTSettingsHeaders (0.63.4):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- React-cxxreact (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- React-jsiexecutor (= 0.63.4)
|
||||
- Yoga
|
||||
- React-Core/RCTTextHeaders (0.63.2):
|
||||
- React-Core/RCTTextHeaders (0.63.4):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- React-cxxreact (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- React-jsiexecutor (= 0.63.4)
|
||||
- Yoga
|
||||
- React-Core/RCTVibrationHeaders (0.63.2):
|
||||
- React-Core/RCTVibrationHeaders (0.63.4):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- React-cxxreact (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- React-jsiexecutor (= 0.63.4)
|
||||
- Yoga
|
||||
- React-Core/RCTWebSocket (0.63.2):
|
||||
- React-Core/RCTWebSocket (0.63.4):
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-Core/Default (= 0.63.2)
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsiexecutor (= 0.63.2)
|
||||
- React-Core/Default (= 0.63.4)
|
||||
- React-cxxreact (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- React-jsiexecutor (= 0.63.4)
|
||||
- Yoga
|
||||
- React-CoreModules (0.63.2):
|
||||
- FBReactNativeSpec (= 0.63.2)
|
||||
- React-CoreModules (0.63.4):
|
||||
- FBReactNativeSpec (= 0.63.4)
|
||||
- Folly (= 2020.01.13.00)
|
||||
- RCTTypeSafety (= 0.63.2)
|
||||
- React-Core/CoreModulesHeaders (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-RCTImage (= 0.63.2)
|
||||
- ReactCommon/turbomodule/core (= 0.63.2)
|
||||
- React-cxxreact (0.63.2):
|
||||
- RCTTypeSafety (= 0.63.4)
|
||||
- React-Core/CoreModulesHeaders (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- React-RCTImage (= 0.63.4)
|
||||
- ReactCommon/turbomodule/core (= 0.63.4)
|
||||
- React-cxxreact (0.63.4):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- DoubleConversion
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-callinvoker (= 0.63.2)
|
||||
- React-jsinspector (= 0.63.2)
|
||||
- React-jsi (0.63.2):
|
||||
- React-callinvoker (= 0.63.4)
|
||||
- React-jsinspector (= 0.63.4)
|
||||
- React-jsi (0.63.4):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- DoubleConversion
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-jsi/Default (= 0.63.2)
|
||||
- React-jsi/Default (0.63.2):
|
||||
- React-jsi/Default (= 0.63.4)
|
||||
- React-jsi/Default (0.63.4):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- DoubleConversion
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-jsiexecutor (0.63.2):
|
||||
- React-jsiexecutor (0.63.4):
|
||||
- DoubleConversion
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-jsinspector (0.63.2)
|
||||
- react-native-safe-area-context (3.1.4):
|
||||
- React
|
||||
- React-cxxreact (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- React-jsinspector (0.63.4)
|
||||
- react-native-safe-area-context (3.2.0):
|
||||
- React-Core
|
||||
- react-native-splash-screen (3.2.0):
|
||||
- React
|
||||
- react-native-webview (11.0.2):
|
||||
- react-native-webview (11.6.4):
|
||||
- React-Core
|
||||
- React-RCTActionSheet (0.63.2):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.63.2)
|
||||
- React-RCTAnimation (0.63.2):
|
||||
- FBReactNativeSpec (= 0.63.2)
|
||||
- React-RCTActionSheet (0.63.4):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.63.4)
|
||||
- React-RCTAnimation (0.63.4):
|
||||
- FBReactNativeSpec (= 0.63.4)
|
||||
- Folly (= 2020.01.13.00)
|
||||
- RCTTypeSafety (= 0.63.2)
|
||||
- React-Core/RCTAnimationHeaders (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- ReactCommon/turbomodule/core (= 0.63.2)
|
||||
- React-RCTBlob (0.63.2):
|
||||
- FBReactNativeSpec (= 0.63.2)
|
||||
- RCTTypeSafety (= 0.63.4)
|
||||
- React-Core/RCTAnimationHeaders (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- ReactCommon/turbomodule/core (= 0.63.4)
|
||||
- React-RCTBlob (0.63.4):
|
||||
- FBReactNativeSpec (= 0.63.4)
|
||||
- Folly (= 2020.01.13.00)
|
||||
- React-Core/RCTBlobHeaders (= 0.63.2)
|
||||
- React-Core/RCTWebSocket (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-RCTNetwork (= 0.63.2)
|
||||
- ReactCommon/turbomodule/core (= 0.63.2)
|
||||
- React-RCTImage (0.63.2):
|
||||
- FBReactNativeSpec (= 0.63.2)
|
||||
- React-Core/RCTBlobHeaders (= 0.63.4)
|
||||
- React-Core/RCTWebSocket (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- React-RCTNetwork (= 0.63.4)
|
||||
- ReactCommon/turbomodule/core (= 0.63.4)
|
||||
- React-RCTImage (0.63.4):
|
||||
- FBReactNativeSpec (= 0.63.4)
|
||||
- Folly (= 2020.01.13.00)
|
||||
- RCTTypeSafety (= 0.63.2)
|
||||
- React-Core/RCTImageHeaders (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- React-RCTNetwork (= 0.63.2)
|
||||
- ReactCommon/turbomodule/core (= 0.63.2)
|
||||
- React-RCTLinking (0.63.2):
|
||||
- FBReactNativeSpec (= 0.63.2)
|
||||
- React-Core/RCTLinkingHeaders (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- ReactCommon/turbomodule/core (= 0.63.2)
|
||||
- React-RCTNetwork (0.63.2):
|
||||
- FBReactNativeSpec (= 0.63.2)
|
||||
- RCTTypeSafety (= 0.63.4)
|
||||
- React-Core/RCTImageHeaders (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- React-RCTNetwork (= 0.63.4)
|
||||
- ReactCommon/turbomodule/core (= 0.63.4)
|
||||
- React-RCTLinking (0.63.4):
|
||||
- FBReactNativeSpec (= 0.63.4)
|
||||
- React-Core/RCTLinkingHeaders (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- ReactCommon/turbomodule/core (= 0.63.4)
|
||||
- React-RCTNetwork (0.63.4):
|
||||
- FBReactNativeSpec (= 0.63.4)
|
||||
- Folly (= 2020.01.13.00)
|
||||
- RCTTypeSafety (= 0.63.2)
|
||||
- React-Core/RCTNetworkHeaders (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- ReactCommon/turbomodule/core (= 0.63.2)
|
||||
- React-RCTSettings (0.63.2):
|
||||
- FBReactNativeSpec (= 0.63.2)
|
||||
- RCTTypeSafety (= 0.63.4)
|
||||
- React-Core/RCTNetworkHeaders (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- ReactCommon/turbomodule/core (= 0.63.4)
|
||||
- React-RCTSettings (0.63.4):
|
||||
- FBReactNativeSpec (= 0.63.4)
|
||||
- Folly (= 2020.01.13.00)
|
||||
- RCTTypeSafety (= 0.63.2)
|
||||
- React-Core/RCTSettingsHeaders (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- ReactCommon/turbomodule/core (= 0.63.2)
|
||||
- React-RCTText (0.63.2):
|
||||
- React-Core/RCTTextHeaders (= 0.63.2)
|
||||
- React-RCTVibration (0.63.2):
|
||||
- FBReactNativeSpec (= 0.63.2)
|
||||
- RCTTypeSafety (= 0.63.4)
|
||||
- React-Core/RCTSettingsHeaders (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- ReactCommon/turbomodule/core (= 0.63.4)
|
||||
- React-RCTText (0.63.4):
|
||||
- React-Core/RCTTextHeaders (= 0.63.4)
|
||||
- React-RCTVibration (0.63.4):
|
||||
- FBReactNativeSpec (= 0.63.4)
|
||||
- Folly (= 2020.01.13.00)
|
||||
- React-Core/RCTVibrationHeaders (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- ReactCommon/turbomodule/core (= 0.63.2)
|
||||
- ReactCommon/turbomodule/core (0.63.2):
|
||||
- React-Core/RCTVibrationHeaders (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- ReactCommon/turbomodule/core (= 0.63.4)
|
||||
- ReactCommon/turbomodule/core (0.63.4):
|
||||
- DoubleConversion
|
||||
- Folly (= 2020.01.13.00)
|
||||
- glog
|
||||
- React-callinvoker (= 0.63.2)
|
||||
- React-Core (= 0.63.2)
|
||||
- React-cxxreact (= 0.63.2)
|
||||
- React-jsi (= 0.63.2)
|
||||
- RNCAsyncStorage (1.13.0):
|
||||
- React-callinvoker (= 0.63.4)
|
||||
- React-Core (= 0.63.4)
|
||||
- React-cxxreact (= 0.63.4)
|
||||
- React-jsi (= 0.63.4)
|
||||
- RNCAsyncStorage (1.15.5):
|
||||
- React-Core
|
||||
- RNCMaskedView (0.1.11):
|
||||
- React
|
||||
- RNCMaskedView (0.1.10):
|
||||
- React
|
||||
- RNGestureHandler (1.7.0):
|
||||
- React
|
||||
- RNI18n (2.0.15):
|
||||
- React
|
||||
- RNReanimated (1.10.2):
|
||||
- React
|
||||
- RNScreens (2.10.1):
|
||||
- React
|
||||
- RNVectorIcons (7.0.0):
|
||||
- RNGestureHandler (1.10.3):
|
||||
- React-Core
|
||||
- RNLocalize (2.1.1):
|
||||
- React-Core
|
||||
- RNScreens (3.4.0):
|
||||
- React-Core
|
||||
- React-RCTImage
|
||||
- RNVectorIcons (7.1.0):
|
||||
- React
|
||||
- Yoga (1.14.0)
|
||||
- YogaKit (1.18.1):
|
||||
|
@ -327,25 +335,25 @@ DEPENDENCIES:
|
|||
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
||||
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
|
||||
- FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`)
|
||||
- Flipper (~> 0.41.1)
|
||||
- Flipper (= 0.87.0)
|
||||
- Flipper-DoubleConversion (= 1.1.7)
|
||||
- Flipper-Folly (~> 2.2)
|
||||
- Flipper-Folly (= 2.5.3)
|
||||
- Flipper-Glog (= 0.3.6)
|
||||
- Flipper-PeerTalk (~> 0.0.4)
|
||||
- Flipper-RSocket (~> 1.1)
|
||||
- FlipperKit (~> 0.41.1)
|
||||
- FlipperKit/Core (~> 0.41.1)
|
||||
- FlipperKit/CppBridge (~> 0.41.1)
|
||||
- FlipperKit/FBCxxFollyDynamicConvert (~> 0.41.1)
|
||||
- FlipperKit/FBDefines (~> 0.41.1)
|
||||
- FlipperKit/FKPortForwarding (~> 0.41.1)
|
||||
- FlipperKit/FlipperKitHighlightOverlay (~> 0.41.1)
|
||||
- FlipperKit/FlipperKitLayoutPlugin (~> 0.41.1)
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable (~> 0.41.1)
|
||||
- FlipperKit/FlipperKitNetworkPlugin (~> 0.41.1)
|
||||
- FlipperKit/FlipperKitReactPlugin (~> 0.41.1)
|
||||
- FlipperKit/FlipperKitUserDefaultsPlugin (~> 0.41.1)
|
||||
- FlipperKit/SKIOSNetworkPlugin (~> 0.41.1)
|
||||
- Flipper-RSocket (= 1.3.1)
|
||||
- FlipperKit (= 0.87.0)
|
||||
- FlipperKit/Core (= 0.87.0)
|
||||
- FlipperKit/CppBridge (= 0.87.0)
|
||||
- FlipperKit/FBCxxFollyDynamicConvert (= 0.87.0)
|
||||
- FlipperKit/FBDefines (= 0.87.0)
|
||||
- FlipperKit/FKPortForwarding (= 0.87.0)
|
||||
- FlipperKit/FlipperKitHighlightOverlay (= 0.87.0)
|
||||
- FlipperKit/FlipperKitLayoutPlugin (= 0.87.0)
|
||||
- FlipperKit/FlipperKitLayoutTextSearchable (= 0.87.0)
|
||||
- FlipperKit/FlipperKitNetworkPlugin (= 0.87.0)
|
||||
- FlipperKit/FlipperKitReactPlugin (= 0.87.0)
|
||||
- FlipperKit/FlipperKitUserDefaultsPlugin (= 0.87.0)
|
||||
- FlipperKit/SKIOSNetworkPlugin (= 0.87.0)
|
||||
- Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
|
||||
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
|
||||
|
@ -373,11 +381,10 @@ DEPENDENCIES:
|
|||
- React-RCTText (from `../node_modules/react-native/Libraries/Text`)
|
||||
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
|
||||
- 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`)"
|
||||
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
|
||||
- RNI18n (from `../node_modules/react-native-i18n`)
|
||||
- RNReanimated (from `../node_modules/react-native-reanimated`)
|
||||
- RNLocalize (from `../node_modules/react-native-localize`)
|
||||
- RNScreens (from `../node_modules/react-native-screens`)
|
||||
- RNVectorIcons (from `../node_modules/react-native-vector-icons`)
|
||||
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
|
||||
|
@ -386,7 +393,6 @@ SPEC REPOS:
|
|||
trunk:
|
||||
- boost-for-react-native
|
||||
- CocoaAsyncSocket
|
||||
- CocoaLibEvent
|
||||
- Flipper
|
||||
- Flipper-DoubleConversion
|
||||
- Flipper-Folly
|
||||
|
@ -394,6 +400,7 @@ SPEC REPOS:
|
|||
- Flipper-PeerTalk
|
||||
- Flipper-RSocket
|
||||
- FlipperKit
|
||||
- libevent
|
||||
- OpenSSL-Universal
|
||||
- YogaKit
|
||||
|
||||
|
@ -457,15 +464,13 @@ EXTERNAL SOURCES:
|
|||
ReactCommon:
|
||||
:path: "../node_modules/react-native/ReactCommon"
|
||||
RNCAsyncStorage:
|
||||
:path: "../node_modules/@react-native-community/async-storage"
|
||||
:path: "../node_modules/@react-native-async-storage/async-storage"
|
||||
RNCMaskedView:
|
||||
:path: "../node_modules/@react-native-community/masked-view"
|
||||
RNGestureHandler:
|
||||
:path: "../node_modules/react-native-gesture-handler"
|
||||
RNI18n:
|
||||
:path: "../node_modules/react-native-i18n"
|
||||
RNReanimated:
|
||||
:path: "../node_modules/react-native-reanimated"
|
||||
RNLocalize:
|
||||
:path: "../node_modules/react-native-localize"
|
||||
RNScreens:
|
||||
:path: "../node_modules/react-native-screens"
|
||||
RNVectorIcons:
|
||||
|
@ -477,53 +482,52 @@ SPEC CHECKSUMS:
|
|||
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
|
||||
BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872
|
||||
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
||||
CocoaLibEvent: 2fab71b8bd46dd33ddb959f7928ec5909f838e3f
|
||||
DoubleConversion: cde416483dac037923206447da6e1454df403714
|
||||
FBLazyVector: 3ef4a7f62e7db01092f9d517d2ebc0d0677c4a37
|
||||
FBReactNativeSpec: dc7fa9088f0f2a998503a352b0554d69a4391c5a
|
||||
Flipper: 33585e2d9810fe5528346be33bcf71b37bb7ae13
|
||||
FBLazyVector: 3bb422f41b18121b71783a905c10e58606f7dc3e
|
||||
FBReactNativeSpec: f2c97f2529dd79c083355182cc158c9f98f4bd6e
|
||||
Flipper: 1bd2db48dcc31e4b167b9a33ec1df01c2ded4893
|
||||
Flipper-DoubleConversion: 38631e41ef4f9b12861c67d17cb5518d06badc41
|
||||
Flipper-Folly: c12092ea368353b58e992843a990a3225d4533c3
|
||||
Flipper-Folly: 755929a4f851b2fb2c347d533a23f191b008554c
|
||||
Flipper-Glog: 1dfd6abf1e922806c52ceb8701a3599a79a200a6
|
||||
Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9
|
||||
Flipper-RSocket: 64e7431a55835eb953b0bf984ef3b90ae9fdddd7
|
||||
FlipperKit: bc68102cd4952a258a23c9c1b316c7bec1fecf83
|
||||
Flipper-RSocket: 127954abe8b162fcaf68d2134d34dc2bd7076154
|
||||
FlipperKit: 651f50a42eb95c01b3e89a60996dd6aded529eeb
|
||||
Folly: b73c3869541e86821df3c387eb0af5f65addfab4
|
||||
glog: 40a13f7840415b9a77023fbcae0f1e6f43192af3
|
||||
OpenSSL-Universal: 8b48cc0d10c1b2923617dfe5c178aa9ed2689355
|
||||
RCTRequired: f13f25e7b12f925f1f6a6a8c69d929a03c0129fe
|
||||
RCTTypeSafety: 44982c5c8e43ff4141eb519a8ddc88059acd1f3a
|
||||
React: e1c65dd41cb9db13b99f24608e47dd595f28ca9a
|
||||
React-callinvoker: 552a6a6bc8b3bb794cf108ad59e5a9e2e3b4fc98
|
||||
React-Core: 9d341e725dc9cd2f49e4c49ad1fc4e8776aa2639
|
||||
React-CoreModules: 5335e168165da7f7083ce7147768d36d3e292318
|
||||
React-cxxreact: d3261ec5f7d11743fbf21e263a34ea51d1f13ebc
|
||||
React-jsi: 54245e1d5f4b690dec614a73a3795964eeef13a8
|
||||
React-jsiexecutor: 8ca588cc921e70590820ce72b8789b02c67cce38
|
||||
React-jsinspector: b14e62ebe7a66e9231e9581279909f2fc3db6606
|
||||
react-native-safe-area-context: 0ed9288ed4409beabb0817b54efc047286fc84da
|
||||
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
|
||||
OpenSSL-Universal: 1aa4f6a6ee7256b83db99ec1ccdaa80d10f9af9b
|
||||
RCTRequired: 082f10cd3f905d6c124597fd1c14f6f2655ff65e
|
||||
RCTTypeSafety: 8c9c544ecbf20337d069e4ae7fd9a377aadf504b
|
||||
React: b0a957a2c44da4113b0c4c9853d8387f8e64e615
|
||||
React-callinvoker: c3f44dd3cb195b6aa46621fff95ded79d59043fe
|
||||
React-Core: d3b2a1ac9a2c13c3bcde712d9281fc1c8a5b315b
|
||||
React-CoreModules: 0581ff36cb797da0943d424f69e7098e43e9be60
|
||||
React-cxxreact: c1480d4fda5720086c90df537ee7d285d4c57ac3
|
||||
React-jsi: a0418934cf48f25b485631deb27c64dc40fb4c31
|
||||
React-jsiexecutor: 93bd528844ad21dc07aab1c67cb10abae6df6949
|
||||
React-jsinspector: 58aef7155bc9a9683f5b60b35eccea8722a4f53a
|
||||
react-native-safe-area-context: f0906bf8bc9835ac9a9d3f97e8bde2a997d8da79
|
||||
react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865
|
||||
react-native-webview: b2542d6fd424bcc3e3b2ec5f854f0abb4ec86c87
|
||||
React-RCTActionSheet: 910163b6b09685a35c4ebbc52b66d1bfbbe39fc5
|
||||
React-RCTAnimation: 9a883bbe1e9d2e158d4fb53765ed64c8dc2200c6
|
||||
React-RCTBlob: 39cf0ece1927996c4466510e25d2105f67010e13
|
||||
React-RCTImage: de355d738727b09ad3692f2a979affbd54b5f378
|
||||
React-RCTLinking: 8122f221d395a63364b2c0078ce284214bd04575
|
||||
React-RCTNetwork: 8f96c7b49ea6a0f28f98258f347b6ad218bc0830
|
||||
React-RCTSettings: 8a49622aff9c1925f5455fa340b6fe4853d64ab6
|
||||
React-RCTText: 1b6773e776e4b33f90468c20fe3b16ca3e224bb8
|
||||
React-RCTVibration: 4d2e726957f4087449739b595f107c0d4b6c2d2d
|
||||
ReactCommon: a0a1edbebcac5e91338371b72ffc66aa822792ce
|
||||
RNCAsyncStorage: b34c5db7bd4b2ef9a7ced5b59b1e6a0c5c6eb24e
|
||||
RNCMaskedView: f5c7d14d6847b7b44853f7acb6284c1da30a3459
|
||||
RNGestureHandler: b6b359bb800ae399a9c8b27032bdbf7c18f08a08
|
||||
RNI18n: e2f7e76389fcc6e84f2c8733ea89b92502351fd8
|
||||
RNReanimated: 7de2dca51deacff78bb880f63c1389a24311b376
|
||||
RNScreens: b748efec66e095134c7166ca333b628cd7e6f3e2
|
||||
RNVectorIcons: da6fe858f5a65d7bbc3379540a889b0b12aa5976
|
||||
Yoga: 7740b94929bbacbddda59bf115b5317e9a161598
|
||||
react-native-webview: 1a19adb5578cdf7f005b7961dcc50c1c6b70f41b
|
||||
React-RCTActionSheet: 89a0ca9f4a06c1f93c26067af074ccdce0f40336
|
||||
React-RCTAnimation: 1bde3ecc0c104c55df246eda516e0deb03c4e49b
|
||||
React-RCTBlob: a97d378b527740cc667e03ebfa183a75231ab0f0
|
||||
React-RCTImage: c1b1f2d3f43a4a528c8946d6092384b5c880d2f0
|
||||
React-RCTLinking: 35ae4ab9dc0410d1fcbdce4d7623194a27214fb2
|
||||
React-RCTNetwork: 29ec2696f8d8cfff7331fac83d3e893c95ef43ae
|
||||
React-RCTSettings: 60f0691bba2074ef394f95d4c2265ec284e0a46a
|
||||
React-RCTText: 5c51df3f08cb9dedc6e790161195d12bac06101c
|
||||
React-RCTVibration: ae4f914cfe8de7d4de95ae1ea6cc8f6315d73d9d
|
||||
ReactCommon: 73d79c7039f473b76db6ff7c6b159c478acbbb3b
|
||||
RNCAsyncStorage: 56a3355a10b5d660c48c6e37325ac85ebfd09885
|
||||
RNCMaskedView: 0e1bc4bfa8365eba5fbbb71e07fbdc0555249489
|
||||
RNGestureHandler: a479ebd5ed4221a810967000735517df0d2db211
|
||||
RNLocalize: 82a569022724d35461e2dc5b5d015a13c3ca995b
|
||||
RNScreens: 21b73c94c9117e1110a79ee0ee80c93ccefed8ce
|
||||
RNVectorIcons: bc69e6a278b14842063605de32bec61f0b251a59
|
||||
Yoga: 4bd86afe9883422a7c4028c00e34790f560923d6
|
||||
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
|
||||
|
||||
PODFILE CHECKSUM: 06472af1eb4acd0770fd4d29e23ee525801f7cd1
|
||||
PODFILE CHECKSUM: 685f7c9567d158eb76c7fbd85c7248da2f22d7c8
|
||||
|
||||
COCOAPODS: 1.9.3
|
||||
COCOAPODS: 1.10.1
|
||||
|
|
|
@ -249,6 +249,7 @@
|
|||
00E356EB1AD99517003FC87E /* Frameworks */,
|
||||
00E356EC1AD99517003FC87E /* Resources */,
|
||||
7BC6AD0A9D3DE575F2E558E1 /* [CP] Copy Pods Resources */,
|
||||
8EEC6804BF6C2BF286A5F7D9 /* [CP] Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
|
@ -271,6 +272,7 @@
|
|||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
|
||||
D2DD3F2F99A693C12757405F /* [CP] Copy Pods Resources */,
|
||||
2E1AEAA3F8B118A5A91DE143 /* [CP] Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
|
@ -326,7 +328,7 @@
|
|||
83CBB9F71A601CBA00E9B192 /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 1130;
|
||||
LastUpgradeCheck = 1240;
|
||||
TargetAttributes = {
|
||||
00E356ED1AD99517003FC87E = {
|
||||
CreatedOnToolsVersion = 6.2;
|
||||
|
@ -474,6 +476,24 @@
|
|||
shellPath = /bin/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 */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -524,6 +544,24 @@
|
|||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-blazerapp-blazerappTests/Pods-blazerapp-blazerappTests-resources.sh\"\n";
|
||||
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 */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -719,7 +757,7 @@
|
|||
"$(inherited)",
|
||||
);
|
||||
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";
|
||||
OTHER_LDFLAGS = (
|
||||
"-ObjC",
|
||||
|
@ -739,7 +777,7 @@
|
|||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
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";
|
||||
OTHER_LDFLAGS = (
|
||||
"-ObjC",
|
||||
|
@ -761,7 +799,7 @@
|
|||
CURRENT_PROJECT_VERSION = 1;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = blazerapp/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
|
@ -784,7 +822,7 @@
|
|||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
INFOPLIST_FILE = blazerapp/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
OTHER_LDFLAGS = (
|
||||
"$(inherited)",
|
||||
|
@ -822,7 +860,7 @@
|
|||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = appletvos;
|
||||
TARGETED_DEVICE_FAMILY = 3;
|
||||
TVOS_DEPLOYMENT_TARGET = 11.0;
|
||||
TVOS_DEPLOYMENT_TARGET = 12.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
|
@ -850,7 +888,7 @@
|
|||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = appletvos;
|
||||
TARGETED_DEVICE_FAMILY = 3;
|
||||
TVOS_DEPLOYMENT_TARGET = 11.0;
|
||||
TVOS_DEPLOYMENT_TARGET = 12.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
@ -877,7 +915,7 @@
|
|||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = appletvos;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/blazerapp-tvOS.app/blazerapp-tvOS";
|
||||
TVOS_DEPLOYMENT_TARGET = 10.1;
|
||||
TVOS_DEPLOYMENT_TARGET = 12.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
|
@ -904,7 +942,7 @@
|
|||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = appletvos;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/blazerapp-tvOS.app/blazerapp-tvOS";
|
||||
TVOS_DEPLOYMENT_TARGET = 10.1;
|
||||
TVOS_DEPLOYMENT_TARGET = 12.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
@ -931,6 +969,7 @@
|
|||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
|
@ -955,7 +994,7 @@
|
|||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
|
||||
|
@ -991,6 +1030,7 @@
|
|||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
|
@ -1008,7 +1048,7 @@
|
|||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "/usr/lib/swift $(inherited)";
|
||||
LIBRARY_SEARCH_PATHS = (
|
||||
"\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1130"
|
||||
LastUpgradeVersion = "1250"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1130"
|
||||
LastUpgradeVersion = "1250"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
|
|
@ -2,37 +2,52 @@
|
|||
"images" : [
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "2x"
|
||||
"scale" : "2x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "29x29",
|
||||
"scale" : "3x"
|
||||
"scale" : "3x",
|
||||
"size" : "20x20"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "2x"
|
||||
"scale" : "2x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "40x40",
|
||||
"scale" : "3x"
|
||||
"scale" : "3x",
|
||||
"size" : "29x29"
|
||||
},
|
||||
{
|
||||
"idiom" : "iphone",
|
||||
"size" : "60x60",
|
||||
"scale" : "2x"
|
||||
"scale" : "2x",
|
||||
"size" : "40x40"
|
||||
},
|
||||
{
|
||||
"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" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
26261
package-lock.json
generated
22
package.json
|
@ -11,27 +11,27 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@k3rn31p4nic/google-translate-api": "github:k3rn31p4nic/google-translate-api",
|
||||
"@react-native-community/async-storage": "github:react-native-community/async-storage",
|
||||
"@react-native-community/masked-view": "^0.1.10",
|
||||
"@react-native-async-storage/async-storage": "^1.15.5",
|
||||
"@react-native-community/masked-view": "^0.1.11",
|
||||
"@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",
|
||||
"@vitalets/google-translate-api": "^4.0.0",
|
||||
"events": "^3.2.0",
|
||||
"i18next": "^19.8.4",
|
||||
"i18next-react-native-language-detector": "^1.0.2",
|
||||
"i18n-js": "^3.8.0",
|
||||
"i18next": "^20.3.3",
|
||||
"lodash.memoize": "^4.1.2",
|
||||
"querystring": "^0.2.0",
|
||||
"react": "16.13.1",
|
||||
"react-i18next": "^11.8.5",
|
||||
"react-i18next": "^11.11.3",
|
||||
"react-native": "^0.63.2",
|
||||
"react-native-elements": "^2.2.0",
|
||||
"react-native-gesture-handler": "^1.7.0",
|
||||
"react-native-i18n": "^2.0.15",
|
||||
"react-native-gesture-handler": "^1.10.3",
|
||||
"react-native-linear-gradient": "^2.5.6",
|
||||
"react-native-locale-detector": "^1.0.1",
|
||||
"react-native-reanimated": "^1.10.2",
|
||||
"react-native-safe-area-context": "^3.1.4",
|
||||
"react-native-screens": "^2.10.1",
|
||||
"react-native-localize": "^2.1.1",
|
||||
"react-native-safe-area-context": "^3.2.0",
|
||||
"react-native-screens": "^3.4.0",
|
||||
"react-native-splash-screen": "^3.2.0",
|
||||
"react-native-vector-icons": "^7.0.0",
|
||||
"react-native-webview": "^11.0.2",
|
||||
|
|
2
rustfmt.toml
Normal file
|
@ -0,0 +1,2 @@
|
|||
imports_granularity="Crate"
|
||||
reorder_imports = true
|