diff --git a/src/routes/(game)/infinite/+page.server.ts b/src/routes/(game)/infinite/+page.server.ts index 5a5f3f2..5a4a450 100644 --- a/src/routes/(game)/infinite/+page.server.ts +++ b/src/routes/(game)/infinite/+page.server.ts @@ -6,15 +6,6 @@ import { like } from 'drizzle-orm'; export async function load() { let characters = await getAllCharacters(); - // Filter out characters that have no height data - characters = characters.filter(char => char.height !== null); - - // Filter out characters that have no status data - characters = characters.filter(char => char.status !== null); - - // Filter out characters that have no origin data - characters = characters.filter(char => char.origin !== null); - // Load column visibility config const columnConfig = await db .select() diff --git a/src/routes/(game)/infinite/+page.svelte b/src/routes/(game)/infinite/+page.svelte index 560444e..c844466 100644 --- a/src/routes/(game)/infinite/+page.svelte +++ b/src/routes/(game)/infinite/+page.svelte @@ -24,6 +24,16 @@ arc: 'Arc' }; + // Character filters + let characterFilters = { + gender: [] as string[], + hasHaki: false, + hasDevilFruit: null as boolean | null, // null = all, true = with fruit, false = without fruit + status: [] as string[], + hasHeight: false, + hasOrigin: false + }; + let wasOriginAvailable = false; let wasFruitAvailable = false; let wasAffiliationAvailable = false; @@ -51,6 +61,16 @@ columnVisibility = data.columnVisibility || {}; } + // Load character filters from localStorage + const storedFilters = localStorage.getItem('infiniteCharacterFilters'); + if (storedFilters) { + try { + characterFilters = JSON.parse(storedFilters); + } catch (e) { + console.error('Failed to parse filters', e); + } + } + // Load current character ID and history IDs from localStorage const storedCharacterId = localStorage.getItem('infiniteCurrentCharacterId'); const storedHistoryIds = localStorage.getItem('infiniteSelectedCharacterIds'); @@ -93,6 +113,11 @@ localStorage.setItem('infiniteColumnVisibility', JSON.stringify(columnVisibility)); } + // Save character filters to localStorage whenever they change + $: if (isLoaded) { + localStorage.setItem('infiniteCharacterFilters', JSON.stringify(characterFilters)); + } + // Save current character ID to localStorage whenever it changes $: if (isLoaded && currentCharacter) { localStorage.setItem('infiniteCurrentCharacterId', JSON.stringify(currentCharacter.id)); @@ -104,7 +129,45 @@ localStorage.setItem('infiniteSelectedCharacterIds', JSON.stringify(selectedIds)); } - $: characters = data.characters || []; + $: allCharacters = data.characters || []; + + // Filter characters based on selected filters + $: characters = allCharacters.filter((char: any) => { + // Gender filter + if (characterFilters.gender.length > 0 && !characterFilters.gender.includes(char.gender)) { + return false; + } + + // Haki filter + if (characterFilters.hasHaki && !(char.hakiObservation || char.hakiArmament || char.hakiConqueror)) { + return false; + } + + // Devil fruit filter + if (characterFilters.hasDevilFruit !== null) { + const hasDevil = char.devilFruitId !== null && char.devilFruitId !== undefined; + if (characterFilters.hasDevilFruit !== hasDevil) { + return false; + } + } + + // Status filter + if (characterFilters.status.length > 0 && !characterFilters.status.includes(char.status)) { + return false; + } + + // Height filter + if (characterFilters.hasHeight && (char.height === null || char.height === undefined)) { + return false; + } + + // Origin filter + if (characterFilters.hasOrigin && (char.origin === null || char.origin === undefined || char.origin === '')) { + return false; + } + + return true; + }); $: hasWon = currentCharacter && selectedCharacters.some(char => char.id === currentCharacter.id); $: if (hasWon && currentCharacter?.id === 'gecko_moria_gecko_moria') { isGeckoMoriaWin = true; @@ -184,6 +247,83 @@ // Add the current character as the correct answer selectedCharacters = [currentCharacter, ...selectedCharacters]; } + + function toggleGenderFilter(gender: string) { + if (characterFilters.gender.includes(gender)) { + characterFilters.gender = characterFilters.gender.filter(g => g !== gender); + } else { + characterFilters.gender = [...characterFilters.gender, gender]; + } + // Regenerate character with new filters + if (!hasWon) { + generateNewCharacter(); + } + } + + function toggleStatusFilter(status: string) { + if (characterFilters.status.includes(status)) { + characterFilters.status = characterFilters.status.filter(s => s !== status); + } else { + characterFilters.status = [...characterFilters.status, status]; + } + // Regenerate character with new filters + if (!hasWon) { + generateNewCharacter(); + } + } + + function toggleHakiFilter() { + characterFilters.hasHaki = !characterFilters.hasHaki; + // Regenerate character with new filters + if (!hasWon) { + generateNewCharacter(); + } + } + + function toggleDevilFruitFilter() { + if (characterFilters.hasDevilFruit === null) { + characterFilters.hasDevilFruit = true; + } else if (characterFilters.hasDevilFruit === true) { + characterFilters.hasDevilFruit = false; + } else { + characterFilters.hasDevilFruit = null; + } + // Regenerate character with new filters + if (!hasWon) { + generateNewCharacter(); + } + } + + function toggleHeightFilter() { + characterFilters.hasHeight = !characterFilters.hasHeight; + // Regenerate character with new filters + if (!hasWon) { + generateNewCharacter(); + } + } + + function toggleOriginFilter() { + characterFilters.hasOrigin = !characterFilters.hasOrigin; + // Regenerate character with new filters + if (!hasWon) { + generateNewCharacter(); + } + } + + function clearAllFilters() { + characterFilters = { + gender: [], + hasHaki: false, + hasDevilFruit: null, + status: [], + hasHeight: false, + hasOrigin: false + }; + // Regenerate character with new filters + if (!hasWon) { + generateNewCharacter(); + } + } @@ -313,21 +453,21 @@ {showFruitUnlock} {showAffiliationUnlock} /> +
+ +
{/if} -
- -
{/if} {:else}
@@ -343,6 +483,118 @@ {columnVisibility} /> + +
+
+
+

Filtres de personnages

+ {#if characterFilters.gender.length > 0 || characterFilters.hasHaki || characterFilters.hasDevilFruit !== null || characterFilters.status.length > 0 || characterFilters.hasHeight || characterFilters.hasOrigin} + + {/if} +
+ +
+ +
+

Genre

+
+ {#each ['Male', 'Female'] as gender} + + {/each} +
+
+ + +
+

Statut

+
+ {#each ['Alive', 'Dead', 'Unknown'] as status} + + {/each} +
+
+ + +
+

Capacités

+
+ + +
+
+ + +
+

Informations

+
+ + +
+
+ +

+ {characters.length} personnage{characters.length > 1 ? 's' : ''} disponible{characters.length > 1 ? 's' : ''} +

+
+
+
+