Skip to content

feat: add shake gesture for ticket QR access#649

Open
Akriti1331 wants to merge 6 commits into
roshankumar0036singh:mainfrom
Akriti1331:feature-unicoin-rewards
Open

feat: add shake gesture for ticket QR access#649
Akriti1331 wants to merge 6 commits into
roshankumar0036singh:mainfrom
Akriti1331:feature-unicoin-rewards

Conversation

@Akriti1331

@Akriti1331 Akriti1331 commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Implemented a shake gesture feature that allows users to quickly access their ticket QR code.

Changes Made

  • Added a reusable useShakeGesture hook using expo-sensors
  • Added shake detection support in WalletScreen
  • Automatically opens the most recently purchased ticket when a shake is detected
  • Added fallback alert when no tickets are available
  • Added expo-sensors dependency

Notes

The repository structure has changed since the issue was opened and the referenced HomeScreen.tsx no longer exists. The feature was implemented in WalletScreen, which is the current entry point for accessing ticket QR codes.

Summary by CodeRabbit

  • New Features
    • You can now shake your device to quickly access a ticket from the wallet screen (with built-in cooldown to prevent repeated triggers).
  • Bug Fixes
    • Improved attendance rewards by increasing user points when attendance check-ins are processed, using a consistent reward value.

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@Akriti1331, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 50 minutes and 25 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 17bfe507-9c22-4eec-8415-7281b82e4832

📥 Commits

Reviewing files that changed from the base of the PR and between e465710 and d61a63e.

📒 Files selected for processing (1)
  • app/src/hooks/useShakeGesture.js
📝 Walkthrough

Walkthrough

Adds a shake-gesture interaction to WalletScreen using a new useShakeGesture hook backed by expo-sensors Accelerometer. Also adds expo-sensors to package.json. Independently, the attendanceStreak Cloud Function is updated to increment a points field by 10 on each valid attendance check-in.

Changes

Shake Gesture for Ticket Navigation

Layer / File(s) Summary
useShakeGesture hook and expo-sensors dependency
app/package.json, app/src/hooks/useShakeGesture.js
expo-sensors (~12.3.0) is added as a runtime dependency. The useShakeGesture hook sets a 100ms Accelerometer interval, computes magnitude from x/y/z readings, fires onShake when magnitude exceeds 2.2 with a 1-second cooldown, and removes the subscription on cleanup.
WalletScreen shake integration
app/src/screens/WalletScreen.js
Alert and useShakeGesture are imported. A shake callback is registered that shows a "No Tickets" alert when the ticket list is empty, or navigates to TicketScreen with the first ticket's id and full data otherwise.

Attendance Points Reward

Layer / File(s) Summary
Points increment in attendance transaction
cloud-functions/src/attendanceStreak.ts
Defines ATTENDANCE_POINTS_REWARD = 10 and adds a points field increment by that constant inside the existing tx.update Firestore transaction call.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • roshankumar0036singh/Uni-Event#619: Modifies cloud-functions/src/attendanceStreak.ts to introduce ATTENDANCE_POINTS_REWARD and increment points in the attendance transaction.

Suggested labels

level:intermediate, quality:clean

Suggested reviewers

  • roshankumar0036singh

Poem

