feat: confetti on task complete#227
Conversation
WalkthroughChanges span UI enhancements across Telegram and web-app components, including a slide-left animation on task cards, badge display in navigation, an in-progress task filter option, and a celebratory confetti effect triggered upon task completion with supporting composable infrastructure. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant CompleteTask
participant useConfetti
participant index.vue
participant Timeout
User->>CompleteTask: Complete task
CompleteTask->>useConfetti: Call pop()
useConfetti->>useConfetti: Set isShown = true
useConfetti->>index.vue: isShown state updated
index.vue->>index.vue: Render confetti container
useConfetti->>Timeout: Schedule 5s timeout
Timeout->>useConfetti: Timeout expires
useConfetti->>useConfetti: Set isShown = false
useConfetti->>index.vue: isShown state updated
index.vue->>index.vue: Hide confetti container
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes The diff includes multiple files with straightforward additions (animations, badge UI, filter logic) and a new composable with state management. While mostly following existing patterns, the variety of changes and cross-component integrations (particularly the confetti feature spanning three files) warrant moderate review attention for logical consistency and proper state handling. Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
apps/atrium-telegram/app/composables/useNavigation.ts (1)
38-38: Consider using a dynamic badge or documenting the static value.Unlike other navigation routes that use dynamic badges based on store state, this route uses a hardcoded
'+1'string. If this is intentional (e.g., to indicate a new feature), consider:
- Adding a comment explaining the static badge
- Making it configurable via a feature flag
- Using i18n for consistency with other UI strings
apps/web-app/app/composables/useConfetti.ts (1)
1-14: Add timeout cleanup to prevent memory leaks.The current implementation doesn't clean up the timeout if the component unmounts or if
pop()is called multiple times in quick succession. This could lead to memory leaks or unexpected behavior.Apply this diff to add proper cleanup:
+import { onUnmounted } from 'vue' + function _useConfetti() { const isShown = ref(false) + let timeoutId: NodeJS.Timeout | null = null function pop() { + if (timeoutId) { + clearTimeout(timeoutId) + } isShown.value = true - setTimeout(() => { + timeoutId = setTimeout(() => { isShown.value = false + timeoutId = null }, 5000) } + onUnmounted(() => { + if (timeoutId) { + clearTimeout(timeoutId) + } + }) + return { isShown, pop } } export const useConfetti = createSharedComposable(_useConfetti)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
apps/atrium-telegram/app/components/TaskInfoCard.vue(1 hunks)apps/atrium-telegram/app/composables/useNavigation.ts(1 hunks)apps/atrium-telegram/app/pages/all-tasks/index.vue(3 hunks)apps/atrium-telegram/app/pages/navigation.vue(2 hunks)apps/web-app/app/components/form/CompleteTask.vue(2 hunks)apps/web-app/app/composables/useConfetti.ts(1 hunks)apps/web-app/app/pages/index.vue(2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (5)
apps/atrium-telegram/app/components/TaskInfoCard.vue (1)
2-2: LGTM!The slide-left animation enhances the task card entrance. The implementation is clean and consistent with other motion presets used throughout the app.
apps/atrium-telegram/app/pages/all-tasks/index.vue (1)
33-33: LGTM!The new "in progress" filter is implemented correctly and follows the established pattern. The logic properly identifies tasks without completion dates.
Also applies to: 119-119, 129-131, 139-140
apps/web-app/app/components/form/CompleteTask.vue (1)
67-67: LGTM!The confetti integration is clean and well-placed. Triggering the celebration after the success toast provides excellent user feedback without interfering with the existing flow.
Also applies to: 103-103
apps/atrium-telegram/app/pages/navigation.vue (1)
18-28: LGTM!The conditional badge rendering is implemented correctly with nice visual polish using the animated pointer icon.
apps/web-app/app/pages/index.vue (1)
2-10: LGTM!The confetti implementation is well-structured:
ClientOnlywrapper correctly handles the client-side-only library- Optional chaining on
confetti?.clientHeightandconfetti?.clientWidthsafely handles the initial null state- The fixed positioning and z-index ensure the confetti displays above all content
- Configuration parameters (particleCount, duration, force) provide a balanced celebratory effect
Also applies to: 87-87, 93-94
| label: 'Задачи', | ||
| to: '/all-tasks', | ||
| icon: 'i-lucide-list-checks', | ||
| badge: 'апдейт', |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
Use i18n for the badge text.
The hardcoded Russian text 'апдейт' bypasses the internationalization system used elsewhere in the app.
Apply this diff to use i18n:
{
label: 'Задачи',
to: '/all-tasks',
icon: 'i-lucide-list-checks',
- badge: 'апдейт',
+ badge: t('app.navigation.tasks.badge'),
onClick: () => vibrate(),
},Then add the corresponding translation key to your locale files.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| badge: 'апдейт', | |
| { | |
| label: 'Задачи', | |
| to: '/all-tasks', | |
| icon: 'i-lucide-list-checks', | |
| badge: t('app.navigation.tasks.badge'), | |
| onClick: () => vibrate(), | |
| }, |
🤖 Prompt for AI Agents
In apps/atrium-telegram/app/pages/navigation.vue around line 63, the badge
property is using hardcoded Russian text "апдейт"; replace it with an i18n key
reference (e.g., $t('navigation.badge.update') or use the component/composable
translation helper used in the project) and update the callsite accordingly so
the badge reads from translations instead of a literal string; then add the
corresponding translation key "navigation.badge.update" (and translations for
other supported locales) to the project's locale files.



Summary by CodeRabbit
Release Notes