Skip to content

Internal mode improvement#11

Merged
justanotheratom merged 8 commits intomainfrom
internal-mode-improvement
Nov 13, 2025
Merged

Internal mode improvement#11
justanotheratom merged 8 commits intomainfrom
internal-mode-improvement

Conversation

@Gaurav-eightinity01
Copy link
Copy Markdown
Collaborator

@Gaurav-eightinity01 Gaurav-eightinity01 commented Nov 7, 2025

Note

Adds an internal mode toggle that registers with PostHog and syncs to Supabase user metadata, plus settings UI loading states for sign-out/reset.

  • Internal Mode:
    • Add AppConstants.Prefs.INTERNAL_FLAGS and helpers isInternalEnabled(...)/setInternalEnabled(...).
    • On app start (IngrediCheckApp), register PostHog super property is_internal.
    • New Analytics helpers: identifyAndRegister(...), registerInternal(...), resetAndRegister(...).
    • AppleAuthViewModel:
      • On session changes/sign-ins, call updateAnalyticsAndSupabase(...) to identify user in PostHog and updateUser { data { put("is_internal", ...) } } in Supabase.
      • Add enableInternalMode(...)/disableInternalMode(...) to toggle flag and update analytics/user metadata.
      • On sign-out, reset PostHog and re-register is_internal.
  • Settings UI (SettingScreen):
    • Hidden tap gesture (7 taps) on version row to enable internal mode; visible "Internal Mode Enabled" row (7 taps) to disable, with toasts.
    • Add loading indicators and disabled interaction for "Sign Out", "Reset App State", and "Delete Data & Account" via IconRow trailingLoading.
    • IconRow updated to show a trailing spinner and disable clicks when loading.
  • CI:
    • Rename workflow job display name to Build APK.

Written by Cursor Bugbot for commit a318fd1. This will update automatically on new commits. Configure here.

Introduces internal mode toggling in settings, with tap gestures to enable/disable and persistent storage via SharedPreferences. Integrates internal mode state with analytics (PostHog) and updates user metadata in Supabase. Also adds loading indicators to settings actions and refactors analytics registration and user metadata update logic.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

userEmail = session.user?.email
userId = session.user?.id
Log.d("AppleAuthViewModel", "User data extracted - Email: $userEmail, ID: $userId")
AppleLoginState.Success(session)
},

P1 Badge Sync analytics after Apple code login

The success branch of signInWithAppleCode populates local state and returns AppleLoginState.Success but never calls updateAnalyticsAndSupabase(session). All other sign‑in paths introduced in this commit perform that call to identify the user in PostHog and push the is_internal flag to Supabase. As a result, users authenticating through the authorization-code flow will never have their analytics identity or metadata updated, so internal-mode tracking remains stale for them.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@justanotheratom
Copy link
Copy Markdown
Contributor

💡 Codex Review

userEmail = session.user?.email
userId = session.user?.id
Log.d("AppleAuthViewModel", "User data extracted - Email: $userEmail, ID: $userId")
AppleLoginState.Success(session)
},

P1 Badge Sync analytics after Apple code login
The success branch of signInWithAppleCode populates local state and returns AppleLoginState.Success but never calls updateAnalyticsAndSupabase(session). All other sign‑in paths introduced in this commit perform that call to identify the user in PostHog and push the is_internal flag to Supabase. As a result, users authenticating through the authorization-code flow will never have their analytics identity or metadata updated, so internal-mode tracking remains stale for them.

ℹ️ About Codex in GitHub

@Gaurav-eightinity01 , look into this

@justanotheratom justanotheratom self-requested a review November 10, 2025 10:46
Copy link
Copy Markdown
Contributor

@justanotheratom justanotheratom left a comment

Choose a reason for hiding this comment

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

address the one comment by codex.
And confirm whether is_internal is getting populated in backend.

Apple authorization-code login now calls
updateAnalyticsAndSupabase(session)
 on success.
This aligns the Apple code flow with other sign-in paths (Google, Apple ID token).
Result: PostHog identify + super property registration happens, and Supabase is_internal metadata is synced based on the stored flag.
Comment thread app/src/main/java/lc/fungee/IngrediCheck/model/repository/LoginAuthRepository.kt Outdated
Replaces the call to repository.updateUserMetadata with a direct call to repository.supabaseClient.auth.updateUser, updating the 'is_internal' field. Adds error handling to catch exceptions during the update.
Comment thread app/src/main/java/lc/fungee/IngrediCheck/model/repository/LoginAuthRepository.kt Outdated

private val httpClient: OkHttpClient = OkHttpClient()

suspend fun updateUserMetadata(metadata: Map<String, Any>): Result<Unit> = withContext(Dispatchers.IO) {
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.

remove this method if it is not called from anywhere anymore

Deleted the updateUserMetadata suspend function and related OkHttp imports from LoginAuthRepository as they are no longer used. This cleans up the repository and removes unnecessary dependencies.
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

This PR is being reviewed by Cursor Bugbot

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

Bug: Google Login: Incomplete User Data Sync

The signInWithGoogleIdToken method is missing the updateAnalyticsAndSupabase(session) call in its success handler. All other login methods (Apple ID token, Apple code, anonymous, and token imports) were updated in this commit to call updateAnalyticsAndSupabase after successful authentication, but Google login was overlooked. This causes Google users' internal mode status and analytics data not to sync with Supabase and PostHog upon login.

app/src/main/java/lc/fungee/IngrediCheck/viewmodel/LoginAuthViewModel.kt#L249-L277

fun signInWithGoogleIdToken(idToken: String, context: Context) {
Log.d("AppleAuthViewModel", "signInWithGoogleIdToken called")
_loginState.value = AppleLoginState.Loading
viewModelScope.launch {
try {
val result = repository.signInWithGoogleIdTokenSdk(idToken)
val newState = result.fold(
onSuccess = { session ->
Log.d("AppleAuthViewModel", "Google login successful")
context.getSharedPreferences(AppConstants.Prefs.USER_SESSION, Context.MODE_PRIVATE)
.edit()
.putString(AppConstants.Prefs.KEY_LOGIN_PROVIDER, AppConstants.Providers.GOOGLE)
.apply()
userEmail = session.user?.email
userId = session.user?.id
AppleLoginState.Success(session)
},
onFailure = { exception ->
Log.e("AppleAuthViewModel", "Google login failed", exception)
AppleLoginState.Error(exception.localizedMessage ?: "Google sign-in failed")
}
)
_loginState.value = newState
} catch (e: Exception) {
Log.e("AppleAuthViewModel", "Exception during Google login", e)
_loginState.value = AppleLoginState.Error("Login failed: ${e.message}")
}
}

Fix in Cursor Fix in Web


Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

This PR is being reviewed by Cursor Bugbot

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

Bug: Incomplete Google Sign-In Flow

The signInWithGoogleIdToken method doesn't call updateAnalyticsAndSupabase(session) after successful login, unlike all other sign-in methods (signInWithAppleIdToken, signInWithAppleCode, signInAnonymously, and completeWithSupabaseTokens). This means Google users won't have their analytics identified or their internal mode flag synced to Supabase, breaking parity with other authentication flows.

app/src/main/java/lc/fungee/IngrediCheck/viewmodel/LoginAuthViewModel.kt#L249-L268

fun signInWithGoogleIdToken(idToken: String, context: Context) {
Log.d("AppleAuthViewModel", "signInWithGoogleIdToken called")
_loginState.value = AppleLoginState.Loading
viewModelScope.launch {
try {
val result = repository.signInWithGoogleIdTokenSdk(idToken)
val newState = result.fold(
onSuccess = { session ->
Log.d("AppleAuthViewModel", "Google login successful")
context.getSharedPreferences(AppConstants.Prefs.USER_SESSION, Context.MODE_PRIVATE)
.edit()
.putString(AppConstants.Prefs.KEY_LOGIN_PROVIDER, AppConstants.Providers.GOOGLE)
.apply()
userEmail = session.user?.email
userId = session.user?.id
AppleLoginState.Success(session)
},
onFailure = { exception ->
Log.e("AppleAuthViewModel", "Google login failed", exception)

Fix in Cursor Fix in Web


) {
if (!isSignOutLoading) {
isSignOutLoading = true
clearAllSession()
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: Permanent Loading Blocks User Interaction

The loading states isSignOutLoading, isDeleteAccountLoading, and isResetLoading are set to true but never reset to false. If onRequireReauth() navigation fails or any operation errors occur before reaching it, the UI remains permanently stuck with a spinner and disabled buttons, preventing users from retrying the action.

Fix in Cursor Fix in Web

@justanotheratom justanotheratom merged commit 637cd84 into main Nov 13, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants