Skip to content

Commit

Permalink
Feature(maps-screen): center map on user's location when user first o…
Browse files Browse the repository at this point in the history
…pens the maps tab (#2895)

* feat(map-screen): opening the map will center on user's location if given permission

* refactor: remove comments and logs

* refactor: prettier

* refactor: relocating config setup for geolocation

* feat: switched to allowing Geolocation library to request permissions in order to better request for ios

* refactor: check code prettier

* feat: focuses on users ip country as a backup option if permissions are denied

* refactor: code minimization

* feat: utilizing graphQL client cache instead of asyncStorage. Required a refactor that moves the retrieval to a hook instead of a standard function

* refactor: minor reorganizations

* refactor: check code

---------

Co-authored-by: Craig Mahood <[email protected]>
  • Loading branch information
MaxwellDG and Craig Mahood authored Dec 29, 2023
1 parent a51b8c2 commit 1ed4f39
Show file tree
Hide file tree
Showing 14 changed files with 508 additions and 91 deletions.
3 changes: 3 additions & 0 deletions app/graphql/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ export const createCache = () =>
colorScheme: {
read: (value) => value ?? "system",
},
countryCode: {
read: (value) => value ?? "SV",
},
feedbackModalShown: {
read: (value) => value ?? false,
},
Expand Down
24 changes: 24 additions & 0 deletions app/graphql/client-only-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import {
BetaQuery,
ColorSchemeDocument,
ColorSchemeQuery,
CountryCodeDocument,
CountryCodeQuery,
FeedbackModalShownDocument,
FeedbackModalShownQuery,
HasPromptedSetDefaultAccountDocument,
Expand All @@ -16,6 +18,7 @@ import {
IntroducingCirclesModalShownDocument,
IntroducingCirclesModalShownQuery,
} from "./generated"
import { CountryCode } from "libphonenumber-js/mobile"

export default gql`
query hideBalance {
Expand All @@ -34,6 +37,10 @@ export default gql`
colorScheme @client # "system" | "light" | "dark"
}
query countryCode {
countryCode @client
}
query feedbackModalShown {
feedbackModalShown @client
}
Expand Down Expand Up @@ -115,6 +122,23 @@ export const updateColorScheme = (client: ApolloClient<unknown>, colorScheme: st
}
}

export const updateCountryCode = (
client: ApolloClient<unknown>,
countryCode: CountryCode,
) => {
try {
client.writeQuery<CountryCodeQuery>({
query: CountryCodeDocument,
data: {
__typename: "Query",
countryCode,
},
})
} catch {
console.warn("impossible to update country code")
}
}

