From b9ae3cf42a8e2a1921e809acdf6c454728b1a0c9 Mon Sep 17 00:00:00 2001 From: AmarTrebinjac Date: Thu, 26 Mar 2026 21:24:25 +0000 Subject: [PATCH 1/2] feat: add Game Center entry points to desktop and mobile sidebars Add navigation entries for the /game-center page, gated behind the quests feature flag. Desktop sidebar shows it below Agentic Hub, mobile profile menu shows it in the Misc section. Includes a new Joystick icon with outlined and filled variants. Co-Authored-By: Claude Opus 4.6 --- .../src/components/icons/Joystick/filled.svg | 4 ++++ .../src/components/icons/Joystick/index.tsx | 10 ++++++++++ .../components/icons/Joystick/outlined.svg | 4 ++++ packages/shared/src/components/icons/index.ts | 1 + .../profile/ProfileSettingsMenu.tsx | 13 ++++++++++++ .../sidebar/sections/MainSection.tsx | 20 +++++++++++++++++++ 6 files changed, 52 insertions(+) create mode 100644 packages/shared/src/components/icons/Joystick/filled.svg create mode 100644 packages/shared/src/components/icons/Joystick/index.tsx create mode 100644 packages/shared/src/components/icons/Joystick/outlined.svg diff --git a/packages/shared/src/components/icons/Joystick/filled.svg b/packages/shared/src/components/icons/Joystick/filled.svg new file mode 100644 index 00000000000..59bd3f9132c --- /dev/null +++ b/packages/shared/src/components/icons/Joystick/filled.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/shared/src/components/icons/Joystick/index.tsx b/packages/shared/src/components/icons/Joystick/index.tsx new file mode 100644 index 00000000000..3bdaaabcc25 --- /dev/null +++ b/packages/shared/src/components/icons/Joystick/index.tsx @@ -0,0 +1,10 @@ +import type { ReactElement } from 'react'; +import React from 'react'; +import type { IconProps } from '../../Icon'; +import Icon from '../../Icon'; +import OutlinedIcon from './outlined.svg'; +import FilledIcon from './filled.svg'; + +export const JoystickIcon = (props: IconProps): ReactElement => ( + +); diff --git a/packages/shared/src/components/icons/Joystick/outlined.svg b/packages/shared/src/components/icons/Joystick/outlined.svg new file mode 100644 index 00000000000..437b196ac50 --- /dev/null +++ b/packages/shared/src/components/icons/Joystick/outlined.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/shared/src/components/icons/index.ts b/packages/shared/src/components/icons/index.ts index 88afa15506a..11cf7a5c9b3 100644 --- a/packages/shared/src/components/icons/index.ts +++ b/packages/shared/src/components/icons/index.ts @@ -80,6 +80,7 @@ export * from './Italic'; export * from './JetBrains'; export * from './Job'; export * from './JobStatus'; +export * from './Joystick'; export * from './Kaggle'; export * from './Key'; export * from './Label'; diff --git a/packages/shared/src/components/profile/ProfileSettingsMenu.tsx b/packages/shared/src/components/profile/ProfileSettingsMenu.tsx index c6a27962ac8..7cf530f7b09 100644 --- a/packages/shared/src/components/profile/ProfileSettingsMenu.tsx +++ b/packages/shared/src/components/profile/ProfileSettingsMenu.tsx @@ -34,6 +34,7 @@ import { TourIcon, FeatherIcon, GiftIcon, + JoystickIcon, } from '../icons'; import { NavDrawer } from '../drawers/NavDrawer'; import { @@ -188,6 +189,11 @@ const useAccountPageItems = ({ onClose }: { onClose?: () => void } = {}) => { onClose?.(); }, }, + gameCenter: { + title: 'Game Center', + icon: JoystickIcon, + href: `${webappUrl}game-center`, + }, trackAchievement: { title: 'Track achievement', icon: PinIcon, @@ -459,6 +465,13 @@ export const InnerProfileSettingsMenu = ({ return false; } + if ( + itemKey === 'gameCenter' && + isQuestsFeatureEnabled !== true + ) { + return false; + } + return true; }) .map(([, item]: [string, ProfileSectionItemProps]) => { diff --git a/packages/shared/src/components/sidebar/sections/MainSection.tsx b/packages/shared/src/components/sidebar/sections/MainSection.tsx index a6e7d137818..a0f4e6aa2a7 100644 --- a/packages/shared/src/components/sidebar/sections/MainSection.tsx +++ b/packages/shared/src/components/sidebar/sections/MainSection.tsx @@ -8,6 +8,7 @@ import { EyeIcon, HomeIcon, HotIcon, + JoystickIcon, SquadIcon, TerminalIcon, YearInReviewIcon, @@ -24,6 +25,7 @@ import { useConditionalFeature } from '../../../hooks'; import { featurePlusCtaCopy, featureYearInReview, + questsFeature, } from '../../../lib/featureManagement'; export const MainSection = ({ @@ -42,6 +44,10 @@ export const MainSection = ({ feature: featureYearInReview, shouldEvaluate: isLoggedIn, }); + const { value: showGameCenter } = useConditionalFeature({ + feature: questsFeature, + shouldEvaluate: isLoggedIn, + }); const menuItems: SidebarMenuItem[] = useMemo(() => { // this path can be opened on extension so it purposly @@ -87,6 +93,18 @@ export const MainSection = ({ } : undefined; + const gameCenter = showGameCenter + ? { + icon: (active: boolean) => ( + } /> + ), + title: 'Game Center', + path: `${webappUrl}game-center`, + isForcedLink: true, + requiresLogin: true, + } + : undefined; + const yearInReview = showYearInReview ? { icon: () => } />, @@ -137,6 +155,7 @@ export const MainSection = ({ isForcedLink: true, requiresLogin: true, }, + gameCenter, yearInReview, plusButton, ].filter(Boolean); @@ -146,6 +165,7 @@ export const MainSection = ({ isLoggedIn, isPlus, onNavTabClick, + showGameCenter, showYearInReview, user, ]); From 32ef2601edb4d8a53fb3c207af26364c60527d3b Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Thu, 26 Mar 2026 21:50:28 +0000 Subject: [PATCH 2/2] fix: resolve TypeScript strict mode violations in ProfileSettingsMenu and MainSection - ProfileSettingsMenu: convert null title to undefined for ProfileSection prop - ProfileSettingsMenu: provide no-op fallback for optional onClose in drawer props - ProfileSettingsMenu: widen return type of ProfileSettingsMenuDesktop to ReactElement | null - MainSection: use type predicate in filter for SidebarMenuItem[] narrowing - MainSection: use non-null assertion for user inside isLoggedIn branch Co-authored-by: Amar Trebinjac --- .../shared/src/components/profile/ProfileSettingsMenu.tsx | 6 +++--- .../shared/src/components/sidebar/sections/MainSection.tsx | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/shared/src/components/profile/ProfileSettingsMenu.tsx b/packages/shared/src/components/profile/ProfileSettingsMenu.tsx index 7cf530f7b09..8264f3c2fda 100644 --- a/packages/shared/src/components/profile/ProfileSettingsMenu.tsx +++ b/packages/shared/src/components/profile/ProfileSettingsMenu.tsx @@ -444,7 +444,7 @@ export const InnerProfileSettingsMenu = ({ { if (item.href === walletUrl && !hasAccessToCores) { @@ -504,7 +504,7 @@ export function ProfileSettingsMenuMobile({ shouldKeepOpen={shouldKeepOpen} drawerProps={{ isOpen, - onClose, + onClose: onClose ?? (() => {}), }} > @@ -512,7 +512,7 @@ export function ProfileSettingsMenuMobile({ ); } -export function ProfileSettingsMenuDesktop(): ReactElement { +export function ProfileSettingsMenuDesktop(): ReactElement | null { const { user } = useAuthContext(); const featureTheme = useFeatureTheme(); diff --git a/packages/shared/src/components/sidebar/sections/MainSection.tsx b/packages/shared/src/components/sidebar/sections/MainSection.tsx index a0f4e6aa2a7..be4a60b3183 100644 --- a/packages/shared/src/components/sidebar/sections/MainSection.tsx +++ b/packages/shared/src/components/sidebar/sections/MainSection.tsx @@ -65,7 +65,7 @@ export const MainSection = ({ action: () => onNavTabClick?.(isCustomDefaultFeed ? SharedFeedPage.MyFeed : '/'), icon: () => ( - + ), } : { @@ -158,7 +158,7 @@ export const MainSection = ({ gameCenter, yearInReview, plusButton, - ].filter(Boolean); + ].filter((item): item is SidebarMenuItem => !!item); }, [ ctaCopy, isCustomDefaultFeed,