-
-
Notifications
You must be signed in to change notification settings - Fork 28
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
base: feature/connect
Are you sure you want to change the base?
Connect #2695
Conversation
There was a problem hiding this 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.
app/res/values/strings.xml
Outdated
@@ -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> |
There was a problem hiding this comment.
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)); |
There was a problem hiding this comment.
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()); |
There was a problem hiding this comment.
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> { |
There was a problem hiding this comment.
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 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 { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public String description; | ||
@Persisting(7) | ||
@MetaField(META_ORGANIZATION) | ||
public String organization; |
There was a problem hiding this comment.
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
?
There was a problem hiding this comment.
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.
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; |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: spelling
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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()); |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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; | ||
} | ||
} |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
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
@damagatchi retest this please |
* @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) { |
There was a problem hiding this comment.
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))); |
There was a problem hiding this comment.
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)```
…android into dv/connect_initial
Not defaulting to null for app record payloads.
…r leaves the page before an API call finishes.
…nto dv/connect_initial
…lavor to override to connect-staging.
…uling hearbeat, do the first request at the time of scheduling
Implements heartbeat for Connect
@damagatchi retest this please |
…ndary phone verification
…user logged in via ConnectID.
…and then new column.
@damagatchi retest this please |
@damagatchi retest this please |
1 similar comment
@damagatchi retest this please |
…nto dv/connect_initial
@damagatchi retest this please |
…care-android into dv/connect_initial. Fixed some merge conflicts.
@damagatchi retest this please |
…care-android into dv/connect_initial
…tal exception instead)
@damagatchi retest this please |
3 similar comments
@damagatchi retest this please |
@damagatchi retest this please |
@damagatchi retest this please |
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
Automated test coverage
No tests yet