From c61efe0c3e8c5d064d4d663128452fa5a3ca2efd Mon Sep 17 00:00:00 2001
From: zkldi <20380519+zkldi@users.noreply.github.com>
Date: Sat, 26 Mar 2022 23:45:43 +0000
Subject: [PATCH] Goals Work
---
.../src/app/pages/dashboard/DashboardPage.tsx | 119 ++++++++++++++----
.../game/charts/ChartInfoFormat.tsx | 4 +-
.../components/tables/goals/UserGoalTable.tsx | 73 +++++++++++
client/src/types/api-returns.ts | 6 +
client/src/util/data.ts | 11 ++
client/src/util/splashes.ts | 10 +-
6 files changed, 197 insertions(+), 26 deletions(-)
create mode 100644 client/src/components/tables/goals/UserGoalTable.tsx
diff --git a/client/src/app/pages/dashboard/DashboardPage.tsx b/client/src/app/pages/dashboard/DashboardPage.tsx
index 518ec4a6f..10d1720d9 100644
--- a/client/src/app/pages/dashboard/DashboardPage.tsx
+++ b/client/src/app/pages/dashboard/DashboardPage.tsx
@@ -2,11 +2,14 @@ import { APIFetchV1 } from "util/api";
import { RFA } from "util/misc";
import { NumericSOV } from "util/sorts";
import { heySplashes } from "util/splashes";
+import { ChangeOpacity } from "util/color-opacity";
+import { CreateGoalMap } from "util/data";
import useSetSubheader from "components/layout/header/useSetSubheader";
import SessionCard from "components/sessions/SessionCard";
import ApiError from "components/util/ApiError";
import AsyncLoader from "components/util/AsyncLoader";
import Divider from "components/util/Divider";
+import GentleLink from "components/util/GentleLink";
import LinkButton from "components/util/LinkButton";
import Loading from "components/util/Loading";
import useApiQuery from "components/util/query/useApiQuery";
@@ -17,8 +20,9 @@ import { TachiConfig } from "lib/config";
import React, { useContext } from "react";
import { Alert } from "react-bootstrap";
import { Link } from "react-router-dom";
-import { GetGameConfig, PublicUserDocument } from "tachi-common";
+import { COLOUR_SET, GetGameConfig, PublicUserDocument } from "tachi-common";
import { UGSWithRankingData, UserRecentSummary } from "types/api-returns";
+import { FolderInfoComponent } from "./users/games/_game/_playtype/folders/FolderSelectPage";
import { GameStatContainer } from "./users/UserGamesPage";
export function DashboardPage() {
@@ -73,33 +77,100 @@ function RecentInfo({ user }: { user: PublicUserDocument }) {
return ;
}
- if (!data.recentSessions.length) {
- return <>>;
+ const folderInfoMap = new Map();
+ for (const folderInfo of data.recentFolderStats) {
+ folderInfoMap.set(folderInfo.folderID, folderInfo);
}
+ const goalMap = CreateGoalMap(data.recentGoals);
+
return (
<>
-
-
-
Today's Summary
- You've gotten {data.recentPlaycount} new score
- {data.recentPlaycount !== 1 ? "s" : ""} today!
-
-
-
- New Sessions
- You've had {data.recentSessions.length} session
- {data.recentSessions.length !== 1 ? "s" : ""} today!
-
- {data.recentSessions.sort(NumericSOV(x => x.timeEnded, true)).map(e => (
-
- ))}
-
+ {data.recentSessions.length !== 0 && (
+ <>
+
+
+
Today's Summary
+ You've gotten {data.recentPlaycount} new score
+ {data.recentPlaycount !== 1 ? "s" : ""} today!
+
+
+
+ New Sessions
+ You've had {data.recentSessions.length} session
+ {data.recentSessions.length !== 1 ? "s" : ""} today!
+
+ {data.recentSessions.sort(NumericSOV(x => x.timeEnded, true)).map(e => (
+
+ ))}
+
+ >
+ )}
+ {data.recentAchievedGoals.length !== 0 && (
+ <>
+
+
+
+ {RFA([
+ "Sweet!",
+ "Nice!",
+ "Lookin' good!",
+ "Good Stuff!",
+ "owo",
+ "Cool!",
+ "Awesome!",
+ "Epic!",
+ ])}
+
+ You've achieved {data.recentAchievedGoals.length} new goal
+ {data.recentAchievedGoals.length !== 1 ? "s" : ""} today!
+
+
+
+
+ {data.recentAchievedGoals.map(e => (
+
+ - {goalMap.get(e.goalID)?.title}
+
+ ))}
+
+
+
+
+ >
+ )}
+ {data.recentFolders.length !== 0 && (
+ <>
+ Here's some folders you checked out recently.
+
+
+ {data.recentFolders.map(e => (
+
+ ))}
+
+
+ >
+ )}
>
);
}
diff --git a/client/src/components/game/charts/ChartInfoFormat.tsx b/client/src/components/game/charts/ChartInfoFormat.tsx
index eb48edb33..82bb9e1cf 100644
--- a/client/src/components/game/charts/ChartInfoFormat.tsx
+++ b/client/src/components/game/charts/ChartInfoFormat.tsx
@@ -6,6 +6,7 @@ import Loading from "components/util/Loading";
import Muted from "components/util/Muted";
import useApiQuery from "components/util/query/useApiQuery";
import { UserContext } from "context/UserContext";
+import { UserGameStatsContext } from "context/UserGameStatsContext";
import React, { useContext } from "react";
import { Col, Row } from "react-bootstrap";
import { Link } from "react-router-dom";
@@ -26,6 +27,7 @@ export default function ChartInfoFormat({
);
const { user } = useContext(UserContext);
+ const { ugs } = useContext(UserGameStatsContext);
if (error) {
;
@@ -48,7 +50,7 @@ export default function ChartInfoFormat({
{data.length !== 0 ? (
data.map(e => (
- {user ? (
+ {user && ugs ? (
[] = [
+ ["User", "User", StrSOV(x => x.__related.user.username)],
+ ["Goal", "Goal", StrSOV(x => x.__related.goal.title)],
+ [
+ "Progress",
+ "Progress",
+ NumericSOV(x => (x.progress === null ? -Infinity : x.progress / x.outOf)),
+ ],
+ ["Achieved On", "Achieved", NumericSOV(x => x.timeAchieved ?? -Infinity)],
+ ];
+
+ return (
+ k.__related.user.username,
+ goal: k => k.__related.goal.title,
+ timestamp: k => k.timeAchieved,
+ }}
+ rowFunction={d => (
+
+
+ |
+
+ {d.__related.goal.title}
+
+ |
+
+ {d.achieved ? (
+ Achieved!
+ ) : (
+ <>
+ {d.progress ?? "N/A"}
+ /{d.outOfHuman}
+ >
+ )}
+ |
+
+
+ )}
+ />
+ );
+}
diff --git a/client/src/types/api-returns.ts b/client/src/types/api-returns.ts
index 071f38d6e..765303c4f 100644
--- a/client/src/types/api-returns.ts
+++ b/client/src/types/api-returns.ts
@@ -4,6 +4,7 @@ import {
ClassAchievementDocument,
FolderDocument,
GamePTConfig,
+ GoalDocument,
Grades,
IDStrings,
IDStringToGame,
@@ -20,6 +21,7 @@ import {
UGSRatingsLookup,
UserGameStats,
UserGameStatsSnapshot,
+ UserGoalDocument,
} from "tachi-common";
export interface UGPTStatsReturn {
@@ -162,6 +164,10 @@ export interface UserRecentSummary {
recentPlaycount: integer;
recentSessions: SessionDocument[];
recentFolders: FolderDocument[];
+ recentFolderStats: FolderStatsInfo[];
+ recentGoals: GoalDocument[];
+ recentImprovedGoals: UserGoalDocument[];
+ recentAchievedGoals: UserGoalDocument[];
}
export interface ServerStatus {
diff --git a/client/src/util/data.ts b/client/src/util/data.ts
index 2c1c39cc7..f4df10dd4 100644
--- a/client/src/util/data.ts
+++ b/client/src/util/data.ts
@@ -1,6 +1,7 @@
import {
ChartDocument,
Game,
+ GoalDocument,
IDStrings,
integer,
PublicUserDocument,
@@ -33,6 +34,16 @@ export function CreateUserMap(users: PublicUserDocument[]) {
return userMap;
}
+export function CreateGoalMap(goals: GoalDocument[]) {
+ const goalMap = new Map();
+
+ for (const goal of goals) {
+ goalMap.set(goal.goalID, goal);
+ }
+
+ return goalMap;
+}
+
export function CreateChartIDMap(arr: T[]): Map {
const map = new Map();
diff --git a/client/src/util/splashes.ts b/client/src/util/splashes.ts
index 35b5c31ae..c5ccb2ae0 100644
--- a/client/src/util/splashes.ts
+++ b/client/src/util/splashes.ts
@@ -110,6 +110,13 @@ export const loggedInSplashes = [
"ok deraadt miod",
"What good are notebooks?",
"Ladies and Gentlemen We Are...",
+ "Source: It came to me in a dream.",
+ "It's called solidarity, you wouldn't get it.",
+ "Come to my house and play BMS.",
+ "There is a leviathan in play.",
+ "Touch Grass.",
+ "arch btw",
+ "Upon Such Great Heights",
];
// Stuff that's bad for the kids, you know?
@@ -126,8 +133,9 @@ export const contentiousSplashes = [
"I have the transfeminine urge to pee.",
"I HAVE TO LIE IN THE MIDDLE OF THE FLOOR",
"COMPLETELY MOTIONLESS NOT DARING TO BREATHE",
- "I wouldn't trade one stupid decision<