Unselected chips now have a 1.5px light gray (#E5E7EB) border so they
stand out against the white background. Selected chips get a matching
primary blue border. Also slightly increased shadow opacity for better
depth perception. Replaced deprecated withOpacity calls with withValues.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- "View All" on "Events Around You" header now toggles between
horizontal scroll and expanded wrap grid showing all categories
- Tapping a category chip replaces all shelf sections with a
filtered vertical list of events for that category only
- Tapping "All Events" restores the shelf layout for all categories
- "View All" on each shelf header (Music, Festivals, etc.) selects
that category in the chips and shows its filtered event list
- Added AnimatedSwitcher for smooth transition between views
- Added AnimatedCrossFade for chip expand/collapse animation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Backend: Rewrote EventListAPI to query per-type with DB-level LIMIT
instead of loading all 734 events into memory. Added slim serializer
(32KB vs 154KB). Added DB indexes on event_type_id and pincode.
Frontend: Category chips now filter locally from _allEvents (instant,
no API call). Top Events and category sections always show all types
regardless of selected category. Added TTL caching for event types
(30min) and events (5min). Reduced API timeout from 30s to 10s.
Added memCacheHeight to all CachedNetworkImage widgets. Batched
setState calls from 5 to 2 during startup. Cached _eventDates getter.
Switched baseUrl to em.eventifyplus.com (Django via Nginx+SSL).
Added initialEvent param to LearnMoreScreen for instant detail views.
Resolved relative media URLs for category icons.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
LearnMoreScreen now accepts an optional initialEvent parameter so it
can render immediately from already-loaded data instead of re-fetching
from the event-details API. This fixes the guest-mode flow where the
unauthenticated API call was failing. Also changed getEventDetails to
requiresAuth: true so logged-in users send their token when the API
path is used.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When lat,lng coordinates are stored in SharedPreferences from
a previous session, reverse geocode them to a human-readable
location name (e.g. "Whitefield, Bengaluru") instead of showing
raw numbers like "10.57376,76.01188".
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New file: lib/core/auth/auth_guard.dart
Static AuthGuard class with isGuest flag and requireLogin() helper
that shows a login prompt bottom sheet when guests try protected actions.
login_screen.dart / desktop_login_screen.dart:
Added "Continue as Guest" button below sign-up link.
Sets AuthGuard.isGuest = true, then navigates to HomeScreen.
api_client.dart:
_buildAuthBody() and GET auth check no longer throw when token is missing.
If no token (guest), request proceeds without auth — backend decides.
home_screen.dart:
Bottom nav guards: tapping Contribute (index 2) or Profile (index 3)
as guest shows login prompt instead of navigating.
auth_service.dart:
AuthGuard.setGuest(false) called on successful login AND register
so guest flag is always cleared when user authenticates.
Guest CAN: browse home, calendar, search, filter, view event details.
Guest CANNOT: contribute, view profile, book events (prompts login).
All CachedNetworkImage instances in list/card contexts now decode at
2x rendered size instead of full resolution. A 3000x2000 event photo
previously decoded to ~24MB in GPU memory even when shown at 96px —
now decodes to <1MB.
Affected screens (16 CachedNetworkImage instances total):
- home_screen.dart: hero (800w), top card (300w), stacked (192w),
horizontal (440x360), full-width (800x400), search (112x112),
filter sheet (160x160), type icons (112x112)
- home_desktop_screen.dart: mini (128x128), grid (600x280), horiz (600x296)
- calendar_screen.dart: event card (400x300)
- profile_screen.dart: avatar (size*2), event tile (120x120)
learn_more_screen.dart intentionally unchanged — full-res for detail view.
Estimated memory reduction: ~500MB → ~30MB for a typical home screen.
UI/UX Pro Max + Flutter Expert audit of the home screen hero section.
viewportFraction 0.88
Adjacent cards peek 6% on each side — users see there is more content
to swipe without any instruction. Most impactful single-line UX change.
Overlay card design
Title and metadata (date + location) now live ON the image behind a
dark gradient (transparent → black 78%) at the bottom 65% of the card.
Previously the title was below the image in a split layout that wasted
space and felt disconnected. Card height increased 300 → 320px.
FEATURED glassmorphism badge
Top-left corner chip with BackdropFilter blur (sigmaX/Y 10) and a
white-border container gives each card a premium editorial feel.
Scale animation (AnimatedBuilder per card)
Active card scales to 1.0, adjacent cards to 0.94. The AnimatedBuilder
is placed inside itemBuilder so only the visible card rebuilds on each
scroll tick — not the PageView or any ancestor.
Auto-scroll resets on page change
onPageChanged now calls _startAutoScroll() which cancels the previous
timer and starts a fresh 3-second countdown. Users who swipe manually
always get a full 3 seconds to read before auto-advance continues.
Shimmer loading placeholder (_HeroShimmer)
New StatefulWidget added below HomeScreen — a LinearGradient scan-line
animated at 1400ms repeat. Replaces the flat Color(0xFF1A2A4A) box that
looked broken while images were loading.
Critical — Image.network → CachedNetworkImage:
- home_screen.dart: hero/carousel banner image now cached with placeholder
- profile_screen.dart: avatar and event list tile images now cached
- calendar_screen.dart: event card images now cached with placeholder
High:
- profile_screen.dart: TextEditingControllers in dialogs now properly
disposed via .then() and after await to prevent memory leaks
Medium:
- search_screen.dart: shrinkWrap:true → ConstrainedBox(maxHeight:320) +
ClampingScrollPhysics for smooth search result scrolling
- learn_more_screen.dart: MediaQuery.of(context) cached once per method
instead of being called multiple times on every frame
Fix 1: Replace overshooting Cubic(1.95) tab glider curve with
Curves.easeInOutCubic; reduce duration 450ms → 280ms
Fix 2: Replace marquee jumpTo() with animateTo(linear) for fluid scroll
Fix 3: Replace Image.network with CachedNetworkImage in search results
Fix 4: Replace Image.network with CachedNetworkImage in desktop cards
Fix 5: Wrap IndexedStack children in RepaintBoundary to isolate
repaints across tabs (Home/Calendar/Contribute/Profile)
Fix 6: Replace setState on PageView.onPageChanged with ValueNotifier
so only the carousel dots widget rebuilds on swipe
Fix 7: Wrap animated tab glider in RepaintBoundary
Fix 8: Replace shrinkWrap:true ListView with ConstrainedBox(maxHeight)
to eliminate O(n) layout pass in search results
Fix 9: Increase image cache to 200MB / 500 images in main()
- Clicking Today/Tomorrow/This week opens a draggable bottom sheet
showing filtered events matching the selected period
- Clicking Date opens calendar picker, then shows events for that date
- Bottom sheet matches web design: lavender bg, drag handle, title with
count, close X button, scrollable event cards
- Event cards show image, title, date, location, and price label
- Sheet auto-clears filter on dismiss
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Make web responsive layout use width-based mobile detection (820px)
- Add date filter chips that actually filter events by date ranges
- Custom calendar dialog with event dots on Date chip tap
- Update location search with Kerala cities and pincode display
- Fix calendar screen overflow errors and broken event indicators
- Replace thumbnail indicators with clean colored dots
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>