mirror of
https://github.com/Kvan7/Exiled-Exchange-2.git
synced 2026-09-20 03:35:39 +00:00
Merge branch 'master' of https://github.com/SnosMe/awakened-poe-trade
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 5.6 KiB |
@@ -10,7 +10,7 @@ interface NinjaDenseInfo {
|
||||
variant?: string
|
||||
}
|
||||
|
||||
export const chaosExaRate = shallowRef<number | undefined>(undefined)
|
||||
export const xchgRate = shallowRef<number | undefined>(undefined)
|
||||
|
||||
type PriceDatabase = Array<{ ns: string, url: string, lines: string }>
|
||||
let PRICES_DB: PriceDatabase = []
|
||||
@@ -31,9 +31,9 @@ async function load (force: boolean = false) {
|
||||
if (leagueAtStartOfLoad === selectedLeague.value) {
|
||||
PRICES_DB = splitJsonBlob(jsonBlob)
|
||||
|
||||
const exalted = findPriceByQuery({ ns: 'ITEM', name: 'Exalted Orb', variant: undefined })
|
||||
if (exalted && exalted.chaos >= 15) {
|
||||
chaosExaRate.value = exalted.chaos
|
||||
const divine = findPriceByQuery({ ns: 'ITEM', name: 'Divine Orb', variant: undefined })
|
||||
if (divine && divine.chaos >= 30) {
|
||||
xchgRate.value = divine.chaos
|
||||
}
|
||||
|
||||
lastUpdateTime = Date.now()
|
||||
@@ -143,29 +143,29 @@ export function findPriceByQuery (query: DbQuery) {
|
||||
return null
|
||||
}
|
||||
|
||||
export function autoCurrency (value: number, currency: 'chaos' | 'exa'): { min: number, max: number, currency: 'chaos' | 'exa' } {
|
||||
export function autoCurrency (value: number, currency: 'chaos' | 'div'): { min: number, max: number, currency: 'chaos' | 'div' } {
|
||||
if (currency === 'chaos') {
|
||||
if (value > ((chaosExaRate.value || 9999) * 0.94)) {
|
||||
if (value < ((chaosExaRate.value || 9999) * 1.06)) {
|
||||
return { min: 1, max: 1, currency: 'exa' }
|
||||
if (value > ((xchgRate.value || 9999) * 0.94)) {
|
||||
if (value < ((xchgRate.value || 9999) * 1.06)) {
|
||||
return { min: 1, max: 1, currency: 'div' }
|
||||
} else {
|
||||
return { min: chaosToExa(value), max: chaosToExa(value), currency: 'exa' }
|
||||
return { min: chaosToStable(value), max: chaosToStable(value), currency: 'div' }
|
||||
}
|
||||
}
|
||||
} else if (currency === 'exa') {
|
||||
} else if (currency === 'div') {
|
||||
if (value < 1) {
|
||||
return { min: exaToChaos(value), max: exaToChaos(value), currency: 'chaos' }
|
||||
return { min: stableToChaos(value), max: stableToChaos(value), currency: 'chaos' }
|
||||
}
|
||||
}
|
||||
return { min: value, max: value, currency }
|
||||
}
|
||||
|
||||
function chaosToExa (count: number) {
|
||||
return count / (chaosExaRate.value || 9999)
|
||||
function chaosToStable (count: number) {
|
||||
return count / (xchgRate.value || 9999)
|
||||
}
|
||||
|
||||
function exaToChaos (count: number) {
|
||||
return count * (chaosExaRate.value || 9999)
|
||||
function stableToChaos (count: number) {
|
||||
return count * (xchgRate.value || 9999)
|
||||
}
|
||||
|
||||
export function displayRounding (value: number, fraction: boolean = false): string {
|
||||
@@ -187,7 +187,7 @@ setInterval(() => {
|
||||
}, RETRY_TIME)
|
||||
|
||||
watch(selectedLeague, () => {
|
||||
chaosExaRate.value = undefined
|
||||
xchgRate.value = undefined
|
||||
PRICES_DB = []
|
||||
load(true)
|
||||
})
|
||||
|
||||
@@ -11,17 +11,17 @@
|
||||
<div id="price-window" class="layout-column shrink-0 text-gray-200 pointer-events-auto" style="width: 28.75rem;">
|
||||
<app-titlebar @close="closePriceCheck" @click="openLeagueSelection" :title="title">
|
||||
<div class="flex">
|
||||
<ui-popover v-if="exaltedCost" trigger="click" boundary="#price-window">
|
||||
<ui-popover v-if="stableOrbCost" trigger="click" boundary="#price-window">
|
||||
<template #target>
|
||||
<button><i class="fas fa-exchange-alt"></i> {{ exaltedCost }}</button>
|
||||
<button><i class="fas fa-exchange-alt"></i> {{ stableOrbCost }}</button>
|
||||
</template>
|
||||
<template #content>
|
||||
<item-quick-price class="text-base"
|
||||
:price="{ min: exaltedCost, max: exaltedCost, currency: 'chaos' }"
|
||||
item-img="/images/exa.png"
|
||||
:price="{ min: stableOrbCost, max: stableOrbCost, currency: 'chaos' }"
|
||||
item-img="/images/divine.png"
|
||||
/>
|
||||
<div v-for="i in 9" :key="i">
|
||||
<div class="pl-1">{{ i / 10 }} exa ⇒ {{ Math.round(exaltedCost * i / 10) }} c</div>
|
||||
<div class="pl-1">{{ i / 10 }} div ⇒ {{ Math.round(stableOrbCost * i / 10) }} c</div>
|
||||
</div>
|
||||
</template>
|
||||
</ui-popover>
|
||||
@@ -71,7 +71,7 @@ import { useI18n } from 'vue-i18n'
|
||||
import CheckedItem from './CheckedItem.vue'
|
||||
import BackgroundInfo from './BackgroundInfo.vue'
|
||||
import { MainProcess } from '@/web/background/IPC'
|
||||
import { chaosExaRate } from '../background/Prices'
|
||||
import { xchgRate } from '../background/Prices'
|
||||
import { selected as league } from '@/web/background/Leagues'
|
||||
import { AppConfig } from '@/web/Config'
|
||||
import { ItemCategory, ItemRarity, parseClipboard, ParsedItem } from '@/parser'
|
||||
@@ -162,7 +162,7 @@ export default defineComponent({
|
||||
})
|
||||
|
||||
const title = computed(() => league.value || 'Awakened PoE Trade')
|
||||
const exaltedCost = computed(() => (chaosExaRate.value) ? Math.round(chaosExaRate.value) : null)
|
||||
const stableOrbCost = computed(() => (xchgRate.value) ? Math.round(xchgRate.value) : null)
|
||||
const isBrowserShown = computed(() => props.config.wmFlags.includes('has-browser'))
|
||||
const overlayKey = computed(() => AppConfig().overlayKey)
|
||||
const showCheckPos = computed(() => wm.active.value && props.config.showCursor)
|
||||
@@ -227,7 +227,7 @@ export default defineComponent({
|
||||
poeUiWidth: wm.poePanelWidth,
|
||||
closePriceCheck,
|
||||
title,
|
||||
exaltedCost,
|
||||
stableOrbCost,
|
||||
showCheckPos,
|
||||
checkPosition,
|
||||
item,
|
||||
|
||||
@@ -31,7 +31,7 @@ export default defineComponent({
|
||||
required: true
|
||||
},
|
||||
prediction: {
|
||||
type: Object as PropType<{ min: number, max: number, currency: 'chaos' | 'exa' }>,
|
||||
type: Object as PropType<{ min: number, max: number, currency: 'chaos' | 'div' }>,
|
||||
required: true
|
||||
},
|
||||
item: {
|
||||
@@ -60,7 +60,7 @@ export default defineComponent({
|
||||
}, {
|
||||
min: props.prediction.min,
|
||||
max: props.prediction.max,
|
||||
currency: (props.prediction.currency === 'exa') ? 'exalt' : 'chaos'
|
||||
currency: (props.prediction.currency === 'div') ? 'divine' : 'chaos'
|
||||
}, props.item)
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Cache } from '../trade/Cache'
|
||||
const cache = new Cache()
|
||||
|
||||
interface PoepricesApiResponse { /* eslint-disable camelcase */
|
||||
currency: 'chaos' | 'exalt'
|
||||
currency: 'chaos' | 'divine'
|
||||
error: number
|
||||
error_msg: string
|
||||
warning_msg: string
|
||||
@@ -20,7 +20,7 @@ export interface RareItemPrice {
|
||||
max: number
|
||||
min: number
|
||||
confidence: number
|
||||
currency: 'chaos' | 'exa'
|
||||
currency: 'chaos' | 'div'
|
||||
explanation: Array<{
|
||||
name: string
|
||||
contrib: number
|
||||
@@ -50,8 +50,12 @@ export async function requestPoeprices (item: ParsedItem): Promise<RareItemPrice
|
||||
cache.set<PoepricesApiResponse>(query, data, 300)
|
||||
}
|
||||
|
||||
if (data.currency !== 'divine' && data.currency !== 'chaos') {
|
||||
throw new Error('poeprices.info gave the price in Exalted Orbs.')
|
||||
}
|
||||
|
||||
return {
|
||||
currency: (data.currency === 'exalt') ? 'exa' : 'chaos',
|
||||
currency: (data.currency === 'divine') ? 'div' : 'chaos',
|
||||
min: data.min,
|
||||
max: data.max,
|
||||
confidence: Math.round(data.pred_confidence_score),
|
||||
|
||||
@@ -33,7 +33,7 @@ export default defineComponent({
|
||||
function getPriceFor (n: number) {
|
||||
const one = findPriceByQuery(getDetailsId(props.item)!)!
|
||||
|
||||
const price = (props.item.info.refName === 'Exalted Orb')
|
||||
const price = (props.item.info.refName === 'Divine Orb')
|
||||
? { min: n * one.chaos, max: n * one.chaos, currency: 'chaos' as const }
|
||||
: autoCurrency(n * one.chaos, 'chaos')
|
||||
|
||||
|
||||
@@ -6,15 +6,15 @@
|
||||
<span class="mr-1">{{ t('Matched:') }}</span>
|
||||
<span v-if="!result" class="text-gray-600">...</span>
|
||||
<div v-else class="flex items-center">
|
||||
<button class="btn flex items-center mr-1" :style="{ background: selectedCurr !== 'chaos' ? 'transparent' : undefined }"
|
||||
@click="selectedCurr = 'chaos'">
|
||||
<button class="btn flex items-center mr-1" :style="{ background: selectedCurr !== 'xchgChaos' ? 'transparent' : undefined }"
|
||||
@click="selectedCurr = 'xchgChaos'">
|
||||
<img src="/images/chaos.png" class="trade-bulk-currency-icon">
|
||||
<span>{{ result.chaos.listed.value?.total ?? '?' }}</span>
|
||||
<span>{{ result.xchgChaos.listed.value?.total ?? '?' }}</span>
|
||||
</button>
|
||||
<button class="btn flex items-center mr-1" :style="{ background: selectedCurr !== 'exa' ? 'transparent' : undefined }"
|
||||
@click="selectedCurr = 'exa'">
|
||||
<img src="/images/exa.png" class="trade-bulk-currency-icon">
|
||||
<span>{{ result.exa.listed.value?.total ?? '?' }}</span>
|
||||
<button class="btn flex items-center mr-1" :style="{ background: selectedCurr !== 'xchgStable' ? 'transparent' : undefined }"
|
||||
@click="selectedCurr = 'xchgStable'">
|
||||
<img src="/images/divine.png" class="trade-bulk-currency-icon">
|
||||
<span>{{ result.xchgStable.listed.value?.total ?? '?' }}</span>
|
||||
</button>
|
||||
<span class="ml-1"><online-filter :filters="filters" /></span>
|
||||
</div>
|
||||
@@ -101,7 +101,7 @@ import TradeLinks from './TradeLinks.vue'
|
||||
const slowdown = artificialSlowdown(900)
|
||||
|
||||
function useBulkApi () {
|
||||
type BulkSearchExtended = Record<'exa' | 'chaos', {
|
||||
type BulkSearchExtended = Record<'xchgChaos' | 'xchgStable', {
|
||||
listed: Ref<BulkSearch | null>
|
||||
listedLazy: ComputedRef<PricingResult[]>
|
||||
}>
|
||||
@@ -120,17 +120,17 @@ function useBulkApi () {
|
||||
|
||||
// override, because at league start many players set wrong price, and this breaks optimistic search
|
||||
const have = (item.info.refName === 'Chaos Orb')
|
||||
? ['exalted']
|
||||
: (item.info.refName === 'Exalted Orb')
|
||||
? ['divine']
|
||||
: (item.info.refName === 'Divine Orb')
|
||||
? ['chaos']
|
||||
: ['exalted', 'chaos']
|
||||
: ['divine', 'chaos']
|
||||
|
||||
const optimisticSearch = await execBulkSearch(
|
||||
item, filters, have, { accountName: AppConfig().accountName })
|
||||
if (_searchId === searchId) {
|
||||
result.value = {
|
||||
exa: getResultsByHave(item, filters, optimisticSearch, 'exalted'),
|
||||
chaos: getResultsByHave(item, filters, optimisticSearch, 'chaos')
|
||||
xchgStable: getResultsByHave(item, filters, optimisticSearch, 'divine'),
|
||||
xchgChaos: getResultsByHave(item, filters, optimisticSearch, 'chaos')
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
@@ -142,7 +142,7 @@ function useBulkApi () {
|
||||
item: ParsedItem,
|
||||
filters: ItemFilters,
|
||||
preloaded: Array<BulkSearch | null>,
|
||||
have: 'exalted' | 'chaos'
|
||||
have: 'divine' | 'chaos'
|
||||
) {
|
||||
const _result = shallowRef(
|
||||
preloaded.some(res => res?.haveTag === have)
|
||||
@@ -160,9 +160,9 @@ function useBulkApi () {
|
||||
item, filters, [have], { accountName: AppConfig().accountName }))[0]!
|
||||
)
|
||||
items.value = _result.value.listed
|
||||
const otherHave = (have === 'exalted')
|
||||
? result.value?.chaos?.listed.value!
|
||||
: result.value?.exa?.listed.value!
|
||||
const otherHave = (have === 'divine')
|
||||
? result.value?.xchgChaos?.listed.value!
|
||||
: result.value?.xchgStable?.listed.value!
|
||||
// fix best guess we did while making optimistic search
|
||||
otherHave.total -= _result.value.total
|
||||
} catch (err) {
|
||||
@@ -196,7 +196,7 @@ export default defineComponent({
|
||||
const widget = computed(() => AppConfig<PriceCheckWidget>('price-check')!)
|
||||
const { error, result, search } = useBulkApi()
|
||||
|
||||
const selectedCurr = shallowRef<'chaos' | 'exa'>('chaos')
|
||||
const selectedCurr = shallowRef<'xchgChaos' | 'xchgStable'>('xchgChaos')
|
||||
|
||||
watch(() => props.item, (item) => {
|
||||
slowdown.reset(item)
|
||||
@@ -212,14 +212,14 @@ export default defineComponent({
|
||||
})
|
||||
|
||||
watch(result, () => {
|
||||
const exaTotal = result.value?.exa.listed.value?.total
|
||||
const chaosTotal = result.value?.chaos.listed.value?.total
|
||||
if (exaTotal == null) {
|
||||
selectedCurr.value = 'chaos'
|
||||
const stableTotal = result.value?.xchgStable.listed.value?.total
|
||||
const chaosTotal = result.value?.xchgChaos.listed.value?.total
|
||||
if (stableTotal == null) {
|
||||
selectedCurr.value = 'xchgChaos'
|
||||
} else if (chaosTotal == null) {
|
||||
selectedCurr.value = 'exa'
|
||||
selectedCurr.value = 'xchgStable'
|
||||
} else {
|
||||
selectedCurr.value = (exaTotal > chaosTotal) ? 'exa' : 'chaos'
|
||||
selectedCurr.value = (stableTotal > chaosTotal) ? 'xchgStable' : 'xchgChaos'
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@ export async function execBulkSearch (
|
||||
.map(result => toPricingResult(result, opts, offer))
|
||||
|
||||
const chaosIsLoaded = (
|
||||
tradeTag === 'exalted' &&
|
||||
tradeTag === 'divine' &&
|
||||
resultsTag.length < results.length &&
|
||||
((results.length - resultsTag.length) >= SHOW_RESULTS || query.total <= API_FETCH_LIMIT)
|
||||
)
|
||||
|
||||
@@ -87,7 +87,7 @@ export default defineComponent({
|
||||
const trend = detailsId && findPriceByQuery(detailsId)
|
||||
if (!trend) return
|
||||
|
||||
const price = (props.item.info.refName === 'Exalted Orb')
|
||||
const price = (props.item.info.refName === 'Divine Orb')
|
||||
? { min: trend.chaos, max: trend.chaos, currency: 'chaos' as const }
|
||||
: autoCurrency(trend.chaos, 'chaos')
|
||||
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
<i class="fas fa-arrow-right text-gray-600 px-1 text-sm"></i>
|
||||
<div class="whitespace-nowrap">
|
||||
<span v-if="approx && !isRange" class="text-gray-600 font-sans">~ </span>
|
||||
<span :class="{ [$style.exalted]: isExa }">{{ minText }}</span>
|
||||
<span :class="{ [$style.golden]: isValuable }">{{ minText }}</span>
|
||||
<span v-if="isRange" class="text-gray-600 font-sans"> ~ </span>
|
||||
<span v-if="isRange" :class="{ [$style.exalted]: isExa }">{{ maxText }}</span>
|
||||
<span v-if="!currencyText" class="font-sans" :class="{ [$style.exalted]: isExa }"> ×</span>
|
||||
<span v-else-if="price" :class="{ [$style.exalted]: isExa }"> {{ price.currency }}</span>
|
||||
<span v-if="isRange" :class="{ [$style.golden]: isValuable }">{{ maxText }}</span>
|
||||
<span v-if="!currencyText" class="font-sans" :class="{ [$style.golden]: isValuable }"> ×</span>
|
||||
<span v-else-if="price" :class="{ [$style.golden]: isValuable }"> {{ price.currency }}</span>
|
||||
</div>
|
||||
<div class="w-8 h-8 flex items-center justify-center shrink-0" v-if="!currencyText">
|
||||
<img v-if="isExa" src="/images/exa.png" class="max-w-full max-h-full">
|
||||
<img v-if="isValuable" src="/images/divine.png" class="max-w-full max-h-full">
|
||||
<img v-else src="/images/chaos.png" class="max-w-full max-h-full">
|
||||
</div>
|
||||
</div>
|
||||
@@ -28,7 +28,7 @@ import { displayRounding } from '../background/Prices'
|
||||
export default defineComponent({
|
||||
props: {
|
||||
price: {
|
||||
type: Object as PropType<{ min: number, max: number, currency: 'exa' | 'chaos' }>,
|
||||
type: Object as PropType<{ min: number, max: number, currency: 'div' | 'chaos' }>,
|
||||
default: undefined
|
||||
},
|
||||
approx: {
|
||||
@@ -56,14 +56,14 @@ export default defineComponent({
|
||||
minText,
|
||||
maxText,
|
||||
isRange: computed(() => { return minText.value !== maxText.value }),
|
||||
isExa: computed(() => { return props.price?.currency === 'exa' })
|
||||
isValuable: computed(() => { return props.price?.currency !== 'chaos' })
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style module>
|
||||
.exalted {
|
||||
.golden {
|
||||
color: #e4c29a;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user