-
Notifications
You must be signed in to change notification settings - Fork 11.5k
feat(companion): UI Enhancements for Android and Extension #26434
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
5 issues found across 29 files
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="companion/utils/bookings-utils.ts">
<violation number="1" location="companion/utils/bookings-utils.ts:303">
P2: Duplicated filter logic: `remainingCount` uses the same filter as `upcomingBookings` but filters `sortedBookings` again. Use `upcomingBookings.length` instead to avoid redundant iteration and improve maintainability.</violation>
</file>
<file name="companion/app/(tabs)/(event-types)/index.tsx">
<violation number="1" location="companion/app/(tabs)/(event-types)/index.tsx:608">
P2: This condition is dead code. The early return at line 508 already handles `filteredEventTypes.length === 0 && searchQuery.trim() !== ""` before the ScrollView is reached. Consider either removing the early return and keeping this ScrollView handling, or removing this unreachable branch.</violation>
</file>
<file name="companion/components/booking-list-item/RecurringBookingListItem.ios.tsx">
<violation number="1" location="companion/components/booking-list-item/RecurringBookingListItem.ios.tsx:23">
P2: The `onLongPress` prop is defined in the interface but never destructured or used in this iOS component. Unlike the base component which wires it to `TouchableOpacity.onLongPress`, this implementation silently ignores the callback. Consider either implementing the long-press handler or removing the prop from the interface.</violation>
</file>
<file name="companion/components/booking-list-item/RecurringBookingListItem.tsx">
<violation number="1" location="companion/components/booking-list-item/RecurringBookingListItem.tsx:128">
P2: The meeting link section duplicates the existing `MeetingLink` component from `BookingListItemParts.tsx`. Consider reusing that component instead of duplicating the logic, which improves maintainability and follows the codebase pattern established in `BookingListItem.tsx`.</violation>
</file>
<file name="companion/hooks/useEventTypeFilter.tsx">
<violation number="1" location="companion/hooks/useEventTypeFilter.tsx:171">
P2: Duplicated sorting logic. The same switch statement for sorting appears in two places (lines 88-102 and 159-173). Extract the sorting logic into a helper function to avoid duplication and improve maintainability.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
* feat(companion): unify dropdown menu for Android and extension - Merge Android-specific dropdown implementations into base component files - EventTypeListItem: Add DropdownMenu with Preview, Copy link, Edit, Duplicate, Delete actions - BookingListItem: Add DropdownMenu with booking actions (reschedule, edit location, add guests, etc.) - RecurringBookingListItem: Add DropdownMenu with recurring booking actions - AvailabilityListItem: Add DropdownMenu with Set as Default, Duplicate, Delete actions - BookingDetailScreen: Add DropdownMenu in header for Android with AlertDialog for cancel confirmation - Delete all .android.tsx files as implementations are now unified * fix(companion): fix typecheck errors after dropdown unification - Remove unused props from EventTypeListItem.ios.tsx (copiedEventTypeId, handleEventTypeLongPress) - Remove unused onActionsPress prop from BookingListItem.ios.tsx - Remove copiedEventTypeId and handleEventTypeLongPress props from index.ios.tsx and index.tsx - Remove onLongPress and onActionsPress props from BookingListScreen.tsx - Remove handleScheduleLongPress, setSelectedSchedule, setShowActionsModal props from AvailabilityListScreen.tsx - Fix BookingDetailScreen.tsx to use correct action property names (reschedule.visible instead of canReschedule, etc.) * fix(companion): remove unused code after dropdown unification - Remove unused handleEventTypeLongPress function and ActionSheetIOS import from index.ios.tsx - Remove unused copiedEventTypeId state, handleEventTypeLongPress function, and ActionSheetIOS import from index.tsx - Prefix unused setSelectedBooking with underscore in BookingListScreen.tsx - Remove unused handleScheduleLongPress function and ActionSheetIOS import from AvailabilityListScreen.tsx * feat(companion): unify booking filter UI for Android and extension - Remove SegmentedControl from web/extension booking list page - Use Header dropdown for booking status filter on both Android and web - Use unified event type filter dropdown for both platforms - Remove unused showFilterModal state and related code - Pass filterOptions, activeFilter, and onFilterChange to Header for all platforms * fix(companion): add header padding for web/extension to prevent button clipping - Add headerLeftContainerStyle and headerRightContainerStyle with 12px padding for web platform - Applied to root Stack and all nested tab Stack layouts - Fixes issue where header buttons were touching edges and getting chopped off on extension/web - Android remains unaffected as the fix is web-only * fix(companion): add HeaderButtonWrapper for web-only header padding - Create HeaderButtonWrapper component that adds 12px margin on web only - Wrap all header buttons with HeaderButtonWrapper to prevent clipping - Revert invalid screenOptions changes that caused typecheck errors - Apply fix to all screens with native header buttons: - reschedule.tsx, edit-location.tsx, add-guests.tsx - mark-no-show.tsx, view-recordings.tsx, meeting-session-details.tsx - event-type-detail.tsx, BookingDetailScreen.tsx, profile-sheet.tsx - edit-availability-day.tsx, edit-availability-name.tsx, edit-availability-override.tsx * update more ui-ux * address cubics comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
7 issues found across 46 files
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them.
<file name="companion/components/availability-list-item/AvailabilityListItem.tsx">
<violation number="1" location="companion/components/availability-list-item/AvailabilityListItem.tsx:104">
P2: The dropdown menu trigger is always rendered even when `scheduleActions` is empty. Consider conditionally rendering the dropdown only when there are actions available to avoid showing an empty menu.</violation>
</file>
<file name="companion/components/booking-list-screen/BookingListScreen.tsx">
<violation number="1" location="companion/components/booking-list-screen/BookingListScreen.tsx:347">
P2: Hardcoded strings in Alert.alert should use `t()` for localization. Consider using translation keys like `t('cancel_all_remaining')` and `t('cancel_all_remaining_confirmation', { count: group.remainingCount })`.</violation>
<violation number="2" location="companion/components/booking-list-screen/BookingListScreen.tsx:366">
P2: The try-catch around `cancelBookingMutation` is ineffective. React Query's `mutate` function doesn't throw - it uses the `onError` callback. The catch block will only handle synchronous errors (rare). Consider either removing the try-catch and relying solely on `onSuccess`/`onError`, or use `mutateAsync` if you need Promise-based error handling.</violation>
</file>
<file name="companion/components/booking-list-item/BookingListItem.tsx">
<violation number="1" location="companion/components/booking-list-item/BookingListItem.tsx:87">
P1: Missing `!isRejected` check in visibility condition. The `getBookingActions` utility already includes this check for reschedule actions. Consider using `actions.reschedule.visible && actions.reschedule.enabled` for consistency, or add `&& !isRejected` to the condition.</violation>
<violation number="2" location="companion/components/booking-list-item/BookingListItem.tsx:94">
P1: Missing `!isRejected` check in visibility condition. Consider adding `&& !isRejected` to match the `getBookingActions` utility logic.</violation>
<violation number="3" location="companion/components/booking-list-item/BookingListItem.tsx:101">
P1: Missing `!isRejected` check in visibility condition. Consider adding `&& !isRejected` to match the `getBookingActions` utility logic.</violation>
<violation number="4" location="companion/components/booking-list-item/BookingListItem.tsx:140">
P1: Missing `!isRejected` check in visibility condition. Consider adding `&& !isRejected` to match the `getBookingActions` utility logic.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
companion/components/availability-list-item/AvailabilityListItem.tsx
Outdated
Show resolved
Hide resolved
…React Query (#26490) * fix(companion): use cached getUserProfile() to reduce redundant /me API calls - Add in-flight promise deduplication to getUserProfile() to prevent concurrent callers from each making a /me API call - Update getEventTypes() to use getUserProfile() instead of getCurrentUser() - Update getBookings() to use getUserProfile() instead of getCurrentUser() - Clear in-flight promise in clearUserProfile() for proper logout cleanup This fixes the iOS bookings page slowness by eliminating redundant /me API calls. iOS was making 4 API calls on tab switch (2 redundant /me calls) vs Android's 2 calls because iOS eagerly loads event types at mount. * refactor(companion): use useEventTypes() hook on Android for unified caching - Replace manual useState + useEffect + useCallback with useEventTypes() hook - Android now uses the same React Query caching layer as iOS - Removes CalComAPIService direct import and safeLogError (no longer needed) - Both platforms now have unified data-fetching pattern with different UI * refactor(companion): migrate booking detail screens to React Query hooks - Update BookingDetailScreen.tsx and BookingDetailScreen.ios.tsx to be presentational components - Accept booking, isLoading, error, refetch, isRefetching props instead of fetching internally - Add RefreshControl for pull-to-refresh support on both platforms - Update booking-detail.tsx and booking-detail.ios.tsx routes to use useBookingByUid() hook - Single source of truth for booking data via React Query - Automatic cache invalidation when mutations occur (reschedule, cancel, etc.) - Eliminates duplicate API calls between route and screen components * refactor(companion): migrate reschedule screens to useRescheduleBooking hook - Update RescheduleScreen.tsx (web/extension) to use useRescheduleBooking mutation - Update RescheduleScreen.ios.tsx to use useRescheduleBooking mutation - Update RescheduleScreen.android.tsx to use useRescheduleBooking mutation - Replace direct CalComAPIService.rescheduleBooking() calls with React Query mutation - Automatic cache invalidation when reschedule succeeds (booking detail + bookings list) - Use isPending from mutation instead of manual isSaving state * fix react compiler memo * refactor(companion): migrate edit-location screens to useUpdateLocation hook - Add useUpdateLocation mutation hook to useBookings.ts - Update EditLocationScreen.tsx (Android/Web) to use useUpdateLocation mutation - Update EditLocationScreen.ios.tsx to use useUpdateLocation mutation - Replace direct CalComAPIService.updateLocationV2() calls with React Query mutation - Use isPending from mutation instead of manual isSaving state - Automatic cache invalidation when location update succeeds (booking detail + bookings list) * refactor(companion): migrate add-guests screen to useAddGuests hook - Add useAddGuests mutation hook to useBookings.ts - Update AddGuestsScreen.tsx to use useAddGuests mutation - Replace direct CalComAPIService.addGuests() call with React Query mutation - Use isPending from mutation instead of manual isSaving state - Automatic cache invalidation when guests are added (booking detail + bookings list) * implement for other booking actions pages
Screen.Recording.2026-01-05.at.6.20.21.PM.mov
and
Screen.Recording.2026-01-06.at.5.04.49.AM.mov
and
booking actions to React Query to enable auto relaod
Screen.Recording.2026-01-06.at.11.53.59.PM.mov
and
Screen.Recording.2026-01-06.at.11.55.03.PM.mov
Summary by cubic
Unified the bookings and event types UI across Android, iOS, and web with header dropdown filters, recurring series grouping with bulk actions, and cleaner empty states. Migrated booking data and actions to React Query for faster loads, pull‑to‑refresh, and reliable cache updates; fixed header button clipping on web.
UI Improvements
Refactors
Written for commit d76031c. Summary will update on new commits.