Conversation
Includes: unified MeaningMap (SVG), MapFrame (zoom/pan/expand), compass needle, label overlap avoidance, staggered neighbour reveal, celebration pulse, dark mode fix, bounce-in animation, word page, game page, server endpoints, PCA/UMAP projections, axis system. Temporary checkpoint commit — not ready for PR.
Includes all work from multiple agents: - Semantic Explorer mode (embeddings, compass, word map, hints) - Word detail pages + meaning map - Daily/Unlimited for all game modes - Octordle, Sedecordle, Duotrigordle modes - Accounts system: Prisma 7, Google OAuth, email/password auth - Sync composable (localStorage ↔ server) - Badge system (16 badges, evaluator, toast notification) - Profile page, login CTAs, header profile icon - SEO hreflang overhaul, sitemap improvements - Design system refinements
… hero Homepage rewrite: - 3-tier personalization: cold visitors see mode cards, returning users see Continue Playing cards with stacked mode+flag icons, streak badge, sign-in CTA, and featured Semantic (English-only, auto-detected) - 4 mode cards: Classic, Semantic (featured/NEW), Speed, Multi-Board (opens BoardPickerModal). Semantic hidden for non-English languages. - Product-wide streak calculation from buildDailyResultMap - Auth integration (useAuth, useLoginModal) - PWA install CTA for eligible returning users - BoardPickerModal integration for multi-board picker Game board layout fix: - SeoNoscript moved to named #seo slot in PageShell, rendered outside the h-[100dvh] game viewport div. Fixes game board squished to ~5px when SeoNoscript's min-h-[100dvh] competed for flex space. - overflow-hidden safety net on PageShell wrapper - All 5 game pages updated to use <template #seo> Profile page: - Product-wide streak hero (any daily mode, any language) with animated counter, best streak, and "play today's daily" prompt when streak is 0 - BadgeGrid editorial component (4-col grid with 1px rules) Archive page: - Mode filter tabs: Classic (active), Speed/Multi-Board/Semantic (Soon) Word page: - "Appeared In" section replacing placeholder daily stats Other: - Added mode_*_label keys to UiConfig type - Fixed BoardPickerModal @click.native -> @click (Vue 3) - Updated stats tests for unified unlimited/classic key bucket - Excluded .claude/worktrees/ from vitest to prevent duplicate test runs
- Wrap PageShell template in single root div to prevent Vue fragment
warnings ("does not have a single root node") that break Nuxt page
transitions. The seo slot + game viewport div were two root nodes.
- Fix "1 plays" → "1 play" singular grammar in archive word cards.
StatsModal: - "Unlimited" button → "Keep Playing" (clearer value proposition) - Sign-in CTA redesigned: subtle text button "Sign in to protect your streak →" replacing the full-width banner bar - Ad slot location identified (comment placeholder between distribution and action buttons) PostGamePanel (keyboard flip): - "Play unlimited →" → "Keep playing →" (consistent copy) - Removed 'unlimited' from mode discovery grid (it's now a play type, not a separate mode) - Added sign-in nudge for logged-out users - Added commented ad slot placeholder for future Ezoic/Mediavine banner
Daily Puzzle card gets the NYT Wordle-style treatment: W-O-R-D-S mini tiles with correct/semicorrect/incorrect colors, large serif heading, longer description, CLASSIC tag. Other modes (Semantic Explorer, Speed Streak, Multi-Board) use the compact list layout with Lucide icons.
- Selecting a language in the grid now updates the homepage language (detectedLanguageCode + hpLangOverride), so mode cards and UI strings reflect the chosen language immediately. - Semantic Explorer always shows in mode cards regardless of language. When user's language isn't English, an English flag badge appears on the icon to indicate language restriction. Route always goes to /en/semantic.
- Moved badges section below Languages (was between profile info and streak hero, displacing more important content) - Badges sorted: earned first, locked after - Collapsed to 8 badges by default with "Show all 16 badges" expand - Added language flag icons to Your Languages section - Imported useFlag composable for flag resolution
- Homepage reads `preferred_language` from localStorage as top priority for language detection, before game results and browser detection. - Selecting a language in the homepage grid persists it to localStorage. - Game pages update `preferred_language` on mount, so navigating to /fi sets Finnish as preferred for the next homepage visit.
- Remove featured Semantic CTA from personalized hub — now redundant since Semantic is always visible in mode cards list. - Remove unused showSemanticFeature computed. - Sync preferredLanguage to server via PUT /api/user/settings. - Server settings endpoint now accepts string keys (preferredLanguage) in addition to boolean keys. - Pull preferredLanguage from server on login and write to localStorage.
When removing a word from the auto-selected context (no ?context= in URL), the remove handler now promotes the full auto-context to explicit URL state first (minus the removed word), so the removal persists. Previously, removing auto-selected words did nothing because they weren't in the URL query.
- Word page: onRemoveContextWord promotes auto-context to URL before removing, so removing auto-selected words actually persists - NearbyInMeaning: availableAxes includes active slice pair even when partner is outside top 6, so MeaningMap legend can render axis labels - Profile: fixed orphaned </div> causing template compile error
Merge of all v4 work: daily/unlimited play types across all game modes, user accounts with Google OAuth, profile page with badges, semantic explorer improvements, and homepage redesign.
|
Important Review skippedToo many files! This PR contains 196 files, which is 46 over the limit of 150. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (92)
📒 Files selected for processing (196)
You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ 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 |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
- Storage keys namespaced per user (game_results:{userId}) with
migration from v1 unscoped to v2 scoped layout
- Sync plugin: Pattern B (server=truth, localStorage=cache),
visibilitychange delta pull, anonymous result claiming on login
- Profile page: tab-based stats (overview/distribution/languages/speed),
mode icons from shared config, cleaner auth flow
- Storage key constants (STORAGE_KEYS) used consistently across codebase
- Logout reloads stores from anonymous keys
- Sidebar defaults to empty mode/playType when not on a game page
Without this, switching between daily and unlimited on the same mode (e.g. /en/dordle → /en/dordle?play=unlimited) reuses the existing component instance, which doesn't re-initialize the game.
Storage:
- User-scoped localStorage keys (game_results:{userId}) for safe multi-user
- One-time v1→v2 migration, STORAGE_KEYS constants, visibilitychange pull
- Pending sync queue: expire after 24h, don't retry 4xx errors
Bug fixes:
- Speed mode & unlimited: remove minimal=1 so word_list loads for validation
- "Keep Playing" button: include ?play in page key for component remount
- Mode card tiles: use --color-muted (not nonexistent --color-incorrect)
- profile.vue: remove duplicate sortedModes declaration (SSR crash)
- LanguageText type: match actual config keys (underscore, not kebab)
- Add @vue/reactivity as explicit dependency
CI fixes:
- Vitest server startup timeout: 60s → 120s for cold CI builds
- Python config tests: check for unknown keys (typos), not missing keys
(runtime merges with defaults, so missing keys aren't bugs)
- Ruff: fix unused vars, zip strict, f-string, ternary in semantic scripts
- Format all Python and TypeScript
…l heading - Merge earnedAt from profile into badge definitions for date display - Pass progress data to BadgeGrid for progress bar rendering - Editorial heading: "Achievement Badges" with "N of M earned" subtitle - Remove old show-more button (BadgeGrid handles tier collapsing)
Promise.all with badge-progress meant if auth failed, the entire badge section disappeared. Now badges+profile load first, progress is fetched separately.
The `Map` import from lucide-vue-next overwrote the built-in Map, causing `new Map()` in the badge earnedAt merge to throw "Map is not a constructor". Aliased to MapIcon.
…profile Lucide's Map component shadowed the global Map constructor in both BadgeGrid.vue and profile.vue. Aliased to MapIcon in BadgeGrid. Removed the entire BADGE_ICONS map from profile.vue — it was dead code since BadgeGrid handles its own icon resolution.
- Removed grid background color so empty trailing cells don't show as colored rectangles. Each card has its own border instead. - Default to showing 8 badges (2 rows) with "Show all N badges" expand button.
Nitro JIT compilation takes 50s+ in CI, leaving <10s for data loading. Bumped both Playwright webServer and vitest setup-server timeouts.
Summary
Major release bringing four interconnected feature systems to Wordle Global.
1. Daily/Unlimited Play Type System
Every game mode now supports both daily (deterministic, same words for everyone) and unlimited (random) play types.
supportedPlayTypeson all game modes — classic, speed, dordle through duotrigordle, semantic?play=unlimitedquery param on any mode route for unlimited playusePlayTypecomposable — reads URL, validates against mode config, persists choice to localStorageisDailyStatsKey)buildSaveKey/buildStatsKeyproduce backward-compatible keys?play=daily|unlimitedparam,speed_daily_wordsfor daily speed (50 deterministic words)/en/words→ 301 →/en/archivewith mode filter tabs2. Sidebar Restructure
Reduced from 10 flat items to 5 organized entries with sub-panel navigation.
useAutoHeightfor smooth expand/collapse animation3. User Accounts & Profiles
Full authentication system with Google OAuth, email/password, and server-side persistence.
nuxt-auth-utils/profile) with avatar, stats, editorial-style badge grid4. Homepage Redesign
Three-tier personalization based on user state.
5. Semantic Explorer Improvements
buildSemanticGradientFromCSS()reads design tokens at runtime6. Animation & Modal Polish
Breaking Changes
defaultPlayType: 'daily'(wasunlimited). Existing unlimited saves preserved via backward-compatible key format./en/words301-redirects to/en/archiveunlimitedremoved fromGAME_MODE_ORDER(sidebar no longer shows it as standalone mode)New Files
composables/usePlayType.ts— play type from URL + localStoragecomposables/useProductStreak.ts— product-wide streak composablecomposables/useToast.ts— toast notification systemcomponents/account/BadgeGrid.vue— editorial-style badge displaycomponents/account/BadgeEarned.vue— badge earned toastcomponents/account/LoginModal.vue— auth modal (Google + email)components/shared/AppToast.vue— toast componentcomponents/app/BoardPickerModal.vue— multi-board mode pickercomponents/app/LanguagePickerModal.vue— in-game language switcherserver/middleware/archive-redirect.ts— 301 redirectserver/middleware/stats-redirect.ts— legacy stats redirectserver/utils/name-generator.ts— random display name generationserver/utils/rate-limit.ts— API rate limitingserver/utils/session.ts— session utilitiesserver/api/auth/*— full auth endpoint suiteserver/api/user/*— profile, settings, game-result, sync endpointsserver/api/avatar/*— avatar proxypages/[lang]/archive.vue— renamed from words.vuepages/profile.vue— user profile + badges + statsTest plan
/en/dordle?play=daily→ verify deterministic daily words/en/words→ verify 301 redirect to/en/archive