mirror of
https://github.com/MadeBaruna/paimon-moe.git
synced 2025-01-06 02:35:25 +01:00
Add achievement version and commission filter
This commit is contained in:
parent
351fd67b9e
commit
a3259bbefa
14 changed files with 142 additions and 63 deletions
|
@ -5,7 +5,7 @@
|
|||
import Icon from './Icon.svelte';
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
|
||||
export let className = '';
|
||||
export let icon = null;
|
||||
export let options;
|
||||
|
@ -38,6 +38,7 @@
|
|||
}
|
||||
|
||||
selected = [...selectedMulti].map((e) => options[e]);
|
||||
dispatch('change');
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -101,19 +102,13 @@
|
|||
$: iconClasses = focused ? 'transform rotate-180' : '';
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.hovered {
|
||||
@apply text-white !important;
|
||||
@apply bg-primary;
|
||||
}
|
||||
</style>
|
||||
|
||||
<svelte:window on:click={onWindowClick} on:keydown={onKeyDown} />
|
||||
|
||||
<div class={`select-none relative ${className}`} bind:this={container}>
|
||||
<button
|
||||
class={`flex w-full relative items-center px-4 bg-background rounded-2xl h-14 focus:outline-none focus:border-primary border-2 border-transparent ease-in duration-100 ${classes}`}
|
||||
on:click={toggleOptions}>
|
||||
on:click={toggleOptions}
|
||||
>
|
||||
{#if icon}
|
||||
<Icon path={icon} color="white" className="mr-3" />
|
||||
{/if}
|
||||
|
@ -123,14 +118,16 @@
|
|||
{#if focused}
|
||||
<div
|
||||
transition:fade={{ duration: 100 }}
|
||||
class="bg-item rounded-2xl absolute mt-2 p-2 w-full z-50 flex flex-col text-white shadow-xl border border-background">
|
||||
class="bg-item rounded-2xl absolute mt-2 p-2 w-full z-50 flex flex-col text-white shadow-xl border border-background"
|
||||
>
|
||||
{#each options as option, index}
|
||||
<span
|
||||
on:click={() => !option.disabled && select(index)}
|
||||
on:mouseenter={() => !option.disabled && onHover(index)}
|
||||
class={`p-3 rounded-xl cursor-pointer flex
|
||||
${selectedIndex === index || selectedMulti.has(index) ? 'text-primary font-semibold' : ''}
|
||||
${hoveredIndex === index ? 'hovered' : ''}`}>
|
||||
${hoveredIndex === index ? 'hovered' : ''}`}
|
||||
>
|
||||
{#if image}<img class="w-6 h-6 mr-2" src={option.image} alt={option.label} />{/if}
|
||||
<span class="flex-1">{option.label}</span>
|
||||
{#if multiselect && selectedMulti.has(index)}
|
||||
|
@ -141,3 +138,10 @@
|
|||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.hovered {
|
||||
@apply text-white !important;
|
||||
@apply bg-primary;
|
||||
}
|
||||
</style>
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -665,7 +665,11 @@
|
|||
"title": "Achievement",
|
||||
"of": "of",
|
||||
"sort": "Show not achieved first",
|
||||
"search": "Search achievement"
|
||||
"search": "Search achievement",
|
||||
"commissions": "commissions",
|
||||
"version": "Version",
|
||||
"type": "Type",
|
||||
"searchError": "Cannot found achievement: {query}"
|
||||
},
|
||||
"furnishing": {
|
||||
"title": "Furnishing",
|
||||
|
|
|
@ -665,7 +665,8 @@
|
|||
"title": "Achievement",
|
||||
"of": "dari",
|
||||
"sort": "Urutkan yang belum didapatkan dulu",
|
||||
"search": "Cari achievement"
|
||||
"search": "Cari achievement",
|
||||
"commissions": "misi harian"
|
||||
},
|
||||
"furnishing": {
|
||||
"title": "Furnitur",
|
||||
|
|
|
@ -9,15 +9,16 @@
|
|||
import { locale, t } from 'svelte-i18n';
|
||||
import { onMount, tick } from 'svelte';
|
||||
import debounce from 'lodash/debounce';
|
||||
import { mdiFilter } from '@mdi/js';
|
||||
|
||||
import Check from '../../components/Check.svelte';
|
||||
import Checkbox from '../../components/Checkbox.svelte';
|
||||
import { getAccountPrefix } from '../../stores/account';
|
||||
import { readSave, updateSave } from '../../stores/saveManager';
|
||||
import Button from '../../components/Button.svelte';
|
||||
import Input from '../../components/Input.svelte';
|
||||
import Icon from '../../components/Icon.svelte';
|
||||
import { mdiFilter } from '@mdi/js';
|
||||
import Select from '../../components/Select.svelte';
|
||||
import { pushToast } from '../../stores/toast';
|
||||
|
||||
export let data;
|
||||
|
||||
|
@ -41,6 +42,12 @@
|
|||
let nameFilter = '';
|
||||
let sortedAchievements = Object.entries(data).sort((a, b) => a[1].order - b[1].order);
|
||||
|
||||
const versions = ['1.0', '1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '2.0', '2.1'].map((e) => ({ label: e, value: e }));
|
||||
let versionFilter = [];
|
||||
|
||||
const types = [{ label: $t('achievement.commissions'), value: 'commissions' }];
|
||||
let typeFilter = [];
|
||||
|
||||
function parseCategories() {
|
||||
categories = Object.entries(achievement)
|
||||
.map(([id, data]) => ({
|
||||
|
@ -116,53 +123,78 @@
|
|||
return;
|
||||
}
|
||||
|
||||
const filterName = nameFilter !== '';
|
||||
const query = nameFilter.toLowerCase();
|
||||
|
||||
let index = 0;
|
||||
let found = null;
|
||||
for (const [id, item] of sortedAchievements) {
|
||||
for (const achievement of item.achievements) {
|
||||
if (Array.isArray(achievement)) {
|
||||
for (const e of achievement) {
|
||||
if (e.name.toLowerCase().includes(query)) {
|
||||
found = achievement;
|
||||
changeCategory(id, index, true, found);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (achievement.name.toLowerCase().includes(query)) {
|
||||
found = achievement;
|
||||
changeCategory(id, index, true, found);
|
||||
if (filterName && !achievement[0].name.toLowerCase().includes(query)) continue;
|
||||
changeCategory(id, index, false);
|
||||
return;
|
||||
} else {
|
||||
if (filterName && !achievement.name.toLowerCase().includes(query)) continue;
|
||||
changeCategory(id, index, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
changeCategory(0, 0, true);
|
||||
pushToast($t('achievement.searchError', { values: { query } }), 'error');
|
||||
}, 500);
|
||||
|
||||
async function changeCategory(id, index, firstLoad, search) {
|
||||
const updateSelectFilter = debounce(() => {
|
||||
changeCategory(active, activeIndex, true);
|
||||
}, 500);
|
||||
|
||||
async function changeCategory(id, index, firstLoad) {
|
||||
active = id;
|
||||
activeIndex = index;
|
||||
|
||||
const filterVersion = versionFilter.length > 0;
|
||||
const filteredVersion = versionFilter.map((e) => e.value);
|
||||
|
||||
const filterComission = typeFilter.map((e) => e.value).includes('commissions');
|
||||
|
||||
const filterName = nameFilter !== '';
|
||||
const query = nameFilter.toLowerCase();
|
||||
|
||||
console.log('filter', filterVersion, filterComission, filterName);
|
||||
if (checkList[active] === undefined) {
|
||||
checkList[active] = {};
|
||||
}
|
||||
|
||||
list = achievement[active].achievements.map((e) => {
|
||||
if (Array.isArray(e)) {
|
||||
for (let i = 0; i < e.length; i++) {
|
||||
e[i].checked = checkList[active][e[i].id] === true;
|
||||
list = achievement[active].achievements
|
||||
.filter((e) => {
|
||||
if (Array.isArray(e)) {
|
||||
if (filterVersion && !filteredVersion.includes(e[0].ver)) return false;
|
||||
if (filterComission && !e[0].commissions) return false;
|
||||
if (filterName && !e[0].name.toLowerCase().includes(query)) return false;
|
||||
return true;
|
||||
} else {
|
||||
if (filterVersion && !filteredVersion.includes(e.ver)) return false;
|
||||
if (filterComission && !e.commissions) return false;
|
||||
if (filterName && !e.name.toLowerCase().includes(query)) return false;
|
||||
return true;
|
||||
}
|
||||
return e;
|
||||
} else {
|
||||
e.checked = checkList[active][e.id] === true;
|
||||
return e;
|
||||
}
|
||||
});
|
||||
})
|
||||
.map((e) => {
|
||||
if (Array.isArray(e)) {
|
||||
for (let i = 0; i < e.length; i++) {
|
||||
e[i].checked = checkList[active][e[i].id] === true;
|
||||
}
|
||||
return e;
|
||||
} else {
|
||||
e.checked = checkList[active][e.id] === true;
|
||||
return e;
|
||||
}
|
||||
});
|
||||
|
||||
if (search) {
|
||||
list = [search];
|
||||
} else if (sort) {
|
||||
if (sort) {
|
||||
originalList = list.slice();
|
||||
list = list.sort((a, b) => {
|
||||
let first = a;
|
||||
|
@ -279,20 +311,22 @@
|
|||
<img src="/images/primogem.png" class="w-4 h-4 ml-1" alt="primogem" />
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
size="sm"
|
||||
on:click={() => {
|
||||
showFilter = !showFilter;
|
||||
}}
|
||||
>
|
||||
<Icon path={mdiFilter} color="white" />
|
||||
</Button>
|
||||
<div class="lg:pl-4 text-white">
|
||||
<Checkbox checked={sort} on:change={() => changeSort(!sort)}>{$t('achievement.sort')}</Checkbox>
|
||||
<div class="flex space-x-2 items-center">
|
||||
<Button
|
||||
size="sm"
|
||||
on:click={() => {
|
||||
showFilter = !showFilter;
|
||||
}}
|
||||
>
|
||||
<Icon path={mdiFilter} color="white" />
|
||||
</Button>
|
||||
<div class="pl-4 text-white">
|
||||
<Checkbox checked={sort} on:change={() => changeSort(!sort)}>{$t('achievement.sort')}</Checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{#if showFilter}
|
||||
<div>
|
||||
<div class="mb-2 flex flex-col md:flex-row space-y-2 md:space-y-0 md:space-x-2">
|
||||
<div
|
||||
class="flex flex-1 relative items-center bg-background rounded-2xl h-14
|
||||
focus-within:border-primary border-2 border-transparent ease-in duration-100"
|
||||
|
@ -305,6 +339,22 @@
|
|||
class="pl-4 w-full min-h-full pr-4 text-white placeholder-gray-500 leading-none bg-transparent border-none focus:outline-none"
|
||||
/>
|
||||
</div>
|
||||
<Select
|
||||
multiselect
|
||||
options={versions}
|
||||
bind:selected={versionFilter}
|
||||
placeholder={$t('achievement.version')}
|
||||
className="w-full md:w-40"
|
||||
on:change={updateSelectFilter}
|
||||
/>
|
||||
<Select
|
||||
multiselect
|
||||
options={types}
|
||||
bind:selected={typeFilter}
|
||||
placeholder={$t('achievement.type')}
|
||||
className="w-full md:w-56"
|
||||
on:change={updateSelectFilter}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="flex flex-col lg:flex-row space-y-3 lg:space-y-0 lg:space-x-3">
|
||||
|
@ -338,7 +388,17 @@
|
|||
{i > 0 && el[i - 1].checked !== true ? 'opacity-25' : ''}"
|
||||
>
|
||||
<div class="flex-1 pr-1">
|
||||
<p class="font-semibold">{it.name}</p>
|
||||
<p class="font-semibold">
|
||||
{it.name}
|
||||
<span class="ml-1 rounded-xl bg-background px-2 text-gray-400 text-sm font-normal select-none">
|
||||
{it.ver}
|
||||
</span>
|
||||
{#if it.commissions}
|
||||
<span class="ml-1 rounded-xl bg-background px-2 text-gray-400 text-sm font-normal select-none">
|
||||
{$t('achievement.commissions')}
|
||||
</span>
|
||||
{/if}
|
||||
</p>
|
||||
<p class="text-gray-400">{it.desc}</p>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
|
@ -359,7 +419,17 @@
|
|||
{:else}
|
||||
<div class="bg-item rounded-xl px-2 py-1 text-white flex items-center">
|
||||
<div class="flex-1 pr-1">
|
||||
<p class="font-semibold">{el.name}</p>
|
||||
<p class="font-semibold">
|
||||
{el.name}
|
||||
<span class="ml-1 rounded-xl bg-background px-2 text-gray-400 text-sm font-normal select-none">
|
||||
{el.ver}
|
||||
</span>
|
||||
{#if el.commissions}
|
||||
<span class="ml-1 rounded-xl bg-background px-2 text-gray-400 text-sm font-normal select-none">
|
||||
{$t('achievement.commissions')}
|
||||
</span>
|
||||
{/if}
|
||||
</p>
|
||||
<p class="text-gray-400">{el.desc}</p>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
|
|
|
@ -252,7 +252,7 @@
|
|||
|
||||
<div class="lg:ml-64 pt-20 px-4 md:px-8 lg:pt-8">
|
||||
<div class="bg-item rounded-xl mb-4 p-4">
|
||||
<p class="text-white">{$t('settings.version')} <b>2.0</b></p>
|
||||
<p class="text-white">{$t('settings.version')} <b>2.1</b></p>
|
||||
</div>
|
||||
<div class="bg-item rounded-xl mb-4 p-4 flex flex-col">
|
||||
<p class="text-white">{$t('settings.multiple')}</p>
|
||||
|
|
Loading…
Reference in a new issue