Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
0e422f7
feat: introduce dual desktop sidebar
tsahimatsliah May 11, 2026
741e26b
refactor(sidebar): polish dual sidebar, drop nested boxes
tsahimatsliah May 11, 2026
e9b0d72
refactor(sidebar): swap surface tones, surface profile identity
tsahimatsliah May 11, 2026
3fc335e
fix(sidebar): restore layout behavior after color swap
tsahimatsliah May 11, 2026
f864b91
fix(sidebar): restore exact layout and swap only container colors
tsahimatsliah May 11, 2026
27a69f7
fix(sidebar): complete color swap by recoloring active rail state
tsahimatsliah May 11, 2026
82d5fb9
style(sidebar): unify sidebar and feed bg on primary background
tsahimatsliah May 11, 2026
b3bd362
style(sidebar): set sidebar surface to surface-float for contrast
tsahimatsliah May 11, 2026
0dd9b97
style(sidebar): polish dual sidebar layout
tsahimatsliah May 12, 2026
41c9ab8
feat(sidebar): dedicated settings and game center panels
tsahimatsliah May 12, 2026
976247f
feat(sidebar): add dedicated Discover rail panel
tsahimatsliah May 12, 2026
8b9bef1
feat(sidebar): add profile rail shortcut
tsahimatsliah May 12, 2026
cc19653
feat(sidebar): track recently visited feeds in Home panel
tsahimatsliah May 12, 2026
6d22c70
fix(feed): style cards-layout actions strip as a header
tsahimatsliah May 12, 2026
db33029
refactor(sidebar): unify utility panel header
tsahimatsliah May 12, 2026
5d27887
style(sidebar): place profile rail link below Game Center
tsahimatsliah May 12, 2026
8ceec0a
fix(settings): persist client-only sidebar flags locally
tsahimatsliah May 12, 2026
6e911b9
refactor(profile-menu): move profile entries into sidebar Profile panel
tsahimatsliah May 12, 2026
4f0d3a7
style(feed): tighten list-frame header and search controls
tsahimatsliah May 12, 2026
f8a6098
fix(sidebar): resolve CI lint, build, and test failures
tsahimatsliah May 12, 2026
28c4a69
chore: re-trigger CI
tsahimatsliah May 12, 2026
404228b
feat(sidebar): polish dual-sidebar UX
tsahimatsliah May 12, 2026
e2754f7
style(sidebar): match rail hover panel to support dropdown
tsahimatsliah May 12, 2026
2526de6
style(sidebar): tighten rail hover panel to match Support dropdown
tsahimatsliah May 12, 2026
fb20955
feat(sidebar): rail icon click navigates to category landing page
tsahimatsliah May 12, 2026
1424a13
style(sidebar): match rail hover panel rows to Support exactly
tsahimatsliah May 12, 2026
a5c3722
fix(sidebar): squads rail click is instant + first item highlights
tsahimatsliah May 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions packages/shared/src/components/MainFeedLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -730,9 +730,6 @@ export default function MainFeedLayout({
{...feedProps}
shortcuts={shortcuts}
disableBriefCard={disableBriefCard}
className={classNames(
shouldUseListFeedLayout && !isFinder && 'laptop:px-6',
)}
/>
)
)}
Expand Down
45 changes: 26 additions & 19 deletions packages/shared/src/components/MainLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import {
ActiveFeedNameContextProvider,
useActiveFeedNameContext,
} from '../contexts';
import { useFeedLayout, useViewSize, ViewSize } from '../hooks';
import { BootPopups } from './modals/BootPopups';
import { SmartComposerHotkey } from './post/SmartComposerHotkey';
import { SmartComposerDevToggle } from './post/SmartComposerDevToggle';
Expand Down Expand Up @@ -76,7 +75,6 @@ function MainLayoutComponent({
isNavItemsButton,
customBanner,
additionalButtons,
screenCentered = true,
showSidebar = true,
className,
onLogoClick,
Expand All @@ -86,20 +84,24 @@ function MainLayoutComponent({
}: MainLayoutProps): ReactElement | null {
const router = useRouter();
const { logEvent } = useLogContext();
const { user, isAuthReady, showLogin } = useAuthContext();
const { user, isAuthReady, isLoggedIn, showLogin } = useAuthContext();
const { growthbook } = useGrowthBookContext();
const { sidebarRendered } = useSidebarRendered();
const { isAvailable: isBannerAvailable } = useBanner();
const { sidebarExpanded, autoDismissNotifications } =
useContext(SettingsContext);
// The dual-sidebar layout takes ownership of the global header chrome
// (logo + search + user actions) for authenticated users on laptop+.
// When that's the case we hide the global header and switch the main
// content over to the floating card treatment (rounded, bordered, shadow)
// and hide the global feedback widget (the rail provides its own).
const sidebarOwnsHeader = isLoggedIn && showSidebar && sidebarRendered;
const [hasLoggedImpression, setHasLoggedImpression] = useState(false);
const { feedName } = useActiveFeedNameContext();
const page = router?.route?.substring(1).trim() as SharedFeedPage;
const currentFeedName = feedName ?? page ?? SharedFeedPage.Popular;
const { isCustomFeed } = useFeedName({ feedName: currentFeedName });
const { plusEntryAnnouncementBar } = usePlusEntry();
const isLaptopXL = useViewSize(ViewSize.LaptopXL);
const { screenCenteredOnMobileLayout } = useFeedLayout();
const { isNotificationsReady, unreadCount } = useNotificationContext();
useNotificationParams();

Expand Down Expand Up @@ -177,11 +179,8 @@ function MainLayoutComponent({
return null;
}

const isScreenCentered =
isLaptopXL && screenCenteredOnMobileLayout ? true : screenCentered;

return (
<div className="antialiased">
<div className="antialiased laptop:bg-[color-mix(in_srgb,var(--theme-surface-secondary)_3%,var(--theme-background-default))]">
{canGoBack && <GoBackHeaderMobile />}
{customBanner}
{isBannerAvailable && <PromotionalBanner />}
Expand All @@ -203,33 +202,41 @@ function MainLayoutComponent({

<MainLayoutHeader
hasBanner={isBannerAvailable}
sidebarRendered={sidebarRendered}
sidebarRendered={showSidebar && sidebarRendered}
additionalButtons={additionalButtons}
onLogoClick={onLogoClick}
/>
<main
className={classNames(
'flex flex-col transition-[padding] duration-300 ease-in-out laptop:pt-16',
showSidebar && 'tablet:pl-16 laptop:pl-11',
'flex flex-col transition-[padding] duration-300 ease-in-out',
showSidebar && 'tablet:pl-16 laptop:pl-16',
!sidebarOwnsHeader && 'laptop:pt-16',
isBannerAvailable && !sidebarOwnsHeader && 'laptop:pt-24',
className,
isAuthReady &&
!isScreenCentered &&
sidebarExpanded &&
'laptop:!pl-60',
isBannerAvailable && 'laptop:pt-24',
isAuthReady && showSidebar && sidebarExpanded && 'laptop:!pl-[19rem]',
)}
>
{isAuthReady && showSidebar && (
<Sidebar
additionalButtons={additionalButtons}
isNavButtons={isNavItemsButton}
showFeedbackWidget={!hideFeedbackWidget}
onNavTabClick={onNavTabClick}
onLogoClick={onLogoClick}
activePage={activePage ?? router.asPath ?? router.pathname}
/>
)}
{children}
<div
className={classNames(
'flex min-h-0 flex-1 flex-col',
sidebarOwnsHeader &&
'laptop:my-3 laptop:ml-1 laptop:mr-3 laptop:min-h-[calc(100vh-1.5rem)] laptop:overflow-hidden laptop:rounded-24 laptop:border laptop:border-border-subtlest-quaternary laptop:bg-background-default laptop:p-0.5 laptop:shadow-2',
)}
>
{children}
</div>
</main>
{!hideFeedbackWidget && <FeedbackWidget />}
{!hideFeedbackWidget && !sidebarOwnsHeader && <FeedbackWidget />}
</div>
);
}
Expand Down
36 changes: 14 additions & 22 deletions packages/shared/src/components/ProfileMenu/ProfileMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,12 @@ import { checkIsExtension } from '../../lib/func';
import { LogoutReason } from '../../lib/user';
import { TargetId } from '../../lib/log';

import { ProfileMenuFooter } from './ProfileMenuFooter';
import { UpgradeToPlus } from '../UpgradeToPlus';
import { ProfileMenuHeader } from './ProfileMenuHeader';
import { ProfileMenuStats } from './ProfileMenuStats';
import { HorizontalSeparator } from '../utilities';

import { ProfileSection } from './ProfileSection';
import { ResourceSection } from './sections/ResourceSection';
import { AccountSection } from './sections/AccountSection';
import { MainSection } from './sections/MainSection';
import { ThemeSection } from './sections/ThemeSection';
import { FeedbackButtonSection } from './sections/FeedbackButtonSection';
import { useCustomizeNewTabMenuItem } from './sections/ExtensionSection';
import { ProfileCompletion } from '../../features/profile/components/ProfileWidgets/ProfileCompletion';
Expand All @@ -35,10 +31,12 @@ const ExtensionSection = dynamic(() =>

interface ProfileMenuProps {
onClose: () => void;
position?: InteractivePopupPosition;
}

export default function ProfileMenu({
onClose,
position = InteractivePopupPosition.ProfileMenu,
}: ProfileMenuProps): ReactElement | null {
const { events } = useRouter();
const { user, logout } = useAuthContext();
Expand All @@ -62,11 +60,12 @@ export default function ProfileMenu({
<InteractivePopup
onClose={onClose}
closeOutsideClick
position={InteractivePopupPosition.ProfileMenu}
position={position}
className="flex max-h-[calc(100vh-4rem)] w-full max-w-80 flex-col gap-3 overflow-y-auto !rounded-10 border border-border-subtlest-tertiary !bg-accent-pepper-subtlest p-3"
>
{showProfileCompletion && <ProfileCompletion />}
<ProfileMenuHeader />
<ProfileMenuStats />

<UpgradeToPlus
target={TargetId.ProfileDropdown}
Expand All @@ -77,21 +76,16 @@ export default function ProfileMenu({
<HorizontalSeparator />

<nav className="flex flex-col gap-2">
<MainSection />
{checkIsExtension() && (
<>
{customizeMenuItem && (
<ProfileSection items={[customizeMenuItem]} />
)}
<ExtensionSection />
<HorizontalSeparator />
</>
)}

<HorizontalSeparator />

<ThemeSection className="px-1" />

<HorizontalSeparator />

<AccountSection prepended={customizeMenuItem} />

{checkIsExtension() && <ExtensionSection />}

<HorizontalSeparator />

<ResourceSection />
<FeedbackButtonSection className="px-1" />

<HorizontalSeparator />
Expand All @@ -106,8 +100,6 @@ export default function ProfileMenu({
]}
/>
</nav>

<ProfileMenuFooter />
</InteractivePopup>
);
}
41 changes: 41 additions & 0 deletions packages/shared/src/components/ProfileMenu/ProfileMenuStats.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import type { ReactElement } from 'react';
import React from 'react';
import { ReputationUserBadge } from '../ReputationUserBadge';
import { CoreIcon } from '../icons';
import { IconSize } from '../Icon';
import { useAuthContext } from '../../contexts/AuthContext';
import { useHasAccessToCores } from '../../hooks/useCoresFeature';
import Link from '../utilities/Link';
import { walletUrl } from '../../lib/constants';
import { largeNumberFormat } from '../../lib';

export const ProfileMenuStats = (): ReactElement | null => {
const { user } = useAuthContext();
const hasCoresAccess = useHasAccessToCores();

if (!user) {
return null;
}

if (!hasCoresAccess && !user.reputation) {
return null;
}

return (
<div className="flex items-center gap-2">
<ReputationUserBadge
className="h-8 rounded-8 px-2 hover:bg-surface-hover"
user={{ reputation: user.reputation }}
iconProps={{ size: IconSize.XSmall }}
/>
{hasCoresAccess && (
<Link href={walletUrl} passHref>
<a className="focus-outline flex h-8 items-center gap-1 rounded-8 px-2 font-bold text-text-primary typo-footnote hover:bg-surface-hover">
<CoreIcon size={IconSize.XSmall} aria-hidden />
{largeNumberFormat(user.balance?.amount ?? 0)}
</a>
</Link>
)}
</div>
);
};

This file was deleted.

Loading
Loading