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

Connect #2695

Open
wants to merge 331 commits into
base: feature/connect
Choose a base branch
from
Open

Connect #2695

wants to merge 331 commits into from

Conversation

OrangeAndGreen
Copy link
Contributor

@OrangeAndGreen OrangeAndGreen commented Aug 24, 2023

Summary

Connect navigation flow

Added Android Navigation component (and SafeArgs plugin) to the project.
Implemented Connect navigation graph.
Implemented 5 UI screens as fragments and built/populated the UIs.

Product Description

When user unlocks ConnectID on login page, button saying "Go to Connect Menu" now appears.
When clicked, the user sees the Jobs List fragment, and can begin navigating through screens with mock data.

Safety Assurance

  • [x ] If the PR is high risk, "High Risk" label is set
  • [x ] I have confidence that this PR will not introduce a regression for the reasons below
  • [x ] Do we need to enhance manual QA test coverage ? If yes, "QA Note" label is set correctly

Automated test coverage

No tests yet

Copy link
Contributor

@shubham1g5 shubham1g5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The drawable added in the PR should be added according to different Android screen densities - ldpi, hdpi, xhdpi, xxhdpi, xxxhdpi . You should be able to ask the designer for these.

@@ -606,6 +606,35 @@
<string name="connect_pictures_skip" cc:translatable="true">Skip</string>
<string name="connect_pictures_continue" cc:translatable="true">Continue</string>

<string name="connect_title" cc:translatable="true">Connect</string>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I think all connect strings should have cc:translatable not set. cc:translatable is meant for CC app's translations which are contained in the app ccz bundle and can be different for each apps. But Connect translations are independent of CC app and will be standard across different CC apps.

View view = inflater.inflate(R.layout.fragment_connect_delivery_details, container, false);

TextView textView = view.findViewById(R.id.connect_delivery_title);
textView.setText(getString(R.string.connect_delivery_review_title));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can set static strings in the xml itself.

public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ConnectJob job = ConnectJobIntroFragmentArgs.fromBundle(getArguments()).getJob();
getActivity().setTitle(job.getTitle());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use a Android view model to bind the UI here instead ? That will take care of things like restoring data state on configuration changes.

return view;
}

private static class MyJobsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be in a separate file as JobsAdapter which can be used both for all jobs and my jobs tabs.

@OrangeAndGreen OrangeAndGreen added this to the 2.55 milestone Sep 14, 2023
@shubham1g5
Copy link
Contributor

@OrangeAndGreen Wants to flag that this PR has taken the same course as earlier Connect PR and is becoming very big to manage. Not asking to change anything with the current PR but we must shift our approach on future connect work to do smaller PRs with smaller commits and try to close existing PRs proactively by requesting reviews on them and addressing feedback before taking on new work. As an example, This Android 13 PR demonstrates how to break changes in individual commits for them to be easily reviewed by commit.

import org.json.JSONObject;

@Table(ConnectAppInfo.STORAGE_KEY)
public class ConnectAppInfo extends Persisted {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can we just call it ConnectApp (Similar to ConnectJob) ? We can also do ConnectAppRecord and ConnectJobRecord looking at other similar meta data classes in code base.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

54feb9e (and oops, also 5052252)

public String description;
@Persisting(7)
@MetaField(META_ORGANIZATION)
public String organization;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curious how is organization different from domain ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the idea here is to get a displayable name for the organization that's providing the opportunity. In practice what I'm seeing right now is that the organization I get from the server is my username with Connect (i.e. the username of the app designer). That's probably just a placeholder or default value of some sort, but it's different than the domain. It's also worth nothing that the domain for the learn and deliver apps does not have to be the same.

Comment on lines 52 to 56
app.domain = json.has(META_DOMAIN) ? json.getString(META_DOMAIN) : null;
app.appId = json.has(META_APP_ID) ? json.getString(META_APP_ID) : null;
app.name = json.has(META_NAME) ? json.getString(META_NAME) : null;
app.description = json.has(META_DESCRIPTION) ? json.getString(META_DESCRIPTION) : null;
app.organization = json.has(META_ORGANIZATION) ? json.getString(META_ORGANIZATION) : null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we know what fields here are optional and what not ? I would like us to throw an exception from here for fields like domain and appID which I would suppose are mandatory fields. We should also appropriately mark nullable fields with @nullable and @Persisting(nullable = true) annotations in their declarations.

this.deliveries = deliveries;
}

public static ConnectJob fromJson(JSONObject json) throws JSONException, ParseException {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment as ConnectAppInfo that we should do data validation here for mandatory properties.

return getJobs(context, ConnectJob.STATUS_LEARNING);
}

public static List<ConnectJob> getClaimdeJobs(Context context) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: spelling

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in f6c3b16

@@ -136,4 +140,74 @@ public static void setRegistrationPhase(Context context, ConnectIdTask phase) {
storeUser(context, user);
}
}

public static void storeAvailableJobs(Context context, List<ConnectJob> jobs) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: should we rename the class to ConnectDatabaseHelper since we are using it for all connect db helpers

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I'll also rename ConnectIdNetworkHelper to drop the Id since it's also being used more widely now. Is there a better place for these classes to live instead of in the activities folder?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding ConnectIdSsoHelper to this list also

}