export const setFeedbackModalShown = (client: ApolloClient<unknown>, shown: boolean) => {
try {
client.writeQuery<FeedbackModalShownQuery>({
Expand Down
4 changes: 4 additions & 0 deletions app/graphql/generated.gql
Original file line number Diff line number Diff line change
Expand Up @@ -949,6 +949,10 @@ query conversionScreen {
}
}

query countryCode {
countryCode @client
}

query currencyList {
currencyList {
__typename
Expand Down
39 changes: 39 additions & 0 deletions app/graphql/generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1511,6 +1511,7 @@ export type Query = {
readonly btcPriceList?: Maybe<ReadonlyArray<Maybe<PricePoint>>>;
readonly businessMapMarkers?: Maybe<ReadonlyArray<Maybe<MapMarker>>>;
readonly colorScheme: Scalars['String']['output'];
readonly countryCode: Scalars['String']['output'];
readonly currencyList: ReadonlyArray<Currency>;
readonly feedbackModalShown: Scalars['Boolean']['output'];
readonly globals?: Maybe<Globals>;
Expand Down Expand Up @@ -2231,6 +2232,11 @@ export type ColorSchemeQueryVariables = Exact<{ [key: string]: never; }>;

export type ColorSchemeQuery = { readonly __typename: 'Query', readonly colorScheme: string };

export type CountryCodeQueryVariables = Exact<{ [key: string]: never; }>;


export type CountryCodeQuery = { readonly __typename: 'Query', readonly countryCode: string };

export type FeedbackModalShownQueryVariables = Exact<{ [key: string]: never; }>;


Expand Down Expand Up @@ -3374,6 +3380,38 @@ export function useColorSchemeLazyQuery(baseOptions?: Apollo.LazyQueryHookOption
export type ColorSchemeQueryHookResult = ReturnType<typeof useColorSchemeQuery>;
export type ColorSchemeLazyQueryHookResult = ReturnType<typeof useColorSchemeLazyQuery>;
export type ColorSchemeQueryResult = Apollo.QueryResult<ColorSchemeQuery, ColorSchemeQueryVariables>;
export const CountryCodeDocument = gql`
query countryCode {
countryCode @client
}
`;

/**
* __useCountryCodeQuery__
*
* To run a query within a React component, call `useCountryCodeQuery` and pass it any options that fit your needs.
* When your component renders, `useCountryCodeQuery` returns an object from Apollo Client that contains loading, error, and data properties
* you can use to render your UI.
*
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
*
* @example
* const { data, loading, error } = useCountryCodeQuery({
* variables: {
* },
* });
*/
export function useCountryCodeQuery(baseOptions?: Apollo.QueryHookOptions<CountryCodeQuery, CountryCodeQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<CountryCodeQuery, CountryCodeQueryVariables>(CountryCodeDocument, options);
}
export function useCountryCodeLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<CountryCodeQuery, CountryCodeQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<CountryCodeQuery, CountryCodeQueryVariables>(CountryCodeDocument, options);
}
export type CountryCodeQueryHookResult = ReturnType<typeof useCountryCodeQuery>;
export type CountryCodeLazyQueryHookResult = ReturnType<typeof useCountryCodeLazyQuery>;
export type CountryCodeQueryResult = Apollo.QueryResult<CountryCodeQuery, CountryCodeQueryVariables>;
export const FeedbackModalShownDocument = gql`
query feedbackModalShown {
feedbackModalShown @client
Expand Down Expand Up @@ -8107,6 +8145,7 @@ export type QueryResolvers<ContextType = any, ParentType extends ResolversParent
btcPriceList?: Resolver<Maybe<ReadonlyArray<Maybe<ResolversTypes['PricePoint']>>>, ParentType, ContextType, RequireFields<QueryBtcPriceListArgs, 'range'>>;
businessMapMarkers?: Resolver<Maybe<ReadonlyArray<Maybe<ResolversTypes['MapMarker']>>>, ParentType, ContextType>;
colorScheme?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
countryCode?: Resolver<ResolversTypes['String'], ParentType, ContextType>;
currencyList?: Resolver<ReadonlyArray<ResolversTypes['Currency']>, ParentType, ContextType>;
feedbackModalShown?: Resolver<ResolversTypes['Boolean'], ParentType, ContextType>;
globals?: Resolver<Maybe<ResolversTypes['Globals']>, ParentType, ContextType>;
Expand Down
1 change: 1 addition & 0 deletions app/graphql/local-schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ extend type Query {
price: String # FIXME test only?
beta: Boolean!
colorScheme: String!
countryCode: String!
feedbackModalShown: Boolean!
hasPromptedSetDefaultAccount: Boolean!
introducingCirclesModalShown: Boolean!
Expand Down
51 changes: 51 additions & 0 deletions app/hooks/use-device-location.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { useApolloClient } from "@apollo/client"
import { useEffect, useState } from "react"
import { updateCountryCode } from "@app/graphql/client-only-query"
import { useCountryCodeQuery } from "@app/graphql/generated"
import axios from "axios"
import { CountryCode } from "libphonenumber-js/mobile"

const useDeviceLocation = () => {
const client = useApolloClient()
const { data, error } = useCountryCodeQuery()

const [loading, setLoading] = useState(true)
const [countryCode, setCountryCode] = useState<CountryCode>("SV")

useEffect(() => {
if (error) {
setLoading(false)
}
}, [error])

useEffect(() => {
if (data) {
const getLocation = async () => {
try {
const response = await axios.get("https://ipapi.co/json/", {
timeout: 5000,
})
const _countryCode = response?.data?.country_code
if (_countryCode) {
setCountryCode(_countryCode)
updateCountryCode(client, _countryCode)
} else {
console.warn("no data. default of SV will be used")
}
// can throw a 429 for device's rate-limiting. resort to cached value if available
} catch (err) {
setCountryCode(data.countryCode as CountryCode)
}
setLoading(false)
}
getLocation()
}
}, [data, client, setLoading, setCountryCode])

return {
countryCode,
loading,
}
}

export default useDeviceLocation
Loading

0 comments on commit 1ed4f39

Please sign in to comment.