Skip to content

Commit a8a5614

Browse files
committed
Add Utils
1 parent 00655e9 commit a8a5614

File tree

9 files changed

+1754
-111
lines changed

9 files changed

+1754
-111
lines changed

.expo/packager-info.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"expoServerPort": 19000,
3+
"webpackServerPort": null,
4+
"expoServerNgrokUrl": "https://bx-3m7.anonymous.flashcards-react-native.exp.direct",
5+
"packagerNgrokUrl": "https://packager.bx-3m7.anonymous.flashcards-react-native.exp.direct",
6+
"ngrokPid": 8199,
7+
"devToolsPort": 19002,
8+
"packagerPort": 19001,
9+
"packagerPid": 8179
10+
}

.expo/settings.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"hostType": "lan",
3+
"lanType": "ip",
4+
"dev": true,
5+
"minify": false,
6+
"urlRandomness": "bx-3m7"
7+
}

App.js

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
1-
import React from 'react';
2-
import { StyleSheet, Text, View } from 'react-native';
1+
import React from 'react'
2+
import { View } from 'react-native'
3+
import { createStore } from 'redux'
4+
import { Provider } from 'react-redux'
5+
import reducer from './redux/reducers'
6+
7+
import MainNavigator from './components/MainNavigator'
8+
9+
import { setLocalNotification } from './utils/helpers'
310

411
export default class App extends React.Component {
12+
componentDidMount() {
13+
setLocalNotification()
14+
}
15+
516
render() {
617
return (
7-
<View style={styles.container}>
8-
<Text>Open up App.js to start working on your app!</Text>
9-
</View>
10-
);
18+
<Provider store={createStore(reducer)}>
19+
<View style={{ flex: 1 }}>
20+
<MainNavigator />
21+
</View>
22+
</Provider>
23+
)
1124
}
12-
}
13-
14-
const styles = StyleSheet.create({
15-
container: {
16-
flex: 1,
17-
backgroundColor: '#fff',
18-
alignItems: 'center',
19-
justifyContent: 'center',
20-
},
21-
});
25+
}

package.json

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,25 @@
44
"start": "expo start",
55
"android": "expo start --android",
66
"ios": "expo start --ios",
7-
"eject": "expo eject"
7+
"eject": "expo eject",
8+
"test": "jest"
9+
},
10+
"jest": {
11+
"preset": "jest-expo"
812
},
913
"dependencies": {
1014
"expo": "^32.0.0",
1115
"react": "16.5.0",
1216
"react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",
13-
"react-navigation": "^3.6.1",
17+
"react-navigation": "^2.12.1",
1418
"react-redux": "^6.0.1",
1519
"redux": "^4.0.1"
1620
},
1721
"devDependencies": {
18-
"babel-preset-expo": "^5.0.0"
22+
"babel-preset-expo": "^5.0.0",
23+
"jest-expo": "^32.0.0",
24+
"react-native-scripts": "^2.0.1",
25+
"react-test-renderer": "^16.8.6"
1926
},
2027
"private": true
2128
}

utils/_data.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { AsyncStorage } from 'react-native'
2+
3+
export const DEBUG_CLEAR_STORAGE = false
4+
export const DECKS_STORAGE_KEY = 'FlashCards:decks'
5+
6+
export function setDummyData() {
7+
let dummyData = {
8+
React: {
9+
key: 'React',
10+
title: 'React',
11+
questions: [
12+
{
13+
question: 'Does React Native work with Android',
14+
answer: 'Yes!'
15+
},
16+
{
17+
question: 'What is a component?',
18+
answer: 'Components let you split the UI into independent, reusable pieces of code'
19+
},
20+
{
21+
question: 'What is React?',
22+
answer: 'A library for managing user interfaces'
23+
},
24+
{
25+
question: 'Where do you make Ajax requests in React?',
26+
answer: 'The componentDidMount lifecycle event'
27+
}
28+
]
29+
},
30+
JavaScript: {
31+
key: 'JavaScript',
32+
title: 'JavaScript',
33+
questions: [
34+
{
35+
question: 'What is a closure?',
36+
answer: 'The combination of a function and the lexical environment within which that function was declared.'
37+
}
38+
]
39+
}
40+
}
41+
42+
AsyncStorage.setItem(DECKS_STORAGE_KEY, JSON.stringify(dummyData))
43+
44+
return dummyData
45+
}

