Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Task 8 #32

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12,851 changes: 12,851 additions & 0 deletions MobileApp/package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions MobileApp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"preset": "jest-expo"
},
"dependencies": {
"base64-arraybuffer": "^0.1.5",
"email-validator": "^2.0.4",
"expo": "^27.0.1",
"firebase": "^5.3.0",
Expand Down
4 changes: 4 additions & 0 deletions MobileApp/src/components/app-navigator.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import EventList from './screens/event-list'
import PeopleList from './screens/people-list'
import EventScreen from './screens/event'
import EventMapScreen from './screens/event-map'
import CameraScreen from './screens/camera'

const ListsNavigator = createBottomTabNavigator({
events: {
Expand All @@ -24,5 +25,8 @@ export default createStackNavigator({
},
event: {
screen: EventMapScreen
},
camera: {
screen: CameraScreen
}
})
90 changes: 90 additions & 0 deletions MobileApp/src/components/common/camera.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React from 'react'
import { Text, View, TouchableOpacity, StyleSheet } from 'react-native'
import { Camera, Permissions } from 'expo'
import {inject} from 'mobx-react'

@inject('people')
export default class CameraExample extends React.Component {
state = {
hasCameraPermission: null,
type: Camera.Constants.Type.back,
}

async componentWillMount() {
const { status } = await Permissions.askAsync(Permissions.CAMERA)
this.setState({ hasCameraPermission: status === 'granted' })
}

flipCamera = () => {
this.setState({
type: this.state.type === Camera.Constants.Type.back
? Camera.Constants.Type.front
: Camera.Constants.Type.back,
})
}

takePicture = async () => {
if (this.camera) {
let photo = await this.camera.takePictureAsync({base64: true})
await this.props.people.updateAvatar(photo.base64, this.props.uid)

this.props.goBack()
}
}

render() {
const { hasCameraPermission } = this.state

if (hasCameraPermission === null) {
return <View />
} else if (hasCameraPermission === false) {
return <Text>No access to camera</Text>
} else {
return (
<View style={{ flex: 1 }}>
<Camera style={styles.camera} type={this.state.type} ref={ref => { this.camera = ref }}>
<View style={styles.textContainer}>
<TouchableOpacity style={styles.flip} onPress={this.flipCamera}>
<Text style={styles.flipText}>
{' '}Flip{' '}
</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={this.takePicture} />
</View>
</Camera>
</View>
)
}
}
}

const styles = StyleSheet.create({
textContainer: {
backgroundColor: 'rgba(255, 255, 255, 0.3)',
flexDirection: 'row',
height: 100,
width: '100%',
justifyContent: 'space-around',
alignItems: 'center'
},
flip: {
flex: 0.1,
alignItems: 'center'
},
flipText: {
fontSize: 18,
marginBottom: 10,
color: 'white'
},
button: {
height: 60,
width: 60,
borderRadius: 100,
backgroundColor: 'red'
},
camera: {
flex: 1,
alignItems: 'flex-end',
justifyContent: 'flex-end'
}
})
10 changes: 7 additions & 3 deletions MobileApp/src/components/people/people-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { Component } from 'react'
import {inject, observer} from 'mobx-react'
import {TouchableOpacity, Text, SectionList, ActivityIndicator, StyleSheet} from 'react-native'
import PersonCard from './person-card'
import { action } from 'mobx'

@inject('people')
@observer
Expand All @@ -22,9 +23,12 @@ class PeopleList extends Component {
return <SectionList
sections = {people.sections}
renderSectionHeader = {({section}) => <Text style={styles.header}>{section.title}</Text>}
renderItem = {({item}) => <TouchableOpacity onPress = {onPersonPress.bind(null, item.key)}>
<PersonCard person = {item.person} />
</TouchableOpacity>}
renderItem = {({item}) => (
<TouchableOpacity
onPress = {onPersonPress.bind(null, item.key)}>
<PersonCard person = {item.person} />
</TouchableOpacity>
)}
/>
}
}
Expand Down
26 changes: 17 additions & 9 deletions MobileApp/src/components/people/person-card.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,32 @@
import React, { Component } from 'react'
import {View, Text, Image, StyleSheet} from 'react-native'
import {View, Text, Image, StyleSheet, TouchableHighlight } from 'react-native'
import Card from '../common/card'
import {inject} from 'mobx-react'

@inject('navigation')
class PersonCard extends Component {
static propTypes = {

};

render() {
const { email, firstName, lastName } = this.props.person
const { email, firstName, lastName, uid, avatar } = this.props.person
return (
<Card style = {styles.container}>
<Image source={{uri: 'http://lorempixel.com/200/100/people/'}} style = {styles.avatar}/>
<View style = {styles.content}>
<Text style = {styles.email}>{email}</Text>
<Text>{firstName} {lastName}</Text>
</View>
</Card>
<TouchableHighlight onLongPress={this.openCamera.bind(null, uid)}>
<Card style = {styles.container}>
<Image source={{uri: avatar || 'http://lorempixel.com/200/100/people/'}} style = {styles.avatar}/>
<View style = {styles.content}>
<Text style = {styles.email}>{email}</Text>
<Text>{firstName} {lastName}</Text>
</View>
</Card>
</TouchableHighlight>
)
}

openCamera = (uid) => {
this.props.navigation.goTo('camera', { uid })
}
}

const styles = StyleSheet.create({
Expand Down
16 changes: 16 additions & 0 deletions MobileApp/src/components/screens/camera.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React, { Component } from 'react'
import Camera from '../common/camera'

class AuthScreen extends Component {
static navigationOptions = {
title: 'camera'
}

render() {
return (
<Camera uid={this.props.navigation.state.params.uid} goBack={this.props.navigation.goBack} />
)
}
}

export default AuthScreen
9 changes: 5 additions & 4 deletions MobileApp/src/config.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import { initializeApp } from 'firebase/app'
import 'firebase/auth'
import 'firebase/database'
import 'firebase/storage'

export const appName = 'adv-react-25-06'
export const appName = 'advreact-25-06-c6bae'

const config = {
apiKey: 'AIzaSyDzqwnZ_39QyqhxYZVPjVH8eBww7DUBmVc',
apiKey: "AIzaSyBM5eZETRfWWS9BoQ-8guawlYzeW7dDToE",
authDomain: `${appName}.firebaseapp.com`,
databaseURL: `https://${appName}.firebaseio.com`,
projectId: appName,
storageBucket: '',
messagingSenderId: '874599443389'
storageBucket: `gs://${appName}.appspot.com`,
messagingSenderId: '985221034928'
}

initializeApp(config)
31 changes: 17 additions & 14 deletions MobileApp/src/stores/navigation.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,28 @@ class NavigationStore extends BasicStore {
onReady = () => {
let firstRun = true

setTimeout(() => {
autorun(() => {
const authenticated = !!this.getStore('auth').user
autorun(() => {
const authenticated = !!this.getStore('auth').user

if (!firstRun) {
authenticated
? this.reset('lists')
: this.reset('auth')
}
if (!firstRun) {
authenticated
? this.reset('lists')
: this.reset('auth')
}

firstRun = false
})
}, 0 )
firstRun = false
})

}

goTo = routeName => this.ref.dispatch(NavigationActions.navigate({
routeName
}))
goTo = (routeName, params) => {
this.ref.dispatch(NavigationActions.navigate({
routeName,
params: {
...params
}
}))
}

reset = routeName => this.ref.dispatch(StackActions.reset({
index: 0,
Expand Down
23 changes: 23 additions & 0 deletions MobileApp/src/stores/people.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import EntitiesStore, {loadAllHelper} from './entities-store'
import {computed, action} from 'mobx'
import groupBy from 'lodash/groupBy'
import firebase from 'firebase/app'
import { decode } from 'base64-arraybuffer'

class PeopleStore extends EntitiesStore {
@computed get sections() {
Expand All @@ -13,6 +15,27 @@ class PeopleStore extends EntitiesStore {
}

@action loadAll = loadAllHelper('people')

@action updateAvatarUrl = (avatarUrl, uid) => {
firebase.database().ref(`people/${uid}`).update({
avatar: avatarUrl
})
}

@action updateAvatar = async (base64, uid) => {
const avatarRef = firebase.storage().ref(`/avatars/${uid}.jpg`)
const bytes = decode(base64)

await avatarRef.put(bytes)
avatarUrl = await avatarRef.getDownloadURL()
/*
почему-то генерируется URL такой картинки, которую не могу открыть при скачивании
картинка также не отображается в приложении.. не пойму почему,
т.к. когда пробую декодировать передаваемый base64 вручную (через онлайн сервис),
сервис мне возвращает корректное изображение
*/
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Странно, похоже на вполне рабочий код, может что-то в апи поменяли. Но в остальном все ок

this.updateAvatarUrl(avatarUrl, uid)
}
}

export default PeopleStore
6 changes: 6 additions & 0 deletions MobileApp/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"compilerOptions": {
"experimentalDecorators": true,
"allowJs": true
}
}