Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Pay on Thursday 27th May] [IOU] Create Currency Modal, with geolocation and Location permissions #1970

Closed
jliexpensify opened this issue Mar 21, 2021 · 8 comments · Fixed by #2194
Assignees
Labels

Comments

@jliexpensify
Copy link
Contributor

jliexpensify commented Mar 21, 2021

If you haven’t already, check out our contributing guidelines for onboarding!


Context

This issue builds on top of the existing IOU Modal, which was implemented in this PR. The IOU Amount step page has already been created and is a controlled component (IOUModal manages its state). The amount step allows users to select the IOU request or bill split amount, depending on how they launched the Modal.

We now seek to extend functionality. We want to use a Geolocation library and an existing API to detect the users preferred currency, allowing them to change it manually, too. We also need to implement a permissions library to request location permission from the user if they decide to change their currency, as we will then seek to detect it automatically from then on.

To open the Modal, you can navigate to localhost:8080/iou/request AND localhost:8080/iou/split.

You can also launch the IOUModal by temporarily modifying the routes in CreateMenu. Launch the request money flow with Navigation.navigate(ROUTES.IOU_REQUEST) and the bill split flow with Navigation.navigate(ROUTES.IOU_BILL)

Mobile & mobile web
Currency Selector - Mobile

Web & Desktop
Currency Selector - Desktop (1)

Deliverables:

  1. Create a new API.js function for calling our GetPreferredCurrency API and another for calling GetCurrencyList. Details at the bottom of this post.
  2. Add the react-native-geolocation and react-native-permissions libraries to the project.
  3. We should create a new function within the PersonalDetails.js Action which calls the new GetPreferredCurrency API.js function
    1. If the location permission has already been granted, we will get lat and lon from getCurrentPosition and pass the params to GetPreferredCurrency, else we ignore those query params (as they are optional)
    2. We should then call GetCurrencyList matching the currency we received from the previous request to get the correct symbol for that currency. (the full currency list should also be persisted to Onyx via a new key: currencyList)
    3. We then persist both the preferredCurrencyCode AND preferredCurrencySymbol data in Onyx, similar to how we store the users timezone
  4. When the IOUModal is opened, we should subscribe to the MY_PERSONAL_DETAILS Onyx key:
    1. We take updated values of preferredCurrencySymbol and preferredCurrencyCode, setting IOUModal props for both of these (currencySelected prop should be deleted, selectedCurrency should be modified to be of type Object: selectedCurrency: { currencyCode: String, currencySymbol: String })
    2. The currency Text component should be updated with this.props.selectedCurrency.currencySymbol
  5. When the currency symbol is tapped, a CurrencyModal should be displayed. This is a new Modal which needs the following functionality:
    1. The Modal should follow the structure of our existing Modals
    2. Retrieve all currencies from GetCurrencyList via another new Action function and again persisting this data to Onyx under the currencyList key.
    3. using the above data, we should display all currencies to the user in a FlatList, using a new OptionsListUtils variant
    4. If the user makes a currency selection then we should pass this value back to the IOUModal via a callback and update the preferredCurrencyCode AND preferredCurrencySymbol Onyx data
    5. The modal should then close, returning the user to the IOUAmount step, with the updated currency symbol

GetPreferredCurrency API
Example of the API which is used to retrieve the users preferred currency

https://www.expensify.com/api?command=GetPreferredCurrency&latitude=0.01&longitude=-1.44
latitude - optional param
longitude - optional param

// Response
{
  "currency": "GBP",
  "jsonCode": 200,
  "requestID": "0uBdrX"
}

GetCurrencyList API
Example of the API which returns all supported currency and symbol parings

https://www.expensify.com/api?command=Mobile_GetConstants&data=[%22currencyList%22]

// Response
{
  "currencyList": "{"AED":{"symbol":"Dhs","name":"UAE Dirham","ISO4217":"784"},"AFN":{"symbol":"Af","name":"Afghan Afghani","ISO4217":"971"},"ALL":{"symbol":"ALL","name":"Albanian
	...
  }}",
  "jsonCode": 200,
  "requestID": "wjy42x"
}

Original issue: https://github.com/Expensify/Expensify/issues/157871#event-4483831003

Upwork Issue: https://www.upwork.com/ab/applicants/1373765458169090048/job-details

@rameshhpathak
Copy link
Contributor

rameshhpathak commented Mar 21, 2021

Hi, I would love to work on this issue!

My proposal: 




  1. I will create a new API.js function for calling GetPreferredCurrency and another for calling GetCurrencyList

  2. Install the react-native-geolocation as well as react-native-permissions libraries to the project.

  3. Create a new function within the PersonalDetails.js action which calls GetPreferredCurrency API.js function. 



    i. If the location permission has already been granted, we will then use geolocation.getCurrentPosition(geo_success,[geo_error], [geo_options]) from the react-native-geolocation library to get lat and long and will pass these to GetPreferredCurrency, or else we will ignore lat and long query parameters.

    ii. Or else, use the react-native-permissions library to request the location permission from the user.

    iii. We should then call the GetCurrencyList, matching the currency we received from calling the previous GetPreferredCurrency request and get the symbol.

    iv. I will create a new key in Onyx for currencyList and persist the full currency list in Onyx using this key.

    v. We also persist both the preferredCurrencyCode and preferredCurrencySymbol data in Onyx, similar to how the current storing of users timezone (fetchTimezone) is implemented.

  4. When IOUModal is opened, we should now subscribe to MY_PERSONAL_DETAILS OnyxKey as follows:

    export default withOnyx ({ myPersonalDetails: { key: ONYXKEYS.MY_PERSONAL_DETAILS }, })(IOUModal);

    and use preferredCurrencySymbol and preferredCurrencyCode from the Onyx to set IOUModal props.

    i. Currently, we hold selectedCurrency as the state in IOUModal with default as USD but this should now be updated to use this.props.selectedCurrency from the Onyx itself.

    ii. The format for selectedCurrency will be of type object: selectedCurrency: { currencyCode: String, currencySymbol: String }

    iii. The currency for the Text Component should be set using this.props.selectedCurrency.currencySymbol in the IOUAmount

  5. When the currency symbol is tapped in IOUAmount, a CurrencyModal should be displayed. The new modal will be built as follows:

    i. Use the same structure of the current existing modals

    ii. Use the GetCurrencyList API.js function to retrieve all currencies via another new Action function within the modal and persist the data to Onyx using currencyList key

    iii. Create a new getCurrencyOptions variant in OptionListUtils.js, similar to getOptions to display the currency list

    iv. Display all the currencies to the user in a FlatList using the above getCurrencyOptions function

    v. Whenever the user selects a currency, pass this value back to IOUModal using a callback and update the preferredCurrencyCode and preferredCurrencySymbol in Onyx data

    vi. When the user confirms the currency selection, close the modal and return the user to the IOUAmount step with the updated currency symbol

Question

The SelectCurrency UI in the picture currently has two sections for the currency selection - Recently Used and All Currencies. Should we use SectionList instead of a FlatList — similar to how I think OptionsList is implemented?

@Julesssss
Copy link
Contributor

Hi @rameshhpathak -- thanks for your proposal.

Should we use SectionList instead of a FlatList — similar to how I think OptionsList is implemented?

Nice spot. Yeah, that would be preferred.

@rameshhpathak
Copy link
Contributor

Got it. Thanks. Also, have submitted the proposal on job posting under the name Ramesh Pathak.

@iwiznia
Copy link
Contributor

iwiznia commented Mar 26, 2021

Is this being worked on? I can't find a PR for this.

@rameshhpathak
Copy link
Contributor

Hi @iwiznia yeah, I will be submitting PR first thing tomorrow as I'm almost done.

@kadiealexander
Copy link
Contributor

Hi @rameshhpathak, how are you getting on with this one? Just as an FYI, the deadline for these issues is typically 7 days from when it's assigned. 😊

@rameshhpathak
Copy link
Contributor

@kadiealexander Hi, sorry! I am resolving the outstanding issues within next half an hour!

@Julesssss Julesssss reopened this May 20, 2021
@Julesssss Julesssss added the Weekly KSv2 label May 20, 2021
@Julesssss Julesssss changed the title [Chat] [IOU] Create Currency Modal, with geolocation and Location permissions [Pay on Thursday 27th May] [IOU] Create Currency Modal, with geolocation and Location permissions May 20, 2021
@trjExpensify
Copy link
Contributor

Paid, thanks Ramesh!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment