Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
360c885
adds research and claude plan for offline loading
shubham1g5 Feb 24, 2026
29bcae1
wip: iterate plan
shubham1g5 Mar 6, 2026
00cf4c6
Add design doc for Claude issue implementer workflow
shubham1g5 Mar 9, 2026
4b36d86
[AI] Add implementation plan for Claude issue implementer workflow
shubham1g5 Mar 9, 2026
a07dab9
[AI] Add TDD iteration design for offline-first Connect architecture
shubham1g5 Mar 10, 2026
7da4b93
[AI] Restructure offline-first plan to follow strict TDD with a/b pha…
shubham1g5 Mar 10, 2026
3ce3681
[AI] Add TDD implementation plan for offline-first Connect architecture
shubham1g5 Mar 10, 2026
af51927
[AI] Phase 0: Add DataState and RefreshPolicy sealed classes
shubham1g5 Mar 10, 2026
5ef5306
[AI] Phase 1a: Add failing tests for ConnectSyncPreferences and Conne…
shubham1g5 Mar 10, 2026
64fda8a
[AI] Phase 1a: Remove redundant same-package import in ConnectSyncPre…
shubham1g5 Mar 10, 2026
94eade6
[AI] Phase 1b: Implement ConnectSyncPreferences and ConnectRequestMan…
shubham1g5 Mar 10, 2026
e7b2633
[AI] Fix thread safety: add @Volatile to ConnectRequestManager.scope
shubham1g5 Mar 10, 2026
c1b6665
[AI] Phase 1.5a: Add failing tests for ConnectNetworkClient
shubham1g5 Mar 10, 2026
08fdff9
[AI] Phase 1.5a: Fix deprecated OkHttp API in ConnectNetworkClientTest
shubham1g5 Mar 10, 2026
70b1643
[AI] Phase 1.5b: Implement ConnectNetworkClient, ConnectApiService, C…
shubham1g5 Mar 10, 2026
121fa45
[AI] Phase 1.5b: Remove redundant import from ConnectNetworkHelper
shubham1g5 Mar 10, 2026
ea88482
[AI] Phase 1.5b: Fix stream leak and restore resume import
shubham1g5 Mar 10, 2026
3fb215a
[AI] Phase 2a: Add failing tests for ConnectRepository
shubham1g5 Mar 10, 2026
0c3a8d8
[AI] Phase 2a: Fix ConnectRepositoryTest quality issues
shubham1g5 Mar 10, 2026
a5e42ea
[AI] Phase 2b: Implement ConnectRepository with offline-first flow
shubham1g5 Mar 10, 2026
cf7fca0
[AI] Phase 2b: Restore RefreshPolicy abstract class with explanation
shubham1g5 Mar 10, 2026
e1d17b2
[AI] Phase 3a+4a: Add failing tests for ViewModels and Fragments
shubham1g5 Mar 10, 2026
c61b707
[AI] Phase 3a/4a: Add required per-state test stubs to fragment tests
shubham1g5 Mar 10, 2026
4d96793
[AI] Phase 3b: Add ConnectJobsListViewModel and migrate ConnectJobsLi…
shubham1g5 Mar 10, 2026
3c4468a
[AI] Phase 3b: Remove unused Toast import from ConnectJobsListsFragment
shubham1g5 Mar 10, 2026
feadf3c
[AI] Phase 4b: Add ConnectLearningProgressViewModel and migrate Conne…
shubham1g5 Mar 10, 2026
9de3658
init is not needed, removed
shubham1g5 Mar 12, 2026
a9bedad
minor lint and fail first changes
shubham1g5 Mar 17, 2026
a3dbffe
[AI] Address PR #3606 review comments
shubham1g5 Mar 17, 2026
9932950
fix code to pass in headers correctly
shubham1g5 Mar 24, 2026
7dd5c51
reset session timing after personal Id login
shubham1g5 Mar 31, 2026
cd1a128
Simplify failure path for sso token, always call the callback
shubham1g5 Mar 31, 2026
751a99d
syntax fixup for headers
shubham1g5 Mar 31, 2026
cb8b403
handle 0 jobs after sync better
shubham1g5 Mar 31, 2026
71c857f
correct exception handling and import
shubham1g5 Mar 31, 2026
8133100
cancel previous workflow if the new one is triggered
shubham1g5 Mar 31, 2026
d5f5c13
complete deferred while re-throwing exception
shubham1g5 Mar 31, 2026
d36c5db
always emits loading before making a network call
shubham1g5 Apr 2, 2026
faba487
bind the new network loading bar to loading methods
shubham1g5 Apr 2, 2026
1dbcac0
remove wait dialog as loading is now shown by the new netowrk bar, re…
shubham1g5 Apr 2, 2026
413adb6
clean up context handling by directly using application's context
shubham1g5 Apr 2, 2026
81f24d4
context and tests fixes for ConnectRepository
shubham1g5 Apr 2, 2026
f2e610a
remove generic exception catch and minor test edits
shubham1g5 Apr 3, 2026
55dc6af
clean up - remove claude plans and stubbed tests
shubham1g5 Apr 3, 2026
42a5663
enable offline status
shubham1g5 Apr 6, 2026
4ed2dbe
we no longer need cached data to be part of error state as we always …
shubham1g5 Apr 7, 2026
558a17e
abstract code better using observeDataState
shubham1g5 Apr 7, 2026
df28dc3
streamline refresh method and related calls
shubham1g5 Apr 7, 2026
c38396d
show offline status as a result of failed API call
shubham1g5 Apr 8, 2026
862b90e
Imlements method to get last sync time from sync prefs
shubham1g5 Apr 8, 2026
aa2c97c
Adds a success indicator
shubham1g5 Apr 8, 2026
4fb5cf3
Adds a failure indicator
shubham1g5 Apr 8, 2026
ddcb4fb
fixes an issue where error bar would show abruptly on half the screen…
shubham1g5 Apr 9, 2026
6619993
identify error state based on last emitted state
shubham1g5 Apr 9, 2026
95793ea
protect against terminal states being emitted as cached values immedi…
shubham1g5 Apr 9, 2026
e9cd81d
remove generic exception catch and minor cleanup
shubham1g5 Apr 9, 2026
cff2d2c
remove wait dialog from learn progress, dry code
shubham1g5 Apr 9, 2026
153decb
renaming and minor lintish changes
shubham1g5 Apr 10, 2026
e2097c3
code style and lint changes for connect network classes
shubham1g5 Apr 10, 2026
e6371c8
cleanup old learn progress network code
shubham1g5 Apr 10, 2026
4574bd4
remove padding from status bar
shubham1g5 Apr 10, 2026
090c7c5
handle token errors in the fragment layer
shubham1g5 Apr 20, 2026
2b3000c
remove redundant check as livedata will never emit emissions when fra…
shubham1g5 Apr 20, 2026
f3f212e
use constants
shubham1g5 Apr 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/connect_warning_color"
android:padding="5dp">
android:background="@color/connect_warning_color">

