Make join queue buttons join the queue directly via action

This commit is contained in:
Kalle
2026-06-20 11:23:14 +03:00
parent 056809b3ef
commit 67d317e80f
3 changed files with 49 additions and 14 deletions

View File

@@ -12,7 +12,7 @@ import {
import { ListButton } from "~/components/SideNav";
import { SENDOUQ_ACTIVITY_LABEL } from "~/features/friends/friends-constants";
import { useDateTimeFormat } from "~/hooks/intl/useDateTimeFormat";
import { SENDOUQ_LOOKING_PAGE, tournamentSubsPage } from "~/utils/urls";
import { SENDOUQ_PAGE, tournamentSubsPage } from "~/utils/urls";
export function FriendMenu({
discordId,
@@ -54,7 +54,7 @@ export function FriendMenu({
})
: null;
const activityHref = resolveActivityHref({ subtitle, tournamentId });
const activity = resolveActivity({ subtitle, tournamentId });
return (
<>
@@ -73,15 +73,27 @@ export function FriendMenu({
<SendouMenuItem href={url} icon={<User />} onAction={onNavigate}>
{t("friends:friendsList.viewUserPage")}
</SendouMenuItem>
{activityHref ? (
{activity?.type === "sendouq" ? (
<SendouMenuItem
href={activityHref.url}
icon={<Swords />}
onAction={() => {
fetcher.submit(
{ _action: "JOIN_QUEUE", direct: "true" },
{ method: "post", action: SENDOUQ_PAGE },
);
onNavigate?.();
}}
>
{t("friends:friendsList.joinSendouQ")}
</SendouMenuItem>
) : null}
{activity?.type === "tournament" ? (
<SendouMenuItem
href={activity.url}
icon={<Swords />}
onAction={onNavigate}
>
{activityHref.isSendouQ
? t("friends:friendsList.joinSendouQ")
: t("friends:friendsList.viewTournament")}
{t("friends:friendsList.viewTournament")}
</SendouMenuItem>
) : null}
{friendshipId !== undefined ? (
@@ -130,18 +142,21 @@ export function FriendMenu({
);
}
function resolveActivityHref(friend: {
function resolveActivity(friend: {
subtitle: string | null;
tournamentId: number | null;
}) {
if (!friend.subtitle) return null;
if (friend.subtitle === SENDOUQ_ACTIVITY_LABEL) {
return { url: SENDOUQ_LOOKING_PAGE, isSendouQ: true };
return { type: "sendouq" } as const;
}
if (friend.tournamentId) {
return { url: tournamentSubsPage(friend.tournamentId), isSendouQ: false };
return {
type: "tournament",
url: tournamentSubsPage(friend.tournamentId),
} as const;
}
return null;

View File

@@ -1,5 +1,5 @@
import { useTranslation } from "react-i18next";
import { Link, useFetcher } from "react-router";
import { useFetcher } from "react-router";
import { SendouButton } from "~/components/elements/Button";
import { SENDOUQ_PAGE } from "~/utils/urls";
import * as RejoinVote from "../core/RejoinVote";
@@ -95,14 +95,25 @@ export function TrustedRejoinSection({
function DeclinedSection() {
const { t } = useTranslation(["q"]);
const rejoinFetcher = useFetcher();
return (
<div className="stack md items-center">
<p className="text-lighter text-sm text-center">
{t("q:match.rematch.declined")}
</p>
<Link to={SENDOUQ_PAGE} className="text-sm">
<SendouButton
variant="minimal"
className="text-sm font-bold"
isPending={rejoinFetcher.state !== "idle"}
onPress={() => {
rejoinFetcher.submit(
{ _action: "JOIN_QUEUE", direct: "true" },
{ method: "post", action: SENDOUQ_PAGE },
);
}}
>
{t("q:match.rematch.rejoinQueue")}
</Link>
</SendouButton>
</div>
);
}

View File

@@ -18,7 +18,11 @@ import { refreshSendouQInstance, SendouQ } from "../core/SendouQ.server";
import { JOIN_CODE_SEARCH_PARAM_KEY } from "../q-constants";
import { frontPageSchema } from "../q-schemas.server";
import { userCanJoinQueueAt } from "../q-utils";
import { SendouQError, setGroupChatMetadata } from "../q-utils.server";
import {
SendouQError,
setGroupChatMetadata,
sqRedirectIfNeeded,
} from "../q-utils.server";
export const action: ActionFunction = async ({ request, url }) => {
const user = requireUser();
@@ -30,6 +34,11 @@ export const action: ActionFunction = async ({ request, url }) => {
try {
switch (data._action) {
case "JOIN_QUEUE": {
sqRedirectIfNeeded({
ownGroup: SendouQ.findOwnGroup(user.id),
currentLocation: "default",
});
await validateCanJoinQ(user);
const { chatCodeToRevalidate } = await SQGroupRepository.createGroup({