diff --git a/app/features/sendouq/queries/deleteLikesByGroupId.server.ts b/app/features/sendouq/queries/deleteLikesByGroupId.server.ts new file mode 100644 index 000000000..9441e2927 --- /dev/null +++ b/app/features/sendouq/queries/deleteLikesByGroupId.server.ts @@ -0,0 +1,11 @@ +import { sql } from "~/db/sql"; + +const stm = sql.prepare(/* sql */ ` + delete from "GroupLike" + where "likerGroupId" = @groupId + or "targetGroupId" = @groupId +`); + +export function deleteLikesByGroupId(groupId: number) { + stm.run({ groupId }); +} diff --git a/app/features/sendouq/queries/findTeamByInviteCode.server.ts b/app/features/sendouq/queries/findGroupByInviteCode.server.ts similarity index 94% rename from app/features/sendouq/queries/findTeamByInviteCode.server.ts rename to app/features/sendouq/queries/findGroupByInviteCode.server.ts index 27cd3b9d0..dbd366801 100644 --- a/app/features/sendouq/queries/findTeamByInviteCode.server.ts +++ b/app/features/sendouq/queries/findGroupByInviteCode.server.ts @@ -23,7 +23,7 @@ const stm = sql.prepare(/* sql */ ` group by "Group"."id" `); -export function findTeamByInviteCode(inviteCode: string): { +export function findGroupByInviteCode(inviteCode: string): { id: number; status: Group["status"]; members: { id: number; discordName: string; role: GroupMember["role"] }[]; diff --git a/app/features/sendouq/queries/morphGroups.server.ts b/app/features/sendouq/queries/morphGroups.server.ts index 99489cfab..ff9ef65bb 100644 --- a/app/features/sendouq/queries/morphGroups.server.ts +++ b/app/features/sendouq/queries/morphGroups.server.ts @@ -1,4 +1,5 @@ import { sql } from "~/db/sql"; +import { deleteLikesByGroupId } from "./deleteLikesByGroupId.server"; const deleteGroupStm = sql.prepare(/* sql */ ` delete from "Group" @@ -15,12 +16,6 @@ const addGroupMemberStm = sql.prepare(/* sql */ ` values (@groupId, @userId, @role) `); -const deleteLikesStm = sql.prepare(/* sql */ ` - delete from "GroupLike" - where "likerGroupId" = @groupId - or "targetGroupId" = @groupId -`); - export const morphGroups = sql.transaction( ({ survivingGroupId, @@ -34,7 +29,7 @@ export const morphGroups = sql.transaction( deleteGroupStm.run({ groupId: otherGroupId }); deleteGroupMapsStm.run({ groupId: otherGroupId }); - deleteLikesStm.run({ groupId: survivingGroupId }); + deleteLikesByGroupId(survivingGroupId); for (const userId of newMembers) { addGroupMemberStm.run({ diff --git a/app/features/sendouq/routes/q.tsx b/app/features/sendouq/routes/q.tsx index e716c5b97..1a7b2f4d5 100644 --- a/app/features/sendouq/routes/q.tsx +++ b/app/features/sendouq/routes/q.tsx @@ -54,7 +54,7 @@ import type { RankingSeason } from "~/features/mmr/season"; import { nextSeason } from "~/features/mmr/season"; import { useUser } from "~/modules/auth"; import { Button } from "~/components/Button"; -import { findTeamByInviteCode } from "../queries/findTeamByInviteCode.server"; +import { findGroupByInviteCode } from "../queries/findGroupByInviteCode.server"; import { Alert } from "~/components/Alert"; import { Dialog } from "~/components/Dialog"; import { joinListToNaturalString } from "~/utils/arrays"; @@ -74,6 +74,8 @@ import invariant from "tiny-invariant"; import { languagesUnified } from "~/modules/i18n/config"; import { CrossIcon } from "~/components/icons/Cross"; import { updateVCStatus } from "../queries/updateVCStatus.server"; +import { sql } from "~/db/sql"; +import { deleteLikesByGroupId } from "../queries/deleteLikesByGroupId.server"; export const handle: SendouRouteHandle = { i18n: ["q"], @@ -137,27 +139,31 @@ export const action: ActionFunction = async ({ request }) => { JOIN_CODE_SEARCH_PARAM_KEY, ); - const teamInvitedTo = - code && user ? findTeamByInviteCode(code) : undefined; - validate(teamInvitedTo, "Invite code doesn't match any active team"); - validate(teamInvitedTo.members.length < FULL_GROUP_SIZE, "Team is full"); + const groupInvitedTo = + code && user ? findGroupByInviteCode(code) : undefined; + validate(groupInvitedTo, "Invite code doesn't match any active team"); + validate(groupInvitedTo.members.length < FULL_GROUP_SIZE, "Team is full"); - addMember({ - groupId: teamInvitedTo.id, - userId: user.id, - }); - if (data._action === "JOIN_TEAM_WITH_TRUST") { - const owner = teamInvitedTo.members.find((m) => m.role === "OWNER"); - invariant(owner, "Owner not found"); - - giveTrust({ - trustGiverUserId: user.id, - trustReceiverUserId: owner.id, + sql.transaction(() => { + addMember({ + groupId: groupInvitedTo.id, + userId: user.id, }); - } + deleteLikesByGroupId(groupInvitedTo.id); + + if (data._action === "JOIN_TEAM_WITH_TRUST") { + const owner = groupInvitedTo.members.find((m) => m.role === "OWNER"); + invariant(owner, "Owner not found"); + + giveTrust({ + trustGiverUserId: user.id, + trustReceiverUserId: owner.id, + }); + } + })(); return redirect( - teamInvitedTo.status === "PREPARING" + groupInvitedTo.status === "PREPARING" ? SENDOUQ_PREPARING_PAGE : SENDOUQ_LOOKING_PAGE, ); @@ -206,7 +212,7 @@ export const loader = async ({ request }: LoaderArgs) => { throw redirect(`${redirectLocation}${code ? "?joining=true" : ""}`); } - const teamInvitedTo = code && user ? findTeamByInviteCode(code) : undefined; + const groupInvitedTo = code && user ? findGroupByInviteCode(code) : undefined; const now = new Date(); const season = currentSeason(now); @@ -219,7 +225,7 @@ export const loader = async ({ request }: LoaderArgs) => { : null, season, upcomingSeason, - teamInvitedTo, + groupInvitedTo, }; }; @@ -248,18 +254,18 @@ export default function QPage() { ) : null} {data.season ? ( <> - {data.hasSkill && data.teamInvitedTo === null ? ( + {data.hasSkill && data.groupInvitedTo === null ? ( Invite code doesn't match any active team ) : null} - {data.teamInvitedTo && - data.teamInvitedTo.members.length < FULL_GROUP_SIZE && + {data.groupInvitedTo && + data.groupInvitedTo.members.length < FULL_GROUP_SIZE && data.hasSkill ? ( setDialogOpen(false)} - members={data.teamInvitedTo.members} + members={data.groupInvitedTo.members} /> ) : null} {!data.hasSkill && user ? : null}