🐇 Shake, shake, shake the phone so bright,
A ticket appears — what a delight!
The accelerometer hums at 100ms pace,
Points stack up with every check-in grace.
Hop along, the sensors sing,
Code delivered on a spring! 🌱

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ 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%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 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: implementing a shake gesture feature for accessing ticket QR codes, which is reflected in the new useShakeGesture hook and its integration into WalletScreen.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/package.json`:
- Around line 1-118: The package.json file is not properly formatted according
to Prettier standards, causing CI warnings. Run the format command using the
prettier script defined in the scripts section of this package.json (the
"format" script) to automatically reformat and normalize the JSON output, then
commit the normalized file to clear the CI warnings.

In `@app/src/hooks/useShakeGesture.js`:
- Around line 5-21: The useEffect dependency on onShake causes the effect to
recreate whenever the onShake callback reference changes, which resets the
lastShake variable (line 6) and bypasses the 1-second cooldown. To preserve the
cooldown state across re-renders and effect recreations, convert the lastShake
variable from a regular let declaration to a useRef hook, so that the timestamp
persists even when the effect tears down and rebuilds due to onShake identity
changes.

In `@app/src/screens/WalletScreen.js`:
- Around line 27-31: In the useShakeGesture callback, add a check to return
early if the loading state is true before checking if tickets.length is empty.
This prevents the "No Tickets" alert from being shown while data is still being
fetched, since tickets starts as an empty array by default. Add a condition like
if (loading) return; before the existing if (!tickets.length) check in the shake
gesture handler.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ee508c48-98da-4884-a888-07987054a33d

📥 Commits

Reviewing files that changed from the base of the PR and between 100ceb3 and 251135f.

⛔ Files ignored due to path filters (1)
  • app/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (4)
  • app/package.json
  • app/src/hooks/useShakeGesture.js
  • app/src/screens/WalletScreen.js
  • cloud-functions/src/attendanceStreak.ts

Comment thread app/package.json
Comment thread app/src/hooks/useShakeGesture.js Outdated
Comment thread app/src/screens/WalletScreen.js
@roshankumar0036singh

Copy link
Copy Markdown
Owner

resolev the issues by coderabbit suggestions

@coderabbitai coderabbitai Bot left a comment

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.

Caution

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

⚠️ Outside diff range comments (1)
app/src/hooks/useShakeGesture.js (1)

5-21: ⚠️ Potential issue | 🔴 Critical

Move useRef to the top level of the hook.

Line 6 calls useRef inside the useEffect callback, which violates React Hooks rules (hooks must be called at the top level). Additionally, the effect dependency on onShake causes unnecessary subscription recreations whenever WalletScreen passes a new inline callback. Fix by moving lastShakeRef out of the effect and storing onShake in a ref to keep the subscription stable.

Proposed fix
 export default function useShakeGesture(onShake) {
+    const lastShakeRef = useRef(0);
+    const onShakeRef = useRef(onShake);
+
+    useEffect(() => {
+        onShakeRef.current = onShake;
+    }, [onShake]);
+
     useEffect(() => {
-        const lastShakeRef = useRef(0);
-
         Accelerometer.setUpdateInterval(100);
 
         const subscription = Accelerometer.addListener(({ x, y, z }) => {
             const acceleration = Math.sqrt(x * x + y * y + z * z);
             const now = Date.now();
 
             if (acceleration > 2.2 && now - lastShakeRef.current > 1000) {
                 lastShakeRef.current = now;
-                onShake?.();
+                onShakeRef.current?.();
             }
         });
 
         return () => subscription.remove();
-    }, [onShake]);
+    }, []);
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/src/hooks/useShakeGesture.js` around lines 5 - 21, In the useShakeGesture
hook, move the lastShakeRef declaration out of the useEffect callback to the top
level of the hook, as calling useRef inside useEffect violates React Hooks
rules. Additionally, create another useRef at the hook's top level to store the
onShake callback, then update the useEffect to reference this ref instead of
using onShake directly in the callback. This keeps the Accelerometer
subscription stable and removes the unnecessary dependency on onShake in the
effect's dependency array. Update the effect to call onShakeRef.current?.()
instead of onShake?.() and include only the necessary dependencies in the array.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@app/src/hooks/useShakeGesture.js`:
- Around line 5-21: In the useShakeGesture hook, move the lastShakeRef
declaration out of the useEffect callback to the top level of the hook, as
calling useRef inside useEffect violates React Hooks rules. Additionally, create
another useRef at the hook's top level to store the onShake callback, then
update the useEffect to reference this ref instead of using onShake directly in
the callback. This keeps the Accelerometer subscription stable and removes the
unnecessary dependency on onShake in the effect's dependency array. Update the
effect to call onShakeRef.current?.() instead of onShake?.() and include only
the necessary dependencies in the array.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: eda85cad-a384-4b8c-83e7-fafea9451ed8

📥 Commits

Reviewing files that changed from the base of the PR and between 92fa546 and e465710.

📒 Files selected for processing (2)
  • app/src/hooks/useShakeGesture.js
  • app/src/screens/WalletScreen.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/src/screens/WalletScreen.js

@sonarqubecloud

Copy link
Copy Markdown

@Akriti1331

Copy link
Copy Markdown
Contributor Author

Sir, @roshankumar0036singh, I have resolved the errors please once have an eye.

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