Skip to content

Conversation

@seshanthS
Copy link
Collaborator

@seshanthS seshanthS commented Nov 12, 2025

Changes

Previous Flow

  1. User backups secret
  2. Click backup again
  3. Show success message, if its queued
  4. It may fail in the backend

New Flow

  1. User backups secret
  2. Click backup again
  3. Show success message, if its queued
  4. If fails -> show backup widget again

Other changes

  1. in /job/{}/status check data.success === true instead of completed
  2. Use data.message.

Summary by CodeRabbit

  • Bug Fixes
    • Improved backup state tracking and reset behavior for points backup functionality.
    • Enhanced job status handling to better manage edge cases during address verification.

✏️ Tip: You can customize this high-level summary in your review settings.

@seshanthS seshanthS requested a review from remicolin November 12, 2025 21:52
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 12, 2025

Walkthrough

Updates the backup points completion flow: the job status service response now uses a boolean success flag with optional message; the settings store adds an optional parameter to reset the completion state; the Points UI component now checks backup state and resets the completion flag when conditions are met.

Changes

Cohort / File(s) Summary
Backup State Management
app/src/stores/settingStore.ts
Updated setBackupForPointsCompleted signature to accept an optional boolean parameter (defaults to true) for controlling completion flag state, enabling reset capability.
UI Backup State Handling
app/src/components/navbar/Points.tsx
Added getBackupState selector integration to monitor backup pending/completed states; introduced new effect that resets hasCompletedBackupForPoints flag to false when no active backup exists but prior completion was recorded. Updated dependency array and comments for clarity.
Job Status Response Type
app/src/services/points/jobStatus.ts
Changed JobStatusResponse from discriminated status field to boolean success flag with optional message; 200 OK handling now evaluates success and applies special case: message 'Address already verified' is treated as completed rather than failed.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Areas requiring attention:

  • jobStatus.ts: The special-case handling for 'Address already verified' message—verify this is the intended semantics and that all callers expect completed status for this condition
  • Points.tsx: Confirm the new effect logic correctly prevents redundant state resets and doesn't introduce timing issues with polling or backup retries
  • settingStore.ts: Ensure callers of setBackupForPointsCompleted(false) are aware of the new reset capability and use it appropriately

Possibly related PRs

Poem

🎯 Points now backed up, flags reset clean,
Boolean success paints the scene,
Address verified, all's redeemed—
State flows smooth where backups gleamed! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: updating backup status handling to use the job status endpoint instead of a separate flag.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch SELF-1175

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@seshanthS seshanthS requested a review from transphorm November 12, 2025 21:52
@seshanthS seshanthS changed the title SELF-1222: Use Job status instead for backup status SELF-1175: Use Job status instead for backup status Nov 12, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
app/src/utils/points/jobStatus.ts (1)

7-10: Update JobStatusResponse type to match the actual API response.

The type definition still references status: 'complete' | 'failed', but the code at lines 36-44 now checks data.success (boolean) and data.message (string). This is a critical type mismatch that breaks type safety.

Update the type definition to reflect the actual API response structure:

 export type JobStatusResponse = {
   job_id: string;
-  status: 'complete' | 'failed';
+  success: boolean;
+  message?: string;
 };
app/src/stores/settingStore.ts (1)

34-34: Update the type declaration to match the implementation signature.

The PersistedSettingsState interface declares setBackupForPointsCompleted: () => void but the implementation at lines 110-111 now accepts an optional boolean parameter (value: boolean = true). This type mismatch breaks type safety.

Update the interface to reflect the new signature:

   hasCompletedBackupForPoints: boolean;
-  setBackupForPointsCompleted: () => void;
+  setBackupForPointsCompleted: (value?: boolean) => void;
   resetBackupForPoints: () => void;
🧹 Nitpick comments (1)
app/src/components/NavBar/Points.tsx (1)

90-93: Fix typos and clarify the comment.

The comment has grammatical errors ("ccan be delayed") and could be clearer about the purpose of this effect.

