format js code with eslint

This commit is contained in:
Kesha Antonov
2021-12-05 21:27:10 +03:00
parent 2ededc9694
commit d157726679
10 changed files with 4404 additions and 2164 deletions

82
.eslintrc.js Normal file
View File

@@ -0,0 +1,82 @@
module.exports = {
env: {
es2020: true,
jest: true,
},
parser: '@babel/eslint-parser',
extends: [
'standard',
'eslint:recommended',
'plugin:react/recommended',
'plugin:react-hooks/recommended',
],
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 11,
sourceType: 'module',
},
plugins: [
'react',
'react-hooks',
],
settings: {
react: {
version: 'detect',
},
},
rules: {
indent: [
'error',
2, {
SwitchCase: 1,
ignoredNodes: [
'TemplateLiteral',
],
},
],
'template-curly-spacing': 'off',
'linebreak-style': [
'error',
'unix',
],
quotes: [
'error',
'single',
],
semi: [
'error',
'never',
],
'comma-dangle': [
'error',
{
arrays: 'always-multiline',
objects: 'always-multiline',
imports: 'always-multiline',
exports: 'never',
functions: 'never',
},
],
'no-func-assign': 'off',
'no-class-assign': 'off',
'no-useless-escape': 'off',
curly: [2, 'multi', 'consistent'],
'react/prop-types': 'off', // TODO: TURN ON AND FIX ALL WARNINGS
'react/display-name': 'off',
},
globals: {
describe: 'readonly',
test: 'readonly',
jest: 'readonly',
expect: 'readonly',
fetch: 'readonly',
navigator: 'readonly',
__DEV__: 'readonly',
XMLHttpRequest: 'readonly',
FormData: 'readonly',
React$Element: 'readonly',
requestAnimationFrame: 'readonly',
},
}

View File

@@ -29,19 +29,22 @@ test('download function', () => {
}); });
test('begin event', () => { test('begin event', () => {
const mockedHeaders = { Etag: '123' }
return new Promise(resolve => { return new Promise(resolve => {
const beginDT = RNBackgroundDownloader.download({ const beginDT = RNBackgroundDownloader.download({
id: 'testBegin', id: 'testBegin',
url: 'test', url: 'test',
destination: 'test' destination: 'test'
}).begin((expectedBytes) => { }).begin(({ expectedBytes, headers }) => {
expect(expectedBytes).toBe(9001); expect(expectedBytes).toBe(9001);
expect(headers).toBe(mockedHeaders);
expect(beginDT.state).toBe('DOWNLOADING'); expect(beginDT.state).toBe('DOWNLOADING');
resolve(); resolve();
}); });
NativeEventEmitter.listeners.downloadBegin({ NativeEventEmitter.listeners.downloadBegin({
id: 'testBegin', id: 'testBegin',
expectedBytes: 9001 expectedBytes: 9001,
headers: mockedHeaders,
}); });
}); });
}); });

View File

@@ -1,3 +1,3 @@
module.exports = { module.exports = {
presets: ["module:metro-react-native-babel-preset"] presets: ['module:metro-react-native-babel-preset'],
} }

131
index.js
View File

