mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-04-25 15:56:19 -05:00
* Tables * Clocks * Maplist preference selector * Fix SSR * Nav icon * RankedOrScrim * Map pool * Create group * Redirect logic * Persist map pool * Advance from preparing page * Rename query * Fix merge * Fix migration order * Seed groups * Find looking groups SQL * Renders something * More UI work * Back to 30min * Likes/dislikes * Always return own group * Fix like order * 3 tc/rm/cb -> 2 * Show only 3 weapons * Pass group size * Handle both liked and liked by same group * Fix SQL * Group preference frontend work * Morphing * Styling * Don't show group controls if not manager * Give/remove manager * Leave group * Leave with confirm * Delete likes when morphing groups * Clocks consistency * Remove bad invariant * Persist settings to local storage * Fix initial value flashing * Fix never resolving loading indicator * REFRESH_GROUP * Flip animations * Tweaks * Auto refresh logic * Groups of 4 seed * Reduce throwing * Load full groups initial * Create match * Match UI initial * Score reporter initial * Push footer down on match page * Score reporter knows when set ended * Score reporting untested * Show score after report * Align better * Look again with same group functionality * More migrations * Team on match page * Show confirmer before reporting score * Report weapons * Report weapos again by admin + skill changing * Handle no tiebreaker given to MapPool * Remove unranked * Remove support for "team id skill" * no-wrap -> nowrap * Preparing page work * Use common GroupCard component * Add some metas * MemberAdder in looking page * Fix GroupCard actions * Fix SZ only map list including other modes * Add season info * Prompt login * Joining team * Manage group on preparing page * Manage group on preparing page * Seed past matches * Add to seed * No map list preference when full group + fix expiry * Fix skill matchesCount calculation * Tiers initial work * Some progress on tiers * Tiering logic * MMR in group cards * Name to challenge * Team MMR * Big team rank icons * Adjust todos * Match score report with confirm * Allow regular members to report score * Handle reporting weapons edge cases * Add tier images * Improve GroupCard spacing * Refactor looking page * Looking mobile UI * Calculate skill only for current season * Divide groups visually when reporting weapons * Fix match page weapons sorting * Add cache to user skills+tier calculation * Admin report match score * Initial leaderboard * Cached leaderboard * Weapon category lb's * Populate SkillTeamUser in SendouQ * Team leaderboard filtered down * Add TODOs * Seasons initlal * Season weapons initial * Weapons stylized * Show rest weapons as + * Hide peak if same as current * Load matches SQL initial * Season matches UI initial * Take user id in account * Add weapons * Paginated matches * Fix pages count logic * Scroll top on data change * Day headers for matches * Link from user page to user seasons page * Summarize maps + ui initial * Map stats * Player info tabs * MMR chart * Chart adjustments * Handle basing team MMR on player MMR * Set initial MMR * Add info about discord to match page * Season support to tournaments * Get tournament skills as well for the graph * WIP * New team rating logic + misc other * tiered -> tiered.server * Update season starting time * TODOs * Add rules page * Hide elements correctly when off-season * Fix crash when only one player with skill * How-to video * Fix StartRank showing when not logged in * Make user leaderboard the default * Make Skill season non-nullable * Add suggested pass to match * Add rule * identifierToUserIds helper * Fix tiers not showing
112 lines
2.7 KiB
TypeScript
112 lines
2.7 KiB
TypeScript
import { nanoid } from "nanoid";
|
|
import { INVITE_CODE_LENGTH } from "~/constants";
|
|
import { sql } from "~/db/sql";
|
|
import type { Group, GroupMember } from "~/db/types";
|
|
import type { MapPool } from "~/modules/map-pool-serializer";
|
|
|
|
const createGroupStm = sql.prepare(/* sql */ `
|
|
insert into "Group"
|
|
("mapListPreference", "inviteCode", "status")
|
|
values
|
|
(@mapListPreference, @inviteCode, @status)
|
|
returning *
|
|
`);
|
|
|
|
const createGroupMemberStm = sql.prepare(/* sql */ `
|
|
insert into "GroupMember"
|
|
("groupId", "userId", "role")
|
|
values
|
|
(@groupId, @userId, @role)
|
|
`);
|
|
|
|
const createMapPoolMapStm = sql.prepare(/* sql */ `
|
|
insert into "MapPoolMap"
|
|
("stageId", "mode", "groupId")
|
|
values
|
|
(@stageId, @mode, @groupId)
|
|
`);
|
|
|
|
type CreateGroupArgs = Pick<Group, "mapListPreference"> & {
|
|
status: Exclude<Group["status"], "INACTIVE">;
|
|
userId: number;
|
|
mapPool: MapPool;
|
|
};
|
|
|
|
const DEFAULT_ROLE: GroupMember["role"] = "OWNER";
|
|
|
|
export const createGroup = sql.transaction((args: CreateGroupArgs) => {
|
|
const group = createGroupStm.get({
|
|
mapListPreference: args.mapListPreference,
|
|
inviteCode: nanoid(INVITE_CODE_LENGTH),
|
|
status: args.status,
|
|
}) as Group;
|
|
|
|
createGroupMemberStm.run({
|
|
groupId: group.id,
|
|
userId: args.userId,
|
|
role: DEFAULT_ROLE,
|
|
});
|
|
|
|
for (const { stageId, mode } of args.mapPool.stageModePairs) {
|
|
createMapPoolMapStm.run({
|
|
stageId,
|
|
mode,
|
|
groupId: group.id,
|
|
});
|
|
}
|
|
|
|
return group;
|
|
});
|
|
|
|
type CreateGroupFromPreviousGroupArgs = {
|
|
previousGroupId: number;
|
|
members: {
|
|
id: number;
|
|
role: GroupMember["role"];
|
|
}[];
|
|
};
|
|
|
|
const createGroupFromPreviousGroupStm = sql.prepare(/* sql */ `
|
|
insert into "Group"
|
|
("mapListPreference", "teamId", "inviteCode", "status")
|
|
values
|
|
(
|
|
(select "mapListPreference" from "Group" where "id" = @previousGroupId),
|
|
(select "teamId" from "Group" where "id" = @previousGroupId),
|
|
@inviteCode,
|
|
@status
|
|
)
|
|
returning *
|
|
`);
|
|
|
|
const stealMapPoolStm = sql.prepare(/* sql */ `
|
|
update "MapPoolMap"
|
|
set "groupId" = @groupId
|
|
where "groupId" = @previousGroupId
|
|
`);
|
|
|
|
export const createGroupFromPreviousGroup = sql.transaction(
|
|
(args: CreateGroupFromPreviousGroupArgs) => {
|
|
const group = createGroupFromPreviousGroupStm.get({
|
|
previousGroupId: args.previousGroupId,
|
|
inviteCode: nanoid(INVITE_CODE_LENGTH),
|
|
status: "PREPARING",
|
|
}) as Group;
|
|
|
|
for (const member of args.members) {
|
|
createGroupMemberStm.run({
|
|
groupId: group.id,
|
|
userId: member.id,
|
|
role: member.role,
|
|
});
|
|
}
|
|
|
|
stealMapPoolStm.run({
|
|
previousGroupId: args.previousGroupId,
|
|
groupId: group.id,
|
|
});
|
|
|
|
return group;
|
|
}
|
|
);
|