-  //we show the backup success message immediately. This flips the flag to false undo the action
-  //and to show the backup button again.
-  //Another way is to show success modal here, but this ccan be delayed (as polling can be upto 32 seconds)
+  // We show the backup success message immediately. This effect resets the flag to false
+  // to undo that action and show the backup button again once there are no pending or completed backups.
+  // Note: Showing the success modal here would be delayed (polling can take up to 32 seconds).
   useEffect(() => {
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 87a81a5 and 0e866da.

📒 Files selected for processing (4)
  • app/src/components/NavBar/Points.tsx (1 hunks)
  • app/src/screens/account/settings/CloudBackupScreen.tsx (3 hunks)
  • app/src/stores/settingStore.ts (1 hunks)
  • app/src/utils/points/jobStatus.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{js,ts,tsx,jsx,sol,nr}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{js,ts,tsx,jsx,sol,nr}: NEVER log sensitive data including PII (names, DOB, passport numbers, addresses), credentials, tokens, API keys, private keys, or session identifiers.
ALWAYS redact/mask sensitive fields in logs using consistent patterns (e.g., ***-***-1234 for passport numbers, J*** D*** for names).

Files:

  • app/src/components/NavBar/Points.tsx
  • app/src/screens/account/settings/CloudBackupScreen.tsx
  • app/src/stores/settingStore.ts
  • app/src/utils/points/jobStatus.ts
app/**/*.{ts,tsx}

📄 CodeRabbit inference engine (app/AGENTS.md)

Type checking must pass before PRs (yarn types)

Files:

  • app/src/components/NavBar/Points.tsx
  • app/src/screens/account/settings/CloudBackupScreen.tsx
  • app/src/stores/settingStore.ts
  • app/src/utils/points/jobStatus.ts
app/src/**/*.{ts,tsx,js,jsx}

⚙️ CodeRabbit configuration file

app/src/**/*.{ts,tsx,js,jsx}: Review React Native TypeScript code for:

  • Component architecture and reusability
  • State management patterns
  • Performance optimizations
  • TypeScript type safety
  • React hooks usage and dependencies
  • Navigation patterns

Files:

  • app/src/components/NavBar/Points.tsx
  • app/src/screens/account/settings/CloudBackupScreen.tsx
  • app/src/stores/settingStore.ts
  • app/src/utils/points/jobStatus.ts
🧠 Learnings (1)
📚 Learning: 2025-09-22T11:10:22.019Z
Learnt from: CR
Repo: selfxyz/self PR: 0
File: .cursorrules:0-0
Timestamp: 2025-09-22T11:10:22.019Z
Learning: Applies to src/screens/**/*.{js,ts,tsx,jsx} : Lazy load screens using `React.lazy()`, organize screens by feature modules.

Applied to files:

  • app/src/screens/account/settings/CloudBackupScreen.tsx
🧬 Code graph analysis (1)
app/src/components/NavBar/Points.tsx (1)
app/src/stores/pointEventStore.ts (1)
  • usePointEventStore (53-334)
⏰ Context from checks skipped due to timeout of 300000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: e2e-ios
  • GitHub Check: android-build-test
  • GitHub Check: analyze-android
  • GitHub Check: build-deps
  • GitHub Check: analyze-ios
🔇 Additional comments (1)
app/src/utils/points/jobStatus.ts (1)

39-42: Clarify the business logic for "Address already verified" special case.

When data.success === false but the message is "Address already verified", the status returns 'completed' instead of 'failed'. This special-case handling is counterintuitive—why does a failed response with this specific message indicate completion?

Consider documenting this business logic with a comment explaining why this particular failure message should be treated as success. For example:

// Special case: If verification fails because address is already verified,
// treat as completed since the end goal (verified address) is achieved
if (data.message && data.message === 'Address already verified') {
  return 'completed';
}

Comment on lines 132 to 134
setTimeout(() => {
navigation.navigate(params.returnToScreen);
}, 500);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Cleanup missing setTimeout timers to prevent memory leaks and stale navigation.

The three setTimeout calls delay navigation by 500ms but don't store the timer ID for cleanup. If the component unmounts during this delay, the navigation call will still execute, potentially causing errors or navigating from an unmounted component.

Store and clean up the timeout:

+  const timeoutRef = React.useRef<NodeJS.Timeout | null>(null);
+
+  React.useEffect(() => {
+    return () => {
+      if (timeoutRef.current) {
+        clearTimeout(timeoutRef.current);
+      }
+    };
+  }, []);

  // In handleICloudBackup:
  if (params?.returnToScreen) {
-    setTimeout(() => {
+    timeoutRef.current = setTimeout(() => {
      navigation.navigate(params.returnToScreen);
    }, 500);
  }

Apply similar changes to the other two setTimeout calls at lines 181-183 and 195-197.

Also consider documenting why the 500ms delay is necessary—this appears related to backup state synchronization but the rationale isn't clear from the code.

Also applies to: 181-183, 195-197

🤖 Prompt for AI Agents
In app/src/screens/account/settings/CloudBackupScreen.tsx around lines 132-134,
181-183 and 195-197, the setTimeout calls that delay navigation by 500ms are not
storing the timer IDs and therefore cannot be cleared on unmount; capture each
setTimeout return value into a const (e.g. const timeoutId = setTimeout(...)),
keep them in component scope (or state/ref) and clear them in the component
cleanup (useEffect return or componentWillUnmount) via clearTimeout(timeoutId);
apply this pattern to all three timeouts and add a short comment noting the
500ms rationale if still required.

removeSubscribedTopic: (topic: string) => void;
hasCompletedBackupForPoints: boolean;
setBackupForPointsCompleted: () => void;
setBackupForPointsCompleted: (value?: boolean) => void;
Copy link
Contributor

Choose a reason for hiding this comment

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

rather than keeping this here and have to derive it from data in the poinEvents store. what about adding a function to pointEvents store hasCompletedBackupForPoints

this would mean less state to worry about

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b69c0bf and 8bcccc4.

📒 Files selected for processing (2)
  • app/src/components/navbar/Points.tsx (1 hunks)
  • app/src/services/points/jobStatus.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (13)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{js,jsx,ts,tsx}: NEVER log sensitive data including PII (names, DOB, passport numbers, addresses), credentials, tokens, API keys, private keys, or session identifiers.
ALWAYS redact/mask sensitive fields in logs using consistent patterns (e.g., ***-***-1234 for passport numbers, J*** D*** for names).

Files:

  • app/src/services/points/jobStatus.ts
  • app/src/components/navbar/Points.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx,js,jsx}: Use React Navigation with createStaticNavigation for type-safe navigation in React Native applications.
Implement platform-specific handling with Platform.OS === 'ios' ? 'iOS' : 'Android' checks before platform-specific code in React Native.
Initialize native modules with initializeNativeModules() before any native operations in React Native.
Implement lazy loading for screens using React.lazy() in React Native applications.
Implement custom modal system with useModal hook and callback registry in React Native.
Integrate haptic feedback using useHapticNavigation hook in React Native navigation.
Use platform-specific initial routes: web uses 'Home', mobile uses 'Splash' in React Navigation.
Use Zustand for global state management in React Native applications.
Use custom hooks for complex state (useModal, useHapticNavigation) instead of inline logic.
Use AsyncStorage for simple data, SQLite for complex data, and Keychain for sensitive data in React Native.
Use @/ alias for src imports and @tests/ alias for test imports in TypeScript/JavaScript files.
Use conditional rendering with Platform.OS for platform-specific code in React Native.
Use Tamagui for UI components in React Native applications.
Do not log sensitive data in production, including identity verification and passport information.
Use Keychain for secure storage of sensitive data in React Native.
Implement proper cleanup of sensitive data after use.
Implement certificate validation for passport data verification.
Always use try-catch for async operations in React Native and TypeScript code.
Implement graceful degradation when native modules fail in React Native.
Provide user-friendly error messages in UI and error handlers.
Lazy load screens and components to optimize bundle size in React Native.
Prevent memory leaks in native modules in React Native.

Files:

  • app/src/services/points/jobStatus.ts
  • app/src/components/navbar/Points.tsx
**/*.{tsx,jsx,ts,js}

📄 CodeRabbit inference engine (.cursorrules)

Implement proper cleanup in useEffect and component unmount hooks in React.

Files:

  • app/src/services/points/jobStatus.ts
  • app/src/components/navbar/Points.tsx
**/{mobile,client,app,time,verification}/**/*.{ts,tsx,js,swift,kt}

📄 CodeRabbit inference engine (.cursor/rules/compliance-verification.mdc)

Use server-signed time tokens or chain block timestamps for trusted time in mobile clients, do not trust device wall-clock alone

Files:

  • app/src/services/points/jobStatus.ts
  • app/src/components/navbar/Points.tsx
**/{mobile,client,app,proof,zk}/**/*.{ts,tsx,js,swift,kt}

📄 CodeRabbit inference engine (.cursor/rules/compliance-verification.mdc)

**/{mobile,client,app,proof,zk}/**/*.{ts,tsx,js,swift,kt}: Include trusted time anchor in proof generation and verify time anchor authenticity before proof generation in mobile implementations
Achieve proof generation in <60 seconds on mid-tier mobile devices

Files:

  • app/src/services/points/jobStatus.ts
  • app/src/components/navbar/Points.tsx
app/src/**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/mobile-sdk-migration.mdc)

Use module mapping @/src/ and @tests/tests/src/ in app Jest configuration

Files:

  • app/src/services/points/jobStatus.ts
  • app/src/components/navbar/Points.tsx
**/*.{ts,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/mobile-sdk-migration.mdc)

**/*.{ts,tsx,js}: Never log PII, credentials, or private keys in production code; use DEBUG_SECRETS_TOKEN flag for debug-level secrets
Use consistent redaction patterns for sensitive fields in logs and test data

Files:

  • app/src/services/points/jobStatus.ts
  • app/src/components/navbar/Points.tsx
app/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/mobile-sdk-migration.mdc)

Update app to consume mobile-sdk-alpha modules after migration and validate all existing app tests pass

Files:

  • app/src/services/points/jobStatus.ts
  • app/src/components/navbar/Points.tsx
app/**/*.{ts,tsx,js,jsx,json,yml,yaml}

📄 CodeRabbit inference engine (app/AGENTS.md)

Ensure yarn nice passes (fixes linting and formatting) before creating a PR

Files:

  • app/src/services/points/jobStatus.ts
  • app/src/components/navbar/Points.tsx
app/**/*.{ts,tsx}

📄 CodeRabbit inference engine (app/AGENTS.md)

Ensure yarn types passes (TypeScript validation) before creating a PR

Files:

  • app/src/services/points/jobStatus.ts
  • app/src/components/navbar/Points.tsx
app/**/*.{ts,tsx,js,jsx,swift,kt,java}

📄 CodeRabbit inference engine (app/AGENTS.md)

app/**/*.{ts,tsx,js,jsx,swift,kt,java}: Flag security-sensitive operations and note performance implications in code comments
Ensure no sensitive data (PII, credentials, tokens) is present in logs

Files:

  • app/src/services/points/jobStatus.ts
  • app/src/components/navbar/Points.tsx
app/src/**/*.{ts,tsx,js,jsx}

⚙️ CodeRabbit configuration file

app/src/**/*.{ts,tsx,js,jsx}: Review React Native TypeScript code for:

  • Component architecture and reusability
  • State management patterns
  • Performance optimizations
  • TypeScript type safety
  • React hooks usage and dependencies
  • Navigation patterns

Files:

  • app/src/services/points/jobStatus.ts
  • app/src/components/navbar/Points.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursorrules)

Implement comprehensive error boundaries in React components.

Files:

  • app/src/components/navbar/Points.tsx
⏰ Context from checks skipped due to timeout of 300000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: test-common
  • GitHub Check: type-check
  • GitHub Check: build-deps
  • GitHub Check: e2e-ios
  • GitHub Check: android-build-test
  • GitHub Check: analyze-android
  • GitHub Check: analyze-ios
🔇 Additional comments (1)
app/src/services/points/jobStatus.ts (1)

7-11: Job status mapping to success flag and special-case looks sound

The new JobStatusResponse shape and the 200-handling using data.success (with the "Address already verified" idempotent-success override) align with the described backend behavior and avoid falsely treating that case as a failure. I don’t see correctness or security concerns in this mapping.

Also applies to: 37-45

Comment on lines +80 to +89
const getBackupState = usePointEventStore(state => {
const backups = state.events.filter(e => e.type === 'backup');
const isPending = backups.some(e => e.status === 'pending');
const isCompleted = backups.some(e => e.status === 'completed');
return {
pending: isPending,
completed: isCompleted,
started: isPending || isCompleted,
};
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find pointEventStore and related files
fd 'pointEventStore' -t f

Repository: selfxyz/self

Length of output: 89


🏁 Script executed:

#!/bin/bash
# Check file structure around the Points.tsx snippet
fd 'Points.tsx' -t f

Repository: selfxyz/self

Length of output: 92


🏁 Script executed:

#!/bin/bash
# Search for loadEvents calls and related event hydration
rg 'loadEvents' -A 5 -B 2

Repository: selfxyz/self

Length of output: 2287


🏁 Script executed:

#!/bin/bash
# Find and inspect pointEventStore to understand initial state and event structure
fd '(pointEventStore|point.*store)' -t f | head -5

Repository: selfxyz/self

Length of output: 89


🏁 Script executed:

#!/bin/bash
# Read the full pointEventStore.ts to understand state initialization and loadEvents
cat app/src/stores/pointEventStore.ts

Repository: selfxyz/self

Length of output: 11191


🏁 Script executed:

#!/bin/bash
# Read Points.tsx around the problematic lines to see full effect structure
cat -n app/src/components/navbar/Points.tsx | sed -n '70,180p'

Repository: selfxyz/self

Length of output: 4641


🏁 Script executed:

#!/bin/bash
# Check how hasCompletedBackupForPoints is used and where backup CTA is controlled
rg 'hasCompletedBackupForPoints' -B 2 -A 2 app/src/components/navbar/Points.tsx

Repository: selfxyz/self

Length of output: 998


🏁 Script executed:

#!/bin/bash
# Search for useSettingStore to understand persistence and initialization
fd 'useSettingStore\|settingStore' -t f

Repository: selfxyz/self

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Check the backup CTA rendering logic to confirm it uses hasCompletedBackupForPoints
rg 'backup.*CTA\|showBackup\|BackupButton' -A 3 -B 3 app/src/components/navbar/Points.tsx

Repository: selfxyz/self

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Look for where the backup UI is actually rendered in Points.tsx
cat -n app/src/components/navbar/Points.tsx | tail -100

Repository: selfxyz/self

Length of output: 2530


🏁 Script executed:

#!/bin/bash
# Search for backup button/action rendering in Points.tsx
rg 'backup\|Backup' app/src/components/navbar/Points.tsx -i

Repository: selfxyz/self

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Get more context from the middle of Points.tsx to see how backup is rendered
cat -n app/src/components/navbar/Points.tsx | sed -n '200,350p'

Repository: selfxyz/self

Length of output: 6299


🏁 Script executed:

#!/bin/bash
# Search for where backup card/action is conditionally rendered
cat -n app/src/components/navbar/Points.tsx | sed -n '350,500p'

Repository: selfxyz/self

Length of output: 5700


🏁 Script executed:

#!/bin/bash
# Look for actionCard or backup action rendering
rg 'actionCard|handleBackupSecret' app/src/components/navbar/Points.tsx -B 5 -A 5

Repository: selfxyz/self

Length of output: 1359


🏁 Script executed:

#!/bin/bash
# Check if isLoading is accessible to Points.tsx component
rg 'isLoading' app/src/components/navbar/Points.tsx

Repository: selfxyz/self

Length of output: 38


🏁 Script executed:

#!/bin/bash
# Verify the usePointEventStore selector exports and getBackupState usage
rg 'usePointEventStore.*state.*=>' app/src/components/navbar/Points.tsx -A 3

Repository: selfxyz/self

Length of output: 533


Backup reset effect clears completion flag before events hydrate from storage

The backup completion flag is cleared before loadEvents() populates stored events, causing the backup CTA to reappear for users who have already completed backup.

On initial mount:

  • state.events is empty, so getBackupState.pending and getBackupState.completed are both false
  • If hasCompletedBackupForPoints was persisted as true, the reset effect (lines 97–110) fires immediately and calls setBackupForPointsCompleted(false)
  • The backup card becomes visible (line 390: !hasUserBackedUpAccount() = true)
  • loadEvents() runs asynchronously in a separate effect (lines 174–176) and hydrates the completed backup event from storage
  • getBackupState.completed becomes true, but the flag is already cleared, and the effect no longer restores it
  • User now sees the backup CTA reappear despite having completed backup

The selector ignores the isLoading state, conflating "events not yet loaded" with "no backup events exist." Gate the reset logic on an explicit hydration flag (e.g., isLoading === false from pointEventStore), or move this responsibility into the job-processing layer that definitively knows when a backup job has failed.

🤖 Prompt for AI Agents
In app/src/components/navbar/Points.tsx around lines 80–89 (and related reset at
97–110, loadEvents effect 174–176, render at 390): the getBackupState selector
treats empty events as "no backup" and the reset effect clears the persisted
completion flag before stored events finish hydrating; to fix, include the
store's loading/hydration flag (e.g., isLoading or isHydrated) in the selector
and in the reset effect so you only consider events once isLoading === false (or
isHydrated === true). Concretely, read isLoading from pointEventStore alongside
events, compute pending/completed only when not loading, and change the reset
effect to early-return if loading; alternatively move the reset responsibility
into the job-processing layer that runs after loadEvents completes.

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.

3 participants