<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_error"
Expand Down
2 changes: 2 additions & 0 deletions app/res/values-es/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,8 @@
<string name="install_barcode_top">¡Bienvenido a CommCare!</string>
<string name="install_barcode_bottom">Por favor, elija un método de instalación a continuación</string>
<string name="connect_last_synced">Última sincronización: %s</string>
<string name="connect_sync_successful">Última sincronización: Justo ahora</string>
<string name="connect_sync_failed">Error al sincronizar actualizaciones, última sincronización: %s</string>
<string name="connect_offline">Sin conexión</string>
<string name="connect_never">Nunca</string>
</resources>
2 changes: 2 additions & 0 deletions app/res/values-fr/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,8 @@ License.
<string name="install_barcode_top">Bienvenue sur CommCare !</string>
<string name="install_barcode_bottom">Veuillez choisir une méthode d\'installation ci-dessous</string>
<string name="connect_last_synced">Dernière synchronisation : %s</string>
<string name="connect_sync_successful">Dernière synchronisation : À l\'instant</string>
<string name="connect_sync_failed">Échec de la synchronisation des mises à jour, dernière synchronisation : %s</string>
<string name="connect_offline">Hors ligne</string>
<string name="connect_never">Jamais</string>
</resources>
2 changes: 2 additions & 0 deletions app/res/values-ha/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,8 @@ Don cikakken aiki na wurin zama na aikace-aikace da yawa, da fatan za a yi sabon
<string name="notification_channel_user_session_title">Zaman mai amfani</string>
<string name="notification_channel_user_session_description">Sanarwa da ke ɗauke da bayani game da zaman mai amfani na yanzu, kamar ranar da ake sa ran zaman ya ƙare</string>
<string name="connect_last_synced">Aiki na ƙarshe: %s</string>
<string name="connect_sync_successful">Aiki na ƙarshe: Yanzu haka</string>
<string name="connect_sync_failed">An kasa daidaita sabuntawa, aiki na ƙarshe: %s</string>
<string name="connect_offline">Babu haɗi</string>
<string name="connect_never">Ba taɓa</string>
</resources>
2 changes: 2 additions & 0 deletions app/res/values-hi/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,8 @@ License.
<string name="install_barcode_top">CommCare में आपका स्वागत है!</string>
<string name="install_barcode_bottom">कृपया नीचे एक इंस्टॉलेशन विधि चुनें</string>
<string name="connect_last_synced">अंतिम सिंक: %s</string>
<string name="connect_sync_successful">अंतिम सिंक: अभी-अभी</string>
<string name="connect_sync_failed">अपडेट सिंक करने में विफल, अंतिम सिंक: %s</string>
<string name="connect_offline">ऑफ़लाइन</string>
<string name="connect_never">कभी नहीं</string>
</resources>
2 changes: 2 additions & 0 deletions app/res/values-lt/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@
<string name="connect_progress_warning_relearn_tasks_pending">Užbaikite paskirtas užduotis, kad galėtumėte toliau teikti paslaugas.</string>
<string name="connect_progress_relearn_tasks_completed">Visos reikalingos užduotys atliktos. Galite tęsti pristatymo veiklą.</string>
<string name="connect_last_synced">Paskutinė sinchronizacija: %s</string>
<string name="connect_sync_successful">Paskutinė sinchronizacija: Ką tik</string>
<string name="connect_sync_failed">Nepavyko sinchronizuoti naujinimų, paskutinė sinchronizacija: %s</string>
<string name="connect_offline">Neprisijungęs</string>
<string name="connect_never">Niekada</string>
</resources>
2 changes: 2 additions & 0 deletions app/res/values-no/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@
<string name="connect_progress_warning_relearn_tasks_pending">Fullfør tildelte oppgaver for å fortsette å levere tjenester.</string>
<string name="connect_progress_relearn_tasks_completed">Alle nødvendige oppgaver er fullført. Du kan fortsette med leveringsaktiviteter.</string>
<string name="connect_last_synced">Sist synkronisert: %s</string>
<string name="connect_sync_successful">Sist synkronisert: Akkurat nå</string>
<string name="connect_sync_failed">Kunne ikke synkronisere oppdateringer, sist synkronisert: %s</string>
<string name="connect_offline">Frakoblet</string>
<string name="connect_never">Aldri</string>
</resources>
2 changes: 2 additions & 0 deletions app/res/values-pt/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,8 @@
<string name="install_barcode_top">Bem-vindo ao CommCare!</string>
<string name="install_barcode_bottom">Por favor, escolha um método de instalação abaixo</string>
<string name="connect_last_synced">Última sincronização: %s</string>
<string name="connect_sync_successful">Última sincronização: Agora mesmo</string>
<string name="connect_sync_failed">Falha ao sincronizar atualizações, última sincronização: %s</string>
<string name="connect_offline">Offline</string>
<string name="connect_never">Nunca</string>
</resources>
2 changes: 2 additions & 0 deletions app/res/values-sw/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,8 @@
<string name="install_barcode_top">Karibu CommCare!</string>
<string name="install_barcode_bottom">Tafadhali chagua njia ya usakinishaji hapa chini</string>
<string name="connect_last_synced">Ilisawazishwa mwisho: %s</string>
<string name="connect_sync_successful">Ilisawazishwa mwisho: Sasa hivi</string>
<string name="connect_sync_failed">Imeshindwa kusawazisha masasisho, ilisawazishwa mwisho: %s</string>
<string name="connect_offline">Nje ya mtandao</string>
<string name="connect_never">Kamwe</string>
</resources>
2 changes: 2 additions & 0 deletions app/res/values-ti/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,8 @@
<string name="install_barcode_top">ናብ CommCare እንቋዕ ብድሓን መጻእኩም!</string>
<string name="install_barcode_bottom">በጃኹም ኣብ ታሕቲ ዘሎ ሜላ ምትካል ምረጹ</string>
<string name="connect_last_synced">ናይ መወዳእታ ምስንኻል: %s</string>
<string name="connect_sync_successful">ናይ መወዳእታ ምስንኻል: ሕጂ ሕጂ</string>
<string name="connect_sync_failed">ምስንኻል ሓዲሽ ነገር ኣይሰለጠን, ናይ መወዳእታ ምስንኻል: %s</string>
<string name="connect_offline">ኦፍላይን</string>
<string name="connect_never">ፈጺሙ</string>
</resources>
1 change: 1 addition & 0 deletions app/res/values/colors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@
<color name="connect_grey">#9A9A9A</color>
<color name="connect_divider_color">#E5E7EB</color>
<color name="connect_background_color">#f7f9fa</color>
<color name="connect_sky_blue">#87BDDF</color>
<color name="connect_aqua">#88BEE1</color>
<color name="connect_green">#16A085</color>
<color name="connect_light_green">#E6F5E5</color>
Expand Down
2 changes: 2 additions & 0 deletions app/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,8 @@

