From fa42cdc56e21d6d50f17db6143b74d8b57f179be Mon Sep 17 00:00:00 2001 From: mat Date: Sat, 23 Apr 2022 22:08:29 -0500 Subject: add /items page --- src/lib/APITypes.d.ts | 18 ++- src/lib/api.ts | 3 +- src/lib/minecraft/Item.svelte | 35 ++++- src/lib/minecraft/MinecraftTooltip.svelte | 2 + src/lib/minecraft/inventory.ts | 21 ++- src/lib/utils.ts | 14 ++ src/routes/items.svelte | 213 ++++++++++++++++++++++++++++++ 7 files changed, 296 insertions(+), 10 deletions(-) create mode 100644 src/routes/items.svelte (limited to 'src') diff --git a/src/lib/APITypes.d.ts b/src/lib/APITypes.d.ts index 7a6039c..827ee13 100644 --- a/src/lib/APITypes.d.ts +++ b/src/lib/APITypes.d.ts @@ -299,13 +299,23 @@ export interface PetsData { } export interface ItemRequirement { - dungeon: { + dungeon?: { type: string level: number } + skill?: { + type: string + level: number + } + slayer?: { + boss: string + level: number + } } + export interface ItemListItem { id: string + headTexture?: string vanillaId: string tier: string | null display: { @@ -313,8 +323,12 @@ export interface ItemListItem { glint: boolean } npcSellPrice: number | null - requirements: ItemRequirement | null + requirements: ItemRequirement + category: string | null + soulbound: boolean + museum: boolean } + export interface ItemListData { lastUpdated: number list: ItemListItem[] diff --git a/src/lib/api.ts b/src/lib/api.ts index 243cf2b..4ffa87d 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -1 +1,2 @@ -export const API_URL = 'https://skyblock-api.matdoes.dev/' +// export const API_URL = 'https://skyblock-api.matdoes.dev/' +export const API_URL = 'http://localhost:8080/' diff --git a/src/lib/minecraft/Item.svelte b/src/lib/minecraft/Item.svelte index 4d0997c..cfcc219 100644 --- a/src/lib/minecraft/Item.svelte +++ b/src/lib/minecraft/Item.svelte @@ -1,5 +1,5 @@ @@ -33,7 +60,7 @@ class:item-custom-head={imageUrl.startsWith('https://mc-heads.net/head/')} /> {/if} - {#if item.count !== 1} + {#if item.count !== undefined && item.count !== 1} {item.count} {/if} diff --git a/src/lib/minecraft/MinecraftTooltip.svelte b/src/lib/minecraft/MinecraftTooltip.svelte index 0cdb237..7149626 100644 --- a/src/lib/minecraft/MinecraftTooltip.svelte +++ b/src/lib/minecraft/MinecraftTooltip.svelte @@ -26,6 +26,8 @@ .minecraft-tooltip { /* this makes it be less dumb about the height so it doesn't add extra or anything */ display: grid; + /* this is so it doesn't change width to fill the container in the item list page */ + max-width: fit-content; } /* these elements exist so we can copy them later from GlobalTooltip */ .tooltip-name, diff --git a/src/lib/minecraft/inventory.ts b/src/lib/minecraft/inventory.ts index 871af93..ec0e193 100644 --- a/src/lib/minecraft/inventory.ts +++ b/src/lib/minecraft/inventory.ts @@ -1,6 +1,6 @@ import * as skyblockAssets from 'skyblock-assets' import { vanilla } from '$lib/packs' - +import { browser } from '$app/env' export interface Item { id?: string @@ -97,6 +97,13 @@ export const inventoryIconMap: Record = { export type Inventories = { [name in keyof typeof INVENTORIES]: Item[] } +// we cache the item urls because it takes a bit of time to get them usually +// { " ": "https://..." } +let itemUrlCache: Record = {} +// clear the cache every 120 seconds, this number is arbitrary +setInterval(() => { + itemUrlCache = {} +}, 120 * 1000) export function itemToUrl(item: Item, pack?: skyblockAssets.MatcherFile, headSize?: number): string { const itemNbt: skyblockAssets.NBT = { display: { @@ -107,6 +114,11 @@ export function itemToUrl(item: Item, pack?: skyblockAssets.MatcherFile, headSiz }, } let textureUrl: string + + const itemCacheIdentifier = `${pack?.dir ?? 'v'} ${JSON.stringify(itemNbt)}` + if (itemCacheIdentifier in itemUrlCache) + return itemUrlCache[itemCacheIdentifier] + if (item.headTexture) { // if it's a head, try without vanilla and if it fails just use the mc-heads url textureUrl = skyblockAssets.getTextureUrl({ @@ -120,21 +132,24 @@ export function itemToUrl(item: Item, pack?: skyblockAssets.MatcherFile, headSiz if (headSize) textureUrl += `/${headSize}` } - } else + } else { textureUrl = skyblockAssets.getTextureUrl({ id: item.vanillaId, nbt: itemNbt, packs: pack ? [pack, vanilla as skyblockAssets.MatcherFile] : [vanilla as skyblockAssets.MatcherFile], }) + } + itemUrlCache[itemCacheIdentifier] = textureUrl return textureUrl } export function skyblockItemToUrl(skyblockItem: string | Item, pack?: skyblockAssets.MatcherFile, headSize?: number) { - const item: Item = typeof skyblockItem === 'string' ? skyblockItemNameToItem(skyblockItem) : skyblockItem + const item = typeof skyblockItem === 'string' ? skyblockItemNameToItem(skyblockItem) : skyblockItem const itemTextureUrl = itemToUrl(item, pack, headSize) return itemTextureUrl } + export function skyblockItemNameToItem(skyblockItemName: string): Item { let item: Item if (Object.keys(skyblockItems).includes(skyblockItemName)) { diff --git a/src/lib/utils.ts b/src/lib/utils.ts index e7bebb2..e34d573 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -17,6 +17,18 @@ export const colorCodes: { [key: string]: string } = { 'f': '#ffffff', // white } +export const TIER_COLORS = { + COMMON: 'f', + UNCOMMON: 'a', + RARE: '9', + EPIC: '5', + LEGENDARY: '6', + MYTHIC: 'e', + DIVINE: 'b', + SPECIAL: 'c', + VERY_SPECIAL: 'c', +} + const specialCodes: { [key: string]: string } = { 'l': 'font-weight: bold' } @@ -60,6 +72,8 @@ export function formattingCodeToHtml(formatted: string): string { } else if (colorCharacter === 'r') { reset() } + } else if (character === '\n') { + htmlOutput += '
' } else { // no xss! htmlOutput += character.replace(/&/g, '&').replace(//g, '>') diff --git a/src/routes/items.svelte b/src/routes/items.svelte new file mode 100644 index 0000000..a14dd85 --- /dev/null +++ b/src/routes/items.svelte @@ -0,0 +1,213 @@ + + + + + +
+ + + +
+
+ Last updated: +
+

SkyBlock Item List

+

{filteredItems.length.toLocaleString()} items.

+
+ + + + + + + +
+
+ {#each filteredItemsSliced as item (item.id)} +
+ +

+ {item.display.name} +

+
+ {#if item.museum} +

+ Museum +

+ {/if} + {#if item.soulbound} +

+ Soulbound +

+ {/if} + {#if item.category} +

+ Category: + + {toTitleCase(cleanId(item.category))} + +

+ {/if} + {#if item.npcSellPrice} +

+ NPC sell price: + + {#if item.npcSellPrice == 1}1 coin{:else} + {item.npcSellPrice.toLocaleString()} coins{/if} + +

+ {/if} + {#if Object.keys(item.requirements).length > 0} +
+ Requirements: +
    + {#if item.requirements.dungeon} +
  • + {cleanId(item.requirements.dungeon.type)} + {item.requirements.dungeon.level} +
  • + {/if} + {#if item.requirements.skill} +
  • + {cleanId(item.requirements.skill.type)} + {item.requirements.skill.level} +
  • + {/if} + {#if item.requirements.slayer} +
  • + {cleanId(item.requirements.slayer.boss)} + Slayer + {item.requirements.slayer.level} +
  • + {/if} +
+
+ {/if} +
+
+ {/each} + {#if filteredItems.length === 0} + No results! + {/if} +
+
+ + -- cgit