@@ -1,74 +1,71 @@
import { NativeModules, NativeEventEmitter } from 'react-native'; import { NativeModules, NativeEventEmitter } from 'react-native'
const { RNBackgroundDownloader } = NativeModules; import DownloadTask from './lib/downloadTask'
const RNBackgroundDownloaderEmitter = new NativeEventEmitter(RNBackgroundDownloader); const { RNBackgroundDownloader } = NativeModules
import DownloadTask from './lib/downloadTask'; const RNBackgroundDownloaderEmitter = new NativeEventEmitter(RNBackgroundDownloader)
const tasksMap = new Map(); const tasksMap = new Map()
let headers = {}; let headers = {}
RNBackgroundDownloaderEmitter.addListener('downloadProgress', events => { RNBackgroundDownloaderEmitter.addListener('downloadProgress', events => {
for (let event of events) { for (const event of events) {
let task = tasksMap.get(event.id); const task = tasksMap.get(event.id)
if (task) { if (task)
task._onProgress(event.percent, event.written, event.total); task._onProgress(event.percent, event.written, event.total)
} }
} })
});
RNBackgroundDownloaderEmitter.addListener('downloadComplete', ({ id, location }) => { RNBackgroundDownloaderEmitter.addListener('downloadComplete', ({ id, location }) => {
let task = tasksMap.get(id); const task = tasksMap.get(id)
if (task) { if (task)
task._onDone({ location }); task._onDone({ location })
}
tasksMap.delete(id); tasksMap.delete(id)
}); })
RNBackgroundDownloaderEmitter.addListener('downloadFailed', event => { RNBackgroundDownloaderEmitter.addListener('downloadFailed', event => {
let task = tasksMap.get(event.id); const task = tasksMap.get(event.id)
if (task) { if (task)
task._onError(event.error, event.errorcode); task._onError(event.error, event.errorcode)
}
tasksMap.delete(event.id); tasksMap.delete(event.id)
}); })
RNBackgroundDownloaderEmitter.addListener('downloadBegin', ({ id, expectedBytes, headers }) => { RNBackgroundDownloaderEmitter.addListener('downloadBegin', ({ id, expectedBytes, headers }) => {
let task = tasksMap.get(id); const task = tasksMap.get(id)
if (task) { if (task)
task._onBegin({ expectedBytes, headers }); task._onBegin({ expectedBytes, headers })
} })
});
export function setHeaders (h = {}) { export function setHeaders (h = {}) {
if (typeof h !== 'object') { if (typeof h !== 'object')
throw new Error('[RNBackgroundDownloader] headers must be an object'); throw new Error('[RNBackgroundDownloader] headers must be an object')
}
headers = h; headers = h
} }
export function checkForExistingDownloads () { export function checkForExistingDownloads () {
return RNBackgroundDownloader.checkForExistingDownloads() return RNBackgroundDownloader.checkForExistingDownloads()
.then(foundTasks => { .then(foundTasks => {
return foundTasks.map(taskInfo => { return foundTasks.map(taskInfo => {
let task = new DownloadTask(taskInfo,tasksMap.get(taskInfo.id)); const task = new DownloadTask(taskInfo, tasksMap.get(taskInfo.id))
if (taskInfo.state === RNBackgroundDownloader.TaskRunning) { if (taskInfo.state === RNBackgroundDownloader.TaskRunning) {
task.state = 'DOWNLOADING'; task.state = 'DOWNLOADING'
} else if (taskInfo.state === RNBackgroundDownloader.TaskSuspended) { } else if (taskInfo.state === RNBackgroundDownloader.TaskSuspended) {
task.state = 'PAUSED'; task.state = 'PAUSED'
} else if (taskInfo.state === RNBackgroundDownloader.TaskCanceling) { } else if (taskInfo.state === RNBackgroundDownloader.TaskCanceling) {
task.stop(); task.stop()
return null; return null
} else if (taskInfo.state === RNBackgroundDownloader.TaskCompleted) { } else if (taskInfo.state === RNBackgroundDownloader.TaskCompleted) {
if (taskInfo.bytesWritten === taskInfo.totalBytes) { if (taskInfo.bytesWritten === taskInfo.totalBytes)
task.state = 'DONE'; task.state = 'DONE'
} else { else
// IOS completed the download but it was not done. // IOS completed the download but it was not done.
return null; return null
} }
} tasksMap.set(taskInfo.id, task)
tasksMap.set(taskInfo.id, task); return task
return task; }).filter(task => task !== null)
}).filter(task => task !== null); })
});
} }
export function completeHandler (jobId) { export function completeHandler (jobId) {
@@ -76,37 +73,37 @@ export function completeHandler (jobId) {
} }
export function download (options) { export function download (options) {
if (!options.id || !options.url || !options.destination) { if (!options.id || !options.url || !options.destination)
throw new Error('[RNBackgroundDownloader] id, url and destination are required'); throw new Error('[RNBackgroundDownloader] id, url and destination are required')
}
if (options.headers && typeof options.headers === 'object') { if (options.headers && typeof options.headers === 'object')
options.headers = { options.headers = {
...headers, ...headers,
...options.headers ...options.headers,
};
} else {
options.headers = headers;
} }
RNBackgroundDownloader.download(options); else
let task = new DownloadTask(options.id); options.headers = headers
tasksMap.set(options.id, task);
return task; RNBackgroundDownloader.download(options)
const task = new DownloadTask(options.id)
tasksMap.set(options.id, task)
return task
} }
export const directories = { export const directories = {
documents: RNBackgroundDownloader.documents documents: RNBackgroundDownloader.documents,
}; }
export const Network = { export const Network = {
WIFI_ONLY: RNBackgroundDownloader.OnlyWifi, WIFI_ONLY: RNBackgroundDownloader.OnlyWifi,
ALL: RNBackgroundDownloader.AllNetworks ALL: RNBackgroundDownloader.AllNetworks,
}; }
export const Priority = { export const Priority = {
HIGH: RNBackgroundDownloader.PriorityHigh, HIGH: RNBackgroundDownloader.PriorityHigh,
MEDIUM: RNBackgroundDownloader.PriorityNormal, MEDIUM: RNBackgroundDownloader.PriorityNormal,
LOW: RNBackgroundDownloader.PriorityLow LOW: RNBackgroundDownloader.PriorityLow,
}; }
export default { export default {
download, download,
@@ -115,5 +112,5 @@ export default {
setHeaders, setHeaders,
directories, directories,
Network, Network,
Priority Priority,
}; }

View File

@@ -1,10 +1,9 @@
import { NativeModules } from 'react-native'; import { NativeModules } from 'react-native'
const { RNBackgroundDownloader } = NativeModules; const { RNBackgroundDownloader } = NativeModules
function validateHandler (handler) { function validateHandler (handler) {
if (!(typeof handler === 'function')) { if (!(typeof handler === 'function'))
throw new TypeError(`[RNBackgroundDownloader] expected argument to be a function, got: ${typeof handler}`); throw new TypeError(`[RNBackgroundDownloader] expected argument to be a function, got: ${typeof handler}`)
}
} }
export default class DownloadTask { export default class DownloadTask {
state = 'PENDING' state = 'PENDING'
@@ -14,12 +13,12 @@ export default class DownloadTask {
constructor (taskInfo, originalTask) { constructor (taskInfo, originalTask) {
if (typeof taskInfo === 'string') { if (typeof taskInfo === 'string') {
this.id = taskInfo; this.id = taskInfo
} else { } else {
this.id = taskInfo.id; this.id = taskInfo.id
this.percent = taskInfo.percent; this.percent = taskInfo.percent
this.bytesWritten = taskInfo.bytesWritten; this.bytesWritten = taskInfo.bytesWritten
this.totalBytes = taskInfo.totalBytes; this.totalBytes = taskInfo.totalBytes
} }
if (originalTask) { if (originalTask) {
@@ -31,71 +30,67 @@ export default class DownloadTask {
} }
begin (handler) { begin (handler) {
validateHandler(handler); validateHandler(handler)
this._beginHandler = handler; this._beginHandler = handler
return this; return this
} }
progress (handler) { progress (handler) {
validateHandler(handler); validateHandler(handler)
this._progressHandler = handler; this._progressHandler = handler
return this; return this
} }
done (handler) { done (handler) {
validateHandler(handler); validateHandler(handler)
this._doneHandler = handler; this._doneHandler = handler
return this; return this
} }
error (handler) { error (handler) {
validateHandler(handler); validateHandler(handler)
this._errorHandler = handler; this._errorHandler = handler
return this; return this
} }
_onBegin ({ expectedBytes, headers }) { _onBegin ({ expectedBytes, headers }) {
this.state = 'DOWNLOADING'; this.state = 'DOWNLOADING'
if (this._beginHandler) { if (this._beginHandler)
this._beginHandler({ expectedBytes, headers }); this._beginHandler({ expectedBytes, headers })
}
} }
_onProgress (percent, bytesWritten, totalBytes) { _onProgress (percent, bytesWritten, totalBytes) {
this.percent = percent; this.percent = percent
this.bytesWritten = bytesWritten; this.bytesWritten = bytesWritten
this.totalBytes = totalBytes; this.totalBytes = totalBytes
if (this._progressHandler) { if (this._progressHandler)
this._progressHandler(percent, bytesWritten, totalBytes); this._progressHandler(percent, bytesWritten, totalBytes)
}
} }
_onDone ({ location }) { _onDone ({ location }) {
this.state = 'DONE'; this.state = 'DONE'
if (this._doneHandler) { if (this._doneHandler)
this._doneHandler({ location }); this._doneHandler({ location })
}
} }
_onError (error, errorCode) { _onError (error, errorCode) {
this.state = 'FAILED'; this.state = 'FAILED'
if (this._errorHandler) { if (this._errorHandler)
this._errorHandler(error, errorCode); this._errorHandler(error, errorCode)
}
} }
pause () { pause () {
this.state = 'PAUSED'; this.state = 'PAUSED'
RNBackgroundDownloader.pauseTask(this.id); RNBackgroundDownloader.pauseTask(this.id)
} }
resume () { resume () {
this.state = 'DOWNLOADING'; this.state = 'DOWNLOADING'
RNBackgroundDownloader.resumeTask(this.id); RNBackgroundDownloader.resumeTask(this.id)
} }
stop () { stop () {
this.state = 'STOPPED'; this.state = 'STOPPED'
RNBackgroundDownloader.stopTask(this.id); RNBackgroundDownloader.stopTask(this.id)
} }
} }

View File

@@ -6,7 +6,7 @@
"scripts": { "scripts": {
"test": "jest", "test": "jest",
"prepublish": "jest && npm run lint", "prepublish": "jest && npm run lint",
"lint": "eslint index.js lib/**" "lint": "eslint ."
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@@ -40,15 +40,32 @@
} }
], ],
"license": "Apache-2.0", "license": "Apache-2.0",
"lint-staged": {
"*.js": "eslint --cache"
},
"peerDependencies": { "peerDependencies": {
"react-native": ">=0.57.0" "react-native": ">=0.57.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.16.0",
"@babel/preset-env": "^7.16.4",
"@babel/runtime": "^7.16.3",
"@babel/eslint-parser": "^7.16.3",
"@react-native-community/eslint-config": "^3.0.1",
"eslint": "7.32.0",
"eslint-config-standard": "^16.0.3",
"eslint-config-standard-jsx": "^10.0.0",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.1.1",
"eslint-plugin-react": "^7.27.1",
"eslint-plugin-react-hooks": "^4.3.0",
"eslint-plugin-standard": "^5.0.0",
"@babel/core": "^7.4.0", "@babel/core": "^7.4.0",
"@babel/runtime": "^7.4.2", "@babel/runtime": "^7.4.2",
"@react-native-community/eslint-config": "^0.0.3", "@react-native-community/eslint-config": "^0.0.3",
"babel-jest": "^24.5.0", "babel-jest": "^24.5.0",
"eslint": "^5.16.0", "lint-staged": ">=12",
"immer": "^3.2.0", "immer": "^3.2.0",
"jest": "^24.5.0", "jest": "^24.5.0",
"metro-react-native-babel-preset": "^0.53.1", "metro-react-native-babel-preset": "^0.53.1",

View File

@@ -6,25 +6,25 @@
* @flow * @flow
*/ */
import React, { Component } from 'react'; import React, { Component } from 'react'
import { Text, SafeAreaView, TextInput, Button, FlatList, View, AsyncStorage, TouchableOpacity, Slider } from 'react-native'; import { Text, SafeAreaView, TextInput, Button, FlatList, View, AsyncStorage, TouchableOpacity, Slider } from 'react-native'
import Icon from 'react-native-vector-icons/Ionicons'; import Icon from 'react-native-vector-icons/Ionicons'
import RNFS from 'react-native-fs'; import RNFS from 'react-native-fs'
import produce from 'immer'; import produce from 'immer'
import RNBGD from '../index'; import RNBGD from '../index'
import styles from './Style'; import styles from './Style'
const testURL = 'https://speed.hetzner.de/100MB.bin'; const testURL = 'https://speed.hetzner.de/100MB.bin'
const urlRegex = /^(?:https?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$/; const urlRegex = /^(?:https?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$/
function isValid (url) { function isValid (url) {
return urlRegex.test(url); return urlRegex.test(url)
} }
export default class App extends Component { export default class App extends Component {
constructor (props) { constructor (props) {
super(props); super(props)
this.idsToData = {}; this.idsToData = {}
} }
state = { state = {
@@ -36,78 +36,77 @@ export default class App extends Component {
}; };
async componentDidMount () { async componentDidMount () {
const tasks = await RNBGD.checkForExistingDownloads(); const tasks = await RNBGD.checkForExistingDownloads()
if (tasks && tasks.length) { if (tasks && tasks.length) {
await this.loadDownloads(); await this.loadDownloads()
const downloadsData = {}; const downloadsData = {}
const downloads = []; const downloads = []
for (let task of tasks) { for (const task of tasks) {
downloads.push(task.id); downloads.push(task.id)
downloadsData[task.id] = { downloadsData[task.id] = {
url: this.idsToData[task.id].url, url: this.idsToData[task.id].url,
percent: task.percent, percent: task.percent,
total: task.totalBytes, total: task.totalBytes,
status: task.state === 'DOWNLOADING' ? 'downloading' : 'paused', status: task.state === 'DOWNLOADING' ? 'downloading' : 'paused',
task: task task: task,
}; }
this.attachToTask(task, this.idsToData[task.id].filePath); this.attachToTask(task, this.idsToData[task.id].filePath)
} }
this.setState({ this.setState({
downloadsData, downloadsData,
downloads downloads,
}); })
} }
} }
saveDownloads () { saveDownloads () {
AsyncStorage.setItem('idsToData', JSON.stringify(this.idsToData)); AsyncStorage.setItem('idsToData', JSON.stringify(this.idsToData))
} }
async loadDownloads () { async loadDownloads () {
const mapStr = await AsyncStorage.getItem('idsToData'); const mapStr = await AsyncStorage.getItem('idsToData')
try { try {
this.idsToData = JSON.parse(mapStr) || {}; this.idsToData = JSON.parse(mapStr) || {}
} catch (e) { } catch (e) {
console.error(e); console.error(e)
} }
} }
pauseOrResume (id) { pauseOrResume (id) {
let newStatus; let newStatus
const download = this.state.downloadsData[id]; const download = this.state.downloadsData[id]
if (download.status === 'downloading') { if (download.status === 'downloading') {
download.task.pause(); download.task.pause()
newStatus = 'paused'; newStatus = 'paused'
} else if (download.status === 'paused') { } else if (download.status === 'paused') {
download.task.resume(); download.task.resume()
newStatus = 'downloading'; newStatus = 'downloading'
} else { } else {
console.error(`Unknown status for play or pause: ${download.status}`); console.error(`Unknown status for play or pause: ${download.status}`)
return; return
} }
this.setState(produce(draft => { this.setState(produce(draft => {
draft.downloadsData[id].status = newStatus; draft.downloadsData[id].status = newStatus
})); }))
} }
cancel (id) { cancel (id) {
const download = this.state.downloadsData[id]; const download = this.state.downloadsData[id]
download.task.stop(); download.task.stop()
delete this.idsToData[id]; delete this.idsToData[id]
this.saveDownloads(); this.saveDownloads()
this.setState(produce(draft => { this.setState(produce(draft => {
delete draft.downloadsData[id]; delete draft.downloadsData[id]
draft.downloads.splice(draft.downloads.indexOf(id), 1); draft.downloads.splice(draft.downloads.indexOf(id), 1)
})); }))
} }
renderRow ({ item: downloadId }) { renderRow ({ item: downloadId }) {
const download = this.state.downloadsData[downloadId]; const download = this.state.downloadsData[downloadId]
let iconName = 'ios-pause'; let iconName = 'ios-pause'
if (download.status === 'paused') { if (download.status === 'paused')
iconName = 'ios-play'; iconName = 'ios-play'
}
return ( return (
<View key={downloadId} style={styles.downloadItem}> <View key={downloadId} style={styles.downloadItem}>
@@ -130,74 +129,74 @@ export default class App extends Component {
</TouchableOpacity> </TouchableOpacity>
</View> </View>
</View> </View>
); )
} }
attachToTask (task, filePath) { attachToTask (task, filePath) {
task.begin(expectedBytes => { task.begin(expectedBytes => {
this.setState(produce(draft => { this.setState(produce(draft => {
draft.downloadsData[task.id].total = expectedBytes; draft.downloadsData[task.id].total = expectedBytes
draft.downloadsData[task.id].status = 'downloading'; draft.downloadsData[task.id].status = 'downloading'
})); }))
}) })
.progress(percent => { .progress(percent => {
this.setState(produce(draft => { this.setState(produce(draft => {
draft.downloadsData[task.id].percent = percent; draft.downloadsData[task.id].percent = percent
})); }))
}) })
.done(async () => { .done(async () => {
try { try {
console.log(`Finished downloading: ${task.id}, deleting it...`); console.log(`Finished downloading: ${task.id}, deleting it...`)
await RNFS.unlink(filePath); await RNFS.unlink(filePath)
console.log(`Deleted ${task.id}`); console.log(`Deleted ${task.id}`)
} catch (e) { } catch (e) {
console.error(e); console.error(e)
} }
delete this.idsToData[task.id]; delete this.idsToData[task.id]
this.saveDownloads(); this.saveDownloads()
this.setState(produce(draft => { this.setState(produce(draft => {
delete draft.downloadsData[task.id]; delete draft.downloadsData[task.id]
draft.downloads.splice(draft.downloads.indexOf(task.id), 1); draft.downloads.splice(draft.downloads.indexOf(task.id), 1)
})); }))
}) })
.error(err => { .error(err => {
console.error(`Download ${task.id} has an error: ${err}`); console.error(`Download ${task.id} has an error: ${err}`)
delete this.idsToData[task.id]; delete this.idsToData[task.id]
this.saveDownloads(); this.saveDownloads()
this.setState(produce(draft => { this.setState(produce(draft => {
delete draft.downloadsData[task.id]; delete draft.downloadsData[task.id]
draft.downloads.splice(draft.downloads.indexOf(task.id), 1); draft.downloads.splice(draft.downloads.indexOf(task.id), 1)
})); }))
}); })
} }
addDownload () { addDownload () {
const id = Math.random() const id = Math.random()
.toString(36) .toString(36)
.substr(2, 6); .substr(2, 6)
const filePath = `${RNBGD.directories.documents}/${id}`; const filePath = `${RNBGD.directories.documents}/${id}`
const url = this.state.url || testURL; const url = this.state.url || testURL
const task = RNBGD.download({ const task = RNBGD.download({
id: id, id: id,
url: url, url: url,
destination: filePath, destination: filePath,
}); })
this.attachToTask(task, filePath); this.attachToTask(task, filePath)
this.idsToData[id] = { this.idsToData[id] = {
url, url,
filePath filePath,
}; }
this.saveDownloads(); this.saveDownloads()
this.setState(produce(draft => { this.setState(produce(draft => {
draft.downloadsData[id] = { draft.downloadsData[id] = {
url: url, url: url,
status: 'idle', status: 'idle',
task: task task: task,
}; }
draft.downloads.push(id); draft.downloads.push(id)
draft.url = ''; draft.url = ''
})); }))
} }
render () { render () {
@@ -211,7 +210,7 @@ export default class App extends Component {
keyboardType="url" keyboardType="url"
placeholder={testURL} placeholder={testURL}
onChangeText={(text) => { onChangeText={(text) => {
this.setState({ url: text.toLowerCase() }); this.setState({ url: text.toLowerCase() })
}} }}
value={this.state.url} value={this.state.url}
/> />
@@ -227,6 +226,6 @@ export default class App extends Component {
extraData={this.state.downloadsData} extraData={this.state.downloadsData}
/> />
</SafeAreaView> </SafeAreaView>
); )
} }
} }

View File

@@ -1,4 +1,4 @@
import { StyleSheet } from 'react-native'; import { StyleSheet } from 'react-native'
export default StyleSheet.create({ export default StyleSheet.create({
container: { container: {
@@ -17,14 +17,14 @@ export default StyleSheet.create({
}, },
downloadingList: { downloadingList: {
flex: 1, flex: 1,
width: '100%' width: '100%',
}, },
downloadItem: { downloadItem: {
height: 100, height: 100,
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center', alignItems: 'center',
paddingHorizontal: 5, paddingHorizontal: 5,
justifyContent: 'space-between' justifyContent: 'space-between',
}, },
buttonsContainer: { buttonsContainer: {
flexDirection: 'row', flexDirection: 'row',
@@ -34,6 +34,6 @@ export default StyleSheet.create({
button: { button: {
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
paddingHorizontal: 10 paddingHorizontal: 10,
} },
}); })

View File

@@ -2,8 +2,8 @@
* @format * @format
*/ */
import {AppRegistry} from 'react-native'; import { AppRegistry } from 'react-native'
import App from './App'; import App from './App'
import {name as appName} from './app.json'; import { name as appName } from './app.json'
AppRegistry.registerComponent(appName, () => App); AppRegistry.registerComponent(appName, () => App)

5697
yarn.lock

File diff suppressed because it is too large Load Diff