if(!stillExists) {
getConnectStorage(context, ConnectJob.class).remove(existing.getID());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about using removeAll instead with a list of ids ? (bulk db operation vs multiple singular ones)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines 164 to 170
for (ConnectJob existingJob : existingList) {
if(newJob.getID() == existingJob.getID()) {
//To update, set ID for the new job from the existing
newJob.setID(existingJob.getID());
break;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we merge this with the loop to find non-existing jobs ? They are both nXn loops so I will prefer to only do these iterations once if possible.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improved in f6c3b16 so that the first nXn loop sets the ID for jobs found in the existing list, reducing the second nXn loop to only n.

HashMap<String, String> headers = new HashMap<>();
RequestBody requestBody;

//TODO: Figure out how to send GET request the right way
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we define a Retrofit Interfaces for standard connect Urls in a separate class like - ConnectRequestEndpoints . You can define method like - public Response<ResponseBody> getJobs(String uri, Multimap<String, String> httpParams, Map<String, String> httpHeaders) throws IOException { in there and define corresponding job url with annotations right in that interface. CommCare Urls are not static (they change for every domain) which is why we don't adpot the similar strategy for CC but we don't have that constraint with connect urls.

@@ -70,7 +70,24 @@ public static AuthInfo.TokenAuth acquireSsoTokenSync(Context context) {
return hqTokenAuth;
}

private static AuthInfo.TokenAuth retrieveConnectToken(Context context) {
public static void retrieveConnectTokenAsync(Context context, TokenCallback callback) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like what's happening here is - Fragment(UI) -> getConnectOpportunities(UI) -> retrieveConnectTokenAsync(UI) -> creates a new thread(t) -> callback(t) -> getInternal()(t) -> triggers AsyncTask(t) . My question is does not an async task needs to get triggered from UI thread ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the code to use an AsyncTask instead, ae8132a

@OrangeAndGreen
Copy link
Contributor Author

@damagatchi retest this please

2 similar comments
@shubham1g5
Copy link
Contributor

@damagatchi retest this please

@shubham1g5
Copy link
Contributor

@damagatchi retest this please

@OrangeAndGreen OrangeAndGreen added the skip-integration-tests Skip android tests. label Oct 3, 2023
* @param context Android context to launch the CommCare with
* @param appId Unique Id for CommCare App that CommCare should launch with
*/
public static void launchCommCareForAppIdFromConnect(Context context, String appId) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Support library should only host methods that are useful for external Apps to integrate with CC, Since this method is connect specific, we should not add it in support library.


private void updateUpdatedDate(Date lastUpdate) {
DateFormat df = SimpleDateFormat.getDateTimeInstance();
updateText.setText(getString(R.string.connect_last_update, df.format(lastUpdate)));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this crashes for me sometimes -

java.lang.IllegalStateException: Fragment ConnectJobsListsFragment{ed114d0} (0884a7a8-bf3a-40a4-a085-088e94a4da8b) not attached to a context.
        at androidx.fragment.app.Fragment.requireContext(Fragment.java:972)
        at androidx.fragment.app.Fragment.getResources(Fragment.java:1036)
        at androidx.fragment.app.Fragment.getString(Fragment.java:1071)
        at org.commcare.fragments.connect.ConnectJobsListsFragment.updateUpdatedDate(ConnectJobsListsFragment.java:154)
        at org.commcare.fragments.connect.ConnectJobsListsFragment.-$$Nest$mupdateUpdatedDate(Unknown Source:0)
        at org.commcare.fragments.connect.ConnectJobsListsFragment$3.processSuccess(ConnectJobsListsFragment.java:132)
        at org.commcare.activities.connect.ConnectNetworkHelper$1.processSuccess(ConnectNetworkHelper.java:295)```

@OrangeAndGreen
Copy link
Contributor Author

@damagatchi retest this please

@OrangeAndGreen
Copy link
Contributor Author

@damagatchi retest this please

@OrangeAndGreen
Copy link
Contributor Author

@damagatchi retest this please

1 similar comment
@OrangeAndGreen
Copy link
Contributor Author

@damagatchi retest this please

@OrangeAndGreen
Copy link
Contributor Author

@damagatchi retest this please

2 similar comments
@OrangeAndGreen
Copy link
Contributor Author

@damagatchi retest this please

@OrangeAndGreen
Copy link
Contributor Author

@damagatchi retest this please

@OrangeAndGreen OrangeAndGreen changed the base branch from feature/connect to dv/connectid_catchup August 27, 2024 17:25
@OrangeAndGreen
Copy link
Contributor Author

@damagatchi retest this please

@OrangeAndGreen
Copy link
Contributor Author

@damagatchi retest this please

3 similar comments
@OrangeAndGreen
Copy link
Contributor Author

@damagatchi retest this please

@OrangeAndGreen
Copy link
Contributor Author

@damagatchi retest this please

@OrangeAndGreen
Copy link
Contributor Author

@damagatchi retest this please

@OrangeAndGreen OrangeAndGreen changed the base branch from dv/connectid_catchup to feature/connect December 5, 2024 19:52
@avazirna avazirna modified the milestones: 2.55, 2.56 Dec 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
skip-integration-tests Skip android tests.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants