-
+
Thunderstore Mod Manager
;
+export function DropDownDivider(props: PrimitiveComponentDefaultProps) {
+ const { rootClasses, ...fProps } = props;
+ return (
+
+ );
}
DropDown.displayName = "DropDown";
diff --git a/packages/cyberstorm/src/newComponents/Heading/Heading.tsx b/packages/cyberstorm/src/newComponents/Heading/Heading.tsx
index 0093ac1fd..7419747ee 100644
--- a/packages/cyberstorm/src/newComponents/Heading/Heading.tsx
+++ b/packages/cyberstorm/src/newComponents/Heading/Heading.tsx
@@ -1,14 +1,16 @@
-import { PropsWithChildren } from "react";
import styles from "./Heading.module.css";
import React from "react";
-import { Frame } from "../../primitiveComponents/Frame/Frame";
+import {
+ Frame,
+ FrameHeadingProps,
+ FrameDisplayProps,
+} from "../../primitiveComponents/Frame/Frame";
+import { classnames } from "../../utils/utils";
interface DefaultProps
extends React.HTMLAttributes,
- PropsWithChildren {
- level?: "1" | "2" | "3" | "4";
- styleLevel?: "1" | "2" | "3" | "4";
- variant?: "primary" | "secondary" | "tertiary" | "accent";
+ Omit,
+ Omit {
mode?: "heading" | "display";
}
@@ -16,9 +18,10 @@ export const Heading = React.forwardRef(
(props: DefaultProps, forwardedRef) => {
const {
children,
- variant = "primary",
- level = "1",
- styleLevel,
+ rootClasses,
+ csVariant = "primary",
+ csLevel = "1",
+ csStyleLevel,
mode = "heading",
...forwardedProps
} = props;
@@ -27,10 +30,10 @@ export const Heading = React.forwardRef(
{children}
diff --git a/packages/cyberstorm/src/newComponents/Link/Link/Link.module.css b/packages/cyberstorm/src/newComponents/Link/Link/Link.module.css
index 5cc237a41..8bb51f0b4 100644
--- a/packages/cyberstorm/src/newComponents/Link/Link/Link.module.css
+++ b/packages/cyberstorm/src/newComponents/Link/Link/Link.module.css
@@ -49,6 +49,18 @@
--link-color: var(--color-primary);
}
+.link[data-variant="tertiary"] {
+ --link-color: var(--color-tertiary);
+}
+
+.link[data-variant="tertiary"]:hover {
+ --link-color: var(--color-primary);
+}
+
+.link[data-variant="tertiary"]:active {
+ --link-color: var(--color-primary);
+}
+
.link[data-variant="accent"] {
--link-color: var(--color-accent);
}
diff --git a/packages/cyberstorm/src/newComponents/Modal/Modal.module.css b/packages/cyberstorm/src/newComponents/Modal/Modal.module.css
index 673e2afa8..332c6c53d 100644
--- a/packages/cyberstorm/src/newComponents/Modal/Modal.module.css
+++ b/packages/cyberstorm/src/newComponents/Modal/Modal.module.css
@@ -25,4 +25,7 @@
right: 1rem;
width: 2.75rem;
height: 2.75rem;
+
+ /* TODO: Fix the specifity issue with button styles */
+ --button-color: var(--color-tertiary) !important;
}
diff --git a/packages/cyberstorm/src/newComponents/Modal/Modal.tsx b/packages/cyberstorm/src/newComponents/Modal/Modal.tsx
index c788bf54c..e760af4a0 100644
--- a/packages/cyberstorm/src/newComponents/Modal/Modal.tsx
+++ b/packages/cyberstorm/src/newComponents/Modal/Modal.tsx
@@ -11,13 +11,16 @@ interface Props extends Omit {
// TODO: Add storybook story
export function Modal(props: Props) {
+ const { csColor = "surface", csVariant = "default" } = props;
+
return (
<>
{props.trigger}
-
+
diff --git a/packages/cyberstorm/src/newComponents/Text/Text.module.css b/packages/cyberstorm/src/newComponents/Text/Text.module.css
new file mode 100644
index 000000000..ecb2fb755
--- /dev/null
+++ b/packages/cyberstorm/src/newComponents/Text/Text.module.css
@@ -0,0 +1,26 @@
+/* Common text styles */
+.text {
+ color: var(--text-color);
+
+ --text-color: var(--color-primary);
+}
+
+.text[data-variant="default"] {
+ --text-color: var(--color-7);
+}
+
+.text[data-variant="primary"] {
+ --text-color: var(--color-primary);
+}
+
+.text[data-variant="secondary"] {
+ --text-color: var(--color-secondary);
+}
+
+.text[data-variant="tertiary"] {
+ --text-color: var(--color-tertiary);
+}
+
+.text[data-variant="accent"] {
+ --text-color: var(--color-accent);
+}
diff --git a/packages/cyberstorm/src/newComponents/Text/Text.tsx b/packages/cyberstorm/src/newComponents/Text/Text.tsx
new file mode 100644
index 000000000..3f664edb9
--- /dev/null
+++ b/packages/cyberstorm/src/newComponents/Text/Text.tsx
@@ -0,0 +1,23 @@
+import styles from "./Text.module.css";
+import React from "react";
+import { FrameTextProps, Frame } from "../../primitiveComponents/Frame/Frame";
+import { classnames } from "../../utils/utils";
+
+export const Text = React.forwardRef<
+ HTMLParagraphElement,
+ Omit
+>((props: Omit, forwardedRef) => {
+ const { children, rootClasses, ...forwardedProps } = props;
+ return (
+
+ {children}
+
+ );
+});
+
+Text.displayName = "Text";
diff --git a/packages/cyberstorm/src/sharedComponentStyles/ButtonStyles/Button.module.css b/packages/cyberstorm/src/sharedComponentStyles/ButtonStyles/Button.module.css
index a6876b189..d98972c10 100644
--- a/packages/cyberstorm/src/sharedComponentStyles/ButtonStyles/Button.module.css
+++ b/packages/cyberstorm/src/sharedComponentStyles/ButtonStyles/Button.module.css
@@ -46,22 +46,22 @@
/* primary */
.button[data-variant="primary"] {
- --button-color: var(--color-text--default);
- --button-bg-color: var(--color-surface--10);
+ --button-color: var(--color-primary);
+ --button-bg-color: hsl(256deg 60% 52% / 1);
}
.button[data-variant="primary"]:hover {
- --button-bg-color: var(--color-surface--10--hover);
+ --button-bg-color: hsl(256deg 67% 56% / 1);
}
.button[data-variant="primary"]:active {
- background-color: var(--button-bg-color-active);
+ background-color: hsl(256deg 60% 52% / 1);
}
/* secondary */
.button[data-variant="secondary"] {
- --button-color: var(--color-text--default);
+ --button-color: var(--color-primary);
--button-bg-color: var(--color-6);
}
@@ -76,7 +76,7 @@
/* tertiary */
.button[data-variant="tertiary"] {
- --button-color: var(--color-text--default);
+ --button-color: var(--color-primary);
--button-bg-color: transparent;
}
diff --git a/packages/dapper-ts/src/index.ts b/packages/dapper-ts/src/index.ts
index 7133552ed..10bf60235 100644
--- a/packages/dapper-ts/src/index.ts
+++ b/packages/dapper-ts/src/index.ts
@@ -24,13 +24,16 @@ import {
export interface DapperTsInterface extends DapperInterface {
config: RequestConfig;
+ removeSessionHook?: () => void;
}
export class DapperTs implements DapperTsInterface {
config: RequestConfig;
+ removeSessionHook?: () => void;
- constructor(config: RequestConfig) {
+ constructor(config: RequestConfig, removeSessionHook?: () => void) {
this.config = config;
+ this.removeSessionHook = removeSessionHook;
this.getDynamicHTML = this.getDynamicHTML.bind(this);
this.getCommunities = this.getCommunities.bind(this);
this.getCommunity = this.getCommunity.bind(this);
diff --git a/packages/dapper-ts/src/methods/currentUser.ts b/packages/dapper-ts/src/methods/currentUser.ts
index f0233edfc..6d2647667 100644
--- a/packages/dapper-ts/src/methods/currentUser.ts
+++ b/packages/dapper-ts/src/methods/currentUser.ts
@@ -1,5 +1,5 @@
import { z } from "zod";
-import { fetchCurrentUser } from "@thunderstore/thunderstore-api";
+import { ApiError, fetchCurrentUser } from "@thunderstore/thunderstore-api";
import { DapperTsInterface } from "../index";
import { formatErrorMessage } from "../utils";
@@ -55,20 +55,33 @@ export async function getCurrentUser(this: DapperTsInterface) {
return emptyUser;
}
- const data = await fetchCurrentUser(this.config);
- const parsed = schema.safeParse(data);
+ try {
+ const data = await fetchCurrentUser(this.config);
+ const parsed = schema.safeParse(data);
- if (!parsed.success) {
- throw new Error(formatErrorMessage(parsed.error));
- }
+ if (!parsed.success) {
+ throw new Error(formatErrorMessage(parsed.error));
+ }
- // For legacy support, the backend returns teams in two formats.
- // Clients don't need to know about the old one, so replace it with
- // the new one.
- const { teams_full, ...currentUser } = {
- ...parsed.data,
- teams: parsed.data.teams_full,
- };
+ // For legacy support, the backend returns teams in two formats.
+ // Clients don't need to know about the old one, so replace it with
+ // the new one.
+ const { teams_full, ...currentUser } = {
+ ...parsed.data,
+ teams: parsed.data.teams_full,
+ };
- return currentUser;
+ return currentUser;
+ } catch (err) {
+ if (
+ err instanceof ApiError &&
+ err.response.status === 401 &&
+ this.removeSessionHook
+ ) {
+ this.removeSessionHook();
+ return emptyUser;
+ } else {
+ throw err;
+ }
+ }
}
diff --git a/packages/thunderstore-api/src/apiFetch.ts b/packages/thunderstore-api/src/apiFetch.ts
index 4ba043352..b6f0e0a0a 100644
--- a/packages/thunderstore-api/src/apiFetch.ts
+++ b/packages/thunderstore-api/src/apiFetch.ts
@@ -10,15 +10,20 @@ export type apiFetchArgs = {
path: string;
query?: string;
request?: Omit;
+ useSession?: boolean;
};
export async function apiFetch2(args: apiFetchArgs) {
- const url = getUrl(args.config, args.path, args.query);
+ const { config, path, request, query, useSession = false } = args;
+ const usedConfig: RequestConfig = useSession
+ ? config
+ : { apiHost: config.apiHost, csrfToken: undefined, sessionId: undefined };
+ const url = getUrl(usedConfig, path, query);
const response = await fetch(url, {
- ...(args.request ?? {}),
+ ...(request ?? {}),
headers: {
...BASE_HEADERS,
- ...getAuthHeaders(args.config),
+ ...getAuthHeaders(usedConfig),
},
});
@@ -33,7 +38,8 @@ export function apiFetch(
config: RequestConfig,
path: string,
query?: string,
- request?: Omit
+ request?: Omit,
+ useSession?: boolean
) {
// TODO: Update the apiFetch signature to take in object args instead
// of positional arguments and then merge apiFetch and apiFetch2
@@ -43,6 +49,7 @@ export function apiFetch(
path,
query,
request,
+ useSession,
});
}
diff --git a/packages/thunderstore-api/src/fetch/currentUser.ts b/packages/thunderstore-api/src/fetch/currentUser.ts
index 5fd9059c0..c66128624 100644
--- a/packages/thunderstore-api/src/fetch/currentUser.ts
+++ b/packages/thunderstore-api/src/fetch/currentUser.ts
@@ -5,5 +5,5 @@ export async function fetchCurrentUser(config: RequestConfig) {
const path = "api/experimental/current-user/";
const request = { cache: "no-store" as RequestCache };
- return await apiFetch(config, path, undefined, request);
+ return await apiFetch(config, path, undefined, request, true);
}
diff --git a/packages/ts-api-react/src/SessionContext.tsx b/packages/ts-api-react/src/SessionContext.tsx
index 1e4f620f5..80830bfcc 100644
--- a/packages/ts-api-react/src/SessionContext.tsx
+++ b/packages/ts-api-react/src/SessionContext.tsx
@@ -191,6 +191,12 @@ const useValidateSession = (
return;
}
+ const deleteCookie = (name: string) => {
+ const date = new Date();
+ date.setTime(0);
+ document.cookie = `${name}=${null}; expires=${date.toUTCString()}; path=/`;
+ };
+
(async () => {
const res = await fetch(`${domain}/api/experimental/auth/validate/`, {
headers: {
@@ -204,6 +210,8 @@ const useValidateSession = (
_storage.removeValue(ID_KEY);
_storage.removeValue(CSRF_TOKEN);
_storage.removeValue(USERNAME_KEY);
+ deleteCookie("sessionid");
+ deleteCookie("csrftoken");
// Router.push("/");
return;
}