<string name="connect_last_update">Updated: %s</string>
<string name="connect_last_synced">Last synced: %s</string>
<string name="connect_sync_successful">Last synced: Just Now</string>
<string name="connect_sync_failed">Failed to sync updates, last synced: %s</string>
<string name="connect_offline">Offline</string>
<string name="connect_never">Never</string>
<string name="connect_title">Connect</string>
Expand Down
3 changes: 3 additions & 0 deletions app/src/org/commcare/CommCareApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
import org.commcare.utils.MarkupUtil;
import org.commcare.utils.MultipleAppsUtil;
import org.commcare.utils.PendingCalcs;
import org.commcare.connect.repository.ConnectSyncPreferences;
import org.commcare.utils.SessionRegistrationHelper;
import org.commcare.utils.SessionStateUninitException;
import org.commcare.utils.SessionUnavailableException;
Expand Down Expand Up @@ -219,6 +220,8 @@ public class CommCareApplication extends Application implements LifecycleEventOb
public void onCreate() {
super.onCreate();

ConnectSyncPreferences.Companion.getInstance(this).markSessionStart();
Comment thread
coderabbitai[bot] marked this conversation as resolved.

turnOnStrictMode();

CommCareApplication.app = this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId() == R.id.action_sync) {
RefreshableFragment refreshable = getRefreshableFragment();
if(refreshable != null) {
refreshable.refresh();
refreshable.refresh(true);
return true;
}
}
Expand Down
30 changes: 1 addition & 29 deletions app/src/org/commcare/connect/network/ApiConnect.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import retrofit2.Call;

