refactor use of item-quick-price

This commit is contained in:
Alexander Drozdov
2022-02-10 20:45:51 +02:00
parent 5edfa0d57e
commit 1d5908eb0d
9 changed files with 94 additions and 101 deletions
+8 -8
View File
@@ -176,25 +176,25 @@ async function load (force: boolean = false) {
}
}
export function findByDetailsId (id: string) {
export function findPriceByQueryId (id: string) {
return PRICE_BY_QUERY_ID.get(id)
}
export function autoCurrency (value: number, currency: string) {
if (currency === 'c') {
export function autoCurrency (value: number, currency: 'chaos' | 'exa'): { min: number, max: number, currency: 'chaos' | 'exa' } {
if (currency === 'chaos') {
if (value > ((chaosExaRate.value || 9999) * 0.94)) {
if (value < ((chaosExaRate.value || 9999) * 1.06)) {
return { val: 1, curr: 'e' }
return { min: 1, max: 1, currency: 'exa' }
} else {
return { val: chaosToExa(value), curr: 'e' }
return { min: chaosToExa(value), max: chaosToExa(value), currency: 'exa' }
}
}
} else if (currency === 'e') {
} else if (currency === 'exa') {
if (value < 1) {
return { val: exaToChaos(value), curr: 'c' }
return { min: exaToChaos(value), max: exaToChaos(value), currency: 'chaos' }
}
}
return { val: value, curr: currency }
return { min: value, max: value, currency }
}
function chaosToExa (count: number) {
+2 -4
View File
@@ -18,11 +18,9 @@
</button>
</template>
<template #content>
<item-quick-price
:min="exaltedCost"
:max="exaltedCost"
<item-quick-price class="text-base"
:price="{ min: exaltedCost, max: exaltedCost, currency: 'chaos' }"
item-img="/images/exa.png"
currency="chaos"
/>
<div v-for="i in 9" :key="i">
<div class="pl-1">{{ i / 10 }} exa ⇒ {{ Math.round(exaltedCost * i / 10) }} c</div>
@@ -1,18 +1,25 @@
<template>
<div v-if="result"
class="flex items-center">
<img v-for="icon in result.icons" class="w-8 h-8" :src="icon">
<span><i class="fas fa-arrow-right text-gray-600 px-2"></i>{{ result.price }}</span>
</div>
<item-quick-price v-if="result"
:price="result.price"
currency-text
>
<template #item>
<div class="flex">
<img v-for="icon in result.icons" class="w-8 h-8" :src="icon">
</div>
</template>
</item-quick-price>
</template>
<script lang="ts">
import { defineComponent, PropType, computed } from 'vue'
import { StatFilter } from './interfaces'
import { autoCurrency, displayRounding, findByDetailsId, ItemInfo } from '@/web/background/Prices'
import { BLIGHT_RECIPES } from '@/assets/data'
import { autoCurrency, findPriceByQueryId } from '@/web/background/Prices'
import { BLIGHT_RECIPES, ITEM_BY_REF } from '@/assets/data'
import ItemQuickPrice from '@/web/ui/ItemQuickPrice.vue'
export default defineComponent({
components: { ItemQuickPrice },
props: {
filter: {
type: Object as PropType<StatFilter>,
@@ -25,27 +32,32 @@ export default defineComponent({
const roll = props.filter.option!.value
const oils = (BLIGHT_RECIPES.recipes[roll] ?? []).map(idx => BLIGHT_RECIPES.oils[idx])
const oils = (BLIGHT_RECIPES.recipes[roll] ?? [])
.map(idx => BLIGHT_RECIPES.oils[idx])
.map(oilName => ITEM_BY_REF('ITEM', oilName)?.[0])
if (!oils.length) return null
const prices = oils
.map(oil => findByDetailsId(`ITEM::${oil}`))
.filter(Boolean) as ItemInfo[]
if (prices.length !== oils.length) return null
const totalChaos = prices.reduce((t, p) => t + p.chaosValue, 0)
const total = autoCurrency(totalChaos, 'c')
let totalChaos: number | undefined = 0
for (const oil of oils) {
if (!oil) return null
const price = findPriceByQueryId(`ITEM::${oil.refName}`)
if (price) {
totalChaos += price.chaosValue
} else {
totalChaos = undefined
break
}
}
return {
icons: prices.map(p => p.icon),
price: `${displayRounding(total.val)} ${total.curr === 'c' ? 'chaos' : 'exa'}`
icons: oils.map(item => item!.icon),
price: (totalChaos != null)
? autoCurrency(totalChaos, 'chaos')
: undefined
}
})
return {
result
}
return { result }
}
})
</script>
@@ -11,12 +11,10 @@
</div>
<div v-else-if="price">
<div class="flex items-center pb-4">
<item-quick-price class="flex-1"
:min="price.min"
:max="price.max"
approx
<item-quick-price class="flex-1 text-base justify-center"
:price="price"
:item-img="item.info.icon"
:currency="price.currency === 'exalt' ? 'exa' : 'chaos'"
approx
/>
<div class="text-center">
<div class="leading-tight">
@@ -20,7 +20,7 @@ export interface RareItemPrice {
max: number
min: number
confidence: number
currency: string
currency: 'chaos' | 'exa'
explanation: Array<{
name: string
contrib: number
@@ -51,7 +51,7 @@ export async function requestPoeprices (item: ParsedItem): Promise<RareItemPrice
}
return {
currency: data.currency,
currency: (data.currency === 'exalt') ? 'exa' : 'chaos',
min: data.min,
max: data.max,
confidence: Math.round(data.pred_confidence_score),
@@ -6,25 +6,17 @@
<div v-if="'related' in result" class="flex-1 p-2 w-1/2">
<div v-for="item in result.related" :key="item.name"
:class="{ 'bg-gray-700 -mx-1 px-1': item.highlight }" class="rounded">
<div class="flex items-center flex-1">
<div class="w-8 h-8 flex items-center justify-center flex-shrink-0">
<img :src="item.icon" :alt="item.name" class="max-w-full max-h-full">
</div>
<i class="fas fa-arrow-right text-gray-600 px-2"></i>
<span class="px-1 text-base whitespace-no-wrap overflow-hidden">{{ item.price }}</span>
</div>
<item-quick-price currency-text fraction class="text-base"
:price="item.price"
:item-img="item.icon" />
<div class="text-left text-gray-600 mb-1 whitespace-no-wrap overflow-hidden">{{ item.name }}</div>
</div>
</div>
<div v-if="'items' in result && result.items.length" class="flex-1 p-2 w-1/2">
<div v-for="item in result.items" :key="item.name">
<div class="flex items-center flex-1">
<div class="w-8 h-8 flex items-center justify-center flex-shrink-0">
<img :src="item.icon" :alt="item.name" class="max-w-full max-h-full">
</div>
<i class="fas fa-arrow-right text-gray-600 px-2"></i>
<span class="px-1 text-base whitespace-no-wrap overflow-hidden">{{ item.price }}</span>
</div>
<item-quick-price currency-text fraction class="text-base"
:price="item.price"
:item-img="item.icon" />
<div class="text-left text-gray-600 mb-1 whitespace-no-wrap overflow-hidden">{{ item.name }}</div>
</div>
</div>
@@ -34,9 +26,10 @@
<script lang="ts">
import { computed, defineComponent, PropType } from 'vue'
import { BaseType, ITEM_BY_REF, ITEM_DROP } from '@/assets/data'
import { displayRounding, findByDetailsId, autoCurrency } from '../../background/Prices'
import { findPriceByQueryId, autoCurrency } from '../../background/Prices'
import { getDetailsId } from '../trends/getDetailsId'
import { ParsedItem } from '@/parser'
import ItemQuickPrice from '@/web/ui/ItemQuickPrice.vue'
function findItemByQueryId (queryId: string): BaseType | undefined {
const [ns, encodedName] = queryId.split('::')
@@ -49,14 +42,11 @@ function findItemByQueryId (queryId: string): BaseType | undefined {
if (found && found.length) return found[0]
}
function findPriceByQueryId (queryId: string) {
let price = '?'
const priceEntry = findByDetailsId(queryId)
function _findPriceByQueryId (queryId: string) {
const priceEntry = findPriceByQueryId(queryId)
if (priceEntry) {
const _ = autoCurrency(priceEntry.chaosValue, 'c')
price = `${displayRounding(_.val, true)} ${_.curr === 'e' ? 'exa' : 'chaos'}`
return autoCurrency(priceEntry.chaosValue, 'chaos')
}
return price
}
function getItemPrices (queryId: string) {
@@ -64,8 +54,8 @@ function getItemPrices (queryId: string) {
if (!dropEntry) return null
const out = {
related: [] as Array<{ name: string, icon: string, price: string, highlight: boolean }>,
items: [] as Array<{ name: string, icon: string, price: string }>
related: [] as Array<{ name: string, icon: string, price: ReturnType<typeof _findPriceByQueryId>, highlight: boolean }>,
items: [] as Array<{ name: string, icon: string, price: ReturnType<typeof _findPriceByQueryId> }>
}
for (const itemId of dropEntry.query) {
const dbItem = findItemByQueryId(itemId)
@@ -74,7 +64,7 @@ function getItemPrices (queryId: string) {
out.related.push({
icon: dbItem.icon,
name: dbItem.name,
price: findPriceByQueryId(itemId),
price: _findPriceByQueryId(itemId),
highlight: (itemId === queryId)
})
}
@@ -85,7 +75,7 @@ function getItemPrices (queryId: string) {
out.items.push({
icon: dbItem.icon,
name: dbItem.name,
price: findPriceByQueryId(itemId)
price: _findPriceByQueryId(itemId)
})
}
@@ -93,6 +83,7 @@ function getItemPrices (queryId: string) {
}
export default defineComponent({
components: { ItemQuickPrice },
props: {
item: {
type: Object as PropType<ParsedItem | null>,
@@ -13,7 +13,7 @@
<script lang="ts">
import { defineComponent, PropType, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { displayRounding, findByDetailsId, autoCurrency } from '../../background/Prices'
import { displayRounding, findPriceByQueryId, autoCurrency } from '../../background/Prices'
import { getDetailsId } from '../trends/getDetailsId'
import { ParsedItem } from '@/parser'
import { ItemFilters } from '../filters/interfaces'
@@ -31,13 +31,13 @@ export default defineComponent({
},
setup (props) {
function getPriceFor (n: number) {
const one = findByDetailsId(getDetailsId(props.item)!)!
const one = findPriceByQueryId(getDetailsId(props.item)!)!
const price = (props.item.info.refName === 'Exalted Orb')
? { val: n * one.chaosValue, curr: 'c' }
: autoCurrency(n * one.chaosValue, 'c')
? { min: n * one.chaosValue, max: n * one.chaosValue, currency: 'chaos' as const }
: autoCurrency(n * one.chaosValue, 'chaos')
return `${displayRounding(price.val, true)} ${price.curr === 'c' ? 'chaos' : 'exa'}`
return `${displayRounding(price.min)} ${price.currency}`
}
const { t } = useI18n()
@@ -46,7 +46,7 @@ export default defineComponent({
t,
show: computed(() => {
const id = getDetailsId(props.item)
return Boolean(props.filters.stackSize && id && findByDetailsId(id))
return Boolean(props.filters.stackSize && id && findPriceByQueryId(id))
}),
value: computed(() => {
return {
+6 -8
View File
@@ -5,12 +5,10 @@
<div class="pl-2">{{ t('Getting price') }} <span class="text-gray-600">{{ t('from poe.ninja ...') }}</span></div>
</div>
<template v-else>
<item-quick-price class="flex-1"
:min="trend.price.val"
:max="trend.price.val"
<item-quick-price class="flex-1 text-base justify-center"
:price="trend.price"
:fraction="filters.stackSize != null"
:item-img="trend.icon"
:currency="trend.price.curr === 'e' ? 'exa' : 'chaos'"
>
<template #item v-if="isValuableBasetype">
<button class="text-gray-400 hover:bg-gray-700 rounded px-1 -mx-1"
@@ -53,7 +51,7 @@
<script lang="ts">
import { defineComponent, PropType, computed, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import { findByDetailsId, autoCurrency } from '../../background/Prices'
import { findPriceByQueryId, autoCurrency } from '../../background/Prices'
import { isValuableBasetype, getDetailsId } from './getDetailsId'
import ItemQuickPrice from '@/web/ui/ItemQuickPrice.vue'
import VueApexcharts from 'vue3-apexcharts'
@@ -84,12 +82,12 @@ export default defineComponent({
const trend = computed(() => {
const detailsId = getDetailsId(props.item)
const trend = detailsId && findByDetailsId(detailsId)
const trend = detailsId && findPriceByQueryId(detailsId)
if (!trend) return
const price = (props.item.info.refName === 'Exalted Orb')
? { val: trend.chaosValue, curr: 'c' }
: autoCurrency(trend.chaosValue, 'c')
? { min: trend.chaosValue, max: trend.chaosValue, currency: 'chaos' as const }
: autoCurrency(trend.chaosValue, 'chaos')
if (trend.graphPoints.length >= 2) {
let changeStr = 'const'
+18 -22
View File
@@ -1,20 +1,20 @@
<template>
<div class="flex items-center justify-center">
<div class="flex items-center overflow-hidden gap-x-1">
<slot name="item">
<div class="w-8 h-8 flex items-center justify-center">
<div class="w-8 h-8 flex items-center justify-center flex-shrink-0">
<img :src="itemImg" class="max-w-full max-h-full overflow-hidden">
</div>
</slot>
<!-- <span class="px-1 text-base" v-if="item.stackSize"><span class="font-sans">×</span> 1</span> -->
<i class="fas fa-arrow-right text-gray-600 px-2"></i>
<div class="px-1 text-base">
<i class="fas fa-arrow-right text-gray-600 px-1 text-sm"></i>
<div>
<span v-if="approx && !isRange" class="text-gray-600 font-sans">~ </span>
<span :class="{ [$style.exalted]: isExa }">{{ minText }}</span>
<span v-if="isRange" class="text-gray-600 font-sans"> ~ </span>
<span v-if="isRange" :class="{ [$style.exalted]: isExa }">{{ maxText }}</span>
<span class="font-sans" :class="{ [$style.exalted]: isExa }"> ×</span>
<span v-if="!currencyText" class="font-sans" :class="{ [$style.exalted]: isExa }"> ×</span>
<span v-else-if="price" :class="{ [$style.exalted]: isExa }">&nbsp;{{ price.currency }}</span>
</div>
<div class="w-8 h-8 flex items-center justify-center">
<div class="w-8 h-8 flex items-center justify-center flex-shrink-0" v-if="!currencyText">
<img v-if="isExa" src="/images/exa.png" class="max-w-full max-h-full">
<img v-else src="/images/chaos.png" class="max-w-full max-h-full">
</div>
@@ -22,22 +22,14 @@
</template>
<script lang="ts">
import { defineComponent, computed } from 'vue'
import { defineComponent, computed, PropType } from 'vue'
import { displayRounding } from '../background/Prices'
export default defineComponent({
props: {
min: {
type: Number,
required: true
},
max: {
type: Number,
required: true
},
currency: {
type: String,
required: true
price: {
type: Object as PropType<{ min: number, max: number, currency: 'exa' | 'chaos' }>,
default: undefined
},
approx: {
type: Boolean,
@@ -50,17 +42,21 @@ export default defineComponent({
itemImg: {
type: String,
default: '/images/wisdom.png'
},
currencyText: {
type: Boolean,
default: false
}
},
setup (props) {
const minText = computed(() => { return displayRounding(props.min, props.fraction) })
const maxText = computed(() => { return displayRounding(props.max, props.fraction) })
const minText = computed(() => (props.price) ? displayRounding(props.price.min, props.fraction) : '?')
const maxText = computed(() => (props.price) ? displayRounding(props.price.max, props.fraction) : '?')
return {
minText,
maxText,
isRange: computed(() => { return minText.value !== maxText.value }),
isExa: computed(() => { return props.currency === 'exa' })
isExa: computed(() => { return props.price?.currency === 'exa' })
}
}
})