diff --git a/src/app.css b/src/app.css index 9548f017a..7af781256 100644 --- a/src/app.css +++ b/src/app.css @@ -214,11 +214,7 @@ } @utility shine { - @apply overflow-hidden; - - &::before { - @apply animate-shine absolute inset-0 z-8 -translate-y-full transform bg-linear-to-t from-[oklch(1_0_0_/_0)] via-[oklch(1_0_0_/_0.50)] to-[oklch(0.77_0.09_243.21_/_0)] content-['']; - } + @apply before:animate-shine overflow-hidden before:absolute before:inset-0 before:z-8 before:bg-linear-to-t before:from-[oklch(1_0_0_/_0)] before:via-[oklch(1_0_0_/_0.50)] before:to-[oklch(0.77_0.09_243.21_/_0)]; } @utility enchanted { diff --git a/src/lib/components/Item.svelte b/src/lib/components/Item.svelte index f886769f1..491f98b9c 100644 --- a/src/lib/components/Item.svelte +++ b/src/lib/components/Item.svelte @@ -8,6 +8,7 @@ import { Avatar, Tooltip } from "bits-ui"; import Image from "lucide-svelte/icons/image"; import { getContext } from "svelte"; + import { type FadeParams } from "svelte/transition"; import Content from "./item/item-content.svelte"; type Props = { @@ -15,9 +16,13 @@ isInventory?: boolean; showCount?: boolean; showRecombobulated?: boolean; + tab?: { + name: string; + icon: string; + }; + inTransitionConfig?: FadeParams; }; - - let { piece, isInventory, showCount, showRecombobulated }: Props = $props(); + let { piece, isInventory, showCount, showRecombobulated, tab, inTransitionConfig }: Props = $props(); const skyblockItem = $derived(piece as ProcessedSkyBlockItem); const bgColor = $derived(getRarityClass(piece.rarity ?? ("common".toLowerCase() as string), "bg")); @@ -57,7 +62,7 @@ {#if isHover.current} - + {/if} diff --git a/src/lib/components/item/item-content.svelte b/src/lib/components/item/item-content.svelte index 421e8ba13..bd7539f32 100644 --- a/src/lib/components/item/item-content.svelte +++ b/src/lib/components/item/item-content.svelte @@ -9,13 +9,13 @@ type Props = { piece: ProcessedSkyBlockItem | ProcessedSkyblockPet; - isInventory?: boolean; - showCount?: boolean; - showRecombobulated?: boolean; isDrawer?: boolean; + tab?: { + name: string; + icon: string; + }; }; - - let { piece, isDrawer }: Props = $props(); + let { piece, isDrawer, tab }: Props = $props(); const skyblockItem = $derived(piece as ProcessedSkyBlockItem); const itemName = $derived(skyblockItem.display_name ?? "???"); @@ -60,8 +60,25 @@ {/if} + {#if typeof tab === "object" && tab.icon} +
+
+
+ + + + {tab.name.slice(0, 2)} + + + +
+
+
+ {/if} {#if packData} -
+
diff --git a/src/lib/sections/stats/Inventory.svelte b/src/lib/sections/stats/Inventory.svelte index 787011f3e..f95c77195 100644 --- a/src/lib/sections/stats/Inventory.svelte +++ b/src/lib/sections/stats/Inventory.svelte @@ -8,8 +8,16 @@ import { cubicInOut } from "svelte/easing"; import { crossfade, fade } from "svelte/transition"; + type Tabs = { + id: string; + icon: string; + items: ProcessedSkyBlockItem[]; + gap: number; + }; + let { order }: { order: number } = $props(); let openTab = $state("inv"); + let searchValue = $state(""); const ctx = getProfileCtx(); const profile = $derived(ctx.profile); @@ -26,7 +34,7 @@ const quiver = $derived(profile.items.quiver); const museum = $derived(profile.items.museum); - const tabs = $derived( + const tabs = $derived( [ { id: "inv", @@ -93,10 +101,36 @@ icon: "/api/head/a6cc486c2be1cb9dfcb2e53dd9a3e9a883bfadb27cb956f1896d602b4067", items: rift_enderchest, gap: 45 + }, + { + id: "search", + icon: "/api/item/EYE_OF_ENDER", + items: [], + gap: 45 } - ].filter((tab) => tab.items.length > 0) + ].filter((tab) => tab.id === "search" || tab.items.length > 0) ); + const allItems = $derived.by(() => { + return tabs.reduce((acc, tab) => { + acc.push(...tab.items); + return acc; + }, [] as ProcessedSkyBlockItem[]); + }); + + const searchedItems = $derived.by(() => { + const search = searchValue.trim(); + if (!search) return []; + const searchedItem = allItems + .map((item) => { + const tab = tabs.find((t) => t.items.includes(item)); + return { item, sourceTab: { name: tab?.id || "", icon: tab?.icon || "" } }; + }) + .filter((item) => item.item.display_name?.toLowerCase().includes(searchValue.toLowerCase())) + .slice(0, 45); + return searchedItem; + }); + const [send, receive] = crossfade({ duration: 300, easing: cubicInOut @@ -137,69 +171,11 @@ {#each tabs as tab} {#if tab.id === "storage" || tab.id === "museum"} - - - {#each tab.items as item, index} - -
- {#if item.texture_path} -
- -
- {:else} - {@render emptyItem()} - {/if} -
-
- {/each} -
- - {#each tab.items as item, index} - -
- {#if item?.containsItems} - {#each item.containsItems as containedItem, index2} - {#if index2 > 0} - {#if index2 % 54 === 0} - {@render gap()} - {/if} - {/if} - - {#if containedItem.texture_path} -
- -
- {:else} - {@render emptyItem()} - {/if} -
- {/each} - {/if} -
-
- {/each} -
+ {@render multipleInventorySection(tab)} + {:else if tab.id == "search"} + {@render searchSection()} {:else} -
- {#each tab.items as item, index} - {#if index > 0} - {#if index % tab.gap === 0} - {@render gap()} - {/if} - {/if} - {#if item.texture_path} -
- {#if tab.id === "inv"} - - {:else} - - {/if} -
- {:else} - {@render emptyItem()} - {/if} - {/each} -
+ {@render inventorySection(tab)} {/if}
{/each} @@ -209,6 +185,10 @@ {/if} +{#snippet itemSnippet(item: ProcessedSkyBlockItem, index: number, tab?: { name: string; icon: string })} + +{/snippet} + {#snippet emptyItem()}
{/snippet} @@ -216,3 +196,89 @@ {#snippet gap()}
{/snippet} + +{#snippet searchSection()} + + {#if searchValue !== "" && searchedItems.length === 0} +

No items found.

+ {:else if searchValue !== ""} +
+ {#each searchedItems as item, index} + {#if item.item} +
+ {@render itemSnippet(item.item, index, item.sourceTab)} +
+ {:else} + {@render emptyItem()} + {/if} + {/each} +
+ {/if} +{/snippet} + +{#snippet multipleInventorySection(tab: Tabs)} + + + {#each tab.items as item, index} + +
+ {#if item.texture_path} +
+ {@render itemSnippet(item, index)} +
+ {:else} + {@render emptyItem()} + {/if} +
+
+ {/each} +
+ {#each tab.items as item, index} + +
+ {#if item?.containsItems} + {#each item.containsItems as containedItem, index2} + {#if index2 > 0} + {#if index2 % 54 === 0} + {@render gap()} + {/if} + {/if} + + {#if containedItem.texture_path} +
+ {@render itemSnippet(containedItem, index2)} +
+ {:else} + {@render emptyItem()} + {/if} +
+ {/each} + {/if} +
+
+ {/each} +
+{/snippet} + +{#snippet inventorySection(tab: Tabs)} +
+ {#each tab.items as item, index} + {#if index > 0} + {#if index % tab.gap === 0} + {@render gap()} + {/if} + {/if} + {#if item.texture_path} +
+ {#if tab.id === "inv"} + {@render itemSnippet({ ...item, rarity: item.rarity ?? "uncommon" } as ProcessedSkyBlockItem, index)} + {:else} + {@render itemSnippet(item, index)} + {/if} +
+ {:else} + {@render emptyItem()} + {/if} + {/each} +
+{/snippet}