Skip to content

Commit

Permalink
Merge pull request #91 from growlerapp/fix/geo-detection
Browse files Browse the repository at this point in the history
fix: geo detection [WIP]
  • Loading branch information
juankeldor authored Oct 17, 2019
2 parents 035eca2 + 9c1add2 commit 601e1b7
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 75 deletions.
13 changes: 11 additions & 2 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

<script>
import vHeader from '@/components/v-Header'
import { checkUserGeoData } from '@/user'
export default {
name: 'App',
Expand All @@ -21,8 +22,16 @@ export default {
vHeader
},
created () {
this.$store.dispatch('userGeoData', { force: false })
mounted () {
/**
* Busca si existe geo data almacenada localmente
* de lo contrario devuelve a splash
*/
if (checkUserGeoData()) {
this.$store.dispatch('userGeoData', { force: false })
} else {
this.$router.push('/')
}
}
}
</script>
Expand Down
7 changes: 4 additions & 3 deletions src/helpers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ const isJSON = json => {
if (json && typeof json === 'object' && json !== null) {
return true
}
} catch (err) {}
return false
} catch (error) {
return error
}
}

export default {
export {
isJSON
}
14 changes: 1 addition & 13 deletions src/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,9 @@ import Home from '@/views/Home'
import Splash from '@/views/Splash'
import About from '@/views/About'
import Store from '@/views/Store'
import user from '@/user'

Vue.use(Router)

const requireUser = (to, from, next) => {
if (!user.checkUserGeoData()) {
next({
path: '/'
})
} else {
next()
}
}

export default new Router({
scrollBehavior () {
return new Promise(resolve => {
Expand All @@ -41,8 +30,7 @@ export default new Router({
{
path: '/home',
name: 'home',
component: Home,
beforeEnter: requireUser
component: Home
},
{
path: '/store/:id',
Expand Down
6 changes: 3 additions & 3 deletions src/store.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Vue from 'vue'
import Vuex from 'vuex'
import user from '@/user'
import { getUserData } from '@/user'

Vue.use(Vuex)

Expand All @@ -16,8 +16,8 @@ export default new Vuex.Store({
setLoading (state, value) {
state.loading = value
},
async setUserGeoData (state, { force }) {
const data = await user.getUserData(force)
async setUserGeoData (state, { force = false }) {
const data = await getUserData(force)
state.userData = data
},
setMenu (state, value) {
Expand Down
89 changes: 60 additions & 29 deletions src/user.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,63 @@
import helpers from '@/helpers'
import { isJSON } from '@/helpers'

/**
* Get user geo from device
* @return {Promise<Object>}
* https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API
*/
const getUserGeoDataFromDevice = () => {
return new Promise((resolve, reject) => {
if (!navigator.geolocation) {
return reject(
new Error('geo error')
)
} else {
navigator.geolocation.getCurrentPosition(result => {
const data = {
if ('geolocation' in navigator) {
navigator.geolocation.getCurrentPosition(result =>
resolve({
lat: result.coords.latitude,
long: result.coords.longitude
}), error => reject(parseError(error))
)
const parseError = error => {
switch (error.code) {
case error.PERMISSION_DENIED:
return {
code: 0,
message: 'User denied the request for geolocation.'
}
case error.POSITION_UNAVAILABLE:
return {
code: 1,
message: 'Location information is unavailable.'
}
case error.TIMEOUT:
return {
code: 2,
message: 'The request to get user location timed out.'
}
case error.UNKNOWN_ERROR:
return {
code: 3,
message: 'An unknown error occurred.'
}
}
return resolve(data)
}
} else {
// eslint-disable-next-line prefer-promise-reject-errors
reject({
code: 3,
message: 'An unknown error occurred.'
})
}
})
}

/**
* Fetch user geo data
* @return {object} user geo data
*/
const fetchUserGeoData = async () => {
const data = await getUserGeoDataFromDevice()
setUserGeoDataToStorage(data)
return data
}

/**
* Set flag if user has joined to app
*/
Expand Down Expand Up @@ -60,37 +96,32 @@ const getUserGeoDataFromStorage = () => {
*/
const checkUserGeoData = () => {
const data = getUserGeoDataFromStorage()
return helpers.isJSON(data) && data.lat && data.long
}

/**
* Fetch user geo data
* @return {object} user geo data
*/
const fetchUserGeoData = async () => {
const data = await getUserGeoDataFromDevice()
setUserGeoDataToStorage(data)
return data
return isJSON(data) && data.lat && data.long
}

/**
* Get user data from storage or user device
* @param {boolean} force
* @return {Promise<object>} user geo data
*/
const getUserData = async (force = false) => {
if (force) {
return fetchUserGeoData()
} else {
return checkUserGeoData()
? getUserGeoDataFromStorage()
: fetchUserGeoData()
const getUserData = (force = false) => {
try {
if (force) {
return fetchUserGeoData()
} else {
return checkUserGeoData()
? getUserGeoDataFromStorage()
: fetchUserGeoData()
}
} catch (error) {
return error
}
}

export default {
export {
getUserData,
checkUserGeoData,
checkHasJoined,
setUserHasJoined
setUserHasJoined,
fetchUserGeoData
}
58 changes: 33 additions & 25 deletions src/views/Splash.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,18 @@
</div>
<h2>Obteniendo tu ubicación...</h2>

<template v-if="isGeoError">
<h3>Debes autorizar la geolocalización para continuar</h3>
<template v-if="isGeoError !== null">
<template v-if="isGeoError === 0">
<h3>Debes autorizar la geolocalización en tu dispositivo para continuar</h3>
</template>
<template v-else-if="isGeoError === 1">
<h3>No podemos detectar donde te encuentras</h3>
</template>
<template v-else>
<h3>Ha ocurrido un error tratando de obtener tu geolocalización</h3>
</template>
<div class="Splash-continue">
<v-button @click.native="forceReload" type="alt">Recargar</v-button>
<v-button @click.native="forceReload" type="alt">Reintentar</v-button>
</div>
</template>
</div>
Expand All @@ -40,7 +48,7 @@
<div class="Splash-loading">
<loading type="relative" color="white" />
</div>
<h2>Cargando datos...</h2>
<h2>Buscando lugares cercanos...</h2>
</template>
</div>

Expand All @@ -50,7 +58,7 @@
</template>

<script>
import user from '@/user'
import { checkHasJoined, setUserHasJoined, checkUserGeoData, getUserData } from '@/user'
import Loading from '@/components/Loading'
import vButton from '@/components/v-Button'
Expand All @@ -63,21 +71,30 @@ export default {
},
data: () => ({
isGeoError: false,
isGeoError: null,
hasUserJoinedToApp: false
}),
async mounted () {
if (user.checkHasJoined()) {
this.hasUserJoinedToApp = true
this.goToHome()
} else {
// iniciar animaciones
await this.playSteps()
// obtener geo
this.getData()
// setear flag usuario primera vez
user.setUserHasJoined()
try {
if (checkHasJoined() && checkUserGeoData()) {
// setea flag de inicio
this.hasUserJoinedToApp = true
// redirije al home
await this.goToHome()
} else {
// iniciar animaciones
await this.playSteps()
// obtener geo data
await getUserData()
this.$store.dispatch('userGeoData', { force: true })
// setea flag de inicio
setUserHasJoined()
// redirecciona al home
await this.goToHome()
}
} catch (error) {
this.isGeoError = error.code
}
},
Expand All @@ -90,15 +107,6 @@ export default {
})
},
async getData () {
try {
await user.getUserData()
this.goToHome()
} catch (e) {
this.isGeoError = true
}
},
async playSteps () {
const step = document.getElementsByClassName('Splash-step')
await this.delay(400)
Expand Down

0 comments on commit 601e1b7

Please sign in to comment.