utils/api.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { AsyncStorage } from 'react-native'
2+
import { DECKS_STORAGE_KEY, DEBUG_CLEAR_STORAGE, setDummyData } from './_data'
3+
4+
export function fetchDecks() {
5+
return AsyncStorage.getItem(DECKS_STORAGE_KEY)
6+
.then(getAllDecks)
7+
}
8+
9+
function getAllDecks(decks) {
10+
if (DEBUG_CLEAR_STORAGE) {
11+
console.log("Cleaning up storage")
12+
AsyncStorage.removeItem(DECKS_STORAGE_KEY)
13+
decks = null
14+
}
15+
16+
if (decks === null && __DEV__) {
17+
console.log("Populate DB with dummy data")
18+
return setDummyData()
19+
} else {
20+
return JSON.parse(decks)
21+
}
22+
}

utils/colors.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export const primaryColor = '#8e24aa'
2+
export const primaryLightColor = '#c158dc'
3+
export const primaryDarkColor = '#5c007a'
4+
export const primaryTextColor = '#ffffff'
5+
export const gray = 'gray'
6+
export const white = '#ffffff'

utils/helpers.js

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { Notifications, Permissions } from 'expo'
2+
import { AsyncStorage } from 'react-native'
3+
4+
const NOTIFICATION_KEY = 'FlashCard:notifications'
5+
6+
export function isEmpty(obj) {
7+
//Source: https://stackoverflow.com/a/4994244/2848021
8+
9+
// null and undefined are "empty"
10+
if (obj == null) return true;
11+
12+
// Assume if it has a length property with a non-zero value
13+
// that that property is correct.
14+
if (obj.length > 0) return false;
15+
if (obj.length === 0) return true;
16+
17+
// If it isn't an object at this point
18+
// it is empty, but it can't be anything *but* empty
19+
// Is it empty? Depends on your application.
20+
if (typeof obj !== "object") return true;
21+
22+
// Otherwise, does it have any properties of its own?
23+
// Note that this doesn't handle
24+
// toString and valueOf enumeration bugs in IE < 9
25+
for (var key in obj) {
26+
if (hasOwnProperty.call(obj, key)) return false;
27+
}
28+
29+
return true;
30+
}
31+
32+
export function clearLocalNotification() {
33+
return AsyncStorage.removeItem(NOTIFICATION_KEY)
34+
.then(Notifications.cancelAllScheduledNotificationsAsync)
35+
}
36+
37+
function createNotification() {
38+
return {
39+
title: 'Time to Study!',
40+
body: "Don't forget to try some Quiz today!",
41+
ios: {
42+
sound: true,
43+
},
44+
android: {
45+
sound: true,
46+
priority: 'high',
47+
sticky: false,
48+
vibrate: true,
49+
}
50+
}
51+
}
52+
53+
export function setLocalNotification() {
54+
AsyncStorage.getItem(NOTIFICATION_KEY)
55+
.then(JSON.parse)
56+
.then((data) => {
57+
if (data === null) {
58+
Permissions.askAsync(Permissions.NOTIFICATIONS)
59+
.then(({ status }) => {
60+
if (status === 'granted') {
61+
Notifications.cancelAllScheduledNotificationsAsync()
62+
63+
let tomorrow = new Date()
64+
tomorrow.setDate(tomorrow.getDate() + 1)
65+
tomorrow.setHours(20)
66+
tomorrow.setMinutes(0)
67+
68+
Notifications.scheduleLocalNotificationAsync(
69+
createNotification(),
70+
{
71+
time: tomorrow,
72+
repeat: 'day',
73+
}
74+
)
75+
76+
AsyncStorage.setItem(NOTIFICATION_KEY, JSON.stringify(true))
77+
}
78+
})
79+
}
80+
})
81+
}

0 commit comments

Comments
 (0)