diff --git a/apps/cyberstorm-remix/README.md b/apps/cyberstorm-remix/README.md
index 9c509481f..b59422122 100644
--- a/apps/cyberstorm-remix/README.md
+++ b/apps/cyberstorm-remix/README.md
@@ -34,7 +34,7 @@ yarn workspace @thunderstore/cyberstorm-remix dev --port 3000 --host 0.0.0.0
1. Open hosts file as administrator (`C:\Windows\System32\drivers\etc`) and add this `127.0.0.1 thunderstore.temp` there
2. Download and install Docker and docker-compose. For windows people, Docker for Windows should be enough.
3. Open up a terminal and navigate to `thunderstore-ui/tools/ts-proxy`
-4. Run `docker-compose up`
+4. Run `docker compose up`
5. Add these to your `.env.development` or `.env.production`
```
PUBLIC_SITE_URL=http://thunderstore.temp
diff --git a/apps/cyberstorm-remix/app/commonComponents/ListingDependency/ListingDependency.css b/apps/cyberstorm-remix/app/commonComponents/ListingDependency/ListingDependency.css
new file mode 100644
index 000000000..01dc213d6
--- /dev/null
+++ b/apps/cyberstorm-remix/app/commonComponents/ListingDependency/ListingDependency.css
@@ -0,0 +1,68 @@
+@layer nimbus-layout {
+ .nimbus-commoncomponents-listingdependency {
+ display: flex;
+ gap: 24px;
+ align-items: flex-start;
+ width: 100%;
+ padding: 16px;
+ border-radius: 8px;
+ background: var(--surface-dim);
+ }
+
+ .nimbus-commoncomponents-listingdependency__image {
+ flex-shrink: 0;
+ width: 80px;
+
+ > svg {
+ width: 40px;
+ height: 40px;
+ color: var(--color-surface-a10);
+ }
+ }
+
+ .nimbus-commoncomponents-listingdependency__info {
+ display: flex;
+ gap: 8px;
+ align-items: center;
+ align-self: stretch;
+ }
+
+ .nimbus-commoncomponents-listingdependency__info__name {
+ color: var(--color-text-primary);
+ font-weight: 700;
+ line-height: 150%;
+ }
+
+ .nimbus-commoncomponents-listingdependency__info__title {
+ display: flex;
+ gap: 4px;
+ align-items: center;
+ align-self: stretch;
+ font-weight: 400;
+ font-size: var(--font-size-body-md);
+ line-height: 150%;
+ }
+
+ .nimbus-commoncomponents-listingdependency__info__by {
+ color: var(--color-text-tertiary);
+ }
+
+ .nimbus-commoncomponents-listingdependency__description {
+ align-self: stretch;
+ color: var(--color-text-secondary);
+ font-weight: 400;
+
+ font-size: var(--font-size-body-md, 14px);
+ line-height: 150%;
+ }
+
+ .nimbus-commoncomponents-listingdependency__version {
+ display: flex;
+ gap: 4px;
+ align-items: flex-start;
+ color: var(--color-text-tertiary);
+ font-weight: 400;
+ font-size: var(--font-size-body-sm);
+ line-height: 170%;
+ }
+}
diff --git a/apps/cyberstorm-remix/app/commonComponents/ListingDependency/ListingDependency.tsx b/apps/cyberstorm-remix/app/commonComponents/ListingDependency/ListingDependency.tsx
new file mode 100644
index 000000000..96a83e040
--- /dev/null
+++ b/apps/cyberstorm-remix/app/commonComponents/ListingDependency/ListingDependency.tsx
@@ -0,0 +1,73 @@
+import "./ListingDependency.css";
+import { dependencyShema } from "@thunderstore/dapper-ts";
+import { Image, NewLink } from "@thunderstore/cyberstorm";
+
+export interface ListingDependencyProps {
+ dependency: typeof dependencyShema._type;
+}
+
+export function ListingDependency(props: ListingDependencyProps) {
+ const { dependency } = props;
+
+ return (
+
+
+
+
+
+ {dependency.name}
+
+
+
+ by
+
+
+ {dependency.namespace}
+
+
+
+
+ {dependency.description}
+
+
+ Version:
+
+ {dependency.version_number}
+
+
+
+
+ );
+}
+
+ListingDependency.displayName = "ListingDependency";
diff --git a/apps/cyberstorm-remix/app/commonComponents/PageHeader/PageHeader.css b/apps/cyberstorm-remix/app/commonComponents/PageHeader/PageHeader.css
index 9a23f1e2e..eea7a58a4 100644
--- a/apps/cyberstorm-remix/app/commonComponents/PageHeader/PageHeader.css
+++ b/apps/cyberstorm-remix/app/commonComponents/PageHeader/PageHeader.css
@@ -5,7 +5,7 @@
gap: var(--space-32);
align-items: flex-start;
align-self: stretch;
- padding: var(--space-24) 0;
+ padding: var(--space-24) 25rem var(--space-24) 0;
}
.nimbus-commoncomponents-page-header__image {
diff --git a/apps/cyberstorm-remix/app/p/components/Dependencies/Dependencies.module.css b/apps/cyberstorm-remix/app/p/components/Dependencies/Dependencies.module.css
deleted file mode 100644
index 319e72923..000000000
--- a/apps/cyberstorm-remix/app/p/components/Dependencies/Dependencies.module.css
+++ /dev/null
@@ -1,56 +0,0 @@
-.root {
- display: flex;
- flex-direction: column;
- gap: var(--gap-xs);
- border-radius: 8px;
-}
-
-.countDescription {
- padding: 0 var(--space-8);
- color: var(--color-text-tertiary);
- font-size: var(--font-size-body-lg);
-}
-
-.item {
- display: flex;
- gap: var(--gap-md);
- padding: var(--space-8);
- border-radius: var(--radius-md);
-}
-
-.item:hover {
- background-color: var(--color-surface-4);
-}
-
-.itemImage {
- width: 5rem;
-}
-
-.itemTitle {
- overflow: hidden;
- font-weight: var(--font-weight-bold);
- font-size: var(--font-size-body-lg);
- line-height: var(--line-height--m);
- white-space: nowrap;
- text-overflow: ellipsis;
-}
-
-.itemDescription {
- overflow: hidden;
- color: var(--color-text-tertiary);
- font-size: var(--font-size-body-lg);
- line-height: var(--line-height--m);
- white-space: nowrap;
- text-overflow: ellipsis;
-}
-
-@media (width >= 60rem) {
- .itemDescription,
- .itemTitle {
- max-width: 250px;
- }
-}
-
-.dependencyDialogTrigger {
- align-items: center;
-}
diff --git a/apps/cyberstorm-remix/app/p/components/Dependencies/Dependencies.tsx b/apps/cyberstorm-remix/app/p/components/Dependencies/Dependencies.tsx
deleted file mode 100644
index c8d649f3e..000000000
--- a/apps/cyberstorm-remix/app/p/components/Dependencies/Dependencies.tsx
+++ /dev/null
@@ -1,103 +0,0 @@
-import {
- Button,
- Dialog,
- ImageWithFallback,
- CyberstormLink,
-} from "@thunderstore/cyberstorm";
-import { faBoxOpen } from "@fortawesome/free-solid-svg-icons";
-import { faCaretRight } from "@fortawesome/free-solid-svg-icons";
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import styles from "./Dependencies.module.css";
-import { WrapperCard } from "@thunderstore/cyberstorm/src/components/WrapperCard/WrapperCard";
-import {
- PackageDependency,
- PackageListingDetails,
-} from "@thunderstore/dapper/types";
-import DependencyDialog from "./DependencyDialog/DependencyDialog";
-
-const PREVIEW_LIMIT = 4;
-
-export default function Dependencies(props: {
- listing: PackageListingDetails;
-}) {
- let countDescription = "";
-
- if (props.listing.dependency_count === 0) {
- countDescription = "This mod doesn't depend on other mods.";
- } else if (props.listing.dependency_count > PREVIEW_LIMIT) {
- countDescription = `+ ${
- props.listing.dependency_count - PREVIEW_LIMIT
- } more`;
- }
-
- return (
-
-
-
- {props.listing.dependencies.slice(0, PREVIEW_LIMIT).map((d) => (
-
- ))}
-
-
- {countDescription === "" ? null : (
- {countDescription}
- )}
-
- }
- headerIcon={}
- headerRightContent={
- props.listing.dependency_count > PREVIEW_LIMIT ? (
-
-
-
- See all
-
-
-
-
-
-
- }
- >
-
-
- ) : null
- }
- />
- );
-}
-
-const PackageDependencyListItem = (props: PackageDependency) => (
-
-
-
-
-
-
-
{props.name}
-
{props.description}
-
-
-
-);
-
-PackageDependencyListItem.displayName = "PackageDependencyListItem";
diff --git a/apps/cyberstorm-remix/app/p/components/Dependencies/DependencyDialog/DependencyDialog.module.css b/apps/cyberstorm-remix/app/p/components/Dependencies/DependencyDialog/DependencyDialog.module.css
deleted file mode 100644
index d0538bfeb..000000000
--- a/apps/cyberstorm-remix/app/p/components/Dependencies/DependencyDialog/DependencyDialog.module.css
+++ /dev/null
@@ -1,48 +0,0 @@
-.root {
- font-size: var(--font-size-body-lg);
- line-height: var(--line-height--m);
-}
-
-.image {
- width: 5rem;
-}
-
-.title {
- font-weight: var(--font-weight-bold);
- font-size: var(--font-size-body-xxxxl);
- line-height: var(--line-height--l);
-}
-
-.description {
- color: var(--color-text-tertiary);
- font-weight: var(--font-weight-medium);
- font-size: var(--font-size-body-lg);
- line-height: var(--line-height--m);
-}
-
-.item {
- display: flex;
- gap: var(--gap-xl);
- padding: var(--space-16) var(--space-32);
-}
-
-.item:hover {
- gap: var(--gap-xl);
- padding: var(--space-16) var(--space-32);
- background-color: var(--color-surface-5);
-}
-
-.preferredVersion {
- padding-top: var(--space-6);
- color: var(--color-text-accent);
- font-weight: var(--font-weight-medium);
- font-size: var(--font-size-body-md);
- line-height: var(--line-height--s);
-}
-
-.preferredVersion__version {
- color: var(--color-highlight);
- font-weight: var(--font-weight-medium);
- font-size: var(--font-size-body-md);
- line-height: var(--line-height--s);
-}
diff --git a/apps/cyberstorm-remix/app/p/components/Dependencies/DependencyDialog/DependencyDialog.tsx b/apps/cyberstorm-remix/app/p/components/Dependencies/DependencyDialog/DependencyDialog.tsx
deleted file mode 100644
index 79b277507..000000000
--- a/apps/cyberstorm-remix/app/p/components/Dependencies/DependencyDialog/DependencyDialog.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import { ImageWithFallback, CyberstormLink } from "@thunderstore/cyberstorm";
-import styles from "./DependencyDialog.module.css";
-import { PackageListingDetails } from "@thunderstore/dapper/types";
-
-export default function DependencyDialog(props: {
- listing: PackageListingDetails;
-}) {
- return (
-
- {props.listing.dependencies.map((depData, index) => (
-
-
-
-
-
-
-
- {depData.name}
-
-
-
{depData.description}
-
- Preferred version:{" "}
-
-
- {depData.version_number}
-
-
-
-
-
- ))}
-
- );
-}
diff --git a/apps/cyberstorm-remix/app/p/components/TeamMembers/TeamMembers.module.css b/apps/cyberstorm-remix/app/p/components/TeamMembers/TeamMembers.module.css
index 713227930..60dc5129f 100644
--- a/apps/cyberstorm-remix/app/p/components/TeamMembers/TeamMembers.module.css
+++ b/apps/cyberstorm-remix/app/p/components/TeamMembers/TeamMembers.module.css
@@ -16,10 +16,17 @@
background-color: var(--color-surface-4);
}
+.itemTitleWrapper {
+ min-width: 0;
+}
+
.itemTitle {
display: flex;
gap: 0.25rem;
align-items: center;
+}
+
+.itemTitleUsername {
overflow: hidden;
color: var(--color-text-primary);
font-weight: 700;
diff --git a/apps/cyberstorm-remix/app/p/components/TeamMembers/TeamMembers.tsx b/apps/cyberstorm-remix/app/p/components/TeamMembers/TeamMembers.tsx
index 13e901b28..2beca267b 100644
--- a/apps/cyberstorm-remix/app/p/components/TeamMembers/TeamMembers.tsx
+++ b/apps/cyberstorm-remix/app/p/components/TeamMembers/TeamMembers.tsx
@@ -59,9 +59,11 @@ function PackageTeamListItem(props: PackageTeamListItemProps) {
rootClasses={styles.item}
>
-
+
- {teamMember.username}
+
+ {teamMember.username}
+
{teamMember.role === "owner" ? (
diff --git a/apps/cyberstorm-remix/app/p/packageListing.css b/apps/cyberstorm-remix/app/p/packageListing.css
index 9d6abdcf3..b3cd5c7f7 100644
--- a/apps/cyberstorm-remix/app/p/packageListing.css
+++ b/apps/cyberstorm-remix/app/p/packageListing.css
@@ -19,7 +19,7 @@
flex-direction: column;
gap: 1rem;
align-items: flex-start;
- min-width: 22.125rem;
+ width: 22.125rem;
}
.nimbus-packagelisting__sidebar__install {
diff --git a/apps/cyberstorm-remix/app/p/tabs/Required/Required.css b/apps/cyberstorm-remix/app/p/tabs/Required/Required.css
new file mode 100644
index 000000000..f54a62539
--- /dev/null
+++ b/apps/cyberstorm-remix/app/p/tabs/Required/Required.css
@@ -0,0 +1,29 @@
+.nimbus-packagelisting__tabs__required {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+.nimbus-packagelisting__tabs__required__title {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+ align-items: flex-start;
+ align-self: stretch;
+ padding-bottom: 24px;
+}
+
+.nimbus-packagelisting__tabs__required__title__description {
+ color: var(--color-text-secondary);
+ font-weight: 400;
+ line-height: 150%;
+}
+
+.nimbus-packagelisting__tabs__required__body {
+ display: flex;
+ flex-direction: column;
+ gap: 2px;
+ align-items: flex-start;
+ align-self: stretch;
+ padding-bottom: 32px;
+}
diff --git a/apps/cyberstorm-remix/app/p/tabs/Required/Required.tsx b/apps/cyberstorm-remix/app/p/tabs/Required/Required.tsx
new file mode 100644
index 000000000..d2595215d
--- /dev/null
+++ b/apps/cyberstorm-remix/app/p/tabs/Required/Required.tsx
@@ -0,0 +1,79 @@
+import "./Required.css";
+import { Heading } from "@thunderstore/cyberstorm";
+import { LoaderFunctionArgs } from "@remix-run/node";
+import { getDapper } from "cyberstorm/dapper/sessionUtils";
+import { ApiError } from "@thunderstore/thunderstore-api";
+import { useLoaderData } from "@remix-run/react";
+import { ListingDependency } from "~/commonComponents/ListingDependency/ListingDependency";
+
+export async function loader({ params }: LoaderFunctionArgs) {
+ if (params.communityId && params.namespaceId && params.packageId) {
+ try {
+ const dapper = await getDapper();
+ return {
+ listing: await dapper.getPackageListingDetails(
+ params.communityId,
+ params.namespaceId,
+ params.packageId
+ ),
+ };
+ } catch (error) {
+ if (error instanceof ApiError) {
+ throw new Response("Listing dependencies not found", { status: 404 });
+ } else {
+ // REMIX TODO: Add sentry
+ throw error;
+ }
+ }
+ }
+ throw new Response("Listing dependencies not found", { status: 404 });
+}
+
+export async function clientLoader({ params }: LoaderFunctionArgs) {
+ if (params.communityId && params.namespaceId && params.packageId) {
+ try {
+ const dapper = await getDapper(true);
+ return {
+ listing: await dapper.getPackageListingDetails(
+ params.communityId,
+ params.namespaceId,
+ params.packageId
+ ),
+ };
+ } catch (error) {
+ if (error instanceof ApiError) {
+ throw new Response("Listing dependencies not found", { status: 404 });
+ } else {
+ // REMIX TODO: Add sentry
+ throw error;
+ }
+ }
+ }
+ throw new Response("Listing dependencies not found", { status: 404 });
+}
+
+export default function Versions() {
+ const { listing } = useLoaderData();
+
+ return (
+
+
+
+ Required mods ({listing.dependencies.length})
+
+
+ This package requires the following packages to work.
+
+
+
+ {listing.dependencies.map((dep, key) => {
+ return ;
+ })}
+
+
+ );
+}
diff --git a/apps/cyberstorm-remix/vite.config.ts b/apps/cyberstorm-remix/vite.config.ts
index e123cd349..b0fc42256 100644
--- a/apps/cyberstorm-remix/vite.config.ts
+++ b/apps/cyberstorm-remix/vite.config.ts
@@ -32,6 +32,7 @@ export default defineConfig({
"p/packageListing.tsx",
() => {
route("", "p/tabs/Readme/Readme.tsx", { index: true });
+ route("required", "p/tabs/Required/Required.tsx");
route("changelog", "p/tabs/Changelog/Changelog.tsx");
route("versions", "p/tabs/Versions/Versions.tsx");
}
diff --git a/packages/cyberstorm-theme/src/components/Link/Link.ts b/packages/cyberstorm-theme/src/components/Link/Link.ts
index fc8440038..1591251cd 100644
--- a/packages/cyberstorm-theme/src/components/Link/Link.ts
+++ b/packages/cyberstorm-theme/src/components/Link/Link.ts
@@ -1,3 +1,3 @@
// Variants
-export const LinkVariantsList = ["primary", "cyber"] as const;
-export type LinkVariants = "primary" | "cyber";
+export const LinkVariantsList = ["primary", "accent", "cyber"] as const;
+export type LinkVariants = "primary" | "accent" | "cyber";
diff --git a/packages/cyberstorm/src/components/Avatar/Avatar.module.css b/packages/cyberstorm/src/components/Avatar/Avatar.module.css
index 3aa5fd344..77ba9839a 100644
--- a/packages/cyberstorm/src/components/Avatar/Avatar.module.css
+++ b/packages/cyberstorm/src/components/Avatar/Avatar.module.css
@@ -1,5 +1,6 @@
.root {
display: flex;
+ flex-shrink: 0;
align-items: center;
justify-content: center;
border-radius: calc(var(--size) * 4.92) !important;
diff --git a/packages/cyberstorm/src/newComponents/Image/Image.css b/packages/cyberstorm/src/newComponents/Image/Image.css
index f7ae84635..0a024a630 100644
--- a/packages/cyberstorm/src/newComponents/Image/Image.css
+++ b/packages/cyberstorm/src/newComponents/Image/Image.css
@@ -42,4 +42,8 @@
aspect-ratio: 1;
transition: var(--animation-duration-sm) ease-out;
}
+
+ .ts-image__icon {
+ width: 100%;
+ }
}
diff --git a/packages/cyberstorm/src/newComponents/Image/Image.tsx b/packages/cyberstorm/src/newComponents/Image/Image.tsx
index 5a5161629..0f7f2176a 100644
--- a/packages/cyberstorm/src/newComponents/Image/Image.tsx
+++ b/packages/cyberstorm/src/newComponents/Image/Image.tsx
@@ -66,10 +66,13 @@ export const Image = React.forwardRef(
) : (
diff --git a/packages/dapper-ts/src/index.ts b/packages/dapper-ts/src/index.ts
index 10bf60235..9eecb0f1c 100644
--- a/packages/dapper-ts/src/index.ts
+++ b/packages/dapper-ts/src/index.ts
@@ -6,6 +6,7 @@ import { getCommunities, getCommunity } from "./methods/communities";
import { getCommunityFilters } from "./methods/communityFilters";
import { getCurrentUser, emptyUser } from "./methods/currentUser";
export const getEmptyUser = emptyUser;
+export { dependencyShema } from "./methods/packageListings";
export { currentUserSchema } from "./methods/currentUser";
import {
getPackageChangelog,
diff --git a/packages/dapper-ts/src/methods/packageListings.ts b/packages/dapper-ts/src/methods/packageListings.ts
index 6addbc9e3..0c7fbd44c 100644
--- a/packages/dapper-ts/src/methods/packageListings.ts
+++ b/packages/dapper-ts/src/methods/packageListings.ts
@@ -95,7 +95,7 @@ export async function getPackageListings(
};
}
-const dependencyShema = z.object({
+export const dependencyShema = z.object({
community_identifier: z.string().nonempty(),
description: z.string(),
icon_url: z.string().nonempty().nullable(),