rune
Version:
CLI to upload your games to Rune
96 lines (95 loc) • 4.73 kB
JavaScript
import { ApolloError } from "@apollo/client/errors/index.js";
import { Box, Text } from "ink";
import React, { useEffect, useMemo, useRef, useState } from "react";
import { Step } from "../../components/Step.js";
import { useGames } from "../../gql/useGames.js";
import { useUpdateGameSdk } from "../../gql/useUpdateGameSdk.js";
import { formatApolloError } from "../../lib/formatApolloError.js";
export function UpdateAll({ args }) {
const filteredGameIds = useMemo(() => args.slice(1), [args]);
const { updateGameSdk } = useUpdateGameSdk();
const { games, gamesLoading } = useGames();
const gamesWithLatestActiveDraftOrInReviewVersions = useMemo(() => games
?.filter((g) => filteredGameIds.length === 0 ||
filteredGameIds.includes(g.id.toString()))
?.map((g) => ({
gameId: g.id,
gameVersionId: g.gameVersions.nodes
.filter((v) => v.status === "DRAFT" ||
v.status === "ACTIVE" ||
v.status === "IN_REVIEW")
.at(0)?.gameVersionId,
}))
.filter((g) => !!g.gameVersionId), [games, filteredGameIds]);
const queue = useRef(Promise.resolve());
const [progressText, setProgressText] = useState("");
const [successes, setSuccesses] = useState([]);
const [failures, setFailures] = useState([]);
const [done, setDone] = useState(false);
useEffect(() => {
if (!gamesLoading && gamesWithLatestActiveDraftOrInReviewVersions) {
gamesWithLatestActiveDraftOrInReviewVersions.forEach(({ gameId, gameVersionId }, i) => {
queue.current = queue.current.then(async () => {
setProgressText(`Updating game ${i + 1} of ${gamesWithLatestActiveDraftOrInReviewVersions.length}`);
try {
const result = await updateGameSdk({ gameId });
if (result?.success) {
setSuccesses((prev) => [...prev, { gameId, gameVersionId }]);
}
else {
setFailures((prev) => [
...prev,
{
gameId,
gameVersionId,
error: result?.error ?? "Unknown error",
},
]);
}
}
catch (error) {
setFailures((prev) => [
...prev,
{
gameId,
gameVersionId,
error: error instanceof ApolloError
? formatApolloError(error, {
default: error.message,
})
: JSON.stringify(error),
},
]);
}
});
});
queue.current.then(() => setDone(true));
}
}, [
gamesLoading,
gamesWithLatestActiveDraftOrInReviewVersions,
updateGameSdk,
]);
return (React.createElement(Step, { status: done ? (failures.length ? "error" : "success") : "waiting", label: done
? failures.length
? successes.length
? "Some games failed to update"
: "All games failed to update"
: "Finished updating all games"
: progressText, view: React.createElement(Box, { flexDirection: "column" },
!!successes.length && (React.createElement(Box, { flexDirection: "column" },
React.createElement(Text, { color: "green" }, "Successfully updated games:"),
React.createElement(Box, { paddingLeft: 1 },
React.createElement(Text, { color: "green" }, successes
.map(({ gameId, gameVersionId }) => `#${gameId} (v${gameVersionId})`)
.join(", "))))),
!!failures.length && (React.createElement(Box, { flexDirection: "column" },
React.createElement(Text, { color: "red" }, "Failed to update:"),
React.createElement(Box, { flexDirection: "column", paddingLeft: 1 }, failures.map(({ gameId, gameVersionId, error }) => (React.createElement(Text, { key: `${gameId}-${gameVersionId}`, color: "red" },
"#",
gameId,
" (v",
gameVersionId,
"): ",
error))))))) }));
}