public class ApiConnect {
private static final String API_VERSION_CONNECT = "1.0";
public static final String API_VERSION_CONNECT = "1.0";

public static void getConnectOpportunities(Context context, @NonNull ConnectUserRecord user, IApiCallback callback) {

Expand Down Expand Up @@ -80,33 +80,6 @@ public void tokenRequestDenied() {

}

public static void getLearningAppProgress(Context context, @NonNull ConnectUserRecord user, String jobUUID, IApiCallback callback) {

ConnectSsoHelper.retrievePersonalIdToken(context, user, new ConnectSsoHelper.TokenCallback() {
@Override
public void tokenRetrieved(AuthInfo.TokenAuth token) {

String tokenAuth = HttpUtils.getCredential(token);
ApiService apiService = ConnectApiClient.Companion.getClientApi();
HashMap<String, String> headers = new HashMap<>();
ConnectNetworkHelper.addVersionHeader(headers, API_VERSION_CONNECT);
Call<ResponseBody> call = apiService.getConnectLearningAppProgress(tokenAuth,jobUUID,headers);
BaseApi.Companion.callApi(context, call, callback,ApiEndPoints.connectLearnProgressURL);
}

@Override
public void tokenUnavailable() {
callback.processTokenUnavailableError();
}

@Override
public void tokenRequestDenied() {
callback.processTokenRequestDeniedError();
}
});

}

public static void claimJob(Context context, @NonNull ConnectUserRecord user, String jobUUID, IApiCallback callback) {
ConnectSsoHelper.retrievePersonalIdToken(context, user, new ConnectSsoHelper.TokenCallback() {
@Override
Expand All @@ -120,7 +93,6 @@ public void tokenRetrieved(AuthInfo.TokenAuth token) {
ApiService apiService = ConnectApiClient.Companion.getClientApi();
Call<ResponseBody> call = apiService.connectClaimJob(tokenAuth,jobUUID,headers,requestBody);
BaseApi.Companion.callApi(context, call, callback,ApiEndPoints.connectClaimJobURL);

}

@Override
Expand Down
6 changes: 0 additions & 6 deletions app/src/org/commcare/connect/network/ApiService.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,6 @@ Call<ResponseBody> connectStartLearningApp(@Header("Authorization") String token
@HeaderMap Map<String, String> headers,
@Body RequestBody connectStartLearningRequest);

@GET(ApiEndPoints.connectLearnProgressURL)
Call<ResponseBody> getConnectLearningAppProgress(@Header("Authorization") String token,
@Path("id") String uuid,
@HeaderMap Map<String, String> headers);


@POST(ApiEndPoints.connectClaimJobURL)
Call<ResponseBody> connectClaimJob(@Header("Authorization") String token,
@Path("id") String uuid,
Expand Down
23 changes: 23 additions & 0 deletions app/src/org/commcare/connect/network/ConnectApiService.kt
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We already have a class for this: ApiService in the org.commcare.connect.network package. Can we move all of those functions from there to here? This is a great opportunity to convert those Java functions to Kotlin

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Think that is not a straightfroward change and will increase the PR scope quite a lot as it would mean changing a lot of network methods and exposing all APIs via ConnectNetworkClient , we also can't really merge getConnectOpportunities from the two service classes as we need both suspend and callback implementations of this method at present unless we migrate all netowork api calls to use Coroutines.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I agree that this will be a significant scope change and I'm cool with leaving it as-is for now. But, how do you feel about creating a new backlog ticket to do this refactor? On first impression, it seems that we have two classes serving the same purpose at a high-level because they are both API services within Connect. Maybe we should also add a short code comment at the top of ConnectApiService explaining the difference between that and ApiService?

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.commcare.connect.network

import okhttp3.ResponseBody
import retrofit2.Response
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.HeaderMap
import retrofit2.http.Path

interface ConnectApiService {
@GET(ApiEndPoints.connectOpportunitiesURL)
suspend fun getConnectOpportunities(
@Header("Authorization") authorization: String,
@HeaderMap headers: Map<String, String>,
): Response<ResponseBody>

@GET(ApiEndPoints.connectLearnProgressURL)
suspend fun getLearningProgress(
@Header("Authorization") authorization: String,
@Path("id") jobId: String,
@HeaderMap headers: Map<String, String>,
): Response<ResponseBody>
}
81 changes: 0 additions & 81 deletions app/src/org/commcare/connect/network/ConnectNetworkHelper.java

This file was deleted.

Loading
Loading