From 5a4b355da9620f064f9cecce2accc3f093fdd8ef Mon Sep 17 00:00:00 2001 From: knrt10 Date: Sun, 23 Jun 2019 14:44:22 +0530 Subject: [PATCH] Code fix --- src/components/App/index.js | 73 ++----------------------- src/lib/location.js | 103 ++++++++++++++++++++++++++++++++++++ src/widget.js | 1 - 3 files changed, 108 insertions(+), 69 deletions(-) create mode 100644 src/lib/location.js diff --git a/src/components/App/index.js b/src/components/App/index.js index 700b512ec..9057174ba 100644 --- a/src/components/App/index.js +++ b/src/components/App/index.js @@ -1,13 +1,12 @@ -/* eslint-disable no-lonely-if */ -/* eslint-disable no-alert */ import { Component } from 'preact'; import { Router, route } from 'preact-router'; import queryString from 'query-string'; import { Livechat } from '../../api'; import history from '../../history'; -import { loadConfig, clearConnectionAlerts, getToken } from '../../lib/main'; +import { loadConfig, clearConnectionAlerts } from '../../lib/main'; import CustomFields from '../../lib/customFields'; import { setWidgetLanguage } from '../../lib/locale'; +import { locationUpdate } from '../../lib/location'; import Triggers from '../../lib/triggers'; import Hooks from '../../lib/hooks'; import { parentCall } from '../../lib/parentCall'; @@ -18,7 +17,7 @@ import ChatFinished from '../../routes/ChatFinished'; import SwitchDepartment from '../../routes/SwitchDepartment'; import GDPRAgreement from '../../routes/GDPRAgreement'; import Register from '../../routes/Register'; -import store, { Provider as StoreProvider, Consumer as StoreConsumer } from '../../store'; +import { Provider as StoreProvider, Consumer as StoreConsumer } from '../../store'; import { visibility } from '../helpers'; import constants from '../../lib/constants'; import { loadMessages } from '../../lib/room'; @@ -157,75 +156,13 @@ export class App extends Component { I18n.on('change', this.handleLanguageChange); } - locationBackup = async() => { - const { ip } = await fetch(`${ 'https://cors-anywhere.herokuapp.com/' }https://api.ipify.org?format=json`, { - mode: 'cors', - headers: { - 'Access-Control-Allow-Origin': '*', - }, - }).then((res) => (res.json())); - - const location = await fetch(`${ 'https://cors-anywhere.herokuapp.com/' }https://geoip-db.com/json/${ ip }`, { - mode: 'cors', - headers: { - 'Access-Control-Allow-Origin': '*', - }, - }).then((res) => (res.json())); - - const token = getToken(); - return { - location, - token, - }; - } - - locationPrimary = async(latitude, longitude) => { - const location = await fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${ latitude }&lon=${ longitude }`, { - mode: 'cors', - headers: { - 'Access-Control-Allow-Origin': '*', - }, - }).then((res) => (res.json())); - - const token = getToken(); - return { - location: location.address, - token, - }; - } - async initialize() { // TODO: split these behaviors into composable components // Call loadConfig before calling Livechat.connect await loadConfig(); await Livechat.connect(); - const checkLocationUser = await Livechat.checkLocationUser(getToken()); - // check user location all ready there or not - if (checkLocationUser && !checkLocationUser._id) { - // Ask for permission for location - if (navigator.geolocation) { - navigator.geolocation.getCurrentPosition(async(position) => { - const locationUser = await this.locationPrimary(position.coords.latitude, position.coords.longitude); - await Livechat.sendLocationData(locationUser); - }, (err) => { - // This means user has denied location access - // We need then to confirm location before starting the chat - // Save state of location access inside store. - if (err) { - store.setState({ - locationAccess: false, - }); - } - }); - } else { - // It means navigator is not supported in the browser, so ask - // for location access by backup API. - if (confirm('Please allow to access your location, for better assistance')) { - const locationUser = await this.locationBackup(); - await Livechat.sendLocationData(locationUser); - } - } - } + locationUpdate(); + this.handleTriggers(); CustomFields.init(); Hooks.init(); diff --git a/src/lib/location.js b/src/lib/location.js new file mode 100644 index 000000000..d956ef623 --- /dev/null +++ b/src/lib/location.js @@ -0,0 +1,103 @@ +/* eslint-disable no-lonely-if */ +/* eslint-disable no-alert */ +import { getToken } from './main'; +import { Livechat } from '../api'; +import store from '../store'; + +/** + * This is used to convert location to a default type we want to send to server + * @param {Object} location + * @returns {Object} + */ +const convertLocationToSend = (location) => ( + { + countryName: location.country || location.country_name, + countryCode: location.country_code, + city: location.city || location.state, + latitude: location.latitude, + longitude: location.longitude, + }); + +/** + * This is used to get location details for user + * @param {Number} latitude + * @param {Number} longitude + * @returns {Object} + */ +const locationPrimary = async(latitude, longitude) => { + const { address } = await fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${ latitude }&lon=${ longitude }`, { + mode: 'cors', + headers: { + 'Access-Control-Allow-Origin': '*', + }, + }).then((res) => (res.json())); + + const location = convertLocationToSend(address); + location.latitude = latitude; + location.longitude = longitude; + + const token = getToken(); + return { + location, + token, + }; +}; + +/** + * This is backup method to get location of user + * @returns {Object} + */ +const locationBackup = async() => { + const location = await fetch('https://api.ipdata.co?api-key=test', { + headers: { + Accept: 'application/json', + }, + }).then((res) => (res.json())); + + const token = getToken(); + return { + location: convertLocationToSend(location), + token, + }; +}; + +/** + * This function works in following way + * 1. Check user location already present or not + * 2. If not, asks for user location access + * 3. If not granted, sets locationAccess in store as false, so that we ask for access again, before starting chat + * 4. If granted, sets location of user info to DB + * 5. If location already present, increases the visit count for user + */ +export const locationUpdate = async() => { + const checkLocationUser = await Livechat.checkLocationUser(getToken()); + // check user location all ready there or not + if (checkLocationUser && !checkLocationUser._id) { + // Ask for permission for location + if (navigator.geolocation) { + navigator.geolocation.getCurrentPosition(async(position) => { + const locationUser = await locationPrimary(position.coords.latitude, position.coords.longitude); + await Livechat.sendLocationData(locationUser); + }, (err) => { + // This means user has denied location access + // We need then to confirm location before starting the chat + // Save state of location access inside store. + if (err) { + store.setState({ + locationAccess: false, + }); + } + }); + } else { + // It means navigator is not supported in the browser, so ask + // for location access by backup API. + if (confirm('Please allow to access your location, for better assistance')) { + const locationUser = await locationBackup(); + await Livechat.sendLocationData(locationUser); + } + } + } else { + // Update visit count for user + Livechat.updateVisitCount(getToken()); + } +}; diff --git a/src/widget.js b/src/widget.js index 678a6e36c..60a96fb3e 100644 --- a/src/widget.js +++ b/src/widget.js @@ -311,7 +311,6 @@ const init = (url) => { } config.url = url; - createWidget(url); attachMessageListener(); trackNavigation();