132 lines
3.9 KiB
TypeScript
132 lines
3.9 KiB
TypeScript
import { error } from '@sveltejs/kit';
|
|
import { db } from '$lib/server/db';
|
|
import { character, characterHistory, config, friendship, user, userCharacterHistory } from '$lib/server/db/schema';
|
|
import { getDailyModeCharacters, getOrCreateTodayCharacter, getYesterdayCharacter, getTodayCharacterWinsCount, getDateKey } from '$lib/server/daily-character';
|
|
import { and, eq, inArray, like, or } from 'drizzle-orm';
|
|
|
|
export async function load(event) {
|
|
const characters = await getDailyModeCharacters();
|
|
const dailyCharacter = await getOrCreateTodayCharacter(characters);
|
|
|
|
if (!dailyCharacter) {
|
|
throw error(404, 'No daily character available. Please check if characters are configured in daily mode.');
|
|
}
|
|
|
|
const yesterdayCharacter = await getYesterdayCharacter(new Date(), characters);
|
|
|
|
// Load the win count for today
|
|
const winCount = await getTodayCharacterWinsCount(dailyCharacter.id);
|
|
|
|
let friendsTodayResults: Array<{
|
|
userId: string;
|
|
name: string;
|
|
image: string | null;
|
|
tryCount: number;
|
|
triedCharacters: Array<{ id: string; name: string; pictureUrl: string | null }>;
|
|
}> = [];
|
|
|
|
if (event.locals.user) {
|
|
const currentUserId = event.locals.user.id;
|
|
|
|
const acceptedFriendships = await db
|
|
.select({
|
|
requesterId: friendship.requesterId,
|
|
addresseeId: friendship.addresseeId
|
|
})
|
|
.from(friendship)
|
|
.where(
|
|
and(
|
|
eq(friendship.status, 'accepted'),
|
|
or(eq(friendship.requesterId, currentUserId), eq(friendship.addresseeId, currentUserId))
|
|
)
|
|
);
|
|
|
|
const friendIds = acceptedFriendships.map((relation) =>
|
|
relation.requesterId === currentUserId ? relation.addresseeId : relation.requesterId
|
|
);
|
|
|
|
if (friendIds.length > 0) {
|
|
const todayDate = getDateKey(new Date());
|
|
|
|
const [todayHistoryEntry] = await db
|
|
.select({ id: characterHistory.id })
|
|
.from(characterHistory)
|
|
.where(eq(characterHistory.date, todayDate))
|
|
.limit(1);
|
|
|
|
const todayCharacterHistoryId = todayHistoryEntry?.id;
|
|
|
|
if (todayCharacterHistoryId) {
|
|
const friendResultsRaw = await db
|
|
.select({
|
|
userId: user.id,
|
|
name: user.name,
|
|
image: user.image,
|
|
tryCount: userCharacterHistory.tryCount,
|
|
triedCharacterIds: userCharacterHistory.triedCharacterIds
|
|
})
|
|
.from(userCharacterHistory)
|
|
.innerJoin(user, eq(userCharacterHistory.userId, user.id))
|
|
.where(
|
|
and(
|
|
eq(userCharacterHistory.characterHistoryId, todayCharacterHistoryId),
|
|
inArray(userCharacterHistory.userId, friendIds)
|
|
)
|
|
)
|
|
.orderBy(userCharacterHistory.tryCount);
|
|
|
|
const uniqueTriedCharacterIds = Array.from(new Set(
|
|
friendResultsRaw.flatMap((entry) => entry.triedCharacterIds ?? [])
|
|
));
|
|
|
|
const triedCharacters = uniqueTriedCharacterIds.length > 0
|
|
? await db
|
|
.select({
|
|
id: character.id,
|
|
name: character.name,
|
|
pictureUrl: character.pictureUrl
|
|
})
|
|
.from(character)
|
|
.where(inArray(character.id, uniqueTriedCharacterIds))
|
|
: [];
|
|
|
|
const triedCharactersById = new Map(triedCharacters.map((entry) => [entry.id, entry]));
|
|
|
|
friendsTodayResults = friendResultsRaw.map((entry) => ({
|
|
userId: entry.userId,
|
|
name: entry.name,
|
|
image: entry.image,
|
|
tryCount: entry.tryCount,
|
|
triedCharacters: (entry.triedCharacterIds ?? [])
|
|
.map((characterId) => triedCharactersById.get(characterId))
|
|
.filter((triedEntry): triedEntry is (typeof triedCharacters)[number] => !!triedEntry)
|
|
}));
|
|
}
|
|
}
|
|
}
|
|
|
|
// Load column visibility config
|
|
const columnConfig = await db
|
|
.select()
|
|
.from(config)
|
|
.where(like(config.key, 'characterHistory.column.%.visible'));
|
|
|
|
// Convert to object for easier access
|
|
const columnVisibility: Record<string, boolean> = {};
|
|
columnConfig.forEach(row => {
|
|
const match = row.key.match(/characterHistory\.column\.(.+)\.visible/);
|
|
if (match) {
|
|
columnVisibility[match[1]] = row.value === 'true';
|
|
}
|
|
});
|
|
|
|
return {
|
|
characters,
|
|
dailyCharacter,
|
|
yesterdayCharacter,
|
|
columnVisibility,
|
|
winCount,
|
|
friendsTodayResults
|
|
};
|
|
}
|