mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-06-23 21:22:04 -05:00
126 lines
3.0 KiB
TypeScript
126 lines
3.0 KiB
TypeScript
import { db } from "~/db/sql";
|
|
import type { Tables, UserMapModePreferences } from "~/db/tables";
|
|
import { actorId } from "~/features/auth/core/user.server";
|
|
import type { WeaponPoolItem } from "~/form/fields/WeaponPoolFormField";
|
|
import type { UnifiedLanguageCode } from "~/modules/i18n/config";
|
|
import { modesShort } from "~/modules/in-game-lists/modes";
|
|
import { matchProfileWeapons } from "~/utils/kysely.server";
|
|
|
|
export async function settingsByUserId(userId: number) {
|
|
const preferences = await db
|
|
.selectFrom("User")
|
|
.select(({ eb }) => [
|
|
"User.mapModePreferences",
|
|
"User.vc",
|
|
"User.languages",
|
|
"User.noScreen",
|
|
matchProfileWeapons(eb).as("weaponPool"),
|
|
])
|
|
.where("id", "=", userId)
|
|
.executeTakeFirstOrThrow();
|
|
|
|
return {
|
|
...preferences,
|
|
languages: preferences.languages?.split(",") as
|
|
| UnifiedLanguageCode[]
|
|
| undefined,
|
|
};
|
|
}
|
|
|
|
export function updateVoiceChat(args: {
|
|
userId: number;
|
|
vc: Tables["User"]["vc"];
|
|
languages: string[];
|
|
}) {
|
|
return db
|
|
.updateTable("User")
|
|
.set({
|
|
vc: args.vc,
|
|
languages: args.languages.length > 0 ? args.languages.join(",") : null,
|
|
})
|
|
.where("User.id", "=", args.userId)
|
|
.execute();
|
|
}
|
|
|
|
export async function updateOwnMatchProfile({
|
|
mapModePreferences,
|
|
vc,
|
|
languages,
|
|
weaponPool,
|
|
noScreen,
|
|
}: {
|
|
mapModePreferences: UserMapModePreferences;
|
|
vc: Tables["User"]["vc"];
|
|
languages: string[];
|
|
weaponPool: WeaponPoolItem[];
|
|
noScreen: number;
|
|
}) {
|
|
const userId = actorId();
|
|
const currentPreferences = (
|
|
await db
|
|
.selectFrom("User")
|
|
.select("mapModePreferences")
|
|
.where("id", "=", userId)
|
|
.executeTakeFirstOrThrow()
|
|
).mapModePreferences;
|
|
|
|
const mergedPool = mergeExcludedModePreferences(
|
|
mapModePreferences.pool,
|
|
currentPreferences?.pool,
|
|
);
|
|
|
|
return db.transaction().execute(async (trx) => {
|
|
await trx
|
|
.deleteFrom("UserWeaponPool")
|
|
.where("userId", "=", userId)
|
|
.execute();
|
|
|
|
if (weaponPool.length > 0) {
|
|
await trx
|
|
.insertInto("UserWeaponPool")
|
|
.values(
|
|
weaponPool.map((wpn, i) => ({
|
|
userId,
|
|
sortOrder: i,
|
|
weaponSplId: wpn.id,
|
|
isFavorite: Number(wpn.isFavorite),
|
|
})),
|
|
)
|
|
.execute();
|
|
}
|
|
|
|
await trx
|
|
.updateTable("User")
|
|
.set({
|
|
mapModePreferences: JSON.stringify({
|
|
...mapModePreferences,
|
|
pool: mergedPool,
|
|
}),
|
|
vc,
|
|
languages: languages.length > 0 ? languages.join(",") : null,
|
|
noScreen,
|
|
})
|
|
.where("id", "=", userId)
|
|
.execute();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Preserves existing preferences for modes not included in the new submission.
|
|
* So if they later want to play this mode again, the system remembers their maps.
|
|
*/
|
|
function mergeExcludedModePreferences(
|
|
newPool: UserMapModePreferences["pool"],
|
|
currentPool: UserMapModePreferences["pool"] | undefined,
|
|
) {
|
|
const modesExcluded = modesShort.filter(
|
|
(mode) => !newPool.some((mp) => mp.mode === mode),
|
|
);
|
|
|
|
const preservedPreferences = modesExcluded.flatMap(
|
|
(mode) => currentPool?.filter((mp) => mp.mode === mode) ?? [],
|
|
);
|
|
|
|
return [...newPool, ...preservedPreferences];
|
|
}
|