Add filter to item list

pull/1/head
I Made Setia Baruna 2021-01-08 18:01:49 +08:00
parent fd09da952d
commit 3fcd9f8c88
3 changed files with 126 additions and 39 deletions

View File

@ -2,7 +2,7 @@
import { createEventDispatcher } from 'svelte'; import { createEventDispatcher } from 'svelte';
import VirtualList from './VirtualList.svelte'; import VirtualList from './VirtualList.svelte';
import { fade } from 'svelte/transition'; import { fade } from 'svelte/transition';
import { mdiChevronDown } from '@mdi/js'; import { mdiChevronDown, mdiCloseCircle } from '@mdi/js';
import Icon from './Icon.svelte'; import Icon from './Icon.svelte';
import { characters as characterList } from '../data/characters'; import { characters as characterList } from '../data/characters';
@ -29,6 +29,7 @@
} }
function select(val) { function select(val) {
console.log('select', val);
selected = val; selected = val;
focused = false; focused = false;
hoveredIndex = -1; hoveredIndex = -1;
@ -132,7 +133,19 @@
{placeholder} {placeholder}
value={nothingSelected || focused ? search : label} value={nothingSelected || focused ? search : label}
on:input={onInput} /> on:input={onInput} />
<Icon path={mdiChevronDown} color="white" className={`absolute right-0 mr-4 duration-100 ease-in ${iconClasses}`} /> {#if selected}
<div class="absolute right-0 mr-4 cursor-pointer" on:click|stopPropagation={() => select(null)}>
<Icon
path={mdiCloseCircle}
color="white"
className={`${iconClasses}`} />
</div>
{:else}
<Icon
path={mdiChevronDown}
color="white"
className={`absolute right-0 mr-4 duration-100 ease-in ${iconClasses}`} />
{/if}
</div> </div>
{#if focused} {#if focused}
<div <div

View File

@ -2,7 +2,7 @@
import { createEventDispatcher } from 'svelte'; import { createEventDispatcher } from 'svelte';
import VirtualList from './VirtualList.svelte'; import VirtualList from './VirtualList.svelte';
import { fade } from 'svelte/transition'; import { fade } from 'svelte/transition';
import { mdiChevronDown } from '@mdi/js'; import { mdiChevronDown, mdiCloseCircle } from '@mdi/js';
import Icon from './Icon.svelte'; import Icon from './Icon.svelte';
import { weaponList } from '../data/weaponList'; import { weaponList } from '../data/weaponList';
@ -134,7 +134,16 @@
{placeholder} {placeholder}
value={nothingSelected || focused ? search : label} value={nothingSelected || focused ? search : label}
on:input={onInput} /> on:input={onInput} />
<Icon path={mdiChevronDown} color="white" className={`absolute right-0 mr-4 duration-100 ease-in ${iconClasses}`} /> {#if selected}
<div class="absolute right-0 mr-4 cursor-pointer" on:click|stopPropagation={() => select(null)}>
<Icon path={mdiCloseCircle} color="white" className={`${iconClasses}`} />
</div>
{:else}
<Icon
path={mdiChevronDown}
color="white"
className={`absolute right-0 mr-4 duration-100 ease-in ${iconClasses}`} />
{/if}
</div> </div>
{#if focused} {#if focused}
<div <div

View File

@ -4,6 +4,9 @@
import { itemList } from '../data/itemList'; import { itemList } from '../data/itemList';
import { weaponList } from '../data/weaponList'; import { weaponList } from '../data/weaponList';
import CharacterSelect from '../components/CharacterSelect.svelte';
import WeaponSelect from '../components/WeaponSelect.svelte';
let dayName = { let dayName = {
monday_thursday: ['Monday', 'Thursday'], monday_thursday: ['Monday', 'Thursday'],
tuesday_friday: ['Tuesday', 'Friday'], tuesday_friday: ['Tuesday', 'Friday'],
@ -24,40 +27,80 @@
let allItems = {}; let allItems = {};
function parseData() { let selectedCharacter = null;
for (const [_, character] of Object.entries(characters)) { let selectedWeapon = null;
const item = character.material.book[0];
if (charactersDays[item.day.join('_')][item.id] === undefined) {
charactersDays[item.day.join('_')][item.id] = [];
}
charactersDays[item.day.join('_')][item.id].push(character.id);
const ascension = character.ascension[0]; function parseData() {
for (const item of ascension.items) { dayName = {
if (item.amount) { monday_thursday: ['Monday', 'Thursday'],
if (allItems[item.item.id] === undefined) { tuesday_friday: ['Tuesday', 'Friday'],
allItems[item.item.id] = {}; wednesday_saturday: ['Wednesday', 'Saturday'],
};
charactersDays = {
monday_thursday: {},
tuesday_friday: {},
wednesday_saturday: {},
};
weaponsDays = {
monday_thursday: {},
tuesday_friday: {},
wednesday_saturday: {},
};
allItems = {};
console.log('parsing', selectedCharacter);
if (
(selectedCharacter === null && selectedWeapon === null) ||
(selectedCharacter !== null && selectedWeapon === null) ||
(selectedCharacter !== null && selectedWeapon !== null)
) {
for (const [_, character] of Object.entries(characters)) {
if (selectedCharacter !== null && selectedCharacter.id !== character.id) continue;
const item = character.material.book[0];
if (charactersDays[item.day.join('_')][item.id] === undefined) {
charactersDays[item.day.join('_')][item.id] = [];
}
charactersDays[item.day.join('_')][item.id].push(character.id);
const ascension = character.ascension[0];
for (const item of ascension.items) {
if (item.amount) {
if (allItems[item.item.id] === undefined) {
allItems[item.item.id] = {};
}
allItems[item.item.id][character.id] = 'characters';
} }
allItems[item.item.id][character.id] = 'characters';
} }
} }
} }
for (const [_, weapon] of Object.entries(weaponList)) { if (
if (weapon.rarity < 4) continue; (selectedCharacter === null && selectedWeapon === null) ||
const items = weapon.ascension[0].items; (selectedCharacter === null && selectedWeapon !== null) ||
for (const itemData of items) { (selectedCharacter !== null && selectedWeapon !== null)
const item = itemData.item; ) {
if (item.day) { for (const [_, weapon] of Object.entries(weaponList)) {
if (weaponsDays[item.day.join('_')][item.id] === undefined) { if (selectedWeapon !== null && selectedWeapon.id !== weapon.id) continue;
weaponsDays[item.day.join('_')][item.id] = [];
const items = weapon.ascension[0].items;
for (const itemData of items) {
const item = itemData.item;
if (item.day) {
if (weaponsDays[item.day.join('_')][item.id] === undefined) {
weaponsDays[item.day.join('_')][item.id] = [];
}
weaponsDays[item.day.join('_')][item.id].push(weapon.id);
} else if (itemData.amount) {
if (allItems[item.id] === undefined) {
allItems[item.id] = {};
}
allItems[item.id][weapon.id] = 'weapons';
} }
weaponsDays[item.day.join('_')][item.id].push(weapon.id);
} else if (itemData.amount) {
if (allItems[item.id] === undefined) {
allItems[item.id] = {};
}
allItems[item.id][weapon.id] = 'weapons';
} }
} }
} }
@ -66,6 +109,9 @@
} }
parseData(); parseData();
$: selectedCharacter, parseData();
$: selectedWeapon, parseData();
</script> </script>
<style> <style>
@ -88,6 +134,12 @@
@apply overflow-y-hidden; @apply overflow-y-hidden;
} }
} }
tr:last-child {
td {
@apply border-b-0;
}
}
</style> </style>
<svelte:head> <svelte:head>
@ -98,6 +150,10 @@
<p class="text-gray-400 px-4 md:px-8 font-medium pb-4" style="margin-top: -1rem;"> <p class="text-gray-400 px-4 md:px-8 font-medium pb-4" style="margin-top: -1rem;">
※ Click the item image to add it to the todo list ※ Click the item image to add it to the todo list
</p> </p>
<div class="pb-4 px-4 md:px-8 grid grid-cols-1 md:grid-cols-2 gap-2 max-w-screen-md">
<CharacterSelect bind:selected={selectedCharacter} placeholder="Search character" />
<WeaponSelect bind:selected={selectedWeapon} placeholder="Search weapon" />
</div>
<div class="block overflow-x-auto whitespace-no-wrap pb-8"> <div class="block overflow-x-auto whitespace-no-wrap pb-8">
<div class="px-4 md:px-8 table max-w-full"> <div class="px-4 md:px-8 table max-w-full">
<table class="w-full block p-4 bg-item rounded-xl"> <table class="w-full block p-4 bg-item rounded-xl">
@ -109,14 +165,15 @@
Materials Materials
</th> </th>
<th class="text-gray-400 select-none font-display text-lg text-left px-4 pb-2 border-gray-700 border-b"> <th class="text-gray-400 select-none font-display text-lg text-left px-4 pb-2 border-gray-700 border-b">
Characters Characters & Weapons
</th> </th>
</thead> </thead>
<tbody> <tbody>
{#each Object.entries(dayName) as [day, dayArr]} {#each Object.entries(dayName) as [day, dayArr]}
{#each Object.entries(charactersDays[day]) as [itemName, chars], index} {#each Object.entries(charactersDays[day]) as [itemName, chars], index}
<tr> <tr>
<td class="py-2"> <td
class={index === Object.entries(charactersDays[day]).length - 1 && Object.entries(weaponsDays[day]).length === 0 ? 'border-gray-700 border-b py-2' : 'py-2'}>
{#if index === 0}{dayArr[0]}<br />{dayArr[1]}{/if} {#if index === 0}{dayArr[0]}<br />{dayArr[1]}{/if}
</td> </td>
<td class="border-gray-700 border-b text-center align-middle py-2"> <td class="border-gray-700 border-b text-center align-middle py-2">
@ -137,7 +194,11 @@
<div <div
class="h-12 w-12 md:h-14 md:w-14 cursor-pointer mr-2 hover:bg-background rounded-xl class="h-12 w-12 md:h-14 md:w-14 cursor-pointer mr-2 hover:bg-background rounded-xl
inline-flex items-center justify-center align-top"> inline-flex items-center justify-center align-top">
<img class="w-full max-h-full object-contain" src={`/images/characters/${char}.png`} alt={char} /> <img
class="w-full max-h-full object-contain"
src={`/images/characters/${char}.png`}
alt={char}
title={characters[char].name} />
</div> </div>
{/each} {/each}
</td> </td>
@ -146,7 +207,9 @@
{#each Object.entries(weaponsDays[day]) as [itemName, weapons], index} {#each Object.entries(weaponsDays[day]) as [itemName, weapons], index}
<tr> <tr>
<td <td
class={index === Object.entries(charactersDays[day]).length - 1 ? 'border-gray-700 border-b py-2' : 'py-2'} /> class={index === Object.entries(weaponsDays[day]).length - 1 || Object.entries(charactersDays[day]).length === 0 ? 'border-gray-700 border-b py-2' : 'py-2'}>
{#if index === 0 && Object.entries(charactersDays[day]).length === 0}{dayArr[0]}<br />{dayArr[1]}{/if}
</td>
<td class="border-gray-700 border-b text-center py-2"> <td class="border-gray-700 border-b text-center py-2">
<div class="flex items-center"> <div class="flex items-center">
<div <div
@ -157,7 +220,7 @@
src={`/images/items/${itemName}.png`} src={`/images/items/${itemName}.png`}
alt={itemName} /> alt={itemName} />
</div> </div>
<span class="whitespace-normal text-left w-0">{itemGroup[itemName].name}</span> <span class="whitespace-normal text-left w-20">{itemGroup[itemName].name}</span>
</div> </div>
</td> </td>
<td class="border-gray-700 border-b weapon-cell pt-2"> <td class="border-gray-700 border-b weapon-cell pt-2">
@ -168,7 +231,8 @@
<img <img
class="w-full max-h-full object-contain" class="w-full max-h-full object-contain"
src={`/images/weapons/${weapon}.png`} src={`/images/weapons/${weapon}.png`}
alt={weapon} /> alt={weapon}
title={weaponList[weapon].name} />
</div> </div>
{/each} {/each}
</td> </td>
@ -187,7 +251,7 @@
Material Material
</th> </th>
<th class="text-gray-400 select-none font-display text-lg text-left px-4 pb-2 border-gray-700 border-b"> <th class="text-gray-400 select-none font-display text-lg text-left px-4 pb-2 border-gray-700 border-b">
Characters Characters & Weapons
</th> </th>
</thead> </thead>
<tbody> <tbody>
@ -213,7 +277,8 @@
<img <img
class="w-full max-h-full object-contain" class="w-full max-h-full object-contain"
src={`/images/${type}/${charName}.png`} src={`/images/${type}/${charName}.png`}
alt={charName} /> alt={charName}
title={type === 'characters' ? characters[charName].name : weaponList[charName].name} />
</div> </div>
{/each} {/each}
</td> </td>