From 8114ccf9fa46e99a953cc7a6f8551e2e5e1b685d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antti=20M=C3=A4ki?= Date: Tue, 7 Nov 2023 12:46:41 +0200 Subject: [PATCH] @thunderstore/dapper: make PackagePreview match the data from backend PackagePreview, used to render package cards, should use the actual values the backend will eventually return. By a decided convetion, the naming should use backend terms to make it easier for developers to work on both repositories. Refs TS-1875 --- .../[namespace]/[package]/dependants/page.tsx | 2 +- .../components/PackageCard.stories.tsx | 17 ++- .../PackageDependantsLayout.stories.tsx | 2 +- .../PackageDependantsLayout.tsx | 16 ++- .../PackageDetailLayout.tsx | 39 +++--- .../PackageTagList/PackageTagList.tsx | 14 +- .../components/PackageCard/PackageCard.tsx | 30 ++--- packages/dapper-fake/src/fakers/package.ts | 126 +++++++----------- packages/dapper/src/types/package.ts | 22 +-- 9 files changed, 125 insertions(+), 143 deletions(-) diff --git a/apps/cyberstorm-nextjs/app/c/[community]/p/[namespace]/[package]/dependants/page.tsx b/apps/cyberstorm-nextjs/app/c/[community]/p/[namespace]/[package]/dependants/page.tsx index f4c3d1570..73f9ed71d 100644 --- a/apps/cyberstorm-nextjs/app/c/[community]/p/[namespace]/[package]/dependants/page.tsx +++ b/apps/cyberstorm-nextjs/app/c/[community]/p/[namespace]/[package]/dependants/page.tsx @@ -9,7 +9,7 @@ export default function Page({ // TODO: dummy data for now, the component shouldn't consume Package // object anyway. const packageData = { - community: params.community, + community_identifier: params.community, namespace: params.namespace, name: params.package, } as Package; diff --git a/apps/cyberstorm-storybook/stories/components/PackageCard.stories.tsx b/apps/cyberstorm-storybook/stories/components/PackageCard.stories.tsx index 44542a602..dc838d3fa 100644 --- a/apps/cyberstorm-storybook/stories/components/PackageCard.stories.tsx +++ b/apps/cyberstorm-storybook/stories/components/PackageCard.stories.tsx @@ -38,18 +38,17 @@ ReferencePackageCard.args = { package: { name: "WaveTimer", namespace: "otDan", - community: "brotato", + community_identifier: "brotato", description: "Modifies the in game timer to have a new look ", - imageSource: + icon_url: "https://gcdn.thunderstore.io/live/repository/icons/otDan-WaveTimer-1.1.0.png.256x256_q95_crop.jpg", - downloadCount: 2707, - likes: 1, + download_count: 2707, + rating_count: 1, size: 106299, - author: "otDan", - lastUpdated: "Tue Feb 28 2023", - isPinned: false, - isNsfw: false, - isDeprecated: false, + last_updated: "2023-02-28T11:23:42.000000Z", + is_pinned: false, + is_nsfw: false, + is_deprecated: false, categories: [ { id: 1, name: "Misc", slug: "misc" }, { id: 2, name: "Mods", slug: "mods" }, diff --git a/apps/cyberstorm-storybook/stories/layouts/PackageDependantsLayout.stories.tsx b/apps/cyberstorm-storybook/stories/layouts/PackageDependantsLayout.stories.tsx index 7539172c9..ad15105bb 100644 --- a/apps/cyberstorm-storybook/stories/layouts/PackageDependantsLayout.stories.tsx +++ b/apps/cyberstorm-storybook/stories/layouts/PackageDependantsLayout.stories.tsx @@ -9,7 +9,7 @@ const meta = { } as Meta; const packageData = { - community: "brotato", + community_identifier: "brotato", namespace: "otDan", name: "WaveTimer", } as Package; diff --git a/packages/cyberstorm/src/components/Layout/PackageDependantsLayout/PackageDependantsLayout.tsx b/packages/cyberstorm/src/components/Layout/PackageDependantsLayout/PackageDependantsLayout.tsx index 413df5ff2..780fa248d 100644 --- a/packages/cyberstorm/src/components/Layout/PackageDependantsLayout/PackageDependantsLayout.tsx +++ b/packages/cyberstorm/src/components/Layout/PackageDependantsLayout/PackageDependantsLayout.tsx @@ -27,8 +27,10 @@ export function PackageDependantsLayout(props: PackageDependantsLayoutProps) { const { package: pkg } = props; const dapper = useDapper(); - const community = usePromise(dapper.getCommunity, [pkg.community]); - const filters = usePromise(dapper.getCommunityFilters, [pkg.community]); + const community = usePromise(dapper.getCommunity, [pkg.community_identifier]); + const filters = usePromise(dapper.getCommunityFilters, [ + pkg.community_identifier, + ]); return ( Packages - + {pkg.namespace} @@ -59,21 +61,21 @@ export function PackageDependantsLayout(props: PackageDependantsLayoutProps) {
Mods that depend on{" "} {pkg.name} {" by "} - + {pkg.namespace}
} mainContent={ diff --git a/packages/cyberstorm/src/components/Layout/PackageDetailLayout/PackageDetailLayout.tsx b/packages/cyberstorm/src/components/Layout/PackageDetailLayout/PackageDetailLayout.tsx index ad2762c88..63c41669c 100644 --- a/packages/cyberstorm/src/components/Layout/PackageDetailLayout/PackageDetailLayout.tsx +++ b/packages/cyberstorm/src/components/Layout/PackageDetailLayout/PackageDetailLayout.tsx @@ -56,6 +56,11 @@ export interface PackageDetailLayoutProps { /** * Cyberstorm PackageDetail Layout + * + * TODO: Use community.background_image_url as the background + * TODO: Change BaseLayout.backGroundImageSource to accept null rather + * than undefined if image URLs are not available, as this is what + * backend returns. (Unless we have a default image.) */ export function PackageDetailLayout(props: PackageDetailLayoutProps) { const { @@ -88,7 +93,7 @@ export function PackageDetailLayout(props: PackageDetailLayoutProps) { const packageDetailsMeta = [ @@ -133,16 +138,16 @@ export function PackageDetailLayout(props: PackageDetailLayoutProps) { return ( Communities - - {packageData.community} + + {packageData.community_name} Packages {packageData.namespace} @@ -155,11 +160,13 @@ export function PackageDetailLayout(props: PackageDetailLayoutProps) { + packageData.icon_url ? ( + + ) : undefined } description={packageData.shortDescription} meta={packageDetailsMeta} @@ -176,7 +183,7 @@ export function PackageDetailLayout(props: PackageDetailLayoutProps) { } additionalFooterContent={ - packageData.isDeprecated ? ( + packageData.is_deprecated ? ( Undeprecate @@ -268,7 +275,7 @@ export function PackageDetailLayout(props: PackageDetailLayoutProps) { @@ -285,7 +292,7 @@ function getMetaInfoData(packageData: Package) { { key: "1", label: "Last Updated", - content: <>{packageData.lastUpdated}, + content: <>{packageData.last_updated}, }, { key: "2", @@ -295,12 +302,12 @@ function getMetaInfoData(packageData: Package) { { key: "3", label: "Downloads", - content: <>{formatInteger(packageData.downloadCount)}, + content: <>{formatInteger(packageData.download_count)}, }, { key: "4", label: "Likes", - content: <>{formatInteger(packageData.likes)}, + content: <>{formatInteger(packageData.rating_count)}, }, { key: "5", @@ -327,7 +334,7 @@ function getMetaInfoData(packageData: Package) { label: "Dependants", content: ( diff --git a/packages/cyberstorm/src/components/Layout/PackageDetailLayout/PackageTagList/PackageTagList.tsx b/packages/cyberstorm/src/components/Layout/PackageDetailLayout/PackageTagList/PackageTagList.tsx index 2762f3379..8bf7b1639 100644 --- a/packages/cyberstorm/src/components/Layout/PackageDetailLayout/PackageTagList/PackageTagList.tsx +++ b/packages/cyberstorm/src/components/Layout/PackageDetailLayout/PackageTagList/PackageTagList.tsx @@ -36,19 +36,19 @@ PackageTagList.displayName = "PackageTagList"; function getPackageFlags(packageData: Package) { const updateTimeDelta = Math.round( - (Date.now() - Date.parse(packageData.lastUpdated)) / 86400000 + (Date.now() - Date.parse(packageData.last_updated)) / 86400000 ); const isNew = updateTimeDelta < 3; if ( - !packageData.isPinned && - !packageData.isNsfw && - !packageData.isDeprecated && + !packageData.is_pinned && + !packageData.is_nsfw && + !packageData.is_deprecated && !isNew ) { return null; } const flagList: ReactNode[] = []; - if (packageData.isPinned) { + if (packageData.is_pinned) { flagList.push( ); } - if (packageData.isDeprecated) { + if (packageData.is_deprecated) { flagList.push( ); } - if (packageData.isNsfw) { + if (packageData.is_nsfw) { flagList.push(
- {p.imageSource ? ( - {p.name} + {p.icon_url ? ( + {p.name} ) : null} {getPackageFlags(p)} @@ -42,7 +42,7 @@ export function PackageCard(props: Props) {
@@ -51,7 +51,7 @@ export function PackageCard(props: Props) {
by - +
{p.namespace}
@@ -80,19 +80,19 @@ PackageCard.displayName = "PackageCard"; function getPackageFlags(packageData: PackagePreview) { const updateTimeDelta = Math.round( - (Date.now() - Date.parse(packageData.lastUpdated)) / 86400000 + (Date.now() - Date.parse(packageData.last_updated)) / 86400000 ); const isNew = updateTimeDelta < 3; if ( - !packageData.isPinned && - !packageData.isNsfw && - !packageData.isDeprecated && + !packageData.is_pinned && + !packageData.is_nsfw && + !packageData.is_deprecated && !isNew ) { return null; } const flagList: ReactNode[] = []; - if (packageData.isPinned) { + if (packageData.is_pinned) { flagList.push( ); } - if (packageData.isDeprecated) { + if (packageData.is_deprecated) { flagList.push( ); } - if (packageData.isNsfw) { + if (packageData.is_nsfw) { flagList.push( @@ -148,12 +148,12 @@ function getMetaItemList(packageData: PackagePreview) { /> } - label={formatInteger(packageData.downloadCount)} + label={formatInteger(packageData.download_count)} colorScheme="tertiary" /> } - label={formatInteger(packageData.likes)} + label={formatInteger(packageData.rating_count)} colorScheme="tertiary" />
diff --git a/packages/dapper-fake/src/fakers/package.ts b/packages/dapper-fake/src/fakers/package.ts index ffe52fc5f..22f135cf4 100644 --- a/packages/dapper-fake/src/fakers/package.ts +++ b/packages/dapper-fake/src/fakers/package.ts @@ -1,14 +1,47 @@ import { faker } from "@faker-js/faker"; -import { - getFakeImg, - getFakeLink, - getFakePackageCategories, - range, - setSeed, -} from "./utils"; +import { getFakeImg, getFakePackageCategories, range, setSeed } from "./utils"; import { getFakeTeamMembers } from "./team"; +// Content used to render one PackageCard in a list view. +const getFakePackagePreview = (community?: string, namespace?: string) => { + const seed = `${community}-${namespace}`; + setSeed(seed); + + return { + categories: getFakePackageCategories(), + community_identifier: community ?? faker.word.sample(), + description: faker.company.buzzPhrase(), + download_count: faker.number.int({ min: 100, max: 10000000 }), + icon_url: faker.helpers.maybe(getFakeImg, { probability: 0.9 }) ?? null, + is_deprecated: faker.datatype.boolean(0.1), + is_nsfw: faker.datatype.boolean(0.1), + is_pinned: faker.datatype.boolean(0.1), + last_updated: faker.date.recent({ days: 700 }).toDateString(), + name: faker.word.words(3).split(" ").join("_"), + namespace: namespace ?? faker.word.sample(), + rating_count: faker.number.int({ min: 0, max: 100000 }), + size: faker.number.int({ min: 20000, max: 4000000000 }), + }; +}; + +export const getFakePackageListings = async ( + communityId?: string, + namespaceId?: string, + // Temporary, will be refactored away when the actual implementation is done. + _teamId?: string, // eslint-disable-line @typescript-eslint/no-unused-vars + _userId?: string // eslint-disable-line @typescript-eslint/no-unused-vars +) => + range(20).map(() => + getFakePackagePreview( + communityId ?? faker.word.sample(), + namespaceId ?? faker.word.sample() + ) + ); + +// TODO: the methods below this point don't yet match what the backend +// will be actually returning. + export const getFakeDependencies = async ( community: string, namespace: string, @@ -32,58 +65,26 @@ export const getFakePackage = async ( setSeed(seed); return { - ...getPackageBase(community, namespace, name), - ...getPackageExtras(), + ...getFakePackagePreview(community, namespace), + community_identifier: community, + community_name: faker.word.sample(), + discordLink: faker.internet.url(), author: faker.person.fullName(), dependantCount: faker.number.int({ min: 0, max: 2000 }), dependencies: await getFakeDependencies(community, namespace, name), dependencyString: faker.string.uuid(), - description: faker.lorem.paragraphs(12), firstUploaded: faker.date.past({ years: 2 }).toDateString(), - team: await getPackageTeam(seed), + gitHubLink: faker.internet.url(), + shortDescription: faker.company.buzzPhrase(), + team: { + name: faker.word.words(3), + members: await getFakeTeamMembers(seed), + }, versions: range(20).map(getPackageVersion), }; }; -// TODO: the DummyDapper implementation in the dapper package at the -// time of this writing has so many shortcomings and bugs that rather -// than try to duplicate that implementation, I'll save time and just -// return some packages. The whole Dapper method interface needs to be -// changed in order to be able to implement all the features we want, so -// this method can be updated once we get there. -export const getFakePackageListings = async ( - communityId?: string, - namespaceId?: string, - teamId?: string, - userId?: string -) => - range(20).map(() => - getFakePackagePreview( - communityId ?? faker.word.sample(), - namespaceId ?? faker.word.sample(), - teamId ?? faker.word.words(3), - userId ?? faker.internet.userName() - ) - ); - -const getFakePackagePreview = ( - community?: string, - namespace?: string, - team?: string, - user?: string -) => { - const seed = `${community}-${namespace}-${team}-${user}`; - setSeed(seed); - - return { - ...getPackageBase(community, namespace), - ...getPackageExtras(), - author: user ?? faker.person.fullName(), - description: faker.company.buzzPhrase(), - }; -}; - const getPackageBase = ( community?: string, namespace?: string, @@ -96,33 +97,6 @@ const getPackageBase = ( imageSource: getFakeImg(), }); -const getPackageExtras = () => ({ - categories: getFakePackageCategories(), - downloadCount: faker.number.int({ min: 1000000, max: 10000000 }), - isDeprecated: faker.datatype.boolean(), - isNsfw: faker.datatype.boolean(), - isPinned: faker.datatype.boolean(), - lastUpdated: faker.date.recent({ days: 700 }).toDateString(), - likes: faker.number.int({ min: 0, max: 100000 }), - size: faker.number.int({ min: 20000, max: 10000000 }), - gitHubLink: faker.internet.url(), - discordLink: faker.internet.url(), -}); - -const getPackageTeam = async (teamId: string) => { - setSeed(teamId); - - return { - name: faker.word.words(3), - imageSource: getFakeImg(), - description: faker.lorem.paragraphs(12), - about: faker.lorem.words(16), - members: await getFakeTeamMembers(teamId), - dynamicLinks: [getFakeLink(), getFakeLink(), getFakeLink()], - donationLink: faker.internet.url(), - }; -}; - const getPackageVersion = () => ({ version: getVersionNumber(), changelog: faker.company.buzzPhrase(), diff --git a/packages/dapper/src/types/package.ts b/packages/dapper/src/types/package.ts index 64fabb4e3..84b724e41 100644 --- a/packages/dapper/src/types/package.ts +++ b/packages/dapper/src/types/package.ts @@ -2,23 +2,23 @@ import { PackageCategory } from "./shared"; import { TeamMember } from "./team"; export interface PackagePreview { + categories: PackageCategory[]; + community_identifier: string; + description: string; + download_count: number; + icon_url: string | null; + is_deprecated: boolean; + is_nsfw: boolean; + is_pinned: boolean; + last_updated: string; name: string; namespace: string; - community: string; - description?: string; - imageSource?: string; - downloadCount: number; - likes: number; + rating_count: number; size: number; - author?: string; - lastUpdated: string; - isPinned?: boolean; - isNsfw?: boolean; - isDeprecated?: boolean; - categories: PackageCategory[]; } export interface Package extends PackagePreview { + community_name: string; shortDescription?: string; additionalImages?: string[]; gitHubLink?: string;