mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-05-11 13:15:18 -05:00
sq initial
This commit is contained in:
parent
a47b3024cc
commit
a4f9b8d251
|
|
@ -1,21 +1,81 @@
|
|||
import type { LoaderFunctionArgs } from "react-router";
|
||||
import { getUser } from "~/features/auth/core/user.server";
|
||||
import { chatAccessible } from "~/features/chat/chat-utils";
|
||||
import { SendouQ } from "~/features/sendouq/core/SendouQ.server";
|
||||
import * as PrivateUserNoteRepository from "~/features/sendouq/PrivateUserNoteRepository.server";
|
||||
import { reportedWeaponsToArrayOfArrays } from "~/features/sendouq-match/core/reported-weapons.server";
|
||||
import * as ReportedWeaponRepository from "~/features/sendouq-match/ReportedWeaponRepository.server";
|
||||
import * as SQMatchRepository from "~/features/sendouq-match/SQMatchRepository.server";
|
||||
import { databaseTimestampToDate } from "~/utils/dates";
|
||||
import { notFoundIfFalsy, parseParams } from "~/utils/remix.server";
|
||||
import { qMatchPageParamsSchema } from "../q-match-schemas";
|
||||
|
||||
// export const loader = async ({ params }: LoaderFunctionArgs) => {
|
||||
// const user = getUser();
|
||||
// const matchId = parseParams({
|
||||
// params,
|
||||
// schema: qMatchPageParamsSchema,
|
||||
// }).id;
|
||||
// const matchUnmapped = notFoundIfFalsy(
|
||||
// await SQMatchRepository.findById(matchId),
|
||||
// );
|
||||
|
||||
// const matchUsers = [
|
||||
// ...matchUnmapped.groupAlpha.members,
|
||||
// ...matchUnmapped.groupBravo.members,
|
||||
// ].map((m) => m.id);
|
||||
// const privateNotes = user
|
||||
// ? await PrivateUserNoteRepository.byAuthorUserId(user.id, matchUsers)
|
||||
// : undefined;
|
||||
|
||||
// const match = SendouQ.mapMatch(matchUnmapped, user, privateNotes);
|
||||
|
||||
// const rawReportedWeapons = match.reportedAt
|
||||
// ? await ReportedWeaponRepository.findByMatchId(matchId)
|
||||
// : null;
|
||||
|
||||
// return {
|
||||
// match,
|
||||
// reportedWeapons: match.reportedAt
|
||||
// ? reportedWeaponsToArrayOfArrays({
|
||||
// groupAlpha: match.groupAlpha,
|
||||
// groupBravo: match.groupBravo,
|
||||
// mapList: match.mapList,
|
||||
// reportedWeapons: rawReportedWeapons,
|
||||
// })
|
||||
// : null,
|
||||
// rawReportedWeapons,
|
||||
// chatCode: (() => {
|
||||
// const isStaff = user?.roles.includes("STAFF") ?? false;
|
||||
// const isParticipant = user && matchUsers.includes(user.id);
|
||||
|
||||
// if (!(isStaff || isParticipant)) return null;
|
||||
|
||||
// const accessible = chatAccessible({
|
||||
// isStaff,
|
||||
// expiresAfterDays: 1,
|
||||
// comparedTo: databaseTimestampToDate(matchUnmapped.createdAt),
|
||||
// });
|
||||
// if (!accessible) return null;
|
||||
|
||||
// if (!isParticipant) return match.chatCode ?? null;
|
||||
|
||||
// const codes = [
|
||||
// match.chatCode,
|
||||
// match.groupAlpha.chatCode,
|
||||
// match.groupBravo.chatCode,
|
||||
// ].filter((c): c is string => Boolean(c));
|
||||
|
||||
// if (codes.length === 0) return null;
|
||||
// if (codes.length === 1) return codes[0];
|
||||
// return codes;
|
||||
// })(),
|
||||
// };
|
||||
// };
|
||||
|
||||
export const loader = async ({ params }: LoaderFunctionArgs) => {
|
||||
const user = getUser();
|
||||
const matchId = parseParams({
|
||||
params,
|
||||
schema: qMatchPageParamsSchema,
|
||||
}).id;
|
||||
|
||||
const matchUnmapped = notFoundIfFalsy(
|
||||
await SQMatchRepository.findById(matchId),
|
||||
);
|
||||
|
|
@ -24,51 +84,14 @@ export const loader = async ({ params }: LoaderFunctionArgs) => {
|
|||
...matchUnmapped.groupAlpha.members,
|
||||
...matchUnmapped.groupBravo.members,
|
||||
].map((m) => m.id);
|
||||
|
||||
const privateNotes = user
|
||||
? await PrivateUserNoteRepository.byAuthorUserId(user.id, matchUsers)
|
||||
: undefined;
|
||||
|
||||
const match = SendouQ.mapMatch(matchUnmapped, user, privateNotes);
|
||||
|
||||
const rawReportedWeapons = match.reportedAt
|
||||
? await ReportedWeaponRepository.findByMatchId(matchId)
|
||||
: null;
|
||||
|
||||
return {
|
||||
match,
|
||||
reportedWeapons: match.reportedAt
|
||||
? reportedWeaponsToArrayOfArrays({
|
||||
groupAlpha: match.groupAlpha,
|
||||
groupBravo: match.groupBravo,
|
||||
mapList: match.mapList,
|
||||
reportedWeapons: rawReportedWeapons,
|
||||
})
|
||||
: null,
|
||||
rawReportedWeapons,
|
||||
chatCode: (() => {
|
||||
const isStaff = user?.roles.includes("STAFF") ?? false;
|
||||
const isParticipant = user && matchUsers.includes(user.id);
|
||||
|
||||
if (!(isStaff || isParticipant)) return null;
|
||||
|
||||
const accessible = chatAccessible({
|
||||
isStaff,
|
||||
expiresAfterDays: 1,
|
||||
comparedTo: databaseTimestampToDate(matchUnmapped.createdAt),
|
||||
});
|
||||
if (!accessible) return null;
|
||||
|
||||
if (!isParticipant) return match.chatCode ?? null;
|
||||
|
||||
const codes = [
|
||||
match.chatCode,
|
||||
match.groupAlpha.chatCode,
|
||||
match.groupBravo.chatCode,
|
||||
].filter((c): c is string => Boolean(c));
|
||||
|
||||
if (codes.length === 0) return null;
|
||||
if (codes.length === 1) return codes[0];
|
||||
return codes;
|
||||
})(),
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,123 +0,0 @@
|
|||
.stagePopoverButton {
|
||||
background-color: transparent;
|
||||
color: var(--color-text-high);
|
||||
font-size: var(--font-xs);
|
||||
padding: 0;
|
||||
border: none;
|
||||
text-decoration: underline;
|
||||
text-decoration-style: dotted;
|
||||
font-weight: var(--weight-body);
|
||||
height: 19.8281px;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
color: var(--color-text-accent);
|
||||
}
|
||||
}
|
||||
|
||||
.modePopoverButton {
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
border: none;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
/** Push footer down to avoid it "flashing" when the score reporter animates */
|
||||
padding-bottom: 14rem;
|
||||
}
|
||||
|
||||
.header {
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.teamsContainer {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
gap: var(--s-8);
|
||||
}
|
||||
|
||||
.mapListChatContainer {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 1fr 2fr;
|
||||
place-items: center;
|
||||
gap: var(--s-4);
|
||||
}
|
||||
|
||||
.userNameContainer {
|
||||
display: flex;
|
||||
gap: var(--s-2);
|
||||
width: 175px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.userWeaponContainer {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.reportSection {
|
||||
display: grid;
|
||||
grid-template-columns: max-content 1fr;
|
||||
row-gap: var(--s-2);
|
||||
column-gap: var(--s-3);
|
||||
align-items: center;
|
||||
font-size: var(--font-xs);
|
||||
}
|
||||
|
||||
.poolPassContainer {
|
||||
display: flex;
|
||||
gap: var(--s-2);
|
||||
flex-direction: column;
|
||||
max-width: max-content;
|
||||
}
|
||||
|
||||
.bottomMidSection {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-self: flex-start;
|
||||
top: var(--layout-sticky-top);
|
||||
position: sticky;
|
||||
}
|
||||
|
||||
.infoHeader {
|
||||
text-transform: uppercase;
|
||||
color: var(--color-text-high);
|
||||
font-size: var(--font-xs);
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.infoValue {
|
||||
font-size: var(--font-xl);
|
||||
font-weight: var(--weight-semi);
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.screenLegality {
|
||||
& svg {
|
||||
width: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.screenLegalityButton {
|
||||
width: 100%;
|
||||
|
||||
&:focus-visible {
|
||||
outline: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.preferenceEmoji {
|
||||
filter: grayscale(100%);
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
@container (width >= 640px) {
|
||||
.teamsContainer {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -155,6 +155,7 @@ class SendouQClass {
|
|||
return this.groups.find((group) => group.inviteCode === inviteCode);
|
||||
}
|
||||
|
||||
// xxx: only needed stuff here
|
||||
/**
|
||||
* Maps a database match to a format with appropriate censoring based on user permissions.
|
||||
* Includes private notes for team members and censors sensitive data for non-participants.
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user