From d14fec28c563c02c0e9e72121fb1433cb7ead44f Mon Sep 17 00:00:00 2001 From: Manuel Emilio Urena Date: Wed, 16 Oct 2024 12:20:07 -0400 Subject: [PATCH] Fixes user profile loading (#1428) --- .../HomeStyleSegmentedControl.tsx | 11 ++++-- src/components/Profile/ProfileNavigation.tsx | 34 ++++++++++++------- src/components/Profile/profile.utils.ts | 10 +++--- src/pages/user/[username]/index.tsx | 15 +++++--- src/server/services/user.service.ts | 11 +++--- 5 files changed, 51 insertions(+), 30 deletions(-) diff --git a/src/components/HomeContentToggle/HomeStyleSegmentedControl.tsx b/src/components/HomeContentToggle/HomeStyleSegmentedControl.tsx index f016762939..251fd4fd72 100644 --- a/src/components/HomeContentToggle/HomeStyleSegmentedControl.tsx +++ b/src/components/HomeContentToggle/HomeStyleSegmentedControl.tsx @@ -8,6 +8,7 @@ import { ThemeIcon, createStyles, Badge, + Loader, } from '@mantine/core'; import { IconProps } from '@tabler/icons-react'; import Link from 'next/link'; @@ -62,6 +63,7 @@ export function HomeStyleSegmentedControl({ onChange, size, sx, + loading, ...props }: Props) { const { classes, theme } = useStyles(); @@ -88,7 +90,11 @@ export function HomeStyleSegmentedControl({ {value.label ?? key} {/* Ideally this is a temporary solution. We should be using the `canViewNsfw` feature flag to return the correct numbers to the users */} - {canViewNsfw && value.count && {value.count}} + {canViewNsfw && value.count != null && ( + + {loading ? : value.count.toLocaleString()} + + )} @@ -117,12 +123,13 @@ export type DataItem = { url: string; icon: (props?: IconProps) => React.ReactNode; disabled?: boolean; - count?: number | string; + count?: number; label?: string; }; type Props = { size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'; value: string; onChange?: (item: DataItem) => void; + loading?: boolean; data: Record; } & Omit; diff --git a/src/components/Profile/ProfileNavigation.tsx b/src/components/Profile/ProfileNavigation.tsx index e1e4bc64e2..179e3aa736 100644 --- a/src/components/Profile/ProfileNavigation.tsx +++ b/src/components/Profile/ProfileNavigation.tsx @@ -9,7 +9,6 @@ import { } from '@tabler/icons-react'; import { trpc } from '~/utils/trpc'; import { useRouter } from 'next/router'; -import { numberWithCommas } from '~/utils/number-helpers'; import { DataItem, HomeStyleSegmentedControl, @@ -25,12 +24,15 @@ const overviewPath = '[username]'; export const ProfileNavigation = ({ username }: ProfileNavigationProps) => { const router = useRouter(); - const { data: userOverview } = trpc.userProfile.overview.useQuery({ - username, - }); - const { articles } = useFeatureFlags(); - const activePath = router.pathname.split('/').pop() || overviewPath; + const { articles, canViewNsfw } = useFeatureFlags(); + + const { + data: userOverview, + isInitialLoading, + isRefetching, + } = trpc.userProfile.overview.useQuery({ username }, { enabled: canViewNsfw }); + const activePath = router.pathname.split('/').pop() || overviewPath; const baseUrl = `/user/${username}`; const opts: Record = { @@ -42,35 +44,41 @@ export const ProfileNavigation = ({ username }: ProfileNavigationProps) => { models: { url: `${baseUrl}/models`, icon: (props) => , - count: numberWithCommas(userOverview?.modelCount), + count: userOverview?.modelCount ?? 0, }, posts: { url: `${baseUrl}/posts`, icon: (props) => , - count: numberWithCommas(userOverview?.postCount), + count: userOverview?.postCount ?? 0, }, images: { url: `${baseUrl}/images`, icon: (props) => , - count: numberWithCommas(userOverview?.imageCount), + count: userOverview?.imageCount ?? 0, }, videos: { url: `${baseUrl}/videos`, icon: (props) => , - count: numberWithCommas(userOverview?.videoCount), + count: userOverview?.videoCount ?? 0, }, articles: { url: `${baseUrl}/articles`, icon: (props) => , - count: numberWithCommas(userOverview?.articleCount), + count: userOverview?.articleCount ?? 0, disabled: !articles, }, collections: { url: `${baseUrl}/collections`, icon: (props) => , - count: numberWithCommas(userOverview?.collectionCount), + count: userOverview?.collectionCount ?? 0, }, }; - return ; + return ( + + ); }; diff --git a/src/components/Profile/profile.utils.ts b/src/components/Profile/profile.utils.ts index f2889509ca..60c2608e53 100644 --- a/src/components/Profile/profile.utils.ts +++ b/src/components/Profile/profile.utils.ts @@ -63,7 +63,7 @@ export const shouldDisplayUserNullState = ({ overview, userWithProfile, }: { - overview: UserOverview; + overview?: Partial; userWithProfile: UserWithProfile; }) => { const userSections = (userWithProfile?.profile?.profileSectionsSettings ?? @@ -82,9 +82,9 @@ export const shouldDisplayUserNullState = ({ return ( (showcaseItems.length === 0 || !someSectionEnabled(['showcase'])) && - (overview.modelCount === 0 || !someSectionEnabled(['modelsOverview', 'popularModels'])) && - (overview.imageCount === 0 || !someSectionEnabled(['imagesOverview'])) && - (overview.articleCount === 0 || !someSectionEnabled(['popularArticles'])) && - (!overview.hasReceivedReviews || !someSectionEnabled(['recentReviews'])) + (overview?.modelCount === 0 || !someSectionEnabled(['modelsOverview', 'popularModels'])) && + (overview?.imageCount === 0 || !someSectionEnabled(['imagesOverview'])) && + (overview?.articleCount === 0 || !someSectionEnabled(['popularArticles'])) && + (!overview?.hasReceivedReviews || !someSectionEnabled(['recentReviews'])) ); }; diff --git a/src/pages/user/[username]/index.tsx b/src/pages/user/[username]/index.tsx index 1f46828c2d..455cb1e385 100644 --- a/src/pages/user/[username]/index.tsx +++ b/src/pages/user/[username]/index.tsx @@ -10,6 +10,7 @@ import { ProfileSectionComponent, shouldDisplayUserNullState, } from '~/components/Profile/profile.utils'; +import { useFeatureFlags } from '~/providers/FeatureFlagsProvider'; import { ProfileSectionSchema, ProfileSectionType } from '~/server/schema/user-profile.schema'; import { userPageQuerySchema } from '~/server/schema/user.schema'; import { createServerSideProps } from '~/server/utils/server-side-helpers'; @@ -33,12 +34,16 @@ export const getServerSideProps = createServerSideProps({ function ProfileOverview() { const router = useRouter(); const { username } = router.query as { username: string }; + + const { canViewNsfw } = useFeatureFlags(); + const { isLoading, data: user } = trpc.userProfile.get.useQuery({ username, }); - const { isLoading: isLoadingOverview, data: userOverview } = trpc.userProfile.overview.useQuery({ - username, - }); + const { data: userOverview } = trpc.userProfile.overview.useQuery( + { username }, + { enabled: canViewNsfw } + ); const sections = useMemo( () => @@ -50,7 +55,7 @@ function ProfileOverview() { [user] ); - if (isLoading || isLoadingOverview) { + if (isLoading) { return (
@@ -58,7 +63,7 @@ function ProfileOverview() { ); } - if (!user || !user.username || !userOverview) { + if (!isLoading && !user) { return ; } diff --git a/src/server/services/user.service.ts b/src/server/services/user.service.ts index 0ff7aa9a96..3c5aab4491 100644 --- a/src/server/services/user.service.ts +++ b/src/server/services/user.service.ts @@ -161,7 +161,11 @@ export const getUserCreator = async ({ }); if (!user) return null; - const modelCount = dbRead.model.count({ + /** + * TODO: seems to be deprecated, we are getting model count from the stats + * though it might be bugged since we are not updating stats if user deletes/unpublishes models + */ + const modelCount = await dbRead.model.count({ where: { userId: user?.id, status: 'Published', @@ -170,10 +174,7 @@ export const getUserCreator = async ({ return { ...user, - - _count: { - models: Number(modelCount), - }, + _count: { models: modelCount }, }; };